1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
/** @file
Definition for IP6 pseudo interface structure.
Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef __EFI_IP6_IF_H__
#define __EFI_IP6_IF_H__
#define IP6_LINK_RX_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'R')
#define IP6_LINK_TX_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'T')
#define IP6_INTERFACE_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'I')
#define IP6_ADDR_INFO_SIGNATURE SIGNATURE_32 ('I', 'P', 'A', 'I')
//
// This prototype is used by both receive and transmission.
// When receiving Netbuf is allocated by IP6_INTERFACE, and
// released by IP6. Flag shows whether the frame is received
// as unicast/multicast/anycast...
//
// When transmitting, the Netbuf is from IP6, and provided
// to the callback as a reference. Flag isn't used.
//
// IpInstance can be NULL which means that it is the IP6 driver
// itself sending the packets. IP6 driver may send packets that
// don't belong to any instance, such as ICMP errors, ICMP
// informational packets. IpInstance is used as a tag in
// this module.
//
typedef
VOID
(*IP6_FRAME_CALLBACK) (
NET_BUF *Packet,
EFI_STATUS IoStatus,
UINT32 LinkFlag,
VOID *Context
);
//
// Each receive request is wrapped in an IP6_LINK_RX_TOKEN.
// Upon completion, the Callback will be called. Only one
// receive request is send to MNP. IpInstance is always NULL.
// Reference MNP's spec for information.
//
typedef struct {
UINT32 Signature;
IP6_FRAME_CALLBACK CallBack;
VOID *Context;
EFI_MANAGED_NETWORK_COMPLETION_TOKEN MnpToken;
} IP6_LINK_RX_TOKEN;
//
// Each transmit request is wrapped in an IP6_LINK_TX_TOKEN.
// Upon completion, the Callback will be called.
//
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
IP6_PROTOCOL *IpInstance;
IP6_FRAME_CALLBACK CallBack;
NET_BUF *Packet;
VOID *Context;
EFI_MAC_ADDRESS DstMac;
EFI_MAC_ADDRESS SrcMac;
EFI_MANAGED_NETWORK_COMPLETION_TOKEN MnpToken;
EFI_MANAGED_NETWORK_TRANSMIT_DATA MnpTxData;
} IP6_LINK_TX_TOKEN;
struct _IP6_ADDRESS_INFO {
UINT32 Signature;
LIST_ENTRY Link;
EFI_IPv6_ADDRESS Address;
BOOLEAN IsAnycast;
UINT8 PrefixLength;
UINT32 ValidLifetime;
UINT32 PreferredLifetime;
};
//
// Callback to select which frame to cancel. Caller can cancel a
// single frame, or all the frame from an IP instance.
//
typedef
BOOLEAN
(*IP6_FRAME_TO_CANCEL) (
IP6_LINK_TX_TOKEN *Frame,
VOID *Context
);
struct _IP6_INTERFACE {
UINT32 Signature;
LIST_ENTRY Link;
INTN RefCnt;
//
// IP address and prefix length of the interface. The fileds
// are invalid if (Configured == FALSE)
//
LIST_ENTRY AddressList;
UINT32 AddressCount;
BOOLEAN Configured;
IP6_SERVICE *Service;
EFI_HANDLE Controller;
EFI_HANDLE Image;
//
// Queues to keep the frames sent and waiting ARP request.
//
LIST_ENTRY ArpQues;
LIST_ENTRY SentFrames;
//
// The interface's configuration variables
//
UINT32 DupAddrDetect;
LIST_ENTRY DupAddrDetectList;
LIST_ENTRY DelayJoinList;
//
// All the IP instances that have the same IP/SubnetMask are linked
// together through IpInstances. If any of the instance enables
// promiscuous receive, PromiscRecv is true.
//
LIST_ENTRY IpInstances;
BOOLEAN PromiscRecv;
};
/**
Create an IP6_INTERFACE.
@param[in] IpSb The IP6 service binding instance.
@param[in] LinkLocal If TRUE, the instance is created for link-local address.
Otherwise, it is not for a link-local address.
@return Point to the created IP6_INTERFACE, otherwise NULL.
**/
IP6_INTERFACE *
Ip6CreateInterface (
IN IP6_SERVICE *IpSb,
IN BOOLEAN LinkLocal
);
/**
Free the interface used by IpInstance. All the IP instance with
the same Ip/prefix pair share the same interface. It is reference
counted. All the frames that haven't been sent will be cancelled.
Because the IpInstance is optional, the caller must remove
IpInstance from the interface's instance list.
@param[in] Interface The interface used by the IpInstance.
@param[in] IpInstance The IP instance that free the interface. NULL if
the IP driver is releasing the default interface.
**/
VOID
Ip6CleanInterface (
IN IP6_INTERFACE *Interface,
IN IP6_PROTOCOL *IpInstance OPTIONAL
);
/**
Free the link layer transmit token. It will close the event
then free the memory used.
@param[in] Token Token to free.
**/
VOID
Ip6FreeLinkTxToken (
IN IP6_LINK_TX_TOKEN *Token
);
/**
Request Ip6OnFrameReceivedDpc as a DPC at TPL_CALLBACK
@param Event The receive event delivered to MNP for receive.
@param Context Context for the callback.
**/
VOID
EFIAPI
Ip6OnFrameReceived (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Request to receive the packet from the interface.
@param[in] CallBack Function to call when the receive finished.
@param[in] IpSb Points to the IP6 service binding instance.
@retval EFI_ALREADY_STARTED There is already a pending receive request.
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources to receive.
@retval EFI_SUCCESS The receive request has been started.
**/
EFI_STATUS
Ip6ReceiveFrame (
IN IP6_FRAME_CALLBACK CallBack,
IN IP6_SERVICE *IpSb
);
/**
Send a frame from the interface. If the next hop is multicast address,
it is transmitted immediately. If the next hop is a unicast,
and the NextHop's MAC is not known, it will perform address resolution.
If some error happened, the CallBack won't be called. So, the caller
must test the return value, and take action when there is an error.
@param[in] Interface The interface to send the frame from
@param[in] IpInstance The IP child that request the transmission.
NULL if it is the IP6 driver itself.
@param[in] Packet The packet to transmit.
@param[in] NextHop The immediate destination to transmit the packet to.
@param[in] CallBack Function to call back when transmit finished.
@param[in] Context Opaque parameter to the call back.
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource to send the frame.
@retval EFI_NO_MAPPING Can't resolve the MAC for the nexthop.
@retval EFI_SUCCESS The packet successfully transmitted.
**/
EFI_STATUS
Ip6SendFrame (
IN IP6_INTERFACE *Interface,
IN IP6_PROTOCOL *IpInstance OPTIONAL,
IN NET_BUF *Packet,
IN EFI_IPv6_ADDRESS *NextHop,
IN IP6_FRAME_CALLBACK CallBack,
IN VOID *Context
);
/**
The heartbeat timer of IP6 service instance. It times out
all of its IP6 children's received-but-not-delivered and
transmitted-but-not-recycle packets.
@param[in] Event The IP6 service instance's heart beat timer.
@param[in] Context The IP6 service instance.
**/
VOID
EFIAPI
Ip6TimerTicking (
IN EFI_EVENT Event,
IN VOID *Context
);
#endif
|