1 /** @file
2   Implementation of EFI_IP6_PROTOCOL protocol interfaces and type definitions.
3 
4   Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
5   (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
6 
7   This program and the accompanying materials
8   are licensed and made available under the terms and conditions of the BSD License
9   which accompanies this distribution.  The full text of the license may be found at
10   http://opensource.org/licenses/bsd-license.php.
11 
12   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #ifndef __EFI_IP6_IMPL_H__
18 #define __EFI_IP6_IMPL_H__
19 
20 #include <Uefi.h>
21 
22 #include <Protocol/ServiceBinding.h>
23 #include <Protocol/ManagedNetwork.h>
24 #include <Protocol/IpSec.h>
25 #include <Protocol/Ip6.h>
26 #include <Protocol/Ip6Config.h>
27 #include <Protocol/Dhcp6.h>
28 #include <Protocol/DevicePath.h>
29 #include <Protocol/HiiConfigRouting.h>
30 #include <Protocol/HiiConfigAccess.h>
31 
32 #include <Library/DebugLib.h>
33 #include <Library/UefiBootServicesTableLib.h>
34 #include <Library/UefiRuntimeServicesTableLib.h>
35 #include <Library/BaseLib.h>
36 #include <Library/UefiLib.h>
37 #include <Library/NetLib.h>
38 #include <Library/BaseMemoryLib.h>
39 #include <Library/MemoryAllocationLib.h>
40 #include <Library/DpcLib.h>
41 #include <Library/HiiLib.h>
42 #include <Library/UefiHiiServicesLib.h>
43 #include <Library/DevicePathLib.h>
44 #include <Library/PrintLib.h>
45 
46 #include <Guid/MdeModuleHii.h>
47 
48 #include "Ip6Common.h"
49 #include "Ip6Driver.h"
50 #include "Ip6Icmp.h"
51 #include "Ip6If.h"
52 #include "Ip6Input.h"
53 #include "Ip6Mld.h"
54 #include "Ip6Nd.h"
55 #include "Ip6Option.h"
56 #include "Ip6Output.h"
57 #include "Ip6Route.h"
58 #include "Ip6ConfigNv.h"
59 #include "Ip6ConfigImpl.h"
60 
61 #define IP6_PROTOCOL_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'P')
62 #define IP6_SERVICE_SIGNATURE  SIGNATURE_32 ('I', 'P', '6', 'S')
63 
64 //
65 // The state of IP6 protocol. It starts from UNCONFIGED. if it is
66 // successfully configured, it goes to CONFIGED. if configure NULL
67 // is called, it becomes UNCONFIGED again. If (partly) destroyed, it
68 // becomes DESTROY.
69 //
70 #define IP6_STATE_UNCONFIGED   0
71 #define IP6_STATE_CONFIGED     1
72 
73 //
74 // The state of IP6 service. It starts from UNSTARTED. It transits
75 // to STARTED if autoconfigure is started. If default address is
76 // configured, it becomes CONFIGED. and if partly destroyed, it goes
77 // to DESTROY.
78 //
79 #define IP6_SERVICE_UNSTARTED  0
80 #define IP6_SERVICE_STARTED    1
81 #define IP6_SERVICE_CONFIGED   2
82 #define IP6_SERVICE_DESTROY    3
83 
84 #define IP6_INSTANCE_FROM_PROTOCOL(Ip6) \
85           CR ((Ip6), IP6_PROTOCOL, Ip6Proto, IP6_PROTOCOL_SIGNATURE)
86 
87 #define IP6_SERVICE_FROM_PROTOCOL(Sb)   \
88           CR ((Sb), IP6_SERVICE, ServiceBinding, IP6_SERVICE_SIGNATURE)
89 
90 #define IP6_NO_MAPPING(IpInstance) (!(IpInstance)->Interface->Configured)
91 
92 extern EFI_IPSEC2_PROTOCOL *mIpSec;
93 extern BOOLEAN             mIpSec2Installed;
94 
95 //
96 // IP6_TXTOKEN_WRAP wraps the upper layer's transmit token.
97 // The user's data is kept in the Packet. When fragment is
98 // needed, each fragment of the Packet has a reference to the
99 // Packet, no data is actually copied. The Packet will be
100 // released when all the fragments of it have been recycled by
101 // MNP. Upon then, the IP6_TXTOKEN_WRAP will be released, and
102 // user's event signalled.
103 //
104 typedef struct {
105   IP6_PROTOCOL              *IpInstance;
106   EFI_IP6_COMPLETION_TOKEN  *Token;
107   EFI_EVENT                 IpSecRecycleSignal;
108   NET_BUF                   *Packet;
109   BOOLEAN                   Sent;
110   INTN                      Life;
111 } IP6_TXTOKEN_WRAP;
112 
113 typedef struct {
114   EFI_EVENT                 IpSecRecycleSignal;
115   NET_BUF                   *Packet;
116 } IP6_IPSEC_WRAP;
117 
118 //
119 // IP6_RXDATA_WRAP wraps the data IP6 child delivers to the
120 // upper layers. The received packet is kept in the Packet.
121 // The Packet itself may be constructured from some fragments.
122 // All the fragments of the Packet is organized by a
123 // IP6_ASSEMBLE_ENTRY structure. If the Packet is recycled by
124 // the upper layer, the assemble entry and its associated
125 // fragments will be freed at last.
126 //
127 typedef struct {
128   LIST_ENTRY                Link;
129   IP6_PROTOCOL              *IpInstance;
130   NET_BUF                   *Packet;
131   EFI_IP6_RECEIVE_DATA      RxData;
132 } IP6_RXDATA_WRAP;
133 
134 struct _IP6_PROTOCOL {
135   UINT32                    Signature;
136 
137   EFI_IP6_PROTOCOL          Ip6Proto;
138   EFI_HANDLE                Handle;
139   INTN                      State;
140 
141   IP6_SERVICE               *Service;
142   LIST_ENTRY                Link; // Link to all the IP protocol from the service
143 
144   UINT8                     PrefixLength; // PrefixLength of the configured station address.
145   //
146   // User's transmit/receive tokens, and received/deliverd packets
147   //
148   NET_MAP                   RxTokens;
149   NET_MAP                   TxTokens;   // map between (User's Token, IP6_TXTOKE_WRAP)
150   LIST_ENTRY                Received;   // Received but not delivered packet
151   LIST_ENTRY                Delivered;  // Delivered and to be recycled packets
152   EFI_LOCK                  RecycleLock;
153 
154   IP6_INTERFACE             *Interface;
155   LIST_ENTRY                AddrLink;   // Ip instances with the same IP address.
156 
157   EFI_IPv6_ADDRESS          *GroupList; // stored in network order.
158   UINT32                    GroupCount;
159 
160   EFI_IP6_CONFIG_DATA       ConfigData;
161   BOOLEAN                   InDestroy;
162 };
163 
164 struct _IP6_SERVICE {
165   UINT32                          Signature;
166   EFI_SERVICE_BINDING_PROTOCOL    ServiceBinding;
167   INTN                            State;
168 
169   //
170   // List of all the IP instances and interfaces, and default
171   // interface and route table and caches.
172   //
173   UINTN                           NumChildren;
174   LIST_ENTRY                      Children;
175 
176   LIST_ENTRY                      Interfaces;
177 
178   IP6_INTERFACE                   *DefaultInterface;
179   IP6_ROUTE_TABLE                 *RouteTable;
180 
181   IP6_LINK_RX_TOKEN               RecvRequest;
182 
183   //
184   // Ip reassemble utilities and MLD data
185   //
186   IP6_ASSEMBLE_TABLE              Assemble;
187   IP6_MLD_SERVICE_DATA            MldCtrl;
188 
189   EFI_IPv6_ADDRESS                LinkLocalAddr;
190   BOOLEAN                         LinkLocalOk;
191   BOOLEAN                         LinkLocalDadFail;
192   BOOLEAN                         Dhcp6NeedStart;
193   BOOLEAN                         Dhcp6NeedInfoRequest;
194 
195   //
196   // ND data
197   //
198   UINT8                           CurHopLimit;
199   UINT32                          LinkMTU;
200   UINT32                          BaseReachableTime;
201   UINT32                          ReachableTime;
202   UINT32                          RetransTimer;
203   LIST_ENTRY                      NeighborTable;
204 
205   LIST_ENTRY                      OnlinkPrefix;
206   LIST_ENTRY                      AutonomousPrefix;
207 
208   LIST_ENTRY                      DefaultRouterList;
209   UINT32                          RoundRobin;
210 
211   UINT8                           InterfaceIdLen;
212   UINT8                           *InterfaceId;
213 
214   BOOLEAN                         RouterAdvertiseReceived;
215   UINT8                           SolicitTimer;
216   UINT32                          Ticks;
217 
218   //
219   // Low level protocol used by this service instance
220   //
221   EFI_HANDLE                      Image;
222   EFI_HANDLE                      Controller;
223 
224   EFI_HANDLE                      MnpChildHandle;
225   EFI_MANAGED_NETWORK_PROTOCOL    *Mnp;
226 
227   EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData;
228   EFI_SIMPLE_NETWORK_MODE         SnpMode;
229 
230   EFI_EVENT                       Timer;
231   EFI_EVENT                       FasterTimer;
232 
233   //
234   // IPv6 Configuration Protocol instance
235   //
236   IP6_CONFIG_INSTANCE             Ip6ConfigInstance;
237 
238   //
239   // The string representation of the current mac address of the
240   // NIC this IP6_SERVICE works on.
241   //
242   CHAR16                          *MacString;
243   UINT32                          MaxPacketSize;
244   UINT32                          OldMaxPacketSize;
245 };
246 
247 /**
248   The callback function for the net buffer which wraps the user's
249   transmit token. Although this function seems simple,
250   there are some subtle aspects.
251   When a user requests the IP to transmit a packet by passing it a
252   token, the token is wrapped in an IP6_TXTOKEN_WRAP and the data
253   is wrapped in a net buffer. The net buffer's Free function is
254   set to Ip6FreeTxToken. The Token and token wrap are added to the
255   IP child's TxToken map. Then the buffer is passed to Ip6Output for
256   transmission. If an error occurs before that, the buffer
257   is freed, which in turn frees the token wrap. The wrap may
258   have been added to the TxToken map or not, and the user's event
259   shouldn't be signaled because we are still in the EfiIp6Transmit. If
260   the buffer has been sent by Ip6Output, it should be removed from
261   the TxToken map and the user's event signaled. The token wrap and buffer
262   are bound together. Refer to the comments in Ip6Output for information
263   about IP fragmentation.
264 
265   @param[in]  Context                The token's wrap.
266 
267 **/
268 VOID
269 EFIAPI
270 Ip6FreeTxToken (
271   IN VOID                   *Context
272   );
273 
274 /**
275   Config the MNP parameter used by IP. The IP driver use one MNP
276   child to transmit/receive frames. By default, it configures MNP
277   to receive unicast/multicast/broadcast. And it will enable/disable
278   the promiscuous receive according to whether there is IP child
279   enable that or not. If Force is FALSE, it will iterate through
280   all the IP children to check whether the promiscuous receive
281   setting has been changed. If it hasn't been changed, it won't
282   reconfigure the MNP. If Force is TRUE, the MNP is configured
283   whether that is changed or not.
284 
285   @param[in]  IpSb               The IP6 service instance that is to be changed.
286   @param[in]  Force              Force the configuration or not.
287 
288   @retval EFI_SUCCESS            The MNP successfully configured/reconfigured.
289   @retval Others                 The configuration failed.
290 
291 **/
292 EFI_STATUS
293 Ip6ServiceConfigMnp (
294   IN IP6_SERVICE            *IpSb,
295   IN BOOLEAN                Force
296   );
297 
298 /**
299   Cancel the user's receive/transmit request. It is the worker function of
300   EfiIp6Cancel API.
301 
302   @param[in]  IpInstance         The IP6 child.
303   @param[in]  Token              The token to cancel. If NULL, all tokens will be
304                                  cancelled.
305 
306   @retval EFI_SUCCESS            The token was cancelled.
307   @retval EFI_NOT_FOUND          The token isn't found on either the
308                                  transmit or receive queue.
309   @retval EFI_DEVICE_ERROR       Not all tokens are cancelled when Token is NULL.
310 
311 **/
312 EFI_STATUS
313 Ip6Cancel (
314   IN IP6_PROTOCOL             *IpInstance,
315   IN EFI_IP6_COMPLETION_TOKEN *Token          OPTIONAL
316   );
317 
318 /**
319   Initialize the IP6_PROTOCOL structure to the unconfigured states.
320 
321   @param[in]       IpSb                   The IP6 service instance.
322   @param[in, out]  IpInstance             The IP6 child instance.
323 
324 **/
325 VOID
326 Ip6InitProtocol (
327   IN IP6_SERVICE            *IpSb,
328   IN OUT IP6_PROTOCOL       *IpInstance
329   );
330 
331 /**
332   Clean up the IP6 child, release all the resources used by it.
333 
334   @param[in, out]  IpInstance    The IP6 child to clean up.
335 
336   @retval EFI_SUCCESS            The IP6 child was cleaned up
337   @retval EFI_DEVICE_ERROR       Some resources failed to be released.
338 
339 **/
340 EFI_STATUS
341 Ip6CleanProtocol (
342   IN OUT IP6_PROTOCOL            *IpInstance
343   );
344 
345 //
346 // EFI_IP6_PROTOCOL interface prototypes
347 //
348 
349 /**
350   Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
351 
352   The GetModeData() function returns the current operational mode data for this driver instance.
353   The data fields in EFI_IP6_MODE_DATA are read only. This function is used optionally to
354   retrieve the operational mode data of underlying networks or drivers.
355 
356   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
357   @param[out] Ip6ModeData        The pointer to the EFI IPv6 Protocol mode data structure.
358   @param[out] MnpConfigData      The pointer to the managed network configuration data structure.
359   @param[out] SnpModeData        The pointer to the simple network mode data structure.
360 
361   @retval EFI_SUCCESS            The operation completed successfully.
362   @retval EFI_INVALID_PARAMETER  This is NULL.
363   @retval EFI_OUT_OF_RESOURCES   The required mode data could not be allocated.
364 
365 **/
366 EFI_STATUS
367 EFIAPI
368 EfiIp6GetModeData (
369   IN EFI_IP6_PROTOCOL                 *This,
370   OUT EFI_IP6_MODE_DATA               *Ip6ModeData     OPTIONAL,
371   OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData   OPTIONAL,
372   OUT EFI_SIMPLE_NETWORK_MODE         *SnpModeData     OPTIONAL
373   );
374 
375 /**
376   Assigns an IPv6 address and subnet mask to this EFI IPv6 Protocol driver instance.
377 
378   The Configure() function is used to set, change, or reset the operational parameters and filter
379   settings for this EFI IPv6 Protocol instance. Until these parameters have been set, no network traffic
380   can be sent or received by this instance. Once the parameters have been reset (by calling this
381   function with Ip6ConfigData set to NULL), no more traffic can be sent or received until these
382   parameters have been set again. Each EFI IPv6 Protocol instance can be started and stopped
383   independently of each other by enabling or disabling their receive filter settings with the
384   Configure() function.
385 
386   If Ip6ConfigData.StationAddress is a valid non-zero IPv6 unicast address, it is required
387   to be one of the currently configured IPv6 addresses list in the EFI IPv6 drivers, or else
388   EFI_INVALID_PARAMETER will be returned. If Ip6ConfigData.StationAddress is
389   unspecified, the IPv6 driver will bind a source address according to the source address selection
390   algorithm. Clients could frequently call GetModeData() to check get a currently configured IPv6.
391   If both Ip6ConfigData.StationAddress and Ip6ConfigData.Destination are unspecified, when
392   transmitting the packet afterwards, the source address filled in each outgoing IPv6 packet
393   is decided based on the destination of this packet.
394 
395   If operational parameters are reset or changed, any pending transmit and receive requests will be
396   cancelled. Their completion token status will be set to EFI_ABORTED, and their events will be
397   signaled.
398 
399   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
400   @param[in]  Ip6ConfigData      The pointer to the EFI IPv6 Protocol configuration data structure.
401                                  If NULL, reset the configuration data.
402 
403   @retval EFI_SUCCESS            The driver instance was successfully opened.
404   @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
405                                  - This is NULL.
406                                  - Ip6ConfigData.StationAddress is neither zero nor
407                                    a unicast IPv6 address.
408                                  - Ip6ConfigData.StationAddress is neither zero nor
409                                    one of the configured IP addresses in the EFI IPv6 driver.
410                                  - Ip6ConfigData.DefaultProtocol is illegal.
411   @retval EFI_OUT_OF_RESOURCES   The EFI IPv6 Protocol driver instance data could not be allocated.
412   @retval EFI_NO_MAPPING         The IPv6 driver was responsible for choosing a source address for
413                                  this instance, but no source address was available for use.
414   @retval EFI_ALREADY_STARTED    The interface is already open and must be stopped before the IPv6
415                                  address or prefix length can be changed.
416   @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred. The EFI IPv6
417                                  Protocol driver instance was not opened.
418   @retval EFI_UNSUPPORTED        Default protocol specified through
419                                  Ip6ConfigData.DefaulProtocol isn't supported.
420 
421 **/
422 EFI_STATUS
423 EFIAPI
424 EfiIp6Configure (
425   IN EFI_IP6_PROTOCOL          *This,
426   IN EFI_IP6_CONFIG_DATA       *Ip6ConfigData OPTIONAL
427   );
428 
429 /**
430   Joins and leaves multicast groups.
431 
432   The Groups() function is used to join and leave multicast group sessions. Joining a group will
433   enable reception of matching multicast packets. Leaving a group will disable reception of matching
434   multicast packets. Source-Specific Multicast isn't required to be supported.
435 
436   If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left.
437 
438   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
439   @param[in]  JoinFlag           Set to TRUE to join the multicast group session and FALSE to leave.
440   @param[in]  GroupAddress       The pointer to the IPv6 multicast address.
441                                  This is an optional parameter that may be NULL.
442 
443   @retval EFI_SUCCESS            The operation completed successfully.
444   @retval EFI_INVALID_PARAMETER  One or more of the following is TRUE:
445                                  - This is NULL.
446                                  - JoinFlag is TRUE and GroupAddress is NULL.
447                                  - GroupAddress is not NULL and *GroupAddress is
448                                    not a multicast IPv6 address.
449                                  - GroupAddress is not NULL and *GroupAddress is in the
450                                    range of SSM destination address.
451   @retval EFI_NOT_STARTED        This instance has not been started.
452   @retval EFI_OUT_OF_RESOURCES   System resources could not be allocated.
453   @retval EFI_UNSUPPORTED        This EFI IPv6 Protocol implementation does not support multicast groups.
454   @retval EFI_ALREADY_STARTED    The group address is already in the group table (when
455                                  JoinFlag is TRUE).
456   @retval EFI_NOT_FOUND          The group address is not in the group table (when JoinFlag is FALSE).
457   @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
458 
459 **/
460 EFI_STATUS
461 EFIAPI
462 EfiIp6Groups (
463   IN EFI_IP6_PROTOCOL  *This,
464   IN BOOLEAN           JoinFlag,
465   IN EFI_IPv6_ADDRESS  *GroupAddress  OPTIONAL
466   );
467 
468 /**
469   Adds and deletes routing table entries.
470 
471   The Routes() function adds a route to or deletes a route from the routing table.
472 
473   Routes are determined by comparing the leftmost PrefixLength bits of Destination with
474   the destination IPv6 address arithmetically. The gateway address must be on the same subnet as the
475   configured station address.
476 
477   The default route is added with Destination and PrefixLegth both set to all zeros. The
478   default route matches all destination IPv6 addresses that do not match any other routes.
479 
480   All EFI IPv6 Protocol instances share a routing table.
481 
482   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
483   @param[in]  DeleteRoute        Set to TRUE to delete this route from the routing table. Set to
484                                  FALSE to add this route to the routing table. Destination,
485                                  PrefixLength and Gateway are used as the key to each
486                                  route entry.
487   @param[in]  Destination        The address prefix of the subnet that needs to be routed.
488                                  This is an optional parameter that may be NULL.
489   @param[in]  PrefixLength       The prefix length of Destination. Ignored if Destination
490                                  is NULL.
491   @param[in]  GatewayAddress     The unicast gateway IPv6 address for this route.
492                                  This is an optional parameter that may be NULL.
493 
494   @retval EFI_SUCCESS            The operation completed successfully.
495   @retval EFI_NOT_STARTED        The driver instance has not been started.
496   @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
497                                  - This is NULL.
498                                  - When DeleteRoute is TRUE, both Destination and
499                                    GatewayAddress are NULL.
500                                  - When DeleteRoute is FALSE, either Destination or
501                                    GatewayAddress is NULL.
502                                  - *GatewayAddress is not a valid unicast IPv6 address.
503                                  - *GatewayAddress is one of the local configured IPv6
504                                    addresses.
505   @retval EFI_OUT_OF_RESOURCES   Could not add the entry to the routing table.
506   @retval EFI_NOT_FOUND          This route is not in the routing table (when DeleteRoute is TRUE).
507   @retval EFI_ACCESS_DENIED      The route is already defined in the routing table (when
508                                  DeleteRoute is FALSE).
509 
510 **/
511 EFI_STATUS
512 EFIAPI
513 EfiIp6Routes (
514   IN EFI_IP6_PROTOCOL    *This,
515   IN BOOLEAN             DeleteRoute,
516   IN EFI_IPv6_ADDRESS    *Destination    OPTIONAL,
517   IN UINT8               PrefixLength,
518   IN EFI_IPv6_ADDRESS    *GatewayAddress OPTIONAL
519   );
520 
521 /**
522   Add or delete Neighbor cache entries.
523 
524   The Neighbors() function is used to add, update, or delete an entry from a neighbor cache.
525   IPv6 neighbor cache entries are typically inserted and updated by the network protocol driver as
526   network traffic is processed. Most neighbor cache entries will timeout and be deleted if the network
527   traffic stops. Neighbor cache entries that were inserted by Neighbors() may be static (will not
528   timeout) or dynamic (will timeout).
529 
530   The implementation should follow the neighbor cache timeout mechanism defined in
531   RFC4861. The default neighbor cache timeout value should be tuned for the expected network
532   environment.
533 
534   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
535   @param[in]  DeleteFlag         Set to TRUE to delete the specified cache entry. Set to FALSE to
536                                  add (or update, if it already exists and Override is TRUE) the
537                                  specified cache entry. TargetIp6Address is used as the key
538                                  to find the requested cache entry.
539   @param[in]  TargetIp6Address   The pointer to the Target IPv6 address.
540   @param[in]  TargetLinkAddress  The pointer to link-layer address of the target. Ignored if NULL.
541   @param[in]  Timeout            Time in 100-ns units that this entry will remain in the neighbor
542                                  cache, it will be deleted after Timeout. A value of zero means that
543                                  the entry is permanent. A non-zero value means that the entry is
544                                  dynamic.
545   @param[in]  Override           If TRUE, the cached link-layer address of the matching entry will
546                                  be overridden and updated; if FALSE, EFI_ACCESS_DENIED
547                                  will be returned if a corresponding cache entry already exists.
548 
549   @retval  EFI_SUCCESS           The data has been queued for transmission.
550   @retval  EFI_NOT_STARTED       This instance has not been started.
551   @retval  EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
552                                  - This is NULL.
553                                  - TargetIpAddress is NULL.
554                                  - *TargetLinkAddress is invalid when not NULL.
555                                  - *TargetIpAddress is not a valid unicast IPv6 address.
556                                  - *TargetIpAddress is one of the local configured IPv6
557                                    addresses.
558   @retval  EFI_OUT_OF_RESOURCES  Could not add the entry to the neighbor cache.
559   @retval  EFI_NOT_FOUND         This entry is not in the neighbor cache (when DeleteFlag  is
560                                  TRUE or when DeleteFlag  is FALSE while
561                                  TargetLinkAddress is NULL.).
562   @retval  EFI_ACCESS_DENIED     The to-be-added entry is already defined in the neighbor cache,
563                                  and that entry is tagged as un-overridden (when Override
564                                  is FALSE).
565 
566 **/
567 EFI_STATUS
568 EFIAPI
569 EfiIp6Neighbors (
570   IN EFI_IP6_PROTOCOL          *This,
571   IN BOOLEAN                   DeleteFlag,
572   IN EFI_IPv6_ADDRESS          *TargetIp6Address,
573   IN EFI_MAC_ADDRESS           *TargetLinkAddress OPTIONAL,
574   IN UINT32                    Timeout,
575   IN BOOLEAN                   Override
576   );
577 
578 /**
579   Places outgoing data packets into the transmit queue.
580 
581   The Transmit() function places a sending request in the transmit queue of this
582   EFI IPv6 Protocol instance. Whenever the packet in the token is sent out or some
583   errors occur, the event in the token will be signaled and the status is updated.
584 
585   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
586   @param[in]  Token              The pointer to the transmit token.
587 
588   @retval  EFI_SUCCESS           The data has been queued for transmission.
589   @retval  EFI_NOT_STARTED       This instance has not been started.
590   @retval  EFI_NO_MAPPING        The IPv6 driver was responsible for choosing
591                                  a source address for this transmission,
592                                  but no source address was available for use.
593   @retval  EFI_INVALID_PARAMETER One or more of the following is TRUE:
594                                  - This is NULL.
595                                  - Token is NULL.
596                                  - Token.Event is NULL.
597                                  - Token.Packet.TxData is NULL.
598                                  - Token.Packet.ExtHdrsLength is not zero and
599                                    Token.Packet.ExtHdrs is NULL.
600                                  - Token.Packet.FragmentCount is zero.
601                                  - One or more of the Token.Packet.TxData.
602                                    FragmentTable[].FragmentLength fields is zero.
603                                  - One or more of the Token.Packet.TxData.
604                                    FragmentTable[].FragmentBuffer fields is NULL.
605                                  - Token.Packet.TxData.DataLength is zero or not
606                                    equal to the sum of fragment lengths.
607                                  - Token.Packet.TxData.DestinationAddress is non-
608                                    zero when DestinationAddress is configured as
609                                    non-zero when doing Configure() for this
610                                    EFI IPv6 protocol instance.
611                                  - Token.Packet.TxData.DestinationAddress is
612                                    unspecified when DestinationAddress is unspecified
613                                    when doing Configure() for this EFI IPv6 protocol
614                                    instance.
615   @retval  EFI_ACCESS_DENIED     The transmit completion token with the same Token.
616                                  The event was already in the transmit queue.
617   @retval  EFI_NOT_READY         The completion token could not be queued because
618                                  the transmit queue is full.
619   @retval  EFI_NOT_FOUND         Not route is found to the destination address.
620   @retval  EFI_OUT_OF_RESOURCES  Could not queue the transmit data.
621   @retval  EFI_BUFFER_TOO_SMALL  Token.Packet.TxData.TotalDataLength is too
622                                  short to transmit.
623   @retval  EFI_BAD_BUFFER_SIZE   If Token.Packet.TxData.DataLength is beyond the
624                                  maximum that which can be described through the
625                                  Fragment Offset field in Fragment header when
626                                  performing fragmentation.
627   @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
628 
629 **/
630 EFI_STATUS
631 EFIAPI
632 EfiIp6Transmit (
633   IN EFI_IP6_PROTOCOL          *This,
634   IN EFI_IP6_COMPLETION_TOKEN  *Token
635   );
636 
637 /**
638   Places a receiving request into the receiving queue.
639 
640   The Receive() function places a completion token into the receive packet queue.
641   This function is always asynchronous.
642 
643   The Token.Event field in the completion token must be filled in by the caller
644   and cannot be NULL. When the receive operation completes, the EFI IPv6 Protocol
645   driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event
646   is signaled.
647 
648   Current Udp implementation creates an IP child for each Udp child.
649   It initates a asynchronous receive immediately whether or not
650   there is no mapping. Therefore, disable the returning EFI_NO_MAPPING for now.
651   To enable it, the following check must be performed:
652 
653   if (NetIp6IsUnspecifiedAddr (&Config->StationAddress) && IP6_NO_MAPPING (IpInstance)) {
654     Status = EFI_NO_MAPPING;
655     goto Exit;
656   }
657 
658   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
659   @param[in]  Token              The pointer to a token that is associated with the
660                                  receive data descriptor.
661 
662   @retval EFI_SUCCESS            The receive completion token was cached.
663   @retval EFI_NOT_STARTED        This EFI IPv6 Protocol instance has not been started.
664   @retval EFI_NO_MAPPING         When IP6 driver responsible for binding source address to this instance,
665                                  while no source address is available for use.
666   @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
667                                  - This is NULL.
668                                  - Token is NULL.
669                                  - Token.Event is NULL.
670   @retval EFI_OUT_OF_RESOURCES   The receive completion token could not be queued due to a lack of system
671                                  resources (usually memory).
672   @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
673                                  The EFI IPv6 Protocol instance has been reset to startup defaults.
674   @retval EFI_ACCESS_DENIED      The receive completion token with the same Token.Event was already
675                                  in the receive queue.
676   @retval EFI_NOT_READY          The receive request could not be queued because the receive queue is full.
677 
678 **/
679 EFI_STATUS
680 EFIAPI
681 EfiIp6Receive (
682   IN EFI_IP6_PROTOCOL          *This,
683   IN EFI_IP6_COMPLETION_TOKEN  *Token
684   );
685 
686 /**
687   Abort an asynchronous transmit or receive request.
688 
689   The Cancel() function is used to abort a pending transmit or receive request.
690   If the token is in the transmit or receive request queues, after calling this
691   function, Token->Status will be set to EFI_ABORTED, and then Token->Event will
692   be signaled. If the token is not in one of the queues, which usually means the
693   asynchronous operation has completed, this function will not signal the token,
694   and EFI_NOT_FOUND is returned.
695 
696   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
697   @param[in]  Token              The pointer to a token that has been issued by
698                                  EFI_IP6_PROTOCOL.Transmit() or
699                                  EFI_IP6_PROTOCOL.Receive(). If NULL, all pending
700                                  tokens are aborted. Type EFI_IP6_COMPLETION_TOKEN is
701                                  defined in EFI_IP6_PROTOCOL.Transmit().
702 
703   @retval EFI_SUCCESS            The asynchronous I/O request was aborted and
704                                  Token->Event was signaled. When Token is NULL, all
705                                  pending requests were aborted, and their events were signaled.
706   @retval EFI_INVALID_PARAMETER  This is NULL.
707   @retval EFI_NOT_STARTED        This instance has not been started.
708   @retval EFI_NOT_FOUND          When Token is not NULL, the asynchronous I/O request was
709                                  not found in the transmit or receive queue. It has either completed
710                                  or was not issued by Transmit() and Receive().
711   @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
712 
713 **/
714 EFI_STATUS
715 EFIAPI
716 EfiIp6Cancel (
717   IN EFI_IP6_PROTOCOL          *This,
718   IN EFI_IP6_COMPLETION_TOKEN  *Token    OPTIONAL
719   );
720 
721 /**
722   Polls for incoming data packets and processes outgoing data packets.
723 
724   The Poll() function polls for incoming data packets and processes outgoing data
725   packets. Network drivers and applications can call the EFI_IP6_PROTOCOL.Poll()
726   function to increase the rate that data packets are moved between the communications
727   device and the transmit and receive queues.
728 
729   In some systems the periodic timer event may not poll the underlying communications
730   device fast enough to transmit and/or receive all data packets without missing
731   incoming packets or dropping outgoing packets. Drivers and applications that are
732   experiencing packet loss should try calling the EFI_IP6_PROTOCOL.Poll() function
733   more often.
734 
735   @param[in]  This               The pointer to the EFI_IP6_PROTOCOL instance.
736 
737   @retval  EFI_SUCCESS           Incoming or outgoing data was processed.
738   @retval  EFI_NOT_STARTED       This EFI IPv6 Protocol instance has not been started.
739   @retval  EFI_INVALID_PARAMETER This is NULL.
740   @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred.
741   @retval  EFI_NOT_READY         No incoming or outgoing data was processed.
742   @retval  EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.
743                                  Consider increasing the polling rate.
744 
745 **/
746 EFI_STATUS
747 EFIAPI
748 EfiIp6Poll (
749   IN EFI_IP6_PROTOCOL          *This
750   );
751 
752 #endif
753