Home | History | Annotate | Download | only in Ip6Dxe
      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