]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Add IPv6 versions of existing IPv4 headers and GUID definitions
authorMichael Brown <mcb30@ipxe.org>
Wed, 7 Jun 2023 11:27:06 +0000 (12:27 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 7 Jun 2023 11:27:06 +0000 (12:27 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/Protocol/Dhcp6.h [new file with mode: 0644]
src/include/ipxe/efi/Protocol/Ip6.h [new file with mode: 0644]
src/include/ipxe/efi/Protocol/Ip6Config.h [new file with mode: 0644]
src/include/ipxe/efi/Protocol/Mtftp6.h [new file with mode: 0644]
src/include/ipxe/efi/Protocol/Tcp6.h [new file with mode: 0644]
src/include/ipxe/efi/Protocol/Udp6.h [new file with mode: 0644]
src/include/ipxe/efi/efi.h
src/interface/efi/efi_debug.c
src/interface/efi/efi_guid.c

diff --git a/src/include/ipxe/efi/Protocol/Dhcp6.h b/src/include/ipxe/efi/Protocol/Dhcp6.h
new file mode 100644 (file)
index 0000000..19f5908
--- /dev/null
@@ -0,0 +1,782 @@
+/** @file
+  UEFI Dynamic Host Configuration Protocol 6 Definition, which is used to get IPv6
+  addresses and other configuration parameters from DHCPv6 servers.
+
+  Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Revision Reference:
+  This Protocol is introduced in UEFI Specification 2.2
+
+**/
+
+#ifndef __EFI_DHCP6_PROTOCOL_H__
+#define __EFI_DHCP6_PROTOCOL_H__
+
+FILE_LICENCE ( BSD2_PATENT );
+
+#define EFI_DHCP6_PROTOCOL_GUID \
+  { \
+    0x87c8bad7, 0x595, 0x4053, {0x82, 0x97, 0xde, 0xde, 0x39, 0x5f, 0x5d, 0x5b } \
+  }
+
+#define EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID \
+  { \
+    0x9fb9a8a1, 0x2f4a, 0x43a6, {0x88, 0x9c, 0xd0, 0xf7, 0xb6, 0xc4, 0x7a, 0xd5 } \
+  }
+
+typedef struct _EFI_DHCP6_PROTOCOL EFI_DHCP6_PROTOCOL;
+
+typedef enum {
+  ///
+  /// The EFI DHCPv6 Protocol instance is configured, and start() needs
+  /// to be called
+  ///
+  Dhcp6Init = 0x0,
+  ///
+  /// A Solicit packet is sent out to discover DHCPv6 server, and the EFI
+  /// DHCPv6 Protocol instance is collecting Advertise packets.
+  ///
+  Dhcp6Selecting = 0x1,
+  ///
+  /// A Request is sent out to the DHCPv6 server, and the EFI DHCPv6
+  /// Protocol instance is waiting for Reply packet.
+  ///
+  Dhcp6Requesting = 0x2,
+  ///
+  /// A Decline packet is sent out to indicate one or more addresses of the
+  /// configured IA are in use by another node, and the EFI DHCPv6.
+  /// Protocol instance is waiting for Reply packet.
+  ///
+  Dhcp6Declining = 0x3,
+  ///
+  /// A Confirm packet is sent out to confirm the IPv6 addresses of the
+  /// configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet.
+  ///
+  Dhcp6Confirming = 0x4,
+  ///
+  /// A Release packet is sent out to release one or more IPv6 addresses of
+  /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet.
+  ///
+  Dhcp6Releasing = 0x5,
+  ///
+  /// The DHCPv6 S.A.R.R process is completed for the configured IA.
+  ///
+  Dhcp6Bound = 0x6,
+  ///
+  /// A Renew packet is sent out to extend lifetime for the IPv6 addresses of
+  /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet.
+  ///
+  Dhcp6Renewing = 0x7,
+  ///
+  /// A Rebind packet is sent out to extend lifetime for the IPv6 addresses of
+  /// the configured IA, and the EFI DHCPv6 Protocol instance is waiting for Reply packet.
+  ///
+  Dhcp6Rebinding = 0x8
+} EFI_DHCP6_STATE;
+
+typedef enum {
+  ///
+  /// A Solicit packet is about to be sent. The packet is passed to Dhcp6Callback and
+  /// can be modified or replaced in Dhcp6Callback.
+  ///
+  Dhcp6SendSolicit = 0x0,
+  ///
+  /// An Advertise packet is received and will be passed to Dhcp6Callback.
+  ///
+  Dhcp6RcvdAdvertise = 0x1,
+  ///
+  /// It is time for Dhcp6Callback to determine whether select the default Advertise
+  /// packet by RFC 3315 policy, or overwrite it by specific user policy.
+  ///
+  Dhcp6SelectAdvertise = 0x2,
+  ///
+  /// A Request packet is about to be sent. The packet is passed to Dhcp6Callback and
+  /// can be modified or replaced in Dhcp6Callback.
+  ///
+  Dhcp6SendRequest = 0x3,
+  ///
+  /// A Reply packet is received and will be passed to Dhcp6Callback.
+  ///
+  Dhcp6RcvdReply = 0x4,
+  ///
+  /// A Reconfigure packet is received and will be passed to Dhcp6Callback.
+  ///
+  Dhcp6RcvdReconfigure = 0x5,
+  ///
+  /// A Decline packet is about to be sent. The packet is passed to Dhcp6Callback and
+  /// can be modified or replaced in Dhcp6Callback.
+  ///
+  Dhcp6SendDecline = 0x6,
+  ///
+  /// A Confirm packet is about to be sent. The packet is passed to Dhcp6Callback and
+  /// can be modified or replaced in Dhcp6Callback.
+  ///
+  Dhcp6SendConfirm = 0x7,
+  ///
+  /// A Release packet is about to be sent. The packet is passed to Dhcp6Callback and
+  /// can be modified or replaced in Dhcp6Callback.
+  ///
+  Dhcp6SendRelease = 0x8,
+  ///
+  /// A Renew packet is about to be sent. The packet is passed to Dhcp6Callback and
+  /// can be modified or replaced in Dhcp6Callback.
+  ///
+  Dhcp6EnterRenewing = 0x9,
+  ///
+  /// A Rebind packet is about to be sent. The packet is passed to Dhcp6Callback and
+  /// can be modified or replaced in Dhcp6Callback.
+  ///
+  Dhcp6EnterRebinding = 0xa
+} EFI_DHCP6_EVENT;
+
+///
+/// An IA which carries assigned not temporary address.
+///
+#define EFI_DHCP6_IA_TYPE_NA  3
+///
+/// An IA which carries assigned temporary address.
+///
+#define EFI_DHCP6_IA_TYPE_TA  4
+
+#pragma pack(1)
+///
+/// EFI_DHCP6_PACKET_OPTION
+/// defines the format of the DHCPv6 option, See RFC 3315 for more information.
+/// This data structure is used to reference option data that is packed in the DHCPv6 packet.
+///
+typedef struct {
+  ///
+  /// The DHCPv6 option code, stored in network order.
+  ///
+  UINT16    OpCode;
+  ///
+  /// Length of the DHCPv6 option data, stored in network order.
+  /// From the first byte to the last byte of the Data field.
+  ///
+  UINT16    OpLen;
+  ///
+  /// The data for the DHCPv6 option, stored in network order.
+  ///
+  UINT8     Data[1];
+} EFI_DHCP6_PACKET_OPTION;
+
+///
+/// EFI_DHCP6_HEADER
+/// defines the format of the DHCPv6 header. See RFC 3315 for more information.
+///
+typedef struct {
+  ///
+  /// The DHCPv6 transaction ID.
+  ///
+  UINT32    MessageType   : 8;
+  ///
+  /// The DHCPv6 message type.
+  ///
+  UINT32    TransactionId : 24;
+} EFI_DHCP6_HEADER;
+
+///
+/// EFI_DHCP6_PACKET
+/// defines the format of the DHCPv6 packet. See RFC 3315 for more information.
+///
+typedef struct {
+  ///
+  /// Size of the EFI_DHCP6_PACKET buffer.
+  ///
+  UINT32    Size;
+  ///
+  /// Length of the EFI_DHCP6_PACKET from the first byte of the Header field to the last
+  /// byte of the Option[] field.
+  ///
+  UINT32    Length;
+  struct {
+    ///
+    /// The DHCPv6 packet header.
+    ///
+    EFI_DHCP6_HEADER    Header;
+    ///
+    /// Start of the DHCPv6 packed option data.
+    ///
+    UINT8               Option[1];
+  } Dhcp6;
+} EFI_DHCP6_PACKET;
+
+#pragma pack()
+
+typedef struct {
+  ///
+  /// Length of DUID in octects.
+  ///
+  UINT16    Length;
+  ///
+  /// Array of DUID octects.
+  ///
+  UINT8     Duid[1];
+} EFI_DHCP6_DUID;
+
+typedef struct {
+  ///
+  /// Initial retransmission timeout.
+  ///
+  UINT32    Irt;
+  ///
+  /// Maximum retransmission count for one packet. If Mrc is zero, there's no upper limit
+  /// for retransmission count.
+  ///
+  UINT32    Mrc;
+  ///
+  /// Maximum retransmission timeout for each retry. It's the upper bound of the number of
+  /// retransmission timeout. If Mrt is zero, there is no upper limit for retransmission
+  /// timeout.
+  ///
+  UINT32    Mrt;
+  ///
+  /// Maximum retransmission duration for one packet. It's the upper bound of the numbers
+  /// the client may retransmit a message. If Mrd is zero, there's no upper limit for
+  /// retransmission duration.
+  ///
+  UINT32    Mrd;
+} EFI_DHCP6_RETRANSMISSION;
+
+typedef struct {
+  ///
+  /// The IPv6 address.
+  ///
+  EFI_IPv6_ADDRESS    IpAddress;
+  ///
+  /// The preferred lifetime in unit of seconds for the IPv6 address.
+  ///
+  UINT32              PreferredLifetime;
+  ///
+  /// The valid lifetime in unit of seconds for the IPv6 address.
+  ///
+  UINT32              ValidLifetime;
+} EFI_DHCP6_IA_ADDRESS;
+
+typedef struct {
+  UINT16    Type;                    ///< Type for an IA.
+  UINT32    IaId;                    ///< The identifier for an IA.
+} EFI_DHCP6_IA_DESCRIPTOR;
+
+typedef struct {
+  ///
+  /// The descriptor for IA.
+  ///
+  EFI_DHCP6_IA_DESCRIPTOR    Descriptor;
+  ///
+  /// The state of the configured IA.
+  ///
+  EFI_DHCP6_STATE            State;
+  ///
+  /// Pointer to the cached latest Reply packet. May be NULL if no packet is cached.
+  ///
+  EFI_DHCP6_PACKET           *ReplyPacket;
+  ///
+  /// Number of IPv6 addresses of the configured IA.
+  ///
+  UINT32                     IaAddressCount;
+  ///
+  /// List of the IPv6 addresses of the configured IA. When the state of the configured IA is
+  /// in Dhcp6Bound, Dhcp6Renewing and Dhcp6Rebinding, the IPv6 addresses are usable.
+  ///
+  EFI_DHCP6_IA_ADDRESS       IaAddress[1];
+} EFI_DHCP6_IA;
+
+typedef struct {
+  ///
+  /// Pointer to the DHCPv6 unique identifier. The caller is responsible for freeing this buffer.
+  ///
+  EFI_DHCP6_DUID    *ClientId;
+  ///
+  /// Pointer to the configured IA of current instance. The caller can free this buffer after
+  /// using it.
+  ///
+  EFI_DHCP6_IA      *Ia;
+} EFI_DHCP6_MODE_DATA;
+
+/**
+  EFI_DHCP6_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol instance to
+  intercept events that occurs in the DHCPv6 S.A.R.R process.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance that is used to configure this
+                                callback function.
+  @param[in]  Context           Pointer to the context that is initialized by EFI_DHCP6_PROTOCOL.Configure().
+  @param[in]  CurrentState      The current state of the configured IA.
+  @param[in]  Dhcp6Event        The event that occurs in the current state, which usually means a state transition.
+  @param[in]  Packet            Pointer to the DHCPv6 packet that is about to be sent or has been received.
+                                The EFI DHCPv6 Protocol instance is responsible for freeing the buffer.
+  @param[out] NewPacket         Pointer to the new DHCPv6 packet to overwrite the Packet. NewPacket can not
+                                share the buffer with Packet. If *NewPacket is not NULL, the EFI DHCPv6
+                                Protocol instance is responsible for freeing the buffer.
+
+  @retval EFI_SUCCESS           Tell the EFI DHCPv6 Protocol instance to continue the DHCPv6 S.A.R.R process.
+  @retval EFI_ABORTED           Tell the EFI DHCPv6 Protocol instance to abort the DHCPv6 S.A.R.R process,
+                                and the state of the configured IA will be transferred to Dhcp6Init.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_CALLBACK)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN VOID                      *Context,
+  IN EFI_DHCP6_STATE           CurrentState,
+  IN EFI_DHCP6_EVENT           Dhcp6Event,
+  IN EFI_DHCP6_PACKET          *Packet,
+  OUT EFI_DHCP6_PACKET         **NewPacket OPTIONAL
+  );
+
+typedef struct {
+  ///
+  /// The callback function is to intercept various events that occur in the DHCPv6 S.A.R.R
+  /// process. Set to NULL to ignore all those events.
+  ///
+  EFI_DHCP6_CALLBACK          Dhcp6Callback;
+  ///
+  /// Pointer to the context that will be passed to Dhcp6Callback.
+  ///
+  VOID                        *CallbackContext;
+  ///
+  /// Number of the DHCPv6 options in the OptionList.
+  ///
+  UINT32                      OptionCount;
+  ///
+  /// List of the DHCPv6 options to be included in Solicit and Request packet. The buffer
+  /// can be freed after EFI_DHCP6_PROTOCOL.Configure() returns. Ignored if
+  /// OptionCount is zero. OptionList should not contain Client Identifier option
+  /// and any IA option, which will be appended by EFI DHCPv6 Protocol instance
+  /// automatically.
+  ///
+  EFI_DHCP6_PACKET_OPTION     **OptionList;
+  ///
+  /// The descriptor for the IA of the EFI DHCPv6 Protocol instance.
+  ///
+  EFI_DHCP6_IA_DESCRIPTOR     IaDescriptor;
+  ///
+  /// If not NULL, the event will be signaled when any IPv6 address information of the
+  /// configured IA is updated, including IPv6 address, preferred lifetime and valid
+  /// lifetime, or the DHCPv6 S.A.R.R process fails. Otherwise, Start(),
+  /// renewrebind(), decline(), release() and stop() will be blocking
+  /// operations, and they will wait for the exchange process completion or failure.
+  ///
+  EFI_EVENT                   IaInfoEvent;
+  ///
+  /// If TRUE, the EFI DHCPv6 Protocol instance is willing to accept Reconfigure packet.
+  /// Otherwise, it will ignore it. Reconfigure Accept option can not be specified through
+  /// OptionList parameter.
+  ///
+  BOOLEAN                     ReconfigureAccept;
+  ///
+  /// If TRUE, the EFI DHCPv6 Protocol instance will send Solicit packet with Rapid
+  /// Commit option. Otherwise, Rapid Commit option will not be included in Solicit
+  /// packet. Rapid Commit option can not be specified through OptionList parameter.
+  ///
+  BOOLEAN                     RapidCommit;
+  ///
+  /// Parameter to control Solicit packet retransmission behavior. The
+  /// buffer can be freed after EFI_DHCP6_PROTOCOL.Configure() returns.
+  ///
+  EFI_DHCP6_RETRANSMISSION    *SolicitRetransmission;
+} EFI_DHCP6_CONFIG_DATA;
+
+/**
+  EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol
+  instance to intercept events that occurs in the DHCPv6 Information Request exchange process.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance that is used to configure this
+                                callback function.
+  @param[in]  Context           Pointer to the context that is initialized in the EFI_DHCP6_PROTOCOL.InfoRequest().
+  @param[in]  Packet            Pointer to Reply packet that has been received. The EFI DHCPv6 Protocol instance is
+                                responsible for freeing the buffer.
+
+  @retval EFI_SUCCESS           Tell the EFI DHCPv6 Protocol instance to finish Information Request exchange process.
+  @retval EFI_NOT_READY         Tell the EFI DHCPv6 Protocol instance to continue Information Request exchange process.
+  @retval EFI_ABORTED           Tell the EFI DHCPv6 Protocol instance to abort the Information Request exchange process.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_INFO_CALLBACK)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN VOID                      *Context,
+  IN EFI_DHCP6_PACKET          *Packet
+  );
+
+/**
+  Retrieve the current operating mode data and configuration data for the EFI DHCPv6 Protocol instance.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance.
+  @param[out] Dhcp6ModeData     Pointer to the DHCPv6 mode data structure. The caller is responsible for freeing this
+                                structure and each reference buffer.
+  @param[out] Dhcp6ConfigData   Pointer to the DHCPv6 configuration data structure. The caller is responsible for
+                                freeing this structure and each reference buffer.
+
+  @retval EFI_SUCCESS           The mode data was returned.
+  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Protocol instance has not been configured when Dhcp6ConfigData is not NULL.
+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:
+                                - This is NULL.
+                                - Both Dhcp6ConfigData and Dhcp6ModeData are NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_GET_MODE_DATA)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  OUT EFI_DHCP6_MODE_DATA      *Dhcp6ModeData OPTIONAL,
+  OUT EFI_DHCP6_CONFIG_DATA    *Dhcp6ConfigData OPTIONAL
+  );
+
+/**
+  Initialize or clean up the configuration data for the EFI DHCPv6 Protocol instance.
+
+  The Configure() function is used to initialize or clean up the configuration data of the EFI
+  DHCPv6 Protocol instance.
+  - When Dhcp6CfgData is not NULL and Configure() is called successfully, the
+    configuration data will be initialized in the EFI DHCPv6 Protocol instance and the state of the
+    configured IA will be transferred into Dhcp6Init.
+  - When Dhcp6CfgData is NULL and Configure() is called successfully, the configuration
+    data will be cleaned up and no IA will be associated with the EFI DHCPv6 Protocol instance.
+
+  To update the configuration data for an EFI DCHPv6 Protocol instance, the original data must be
+  cleaned up before setting the new configuration data.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance.
+  @param[in]  Dhcp6CfgData      Pointer to the DHCPv6 configuration data structure.
+
+  @retval EFI_SUCCESS           The mode data was returned.
+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE
+                                - This is NULL.
+                                - OptionCount > 0 and OptionList is NULL.
+                                - OptionList is not NULL, and Client Id option, Reconfigure Accept option,
+                                  Rapid Commit option or any IA option is specified in the OptionList.
+                                - IaDescriptor.Type is neither EFI_DHCP6_IA_TYPE_NA nor EFI_DHCP6_IA_TYPE_NA.
+                                - IaDescriptor is not unique.
+                                - Both IaInfoEvent and SolicitRetransimssion are NULL.
+                                - SolicitRetransmission is not NULL, and both SolicitRetransimssion->Mrc and
+                                  SolicitRetransmission->Mrd are zero.
+  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Protocol instance has been already configured
+                                when Dhcp6CfgData is not NULL.
+                                The EFI DHCPv6 Protocol instance has already started the
+                                DHCPv6 S.A.R.R when Dhcp6CfgData is NULL.
+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_CONFIGURE)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN EFI_DHCP6_CONFIG_DATA     *Dhcp6CfgData OPTIONAL
+  );
+
+/**
+  Start the DHCPv6 S.A.R.R process.
+
+  The Start() function starts the DHCPv6 S.A.R.R process. This function can be called only when
+  the state of the configured IA is in the Dhcp6Init state. If the DHCPv6 S.A.R.R process completes
+  successfully, the state of the configured IA will be transferred through Dhcp6Selecting and
+  Dhcp6Requesting to Dhcp6Bound state. The update of the IPv6 addresses will be notified through
+  EFI_DHCP6_CONFIG_DATA.IaInfoEvent. At the time when each event occurs in this process, the
+  callback function set by EFI_DHCP6_PROTOCOL.Configure() will be called and the user can take
+  this opportunity to control the process. If EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the
+  Start() function call is a blocking operation. It will return after the DHCPv6 S.A.R.R process
+  completes or aborted by users. If the process is aborted by system or network error, the state of
+  the configured IA will be transferred to Dhcp6Init. The Start() function can be called again to
+  restart the process.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The DHCPv6 S.A.R.R process is completed and at least one IPv6
+                                address has been bound to the configured IA when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL.
+                                The DHCPv6 S.A.R.R process is started when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
+  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Child instance hasn't been configured.
+  @retval EFI_INVALID_PARAMETER This is NULL.
+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval EFI_ALREADY_STARTED   The DHCPv6 S.A.R.R process has already started.
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.
+  @retval EFI_NO_RESPONSE       The DHCPv6 S.A.R.R process failed because of no response.
+  @retval EFI_NO_MAPPING        No IPv6 address has been bound to the configured IA after the
+                                DHCPv6 S.A.R.R process.
+  @retval EFI_ABORTED           The DHCPv6 S.A.R.R process aborted by user.
+  @retval EFI_NO_MEDIA          There was a media error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_START)(
+  IN EFI_DHCP6_PROTOCOL        *This
+  );
+
+/**
+  Request configuration information without the assignment of any IA addresses of the client.
+
+  The InfoRequest() function is used to request configuration information without the assignment
+  of any IPv6 address of the client. Client sends out Information Request packet to obtain
+  the required configuration information, and DHCPv6 server responds with Reply packet containing
+  the information for the client. The received Reply packet will be passed to the user by
+  ReplyCallback function. If user returns EFI_NOT_READY from ReplyCallback, the EFI DHCPv6
+  Protocol instance will continue to receive other Reply packets unless timeout according to
+  the Retransmission parameter. Otherwise, the Information Request exchange process will be
+  finished successfully if user returns EFI_SUCCESS from ReplyCallback.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance.
+  @param[in]  SendClientId      If TRUE, the EFI DHCPv6 Protocol instance will build Client
+                                Identifier option and include it into Information Request
+                                packet. If FALSE, Client Identifier option will not be included.
+                                Client Identifier option can not be specified through OptionList
+                                parameter.
+  @param[in]  OptionRequest     Pointer to the Option Request option in the Information Request
+                                packet. Option Request option can not be specified through
+                                OptionList parameter.
+  @param[in]  OptionCount       Number of options in OptionList.
+  @param[in]  OptionList        List of other DHCPv6 options. These options will be appended
+                                to the Option Request option. The caller is responsible for
+                                freeing this buffer. Type is defined in EFI_DHCP6_PROTOCOL.GetModeData().
+  @param[in]  Retransmission    Parameter to control Information Request packet retransmission
+                                behavior. The buffer can be freed after EFI_DHCP6_PROTOCOL.InfoRequest()
+                                returns.
+  @param[in]  TimeoutEvent      If not NULL, this event is signaled when the information request
+                                exchange aborted because of no response. If NULL, the function
+                                call is a blocking operation; and it will return after the
+                                information-request exchange process finish or aborted by users.
+  @param[in]  ReplyCallback     The callback function is to intercept various events that occur
+                                in the Information Request exchange process. It should not be
+                                set to NULL.
+  @param[in]  CallbackContext   Pointer to the context that will be passed to ReplyCallback.
+
+  @retval EFI_SUCCESS           The DHCPv6 S.A.R.R process is completed and at least one IPv6
+  @retval EFI_SUCCESS           The DHCPv6 information request exchange process completed
+                                when TimeoutEvent is NULL. Information Request packet has been
+                                sent to DHCPv6 server when TimeoutEvent is not NULL.
+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:
+                                - This is NULL.
+                                - OptionRequest is NULL or OptionRequest->OpCode is invalid.
+                                - OptionCount > 0 and OptionList is NULL.
+                                - OptionList is not NULL, and Client Identify option or
+                                  Option Request option is specified in the OptionList.
+                                - Retransimssion is NULL.
+                                - Both Retransimssion->Mrc and Retransmission->Mrd are zero.
+                                - ReplyCallback is NULL.
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.
+  @retval EFI_NO_RESPONSE       The DHCPv6 information request exchange process failed
+                                because of no response, or not all requested-options are
+                                responded by DHCPv6 servers when Timeout happened.
+  @retval EFI_ABORTED           The DHCPv6 information request exchange process aborted by user.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_INFO_REQUEST)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN BOOLEAN                   SendClientId,
+  IN EFI_DHCP6_PACKET_OPTION   *OptionRequest,
+  IN UINT32                    OptionCount,
+  IN EFI_DHCP6_PACKET_OPTION   *OptionList[] OPTIONAL,
+  IN EFI_DHCP6_RETRANSMISSION  *Retransmission,
+  IN EFI_EVENT                 TimeoutEvent OPTIONAL,
+  IN EFI_DHCP6_INFO_CALLBACK   ReplyCallback,
+  IN VOID                      *CallbackContext OPTIONAL
+  );
+
+/**
+  Manually extend the valid and preferred lifetimes for the IPv6 addresses of the configured
+  IA and update other configuration parameters by sending Renew or Rebind packet.
+
+  The RenewRebind() function is used to manually extend the valid and preferred lifetimes for the
+  IPv6 addresses of the configured IA and update other configuration parameters by sending Renew or
+  Rebind packet.
+  - When RebindRequest is FALSE and the state of the configured IA is Dhcp6Bound, it
+  will send Renew packet to the previously DHCPv6 server and transfer the state of the configured
+  IA to Dhcp6Renewing. If valid Reply packet received, the state transfers to Dhcp6Bound
+  and the valid and preferred timer restarts. If fails, the state transfers to Dhcp6Bound but the
+  timer continues.
+  - When RebindRequest is TRUE and the state of the configured IA is Dhcp6Bound, it will
+  send Rebind packet. If valid Reply packet received, the state transfers to Dhcp6Bound and the
+  valid and preferred timer restarts. If fails, the state transfers to Dhcp6Init and the IA can't
+  be used.
+
+  @param[in]  This              Pointer to the EFI_DHCP4_PROTOCOL instance.
+  @param[in]  RebindRequest     If TRUE, it will send Rebind packet and enter the Dhcp6Rebinding state.
+                                Otherwise, it will send Renew packet and enter the Dhcp6Renewing state.
+
+  @retval EFI_SUCCESS           The DHCPv6 renew/rebind exchange process has completed and at
+                                least one IPv6 address of the configured IA has been bound again
+                                when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL.
+                                The EFI DHCPv6 Protocol instance has sent Renew or Rebind packet
+                                when EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
+  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Child instance hasn't been configured, or the state
+                                of the configured IA is not in Dhcp6Bound.
+  @retval EFI_ALREADY_STARTED   The state of the configured IA has already entered Dhcp6Renewing
+                                when RebindRequest is FALSE.
+                                The state of the configured IA has already entered Dhcp6Rebinding
+                                when RebindRequest is TRUE.
+  @retval EFI_INVALID_PARAMETER This is NULL.
+  @retval EFI_DEVICE_ERROR      An unexpected system or system error occurred.
+  @retval EFI_NO_RESPONSE       The DHCPv6 renew/rebind exchange process failed because of no response.
+  @retval EFI_NO_MAPPING        No IPv6 address has been bound to the configured IA after the DHCPv6
+                                renew/rebind exchange process.
+  @retval EFI_ABORTED           The DHCPv6 renew/rebind exchange process aborted by user.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_RENEW_REBIND)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN BOOLEAN                   RebindRequest
+  );
+
+/**
+  Inform that one or more IPv6 addresses assigned by a server are already in use by
+  another node.
+
+  The Decline() function is used to manually decline the assignment of IPv6 addresses, which
+  have been already used by another node. If all IPv6 addresses of the configured IA are declined
+  through this function, the state of the IA will switch through Dhcp6Declining to Dhcp6Init,
+  otherwise, the state of the IA will restore to Dhcp6Bound after the declining process. The
+  Decline() can only be called when the IA is in Dhcp6Bound state. If the
+  EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, this function is a blocking operation. It
+  will return after the declining process finishes, or aborted by user.
+
+  @param[in]  This              Pointer to the EFI_DHCP4_PROTOCOL instance.
+  @param[in]  AddressCount      Number of declining IPv6 addresses.
+  @param[in]  Addresses         Pointer to the buffer stored all the declining IPv6 addresses.
+
+  @retval EFI_SUCCESS           The DHCPv6 decline exchange process has completed when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL.
+                                The EFI DHCPv6 Protocol instance has sent Decline packet when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE
+                                - This is NULL.
+                                - AddressCount is zero or Addresses is NULL.
+  @retval EFI_NOT_FOUND         Any specified IPv6 address is not correlated with the configured IA
+                                for this instance.
+  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Child instance hasn't been configured, or the
+                                state of the configured IA is not in Dhcp6Bound.
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.
+  @retval EFI_ABORTED           The DHCPv6 decline exchange process aborted by user.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_DECLINE)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN UINT32                    AddressCount,
+  IN EFI_IPv6_ADDRESS          *Addresses
+  );
+
+/**
+  Release one or more IPv6 addresses associated with the configured IA for current instance.
+
+  The Release() function is used to manually release the one or more IPv6 address. If AddressCount
+  is zero, it will release all IPv6 addresses of the configured IA. If all IPv6 addresses of the IA
+  are released through this function, the state of the IA will switch through Dhcp6Releasing to
+  Dhcp6Init, otherwise, the state of the IA will restore to Dhcp6Bound after the releasing process.
+  The Release() can only be called when the IA is in Dhcp6Bound state. If the
+  EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL, the function is a blocking operation. It will return
+  after the releasing process finishes, or aborted by user.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance.
+  @param[in]  AddressCount      Number of releasing IPv6 addresses.
+  @param[in]  Addresses         Pointer to the buffer stored all the releasing IPv6 addresses.
+                                Ignored if AddressCount is zero.
+  @retval EFI_SUCCESS           The DHCPv6 release exchange process has completed when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL.
+                                The EFI DHCPv6 Protocol instance has sent Release packet when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE
+                                - This is NULL.
+                                - AddressCount is not zero or Addresses is NULL.
+  @retval EFI_NOT_FOUND         Any specified IPv6 address is not correlated with the configured
+                                IA for this instance.
+  @retval EFI_ACCESS_DENIED     The EFI DHCPv6 Child instance hasn't been configured, or the
+                                state of the configured IA is not in Dhcp6Bound.
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.
+  @retval EFI_ABORTED           The DHCPv6 release exchange process aborted by user.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_RELEASE)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN UINT32                    AddressCount,
+  IN EFI_IPv6_ADDRESS          *Addresses
+  );
+
+/**
+  Stop the DHCPv6 S.A.R.R process.
+
+  The Stop() function is used to stop the DHCPv6 S.A.R.R process. If this function is called
+  successfully, all the IPv6 addresses of the configured IA will be released and the state of
+  the configured IA will be transferred to Dhcp6Init.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The DHCPv6 S.A.R.R process has been stopped when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is NULL.
+                                The EFI DHCPv6 Protocol instance has sent Release packet if
+                                need release or has been stopped if needn't, when
+                                EFI_DHCP6_CONFIG_DATA.IaInfoEvent is not NULL.
+  @retval EFI_INVALID_PARAMETER This is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_STOP)(
+  IN EFI_DHCP6_PROTOCOL        *This
+  );
+
+/**
+  Parse the option data in the DHCPv6 packet.
+
+  The Parse() function is used to retrieve the option list in the DHCPv6 packet.
+
+  @param[in]  This              Pointer to the EFI_DHCP6_PROTOCOL instance.
+
+  @param[in]  Packet            Pointer to packet to be parsed.
+  @param[in]  OptionCount       On input, the number of entries in the PacketOptionList.
+                                On output, the number of DHCPv6 options in the Packet.
+  @param[in]  PacketOptionList  List of pointers to the DHCPv6 options in the Packet.
+                                The OpCode and OpLen in EFI_DHCP6_PACKET_OPTION are
+                                both stored in network byte order.
+  @retval EFI_SUCCESS           The packet was successfully parsed.
+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE
+                                - This is NULL.
+                                - Packet is NULL.
+                                - Packet is not a well-formed DHCPv6 packet.
+                                - OptionCount is NULL.
+                                - *OptionCount is not zero and PacketOptionList is NULL.
+  @retval EFI_BUFFER_TOO_SMALL  *OptionCount is smaller than the number of options that were
+                                found in the Packet.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DHCP6_PARSE)(
+  IN EFI_DHCP6_PROTOCOL        *This,
+  IN EFI_DHCP6_PACKET          *Packet,
+  IN OUT UINT32                *OptionCount,
+  OUT EFI_DHCP6_PACKET_OPTION  *PacketOptionList[] OPTIONAL
+  );
+
+///
+/// The EFI DHCPv6 Protocol is used to get IPv6 addresses and other configuration parameters
+/// from DHCPv6 servers.
+///
+struct _EFI_DHCP6_PROTOCOL {
+  EFI_DHCP6_GET_MODE_DATA    GetModeData;
+  EFI_DHCP6_CONFIGURE        Configure;
+  EFI_DHCP6_START            Start;
+  EFI_DHCP6_INFO_REQUEST     InfoRequest;
+  EFI_DHCP6_RENEW_REBIND     RenewRebind;
+  EFI_DHCP6_DECLINE          Decline;
+  EFI_DHCP6_RELEASE          Release;
+  EFI_DHCP6_STOP             Stop;
+  EFI_DHCP6_PARSE            Parse;
+};
+
+extern EFI_GUID  gEfiDhcp6ProtocolGuid;
+extern EFI_GUID  gEfiDhcp6ServiceBindingProtocolGuid;
+
+#endif
diff --git a/src/include/ipxe/efi/Protocol/Ip6.h b/src/include/ipxe/efi/Protocol/Ip6.h
new file mode 100644 (file)
index 0000000..c70df19
--- /dev/null
@@ -0,0 +1,948 @@
+/** @file
+  This file defines the EFI IPv6 (Internet Protocol version 6)
+  Protocol interface. It is split into the following three main
+  sections:
+  - EFI IPv6 Service Binding Protocol
+  - EFI IPv6 Variable (deprecated in UEFI 2.4B)
+  - EFI IPv6 Protocol
+  The EFI IPv6 Protocol provides basic network IPv6 packet I/O services,
+  which includes support for Neighbor Discovery Protocol (ND), Multicast
+  Listener Discovery Protocol (MLD), and a subset of the Internet Control
+  Message Protocol (ICMPv6).
+
+  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Revision Reference:
+  This Protocol is introduced in UEFI Specification 2.2
+
+**/
+
+#ifndef __EFI_IP6_PROTOCOL_H__
+#define __EFI_IP6_PROTOCOL_H__
+
+FILE_LICENCE ( BSD2_PATENT );
+
+#include <ipxe/efi/Protocol/ManagedNetwork.h>
+
+#define EFI_IP6_SERVICE_BINDING_PROTOCOL_GUID \
+  { \
+    0xec835dd3, 0xfe0f, 0x617b, {0xa6, 0x21, 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 } \
+  }
+
+#define EFI_IP6_PROTOCOL_GUID \
+  { \
+    0x2c8759d5, 0x5c2d, 0x66ef, {0x92, 0x5f, 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 } \
+  }
+
+typedef struct _EFI_IP6_PROTOCOL EFI_IP6_PROTOCOL;
+
+///
+/// EFI_IP6_ADDRESS_PAIR is deprecated in the UEFI 2.4B and should not be used any more.
+/// The definition in here is only present to provide backwards compatability.
+///
+typedef struct {
+  ///
+  /// The EFI IPv6 Protocol instance handle that is using this address/prefix pair.
+  ///
+  EFI_HANDLE          InstanceHandle;
+  ///
+  /// IPv6 address in network byte order.
+  ///
+  EFI_IPv6_ADDRESS    Ip6Address;
+  ///
+  /// The length of the prefix associated with the Ip6Address.
+  ///
+  UINT8               PrefixLength;
+} EFI_IP6_ADDRESS_PAIR;
+
+///
+/// EFI_IP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more.
+/// The definition in here is only present to provide backwards compatability.
+///
+typedef struct {
+  ///
+  /// The handle of the driver that creates this entry.
+  ///
+  EFI_HANDLE              DriverHandle;
+  ///
+  /// The number of IPv6 address pairs that follow this data structure.
+  ///
+  UINT32                  AddressCount;
+  ///
+  /// List of IPv6 address pairs that are currently in use.
+  ///
+  EFI_IP6_ADDRESS_PAIR    AddressPairs[1];
+} EFI_IP6_VARIABLE_DATA;
+
+///
+/// ICMPv6 type definitions for error messages
+///
+///@{
+#define ICMP_V6_DEST_UNREACHABLE   0x1
+#define ICMP_V6_PACKET_TOO_BIG     0x2
+#define ICMP_V6_TIME_EXCEEDED      0x3
+#define ICMP_V6_PARAMETER_PROBLEM  0x4
+///@}
+
+///
+/// ICMPv6 type definition for informational messages
+///
+///@{
+#define ICMP_V6_ECHO_REQUEST        0x80
+#define ICMP_V6_ECHO_REPLY          0x81
+#define ICMP_V6_LISTENER_QUERY      0x82
+#define ICMP_V6_LISTENER_REPORT     0x83
+#define ICMP_V6_LISTENER_DONE       0x84
+#define ICMP_V6_ROUTER_SOLICIT      0x85
+#define ICMP_V6_ROUTER_ADVERTISE    0x86
+#define ICMP_V6_NEIGHBOR_SOLICIT    0x87
+#define ICMP_V6_NEIGHBOR_ADVERTISE  0x88
+#define ICMP_V6_REDIRECT            0x89
+#define ICMP_V6_LISTENER_REPORT_2   0x8F
+///@}
+
+///
+/// ICMPv6 code definitions for ICMP_V6_DEST_UNREACHABLE
+///
+///@{
+#define ICMP_V6_NO_ROUTE_TO_DEST    0x0
+#define ICMP_V6_COMM_PROHIBITED     0x1
+#define ICMP_V6_BEYOND_SCOPE        0x2
+#define ICMP_V6_ADDR_UNREACHABLE    0x3
+#define ICMP_V6_PORT_UNREACHABLE    0x4
+#define ICMP_V6_SOURCE_ADDR_FAILED  0x5
+#define ICMP_V6_ROUTE_REJECTED      0x6
+///@}
+
+///
+/// ICMPv6 code definitions for ICMP_V6_TIME_EXCEEDED
+///
+///@{
+#define ICMP_V6_TIMEOUT_HOP_LIMIT   0x0
+#define ICMP_V6_TIMEOUT_REASSEMBLE  0x1
+///@}
+
+///
+/// ICMPv6 code definitions for ICMP_V6_PARAMETER_PROBLEM
+///
+///@{
+#define ICMP_V6_ERRONEOUS_HEADER      0x0
+#define ICMP_V6_UNRECOGNIZE_NEXT_HDR  0x1
+#define ICMP_V6_UNRECOGNIZE_OPTION    0x2
+///@}
+
+///
+/// EFI_IP6_CONFIG_DATA
+/// is used to report and change IPv6 session parameters.
+///
+typedef struct {
+  ///
+  /// For the IPv6 packet to send and receive, this is the default value
+  /// of the 'Next Header' field in the last IPv6 extension header or in
+  /// the IPv6 header if there are no extension headers. Ignored when
+  /// AcceptPromiscuous is TRUE.
+  ///
+  UINT8               DefaultProtocol;
+  ///
+  /// Set to TRUE to receive all IPv6 packets that get through the
+  /// receive filters.
+  /// Set to FALSE to receive only the DefaultProtocol IPv6
+  /// packets that get through the receive filters. Ignored when
+  /// AcceptPromiscuous is TRUE.
+  ///
+  BOOLEAN             AcceptAnyProtocol;
+  ///
+  /// Set to TRUE to receive ICMP error report packets. Ignored when
+  /// AcceptPromiscuous or AcceptAnyProtocol is TRUE.
+  ///
+  BOOLEAN             AcceptIcmpErrors;
+  ///
+  /// Set to TRUE to receive all IPv6 packets that are sent to any
+  /// hardware address or any protocol address. Set to FALSE to stop
+  /// receiving all promiscuous IPv6 packets.
+  ///
+  BOOLEAN             AcceptPromiscuous;
+  ///
+  /// The destination address of the packets that will be transmitted.
+  /// Ignored if it is unspecified.
+  ///
+  EFI_IPv6_ADDRESS    DestinationAddress;
+  ///
+  /// The station IPv6 address that will be assigned to this EFI IPv6
+  /// Protocol instance. This field can be set and changed only when
+  /// the EFI IPv6 driver is transitioning from the stopped to the started
+  /// states. If the StationAddress is specified, the EFI IPv6 Protocol
+  /// driver will deliver only incoming IPv6 packets whose destination
+  /// matches this IPv6 address exactly. The StationAddress is required
+  /// to be one of currently configured IPv6 addresses. An address
+  /// containing all zeroes is also accepted as a special case. Under this
+  /// situation, the IPv6 driver is responsible for binding a source
+  /// address to this EFI IPv6 protocol instance according to the source
+  /// address selection algorithm. Only incoming packets destined to
+  /// the selected address will be delivered to the user.  And the
+  /// selected station address can be retrieved through later
+  /// GetModeData() call. If no address is available for selecting,
+  /// EFI_NO_MAPPING will be returned, and the station address will
+  /// only be successfully bound to this EFI IPv6 protocol instance
+  /// after IP6ModeData.IsConfigured changed to TRUE.
+  ///
+  EFI_IPv6_ADDRESS    StationAddress;
+  ///
+  /// TrafficClass field in transmitted IPv6 packets. Default value
+  /// is zero.
+  ///
+  UINT8               TrafficClass;
+  ///
+  /// HopLimit field in transmitted IPv6 packets.
+  ///
+  UINT8               HopLimit;
+  ///
+  /// FlowLabel field in transmitted IPv6 packets. Default value is
+  /// zero.
+  ///
+  UINT32              FlowLabel;
+  ///
+  /// The timer timeout value (number of microseconds) for the
+  /// receive timeout event to be associated with each assembled
+  /// packet. Zero means do not drop assembled packets.
+  ///
+  UINT32              ReceiveTimeout;
+  ///
+  /// The timer timeout value (number of microseconds) for the
+  /// transmit timeout event to be associated with each outgoing
+  /// packet. Zero means do not drop outgoing packets.
+  ///
+  UINT32              TransmitTimeout;
+} EFI_IP6_CONFIG_DATA;
+
+///
+/// EFI_IP6_ADDRESS_INFO
+///
+typedef struct {
+  EFI_IPv6_ADDRESS    Address;           ///< The IPv6 address.
+  UINT8               PrefixLength;      ///< The length of the prefix associated with the Address.
+} EFI_IP6_ADDRESS_INFO;
+
+///
+/// EFI_IP6_ROUTE_TABLE
+/// is the entry structure that is used in routing tables
+///
+typedef struct {
+  ///
+  /// The IPv6 address of the gateway to be used as the next hop for
+  /// packets to this prefix. If the IPv6 address is all zeros, then the
+  /// prefix is on-link.
+  ///
+  EFI_IPv6_ADDRESS    Gateway;
+  ///
+  /// The destination prefix to be routed.
+  ///
+  EFI_IPv6_ADDRESS    Destination;
+  ///
+  /// The length of the prefix associated with the Destination.
+  ///
+  UINT8               PrefixLength;
+} EFI_IP6_ROUTE_TABLE;
+
+///
+/// EFI_IP6_NEIGHBOR_STATE
+///
+typedef enum {
+  ///
+  /// Address resolution is being performed on this entry. Specially,
+  /// Neighbor Solicitation has been sent to the solicited-node
+  /// multicast address of the target, but corresponding Neighbor
+  /// Advertisement has not been received.
+  ///
+  EfiNeighborInComplete,
+  ///
+  /// Positive confirmation was received that the forward path to the
+  /// neighbor was functioning properly.
+  ///
+  EfiNeighborReachable,
+  ///
+  /// Reachable Time has elapsed since the last positive confirmation
+  /// was received. In this state, the forward path to the neighbor was
+  /// functioning properly.
+  ///
+  EfiNeighborStale,
+  ///
+  /// This state is an optimization that gives upper-layer protocols
+  /// additional time to provide reachability confirmation.
+  ///
+  EfiNeighborDelay,
+  ///
+  /// A reachability confirmation is actively sought by retransmitting
+  /// Neighbor Solicitations every RetransTimer milliseconds until a
+  /// reachability confirmation is received.
+  ///
+  EfiNeighborProbe
+} EFI_IP6_NEIGHBOR_STATE;
+
+///
+/// EFI_IP6_NEIGHBOR_CACHE
+/// is the entry structure that is used in neighbor cache. It records a set
+/// of entries about individual neighbors to which traffic has been sent recently.
+///
+typedef struct {
+  EFI_IPv6_ADDRESS          Neighbor;    ///< The on-link unicast/anycast IP address of the neighbor.
+  EFI_MAC_ADDRESS           LinkAddress; ///< Link-layer address of the neighbor.
+  EFI_IP6_NEIGHBOR_STATE    State;       ///< State of this neighbor cache entry.
+} EFI_IP6_NEIGHBOR_CACHE;
+
+///
+/// EFI_IP6_ICMP_TYPE
+/// is used to describe those ICMP messages that are supported by this EFI
+/// IPv6 Protocol driver.
+///
+typedef struct {
+  UINT8    Type;                  ///< The type of ICMP message.
+  UINT8    Code;                  ///< The code of the ICMP message.
+} EFI_IP6_ICMP_TYPE;
+
+///
+/// EFI_IP6_MODE_DATA
+///
+typedef struct {
+  ///
+  /// Set to TRUE after this EFI IPv6 Protocol instance is started.
+  /// All other fields in this structure are undefined until this field is TRUE.
+  /// Set to FALSE when the EFI IPv6 Protocol instance is stopped.
+  ///
+  BOOLEAN                   IsStarted;
+  ///
+  /// The maximum packet size, in bytes, of the packet which the upper layer driver could feed.
+  ///
+  UINT32                    MaxPacketSize;
+  ///
+  /// Current configuration settings. Undefined until IsStarted is TRUE.
+  ///
+  EFI_IP6_CONFIG_DATA       ConfigData;
+  ///
+  /// Set to TRUE when the EFI IPv6 Protocol instance is configured.
+  /// The instance is configured when it has a station address and
+  /// corresponding prefix length.
+  /// Set to FALSE when the EFI IPv6 Protocol instance is not configured.
+  ///
+  BOOLEAN                   IsConfigured;
+  ///
+  /// Number of configured IPv6 addresses on this interface.
+  ///
+  UINT32                    AddressCount;
+  ///
+  /// List of currently configured IPv6 addresses and corresponding
+  /// prefix lengths assigned to this interface. It is caller's
+  /// responsibility to free this buffer.
+  ///
+  EFI_IP6_ADDRESS_INFO      *AddressList;
+  ///
+  /// Number of joined multicast groups. Undefined until
+  /// IsConfigured is TRUE.
+  ///
+  UINT32                    GroupCount;
+  ///
+  /// List of joined multicast group addresses. It is caller's
+  /// responsibility to free this buffer. Undefined until
+  /// IsConfigured is TRUE.
+  ///
+  EFI_IPv6_ADDRESS          *GroupTable;
+  ///
+  /// Number of entries in the routing table. Undefined until
+  /// IsConfigured is TRUE.
+  ///
+  UINT32                    RouteCount;
+  ///
+  /// Routing table entries. It is caller's responsibility to free this buffer.
+  ///
+  EFI_IP6_ROUTE_TABLE       *RouteTable;
+  ///
+  /// Number of entries in the neighbor cache. Undefined until
+  /// IsConfigured is TRUE.
+  ///
+  UINT32                    NeighborCount;
+  ///
+  /// Neighbor cache entries. It is caller's responsibility to free this
+  /// buffer. Undefined until IsConfigured is TRUE.
+  ///
+  EFI_IP6_NEIGHBOR_CACHE    *NeighborCache;
+  ///
+  /// Number of entries in the prefix table. Undefined until
+  /// IsConfigured is TRUE.
+  ///
+  UINT32                    PrefixCount;
+  ///
+  /// On-link Prefix table entries. It is caller's responsibility to free this
+  /// buffer. Undefined until IsConfigured is TRUE.
+  ///
+  EFI_IP6_ADDRESS_INFO      *PrefixTable;
+  ///
+  /// Number of entries in the supported ICMP types list.
+  ///
+  UINT32                    IcmpTypeCount;
+  ///
+  /// Array of ICMP types and codes that are supported by this EFI
+  /// IPv6 Protocol driver. It is caller's responsibility to free this
+  /// buffer.
+  ///
+  EFI_IP6_ICMP_TYPE         *IcmpTypeList;
+} EFI_IP6_MODE_DATA;
+
+///
+/// EFI_IP6_HEADER
+/// The fields in the IPv6 header structure are defined in the Internet
+/// Protocol version6 specification.
+///
+#pragma pack(1)
+typedef struct _EFI_IP6_HEADER {
+  UINT8               TrafficClassH : 4;
+  UINT8               Version       : 4;
+  UINT8               FlowLabelH    : 4;
+  UINT8               TrafficClassL : 4;
+  UINT16              FlowLabelL;
+  UINT16              PayloadLength;
+  UINT8               NextHeader;
+  UINT8               HopLimit;
+  EFI_IPv6_ADDRESS    SourceAddress;
+  EFI_IPv6_ADDRESS    DestinationAddress;
+} EFI_IP6_HEADER;
+#pragma pack()
+
+///
+/// EFI_IP6_FRAGMENT_DATA
+/// describes the location and length of the IPv6 packet
+/// fragment to transmit or that has been received.
+///
+typedef struct _EFI_IP6_FRAGMENT_DATA {
+  UINT32    FragmentLength;                ///< Length of fragment data. This field may not be set to zero.
+  VOID      *FragmentBuffer;               ///< Pointer to fragment data. This field may not be set to NULL.
+} EFI_IP6_FRAGMENT_DATA;
+
+///
+/// EFI_IP6_RECEIVE_DATA
+///
+typedef struct _EFI_IP6_RECEIVE_DATA {
+  ///
+  /// Time when the EFI IPv6 Protocol driver accepted the packet.
+  /// Ignored if it is zero.
+  ///
+  EFI_TIME                 TimeStamp;
+  ///
+  /// After this event is signaled, the receive data structure is released
+  /// and must not be referenced.
+  ///
+  EFI_EVENT                RecycleSignal;
+  ///
+  /// Length of the IPv6 packet headers, including both the IPv6
+  /// header and any extension headers.
+  ///
+  UINT32                   HeaderLength;
+  ///
+  /// Pointer to the IPv6 packet header. If the IPv6 packet was
+  /// fragmented, this argument is a pointer to the header in the first
+  /// fragment.
+  ///
+  EFI_IP6_HEADER           *Header;
+  ///
+  /// Sum of the lengths of IPv6 packet buffers in FragmentTable. May
+  /// be zero.
+  ///
+  UINT32                   DataLength;
+  ///
+  /// Number of IPv6 payload fragments. May be zero.
+  ///
+  UINT32                   FragmentCount;
+  ///
+  /// Array of payload fragment lengths and buffer pointers.
+  ///
+  EFI_IP6_FRAGMENT_DATA    FragmentTable[1];
+} EFI_IP6_RECEIVE_DATA;
+
+///
+/// EFI_IP6_OVERRIDE_DATA
+/// The information and flags in the override data structure will override
+/// default parameters or settings for one Transmit() function call.
+///
+typedef struct _EFI_IP6_OVERRIDE_DATA {
+  UINT8     Protocol;                 ///< Protocol type override.
+  UINT8     HopLimit;                 ///< Hop-Limit override.
+  UINT32    FlowLabel;                ///< Flow-Label override.
+} EFI_IP6_OVERRIDE_DATA;
+
+///
+/// EFI_IP6_TRANSMIT_DATA
+///
+typedef struct _EFI_IP6_TRANSMIT_DATA {
+  ///
+  /// The destination IPv6 address.  If it is unspecified,
+  /// ConfigData.DestinationAddress will be used instead.
+  ///
+  EFI_IPv6_ADDRESS         DestinationAddress;
+  ///
+  /// If not NULL, the IPv6 transmission control override data.
+  ///
+  EFI_IP6_OVERRIDE_DATA    *OverrideData;
+  ///
+  /// Total length in byte of the IPv6 extension headers specified in
+  /// ExtHdrs.
+  ///
+  UINT32                   ExtHdrsLength;
+  ///
+  /// Pointer to the IPv6 extension headers. The IP layer will append
+  /// the required extension headers if they are not specified by
+  /// ExtHdrs. Ignored if ExtHdrsLength is zero.
+  ///
+  VOID                     *ExtHdrs;
+  ///
+  /// The protocol of first extension header in ExtHdrs. Ignored if
+  /// ExtHdrsLength is zero.
+  ///
+  UINT8                    NextHeader;
+  ///
+  /// Total length in bytes of the FragmentTable data to transmit.
+  ///
+  UINT32                   DataLength;
+  ///
+  /// Number of entries in the fragment data table.
+  ///
+  UINT32                   FragmentCount;
+  ///
+  /// Start of the fragment data table.
+  ///
+  EFI_IP6_FRAGMENT_DATA    FragmentTable[1];
+} EFI_IP6_TRANSMIT_DATA;
+
+///
+/// EFI_IP6_COMPLETION_TOKEN
+/// structures are used for both transmit and receive operations.
+///
+typedef struct {
+  ///
+  /// This Event will be signaled after the Status field is updated by
+  /// the EFI IPv6 Protocol driver. The type of Event must be EFI_NOTIFY_SIGNAL.
+  ///
+  EFI_EVENT    Event;
+  ///
+  /// Will be set to one of the following values:
+  /// - EFI_SUCCESS:  The receive or transmit completed
+  ///   successfully.
+  /// - EFI_ABORTED:  The receive or transmit was aborted
+  /// - EFI_TIMEOUT:  The transmit timeout expired.
+  /// - EFI_ICMP_ERROR:  An ICMP error packet was received.
+  /// - EFI_DEVICE_ERROR:  An unexpected system or network
+  ///   error occurred.
+  /// - EFI_SECURITY_VIOLATION: The transmit or receive was
+  ///   failed because of an IPsec policy check.
+  /// - EFI_NO_MEDIA: There was a media error.
+  ///
+  EFI_STATUS    Status;
+  union {
+    ///
+    /// When the Token is used for receiving, RxData is a pointer to the EFI_IP6_RECEIVE_DATA.
+    ///
+    EFI_IP6_RECEIVE_DATA     *RxData;
+    ///
+    /// When the Token is used for transmitting, TxData is a pointer to the EFI_IP6_TRANSMIT_DATA.
+    ///
+    EFI_IP6_TRANSMIT_DATA    *TxData;
+  } Packet;
+} EFI_IP6_COMPLETION_TOKEN;
+
+/**
+  Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
+
+  The GetModeData() function returns the current operational mode data for this driver instance.
+  The data fields in EFI_IP6_MODE_DATA are read only. This function is used optionally to
+  retrieve the operational mode data of underlying networks or drivers..
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[out] Ip6ModeData        Pointer to the EFI IPv6 Protocol mode data structure.
+  @param[out] MnpConfigData      Pointer to the managed network configuration data structure.
+  @param[out] SnpModeData        Pointer to the simple network mode data structure.
+
+  @retval EFI_SUCCESS            The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER  This is NULL.
+  @retval EFI_OUT_OF_RESOURCES   The required mode data could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_GET_MODE_DATA)(
+  IN EFI_IP6_PROTOCOL                 *This,
+  OUT EFI_IP6_MODE_DATA               *Ip6ModeData     OPTIONAL,
+  OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData   OPTIONAL,
+  OUT EFI_SIMPLE_NETWORK_MODE         *SnpModeData     OPTIONAL
+  );
+
+/**
+  Assigns an IPv6 address and subnet mask to this EFI IPv6 Protocol driver instance.
+
+  The Configure() function is used to set, change, or reset the operational parameters and filter
+  settings for this EFI IPv6 Protocol instance. Until these parameters have been set, no network traffic
+  can be sent or received by this instance. Once the parameters have been reset (by calling this
+  function with Ip6ConfigData set to NULL), no more traffic can be sent or received until these
+  parameters have been set again. Each EFI IPv6 Protocol instance can be started and stopped
+  independently of each other by enabling or disabling their receive filter settings with the
+  Configure() function.
+
+  If Ip6ConfigData.StationAddress is a valid non-zero IPv6 unicast address, it is required
+  to be one of the currently configured IPv6 addresses list in the EFI IPv6 drivers, or else
+  EFI_INVALID_PARAMETER will be returned. If Ip6ConfigData.StationAddress is
+  unspecified, the IPv6 driver will bind a source address according to the source address selection
+  algorithm. Clients could frequently call GetModeData() to check get currently configured IPv6
+  address list in the EFI IPv6 driver. If both Ip6ConfigData.StationAddress and
+  Ip6ConfigData.Destination are unspecified, when transmitting the packet afterwards, the
+  source address filled in each outgoing IPv6 packet is decided based on the destination of this packet. .
+
+  If operational parameters are reset or changed, any pending transmit and receive requests will be
+  cancelled. Their completion token status will be set to EFI_ABORTED and their events will be
+  signaled.
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[in]  Ip6ConfigData      Pointer to the EFI IPv6 Protocol configuration data structure.
+
+  @retval EFI_SUCCESS            The driver instance was successfully opened.
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
+                                 - This is NULL.
+                                 - Ip6ConfigData.StationAddress is neither zero nor
+                                   a unicast IPv6 address.
+                                 - Ip6ConfigData.StationAddress is neither zero nor
+                                   one of the configured IP addresses in the EFI IPv6 driver.
+                                 - Ip6ConfigData.DefaultProtocol is illegal.
+  @retval EFI_OUT_OF_RESOURCES   The EFI IPv6 Protocol driver instance data could not be allocated.
+  @retval EFI_NO_MAPPING         The IPv6 driver was responsible for choosing a source address for
+                                 this instance, but no source address was available for use.
+  @retval EFI_ALREADY_STARTED    The interface is already open and must be stopped before the IPv6
+                                 address or prefix length can be changed.
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred. The EFI IPv6
+                                 Protocol driver instance is not opened.
+  @retval EFI_UNSUPPORTED        Default protocol specified through
+                                 Ip6ConfigData.DefaulProtocol isn't supported.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIGURE)(
+  IN EFI_IP6_PROTOCOL            *This,
+  IN EFI_IP6_CONFIG_DATA         *Ip6ConfigData OPTIONAL
+  );
+
+/**
+  Joins and leaves multicast groups.
+
+  The Groups() function is used to join and leave multicast group sessions. Joining a group will
+  enable reception of matching multicast packets. Leaving a group will disable reception of matching
+  multicast packets. Source-Specific Multicast isn't required to be supported.
+
+  If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left.
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[in]  JoinFlag           Set to TRUE to join the multicast group session and FALSE to leave.
+  @param[in]  GroupAddress       Pointer to the IPv6 multicast address.
+
+  @retval EFI_SUCCESS            The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER  One or more of the following is TRUE:
+                                 - This is NULL.
+                                 - JoinFlag is TRUE and GroupAddress is NULL.
+                                 - GroupAddress is not NULL and *GroupAddress is
+                                   not a multicast IPv6 address.
+                                 - GroupAddress is not NULL and *GroupAddress is in the
+                                   range of SSM destination address.
+  @retval EFI_NOT_STARTED        This instance has not been started.
+  @retval EFI_OUT_OF_RESOURCES   System resources could not be allocated.
+  @retval EFI_UNSUPPORTED        This EFI IPv6 Protocol implementation does not support multicast groups.
+  @retval EFI_ALREADY_STARTED    The group address is already in the group table (when
+                                 JoinFlag is TRUE).
+  @retval EFI_NOT_FOUND          The group address is not in the group table (when JoinFlag is FALSE).
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_GROUPS)(
+  IN EFI_IP6_PROTOCOL            *This,
+  IN BOOLEAN                     JoinFlag,
+  IN EFI_IPv6_ADDRESS            *GroupAddress  OPTIONAL
+  );
+
+/**
+  Adds and deletes routing table entries.
+
+  The Routes() function adds a route to or deletes a route from the routing table.
+
+  Routes are determined by comparing the leftmost PrefixLength bits of Destination with
+  the destination IPv6 address arithmetically. The gateway address must be on the same subnet as the
+  configured station address.
+
+  The default route is added with Destination and PrefixLegth both set to all zeros. The
+  default route matches all destination IPv6 addresses that do not match any other routes.
+
+  All EFI IPv6 Protocol instances share a routing table.
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[in]  DeleteRoute        Set to TRUE to delete this route from the routing table. Set to
+                                 FALSE to add this route to the routing table. Destination,
+                                 PrefixLength and Gateway are used as the key to each
+                                 route entry.
+  @param[in]  Destination        The address prefix of the subnet that needs to be routed.
+  @param[in]  PrefixLength       The prefix length of Destination. Ignored if Destination
+                                 is NULL.
+  @param[in]  GatewayAddress     The unicast gateway IPv6 address for this route.
+
+  @retval EFI_SUCCESS            The operation completed successfully.
+  @retval EFI_NOT_STARTED        The driver instance has not been started.
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
+                                 - This is NULL.
+                                 - When DeleteRoute is TRUE, both Destination and
+                                   GatewayAddress are NULL.
+                                 - When DeleteRoute is FALSE, either Destination or
+                                   GatewayAddress is NULL.
+                                 - *GatewayAddress is not a valid unicast IPv6 address.
+                                 - *GatewayAddress is one of the local configured IPv6
+                                   addresses.
+  @retval EFI_OUT_OF_RESOURCES   Could not add the entry to the routing table.
+  @retval EFI_NOT_FOUND          This route is not in the routing table (when DeleteRoute is TRUE).
+  @retval EFI_ACCESS_DENIED      The route is already defined in the routing table (when
+                                 DeleteRoute is FALSE).
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_ROUTES)(
+  IN EFI_IP6_PROTOCOL            *This,
+  IN BOOLEAN                     DeleteRoute,
+  IN EFI_IPv6_ADDRESS            *Destination OPTIONAL,
+  IN UINT8                       PrefixLength,
+  IN EFI_IPv6_ADDRESS            *GatewayAddress OPTIONAL
+  );
+
+/**
+  Add or delete Neighbor cache entries.
+
+  The Neighbors() function is used to add, update, or delete an entry from neighbor cache.
+  IPv6 neighbor cache entries are typically inserted and updated by the network protocol driver as
+  network traffic is processed. Most neighbor cache entries will time out and be deleted if the network
+  traffic stops. Neighbor cache entries that were inserted by Neighbors() may be static (will not
+  timeout) or dynamic (will time out).
+
+  The implementation should follow the neighbor cache timeout mechanism which is defined in
+  RFC4861. The default neighbor cache timeout value should be tuned for the expected network
+  environment
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[in]  DeleteFlag         Set to TRUE to delete the specified cache entry, set to FALSE to
+                                 add (or update, if it already exists and Override is TRUE) the
+                                 specified cache entry. TargetIp6Address is used as the key
+                                 to find the requested cache entry.
+  @param[in]  TargetIp6Address   Pointer to Target IPv6 address.
+  @param[in]  TargetLinkAddress  Pointer to link-layer address of the target. Ignored if NULL.
+  @param[in]  Timeout            Time in 100-ns units that this entry will remain in the neighbor
+                                 cache, it will be deleted after Timeout. A value of zero means that
+                                 the entry is permanent. A non-zero value means that the entry is
+                                 dynamic.
+  @param[in]  Override           If TRUE, the cached link-layer address of the matching entry will
+                                 be overridden and updated; if FALSE, EFI_ACCESS_DENIED
+                                 will be returned if a corresponding cache entry already existed.
+
+  @retval  EFI_SUCCESS           The data has been queued for transmission.
+  @retval  EFI_NOT_STARTED       This instance has not been started.
+  @retval  EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+                                 - This is NULL.
+                                 - TargetIpAddress is NULL.
+                                 - *TargetLinkAddress is invalid when not NULL.
+                                 - *TargetIpAddress is not a valid unicast IPv6 address.
+                                 - *TargetIpAddress is one of the local configured IPv6
+                                   addresses.
+  @retval  EFI_OUT_OF_RESOURCES  Could not add the entry to the neighbor cache.
+  @retval  EFI_NOT_FOUND         This entry is not in the neighbor cache (when DeleteFlag  is
+                                 TRUE or when DeleteFlag  is FALSE while
+                                 TargetLinkAddress is NULL.).
+  @retval  EFI_ACCESS_DENIED     The to-be-added entry is already defined in the neighbor cache,
+                                 and that entry is tagged as un-overridden (when DeleteFlag
+                                 is FALSE).
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_NEIGHBORS)(
+  IN EFI_IP6_PROTOCOL            *This,
+  IN BOOLEAN                     DeleteFlag,
+  IN EFI_IPv6_ADDRESS            *TargetIp6Address,
+  IN EFI_MAC_ADDRESS             *TargetLinkAddress,
+  IN UINT32                      Timeout,
+  IN BOOLEAN                     Override
+  );
+
+/**
+  Places outgoing data packets into the transmit queue.
+
+  The Transmit() function places a sending request in the transmit queue of this
+  EFI IPv6 Protocol instance. Whenever the packet in the token is sent out or some
+  errors occur, the event in the token will be signaled and the status is updated.
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[in]  Token              Pointer to the transmit token.
+
+  @retval  EFI_SUCCESS           The data has been queued for transmission.
+  @retval  EFI_NOT_STARTED       This instance has not been started.
+  @retval  EFI_NO_MAPPING        The IPv6 driver was responsible for choosing a source address for
+                                 this transmission, but no source address was available for use.
+  @retval  EFI_INVALID_PARAMETER One or more of the following is TRUE:
+                                 - This is NULL.
+                                 - Token is NULL.
+                                 - Token.Event is NULL.
+                                 - Token.Packet.TxData is NULL.
+                                 - Token.Packet.ExtHdrsLength is not zero and Token.Packet.ExtHdrs is NULL.
+                                 - Token.Packet.FragmentCount is zero.
+                                 - One or more of the Token.Packet.TxData.FragmentTable[].FragmentLength fields is zero.
+                                 - One or more of the Token.Packet.TxData.FragmentTable[].FragmentBuffer fields is NULL.
+                                 - Token.Packet.TxData.DataLength is zero or not equal to the sum of fragment lengths.
+                                 - Token.Packet.TxData.DestinationAddress is non-zero when DestinationAddress is configured as
+                                   non-zero when doing Configure() for this EFI IPv6 protocol instance.
+                                 - Token.Packet.TxData.DestinationAddress is unspecified when DestinationAddress is unspecified
+                                   when doing Configure() for this EFI IPv6 protocol instance.
+  @retval  EFI_ACCESS_DENIED     The transmit completion token with the same Token.Event
+                                 was already in the transmit queue.
+  @retval  EFI_NOT_READY         The completion token could not be queued because the transmit
+                                 queue is full.
+  @retval  EFI_NOT_FOUND         Not route is found to destination address.
+  @retval  EFI_OUT_OF_RESOURCES  Could not queue the transmit data.
+  @retval  EFI_BUFFER_TOO_SMALL  Token.Packet.TxData.TotalDataLength is too
+                                 short to transmit.
+  @retval  EFI_BAD_BUFFER_SIZE   If Token.Packet.TxData.DataLength is beyond the
+                                 maximum that which can be described through the Fragment Offset
+                                 field in Fragment header when performing fragmentation.
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_TRANSMIT)(
+  IN EFI_IP6_PROTOCOL            *This,
+  IN EFI_IP6_COMPLETION_TOKEN    *Token
+  );
+
+/**
+  Places a receiving request into the receiving queue.
+
+  The Receive() function places a completion token into the receive packet queue.
+  This function is always asynchronous.
+
+  The Token.Event field in the completion token must be filled in by the caller
+  and cannot be NULL. When the receive operation completes, the EFI IPv6 Protocol
+  driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event
+  is signaled.
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[in]  Token              Pointer to a token that is associated with the receive data descriptor.
+
+  @retval EFI_SUCCESS            The receive completion token was cached.
+  @retval EFI_NOT_STARTED        This EFI IPv6 Protocol instance has not been started.
+  @retval EFI_NO_MAPPING         When IP6 driver responsible for binding source address to this instance,
+                                 while no source address is available for use.
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
+                                 - This is NULL.
+                                 - Token is NULL.
+                                 - Token.Event is NULL.
+  @retval EFI_OUT_OF_RESOURCES   The receive completion token could not be queued due to a lack of system
+                                 resources (usually memory).
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
+                                 The EFI IPv6 Protocol instance has been reset to startup defaults.
+  @retval EFI_ACCESS_DENIED      The receive completion token with the same Token.Event was already
+                                 in the receive queue.
+  @retval EFI_NOT_READY          The receive request could not be queued because the receive queue is full.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_RECEIVE)(
+  IN EFI_IP6_PROTOCOL            *This,
+  IN EFI_IP6_COMPLETION_TOKEN    *Token
+  );
+
+/**
+  Abort an asynchronous transmit or receive request.
+
+  The Cancel() function is used to abort a pending transmit or receive request.
+  If the token is in the transmit or receive request queues, after calling this
+  function, Token->Status will be set to EFI_ABORTED and then Token->Event will
+  be signaled. If the token is not in one of the queues, which usually means the
+  asynchronous operation has completed, this function will not signal the token
+  and EFI_NOT_FOUND is returned.
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+  @param[in]  Token              Pointer to a token that has been issued by
+                                 EFI_IP6_PROTOCOL.Transmit() or
+                                 EFI_IP6_PROTOCOL.Receive(). If NULL, all pending
+                                 tokens are aborted. Type EFI_IP6_COMPLETION_TOKEN is
+                                 defined in EFI_IP6_PROTOCOL.Transmit().
+
+  @retval EFI_SUCCESS            The asynchronous I/O request was aborted and
+                                 Token->Event was signaled. When Token is NULL, all
+                                 pending requests were aborted and their events were signaled.
+  @retval EFI_INVALID_PARAMETER  This is NULL.
+  @retval EFI_NOT_STARTED        This instance has not been started.
+  @retval EFI_NOT_FOUND          When Token is not NULL, the asynchronous I/O request was
+                                 not found in the transmit or receive queue. It has either completed
+                                 or was not issued by Transmit() and Receive().
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CANCEL)(
+  IN EFI_IP6_PROTOCOL            *This,
+  IN EFI_IP6_COMPLETION_TOKEN    *Token    OPTIONAL
+  );
+
+/**
+  Polls for incoming data packets and processes outgoing data packets.
+
+  The Poll() function polls for incoming data packets and processes outgoing data
+  packets. Network drivers and applications can call the EFI_IP6_PROTOCOL.Poll()
+  function to increase the rate that data packets are moved between the communications
+  device and the transmit and receive queues.
+
+  In some systems the periodic timer event may not poll the underlying communications
+  device fast enough to transmit and/or receive all data packets without missing
+  incoming packets or dropping outgoing packets. Drivers and applications that are
+  experiencing packet loss should try calling the EFI_IP6_PROTOCOL.Poll() function
+  more often.
+
+  @param[in]  This               Pointer to the EFI_IP6_PROTOCOL instance.
+
+  @retval  EFI_SUCCESS           Incoming or outgoing data was processed.
+  @retval  EFI_NOT_STARTED       This EFI IPv6 Protocol instance has not been started.
+  @retval  EFI_INVALID_PARAMETER This is NULL.
+  @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred.
+  @retval  EFI_NOT_READY         No incoming or outgoing data is processed.
+  @retval  EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.
+                                 Consider increasing the polling rate.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_POLL)(
+  IN EFI_IP6_PROTOCOL            *This
+  );
+
+///
+/// The EFI IPv6 Protocol implements a simple packet-oriented interface that can be
+/// used by drivers, daemons, and applications to transmit and receive network packets.
+///
+struct _EFI_IP6_PROTOCOL {
+  EFI_IP6_GET_MODE_DATA    GetModeData;
+  EFI_IP6_CONFIGURE        Configure;
+  EFI_IP6_GROUPS           Groups;
+  EFI_IP6_ROUTES           Routes;
+  EFI_IP6_NEIGHBORS        Neighbors;
+  EFI_IP6_TRANSMIT         Transmit;
+  EFI_IP6_RECEIVE          Receive;
+  EFI_IP6_CANCEL           Cancel;
+  EFI_IP6_POLL             Poll;
+};
+
+extern EFI_GUID  gEfiIp6ServiceBindingProtocolGuid;
+extern EFI_GUID  gEfiIp6ProtocolGuid;
+
+#endif
diff --git a/src/include/ipxe/efi/Protocol/Ip6Config.h b/src/include/ipxe/efi/Protocol/Ip6Config.h
new file mode 100644 (file)
index 0000000..5665e93
--- /dev/null
@@ -0,0 +1,369 @@
+/** @file
+  This file provides a definition of the EFI IPv6 Configuration
+  Protocol.
+
+Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __EFI_IP6CONFIG_PROTOCOL_H__
+#define __EFI_IP6CONFIG_PROTOCOL_H__
+
+FILE_LICENCE ( BSD2_PATENT );
+
+#include <ipxe/efi/Protocol/Ip6.h>
+
+#define EFI_IP6_CONFIG_PROTOCOL_GUID \
+  { \
+    0x937fe521, 0x95ae, 0x4d1a, {0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \
+  }
+
+typedef struct _EFI_IP6_CONFIG_PROTOCOL EFI_IP6_CONFIG_PROTOCOL;
+
+///
+/// EFI_IP6_CONFIG_DATA_TYPE
+///
+typedef enum {
+  ///
+  /// The interface information of the communication
+  /// device this EFI IPv6 Configuration Protocol instance manages.
+  /// This type of data is read only.The corresponding Data is of type
+  /// EFI_IP6_CONFIG_INTERFACE_INFO.
+  ///
+  Ip6ConfigDataTypeInterfaceInfo,
+  ///
+  /// The alternative interface ID for the
+  /// communication device this EFI IPv6 Configuration Protocol
+  /// instance manages if the link local IPv6 address generated from
+  /// the interfaced ID based on the default source the EFI IPv6
+  /// Protocol uses is a duplicate address. The length of the interface
+  /// ID is 64 bit. The corresponding Data is of type
+  /// EFI_IP6_CONFIG_INTERFACE_ID.
+  ///
+  Ip6ConfigDataTypeAltInterfaceId,
+  ///
+  /// The general configuration policy for the EFI IPv6 network
+  /// stack running on the communication device this EFI IPv6
+  /// Configuration Protocol instance manages. The policy will affect
+  /// other configuration settings. The corresponding Data is of type
+  /// EFI_IP6_CONFIG_POLICY.
+  ///
+  Ip6ConfigDataTypePolicy,
+  ///
+  /// The number of consecutive
+  /// Neighbor Solicitation messages sent while performing Duplicate
+  /// Address Detection on a tentative address. A value of zero
+  /// indicates that Duplicate Address Detection will not be performed
+  /// on tentative addresses. The corresponding Data is of type
+  /// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS.
+  ///
+  Ip6ConfigDataTypeDupAddrDetectTransmits,
+  ///
+  /// The station addresses set manually for the EFI
+  /// IPv6 network stack. It is only configurable when the policy is
+  /// Ip6ConfigPolicyManual. The corresponding Data is a
+  /// pointer to an array of EFI_IPv6_ADDRESS instances. When
+  /// DataSize is 0 and Data is NULL, the existing configuration
+  /// is cleared from the EFI IPv6 Configuration Protocol instance.
+  ///
+  Ip6ConfigDataTypeManualAddress,
+  ///
+  /// The gateway addresses set manually for the EFI IPv6
+  /// network stack running on the communication device this EFI
+  /// IPv6 Configuration Protocol manages. It is not configurable when
+  /// the policy is Ip6ConfigPolicyAutomatic. The gateway
+  /// addresses must be unicast IPv6 addresses. The corresponding
+  /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
+  /// When DataSize is 0 and Data is NULL, the existing configuration
+  /// is cleared from the EFI IPv6 Configuration Protocol instance.
+  ///
+  Ip6ConfigDataTypeGateway,
+  ///
+  /// The DNS server list for the EFI IPv6 network stack
+  /// running on the communication device this EFI IPv6
+  /// Configuration Protocol manages. It is not configurable when the
+  /// policy is Ip6ConfigPolicyAutomatic.The DNS server
+  /// addresses must be unicast IPv6 addresses. The corresponding
+  /// Data is a pointer to an array of EFI_IPv6_ADDRESS instances.
+  /// When DataSize is 0 and Data is NULL, the existing configuration
+  /// is cleared from the EFI IPv6 Configuration Protocol instance.
+  ///
+  Ip6ConfigDataTypeDnsServer,
+  ///
+  /// The number of this enumeration memebers.
+  ///
+  Ip6ConfigDataTypeMaximum
+} EFI_IP6_CONFIG_DATA_TYPE;
+
+///
+/// EFI_IP6_CONFIG_INTERFACE_INFO
+/// describes the operational state of the interface this
+/// EFI IPv6 Configuration Protocol instance manages.
+///
+typedef struct {
+  ///
+  /// The name of the interface. It is a NULL-terminated string.
+  ///
+  CHAR16                  Name[32];
+  ///
+  /// The interface type of the network interface.
+  ///
+  UINT8                   IfType;
+  ///
+  /// The size, in bytes, of the network interface's hardware address.
+  ///
+  UINT32                  HwAddressSize;
+  ///
+  /// The hardware address for the network interface.
+  ///
+  EFI_MAC_ADDRESS         HwAddress;
+  ///
+  /// Number of EFI_IP6_ADDRESS_INFO structures pointed to by AddressInfo.
+  ///
+  UINT32                  AddressInfoCount;
+  ///
+  /// Pointer to an array of EFI_IP6_ADDRESS_INFO instances
+  /// which contain the local IPv6 addresses and the corresponding
+  /// prefix length information. Set to NULL if AddressInfoCount
+  /// is zero.
+  ///
+  EFI_IP6_ADDRESS_INFO    *AddressInfo;
+  ///
+  /// Number of route table entries in the following RouteTable.
+  ///
+  UINT32                  RouteCount;
+  ///
+  /// The route table of the IPv6 network stack runs on this interface.
+  /// Set to NULL if RouteCount is zero.
+  ///
+  EFI_IP6_ROUTE_TABLE     *RouteTable;
+} EFI_IP6_CONFIG_INTERFACE_INFO;
+
+///
+/// EFI_IP6_CONFIG_INTERFACE_ID
+/// describes the 64-bit interface ID.
+///
+typedef struct {
+  UINT8    Id[8];
+} EFI_IP6_CONFIG_INTERFACE_ID;
+
+///
+/// EFI_IP6_CONFIG_POLICY
+/// defines the general configuration policy the EFI IPv6
+/// Configuration Protocol supports.
+///
+typedef enum {
+  ///
+  /// Under this policy, the IpI6ConfigDataTypeManualAddress,
+  /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer
+  /// configuration data are required to be set manually.
+  /// The EFI IPv6 Protocol will get all required configuration
+  /// such as address, prefix and gateway settings from the EFI
+  /// IPv6 Configuration protocol.
+  ///
+  Ip6ConfigPolicyManual,
+  ///
+  /// Under this policy, the IpI6ConfigDataTypeManualAddress,
+  /// Ip6ConfigDataTypeGateway and Ip6ConfigDataTypeDnsServer
+  /// configuration data are not allowed to set via SetData().
+  /// All of these configurations are retrieved from some auto
+  /// configuration mechanism.
+  /// The EFI IPv6 Protocol will use the IPv6 stateless address
+  /// autoconfiguration mechanism and/or the IPv6 stateful address
+  /// autoconfiguration mechanism described in the related RFCs to
+  /// get address and other configuration information
+  ///
+  Ip6ConfigPolicyAutomatic
+} EFI_IP6_CONFIG_POLICY;
+
+///
+/// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS
+/// describes the number of consecutive Neighbor Solicitation messages sent
+/// while performing Duplicate Address Detection on a tentative address.
+/// The default value for a newly detected communication device is 1.
+///
+typedef struct {
+  UINT32    DupAddrDetectTransmits;  ///< The number of consecutive Neighbor Solicitation messages sent.
+} EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS;
+
+///
+/// EFI_IP6_CONFIG_MANUAL_ADDRESS
+/// is used to set the station address information for the EFI IPv6 network
+/// stack manually when the policy is Ip6ConfigPolicyManual.
+///
+typedef struct {
+  EFI_IPv6_ADDRESS    Address;         ///< The IPv6 unicast address.
+  BOOLEAN             IsAnycast;       ///< Set to TRUE if Address is anycast.
+  UINT8               PrefixLength;    ///< The length, in bits, of the prefix associated with this Address.
+} EFI_IP6_CONFIG_MANUAL_ADDRESS;
+
+/**
+  Set the configuration for the EFI IPv6 network stack running on the communication
+  device this EFI IPv6 Configuration Protocol instance manages.
+
+  This function is used to set the configuration data of type DataType for the EFI
+  IPv6 network stack running on the communication device this EFI IPv6 Configuration
+  Protocol instance manages.
+
+  The DataSize is used to calculate the count of structure instances in the Data for
+  some DataType that multiple structure instances are allowed.
+
+  This function is always non-blocking. When setting some type of configuration data,
+  an asynchronous process is invoked to check the correctness of the data, such as
+  doing Duplicate Address Detection on the manually set local IPv6 addresses.
+  EFI_NOT_READY is returned immediately to indicate that such an asynchronous process
+  is invoked and the process is not finished yet. The caller willing to get the result
+  of the asynchronous process is required to call RegisterDataNotify() to register an
+  event on the specified configuration data. Once the event is signaled, the caller
+  can call GetData() to get back the configuration data in order to know the result.
+  For other types of configuration data that do not require an asynchronous configuration
+  process, the result of the operation is immediately returned.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to set.
+  @param[in]     DataSize       Size of the buffer pointed to by Data in bytes.
+  @param[in]     Data           The data buffer to set. The type of the data buffer is
+                                associated with the DataType.
+
+  @retval EFI_SUCCESS           The specified configuration data for the EFI IPv6
+                                network stack is set successfully.
+  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
+                                - This is NULL.
+                                - One or more fields in Data and DataSize do not match the
+                                  requirement of the data type indicated by DataType.
+  @retval EFI_WRITE_PROTECTED   The specified configuration data is read-only or the specified
+                                configuration data can not be set under the current policy
+  @retval EFI_ACCESS_DENIED     Another set operation on the specified configuration
+                                data is already in process.
+  @retval EFI_NOT_READY         An asynchronous process is invoked to set the specified
+                                configuration data and the process is not finished yet.
+  @retval EFI_BAD_BUFFER_SIZE   The DataSize does not match the size of the type
+                                indicated by DataType.
+  @retval EFI_UNSUPPORTED       This DataType is not supported.
+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval EFI_DEVICE_ERROR      An unexpected system error or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_SET_DATA)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN UINTN                      DataSize,
+  IN VOID                       *Data
+  );
+
+/**
+  Get the configuration data for the EFI IPv6 network stack running on the communication
+  device this EFI IPv6 Configuration Protocol instance manages.
+
+  This function returns the configuration data of type DataType for the EFI IPv6 network
+  stack running on the communication device this EFI IPv6 Configuration Protocol instance
+  manages.
+
+  The caller is responsible for allocating the buffer used to return the specified
+  configuration data and the required size will be returned to the caller if the size of
+  the buffer is too small.
+
+  EFI_NOT_READY is returned if the specified configuration data is not ready due to an
+  already in progress asynchronous configuration process. The caller can call RegisterDataNotify()
+  to register an event on the specified configuration data. Once the asynchronous configuration
+  process is finished, the event will be signaled and a subsequent GetData() call will return
+  the specified configuration data.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to get.
+  @param[in,out] DataSize       On input, in bytes, the size of Data. On output, in bytes, the
+                                size of buffer required to store the specified configuration data.
+  @param[in]     Data           The data buffer in which the configuration data is returned. The
+                                type of the data buffer is associated with the DataType.
+
+  @retval EFI_SUCCESS           The specified configuration data is got successfully.
+  @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
+                                - This is NULL.
+                                - DataSize is NULL.
+                                - Data is NULL if *DataSize is not zero.
+  @retval EFI_BUFFER_TOO_SMALL  The size of Data is too small for the specified configuration data
+                                and the required size is returned in DataSize.
+  @retval EFI_NOT_READY         The specified configuration data is not ready due to an already in
+                                progress asynchronous configuration process.
+  @retval EFI_NOT_FOUND         The specified configuration data is not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_GET_DATA)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN OUT UINTN                  *DataSize,
+  IN VOID                       *Data   OPTIONAL
+  );
+
+/**
+  Register an event that is to be signaled whenever a configuration process on the specified
+  configuration data is done.
+
+  This function registers an event that is to be signaled whenever a configuration process
+  on the specified configuration data is done. An event can be registered for different DataType
+  simultaneously and the caller is responsible for determining which type of configuration data
+  causes the signaling of the event in such case.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to unregister the event for.
+  @param[in]     Event          The event to register.
+
+  @retval EFI_SUCCESS           The notification event for the specified configuration data is
+                                registered.
+  @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
+  @retval EFI_UNSUPPORTED       The configuration data type specified by DataType is not
+                                supported.
+  @retval EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval EFI_ACCESS_DENIED     The Event is already registered for the DataType.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_REGISTER_NOTIFY)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN EFI_EVENT                  Event
+  );
+
+/**
+  Remove a previously registered event for the specified configuration data.
+
+  This function removes a previously registered event for the specified configuration data.
+
+  @param[in]     This           Pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
+  @param[in]     DataType       The type of data to remove the previously registered event for.
+  @param[in]     Event          The event to unregister.
+
+  @retval EFI_SUCCESS           The event registered for the specified configuration data is removed.
+  @retval EFI_INVALID_PARAMETER This is NULL or Event is NULL.
+  @retval EFI_NOT_FOUND         The Event has not been registered for the specified
+                                DataType.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_IP6_CONFIG_UNREGISTER_NOTIFY)(
+  IN EFI_IP6_CONFIG_PROTOCOL    *This,
+  IN EFI_IP6_CONFIG_DATA_TYPE   DataType,
+  IN EFI_EVENT                  Event
+  );
+
+///
+/// The EFI_IP6_CONFIG_PROTOCOL provides the mechanism to set and get various
+/// types of configurations for the EFI IPv6 network stack.
+///
+struct _EFI_IP6_CONFIG_PROTOCOL {
+  EFI_IP6_CONFIG_SET_DATA             SetData;
+  EFI_IP6_CONFIG_GET_DATA             GetData;
+  EFI_IP6_CONFIG_REGISTER_NOTIFY      RegisterDataNotify;
+  EFI_IP6_CONFIG_UNREGISTER_NOTIFY    UnregisterDataNotify;
+};
+
+extern EFI_GUID  gEfiIp6ConfigProtocolGuid;
+
+#endif
diff --git a/src/include/ipxe/efi/Protocol/Mtftp6.h b/src/include/ipxe/efi/Protocol/Mtftp6.h
new file mode 100644 (file)
index 0000000..b08af87
--- /dev/null
@@ -0,0 +1,820 @@
+/** @file
+  UEFI Multicast Trivial File Transfer Protocol v6 Definition, which is built upon
+  the EFI UDPv6 Protocol and provides basic services for client-side unicast and/or
+  multicast TFTP operations.
+
+  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Revision Reference:
+  This Protocol is introduced in UEFI Specification 2.2
+
+**/
+
+#ifndef __EFI_MTFTP6_PROTOCOL_H__
+#define __EFI_MTFTP6_PROTOCOL_H__
+
+FILE_LICENCE ( BSD2_PATENT );
+
+#define EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID \
+  { \
+    0xd9760ff3, 0x3cca, 0x4267, {0x80, 0xf9, 0x75, 0x27, 0xfa, 0xfa, 0x42, 0x23 } \
+  }
+
+#define EFI_MTFTP6_PROTOCOL_GUID \
+  { \
+    0xbf0a78ba, 0xec29, 0x49cf, {0xa1, 0xc9, 0x7a, 0xe5, 0x4e, 0xab, 0x6a, 0x51 } \
+  }
+
+typedef struct _EFI_MTFTP6_PROTOCOL  EFI_MTFTP6_PROTOCOL;
+typedef struct _EFI_MTFTP6_TOKEN     EFI_MTFTP6_TOKEN;
+
+///
+/// MTFTP Packet OpCodes
+///@{
+#define EFI_MTFTP6_OPCODE_RRQ    1   ///< The MTFTPv6 packet is a read request.
+#define EFI_MTFTP6_OPCODE_WRQ    2   ///< The MTFTPv6 packet is a write request.
+#define EFI_MTFTP6_OPCODE_DATA   3   ///< The MTFTPv6 packet is a data packet.
+#define EFI_MTFTP6_OPCODE_ACK    4   ///< The MTFTPv6 packet is an acknowledgement packet.
+#define EFI_MTFTP6_OPCODE_ERROR  5   ///< The MTFTPv6 packet is an error packet.
+#define EFI_MTFTP6_OPCODE_OACK   6   ///< The MTFTPv6 packet is an option acknowledgement packet.
+#define EFI_MTFTP6_OPCODE_DIR    7   ///< The MTFTPv6 packet is a directory query packet.
+#define EFI_MTFTP6_OPCODE_DATA8  8   ///< The MTFTPv6 packet is a data packet with a big block number.
+#define EFI_MTFTP6_OPCODE_ACK8   9   ///< The MTFTPv6 packet is an acknowledgement packet with a big block number.
+///@}
+
+///
+/// MTFTP ERROR Packet ErrorCodes
+///@{
+///
+/// The error code is not defined. See the error message in the packet (if any) for details.
+///
+#define EFI_MTFTP6_ERRORCODE_NOT_DEFINED  0
+///
+/// The file was not found.
+///
+#define EFI_MTFTP6_ERRORCODE_FILE_NOT_FOUND  1
+///
+/// There was an access violation.
+///
+#define EFI_MTFTP6_ERRORCODE_ACCESS_VIOLATION  2
+///
+/// The disk was full or its allocation was exceeded.
+///
+#define EFI_MTFTP6_ERRORCODE_DISK_FULL  3
+///
+/// The MTFTPv6 operation was illegal.
+///
+#define EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION  4
+///
+/// The transfer ID is unknown.
+///
+#define EFI_MTFTP6_ERRORCODE_UNKNOWN_TRANSFER_ID  5
+///
+/// The file already exists.
+///
+#define EFI_MTFTP6_ERRORCODE_FILE_ALREADY_EXISTS  6
+///
+/// There is no such user.
+///
+#define EFI_MTFTP6_ERRORCODE_NO_SUCH_USER  7
+///
+/// The request has been denied due to option negotiation.
+///
+#define EFI_MTFTP6_ERRORCODE_REQUEST_DENIED  8
+///@}
+
+#pragma pack(1)
+
+///
+/// EFI_MTFTP6_REQ_HEADER
+///
+typedef struct {
+  ///
+  /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_RRQ for a read request
+  /// or OpCode = EFI_MTFTP6_OPCODE_WRQ for a write request.
+  ///
+  UINT16    OpCode;
+  ///
+  /// The file name to be downloaded or uploaded.
+  ///
+  UINT8     Filename[1];
+} EFI_MTFTP6_REQ_HEADER;
+
+///
+/// EFI_MTFTP6_OACK_HEADER
+///
+typedef struct {
+  ///
+  /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_OACK.
+  ///
+  UINT16    OpCode;
+  ///
+  /// The option strings in the option acknowledgement packet.
+  ///
+  UINT8     Data[1];
+} EFI_MTFTP6_OACK_HEADER;
+
+///
+/// EFI_MTFTP6_DATA_HEADER
+///
+typedef struct {
+  ///
+  /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_DATA.
+  ///
+  UINT16    OpCode;
+  ///
+  /// Block number of this data packet.
+  ///
+  UINT16    Block;
+  ///
+  /// The content of this data packet.
+  ///
+  UINT8     Data[1];
+} EFI_MTFTP6_DATA_HEADER;
+
+///
+/// EFI_MTFTP6_ACK_HEADER
+///
+typedef struct {
+  ///
+  /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ACK.
+  ///
+  UINT16    OpCode;
+  ///
+  /// The block number of the data packet that is being acknowledged.
+  ///
+  UINT16    Block[1];
+} EFI_MTFTP6_ACK_HEADER;
+
+///
+/// EFI_MTFTP6_DATA8_HEADER
+///
+typedef struct {
+  ///
+  /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_DATA8.
+  ///
+  UINT16    OpCode;
+  ///
+  /// The block number of data packet.
+  ///
+  UINT64    Block;
+  ///
+  /// The content of this data packet.
+  ///
+  UINT8     Data[1];
+} EFI_MTFTP6_DATA8_HEADER;
+
+///
+/// EFI_MTFTP6_ACK8_HEADER
+///
+typedef struct {
+  ///
+  /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ACK8.
+  ///
+  UINT16    OpCode;
+  ///
+  /// The block number of the data packet that is being acknowledged.
+  ///
+  UINT64    Block[1];
+} EFI_MTFTP6_ACK8_HEADER;
+
+///
+/// EFI_MTFTP6_ERROR_HEADER
+///
+typedef struct {
+  ///
+  /// For this packet type, OpCode = EFI_MTFTP6_OPCODE_ERROR.
+  ///
+  UINT16    OpCode;
+  ///
+  /// The error number as defined by the MTFTPv6 packet error codes.
+  ///
+  UINT16    ErrorCode;
+  ///
+  /// Error message string.
+  ///
+  UINT8     ErrorMessage[1];
+} EFI_MTFTP6_ERROR_HEADER;
+
+///
+/// EFI_MTFTP6_PACKET
+///
+typedef union {
+  UINT16                     OpCode; ///< Type of packets as defined by the MTFTPv6 packet opcodes.
+  EFI_MTFTP6_REQ_HEADER      Rrq;    ///< Read request packet header.
+  EFI_MTFTP6_REQ_HEADER      Wrq;    ///< write request packet header.
+  EFI_MTFTP6_OACK_HEADER     Oack;   ///< Option acknowledge packet header.
+  EFI_MTFTP6_DATA_HEADER     Data;   ///< Data packet header.
+  EFI_MTFTP6_ACK_HEADER      Ack;    ///< Acknowledgement packet header.
+  EFI_MTFTP6_DATA8_HEADER    Data8;  ///< Data packet header with big block number.
+  EFI_MTFTP6_ACK8_HEADER     Ack8;   ///< Acknowledgement header with big block number.
+  EFI_MTFTP6_ERROR_HEADER    Error;  ///< Error packet header.
+} EFI_MTFTP6_PACKET;
+
+#pragma pack()
+
+///
+/// EFI_MTFTP6_CONFIG_DATA
+///
+typedef struct {
+  ///
+  /// The local IP address to use. Set to zero to let the underlying IPv6
+  /// driver choose a source address. If not zero it must be one of the
+  /// configured IP addresses in the underlying IPv6 driver.
+  ///
+  EFI_IPv6_ADDRESS    StationIp;
+  ///
+  /// Local port number. Set to zero to use the automatically assigned port number.
+  ///
+  UINT16              LocalPort;
+  ///
+  /// The IP address of the MTFTPv6 server.
+  ///
+  EFI_IPv6_ADDRESS    ServerIp;
+  ///
+  /// The initial MTFTPv6 server port number. Request packets are
+  /// sent to this port. This number is almost always 69 and using zero
+  /// defaults to 69.
+  UINT16              InitialServerPort;
+  ///
+  /// The number of times to transmit MTFTPv6 request packets and wait for a response.
+  ///
+  UINT16              TryCount;
+  ///
+  /// The number of seconds to wait for a response after sending the MTFTPv6 request packet.
+  ///
+  UINT16              TimeoutValue;
+} EFI_MTFTP6_CONFIG_DATA;
+
+///
+/// EFI_MTFTP6_MODE_DATA
+///
+typedef struct {
+  ///
+  /// The configuration data of this instance.
+  ///
+  EFI_MTFTP6_CONFIG_DATA    ConfigData;
+  ///
+  /// The number of option strings in the following SupportedOptions array.
+  ///
+  UINT8                     SupportedOptionCount;
+  ///
+  /// An array of null-terminated ASCII option strings that are recognized and supported by
+  /// this EFI MTFTPv6 Protocol driver implementation. The buffer is
+  /// read only to the caller and the caller should NOT free the buffer.
+  ///
+  UINT8                     **SupportedOptions;
+} EFI_MTFTP6_MODE_DATA;
+
+///
+/// EFI_MTFTP_OVERRIDE_DATA
+///
+typedef struct {
+  ///
+  /// IP address of the MTFTPv6 server. If set to all zero, the value that
+  /// was set by the EFI_MTFTP6_PROTOCOL.Configure() function will be used.
+  ///
+  EFI_IPv6_ADDRESS    ServerIp;
+  ///
+  /// MTFTPv6 server port number. If set to zero, it will use the value
+  /// that was set by the EFI_MTFTP6_PROTOCOL.Configure() function.
+  ///
+  UINT16              ServerPort;
+  ///
+  /// Number of times to transmit MTFTPv6 request packets and wait
+  /// for a response. If set to zero, the value that was set by
+  /// theEFI_MTFTP6_PROTOCOL.Configure() function will be used.
+  ///
+  UINT16              TryCount;
+  ///
+  /// Number of seconds to wait for a response after sending the
+  /// MTFTPv6 request packet. If set to zero, the value that was set by
+  /// the EFI_MTFTP6_PROTOCOL.Configure() function will be used.
+  ///
+  UINT16              TimeoutValue;
+} EFI_MTFTP6_OVERRIDE_DATA;
+
+///
+/// EFI_MTFTP6_OPTION
+///
+typedef struct {
+  UINT8    *OptionStr;               ///< Pointer to the null-terminated ASCII MTFTPv6 option string.
+  UINT8    *ValueStr;                ///< Pointer to the null-terminated ASCII MTFTPv6 value string.
+} EFI_MTFTP6_OPTION;
+
+/**
+  EFI_MTFTP6_TIMEOUT_CALLBACK is a callback function that the caller provides to capture the
+  timeout event in the EFI_MTFTP6_PROTOCOL.ReadFile(), EFI_MTFTP6_PROTOCOL.WriteFile() or
+  EFI_MTFTP6_PROTOCOL.ReadDirectory() functions.
+
+  Whenever a timeout occurs, the EFI MTFTPv6 Protocol driver will call the EFI_MTFTP6_TIMEOUT_CALLBACK
+  function to notify the caller of the timeout event. Any status code other than EFI_SUCCESS
+  that is returned from this function will abort the current download process.
+
+  @param[in] This          Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in] Token         The token that the caller provided in the EFI_MTFTP6_PROTOCOl.ReadFile(),
+                           WriteFile() or ReadDirectory() function.
+  @param[in] PacketLen     Indicates the length of the packet.
+  @param[in] Packet        Pointer to an MTFTPv6 packet.
+
+  @retval EFI_SUCCESS      Operation success.
+  @retval Others           Aborts session.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_CHECK_PACKET)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_TOKEN         *Token,
+  IN UINT16                   PacketLen,
+  IN EFI_MTFTP6_PACKET        *Packet
+  );
+
+/**
+  EFI_MTFTP6_TIMEOUT_CALLBACK is a callback function that the caller provides to capture the
+  timeout event in the EFI_MTFTP6_PROTOCOL.ReadFile(), EFI_MTFTP6_PROTOCOL.WriteFile() or
+  EFI_MTFTP6_PROTOCOL.ReadDirectory() functions.
+
+  Whenever a timeout occurs, the EFI MTFTPv6 Protocol driver will call the EFI_MTFTP6_TIMEOUT_CALLBACK
+  function to notify the caller of the timeout event. Any status code other than EFI_SUCCESS
+  that is returned from this function will abort the current download process.
+
+  @param[in]      This     Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]      Token    The token that is provided in the EFI_MTFTP6_PROTOCOL.ReadFile() or
+                           EFI_MTFTP6_PROTOCOL.WriteFile() or EFI_MTFTP6_PROTOCOL.ReadDirectory()
+                           functions by the caller.
+
+  @retval EFI_SUCCESS      Operation success.
+  @retval Others           Aborts session.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_TIMEOUT_CALLBACK)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_TOKEN         *Token
+  );
+
+/**
+  EFI_MTFTP6_PACKET_NEEDED is a callback function that the caller provides to feed data to the
+  EFI_MTFTP6_PROTOCOL.WriteFile() function.
+
+  EFI_MTFTP6_PACKET_NEEDED provides another mechanism for the caller to provide data to upload
+  other than a static buffer. The EFI MTFTP6 Protocol driver always calls EFI_MTFTP6_PACKET_NEEDED
+  to get packet data from the caller if no static buffer was given in the initial call to
+  EFI_MTFTP6_PROTOCOL.WriteFile() function. Setting *Length to zero signals the end of the session.
+  Returning a status code other than EFI_SUCCESS aborts the session.
+
+  @param[in]      This     Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]      Token    The token provided in the EFI_MTFTP6_PROTOCOL.WriteFile() by the caller.
+  @param[in, out] Length   Indicates the length of the raw data wanted on input, and the
+                           length the data available on output.
+  @param[out]     Buffer   Pointer to the buffer where the data is stored.
+
+  @retval EFI_SUCCESS      Operation success.
+  @retval Others           Aborts session.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_PACKET_NEEDED)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_TOKEN         *Token,
+  IN OUT UINT16               *Length,
+  OUT VOID                    **Buffer
+  );
+
+struct _EFI_MTFTP6_TOKEN {
+  ///
+  /// The status that is returned to the caller at the end of the operation
+  /// to indicate whether this operation completed successfully.
+  /// Defined Status values are listed below.
+  ///
+  EFI_STATUS                     Status;
+  ///
+  /// The event that will be signaled when the operation completes. If
+  /// set to NULL, the corresponding function will wait until the read or
+  /// write operation finishes. The type of Event must be EVT_NOTIFY_SIGNAL.
+  ///
+  EFI_EVENT                      Event;
+  ///
+  /// If not NULL, the data that will be used to override the existing
+  /// configure data.
+  ///
+  EFI_MTFTP6_OVERRIDE_DATA       *OverrideData;
+  ///
+  /// Pointer to the null-terminated ASCII file name string.
+  ///
+  UINT8                          *Filename;
+  ///
+  /// Pointer to the null-terminated ASCII mode string. If NULL, octet is used.
+  ///
+  UINT8                          *ModeStr;
+  ///
+  /// Number of option/value string pairs.
+  ///
+  UINT32                         OptionCount;
+  ///
+  /// Pointer to an array of option/value string pairs. Ignored if
+  /// OptionCount is zero. Both a remote server and this driver
+  /// implementation should support these options. If one or more
+  /// options are unrecognized by this implementation, it is sent to the
+  /// remote server without being changed.
+  ///
+  EFI_MTFTP6_OPTION              *OptionList;
+  ///
+  /// On input, the size, in bytes, of Buffer. On output, the number
+  /// of bytes transferred.
+  ///
+  UINT64                         BufferSize;
+  ///
+  /// Pointer to the data buffer. Data that is downloaded from the
+  /// MTFTPv6 server is stored here. Data that is uploaded to the
+  /// MTFTPv6 server is read from here. Ignored if BufferSize is zero.
+  ///
+  VOID                           *Buffer;
+  ///
+  /// Pointer to the context that will be used by CheckPacket,
+  /// TimeoutCallback and PacketNeeded.
+  ///
+  VOID                           *Context;
+  ///
+  /// Pointer to the callback function to check the contents of the
+  /// received packet.
+  ///
+  EFI_MTFTP6_CHECK_PACKET        CheckPacket;
+  ///
+  /// Pointer to the function to be called when a timeout occurs.
+  ///
+  EFI_MTFTP6_TIMEOUT_CALLBACK    TimeoutCallback;
+  ///
+  /// Pointer to the function to provide the needed packet contents.
+  /// Only used in WriteFile() operation.
+  ///
+  EFI_MTFTP6_PACKET_NEEDED       PacketNeeded;
+};
+
+/**
+  Read the current operational settings.
+
+  The GetModeData() function reads the current operational settings of this EFI MTFTPv6
+  Protocol driver instance.
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[out] ModeData           The buffer in which the EFI MTFTPv6 Protocol driver mode
+                                 data is returned.
+
+  @retval  EFI_SUCCESS           The configuration data was successfully returned.
+  @retval  EFI_OUT_OF_RESOURCES  The required mode data could not be allocated.
+  @retval  EFI_INVALID_PARAMETER This is NULL or ModeData is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_GET_MODE_DATA)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  OUT EFI_MTFTP6_MODE_DATA    *ModeData
+  );
+
+/**
+  Initializes, changes, or resets the default operational setting for this EFI MTFTPv6
+  Protocol driver instance.
+
+  The Configure() function is used to set and change the configuration data for this EFI
+  MTFTPv6 Protocol driver instance. The configuration data can be reset to startup defaults by calling
+  Configure() with MtftpConfigData set to NULL. Whenever the instance is reset, any
+  pending operation is aborted. By changing the EFI MTFTPv6 Protocol driver instance configuration
+  data, the client can connect to different MTFTPv6 servers. The configuration parameters in
+  MtftpConfigData are used as the default parameters in later MTFTPv6 operations and can be
+  overridden in later operations.
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]  MtftpConfigData    Pointer to the configuration data structure.
+
+  @retval  EFI_SUCCESS           The EFI MTFTPv6 Protocol instance was configured successfully.
+  @retval  EFI_INVALID_PARAMETER One or more following conditions are TRUE:
+                                 - This is NULL.
+                                 - MtftpConfigData.StationIp is neither zero nor one
+                                   of the configured IP addresses in the underlying IPv6 driver.
+                                 - MtftpCofigData.ServerIp is not a valid IPv6 unicast address.
+  @retval  EFI_ACCESS_DENIED     - The configuration could not be changed at this time because there
+                                   is some MTFTP background operation in progress.
+                                 - MtftpCofigData.LocalPort is already in use.
+  @retval  EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
+                                 address for this instance, but no source address was available for use.
+  @retval  EFI_OUT_OF_RESOURCES  The EFI MTFTPv6 Protocol driver instance data could not be
+                                 allocated.
+  @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred. The EFI
+                                 MTFTPv6 Protocol driver instance is not configured.
+
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_CONFIGURE)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_CONFIG_DATA   *MtftpConfigData OPTIONAL
+  );
+
+/**
+  Get information about a file from an MTFTPv6 server.
+
+  The GetInfo() function assembles an MTFTPv6 request packet with options, sends it to the
+  MTFTPv6 server, and may return an MTFTPv6 OACK, MTFTPv6 ERROR, or ICMP ERROR packet.
+  Retries occur only if no response packets are received from the MTFTPv6 server before the
+  timeout expires.
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]  OverrideData       Data that is used to override the existing parameters. If NULL, the
+                                 default parameters that were set in the EFI_MTFTP6_PROTOCOL.Configure()
+                                 function are used.
+  @param[in]  Filename           Pointer to null-terminated ASCII file name string.
+  @param[in]  ModeStr            Pointer to null-terminated ASCII mode string. If NULL, octet will be used
+  @param[in]  OptionCount        Number of option/value string pairs in OptionList.
+  @param[in]  OptionList         Pointer to array of option/value string pairs. Ignored if
+                                 OptionCount is zero.
+  @param[out] PacketLength       The number of bytes in the returned packet.
+  @param[out] Packet             The pointer to the received packet. This buffer must be freed by
+                                 the caller.
+
+  @retval  EFI_SUCCESS              An MTFTPv6 OACK packet was received and is in the Packet.
+  @retval  EFI_INVALID_PARAMETER    One or more of the following conditions is TRUE:
+                                    - This is NULL.
+                                    - Filename is NULL
+                                    - OptionCount is not zero and OptionList is NULL.
+                                    - One or more options in OptionList have wrong format.
+                                    - PacketLength is NULL.
+                                    - OverrideData.ServerIp is not valid unicast IPv6 addresses.
+  @retval  EFI_UNSUPPORTED          One or more options in the OptionList are unsupported by
+                                    this implementation.
+  @retval  EFI_NOT_STARTED          The EFI MTFTPv6 Protocol driver has not been started.
+  @retval  EFI_NO_MAPPING           The underlying IPv6 driver was responsible for choosing a source
+                                    address for this instance, but no source address was available for use.
+  @retval  EFI_ACCESS_DENIED        The previous operation has not completed yet.
+  @retval  EFI_OUT_OF_RESOURCES     Required system resources could not be allocated.
+  @retval  EFI_TFTP_ERROR           An MTFTPv6 ERROR packet was received and is in the Packet.
+  @retval  EFI_NETWORK_UNREACHABLE  An ICMP network unreachable error packet was received and the Packet is set to NULL.
+  @retval  EFI_HOST_UNREACHABLE     An ICMP host unreachable error packet was received and the Packet is set to NULL.
+  @retval  EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received and the Packet is set to NULL.
+  @retval  EFI_PORT_UNREACHABLE     An ICMP port unreachable error packet was received and the Packet is set to NULL.
+  @retval  EFI_ICMP_ERROR           Some other ICMP ERROR packet was received and the Packet is set to NULL.
+  @retval  EFI_PROTOCOL_ERROR       An unexpected MTFTPv6 packet was received and is in the Packet.
+  @retval  EFI_TIMEOUT              No responses were received from the MTFTPv6 server.
+  @retval  EFI_DEVICE_ERROR         An unexpected network error or system error occurred.
+  @retval  EFI_NO_MEDIA             There was a media error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_GET_INFO)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_OVERRIDE_DATA *OverrideData OPTIONAL,
+  IN UINT8                    *Filename,
+  IN UINT8                    *ModeStr OPTIONAL,
+  IN UINT8                    OptionCount,
+  IN EFI_MTFTP6_OPTION        *OptionList OPTIONAL,
+  OUT UINT32                  *PacketLength,
+  OUT EFI_MTFTP6_PACKET       **Packet OPTIONAL
+  );
+
+/**
+  Parse the options in an MTFTPv6 OACK packet.
+
+  The ParseOptions() function parses the option fields in an MTFTPv6 OACK packet and
+  returns the number of options that were found and optionally a list of pointers to
+  the options in the packet.
+  If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is returned
+  and *OptionCount and *OptionList stop at the last valid option.
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]  PacketLen          Length of the OACK packet to be parsed.
+  @param[in]  Packet             Pointer to the OACK packet to be parsed.
+  @param[out] OptionCount        Pointer to the number of options in the following OptionList.
+  @param[out] OptionList         Pointer to EFI_MTFTP6_OPTION storage. Each pointer in the
+                                 OptionList points to the corresponding MTFTP option buffer
+                                 in the Packet. Call the EFI Boot Service FreePool() to
+                                 release the OptionList if the options in this OptionList
+                                 are not needed any more.
+
+  @retval  EFI_SUCCESS           The OACK packet was valid and the OptionCount and
+                                 OptionList parameters have been updated.
+  @retval  EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+                                 - PacketLen is 0.
+                                 - Packet is NULL or Packet is not a valid MTFTPv6 packet.
+                                 - OptionCount is NULL.
+  @retval  EFI_NOT_FOUND         No options were found in the OACK packet.
+  @retval  EFI_OUT_OF_RESOURCES  Storage for the OptionList array can not be allocated.
+  @retval  EFI_PROTOCOL_ERROR    One or more of the option fields is invalid.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_PARSE_OPTIONS)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN UINT32                   PacketLen,
+  IN EFI_MTFTP6_PACKET        *Packet,
+  OUT UINT32                  *OptionCount,
+  OUT EFI_MTFTP6_OPTION       **OptionList OPTIONAL
+  );
+
+/**
+  Download a file from an MTFTPv6 server.
+
+  The ReadFile() function is used to initialize and start an MTFTPv6 download process and
+  optionally wait for completion. When the download operation completes, whether successfully or
+  not, the Token.Status field is updated by the EFI MTFTPv6 Protocol driver and then
+  Token.Event is signaled if it is not NULL.
+
+  Data can be downloaded from the MTFTPv6 server into either of the following locations:
+  - A fixed buffer that is pointed to by Token.Buffer
+  - A download service function that is pointed to by Token.CheckPacket
+
+  If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket
+  will be called first. If the call is successful, the packet will be stored in Token.Buffer.
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]  Token              Pointer to the token structure to provide the parameters that are
+                                 used in this operation.
+
+  @retval  EFI_SUCCESS              The data file has been transferred successfully.
+  @retval  EFI_OUT_OF_RESOURCES     Required system resources could not be allocated.
+  @retval  EFI_BUFFER_TOO_SMALL     BufferSize is not zero but not large enough to hold the
+                                    downloaded data in downloading process.
+  @retval  EFI_ABORTED              Current operation is aborted by user.
+  @retval  EFI_NETWORK_UNREACHABLE  An ICMP network unreachable error packet was received.
+  @retval  EFI_HOST_UNREACHABLE     An ICMP host unreachable error packet was received.
+  @retval  EFI_PROTOCOL_UNREACHABLE An ICMP protocol unreachable error packet was received.
+  @retval  EFI_PORT_UNREACHABLE     An ICMP port unreachable error packet was received.
+  @retval  EFI_ICMP_ERROR           An ICMP ERROR packet was received.
+  @retval  EFI_TIMEOUT              No responses were received from the MTFTPv6 server.
+  @retval  EFI_TFTP_ERROR           An MTFTPv6 ERROR packet was received.
+  @retval  EFI_DEVICE_ERROR         An unexpected network error or system error occurred.
+  @retval  EFI_NO_MEDIA             There was a media error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_READ_FILE)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_TOKEN         *Token
+  );
+
+/**
+  Send a file to an MTFTPv6 server. May be unsupported in some implementations.
+
+  The WriteFile() function is used to initialize an uploading operation with the given option list
+  and optionally wait for completion. If one or more of the options is not supported by the server, the
+  unsupported options are ignored and a standard TFTP process starts instead. When the upload
+  process completes, whether successfully or not, Token.Event is signaled, and the EFI MTFTPv6
+  Protocol driver updates Token.Status.
+
+  The caller can supply the data to be uploaded in the following two modes:
+  - Through the user-provided buffer
+  - Through a callback function
+
+  With the user-provided buffer, the Token.BufferSize field indicates the length of the buffer,
+  and the driver will upload the data in the buffer. With an EFI_MTFTP6_PACKET_NEEDED
+  callback function, the driver will call this callback function to get more data from the user to upload.
+  See the definition of EFI_MTFTP6_PACKET_NEEDED for more information. These two modes
+  cannot be used at the same time. The callback function will be ignored if the user provides the
+  buffer.
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]  Token              Pointer to the token structure to provide the parameters that are
+                                 used in this operation.
+
+  @retval  EFI_SUCCESS           The upload session has started.
+  @retval  EFI_UNSUPPORTED       The operation is not supported by this implementation.
+  @retval  EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+                                 - This is NULL.
+                                 - Token is NULL.
+                                 - Token.Filename is NULL.
+                                 - Token.OptionCount is not zero and Token.OptionList is NULL.
+                                 - One or more options in Token.OptionList have wrong format.
+                                 - Token.Buffer and Token.PacketNeeded are both NULL.
+                                 - Token.OverrideData.ServerIp is not valid unicast IPv6 addresses.
+  @retval  EFI_UNSUPPORTED       One or more options in the Token.OptionList are not
+                                 supported by this implementation.
+  @retval  EFI_NOT_STARTED       The EFI MTFTPv6 Protocol driver has not been started.
+  @retval  EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
+                                 address for this instance, but no source address was available for use.
+  @retval  EFI_ALREADY_STARTED   This Token is already being used in another MTFTPv6 session.
+  @retval  EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval  EFI_ACCESS_DENIED     The previous operation has not completed yet.
+  @retval  EFI_DEVICE_ERROR      An unexpected network error or system error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_WRITE_FILE)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_TOKEN         *Token
+  );
+
+/**
+  Download a data file directory from an MTFTPv6 server. May be unsupported in some implementations.
+
+  The ReadDirectory() function is used to return a list of files on the MTFTPv6 server that are
+  logically (or operationally) related to Token.Filename. The directory request packet that is sent
+  to the server is built with the option list that was provided by caller, if present.
+
+  The file information that the server returns is put into either of the following locations:
+  - A fixed buffer that is pointed to by Token.Buffer
+  - A download service function that is pointed to by Token.CheckPacket
+
+  If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket
+  will be called first. If the call is successful, the packet will be stored in Token.Buffer.
+
+  The returned directory listing in the Token.Buffer or EFI_MTFTP6_PACKET consists of a list
+  of two or three variable-length ASCII strings, each terminated by a null character, for each file in the
+  directory. If the multicast option is involved, the first field of each directory entry is the static
+  multicast IP address and UDP port number that is associated with the file name. The format of the
+  field is ip:ip:ip:ip:port. If the multicast option is not involved, this field and its terminating
+  null character are not present.
+
+  The next field of each directory entry is the file name and the last field is the file information string.
+  The information string contains the file size and the create/modify timestamp. The format of the
+  information string is filesize yyyy-mm-dd hh:mm:ss:ffff. The timestamp is
+  Coordinated Universal Time (UTC; also known as Greenwich Mean Time [GMT]).
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+  @param[in]  Token              Pointer to the token structure to provide the parameters that are
+                                 used in this operation.
+
+  @retval  EFI_SUCCESS           The MTFTPv6 related file "directory" has been downloaded.
+  @retval  EFI_UNSUPPORTED       The EFI MTFTPv6 Protocol driver does not support this function.
+  @retval  EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+                                 - This is NULL.
+                                 - Token is NULL.
+                                 - Token.Filename is NULL.
+                                 - Token.OptionCount is not zero and Token.OptionList is NULL.
+                                 - One or more options in Token.OptionList have wrong format.
+                                 - Token.Buffer and Token.CheckPacket are both NULL.
+                                 - Token.OverrideData.ServerIp is not valid unicast IPv6 addresses.
+  @retval  EFI_UNSUPPORTED       One or more options in the Token.OptionList are not
+                                 supported by this implementation.
+  @retval  EFI_NOT_STARTED       The EFI MTFTPv6 Protocol driver has not been started.
+  @retval  EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
+                                 address for this instance, but no source address was available for use.
+  @retval  EFI_ALREADY_STARTED   This Token is already being used in another MTFTPv6 session.
+  @retval  EFI_OUT_OF_RESOURCES  Required system resources could not be allocated.
+  @retval  EFI_ACCESS_DENIED     The previous operation has not completed yet.
+  @retval  EFI_DEVICE_ERROR      An unexpected network error or system error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_READ_DIRECTORY)(
+  IN EFI_MTFTP6_PROTOCOL      *This,
+  IN EFI_MTFTP6_TOKEN         *Token
+  );
+
+/**
+  Polls for incoming data packets and processes outgoing data packets.
+
+  The Poll() function can be used by network drivers and applications to increase the rate that data
+  packets are moved between the communications device and the transmit and receive queues.
+  In some systems, the periodic timer event in the managed network driver may not poll the
+  underlying communications device fast enough to transmit and/or receive all data packets without
+  missing incoming packets or dropping outgoing packets. Drivers and applications that are
+  experiencing packet loss should try calling the Poll() function more often.
+
+  @param[in]  This               Pointer to the EFI_MTFTP6_PROTOCOL instance.
+
+  @retval  EFI_SUCCESS           Incoming or outgoing data was processed.
+  @retval  EFI_NOT_STARTED       This EFI MTFTPv6 Protocol instance has not been started.
+  @retval  EFI_INVALID_PARAMETER This is NULL.
+  @retval  EFI_DEVICE_ERROR      An unexpected system or network error occurred.
+  @retval  EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.
+                                 Consider increasing the polling rate.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_MTFTP6_POLL)(
+  IN EFI_MTFTP6_PROTOCOL      *This
+  );
+
+///
+/// The EFI_MTFTP6_PROTOCOL is designed to be used by UEFI drivers and applications to transmit
+/// and receive data files. The EFI MTFTPv6 Protocol driver uses the underlying EFI UDPv6 Protocol
+/// driver and EFI IPv6 Protocol driver.
+///
+struct _EFI_MTFTP6_PROTOCOL {
+  EFI_MTFTP6_GET_MODE_DATA     GetModeData;
+  EFI_MTFTP6_CONFIGURE         Configure;
+  EFI_MTFTP6_GET_INFO          GetInfo;
+  EFI_MTFTP6_PARSE_OPTIONS     ParseOptions;
+  EFI_MTFTP6_READ_FILE         ReadFile;
+  EFI_MTFTP6_WRITE_FILE        WriteFile;
+  EFI_MTFTP6_READ_DIRECTORY    ReadDirectory;
+  EFI_MTFTP6_POLL              Poll;
+};
+
+extern EFI_GUID  gEfiMtftp6ServiceBindingProtocolGuid;
+extern EFI_GUID  gEfiMtftp6ProtocolGuid;
+
+#endif
diff --git a/src/include/ipxe/efi/Protocol/Tcp6.h b/src/include/ipxe/efi/Protocol/Tcp6.h
new file mode 100644 (file)
index 0000000..eed2f7c
--- /dev/null
@@ -0,0 +1,858 @@
+/** @file
+  EFI TCPv6(Transmission Control Protocol version 6) Protocol Definition
+  The EFI TCPv6 Service Binding Protocol is used to locate EFI TCPv6 Protocol drivers to create
+  and destroy child of the driver to communicate with other host using TCP protocol.
+  The EFI TCPv6 Protocol provides services to send and receive data stream.
+
+  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Revision Reference:
+  This Protocol is introduced in UEFI Specification 2.2
+
+**/
+
+#ifndef __EFI_TCP6_PROTOCOL_H__
+#define __EFI_TCP6_PROTOCOL_H__
+
+FILE_LICENCE ( BSD2_PATENT );
+
+#include <ipxe/efi/Protocol/ManagedNetwork.h>
+#include <ipxe/efi/Protocol/Ip6.h>
+
+#define EFI_TCP6_SERVICE_BINDING_PROTOCOL_GUID \
+  { \
+    0xec20eb79, 0x6c1a, 0x4664, {0x9a, 0x0d, 0xd2, 0xe4, 0xcc, 0x16, 0xd6, 0x64 } \
+  }
+
+#define EFI_TCP6_PROTOCOL_GUID \
+  { \
+    0x46e44855, 0xbd60, 0x4ab7, {0xab, 0x0d, 0xa6, 0x79, 0xb9, 0x44, 0x7d, 0x77 } \
+  }
+
+typedef struct _EFI_TCP6_PROTOCOL EFI_TCP6_PROTOCOL;
+
+///
+/// EFI_TCP6_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more.
+/// The definition in here is only present to provide backwards compatability.
+///
+typedef struct {
+  ///
+  /// The EFI TCPv6 Protocol instance handle that is using this
+  /// address/port pair.
+  ///
+  EFI_HANDLE          InstanceHandle;
+  ///
+  /// The local IPv6 address to which this TCP instance is bound. Set
+  /// to 0::/128, if this TCP instance is configured to listen on all
+  /// available source addresses.
+  ///
+  EFI_IPv6_ADDRESS    LocalAddress;
+  ///
+  /// The local port number in host byte order.
+  ///
+  UINT16              LocalPort;
+  ///
+  /// The remote IPv6 address. It may be 0::/128 if this TCP instance is
+  /// not connected to any remote host.
+  ///
+  EFI_IPv6_ADDRESS    RemoteAddress;
+  ///
+  /// The remote port number in host byte order. It may be zero if this
+  /// TCP instance is not connected to any remote host.
+  ///
+  UINT16              RemotePort;
+} EFI_TCP6_SERVICE_POINT;
+
+///
+/// EFI_TCP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more.
+/// The definition in here is only present to provide backwards compatability.
+///
+typedef struct {
+  EFI_HANDLE                DriverHandle; ///< The handle of the driver that creates this entry.
+  UINT32                    ServiceCount; ///< The number of address/port pairs following this data structure.
+  EFI_TCP6_SERVICE_POINT    Services[1];  ///< List of address/port pairs that are currently in use.
+} EFI_TCP6_VARIABLE_DATA;
+
+///
+/// EFI_TCP6_ACCESS_POINT
+///
+typedef struct {
+  ///
+  /// The local IP address assigned to this TCP instance. The EFI
+  /// TCPv6 driver will only deliver incoming packets whose
+  /// destination addresses exactly match the IP address. Set to zero to
+  /// let the underlying IPv6 driver choose a source address. If not zero
+  /// it must be one of the configured IP addresses in the underlying
+  /// IPv6 driver.
+  ///
+  EFI_IPv6_ADDRESS    StationAddress;
+  ///
+  /// The local port number to which this EFI TCPv6 Protocol instance
+  /// is bound. If the instance doesn't care the local port number, set
+  /// StationPort to zero to use an ephemeral port.
+  ///
+  UINT16              StationPort;
+  ///
+  /// The remote IP address to which this EFI TCPv6 Protocol instance
+  /// is connected. If ActiveFlag is FALSE (i.e. a passive TCPv6
+  /// instance), the instance only accepts connections from the
+  /// RemoteAddress. If ActiveFlag is TRUE the instance will
+  /// connect to the RemoteAddress, i.e., outgoing segments will be
+  /// sent to this address and only segments from this address will be
+  /// delivered to the application. When ActiveFlag is FALSE, it
+  /// can be set to zero and means that incoming connection requests
+  /// from any address will be accepted.
+  ///
+  EFI_IPv6_ADDRESS    RemoteAddress;
+  ///
+  /// The remote port to which this EFI TCPv6 Protocol instance
+  /// connects or from which connection request will be accepted by
+  /// this EFI TCPv6 Protocol instance. If ActiveFlag is FALSE it
+  /// can be zero and means that incoming connection request from
+  /// any port will be accepted. Its value can not be zero when
+  /// ActiveFlag is TRUE.
+  ///
+  UINT16     RemotePort;
+  ///
+  /// Set it to TRUE to initiate an active open. Set it to FALSE to
+  /// initiate a passive open to act as a server.
+  ///
+  BOOLEAN    ActiveFlag;
+} EFI_TCP6_ACCESS_POINT;
+
+///
+/// EFI_TCP6_OPTION
+///
+typedef struct {
+  ///
+  /// The size of the TCP receive buffer.
+  ///
+  UINT32    ReceiveBufferSize;
+  ///
+  /// The size of the TCP send buffer.
+  ///
+  UINT32    SendBufferSize;
+  ///
+  /// The length of incoming connect request queue for a passive
+  /// instance. When set to zero, the value is implementation specific.
+  ///
+  UINT32    MaxSynBackLog;
+  ///
+  /// The maximum seconds a TCP instance will wait for before a TCP
+  /// connection established. When set to zero, the value is
+  /// implementation specific.
+  ///
+  UINT32    ConnectionTimeout;
+  ///
+  /// The number of times TCP will attempt to retransmit a packet on
+  /// an established connection. When set to zero, the value is
+  /// implementation specific.
+  ///
+  UINT32    DataRetries;
+  ///
+  /// How many seconds to wait in the FIN_WAIT_2 states for a final
+  /// FIN flag before the TCP instance is closed. This timeout is in
+  /// effective only if the application has called Close() to
+  /// disconnect the connection completely. It is also called
+  /// FIN_WAIT_2 timer in other implementations. When set to zero,
+  /// it should be disabled because the FIN_WAIT_2 timer itself is
+  /// against the standard. The default value is 60.
+  ///
+  UINT32     FinTimeout;
+  ///
+  /// How many seconds to wait in TIME_WAIT state before the TCP
+  /// instance is closed. The timer is disabled completely to provide a
+  /// method to close the TCP connection quickly if it is set to zero. It
+  /// is against the related RFC documents.
+  ///
+  UINT32     TimeWaitTimeout;
+  ///
+  /// The maximum number of TCP keep-alive probes to send before
+  /// giving up and resetting the connection if no response from the
+  /// other end. Set to zero to disable keep-alive probe.
+  ///
+  UINT32     KeepAliveProbes;
+  ///
+  /// The number of seconds a connection needs to be idle before TCP
+  /// sends out periodical keep-alive probes. When set to zero, the
+  /// value is implementation specific. It should be ignored if keep-
+  /// alive probe is disabled.
+  ///
+  UINT32     KeepAliveTime;
+  ///
+  /// The number of seconds between TCP keep-alive probes after the
+  /// periodical keep-alive probe if no response. When set to zero, the
+  /// value is implementation specific. It should be ignored if keep-
+  /// alive probe is disabled.
+  ///
+  UINT32     KeepAliveInterval;
+  ///
+  /// Set it to TRUE to enable the Nagle algorithm as defined in
+  /// RFC896. Set it to FALSE to disable it.
+  ///
+  BOOLEAN    EnableNagle;
+  ///
+  /// Set it to TRUE to enable TCP timestamps option as defined in
+  /// RFC1323. Set to FALSE to disable it.
+  ///
+  BOOLEAN    EnableTimeStamp;
+  ///
+  /// Set it to TRUE to enable TCP window scale option as defined in
+  /// RFC1323. Set it to FALSE to disable it.
+  ///
+  BOOLEAN    EnableWindowScaling;
+  ///
+  /// Set it to TRUE to enable selective acknowledge mechanism
+  /// described in RFC 2018. Set it to FALSE to disable it.
+  /// Implementation that supports SACK can optionally support
+  /// DSAK as defined in RFC 2883.
+  ///
+  BOOLEAN    EnableSelectiveAck;
+  ///
+  /// Set it to TRUE to enable path MTU discovery as defined in
+  /// RFC 1191. Set to FALSE to disable it.
+  ///
+  BOOLEAN    EnablePathMtuDiscovery;
+} EFI_TCP6_OPTION;
+
+///
+/// EFI_TCP6_CONFIG_DATA
+///
+typedef struct {
+  ///
+  /// TrafficClass field in transmitted IPv6 packets.
+  ///
+  UINT8                    TrafficClass;
+  ///
+  /// HopLimit field in transmitted IPv6 packets.
+  ///
+  UINT8                    HopLimit;
+  ///
+  /// Used to specify TCP communication end settings for a TCP instance.
+  ///
+  EFI_TCP6_ACCESS_POINT    AccessPoint;
+  ///
+  /// Used to configure the advance TCP option for a connection. If set
+  /// to NULL, implementation specific options for TCP connection will be used.
+  ///
+  EFI_TCP6_OPTION          *ControlOption;
+} EFI_TCP6_CONFIG_DATA;
+
+///
+/// EFI_TCP6_CONNECTION_STATE
+///
+typedef enum {
+  Tcp6StateClosed      = 0,
+  Tcp6StateListen      = 1,
+  Tcp6StateSynSent     = 2,
+  Tcp6StateSynReceived = 3,
+  Tcp6StateEstablished = 4,
+  Tcp6StateFinWait1    = 5,
+  Tcp6StateFinWait2    = 6,
+  Tcp6StateClosing     = 7,
+  Tcp6StateTimeWait    = 8,
+  Tcp6StateCloseWait   = 9,
+  Tcp6StateLastAck     = 10
+} EFI_TCP6_CONNECTION_STATE;
+
+///
+/// EFI_TCP6_COMPLETION_TOKEN
+/// is used as a common header for various asynchronous tokens.
+///
+typedef struct {
+  ///
+  /// The Event to signal after request is finished and Status field is
+  /// updated by the EFI TCPv6 Protocol driver.
+  ///
+  EFI_EVENT     Event;
+  ///
+  /// The result of the completed operation.
+  ///
+  EFI_STATUS    Status;
+} EFI_TCP6_COMPLETION_TOKEN;
+
+///
+/// EFI_TCP6_CONNECTION_TOKEN
+/// will be set if the active open succeeds or an unexpected
+/// error happens.
+///
+typedef struct {
+  ///
+  /// The Status in the CompletionToken will be set to one of
+  /// the following values if the active open succeeds or an unexpected
+  /// error happens:
+  /// EFI_SUCCESS:              The active open succeeds and the instance's
+  ///                           state is Tcp6StateEstablished.
+  /// EFI_CONNECTION_RESET:     The connect fails because the connection is reset
+  ///                           either by instance itself or the communication peer.
+  /// EFI_CONNECTION_REFUSED:   The receiving or transmission operation fails because this
+  ///                           connection is refused.
+  /// EFI_ABORTED:              The active open is aborted.
+  /// EFI_TIMEOUT:              The connection establishment timer expires and
+  ///                           no more specific information is available.
+  /// EFI_NETWORK_UNREACHABLE:  The active open fails because
+  ///                           an ICMP network unreachable error is received.
+  /// EFI_HOST_UNREACHABLE:     The active open fails because an
+  ///                           ICMP host unreachable error is received.
+  /// EFI_PROTOCOL_UNREACHABLE: The active open fails
+  ///                           because an ICMP protocol unreachable error is received.
+  /// EFI_PORT_UNREACHABLE:     The connection establishment
+  ///                           timer times out and an ICMP port unreachable error is received.
+  /// EFI_ICMP_ERROR:           The connection establishment timer times
+  ///                           out and some other ICMP error is received.
+  /// EFI_DEVICE_ERROR:         An unexpected system or network error occurred.
+  /// EFI_SECURITY_VIOLATION:   The active open was failed because of IPSec policy check.
+  /// EFI_NO_MEDIA:             There was a media error.
+  ///
+  EFI_TCP6_COMPLETION_TOKEN    CompletionToken;
+} EFI_TCP6_CONNECTION_TOKEN;
+
+///
+/// EFI_TCP6_LISTEN_TOKEN
+/// returns when list operation finishes.
+///
+typedef struct {
+  ///
+  /// The Status in CompletionToken will be set to the
+  /// following value if accept finishes:
+  /// EFI_SUCCESS:            A remote peer has successfully established a
+  ///                         connection to this instance. A new TCP instance has also been
+  ///                         created for the connection.
+  /// EFI_CONNECTION_RESET:   The accept fails because the connection is reset either
+  ///                         by instance itself or communication peer.
+  /// EFI_ABORTED:            The accept request has been aborted.
+  /// EFI_SECURITY_VIOLATION: The accept operation was failed because of IPSec policy check.
+  ///
+  EFI_TCP6_COMPLETION_TOKEN    CompletionToken;
+  EFI_HANDLE                   NewChildHandle;
+} EFI_TCP6_LISTEN_TOKEN;
+
+///
+/// EFI_TCP6_FRAGMENT_DATA
+/// allows multiple receive or transmit buffers to be specified. The
+/// purpose of this structure is to provide scattered read and write.
+///
+typedef struct {
+  UINT32    FragmentLength;  ///< Length of data buffer in the fragment.
+  VOID      *FragmentBuffer; ///< Pointer to the data buffer in the fragment.
+} EFI_TCP6_FRAGMENT_DATA;
+
+///
+/// EFI_TCP6_RECEIVE_DATA
+/// When TCPv6 driver wants to deliver received data to the application,
+/// it will pick up the first queued receiving token, update its
+/// Token->Packet.RxData then signal the Token->CompletionToken.Event.
+///
+typedef struct {
+  ///
+  /// Whether the data is urgent. When this flag is set, the instance is in
+  /// urgent mode.
+  ///
+  BOOLEAN                   UrgentFlag;
+  ///
+  /// When calling Receive() function, it is the byte counts of all
+  /// Fragmentbuffer in FragmentTable allocated by user.
+  /// When the token is signaled by TCPv6 driver it is the length of
+  /// received data in the fragments.
+  ///
+  UINT32                    DataLength;
+  ///
+  /// Number of fragments.
+  ///
+  UINT32                    FragmentCount;
+  ///
+  /// An array of fragment descriptors.
+  ///
+  EFI_TCP6_FRAGMENT_DATA    FragmentTable[1];
+} EFI_TCP6_RECEIVE_DATA;
+
+///
+/// EFI_TCP6_TRANSMIT_DATA
+/// The EFI TCPv6 Protocol user must fill this data structure before sending a packet.
+/// The packet may contain multiple buffers in non-continuous memory locations.
+///
+typedef struct {
+  ///
+  /// Push If TRUE, data must be transmitted promptly, and the PUSH bit in
+  /// the last TCP segment created will be set. If FALSE, data
+  /// transmission may be delayed to combine with data from
+  /// subsequent Transmit()s for efficiency.
+  ///
+  BOOLEAN                   Push;
+  ///
+  /// The data in the fragment table are urgent and urgent point is in
+  /// effect if TRUE. Otherwise those data are NOT considered urgent.
+  ///
+  BOOLEAN                   Urgent;
+  ///
+  /// Length of the data in the fragments.
+  ///
+  UINT32                    DataLength;
+  ///
+  /// Number of fragments.
+  ///
+  UINT32                    FragmentCount;
+  ///
+  /// An array of fragment descriptors.
+  ///
+  EFI_TCP6_FRAGMENT_DATA    FragmentTable[1];
+} EFI_TCP6_TRANSMIT_DATA;
+
+///
+/// EFI_TCP6_IO_TOKEN
+/// returns When transmission finishes or meets any unexpected error.
+///
+typedef struct {
+  ///
+  /// When transmission finishes or meets any unexpected error it will
+  /// be set to one of the following values:
+  /// EFI_SUCCESS:              The receiving or transmission operation
+  ///                           completes successfully.
+  /// EFI_CONNECTION_FIN:       The receiving operation fails because the communication peer
+  ///                           has closed the connection and there is no more data in the
+  ///                           receive buffer of the instance.
+  /// EFI_CONNECTION_RESET:     The receiving or transmission operation fails
+  ///                           because this connection is reset either by instance
+  ///                           itself or the communication peer.
+  /// EFI_ABORTED:              The receiving or transmission is aborted.
+  /// EFI_TIMEOUT:              The transmission timer expires and no more
+  ///                           specific information is available.
+  /// EFI_NETWORK_UNREACHABLE:  The transmission fails
+  ///                           because an ICMP network unreachable error is received.
+  /// EFI_HOST_UNREACHABLE:     The transmission fails because an
+  ///                           ICMP host unreachable error is received.
+  /// EFI_PROTOCOL_UNREACHABLE: The transmission fails
+  ///                           because an ICMP protocol unreachable error is received.
+  /// EFI_PORT_UNREACHABLE:     The transmission fails and an
+  ///                           ICMP port unreachable error is received.
+  /// EFI_ICMP_ERROR:           The transmission fails and some other
+  ///                           ICMP error is received.
+  /// EFI_DEVICE_ERROR:         An unexpected system or network error occurs.
+  /// EFI_SECURITY_VIOLATION:   The receiving or transmission
+  ///                           operation was failed because of IPSec policy check
+  /// EFI_NO_MEDIA:             There was a media error.
+  ///
+  EFI_TCP6_COMPLETION_TOKEN    CompletionToken;
+  union {
+    ///
+    /// When this token is used for receiving, RxData is a pointer to
+    /// EFI_TCP6_RECEIVE_DATA.
+    ///
+    EFI_TCP6_RECEIVE_DATA     *RxData;
+    ///
+    /// When this token is used for transmitting, TxData is a pointer to
+    /// EFI_TCP6_TRANSMIT_DATA.
+    ///
+    EFI_TCP6_TRANSMIT_DATA    *TxData;
+  } Packet;
+} EFI_TCP6_IO_TOKEN;
+
+///
+/// EFI_TCP6_CLOSE_TOKEN
+/// returns when close operation finishes.
+///
+typedef struct {
+  ///
+  /// When close finishes or meets any unexpected error it will be set
+  /// to one of the following values:
+  /// EFI_SUCCESS:            The close operation completes successfully.
+  /// EFI_ABORTED:            User called configure with NULL without close stopping.
+  /// EFI_SECURITY_VIOLATION: The close operation was failed because of IPSec policy check.
+  ///
+  EFI_TCP6_COMPLETION_TOKEN    CompletionToken;
+  ///
+  /// Abort the TCP connection on close instead of the standard TCP
+  /// close process when it is set to TRUE. This option can be used to
+  /// satisfy a fast disconnect.
+  ///
+  BOOLEAN                      AbortOnClose;
+} EFI_TCP6_CLOSE_TOKEN;
+
+/**
+  Get the current operational status.
+
+  The GetModeData() function copies the current operational settings of this EFI TCPv6
+  Protocol instance into user-supplied buffers. This function can also be used to retrieve
+  the operational setting of underlying drivers such as IPv6, MNP, or SNP.
+
+  @param[in]  This              Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[out] Tcp6State         The buffer in which the current TCP state is returned.
+  @param[out] Tcp6ConfigData    The buffer in which the current TCP configuration is returned.
+  @param[out] Ip6ModeData       The buffer in which the current IPv6 configuration data used by
+                                the TCP instance is returned.
+  @param[out] MnpConfigData     The buffer in which the current MNP configuration data used
+                                indirectly by the TCP instance is returned.
+  @param[out] SnpModeData       The buffer in which the current SNP mode data used indirectly by
+                                the TCP instance is returned.
+
+  @retval EFI_SUCCESS           The mode data was read.
+  @retval EFI_NOT_STARTED       No configuration data is available because this instance hasn't
+                                been started.
+  @retval EFI_INVALID_PARAMETER This is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_GET_MODE_DATA)(
+  IN  EFI_TCP6_PROTOCOL                  *This,
+  OUT EFI_TCP6_CONNECTION_STATE          *Tcp6State OPTIONAL,
+  OUT EFI_TCP6_CONFIG_DATA               *Tcp6ConfigData OPTIONAL,
+  OUT EFI_IP6_MODE_DATA                  *Ip6ModeData OPTIONAL,
+  OUT EFI_MANAGED_NETWORK_CONFIG_DATA    *MnpConfigData OPTIONAL,
+  OUT EFI_SIMPLE_NETWORK_MODE            *SnpModeData OPTIONAL
+  );
+
+/**
+  Initialize or brutally reset the operational parameters for this EFI TCPv6 instance.
+
+  The Configure() function does the following:
+  - Initialize this TCP instance, i.e., initialize the communication end settings and
+    specify active open or passive open for an instance.
+  - Reset this TCP instance brutally, i.e., cancel all pending asynchronous tokens, flush
+    transmission and receiving buffer directly without informing the communication peer.
+
+  No other TCPv6 Protocol operation except Poll() can be executed by this instance until
+  it is configured properly. For an active TCP instance, after a proper configuration it
+  may call Connect() to initiates the three-way handshake. For a passive TCP instance,
+  its state will transit to Tcp6StateListen after configuration, and Accept() may be
+  called to listen the incoming TCP connection requests. If Tcp6ConfigData is set to NULL,
+  the instance is reset. Resetting process will be done brutally, the state machine will
+  be set to Tcp6StateClosed directly, the receive queue and transmit queue will be flushed,
+  and no traffic is allowed through this instance.
+
+  @param[in] This               Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[in] Tcp6ConfigData     Pointer to the configure data to configure the instance.
+                                If Tcp6ConfigData is set to NULL, the instance is reset.
+
+  @retval EFI_SUCCESS           The operational settings are set, changed, or reset
+                                successfully.
+  @retval EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
+                                address for this instance, but no source address was available for
+                                use.
+  @retval EFI_INVALID_PARAMETER One or more of the following conditions are TRUE:
+                                - This is NULL.
+                                - Tcp6ConfigData->AccessPoint.StationAddress is neither zero nor
+                                  one of the configured IP addresses in the underlying IPv6 driver.
+                                - Tcp6ConfigData->AccessPoint.RemoteAddress isn't a valid unicast
+                                  IPv6 address.
+                                - Tcp6ConfigData->AccessPoint.RemoteAddress is zero or
+                                  Tcp6ConfigData->AccessPoint.RemotePort is zero when
+                                  Tcp6ConfigData->AccessPoint.ActiveFlag is TRUE.
+                                - A same access point has been configured in other TCP
+                                  instance properly.
+  @retval EFI_ACCESS_DENIED     Configuring TCP instance when it is configured without
+                                calling Configure() with NULL to reset it.
+  @retval EFI_UNSUPPORTED       One or more of the control options are not supported in
+                                the implementation.
+  @retval EFI_OUT_OF_RESOURCES  Could not allocate enough system resources when
+                                executing Configure().
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CONFIGURE)(
+  IN EFI_TCP6_PROTOCOL        *This,
+  IN EFI_TCP6_CONFIG_DATA     *Tcp6ConfigData OPTIONAL
+  );
+
+/**
+  Initiate a nonblocking TCP connection request for an active TCP instance.
+
+  The Connect() function will initiate an active open to the remote peer configured
+  in current TCP instance if it is configured active. If the connection succeeds or
+  fails due to any error, the ConnectionToken->CompletionToken.Event will be signaled
+  and ConnectionToken->CompletionToken.Status will be updated accordingly. This
+  function can only be called for the TCP instance in Tcp6StateClosed state. The
+  instance will transfer into Tcp6StateSynSent if the function returns EFI_SUCCESS.
+  If TCP three-way handshake succeeds, its state will become Tcp6StateEstablished,
+  otherwise, the state will return to Tcp6StateClosed.
+
+  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[in] ConnectionToken     Pointer to the connection token to return when the TCP three
+                                 way handshake finishes.
+
+  @retval EFI_SUCCESS            The connection request is successfully initiated and the state of
+                                 this TCP instance has been changed to Tcp6StateSynSent.
+  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
+  @retval EFI_ACCESS_DENIED      One or more of the following conditions are TRUE:
+                                 - This instance is not configured as an active one.
+                                 - This instance is not in Tcp6StateClosed state.
+  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
+                                 - This is NULL.
+                                 - ConnectionToken is NULL.
+                                 - ConnectionToken->CompletionToken.Event is NULL.
+  @retval EFI_OUT_OF_RESOURCES   The driver can't allocate enough resource to initiate the active open.
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CONNECT)(
+  IN EFI_TCP6_PROTOCOL           *This,
+  IN EFI_TCP6_CONNECTION_TOKEN   *ConnectionToken
+  );
+
+/**
+  Listen on the passive instance to accept an incoming connection request. This is a
+  nonblocking operation.
+
+  The Accept() function initiates an asynchronous accept request to wait for an incoming
+  connection on the passive TCP instance. If a remote peer successfully establishes a
+  connection with this instance, a new TCP instance will be created and its handle will
+  be returned in ListenToken->NewChildHandle. The newly created instance is configured
+  by inheriting the passive instance's configuration and is ready for use upon return.
+  The new instance is in the Tcp6StateEstablished state.
+
+  The ListenToken->CompletionToken.Event will be signaled when a new connection is
+  accepted, user aborts the listen or connection is reset.
+
+  This function only can be called when current TCP instance is in Tcp6StateListen state.
+
+  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[in] ListenToken         Pointer to the listen token to return when operation finishes.
+
+
+  @retval EFI_SUCCESS            The listen token has been queued successfully.
+  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
+  @retval EFI_ACCESS_DENIED      One or more of the following are TRUE:
+                                 - This instance is not a passive instance.
+                                 - This instance is not in Tcp6StateListen state.
+                                 - The same listen token has already existed in the listen
+                                   token queue of this TCP instance.
+  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
+                                 - This is NULL.
+                                 - ListenToken is NULL.
+                                 - ListentToken->CompletionToken.Event is NULL.
+  @retval EFI_OUT_OF_RESOURCES   Could not allocate enough resource to finish the operation.
+  @retval EFI_DEVICE_ERROR       Any unexpected and not belonged to above category error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_ACCEPT)(
+  IN EFI_TCP6_PROTOCOL             *This,
+  IN EFI_TCP6_LISTEN_TOKEN         *ListenToken
+  );
+
+/**
+  Queues outgoing data into the transmit queue.
+
+  The Transmit() function queues a sending request to this TCP instance along with the
+  user data. The status of the token is updated and the event in the token will be
+  signaled once the data is sent out or some error occurs.
+
+  @param[in] This                 Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[in] Token                Pointer to the completion token to queue to the transmit queue.
+
+  @retval EFI_SUCCESS             The data has been queued for transmission.
+  @retval EFI_NOT_STARTED         This EFI TCPv6 Protocol instance has not been configured.
+  @retval EFI_NO_MAPPING          The underlying IPv6 driver was responsible for choosing a
+                                  source address for this instance, but no source address was
+                                  available for use.
+  @retval EFI_INVALID_PARAMETER   One or more of the following are TRUE:
+                                  - This is NULL.
+                                  - Token is NULL.
+                                  - Token->CompletionToken.Event is NULL.
+                                  - Token->Packet.TxData is NULL.
+                                  - Token->Packet.FragmentCount is zero.
+                                  - Token->Packet.DataLength is not equal to the sum of fragment lengths.
+  @retval EFI_ACCESS_DENIED       One or more of the following conditions are TRUE:
+                                  - A transmit completion token with the same Token->
+                                    CompletionToken.Event was already in the
+                                    transmission queue.
+                                  - The current instance is in Tcp6StateClosed state.
+                                  - The current instance is a passive one and it is in
+                                    Tcp6StateListen state.
+                                  - User has called Close() to disconnect this connection.
+  @retval EFI_NOT_READY           The completion token could not be queued because the
+                                  transmit queue is full.
+  @retval EFI_OUT_OF_RESOURCES    Could not queue the transmit data because of resource
+                                  shortage.
+  @retval EFI_NETWORK_UNREACHABLE There is no route to the destination network or address.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_TRANSMIT)(
+  IN EFI_TCP6_PROTOCOL            *This,
+  IN EFI_TCP6_IO_TOKEN            *Token
+  );
+
+/**
+  Places an asynchronous receive request into the receiving queue.
+
+  The Receive() function places a completion token into the receive packet queue. This
+  function is always asynchronous. The caller must allocate the Token->CompletionToken.Event
+  and the FragmentBuffer used to receive data. The caller also must fill the DataLength which
+  represents the whole length of all FragmentBuffer. When the receive operation completes, the
+  EFI TCPv6 Protocol driver updates the Token->CompletionToken.Status and Token->Packet.RxData
+  fields and the Token->CompletionToken.Event is signaled. If got data the data and its length
+  will be copied into the FragmentTable, at the same time the full length of received data will
+  be recorded in the DataLength fields. Providing a proper notification function and context
+  for the event will enable the user to receive the notification and receiving status. That
+  notification function is guaranteed to not be re-entered.
+
+  @param[in] This               Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[in] Token              Pointer to a token that is associated with the receive data
+                                descriptor.
+
+  @retval EFI_SUCCESS            The receive completion token was cached.
+  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
+  @retval EFI_NO_MAPPING         The underlying IPv6 driver was responsible for choosing a source
+                                 address for this instance, but no source address was available for use.
+  @retval EFI_INVALID_PARAMETER  One or more of the following conditions is TRUE:
+                                 - This is NULL.
+                                 - Token is NULL.
+                                 - Token->CompletionToken.Event is NULL.
+                                 - Token->Packet.RxData is NULL.
+                                 - Token->Packet.RxData->DataLength is 0.
+                                 - The Token->Packet.RxData->DataLength is not the
+                                   sum of all FragmentBuffer length in FragmentTable.
+  @retval EFI_OUT_OF_RESOURCES   The receive completion token could not be queued due to a lack of
+                                 system resources (usually memory).
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
+                                 The EFI TCPv6 Protocol instance has been reset to startup defaults.
+  @retval EFI_ACCESS_DENIED      One or more of the following conditions is TRUE:
+                                 - A receive completion token with the same Token->CompletionToken.Event
+                                   was already in the receive queue.
+                                 - The current instance is in Tcp6StateClosed state.
+                                 - The current instance is a passive one and it is in
+                                   Tcp6StateListen state.
+                                 - User has called Close() to disconnect this connection.
+  @retval EFI_CONNECTION_FIN     The communication peer has closed the connection and there is no
+                                 any buffered data in the receive buffer of this instance
+  @retval EFI_NOT_READY          The receive request could not be queued because the receive queue is full.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_RECEIVE)(
+  IN EFI_TCP6_PROTOCOL           *This,
+  IN EFI_TCP6_IO_TOKEN           *Token
+  );
+
+/**
+  Disconnecting a TCP connection gracefully or reset a TCP connection. This function is a
+  nonblocking operation.
+
+  Initiate an asynchronous close token to TCP driver. After Close() is called, any buffered
+  transmission data will be sent by TCP driver and the current instance will have a graceful close
+  working flow described as RFC 793 if AbortOnClose is set to FALSE, otherwise, a rest packet
+  will be sent by TCP driver to fast disconnect this connection. When the close operation completes
+  successfully the TCP instance is in Tcp6StateClosed state, all pending asynchronous
+  operations are signaled and any buffers used for TCP network traffic are flushed.
+
+  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[in] CloseToken          Pointer to the close token to return when operation finishes.
+
+  @retval EFI_SUCCESS            The Close() is called successfully.
+  @retval EFI_NOT_STARTED        This EFI TCPv6 Protocol instance has not been configured.
+  @retval EFI_ACCESS_DENIED      One or more of the following are TRUE:
+                                 - CloseToken or CloseToken->CompletionToken.Event is already in use.
+                                 - Previous Close() call on this instance has not finished.
+  @retval EFI_INVALID_PARAMETER  One or more of the following are TRUE:
+                                 - This is NULL.
+                                 - CloseToken is NULL.
+                                 - CloseToken->CompletionToken.Event is NULL.
+  @retval EFI_OUT_OF_RESOURCES   Could not allocate enough resource to finish the operation.
+  @retval EFI_DEVICE_ERROR       Any unexpected and not belonged to above category error.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CLOSE)(
+  IN EFI_TCP6_PROTOCOL           *This,
+  IN EFI_TCP6_CLOSE_TOKEN        *CloseToken
+  );
+
+/**
+  Abort an asynchronous connection, listen, transmission or receive request.
+
+  The Cancel() function aborts a pending connection, listen, transmit or
+  receive request.
+
+  If Token is not NULL and the token is in the connection, listen, transmission
+  or receive queue when it is being cancelled, its Token->Status will be set
+  to EFI_ABORTED and then Token->Event will be signaled.
+
+  If the token is not in one of the queues, which usually means that the
+  asynchronous operation has completed, EFI_NOT_FOUND is returned.
+
+  If Token is NULL all asynchronous token issued by Connect(), Accept(),
+  Transmit() and Receive() will be aborted.
+
+  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
+  @param[in] Token               Pointer to a token that has been issued by
+                                 EFI_TCP6_PROTOCOL.Connect(),
+                                 EFI_TCP6_PROTOCOL.Accept(),
+                                 EFI_TCP6_PROTOCOL.Transmit() or
+                                 EFI_TCP6_PROTOCOL.Receive(). If NULL, all pending
+                                 tokens issued by above four functions will be aborted. Type
+                                 EFI_TCP6_COMPLETION_TOKEN is defined in
+                                 EFI_TCP_PROTOCOL.Connect().
+
+  @retval EFI_SUCCESS            The asynchronous I/O request is aborted and Token->Event
+                                 is signaled.
+  @retval EFI_INVALID_PARAMETER  This is NULL.
+  @retval EFI_NOT_STARTED        This instance hasn't been configured.
+  @retval EFI_NOT_FOUND          The asynchronous I/O request isn't found in the transmission or
+                                 receive queue. It has either completed or wasn't issued by
+                                 Transmit() and Receive().
+  @retval EFI_UNSUPPORTED        The implementation does not support this function.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_CANCEL)(
+  IN EFI_TCP6_PROTOCOL           *This,
+  IN EFI_TCP6_COMPLETION_TOKEN   *Token OPTIONAL
+  );
+
+/**
+  Poll to receive incoming data and transmit outgoing segments.
+
+  The Poll() function increases the rate that data is moved between the network
+  and application and can be called when the TCP instance is created successfully.
+  Its use is optional.
+
+  @param[in] This                Pointer to the EFI_TCP6_PROTOCOL instance.
+
+  @retval EFI_SUCCESS            Incoming or outgoing data was processed.
+  @retval EFI_INVALID_PARAMETER  This is NULL.
+  @retval EFI_DEVICE_ERROR       An unexpected system or network error occurred.
+  @retval EFI_NOT_READY          No incoming or outgoing data is processed.
+  @retval EFI_TIMEOUT            Data was dropped out of the transmission or receive queue.
+                                 Consider increasing the polling rate.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCP6_POLL)(
+  IN EFI_TCP6_PROTOCOL        *This
+  );
+
+///
+/// EFI_TCP6_PROTOCOL
+/// defines the EFI TCPv6 Protocol child to be used by any network drivers or
+/// applications to send or receive data stream. It can either listen on a
+/// specified port as a service or actively connect to remote peer as a client.
+/// Each instance has its own independent settings.
+///
+struct _EFI_TCP6_PROTOCOL {
+  EFI_TCP6_GET_MODE_DATA    GetModeData;
+  EFI_TCP6_CONFIGURE        Configure;
+  EFI_TCP6_CONNECT          Connect;
+  EFI_TCP6_ACCEPT           Accept;
+  EFI_TCP6_TRANSMIT         Transmit;
+  EFI_TCP6_RECEIVE          Receive;
+  EFI_TCP6_CLOSE            Close;
+  EFI_TCP6_CANCEL           Cancel;
+  EFI_TCP6_POLL             Poll;
+};
+
+extern EFI_GUID  gEfiTcp6ServiceBindingProtocolGuid;
+extern EFI_GUID  gEfiTcp6ProtocolGuid;
+
+#endif
diff --git a/src/include/ipxe/efi/Protocol/Udp6.h b/src/include/ipxe/efi/Protocol/Udp6.h
new file mode 100644 (file)
index 0000000..5a62a3e
--- /dev/null
@@ -0,0 +1,576 @@
+/** @file
+  The EFI UDPv6 (User Datagram Protocol version 6) Protocol Definition, which is built upon
+  the EFI IPv6 Protocol and provides simple packet-oriented services to transmit and receive
+  UDP packets.
+
+  Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+  @par Revision Reference:
+  This Protocol is introduced in UEFI Specification 2.2
+
+**/
+
+#ifndef __EFI_UDP6_PROTOCOL_H__
+#define __EFI_UDP6_PROTOCOL_H__
+
+FILE_LICENCE ( BSD2_PATENT );
+
+#include <ipxe/efi/Protocol/Ip6.h>
+
+#define EFI_UDP6_SERVICE_BINDING_PROTOCOL_GUID \
+  { \
+    0x66ed4721, 0x3c98, 0x4d3e, {0x81, 0xe3, 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54 } \
+  }
+
+#define EFI_UDP6_PROTOCOL_GUID \
+  { \
+    0x4f948815, 0xb4b9, 0x43cb, {0x8a, 0x33, 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55 } \
+  }
+
+///
+/// EFI_UDP6_SERVICE_POINT is deprecated in the UEFI 2.4B and should not be used any more.
+/// The definition in here is only present to provide backwards compatability.
+///
+typedef struct {
+  ///
+  /// The EFI UDPv6 Protocol instance handle that is using this address/port pair.
+  ///
+  EFI_HANDLE          InstanceHandle;
+  ///
+  /// The IPv6 address to which this instance of the EFI UDPv6 Protocol is bound.
+  /// Set to 0::/128, if this instance is used to listen all packets from any
+  /// source address.
+  ///
+  EFI_IPv6_ADDRESS    LocalAddress;
+  ///
+  /// The port number in host byte order on which the service is listening.
+  ///
+  UINT16              LocalPort;
+  ///
+  /// The IPv6 address of the remote host. May be 0::/128 if it is not connected
+  /// to any remote host or connected with more than one remote host.
+  ///
+  EFI_IPv6_ADDRESS    RemoteAddress;
+  ///
+  /// The port number in host byte order on which the remote host is
+  /// listening. Maybe zero if it is not connected to any remote host.
+  ///
+  UINT16              RemotePort;
+} EFI_UDP6_SERVICE_POINT;
+
+///
+/// EFI_UDP6_VARIABLE_DATA is deprecated in the UEFI 2.4B and should not be used any more.
+/// The definition in here is only present to provide backwards compatability.
+///
+typedef struct {
+  ///
+  /// The handle of the driver that creates this entry.
+  ///
+  EFI_HANDLE                DriverHandle;
+  ///
+  /// The number of address/port pairs that follow this data structure.
+  ///
+  UINT32                    ServiceCount;
+  ///
+  /// List of address/port pairs that are currently in use.
+  ///
+  EFI_UDP6_SERVICE_POINT    Services[1];
+} EFI_UDP6_VARIABLE_DATA;
+
+typedef struct _EFI_UDP6_PROTOCOL EFI_UDP6_PROTOCOL;
+
+///
+/// EFI_UDP6_FRAGMENT_DATA allows multiple receive or transmit buffers to be specified.
+/// The purpose of this structure is to avoid copying the same packet multiple times.
+///
+typedef struct {
+  UINT32    FragmentLength;      ///< Length of the fragment data buffer.
+  VOID      *FragmentBuffer;     ///< Pointer to the fragment data buffer.
+} EFI_UDP6_FRAGMENT_DATA;
+
+///
+/// The EFI_UDP6_SESSION_DATA is used to retrieve the settings when receiving packets or
+/// to override the existing settings (only DestinationAddress and DestinationPort can
+/// be overridden) of this EFI UDPv6 Protocol instance when sending packets.
+///
+typedef struct {
+  ///
+  /// Address from which this packet is sent. This field should not be used when
+  /// sending packets.
+  ///
+  EFI_IPv6_ADDRESS    SourceAddress;
+  ///
+  /// Port from which this packet is sent. It is in host byte order. This field should
+  /// not be used when sending packets.
+  ///
+  UINT16              SourcePort;
+  ///
+  /// Address to which this packet is sent. When sending packet, it'll be ignored
+  /// if it is zero.
+  ///
+  EFI_IPv6_ADDRESS    DestinationAddress;
+  ///
+  /// Port to which this packet is sent. When sending packet, it'll be
+  /// ignored if it is zero.
+  ///
+  UINT16              DestinationPort;
+} EFI_UDP6_SESSION_DATA;
+
+typedef struct {
+  ///
+  /// Set to TRUE to accept UDP packets that are sent to any address.
+  ///
+  BOOLEAN    AcceptPromiscuous;
+  ///
+  /// Set to TRUE to accept UDP packets that are sent to any port.
+  ///
+  BOOLEAN    AcceptAnyPort;
+  ///
+  /// Set to TRUE to allow this EFI UDPv6 Protocol child instance to open a port number
+  /// that is already being used by another EFI UDPv6 Protocol child instance.
+  ///
+  BOOLEAN    AllowDuplicatePort;
+  ///
+  /// TrafficClass field in transmitted IPv6 packets.
+  ///
+  UINT8      TrafficClass;
+  ///
+  /// HopLimit field in transmitted IPv6 packets.
+  ///
+  UINT8      HopLimit;
+  ///
+  /// The receive timeout value (number of microseconds) to be associated with each
+  /// incoming packet. Zero means do not drop incoming packets.
+  ///
+  UINT32     ReceiveTimeout;
+  ///
+  /// The transmit timeout value (number of microseconds) to be associated with each
+  /// outgoing packet. Zero means do not drop outgoing packets.
+  ///
+  UINT32     TransmitTimeout;
+  ///
+  /// The station IP address that will be assigned to this EFI UDPv6 Protocol instance.
+  /// The EFI UDPv6 and EFI IPv6 Protocol drivers will only deliver incoming packets
+  /// whose destination matches this IP address exactly. Address 0::/128 is also accepted
+  /// as a special case. Under this situation, underlying IPv6 driver is responsible for
+  /// binding a source address to this EFI IPv6 protocol instance according to source
+  /// address selection algorithm. Only incoming packet from the selected source address
+  /// is delivered. This field can be set and changed only when the EFI IPv6 driver is
+  /// transitioning from the stopped to the started states. If no address is available
+  /// for selecting, the EFI IPv6 Protocol driver will use EFI_IP6_CONFIG_PROTOCOL to
+  /// retrieve the IPv6 address.
+  EFI_IPv6_ADDRESS    StationAddress;
+  ///
+  /// The port number to which this EFI UDPv6 Protocol instance is bound. If a client
+  /// of the EFI UDPv6 Protocol does not care about the port number, set StationPort
+  /// to zero. The EFI UDPv6 Protocol driver will assign a random port number to transmitted
+  /// UDP packets. Ignored it if AcceptAnyPort is TRUE.
+  ///
+  UINT16              StationPort;
+  ///
+  /// The IP address of remote host to which this EFI UDPv6 Protocol instance is connecting.
+  /// If RemoteAddress is not 0::/128, this EFI UDPv6 Protocol instance will be connected to
+  /// RemoteAddress; i.e., outgoing packets of this EFI UDPv6 Protocol instance will be sent
+  /// to this address by default and only incoming packets from this address will be delivered
+  /// to client. Ignored for incoming filtering if AcceptPromiscuous is TRUE.
+  EFI_IPv6_ADDRESS    RemoteAddress;
+  ///
+  /// The port number of the remote host to which this EFI UDPv6 Protocol instance is connecting.
+  /// If it is not zero, outgoing packets of this EFI UDPv6 Protocol instance will be sent to
+  /// this port number by default and only incoming packets from this port will be delivered
+  /// to client. Ignored if RemoteAddress is 0::/128 and ignored for incoming filtering if
+  /// AcceptPromiscuous is TRUE.
+  UINT16              RemotePort;
+} EFI_UDP6_CONFIG_DATA;
+
+///
+/// The EFI UDPv6 Protocol client must fill this data structure before sending a packet.
+/// The packet may contain multiple buffers that may be not in a continuous memory location.
+///
+typedef struct {
+  ///
+  /// If not NULL, the data that is used to override the transmitting settings.Only the two
+  /// filed UdpSessionData.DestinationAddress and UdpSessionData.DestionPort can be used as
+  /// the transmitting setting filed.
+  ///
+  EFI_UDP6_SESSION_DATA     *UdpSessionData;
+  ///
+  /// Sum of the fragment data length. Must not exceed the maximum UDP packet size.
+  ///
+  UINT32                    DataLength;
+  ///
+  /// Number of fragments.
+  ///
+  UINT32                    FragmentCount;
+  ///
+  /// Array of fragment descriptors.
+  ///
+  EFI_UDP6_FRAGMENT_DATA    FragmentTable[1];
+} EFI_UDP6_TRANSMIT_DATA;
+
+///
+/// EFI_UDP6_RECEIVE_DATA is filled by the EFI UDPv6 Protocol driver when this EFI UDPv6
+/// Protocol instance receives an incoming packet. If there is a waiting token for incoming
+/// packets, the CompletionToken.Packet.RxData field is updated to this incoming packet and
+/// the CompletionToken.Event is signaled. The EFI UDPv6 Protocol client must signal the
+/// RecycleSignal after processing the packet.
+/// FragmentTable could contain multiple buffers that are not in the continuous memory locations.
+/// The EFI UDPv6 Protocol client might need to combine two or more buffers in FragmentTable to
+/// form their own protocol header.
+///
+typedef struct {
+  ///
+  /// Time when the EFI UDPv6 Protocol accepted the packet.
+  ///
+  EFI_TIME                  TimeStamp;
+  ///
+  /// Indicates the event to signal when the received data has been processed.
+  ///
+  EFI_EVENT                 RecycleSignal;
+  ///
+  /// The UDP session data including SourceAddress, SourcePort, DestinationAddress,
+  /// and DestinationPort.
+  ///
+  EFI_UDP6_SESSION_DATA     UdpSession;
+  ///
+  /// The sum of the fragment data length.
+  ///
+  UINT32                    DataLength;
+  ///
+  /// Number of fragments. Maybe zero.
+  ///
+  UINT32                    FragmentCount;
+  ///
+  /// Array of fragment descriptors. Maybe zero.
+  ///
+  EFI_UDP6_FRAGMENT_DATA    FragmentTable[1];
+} EFI_UDP6_RECEIVE_DATA;
+
+///
+/// The EFI_UDP6_COMPLETION_TOKEN structures are used for both transmit and receive operations.
+/// When used for transmitting, the Event and TxData fields must be filled in by the EFI UDPv6
+/// Protocol client. After the transmit operation completes, the Status field is updated by the
+/// EFI UDPv6 Protocol and the Event is signaled.
+/// When used for receiving, only the Event field must be filled in by the EFI UDPv6 Protocol
+/// client. After a packet is received, RxData and Status are filled in by the EFI UDPv6 Protocol
+/// and the Event is signaled.
+///
+typedef struct {
+  ///
+  /// This Event will be signaled after the Status field is updated by the EFI UDPv6 Protocol
+  /// driver. The type of Event must be EVT_NOTIFY_SIGNAL.
+  ///
+  EFI_EVENT    Event;
+  ///
+  /// Will be set to one of the following values:
+  ///   - EFI_SUCCESS: The receive or transmit operation completed successfully.
+  ///   - EFI_ABORTED: The receive or transmit was aborted.
+  ///   - EFI_TIMEOUT: The transmit timeout expired.
+  ///   - EFI_NETWORK_UNREACHABLE: The destination network is unreachable. RxData is set to
+  ///     NULL in this situation.
+  ///   - EFI_HOST_UNREACHABLE: The destination host is unreachable. RxData is set to NULL in
+  ///     this situation.
+  ///   - EFI_PROTOCOL_UNREACHABLE: The UDP protocol is unsupported in the remote system.
+  ///     RxData is set to NULL in this situation.
+  ///   - EFI_PORT_UNREACHABLE: No service is listening on the remote port. RxData is set to
+  ///     NULL in this situation.
+  ///   - EFI_ICMP_ERROR: Some other Internet Control Message Protocol (ICMP) error report was
+  ///     received. For example, packets are being sent too fast for the destination to receive them
+  ///     and the destination sent an ICMP source quench report. RxData is set to NULL in this situation.
+  ///   - EFI_DEVICE_ERROR: An unexpected system or network error occurred.
+  ///   - EFI_SECURITY_VIOLATION: The transmit or receive was failed because of IPsec policy check.
+  ///   - EFI_NO_MEDIA: There was a media error.
+  ///
+  EFI_STATUS    Status;
+  union {
+    ///
+    /// When this token is used for receiving, RxData is a pointer to EFI_UDP6_RECEIVE_DATA.
+    ///
+    EFI_UDP6_RECEIVE_DATA     *RxData;
+    ///
+    /// When this token is used for transmitting, TxData is a pointer to EFI_UDP6_TRANSMIT_DATA.
+    ///
+    EFI_UDP6_TRANSMIT_DATA    *TxData;
+  } Packet;
+} EFI_UDP6_COMPLETION_TOKEN;
+
+/**
+  Read the current operational settings.
+
+  The GetModeData() function copies the current operational settings of this EFI UDPv6 Protocol
+  instance into user-supplied buffers. This function is used optionally to retrieve the operational
+  mode data of underlying networks or drivers.
+
+  @param[in]   This             Pointer to the EFI_UDP6_PROTOCOL instance.
+  @param[out]  Udp6ConfigData   The buffer in which the current UDP configuration data is returned.
+  @param[out]  Ip6ModeData      The buffer in which the current EFI IPv6 Protocol mode data is returned.
+  @param[out]  MnpConfigData    The buffer in which the current managed network configuration data is
+                                returned.
+  @param[out]  SnpModeData      The buffer in which the simple network mode data is returned.
+
+  @retval EFI_SUCCESS           The mode data was read.
+  @retval EFI_NOT_STARTED       When Udp6ConfigData is queried, no configuration data is available
+                                because this instance has not been started.
+  @retval EFI_INVALID_PARAMETER This is NULL.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_GET_MODE_DATA)(
+  IN EFI_UDP6_PROTOCOL                 *This,
+  OUT EFI_UDP6_CONFIG_DATA             *Udp6ConfigData OPTIONAL,
+  OUT EFI_IP6_MODE_DATA                *Ip6ModeData    OPTIONAL,
+  OUT EFI_MANAGED_NETWORK_CONFIG_DATA  *MnpConfigData  OPTIONAL,
+  OUT EFI_SIMPLE_NETWORK_MODE          *SnpModeData    OPTIONAL
+  );
+
+/**
+  Initializes, changes, or resets the operational parameters for this instance of the EFI UDPv6
+  Protocol.
+
+  The Configure() function is used to do the following:
+  - Initialize and start this instance of the EFI UDPv6 Protocol.
+  - Change the filtering rules and operational parameters.
+  - Reset this instance of the EFI UDPv6 Protocol.
+
+  Until these parameters are initialized, no network traffic can be sent or received by this instance.
+  This instance can be also reset by calling Configure() with UdpConfigData set to NULL.
+  Once reset, the receiving queue and transmitting queue are flushed and no traffic is allowed through
+  this instance.
+
+  With different parameters in UdpConfigData, Configure() can be used to bind this instance to specified
+  port.
+
+  @param[in]   This             Pointer to the EFI_UDP6_PROTOCOL instance.
+  @param[in]   UdpConfigData    Pointer to the buffer contained the configuration data.
+
+  @retval EFI_SUCCESS           The configuration settings were set, changed, or reset successfully.
+  @retval EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
+                                address for this instance, but no source address was available for use.
+  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:
+                                - This is NULL.
+                                - UdpConfigData.StationAddress neither zero nor one of the configured IP
+                                  addresses in the underlying IPv6 driver.
+                                - UdpConfigData.RemoteAddress is not a valid unicast IPv6 address if it
+                                  is not zero.
+  @retval EFI_ALREADY_STARTED   The EFI UDPv6 Protocol instance is already started/configured and must be
+                                stopped/reset before it can be reconfigured. Only TrafficClass, HopLimit,
+                                ReceiveTimeout, and TransmitTimeout can be reconfigured without stopping
+                                the current instance of the EFI UDPv6 Protocol.
+  @retval EFI_ACCESS_DENIED     UdpConfigData.AllowDuplicatePort is FALSE and UdpConfigData.StationPort
+                                is already used by other instance.
+  @retval EFI_OUT_OF_RESOURCES  The EFI UDPv6 Protocol driver cannot allocate memory for this EFI UDPv6
+                                Protocol instance.
+  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred and this instance was not
+                                opened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_CONFIGURE)(
+  IN EFI_UDP6_PROTOCOL     *This,
+  IN EFI_UDP6_CONFIG_DATA  *UdpConfigData OPTIONAL
+  );
+
+/**
+  Joins and leaves multicast groups.
+
+  The Groups() function is used to join or leave one or more multicast group.
+  If the JoinFlag is FALSE and the MulticastAddress is NULL, then all currently joined groups are left.
+
+  @param[in]   This             Pointer to the EFI_UDP6_PROTOCOL instance.
+  @param[in]   JoinFlag         Set to TRUE to join a multicast group. Set to FALSE to leave one
+                                or all multicast groups.
+  @param[in]   MulticastAddress Pointer to multicast group address to join or leave.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_STARTED       The EFI UDPv6 Protocol instance has not been started.
+  @retval EFI_OUT_OF_RESOURCES  Could not allocate resources to join the group.
+  @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+                                - This is NULL.
+                                - JoinFlag is TRUE and MulticastAddress is NULL.
+                                - JoinFlag is TRUE and *MulticastAddress is not a valid multicast address.
+  @retval EFI_ALREADY_STARTED   The group address is already in the group table (when JoinFlag is TRUE).
+  @retval EFI_NOT_FOUND         The group address is not in the group table (when JoinFlag is FALSE).
+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_GROUPS)(
+  IN EFI_UDP6_PROTOCOL  *This,
+  IN BOOLEAN            JoinFlag,
+  IN EFI_IPv6_ADDRESS   *MulticastAddress OPTIONAL
+  );
+
+/**
+  Queues outgoing data packets into the transmit queue.
+
+  The Transmit() function places a sending request to this instance of the EFI UDPv6 Protocol,
+  alongside the transmit data that was filled by the user. Whenever the packet in the token is
+  sent out or some errors occur, the Token.Event will be signaled and Token.Status is updated.
+  Providing a proper notification function and context for the event will enable the user to
+  receive the notification and transmitting status.
+
+  @param[in]   This             Pointer to the EFI_UDP6_PROTOCOL instance.
+  @param[in]   Token            Pointer to the completion token that will be placed into the
+                                transmit queue.
+
+  @retval EFI_SUCCESS           The data has been queued for transmission.
+  @retval EFI_NOT_STARTED       This EFI UDPv6 Protocol instance has not been started.
+  @retval EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
+                                address for this instance, but no source address was available
+                                for use.
+  @retval EFI_INVALID_PARAMETER One or more of the following are TRUE:
+                                - This is NULL.
+                                - Token is NULL.
+                                - Token.Event is NULL.
+                                - Token.Packet.TxData is NULL.
+                                - Token.Packet.TxData.FragmentCount is zero.
+                                - Token.Packet.TxData.DataLength is not equal to the sum of fragment
+                                  lengths.
+                                - One or more of the Token.Packet.TxData.FragmentTable[].FragmentLength
+                                  fields is zero.
+                                - One or more of the Token.Packet.TxData.FragmentTable[].FragmentBuffer
+                                  fields is NULL.
+                                - Token.Packet.TxData.UdpSessionData.DestinationAddress is not zero
+                                  and is not valid unicast Ipv6 address if UdpSessionData is not NULL.
+                                - Token.Packet.TxData.UdpSessionData is NULL and this instance's
+                                  UdpConfigData.RemoteAddress is unspecified.
+                                - Token.Packet.TxData.UdpSessionData.DestinationAddress is non-zero
+                                  when DestinationAddress is configured as non-zero when doing Configure()
+                                  for this EFI Udp6 protocol instance.
+                                - Token.Packet.TxData.UdpSesionData.DestinationAddress is zero when
+                                  DestinationAddress is unspecified when doing Configure() for this
+                                  EFI Udp6 protocol instance.
+  @retval EFI_ACCESS_DENIED     The transmit completion token with the same Token.Event was already
+                                in the transmit queue.
+  @retval EFI_NOT_READY         The completion token could not be queued because the transmit queue
+                                is full.
+  @retval EFI_OUT_OF_RESOURCES  Could not queue the transmit data.
+  @retval EFI_NOT_FOUND         There is no route to the destination network or address.
+  @retval EFI_BAD_BUFFER_SIZE   The data length is greater than the maximum UDP packet size.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_TRANSMIT)(
+  IN EFI_UDP6_PROTOCOL          *This,
+  IN EFI_UDP6_COMPLETION_TOKEN  *Token
+  );
+
+/**
+  Places an asynchronous receive request into the receiving queue.
+
+  The Receive() function places a completion token into the receive packet queue. This function is
+  always asynchronous.
+  The caller must fill in the Token.Event field in the completion token, and this field cannot be
+  NULL. When the receive operation completes, the EFI UDPv6 Protocol driver updates the Token.Status
+  and Token.Packet.RxData fields and the Token.Event is signaled.
+  Providing a proper notification function and context for the event will enable the user to receive
+  the notification and receiving status. That notification function is guaranteed to not be re-entered.
+
+  @param[in]   This             Pointer to the EFI_UDP6_PROTOCOL instance.
+  @param[in]   Token            Pointer to a token that is associated with the receive data descriptor.
+
+  @retval EFI_SUCCESS           The receive completion token was cached.
+  @retval EFI_NOT_STARTED       This EFI UDPv6 Protocol instance has not been started.
+  @retval EFI_NO_MAPPING        The underlying IPv6 driver was responsible for choosing a source
+                                address for this instance, but no source address was available
+                                for use.
+  @retval EFI_INVALID_PARAMETER One or more of the following is TRUE:
+                                - This is NULL.
+                                - Token is NULL.
+                                - Token.Event is NULL.
+  @retval EFI_OUT_OF_RESOURCES  The receive completion token could not be queued due to a lack of system
+                                resources (usually memory).
+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred. The EFI UDPv6 Protocol
+                                instance has been reset to startup defaults.
+  @retval EFI_ACCESS_DENIED     A receive completion token with the same Token.Event was already in
+                                the receive queue.
+  @retval EFI_NOT_READY         The receive request could not be queued because the receive queue is full.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_RECEIVE)(
+  IN EFI_UDP6_PROTOCOL          *This,
+  IN EFI_UDP6_COMPLETION_TOKEN  *Token
+  );
+
+/**
+  Aborts an asynchronous transmit or receive request.
+
+  The Cancel() function is used to abort a pending transmit or receive request. If the token is in the
+  transmit or receive request queues, after calling this function, Token.Status will be set to
+  EFI_ABORTED and then Token.Event will be signaled. If the token is not in one of the queues,
+  which usually means that the asynchronous operation has completed, this function will not signal the
+  token and EFI_NOT_FOUND is returned.
+
+  @param[in]   This             Pointer to the EFI_UDP6_PROTOCOL instance.
+  @param[in]   Token            Pointer to a token that has been issued by EFI_UDP6_PROTOCOL.Transmit()
+                                or EFI_UDP6_PROTOCOL.Receive().If NULL, all pending tokens are aborted.
+
+  @retval EFI_SUCCESS           The asynchronous I/O request was aborted and Token.Event was signaled.
+                                When Token is NULL, all pending requests are aborted and their events
+                                are signaled.
+  @retval EFI_INVALID_PARAMETER This is NULL.
+  @retval EFI_NOT_STARTED       This instance has not been started.
+  @retval EFI_NOT_FOUND         When Token is not NULL, the asynchronous I/O request was not found in
+                                the transmit or receive queue. It has either completed or was not issued
+                                by Transmit() and Receive().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_CANCEL)(
+  IN EFI_UDP6_PROTOCOL          *This,
+  IN EFI_UDP6_COMPLETION_TOKEN  *Token OPTIONAL
+  );
+
+/**
+  Polls for incoming data packets and processes outgoing data packets.
+
+  The Poll() function can be used by network drivers and applications to increase the rate that data
+  packets are moved between the communications device and the transmit and receive queues.
+  In some systems, the periodic timer event in the managed network driver may not poll the underlying
+  communications device fast enough to transmit and/or receive all data packets without missing incoming
+  packets or dropping outgoing packets. Drivers and applications that are experiencing packet loss should
+  try calling the Poll() function more often.
+
+  @param[in]   This             Pointer to the EFI_UDP6_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           Incoming or outgoing data was processed.
+  @retval EFI_INVALID_PARAMETER This is NULL.
+  @retval EFI_DEVICE_ERROR      An unexpected system or network error occurred.
+  @retval EFI_TIMEOUT           Data was dropped out of the transmit and/or receive queue.
+                                Consider increasing the polling rate.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_UDP6_POLL)(
+  IN EFI_UDP6_PROTOCOL  *This
+  );
+
+///
+/// The EFI_UDP6_PROTOCOL defines an EFI UDPv6 Protocol session that can be used by any network drivers,
+/// applications, or daemons to transmit or receive UDP packets. This protocol instance can either be
+/// bound to a specified port as a service or connected to some remote peer as an active client.
+/// Each instance has its own settings, such as group table, that are independent from each other.
+///
+struct _EFI_UDP6_PROTOCOL {
+  EFI_UDP6_GET_MODE_DATA    GetModeData;
+  EFI_UDP6_CONFIGURE        Configure;
+  EFI_UDP6_GROUPS           Groups;
+  EFI_UDP6_TRANSMIT         Transmit;
+  EFI_UDP6_RECEIVE          Receive;
+  EFI_UDP6_CANCEL           Cancel;
+  EFI_UDP6_POLL             Poll;
+};
+
+extern EFI_GUID  gEfiUdp6ServiceBindingProtocolGuid;
+extern EFI_GUID  gEfiUdp6ProtocolGuid;
+
+#endif
index 29117fa356e5206aa2386de0a2ee22c6c300db8f..0d90fbb7960684e52c76a5f1ac309b8cc6e95bf5 100644 (file)
@@ -184,6 +184,8 @@ extern EFI_GUID efi_console_control_protocol_guid;
 extern EFI_GUID efi_device_path_protocol_guid;
 extern EFI_GUID efi_dhcp4_protocol_guid;
 extern EFI_GUID efi_dhcp4_service_binding_protocol_guid;
+extern EFI_GUID efi_dhcp6_protocol_guid;
+extern EFI_GUID efi_dhcp6_service_binding_protocol_guid;
 extern EFI_GUID efi_disk_io_protocol_guid;
 extern EFI_GUID efi_driver_binding_protocol_guid;
 extern EFI_GUID efi_graphics_output_protocol_guid;
@@ -192,6 +194,9 @@ extern EFI_GUID efi_hii_font_protocol_guid;
 extern EFI_GUID efi_ip4_protocol_guid;
 extern EFI_GUID efi_ip4_config_protocol_guid;
 extern EFI_GUID efi_ip4_service_binding_protocol_guid;
+extern EFI_GUID efi_ip6_protocol_guid;
+extern EFI_GUID efi_ip6_config_protocol_guid;
+extern EFI_GUID efi_ip6_service_binding_protocol_guid;
 extern EFI_GUID efi_load_file_protocol_guid;
 extern EFI_GUID efi_load_file2_protocol_guid;
 extern EFI_GUID efi_loaded_image_protocol_guid;
@@ -200,6 +205,8 @@ extern EFI_GUID efi_managed_network_protocol_guid;
 extern EFI_GUID efi_managed_network_service_binding_protocol_guid;
 extern EFI_GUID efi_mtftp4_protocol_guid;
 extern EFI_GUID efi_mtftp4_service_binding_protocol_guid;
+extern EFI_GUID efi_mtftp6_protocol_guid;
+extern EFI_GUID efi_mtftp6_service_binding_protocol_guid;
 extern EFI_GUID efi_nii_protocol_guid;
 extern EFI_GUID efi_nii31_protocol_guid;
 extern EFI_GUID efi_pci_io_protocol_guid;
@@ -216,9 +223,13 @@ extern EFI_GUID efi_simple_text_output_protocol_guid;
 extern EFI_GUID efi_tcg_protocol_guid;
 extern EFI_GUID efi_tcp4_protocol_guid;
 extern EFI_GUID efi_tcp4_service_binding_protocol_guid;
+extern EFI_GUID efi_tcp6_protocol_guid;
+extern EFI_GUID efi_tcp6_service_binding_protocol_guid;
 extern EFI_GUID efi_tree_protocol_guid;
 extern EFI_GUID efi_udp4_protocol_guid;
 extern EFI_GUID efi_udp4_service_binding_protocol_guid;
+extern EFI_GUID efi_udp6_protocol_guid;
+extern EFI_GUID efi_udp6_service_binding_protocol_guid;
 extern EFI_GUID efi_uga_draw_protocol_guid;
 extern EFI_GUID efi_unicode_collation_protocol_guid;
 extern EFI_GUID efi_usb_hc_protocol_guid;
index 02cbf9fa4f1569e2663b55851347d2b43e2465e7..8922fa2a54f8924fa07a265268296dc1c2aadc68 100644 (file)
@@ -99,6 +99,10 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
          "Dhcp4" },
        { &efi_dhcp4_service_binding_protocol_guid,
          "Dhcp4Sb" },
+       { &efi_dhcp6_protocol_guid,
+         "Dhcp6" },
+       { &efi_dhcp6_service_binding_protocol_guid,
+         "Dhcp6Sb" },
        { &efi_disk_io_protocol_guid,
          "DiskIo" },
        { &efi_graphics_output_protocol_guid,
@@ -113,6 +117,12 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
          "Ip4Config" },
        { &efi_ip4_service_binding_protocol_guid,
          "Ip4Sb" },
+       { &efi_ip6_protocol_guid,
+         "Ip6" },
+       { &efi_ip6_config_protocol_guid,
+         "Ip6Config" },
+       { &efi_ip6_service_binding_protocol_guid,
+         "Ip6Sb" },
        { &efi_iscsi4_dxe_guid,
          "IScsi4Dxe" },
        { &efi_load_file_protocol_guid,
@@ -131,6 +141,10 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
          "Mtftp4" },
        { &efi_mtftp4_service_binding_protocol_guid,
          "Mtftp4Sb" },
+       { &efi_mtftp6_protocol_guid,
+         "Mtftp6" },
+       { &efi_mtftp6_service_binding_protocol_guid,
+         "Mtftp6Sb" },
        { &efi_nii_protocol_guid,
          "Nii" },
        { &efi_nii31_protocol_guid,
@@ -163,12 +177,20 @@ static struct efi_well_known_guid efi_well_known_guids[] = {
          "Tcp4" },
        { &efi_tcp4_service_binding_protocol_guid,
          "Tcp4Sb" },
+       { &efi_tcp6_protocol_guid,
+         "Tcp6" },
+       { &efi_tcp6_service_binding_protocol_guid,
+         "Tcp6Sb" },
        { &efi_tree_protocol_guid,
          "TrEE" },
        { &efi_udp4_protocol_guid,
          "Udp4" },
        { &efi_udp4_service_binding_protocol_guid,
          "Udp4Sb" },
+       { &efi_udp6_protocol_guid,
+         "Udp6" },
+       { &efi_udp6_service_binding_protocol_guid,
+         "Udp6Sb" },
        { &efi_uga_draw_protocol_guid,
          "UgaDraw" },
        { &efi_unicode_collation_protocol_guid,
index 25c342ffb70fc48f4b3dc6b0388f7eea514f150a..b9f8e155085fa848e04ac08ce1b326bdd5989ed7 100644 (file)
@@ -37,6 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/Protocol/DevicePath.h>
 #include <ipxe/efi/Protocol/DevicePathToText.h>
 #include <ipxe/efi/Protocol/Dhcp4.h>
+#include <ipxe/efi/Protocol/Dhcp6.h>
 #include <ipxe/efi/Protocol/DiskIo.h>
 #include <ipxe/efi/Protocol/DriverBinding.h>
 #include <ipxe/efi/Protocol/GraphicsOutput.h>
@@ -44,11 +45,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/Protocol/HiiFont.h>
 #include <ipxe/efi/Protocol/Ip4.h>
 #include <ipxe/efi/Protocol/Ip4Config.h>
+#include <ipxe/efi/Protocol/Ip6.h>
+#include <ipxe/efi/Protocol/Ip6Config.h>
 #include <ipxe/efi/Protocol/LoadFile.h>
 #include <ipxe/efi/Protocol/LoadFile2.h>
 #include <ipxe/efi/Protocol/LoadedImage.h>
 #include <ipxe/efi/Protocol/ManagedNetwork.h>
 #include <ipxe/efi/Protocol/Mtftp4.h>
+#include <ipxe/efi/Protocol/Mtftp6.h>
 #include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
 #include <ipxe/efi/Protocol/PciIo.h>
 #include <ipxe/efi/Protocol/PciRootBridgeIo.h>
@@ -63,7 +67,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #include <ipxe/efi/Protocol/SimpleTextOut.h>
 #include <ipxe/efi/Protocol/TcgService.h>
 #include <ipxe/efi/Protocol/Tcp4.h>
+#include <ipxe/efi/Protocol/Tcp6.h>
 #include <ipxe/efi/Protocol/Udp4.h>
+#include <ipxe/efi/Protocol/Udp6.h>
 #include <ipxe/efi/Protocol/UgaDraw.h>
 #include <ipxe/efi/Protocol/UnicodeCollation.h>
 #include <ipxe/efi/Protocol/UsbHostController.h>
@@ -140,6 +146,14 @@ EFI_GUID efi_dhcp4_protocol_guid
 EFI_GUID efi_dhcp4_service_binding_protocol_guid
        = EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID;
 
+/** DHCPv6 protocol GUID */
+EFI_GUID efi_dhcp6_protocol_guid
+       = EFI_DHCP6_PROTOCOL_GUID;
+
+/** DHCPv6 service binding protocol GUID */
+EFI_GUID efi_dhcp6_service_binding_protocol_guid
+       = EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID;
+
 /** Disk I/O protocol GUID */
 EFI_GUID efi_disk_io_protocol_guid
        = EFI_DISK_IO_PROTOCOL_GUID;
@@ -172,6 +186,18 @@ EFI_GUID efi_ip4_config_protocol_guid
 EFI_GUID efi_ip4_service_binding_protocol_guid
        = EFI_IP4_SERVICE_BINDING_PROTOCOL_GUID;
 
+/** IPv6 protocol GUID */
+EFI_GUID efi_ip6_protocol_guid
+       = EFI_IP6_PROTOCOL_GUID;
+
+/** IPv6 configuration protocol GUID */
+EFI_GUID efi_ip6_config_protocol_guid
+       = EFI_IP6_CONFIG_PROTOCOL_GUID;
+
+/** IPv6 service binding protocol GUID */
+EFI_GUID efi_ip6_service_binding_protocol_guid
+       = EFI_IP6_SERVICE_BINDING_PROTOCOL_GUID;
+
 /** Load file protocol GUID */
 EFI_GUID efi_load_file_protocol_guid
        = EFI_LOAD_FILE_PROTOCOL_GUID;
@@ -204,6 +230,14 @@ EFI_GUID efi_mtftp4_protocol_guid
 EFI_GUID efi_mtftp4_service_binding_protocol_guid
        = EFI_MTFTP4_SERVICE_BINDING_PROTOCOL_GUID;
 
+/** MTFTPv6 protocol GUID */
+EFI_GUID efi_mtftp6_protocol_guid
+       = EFI_MTFTP6_PROTOCOL_GUID;
+
+/** MTFTPv6 service binding protocol GUID */
+EFI_GUID efi_mtftp6_service_binding_protocol_guid
+       = EFI_MTFTP6_SERVICE_BINDING_PROTOCOL_GUID;
+
 /** Network interface identifier protocol GUID (old version) */
 EFI_GUID efi_nii_protocol_guid
        = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_GUID;
@@ -268,6 +302,14 @@ EFI_GUID efi_tcp4_protocol_guid
 EFI_GUID efi_tcp4_service_binding_protocol_guid
        = EFI_TCP4_SERVICE_BINDING_PROTOCOL_GUID;
 
+/** TCPv6 protocol GUID */
+EFI_GUID efi_tcp6_protocol_guid
+       = EFI_TCP6_PROTOCOL_GUID;
+
+/** TCPv6 service binding protocol GUID */
+EFI_GUID efi_tcp6_service_binding_protocol_guid
+       = EFI_TCP6_SERVICE_BINDING_PROTOCOL_GUID;
+
 /** TrEE protocol GUID */
 EFI_GUID efi_tree_protocol_guid
        = EFI_TREE_PROTOCOL_GUID;
@@ -280,6 +322,14 @@ EFI_GUID efi_udp4_protocol_guid
 EFI_GUID efi_udp4_service_binding_protocol_guid
        = EFI_UDP4_SERVICE_BINDING_PROTOCOL_GUID;
 
+/** UDPv6 protocol GUID */
+EFI_GUID efi_udp6_protocol_guid
+       = EFI_UDP6_PROTOCOL_GUID;
+
+/** UDPv6 service binding protocol GUID */
+EFI_GUID efi_udp6_service_binding_protocol_guid
+       = EFI_UDP6_SERVICE_BINDING_PROTOCOL_GUID;
+
 /** UGA draw protocol GUID */
 EFI_GUID efi_uga_draw_protocol_guid
        = EFI_UGA_DRAW_PROTOCOL_GUID;