From d33896d88d9d32d516129e92e25b80f8fddc6f7b Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Wed, 25 Apr 2018 17:23:25 +0800 Subject: Remove Core Package Remove Core Package since we will use EDK2 code from edk2 repository: https://github.com/tianocore/edk2 Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Guo Mang --- Core/NetworkPkg/Ip6Dxe/ComponentName.c | 474 ----- Core/NetworkPkg/Ip6Dxe/Ip6Common.c | 673 ------- Core/NetworkPkg/Ip6Dxe/Ip6Common.h | 318 --- Core/NetworkPkg/Ip6Dxe/Ip6Config.vfr | 178 -- Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c | 2386 ---------------------- Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.h | 313 --- Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.c | 2095 -------------------- Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.h | 68 - Core/NetworkPkg/Ip6Dxe/Ip6Driver.c | 1026 ---------- Core/NetworkPkg/Ip6Dxe/Ip6Driver.h | 192 -- Core/NetworkPkg/Ip6Dxe/Ip6Dxe.inf | 116 -- Core/NetworkPkg/Ip6Dxe/Ip6Dxe.uni | 26 - Core/NetworkPkg/Ip6Dxe/Ip6DxeExtra.uni | 20 - Core/NetworkPkg/Ip6Dxe/Ip6DxeStrings.uni | 61 - Core/NetworkPkg/Ip6Dxe/Ip6Icmp.c | 685 ------- Core/NetworkPkg/Ip6Dxe/Ip6Icmp.h | 108 - Core/NetworkPkg/Ip6Dxe/Ip6If.c | 798 -------- Core/NetworkPkg/Ip6Dxe/Ip6If.h | 267 --- Core/NetworkPkg/Ip6Dxe/Ip6Impl.c | 1847 ----------------- Core/NetworkPkg/Ip6Dxe/Ip6Impl.h | 754 ------- Core/NetworkPkg/Ip6Dxe/Ip6Input.c | 1831 ----------------- Core/NetworkPkg/Ip6Dxe/Ip6Input.h | 235 --- Core/NetworkPkg/Ip6Dxe/Ip6Mld.c | 908 --------- Core/NetworkPkg/Ip6Dxe/Ip6Mld.h | 198 -- Core/NetworkPkg/Ip6Dxe/Ip6Nd.c | 3155 ------------------------------ Core/NetworkPkg/Ip6Dxe/Ip6Nd.h | 749 ------- Core/NetworkPkg/Ip6Dxe/Ip6NvData.h | 69 - Core/NetworkPkg/Ip6Dxe/Ip6Option.c | 758 ------- Core/NetworkPkg/Ip6Dxe/Ip6Option.h | 191 -- Core/NetworkPkg/Ip6Dxe/Ip6Output.c | 1091 ----------- Core/NetworkPkg/Ip6Dxe/Ip6Output.h | 141 -- Core/NetworkPkg/Ip6Dxe/Ip6Route.c | 635 ------ Core/NetworkPkg/Ip6Dxe/Ip6Route.h | 299 --- 33 files changed, 22665 deletions(-) delete mode 100644 Core/NetworkPkg/Ip6Dxe/ComponentName.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Common.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Common.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Config.vfr delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Driver.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Driver.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Dxe.inf delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Dxe.uni delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6DxeExtra.uni delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6DxeStrings.uni delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Icmp.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Icmp.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6If.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6If.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Impl.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Impl.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Input.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Input.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Mld.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Mld.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Nd.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Nd.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6NvData.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Option.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Option.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Output.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Output.h delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Route.c delete mode 100644 Core/NetworkPkg/Ip6Dxe/Ip6Route.h (limited to 'Core/NetworkPkg/Ip6Dxe') diff --git a/Core/NetworkPkg/Ip6Dxe/ComponentName.c b/Core/NetworkPkg/Ip6Dxe/ComponentName.c deleted file mode 100644 index 6a1f082edd..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/ComponentName.c +++ /dev/null @@ -1,474 +0,0 @@ -/** @file - Implementation of EFI_COMPONENT_NAME_PROTOCOL and - EFI_COMPONENT_NAME2_PROTOCOL protocol. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -// -// EFI Component Name Functions -// - -/** - Retrieves a Unicode string that is the user-readable name of the driver. - - This function retrieves the user-readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user-readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param[in] Language A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param[out] DriverName A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -Ip6ComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ); - -/** - Retrieves a Unicode string that is the user-readable name of the controller - that is managed by a driver. - - This function retrieves the user-readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user-readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param[in] ControllerHandle The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param[in] ChildHandle The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param[in] Language A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param[out] ControllerName A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user-readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -Ip6ComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ); - -// -// EFI Component Name Protocol. -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gIp6ComponentName = { - Ip6ComponentNameGetDriverName, - Ip6ComponentNameGetControllerName, - "eng" -}; - -// -// EFI Component Name 2 Protocol. -// -GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gIp6ComponentName2 = { - (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) Ip6ComponentNameGetDriverName, - (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) Ip6ComponentNameGetControllerName, - "en" -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mIp6DriverNameTable[] = { - { - "eng;en", - L"IP6 Network Service Driver" - }, - { - NULL, - NULL - } -}; - -GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable = NULL; - -/** - Retrieves a Unicode string that is the user-readable name of the driver. - - This function retrieves the user-readable name of a driver in the form of a - Unicode string. If the driver specified by This has a user-readable name in - the language specified by Language, then a pointer to the driver name is - returned in DriverName, and EFI_SUCCESS is returned. If the driver specified - by This does not support the language specified by Language, - then EFI_UNSUPPORTED is returned. - - @param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param[in] Language A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified - in RFC 4646 or ISO 639-2 language code format. - - @param[out] DriverName A pointer to the Unicode string to return. - This Unicode string is the name of the - driver specified by This in the language - specified by Language. - - @retval EFI_SUCCESS The Unicode string for the Driver specified by - This and the language specified by Language was - returned in DriverName. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER DriverName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -Ip6ComponentNameGetDriverName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN CHAR8 *Language, - OUT CHAR16 **DriverName - ) -{ - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - mIp6DriverNameTable, - DriverName, - (BOOLEAN) (This == &gIp6ComponentName) - ); - -} - -/** - Update the component name for the IP6 child handle. - - @param Ip6[in] A pointer to the EFI_IP6_PROTOCOL. - - - @retval EFI_SUCCESS Update the ControllerNameTable of this instance successfully. - @retval EFI_INVALID_PARAMETER The input parameter is invalid. - -**/ -EFI_STATUS -UpdateName ( - IN EFI_IP6_PROTOCOL *Ip6 - ) -{ - EFI_STATUS Status; - CHAR16 HandleName[128]; - EFI_IP6_MODE_DATA Ip6ModeData; - UINTN Offset; - CHAR16 Address[sizeof"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"]; - - if (Ip6 == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Format the child name into the string buffer. - // - Offset = 0; - Status = Ip6->GetModeData (Ip6, &Ip6ModeData, NULL, NULL); - if (!EFI_ERROR (Status)) { - if (Ip6ModeData.AddressList != NULL) { - FreePool (Ip6ModeData.AddressList); - } - - if (Ip6ModeData.GroupTable != NULL) { - FreePool (Ip6ModeData.GroupTable); - } - - if (Ip6ModeData.RouteTable != NULL) { - FreePool (Ip6ModeData.RouteTable); - } - - if (Ip6ModeData.NeighborCache != NULL) { - FreePool (Ip6ModeData.NeighborCache); - } - - if (Ip6ModeData.PrefixTable != NULL) { - FreePool (Ip6ModeData.PrefixTable); - } - - if (Ip6ModeData.IcmpTypeList != NULL) { - FreePool (Ip6ModeData.IcmpTypeList); - } - } - - if (!EFI_ERROR (Status) && Ip6ModeData.IsStarted) { - Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.StationAddress, Address, sizeof(Address)); - if (EFI_ERROR (Status)) { - return Status; - } - Offset += UnicodeSPrint ( - HandleName, - sizeof(HandleName), - L"IPv6(StationAddress=%s, ", - Address - ); - Status = NetLibIp6ToStr (&Ip6ModeData.ConfigData.DestinationAddress, Address, sizeof(Address)); - if (EFI_ERROR (Status)) { - return Status; - } - UnicodeSPrint ( - HandleName + Offset, - sizeof(HandleName) - Offset * sizeof (CHAR16), - L"DestinationAddress=%s)", - Address - ); - } else if (!Ip6ModeData.IsStarted) { - UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(Not started)"); - } else { - UnicodeSPrint (HandleName, sizeof(HandleName), L"IPv6(%r)", Status); - } - - if (gIp6ControllerNameTable != NULL) { - FreeUnicodeStringTable (gIp6ControllerNameTable); - gIp6ControllerNameTable = NULL; - } - - Status = AddUnicodeString2 ( - "eng", - gIp6ComponentName.SupportedLanguages, - &gIp6ControllerNameTable, - HandleName, - TRUE - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return AddUnicodeString2 ( - "en", - gIp6ComponentName2.SupportedLanguages, - &gIp6ControllerNameTable, - HandleName, - FALSE - ); -} - -/** - Retrieves a Unicode string that is the user-readable name of the controller - that is being managed by a driver. - - This function retrieves the user-readable name of the controller specified by - ControllerHandle and ChildHandle in the form of a Unicode string. If the - driver specified by This has a user-readable name in the language specified by - Language, then a pointer to the controller name is returned in ControllerName, - and EFI_SUCCESS is returned. If the driver specified by This is not currently - managing the controller specified by ControllerHandle and ChildHandle, - then EFI_UNSUPPORTED is returned. If the driver specified by This does not - support the language specified by Language, then EFI_UNSUPPORTED is returned. - - @param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or - EFI_COMPONENT_NAME_PROTOCOL instance. - - @param[in] ControllerHandle The handle of a controller that the driver - specified by This is managing. This handle - specifies the controller whose name is to be - returned. - - @param[in] ChildHandle The handle of the child controller to retrieve - the name of. This is an optional parameter that - may be NULL. It will be NULL for device - drivers. It will also be NULL for a bus drivers - that wish to retrieve the name of the bus - controller. It will not be NULL for a bus - driver that wishes to retrieve the name of a - child controller. - - @param[in] Language A pointer to a Null-terminated ASCII string - array indicating the language. This is the - language of the driver name that the caller is - requesting, and it must match one of the - languages specified in SupportedLanguages. The - number of languages supported by a driver is up - to the driver writer. Language is specified in - RFC 4646 or ISO 639-2 language code format. - - @param[out] ControllerName A pointer to the Unicode string to return. - This Unicode string is the name of the - controller specified by ControllerHandle and - ChildHandle in the language specified by - Language from the point of view of the driver - specified by This. - - @retval EFI_SUCCESS The Unicode string for the user-readable name in - the language specified by Language for the - driver specified by This was returned in - DriverName. - - @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. - - @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it is not a valid - EFI_HANDLE. - - @retval EFI_INVALID_PARAMETER Language is NULL. - - @retval EFI_INVALID_PARAMETER ControllerName is NULL. - - @retval EFI_UNSUPPORTED The driver specified by This is not currently - managing the controller specified by - ControllerHandle and ChildHandle. - - @retval EFI_UNSUPPORTED The driver specified by This does not support - the language specified by Language. - -**/ -EFI_STATUS -EFIAPI -Ip6ComponentNameGetControllerName ( - IN EFI_COMPONENT_NAME_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_HANDLE ChildHandle OPTIONAL, - IN CHAR8 *Language, - OUT CHAR16 **ControllerName - ) -{ - EFI_STATUS Status; - EFI_IP6_PROTOCOL *Ip6; - - // - // Only provide names for child handles. - // - if (ChildHandle == NULL) { - return EFI_UNSUPPORTED; - } - - // - // Make sure this driver produced ChildHandle - // - Status = EfiTestChildHandle ( - ControllerHandle, - ChildHandle, - &gEfiManagedNetworkProtocolGuid - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Retrieve an instance of a produced protocol from ChildHandle - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiIp6ProtocolGuid, - (VOID **)&Ip6, - NULL, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Update the component name for this child handle. - // - Status = UpdateName (Ip6); - if (EFI_ERROR (Status)) { - return Status; - } - - return LookupUnicodeString2 ( - Language, - This->SupportedLanguages, - gIp6ControllerNameTable, - ControllerName, - (BOOLEAN)(This == &gIp6ComponentName) - ); -} diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Common.c b/Core/NetworkPkg/Ip6Dxe/Ip6Common.c deleted file mode 100644 index 7007301f81..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Common.c +++ /dev/null @@ -1,673 +0,0 @@ -/** @file - The implementation of common functions shared by IP6 driver. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -/** - Build a array of EFI_IP6_ADDRESS_INFO to be returned to the caller. The number - of EFI_IP6_ADDRESS_INFO is also returned. If AddressList is NULL, - only the address count is returned. - - @param[in] IpSb The IP6 service binding instance. - @param[out] AddressCount The number of returned addresses. - @param[out] AddressList The pointer to the array of EFI_IP6_ADDRESS_INFO. - This is an optional parameter. - - - @retval EFI_SUCCESS The address array successfully built. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the address info. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - -**/ -EFI_STATUS -Ip6BuildEfiAddressList ( - IN IP6_SERVICE *IpSb, - OUT UINT32 *AddressCount, - OUT EFI_IP6_ADDRESS_INFO **AddressList OPTIONAL - ) -{ - UINT32 Count; - LIST_ENTRY *Entry; - EFI_IP6_ADDRESS_INFO *EfiAddrInfo; - IP6_ADDRESS_INFO *AddrInfo; - - if (AddressCount == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (IpSb->LinkLocalOk) { - Count = 1 + IpSb->DefaultInterface->AddressCount; - } else { - Count = 0; - } - - *AddressCount = Count; - - if ((AddressList == NULL) || (Count == 0)) { - return EFI_SUCCESS; - } - - if (*AddressList == NULL) { - *AddressList = AllocatePool (sizeof (EFI_IP6_ADDRESS_INFO) * Count); - if (*AddressList == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - EfiAddrInfo = *AddressList; - - IP6_COPY_ADDRESS (&EfiAddrInfo->Address, &IpSb->LinkLocalAddr); - EfiAddrInfo->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH; - - EfiAddrInfo++; - Count = 1; - - NET_LIST_FOR_EACH (Entry, &IpSb->DefaultInterface->AddressList) { - AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE); - - IP6_COPY_ADDRESS (&EfiAddrInfo->Address, &AddrInfo->Address); - EfiAddrInfo->PrefixLength = AddrInfo->PrefixLength; - - EfiAddrInfo++; - Count++; - } - - ASSERT (Count == *AddressCount); - - return EFI_SUCCESS; -} - -/** - Generate the multicast addresses identify the group of all IPv6 nodes or IPv6 - routers defined in RFC4291. - - All Nodes Addresses: FF01::1, FF02::1. - All Router Addresses: FF01::2, FF02::2, FF05::2. - - @param[in] Router If TRUE, generate all routers addresses, - else generate all node addresses. - @param[in] Scope interface-local(1), link-local(2), or site-local(5) - @param[out] Ip6Addr The generated multicast address. - - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_SUCCESS The address is generated. - -**/ -EFI_STATUS -Ip6SetToAllNodeMulticast ( - IN BOOLEAN Router, - IN UINT8 Scope, - OUT EFI_IPv6_ADDRESS *Ip6Addr - ) -{ - if (Ip6Addr == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (!Router && Scope == IP6_SITE_LOCAL_SCOPE) { - return EFI_INVALID_PARAMETER; - } - - ZeroMem (Ip6Addr, sizeof (EFI_IPv6_ADDRESS)); - Ip6Addr->Addr[0] = 0xFF; - Ip6Addr->Addr[1] = Scope; - - if (!Router) { - Ip6Addr->Addr[15] = 0x1; - } else { - Ip6Addr->Addr[15] = 0x2; - } - - return EFI_SUCCESS; -} - -/** - This function converts MAC address to 64 bits interface ID according to RFC4291 - and returns the interface ID. Currently only 48-bit MAC address is supported by - this function. - - @param[in, out] IpSb The IP6 service binding instance. - - @retval NULL The operation fails. - @return Pointer to the generated interface ID. - -**/ -UINT8 * -Ip6CreateInterfaceID ( - IN OUT IP6_SERVICE *IpSb - ) -{ - UINT8 InterfaceId[8]; - UINT8 Byte; - EFI_MAC_ADDRESS *MacAddr; - UINT32 AddrLen; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - AddrLen = IpSb->SnpMode.HwAddressSize; - - // - // Currently only IEEE 802 48-bit MACs are supported to create link local address. - // - if (AddrLen != IP6_MAC_LEN || IpSb->InterfaceIdLen != IP6_IF_ID_LEN) { - return NULL; - } - - MacAddr = &IpSb->SnpMode.CurrentAddress; - - // - // Convert MAC address to 64 bits interface ID according to Appendix A of RFC4291: - // 1. Insert 0xFFFE to the middle - // 2. Invert the universal/local bit - bit 6 in network order - // - CopyMem (InterfaceId, MacAddr, 3); - InterfaceId[3] = 0xFF; - InterfaceId[4] = 0xFE; - CopyMem (&InterfaceId[5], &MacAddr->Addr[3], 3); - - Byte = (UINT8) (InterfaceId[0] & IP6_U_BIT); - if (Byte == IP6_U_BIT) { - InterfaceId[0] &= ~IP6_U_BIT; - } else { - InterfaceId[0] |= IP6_U_BIT; - } - - // - // Return the interface ID. - // - return AllocateCopyPool (IpSb->InterfaceIdLen, InterfaceId); -} - -/** - This function creates link-local address from interface identifier. The - interface identifier is normally created from MAC address. It might be manually - configured by administrator if the link-local address created from MAC address - is a duplicate address. - - @param[in, out] IpSb The IP6 service binding instance. - - @retval NULL If the operation fails. - @return The generated Link Local address, in network order. - -**/ -EFI_IPv6_ADDRESS * -Ip6CreateLinkLocalAddr ( - IN OUT IP6_SERVICE *IpSb - ) -{ - EFI_IPv6_ADDRESS *Ip6Addr; - EFI_IP6_CONFIG_PROTOCOL *Ip6Config; - UINTN DataSize; - EFI_IP6_CONFIG_INTERFACE_ID InterfaceId; - EFI_STATUS Status; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - if (IpSb->InterfaceId != NULL) { - FreePool (IpSb->InterfaceId); - } - - // - // Get the interface id if it is manully configured. - // - Ip6Config = &IpSb->Ip6ConfigInstance.Ip6Config; - DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID); - ZeroMem (&InterfaceId, DataSize); - - Status = Ip6Config->GetData ( - Ip6Config, - Ip6ConfigDataTypeAltInterfaceId, - &DataSize, - &InterfaceId - ); - if (Status == EFI_NOT_FOUND) { - // - // Since the interface id is not configured, generate the interface id from - // MAC address. - // - IpSb->InterfaceId = Ip6CreateInterfaceID (IpSb); - if (IpSb->InterfaceId == NULL) { - return NULL; - } - - CopyMem (&InterfaceId, IpSb->InterfaceId, IpSb->InterfaceIdLen); - // - // Record the interface id. - // - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypeAltInterfaceId, - DataSize, - &InterfaceId - ); - if (EFI_ERROR (Status)) { - FreePool (IpSb->InterfaceId); - IpSb->InterfaceId = NULL; - return NULL; - } - } else if (!EFI_ERROR (Status)) { - IpSb->InterfaceId = AllocateCopyPool (DataSize, &InterfaceId); - if (IpSb->InterfaceId == NULL) { - return NULL; - } - } else { - return NULL; - } - - // - // Append FE80::/64 to the left of IPv6 address then return. - // - Ip6Addr = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS)); - if (Ip6Addr == NULL) { - FreePool (IpSb->InterfaceId); - IpSb->InterfaceId = NULL; - return NULL; - } - - CopyMem (&Ip6Addr->Addr[8], IpSb->InterfaceId, IpSb->InterfaceIdLen); - Ip6Addr->Addr[1] = 0x80; - Ip6Addr->Addr[0] = 0xFE; - - return Ip6Addr; -} - -/** - Compute the solicited-node multicast address for an unicast or anycast address, - by taking the low-order 24 bits of this address, and appending those bits to - the prefix FF02:0:0:0:0:1:FF00::/104. - - @param[in] Ip6Addr The unicast or anycast address, in network order. - @param[out] MulticastAddr The generated solicited-node multicast address, - in network order. - -**/ -VOID -Ip6CreateSNMulticastAddr ( - IN EFI_IPv6_ADDRESS *Ip6Addr, - OUT EFI_IPv6_ADDRESS *MulticastAddr - ) -{ - ASSERT (Ip6Addr != NULL && MulticastAddr != NULL); - - ZeroMem (MulticastAddr, sizeof (EFI_IPv6_ADDRESS)); - - MulticastAddr->Addr[0] = 0xFF; - MulticastAddr->Addr[1] = 0x02; - MulticastAddr->Addr[11] = 0x1; - MulticastAddr->Addr[12] = 0xFF; - - CopyMem (&MulticastAddr->Addr[13], &Ip6Addr->Addr[13], 3); -} - -/** - Insert a node IP6_ADDRESS_INFO to an IP6 interface. - - @param[in, out] IpIf Points to an IP6 interface. - @param[in] AddrInfo Points to IP6_ADDRESS_INFO - -**/ -VOID -Ip6AddAddr ( - IN OUT IP6_INTERFACE *IpIf, - IN IP6_ADDRESS_INFO *AddrInfo - ) -{ - InsertHeadList (&IpIf->AddressList, &AddrInfo->Link); - IpIf->AddressCount++; -} - -/** - Callback function which provided by user to remove one node in NetDestroyLinkList process. - - @param[in] Entry The entry to be removed. - @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. - - @retval EFI_SUCCESS The entry has been removed successfully. - @retval Others Fail to remove the entry. - -**/ -EFI_STATUS -EFIAPI -Ip6DestroyChildEntryByAddr ( - IN LIST_ENTRY *Entry, - IN VOID *Context - ) -{ - IP6_PROTOCOL *Instance; - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - EFI_IPv6_ADDRESS *Address; - - Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE); - ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->ServiceBinding; - Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT*) Context)->Address; - - if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) { - return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - } - - return EFI_SUCCESS; -} - -/** - Destroy the IP instance if its StationAddress is removed. It is the help function - for Ip6RemoveAddr(). - - @param[in, out] IpSb Points to an IP6 service binding instance. - @param[in] Address The to be removed address - -**/ -VOID -Ip6DestroyInstanceByAddress ( - IN OUT IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Address - ) -{ - LIST_ENTRY *List; - IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT Context; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - List = &IpSb->Children; - Context.ServiceBinding = &IpSb->ServiceBinding; - Context.Address = Address; - NetDestroyLinkList ( - List, - Ip6DestroyChildEntryByAddr, - &Context, - NULL - ); -} - -/** - Remove the IPv6 address from the address list node points to IP6_ADDRESS_INFO. - - This function removes the matching IPv6 addresses from the address list and - adjusts the address count of the address list. If IpSb is not NULL, this function - calls Ip6LeaveGroup to see whether it should call Mnp->Groups() to remove the - its solicited-node multicast MAC address from the filter list and sends out - a Multicast Listener Done. If Prefix is NULL, all address in the address list - will be removed. If Prefix is not NULL, the address that matching the Prefix - with PrefixLength in the address list will be removed. - - @param[in] IpSb NULL or points to IP6 service binding instance. - @param[in, out] AddressList Address list array. - @param[in, out] AddressCount The count of addresses in address list array. - @param[in] Prefix NULL or an IPv6 address prefix. - @param[in] PrefixLength The length of Prefix. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_NOT_FOUND The address matching the Prefix with PrefixLength - cannot be found in the address list. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - -**/ -EFI_STATUS -Ip6RemoveAddr ( - IN IP6_SERVICE *IpSb OPTIONAL, - IN OUT LIST_ENTRY *AddressList, - IN OUT UINT32 *AddressCount, - IN EFI_IPv6_ADDRESS *Prefix OPTIONAL, - IN UINT8 PrefixLength - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_ADDRESS_INFO *AddrInfo; - EFI_IPv6_ADDRESS SnMCastAddr; - - if (IsListEmpty (AddressList) || *AddressCount < 1 || PrefixLength > IP6_PREFIX_MAX) { - return EFI_INVALID_PARAMETER; - } - - Status = EFI_NOT_FOUND; - - NET_LIST_FOR_EACH_SAFE (Entry, Next, AddressList) { - AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE); - - if (Prefix == NULL || - (PrefixLength == 128 && EFI_IP6_EQUAL (Prefix, &AddrInfo->Address)) || - (PrefixLength == AddrInfo->PrefixLength && NetIp6IsNetEqual (Prefix, &AddrInfo->Address, PrefixLength)) - ) { - if (IpSb != NULL) { - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - Ip6CreateSNMulticastAddr (&AddrInfo->Address, &SnMCastAddr); - Ip6LeaveGroup (IpSb, &SnMCastAddr); - - // - // Destroy any instance who is using the dying address as the source address. - // - Ip6DestroyInstanceByAddress (IpSb, &AddrInfo->Address); - } - - RemoveEntryList (Entry); - FreePool (AddrInfo); - (*AddressCount)--; - - Status = EFI_SUCCESS; - } - } - - return Status; -} - -/** - Check whether the incoming Ipv6 address is a solicited-node multicast address. - - @param[in] Ip6 Ip6 address, in network order. - - @retval TRUE Yes, solicited-node multicast address - @retval FALSE No - -**/ -BOOLEAN -Ip6IsSNMulticastAddr ( - IN EFI_IPv6_ADDRESS *Ip6 - ) -{ - EFI_IPv6_ADDRESS Sn; - BOOLEAN Flag; - - Ip6CreateSNMulticastAddr (Ip6, &Sn); - Flag = FALSE; - - if (CompareMem (Sn.Addr, Ip6->Addr, 13) == 0) { - Flag = TRUE; - } - - return Flag; -} - -/** - Check whether the incoming IPv6 address is one of the maintained addresses in - the IP6 service binding instance. - - @param[in] IpSb Points to a IP6 service binding instance. - @param[in] Address The IP6 address to be checked. - @param[out] Interface If not NULL, output the IP6 interface which - maintains the Address. - @param[out] AddressInfo If not NULL, output the IP6 address information - of the Address. - - @retval TRUE Yes, it is one of the maintained address. - @retval FALSE No, it is not one of the maintained address. - -**/ -BOOLEAN -Ip6IsOneOfSetAddress ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Address, - OUT IP6_INTERFACE **Interface OPTIONAL, - OUT IP6_ADDRESS_INFO **AddressInfo OPTIONAL - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Entry2; - IP6_INTERFACE *IpIf; - IP6_ADDRESS_INFO *TmpAddressInfo; - - // - // Check link-local address first - // - if (IpSb->LinkLocalOk && EFI_IP6_EQUAL (&IpSb->LinkLocalAddr, Address)) { - if (Interface != NULL) { - *Interface = IpSb->DefaultInterface; - } - - if (AddressInfo != NULL) { - *AddressInfo = NULL; - } - - return TRUE; - } - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE); - - NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) { - TmpAddressInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE); - - if (EFI_IP6_EQUAL (&TmpAddressInfo->Address, Address)) { - if (Interface != NULL) { - *Interface = IpIf; - } - - if (AddressInfo != NULL) { - *AddressInfo = TmpAddressInfo; - } - - return TRUE; - } - } - } - - return FALSE; -} - -/** - Check whether the incoming MAC address is valid. - - @param[in] IpSb Points to a IP6 service binding instance. - @param[in] LinkAddress The MAC address. - - @retval TRUE Yes, it is valid. - @retval FALSE No, it is not valid. - -**/ -BOOLEAN -Ip6IsValidLinkAddress ( - IN IP6_SERVICE *IpSb, - IN EFI_MAC_ADDRESS *LinkAddress - ) -{ - UINT32 Index; - - // - // TODO: might be updated later to be more acceptable. - // - for (Index = IpSb->SnpMode.HwAddressSize; Index < sizeof (EFI_MAC_ADDRESS); Index++) { - if (LinkAddress->Addr[Index] != 0) { - return FALSE; - } - } - - return TRUE; -} - -/** - Copy the PrefixLength bits from Src to Dest. - - @param[out] Dest A pointer to the buffer to copy to. - @param[in] Src A pointer to the buffer to copy from. - @param[in] PrefixLength The number of bits to copy. - -**/ -VOID -Ip6CopyAddressByPrefix ( - OUT EFI_IPv6_ADDRESS *Dest, - IN EFI_IPv6_ADDRESS *Src, - IN UINT8 PrefixLength - ) -{ - UINT8 Byte; - UINT8 Bit; - UINT8 Mask; - - ASSERT (Dest != NULL && Src != NULL); - ASSERT (PrefixLength <= IP6_PREFIX_MAX); - - Byte = (UINT8) (PrefixLength / 8); - Bit = (UINT8) (PrefixLength % 8); - - ZeroMem (Dest, sizeof (EFI_IPv6_ADDRESS)); - - CopyMem (Dest, Src, Byte); - - if (Bit > 0) { - Mask = (UINT8) (0xFF << (8 - Bit)); - ASSERT (Byte < 16); - Dest->Addr[Byte] = (UINT8) (Src->Addr[Byte] & Mask); - } -} - -/** - Get the MAC address for a multicast IP address. Call - Mnp's McastIpToMac to find the MAC address instead of - hard-coding the NIC to be Ethernet. - - @param[in] Mnp The Mnp instance to get the MAC address. - @param[in] Multicast The multicast IP address to translate. - @param[out] Mac The buffer to hold the translated address. - - @retval EFI_SUCCESS The multicast IP successfully - translated to a multicast MAC address. - @retval Other The address is not converted because an error occurred. - -**/ -EFI_STATUS -Ip6GetMulticastMac ( - IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp, - IN EFI_IPv6_ADDRESS *Multicast, - OUT EFI_MAC_ADDRESS *Mac - ) -{ - EFI_IP_ADDRESS EfiIp; - - IP6_COPY_ADDRESS (&EfiIp.v6, Multicast); - - return Mnp->McastIpToMac (Mnp, TRUE, &EfiIp, Mac); -} - -/** - Convert the multibyte field in IP header's byter order. - In spite of its name, it can also be used to convert from - host to network byte order. - - @param[in, out] Head The IP head to convert. - - @return Point to the converted IP head. - -**/ -EFI_IP6_HEADER * -Ip6NtohHead ( - IN OUT EFI_IP6_HEADER *Head - ) -{ - Head->FlowLabelL = NTOHS (Head->FlowLabelL); - Head->PayloadLength = NTOHS (Head->PayloadLength); - - return Head; -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Common.h b/Core/NetworkPkg/Ip6Dxe/Ip6Common.h deleted file mode 100644 index 488c5b23b7..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Common.h +++ /dev/null @@ -1,318 +0,0 @@ -/** @file - Common definition and functions for IP6 driver. - - Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_COMMON_H__ -#define __EFI_IP6_COMMON_H__ - -#define IP6_LINK_EQUAL(Mac1, Mac2) (CompareMem ((Mac1), (Mac2), sizeof (EFI_MAC_ADDRESS)) == 0) - -// -// Convert the Microsecond to second. IP transmit/receive time is -// in the unit of microsecond. IP ticks once per second. -// -#define IP6_US_TO_SEC(Us) (((Us) + 999999) / 1000000) - -#define IP6_ETHER_PROTO 0x86DD - -#define IP6_MAC_LEN 6 -#define IP6_IF_ID_LEN 8 - -#define IP6_INTERFACE_LOCAL_SCOPE 1 -#define IP6_LINK_LOCAL_SCOPE 2 -#define IP6_SITE_LOCAL_SCOPE 5 - -#define IP6_INFINIT_LIFETIME 0xFFFFFFFF - -#define IP6_HOP_LIMIT 255 -// -// Make it to 64 since all 54 bits are zero. -// -#define IP6_LINK_LOCAL_PREFIX_LENGTH 64 - -#define IP6_TIMER_INTERVAL_IN_MS 100 -#define IP6_ONE_SECOND_IN_MS 1000 - -// -// The packet is received as link level broadcast/multicast/promiscuous. -// -#define IP6_LINK_BROADCAST 0x00000001 -#define IP6_LINK_MULTICAST 0x00000002 -#define IP6_LINK_PROMISC 0x00000004 - -#define IP6_U_BIT 0x02 - -typedef enum { - Ip6Promiscuous = 1, - Ip6Unicast, - Ip6Multicast, - Ip6AnyCast -} IP6_ADDRESS_TYPE; - -typedef struct { - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - EFI_IPv6_ADDRESS *Address; -} IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT; - -typedef struct _IP6_INTERFACE IP6_INTERFACE; -typedef struct _IP6_PROTOCOL IP6_PROTOCOL; -typedef struct _IP6_SERVICE IP6_SERVICE; -typedef struct _IP6_ADDRESS_INFO IP6_ADDRESS_INFO; - -/** - Build a array of EFI_IP6_ADDRESS_INFO to be returned to the caller. The number - of EFI_IP6_ADDRESS_INFO is also returned. If AddressList is NULL, - only the address count is returned. - - @param[in] IpSb The IP6 service binding instance. - @param[out] AddressCount The number of returned addresses. - @param[out] AddressList The pointer to the array of EFI_IP6_ADDRESS_INFO. - This is an optional parameter. - - - @retval EFI_SUCCESS The address array is successfully build - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the address info. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - -**/ -EFI_STATUS -Ip6BuildEfiAddressList ( - IN IP6_SERVICE *IpSb, - OUT UINT32 *AddressCount, - OUT EFI_IP6_ADDRESS_INFO **AddressList OPTIONAL - ); - -/** - Generate the multicast addresses identify the group of all IPv6 nodes or IPv6 - routers defined in RFC4291. - - All Nodes Addresses: FF01::1, FF02::1. - All Router Addresses: FF01::2, FF02::2, FF05::2. - - @param[in] Router If TRUE, generate all routers addresses, - else generate all node addresses. - @param[in] Scope interface-local(1), link-local(2), or site-local(5) - @param[out] Ip6Addr The generated multicast address. - - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_SUCCESS The address is generated. - -**/ -EFI_STATUS -Ip6SetToAllNodeMulticast ( - IN BOOLEAN Router, - IN UINT8 Scope, - OUT EFI_IPv6_ADDRESS *Ip6Addr - ); - -/** - This function converts MAC address to 64 bits interface ID according to RFC4291 - and returns the interface ID. Currently only 48-bit MAC address is supported by - this function. - - @param[in, out] IpSb The IP6 service binding instance. - - @retval NULL The operation fails. - @return Pointer to the generated interface ID. - -**/ -UINT8 * -Ip6CreateInterfaceID ( - IN OUT IP6_SERVICE *IpSb - ); - -/** - This function creates link-local address from interface identifier. The - interface identifier is normally created from MAC address. It might be manually - configured by administrator if the link-local address created from MAC address - is a duplicate address. - - @param[in, out] IpSb The IP6 service binding instance. - - @retval NULL If the operation fails. - @return The generated Link Local address, in network order. - -**/ -EFI_IPv6_ADDRESS * -Ip6CreateLinkLocalAddr ( - IN OUT IP6_SERVICE *IpSb - ); - -/** - Compute the solicited-node multicast address for an unicast or anycast address, - by taking the low-order 24 bits of this address, and appending those bits to - the prefix FF02:0:0:0:0:1:FF00::/104. - - @param Ip6Addr The unicast or anycast address, in network order. - @param MulticastAddr The generated solicited-node multicast address, - in network order. - -**/ -VOID -Ip6CreateSNMulticastAddr ( - IN EFI_IPv6_ADDRESS *Ip6Addr, - OUT EFI_IPv6_ADDRESS *MulticastAddr - ); - -/** - Check whether the incoming Ipv6 address is a solicited-node multicast address. - - @param[in] Ip6 Ip6 address, in network order. - - @retval TRUE Yes, solicited-node multicast address - @retval FALSE No - -**/ -BOOLEAN -Ip6IsSNMulticastAddr ( - IN EFI_IPv6_ADDRESS *Ip6 - ); - -/** - Check whether the incoming IPv6 address is one of the maintained address in - the IP6 service binding instance. - - @param[in] IpSb Points to a IP6 service binding instance - @param[in] Address The IP6 address to be checked. - @param[out] Interface If not NULL, output the IP6 interface which - maintains the Address. - @param[out] AddressInfo If not NULL, output the IP6 address information - of the Address. - - @retval TRUE Yes, it is one of the maintained addresses. - @retval FALSE No, it is not one of the maintained addresses. - -**/ -BOOLEAN -Ip6IsOneOfSetAddress ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Address, - OUT IP6_INTERFACE **Interface OPTIONAL, - OUT IP6_ADDRESS_INFO **AddressInfo OPTIONAL - ); - -/** - Check whether the incoming MAC address is valid. - - @param[in] IpSb Points to a IP6 service binding instance. - @param[in] LinkAddress The MAC address. - - @retval TRUE Yes, it is valid. - @retval FALSE No, it is not valid. - -**/ -BOOLEAN -Ip6IsValidLinkAddress ( - IN IP6_SERVICE *IpSb, - IN EFI_MAC_ADDRESS *LinkAddress - ); - - -/** - Copy the PrefixLength bits from Src to Dest. - - @param[out] Dest A pointer to the buffer to copy to. - @param[in] Src A pointer to the buffer to copy from. - @param[in] PrefixLength The number of bits to copy. - -**/ -VOID -Ip6CopyAddressByPrefix ( - OUT EFI_IPv6_ADDRESS *Dest, - IN EFI_IPv6_ADDRESS *Src, - IN UINT8 PrefixLength - ); - -/** - Insert a node IP6_ADDRESS_INFO to an IP6 interface. - - @param[in, out] IpIf Points to an IP6 interface. - @param[in] AddrInfo Points to an IP6_ADDRESS_INFO. - -**/ -VOID -Ip6AddAddr ( - IN OUT IP6_INTERFACE *IpIf, - IN IP6_ADDRESS_INFO *AddrInfo - ); - -/** - Remove the IPv6 address from the address list node points to IP6_ADDRESS_INFO. - - This function removes the matching IPv6 addresses from the address list and - adjusts the address count of the address list. If IpSb is not NULL, this function - calls Ip6LeaveGroup to see whether it should call Mnp->Groups() to remove the - its solicited-node multicast MAC address from the filter list and sends out - a Multicast Listener Done. If Prefix is NULL, all address in the address list - will be removed. If Prefix is not NULL, the address that matching the Prefix - with PrefixLength in the address list will be removed. - - @param[in] IpSb NULL or points to IP6 service binding instance. - @param[in, out] AddressList address list array - @param[in, out] AddressCount the count of addresses in address list array - @param[in] Prefix NULL or an IPv6 address prefix - @param[in] PrefixLength the length of Prefix - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_NOT_FOUND The address matching the Prefix with PrefixLength - cannot be found in address list. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - -**/ -EFI_STATUS -Ip6RemoveAddr ( - IN IP6_SERVICE *IpSb OPTIONAL, - IN OUT LIST_ENTRY *AddressList, - IN OUT UINT32 *AddressCount, - IN EFI_IPv6_ADDRESS *Prefix OPTIONAL, - IN UINT8 PrefixLength - ); - -/** - Get the MAC address for a multicast IP address. Call - Mnp's McastIpToMac to find the MAC address instead of - hard-coding the NIC to be Ethernet. - - @param[in] Mnp The Mnp instance to get the MAC address. - @param[in] Multicast The multicast IP address to translate. - @param[out] Mac The buffer to hold the translated address. - - @retval EFI_SUCCESS The multicast IP is successfully - translated to a multicast MAC address. - @retval Other The address is not converted because an error occurred. - -**/ -EFI_STATUS -Ip6GetMulticastMac ( - IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp, - IN EFI_IPv6_ADDRESS *Multicast, - OUT EFI_MAC_ADDRESS *Mac - ); - -/** - Convert the multibyte field in IP header's byter order. - In spite of its name, it can also be used to convert from - host to network byte order. - - @param[in, out] Head The IP head to convert. - - @return Point to the converted IP head. - -**/ -EFI_IP6_HEADER * -Ip6NtohHead ( - IN OUT EFI_IP6_HEADER *Head - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Config.vfr b/Core/NetworkPkg/Ip6Dxe/Ip6Config.vfr deleted file mode 100644 index 67fd386bca..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Config.vfr +++ /dev/null @@ -1,178 +0,0 @@ -/** @file - VFR file used by the IP6 configuration component. - - Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6NvData.h" - -#define EFI_NETWORK_DEVICE_CLASS 0x04 - -formset - guid = IP6_CONFIG_NVDATA_GUID, - title = STRING_TOKEN(STR_IP6_CONFIG_FORM_TITLE), - help = STRING_TOKEN(STR_IP6_CONFIG_FORM_HELP), - - varstore IP6_CONFIG_IFR_NVDATA, - name = IP6_CONFIG_IFR_NVDATA, - guid = IP6_CONFIG_NVDATA_GUID; - - form formid = FORMID_HEAD_FORM, - title = STRING_TOKEN(STR_IP6_DEVICE_FORM_TITLE); - - goto FORMID_MAIN_FORM, - prompt = STRING_TOKEN (STR_GET_CURRENT_SETTING), - help = STRING_TOKEN (STR_GET_CURRENT_SETTING_HELP), - flags = INTERACTIVE, - key = KEY_GET_CURRENT_SETTING; - - endform; - - form formid = FORMID_MAIN_FORM, - title = STRING_TOKEN(STR_IP6_DEVICE_FORM_TITLE); - - text - help = STRING_TOKEN(STR_IP6_INTERFACE_NAME_HELP), - text = STRING_TOKEN(STR_IP6_INTERFACE_NAME), - text = STRING_TOKEN(STR_IP6_INTERFACE_NAME_CONTENT); - - text - help = STRING_TOKEN(STR_IP6_INTERFACE_TYPE_HELP), - text = STRING_TOKEN(STR_IP6_INTERFACE_TYPE), - text = STRING_TOKEN(STR_IP6_INTERFACE_TYPE_CONTENT); - - text - help = STRING_TOKEN(STR_IP6_MAC_ADDRESS_HELP), - text = STRING_TOKEN(STR_IP6_MAC_ADDRESS), - text = STRING_TOKEN(STR_IP6_MAC_ADDRESS_CONTENT); - - text - help = STRING_TOKEN(STR_IP6_HOST_ADDRESS_HELP), - text = STRING_TOKEN(STR_IP6_HOST_ADDRESS), - text = STRING_TOKEN(STR_NULL); - - label HOST_ADDRESS_LABEL; - label LABEL_END; - - text - help = STRING_TOKEN(STR_IP6_ROUTE_TABLE_HELP), - text = STRING_TOKEN(STR_IP6_ROUTE_TABLE), - text = STRING_TOKEN(STR_NULL); - - label ROUTE_TABLE_LABEL; - label LABEL_END; - - text - help = STRING_TOKEN(STR_IP6_GATEWAY_ADDRESS_HELP), - text = STRING_TOKEN(STR_IP6_GATEWAY_ADDRESS), - text = STRING_TOKEN(STR_NULL); - - label GATEWAY_ADDRESS_LABEL; - label LABEL_END; - - text - help = STRING_TOKEN(STR_IP6_DNS_ADDRESS_HELP), - text = STRING_TOKEN(STR_IP6_DNS_ADDRESS), - text = STRING_TOKEN(STR_NULL); - - label DNS_ADDRESS_LABEL; - label LABEL_END; - - string varid = IP6_CONFIG_IFR_NVDATA.InterfaceId, - prompt = STRING_TOKEN(STR_IP6_INTERFACE_ID), - help = STRING_TOKEN(STR_IP6_INTERFACE_ID_HELP), - flags = INTERACTIVE, - key = KEY_INTERFACE_ID, - minsize = INTERFACE_ID_STR_MIN_SIZE, - maxsize = INTERFACE_ID_STR_MAX_SIZE, - endstring; - - numeric varid = IP6_CONFIG_IFR_NVDATA.DadTransmitCount, - prompt = STRING_TOKEN(STR_IP6_DAD_TRANSMIT_COUNT), - help = STRING_TOKEN(STR_IP6_DAD_TRANSMIT_COUNT_HELP), - flags = 0, - minimum = 0, - maximum = DAD_MAX_TRANSMIT_COUNT, - step = 0, - endnumeric; - - oneof varid = IP6_CONFIG_IFR_NVDATA.Policy, - prompt = STRING_TOKEN(STR_POLICY_TYPE_PROMPT), - help = STRING_TOKEN(STR_POLICY_TYPE_HELP), - option text = STRING_TOKEN(STR_POLICY_TYPE_AUTO), value = IP6_POLICY_AUTO, flags = DEFAULT; - option text = STRING_TOKEN(STR_POLICY_TYPE_MANUAL), value = IP6_POLICY_MANUAL, flags = 0; - endoneof; - - subtitle text = STRING_TOKEN(STR_NULL); - - suppressif ideqval IP6_CONFIG_IFR_NVDATA.Policy == IP6_POLICY_AUTO; - goto FORMID_MANUAL_CONFIG_FORM, - prompt = STRING_TOKEN(STR_IP6_AD_CONFIG_FORM), - help = STRING_TOKEN(STR_IP6_AD_CONFIG_FORM_HELP), - flags = 0; - subtitle text = STRING_TOKEN(STR_NULL); - endif; - - text - help = STRING_TOKEN (STR_SAVE_CHANGES_HELP), - text = STRING_TOKEN (STR_SAVE_CHANGES), - flags = INTERACTIVE, - key = KEY_SAVE_CHANGES; - - endform; - - form formid = FORMID_MANUAL_CONFIG_FORM, - title = STRING_TOKEN(STR_IP6_AD_CONFIG_FORM); - - string varid = IP6_CONFIG_IFR_NVDATA.ManualAddress, - prompt = STRING_TOKEN(STR_IP6_MANUAL_ADDRESS), - help = STRING_TOKEN(STR_IP6_MANUAL_ADDRESS_HELP), - flags = INTERACTIVE, - key = KEY_MANUAL_ADDRESS, - minsize = ADDRESS_STR_MIN_SIZE, - maxsize = ADDRESS_STR_MAX_SIZE, - endstring; - - string varid = IP6_CONFIG_IFR_NVDATA.GatewayAddress, - prompt = STRING_TOKEN(STR_IP6_NEW_GATEWAY_ADDRESS), - help = STRING_TOKEN(STR_IP6_NEW_GATEWAY_ADDR_HELP), - flags = INTERACTIVE, - key = KEY_GATEWAY_ADDRESS, - minsize = ADDRESS_STR_MIN_SIZE, - maxsize = ADDRESS_STR_MAX_SIZE, - endstring; - - string varid = IP6_CONFIG_IFR_NVDATA.DnsAddress, - prompt = STRING_TOKEN(STR_IP6_NEW_DNS_ADDRESS), - help = STRING_TOKEN(STR_IP6_NEW_DNS_ADDRESS_HELP), - flags = INTERACTIVE, - key = KEY_DNS_ADDRESS, - minsize = ADDRESS_STR_MIN_SIZE, - maxsize = ADDRESS_STR_MAX_SIZE, - endstring; - - text - help = STRING_TOKEN (STR_SAVE_AND_EXIT), - text = STRING_TOKEN (STR_SAVE_AND_EXIT), - flags = INTERACTIVE, - key = KEY_SAVE_CONFIG_CHANGES; - - text - help = STRING_TOKEN (STR_NO_SAVE_AND_EXIT), - text = STRING_TOKEN (STR_NO_SAVE_AND_EXIT), - flags = INTERACTIVE, - key = KEY_IGNORE_CONFIG_CHANGES; - - endform; - -endformset; - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c b/Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c deleted file mode 100644 index 7575b7947d..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.c +++ /dev/null @@ -1,2386 +0,0 @@ -/** @file - The implementation of EFI IPv6 Configuration Protocol. - - Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -LIST_ENTRY mIp6ConfigInstanceList = {&mIp6ConfigInstanceList, &mIp6ConfigInstanceList}; - -/** - The event process routine when the DHCPv6 service binding protocol is installed - in the system. - - @param[in] Event Not used. - @param[in] Context Pointer to the IP6 config instance data. - -**/ -VOID -EFIAPI -Ip6ConfigOnDhcp6SbInstalled ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Update the current policy to NewPolicy. During the transition - period, the default router list, on-link prefix list, autonomous prefix list - and address list in all interfaces will be released. - - @param[in] IpSb The IP6 service binding instance. - @param[in] NewPolicy The new policy to be updated to. - -**/ -VOID -Ip6ConfigOnPolicyChanged ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_CONFIG_POLICY NewPolicy - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Entry2; - LIST_ENTRY *Next; - IP6_INTERFACE *IpIf; - IP6_DAD_ENTRY *DadEntry; - IP6_DELAY_JOIN_LIST *DelayNode; - - // - // Currently there are only two policies: Manual and Automatic. Regardless of - // what transition is going on, i.e., Manual -> Automatic and Automatic -> - // Manual, we have to free default router list, on-link prefix list, autonomous - // prefix list, address list in all the interfaces and destroy any IPv6 child - // instance whose local IP is neither 0 nor the link-local address. - // - Ip6CleanDefaultRouterList (IpSb); - Ip6CleanPrefixListTable (IpSb, &IpSb->OnlinkPrefix); - Ip6CleanPrefixListTable (IpSb, &IpSb->AutonomousPrefix); - - // - // It's tricky... If the LinkLocal address is O.K., add back the link-local - // prefix to the on-link prefix table. - // - if (IpSb->LinkLocalOk) { - Ip6CreatePrefixListEntry ( - IpSb, - TRUE, - (UINT32) IP6_INFINIT_LIFETIME, - (UINT32) IP6_INFINIT_LIFETIME, - IP6_LINK_LOCAL_PREFIX_LENGTH, - &IpSb->LinkLocalAddr - ); - } - - // - // All IPv6 children that use global unicast address as it's source address - // should be destryoed now. The survivers are those use the link-local address - // or the unspecified address as the source address. - // TODO: Conduct a check here. - Ip6RemoveAddr ( - IpSb, - &IpSb->DefaultInterface->AddressList, - &IpSb->DefaultInterface->AddressCount, - NULL, - 0 - ); - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - // - // remove all pending delay node and DAD entries for the global addresses. - // - IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE); - - NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) { - DelayNode = NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, Link); - if (!NetIp6IsLinkLocalAddr (&DelayNode->AddressInfo->Address)) { - RemoveEntryList (&DelayNode->Link); - FreePool (DelayNode); - } - } - - NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) { - DadEntry = NET_LIST_USER_STRUCT_S (Entry2, IP6_DAD_ENTRY, Link, IP6_DAD_ENTRY_SIGNATURE); - - if (!NetIp6IsLinkLocalAddr (&DadEntry->AddressInfo->Address)) { - // - // Fail this DAD entry if the address is not link-local. - // - Ip6OnDADFinished (FALSE, IpIf, DadEntry); - } - } - } - - if (NewPolicy == Ip6ConfigPolicyAutomatic) { - // - // Set parameters to trigger router solicitation sending in timer handler. - // - IpSb->RouterAdvertiseReceived = FALSE; - IpSb->SolicitTimer = IP6_MAX_RTR_SOLICITATIONS; - // - // delay 1 second - // - IpSb->Ticks = (UINT32) IP6_GET_TICKS (IP6_ONE_SECOND_IN_MS); - } - -} - -/** - The work function to trigger the DHCPv6 process to perform a stateful autoconfiguration. - - @param[in] Instance Pointer to the IP6 config instance data. - @param[in] OtherInfoOnly If FALSE, get stateful address and other information - via DHCPv6. Otherwise, only get the other information. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_UNSUPPORTED The DHCP6 driver is not available. - -**/ -EFI_STATUS -Ip6ConfigStartStatefulAutoConfig ( - IN IP6_CONFIG_INSTANCE *Instance, - IN BOOLEAN OtherInfoOnly - ) -{ - EFI_STATUS Status; - IP6_SERVICE *IpSb; - EFI_DHCP6_CONFIG_DATA Dhcp6CfgData; - EFI_DHCP6_PROTOCOL *Dhcp6; - EFI_DHCP6_PACKET_OPTION *OptList[1]; - UINT16 OptBuf[4]; - EFI_DHCP6_PACKET_OPTION *Oro; - EFI_DHCP6_RETRANSMISSION InfoReqReXmit; - - // - // A host must not invoke stateful address configuration if it is already - // participating in the statuful protocol as a result of an earlier advertisement. - // - if (Instance->Dhcp6Handle != NULL) { - return EFI_SUCCESS; - } - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - - Instance->OtherInfoOnly = OtherInfoOnly; - - Status = NetLibCreateServiceChild ( - IpSb->Controller, - IpSb->Image, - &gEfiDhcp6ServiceBindingProtocolGuid, - &Instance->Dhcp6Handle - ); - - if (Status == EFI_UNSUPPORTED) { - // - // No DHCPv6 Service Binding protocol, register a notify. - // - if (Instance->Dhcp6SbNotifyEvent == NULL) { - Instance->Dhcp6SbNotifyEvent = EfiCreateProtocolNotifyEvent ( - &gEfiDhcp6ServiceBindingProtocolGuid, - TPL_CALLBACK, - Ip6ConfigOnDhcp6SbInstalled, - (VOID *) Instance, - &Instance->Registration - ); - } - } - - if (EFI_ERROR (Status)) { - return Status; - } - - if (Instance->Dhcp6SbNotifyEvent != NULL) { - gBS->CloseEvent (Instance->Dhcp6SbNotifyEvent); - } - - Status = gBS->OpenProtocol ( - Instance->Dhcp6Handle, - &gEfiDhcp6ProtocolGuid, - (VOID **) &Instance->Dhcp6, - IpSb->Image, - IpSb->Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - ASSERT_EFI_ERROR (Status); - - Dhcp6 = Instance->Dhcp6; - Dhcp6->Configure (Dhcp6, NULL); - - // - // Set the exta options to send. Here we only want the option request option - // with DNS SERVERS. - // - Oro = (EFI_DHCP6_PACKET_OPTION *) OptBuf; - Oro->OpCode = HTONS (DHCP6_OPT_ORO); - Oro->OpLen = HTONS (2); - *((UINT16 *) &Oro->Data[0]) = HTONS (DHCP6_OPT_DNS_SERVERS); - OptList[0] = Oro; - - Status = EFI_SUCCESS; - - if (!OtherInfoOnly) { - // - // Get stateful address and other information via DHCPv6. - // - Dhcp6CfgData.Dhcp6Callback = NULL; - Dhcp6CfgData.CallbackContext = NULL; - Dhcp6CfgData.OptionCount = 1; - Dhcp6CfgData.OptionList = &OptList[0]; - Dhcp6CfgData.IaDescriptor.Type = EFI_DHCP6_IA_TYPE_NA; - Dhcp6CfgData.IaDescriptor.IaId = Instance->IaId; - Dhcp6CfgData.IaInfoEvent = Instance->Dhcp6Event; - Dhcp6CfgData.ReconfigureAccept = FALSE; - Dhcp6CfgData.RapidCommit = FALSE; - Dhcp6CfgData.SolicitRetransmission = NULL; - - Status = Dhcp6->Configure (Dhcp6, &Dhcp6CfgData); - - if (!EFI_ERROR (Status)) { - - if (IpSb->LinkLocalOk) { - Status = Dhcp6->Start (Dhcp6); - } else { - IpSb->Dhcp6NeedStart = TRUE; - } - - } - } else { - // - // Only get other information via DHCPv6, this doesn't require a config - // action. - // - InfoReqReXmit.Irt = 4; - InfoReqReXmit.Mrc = 64; - InfoReqReXmit.Mrt = 60; - InfoReqReXmit.Mrd = 0; - - if (IpSb->LinkLocalOk) { - Status = Dhcp6->InfoRequest ( - Dhcp6, - TRUE, - Oro, - 0, - NULL, - &InfoReqReXmit, - Instance->Dhcp6Event, - Ip6ConfigOnDhcp6Reply, - Instance - ); - } else { - IpSb->Dhcp6NeedInfoRequest = TRUE; - } - - } - - return Status; -} - -/** - Signal the registered event. It is the callback routine for NetMapIterate. - - @param[in] Map Points to the list of registered event. - @param[in] Item The registered event. - @param[in] Arg Not used. - -**/ -EFI_STATUS -EFIAPI -Ip6ConfigSignalEvent ( - IN NET_MAP *Map, - IN NET_MAP_ITEM *Item, - IN VOID *Arg - ) -{ - gBS->SignalEvent ((EFI_EVENT) Item->Key); - - return EFI_SUCCESS; -} - -/** - Read the configuration data from variable storage according to the VarName and - gEfiIp6ConfigProtocolGuid. It checks the integrity of variable data. If the - data is corrupted, it clears the variable data to ZERO. Othewise, it outputs the - configuration data to IP6_CONFIG_INSTANCE. - - @param[in] VarName The pointer to the variable name - @param[in, out] Instance The pointer to the IP6 config instance data. - - @retval EFI_NOT_FOUND The variable can not be found or already corrupted. - @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation. - @retval EFI_SUCCESS The configuration data was retrieved successfully. - -**/ -EFI_STATUS -Ip6ConfigReadConfigData ( - IN CHAR16 *VarName, - IN OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - EFI_STATUS Status; - UINTN VarSize; - IP6_CONFIG_VARIABLE *Variable; - IP6_CONFIG_DATA_ITEM *DataItem; - UINTN Index; - IP6_CONFIG_DATA_RECORD DataRecord; - CHAR8 *Data; - - // - // Try to read the configuration variable. - // - VarSize = 0; - Status = gRT->GetVariable ( - VarName, - &gEfiIp6ConfigProtocolGuid, - NULL, - &VarSize, - NULL - ); - - if (Status == EFI_BUFFER_TOO_SMALL) { - // - // Allocate buffer and read the config variable. - // - Variable = AllocatePool (VarSize); - if (Variable == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = gRT->GetVariable ( - VarName, - &gEfiIp6ConfigProtocolGuid, - NULL, - &VarSize, - Variable - ); - if (EFI_ERROR (Status) || (UINT16) (~NetblockChecksum ((UINT8 *) Variable, (UINT32) VarSize)) != 0) { - // - // GetVariable still error or the variable is corrupted. - // Fall back to the default value. - // - FreePool (Variable); - - // - // Remove the problematic variable and return EFI_NOT_FOUND, a new - // variable will be set again. - // - gRT->SetVariable ( - VarName, - &gEfiIp6ConfigProtocolGuid, - IP6_CONFIG_VARIABLE_ATTRIBUTE, - 0, - NULL - ); - - return EFI_NOT_FOUND; - } - - // - // Get the IAID we use. - // - Instance->IaId = Variable->IaId; - - for (Index = 0; Index < Variable->DataRecordCount; Index++) { - - CopyMem (&DataRecord, &Variable->DataRecord[Index], sizeof (DataRecord)); - - DataItem = &Instance->DataItem[DataRecord.DataType]; - if (DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED) && - (DataItem->DataSize != DataRecord.DataSize) - ) { - // - // Perhaps a corrupted data record... - // - continue; - } - - if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) { - // - // This data item has variable length data. - // - DataItem->Data.Ptr = AllocatePool (DataRecord.DataSize); - if (DataItem->Data.Ptr == NULL) { - // - // no memory resource - // - continue; - } - } - - Data = (CHAR8 *) Variable + DataRecord.Offset; - CopyMem (DataItem->Data.Ptr, Data, DataRecord.DataSize); - - DataItem->DataSize = DataRecord.DataSize; - DataItem->Status = EFI_SUCCESS; - } - - FreePool (Variable); - return EFI_SUCCESS; - } - - return Status; -} - -/** - Write the configuration data from IP6_CONFIG_INSTANCE to variable storage. - - @param[in] VarName The pointer to the variable name. - @param[in] Instance The pointer to the IP6 configuration instance data. - - @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation. - @retval EFI_SUCCESS The configuration data is written successfully. - -**/ -EFI_STATUS -Ip6ConfigWriteConfigData ( - IN CHAR16 *VarName, - IN IP6_CONFIG_INSTANCE *Instance - ) -{ - UINTN Index; - UINTN VarSize; - IP6_CONFIG_DATA_ITEM *DataItem; - IP6_CONFIG_VARIABLE *Variable; - IP6_CONFIG_DATA_RECORD *DataRecord; - CHAR8 *Heap; - EFI_STATUS Status; - - VarSize = sizeof (IP6_CONFIG_VARIABLE) - sizeof (IP6_CONFIG_DATA_RECORD); - - for (Index = 0; Index < Ip6ConfigDataTypeMaximum; Index++) { - - DataItem = &Instance->DataItem[Index]; - if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) && !EFI_ERROR (DataItem->Status)) { - - VarSize += sizeof (IP6_CONFIG_DATA_RECORD) + DataItem->DataSize; - } - } - - Variable = AllocatePool (VarSize); - if (Variable == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Variable->IaId = Instance->IaId; - Heap = (CHAR8 *) Variable + VarSize; - Variable->DataRecordCount = 0; - - for (Index = 0; Index < Ip6ConfigDataTypeMaximum; Index++) { - - DataItem = &Instance->DataItem[Index]; - if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_VOLATILE) && !EFI_ERROR (DataItem->Status)) { - - Heap -= DataItem->DataSize; - CopyMem (Heap, DataItem->Data.Ptr, DataItem->DataSize); - - DataRecord = &Variable->DataRecord[Variable->DataRecordCount]; - DataRecord->DataType = (EFI_IP6_CONFIG_DATA_TYPE) Index; - DataRecord->DataSize = (UINT32) DataItem->DataSize; - DataRecord->Offset = (UINT16) (Heap - (CHAR8 *) Variable); - - Variable->DataRecordCount++; - } - } - - Variable->Checksum = 0; - Variable->Checksum = (UINT16) ~NetblockChecksum ((UINT8 *) Variable, (UINT32) VarSize); - - Status = gRT->SetVariable ( - VarName, - &gEfiIp6ConfigProtocolGuid, - IP6_CONFIG_VARIABLE_ATTRIBUTE, - VarSize, - Variable - ); - - FreePool (Variable); - - return Status; -} - -/** - The work function for EfiIp6ConfigGetData() to get the interface information - of the communication device this IP6Config instance manages. - - @param[in] Instance Pointer to the IP6 config instance data. - @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. - Ignored if DataSize is 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_SUCCESS The specified configuration data was obtained. - -**/ -EFI_STATUS -Ip6ConfigGetIfInfo ( - IN IP6_CONFIG_INSTANCE *Instance, - IN OUT UINTN *DataSize, - IN VOID *Data OPTIONAL - ) -{ - IP6_SERVICE *IpSb; - UINTN Length; - IP6_CONFIG_DATA_ITEM *Item; - EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo; - UINT32 AddressCount; - UINT32 RouteCount; - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - Length = sizeof (EFI_IP6_CONFIG_INTERFACE_INFO); - - // - // Calculate the required length, add the buffer size for AddressInfo and - // RouteTable - // - Ip6BuildEfiAddressList (IpSb, &AddressCount, NULL); - Ip6BuildEfiRouteTable (IpSb->RouteTable, &RouteCount, NULL); - - Length += AddressCount * sizeof (EFI_IP6_ADDRESS_INFO) + RouteCount * sizeof (EFI_IP6_ROUTE_TABLE); - - if (*DataSize < Length) { - *DataSize = Length; - return EFI_BUFFER_TOO_SMALL; - } - - // - // Copy the fixed size part of the interface info. - // - Item = &Instance->DataItem[Ip6ConfigDataTypeInterfaceInfo]; - IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data; - CopyMem (IfInfo, Item->Data.Ptr, sizeof (EFI_IP6_CONFIG_INTERFACE_INFO)); - - // - // AddressInfo - // - IfInfo->AddressInfo = (EFI_IP6_ADDRESS_INFO *) (IfInfo + 1); - Ip6BuildEfiAddressList (IpSb, &IfInfo->AddressInfoCount, &IfInfo->AddressInfo); - - // - // RouteTable - // - IfInfo->RouteTable = (EFI_IP6_ROUTE_TABLE *) (IfInfo->AddressInfo + IfInfo->AddressInfoCount); - Ip6BuildEfiRouteTable (IpSb->RouteTable, &IfInfo->RouteCount, &IfInfo->RouteTable); - - if (IfInfo->AddressInfoCount == 0) { - IfInfo->AddressInfo = NULL; - } - - if (IfInfo->RouteCount == 0) { - IfInfo->RouteTable = NULL; - } - - return EFI_SUCCESS; -} - -/** - The work function for EfiIp6ConfigSetData() to set the alternative inteface ID - for the communication device managed by this IP6Config instance, if the link local - IPv6 addresses generated from the interface ID based on the default source the - EFI IPv6 Protocol uses is a duplicate address. - - @param[in] Instance Pointer to the IP6 configuration instance data. - @param[in] DataSize Size of the buffer pointed to by Data in bytes. - @param[in] Data The data buffer to set. - - @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type, - 8 bytes. - @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 - network stack was set. - -**/ -EFI_STATUS -Ip6ConfigSetAltIfId ( - IN IP6_CONFIG_INSTANCE *Instance, - IN UINTN DataSize, - IN VOID *Data - ) -{ - EFI_IP6_CONFIG_INTERFACE_ID *OldIfId; - EFI_IP6_CONFIG_INTERFACE_ID *NewIfId; - IP6_CONFIG_DATA_ITEM *DataItem; - - if (DataSize != sizeof (EFI_IP6_CONFIG_INTERFACE_ID)) { - return EFI_BAD_BUFFER_SIZE; - } - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeAltInterfaceId]; - OldIfId = DataItem->Data.AltIfId; - NewIfId = (EFI_IP6_CONFIG_INTERFACE_ID *) Data; - - CopyMem (OldIfId, NewIfId, DataSize); - DataItem->Status = EFI_SUCCESS; - - return EFI_SUCCESS; -} - -/** - The work function for EfiIp6ConfigSetData() to set the general configuration - policy for the EFI IPv6 network stack that is running on the communication device - managed by this IP6Config instance. The policy will affect other configuration settings. - - @param[in] Instance Pointer to the IP6 config instance data. - @param[in] DataSize Size of the buffer pointed to by Data in bytes. - @param[in] Data The data buffer to set. - - @retval EFI_INVALID_PARAMETER The to be set policy is invalid. - @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type. - @retval EFI_ABORTED The new policy equals the current policy. - @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 - network stack was set. - -**/ -EFI_STATUS -Ip6ConfigSetPolicy ( - IN IP6_CONFIG_INSTANCE *Instance, - IN UINTN DataSize, - IN VOID *Data - ) -{ - EFI_IP6_CONFIG_POLICY NewPolicy; - IP6_CONFIG_DATA_ITEM *DataItem; - IP6_SERVICE *IpSb; - - if (DataSize != sizeof (EFI_IP6_CONFIG_POLICY)) { - return EFI_BAD_BUFFER_SIZE; - } - - NewPolicy = *((EFI_IP6_CONFIG_POLICY *) Data); - - if (NewPolicy > Ip6ConfigPolicyAutomatic) { - return EFI_INVALID_PARAMETER; - } - - if (NewPolicy == Instance->Policy) { - - return EFI_ABORTED; - } else { - // - // Clean the ManualAddress, Gateway and DnsServers, shrink the variable - // data size, and fire up all the related events. - // - DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress]; - if (DataItem->Data.Ptr != NULL) { - FreePool (DataItem->Data.Ptr); - } - DataItem->Data.Ptr = NULL; - DataItem->DataSize = 0; - DataItem->Status = EFI_NOT_FOUND; - NetMapIterate (&DataItem->EventMap, Ip6ConfigSignalEvent, NULL); - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeGateway]; - if (DataItem->Data.Ptr != NULL) { - FreePool (DataItem->Data.Ptr); - } - DataItem->Data.Ptr = NULL; - DataItem->DataSize = 0; - DataItem->Status = EFI_NOT_FOUND; - NetMapIterate (&DataItem->EventMap, Ip6ConfigSignalEvent, NULL); - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeDnsServer]; - DataItem->Data.Ptr = NULL; - DataItem->DataSize = 0; - DataItem->Status = EFI_NOT_FOUND; - NetMapIterate (&DataItem->EventMap, Ip6ConfigSignalEvent, NULL); - - if (NewPolicy == Ip6ConfigPolicyManual) { - // - // The policy is changed from automatic to manual. Stop the DHCPv6 process - // and destroy the DHCPv6 child. - // - if (Instance->Dhcp6Handle != NULL) { - Ip6ConfigDestroyDhcp6 (Instance); - } - } - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - Ip6ConfigOnPolicyChanged (IpSb, NewPolicy); - - Instance->Policy = NewPolicy; - - return EFI_SUCCESS; - } -} - -/** - The work function for EfiIp6ConfigSetData() to set 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 a tentative address. - - @param[in] Instance The Instance Pointer to the IP6 config instance data. - @param[in] DataSize Size of the buffer pointed to by Data in bytes. - @param[in] Data The data buffer to set. - - @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type. - @retval EFI_ABORTED The new transmit count equals the current configuration. - @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 - network stack was set. - -**/ -EFI_STATUS -Ip6ConfigSetDadXmits ( - IN IP6_CONFIG_INSTANCE *Instance, - IN UINTN DataSize, - IN VOID *Data - ) -{ - EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS *OldDadXmits; - - if (DataSize != sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS)) { - return EFI_BAD_BUFFER_SIZE; - } - - OldDadXmits = Instance->DataItem[Ip6ConfigDataTypeDupAddrDetectTransmits].Data.DadXmits; - - if ((*(UINT32 *) Data) == OldDadXmits->DupAddrDetectTransmits) { - - return EFI_ABORTED; - } else { - - OldDadXmits->DupAddrDetectTransmits = *((UINT32 *) Data); - return EFI_SUCCESS; - } -} - -/** - The callback function for Ip6SetAddr. The prototype is defined - as IP6_DAD_CALLBACK. It is called after Duplicate Address Detection is performed - for the manual address set by Ip6ConfigSetMaunualAddress. - - @param[in] IsDadPassed If TRUE, Duplicate Address Detection passed. - @param[in] TargetAddress The tentative IPv6 address to be checked. - @param[in] Context Pointer to the IP6 configuration instance data. - -**/ -VOID -Ip6ManualAddrDadCallback ( - IN BOOLEAN IsDadPassed, - IN EFI_IPv6_ADDRESS *TargetAddress, - IN VOID *Context - ) -{ - IP6_CONFIG_INSTANCE *Instance; - UINTN Index; - IP6_CONFIG_DATA_ITEM *Item; - EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddr; - EFI_IP6_CONFIG_MANUAL_ADDRESS *PassedAddr; - UINTN DadPassCount; - UINTN DadFailCount; - IP6_SERVICE *IpSb; - - Instance = (IP6_CONFIG_INSTANCE *) Context; - NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE); - Item = &Instance->DataItem[Ip6ConfigDataTypeManualAddress]; - ManualAddr = NULL; - - if (Item->DataSize == 0) { - return; - } - - for (Index = 0; Index < Item->DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS); Index++) { - // - // Find the original tag used to place into the NET_MAP. - // - ManualAddr = Item->Data.ManualAddress + Index; - if (EFI_IP6_EQUAL (TargetAddress, &ManualAddr->Address)) { - break; - } - } - - ASSERT (Index != Item->DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); - - if (IsDadPassed) { - NetMapInsertTail (&Instance->DadPassedMap, ManualAddr, NULL); - } else { - NetMapInsertTail (&Instance->DadFailedMap, ManualAddr, NULL); - } - - DadPassCount = NetMapGetCount (&Instance->DadPassedMap); - DadFailCount = NetMapGetCount (&Instance->DadFailedMap); - - if ((DadPassCount + DadFailCount) == (Item->DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS))) { - // - // All addresses have finished the configuration process. - // - if (DadFailCount != 0) { - // - // There is at least one duplicate address. - // - FreePool (Item->Data.Ptr); - - Item->DataSize = DadPassCount * sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS); - if (Item->DataSize == 0) { - // - // All failed, bad luck. - // - Item->Data.Ptr = NULL; - Item->Status = EFI_NOT_FOUND; - } else { - // - // Part of addresses are detected to be duplicates, so update the - // data with those passed. - // - PassedAddr = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) AllocatePool (Item->DataSize); - ASSERT (PassedAddr != NULL); - - Item->Data.Ptr = PassedAddr; - Item->Status = EFI_SUCCESS; - - while (!NetMapIsEmpty (&Instance->DadPassedMap)) { - ManualAddr = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) NetMapRemoveHead (&Instance->DadPassedMap, NULL); - CopyMem (PassedAddr, ManualAddr, sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); - - PassedAddr++; - } - - ASSERT ((UINTN) PassedAddr - (UINTN) Item->Data.Ptr == Item->DataSize); - } - } else { - // - // All addresses are valid. - // - Item->Status = EFI_SUCCESS; - } - - // - // Remove the tags we put in the NET_MAPs. - // - while (!NetMapIsEmpty (&Instance->DadFailedMap)) { - NetMapRemoveHead (&Instance->DadFailedMap, NULL); - } - - while (!NetMapIsEmpty (&Instance->DadPassedMap)) { - NetMapRemoveHead (&Instance->DadPassedMap, NULL); - } - - // - // Signal the waiting events. - // - NetMapIterate (&Item->EventMap, Ip6ConfigSignalEvent, NULL); - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - Ip6ConfigWriteConfigData (IpSb->MacString, Instance); - } -} - -/** - The work function for EfiIp6ConfigSetData() to set the station addresses manually - for the EFI IPv6 network stack. It is only configurable when the policy is - Ip6ConfigPolicyManual. - - @param[in] Instance Pointer to the IP6 configuration instance data. - @param[in] DataSize Size of the buffer pointed to by Data in bytes. - @param[in] Data The data buffer to set. - - @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type. - @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set - under the current policy. - @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid. - @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation. - @retval EFI_NOT_READY An asynchrous process is invoked to set the specified - configuration data, and the process is not finished. - @retval EFI_ABORTED The manual addresses to be set equal current - configuration. - @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 - network stack was set. - -**/ -EFI_STATUS -Ip6ConfigSetMaunualAddress ( - IN IP6_CONFIG_INSTANCE *Instance, - IN UINTN DataSize, - IN VOID *Data - ) -{ - EFI_IP6_CONFIG_MANUAL_ADDRESS *NewAddress; - EFI_IP6_CONFIG_MANUAL_ADDRESS *TmpAddress; - IP6_CONFIG_DATA_ITEM *DataItem; - UINTN NewAddressCount; - UINTN Index1; - UINTN Index2; - IP6_SERVICE *IpSb; - IP6_ADDRESS_INFO *CurrentAddrInfo; - IP6_ADDRESS_INFO *Copy; - LIST_ENTRY CurrentSourceList; - UINT32 CurrentSourceCount; - LIST_ENTRY *Entry; - LIST_ENTRY *Entry2; - IP6_INTERFACE *IpIf; - IP6_PREFIX_LIST_ENTRY *PrefixEntry; - EFI_STATUS Status; - BOOLEAN IsUpdated; - - ASSERT (Instance->DataItem[Ip6ConfigDataTypeManualAddress].Status != EFI_NOT_READY); - - if (((DataSize % sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)) != 0) || (DataSize == 0)) { - return EFI_BAD_BUFFER_SIZE; - } - - if (Instance->Policy != Ip6ConfigPolicyManual) { - return EFI_WRITE_PROTECTED; - } - - NewAddressCount = DataSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS); - NewAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) Data; - - for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) { - - if (NetIp6IsLinkLocalAddr (&NewAddress->Address) || - !NetIp6IsValidUnicast (&NewAddress->Address) || - (NewAddress->PrefixLength > 128) - ) { - // - // make sure the IPv6 address is unicast and not link-local address && - // the prefix length is valid. - // - return EFI_INVALID_PARAMETER; - } - - TmpAddress = NewAddress + 1; - for (Index2 = Index1 + 1; Index2 < NewAddressCount; Index2++, TmpAddress++) { - // - // Any two addresses in the array can't be equal. - // - if (EFI_IP6_EQUAL (&TmpAddress->Address, &NewAddress->Address)) { - - return EFI_INVALID_PARAMETER; - } - } - } - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - - // - // Build the current source address list. - // - InitializeListHead (&CurrentSourceList); - CurrentSourceCount = 0; - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE); - - NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) { - CurrentAddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE); - - Copy = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), CurrentAddrInfo); - if (Copy == NULL) { - break; - } - - InsertTailList (&CurrentSourceList, &Copy->Link); - CurrentSourceCount++; - } - } - - // - // Update the value... a long journey starts - // - NewAddress = AllocateCopyPool (DataSize, Data); - if (NewAddress == NULL) { - Ip6RemoveAddr (NULL, &CurrentSourceList, &CurrentSourceCount, NULL, 0); - - return EFI_OUT_OF_RESOURCES; - } - - // - // Store the new data, and init the DataItem status to EFI_NOT_READY because - // we may have an asynchronous configuration process. - // - DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress]; - if (DataItem->Data.Ptr != NULL) { - FreePool (DataItem->Data.Ptr); - } - DataItem->Data.Ptr = NewAddress; - DataItem->DataSize = DataSize; - DataItem->Status = EFI_NOT_READY; - - // - // Trigger DAD, it's an asynchronous process. - // - IsUpdated = FALSE; - - for (Index1 = 0; Index1 < NewAddressCount; Index1++, NewAddress++) { - if (Ip6IsOneOfSetAddress (IpSb, &NewAddress->Address, NULL, &CurrentAddrInfo)) { - ASSERT (CurrentAddrInfo != NULL); - // - // Remove this already existing source address from the CurrentSourceList - // built before. - // - Ip6RemoveAddr ( - NULL, - &CurrentSourceList, - &CurrentSourceCount, - &CurrentAddrInfo->Address, - 128 - ); - - // - // If the new address's prefix length is not specified, just use the previous configured - // prefix length for this address. - // - if (NewAddress->PrefixLength == 0) { - NewAddress->PrefixLength = CurrentAddrInfo->PrefixLength; - } - - // - // This manual address is already in use, see whether prefix length is changed. - // - if (NewAddress->PrefixLength != CurrentAddrInfo->PrefixLength) { - // - // Remove the on-link prefix table, the route entry will be removed - // implicitly. - // - PrefixEntry = Ip6FindPrefixListEntry ( - IpSb, - TRUE, - CurrentAddrInfo->PrefixLength, - &CurrentAddrInfo->Address - ); - if (PrefixEntry != NULL) { - Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE); - } - - // - // Save the prefix length. - // - CurrentAddrInfo->PrefixLength = NewAddress->PrefixLength; - IsUpdated = TRUE; - } - - // - // create a new on-link prefix entry. - // - PrefixEntry = Ip6FindPrefixListEntry ( - IpSb, - TRUE, - NewAddress->PrefixLength, - &NewAddress->Address - ); - if (PrefixEntry == NULL) { - Ip6CreatePrefixListEntry ( - IpSb, - TRUE, - (UINT32) IP6_INFINIT_LIFETIME, - (UINT32) IP6_INFINIT_LIFETIME, - NewAddress->PrefixLength, - &NewAddress->Address - ); - } - - CurrentAddrInfo->IsAnycast = NewAddress->IsAnycast; - // - // Artificially mark this address passed DAD be'coz it is already in use. - // - Ip6ManualAddrDadCallback (TRUE, &NewAddress->Address, Instance); - } else { - // - // A new address. - // - IsUpdated = TRUE; - - // - // Set the new address, this will trigger DAD and activate the address if - // DAD succeeds. - // - Ip6SetAddress ( - IpSb->DefaultInterface, - &NewAddress->Address, - NewAddress->IsAnycast, - NewAddress->PrefixLength, - (UINT32) IP6_INFINIT_LIFETIME, - (UINT32) IP6_INFINIT_LIFETIME, - Ip6ManualAddrDadCallback, - Instance - ); - } - } - - // - // Check the CurrentSourceList, it now contains those addresses currently in - // use and will be removed. - // - IpIf = IpSb->DefaultInterface; - - while (!IsListEmpty (&CurrentSourceList)) { - IsUpdated = TRUE; - - CurrentAddrInfo = NET_LIST_HEAD (&CurrentSourceList, IP6_ADDRESS_INFO, Link); - - // - // This local address is going to be removed, the IP instances that are - // currently using it will be destroyed. - // - Ip6RemoveAddr ( - IpSb, - &IpIf->AddressList, - &IpIf->AddressCount, - &CurrentAddrInfo->Address, - 128 - ); - - // - // Remove the on-link prefix table, the route entry will be removed - // implicitly. - // - PrefixEntry = Ip6FindPrefixListEntry ( - IpSb, - TRUE, - CurrentAddrInfo->PrefixLength, - &CurrentAddrInfo->Address - ); - if (PrefixEntry != NULL) { - Ip6DestroyPrefixListEntry (IpSb, PrefixEntry, TRUE, FALSE); - } - - RemoveEntryList (&CurrentAddrInfo->Link); - FreePool (CurrentAddrInfo); - } - - if (IsUpdated) { - if (DataItem->Status == EFI_NOT_READY) { - // - // If DAD is disabled on this interface, the configuration process is - // actually synchronous, and the data item's status will be changed to - // the final status before we reach here, just check it. - // - Status = EFI_NOT_READY; - } else { - Status = EFI_SUCCESS; - } - } else { - // - // No update is taken, reset the status to success and return EFI_ABORTED. - // - DataItem->Status = EFI_SUCCESS; - Status = EFI_ABORTED; - } - - return Status; -} - -/** - The work function for EfiIp6ConfigSetData() to set the gateway addresses manually - for the EFI IPv6 network stack that is running on the communication device that - this EFI IPv6 Configuration Protocol manages. It is not configurable when the policy is - Ip6ConfigPolicyAutomatic. The gateway addresses must be unicast IPv6 addresses. - - @param[in] Instance The pointer to the IP6 config instance data. - @param[in] DataSize The size of the buffer pointed to by Data in bytes. - @param[in] Data The data buffer to set. This points to an array of - EFI_IPv6_ADDRESS instances. - - @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type. - @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set - under the current policy. - @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to complete the operation. - @retval EFI_ABORTED The manual gateway addresses to be set equal the - current configuration. - @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 - network stack was set. - -**/ -EFI_STATUS -Ip6ConfigSetGateway ( - IN IP6_CONFIG_INSTANCE *Instance, - IN UINTN DataSize, - IN VOID *Data - ) -{ - UINTN Index1; - UINTN Index2; - EFI_IPv6_ADDRESS *OldGateway; - EFI_IPv6_ADDRESS *NewGateway; - UINTN OldGatewayCount; - UINTN NewGatewayCount; - IP6_CONFIG_DATA_ITEM *Item; - BOOLEAN OneRemoved; - BOOLEAN OneAdded; - IP6_SERVICE *IpSb; - IP6_DEFAULT_ROUTER *DefaultRouter; - VOID *Tmp; - - if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) { - return EFI_BAD_BUFFER_SIZE; - } - - if (Instance->Policy != Ip6ConfigPolicyManual) { - return EFI_WRITE_PROTECTED; - } - - NewGateway = (EFI_IPv6_ADDRESS *) Data; - NewGatewayCount = DataSize / sizeof (EFI_IPv6_ADDRESS); - for (Index1 = 0; Index1 < NewGatewayCount; Index1++) { - - if (!NetIp6IsValidUnicast (NewGateway + Index1)) { - - return EFI_INVALID_PARAMETER; - } - - for (Index2 = Index1 + 1; Index2 < NewGatewayCount; Index2++) { - if (EFI_IP6_EQUAL (NewGateway + Index1, NewGateway + Index2)) { - return EFI_INVALID_PARAMETER; - } - } - } - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - Item = &Instance->DataItem[Ip6ConfigDataTypeGateway]; - OldGateway = Item->Data.Gateway; - OldGatewayCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS); - OneRemoved = FALSE; - OneAdded = FALSE; - - if (NewGatewayCount != OldGatewayCount) { - Tmp = AllocatePool (DataSize); - if (Tmp == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } else { - Tmp = NULL; - } - - for (Index1 = 0; Index1 < OldGatewayCount; Index1++) { - // - // Find the gateways that are no long in the new setting and remove them. - // - for (Index2 = 0; Index2 < NewGatewayCount; Index2++) { - if (EFI_IP6_EQUAL (OldGateway + Index1, NewGateway + Index2)) { - OneRemoved = TRUE; - break; - } - } - - if (Index2 == NewGatewayCount) { - // - // Remove this default router. - // - DefaultRouter = Ip6FindDefaultRouter (IpSb, OldGateway + Index1); - if (DefaultRouter != NULL) { - Ip6DestroyDefaultRouter (IpSb, DefaultRouter); - } - } - } - - for (Index1 = 0; Index1 < NewGatewayCount; Index1++) { - - DefaultRouter = Ip6FindDefaultRouter (IpSb, NewGateway + Index1); - if (DefaultRouter == NULL) { - Ip6CreateDefaultRouter (IpSb, NewGateway + Index1, IP6_INF_ROUTER_LIFETIME); - OneAdded = TRUE; - } - } - - if (!OneRemoved && !OneAdded) { - Item->Status = EFI_SUCCESS; - return EFI_ABORTED; - } else { - - if (Tmp != NULL) { - if (Item->Data.Ptr != NULL) { - FreePool (Item->Data.Ptr); - } - Item->Data.Ptr = Tmp; - } - - CopyMem (Item->Data.Ptr, Data, DataSize); - Item->DataSize = DataSize; - Item->Status = EFI_SUCCESS; - return EFI_SUCCESS; - } -} - -/** - The work function for EfiIp6ConfigSetData() to set the DNS server list for the - EFI IPv6 network stack running on the communication device that this EFI IPv6 - Configuration Protocol manages. It is not configurable when the policy is - Ip6ConfigPolicyAutomatic. The DNS server addresses must be unicast IPv6 addresses. - - @param[in] Instance The pointer to the IP6 config instance data. - @param[in] DataSize The size of the buffer pointed to by Data in bytes. - @param[in] Data The data buffer to set, points to an array of - EFI_IPv6_ADDRESS instances. - - @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type. - @retval EFI_WRITE_PROTECTED The specified configuration data cannot be set - under the current policy. - @retval EFI_INVALID_PARAMETER One or more fields in Data is invalid. - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation. - @retval EFI_ABORTED The DNS server addresses to be set equal the current - configuration. - @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 - network stack was set. - -**/ -EFI_STATUS -Ip6ConfigSetDnsServer ( - IN IP6_CONFIG_INSTANCE *Instance, - IN UINTN DataSize, - IN VOID *Data - ) -{ - UINTN OldIndex; - UINTN NewIndex; - EFI_IPv6_ADDRESS *OldDns; - EFI_IPv6_ADDRESS *NewDns; - UINTN OldDnsCount; - UINTN NewDnsCount; - IP6_CONFIG_DATA_ITEM *Item; - BOOLEAN OneAdded; - VOID *Tmp; - - if ((DataSize % sizeof (EFI_IPv6_ADDRESS) != 0) || (DataSize == 0)) { - return EFI_BAD_BUFFER_SIZE; - } - - if (Instance->Policy != Ip6ConfigPolicyManual) { - return EFI_WRITE_PROTECTED; - } - - Item = &Instance->DataItem[Ip6ConfigDataTypeDnsServer]; - NewDns = (EFI_IPv6_ADDRESS *) Data; - OldDns = Item->Data.DnsServers; - NewDnsCount = DataSize / sizeof (EFI_IPv6_ADDRESS); - OldDnsCount = Item->DataSize / sizeof (EFI_IPv6_ADDRESS); - OneAdded = FALSE; - - if (NewDnsCount != OldDnsCount) { - Tmp = AllocatePool (DataSize); - if (Tmp == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } else { - Tmp = NULL; - } - - for (NewIndex = 0; NewIndex < NewDnsCount; NewIndex++) { - - if (!NetIp6IsValidUnicast (NewDns + NewIndex)) { - // - // The dns server address must be unicast. - // - if (Tmp != NULL) { - FreePool (Tmp); - } - return EFI_INVALID_PARAMETER; - } - - if (OneAdded) { - // - // If any address in the new setting is not in the old settings, skip the - // comparision below. - // - continue; - } - - for (OldIndex = 0; OldIndex < OldDnsCount; OldIndex++) { - if (EFI_IP6_EQUAL (NewDns + NewIndex, OldDns + OldIndex)) { - // - // If found break out. - // - break; - } - } - - if (OldIndex == OldDnsCount) { - OneAdded = TRUE; - } - } - - if (!OneAdded && (DataSize == Item->DataSize)) { - // - // No new item is added and the size is the same. - // - Item->Status = EFI_SUCCESS; - return EFI_ABORTED; - } else { - if (Tmp != NULL) { - if (Item->Data.Ptr != NULL) { - FreePool (Item->Data.Ptr); - } - Item->Data.Ptr = Tmp; - } - - CopyMem (Item->Data.Ptr, Data, DataSize); - Item->DataSize = DataSize; - Item->Status = EFI_SUCCESS; - return EFI_SUCCESS; - } -} - -/** - Generate the operational state of the interface this IP6 config instance manages - and output in EFI_IP6_CONFIG_INTERFACE_INFO. - - @param[in] IpSb The pointer to the IP6 service binding instance. - @param[out] IfInfo The pointer to the IP6 configuration interface information structure. - -**/ -VOID -Ip6ConfigInitIfInfo ( - IN IP6_SERVICE *IpSb, - OUT EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo - ) -{ - UnicodeSPrint ( - IfInfo->Name, - sizeof (IfInfo->Name), - L"eth%d", - IpSb->Ip6ConfigInstance.IfIndex - ); - - IfInfo->IfType = IpSb->SnpMode.IfType; - IfInfo->HwAddressSize = IpSb->SnpMode.HwAddressSize; - CopyMem (&IfInfo->HwAddress, &IpSb->SnpMode.CurrentAddress, IfInfo->HwAddressSize); -} - -/** - Parse DHCPv6 reply packet to get the DNS server list. - It is the work function for Ip6ConfigOnDhcp6Reply and Ip6ConfigOnDhcp6Event. - - @param[in] Dhcp6 The pointer to the EFI_DHCP6_PROTOCOL instance. - @param[in, out] Instance The pointer to the IP6 configuration instance data. - @param[in] Reply The pointer to the DHCPv6 reply packet. - - @retval EFI_SUCCESS The DNS server address was retrieved from the reply packet. - @retval EFI_NOT_READY The reply packet does not contain the DNS server option, or - the DNS server address is not valid. - -**/ -EFI_STATUS -Ip6ConfigParseDhcpReply ( - IN EFI_DHCP6_PROTOCOL *Dhcp6, - IN OUT IP6_CONFIG_INSTANCE *Instance, - IN EFI_DHCP6_PACKET *Reply - ) -{ - EFI_STATUS Status; - UINT32 OptCount; - EFI_DHCP6_PACKET_OPTION **OptList; - UINT16 OpCode; - UINT16 Length; - UINTN Index; - UINTN Index2; - EFI_IPv6_ADDRESS *DnsServer; - IP6_CONFIG_DATA_ITEM *Item; - - // - // A DHCPv6 reply packet is received as the response to our InfoRequest - // packet. - // - OptCount = 0; - Status = Dhcp6->Parse (Dhcp6, Reply, &OptCount, NULL); - if (Status != EFI_BUFFER_TOO_SMALL) { - return EFI_NOT_READY; - } - - OptList = AllocatePool (OptCount * sizeof (EFI_DHCP6_PACKET_OPTION *)); - if (OptList == NULL) { - return EFI_NOT_READY; - } - - Status = Dhcp6->Parse (Dhcp6, Reply, &OptCount, OptList); - if (EFI_ERROR (Status)) { - Status = EFI_NOT_READY; - goto ON_EXIT; - } - - Status = EFI_SUCCESS; - - for (Index = 0; Index < OptCount; Index++) { - // - // Go through all the options to check the ones we are interested in. - // The OpCode and Length are in network byte-order and may not be naturally - // aligned. - // - CopyMem (&OpCode, &OptList[Index]->OpCode, sizeof (OpCode)); - OpCode = NTOHS (OpCode); - - if (OpCode == DHCP6_OPT_DNS_SERVERS) { - CopyMem (&Length, &OptList[Index]->OpLen, sizeof (Length)); - Length = NTOHS (Length); - - if ((Length == 0) || ((Length % sizeof (EFI_IPv6_ADDRESS)) != 0)) { - // - // The length should be a multiple of 16 bytes. - // - Status = EFI_NOT_READY; - break; - } - - // - // Validate the DnsServers: whether they are unicast addresses. - // - DnsServer = (EFI_IPv6_ADDRESS *) OptList[Index]->Data; - for (Index2 = 0; Index2 < Length / sizeof (EFI_IPv6_ADDRESS); Index2++) { - if (!NetIp6IsValidUnicast (DnsServer)) { - Status = EFI_NOT_READY; - goto ON_EXIT; - } - - DnsServer++; - } - - Item = &Instance->DataItem[Ip6ConfigDataTypeDnsServer]; - - if (Item->DataSize != Length) { - if (Item->Data.Ptr != NULL) { - FreePool (Item->Data.Ptr); - } - - Item->Data.Ptr = AllocatePool (Length); - ASSERT (Item->Data.Ptr != NULL); - } - - CopyMem (Item->Data.Ptr, OptList[Index]->Data, Length); - Item->DataSize = Length; - Item->Status = EFI_SUCCESS; - - // - // Signal the waiting events. - // - NetMapIterate (&Item->EventMap, Ip6ConfigSignalEvent, NULL); - - break; - } - } - -ON_EXIT: - - FreePool (OptList); - return Status; -} - -/** - The callback function for Ip6SetAddr. The prototype is defined - as IP6_DAD_CALLBACK. It is called after Duplicate Address Detection is performed - on the tentative address by DHCPv6 in Ip6ConfigOnDhcp6Event(). - - @param[in] IsDadPassed If TRUE, Duplicate Address Detection passes. - @param[in] TargetAddress The tentative IPv6 address to be checked. - @param[in] Context Pointer to the IP6 configuration instance data. - -**/ -VOID -Ip6ConfigSetStatefulAddrCallback ( - IN BOOLEAN IsDadPassed, - IN EFI_IPv6_ADDRESS *TargetAddress, - IN VOID *Context - ) -{ - IP6_CONFIG_INSTANCE *Instance; - - Instance = (IP6_CONFIG_INSTANCE *) Context; - NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE); - - // - // We should record the addresses that fail the DAD, and DECLINE them. - // - if (IsDadPassed) { - // - // Decrease the count, no interests in those passed DAD. - // - if (Instance->FailedIaAddressCount > 0 ) { - Instance->FailedIaAddressCount--; - } - } else { - // - // Record it. - // - IP6_COPY_ADDRESS (Instance->DeclineAddress + Instance->DeclineAddressCount, TargetAddress); - Instance->DeclineAddressCount++; - } - - if (Instance->FailedIaAddressCount == Instance->DeclineAddressCount) { - // - // The checking on all addresses are finished. - // - if (Instance->DeclineAddressCount != 0) { - // - // Decline those duplicates. - // - if (Instance->Dhcp6 != NULL) { - Instance->Dhcp6->Decline ( - Instance->Dhcp6, - Instance->DeclineAddressCount, - Instance->DeclineAddress - ); - } - } - - if (Instance->DeclineAddress != NULL) { - FreePool (Instance->DeclineAddress); - } - Instance->DeclineAddress = NULL; - Instance->DeclineAddressCount = 0; - } -} - -/** - The event handle routine when DHCPv6 process is finished or is updated. - - @param[in] Event Not used. - @param[in] Context The pointer to the IP6 configuration instance data. - -**/ -VOID -EFIAPI -Ip6ConfigOnDhcp6Event ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - IP6_CONFIG_INSTANCE *Instance; - EFI_DHCP6_PROTOCOL *Dhcp6; - EFI_STATUS Status; - EFI_DHCP6_MODE_DATA Dhcp6ModeData; - EFI_DHCP6_IA *Ia; - EFI_DHCP6_IA_ADDRESS *IaAddr; - UINT32 Index; - IP6_SERVICE *IpSb; - IP6_ADDRESS_INFO *AddrInfo; - IP6_INTERFACE *IpIf; - - Instance = (IP6_CONFIG_INSTANCE *) Context; - - if ((Instance->Policy != Ip6ConfigPolicyAutomatic) || Instance->OtherInfoOnly) { - // - // IPv6 is not operating in the automatic policy now or - // the DHCPv6 information request message exchange is aborted. - // - return ; - } - - // - // The stateful address autoconfiguration is done or updated. - // - Dhcp6 = Instance->Dhcp6; - - Status = Dhcp6->GetModeData (Dhcp6, &Dhcp6ModeData, NULL); - if (EFI_ERROR (Status)) { - return ; - } - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - IpIf = IpSb->DefaultInterface; - Ia = Dhcp6ModeData.Ia; - IaAddr = Ia->IaAddress; - - if (Instance->DeclineAddress != NULL) { - FreePool (Instance->DeclineAddress); - } - - Instance->DeclineAddress = (EFI_IPv6_ADDRESS *) AllocatePool (Ia->IaAddressCount * sizeof (EFI_IPv6_ADDRESS)); - if (Instance->DeclineAddress == NULL) { - goto ON_EXIT; - } - - Instance->FailedIaAddressCount = Ia->IaAddressCount; - Instance->DeclineAddressCount = 0; - - for (Index = 0; Index < Ia->IaAddressCount; Index++, IaAddr++) { - if (Ia->IaAddress[Index].ValidLifetime != 0 && Ia->State == Dhcp6Bound) { - // - // Set this address, either it's a new address or with updated lifetimes. - // An appropriate prefix length will be set. - // - Ip6SetAddress ( - IpIf, - &IaAddr->IpAddress, - FALSE, - 0, - IaAddr->ValidLifetime, - IaAddr->PreferredLifetime, - Ip6ConfigSetStatefulAddrCallback, - Instance - ); - } else { - // - // discard this address, artificially decrease the count as if this address - // passed DAD. - // - if (Ip6IsOneOfSetAddress (IpSb, &IaAddr->IpAddress, NULL, &AddrInfo)) { - ASSERT (AddrInfo != NULL); - Ip6RemoveAddr ( - IpSb, - &IpIf->AddressList, - &IpIf->AddressCount, - &AddrInfo->Address, - AddrInfo->PrefixLength - ); - } - - if (Instance->FailedIaAddressCount > 0) { - Instance->FailedIaAddressCount--; - } - } - } - - // - // Parse the Reply packet to get the options we need. - // - if (Dhcp6ModeData.Ia->ReplyPacket != NULL) { - Ip6ConfigParseDhcpReply (Dhcp6, Instance, Dhcp6ModeData.Ia->ReplyPacket); - } - -ON_EXIT: - - FreePool (Dhcp6ModeData.ClientId); - FreePool (Dhcp6ModeData.Ia); -} - -/** - The event process routine when the DHCPv6 server is answered with a reply packet - for an information request. - - @param[in] This Points to the EFI_DHCP6_PROTOCOL. - @param[in] Context The pointer to the IP6 configuration instance data. - @param[in] Packet The DHCPv6 reply packet. - - @retval EFI_SUCCESS The DNS server address was retrieved from the reply packet. - @retval EFI_NOT_READY The reply packet does not contain the DNS server option, or - the DNS server address is not valid. - -**/ -EFI_STATUS -EFIAPI -Ip6ConfigOnDhcp6Reply ( - IN EFI_DHCP6_PROTOCOL *This, - IN VOID *Context, - IN EFI_DHCP6_PACKET *Packet - ) -{ - return Ip6ConfigParseDhcpReply (This, (IP6_CONFIG_INSTANCE *) Context, Packet); -} - -/** - The event process routine when the DHCPv6 service binding protocol is installed - in the system. - - @param[in] Event Not used. - @param[in] Context The pointer to the IP6 config instance data. - -**/ -VOID -EFIAPI -Ip6ConfigOnDhcp6SbInstalled ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - IP6_CONFIG_INSTANCE *Instance; - - Instance = (IP6_CONFIG_INSTANCE *) Context; - - if ((Instance->Dhcp6Handle != NULL) || (Instance->Policy != Ip6ConfigPolicyAutomatic)) { - // - // The DHCP6 child is already created or the policy is no longer AUTOMATIC. - // - return ; - } - - Ip6ConfigStartStatefulAutoConfig (Instance, Instance->OtherInfoOnly); -} - -/** - 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 that is running on the communication device that this EFI IPv6 - Configuration Protocol instance manages. - - DataSize is used to calculate the count of structure instances in the Data for - a DataType in which 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 - performing 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 wanting 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 obtain the configuration data and 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 The 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 was set successfully. - @retval EFI_INVALID_PARAMETER One or more of the following are TRUE: - - This is NULL. - - Data is NULL. - - One or more fields in Data 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 cannot 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 was 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6ConfigSetData ( - IN EFI_IP6_CONFIG_PROTOCOL *This, - IN EFI_IP6_CONFIG_DATA_TYPE DataType, - IN UINTN DataSize, - IN VOID *Data - ) -{ - EFI_TPL OldTpl; - EFI_STATUS Status; - IP6_CONFIG_INSTANCE *Instance; - IP6_SERVICE *IpSb; - - if ((This == NULL) || (Data == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (DataType >= Ip6ConfigDataTypeMaximum) { - return EFI_UNSUPPORTED; - } - - Instance = IP6_CONFIG_INSTANCE_FROM_PROTOCOL (This); - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Status = Instance->DataItem[DataType].Status; - if (Status != EFI_NOT_READY) { - - if (Instance->DataItem[DataType].SetData == NULL) { - // - // This type of data is readonly. - // - Status = EFI_WRITE_PROTECTED; - } else { - - Status = Instance->DataItem[DataType].SetData (Instance, DataSize, Data); - if (!EFI_ERROR (Status)) { - // - // Fire up the events registered with this type of data. - // - NetMapIterate (&Instance->DataItem[DataType].EventMap, Ip6ConfigSignalEvent, NULL); - Ip6ConfigWriteConfigData (IpSb->MacString, Instance); - } else if (Status == EFI_ABORTED) { - // - // The SetData is aborted because the data to set is the same with - // the one maintained. - // - Status = EFI_SUCCESS; - NetMapIterate (&Instance->DataItem[DataType].EventMap, Ip6ConfigSignalEvent, NULL); - } - } - } else { - // - // Another asynchornous process is on the way. - // - Status = EFI_ACCESS_DENIED; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Get the configuration data for the EFI IPv6 network stack running on the communication - device that 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 that this EFI IPv6 Configuration Protocol instance - manages. - - The caller is responsible for allocating the buffer used to return the specified - configuration data. 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 - asynchronous configuration process already in progress. 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. - This is an optional parameter that may be NULL. - - @retval EFI_SUCCESS The specified configuration data was obtained 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 - asynchronous configuration process already in progress. - @retval EFI_NOT_FOUND The specified configuration data is not found. - -**/ -EFI_STATUS -EFIAPI -EfiIp6ConfigGetData ( - IN EFI_IP6_CONFIG_PROTOCOL *This, - IN EFI_IP6_CONFIG_DATA_TYPE DataType, - IN OUT UINTN *DataSize, - IN VOID *Data OPTIONAL - ) -{ - EFI_TPL OldTpl; - EFI_STATUS Status; - IP6_CONFIG_INSTANCE *Instance; - IP6_CONFIG_DATA_ITEM *DataItem; - - if ((This == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data == NULL))) { - return EFI_INVALID_PARAMETER; - } - - if (DataType >= Ip6ConfigDataTypeMaximum) { - return EFI_NOT_FOUND; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = IP6_CONFIG_INSTANCE_FROM_PROTOCOL (This); - DataItem = &Instance->DataItem[DataType]; - - Status = Instance->DataItem[DataType].Status; - if (!EFI_ERROR (Status)) { - - if (DataItem->GetData != NULL) { - - Status = DataItem->GetData (Instance, DataSize, Data); - } else if (*DataSize < Instance->DataItem[DataType].DataSize) { - // - // Update the buffer length. - // - *DataSize = Instance->DataItem[DataType].DataSize; - Status = EFI_BUFFER_TOO_SMALL; - } else { - - *DataSize = Instance->DataItem[DataType].DataSize; - CopyMem (Data, Instance->DataItem[DataType].Data.Ptr, *DataSize); - } - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Register an event that is 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 performed. An event can be registered - for a different DataType simultaneously. The caller is responsible for determining - which type of configuration data causes the signaling of the event in such an event. - - @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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6ConfigRegisterDataNotify ( - IN EFI_IP6_CONFIG_PROTOCOL *This, - IN EFI_IP6_CONFIG_DATA_TYPE DataType, - IN EFI_EVENT Event - ) -{ - EFI_TPL OldTpl; - EFI_STATUS Status; - IP6_CONFIG_INSTANCE *Instance; - NET_MAP *EventMap; - NET_MAP_ITEM *Item; - - if ((This == NULL) || (Event == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (DataType >= Ip6ConfigDataTypeMaximum) { - return EFI_UNSUPPORTED; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = IP6_CONFIG_INSTANCE_FROM_PROTOCOL (This); - EventMap = &Instance->DataItem[DataType].EventMap; - - // - // Check whether this event is already registered for this DataType. - // - Item = NetMapFindKey (EventMap, Event); - if (Item == NULL) { - - Status = NetMapInsertTail (EventMap, Event, NULL); - - if (EFI_ERROR (Status)) { - - Status = EFI_OUT_OF_RESOURCES; - } - - } else { - - Status = EFI_ACCESS_DENIED; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Remove a previously registered event for the specified configuration data. - - @param This The pointer to the EFI_IP6_CONFIG_PROTOCOL instance. - @param DataType The type of data to remove from the previously - registered event. - @param Event The event to be unregistered. - - @retval EFI_SUCCESS The event registered for the specified - configuration data was 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6ConfigUnregisterDataNotify ( - IN EFI_IP6_CONFIG_PROTOCOL *This, - IN EFI_IP6_CONFIG_DATA_TYPE DataType, - IN EFI_EVENT Event - ) -{ - EFI_TPL OldTpl; - EFI_STATUS Status; - IP6_CONFIG_INSTANCE *Instance; - NET_MAP_ITEM *Item; - - if ((This == NULL) || (Event == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (DataType >= Ip6ConfigDataTypeMaximum) { - return EFI_NOT_FOUND; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = IP6_CONFIG_INSTANCE_FROM_PROTOCOL (This); - - Item = NetMapFindKey (&Instance->DataItem[DataType].EventMap, Event); - if (Item != NULL) { - - NetMapRemoveItem (&Instance->DataItem[DataType].EventMap, Item, NULL); - Status = EFI_SUCCESS; - } else { - - Status = EFI_NOT_FOUND; - } - - gBS->RestoreTPL (OldTpl); - - return Status; -} - -/** - Initialize an IP6_CONFIG_INSTANCE. - - @param[out] Instance The buffer of IP6_CONFIG_INSTANCE to be initialized. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation. - @retval EFI_SUCCESS The IP6_CONFIG_INSTANCE initialized successfully. - -**/ -EFI_STATUS -Ip6ConfigInitInstance ( - OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - IP6_SERVICE *IpSb; - IP6_CONFIG_INSTANCE *TmpInstance; - LIST_ENTRY *Entry; - EFI_STATUS Status; - UINTN Index; - UINT16 IfIndex; - IP6_CONFIG_DATA_ITEM *DataItem; - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - - Instance->Signature = IP6_CONFIG_INSTANCE_SIGNATURE; - - // - // Determine the index of this interface. - // - IfIndex = 0; - NET_LIST_FOR_EACH (Entry, &mIp6ConfigInstanceList) { - TmpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_CONFIG_INSTANCE, Link, IP6_CONFIG_INSTANCE_SIGNATURE); - - if (TmpInstance->IfIndex > IfIndex) { - // - // There is a sequence hole because some interface is down. - // - break; - } - - IfIndex++; - } - - Instance->IfIndex = IfIndex; - NetListInsertBefore (Entry, &Instance->Link); - - for (Index = 0; Index < Ip6ConfigDataTypeMaximum; Index++) { - // - // Initialize the event map for each data item. - // - NetMapInit (&Instance->DataItem[Index].EventMap); - } - - // - // Initialize the NET_MAPs used for DAD on manually configured source addresses. - // - NetMapInit (&Instance->DadFailedMap); - NetMapInit (&Instance->DadPassedMap); - - // - // Initialize each data type: associate storage and set data size for the - // fixed size data types, hook the SetData function, set the data attribute. - // - DataItem = &Instance->DataItem[Ip6ConfigDataTypeInterfaceInfo]; - DataItem->GetData = Ip6ConfigGetIfInfo; - DataItem->Data.Ptr = &Instance->InterfaceInfo; - DataItem->DataSize = sizeof (Instance->InterfaceInfo); - SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED | DATA_ATTRIB_VOLATILE); - Ip6ConfigInitIfInfo (IpSb, &Instance->InterfaceInfo); - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeAltInterfaceId]; - DataItem->SetData = Ip6ConfigSetAltIfId; - DataItem->Data.Ptr = &Instance->AltIfId; - DataItem->DataSize = sizeof (Instance->AltIfId); - DataItem->Status = EFI_NOT_FOUND; - SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED); - - DataItem = &Instance->DataItem[Ip6ConfigDataTypePolicy]; - DataItem->SetData = Ip6ConfigSetPolicy; - DataItem->Data.Ptr = &Instance->Policy; - DataItem->DataSize = sizeof (Instance->Policy); - Instance->Policy = Ip6ConfigPolicyManual; - SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED); - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeDupAddrDetectTransmits]; - DataItem->SetData = Ip6ConfigSetDadXmits; - DataItem->Data.Ptr = &Instance->DadXmits; - DataItem->DataSize = sizeof (Instance->DadXmits); - Instance->DadXmits.DupAddrDetectTransmits = IP6_CONFIG_DEFAULT_DAD_XMITS; - SET_DATA_ATTRIB (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED); - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeManualAddress]; - DataItem->SetData = Ip6ConfigSetMaunualAddress; - DataItem->Status = EFI_NOT_FOUND; - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeGateway]; - DataItem->SetData = Ip6ConfigSetGateway; - DataItem->Status = EFI_NOT_FOUND; - - DataItem = &Instance->DataItem[Ip6ConfigDataTypeDnsServer]; - DataItem->SetData = Ip6ConfigSetDnsServer; - DataItem->Status = EFI_NOT_FOUND; - - // - // Create the event used for DHCP. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - Ip6ConfigOnDhcp6Event, - Instance, - &Instance->Dhcp6Event - ); - ASSERT_EFI_ERROR (Status); - - Instance->Configured = TRUE; - - // - // Try to read the config data from NV variable. - // - Status = Ip6ConfigReadConfigData (IpSb->MacString, Instance); - if (Status == EFI_NOT_FOUND) { - // - // The NV variable is not set, so generate a random IAID, and write down the - // fresh new configuration as the NV variable now. - // - Instance->IaId = NET_RANDOM (NetRandomInitSeed ()); - - for (Index = 0; Index < IpSb->SnpMode.HwAddressSize; Index++) { - Instance->IaId |= (IpSb->SnpMode.CurrentAddress.Addr[Index] << ((Index << 3) & 31)); - } - - Ip6ConfigWriteConfigData (IpSb->MacString, Instance); - } else if (EFI_ERROR (Status)) { - return Status; - } - - Instance->Ip6Config.SetData = EfiIp6ConfigSetData; - Instance->Ip6Config.GetData = EfiIp6ConfigGetData; - Instance->Ip6Config.RegisterDataNotify = EfiIp6ConfigRegisterDataNotify; - Instance->Ip6Config.UnregisterDataNotify = EfiIp6ConfigUnregisterDataNotify; - - - // - // Publish the IP6 configuration form - // - return Ip6ConfigFormInit (Instance); -} - -/** - Release an IP6_CONFIG_INSTANCE. - - @param[in, out] Instance The buffer of IP6_CONFIG_INSTANCE to be freed. - -**/ -VOID -Ip6ConfigCleanInstance ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - UINTN Index; - IP6_CONFIG_DATA_ITEM *DataItem; - - if (Instance->DeclineAddress != NULL) { - FreePool (Instance->DeclineAddress); - } - - if (!Instance->Configured) { - return ; - } - - if (Instance->Dhcp6Handle != NULL) { - - Ip6ConfigDestroyDhcp6 (Instance); - } - - // - // Close the event. - // - if (Instance->Dhcp6Event != NULL) { - gBS->CloseEvent (Instance->Dhcp6Event); - } - - NetMapClean (&Instance->DadPassedMap); - NetMapClean (&Instance->DadFailedMap); - - for (Index = 0; Index < Ip6ConfigDataTypeMaximum; Index++) { - - DataItem = &Instance->DataItem[Index]; - - if (!DATA_ATTRIB_SET (DataItem->Attribute, DATA_ATTRIB_SIZE_FIXED)) { - if (DataItem->Data.Ptr != NULL) { - FreePool (DataItem->Data.Ptr); - } - DataItem->Data.Ptr = NULL; - DataItem->DataSize = 0; - } - - NetMapClean (&Instance->DataItem[Index].EventMap); - } - - Ip6ConfigFormUnload (Instance); - - RemoveEntryList (&Instance->Link); -} - -/** - Destroy the Dhcp6 child in IP6_CONFIG_INSTANCE and release the resources. - - @param[in, out] Instance The buffer of IP6_CONFIG_INSTANCE to be freed. - - @retval EFI_SUCCESS The child was successfully destroyed. - @retval Others Failed to destroy the child. - -**/ -EFI_STATUS -Ip6ConfigDestroyDhcp6 ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - IP6_SERVICE *IpSb; - EFI_STATUS Status; - EFI_DHCP6_PROTOCOL *Dhcp6; - - Dhcp6 = Instance->Dhcp6; - ASSERT (Dhcp6 != NULL); - - Dhcp6->Stop (Dhcp6); - Dhcp6->Configure (Dhcp6, NULL); - Instance->Dhcp6 = NULL; - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - - // - // Close DHCPv6 protocol and destroy the child. - // - Status = gBS->CloseProtocol ( - Instance->Dhcp6Handle, - &gEfiDhcp6ProtocolGuid, - IpSb->Image, - IpSb->Controller - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = NetLibDestroyServiceChild ( - IpSb->Controller, - IpSb->Image, - &gEfiDhcp6ServiceBindingProtocolGuid, - Instance->Dhcp6Handle - ); - - Instance->Dhcp6Handle = NULL; - - return Status; -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.h b/Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.h deleted file mode 100644 index 3a6e8ad4d1..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigImpl.h +++ /dev/null @@ -1,313 +0,0 @@ -/** @file - Definitions for EFI IPv6 Configuartion Protocol implementation. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __IP6_CONFIG_IMPL_H__ -#define __IP6_CONFIG_IMPL_H__ - -#define IP6_CONFIG_INSTANCE_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'C') -#define IP6_FORM_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('I', 'F', 'C', 'I') -#define IP6_CONFIG_VARIABLE_ATTRIBUTE (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) - -#define IP6_CONFIG_DEFAULT_DAD_XMITS 1 - -#define DATA_ATTRIB_SIZE_FIXED 0x1 -#define DATA_ATTRIB_VOLATILE 0x2 - -#define DATA_ATTRIB_SET(Attrib, Bits) (BOOLEAN)((Attrib) & (Bits)) -#define SET_DATA_ATTRIB(Attrib, Bits) ((Attrib) |= (Bits)) - -typedef struct _IP6_CONFIG_INSTANCE IP6_CONFIG_INSTANCE; - -#define IP6_CONFIG_INSTANCE_FROM_PROTOCOL(Proto) \ - CR ((Proto), \ - IP6_CONFIG_INSTANCE, \ - Ip6Config, \ - IP6_CONFIG_INSTANCE_SIGNATURE \ - ) - - -#define IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK(Callback) \ - CR ((Callback), \ - IP6_CONFIG_INSTANCE, \ - CallbackInfo, \ - IP6_CONFIG_INSTANCE_SIGNATURE \ - ) - -#define IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE(Instance) \ - CR ((Instance), \ - IP6_SERVICE, \ - Ip6ConfigInstance, \ - IP6_SERVICE_SIGNATURE \ - ) - -#define IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS(ConfigAccess) \ - CR ((ConfigAccess), \ - IP6_FORM_CALLBACK_INFO, \ - HiiConfigAccess, \ - IP6_FORM_CALLBACK_INFO_SIGNATURE \ - ) - -/** - The prototype of work function for EfiIp6ConfigSetData(). - - @param[in] Instance The pointer to the IP6 config instance data. - @param[in] DataSize In bytes, the size of the buffer pointed to by Data. - @param[in] Data The data buffer to set. - - @retval EFI_BAD_BUFFER_SIZE The DataSize does not match the size of the type, - 8 bytes. - @retval EFI_SUCCESS The specified configuration data for the EFI IPv6 - network stack was set successfully. - -**/ -typedef -EFI_STATUS -(*IP6_CONFIG_SET_DATA) ( - IN IP6_CONFIG_INSTANCE *Instance, - IN UINTN DataSize, - IN VOID *Data - ); - -/** - The prototype of work function for EfiIp6ConfigGetData(). - - @param[in] Instance The pointer to the IP6 config instance data. - @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. - Ignored if DataSize is 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_SUCCESS The specified configuration data was obtained successfully. - -**/ -typedef -EFI_STATUS -(*IP6_CONFIG_GET_DATA) ( - IN IP6_CONFIG_INSTANCE *Instance, - IN OUT UINTN *DataSize, - IN VOID *Data OPTIONAL - ); - -typedef union { - VOID *Ptr; - EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo; - EFI_IP6_CONFIG_INTERFACE_ID *AltIfId; - EFI_IP6_CONFIG_POLICY *Policy; - EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS *DadXmits; - EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress; - EFI_IPv6_ADDRESS *Gateway; - EFI_IPv6_ADDRESS *DnsServers; -} IP6_CONFIG_DATA; - -typedef struct { - IP6_CONFIG_SET_DATA SetData; - IP6_CONFIG_GET_DATA GetData; - EFI_STATUS Status; - UINT8 Attribute; - NET_MAP EventMap; - IP6_CONFIG_DATA Data; - UINTN DataSize; -} IP6_CONFIG_DATA_ITEM; - -typedef struct { - UINT16 Offset; - UINT32 DataSize; - EFI_IP6_CONFIG_DATA_TYPE DataType; -} IP6_CONFIG_DATA_RECORD; - -#pragma pack(1) - -// -// heap data that contains the data for each data record. -// -// BOOLEAN IsAltIfIdSet; -// EFI_IP6_CONFIG_POLICY Policy; -// EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits; -// UINT32 ManualaddressCount; -// UINT32 GatewayCount; -// UINT32 DnsServersCount; -// EFI_IP6_CONFIG_INTERFACE_ID AltIfId; -// EFI_IP6_CONFIG_MANUAL_ADDRESS ManualAddress[]; -// EFI_IPv6_ADDRESS Gateway[]; -// EFI_IPv6_ADDRESS DnsServers[]; -// -typedef struct { - UINT32 IaId; - UINT16 Checksum; - UINT16 DataRecordCount; - IP6_CONFIG_DATA_RECORD DataRecord[1]; -} IP6_CONFIG_VARIABLE; - -#pragma pack() - -typedef struct { - LIST_ENTRY Link; - EFI_IP6_ADDRESS_INFO AddrInfo; -} IP6_ADDRESS_INFO_ENTRY; - -typedef struct { - EFI_IP6_CONFIG_POLICY Policy; ///< manual or automatic - EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadTransmitCount; ///< dad transmits count - EFI_IP6_CONFIG_INTERFACE_ID InterfaceId; ///< alternative interface id - LIST_ENTRY ManualAddress; ///< IP addresses - UINT32 ManualAddressCount; ///< IP addresses count - LIST_ENTRY GatewayAddress; ///< Gateway address - UINT32 GatewayAddressCount; ///< Gateway address count - LIST_ENTRY DnsAddress; ///< DNS server address - UINT32 DnsAddressCount; ///< DNS server address count -} IP6_CONFIG_NVDATA; - -typedef struct _IP6_FORM_CALLBACK_INFO { - UINT32 Signature; - EFI_HANDLE ChildHandle; - EFI_HII_CONFIG_ACCESS_PROTOCOL HiiConfigAccess; - EFI_DEVICE_PATH_PROTOCOL *HiiVendorDevicePath; - EFI_HII_HANDLE RegisteredHandle; -} IP6_FORM_CALLBACK_INFO; - -struct _IP6_CONFIG_INSTANCE { - UINT32 Signature; - BOOLEAN Configured; - LIST_ENTRY Link; - UINT16 IfIndex; - - EFI_IP6_CONFIG_INTERFACE_INFO InterfaceInfo; - EFI_IP6_CONFIG_INTERFACE_ID AltIfId; - EFI_IP6_CONFIG_POLICY Policy; - EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits; - - IP6_CONFIG_DATA_ITEM DataItem[Ip6ConfigDataTypeMaximum]; - NET_MAP DadFailedMap; - NET_MAP DadPassedMap; - - EFI_IP6_CONFIG_PROTOCOL Ip6Config; - - EFI_EVENT Dhcp6SbNotifyEvent; - VOID *Registration; - EFI_HANDLE Dhcp6Handle; - EFI_DHCP6_PROTOCOL *Dhcp6; - BOOLEAN OtherInfoOnly; - UINT32 IaId; - EFI_EVENT Dhcp6Event; - UINT32 FailedIaAddressCount; - EFI_IPv6_ADDRESS *DeclineAddress; - UINT32 DeclineAddressCount; - - IP6_FORM_CALLBACK_INFO CallbackInfo; - IP6_CONFIG_NVDATA Ip6NvData; -}; - -/** - Read the configuration data from variable storage according to the VarName and - gEfiIp6ConfigProtocolGuid. It checks the integrity of variable data. If the - data is corrupted, it clears the variable data to ZERO. Othewise, it outputs the - configuration data to IP6_CONFIG_INSTANCE. - - @param[in] VarName The pointer to the variable name - @param[in, out] Instance The pointer to the IP6 config instance data. - - @retval EFI_NOT_FOUND The variable can not be found or already corrupted. - @retval EFI_OUT_OF_RESOURCES Fail to allocate resource to complete the operation. - @retval EFI_SUCCESS The configuration data was retrieved successfully. - -**/ -EFI_STATUS -Ip6ConfigReadConfigData ( - IN CHAR16 *VarName, - IN OUT IP6_CONFIG_INSTANCE *Instance - ); - -/** - The event process routine when the DHCPv6 server is answered with a reply packet - for an information request. - - @param[in] This Points to the EFI_DHCP6_PROTOCOL. - @param[in] Context The pointer to the IP6 configuration instance data. - @param[in] Packet The DHCPv6 reply packet. - - @retval EFI_SUCCESS The DNS server address was retrieved from the reply packet. - @retval EFI_NOT_READY The reply packet does not contain the DNS server option, or - the DNS server address is not valid. - -**/ -EFI_STATUS -EFIAPI -Ip6ConfigOnDhcp6Reply ( - IN EFI_DHCP6_PROTOCOL *This, - IN VOID *Context, - IN EFI_DHCP6_PACKET *Packet - ); - -/** - The work function to trigger the DHCPv6 process to perform a stateful autoconfiguration. - - @param[in] Instance Pointer to the IP6 config instance data. - @param[in] OtherInfoOnly If FALSE, get stateful address and other information - via DHCPv6. Otherwise, only get the other information. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_UNSUPPORTED The DHCP6 driver is not available. - -**/ -EFI_STATUS -Ip6ConfigStartStatefulAutoConfig ( - IN IP6_CONFIG_INSTANCE *Instance, - IN BOOLEAN OtherInfoOnly - ); - -/** - Initialize an IP6_CONFIG_INSTANCE. - - @param[out] Instance The buffer of IP6_CONFIG_INSTANCE to be initialized. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation. - @retval EFI_SUCCESS The IP6_CONFIG_INSTANCE initialized successfully. - -**/ -EFI_STATUS -Ip6ConfigInitInstance ( - OUT IP6_CONFIG_INSTANCE *Instance - ); - -/** - Release an IP6_CONFIG_INSTANCE. - - @param[in, out] Instance The buffer of IP6_CONFIG_INSTANCE to be freed. - -**/ -VOID -Ip6ConfigCleanInstance ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ); - -/** - Destroy the Dhcp6 child in IP6_CONFIG_INSTANCE and release the resources. - - @param[in, out] Instance The buffer of IP6_CONFIG_INSTANCE to be freed. - - @retval EFI_SUCCESS The child was successfully destroyed. - @retval Others Failed to destroy the child. - -**/ -EFI_STATUS -Ip6ConfigDestroyDhcp6 ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.c b/Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.c deleted file mode 100644 index 1b878a56a3..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.c +++ /dev/null @@ -1,2095 +0,0 @@ -/** @file - Helper functions for configuring or obtaining the parameters relating to IP6. - - Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -CHAR16 mIp6ConfigStorageName[] = L"IP6_CONFIG_IFR_NVDATA"; - -/** - The notify function of create event when performing a manual configuration. - - @param[in] Event The pointer of Event. - @param[in] Context The pointer of Context. - -**/ -VOID -EFIAPI -Ip6ConfigManualAddressNotify ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - *((BOOLEAN *) Context) = TRUE; -} - -/** - Get the configuration data for the EFI IPv6 network stack running on the - communication. It is a help function to the call EfiIp6ConfigGetData(). - - @param[in] Ip6Config The pointer to the EFI_IP6_CONFIG_PROTOCOL instance. - @param[in] DataType The type of data to get. - @param[out] DataSize The size of buffer required in bytes. - @param[out] Data The data buffer in which the configuration data is returned. The - type of the data buffer associated with the DataType. - It is the caller's responsibility to free the resource. - - @retval EFI_SUCCESS The specified configuration data was obtained successfully. - @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE: - - Ip6Config is NULL or invalid. - - DataSize is NULL. - - Data is NULL. - @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resources. - @retval EFI_NOT_READY The specified configuration data is not ready due to an - asynchronous configuration process already in progress. - @retval EFI_NOT_FOUND The specified configuration data was not found. - -**/ -EFI_STATUS -Ip6ConfigNvGetData ( - IN EFI_IP6_CONFIG_PROTOCOL *Ip6Config, - IN EFI_IP6_CONFIG_DATA_TYPE DataType, - OUT UINTN *DataSize, - OUT VOID **Data - ) -{ - UINTN BufferSize; - VOID *Buffer; - EFI_STATUS Status; - - if ((Ip6Config == NULL) || (Data == NULL) || (DataSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - BufferSize = 0; - Status = Ip6Config->GetData ( - Ip6Config, - DataType, - &BufferSize, - NULL - ); - if (Status != EFI_BUFFER_TOO_SMALL) { - return Status; - } - - Buffer = AllocateZeroPool (BufferSize); - if (Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = Ip6Config->GetData ( - Ip6Config, - DataType, - &BufferSize, - Buffer - ); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - return Status; - } - - *DataSize = BufferSize; - *Data = Buffer; - - return EFI_SUCCESS; -} - -/** - Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified - with ListHead. - - @param[in] ListHead The head of the list array in IP6_ADDRESS_INFO_ENTRY. - -**/ -VOID -Ip6FreeAddressInfoList ( - IN LIST_ENTRY *ListHead - ) -{ - IP6_ADDRESS_INFO_ENTRY *Node; - LIST_ENTRY *Entry; - LIST_ENTRY *NextEntry; - - NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ListHead) { - Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link); - RemoveEntryList (&Node->Link); - FreePool (Node); - } -} - -/** - Convert the IPv6 address into a formatted string. - - @param[in] Ip6 The IPv6 address. - @param[out] Str The formatted IP string. - -**/ -VOID -Ip6ToStr ( - IN EFI_IPv6_ADDRESS *Ip6, - OUT CHAR16 *Str - ) -{ - UINTN Index; - BOOLEAN Short; - UINTN Number; - CHAR16 FormatString[8]; - - Short = FALSE; - - for (Index = 0; Index < 15; Index = Index + 2) { - if (!Short && - Index % 2 == 0 && - Ip6->Addr[Index] == 0 && - Ip6->Addr[Index + 1] == 0 - ) { - // - // Deal with the case of ::. - // - if (Index == 0) { - *Str = L':'; - *(Str + 1) = L':'; - Str = Str + 2; - } else { - *Str = L':'; - Str = Str + 1; - } - - while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) { - Index = Index + 2; - } - - Short = TRUE; - - if (Index == 16) { - // - // :: is at the end of the address. - // - *Str = L'\0'; - break; - } - } - - ASSERT (Index < 15); - - if (Ip6->Addr[Index] == 0) { - Number = UnicodeSPrint (Str, 2 * IP6_STR_MAX_SIZE, L"%x:", (UINTN) Ip6->Addr[Index + 1]); - } else { - if (Ip6->Addr[Index + 1] < 0x10) { - CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:")); - } else { - CopyMem (FormatString, L"%x%x:", StrSize (L"%x%x:")); - } - - Number = UnicodeSPrint ( - Str, - 2 * IP6_STR_MAX_SIZE, - (CONST CHAR16 *) FormatString, - (UINTN) Ip6->Addr[Index], - (UINTN) Ip6->Addr[Index + 1] - ); - } - - Str = Str + Number; - - if (Index + 2 == 16) { - *Str = L'\0'; - if (*(Str - 1) == L':') { - *(Str - 1) = L'\0'; - } - } - } -} - -/** - Convert EFI_IP6_CONFIG_INTERFACE_ID to string format. - - @param[out] String The buffer to store the converted string. - @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID. - - @retval EFI_SUCCESS The string converted successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - -**/ -EFI_STATUS -Ip6ConvertInterfaceIdToString ( - OUT CHAR16 *String, - IN EFI_IP6_CONFIG_INTERFACE_ID *IfId - ) -{ - UINT8 Index; - UINTN Number; - - if ((String == NULL) || (IfId == NULL)) { - return EFI_INVALID_PARAMETER; - } - - for (Index = 0; Index < 8; Index++) { - Number = UnicodeSPrint ( - String, - 2 * INTERFACE_ID_STR_STORAGE, - L"%x:", - (UINTN) IfId->Id[Index] - ); - String = String + Number; - } - - *(String - 1) = '\0'; - - return EFI_SUCCESS; -} - -/** - Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID. - - @param[in] String The buffer of the string to be parsed. - @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - -**/ -EFI_STATUS -Ip6ParseInterfaceIdFromString ( - IN CONST CHAR16 *String, - OUT EFI_IP6_CONFIG_INTERFACE_ID *IfId - ) -{ - UINT8 Index; - CHAR16 *IfIdStr; - CHAR16 *TempStr; - UINTN NodeVal; - - if ((String == NULL) || (IfId == NULL)) { - return EFI_INVALID_PARAMETER; - } - - IfIdStr = (CHAR16 *) String; - - ZeroMem (IfId, sizeof (EFI_IP6_CONFIG_INTERFACE_ID)); - - for (Index = 0; Index < 8; Index++) { - TempStr = IfIdStr; - - while ((*IfIdStr != L'\0') && (*IfIdStr != L':')) { - IfIdStr++; - } - - // - // The InterfaceId format is X:X:X:X, the number of X should not exceed 8. - // If the number of X is less than 8, zero is appended to the InterfaceId. - // - if ((*IfIdStr == ':') && (Index == 7)) { - return EFI_INVALID_PARAMETER; - } - - // - // Convert the string to interface id. AsciiStrHexToUintn stops at the - // first character that is not a valid hex character, ':' or '\0' here. - // - NodeVal = StrHexToUintn (TempStr); - if (NodeVal > 0xFF) { - return EFI_INVALID_PARAMETER; - } - - IfId->Id[Index] = (UINT8) NodeVal; - - IfIdStr++; - } - - return EFI_SUCCESS; -} - -/** - Create Hii Extend Label OpCode as the start opcode and end opcode. It is - a help function. - - @param[in] StartLabelNumber The number of start label. - @param[out] StartOpCodeHandle Points to the start opcode handle. - @param[out] StartLabel Points to the created start opcode. - @param[out] EndOpCodeHandle Points to the end opcode handle. - @param[out] EndLabel Points to the created end opcode. - - @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this - operation. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_SUCCESS The operation completed successfully. - -**/ -EFI_STATUS -Ip6CreateOpCode ( - IN UINT16 StartLabelNumber, - OUT VOID **StartOpCodeHandle, - OUT EFI_IFR_GUID_LABEL **StartLabel, - OUT VOID **EndOpCodeHandle, - OUT EFI_IFR_GUID_LABEL **EndLabel - ) -{ - EFI_STATUS Status; - EFI_IFR_GUID_LABEL *InternalStartLabel; - EFI_IFR_GUID_LABEL *InternalEndLabel; - - if (StartOpCodeHandle == NULL || StartLabel == NULL || EndOpCodeHandle == NULL || EndLabel == NULL) { - return EFI_INVALID_PARAMETER; - } - - *StartOpCodeHandle = NULL; - *EndOpCodeHandle = NULL; - Status = EFI_OUT_OF_RESOURCES; - - // - // Initialize the container for dynamic opcodes. - // - *StartOpCodeHandle = HiiAllocateOpCodeHandle (); - if (*StartOpCodeHandle == NULL) { - return Status; - } - - *EndOpCodeHandle = HiiAllocateOpCodeHandle (); - if (*EndOpCodeHandle == NULL) { - goto Exit; - } - - // - // Create Hii Extend Label OpCode as the start opcode. - // - InternalStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( - *StartOpCodeHandle, - &gEfiIfrTianoGuid, - NULL, - sizeof (EFI_IFR_GUID_LABEL) - ); - if (InternalStartLabel == NULL) { - goto Exit; - } - - InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; - InternalStartLabel->Number = StartLabelNumber; - - // - // Create Hii Extend Label OpCode as the end opcode. - // - InternalEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( - *EndOpCodeHandle, - &gEfiIfrTianoGuid, - NULL, - sizeof (EFI_IFR_GUID_LABEL) - ); - if (InternalEndLabel == NULL) { - goto Exit; - } - - InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; - InternalEndLabel->Number = LABEL_END; - - *StartLabel = InternalStartLabel; - *EndLabel = InternalEndLabel; - - return EFI_SUCCESS; - -Exit: - - if (*StartOpCodeHandle != NULL) { - HiiFreeOpCodeHandle (*StartOpCodeHandle); - } - - if (*EndOpCodeHandle != NULL) { - HiiFreeOpCodeHandle (*EndOpCodeHandle); - } - - return Status; -} - -/** - This function converts the different format of address list to string format and - then generates the corresponding text opcode to illustarate the address info in - IP6 configuration page. Currently, the following formats are supported: - EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress; - EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress; - EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable. - - @param[in, out] String The pointer to the buffer to store the converted - string. - @param[in] HiiHandle A handle that was previously registered in the - HII Database. - @param[in] AddressType The address type. - @param[in] AddressInfo Pointer to the address list. - @param[in] AddressCount The address count of the address list. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_UNSUPPORTED The AddressType is not supported. - - -**/ -EFI_STATUS -Ip6ConvertAddressListToString ( - IN OUT CHAR16 *String, - IN EFI_HII_HANDLE HiiHandle, - IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType, - IN VOID *AddressInfo, - IN UINTN AddressCount - ) -{ - UINTN Index; - UINTN Number; - CHAR16 *TempStr; - EFI_STATUS Status; - VOID *StartOpCodeHandle; - EFI_IFR_GUID_LABEL *StartLabel; - VOID *EndOpCodeHandle; - EFI_IFR_GUID_LABEL *EndLabel; - UINT16 StartLabelNumber; - EFI_STRING_ID TextTwo; - UINT8 *AddressHead; - UINT8 PrefixLength; - EFI_IPv6_ADDRESS *Address; - - if ((String == NULL) || (HiiHandle == NULL) || (AddressInfo == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (AddressType == Ip6ConfigNvHostAddress) { - StartLabelNumber = HOST_ADDRESS_LABEL; - } else if (AddressType == Ip6ConfigNvGatewayAddress) { - StartLabelNumber = GATEWAY_ADDRESS_LABEL; - } else if (AddressType == Ip6ConfigNvDnsAddress) { - StartLabelNumber = DNS_ADDRESS_LABEL; - } else if (AddressType == Ip6ConfigNvRouteTable) { - StartLabelNumber = ROUTE_TABLE_LABEL; - } else { - ASSERT (FALSE); - return EFI_UNSUPPORTED; - } - - Status = Ip6CreateOpCode ( - StartLabelNumber, - &StartOpCodeHandle, - &StartLabel, - &EndOpCodeHandle, - &EndLabel - ); - if (EFI_ERROR (Status)) { - return Status; - } - - AddressHead = (UINT8 *) AddressInfo; - - for (Index = 0; Index < AddressCount; Index++) { - if (AddressType == Ip6ConfigNvHostAddress) { - AddressInfo = AddressHead + sizeof (EFI_IP6_ADDRESS_INFO) * Index; - Address = &((EFI_IP6_ADDRESS_INFO *) AddressInfo)->Address; - } else if (AddressType == Ip6ConfigNvRouteTable) { - AddressInfo = AddressHead + sizeof (EFI_IP6_ROUTE_TABLE) * Index; - Address = &((EFI_IP6_ROUTE_TABLE *) AddressInfo)->Destination; - } else { - AddressInfo = AddressHead + sizeof (EFI_IPv6_ADDRESS) * Index; - Address = AddressInfo; - } - - // - // Convert the IP address info to string. - // - Ip6ToStr (Address, String); - TempStr = String + StrLen (String); - - if ((AddressType == Ip6ConfigNvHostAddress) || (AddressType == Ip6ConfigNvRouteTable)) { - if (AddressType == Ip6ConfigNvHostAddress) { - PrefixLength = ((EFI_IP6_ADDRESS_INFO *) AddressInfo)->PrefixLength; - } else { - PrefixLength = ((EFI_IP6_ROUTE_TABLE *) AddressInfo)->PrefixLength; - } - - // - // Append the prefix length to the string. - // - *TempStr = L'/'; - TempStr++; - Number = UnicodeSPrint (TempStr, 6, L"%d", PrefixLength); - TempStr = TempStr + Number; - } - - if (AddressType == Ip6ConfigNvRouteTable) { - // - // Append " >> " to the string. - // - Number = UnicodeSPrint (TempStr, 8, L" >> "); - TempStr = TempStr + Number; - - // - // Append the gateway address to the string. - // - Ip6ToStr (&((EFI_IP6_ROUTE_TABLE *) AddressInfo)->Gateway, TempStr); - TempStr = TempStr + StrLen (TempStr); - } - - // - // Generate a text opcode and update the UI. - // - TextTwo = HiiSetString (HiiHandle, 0, String, NULL); - if (TextTwo == 0) { - Status = EFI_INVALID_PARAMETER; - goto Exit; - } - - HiiCreateTextOpCode (StartOpCodeHandle, STR_NULL, STR_NULL, TextTwo); - - String = TempStr; - *String = IP6_ADDRESS_DELIMITER; - String++; - } - - *(String - 1) = '\0'; - - Status = HiiUpdateForm ( - HiiHandle, // HII handle - &gIp6ConfigNvDataGuid, // Formset GUID - FORMID_MAIN_FORM, // Form ID - StartOpCodeHandle, // Label for where to insert opcodes - EndOpCodeHandle // Replace data - ); - -Exit: - HiiFreeOpCodeHandle (StartOpCodeHandle); - HiiFreeOpCodeHandle (EndOpCodeHandle); - - return Status; -} - -/** - Parse address list in string format and convert it to a list array of node in - IP6_ADDRESS_INFO_ENTRY. - - @param[in] String The buffer to string to be parsed. - @param[out] ListHead The list head of array. - @param[out] AddressCount The number of list nodes in the array. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource. - -**/ -EFI_STATUS -Ip6ParseAddressListFromString ( - IN CONST CHAR16 *String, - OUT LIST_ENTRY *ListHead, - OUT UINT32 *AddressCount - ) -{ - EFI_STATUS Status; - CHAR16 *LocalString; - CHAR16 *Temp; - CHAR16 *TempStr; - EFI_IP6_ADDRESS_INFO AddressInfo; - IP6_ADDRESS_INFO_ENTRY *Node; - BOOLEAN Last; - UINT32 Count; - - if ((String == NULL) || (ListHead == NULL) || (AddressCount == NULL)) { - return EFI_INVALID_PARAMETER; - } - - ZeroMem (&AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO)); - LocalString = (CHAR16 *) AllocateCopyPool (StrSize (String), String); - if (LocalString == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Clean the original address list. - // - Ip6FreeAddressInfoList (ListHead); - - Temp = LocalString; - Last = FALSE; - Count = 0; - - while (*LocalString != L'\0') { - TempStr = LocalString; - while ((*LocalString != L'\0') && (*LocalString != IP6_ADDRESS_DELIMITER)) { - LocalString++; - } - - if (*LocalString == L'\0') { - Last = TRUE; - } - - *LocalString = L'\0'; - - Status = NetLibStrToIp6andPrefix (TempStr, &AddressInfo.Address, &AddressInfo.PrefixLength); - if (EFI_ERROR (Status)) { - goto Error; - } - - if (AddressInfo.PrefixLength == 0xFF) { - AddressInfo.PrefixLength = 0; - } - - if (!NetIp6IsValidUnicast (&AddressInfo.Address)) { - Status = EFI_INVALID_PARAMETER; - goto Error; - } - - Node = AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY)); - if (Node == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - CopyMem (&Node->AddrInfo, &AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO)); - InsertTailList (ListHead, &Node->Link); - Count++; - - if (Last) { - break; - } - - LocalString++; - } - - FreePool (Temp); - *AddressCount = Count; - return EFI_SUCCESS; - -Error: - Ip6FreeAddressInfoList (ListHead); - FreePool (Temp); - return Status; -} - -/** - This function converts the interface info to string and draws it to the IP6 UI. - The interface information includes interface name, interface type, hardware - address and route table information. - - @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO. - @param[in] HiiHandle The handle that was previously registered in the - HII Database. - @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources. - -**/ -EFI_STATUS -Ip6ConvertInterfaceInfoToString ( - IN EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo, - IN EFI_HII_HANDLE HiiHandle, - IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData - ) -{ - UINT32 Index; - UINTN Number; - CHAR16 *String; - CHAR16 PortString[ADDRESS_STR_MAX_SIZE]; - CHAR16 FormatString[8]; - EFI_STRING_ID StringId; - - if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Print the interface name. - // - StringId = HiiSetString ( - HiiHandle, - STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT), - IfInfo->Name, - NULL - ); - if (StringId == 0) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Print the interface type. - // - if (IfInfo->IfType == Ip6InterfaceTypeEthernet) { - CopyMem (PortString, IP6_ETHERNET, sizeof (IP6_ETHERNET)); - } else if (IfInfo->IfType == Ip6InterfaceTypeExperimentalEthernet) { - CopyMem (PortString, IP6_EXPERIMENTAL_ETHERNET, sizeof (IP6_EXPERIMENTAL_ETHERNET)); - } else { - // - // Refer to RFC1700, chapter Number Hardware Type. - // - UnicodeSPrint (PortString, 6, L"%d", IfInfo->IfType); - } - - StringId = HiiSetString ( - HiiHandle, - STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT), - PortString, - NULL - ); - if (StringId == 0) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Convert the hardware address. - // - String = PortString; - ASSERT (IfInfo->HwAddressSize <= 32); - - for (Index = 0; Index < IfInfo->HwAddressSize; Index++) { - - if (IfInfo->HwAddress.Addr[Index] < 0x10) { - CopyMem (FormatString, L"0%x-", sizeof (L"0%x-")); - } else { - CopyMem (FormatString, L"%x-", sizeof (L"%x-")); - } - - Number = UnicodeSPrint ( - String, - 8, - (CONST CHAR16 *) FormatString, - (UINTN) IfInfo->HwAddress.Addr[Index] - ); - String = String + Number; - } - - if (Index != 0) { - ASSERT (String > PortString); - String--; - *String = '\0'; - } - - // - // Print the hardware address. - // - StringId = HiiSetString ( - HiiHandle, - STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT), - PortString, - NULL - ); - if (StringId == 0) { - return EFI_OUT_OF_RESOURCES; - } - - return EFI_SUCCESS; -} - -/** - Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY. - - @param[in] Instance Points to IP6 config instance data. - @param[in] AddressType The address type. - @param[out] AddressInfo The pointer to the buffer to store the address list. - @param[out] AddressSize The address size of the address list. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_UNSUPPORTED The AddressType is not supported. - -**/ -EFI_STATUS -Ip6BuildNvAddressInfo ( - IN IP6_CONFIG_INSTANCE *Instance, - IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType, - OUT VOID **AddressInfo, - OUT UINTN *AddressSize - ) -{ - IP6_CONFIG_NVDATA *Ip6NvData; - LIST_ENTRY *Entry; - LIST_ENTRY *ListHead; - IP6_ADDRESS_INFO_ENTRY *Node; - VOID *AddressList; - VOID *TmpStr; - UINTN DataSize; - EFI_IPv6_ADDRESS *Ip6Address; - EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress; - - if ((Instance == NULL) || (AddressInfo == NULL) || (AddressSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE); - - Ip6NvData = &Instance->Ip6NvData; - - if (AddressType == Ip6ConfigNvHostAddress) { - ListHead = &Ip6NvData->ManualAddress; - DataSize = sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS) * Ip6NvData->ManualAddressCount; - } else if (AddressType == Ip6ConfigNvGatewayAddress) { - ListHead = &Ip6NvData->GatewayAddress; - DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->GatewayAddressCount; - } else if (AddressType == Ip6ConfigNvDnsAddress) { - ListHead = &Ip6NvData->DnsAddress; - DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->DnsAddressCount; - } else { - return EFI_UNSUPPORTED; - } - - AddressList = AllocateZeroPool (DataSize); - if (AddressList == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - TmpStr = AddressList; - - NET_LIST_FOR_EACH (Entry, ListHead) { - Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link); - if (AddressType == Ip6ConfigNvHostAddress) { - ManualAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) AddressList; - IP6_COPY_ADDRESS (&ManualAddress->Address, &Node->AddrInfo.Address); - ManualAddress->PrefixLength = Node->AddrInfo.PrefixLength; - AddressList = (UINT8 *) AddressList + sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS); - } else { - Ip6Address = (EFI_IPv6_ADDRESS *) AddressList; - IP6_COPY_ADDRESS (Ip6Address, &Node->AddrInfo.Address); - AddressList = (UINT8 *) AddressList + sizeof (EFI_IPv6_ADDRESS); - } - } - - *AddressInfo = TmpStr; - *AddressSize = DataSize; - return EFI_SUCCESS; -} - -/** - Convert the IP6 configuration data into the IFR data. - - @param[in, out] IfrNvData The IFR NV data. - @param[in] Instance The IP6 config instance data. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_UNSUPPORTED The policy is not supported in the current implementation. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -Ip6ConvertConfigNvDataToIfrNvData ( - IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData, - IN IP6_CONFIG_INSTANCE *Instance - ) -{ - IP6_CONFIG_NVDATA *Ip6NvData; - EFI_IP6_CONFIG_PROTOCOL *Ip6Config; - UINTN DataSize; - VOID *Data; - EFI_STATUS Status; - EFI_IP6_CONFIG_POLICY Policy; - EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits; - EFI_HII_HANDLE HiiHandle; - - if ((IfrNvData == NULL) || (Instance == NULL)) { - return EFI_INVALID_PARAMETER; - } - - NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE); - - Ip6Config = &Instance->Ip6Config; - Ip6NvData = &Instance->Ip6NvData; - Data = NULL; - DataSize = 0; - HiiHandle = Instance->CallbackInfo.RegisteredHandle; - - // - // Get the current interface info. - // - Status = Ip6ConfigNvGetData ( - Ip6Config, - Ip6ConfigDataTypeInterfaceInfo, - &DataSize, - (VOID **) &Data - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - // - // Convert the interface info to string and print. - // - Status = Ip6ConvertInterfaceInfoToString ( - (EFI_IP6_CONFIG_INTERFACE_INFO *) Data, - HiiHandle, - IfrNvData - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - // - // Get the interface id. - // - DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID); - ZeroMem (&Ip6NvData->InterfaceId, DataSize); - Status = Ip6Config->GetData ( - Ip6Config, - Ip6ConfigDataTypeAltInterfaceId, - &DataSize, - &Ip6NvData->InterfaceId - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId); - - // - // Get current policy. - // - DataSize = sizeof (EFI_IP6_CONFIG_POLICY); - Status = Ip6Config->GetData ( - Ip6Config, - Ip6ConfigDataTypePolicy, - &DataSize, - &Policy - ); - - if (EFI_ERROR (Status)) { - goto Exit; - } - - if (Policy == Ip6ConfigPolicyManual) { - IfrNvData->Policy = IP6_POLICY_MANUAL; - } else if (Policy == Ip6ConfigPolicyAutomatic) { - IfrNvData->Policy = IP6_POLICY_AUTO; - } else { - ASSERT (FALSE); - Status = EFI_UNSUPPORTED; - goto Exit; - } - - // - // Get Duplicate Address Detection Transmits count. - // - DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS); - Status = Ip6Config->GetData ( - Ip6Config, - Ip6ConfigDataTypeDupAddrDetectTransmits, - &DataSize, - &DadXmits - ); - - if (EFI_ERROR (Status)) { - goto Exit; - } - - IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits; - -Exit: - if (Data != NULL) { - FreePool (Data); - } - - return Status; -} - -/** - Convert IFR data into IP6 configuration data. The policy, alternative interface - ID, and DAD transmit counts, and will be saved. - - @param[in] IfrNvData The IFR NV data. - @param[in, out] Instance The IP6 config instance data. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -Ip6ConvertIfrNvDataToConfigNvDataGeneral ( - IN IP6_CONFIG_IFR_NVDATA *IfrNvData, - IN OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - IP6_CONFIG_NVDATA *Ip6NvData; - EFI_IP6_CONFIG_PROTOCOL *Ip6Config; - EFI_STATUS Status; - - if ((IfrNvData == NULL) || (Instance == NULL)) { - return EFI_INVALID_PARAMETER; - } - - NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE); - Ip6NvData = &Instance->Ip6NvData; - Ip6Config = &Instance->Ip6Config; - - // - // Update those fields which don't have INTERACTIVE attribute. - // - if (IfrNvData->Policy == IP6_POLICY_AUTO) { - Ip6NvData->Policy = Ip6ConfigPolicyAutomatic; - } else if (IfrNvData->Policy == IP6_POLICY_MANUAL) { - Ip6NvData->Policy = Ip6ConfigPolicyManual; - } - - Ip6NvData->DadTransmitCount.DupAddrDetectTransmits = IfrNvData->DadTransmitCount; - - // - // Set the configured policy. - // - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypePolicy, - sizeof (EFI_IP6_CONFIG_POLICY), - &Ip6NvData->Policy - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set the duplicate address detection transmits count. - // - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypeDupAddrDetectTransmits, - sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS), - &Ip6NvData->DadTransmitCount - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Set the alternative interface ID - // - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypeAltInterfaceId, - sizeof (EFI_IP6_CONFIG_INTERFACE_ID), - &Ip6NvData->InterfaceId - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; -} - -/** - Convert IFR data into IP6 configuration data. The policy, configured - manual address, gateway address, and DNS server address will be saved. - - @param[in] IfrNvData The IFR NV data. - @param[in, out] Instance The IP6 config instance data. - - @retval EFI_SUCCESS The operation finished successfully. - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -Ip6ConvertIfrNvDataToConfigNvDataAdvanced ( - IN IP6_CONFIG_IFR_NVDATA *IfrNvData, - IN OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - IP6_CONFIG_NVDATA *Ip6NvData; - EFI_IP6_CONFIG_PROTOCOL *Ip6Config; - EFI_STATUS Status; - EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress; - EFI_IPv6_ADDRESS *Address; - BOOLEAN IsAddressOk; - EFI_EVENT SetAddressEvent; - EFI_EVENT TimeoutEvent; - UINTN DataSize; - - if ((IfrNvData == NULL) || (Instance == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (IfrNvData->Policy == IP6_POLICY_AUTO) { - return EFI_SUCCESS; - } - - NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE); - Ip6NvData = &Instance->Ip6NvData; - Ip6Config = &Instance->Ip6Config; - - // - // Update those fields which don't have INTERACTIVE attribute. - // - Ip6NvData->Policy = Ip6ConfigPolicyManual; - - // - // Set the configured policy. - // - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypePolicy, - sizeof (EFI_IP6_CONFIG_POLICY), - &Ip6NvData->Policy - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Create events & timers for asynchronous settings. - // - SetAddressEvent = NULL; - TimeoutEvent = NULL; - ManualAddress = NULL; - Address = NULL; - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - Ip6ConfigManualAddressNotify, - &IsAddressOk, - &SetAddressEvent - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Status = gBS->CreateEvent ( - EVT_TIMER, - TPL_CALLBACK, - NULL, - NULL, - &TimeoutEvent - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - // - // Set the manual address list. This is an asynchronous process. - // - if (!IsListEmpty (&Ip6NvData->ManualAddress) && (Ip6NvData->ManualAddressCount != 0)) { - Status = Ip6BuildNvAddressInfo ( - Instance, - Ip6ConfigNvHostAddress, - (VOID **) &ManualAddress, - &DataSize - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - IsAddressOk = FALSE; - - Status = Ip6Config->RegisterDataNotify ( - Ip6Config, - Ip6ConfigDataTypeManualAddress, - SetAddressEvent - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypeManualAddress, - DataSize, - (VOID *) ManualAddress - ); - if (Status == EFI_NOT_READY) { - gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000); - while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) { - if (IsAddressOk) { - Status = EFI_SUCCESS; - } - break; - } - } - - Status = Ip6Config->UnregisterDataNotify ( - Ip6Config, - Ip6ConfigDataTypeManualAddress, - SetAddressEvent - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - } - - // - // Set gateway address list. - // - if (!IsListEmpty (&Ip6NvData->GatewayAddress) && (Ip6NvData->GatewayAddressCount != 0)) { - Status = Ip6BuildNvAddressInfo ( - Instance, - Ip6ConfigNvGatewayAddress, - (VOID **) &Address, - &DataSize - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypeGateway, - DataSize, - (VOID *) Address - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - FreePool (Address); - Address = NULL; - } - - // - // Set DNS server address list. - // - if (!IsListEmpty (&Ip6NvData->DnsAddress) && (Ip6NvData->DnsAddressCount != 0)) { - Status = Ip6BuildNvAddressInfo ( - Instance, - Ip6ConfigNvDnsAddress, - (VOID **) &Address, - &DataSize - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - - Status = Ip6Config->SetData ( - Ip6Config, - Ip6ConfigDataTypeDnsServer, - DataSize, - (VOID *) Address - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - } - - Status = EFI_SUCCESS; - -Exit: - if (SetAddressEvent != NULL) { - gBS->CloseEvent (SetAddressEvent); - } - - if (TimeoutEvent != NULL) { - gBS->CloseEvent (TimeoutEvent); - } - - if (ManualAddress != NULL) { - FreePool (ManualAddress); - } - - if (Address != NULL) { - FreePool (Address); - } - - return Status; -} - - -/** - This function allows the caller to request the current - configuration for one or more named elements. The resulting - string is in format. Any and all alternative - configuration strings shall also be appended to the end of the - current configuration string. If they are, they must appear - after the current configuration. They must contain the same - routing (GUID, NAME, PATH) as the current configuration string. - They must have an additional description indicating the type of - alternative configuration the string represents, - "ALTCFG=". That (when - converted from Hex UNICODE to binary) is a reference to a - string in the associated string pack. - - @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - @param[in] Request A null-terminated Unicode string in - format. Note that this - includes the routing information as well as - the configurable name / value pairs. It is - invalid for this string to be in - format. - @param[out] Progress On return, points to a character in the - Request string. Points to the string's null - terminator if request was successful. Points - to the most recent "&" before the first - failing name / value pair (or the beginning - of the string if the failure is in the first - name / value pair) if the request was not - successful. - @param[out] Results A null-terminated Unicode string in - format which has all values - filled in for the names in the Request string. - String to be allocated by the called function. - - @retval EFI_SUCCESS The Results string is filled with the - values corresponding to all requested - names. - @retval EFI_OUT_OF_RESOURCES Not enough memory to store the - parts of the results that must be - stored awaiting possible future - protocols. - @retval EFI_INVALID_PARAMETER For example, passing in a NULL - for the Request parameter - would result in this type of - error. In this case, the - Progress parameter would be - set to NULL. - @retval EFI_NOT_FOUND Routing data doesn't match any - known driver. Progress set to the - first character in the routing header. - Note: There is no requirement that the - driver validate the routing data. It - must skip the in order to - process the names. - @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set - to most recent & before the - error or the beginning of the - string. - @retval EFI_INVALID_PARAMETER Unknown name. Progress points - to the & before the name in - question. Currently not implemented. -**/ -EFI_STATUS -EFIAPI -Ip6FormExtractConfig ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN CONST EFI_STRING Request, - OUT EFI_STRING *Progress, - OUT EFI_STRING *Results - ) -{ - - EFI_STATUS Status; - IP6_FORM_CALLBACK_INFO *Private; - IP6_CONFIG_INSTANCE *Ip6ConfigInstance; - IP6_CONFIG_IFR_NVDATA *IfrNvData; - EFI_STRING ConfigRequestHdr; - EFI_STRING ConfigRequest; - BOOLEAN AllocatedRequest; - UINTN Size; - UINTN BufferSize; - - if (This == NULL || Progress == NULL || Results == NULL) { - return EFI_INVALID_PARAMETER; - } - - *Progress = Request; - if ((Request != NULL) && - !HiiIsConfigHdrMatch (Request, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) { - return EFI_NOT_FOUND; - } - - ConfigRequestHdr = NULL; - ConfigRequest = NULL; - AllocatedRequest = FALSE; - Size = 0; - - Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This); - Ip6ConfigInstance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private); - BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA); - - IfrNvData = (IP6_CONFIG_IFR_NVDATA *) AllocateZeroPool (BufferSize); - if (IfrNvData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = Ip6ConvertConfigNvDataToIfrNvData (IfrNvData, Ip6ConfigInstance); - if (EFI_ERROR (Status)) { - goto Exit; - } - - ConfigRequest = Request; - if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { - // - // Request has no request element, construct full request string. - // Allocate and fill a buffer large enough to hold the template - // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator. - // - ConfigRequestHdr = HiiConstructConfigHdr ( - &gIp6ConfigNvDataGuid, - mIp6ConfigStorageName, - Private->ChildHandle - ); - Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); - ConfigRequest = AllocateZeroPool (Size); - ASSERT (ConfigRequest != NULL); - AllocatedRequest = TRUE; - UnicodeSPrint ( - ConfigRequest, - Size, - L"%s&OFFSET=0&WIDTH=%016LX", - ConfigRequestHdr, - (UINT64) BufferSize - ); - FreePool (ConfigRequestHdr); - } - - // - // Convert buffer data to by helper function BlockToConfig() - // - Status = gHiiConfigRouting->BlockToConfig ( - gHiiConfigRouting, - ConfigRequest, - (UINT8 *) IfrNvData, - BufferSize, - Results, - Progress - ); - -Exit: - FreePool (IfrNvData); - // - // Free the allocated config request string. - // - if (AllocatedRequest) { - FreePool (ConfigRequest); - ConfigRequest = NULL; - } - // - // Set Progress string to the original request string. - // - if (Request == NULL) { - *Progress = NULL; - } else if (StrStr (Request, L"OFFSET") == NULL) { - *Progress = Request + StrLen (Request); - } - - return Status; -} - -/** - This function applies changes in a driver's configuration. - Input is a Configuration, which has the routing data for this - driver followed by name / value configuration pairs. The driver - must apply those pairs to its configurable storage. If the - driver's configuration is stored in a linear block of data - and the driver's name / value pairs are in - format, it may use the ConfigToBlock helper function (above) to - simplify the job. Currently not implemented. - - @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - @param[in] Configuration A null-terminated Unicode string in - format. - @param[out] Progress A pointer to a string filled in with the - offset of the most recent '&' before the - first failing name / value pair (or the - beginn ing of the string if the failure - is in the first name / value pair) or - the terminating NULL if all was - successful. - - @retval EFI_SUCCESS The results have been distributed or are - awaiting distribution. - @retval EFI_OUT_OF_MEMORY Not enough memory to store the - parts of the results that must be - stored awaiting possible future - protocols. - @retval EFI_INVALID_PARAMETERS Passing in a NULL for the - Results parameter would result - in this type of error. - @retval EFI_NOT_FOUND Target for the specified routing data - was not found. -**/ -EFI_STATUS -EFIAPI -Ip6FormRouteConfig ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN CONST EFI_STRING Configuration, - OUT EFI_STRING *Progress - ) -{ - if (This == NULL || Configuration == NULL || Progress == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check routing data in . - // Note: if only one Storage is used, then this checking could be skipped. - // - if (!HiiIsConfigHdrMatch (Configuration, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) { - *Progress = Configuration; - return EFI_NOT_FOUND; - } - - *Progress = Configuration + StrLen (Configuration); - - return EFI_SUCCESS; -} - -/** - Display host addresses, route table, DNS addresses and gateway addresses in - "IPv6 Current Setting" page. - - @param[in] Instance The IP6 config instance data. - - @retval EFI_SUCCESS The operation finished successfully. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -Ip6GetCurrentSetting ( - IN IP6_CONFIG_INSTANCE *Instance - ) -{ - EFI_IP6_CONFIG_PROTOCOL *Ip6Config; - EFI_HII_HANDLE HiiHandle; - EFI_IP6_CONFIG_INTERFACE_INFO *Data; - UINTN DataSize; - EFI_STATUS Status; - CHAR16 PortString[ADDRESS_STR_MAX_SIZE]; - EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo; - - - Ip6Config = &Instance->Ip6Config; - HiiHandle = Instance->CallbackInfo.RegisteredHandle; - Data = NULL; - - // - // Get current interface info. - // - Status = Ip6ConfigNvGetData ( - Ip6Config, - Ip6ConfigDataTypeInterfaceInfo, - &DataSize, - (VOID **) &Data - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Generate dynamic text opcode for host address and draw it. - // - IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data; - Status = Ip6ConvertAddressListToString ( - PortString, - HiiHandle, - Ip6ConfigNvHostAddress, - IfInfo->AddressInfo, - IfInfo->AddressInfoCount - ); - if (EFI_ERROR (Status)) { - FreePool (Data); - return Status; - } - - // - // Generate the dynamic text opcode for route table and draw it. - // - Status = Ip6ConvertAddressListToString ( - PortString, - HiiHandle, - Ip6ConfigNvRouteTable, - IfInfo->RouteTable, - IfInfo->RouteCount - ); - if (EFI_ERROR (Status)) { - FreePool (Data); - return Status; - } - - // - // Get DNS server list. - // - FreePool (Data); - DataSize = 0; - Data = NULL; - Status = Ip6ConfigNvGetData ( - Ip6Config, - Ip6ConfigDataTypeDnsServer, - &DataSize, - (VOID **) &Data - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - if (Data != NULL) { - FreePool (Data); - } - return Status; - } - - if (DataSize > 0) { - // - // Generate the dynamic text opcode for DNS server and draw it. - // - Status = Ip6ConvertAddressListToString ( - PortString, - HiiHandle, - Ip6ConfigNvDnsAddress, - Data, - DataSize / sizeof (EFI_IPv6_ADDRESS) - ); - if (EFI_ERROR (Status)) { - FreePool (Data); - return Status; - } - } - - // - // Get gateway adderss list. - // - if (Data != NULL) { - FreePool (Data); - } - - DataSize = 0; - Data = NULL; - Status = Ip6ConfigNvGetData ( - Ip6Config, - Ip6ConfigDataTypeGateway, - &DataSize, - (VOID **) &Data - ); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - if (Data != NULL) { - FreePool (Data); - } - return Status; - } - - if (DataSize > 0) { - // - // Generate the dynamic text opcode for gateway and draw it. - // - Status = Ip6ConvertAddressListToString ( - PortString, - HiiHandle, - Ip6ConfigNvGatewayAddress, - Data, - DataSize / sizeof (EFI_IPv6_ADDRESS) - ); - if (EFI_ERROR (Status)) { - FreePool (Data); - return Status; - } - } - - if (Data != NULL) { - FreePool (Data); - } - - return EFI_SUCCESS; -} - -/** - This function is called to provide results data to the driver. - This data consists of a unique key that is used to identify - which data is either being passed back or being asked for. - - @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - @param[in] Action Specifies the type of action taken by the browser. - @param[in] QuestionId A unique value which is sent to the original - exporting driver so that it can identify the type - of data to expect. The format of the data tends to - vary based on the opcode that generated the callback. - @param[in] Type The type of value for the question. - @param[in] Value A pointer to the data being sent to the original - exporting driver. - @param[out] ActionRequest On return, points to the action requested by the - callback function. - - @retval EFI_SUCCESS The callback successfully handled the action. - @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the - variable and its data. - @retval EFI_DEVICE_ERROR The variable could not be saved. - @retval EFI_UNSUPPORTED The specified Action is not supported by the - callback. Currently not implemented. - @retval EFI_INVALID_PARAMETER Passed in the wrong parameter. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -Ip6FormCallback ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN EFI_BROWSER_ACTION Action, - IN EFI_QUESTION_ID QuestionId, - IN UINT8 Type, - IN EFI_IFR_TYPE_VALUE *Value, - OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest - ) -{ - IP6_FORM_CALLBACK_INFO *Private; - UINTN BufferSize; - IP6_CONFIG_IFR_NVDATA *IfrNvData; - EFI_STATUS Status; - EFI_INPUT_KEY Key; - IP6_CONFIG_INSTANCE *Instance; - IP6_CONFIG_NVDATA *Ip6NvData; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This); - Instance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private); - Ip6NvData = &Instance->Ip6NvData; - - if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)){ - return EFI_SUCCESS; - } - - if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) { - return EFI_UNSUPPORTED; - } - - if ((Value == NULL) || (ActionRequest == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Retrieve uncommitted data from Browser - // - - BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA); - IfrNvData = AllocateZeroPool (BufferSize); - if (IfrNvData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = EFI_SUCCESS; - - HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData); - - if (Action == EFI_BROWSER_ACTION_CHANGING) { - switch (QuestionId) { - case KEY_GET_CURRENT_SETTING: - Status = Ip6GetCurrentSetting (Instance); - break; - - default: - break; - } - } else if (Action == EFI_BROWSER_ACTION_CHANGED) { - switch (QuestionId) { - case KEY_SAVE_CONFIG_CHANGES: - Status = Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData, Instance); - if (EFI_ERROR (Status)) { - break; - } - - Status = Ip6GetCurrentSetting (Instance); - - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; - break; - - case KEY_IGNORE_CONFIG_CHANGES: - Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress); - Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress); - Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress); - - Ip6NvData->ManualAddressCount = 0; - Ip6NvData->GatewayAddressCount = 0; - Ip6NvData->DnsAddressCount = 0; - - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; - break; - - case KEY_SAVE_CHANGES: - Status = Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData, Instance); - if (EFI_ERROR (Status)) { - break; - } - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; - break; - - case KEY_INTERFACE_ID: - Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId); - if (EFI_ERROR (Status)) { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"Invalid Interface ID!", - NULL - ); - } - - break; - - case KEY_MANUAL_ADDRESS: - Status = Ip6ParseAddressListFromString ( - IfrNvData->ManualAddress, - &Ip6NvData->ManualAddress, - &Ip6NvData->ManualAddressCount - ); - if (EFI_ERROR (Status)) { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"Invalid Host Addresses!", - NULL - ); - } - - break; - - case KEY_GATEWAY_ADDRESS: - Status = Ip6ParseAddressListFromString ( - IfrNvData->GatewayAddress, - &Ip6NvData->GatewayAddress, - &Ip6NvData->GatewayAddressCount - ); - if (EFI_ERROR (Status)) { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"Invalid Gateway Addresses!", - NULL - ); - } - - break; - - case KEY_DNS_ADDRESS: - Status = Ip6ParseAddressListFromString ( - IfrNvData->DnsAddress, - &Ip6NvData->DnsAddress, - &Ip6NvData->DnsAddressCount - ); - if (EFI_ERROR (Status)) { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"Invalid DNS Addresses!", - NULL - ); - } - - break; - - default: - break; - } - } - - if (!EFI_ERROR (Status)) { - // - // Pass changed uncommitted data back to Form Browser. - // - BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA); - HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL); - } - - FreePool (IfrNvData); - return Status; -} - -/** - Install HII Config Access protocol for network device and allocate resources. - - @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form. - - @retval EFI_SUCCESS The HII Config Access protocol is installed. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -Ip6ConfigFormInit ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - EFI_STATUS Status; - IP6_SERVICE *IpSb; - IP6_FORM_CALLBACK_INFO *CallbackInfo; - EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; - VENDOR_DEVICE_PATH VendorDeviceNode; - EFI_SERVICE_BINDING_PROTOCOL *MnpSb; - CHAR16 *MacString; - CHAR16 MenuString[128]; - CHAR16 PortString[128]; - CHAR16 *OldMenuString; - EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - ASSERT (IpSb != NULL); - - Status = gBS->HandleProtocol ( - IpSb->Controller, - &gEfiDevicePathProtocolGuid, - (VOID **) &ParentDevicePath - ); - if (EFI_ERROR (Status)) { - return Status; - } - - CallbackInfo = &Instance->CallbackInfo; - CallbackInfo->Signature = IP6_FORM_CALLBACK_INFO_SIGNATURE; - - // - // Construct device path node for EFI HII Config Access protocol, - // which consists of controller physical device path and one hardware - // vendor guid node. - // - ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH)); - VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH; - VendorDeviceNode.Header.SubType = HW_VENDOR_DP; - - CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid); - - SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH)); - CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode ( - ParentDevicePath, - (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode - ); - if (CallbackInfo->HiiVendorDevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - ConfigAccess = &CallbackInfo->HiiConfigAccess; - ConfigAccess->ExtractConfig = Ip6FormExtractConfig; - ConfigAccess->RouteConfig = Ip6FormRouteConfig; - ConfigAccess->Callback = Ip6FormCallback; - - // - // Install Device Path Protocol and Config Access protocol on new handle - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &CallbackInfo->ChildHandle, - &gEfiDevicePathProtocolGuid, - CallbackInfo->HiiVendorDevicePath, - &gEfiHiiConfigAccessProtocolGuid, - ConfigAccess, - NULL - ); - if (!EFI_ERROR (Status)) { - // - // Open the Parent Handle for the child - // - Status = gBS->OpenProtocol ( - IpSb->Controller, - &gEfiManagedNetworkServiceBindingProtocolGuid, - (VOID **) &MnpSb, - IpSb->Image, - CallbackInfo->ChildHandle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - } - - if (EFI_ERROR (Status)) { - goto Error; - } - - // - // Publish our HII data - // - CallbackInfo->RegisteredHandle = HiiAddPackages ( - &gIp6ConfigNvDataGuid, - CallbackInfo->ChildHandle, - Ip6DxeStrings, - Ip6ConfigBin, - NULL - ); - if (CallbackInfo->RegisteredHandle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - // - // Append MAC string in the menu help string and tile help string - // - Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString); - if (!EFI_ERROR (Status)) { - OldMenuString = HiiGetString ( - CallbackInfo->RegisteredHandle, - STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP), - NULL) - ; - UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString); - HiiSetString ( - CallbackInfo->RegisteredHandle, - STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP), - MenuString, - NULL - ); - UnicodeSPrint (PortString, 128, L"MAC:%s", MacString); - HiiSetString ( - CallbackInfo->RegisteredHandle, - STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP), - PortString, - NULL - ); - - FreePool (MacString); - FreePool (OldMenuString); - - InitializeListHead (&Instance->Ip6NvData.ManualAddress); - InitializeListHead (&Instance->Ip6NvData.GatewayAddress); - InitializeListHead (&Instance->Ip6NvData.DnsAddress); - - return EFI_SUCCESS; - } - -Error: - Ip6ConfigFormUnload (Instance); - return Status; -} - -/** - Uninstall the HII Config Access protocol for network devices and free up the resources. - - @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form. - -**/ -VOID -Ip6ConfigFormUnload ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ) -{ - IP6_SERVICE *IpSb; - IP6_FORM_CALLBACK_INFO *CallbackInfo; - IP6_CONFIG_NVDATA *Ip6NvData; - - IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance); - ASSERT (IpSb != NULL); - - CallbackInfo = &Instance->CallbackInfo; - - if (CallbackInfo->ChildHandle != NULL) { - - // - // Close the child handle - // - gBS->CloseProtocol ( - IpSb->Controller, - &gEfiManagedNetworkServiceBindingProtocolGuid, - IpSb->Image, - CallbackInfo->ChildHandle - ); - // - // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL - // - gBS->UninstallMultipleProtocolInterfaces ( - CallbackInfo->ChildHandle, - &gEfiDevicePathProtocolGuid, - CallbackInfo->HiiVendorDevicePath, - &gEfiHiiConfigAccessProtocolGuid, - &CallbackInfo->HiiConfigAccess, - NULL - ); - } - - if (CallbackInfo->HiiVendorDevicePath != NULL) { - FreePool (CallbackInfo->HiiVendorDevicePath); - } - - if (CallbackInfo->RegisteredHandle != NULL) { - // - // Remove HII package list - // - HiiRemovePackages (CallbackInfo->RegisteredHandle); - } - - Ip6NvData = &Instance->Ip6NvData; - - Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress); - Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress); - Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress); - - Ip6NvData->ManualAddressCount = 0; - Ip6NvData->GatewayAddressCount = 0; - Ip6NvData->DnsAddressCount = 0; -} diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.h b/Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.h deleted file mode 100644 index ef1893c549..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6ConfigNv.h +++ /dev/null @@ -1,68 +0,0 @@ -/** @file - The header file of Ip6ConfigNv.c. - - Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _IP6_CONFIGNV_H_ -#define _IP6_CONFIGNV_H_ - -#include "Ip6NvData.h" -#include "Ip6ConfigImpl.h" - -extern UINT8 Ip6ConfigBin[]; -extern UINT8 Ip6DxeStrings[]; - -#define IP6_ETHERNET L"Ethernet" -#define IP6_EXPERIMENTAL_ETHERNET L"Experimental Ethernet" -#define IP6_ADDRESS_DELIMITER L' ' -#define IP6_LINK_LOCAL_PREFIX L"FE80::" - -typedef enum { - Ip6InterfaceTypeEthernet = 1, - Ip6InterfaceTypeExperimentalEthernet -} IP6_INTERFACE_TYPE; - -typedef enum { - Ip6ConfigNvHostAddress, - Ip6ConfigNvGatewayAddress, - Ip6ConfigNvDnsAddress, - Ip6ConfigNvRouteTable -} IP6_CONFIG_NV_ADDRESS_TYPE; - -/** - Install HII Config Access protocol for network device and allocate resources. - - @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form. - - @retval EFI_SUCCESS The HII Config Access protocol is installed. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -Ip6ConfigFormInit ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ); - -/** - Uninstall HII Config Access protocol for network device and free resource. - - @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form. - -**/ -VOID -Ip6ConfigFormUnload ( - IN OUT IP6_CONFIG_INSTANCE *Instance - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Driver.c b/Core/NetworkPkg/Ip6Dxe/Ip6Driver.c deleted file mode 100644 index 8a8cc8916a..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Driver.c +++ /dev/null @@ -1,1026 +0,0 @@ -/** @file - The driver binding and service binding protocol for IP6 driver. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -EFI_DRIVER_BINDING_PROTOCOL gIp6DriverBinding = { - Ip6DriverBindingSupported, - Ip6DriverBindingStart, - Ip6DriverBindingStop, - 0xa, - NULL, - NULL -}; - -BOOLEAN mIpSec2Installed = FALSE; - -/** - Callback function for IpSec2 Protocol install. - - @param[in] Event Event whose notification function is being invoked - @param[in] Context Pointer to the notification function's context - -**/ -VOID -EFIAPI -IpSec2InstalledCallback ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - // - // Close the event so it does not get called again. - // - gBS->CloseEvent (Event); - - mIpSec2Installed = TRUE; - - return; -} - -/** - This is the declaration of an EFI image entry point. This entry point is - the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including - both device drivers and bus drivers. - - The entry point for IP6 driver which installs the driver - binding and component name protocol on its image. - - @param[in] ImageHandle The firmware allocated handle for the UEFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - VOID *Registration; - - EfiCreateProtocolNotifyEvent ( - &gEfiIpSec2ProtocolGuid, - TPL_CALLBACK, - IpSec2InstalledCallback, - NULL, - &Registration - ); - - return EfiLibInstallDriverBindingComponentName2 ( - ImageHandle, - SystemTable, - &gIp6DriverBinding, - ImageHandle, - &gIp6ComponentName, - &gIp6ComponentName2 - ); -} - -/** - Test to see if this driver supports ControllerHandle. - - @param[in] This Protocol instance pointer. - @param[in] ControllerHandle Handle of device to test. - @param[in] RemainingDevicePath Optional parameter use to pick a specific child - device to start. - - @retval EFI_SUCCESS This driver supports this device. - @retval EFI_ALREADY_STARTED This driver is already running on this device. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - // - // Test for the MNP service binding Protocol - // - return gBS->OpenProtocol ( - ControllerHandle, - &gEfiManagedNetworkServiceBindingProtocolGuid, - NULL, - This->DriverBindingHandle, - ControllerHandle, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); -} - -/** - Clean up an IP6 service binding instance. It releases all - the resource allocated by the instance. The instance may be - partly initialized, or partly destroyed. If a resource is - destroyed, it is marked as that in case the destroy failed and - being called again later. - - @param[in] IpSb The IP6 service binding instance to clean up. - - @retval EFI_SUCCESS The resource used by the instance are cleaned up. - @retval Others Failed to clean up some of the resources. - -**/ -EFI_STATUS -Ip6CleanService ( - IN IP6_SERVICE *IpSb - ) -{ - EFI_STATUS Status; - EFI_IPv6_ADDRESS AllNodes; - IP6_NEIGHBOR_ENTRY *NeighborCache; - - IpSb->State = IP6_SERVICE_DESTROY; - - if (IpSb->Timer != NULL) { - gBS->SetTimer (IpSb->Timer, TimerCancel, 0); - gBS->CloseEvent (IpSb->Timer); - - IpSb->Timer = NULL; - } - - if (IpSb->FasterTimer != NULL) { - gBS->SetTimer (IpSb->FasterTimer, TimerCancel, 0); - gBS->CloseEvent (IpSb->FasterTimer); - - IpSb->FasterTimer = NULL; - } - - Ip6ConfigCleanInstance (&IpSb->Ip6ConfigInstance); - - if (!IpSb->LinkLocalDadFail) { - // - // Leave link-scope all-nodes multicast address (FF02::1) - // - Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes); - - Status = Ip6LeaveGroup (IpSb, &AllNodes); - if (EFI_ERROR (Status)) { - return Status; - } - } - - if (IpSb->DefaultInterface != NULL) { - Ip6CleanInterface (IpSb->DefaultInterface, NULL); - IpSb->DefaultInterface = NULL; - } - - Ip6CleanDefaultRouterList (IpSb); - - Ip6CleanPrefixListTable (IpSb, &IpSb->OnlinkPrefix); - Ip6CleanPrefixListTable (IpSb, &IpSb->AutonomousPrefix); - - if (IpSb->RouteTable != NULL) { - Ip6CleanRouteTable (IpSb->RouteTable); - IpSb->RouteTable = NULL; - } - - if (IpSb->InterfaceId != NULL) { - FreePool (IpSb->InterfaceId); - } - - IpSb->InterfaceId = NULL; - - Ip6CleanAssembleTable (&IpSb->Assemble); - - if (IpSb->MnpChildHandle != NULL) { - if (IpSb->Mnp != NULL) { - IpSb->Mnp->Cancel (IpSb->Mnp, NULL); - IpSb->Mnp->Configure (IpSb->Mnp, NULL); - gBS->CloseProtocol ( - IpSb->MnpChildHandle, - &gEfiManagedNetworkProtocolGuid, - IpSb->Image, - IpSb->Controller - ); - - IpSb->Mnp = NULL; - } - - NetLibDestroyServiceChild ( - IpSb->Controller, - IpSb->Image, - &gEfiManagedNetworkServiceBindingProtocolGuid, - IpSb->MnpChildHandle - ); - - IpSb->MnpChildHandle = NULL; - } - - if (IpSb->RecvRequest.MnpToken.Event != NULL) { - gBS->CloseEvent (IpSb->RecvRequest.MnpToken.Event); - } - - // - // Free the Neighbor Discovery resources - // - while (!IsListEmpty (&IpSb->NeighborTable)) { - NeighborCache = NET_LIST_HEAD (&IpSb->NeighborTable, IP6_NEIGHBOR_ENTRY, Link); - Ip6FreeNeighborEntry (IpSb, NeighborCache, FALSE, TRUE, EFI_SUCCESS, NULL, NULL); - } - - return EFI_SUCCESS; -} - -/** - Create a new IP6 driver service binding protocol. - - @param[in] Controller The controller that has MNP service binding - installed. - @param[in] ImageHandle The IP6 driver's image handle. - @param[out] Service The variable to receive the newly created IP6 - service. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources. - @retval EFI_SUCCESS A new IP6 service binding private is created. - -**/ -EFI_STATUS -Ip6CreateService ( - IN EFI_HANDLE Controller, - IN EFI_HANDLE ImageHandle, - OUT IP6_SERVICE **Service - ) -{ - IP6_SERVICE *IpSb; - EFI_STATUS Status; - EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken; - EFI_MANAGED_NETWORK_CONFIG_DATA *Config; - - ASSERT (Service != NULL); - - *Service = NULL; - - // - // allocate a service private data then initialize all the filed to - // empty resources, so if any thing goes wrong when allocating - // resources, Ip6CleanService can be called to clean it up. - // - IpSb = AllocateZeroPool (sizeof (IP6_SERVICE)); - - if (IpSb == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - IpSb->Signature = IP6_SERVICE_SIGNATURE; - IpSb->ServiceBinding.CreateChild = Ip6ServiceBindingCreateChild; - IpSb->ServiceBinding.DestroyChild = Ip6ServiceBindingDestroyChild; - IpSb->State = IP6_SERVICE_UNSTARTED; - - IpSb->NumChildren = 0; - InitializeListHead (&IpSb->Children); - - InitializeListHead (&IpSb->Interfaces); - IpSb->DefaultInterface = NULL; - IpSb->RouteTable = NULL; - - IpSb->RecvRequest.Signature = IP6_LINK_RX_SIGNATURE; - IpSb->RecvRequest.CallBack = NULL; - IpSb->RecvRequest.Context = NULL; - MnpToken = &IpSb->RecvRequest.MnpToken; - MnpToken->Event = NULL; - MnpToken->Status = EFI_NOT_READY; - MnpToken->Packet.RxData = NULL; - - Ip6CreateAssembleTable (&IpSb->Assemble); - - IpSb->MldCtrl.Mldv1QuerySeen = 0; - InitializeListHead (&IpSb->MldCtrl.Groups); - - ZeroMem (&IpSb->LinkLocalAddr, sizeof (EFI_IPv6_ADDRESS)); - IpSb->LinkLocalOk = FALSE; - IpSb->LinkLocalDadFail = FALSE; - IpSb->Dhcp6NeedStart = FALSE; - IpSb->Dhcp6NeedInfoRequest = FALSE; - - IpSb->CurHopLimit = IP6_HOP_LIMIT; - IpSb->LinkMTU = IP6_MIN_LINK_MTU; - IpSb->BaseReachableTime = IP6_REACHABLE_TIME; - Ip6UpdateReachableTime (IpSb); - // - // RFC4861 RETRANS_TIMER: 1,000 milliseconds - // - IpSb->RetransTimer = IP6_RETRANS_TIMER; - - IpSb->RoundRobin = 0; - - InitializeListHead (&IpSb->NeighborTable); - InitializeListHead (&IpSb->DefaultRouterList); - InitializeListHead (&IpSb->OnlinkPrefix); - InitializeListHead (&IpSb->AutonomousPrefix); - - IpSb->InterfaceIdLen = IP6_IF_ID_LEN; - IpSb->InterfaceId = NULL; - - IpSb->RouterAdvertiseReceived = FALSE; - IpSb->SolicitTimer = IP6_MAX_RTR_SOLICITATIONS; - IpSb->Ticks = 0; - - IpSb->Image = ImageHandle; - IpSb->Controller = Controller; - - IpSb->MnpChildHandle = NULL; - IpSb->Mnp = NULL; - - Config = &IpSb->MnpConfigData; - Config->ReceivedQueueTimeoutValue = 0; - Config->TransmitQueueTimeoutValue = 0; - Config->ProtocolTypeFilter = IP6_ETHER_PROTO; - Config->EnableUnicastReceive = TRUE; - Config->EnableMulticastReceive = TRUE; - Config->EnableBroadcastReceive = TRUE; - Config->EnablePromiscuousReceive = FALSE; - Config->FlushQueuesOnReset = TRUE; - Config->EnableReceiveTimestamps = FALSE; - Config->DisableBackgroundPolling = FALSE; - - ZeroMem (&IpSb->SnpMode, sizeof (EFI_SIMPLE_NETWORK_MODE)); - - IpSb->Timer = NULL; - IpSb->FasterTimer = NULL; - - ZeroMem (&IpSb->Ip6ConfigInstance, sizeof (IP6_CONFIG_INSTANCE)); - - IpSb->MacString = NULL; - - // - // Create various resources. First create the route table, timer - // event, MNP token event and MNP child. - // - - IpSb->RouteTable = Ip6CreateRouteTable (); - if (IpSb->RouteTable == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_ERROR; - } - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL | EVT_TIMER, - TPL_CALLBACK, - Ip6TimerTicking, - IpSb, - &IpSb->Timer - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL | EVT_TIMER, - TPL_CALLBACK, - Ip6NdFasterTimerTicking, - IpSb, - &IpSb->FasterTimer - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = NetLibCreateServiceChild ( - Controller, - ImageHandle, - &gEfiManagedNetworkServiceBindingProtocolGuid, - &IpSb->MnpChildHandle - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = gBS->OpenProtocol ( - IpSb->MnpChildHandle, - &gEfiManagedNetworkProtocolGuid, - (VOID **) (&IpSb->Mnp), - ImageHandle, - Controller, - EFI_OPEN_PROTOCOL_BY_DRIVER - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = Ip6ServiceConfigMnp (IpSb, TRUE); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &IpSb->SnpMode); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - IpSb->MaxPacketSize = IP6_MIN_LINK_MTU - sizeof (EFI_IP6_HEADER); - if (NetLibGetVlanId (IpSb->Controller) != 0) { - // - // This is a VLAN device, reduce MTU by VLAN tag length - // - IpSb->MaxPacketSize -= NET_VLAN_TAG_LEN; - } - IpSb->OldMaxPacketSize = IpSb->MaxPacketSize; - - // - // Currently only ETHERNET is supported in IPv6 stack, since - // link local address requires an IEEE 802 48-bit MACs for - // EUI-64 format interface identifier mapping. - // - if (IpSb->SnpMode.IfType != NET_IFTYPE_ETHERNET) { - Status = EFI_UNSUPPORTED; - goto ON_ERROR; - } - - Status = Ip6InitMld (IpSb); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &IpSb->MacString); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = Ip6ConfigInitInstance (&IpSb->Ip6ConfigInstance); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - IpSb->DefaultInterface = Ip6CreateInterface (IpSb, TRUE); - if (IpSb->DefaultInterface == NULL) { - Status = EFI_DEVICE_ERROR; - goto ON_ERROR; - } - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - Ip6OnFrameReceived, - &IpSb->RecvRequest, - &MnpToken->Event - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - InsertHeadList (&IpSb->Interfaces, &IpSb->DefaultInterface->Link); - - *Service = IpSb; - return EFI_SUCCESS; - -ON_ERROR: - Ip6CleanService (IpSb); - FreePool (IpSb); - return Status; -} - - -/** - Start this driver on ControllerHandle. - - @param[in] This Protocol instance pointer. - @param[in] ControllerHandle Handle of device to bind driver to. - @param[in] RemainingDevicePath Optional parameter used to pick a specific child - device to start. - - @retval EFI_SUCCES This driver is added to ControllerHandle. - @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ) -{ - IP6_SERVICE *IpSb; - EFI_STATUS Status; - EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg; - IP6_CONFIG_DATA_ITEM *DataItem; - - IpSb = NULL; - Ip6Cfg = NULL; - DataItem = NULL; - - // - // Test for the Ip6 service binding protocol - // - Status = gBS->OpenProtocol ( - ControllerHandle, - &gEfiIp6ServiceBindingProtocolGuid, - NULL, - This->DriverBindingHandle, - ControllerHandle, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - - if (Status == EFI_SUCCESS) { - return EFI_ALREADY_STARTED; - } - - Status = Ip6CreateService (ControllerHandle, This->DriverBindingHandle, &IpSb); - - if (EFI_ERROR (Status)) { - return Status; - } - - ASSERT (IpSb != NULL); - - Ip6Cfg = &IpSb->Ip6ConfigInstance.Ip6Config; - - // - // Install the Ip6ServiceBinding Protocol onto ControlerHandle - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &ControllerHandle, - &gEfiIp6ServiceBindingProtocolGuid, - &IpSb->ServiceBinding, - &gEfiIp6ConfigProtocolGuid, - Ip6Cfg, - NULL - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // Read the config data from NV variable again. - // The default data can be changed by other drivers. - // - Status = Ip6ConfigReadConfigData (IpSb->MacString, &IpSb->Ip6ConfigInstance); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // If there is any default manual address, set it. - // - DataItem = &IpSb->Ip6ConfigInstance.DataItem[Ip6ConfigDataTypeManualAddress]; - if (DataItem->Data.Ptr != NULL) { - Status = Ip6Cfg->SetData ( - Ip6Cfg, - Ip6ConfigDataTypeManualAddress, - DataItem->DataSize, - DataItem->Data.Ptr - ); - if (EFI_ERROR(Status) && Status != EFI_NOT_READY) { - goto ON_ERROR; - } - } - - // - // If there is any default gateway address, set it. - // - DataItem = &IpSb->Ip6ConfigInstance.DataItem[Ip6ConfigDataTypeGateway]; - if (DataItem->Data.Ptr != NULL) { - Status = Ip6Cfg->SetData ( - Ip6Cfg, - Ip6ConfigDataTypeGateway, - DataItem->DataSize, - DataItem->Data.Ptr - ); - if (EFI_ERROR(Status)) { - goto ON_ERROR; - } - } - - // - // ready to go: start the receiving and timer - // - Status = Ip6ReceiveFrame (Ip6AcceptFrame, IpSb); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // The timer expires every 100 (IP6_TIMER_INTERVAL_IN_MS) milliseconds. - // - Status = gBS->SetTimer ( - IpSb->FasterTimer, - TimerPeriodic, - TICKS_PER_MS * IP6_TIMER_INTERVAL_IN_MS - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // The timer expires every 1000 (IP6_ONE_SECOND_IN_MS) milliseconds. - // - Status = gBS->SetTimer ( - IpSb->Timer, - TimerPeriodic, - TICKS_PER_MS * IP6_ONE_SECOND_IN_MS - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // Initialize the IP6 ID - // - mIp6Id = NET_RANDOM (NetRandomInitSeed ()); - - return EFI_SUCCESS; - -ON_ERROR: - Ip6CleanService (IpSb); - FreePool (IpSb); - return Status; -} - -/** - Callback function which provided by user to remove one node in NetDestroyLinkList process. - - @param[in] Entry The entry to be removed. - @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. - - @retval EFI_SUCCESS The entry has been removed successfully. - @retval Others Fail to remove the entry. - -**/ -EFI_STATUS -EFIAPI -Ip6DestroyChildEntryInHandleBuffer ( - IN LIST_ENTRY *Entry, - IN VOID *Context - ) -{ - IP6_PROTOCOL *IpInstance; - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - UINTN NumberOfChildren; - EFI_HANDLE *ChildHandleBuffer; - - if (Entry == NULL || Context == NULL) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE); - ServiceBinding = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ServiceBinding; - NumberOfChildren = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->NumberOfChildren; - ChildHandleBuffer = ((IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)->ChildHandleBuffer; - - if (!NetIsInHandleBuffer (IpInstance->Handle, NumberOfChildren, ChildHandleBuffer)) { - return EFI_SUCCESS; - } - - return ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); -} - -/** - Stop this driver on ControllerHandle. - - @param[in] This Protocol instance pointer. - @param[in] ControllerHandle Handle of device to stop driver on. - @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number - of children is zero, stop the entire bus driver. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL - ) -{ - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - IP6_SERVICE *IpSb; - EFI_HANDLE NicHandle; - EFI_STATUS Status; - LIST_ENTRY *List; - INTN State; - BOOLEAN IsDhcp6; - IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; - - IsDhcp6 = FALSE; - NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); - if (NicHandle == NULL) { - NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid); - if (NicHandle != NULL) { - IsDhcp6 = TRUE; - } else { - return EFI_SUCCESS; - } - } - - Status = gBS->OpenProtocol ( - NicHandle, - &gEfiIp6ServiceBindingProtocolGuid, - (VOID **) &ServiceBinding, - This->DriverBindingHandle, - NicHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - IpSb = IP6_SERVICE_FROM_PROTOCOL (ServiceBinding); - - if (IsDhcp6) { - Status = Ip6ConfigDestroyDhcp6 (&IpSb->Ip6ConfigInstance); - gBS->CloseEvent (IpSb->Ip6ConfigInstance.Dhcp6Event); - IpSb->Ip6ConfigInstance.Dhcp6Event = NULL; - } else if (NumberOfChildren != 0) { - // - // NumberOfChildren is not zero, destroy the IP6 children instances in ChildHandleBuffer. - // - List = &IpSb->Children; - Context.ServiceBinding = ServiceBinding; - Context.NumberOfChildren = NumberOfChildren; - Context.ChildHandleBuffer = ChildHandleBuffer; - Status = NetDestroyLinkList ( - List, - Ip6DestroyChildEntryInHandleBuffer, - &Context, - NULL - ); - } else if (IsListEmpty (&IpSb->Children)) { - State = IpSb->State; - Status = Ip6CleanService (IpSb); - if (EFI_ERROR (Status)) { - IpSb->State = State; - goto Exit; - } - - Status = gBS->UninstallMultipleProtocolInterfaces ( - NicHandle, - &gEfiIp6ServiceBindingProtocolGuid, - ServiceBinding, - &gEfiIp6ConfigProtocolGuid, - &IpSb->Ip6ConfigInstance.Ip6Config, - NULL - ); - ASSERT_EFI_ERROR (Status); - FreePool (IpSb); - Status = EFI_SUCCESS; - } - -Exit: - return Status; -} - - -/** - Creates a child handle with a set of I/O services. - - @param[in] This Protocol instance pointer. - @param[in] ChildHandle Pointer to the handle of the child to create. If - it is NULL, then a new handle is created. If it - is not NULL, then the I/O services are added to - the existing child handle. - - @retval EFI_SUCCES The child handle was created with the I/O services. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create - the child. - @retval other The child handle was not created. - -**/ -EFI_STATUS -EFIAPI -Ip6ServiceBindingCreateChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE *ChildHandle - ) -{ - IP6_SERVICE *IpSb; - IP6_PROTOCOL *IpInstance; - EFI_TPL OldTpl; - EFI_STATUS Status; - VOID *Mnp; - - if ((This == NULL) || (ChildHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - IpSb = IP6_SERVICE_FROM_PROTOCOL (This); - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - IpInstance = AllocatePool (sizeof (IP6_PROTOCOL)); - - if (IpInstance == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Ip6InitProtocol (IpSb, IpInstance); - - // - // Install Ip6 onto ChildHandle - // - Status = gBS->InstallMultipleProtocolInterfaces ( - ChildHandle, - &gEfiIp6ProtocolGuid, - &IpInstance->Ip6Proto, - NULL - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - IpInstance->Handle = *ChildHandle; - - // - // Open the Managed Network protocol BY_CHILD. - // - Status = gBS->OpenProtocol ( - IpSb->MnpChildHandle, - &gEfiManagedNetworkProtocolGuid, - (VOID **) &Mnp, - gIp6DriverBinding.DriverBindingHandle, - IpInstance->Handle, - EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER - ); - if (EFI_ERROR (Status)) { - gBS->UninstallMultipleProtocolInterfaces ( - ChildHandle, - &gEfiIp6ProtocolGuid, - &IpInstance->Ip6Proto, - NULL - ); - - goto ON_ERROR; - } - - // - // Insert it into the service binding instance. - // - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - InsertTailList (&IpSb->Children, &IpInstance->Link); - IpSb->NumChildren++; - - gBS->RestoreTPL (OldTpl); - -ON_ERROR: - - if (EFI_ERROR (Status)) { - - Ip6CleanProtocol (IpInstance); - - FreePool (IpInstance); - } - - return Status; -} - -/** - Destroys a child handle with a set of I/O services. - - @param[in] This Protocol instance pointer. - @param[in] ChildHandle Handle of the child to destroy. - - @retval EFI_SUCCES The I/O services were removed from the child - handle. - @retval EFI_UNSUPPORTED The child handle does not support the I/O services - that are being removed. - @retval EFI_INVALID_PARAMETER Child handle is NULL. - @retval EFI_ACCESS_DENIED The child handle could not be destroyed because - its I/O services are being used. - @retval other The child handle was not destroyed. - -**/ -EFI_STATUS -EFIAPI -Ip6ServiceBindingDestroyChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE ChildHandle - ) -{ - EFI_STATUS Status; - IP6_SERVICE *IpSb; - IP6_PROTOCOL *IpInstance; - EFI_IP6_PROTOCOL *Ip6; - EFI_TPL OldTpl; - - if ((This == NULL) || (ChildHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Retrieve the private context data structures - // - IpSb = IP6_SERVICE_FROM_PROTOCOL (This); - - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiIp6ProtocolGuid, - (VOID **) &Ip6, - gIp6DriverBinding.DriverBindingHandle, - ChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (Ip6); - - if (IpInstance->Service != IpSb) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - // - // A child can be destroyed more than once. For example, - // Ip6DriverBindingStop will destroy all of its children. - // when UDP driver is being stopped, it will destroy all - // the IP child it opens. - // - if (IpInstance->InDestroy) { - gBS->RestoreTPL (OldTpl); - return EFI_SUCCESS; - } - - IpInstance->InDestroy = TRUE; - - // - // Close the Managed Network protocol. - // - gBS->CloseProtocol ( - IpSb->MnpChildHandle, - &gEfiManagedNetworkProtocolGuid, - gIp6DriverBinding.DriverBindingHandle, - ChildHandle - ); - - // - // Uninstall the IP6 protocol first. Many thing happens during - // this: - // 1. The consumer of the IP6 protocol will be stopped if it - // opens the protocol BY_DRIVER. For eaxmple, if MNP driver is - // stopped, IP driver's stop function will be called, and uninstall - // EFI_IP6_PROTOCOL will trigger the UDP's stop function. This - // makes it possible to create the network stack bottom up, and - // stop it top down. - // 2. the upper layer will recycle the received packet. The recycle - // event's TPL is higher than this function. The recycle events - // will be called back before preceeding. If any packets not recycled, - // that means there is a resource leak. - // - gBS->RestoreTPL (OldTpl); - Status = gBS->UninstallProtocolInterface ( - ChildHandle, - &gEfiIp6ProtocolGuid, - &IpInstance->Ip6Proto - ); - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - Status = Ip6CleanProtocol (IpInstance); - if (EFI_ERROR (Status)) { - gBS->InstallMultipleProtocolInterfaces ( - &ChildHandle, - &gEfiIp6ProtocolGuid, - Ip6, - NULL - ); - - goto ON_ERROR; - } - - RemoveEntryList (&IpInstance->Link); - ASSERT (IpSb->NumChildren > 0); - IpSb->NumChildren--; - - gBS->RestoreTPL (OldTpl); - - FreePool (IpInstance); - return EFI_SUCCESS; - -ON_ERROR: - gBS->RestoreTPL (OldTpl); - - return Status; -} diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Driver.h b/Core/NetworkPkg/Ip6Dxe/Ip6Driver.h deleted file mode 100644 index 0874c4c93b..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Driver.h +++ /dev/null @@ -1,192 +0,0 @@ -/** @file - The driver binding and service binding protocol for IP6 driver. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_DRIVER_H__ -#define __EFI_IP6_DRIVER_H__ - -extern EFI_DRIVER_BINDING_PROTOCOL gIp6DriverBinding; -extern EFI_COMPONENT_NAME_PROTOCOL gIp6ComponentName; -extern EFI_COMPONENT_NAME2_PROTOCOL gIp6ComponentName2; -extern EFI_UNICODE_STRING_TABLE *gIp6ControllerNameTable; - -typedef struct { - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - UINTN NumberOfChildren; - EFI_HANDLE *ChildHandleBuffer; -}IP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; - -/** - Clean up an IP6 service binding instance. It releases all - the resource allocated by the instance. The instance may be - partly initialized, or partly destroyed. If a resource is - destroyed, it is marked as that in case the destroy failed and - being called again later. - - @param[in] IpSb The IP6 service binding instance to clean up. - - @retval EFI_SUCCESS The resource used by the instance are cleaned up. - @retval Others Failed to clean up some of the resources. - -**/ -EFI_STATUS -Ip6CleanService ( - IN IP6_SERVICE *IpSb - ); - -// -// Function prototype for the driver's entry point -// - -/** - This is the declaration of an EFI image entry point. This entry point is - the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including - both device drivers and bus drivers. - - The entry point for IP6 driver which installs the driver - binding and component name protocol on its image. - - @param[in] ImageHandle The firmware allocated handle for the UEFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -// -// Function prototypes for the Drivr Binding Protocol -// - -/** - Test to see if this driver supports ControllerHandle. - - @param[in] This Protocol instance pointer. - @param[in] ControllerHandle Handle of device to test. - @param[in] RemainingDevicePath Optional parameter use to pick a specific child - device to start. - - @retval EFI_SUCCESS This driver supports this device. - @retval EFI_ALREADY_STARTED This driver is already running on this device. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverBindingSupported ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ); - -/** - Start this driver on ControllerHandle. - - @param[in] This Protocol instance pointer. - @param[in] ControllerHandle Handle of device to bind driver to. - @param[in] RemainingDevicePath Optional parameter used to pick a specific child - device to start. - - @retval EFI_SUCCES This driver is added to ControllerHandle. - @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle. - @retval other This driver does not support this device. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverBindingStart ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL - ); - -/** - Stop this driver on ControllerHandle. - - @param[in] This Protocol instance pointer. - @param[in] ControllerHandle Handle of device to stop driver on. - @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number - of children is zero, stop the entire bus driver. - @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL - if NumberOfChildren is 0. - - @retval EFI_SUCCESS The device was stopped. - @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. - -**/ -EFI_STATUS -EFIAPI -Ip6DriverBindingStop ( - IN EFI_DRIVER_BINDING_PROTOCOL *This, - IN EFI_HANDLE ControllerHandle, - IN UINTN NumberOfChildren, - IN EFI_HANDLE *ChildHandleBuffer OPTIONAL - ); - -// -// Function prototypes for the ServiceBinding Protocol -// - -/** - Creates a child handle with a set of I/O services. - - @param[in] This Protocol instance pointer. - @param[in] ChildHandle Pointer to the handle of the child to create. If - it is NULL, then a new handle is created. If it - is not NULL, then the I/O services are added to - the existing child handle. - - @retval EFI_SUCCES The child handle was created with the I/O services. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create - the child. - @retval other The child handle was not created. - -**/ -EFI_STATUS -EFIAPI -Ip6ServiceBindingCreateChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE *ChildHandle - ); - -/** - Destroys a child handle with a set of I/O services. - - @param[in] This Protocol instance pointer. - @param[in] ChildHandle Handle of the child to destroy. - - @retval EFI_SUCCES The I/O services were removed from the child - handle. - @retval EFI_UNSUPPORTED The child handle does not support the I/O services - that are being removed. - @retval EFI_INVALID_PARAMETER Child handle is NULL. - @retval EFI_ACCESS_DENIED The child handle could not be destroyed because - its I/O services are being used. - @retval other The child handle was not destroyed. - -**/ -EFI_STATUS -EFIAPI -Ip6ServiceBindingDestroyChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE ChildHandle - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Dxe.inf b/Core/NetworkPkg/Ip6Dxe/Ip6Dxe.inf deleted file mode 100644 index 2d0fecc77e..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Dxe.inf +++ /dev/null @@ -1,116 +0,0 @@ -## @file -# Basic IPv6 packet I/O Service. -# -# This module 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). This driver -# also provides the mechanism to set and get various types of configurations for -# the EFI IPv6 network stack. -# -# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = Ip6Dxe - FILE_GUID = 5BEDB5CC-D830-4eb2-8742-2D4CC9B54F2C - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = Ip6DriverEntryPoint - UNLOAD_IMAGE = NetLibDefaultUnload - MODULE_UNI_FILE = Ip6Dxe.uni - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# -# DRIVER_BINDING = gIp6DriverBinding -# COMPONENT_NAME = gIp6ComponentName -# COMPONENT_NAME2 = gIp6ComponentName2 -# - -[Sources] - Ip6Output.h - Ip6Option.h - Ip6Input.h - Ip6Nd.h - Ip6Mld.h - Ip6Impl.c - Ip6Driver.c - ComponentName.c - Ip6Nd.c - Ip6Input.c - Ip6ConfigImpl.c - Ip6ConfigImpl.h - Ip6Impl.h - Ip6Option.c - Ip6If.h - Ip6Icmp.h - Ip6Mld.c - Ip6Common.c - Ip6Route.c - Ip6If.c - Ip6Driver.h - Ip6Output.c - Ip6Icmp.c - Ip6Common.h - Ip6Route.h - Ip6DxeStrings.uni - Ip6NvData.h - Ip6ConfigNv.c - Ip6ConfigNv.h - Ip6Config.vfr - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - NetworkPkg/NetworkPkg.dec - -[LibraryClasses] - BaseLib - BaseMemoryLib - DevicePathLib - HiiLib - UefiHiiServicesLib - PrintLib - MemoryAllocationLib - UefiBootServicesTableLib - UefiDriverEntryPoint - UefiRuntimeServicesTableLib - UefiLib - DebugLib - NetLib - DpcLib - -[Protocols] - gEfiManagedNetworkServiceBindingProtocolGuid ## TO_START - gEfiManagedNetworkProtocolGuid ## TO_START - gEfiIp6ServiceBindingProtocolGuid ## BY_START - gEfiIp6ProtocolGuid ## BY_START - gEfiIp6ConfigProtocolGuid ## BY_START - gEfiDhcp6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES - gEfiDhcp6ProtocolGuid ## SOMETIMES_CONSUMES - gEfiIpSec2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiHiiConfigAccessProtocolGuid ## SOMETIMES_CONSUMES - -[Guids] - ## SOMETIMES_CONSUMES ## HII - gEfiIfrTianoGuid - ## SOMETIMES_CONSUMES ## UNDEFINED # HiiIsConfigHdrMatch mIp6ConfigStorageName - ## SOMETIMES_PRODUCES ## UNDEFINED # HiiConstructConfigHdr mIp6ConfigStorageName - ## SOMETIMES_PRODUCES ## UNDEFINED # HiiAddPackages Ip6DxeStrings Ip6ConfigBin - ## SOMETIMES_CONSUMES ## UNDEFINED # HiiUpdateForm - ## SOMETIMES_CONSUMES ## HII - gIp6ConfigNvDataGuid -[UserExtensions.TianoCore."ExtraFiles"] - Ip6DxeExtra.uni diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Dxe.uni b/Core/NetworkPkg/Ip6Dxe/Ip6Dxe.uni deleted file mode 100644 index 11e97344f4..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Dxe.uni +++ /dev/null @@ -1,26 +0,0 @@ -// /** @file -// Basic IPv6 packet I/O Service. -// -// This module 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). This driver -// also provides the mechanism to set and get various types of configurations for -// the EFI IPv6 network stack. -// -// Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php. -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Basic IPv6 packet I/O Service" - -#string STR_MODULE_DESCRIPTION #language en-US "This module 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). This driver also provides the mechanism to set and get various types of configurations for the EFI IPv6 network stack." - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6DxeExtra.uni b/Core/NetworkPkg/Ip6Dxe/Ip6DxeExtra.uni deleted file mode 100644 index c3c34e4ab7..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6DxeExtra.uni +++ /dev/null @@ -1,20 +0,0 @@ -// /** @file -// Ip6Dxe Localized Strings and Content -// -// Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
-// -// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which accompanies this distribution. The full text of the license may be found at -// http://opensource.org/licenses/bsd-license.php. -// -// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"Ip6 DXE" - - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6DxeStrings.uni b/Core/NetworkPkg/Ip6Dxe/Ip6DxeStrings.uni deleted file mode 100644 index 3c9beec6a0..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6DxeStrings.uni +++ /dev/null @@ -1,61 +0,0 @@ -/** @file - String definitions for IP6 configuration. - - Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#langdef en-US "English" - -#string STR_IP6_CONFIG_FORM_TITLE #language en-US "IPv6 Network Configuration" -#string STR_IP6_CONFIG_FORM_HELP #language en-US "Configure IPv6 network parameters." -#string STR_IP6_DEVICE_FORM_TITLE #language en-US "IPv6 Current Setting" -#string STR_IP6_DEVICE_FORM_HELP #language en-US "Display IPv6 network parameters." -#string STR_IP6_INTERFACE_NAME #language en-US "Interface Name :" -#string STR_IP6_INTERFACE_NAME_HELP #language en-US "The name of the interface." -#string STR_IP6_INTERFACE_NAME_CONTENT #language en-US "" -#string STR_IP6_INTERFACE_TYPE #language en-US "Interface Type :" -#string STR_IP6_INTERFACE_TYPE_HELP #language en-US "The interface type of the network interface, defined in RFC1700." -#string STR_IP6_INTERFACE_TYPE_CONTENT #language en-US "" -#string STR_IP6_MAC_ADDRESS #language en-US "MAC address :" -#string STR_IP6_MAC_ADDRESS_HELP #language en-US "The hardware address of the network interface." -#string STR_IP6_MAC_ADDRESS_CONTENT #language en-US "" -#string STR_IP6_HOST_ADDRESS #language en-US "Host addresses :" -#string STR_IP6_HOST_ADDRESS_HELP #language en-US "The address list which contain the local IPv6 addresses and the corresponding prefix length information." -#string STR_IP6_ROUTE_TABLE #language en-US "Route Table :" -#string STR_IP6_ROUTE_TABLE_HELP #language en-US "The route table of the IPv6 network stack runs on this interface." -#string STR_IP6_GATEWAY_ADDRESS #language en-US "Gateway addresses :" -#string STR_IP6_GATEWAY_ADDRESS_HELP #language en-US "Current gateway IPv6 addresses." -#string STR_IP6_DNS_ADDRESS #language en-US "DNS addresses :" -#string STR_IP6_DNS_ADDRESS_HELP #language en-US "Current DNS server list." -#string STR_IP6_INTERFACE_ID #language en-US "Interface ID" -#string STR_IP6_INTERFACE_ID_HELP #language en-US "The 64 bit alternative interface ID for the device. The string is colon separated. e.g. ff:dd:88:66:cc:1:2:3" -#string STR_IP6_DAD_TRANSMIT_COUNT #language en-US "DAD Transmit Count" -#string STR_IP6_DAD_TRANSMIT_COUNT_HELP #language en-US "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 is not performed." -#string STR_POLICY_TYPE_PROMPT #language en-US "Policy" -#string STR_POLICY_TYPE_HELP #language en-US "automatic or manual" -#string STR_POLICY_TYPE_AUTO #language en-US "automatic" -#string STR_POLICY_TYPE_MANUAL #language en-US "manual" -#string STR_IP6_AD_CONFIG_FORM #language en-US "Advanced Configuration" -#string STR_IP6_AD_CONFIG_FORM_HELP #language en-US "Configure the interface manually. IP address, gateway address, and DNS server address can be configured." -#string STR_IP6_MANUAL_ADDRESS #language en-US "New IPv6 address" -#string STR_IP6_MANUAL_ADDRESS_HELP #language en-US "Manual IP address can only be configured under manual policy. Separate the IP address with blank space to configure more than one address. e.g. 2002::1/64 2002::2/64" -#string STR_IP6_NEW_GATEWAY_ADDRESS #language en-US "New Gateway addresses" -#string STR_IP6_NEW_GATEWAY_ADDR_HELP #language en-US "Gateway IP address can only be configured under manual policy. e.g. 2002::3. Separate the IP address with blank space to configure more than one address." -#string STR_IP6_NEW_DNS_ADDRESS #language en-US "New DNS addresses" -#string STR_IP6_NEW_DNS_ADDRESS_HELP #language en-US "DNS addresses can only be configured under manual policy. e.g. 2002::4. Separate the IP address with blank space to configure more than one address." -#string STR_SAVE_CHANGES #language en-US "Save Changes and Exit" -#string STR_SAVE_CHANGES_HELP #language en-US "Save Changes for interface ID, DAD transmit count, policy, and data in advanced configuration." -#string STR_SAVE_AND_EXIT #language en-US "Commit Changes and Exit" -#string STR_NO_SAVE_AND_EXIT #language en-US "Discard Changes and Exit" -#string STR_NULL #language en-US "" -#string STR_GET_CURRENT_SETTING #language en-US "Enter Configuration Menu" -#string STR_GET_CURRENT_SETTING_HELP #language en-US "Press ENTER to enter configuration menu for IPv6 configuration." diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Icmp.c b/Core/NetworkPkg/Ip6Dxe/Ip6Icmp.c deleted file mode 100644 index 1828d51a7d..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Icmp.c +++ /dev/null @@ -1,685 +0,0 @@ -/** @file - The ICMPv6 handle routines to process the ICMPv6 control messages. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- (C) Copyright 2016 Hewlett Packard Enterprise Development LP
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -EFI_IP6_ICMP_TYPE mIp6SupportedIcmp[23] = { - - { - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_NO_ROUTE_TO_DEST - }, - { - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_COMM_PROHIBITED - }, - { - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_BEYOND_SCOPE - }, - { - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_ADDR_UNREACHABLE - }, - { - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_PORT_UNREACHABLE - }, - { - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_SOURCE_ADDR_FAILED - }, - { - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_ROUTE_REJECTED - }, - - { - ICMP_V6_PACKET_TOO_BIG, - ICMP_V6_DEFAULT_CODE - }, - - { - ICMP_V6_TIME_EXCEEDED, - ICMP_V6_TIMEOUT_HOP_LIMIT - }, - { - ICMP_V6_TIME_EXCEEDED, - ICMP_V6_TIMEOUT_REASSEMBLE - }, - - { - ICMP_V6_PARAMETER_PROBLEM, - ICMP_V6_ERRONEOUS_HEADER - }, - { - ICMP_V6_PARAMETER_PROBLEM, - ICMP_V6_UNRECOGNIZE_NEXT_HDR - }, - { - ICMP_V6_PARAMETER_PROBLEM, - ICMP_V6_UNRECOGNIZE_OPTION - }, - - { - ICMP_V6_ECHO_REQUEST, - ICMP_V6_DEFAULT_CODE - }, - { - ICMP_V6_ECHO_REPLY, - ICMP_V6_DEFAULT_CODE - }, - - { - ICMP_V6_LISTENER_QUERY, - ICMP_V6_DEFAULT_CODE - }, - { - ICMP_V6_LISTENER_REPORT, - ICMP_V6_DEFAULT_CODE - }, - { - ICMP_V6_LISTENER_REPORT_2, - ICMP_V6_DEFAULT_CODE - }, - { - ICMP_V6_LISTENER_DONE, - ICMP_V6_DEFAULT_CODE - }, - - { - ICMP_V6_ROUTER_SOLICIT, - ICMP_V6_DEFAULT_CODE - }, - { - ICMP_V6_ROUTER_ADVERTISE, - ICMP_V6_DEFAULT_CODE - }, - { - ICMP_V6_NEIGHBOR_SOLICIT, - ICMP_V6_DEFAULT_CODE - }, - { - ICMP_V6_NEIGHBOR_ADVERTISE, - ICMP_V6_DEFAULT_CODE - }, -}; - -/** - Reply an ICMPv6 echo request. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the ICMPv6 informational message. - @param[in] Packet The content of the ICMPv6 message with the IP head - removed. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. - @retval EFI_SUCCESS Successfully answered the ICMPv6 Echo request. - @retval Others Failed to answer the ICMPv6 Echo request. - -**/ -EFI_STATUS -Ip6IcmpReplyEcho ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_INFORMATION_HEAD *Icmp; - NET_BUF *Data; - EFI_STATUS Status; - EFI_IP6_HEADER ReplyHead; - - Status = EFI_OUT_OF_RESOURCES; - // - // make a copy the packet, it is really a bad idea to - // send the MNP's buffer back to MNP. - // - Data = NetbufDuplicate (Packet, NULL, IP6_MAX_HEADLEN); - if (Data == NULL) { - goto Exit; - } - - // - // Change the ICMP type to echo reply, exchange the source - // and destination, then send it. The source is updated to - // use specific destination. See RFC1122. SRR/RR option - // update is omitted. - // - Icmp = (IP6_ICMP_INFORMATION_HEAD *) NetbufGetByte (Data, 0, NULL); - if (Icmp == NULL) { - NetbufFree (Data); - goto Exit; - } - - Icmp->Head.Type = ICMP_V6_ECHO_REPLY; - Icmp->Head.Checksum = 0; - - // - // Generate the IPv6 basic header - // If the Echo Reply is a response to a Echo Request sent to one of the node's unicast address, - // the Source address of the Echo Reply must be the same address. - // - ZeroMem (&ReplyHead, sizeof (EFI_IP6_HEADER)); - - ReplyHead.PayloadLength = HTONS ((UINT16) (Packet->TotalSize)); - ReplyHead.NextHeader = IP6_ICMP; - ReplyHead.HopLimit = IpSb->CurHopLimit; - IP6_COPY_ADDRESS (&ReplyHead.DestinationAddress, &Head->SourceAddress); - - if (Ip6IsOneOfSetAddress (IpSb, &Head->DestinationAddress, NULL, NULL)) { - IP6_COPY_ADDRESS (&ReplyHead.SourceAddress, &Head->DestinationAddress); - } - - // - // If source is unspecified, Ip6Output will select a source for us - // - Status = Ip6Output ( - IpSb, - NULL, - NULL, - Data, - &ReplyHead, - NULL, - 0, - Ip6SysPacketSent, - NULL - ); - -Exit: - NetbufFree (Packet); - return Status; -} - -/** - Process Packet Too Big message sent by a router in response to a packet that - it cannot forward because the packet is larger than the MTU of outgoing link. - Since this driver already uses IPv6 minimum link MTU as the maximum packet size, - if Packet Too Big message is still received, do not reduce the packet size, but - rather include a Fragment header in the subsequent packets. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the ICMPv6 error packet. - @param[in] Packet The content of the ICMPv6 error with the IP head - removed. - - @retval EFI_SUCCESS The ICMPv6 error processed successfully. - @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lack of - resource. - @retval EFI_NOT_FOUND The packet too big message is not sent to us. - -**/ -EFI_STATUS -Ip6ProcessPacketTooBig ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_ERROR_HEAD Icmp; - UINT32 Mtu; - IP6_ROUTE_ENTRY *RouteEntry; - EFI_IPv6_ADDRESS *DestAddress; - - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - Mtu = NTOHL (Icmp.Fourth); - DestAddress = &Icmp.IpHead.DestinationAddress; - - if (Mtu < IP6_MIN_LINK_MTU) { - // - // Normally the multicast address is considered to be on-link and not recorded - // in route table. Here it is added into the table since the MTU information - // need be recorded. - // - if (IP6_IS_MULTICAST (DestAddress)) { - RouteEntry = Ip6CreateRouteEntry (DestAddress, 128, NULL); - if (RouteEntry == NULL) { - NetbufFree (Packet); - return EFI_OUT_OF_RESOURCES; - } - - RouteEntry->Flag = IP6_DIRECT_ROUTE | IP6_PACKET_TOO_BIG; - InsertHeadList (&IpSb->RouteTable->RouteArea[128], &RouteEntry->Link); - IpSb->RouteTable->TotalNum++; - } else { - RouteEntry = Ip6FindRouteEntry (IpSb->RouteTable, DestAddress, NULL); - if (RouteEntry == NULL) { - NetbufFree (Packet); - return EFI_NOT_FOUND; - } - - RouteEntry->Flag = RouteEntry->Flag | IP6_PACKET_TOO_BIG; - - Ip6FreeRouteEntry (RouteEntry); - } - } - - NetbufFree (Packet); - return EFI_SUCCESS; -} - -/** - Process the ICMPv6 error packet, and deliver the packet to upper layer. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the ICMPv6 error packet. - @param[in] Packet The content of the ICMPv6 error with the IP head - removed. - - @retval EFI_SUCCESS The ICMPv6 error processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessIcmpError ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_ERROR_HEAD Icmp; - - // - // Check the validity of the packet - // - if (Packet->TotalSize < sizeof (Icmp)) { - goto DROP; - } - - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - if (Icmp.Head.Type == ICMP_V6_PACKET_TOO_BIG) { - return Ip6ProcessPacketTooBig (IpSb, Head, Packet); - } - - // - // Notify the upper-layer process that an ICMPv6 eror message is received. - // - IP6_GET_CLIP_INFO (Packet)->Status = EFI_ICMP_ERROR; - return Ip6Demultiplex (IpSb, Head, Packet); - -DROP: - NetbufFree (Packet); - Packet = NULL; - return EFI_INVALID_PARAMETER; -} - -/** - Process the ICMPv6 informational messages. If it is an ICMPv6 echo - request, answer it. If it is a MLD message, trigger MLD routines to - process it. If it is a ND message, trigger ND routines to process it. - Otherwise, deliver it to upper layer. - - @param[in] IpSb The IP service that receivd the packet. - @param[in] Head The IP head of the ICMPv6 informational packet. - @param[in] Packet The content of the ICMPv6 informational packet - with IP head removed. - - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval EFI_SUCCESS The ICMPv6 informational message processed. - @retval Others Failed to process ICMPv6 informational message. - -**/ -EFI_STATUS -Ip6ProcessIcmpInformation ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_INFORMATION_HEAD Icmp; - EFI_STATUS Status; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - NET_CHECK_SIGNATURE (Packet, NET_BUF_SIGNATURE); - ASSERT (Head != NULL); - - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - Status = EFI_INVALID_PARAMETER; - - switch (Icmp.Head.Type) { - case ICMP_V6_ECHO_REQUEST: - // - // If ICMPv6 echo, reply it - // - if (Icmp.Head.Code == 0) { - Status = Ip6IcmpReplyEcho (IpSb, Head, Packet); - } - break; - case ICMP_V6_LISTENER_QUERY: - Status = Ip6ProcessMldQuery (IpSb, Head, Packet); - break; - case ICMP_V6_LISTENER_REPORT: - case ICMP_V6_LISTENER_REPORT_2: - Status = Ip6ProcessMldReport (IpSb, Head, Packet); - break; - case ICMP_V6_NEIGHBOR_SOLICIT: - Status = Ip6ProcessNeighborSolicit (IpSb, Head, Packet); - break; - case ICMP_V6_NEIGHBOR_ADVERTISE: - Status = Ip6ProcessNeighborAdvertise (IpSb, Head, Packet); - break; - case ICMP_V6_ROUTER_ADVERTISE: - Status = Ip6ProcessRouterAdvertise (IpSb, Head, Packet); - break; - case ICMP_V6_REDIRECT: - Status = Ip6ProcessRedirect (IpSb, Head, Packet); - break; - case ICMP_V6_ECHO_REPLY: - Status = Ip6Demultiplex (IpSb, Head, Packet); - break; - default: - Status = EFI_INVALID_PARAMETER; - break; - } - - return Status; -} - -/** - Handle the ICMPv6 packet. First validate the message format, - then, according to the message types, process it as an informational packet or - an error packet. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the ICMPv6 packet. - @param[in] Packet The content of the ICMPv6 packet with IP head - removed. - - @retval EFI_INVALID_PARAMETER The packet is malformated. - @retval EFI_SUCCESS The ICMPv6 message successfully processed. - @retval Others Failed to handle the ICMPv6 packet. - -**/ -EFI_STATUS -Ip6IcmpHandle ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_HEAD Icmp; - UINT16 PseudoCheckSum; - UINT16 CheckSum; - - // - // Check the validity of the incoming packet. - // - if (Packet->TotalSize < sizeof (Icmp)) { - goto DROP; - } - - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - - // - // Make sure checksum is valid. - // - PseudoCheckSum = NetIp6PseudoHeadChecksum ( - &Head->SourceAddress, - &Head->DestinationAddress, - IP6_ICMP, - Packet->TotalSize - ); - CheckSum = (UINT16) ~NetAddChecksum (PseudoCheckSum, NetbufChecksum (Packet)); - if (CheckSum != 0) { - goto DROP; - } - - // - // According to the packet type, call corresponding process - // - if (Icmp.Type <= ICMP_V6_ERROR_MAX) { - return Ip6ProcessIcmpError (IpSb, Head, Packet); - } else { - return Ip6ProcessIcmpInformation (IpSb, Head, Packet); - } - -DROP: - NetbufFree (Packet); - return EFI_INVALID_PARAMETER; -} - -/** - Retrieve the Prefix address according to the PrefixLength by clear the useless - bits. - - @param[in] PrefixLength The prefix length of the prefix. - @param[in, out] Prefix On input, points to the original prefix address - with dirty bits; on output, points to the updated - address with useless bit clear. - -**/ -VOID -Ip6GetPrefix ( - IN UINT8 PrefixLength, - IN OUT EFI_IPv6_ADDRESS *Prefix - ) -{ - UINT8 Byte; - UINT8 Bit; - UINT8 Mask; - UINT8 Value; - - ASSERT ((Prefix != NULL) && (PrefixLength < IP6_PREFIX_MAX)); - - if (PrefixLength == 0) { - ZeroMem (Prefix, sizeof (EFI_IPv6_ADDRESS)); - return ; - } - - if (PrefixLength >= IP6_PREFIX_MAX) { - return ; - } - - Byte = (UINT8) (PrefixLength / 8); - Bit = (UINT8) (PrefixLength % 8); - Value = Prefix->Addr[Byte]; - - if (Byte > 0) { - ZeroMem (Prefix->Addr + Byte, 16 - Byte); - } - - if (Bit > 0) { - Mask = (UINT8) (0xFF << (8 - Bit)); - Prefix->Addr[Byte] = (UINT8) (Value & Mask); - } - -} - -/** - Check whether the DestinationAddress is an anycast address. - - @param[in] IpSb The IP service that received the packet. - @param[in] DestinationAddress Points to the Destination Address of the packet. - - @retval TRUE The DestinationAddress is anycast address. - @retval FALSE The DestinationAddress is not anycast address. - -**/ -BOOLEAN -Ip6IsAnycast ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *DestinationAddress - ) -{ - IP6_PREFIX_LIST_ENTRY *PrefixEntry; - EFI_IPv6_ADDRESS Prefix; - BOOLEAN Flag; - - ZeroMem (&Prefix, sizeof (EFI_IPv6_ADDRESS)); - - Flag = FALSE; - - // - // If the address is known as on-link or autonomous prefix, record it as - // anycast address. - // - do { - PrefixEntry = Ip6FindPrefixListEntry (IpSb, Flag, 255, DestinationAddress); - if (PrefixEntry != NULL) { - IP6_COPY_ADDRESS (&Prefix, &PrefixEntry->Prefix); - Ip6GetPrefix (PrefixEntry->PrefixLength, &Prefix); - if (EFI_IP6_EQUAL (&Prefix, DestinationAddress)) { - return TRUE; - } - } - - Flag = (BOOLEAN) !Flag; - } while (Flag); - - return FALSE; -} - -/** - Generate ICMPv6 error message and send it out to DestinationAddress. Currently - Destination Unreachable message, Time Exceeded message and Parameter Problem - message are supported. - - @param[in] IpSb The IP service that received the packet. - @param[in] Packet The packet which invoking ICMPv6 error. - @param[in] SourceAddress If not NULL, points to the SourceAddress. - Otherwise, the IP layer will select a source address - according to the DestinationAddress. - @param[in] DestinationAddress Points to the Destination Address of the ICMPv6 - error message. - @param[in] Type The type of the ICMPv6 message. - @param[in] Code The additional level of the ICMPv6 message. - @param[in] Pointer If not NULL, identifies the octet offset within - the invoking packet where the error was detected. - - @retval EFI_INVALID_PARAMETER The packet is malformated. - @retval EFI_OUT_OF_RESOURCES There is no sufficient resource to complete the - operation. - @retval EFI_SUCCESS The ICMPv6 message was successfully sent out. - @retval Others Failed to generate the ICMPv6 packet. - -**/ -EFI_STATUS -Ip6SendIcmpError ( - IN IP6_SERVICE *IpSb, - IN NET_BUF *Packet, - IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, - IN EFI_IPv6_ADDRESS *DestinationAddress, - IN UINT8 Type, - IN UINT8 Code, - IN UINT32 *Pointer OPTIONAL - ) -{ - UINT32 PacketLen; - NET_BUF *ErrorMsg; - UINT16 PayloadLen; - EFI_IP6_HEADER Head; - IP6_ICMP_INFORMATION_HEAD *IcmpHead; - UINT8 *ErrorBody; - - if (DestinationAddress == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // An ICMPv6 error message must not be originated as a result of receiving - // a packet whose source address does not uniquely identify a single node -- - // e.g., the IPv6 Unspecified Address, an IPv6 multicast address, or an address - // known by the ICMP message originator to be an IPv6 anycast address. - // - if (NetIp6IsUnspecifiedAddr (DestinationAddress) || - IP6_IS_MULTICAST (DestinationAddress) || - Ip6IsAnycast (IpSb, DestinationAddress) - ) { - return EFI_INVALID_PARAMETER; - } - - switch (Type) { - case ICMP_V6_DEST_UNREACHABLE: - case ICMP_V6_TIME_EXCEEDED: - break; - - case ICMP_V6_PARAMETER_PROBLEM: - if (Pointer == NULL) { - return EFI_INVALID_PARAMETER; - } - - break; - - default: - return EFI_INVALID_PARAMETER; - } - - PacketLen = sizeof (IP6_ICMP_ERROR_HEAD) + Packet->TotalSize; - - if (PacketLen > IpSb->MaxPacketSize) { - PacketLen = IpSb->MaxPacketSize; - } - - ErrorMsg = NetbufAlloc (PacketLen); - if (ErrorMsg == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - PayloadLen = (UINT16) (PacketLen - sizeof (EFI_IP6_HEADER)); - - // - // Create the basic IPv6 header. - // - ZeroMem (&Head, sizeof (EFI_IP6_HEADER)); - - Head.PayloadLength = HTONS (PayloadLen); - Head.NextHeader = IP6_ICMP; - Head.HopLimit = IpSb->CurHopLimit; - - if (SourceAddress != NULL) { - IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress); - } else { - ZeroMem (&Head.SourceAddress, sizeof (EFI_IPv6_ADDRESS)); - } - - IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress); - - NetbufReserve (ErrorMsg, sizeof (EFI_IP6_HEADER)); - - // - // Fill in the ICMP error message head - // - IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (ErrorMsg, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE); - if (IcmpHead == NULL) { - NetbufFree (ErrorMsg); - return EFI_OUT_OF_RESOURCES; - } - - ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD)); - IcmpHead->Head.Type = Type; - IcmpHead->Head.Code = Code; - - if (Pointer != NULL) { - IcmpHead->Fourth = HTONL (*Pointer); - } - - // - // Fill in the ICMP error message body - // - PayloadLen -= sizeof (IP6_ICMP_INFORMATION_HEAD); - ErrorBody = NetbufAllocSpace (ErrorMsg, PayloadLen, FALSE); - if (ErrorBody != NULL) { - ZeroMem (ErrorBody, PayloadLen); - NetbufCopy (Packet, 0, PayloadLen, ErrorBody); - } - - // - // Transmit the packet - // - return Ip6Output (IpSb, NULL, NULL, ErrorMsg, &Head, NULL, 0, Ip6SysPacketSent, NULL); -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Icmp.h b/Core/NetworkPkg/Ip6Dxe/Ip6Icmp.h deleted file mode 100644 index 6852ae5490..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Icmp.h +++ /dev/null @@ -1,108 +0,0 @@ -/** @file - Header file for ICMPv6 protocol. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_ICMP_H__ -#define __EFI_IP6_ICMP_H__ - -#define ICMP_V6_DEFAULT_CODE 0 - -#define ICMP_V6_ERROR_MAX 127 - -// -// ICMPv6 message classes, each class of ICMPv6 message shares -// a common message format. INVALID_MESSAGE is only a flag. -// -#define ICMP_V6_INVALID_MESSAGE 0 -#define ICMP_V6_ERROR_MESSAGE 1 -#define ICMP_V6_INFORMATION_MESSAGE 2 - - -extern EFI_IP6_ICMP_TYPE mIp6SupportedIcmp[]; - -/** - Handle the ICMPv6 packet. First validate the message format, - then, according to the message types, process it as an informational packet or - an error packet. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the ICMPv6 packet. - @param[in] Packet The content of the ICMPv6 packet with IP head - removed. - - @retval EFI_INVALID_PARAMETER The packet is malformated. - @retval EFI_SUCCESS The ICMPv6 message successfully processed. - @retval Others Failed to handle the ICMPv6 packet. - -**/ -EFI_STATUS -Ip6IcmpHandle ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - -/** - Check whether the DestinationAddress is an anycast address. - - @param[in] IpSb The IP service that received the packet. - @param[in] DestinationAddress Points to the Destination Address of the packet. - - @retval TRUE The DestinationAddress is anycast address. - @retval FALSE The DestinationAddress is not anycast address. - -**/ -BOOLEAN -Ip6IsAnycast ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *DestinationAddress - ); - -/** - Generate ICMPv6 error message and send it out to DestinationAddress. Currently - Destination Unreachable message, Time Exceeded message and Parameter Problem - message are supported. - - @param[in] IpSb The IP service that received the packet. - @param[in] Packet The packet which invoking ICMPv6 error. - @param[in] SourceAddress If not NULL, points to the SourceAddress. - Otherwise, the IP layer will select a source address - according to the DestinationAddress. - @param[in] DestinationAddress Points to the Destination Address of the ICMPv6 - error message. - @param[in] Type The type of the ICMPv6 message. - @param[in] Code The additional level of the ICMPv6 message. - @param[in] Pointer If not NULL, identifies the octet offset within - the invoking packet where the error was detected. - - @retval EFI_INVALID_PARAMETER The packet is malformated. - @retval EFI_OUT_OF_RESOURCES There is no sufficient resource to complete the - operation. - @retval EFI_SUCCESS The ICMPv6 message was successfully sent out. - @retval Others Failed to generate the ICMPv6 packet. - -**/ -EFI_STATUS -Ip6SendIcmpError ( - IN IP6_SERVICE *IpSb, - IN NET_BUF *Packet, - IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, - IN EFI_IPv6_ADDRESS *DestinationAddress, - IN UINT8 Type, - IN UINT8 Code, - IN UINT32 *Pointer OPTIONAL - ); - -#endif - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6If.c b/Core/NetworkPkg/Ip6Dxe/Ip6If.c deleted file mode 100644 index 280cd764f1..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6If.c +++ /dev/null @@ -1,798 +0,0 @@ -/** @file - Implement IP6 pesudo interface. - - Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -/** - Request Ip6OnFrameSentDpc as a DPC at TPL_CALLBACK. - - @param[in] Event The transmit token's event. - @param[in] Context The Context which is pointed to the token. - -**/ -VOID -EFIAPI -Ip6OnFrameSent ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Fileter function to cancel all the frame related to an IP instance. - - @param[in] Frame The transmit request to test whether to cancel. - @param[in] Context The context which is the Ip instance that issued - the transmit. - - @retval TRUE The frame belongs to this instance and is to be - removed. - @retval FALSE The frame doesn't belong to this instance. - -**/ -BOOLEAN -Ip6CancelInstanceFrame ( - IN IP6_LINK_TX_TOKEN *Frame, - IN VOID *Context - ) -{ - if (Frame->IpInstance == (IP6_PROTOCOL *) Context) { - return TRUE; - } - - return FALSE; -} - -/** - Set the interface's address. This will trigger the DAD process for the - address to set. To set an already set address, the lifetimes wil be - updated to the new value passed in. - - @param[in] Interface The interface to set the address. - @param[in] Ip6Addr The interface's to be assigned IPv6 address. - @param[in] IsAnycast If TRUE, the unicast IPv6 address is anycast. - Otherwise, it is not anycast. - @param[in] PrefixLength The prefix length of the Ip6Addr. - @param[in] ValidLifetime The valid lifetime for this address. - @param[in] PreferredLifetime The preferred lifetime for this address. - @param[in] DadCallback The caller's callback to trigger when DAD finishes. - This is an optional parameter that may be NULL. - @param[in] Context The context that will be passed to DadCallback. - This is an optional parameter that may be NULL. - - @retval EFI_SUCCESS The interface is scheduled to be configured with - the specified address. - @retval EFI_OUT_OF_RESOURCES Failed to set the interface's address due to - lack of resources. - -**/ -EFI_STATUS -Ip6SetAddress ( - IN IP6_INTERFACE *Interface, - IN EFI_IPv6_ADDRESS *Ip6Addr, - IN BOOLEAN IsAnycast, - IN UINT8 PrefixLength, - IN UINT32 ValidLifetime, - IN UINT32 PreferredLifetime, - IN IP6_DAD_CALLBACK DadCallback OPTIONAL, - IN VOID *Context OPTIONAL - ) -{ - IP6_SERVICE *IpSb; - IP6_ADDRESS_INFO *AddressInfo; - LIST_ENTRY *Entry; - IP6_PREFIX_LIST_ENTRY *PrefixEntry; - UINT64 Delay; - IP6_DELAY_JOIN_LIST *DelayNode; - - NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE); - - IpSb = Interface->Service; - - if (Ip6IsOneOfSetAddress (IpSb, Ip6Addr, NULL, &AddressInfo)) { - ASSERT (AddressInfo != NULL); - // - // Update the lifetime. - // - AddressInfo->ValidLifetime = ValidLifetime; - AddressInfo->PreferredLifetime = PreferredLifetime; - - if (DadCallback != NULL) { - DadCallback (TRUE, Ip6Addr, Context); - } - - return EFI_SUCCESS; - } - - AddressInfo = (IP6_ADDRESS_INFO *) AllocatePool (sizeof (IP6_ADDRESS_INFO)); - if (AddressInfo == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - AddressInfo->Signature = IP6_ADDR_INFO_SIGNATURE; - IP6_COPY_ADDRESS (&AddressInfo->Address, Ip6Addr); - AddressInfo->IsAnycast = IsAnycast; - AddressInfo->PrefixLength = PrefixLength; - AddressInfo->ValidLifetime = ValidLifetime; - AddressInfo->PreferredLifetime = PreferredLifetime; - - if (AddressInfo->PrefixLength == 0) { - // - // Find an appropriate prefix from on-link prefixes and update the prefixlength. - // Longest prefix match is used here. - // - NET_LIST_FOR_EACH (Entry, &IpSb->OnlinkPrefix) { - PrefixEntry = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link); - - if (NetIp6IsNetEqual (&PrefixEntry->Prefix, &AddressInfo->Address, PrefixEntry->PrefixLength)) { - AddressInfo->PrefixLength = PrefixEntry->PrefixLength; - break; - } - } - } - - if (AddressInfo->PrefixLength == 0) { - // - // If the prefix length is still zero, try the autonomous prefixes. - // Longest prefix match is used here. - // - NET_LIST_FOR_EACH (Entry, &IpSb->AutonomousPrefix) { - PrefixEntry = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link); - - if (NetIp6IsNetEqual (&PrefixEntry->Prefix, &AddressInfo->Address, PrefixEntry->PrefixLength)) { - AddressInfo->PrefixLength = PrefixEntry->PrefixLength; - break; - } - } - } - - if (AddressInfo->PrefixLength == 0) { - // - // BUGBUG: Stil fail, use 64 as the default prefix length. - // - AddressInfo->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH; - } - - - // - // Node should delay joining the solicited-node mulitcast address by a random delay - // between 0 and MAX_RTR_SOLICITATION_DELAY (1 second). - // Thus queue the address to be processed in Duplicate Address Detection module - // after the delay time (in milliseconds). - // - Delay = (UINT64) NET_RANDOM (NetRandomInitSeed ()); - Delay = MultU64x32 (Delay, IP6_ONE_SECOND_IN_MS); - Delay = RShiftU64 (Delay, 32); - - DelayNode = (IP6_DELAY_JOIN_LIST *) AllocatePool (sizeof (IP6_DELAY_JOIN_LIST)); - if (DelayNode == NULL) { - FreePool (AddressInfo); - return EFI_OUT_OF_RESOURCES; - } - - DelayNode->DelayTime = (UINT32) (DivU64x32 (Delay, IP6_TIMER_INTERVAL_IN_MS)); - DelayNode->Interface = Interface; - DelayNode->AddressInfo = AddressInfo; - DelayNode->DadCallback = DadCallback; - DelayNode->Context = Context; - - InsertTailList (&Interface->DelayJoinList, &DelayNode->Link); - return EFI_SUCCESS; -} - -/** - Create an IP6_INTERFACE. - - @param[in] IpSb The IP6 service binding instance. - @param[in] LinkLocal If TRUE, the instance is created for link-local address. - Otherwise, it is not for a link-local address. - - @return Point to the created IP6_INTERFACE, otherwise NULL. - -**/ -IP6_INTERFACE * -Ip6CreateInterface ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN LinkLocal - ) -{ - EFI_STATUS Status; - IP6_INTERFACE *Interface; - EFI_IPv6_ADDRESS *Ip6Addr; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - Interface = AllocatePool (sizeof (IP6_INTERFACE)); - if (Interface == NULL) { - return NULL; - } - - Interface->Signature = IP6_INTERFACE_SIGNATURE; - Interface->RefCnt = 1; - - InitializeListHead (&Interface->AddressList); - Interface->AddressCount = 0; - Interface->Configured = FALSE; - - Interface->Service = IpSb; - Interface->Controller = IpSb->Controller; - Interface->Image = IpSb->Image; - - InitializeListHead (&Interface->ArpQues); - InitializeListHead (&Interface->SentFrames); - - Interface->DupAddrDetect = IpSb->Ip6ConfigInstance.DadXmits.DupAddrDetectTransmits; - InitializeListHead (&Interface->DupAddrDetectList); - - InitializeListHead (&Interface->DelayJoinList); - - InitializeListHead (&Interface->IpInstances); - Interface->PromiscRecv = FALSE; - - if (!LinkLocal) { - return Interface; - } - - // - // Get the link local addr - // - Ip6Addr = Ip6CreateLinkLocalAddr (IpSb); - if (Ip6Addr == NULL) { - goto ON_ERROR; - } - - // - // Perform DAD - Duplicate Address Detection. - // - Status = Ip6SetAddress ( - Interface, - Ip6Addr, - FALSE, - IP6_LINK_LOCAL_PREFIX_LENGTH, - (UINT32) IP6_INFINIT_LIFETIME, - (UINT32) IP6_INFINIT_LIFETIME, - NULL, - NULL - ); - - FreePool (Ip6Addr); - - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - return Interface; - -ON_ERROR: - - FreePool (Interface); - return NULL; -} - -/** - Free the interface used by IpInstance. All the IP instance with - the same Ip/prefix pair share the same interface. It is reference - counted. All the frames that haven't been sent will be cancelled. - Because the IpInstance is optional, the caller must remove - IpInstance from the interface's instance list. - - @param[in] Interface The interface used by the IpInstance. - @param[in] IpInstance The IP instance that free the interface. NULL if - the IP driver is releasing the default interface. - -**/ -VOID -Ip6CleanInterface ( - IN IP6_INTERFACE *Interface, - IN IP6_PROTOCOL *IpInstance OPTIONAL - ) -{ - IP6_DAD_ENTRY *Duplicate; - IP6_DELAY_JOIN_LIST *Delay; - - NET_CHECK_SIGNATURE (Interface, IP6_INTERFACE_SIGNATURE); - ASSERT (Interface->RefCnt > 0); - - // - // Remove all the pending transmit token related to this IP instance. - // - Ip6CancelFrames (Interface, EFI_ABORTED, Ip6CancelInstanceFrame, IpInstance); - - if (--Interface->RefCnt > 0) { - return; - } - - // - // Destroy the interface if this is the last IP instance. - // Remove all the system transmitted packets - // from this interface, cancel the receive request if exists. - // - Ip6CancelFrames (Interface, EFI_ABORTED, Ip6CancelInstanceFrame, NULL); - - ASSERT (IsListEmpty (&Interface->IpInstances)); - ASSERT (IsListEmpty (&Interface->ArpQues)); - ASSERT (IsListEmpty (&Interface->SentFrames)); - - while (!IsListEmpty (&Interface->DupAddrDetectList)) { - Duplicate = NET_LIST_HEAD (&Interface->DupAddrDetectList, IP6_DAD_ENTRY, Link); - NetListRemoveHead (&Interface->DupAddrDetectList); - FreePool (Duplicate); - } - - while (!IsListEmpty (&Interface->DelayJoinList)) { - Delay = NET_LIST_HEAD (&Interface->DelayJoinList, IP6_DELAY_JOIN_LIST, Link); - NetListRemoveHead (&Interface->DelayJoinList); - FreePool (Delay); - } - - Ip6RemoveAddr (Interface->Service, &Interface->AddressList, &Interface->AddressCount, NULL, 0); - - RemoveEntryList (&Interface->Link); - FreePool (Interface); -} - -/** - Create and wrap a transmit request into a newly allocated IP6_LINK_TX_TOKEN. - - @param[in] Interface The interface to send out from. - @param[in] IpInstance The IpInstance that transmit the packet. NULL if - the packet is sent by the IP6 driver itself. - @param[in] Packet The packet to transmit - @param[in] CallBack Call back function to execute if transmission - finished. - @param[in] Context Opaque parameter to the callback. - - @return The wrapped token if succeed or NULL. - -**/ -IP6_LINK_TX_TOKEN * -Ip6CreateLinkTxToken ( - IN IP6_INTERFACE *Interface, - IN IP6_PROTOCOL *IpInstance OPTIONAL, - IN NET_BUF *Packet, - IN IP6_FRAME_CALLBACK CallBack, - IN VOID *Context - ) -{ - EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken; - EFI_MANAGED_NETWORK_TRANSMIT_DATA *MnpTxData; - IP6_LINK_TX_TOKEN *Token; - EFI_STATUS Status; - UINT32 Count; - - Token = AllocatePool (sizeof (IP6_LINK_TX_TOKEN) + (Packet->BlockOpNum - 1) * sizeof (EFI_MANAGED_NETWORK_FRAGMENT_DATA)); - - if (Token == NULL) { - return NULL; - } - - Token->Signature = IP6_LINK_TX_SIGNATURE; - InitializeListHead (&Token->Link); - - Token->IpInstance = IpInstance; - Token->CallBack = CallBack; - Token->Packet = Packet; - Token->Context = Context; - ZeroMem (&Token->DstMac, sizeof (EFI_MAC_ADDRESS)); - IP6_COPY_LINK_ADDRESS (&Token->SrcMac, &Interface->Service->SnpMode.CurrentAddress); - - MnpToken = &(Token->MnpToken); - MnpToken->Status = EFI_NOT_READY; - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - Ip6OnFrameSent, - Token, - &MnpToken->Event - ); - - if (EFI_ERROR (Status)) { - FreePool (Token); - return NULL; - } - - MnpTxData = &Token->MnpTxData; - MnpToken->Packet.TxData = MnpTxData; - - MnpTxData->DestinationAddress = &Token->DstMac; - MnpTxData->SourceAddress = &Token->SrcMac; - MnpTxData->ProtocolType = IP6_ETHER_PROTO; - MnpTxData->DataLength = Packet->TotalSize; - MnpTxData->HeaderLength = 0; - - Count = Packet->BlockOpNum; - - NetbufBuildExt (Packet, (NET_FRAGMENT *) MnpTxData->FragmentTable, &Count); - MnpTxData->FragmentCount = (UINT16)Count; - - return Token; -} - -/** - Free the link layer transmit token. It will close the event, - then free the memory used. - - @param[in] Token Token to free. - -**/ -VOID -Ip6FreeLinkTxToken ( - IN IP6_LINK_TX_TOKEN *Token - ) -{ - NET_CHECK_SIGNATURE (Token, IP6_LINK_TX_SIGNATURE); - - gBS->CloseEvent (Token->MnpToken.Event); - FreePool (Token); -} - -/** - Callback function when the received packet is freed. - Check Ip6OnFrameReceived for information. - - @param[in] Context Points to EFI_MANAGED_NETWORK_RECEIVE_DATA. - -**/ -VOID -EFIAPI -Ip6RecycleFrame ( - IN VOID *Context - ) -{ - EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData; - - RxData = (EFI_MANAGED_NETWORK_RECEIVE_DATA *) Context; - - gBS->SignalEvent (RxData->RecycleEvent); -} - -/** - Received a frame from MNP. Wrap it in net buffer then deliver - it to IP's input function. The ownship of the packet also - is transferred to IP. When Ip is finished with this packet, it - will call NetbufFree to release the packet, NetbufFree will - again call the Ip6RecycleFrame to signal MNP's event and free - the token used. - - @param[in] Context Context for the callback. - -**/ -VOID -EFIAPI -Ip6OnFrameReceivedDpc ( - IN VOID *Context - ) -{ - EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken; - EFI_MANAGED_NETWORK_RECEIVE_DATA *MnpRxData; - IP6_LINK_RX_TOKEN *Token; - NET_FRAGMENT Netfrag; - NET_BUF *Packet; - UINT32 Flag; - IP6_SERVICE *IpSb; - - Token = (IP6_LINK_RX_TOKEN *) Context; - NET_CHECK_SIGNATURE (Token, IP6_LINK_RX_SIGNATURE); - - // - // First clear the interface's receive request in case the - // caller wants to call Ip6ReceiveFrame in the callback. - // - IpSb = (IP6_SERVICE *) Token->Context; - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - - MnpToken = &Token->MnpToken; - MnpRxData = MnpToken->Packet.RxData; - - if (EFI_ERROR (MnpToken->Status) || (MnpRxData == NULL)) { - Token->CallBack (NULL, MnpToken->Status, 0, Token->Context); - return ; - } - - // - // Wrap the frame in a net buffer then deliever it to IP input. - // IP will reassemble the packet, and deliver it to upper layer - // - Netfrag.Len = MnpRxData->DataLength; - Netfrag.Bulk = MnpRxData->PacketData; - - Packet = NetbufFromExt (&Netfrag, 1, IP6_MAX_HEADLEN, 0, Ip6RecycleFrame, Token->MnpToken.Packet.RxData); - - if (Packet == NULL) { - gBS->SignalEvent (MnpRxData->RecycleEvent); - - Token->CallBack (NULL, EFI_OUT_OF_RESOURCES, 0, Token->Context); - - return ; - } - - Flag = (MnpRxData->BroadcastFlag ? IP6_LINK_BROADCAST : 0); - Flag |= (MnpRxData->MulticastFlag ? IP6_LINK_MULTICAST : 0); - Flag |= (MnpRxData->PromiscuousFlag ? IP6_LINK_PROMISC : 0); - - Token->CallBack (Packet, EFI_SUCCESS, Flag, Token->Context); -} - -/** - Request Ip6OnFrameReceivedDpc as a DPC at TPL_CALLBACK. - - @param Event The receive event delivered to MNP for receive. - @param Context Context for the callback. - -**/ -VOID -EFIAPI -Ip6OnFrameReceived ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - // - // Request Ip6OnFrameReceivedDpc as a DPC at TPL_CALLBACK - // - QueueDpc (TPL_CALLBACK, Ip6OnFrameReceivedDpc, Context); -} - -/** - Request to receive the packet from the interface. - - @param[in] CallBack Function to call when receive finished. - @param[in] IpSb Points to IP6 service binding instance. - - @retval EFI_ALREADY_STARTED There is already a pending receive request. - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to receive. - @retval EFI_SUCCESS The recieve request has been started. - -**/ -EFI_STATUS -Ip6ReceiveFrame ( - IN IP6_FRAME_CALLBACK CallBack, - IN IP6_SERVICE *IpSb - ) -{ - EFI_STATUS Status; - IP6_LINK_RX_TOKEN *Token; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - Token = &IpSb->RecvRequest; - Token->CallBack = CallBack; - Token->Context = (VOID *) IpSb; - - Status = IpSb->Mnp->Receive (IpSb->Mnp, &Token->MnpToken); - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_SUCCESS; -} - -/** - Callback funtion when frame transmission is finished. It will - call the frame owner's callback function to tell it the result. - - @param[in] Context Context which points to the token. - -**/ -VOID -EFIAPI -Ip6OnFrameSentDpc ( - IN VOID *Context - ) -{ - IP6_LINK_TX_TOKEN *Token; - - Token = (IP6_LINK_TX_TOKEN *) Context; - NET_CHECK_SIGNATURE (Token, IP6_LINK_TX_SIGNATURE); - - RemoveEntryList (&Token->Link); - - Token->CallBack ( - Token->Packet, - Token->MnpToken.Status, - 0, - Token->Context - ); - - Ip6FreeLinkTxToken (Token); -} - -/** - Request Ip6OnFrameSentDpc as a DPC at TPL_CALLBACK. - - @param[in] Event The transmit token's event. - @param[in] Context Context which points to the token. - -**/ -VOID -EFIAPI -Ip6OnFrameSent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - // - // Request Ip6OnFrameSentDpc as a DPC at TPL_CALLBACK - // - QueueDpc (TPL_CALLBACK, Ip6OnFrameSentDpc, Context); -} - -/** - Send a frame from the interface. If the next hop is a multicast address, - it is transmitted immediately. If the next hop is a unicast, - and the NextHop's MAC is not known, it will perform address resolution. - If an error occurred, the CallBack won't be called. So, the caller - must test the return value, and take action when there is an error. - - @param[in] Interface The interface to send the frame from - @param[in] IpInstance The IP child that request the transmission. - NULL if it is the IP6 driver itself. - @param[in] Packet The packet to transmit. - @param[in] NextHop The immediate destination to transmit the packet to. - @param[in] CallBack Function to call back when transmit finished. - @param[in] Context Opaque parameter to the callback. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to send the frame. - @retval EFI_NO_MAPPING Can't resolve the MAC for the nexthop. - @retval EFI_SUCCESS The packet successfully transmitted. - -**/ -EFI_STATUS -Ip6SendFrame ( - IN IP6_INTERFACE *Interface, - IN IP6_PROTOCOL *IpInstance OPTIONAL, - IN NET_BUF *Packet, - IN EFI_IPv6_ADDRESS *NextHop, - IN IP6_FRAME_CALLBACK CallBack, - IN VOID *Context - ) -{ - IP6_SERVICE *IpSb; - IP6_LINK_TX_TOKEN *Token; - EFI_STATUS Status; - IP6_NEIGHBOR_ENTRY *NeighborCache; - LIST_ENTRY *Entry; - IP6_NEIGHBOR_ENTRY *ArpQue; - - IpSb = Interface->Service; - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - // - // Only when link local address is performing DAD, the interface could be used in unconfigured. - // - if (IpSb->LinkLocalOk) { - ASSERT (Interface->Configured); - } - - Token = Ip6CreateLinkTxToken (Interface, IpInstance, Packet, CallBack, Context); - - if (Token == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (IP6_IS_MULTICAST (NextHop)) { - Status = Ip6GetMulticastMac (IpSb->Mnp, NextHop, &Token->DstMac); - if (EFI_ERROR (Status)) { - goto Error; - } - - goto SendNow; - } - - // - // If send to itself, directly send out - // - if (EFI_IP6_EQUAL (&Packet->Ip.Ip6->DestinationAddress, &Packet->Ip.Ip6->SourceAddress)) { - IP6_COPY_LINK_ADDRESS (&Token->DstMac, &IpSb->SnpMode.CurrentAddress); - goto SendNow; - } - - // - // If unicast, check the neighbor state. - // - - NeighborCache = Ip6FindNeighborEntry (IpSb, NextHop); - ASSERT (NeighborCache != NULL); - - if (NeighborCache->Interface == NULL) { - NeighborCache->Interface = Interface; - } - - switch (NeighborCache->State) { - case EfiNeighborStale: - NeighborCache->State = EfiNeighborDelay; - NeighborCache->Ticks = (UINT32) IP6_GET_TICKS (IP6_DELAY_FIRST_PROBE_TIME); - // - // Fall through - // - case EfiNeighborReachable: - case EfiNeighborDelay: - case EfiNeighborProbe: - IP6_COPY_LINK_ADDRESS (&Token->DstMac, &NeighborCache->LinkAddress); - goto SendNow; - break; - - default: - break; - } - - // - // Have to do asynchronous ARP resolution. First check whether there is - // already a pending request. - // - NET_LIST_FOR_EACH (Entry, &Interface->ArpQues) { - ArpQue = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, ArpList); - if (ArpQue == NeighborCache) { - InsertTailList (&NeighborCache->Frames, &Token->Link); - NeighborCache->ArpFree = TRUE; - return EFI_SUCCESS; - } - } - - // - // First frame requires ARP. - // - InsertTailList (&NeighborCache->Frames, &Token->Link); - InsertTailList (&Interface->ArpQues, &NeighborCache->ArpList); - - NeighborCache->ArpFree = TRUE; - - return EFI_SUCCESS; - -SendNow: - // - // Insert the tx token into the SentFrames list before calling Mnp->Transmit. - // Remove it if the returned status is not EFI_SUCCESS. - // - InsertTailList (&Interface->SentFrames, &Token->Link); - Status = IpSb->Mnp->Transmit (IpSb->Mnp, &Token->MnpToken); - if (EFI_ERROR (Status)) { - RemoveEntryList (&Token->Link); - goto Error; - } - - return EFI_SUCCESS; - -Error: - Ip6FreeLinkTxToken (Token); - return Status; -} - -/** - The heartbeat timer of IP6 service instance. It times out - all of its IP6 children's received-but-not-delivered and - transmitted-but-not-recycle packets. - - @param[in] Event The IP6 service instance's heartbeat timer. - @param[in] Context The IP6 service instance. - -**/ -VOID -EFIAPI -Ip6TimerTicking ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - IP6_SERVICE *IpSb; - - IpSb = (IP6_SERVICE *) Context; - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - Ip6PacketTimerTicking (IpSb); - Ip6NdTimerTicking (IpSb); - Ip6MldTimerTicking (IpSb); -} diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6If.h b/Core/NetworkPkg/Ip6Dxe/Ip6If.h deleted file mode 100644 index 736035ec39..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6If.h +++ /dev/null @@ -1,267 +0,0 @@ -/** @file - Definition for IP6 pesudo interface structure. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_IF_H__ -#define __EFI_IP6_IF_H__ - -#define IP6_LINK_RX_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'R') -#define IP6_LINK_TX_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'T') -#define IP6_INTERFACE_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'I') -#define IP6_ADDR_INFO_SIGNATURE SIGNATURE_32 ('I', 'P', 'A', 'I') - -// -// This prototype is used by both receive and transmission. -// When receiving Netbuf is allocated by IP6_INTERFACE, and -// released by IP6. Flag shows whether the frame is received -// as unicast/multicast/anycast... -// -// When transmitting, the Netbuf is from IP6, and provided -// to the callback as a reference. Flag isn't used. -// -// IpInstance can be NULL which means that it is the IP6 driver -// itself sending the packets. IP6 driver may send packets that -// don't belong to any instance, such as ICMP errors, ICMP -// informational packets. IpInstance is used as a tag in -// this module. -// -typedef -VOID -(*IP6_FRAME_CALLBACK) ( - NET_BUF *Packet, - EFI_STATUS IoStatus, - UINT32 LinkFlag, - VOID *Context - ); - -// -// Each receive request is wrapped in an IP6_LINK_RX_TOKEN. -// Upon completion, the Callback will be called. Only one -// receive request is send to MNP. IpInstance is always NULL. -// Reference MNP's spec for information. -// -typedef struct { - UINT32 Signature; - IP6_FRAME_CALLBACK CallBack; - VOID *Context; - EFI_MANAGED_NETWORK_COMPLETION_TOKEN MnpToken; -} IP6_LINK_RX_TOKEN; - -// -// Each transmit request is wrapped in an IP6_LINK_TX_TOKEN. -// Upon completion, the Callback will be called. -// -typedef struct { - UINT32 Signature; - LIST_ENTRY Link; - - IP6_PROTOCOL *IpInstance; - IP6_FRAME_CALLBACK CallBack; - NET_BUF *Packet; - VOID *Context; - - EFI_MAC_ADDRESS DstMac; - EFI_MAC_ADDRESS SrcMac; - - EFI_MANAGED_NETWORK_COMPLETION_TOKEN MnpToken; - EFI_MANAGED_NETWORK_TRANSMIT_DATA MnpTxData; -} IP6_LINK_TX_TOKEN; - -struct _IP6_ADDRESS_INFO { - UINT32 Signature; - LIST_ENTRY Link; - EFI_IPv6_ADDRESS Address; - BOOLEAN IsAnycast; - UINT8 PrefixLength; - UINT32 ValidLifetime; - UINT32 PreferredLifetime; -}; - -// -// Callback to select which frame to cancel. Caller can cancel a -// single frame, or all the frame from an IP instance. -// -typedef -BOOLEAN -(*IP6_FRAME_TO_CANCEL) ( - IP6_LINK_TX_TOKEN *Frame, - VOID *Context - ); - -struct _IP6_INTERFACE { - UINT32 Signature; - LIST_ENTRY Link; - INTN RefCnt; - - // - // IP address and prefix length of the interface. The fileds - // are invalid if (Configured == FALSE) - // - LIST_ENTRY AddressList; - UINT32 AddressCount; - BOOLEAN Configured; - - IP6_SERVICE *Service; - - EFI_HANDLE Controller; - EFI_HANDLE Image; - - - // - // Queues to keep the frames sent and waiting ARP request. - // - LIST_ENTRY ArpQues; - LIST_ENTRY SentFrames; - - - // - // The interface's configuration variables - // - UINT32 DupAddrDetect; - LIST_ENTRY DupAddrDetectList; - LIST_ENTRY DelayJoinList; - - // - // All the IP instances that have the same IP/SubnetMask are linked - // together through IpInstances. If any of the instance enables - // promiscuous receive, PromiscRecv is true. - // - LIST_ENTRY IpInstances; - BOOLEAN PromiscRecv; -}; - -/** - Create an IP6_INTERFACE. - - @param[in] IpSb The IP6 service binding instance. - @param[in] LinkLocal If TRUE, the instance is created for link-local address. - Otherwise, it is not for a link-local address. - - @return Point to the created IP6_INTERFACE, otherwise NULL. - -**/ -IP6_INTERFACE * -Ip6CreateInterface ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN LinkLocal - ); - -/** - Free the interface used by IpInstance. All the IP instance with - the same Ip/prefix pair share the same interface. It is reference - counted. All the frames that haven't been sent will be cancelled. - Because the IpInstance is optional, the caller must remove - IpInstance from the interface's instance list. - - @param[in] Interface The interface used by the IpInstance. - @param[in] IpInstance The IP instance that free the interface. NULL if - the IP driver is releasing the default interface. - -**/ -VOID -Ip6CleanInterface ( - IN IP6_INTERFACE *Interface, - IN IP6_PROTOCOL *IpInstance OPTIONAL - ); - -/** - Free the link layer transmit token. It will close the event - then free the memory used. - - @param[in] Token Token to free. - -**/ -VOID -Ip6FreeLinkTxToken ( - IN IP6_LINK_TX_TOKEN *Token - ); - -/** - Request Ip6OnFrameReceivedDpc as a DPC at TPL_CALLBACK - - @param Event The receive event delivered to MNP for receive. - @param Context Context for the callback. - -**/ -VOID -EFIAPI -Ip6OnFrameReceived ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Request to receive the packet from the interface. - - @param[in] CallBack Function to call when the receive finished. - @param[in] IpSb Points to the IP6 service binding instance. - - @retval EFI_ALREADY_STARTED There is already a pending receive request. - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to receive. - @retval EFI_SUCCESS The recieve request has been started. - -**/ -EFI_STATUS -Ip6ReceiveFrame ( - IN IP6_FRAME_CALLBACK CallBack, - IN IP6_SERVICE *IpSb - ); - -/** - Send a frame from the interface. If the next hop is multicast address, - it is transmitted immediately. If the next hop is a unicast, - and the NextHop's MAC is not known, it will perform address resolution. - If some error happened, the CallBack won't be called. So, the caller - must test the return value, and take action when there is an error. - - @param[in] Interface The interface to send the frame from - @param[in] IpInstance The IP child that request the transmission. - NULL if it is the IP6 driver itself. - @param[in] Packet The packet to transmit. - @param[in] NextHop The immediate destination to transmit the packet to. - @param[in] CallBack Function to call back when transmit finished. - @param[in] Context Opaque parameter to the call back. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to send the frame. - @retval EFI_NO_MAPPING Can't resolve the MAC for the nexthop. - @retval EFI_SUCCESS The packet successfully transmitted. - -**/ -EFI_STATUS -Ip6SendFrame ( - IN IP6_INTERFACE *Interface, - IN IP6_PROTOCOL *IpInstance OPTIONAL, - IN NET_BUF *Packet, - IN EFI_IPv6_ADDRESS *NextHop, - IN IP6_FRAME_CALLBACK CallBack, - IN VOID *Context - ); - -/** - The heartbeat timer of IP6 service instance. It times out - all of its IP6 children's received-but-not-delivered and - transmitted-but-not-recycle packets. - - @param[in] Event The IP6 service instance's heart beat timer. - @param[in] Context The IP6 service instance. - -**/ -VOID -EFIAPI -Ip6TimerTicking ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Impl.c b/Core/NetworkPkg/Ip6Dxe/Ip6Impl.c deleted file mode 100644 index c937423428..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Impl.c +++ /dev/null @@ -1,1847 +0,0 @@ -/** @file - Implementation of EFI_IP6_PROTOCOL protocol interfaces. - - (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -EFI_IPSEC2_PROTOCOL *mIpSec = NULL; - -EFI_IP6_PROTOCOL mEfiIp6ProtocolTemplete = { - EfiIp6GetModeData, - EfiIp6Configure, - EfiIp6Groups, - EfiIp6Routes, - EfiIp6Neighbors, - EfiIp6Transmit, - EfiIp6Receive, - EfiIp6Cancel, - EfiIp6Poll -}; - -/** - 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6GetModeData ( - 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 - ) -{ - IP6_PROTOCOL *IpInstance; - IP6_SERVICE *IpSb; - IP6_INTERFACE *IpIf; - EFI_IP6_CONFIG_DATA *Config; - EFI_STATUS Status; - EFI_TPL OldTpl; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - IpIf = IpInstance->Interface; - - if (IpSb->LinkLocalDadFail) { - return EFI_INVALID_PARAMETER; - } - - if (Ip6ModeData != NULL) { - // - // IsStarted is "whether the EfiIp6Configure has been called". - // IsConfigured is "whether the station address has been configured" - // - Ip6ModeData->IsStarted = (BOOLEAN) (IpInstance->State == IP6_STATE_CONFIGED); - Ip6ModeData->MaxPacketSize = IpSb->MaxPacketSize; - CopyMem (&Ip6ModeData->ConfigData, &IpInstance->ConfigData, sizeof (EFI_IP6_CONFIG_DATA)); - Ip6ModeData->IsConfigured = FALSE; - - Ip6ModeData->AddressCount = 0; - Ip6ModeData->AddressList = NULL; - - Ip6ModeData->GroupCount = IpInstance->GroupCount; - Ip6ModeData->GroupTable = NULL; - - Ip6ModeData->RouteCount = 0; - Ip6ModeData->RouteTable = NULL; - - Ip6ModeData->NeighborCount = 0; - Ip6ModeData->NeighborCache = NULL; - - Ip6ModeData->PrefixCount = 0; - Ip6ModeData->PrefixTable = NULL; - - Ip6ModeData->IcmpTypeCount = 23; - Ip6ModeData->IcmpTypeList = AllocateCopyPool ( - Ip6ModeData->IcmpTypeCount * sizeof (EFI_IP6_ICMP_TYPE), - mIp6SupportedIcmp - ); - if (Ip6ModeData->IcmpTypeList == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - // - // Return the currently configured IPv6 addresses and corresponding prefix lengths. - // - Status = Ip6BuildEfiAddressList ( - IpSb, - &Ip6ModeData->AddressCount, - &Ip6ModeData->AddressList - ); - if (EFI_ERROR (Status)) { - goto Error; - } - - // - // Return the current station address for this IP child. - // If UseAnyStationAddress is set to TRUE, IP6 driver will - // select a source address from its address list. Otherwise use the - // StationAddress in config data. - // - if (Ip6ModeData->IsStarted) { - Config = &Ip6ModeData->ConfigData; - - if (IpIf->Configured || NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) { - Ip6ModeData->IsConfigured = TRUE; - } else { - Ip6ModeData->IsConfigured = FALSE; - } - - // - // Build a EFI route table for user from the internal route table. - // - Status = Ip6BuildEfiRouteTable ( - IpSb->RouteTable, - &Ip6ModeData->RouteCount, - &Ip6ModeData->RouteTable - ); - - if (EFI_ERROR (Status)) { - goto Error; - } - } - - if (Ip6ModeData->IsConfigured) { - // - // Return the joined multicast group addresses. - // - if (IpInstance->GroupCount != 0) { - Ip6ModeData->GroupTable = AllocateCopyPool ( - IpInstance->GroupCount * sizeof (EFI_IPv6_ADDRESS), - IpInstance->GroupList - ); - if (Ip6ModeData->GroupTable == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - } - // - // Return the neighbor cache entries - // - Status = Ip6BuildEfiNeighborCache ( - IpInstance, - &Ip6ModeData->NeighborCount, - &Ip6ModeData->NeighborCache - ); - if (EFI_ERROR (Status)) { - goto Error; - } - - // - // Return the prefix table entries - // - Status = Ip6BuildPrefixTable ( - IpInstance, - &Ip6ModeData->PrefixCount, - &Ip6ModeData->PrefixTable - ); - if (EFI_ERROR (Status)) { - goto Error; - } - - } - } - - // - // Get fresh mode data from MNP, since underlying media status may change - // - Status = IpSb->Mnp->GetModeData (IpSb->Mnp, MnpConfigData, SnpModeData); - - goto Exit; - -Error: - if (Ip6ModeData != NULL) { - if (Ip6ModeData->AddressList != NULL) { - FreePool (Ip6ModeData->AddressList); - } - - if (Ip6ModeData->GroupTable != NULL) { - FreePool (Ip6ModeData->GroupTable); - } - - if (Ip6ModeData->RouteTable != NULL) { - FreePool (Ip6ModeData->RouteTable); - } - - if (Ip6ModeData->NeighborCache != NULL) { - FreePool (Ip6ModeData->NeighborCache); - } - - if (Ip6ModeData->PrefixTable != NULL) { - FreePool (Ip6ModeData->PrefixTable); - } - - if (Ip6ModeData->IcmpTypeList != NULL) { - FreePool (Ip6ModeData->IcmpTypeList); - } - } - -Exit: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Validate that Ipv6 address is OK to be used as station address or next hop address/ neighbor. - - @param[in] IpSb The IP6 service instance. - @param[in] Ip The IPv6 address to validate. - @param[in] Flag If TRUE, validate if the address is OK to be used - as station address. If FALSE, validate if the - address is OK to be used as the next hop address/ - neighbor. - - @retval TRUE The Ip address is valid and could be used. - @retval FALSE Invalid Ip address. - -**/ -BOOLEAN -Ip6IsValidAddress ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Ip, - IN BOOLEAN Flag - ) -{ - if (!NetIp6IsUnspecifiedAddr (Ip)) { - if (!NetIp6IsValidUnicast(Ip)) { - return FALSE; - } - if (Ip6IsOneOfSetAddress (IpSb, Ip, NULL, NULL)) { - return Flag; - } - } else { - return Flag; - } - - return (BOOLEAN) !Flag; -} - -/** - Validate whether the value of protocol is illegal or not. Protocol is the 'Next Header' field - in the last IPv6 extension header, or basic IPv6 header is there's no extension header. - - @param[in] Protocol Default value of 'Next Header' - - @retval TRUE The protocol is illegal. - @retval FALSE The protocol is legal. - -**/ -BOOLEAN -Ip6IsIllegalProtocol ( - IN UINT8 Protocol - ) -{ - if (Protocol == IP6_HOP_BY_HOP || Protocol == EFI_IP_PROTO_ICMP || Protocol == IP4_PROTO_IGMP) { - return TRUE; - } - - if (Protocol == 41 || Protocol == 43 || Protocol == 44 || Protocol == 59 || Protocol == 60 || Protocol == 124) { - return TRUE; - } - - return FALSE; -} - -/** - Intiialize the IP6_PROTOCOL structure to the unconfigured states. - - @param[in] IpSb The IP6 service instance. - @param[in, out] IpInstance The IP6 child instance. - -**/ -VOID -Ip6InitProtocol ( - IN IP6_SERVICE *IpSb, - IN OUT IP6_PROTOCOL *IpInstance - ) -{ - ASSERT ((IpSb != NULL) && (IpInstance != NULL)); - - ZeroMem (IpInstance, sizeof (IP6_PROTOCOL)); - - IpInstance->Signature = IP6_PROTOCOL_SIGNATURE; - IpInstance->State = IP6_STATE_UNCONFIGED; - IpInstance->Service = IpSb; - IpInstance->GroupList = NULL; - CopyMem (&IpInstance->Ip6Proto, &mEfiIp6ProtocolTemplete, sizeof (EFI_IP6_PROTOCOL)); - - NetMapInit (&IpInstance->RxTokens); - NetMapInit (&IpInstance->TxTokens); - InitializeListHead (&IpInstance->Received); - InitializeListHead (&IpInstance->Delivered); - - EfiInitializeLock (&IpInstance->RecycleLock, TPL_NOTIFY); -} - -/** - Configure the IP6 child. If the child is already configured, - change the configuration parameter. Otherwise, configure it - for the first time. The caller should validate the configuration - before deliver them to it. It also don't do configure NULL. - - @param[in, out] IpInstance The IP6 child to configure. - @param[in] Config The configure data. - - @retval EFI_SUCCESS The IP6 child is successfully configured. - @retval EFI_DEVICE_ERROR Failed to free the pending transive or to - configure underlying MNP, or other errors. - @retval EFI_NO_MAPPING The IP6 child is configured to use the default - address, but the default address hasn't been - configured. The IP6 child doesn't need to be - reconfigured when the default address is configured. - @retval EFI_OUT_OF_RESOURCES No more memory space is available. - @retval other Other error occurs. - -**/ -EFI_STATUS -Ip6ConfigProtocol ( - IN OUT IP6_PROTOCOL *IpInstance, - IN EFI_IP6_CONFIG_DATA *Config - ) -{ - IP6_SERVICE *IpSb; - IP6_INTERFACE *IpIf; - EFI_STATUS Status; - EFI_IP6_CONFIG_DATA *Current; - IP6_ADDRESS_INFO *AddressInfo; - BOOLEAN StationZero; - BOOLEAN DestZero; - EFI_IPv6_ADDRESS Source; - BOOLEAN AddrOk; - - IpSb = IpInstance->Service; - Current = &IpInstance->ConfigData; - - // - // User is changing packet filters. It must be stopped - // before the station address can be changed. - // - if (IpInstance->State == IP6_STATE_CONFIGED) { - // - // Cancel all the pending transmit/receive from upper layer - // - Status = Ip6Cancel (IpInstance, NULL); - - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA)); - return EFI_SUCCESS; - } - - // - // Set up the interface. - // - StationZero = NetIp6IsUnspecifiedAddr (&Config->StationAddress); - DestZero = NetIp6IsUnspecifiedAddr (&Config->DestinationAddress); - - if (StationZero && DestZero) { - // - // StationAddress is still zero. - // - - NET_GET_REF (IpSb->DefaultInterface); - IpInstance->Interface = IpSb->DefaultInterface; - InsertTailList (&IpSb->DefaultInterface->IpInstances, &IpInstance->AddrLink); - - CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA)); - IpInstance->State = IP6_STATE_CONFIGED; - - return EFI_SUCCESS; - } - - if (StationZero && !DestZero) { - Status = Ip6SelectSourceAddress (IpSb, &Config->DestinationAddress, &Source); - if (EFI_ERROR (Status)) { - return Status; - } - } else { - IP6_COPY_ADDRESS (&Source, &Config->StationAddress); - } - - AddrOk = Ip6IsOneOfSetAddress (IpSb, &Source, &IpIf, &AddressInfo); - if (AddrOk) { - if (AddressInfo != NULL) { - IpInstance->PrefixLength = AddressInfo->PrefixLength; - } else { - IpInstance->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH; - } - } else { - // - // The specified source address is not one of the addresses IPv6 maintains. - // - return EFI_INVALID_PARAMETER; - } - - - NET_GET_REF (IpIf); - IpInstance->Interface = IpIf; - InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink); - - CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA)); - IP6_COPY_ADDRESS (&Current->StationAddress, &Source); - IpInstance->State = IP6_STATE_CONFIGED; - - return EFI_SUCCESS; -} - -/** - Clean up the IP6 child, and release all the resources used by it. - - @param[in, out] IpInstance The IP6 child to clean up. - - @retval EFI_SUCCESS The IP6 child is cleaned up. - @retval EFI_DEVICE_ERROR Some resources failed to be released. - -**/ -EFI_STATUS -Ip6CleanProtocol ( - IN OUT IP6_PROTOCOL *IpInstance - ) -{ - if (EFI_ERROR (Ip6Cancel (IpInstance, NULL))) { - return EFI_DEVICE_ERROR; - } - - if (EFI_ERROR (Ip6Groups (IpInstance, FALSE, NULL))) { - return EFI_DEVICE_ERROR; - } - - // - // Some packets haven't been recycled. It is because either the - // user forgets to recycle the packets, or because the callback - // hasn't been called. Just leave it alone. - // - if (!IsListEmpty (&IpInstance->Delivered)) { - ; - } - - if (IpInstance->Interface != NULL) { - RemoveEntryList (&IpInstance->AddrLink); - Ip6CleanInterface (IpInstance->Interface, IpInstance); - IpInstance->Interface = NULL; - } - - if (IpInstance->GroupList != NULL) { - FreePool (IpInstance->GroupList); - IpInstance->GroupList = NULL; - IpInstance->GroupCount = 0; - } - - NetMapClean (&IpInstance->TxTokens); - - NetMapClean (&IpInstance->RxTokens); - - return EFI_SUCCESS; -} - -/** - Configure the MNP parameter used by IP. The IP driver uses one MNP - child to transmit/receive frames. By default, it configures MNP - to receive unicast/multicast/broadcast. Also, it will enable/disable - the promiscuous receive according to whether there is IP child - enable that or not. If Force is FALSE, it will iterate through - all the IP children to check whether the promiscuous receive - setting has been changed. If it hasn't been changed, it won't - reconfigure the MNP. If Force is TRUE, the MNP is configured - whether that is changed or not. - - @param[in] IpSb The IP6 service instance that is to be changed. - @param[in] Force Force the configuration or not. - - @retval EFI_SUCCESS The MNP successfully configured/reconfigured. - @retval Others Configuration failed. - -**/ -EFI_STATUS -Ip6ServiceConfigMnp ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN Force - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *ProtoEntry; - IP6_INTERFACE *IpIf; - IP6_PROTOCOL *IpInstance; - BOOLEAN Reconfig; - BOOLEAN PromiscReceive; - EFI_STATUS Status; - - Reconfig = FALSE; - PromiscReceive = FALSE; - - if (!Force) { - // - // Iterate through the IP children to check whether promiscuous - // receive setting has been changed. Update the interface's receive - // filter also. - // - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - - IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link); - IpIf->PromiscRecv = FALSE; - - NET_LIST_FOR_EACH (ProtoEntry, &IpIf->IpInstances) { - IpInstance = NET_LIST_USER_STRUCT (ProtoEntry, IP6_PROTOCOL, AddrLink); - - if (IpInstance->ConfigData.AcceptPromiscuous) { - IpIf->PromiscRecv = TRUE; - PromiscReceive = TRUE; - } - } - } - - // - // If promiscuous receive isn't changed, it isn't necessary to reconfigure. - // - if (PromiscReceive == IpSb->MnpConfigData.EnablePromiscuousReceive) { - return EFI_SUCCESS; - } - - Reconfig = TRUE; - IpSb->MnpConfigData.EnablePromiscuousReceive = PromiscReceive; - } - - Status = IpSb->Mnp->Configure (IpSb->Mnp, &IpSb->MnpConfigData); - - // - // recover the original configuration if failed to set the configure. - // - if (EFI_ERROR (Status) && Reconfig) { - IpSb->MnpConfigData.EnablePromiscuousReceive = (BOOLEAN) !PromiscReceive; - } - - return Status; -} - -/** - 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 listed 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. - If NULL, reset the configuration data. - - @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 was not opened. - @retval EFI_UNSUPPORTED Default protocol specified through - Ip6ConfigData.DefaulProtocol isn't supported. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Configure ( - IN EFI_IP6_PROTOCOL *This, - IN EFI_IP6_CONFIG_DATA *Ip6ConfigData OPTIONAL - ) -{ - IP6_PROTOCOL *IpInstance; - EFI_IP6_CONFIG_DATA *Current; - EFI_TPL OldTpl; - EFI_STATUS Status; - IP6_SERVICE *IpSb; - - // - // First, validate the parameters - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - - if (IpSb->LinkLocalDadFail && Ip6ConfigData != NULL) { - return EFI_DEVICE_ERROR; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Status = EFI_INVALID_PARAMETER; - - // - // Validate the configuration first. - // - if (Ip6ConfigData != NULL) { - // - // Check whether the station address is valid. - // - if (!Ip6IsValidAddress (IpSb, &Ip6ConfigData->StationAddress, TRUE)) { - goto Exit; - } - // - // Check whether the default protocol is valid. - // - if (Ip6IsIllegalProtocol (Ip6ConfigData->DefaultProtocol)) { - goto Exit; - } - - // - // User can only update packet filters when already configured. - // If it wants to change the station address, it must configure(NULL) - // the instance firstly. - // - if (IpInstance->State == IP6_STATE_CONFIGED) { - Current = &IpInstance->ConfigData; - - if (!EFI_IP6_EQUAL (&Current->StationAddress, &Ip6ConfigData->StationAddress)) { - Status = EFI_ALREADY_STARTED; - goto Exit; - } - - if (NetIp6IsUnspecifiedAddr (&Current->StationAddress) && IP6_NO_MAPPING (IpInstance)) { - Status = EFI_NO_MAPPING; - goto Exit; - } - } - } - - // - // Configure the instance or clean it up. - // - if (Ip6ConfigData != NULL) { - Status = Ip6ConfigProtocol (IpInstance, Ip6ConfigData); - } else { - Status = Ip6CleanProtocol (IpInstance); - - // - // Don't change the state if it is DESTROY, consider the following - // valid sequence: Mnp is unloaded-->Ip Stopped-->Udp Stopped, - // Configure (ThisIp, NULL). If the state is changed to UNCONFIGED, - // the unload fails miserably. - // - if (IpInstance->State == IP6_STATE_CONFIGED) { - IpInstance->State = IP6_STATE_UNCONFIGED; - } - } - - // - // Update the MNP's configure data. Ip6ServiceConfigMnp will check - // whether it is necessary to reconfigure the MNP. - // - Ip6ServiceConfigMnp (IpInstance->Service, FALSE); - -Exit: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - 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. - This is an optional parameter that may be NULL. - - @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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Groups ( - IN EFI_IP6_PROTOCOL *This, - IN BOOLEAN JoinFlag, - IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL - ) -{ - EFI_TPL OldTpl; - EFI_STATUS Status; - IP6_PROTOCOL *IpInstance; - IP6_SERVICE *IpSb; - - if ((This == NULL) || (JoinFlag && GroupAddress == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (GroupAddress != NULL && !IP6_IS_MULTICAST (GroupAddress)) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (IpInstance->State != IP6_STATE_CONFIGED) { - Status = EFI_NOT_STARTED; - goto ON_EXIT; - } - - Status = Ip6Groups (IpInstance, JoinFlag, GroupAddress); - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - 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. - This is an optional parameter that may be NULL. - @param[in] PrefixLength The prefix length of Destination. Ignored if Destination - is NULL. - @param[in] GatewayAddress The unicast gateway IPv6 address for this route. - This is an optional parameter that may be NULL. - - @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). - -**/ -EFI_STATUS -EFIAPI -EfiIp6Routes ( - IN EFI_IP6_PROTOCOL *This, - IN BOOLEAN DeleteRoute, - IN EFI_IPv6_ADDRESS *Destination OPTIONAL, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL - ) -{ - IP6_PROTOCOL *IpInstance; - EFI_STATUS Status; - EFI_TPL OldTpl; - IP6_SERVICE *IpSb; - - if ((This == NULL) || (PrefixLength > IP6_PREFIX_MAX)) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - if (IpInstance->State != IP6_STATE_CONFIGED) { - return EFI_NOT_STARTED; - } - - if (DeleteRoute && (Destination == NULL) && (GatewayAddress == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (!DeleteRoute && (Destination == NULL || GatewayAddress == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (GatewayAddress != NULL) { - if (!Ip6IsValidAddress (IpSb, GatewayAddress, FALSE)) { - return EFI_INVALID_PARAMETER; - } - - if (!NetIp6IsUnspecifiedAddr (GatewayAddress) && - !NetIp6IsNetEqual (GatewayAddress, &IpInstance->ConfigData.StationAddress, PrefixLength) - ) { - return EFI_INVALID_PARAMETER; - } - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - // - // Update the route table - // - if (DeleteRoute) { - Status = Ip6DelRoute (IpSb->RouteTable, Destination, PrefixLength, GatewayAddress); - } else { - Status = Ip6AddRoute (IpSb->RouteTable, Destination, PrefixLength, GatewayAddress); - } - - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - 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 timeout 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 timeout). - - 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 the Target IPv6 address. - @param[in] TargetLinkAddress Pointer to the 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 Override - is FALSE). - -**/ -EFI_STATUS -EFIAPI -EfiIp6Neighbors ( - IN EFI_IP6_PROTOCOL *This, - IN BOOLEAN DeleteFlag, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, - IN UINT32 Timeout, - IN BOOLEAN Override - ) -{ - EFI_TPL OldTpl; - EFI_STATUS Status; - IP6_PROTOCOL *IpInstance; - IP6_SERVICE *IpSb; - - if (This == NULL || TargetIp6Address == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (NetIp6IsUnspecifiedAddr (TargetIp6Address)) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - if (!Ip6IsValidAddress (IpSb, TargetIp6Address, FALSE)) { - return EFI_INVALID_PARAMETER; - } - - if (TargetLinkAddress != NULL) { - if (!Ip6IsValidLinkAddress (IpSb, TargetLinkAddress)) { - return EFI_INVALID_PARAMETER; - } - } - - if (Ip6IsOneOfSetAddress (IpSb, TargetIp6Address, NULL, NULL)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - if (IpInstance->State != IP6_STATE_CONFIGED) { - Status = EFI_NOT_STARTED; - goto Exit; - } - - if (DeleteFlag) { - Status = Ip6DelNeighbor (IpInstance->Service, TargetIp6Address, TargetLinkAddress, Timeout, Override); - } else { - Status = Ip6AddNeighbor (IpInstance->Service, TargetIp6Address, TargetLinkAddress, Timeout, Override); - } - -Exit: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Check whether the user's token or event has already - been enqueue on IP6's list. - - @param[in] Map The container of either user's transmit or receive - token. - @param[in] Item Current item to check against. - @param[in] Context The Token to check againist. - - @retval EFI_ACCESS_DENIED The token or event has already been enqueued in IP - @retval EFI_SUCCESS The current item isn't the same token/event as the - context. - -**/ -EFI_STATUS -EFIAPI -Ip6TokenExist ( - IN NET_MAP *Map, - IN NET_MAP_ITEM *Item, - IN VOID *Context - ) -{ - EFI_IP6_COMPLETION_TOKEN *Token; - EFI_IP6_COMPLETION_TOKEN *TokenInItem; - - Token = (EFI_IP6_COMPLETION_TOKEN *) Context; - TokenInItem = (EFI_IP6_COMPLETION_TOKEN *) Item->Key; - - if (Token == TokenInItem || Token->Event == TokenInItem->Event) { - return EFI_ACCESS_DENIED; - } - - return EFI_SUCCESS; -} - -/** - Validate the user's token against the current station address. - - @param[in] Token User's token to validate. - - @retval EFI_INVALID_PARAMETER Some parameters are invalid. - @retval EFI_BAD_BUFFER_SIZE The user's option/data is too long. - @retval EFI_SUCCESS The token is OK. - -**/ -EFI_STATUS -Ip6TxTokenValid ( - IN EFI_IP6_COMPLETION_TOKEN *Token - ) -{ - EFI_IP6_TRANSMIT_DATA *TxData; - UINT32 Index; - UINT32 DataLength; - - if (Token == NULL || Token->Event == NULL) { - return EFI_INVALID_PARAMETER; - } - - TxData = Token->Packet.TxData; - - if (TxData == NULL || (TxData->ExtHdrsLength != 0 && TxData->ExtHdrs == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (TxData->FragmentCount == 0 || TxData->DataLength == 0) { - return EFI_INVALID_PARAMETER; - } - - for (DataLength = 0, Index = 0; Index < TxData->FragmentCount; Index++) { - if (TxData->FragmentTable[Index].FragmentLength == 0 || TxData->FragmentTable[Index].FragmentBuffer == NULL) { - return EFI_INVALID_PARAMETER; - } - - DataLength += TxData->FragmentTable[Index].FragmentLength; - } - - if (TxData->DataLength != DataLength) { - return EFI_INVALID_PARAMETER; - } - - // - // TODO: Token.Packet.TxData.DataLength is too short to transmit. - // return EFI_BUFFER_TOO_SMALL; - // - - // - // 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. - // - if (TxData->DataLength > 64 * 1024) { - return EFI_BAD_BUFFER_SIZE; - } - - return EFI_SUCCESS; -} - -/** - The callback function for the net buffer which wraps the user's - transmit token. Although this function seems simple, there - are some subtle aspects. - When user requests the IP to transmit a packet by passing it a - token, the token is wrapped in an IP6_TXTOKEN_WRAP and the data - is wrapped in an net buffer. The net buffer's Free function is - set to Ip6FreeTxToken. The Token and token wrap are added to the - IP child's TxToken map. Then the buffer is passed to Ip6Output for - transmission. If an error happened before that, the buffer - is freed, which in turn frees the token wrap. The wrap may - have been added to the TxToken map or not, and the user's event - shouldn't be fired because we are still in the EfiIp6Transmit. If - the buffer has been sent by Ip6Output, it should be removed from - the TxToken map and user's event signaled. The token wrap and buffer - are bound together. Check the comments in Ip6Output for information - about IP fragmentation. - - @param[in] Context The token's wrap. - -**/ -VOID -EFIAPI -Ip6FreeTxToken ( - IN VOID *Context - ) -{ - IP6_TXTOKEN_WRAP *Wrap; - NET_MAP_ITEM *Item; - - Wrap = (IP6_TXTOKEN_WRAP *) Context; - - // - // Signal IpSecRecycleEvent to inform IPsec free the memory - // - if (Wrap->IpSecRecycleSignal != NULL) { - gBS->SignalEvent (Wrap->IpSecRecycleSignal); - } - - // - // Find the token in the instance's map. EfiIp6Transmit put the - // token to the map. If that failed, NetMapFindKey will return NULL. - // - Item = NetMapFindKey (&Wrap->IpInstance->TxTokens, Wrap->Token); - - if (Item != NULL) { - NetMapRemoveItem (&Wrap->IpInstance->TxTokens, Item, NULL); - } - - if (Wrap->Sent) { - gBS->SignalEvent (Wrap->Token->Event); - - // - // Dispatch the DPC queued by the NotifyFunction of Token->Event. - // - DispatchDpc (); - } - - FreePool (Wrap); -} - - -/** - The callback function to Ip6Output to update the transmit status. - - @param[in] Packet The user's transmit packet. - @param[in] IoStatus The result of the transmission. - @param[in] Flag Not used during transmission. - @param[in] Context The token's wrap. - -**/ -VOID -Ip6OnPacketSent ( - IN NET_BUF *Packet, - IN EFI_STATUS IoStatus, - IN UINT32 Flag, - IN VOID *Context - ) -{ - IP6_TXTOKEN_WRAP *Wrap; - - // - // This is the transmission request from upper layer, - // not the IP6 driver itself. - // - Wrap = (IP6_TXTOKEN_WRAP *) Context; - Wrap->Token->Status = IoStatus; - - NetbufFree (Wrap->Packet); -} - -/** - 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Transmit ( - IN EFI_IP6_PROTOCOL *This, - IN EFI_IP6_COMPLETION_TOKEN *Token - ) -{ - IP6_SERVICE *IpSb; - IP6_PROTOCOL *IpInstance; - EFI_IP6_CONFIG_DATA *Config; - EFI_STATUS Status; - EFI_TPL OldTpl; - EFI_IP6_HEADER Head; - EFI_IP6_TRANSMIT_DATA *TxData; - EFI_IP6_OVERRIDE_DATA *Override; - IP6_TXTOKEN_WRAP *Wrap; - UINT8 *ExtHdrs; - - // - // Check input parameters. - // - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - ExtHdrs = NULL; - - Status = Ip6TxTokenValid (Token); - if (EFI_ERROR (Status)) { - return Status; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (IpInstance->State != IP6_STATE_CONFIGED) { - Status = EFI_NOT_STARTED; - goto Exit; - } - - Config = &IpInstance->ConfigData; - - // - // Check whether the token or signal already existed. - // - if (EFI_ERROR (NetMapIterate (&IpInstance->TxTokens, Ip6TokenExist, Token))) { - Status = EFI_ACCESS_DENIED; - goto Exit; - } - - // - // Build the IP header, fill in the information from ConfigData or OverrideData - // - ZeroMem (&Head, sizeof(EFI_IP6_HEADER)); - TxData = Token->Packet.TxData; - IP6_COPY_ADDRESS (&Head.SourceAddress, &Config->StationAddress); - IP6_COPY_ADDRESS (&Head.DestinationAddress, &Config->DestinationAddress); - - Status = EFI_INVALID_PARAMETER; - - if (NetIp6IsUnspecifiedAddr (&TxData->DestinationAddress)) { - if (NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) { - goto Exit; - } - - ASSERT (!NetIp6IsUnspecifiedAddr (&Config->StationAddress)); - - } else { - // - // StationAddress is unspecified only when ConfigData.Dest is unspecified. - // Use TxData.Dest to override the DestinationAddress. - // - if (!NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) { - goto Exit; - } - - if (NetIp6IsUnspecifiedAddr (&Config->StationAddress)) { - Status = Ip6SelectSourceAddress ( - IpSb, - &TxData->DestinationAddress, - &Head.SourceAddress - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - } - - IP6_COPY_ADDRESS (&Head.DestinationAddress, &TxData->DestinationAddress); - } - - // - // Fill in Head infos. - // - Head.NextHeader = Config->DefaultProtocol; - if (TxData->ExtHdrsLength != 0) { - Head.NextHeader = TxData->NextHeader; - } - - if (TxData->OverrideData != NULL) { - Override = TxData->OverrideData; - Head.NextHeader = Override->Protocol; - Head.HopLimit = Override->HopLimit; - Head.FlowLabelL = HTONS ((UINT16) Override->FlowLabel); - Head.FlowLabelH = (UINT8) ((Override->FlowLabel >> 16) & 0x0F); - } else { - Head.HopLimit = Config->HopLimit; - Head.FlowLabelL = HTONS ((UINT16) Config->FlowLabel); - Head.FlowLabelH = (UINT8) ((Config->FlowLabel >> 16) & 0x0F); - } - - Head.PayloadLength = HTONS ((UINT16) (TxData->ExtHdrsLength + TxData->DataLength)); - - // - // OK, it survives all the validation check. Wrap the token in - // a IP6_TXTOKEN_WRAP and the data in a netbuf - // - Status = EFI_OUT_OF_RESOURCES; - Wrap = AllocateZeroPool (sizeof (IP6_TXTOKEN_WRAP)); - if (Wrap == NULL) { - goto Exit; - } - - Wrap->IpInstance = IpInstance; - Wrap->Token = Token; - Wrap->Sent = FALSE; - Wrap->Life = IP6_US_TO_SEC (Config->TransmitTimeout); - Wrap->Packet = NetbufFromExt ( - (NET_FRAGMENT *) TxData->FragmentTable, - TxData->FragmentCount, - IP6_MAX_HEADLEN, - 0, - Ip6FreeTxToken, - Wrap - ); - - if (Wrap->Packet == NULL) { - FreePool (Wrap); - goto Exit; - } - - Token->Status = EFI_NOT_READY; - - Status = NetMapInsertTail (&IpInstance->TxTokens, Token, Wrap); - if (EFI_ERROR (Status)) { - // - // NetbufFree will call Ip6FreeTxToken, which in turn will - // free the IP6_TXTOKEN_WRAP. Now, the token wrap hasn't been - // enqueued. - // - NetbufFree (Wrap->Packet); - goto Exit; - } - - // - // Allocate a new buffer to store IPv6 extension headers to avoid updating - // the original data in EFI_IP6_COMPLETION_TOKEN. - // - if (TxData->ExtHdrsLength != 0 && TxData->ExtHdrs != NULL) { - ExtHdrs = (UINT8 *) AllocateCopyPool (TxData->ExtHdrsLength, TxData->ExtHdrs); - if (ExtHdrs == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - } - - // - // Mark the packet sent before output it. Mark it not sent again if the - // returned status is not EFI_SUCCESS; - // - Wrap->Sent = TRUE; - - Status = Ip6Output ( - IpSb, - NULL, - IpInstance, - Wrap->Packet, - &Head, - ExtHdrs, - TxData->ExtHdrsLength, - Ip6OnPacketSent, - Wrap - ); - if (EFI_ERROR (Status)) { - Wrap->Sent = FALSE; - NetbufFree (Wrap->Packet); - } - -Exit: - gBS->RestoreTPL (OldTpl); - - if (ExtHdrs != NULL) { - FreePool (ExtHdrs); - } - - return Status; -} - -/** - 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. - - Current Udp implementation creates an IP child for each Udp child. - It initates a asynchronous receive immediately no matter whether - there is no mapping or not. Therefore, disable the returning EFI_NO_MAPPING for now. - To enable it, the following check must be performed: - - if (NetIp6IsUnspecifiedAddr (&Config->StationAddress) && IP6_NO_MAPPING (IpInstance)) { - Status = EFI_NO_MAPPING; - goto Exit; - } - - @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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Receive ( - IN EFI_IP6_PROTOCOL *This, - IN EFI_IP6_COMPLETION_TOKEN *Token - ) -{ - IP6_PROTOCOL *IpInstance; - EFI_STATUS Status; - EFI_TPL OldTpl; - IP6_SERVICE *IpSb; - - if (This == NULL || Token == NULL || Token->Event == NULL) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (IpInstance->State != IP6_STATE_CONFIGED) { - Status = EFI_NOT_STARTED; - goto Exit; - } - - // - // Check whether the toke is already on the receive queue. - // - Status = NetMapIterate (&IpInstance->RxTokens, Ip6TokenExist, Token); - - if (EFI_ERROR (Status)) { - Status = EFI_ACCESS_DENIED; - goto Exit; - } - - // - // Queue the token then check whether there is pending received packet. - // - Status = NetMapInsertTail (&IpInstance->RxTokens, Token, NULL); - - if (EFI_ERROR (Status)) { - goto Exit; - } - - Status = Ip6InstanceDeliverPacket (IpInstance); - - // - // Dispatch the DPC queued by the NotifyFunction of this instane's receive - // event. - // - DispatchDpc (); - -Exit: - gBS->RestoreTPL (OldTpl); - return Status; -} - - -/** - Cancel the transmitted but not recycled packet. If a matching - token is found, it will call Ip6CancelPacket to cancel the - packet. Ip6CancelPacket cancels all the fragments of the - packet. When all the fragments are freed, the IP6_TXTOKEN_WRAP - is deleted from the Map, and user's event is signalled. - Because Ip6CancelPacket and other functions are all called in - line, after Ip6CancelPacket returns, the Item has been freed. - - @param[in] Map The IP6 child's transmit queue. - @param[in] Item The current transmitted packet to test. - @param[in] Context The user's token to cancel. - - @retval EFI_SUCCESS Continue to check the next Item. - @retval EFI_ABORTED The user's Token (Token != NULL) is cancelled. - -**/ -EFI_STATUS -EFIAPI -Ip6CancelTxTokens ( - IN NET_MAP *Map, - IN NET_MAP_ITEM *Item, - IN VOID *Context - ) -{ - EFI_IP6_COMPLETION_TOKEN *Token; - IP6_TXTOKEN_WRAP *Wrap; - - Token = (EFI_IP6_COMPLETION_TOKEN *) Context; - - // - // Return EFI_SUCCESS to check the next item in the map if - // this one doesn't match. - // - if ((Token != NULL) && (Token != Item->Key)) { - return EFI_SUCCESS; - } - - Wrap = (IP6_TXTOKEN_WRAP *) Item->Value; - ASSERT (Wrap != NULL); - - // - // Don't access the Item, Wrap and Token's members after this point. - // Item and wrap has been freed. And we no longer own the Token. - // - Ip6CancelPacket (Wrap->IpInstance->Interface, Wrap->Packet, EFI_ABORTED); - - // - // If only one item is to be cancel, return EFI_ABORTED to stop - // iterating the map any more. - // - if (Token != NULL) { - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - - -/** - Cancel the receive request. This is simple, because - it is only enqueued in our local receive map. - - @param[in] Map The IP6 child's receive queue. - @param[in] Item Current receive request to cancel. - @param[in] Context The user's token to cancel. - - - @retval EFI_SUCCESS Continue to check the next receive request on the - queue. - @retval EFI_ABORTED The user's token (token != NULL) has been - cancelled. - -**/ -EFI_STATUS -EFIAPI -Ip6CancelRxTokens ( - IN NET_MAP *Map, - IN NET_MAP_ITEM *Item, - IN VOID *Context - ) -{ - EFI_IP6_COMPLETION_TOKEN *Token; - EFI_IP6_COMPLETION_TOKEN *This; - - Token = (EFI_IP6_COMPLETION_TOKEN *) Context; - This = Item->Key; - - if ((Token != NULL) && (Token != This)) { - return EFI_SUCCESS; - } - - NetMapRemoveItem (Map, Item, NULL); - - This->Status = EFI_ABORTED; - This->Packet.RxData = NULL; - gBS->SignalEvent (This->Event); - - if (Token != NULL) { - return EFI_ABORTED; - } - - return EFI_SUCCESS; -} - -/** - Cancel the user's receive/transmit request. It is the worker function of - EfiIp6Cancel API. - - @param[in] IpInstance The IP6 child. - @param[in] Token The token to cancel. If NULL, all token will be - cancelled. - - @retval EFI_SUCCESS The token is cancelled. - @retval EFI_NOT_FOUND The token isn't found on either the - transmit/receive queue. - @retval EFI_DEVICE_ERROR Not all tokens are cancelled when Token is NULL. - -**/ -EFI_STATUS -Ip6Cancel ( - IN IP6_PROTOCOL *IpInstance, - IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL - ) -{ - EFI_STATUS Status; - - // - // First check the transmitted packet. Ip6CancelTxTokens returns - // EFI_ABORTED to mean that the token has been cancelled when - // token != NULL. So, return EFI_SUCCESS for this condition. - // - Status = NetMapIterate (&IpInstance->TxTokens, Ip6CancelTxTokens, Token); - if (EFI_ERROR (Status)) { - if ((Token != NULL) && (Status == EFI_ABORTED)) { - return EFI_SUCCESS; - } - - return Status; - } - - // - // Check the receive queue. Ip6CancelRxTokens also returns EFI_ABORT - // for Token!=NULL and it is cancelled. - // - Status = NetMapIterate (&IpInstance->RxTokens, Ip6CancelRxTokens, Token); - // - // Dispatch the DPCs queued by the NotifyFunction of the canceled rx token's - // events. - // - DispatchDpc (); - if (EFI_ERROR (Status)) { - if ((Token != NULL) && (Status == EFI_ABORTED)) { - return EFI_SUCCESS; - } - - return Status; - } - - // - // OK, if the Token is found when Token != NULL, the NetMapIterate - // will return EFI_ABORTED, which has been interrupted as EFI_SUCCESS. - // - if (Token != NULL) { - return EFI_NOT_FOUND; - } - - // - // If Token == NULL, cancel all the tokens. return error if not - // all of them are cancelled. - // - if (!NetMapIsEmpty (&IpInstance->TxTokens) || !NetMapIsEmpty (&IpInstance->RxTokens)) { - - return EFI_DEVICE_ERROR; - } - - return EFI_SUCCESS; -} - -/** - 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Cancel ( - IN EFI_IP6_PROTOCOL *This, - IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL - ) -{ - IP6_PROTOCOL *IpInstance; - EFI_STATUS Status; - EFI_TPL OldTpl; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - if (IpInstance->State != IP6_STATE_CONFIGED) { - Status = EFI_NOT_STARTED; - goto Exit; - } - - Status = Ip6Cancel (IpInstance, Token); - -Exit: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - 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 error or network error occurred. - @retval EFI_NOT_READY No incoming or outgoing data was processed. - @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. - Consider increasing the polling rate. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Poll ( - IN EFI_IP6_PROTOCOL *This - ) -{ - IP6_PROTOCOL *IpInstance; - IP6_SERVICE *IpSb; - EFI_MANAGED_NETWORK_PROTOCOL *Mnp; - - if (This == NULL) { - return EFI_INVALID_PARAMETER; - } - - IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This); - IpSb = IpInstance->Service; - - if (IpSb->LinkLocalDadFail) { - return EFI_DEVICE_ERROR; - } - - if (IpInstance->State == IP6_STATE_UNCONFIGED) { - return EFI_NOT_STARTED; - } - - Mnp = IpInstance->Service->Mnp; - - // - // Don't lock the Poll function to enable the deliver of - // the packet polled up. - // - return Mnp->Poll (Mnp); - -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Impl.h b/Core/NetworkPkg/Ip6Dxe/Ip6Impl.h deleted file mode 100644 index 9960a9a711..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Impl.h +++ /dev/null @@ -1,754 +0,0 @@ -/** @file - Implementation of EFI_IP6_PROTOCOL protocol interfaces and type definitions. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_IMPL_H__ -#define __EFI_IP6_IMPL_H__ - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "Ip6Common.h" -#include "Ip6Driver.h" -#include "Ip6Icmp.h" -#include "Ip6If.h" -#include "Ip6Input.h" -#include "Ip6Mld.h" -#include "Ip6Nd.h" -#include "Ip6Option.h" -#include "Ip6Output.h" -#include "Ip6Route.h" -#include "Ip6ConfigNv.h" -#include "Ip6ConfigImpl.h" - -#define IP6_PROTOCOL_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'P') -#define IP6_SERVICE_SIGNATURE SIGNATURE_32 ('I', 'P', '6', 'S') - -// -// The state of IP6 protocol. It starts from UNCONFIGED. if it is -// successfully configured, it goes to CONFIGED. if configure NULL -// is called, it becomes UNCONFIGED again. If (partly) destroyed, it -// becomes DESTROY. -// -#define IP6_STATE_UNCONFIGED 0 -#define IP6_STATE_CONFIGED 1 - -// -// The state of IP6 service. It starts from UNSTARTED. It transits -// to STARTED if autoconfigure is started. If default address is -// configured, it becomes CONFIGED. and if partly destroyed, it goes -// to DESTROY. -// -#define IP6_SERVICE_UNSTARTED 0 -#define IP6_SERVICE_STARTED 1 -#define IP6_SERVICE_CONFIGED 2 -#define IP6_SERVICE_DESTROY 3 - -#define IP6_INSTANCE_FROM_PROTOCOL(Ip6) \ - CR ((Ip6), IP6_PROTOCOL, Ip6Proto, IP6_PROTOCOL_SIGNATURE) - -#define IP6_SERVICE_FROM_PROTOCOL(Sb) \ - CR ((Sb), IP6_SERVICE, ServiceBinding, IP6_SERVICE_SIGNATURE) - -#define IP6_NO_MAPPING(IpInstance) (!(IpInstance)->Interface->Configured) - -extern EFI_IPSEC2_PROTOCOL *mIpSec; -extern BOOLEAN mIpSec2Installed; - -// -// IP6_TXTOKEN_WRAP wraps the upper layer's transmit token. -// The user's data is kept in the Packet. When fragment is -// needed, each fragment of the Packet has a reference to the -// Packet, no data is actually copied. The Packet will be -// released when all the fragments of it have been recycled by -// MNP. Upon then, the IP6_TXTOKEN_WRAP will be released, and -// user's event signalled. -// -typedef struct { - IP6_PROTOCOL *IpInstance; - EFI_IP6_COMPLETION_TOKEN *Token; - EFI_EVENT IpSecRecycleSignal; - NET_BUF *Packet; - BOOLEAN Sent; - INTN Life; -} IP6_TXTOKEN_WRAP; - -typedef struct { - EFI_EVENT IpSecRecycleSignal; - NET_BUF *Packet; -} IP6_IPSEC_WRAP; - -// -// IP6_RXDATA_WRAP wraps the data IP6 child delivers to the -// upper layers. The received packet is kept in the Packet. -// The Packet itself may be constructured from some fragments. -// All the fragments of the Packet is organized by a -// IP6_ASSEMBLE_ENTRY structure. If the Packet is recycled by -// the upper layer, the assemble entry and its associated -// fragments will be freed at last. -// -typedef struct { - LIST_ENTRY Link; - IP6_PROTOCOL *IpInstance; - NET_BUF *Packet; - EFI_IP6_RECEIVE_DATA RxData; -} IP6_RXDATA_WRAP; - -struct _IP6_PROTOCOL { - UINT32 Signature; - - EFI_IP6_PROTOCOL Ip6Proto; - EFI_HANDLE Handle; - INTN State; - - IP6_SERVICE *Service; - LIST_ENTRY Link; // Link to all the IP protocol from the service - - UINT8 PrefixLength; // PrefixLength of the configured station address. - // - // User's transmit/receive tokens, and received/deliverd packets - // - NET_MAP RxTokens; - NET_MAP TxTokens; // map between (User's Token, IP6_TXTOKE_WRAP) - LIST_ENTRY Received; // Received but not delivered packet - LIST_ENTRY Delivered; // Delivered and to be recycled packets - EFI_LOCK RecycleLock; - - IP6_INTERFACE *Interface; - LIST_ENTRY AddrLink; // Ip instances with the same IP address. - - EFI_IPv6_ADDRESS *GroupList; // stored in network order. - UINT32 GroupCount; - - EFI_IP6_CONFIG_DATA ConfigData; - BOOLEAN InDestroy; -}; - -struct _IP6_SERVICE { - UINT32 Signature; - EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; - INTN State; - - // - // List of all the IP instances and interfaces, and default - // interface and route table and caches. - // - UINTN NumChildren; - LIST_ENTRY Children; - - LIST_ENTRY Interfaces; - - IP6_INTERFACE *DefaultInterface; - IP6_ROUTE_TABLE *RouteTable; - - IP6_LINK_RX_TOKEN RecvRequest; - - // - // Ip reassemble utilities and MLD data - // - IP6_ASSEMBLE_TABLE Assemble; - IP6_MLD_SERVICE_DATA MldCtrl; - - EFI_IPv6_ADDRESS LinkLocalAddr; - BOOLEAN LinkLocalOk; - BOOLEAN LinkLocalDadFail; - BOOLEAN Dhcp6NeedStart; - BOOLEAN Dhcp6NeedInfoRequest; - - // - // ND data - // - UINT8 CurHopLimit; - UINT32 LinkMTU; - UINT32 BaseReachableTime; - UINT32 ReachableTime; - UINT32 RetransTimer; - LIST_ENTRY NeighborTable; - - LIST_ENTRY OnlinkPrefix; - LIST_ENTRY AutonomousPrefix; - - LIST_ENTRY DefaultRouterList; - UINT32 RoundRobin; - - UINT8 InterfaceIdLen; - UINT8 *InterfaceId; - - BOOLEAN RouterAdvertiseReceived; - UINT8 SolicitTimer; - UINT32 Ticks; - - // - // Low level protocol used by this service instance - // - EFI_HANDLE Image; - EFI_HANDLE Controller; - - EFI_HANDLE MnpChildHandle; - EFI_MANAGED_NETWORK_PROTOCOL *Mnp; - - EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData; - EFI_SIMPLE_NETWORK_MODE SnpMode; - - EFI_EVENT Timer; - EFI_EVENT FasterTimer; - - // - // IPv6 Configuration Protocol instance - // - IP6_CONFIG_INSTANCE Ip6ConfigInstance; - - // - // The string representation of the current mac address of the - // NIC this IP6_SERVICE works on. - // - CHAR16 *MacString; - UINT32 MaxPacketSize; - UINT32 OldMaxPacketSize; -}; - -/** - The callback function for the net buffer which wraps the user's - transmit token. Although this function seems simple, - there are some subtle aspects. - When a user requests the IP to transmit a packet by passing it a - token, the token is wrapped in an IP6_TXTOKEN_WRAP and the data - is wrapped in a net buffer. The net buffer's Free function is - set to Ip6FreeTxToken. The Token and token wrap are added to the - IP child's TxToken map. Then the buffer is passed to Ip6Output for - transmission. If an error occurs before that, the buffer - is freed, which in turn frees the token wrap. The wrap may - have been added to the TxToken map or not, and the user's event - shouldn't be signaled because we are still in the EfiIp6Transmit. If - the buffer has been sent by Ip6Output, it should be removed from - the TxToken map and the user's event signaled. The token wrap and buffer - are bound together. Refer to the comments in Ip6Output for information - about IP fragmentation. - - @param[in] Context The token's wrap. - -**/ -VOID -EFIAPI -Ip6FreeTxToken ( - IN VOID *Context - ); - -/** - Config the MNP parameter used by IP. The IP driver use one MNP - child to transmit/receive frames. By default, it configures MNP - to receive unicast/multicast/broadcast. And it will enable/disable - the promiscuous receive according to whether there is IP child - enable that or not. If Force is FALSE, it will iterate through - all the IP children to check whether the promiscuous receive - setting has been changed. If it hasn't been changed, it won't - reconfigure the MNP. If Force is TRUE, the MNP is configured - whether that is changed or not. - - @param[in] IpSb The IP6 service instance that is to be changed. - @param[in] Force Force the configuration or not. - - @retval EFI_SUCCESS The MNP successfully configured/reconfigured. - @retval Others The configuration failed. - -**/ -EFI_STATUS -Ip6ServiceConfigMnp ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN Force - ); - -/** - Cancel the user's receive/transmit request. It is the worker function of - EfiIp6Cancel API. - - @param[in] IpInstance The IP6 child. - @param[in] Token The token to cancel. If NULL, all tokens will be - cancelled. - - @retval EFI_SUCCESS The token was cancelled. - @retval EFI_NOT_FOUND The token isn't found on either the - transmit or receive queue. - @retval EFI_DEVICE_ERROR Not all tokens are cancelled when Token is NULL. - -**/ -EFI_STATUS -Ip6Cancel ( - IN IP6_PROTOCOL *IpInstance, - IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL - ); - -/** - Initialize the IP6_PROTOCOL structure to the unconfigured states. - - @param[in] IpSb The IP6 service instance. - @param[in, out] IpInstance The IP6 child instance. - -**/ -VOID -Ip6InitProtocol ( - IN IP6_SERVICE *IpSb, - IN OUT IP6_PROTOCOL *IpInstance - ); - -/** - Clean up the IP6 child, release all the resources used by it. - - @param[in, out] IpInstance The IP6 child to clean up. - - @retval EFI_SUCCESS The IP6 child was cleaned up - @retval EFI_DEVICE_ERROR Some resources failed to be released. - -**/ -EFI_STATUS -Ip6CleanProtocol ( - IN OUT IP6_PROTOCOL *IpInstance - ); - -// -// EFI_IP6_PROTOCOL interface prototypes -// - -/** - 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 The pointer to the EFI_IP6_PROTOCOL instance. - @param[out] Ip6ModeData The pointer to the EFI IPv6 Protocol mode data structure. - @param[out] MnpConfigData The pointer to the managed network configuration data structure. - @param[out] SnpModeData The 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6GetModeData ( - 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 a currently configured IPv6. - 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 The pointer to the EFI_IP6_PROTOCOL instance. - @param[in] Ip6ConfigData The pointer to the EFI IPv6 Protocol configuration data structure. - If NULL, reset the configuration data. - - @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 was not opened. - @retval EFI_UNSUPPORTED Default protocol specified through - Ip6ConfigData.DefaulProtocol isn't supported. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Configure ( - 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 The 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 The pointer to the IPv6 multicast address. - This is an optional parameter that may be NULL. - - @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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Groups ( - 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 The 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. - This is an optional parameter that may be NULL. - @param[in] PrefixLength The prefix length of Destination. Ignored if Destination - is NULL. - @param[in] GatewayAddress The unicast gateway IPv6 address for this route. - This is an optional parameter that may be NULL. - - @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). - -**/ -EFI_STATUS -EFIAPI -EfiIp6Routes ( - 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 a 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 timeout 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 timeout). - - The implementation should follow the neighbor cache timeout mechanism defined in - RFC4861. The default neighbor cache timeout value should be tuned for the expected network - environment. - - @param[in] This The 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 The pointer to the Target IPv6 address. - @param[in] TargetLinkAddress The 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 exists. - - @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 Override - is FALSE). - -**/ -EFI_STATUS -EFIAPI -EfiIp6Neighbors ( - IN EFI_IP6_PROTOCOL *This, - IN BOOLEAN DeleteFlag, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, - 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 The pointer to the EFI_IP6_PROTOCOL instance. - @param[in] Token The 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. - The 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 the 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Transmit ( - 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. - - Current Udp implementation creates an IP child for each Udp child. - It initates a asynchronous receive immediately whether or not - there is no mapping. Therefore, disable the returning EFI_NO_MAPPING for now. - To enable it, the following check must be performed: - - if (NetIp6IsUnspecifiedAddr (&Config->StationAddress) && IP6_NO_MAPPING (IpInstance)) { - Status = EFI_NO_MAPPING; - goto Exit; - } - - @param[in] This The pointer to the EFI_IP6_PROTOCOL instance. - @param[in] Token The 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Receive ( - 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 The pointer to the EFI_IP6_PROTOCOL instance. - @param[in] Token The 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. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Cancel ( - 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 The 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 was processed. - @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue. - Consider increasing the polling rate. - -**/ -EFI_STATUS -EFIAPI -EfiIp6Poll ( - IN EFI_IP6_PROTOCOL *This - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Input.c b/Core/NetworkPkg/Ip6Dxe/Ip6Input.c deleted file mode 100644 index e53e0874b9..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Input.c +++ /dev/null @@ -1,1831 +0,0 @@ -/** @file - IP6 internal functions to process the incoming packets. - - Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
- (C) Copyright 2015 Hewlett-Packard Development Company, L.P.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -/** - Create an empty assemble entry for the packet identified by - (Dst, Src, Id). The default life for the packet is 60 seconds. - - @param[in] Dst The destination address. - @param[in] Src The source address. - @param[in] Id The ID field in the IP header. - - @return NULL if failed to allocate memory for the entry. Otherwise, - the pointer to the just created reassemble entry. - -**/ -IP6_ASSEMBLE_ENTRY * -Ip6CreateAssembleEntry ( - IN EFI_IPv6_ADDRESS *Dst, - IN EFI_IPv6_ADDRESS *Src, - IN UINT32 Id - ) -{ - IP6_ASSEMBLE_ENTRY *Assemble; - - Assemble = AllocatePool (sizeof (IP6_ASSEMBLE_ENTRY)); - if (Assemble == NULL) { - return NULL; - } - - IP6_COPY_ADDRESS (&Assemble->Dst, Dst); - IP6_COPY_ADDRESS (&Assemble->Src, Src); - InitializeListHead (&Assemble->Fragments); - - Assemble->Id = Id; - Assemble->Life = IP6_FRAGMENT_LIFE + 1; - - Assemble->TotalLen = 0; - Assemble->CurLen = 0; - Assemble->Head = NULL; - Assemble->Info = NULL; - Assemble->Packet = NULL; - - return Assemble; -} - -/** - Release all the fragments of a packet, then free the assemble entry. - - @param[in] Assemble The assemble entry to free. - -**/ -VOID -Ip6FreeAssembleEntry ( - IN IP6_ASSEMBLE_ENTRY *Assemble - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - NET_BUF *Fragment; - - NET_LIST_FOR_EACH_SAFE (Entry, Next, &Assemble->Fragments) { - Fragment = NET_LIST_USER_STRUCT (Entry, NET_BUF, List); - - RemoveEntryList (Entry); - NetbufFree (Fragment); - } - - if (Assemble->Packet != NULL) { - NetbufFree (Assemble->Packet); - } - - FreePool (Assemble); -} - -/** - Release all the fragments of the packet. This is the callback for - the assembled packet's OnFree. It will free the assemble entry, - which in turn frees all the fragments of the packet. - - @param[in] Arg The assemble entry to free. - -**/ -VOID -EFIAPI -Ip6OnFreeFragments ( - IN VOID *Arg - ) -{ - Ip6FreeAssembleEntry ((IP6_ASSEMBLE_ENTRY *) Arg); -} - -/** - Trim the packet to fit in [Start, End), and update per the - packet information. - - @param[in, out] Packet Packet to trim. - @param[in] Start The sequence of the first byte to fit in. - @param[in] End One beyond the sequence of last byte to fit in. - -**/ -VOID -Ip6TrimPacket ( - IN OUT NET_BUF *Packet, - IN INTN Start, - IN INTN End - ) -{ - IP6_CLIP_INFO *Info; - INTN Len; - - Info = IP6_GET_CLIP_INFO (Packet); - - ASSERT (Info->Start + Info->Length == Info->End); - ASSERT ((Info->Start < End) && (Start < Info->End)); - - if (Info->Start < Start) { - Len = Start - Info->Start; - - NetbufTrim (Packet, (UINT32) Len, NET_BUF_HEAD); - Info->Start = (UINT32) Start; - Info->Length -= (UINT32) Len; - } - - if (End < Info->End) { - Len = End - Info->End; - - NetbufTrim (Packet, (UINT32) Len, NET_BUF_TAIL); - Info->End = (UINT32) End; - Info->Length -= (UINT32) Len; - } -} - -/** - Reassemble the IP fragments. If all the fragments of the packet - have been received, it will wrap the packet in a net buffer then - return it to caller. If the packet can't be assembled, NULL is - returned. - - @param[in, out] Table The assemble table used. A new assemble entry will be created - if the Packet is from a new chain of fragments. - @param[in] Packet The fragment to assemble. It might be freed if the fragment - can't be re-assembled. - - @return NULL if the packet can't be reassembled. The pointer to the just assembled - packet if all the fragments of the packet have arrived. - -**/ -NET_BUF * -Ip6Reassemble ( - IN OUT IP6_ASSEMBLE_TABLE *Table, - IN NET_BUF *Packet - ) -{ - EFI_IP6_HEADER *Head; - IP6_CLIP_INFO *This; - IP6_CLIP_INFO *Node; - IP6_ASSEMBLE_ENTRY *Assemble; - IP6_ASSEMBLE_ENTRY *Entry; - LIST_ENTRY *ListHead; - LIST_ENTRY *Prev; - LIST_ENTRY *Cur; - NET_BUF *Fragment; - NET_BUF *TmpPacket; - NET_BUF *NewPacket; - NET_BUF *Duplicate; - UINT8 *DupHead; - INTN Index; - UINT16 UnFragmentLen; - UINT8 *NextHeader; - - Head = Packet->Ip.Ip6; - This = IP6_GET_CLIP_INFO (Packet); - - ASSERT (Head != NULL); - - // - // Find the corresponding assemble entry by (Dst, Src, Id) - // - Assemble = NULL; - Index = IP6_ASSEMBLE_HASH (&Head->DestinationAddress, &Head->SourceAddress, This->Id); - - NET_LIST_FOR_EACH (Cur, &Table->Bucket[Index]) { - Entry = NET_LIST_USER_STRUCT (Cur, IP6_ASSEMBLE_ENTRY, Link); - - if (Entry->Id == This->Id && - EFI_IP6_EQUAL (&Entry->Src, &Head->SourceAddress) && - EFI_IP6_EQUAL (&Entry->Dst, &Head->DestinationAddress) - ) { - Assemble = Entry; - break; - } - } - - // - // Create a new entry if can not find an existing one, insert it to assemble table - // - if (Assemble == NULL) { - Assemble = Ip6CreateAssembleEntry ( - &Head->DestinationAddress, - &Head->SourceAddress, - This->Id - ); - - if (Assemble == NULL) { - goto Error; - } - - InsertHeadList (&Table->Bucket[Index], &Assemble->Link); - } - - // - // Find the point to insert the packet: before the first - // fragment with THIS.Start < CUR.Start. the previous one - // has PREV.Start <= THIS.Start < CUR.Start. - // - ListHead = &Assemble->Fragments; - - NET_LIST_FOR_EACH (Cur, ListHead) { - Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List); - - if (This->Start < IP6_GET_CLIP_INFO (Fragment)->Start) { - break; - } - } - - // - // Check whether the current fragment overlaps with the previous one. - // It holds that: PREV.Start <= THIS.Start < THIS.End. Only need to - // check whether THIS.Start < PREV.End for overlap. If two fragments - // overlaps, trim the overlapped part off THIS fragment. - // - if ((Prev = Cur->BackLink) != ListHead) { - Fragment = NET_LIST_USER_STRUCT (Prev, NET_BUF, List); - Node = IP6_GET_CLIP_INFO (Fragment); - - if (This->Start < Node->End) { - if (This->End <= Node->End) { - goto Error; - } - - // - // Trim the previous fragment from tail. - // - Ip6TrimPacket (Fragment, Node->Start, This->Start); - } - } - - // - // Insert the fragment into the packet. The fragment may be removed - // from the list by the following checks. - // - NetListInsertBefore (Cur, &Packet->List); - - // - // Check the packets after the insert point. It holds that: - // THIS.Start <= NODE.Start < NODE.End. The equality holds - // if PREV and NEXT are continuous. THIS fragment may fill - // several holes. Remove the completely overlapped fragments - // - while (Cur != ListHead) { - Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List); - Node = IP6_GET_CLIP_INFO (Fragment); - - // - // Remove fragments completely overlapped by this fragment - // - if (Node->End <= This->End) { - Cur = Cur->ForwardLink; - - RemoveEntryList (&Fragment->List); - Assemble->CurLen -= Node->Length; - - NetbufFree (Fragment); - continue; - } - - // - // The conditions are: THIS.Start <= NODE.Start, and THIS.End < - // NODE.End. Two fragments overlaps if NODE.Start < THIS.End. - // If two fragments start at the same offset, remove THIS fragment - // because ((THIS.Start == NODE.Start) && (THIS.End < NODE.End)). - // - if (Node->Start < This->End) { - if (This->Start == Node->Start) { - RemoveEntryList (&Packet->List); - goto Error; - } - - Ip6TrimPacket (Packet, This->Start, Node->Start); - } - - break; - } - - // - // Update the assemble info: increase the current length. If it is - // the frist fragment, update the packet's IP head and per packet - // info. If it is the last fragment, update the total length. - // - Assemble->CurLen += This->Length; - - if (This->Start == 0) { - // - // Once the first fragment is enqueued, it can't be removed - // from the fragment list. So, Assemble->Head always point - // to valid memory area. - // - if ((Assemble->Head != NULL) || (Assemble->Packet != NULL)) { - goto Error; - } - - // - // Backup the first fragment in case the reasembly of that packet fail. - // - Duplicate = NetbufDuplicate (Packet, NULL, sizeof (EFI_IP6_HEADER)); - if (Duplicate == NULL) { - goto Error; - } - - // - // Revert IP head to network order. - // - DupHead = NetbufGetByte (Duplicate, 0, NULL); - ASSERT (DupHead != NULL); - Duplicate->Ip.Ip6 = Ip6NtohHead ((EFI_IP6_HEADER *) DupHead); - Assemble->Packet = Duplicate; - - // - // Adjust the unfragmentable part in first fragment - // - UnFragmentLen = (UINT16) (This->HeadLen - sizeof (EFI_IP6_HEADER)); - if (UnFragmentLen == 0) { - // - // There is not any unfragmentable extension header. - // - ASSERT (Head->NextHeader == IP6_FRAGMENT); - Head->NextHeader = This->NextHeader; - } else { - NextHeader = NetbufGetByte ( - Packet, - This->FormerNextHeader + sizeof (EFI_IP6_HEADER), - 0 - ); - if (NextHeader == NULL) { - goto Error; - } - - *NextHeader = This->NextHeader; - } - - Assemble->Head = Head; - Assemble->Info = IP6_GET_CLIP_INFO (Packet); - } - - // - // Don't update the length more than once. - // - if ((This->LastFrag != 0) && (Assemble->TotalLen == 0)) { - Assemble->TotalLen = This->End; - } - - // - // Deliver the whole packet if all the fragments received. - // All fragments received if: - // 1. received the last one, so, the totoal length is know - // 2. received all the data. If the last fragment on the - // queue ends at the total length, all data is received. - // - if ((Assemble->TotalLen != 0) && (Assemble->CurLen >= Assemble->TotalLen)) { - - RemoveEntryList (&Assemble->Link); - - // - // If the packet is properly formated, the last fragment's End - // equals to the packet's total length. Otherwise, the packet - // is a fake, drop it now. - // - Fragment = NET_LIST_USER_STRUCT (ListHead->BackLink, NET_BUF, List); - if (IP6_GET_CLIP_INFO (Fragment)->End != (INTN) Assemble->TotalLen) { - Ip6FreeAssembleEntry (Assemble); - goto Error; - } - - Fragment = NET_LIST_HEAD (ListHead, NET_BUF, List); - This = Assemble->Info; - - // - // This TmpPacket is used to hold the unfragmentable part, i.e., - // the IPv6 header and the unfragmentable extension headers. Be noted that - // the Fragment Header is exluded. - // - TmpPacket = NetbufGetFragment (Fragment, 0, This->HeadLen, 0); - ASSERT (TmpPacket != NULL); - - NET_LIST_FOR_EACH (Cur, ListHead) { - // - // Trim off the unfragment part plus the fragment header from all fragments. - // - Fragment = NET_LIST_USER_STRUCT (Cur, NET_BUF, List); - NetbufTrim (Fragment, This->HeadLen + sizeof (IP6_FRAGMENT_HEADER), TRUE); - } - - InsertHeadList (ListHead, &TmpPacket->List); - - // - // Wrap the packet in a net buffer then deliver it up - // - NewPacket = NetbufFromBufList ( - &Assemble->Fragments, - 0, - 0, - Ip6OnFreeFragments, - Assemble - ); - - if (NewPacket == NULL) { - Ip6FreeAssembleEntry (Assemble); - goto Error; - } - - NewPacket->Ip.Ip6 = Assemble->Head; - - CopyMem (IP6_GET_CLIP_INFO (NewPacket), Assemble->Info, sizeof (IP6_CLIP_INFO)); - - return NewPacket; - } - - return NULL; - -Error: - NetbufFree (Packet); - return NULL; -} - - -/** - The callback function for the net buffer that wraps the packet processed by - IPsec. It releases the wrap packet and also signals IPsec to free the resources. - - @param[in] Arg The wrap context. - -**/ -VOID -EFIAPI -Ip6IpSecFree ( - IN VOID *Arg - ) -{ - IP6_IPSEC_WRAP *Wrap; - - Wrap = (IP6_IPSEC_WRAP *) Arg; - - if (Wrap->IpSecRecycleSignal != NULL) { - gBS->SignalEvent (Wrap->IpSecRecycleSignal); - } - - NetbufFree (Wrap->Packet); - - FreePool (Wrap); - - return; -} - -/** - The work function to locate the IPsec protocol to process the inbound or - outbound IP packets. The process routine handles the packet with the following - actions: bypass the packet, discard the packet, or protect the packet. - - @param[in] IpSb The IP6 service instance. - @param[in, out] Head The caller-supplied IP6 header. - @param[in, out] LastHead The next header field of last IP header. - @param[in, out] Netbuf The IP6 packet to be processed by IPsec. - @param[in, out] ExtHdrs The caller-supplied options. - @param[in, out] ExtHdrsLen The length of the option. - @param[in] Direction The directionality in an SPD entry, - EfiIPsecInBound, or EfiIPsecOutBound. - @param[in] Context The token's wrap. - - @retval EFI_SUCCESS The IPsec protocol is not available or disabled. - @retval EFI_SUCCESS The packet was bypassed, and all buffers remain the same. - @retval EFI_SUCCESS The packet was protected. - @retval EFI_ACCESS_DENIED The packet was discarded. - @retval EFI_OUT_OF_RESOURCES There are not suffcient resources to complete the operation. - @retval EFI_BUFFER_TOO_SMALL The number of non-empty blocks is bigger than the - number of input data blocks when building a fragment table. - -**/ -EFI_STATUS -Ip6IpSecProcessPacket ( - IN IP6_SERVICE *IpSb, - IN OUT EFI_IP6_HEADER **Head, - IN OUT UINT8 *LastHead, - IN OUT NET_BUF **Netbuf, - IN OUT UINT8 **ExtHdrs, - IN OUT UINT32 *ExtHdrsLen, - IN EFI_IPSEC_TRAFFIC_DIR Direction, - IN VOID *Context - ) -{ - NET_FRAGMENT *FragmentTable; - NET_FRAGMENT *OriginalFragmentTable; - UINT32 FragmentCount; - UINT32 OriginalFragmentCount; - EFI_EVENT RecycleEvent; - NET_BUF *Packet; - IP6_TXTOKEN_WRAP *TxWrap; - IP6_IPSEC_WRAP *IpSecWrap; - EFI_STATUS Status; - EFI_IP6_HEADER *PacketHead; - UINT8 *Buf; - EFI_IP6_HEADER ZeroHead; - - Status = EFI_SUCCESS; - - if (!mIpSec2Installed) { - goto ON_EXIT; - } - - Packet = *Netbuf; - RecycleEvent = NULL; - IpSecWrap = NULL; - FragmentTable = NULL; - PacketHead = NULL; - Buf = NULL; - TxWrap = (IP6_TXTOKEN_WRAP *) Context; - FragmentCount = Packet->BlockOpNum; - ZeroMem (&ZeroHead, sizeof (EFI_IP6_HEADER)); - - if (mIpSec == NULL) { - gBS->LocateProtocol (&gEfiIpSec2ProtocolGuid, NULL, (VOID **) &mIpSec); - - // - // Check whether the ipsec protocol is available. - // - if (mIpSec == NULL) { - goto ON_EXIT; - } - } - - // - // Check whether the ipsec enable variable is set. - // - if (mIpSec->DisabledFlag) { - // - // If IPsec is disabled, restore the original MTU - // - IpSb->MaxPacketSize = IpSb->OldMaxPacketSize; - goto ON_EXIT; - } else { - // - // If IPsec is enabled, use the MTU which reduce the IPsec header length. - // - IpSb->MaxPacketSize = IpSb->OldMaxPacketSize - IP6_MAX_IPSEC_HEADLEN; - } - - - // - // Bypass all multicast inbound or outbound traffic. - // - if (IP6_IS_MULTICAST (&(*Head)->DestinationAddress) || IP6_IS_MULTICAST (&(*Head)->SourceAddress)) { - goto ON_EXIT; - } - - // - // Rebuild fragment table from netbuf to ease ipsec process. - // - FragmentTable = AllocateZeroPool (FragmentCount * sizeof (NET_FRAGMENT)); - - if (FragmentTable == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = NetbufBuildExt (Packet, FragmentTable, &FragmentCount); - OriginalFragmentTable = FragmentTable; - OriginalFragmentCount = FragmentCount; - - if (EFI_ERROR(Status)) { - FreePool (FragmentTable); - goto ON_EXIT; - } - - // - // Convert host byte order to network byte order - // - Ip6NtohHead (*Head); - - Status = mIpSec->ProcessExt ( - mIpSec, - IpSb->Controller, - IP_VERSION_6, - (VOID *) (*Head), - LastHead, - (VOID **) ExtHdrs, - ExtHdrsLen, - (EFI_IPSEC_FRAGMENT_DATA **) (&FragmentTable), - &FragmentCount, - Direction, - &RecycleEvent - ); - // - // Convert back to host byte order - // - Ip6NtohHead (*Head); - - if (EFI_ERROR (Status)) { - FreePool (OriginalFragmentTable); - goto ON_EXIT; - } - - if (OriginalFragmentCount == FragmentCount && OriginalFragmentTable == FragmentTable) { - // - // For ByPass Packet - // - FreePool (FragmentTable); - goto ON_EXIT; - } else { - // - // Free the FragmentTable which allocated before calling the IPsec. - // - FreePool (OriginalFragmentTable); - } - - if (Direction == EfiIPsecOutBound && TxWrap != NULL) { - TxWrap->IpSecRecycleSignal = RecycleEvent; - TxWrap->Packet = NetbufFromExt ( - FragmentTable, - FragmentCount, - IP6_MAX_HEADLEN, - 0, - Ip6FreeTxToken, - TxWrap - ); - if (TxWrap->Packet == NULL) { - TxWrap->Packet = *Netbuf; - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - CopyMem ( - IP6_GET_CLIP_INFO (TxWrap->Packet), - IP6_GET_CLIP_INFO (Packet), - sizeof (IP6_CLIP_INFO) - ); - - NetIpSecNetbufFree(Packet); - *Netbuf = TxWrap->Packet; - - } else { - - IpSecWrap = AllocateZeroPool (sizeof (IP6_IPSEC_WRAP)); - - if (IpSecWrap == NULL) { - Status = EFI_OUT_OF_RESOURCES; - gBS->SignalEvent (RecycleEvent); - goto ON_EXIT; - } - - IpSecWrap->IpSecRecycleSignal = RecycleEvent; - IpSecWrap->Packet = Packet; - Packet = NetbufFromExt ( - FragmentTable, - FragmentCount, - IP6_MAX_HEADLEN, - 0, - Ip6IpSecFree, - IpSecWrap - ); - - if (Packet == NULL) { - Packet = IpSecWrap->Packet; - gBS->SignalEvent (RecycleEvent); - FreePool (IpSecWrap); - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - if (Direction == EfiIPsecInBound && 0 != CompareMem (&ZeroHead, *Head, sizeof (EFI_IP6_HEADER))) { - - PacketHead = (EFI_IP6_HEADER *) NetbufAllocSpace ( - Packet, - sizeof (EFI_IP6_HEADER) + *ExtHdrsLen, - NET_BUF_HEAD - ); - if (PacketHead == NULL) { - *Netbuf = Packet; - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - CopyMem (PacketHead, *Head, sizeof (EFI_IP6_HEADER)); - *Head = PacketHead; - Packet->Ip.Ip6 = PacketHead; - - if (*ExtHdrs != NULL) { - Buf = (UINT8 *) (PacketHead + 1); - CopyMem (Buf, *ExtHdrs, *ExtHdrsLen); - } - - NetbufTrim (Packet, sizeof (EFI_IP6_HEADER) + *ExtHdrsLen, TRUE); - CopyMem ( - IP6_GET_CLIP_INFO (Packet), - IP6_GET_CLIP_INFO (IpSecWrap->Packet), - sizeof (IP6_CLIP_INFO) - ); - } - *Netbuf = Packet; - } - -ON_EXIT: - return Status; -} - -/** - Pre-process the IPv6 packet. First validates the IPv6 packet, and - then reassembles packet if it is necessary. - - @param[in] IpSb The IP6 service instance. - @param[in, out] Packet The received IP6 packet to be processed. - @param[in] Flag The link layer flag for the packet received, such - as multicast. - @param[out] Payload The pointer to the payload of the recieved packet. - it starts from the first byte of the extension header. - @param[out] LastHead The pointer of NextHeader of the last extension - header processed by IP6. - @param[out] ExtHdrsLen The length of the whole option. - @param[out] UnFragmentLen The length of unfragmented length of extension headers. - @param[out] Fragmented Indicate whether the packet is fragmented. - @param[out] Head The pointer to the EFI_IP6_Header. - - @retval EFI_SUCCESS The received packet is well format. - @retval EFI_INVALID_PARAMETER The received packet is malformed. - -**/ -EFI_STATUS -Ip6PreProcessPacket ( - IN IP6_SERVICE *IpSb, - IN OUT NET_BUF **Packet, - IN UINT32 Flag, - OUT UINT8 **Payload, - OUT UINT8 **LastHead, - OUT UINT32 *ExtHdrsLen, - OUT UINT32 *UnFragmentLen, - OUT BOOLEAN *Fragmented, - OUT EFI_IP6_HEADER **Head - ) -{ - UINT16 PayloadLen; - UINT16 TotalLen; - UINT32 FormerHeadOffset; - UINT32 HeadLen; - IP6_FRAGMENT_HEADER *FragmentHead; - UINT16 FragmentOffset; - IP6_CLIP_INFO *Info; - EFI_IPv6_ADDRESS Loopback; - - HeadLen = 0; - PayloadLen = 0; - // - // Check whether the input packet is a valid packet - // - if ((*Packet)->TotalSize < IP6_MIN_HEADLEN) { - return EFI_INVALID_PARAMETER; - } - - // - // Get header information of the packet. - // - *Head = (EFI_IP6_HEADER *) NetbufGetByte (*Packet, 0, NULL); - if (*Head == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Multicast addresses must not be used as source addresses in IPv6 packets. - // - if (((*Head)->Version != 6) || (IP6_IS_MULTICAST (&(*Head)->SourceAddress))) { - return EFI_INVALID_PARAMETER; - } - - // - // A packet with a destination address of loopback ::1/128 or unspecified must be dropped. - // - ZeroMem (&Loopback, sizeof (EFI_IPv6_ADDRESS)); - Loopback.Addr[15] = 0x1; - if ((CompareMem (&Loopback, &(*Head)->DestinationAddress, sizeof (EFI_IPv6_ADDRESS)) == 0) || - (NetIp6IsUnspecifiedAddr (&(*Head)->DestinationAddress))) { - return EFI_INVALID_PARAMETER; - } - - // - // Convert the IP header to host byte order. - // - (*Packet)->Ip.Ip6 = Ip6NtohHead (*Head); - - // - // Get the per packet info. - // - Info = IP6_GET_CLIP_INFO (*Packet); - Info->LinkFlag = Flag; - Info->CastType = 0; - - if (IpSb->MnpConfigData.EnablePromiscuousReceive) { - Info->CastType = Ip6Promiscuous; - } - - if (Ip6IsOneOfSetAddress (IpSb, &(*Head)->DestinationAddress, NULL, NULL)) { - Info->CastType = Ip6Unicast; - } else if (IP6_IS_MULTICAST (&(*Head)->DestinationAddress)) { - if (Ip6FindMldEntry (IpSb, &(*Head)->DestinationAddress) != NULL) { - Info->CastType = Ip6Multicast; - } - } - - // - // Drop the packet that is not delivered to us. - // - if (Info->CastType == 0) { - return EFI_INVALID_PARAMETER; - } - - - PayloadLen = (*Head)->PayloadLength; - - Info->Start = 0; - Info->Length = PayloadLen; - Info->End = Info->Start + Info->Length; - Info->HeadLen = (UINT16) sizeof (EFI_IP6_HEADER); - Info->Status = EFI_SUCCESS; - Info->LastFrag = FALSE; - - TotalLen = (UINT16) (PayloadLen + sizeof (EFI_IP6_HEADER)); - - // - // Mnp may deliver frame trailer sequence up, trim it off. - // - if (TotalLen < (*Packet)->TotalSize) { - NetbufTrim (*Packet, (*Packet)->TotalSize - TotalLen, FALSE); - } - - if (TotalLen != (*Packet)->TotalSize) { - return EFI_INVALID_PARAMETER; - } - - // - // Check the extension headers, if exist validate them - // - if (PayloadLen != 0) { - *Payload = AllocatePool ((UINTN) PayloadLen); - if (*Payload == NULL) { - return EFI_INVALID_PARAMETER; - } - - NetbufCopy (*Packet, sizeof (EFI_IP6_HEADER), PayloadLen, *Payload); - } - - if (!Ip6IsExtsValid ( - IpSb, - *Packet, - &(*Head)->NextHeader, - *Payload, - (UINT32) PayloadLen, - TRUE, - &FormerHeadOffset, - LastHead, - ExtHdrsLen, - UnFragmentLen, - Fragmented - )) { - return EFI_INVALID_PARAMETER; - } - - HeadLen = sizeof (EFI_IP6_HEADER) + *UnFragmentLen; - - if (*Fragmented) { - // - // Get the fragment offset from the Fragment header - // - FragmentHead = (IP6_FRAGMENT_HEADER *) NetbufGetByte (*Packet, HeadLen, NULL); - if (FragmentHead == NULL) { - return EFI_INVALID_PARAMETER; - } - - FragmentOffset = NTOHS (FragmentHead->FragmentOffset); - - if ((FragmentOffset & 0x1) == 0) { - Info->LastFrag = TRUE; - } - - FragmentOffset &= (~0x1); - - // - // This is the first fragment of the packet - // - if (FragmentOffset == 0) { - Info->NextHeader = FragmentHead->NextHeader; - } - - Info->HeadLen = (UINT16) HeadLen; - HeadLen += sizeof (IP6_FRAGMENT_HEADER); - Info->Start = FragmentOffset; - Info->Length = TotalLen - (UINT16) HeadLen; - Info->End = Info->Start + Info->Length; - Info->Id = FragmentHead->Identification; - Info->FormerNextHeader = FormerHeadOffset; - - // - // Fragments should in the unit of 8 octets long except the last one. - // - if ((Info->LastFrag == 0) && (Info->Length % 8 != 0)) { - return EFI_INVALID_PARAMETER; - } - - // - // Reassemble the packet. - // - *Packet = Ip6Reassemble (&IpSb->Assemble, *Packet); - if (*Packet == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Re-check the assembled packet to get the right values. - // - *Head = (*Packet)->Ip.Ip6; - PayloadLen = (*Head)->PayloadLength; - if (PayloadLen != 0) { - if (*Payload != NULL) { - FreePool (*Payload); - } - - *Payload = AllocatePool ((UINTN) PayloadLen); - if (*Payload == NULL) { - return EFI_INVALID_PARAMETER; - } - - NetbufCopy (*Packet, sizeof (EFI_IP6_HEADER), PayloadLen, *Payload); - } - - if (!Ip6IsExtsValid ( - IpSb, - *Packet, - &(*Head)->NextHeader, - *Payload, - (UINT32) PayloadLen, - TRUE, - NULL, - LastHead, - ExtHdrsLen, - UnFragmentLen, - Fragmented - )) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Trim the head off, after this point, the packet is headless. - // and Packet->TotalLen == Info->Length. - // - NetbufTrim (*Packet, sizeof (EFI_IP6_HEADER) + *ExtHdrsLen, TRUE); - - return EFI_SUCCESS; -} - -/** - The IP6 input routine. It is called by the IP6_INTERFACE when an - IP6 fragment is received from MNP. - - @param[in] Packet The IP6 packet received. - @param[in] IoStatus The return status of receive request. - @param[in] Flag The link layer flag for the packet received, such - as multicast. - @param[in] Context The IP6 service instance that owns the MNP. - -**/ -VOID -Ip6AcceptFrame ( - IN NET_BUF *Packet, - IN EFI_STATUS IoStatus, - IN UINT32 Flag, - IN VOID *Context - ) -{ - IP6_SERVICE *IpSb; - EFI_IP6_HEADER *Head; - UINT8 *Payload; - UINT8 *LastHead; - UINT32 UnFragmentLen; - UINT32 ExtHdrsLen; - BOOLEAN Fragmented; - EFI_STATUS Status; - EFI_IP6_HEADER ZeroHead; - - IpSb = (IP6_SERVICE *) Context; - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - Payload = NULL; - LastHead = NULL; - - // - // Check input parameters - // - if (EFI_ERROR (IoStatus) || (IpSb->State == IP6_SERVICE_DESTROY)) { - goto Drop; - } - - // - // Pre-Process the Ipv6 Packet and then reassemble if it is necessary. - // - Status = Ip6PreProcessPacket ( - IpSb, - &Packet, - Flag, - &Payload, - &LastHead, - &ExtHdrsLen, - &UnFragmentLen, - &Fragmented, - &Head - ); - if (EFI_ERROR (Status)) { - goto Restart; - } - // - // After trim off, the packet is a esp/ah/udp/tcp/icmp6 net buffer, - // and no need consider any other ahead ext headers. - // - Status = Ip6IpSecProcessPacket ( - IpSb, - &Head, - LastHead, // need get the lasthead value for input - &Packet, - &Payload, - &ExtHdrsLen, - EfiIPsecInBound, - NULL - ); - - if (EFI_ERROR (Status)) { - goto Restart; - } - - // - // If the packet is protected by IPsec Tunnel Mode, Check the Inner Ip Packet. - // - ZeroMem (&ZeroHead, sizeof (EFI_IP6_HEADER)); - if (0 == CompareMem (Head, &ZeroHead, sizeof (EFI_IP6_HEADER))) { - Status = Ip6PreProcessPacket ( - IpSb, - &Packet, - Flag, - &Payload, - &LastHead, - &ExtHdrsLen, - &UnFragmentLen, - &Fragmented, - &Head - ); - if (EFI_ERROR (Status)) { - goto Restart; - } - } - - // - // Check the Packet again. - // - if (Packet == NULL) { - goto Restart; - } - - // - // Packet may have been changed. The ownership of the packet - // is transfered to the packet process logic. - // - Head = Packet->Ip.Ip6; - IP6_GET_CLIP_INFO (Packet)->Status = EFI_SUCCESS; - - switch (*LastHead) { - case IP6_ICMP: - Ip6IcmpHandle (IpSb, Head, Packet); - break; - default: - Ip6Demultiplex (IpSb, Head, Packet); - } - - Packet = NULL; - - // - // Dispatch the DPCs queued by the NotifyFunction of the rx token's events - // which are signaled with received data. - // - DispatchDpc (); - -Restart: - if (Payload != NULL) { - FreePool (Payload); - } - - Ip6ReceiveFrame (Ip6AcceptFrame, IpSb); - -Drop: - if (Packet != NULL) { - NetbufFree (Packet); - } - - return ; -} - -/** - Initialize an already allocated assemble table. This is generally - the assemble table embedded in the IP6 service instance. - - @param[in, out] Table The assemble table to initialize. - -**/ -VOID -Ip6CreateAssembleTable ( - IN OUT IP6_ASSEMBLE_TABLE *Table - ) -{ - UINT32 Index; - - for (Index = 0; Index < IP6_ASSEMLE_HASH_SIZE; Index++) { - InitializeListHead (&Table->Bucket[Index]); - } -} - -/** - Clean up the assemble table by removing all of the fragments - and assemble entries. - - @param[in, out] Table The assemble table to clean up. - -**/ -VOID -Ip6CleanAssembleTable ( - IN OUT IP6_ASSEMBLE_TABLE *Table - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_ASSEMBLE_ENTRY *Assemble; - UINT32 Index; - - for (Index = 0; Index < IP6_ASSEMLE_HASH_SIZE; Index++) { - NET_LIST_FOR_EACH_SAFE (Entry, Next, &Table->Bucket[Index]) { - Assemble = NET_LIST_USER_STRUCT (Entry, IP6_ASSEMBLE_ENTRY, Link); - - RemoveEntryList (Entry); - Ip6FreeAssembleEntry (Assemble); - } - } -} - - -/** - The signal handle of IP6's recycle event. It is called back - when the upper layer releases the packet. - - @param[in] Event The IP6's recycle event. - @param[in] Context The context of the handle, which is a IP6_RXDATA_WRAP. - -**/ -VOID -EFIAPI -Ip6OnRecyclePacket ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - IP6_RXDATA_WRAP *Wrap; - - Wrap = (IP6_RXDATA_WRAP *) Context; - - EfiAcquireLockOrFail (&Wrap->IpInstance->RecycleLock); - RemoveEntryList (&Wrap->Link); - EfiReleaseLock (&Wrap->IpInstance->RecycleLock); - - ASSERT (!NET_BUF_SHARED (Wrap->Packet)); - NetbufFree (Wrap->Packet); - - gBS->CloseEvent (Wrap->RxData.RecycleSignal); - FreePool (Wrap); -} - -/** - Wrap the received packet to a IP6_RXDATA_WRAP, which will be - delivered to the upper layer. Each IP6 child that accepts the - packet will get a not-shared copy of the packet which is wrapped - in the IP6_RXDATA_WRAP. The IP6_RXDATA_WRAP->RxData is passed - to the upper layer. The upper layer will signal the recycle event in - it when it is done with the packet. - - @param[in] IpInstance The IP6 child to receive the packet. - @param[in] Packet The packet to deliver up. - - @return NULL if it failed to wrap the packet; otherwise, the wrapper. - -**/ -IP6_RXDATA_WRAP * -Ip6WrapRxData ( - IN IP6_PROTOCOL *IpInstance, - IN NET_BUF *Packet - ) -{ - IP6_RXDATA_WRAP *Wrap; - EFI_IP6_RECEIVE_DATA *RxData; - EFI_STATUS Status; - - Wrap = AllocatePool (IP6_RXDATA_WRAP_SIZE (Packet->BlockOpNum)); - - if (Wrap == NULL) { - return NULL; - } - - InitializeListHead (&Wrap->Link); - - Wrap->IpInstance = IpInstance; - Wrap->Packet = Packet; - RxData = &Wrap->RxData; - - ZeroMem (&RxData->TimeStamp, sizeof (EFI_TIME)); - - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - Ip6OnRecyclePacket, - Wrap, - &RxData->RecycleSignal - ); - - if (EFI_ERROR (Status)) { - FreePool (Wrap); - return NULL; - } - - ASSERT (Packet->Ip.Ip6 != NULL); - - // - // The application expects a network byte order header. - // - RxData->HeaderLength = sizeof (EFI_IP6_HEADER); - RxData->Header = (EFI_IP6_HEADER *) Ip6NtohHead (Packet->Ip.Ip6); - RxData->DataLength = Packet->TotalSize; - - // - // Build the fragment table to be delivered up. - // - RxData->FragmentCount = Packet->BlockOpNum; - NetbufBuildExt (Packet, (NET_FRAGMENT *) RxData->FragmentTable, &RxData->FragmentCount); - - return Wrap; -} - -/** - Check whether this IP child accepts the packet. - - @param[in] IpInstance The IP child to check. - @param[in] Head The IP header of the packet. - @param[in] Packet The data of the packet. - - @retval TRUE The child wants to receive the packet. - @retval FALSE The child does not want to receive the packet. - -**/ -BOOLEAN -Ip6InstanceFrameAcceptable ( - IN IP6_PROTOCOL *IpInstance, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_ERROR_HEAD Icmp; - EFI_IP6_CONFIG_DATA *Config; - IP6_CLIP_INFO *Info; - UINT8 *Proto; - UINT32 Index; - UINT8 *ExtHdrs; - UINT16 ErrMsgPayloadLen; - UINT8 *ErrMsgPayload; - - Config = &IpInstance->ConfigData; - Proto = NULL; - - // - // Dirty trick for the Tiano UEFI network stack implmentation. If - // ReceiveTimeout == -1, the receive of the packet for this instance - // is disabled. The UEFI spec don't have such captibility. We add - // this to improve the performance because IP will make a copy of - // the received packet for each accepting instance. Some IP instances - // used by UDP/TCP only send packets, they don't wants to receive. - // - if (Config->ReceiveTimeout == (UINT32)(-1)) { - return FALSE; - } - - if (Config->AcceptPromiscuous) { - return TRUE; - } - - // - // Check whether the protocol is acceptable. - // - ExtHdrs = NetbufGetByte (Packet, 0, NULL); - - if (!Ip6IsExtsValid ( - IpInstance->Service, - Packet, - &Head->NextHeader, - ExtHdrs, - (UINT32) Head->PayloadLength, - TRUE, - NULL, - &Proto, - NULL, - NULL, - NULL - )) { - return FALSE; - } - - // - // The upper layer driver may want to receive the ICMPv6 error packet - // invoked by its packet, like UDP. - // - if ((*Proto == IP6_ICMP) && (!Config->AcceptAnyProtocol) && (*Proto != Config->DefaultProtocol)) { - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - - if (Icmp.Head.Type <= ICMP_V6_ERROR_MAX) { - if (!Config->AcceptIcmpErrors) { - return FALSE; - } - - // - // Get the protocol of the invoking packet of ICMPv6 error packet. - // - ErrMsgPayloadLen = NTOHS (Icmp.IpHead.PayloadLength); - ErrMsgPayload = NetbufGetByte (Packet, sizeof (Icmp), NULL); - - if (!Ip6IsExtsValid ( - NULL, - NULL, - &Icmp.IpHead.NextHeader, - ErrMsgPayload, - ErrMsgPayloadLen, - TRUE, - NULL, - &Proto, - NULL, - NULL, - NULL - )) { - return FALSE; - } - } - } - - // - // Match the protocol - // - if (!Config->AcceptAnyProtocol && (*Proto != Config->DefaultProtocol)) { - return FALSE; - } - - // - // Check for broadcast, the caller has computed the packet's - // cast type for this child's interface. - // - Info = IP6_GET_CLIP_INFO (Packet); - - // - // If it is a multicast packet, check whether we are in the group. - // - if (Info->CastType == Ip6Multicast) { - // - // Receive the multicast if the instance wants to receive all packets. - // - if (NetIp6IsUnspecifiedAddr (&IpInstance->ConfigData.StationAddress)) { - return TRUE; - } - - for (Index = 0; Index < IpInstance->GroupCount; Index++) { - if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, &Head->DestinationAddress)) { - break; - } - } - - return (BOOLEAN)(Index < IpInstance->GroupCount); - } - - return TRUE; -} - -/** - Enqueue a shared copy of the packet to the IP6 child if the - packet is acceptable to it. Here the data of the packet is - shared, but the net buffer isn't. - - @param IpInstance The IP6 child to enqueue the packet to. - @param Head The IP header of the received packet. - @param Packet The data of the received packet. - - @retval EFI_NOT_STARTED The IP child hasn't been configured. - @retval EFI_INVALID_PARAMETER The child doesn't want to receive the packet. - @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources - @retval EFI_SUCCESS A shared copy the packet is enqueued to the child. - -**/ -EFI_STATUS -Ip6InstanceEnquePacket ( - IN IP6_PROTOCOL *IpInstance, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_CLIP_INFO *Info; - NET_BUF *Clone; - - // - // Check whether the packet is acceptable to this instance. - // - if (IpInstance->State != IP6_STATE_CONFIGED) { - return EFI_NOT_STARTED; - } - - if (!Ip6InstanceFrameAcceptable (IpInstance, Head, Packet)) { - return EFI_INVALID_PARAMETER; - } - - // - // Enque a shared copy of the packet. - // - Clone = NetbufClone (Packet); - - if (Clone == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Set the receive time out for the assembled packet. If it expires, - // packet will be removed from the queue. - // - Info = IP6_GET_CLIP_INFO (Clone); - Info->Life = IP6_US_TO_SEC (IpInstance->ConfigData.ReceiveTimeout); - - InsertTailList (&IpInstance->Received, &Clone->List); - return EFI_SUCCESS; -} - -/** - Deliver the received packets to the upper layer if there are both received - requests and enqueued packets. If the enqueued packet is shared, it will - duplicate it to a non-shared packet, release the shared packet, then - deliver the non-shared packet up. - - @param[in] IpInstance The IP child to deliver the packet up. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to deliver the - packets. - @retval EFI_SUCCESS All the enqueued packets that can be delivered - are delivered up. - -**/ -EFI_STATUS -Ip6InstanceDeliverPacket ( - IN IP6_PROTOCOL *IpInstance - ) -{ - EFI_IP6_COMPLETION_TOKEN *Token; - IP6_RXDATA_WRAP *Wrap; - NET_BUF *Packet; - NET_BUF *Dup; - UINT8 *Head; - - // - // Deliver a packet if there are both a packet and a receive token. - // - while (!IsListEmpty (&IpInstance->Received) && !NetMapIsEmpty (&IpInstance->RxTokens)) { - - Packet = NET_LIST_HEAD (&IpInstance->Received, NET_BUF, List); - - if (!NET_BUF_SHARED (Packet)) { - // - // If this is the only instance that wants the packet, wrap it up. - // - Wrap = Ip6WrapRxData (IpInstance, Packet); - - if (Wrap == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - RemoveEntryList (&Packet->List); - - } else { - // - // Create a duplicated packet if this packet is shared - // - Dup = NetbufDuplicate (Packet, NULL, sizeof (EFI_IP6_HEADER)); - - if (Dup == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Copy the IP head over. The packet to deliver up is - // headless. Trim the head off after copy. The IP head - // may be not continuous before the data. - // - Head = NetbufAllocSpace (Dup, sizeof (EFI_IP6_HEADER), NET_BUF_HEAD); - ASSERT (Head != NULL); - Dup->Ip.Ip6 = (EFI_IP6_HEADER *) Head; - - CopyMem (Head, Packet->Ip.Ip6, sizeof (EFI_IP6_HEADER)); - NetbufTrim (Dup, sizeof (EFI_IP6_HEADER), TRUE); - - Wrap = Ip6WrapRxData (IpInstance, Dup); - - if (Wrap == NULL) { - NetbufFree (Dup); - return EFI_OUT_OF_RESOURCES; - } - - RemoveEntryList (&Packet->List); - NetbufFree (Packet); - - Packet = Dup; - } - - // - // Insert it into the delivered packet, then get a user's - // receive token, pass the wrapped packet up. - // - EfiAcquireLockOrFail (&IpInstance->RecycleLock); - InsertHeadList (&IpInstance->Delivered, &Wrap->Link); - EfiReleaseLock (&IpInstance->RecycleLock); - - Token = NetMapRemoveHead (&IpInstance->RxTokens, NULL); - Token->Status = IP6_GET_CLIP_INFO (Packet)->Status; - Token->Packet.RxData = &Wrap->RxData; - - gBS->SignalEvent (Token->Event); - } - - return EFI_SUCCESS; -} - -/** - Enqueue a received packet to all the IP children that share - the same interface. - - @param[in] IpSb The IP6 service instance that receive the packet. - @param[in] Head The header of the received packet. - @param[in] Packet The data of the received packet. - @param[in] IpIf The interface to enqueue the packet to. - - @return The number of the IP6 children that accepts the packet. - -**/ -INTN -Ip6InterfaceEnquePacket ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet, - IN IP6_INTERFACE *IpIf - ) -{ - IP6_PROTOCOL *IpInstance; - IP6_CLIP_INFO *Info; - LIST_ENTRY *Entry; - INTN Enqueued; - INTN LocalType; - INTN SavedType; - - // - // First, check that the packet is acceptable to this interface - // and find the local cast type for the interface. - // - LocalType = 0; - Info = IP6_GET_CLIP_INFO (Packet); - - if (IpIf->PromiscRecv) { - LocalType = Ip6Promiscuous; - } else { - LocalType = Info->CastType; - } - - // - // Iterate through the ip instances on the interface, enqueue - // the packet if filter passed. Save the original cast type, - // and pass the local cast type to the IP children on the - // interface. The global cast type will be restored later. - // - SavedType = Info->CastType; - Info->CastType = (UINT32) LocalType; - - Enqueued = 0; - - NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) { - IpInstance = NET_LIST_USER_STRUCT (Entry, IP6_PROTOCOL, AddrLink); - NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE); - - if (Ip6InstanceEnquePacket (IpInstance, Head, Packet) == EFI_SUCCESS) { - Enqueued++; - } - } - - Info->CastType = (UINT32) SavedType; - return Enqueued; -} - -/** - Deliver the packet for each IP6 child on the interface. - - @param[in] IpSb The IP6 service instance that received the packet. - @param[in] IpIf The IP6 interface to deliver the packet. - -**/ -VOID -Ip6InterfaceDeliverPacket ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *IpIf - ) -{ - IP6_PROTOCOL *IpInstance; - LIST_ENTRY *Entry; - - NET_LIST_FOR_EACH (Entry, &IpIf->IpInstances) { - IpInstance = NET_LIST_USER_STRUCT (Entry, IP6_PROTOCOL, AddrLink); - Ip6InstanceDeliverPacket (IpInstance); - } -} - -/** - De-multiplex the packet. the packet delivery is processed in two - passes. The first pass will enqueue a shared copy of the packet - to each IP6 child that accepts the packet. The second pass will - deliver a non-shared copy of the packet to each IP6 child that - has pending receive requests. Data is copied if more than one - child wants to consume the packet, because each IP child needs - its own copy of the packet to make changes. - - @param[in] IpSb The IP6 service instance that received the packet. - @param[in] Head The header of the received packet. - @param[in] Packet The data of the received packet. - - @retval EFI_NOT_FOUND No IP child accepts the packet. - @retval EFI_SUCCESS The packet is enqueued or delivered to some IP - children. - -**/ -EFI_STATUS -Ip6Demultiplex ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - - LIST_ENTRY *Entry; - IP6_INTERFACE *IpIf; - INTN Enqueued; - - // - // Two pass delivery: first, enque a shared copy of the packet - // to each instance that accept the packet. - // - Enqueued = 0; - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link); - - if (IpIf->Configured) { - Enqueued += Ip6InterfaceEnquePacket (IpSb, Head, Packet, IpIf); - } - } - - // - // Second: deliver a duplicate of the packet to each instance. - // Release the local reference first, so that the last instance - // getting the packet will not copy the data. - // - NetbufFree (Packet); - Packet = NULL; - - if (Enqueued == 0) { - return EFI_NOT_FOUND; - } - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link); - - if (IpIf->Configured) { - Ip6InterfaceDeliverPacket (IpSb, IpIf); - } - } - - return EFI_SUCCESS; -} - -/** - Decrease the life of the transmitted packets. If it is - decreased to zero, cancel the packet. This function is - called by Ip6packetTimerTicking that provides timeout for both the - received-but-not-delivered and transmitted-but-not-recycle - packets. - - @param[in] Map The IP6 child's transmit map. - @param[in] Item Current transmitted packet. - @param[in] Context Not used. - - @retval EFI_SUCCESS Always returns EFI_SUCCESS. - -**/ -EFI_STATUS -EFIAPI -Ip6SentPacketTicking ( - IN NET_MAP *Map, - IN NET_MAP_ITEM *Item, - IN VOID *Context - ) -{ - IP6_TXTOKEN_WRAP *Wrap; - - Wrap = (IP6_TXTOKEN_WRAP *) Item->Value; - ASSERT (Wrap != NULL); - - if ((Wrap->Life > 0) && (--Wrap->Life == 0)) { - Ip6CancelPacket (Wrap->IpInstance->Interface, Wrap->Packet, EFI_ABORTED); - } - - return EFI_SUCCESS; -} - -/** - Timeout the fragments, and the enqueued, and transmitted packets. - - @param[in] IpSb The IP6 service instance to timeout. - -**/ -VOID -Ip6PacketTimerTicking ( - IN IP6_SERVICE *IpSb - ) -{ - LIST_ENTRY *InstanceEntry; - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_PROTOCOL *IpInstance; - IP6_ASSEMBLE_ENTRY *Assemble; - NET_BUF *Packet; - IP6_CLIP_INFO *Info; - UINT32 Index; - - // - // First, time out the fragments. The packet's life is counting down - // once the first-arriving fragment of that packet was received. - // - for (Index = 0; Index < IP6_ASSEMLE_HASH_SIZE; Index++) { - NET_LIST_FOR_EACH_SAFE (Entry, Next, &(IpSb->Assemble.Bucket[Index])) { - Assemble = NET_LIST_USER_STRUCT (Entry, IP6_ASSEMBLE_ENTRY, Link); - - if ((Assemble->Life > 0) && (--Assemble->Life == 0)) { - // - // If the first fragment (the one with a Fragment Offset of zero) - // has been received, an ICMP Time Exceeded - Fragment Reassembly - // Time Exceeded message should be sent to the source of that fragment. - // - if ((Assemble->Packet != NULL) && - !IP6_IS_MULTICAST (&Assemble->Head->DestinationAddress)) { - Ip6SendIcmpError ( - IpSb, - Assemble->Packet, - NULL, - &Assemble->Head->SourceAddress, - ICMP_V6_TIME_EXCEEDED, - ICMP_V6_TIMEOUT_REASSEMBLE, - NULL - ); - } - - // - // If reassembly of a packet is not completed within 60 seconds of - // the reception of the first-arriving fragment of that packet, the - // reassembly must be abandoned and all the fragments that have been - // received for that packet must be discarded. - // - RemoveEntryList (Entry); - Ip6FreeAssembleEntry (Assemble); - } - } - } - - NET_LIST_FOR_EACH (InstanceEntry, &IpSb->Children) { - IpInstance = NET_LIST_USER_STRUCT (InstanceEntry, IP6_PROTOCOL, Link); - - // - // Second, time out the assembled packets enqueued on each IP child. - // - NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpInstance->Received) { - Packet = NET_LIST_USER_STRUCT (Entry, NET_BUF, List); - Info = IP6_GET_CLIP_INFO (Packet); - - if ((Info->Life > 0) && (--Info->Life == 0)) { - RemoveEntryList (Entry); - NetbufFree (Packet); - } - } - - // - // Third: time out the transmitted packets. - // - NetMapIterate (&IpInstance->TxTokens, Ip6SentPacketTicking, NULL); - } -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Input.h b/Core/NetworkPkg/Ip6Dxe/Ip6Input.h deleted file mode 100644 index 4d7ffc1c4f..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Input.h +++ /dev/null @@ -1,235 +0,0 @@ -/** @file - IP6 internal functions and definitions to process the incoming packets. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_INPUT_H__ -#define __EFI_IP6_INPUT_H__ - -#define IP6_MIN_HEADLEN 40 -#define IP6_MAX_HEADLEN 120 -/// -/// 8(ESP header) + 16(max IV) + 16(max padding) + 2(ESP tail) + 12(max ICV) = 54 -/// -#define IP6_MAX_IPSEC_HEADLEN 54 - - -#define IP6_ASSEMLE_HASH_SIZE 127 -/// -/// Lift time in seconds. -/// -#define IP6_FRAGMENT_LIFE 60 -#define IP6_MAX_PACKET_SIZE 65535 - - -#define IP6_GET_CLIP_INFO(Packet) ((IP6_CLIP_INFO *) ((Packet)->ProtoData)) - -#define IP6_ASSEMBLE_HASH(Dst, Src, Id) \ - ((*((UINT32 *) (Dst)) + *((UINT32 *) (Src)) + (Id)) % IP6_ASSEMLE_HASH_SIZE) - -#define IP6_RXDATA_WRAP_SIZE(NumFrag) \ - (sizeof (IP6_RXDATA_WRAP) + sizeof (EFI_IP6_FRAGMENT_DATA) * ((NumFrag) - 1)) - -// -// Per packet information for input process. LinkFlag specifies whether -// the packet is received as Link layer unicast, multicast or broadcast. -// The CastType is the IP layer cast type, such as IP multicast or unicast. -// Start, End and Length are staffs used to assemble the packets. Start -// is the sequence number of the first byte of data in the packet. Length -// is the number of bytes of data. End = Start + Length, that is, the -// sequence number of last byte + 1. Each assembled packet has a count down -// life. If it isn't consumed before Life reaches zero, the packet is released. -// -typedef struct { - UINT32 LinkFlag; - INT32 CastType; - INT32 Start; - INT32 End; - INT32 Length; - UINT32 Life; - EFI_STATUS Status; - UINT32 Id; - UINT16 HeadLen; - UINT8 NextHeader; - UINT8 LastFrag; - UINT32 FormerNextHeader; -} IP6_CLIP_INFO; - -// -// Structure used to assemble IP packets. -// -typedef struct { - LIST_ENTRY Link; - LIST_ENTRY Fragments; // List of all the fragments of this packet - - // - // Identity of one IP6 packet. Each fragment of a packet has - // the same (Dst, Src, Id). - // - EFI_IPv6_ADDRESS Dst; - EFI_IPv6_ADDRESS Src; - UINT32 Id; - - UINT32 TotalLen; - UINT32 CurLen; - UINT32 Life; // Count down life for the packet. - - EFI_IP6_HEADER *Head; // IP head of the first fragment - IP6_CLIP_INFO *Info; // Per packet information of the first fragment - NET_BUF *Packet; // The first fragment of the packet -} IP6_ASSEMBLE_ENTRY; - -// -// Each Ip service instance has an assemble table to reassemble -// the packets before delivery to its children. It is organized -// as hash table. -// -typedef struct { - LIST_ENTRY Bucket[IP6_ASSEMLE_HASH_SIZE]; -} IP6_ASSEMBLE_TABLE; - -/** - The IP6 input routine. It is called by the IP6_INTERFACE when an - IP6 fragment is received from MNP. - - @param[in] Packet The IP6 packet received. - @param[in] IoStatus The return status of receive request. - @param[in] Flag The link layer flag for the packet received, such - as multicast. - @param[in] Context The IP6 service instance that own the MNP. - -**/ -VOID -Ip6AcceptFrame ( - IN NET_BUF *Packet, - IN EFI_STATUS IoStatus, - IN UINT32 Flag, - IN VOID *Context - ); - -/** - Deliver the received packets to upper layer if there are both received - requests and enqueued packets. If the enqueued packet is shared, it will - duplicate it to a non-shared packet, release the shared packet, then - deliver the non-shared packet up. - - @param[in] IpInstance The IP child to deliver the packet up. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to deliver the - packets. - @retval EFI_SUCCESS All the enqueued packets that can be delivered - are delivered up. - -**/ -EFI_STATUS -Ip6InstanceDeliverPacket ( - IN IP6_PROTOCOL *IpInstance - ); - -/** - The work function to locate the IPsec protocol to process the inbound or - outbound IP packets. The process routine handles the packet with the following - actions: bypass the packet, discard the packet, or protect the packet. - - @param[in] IpSb The IP6 service instance. - @param[in, out] Head The caller-supplied IP6 header. - @param[in, out] LastHead The next header field of last IP header. - @param[in, out] Netbuf The IP6 packet to be processed by IPsec. - @param[in, out] ExtHdrs The caller-supplied options. - @param[in, out] ExtHdrsLen The length of the option. - @param[in] Direction The directionality in an SPD entry, - EfiIPsecInBound, or EfiIPsecOutBound. - @param[in] Context The token's wrap. - - @retval EFI_SUCCESS The IPsec protocol is not available or disabled. - @retval EFI_SUCCESS The packet was bypassed, and all buffers remain the same. - @retval EFI_SUCCESS The packet was protected. - @retval EFI_ACCESS_DENIED The packet was discarded. - @retval EFI_OUT_OF_RESOURCES There are not suffcient resources to complete the operation. - @retval EFI_BUFFER_TOO_SMALL The number of non-empty blocks is bigger than the - number of input data blocks when building a fragment table. - -**/ -EFI_STATUS -Ip6IpSecProcessPacket ( - IN IP6_SERVICE *IpSb, - IN OUT EFI_IP6_HEADER **Head, - IN OUT UINT8 *LastHead, - IN OUT NET_BUF **Netbuf, - IN OUT UINT8 **ExtHdrs, - IN OUT UINT32 *ExtHdrsLen, - IN EFI_IPSEC_TRAFFIC_DIR Direction, - IN VOID *Context - ); - -/** - Initialize an already allocated assemble table. This is generally - the assemble table embedded in the IP6 service instance. - - @param[in, out] Table The assemble table to initialize. - -**/ -VOID -Ip6CreateAssembleTable ( - IN OUT IP6_ASSEMBLE_TABLE *Table - ); - -/** - Clean up the assemble table: remove all the fragments - and assemble entries. - - @param[in, out] Table The assemble table to clean up. - -**/ -VOID -Ip6CleanAssembleTable ( - IN OUT IP6_ASSEMBLE_TABLE *Table - ); - -/** - Demultiple the packet. the packet delivery is processed in two - passes. The first pass will enque a shared copy of the packet - to each IP6 child that accepts the packet. The second pass will - deliver a non-shared copy of the packet to each IP6 child that - has pending receive requests. Data is copied if more than one - child wants to consume the packet bacause each IP child need - its own copy of the packet to make changes. - - @param[in] IpSb The IP6 service instance that received the packet. - @param[in] Head The header of the received packet. - @param[in] Packet The data of the received packet. - - @retval EFI_NOT_FOUND No IP child accepts the packet. - @retval EFI_SUCCESS The packet is enqueued or delivered to some IP - children. - -**/ -EFI_STATUS -Ip6Demultiplex ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - -/** - Timeout the fragmented, enqueued, and transmitted packets. - - @param[in] IpSb The IP6 service instance to timeout. - -**/ -VOID -Ip6PacketTimerTicking ( - IN IP6_SERVICE *IpSb - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Mld.c b/Core/NetworkPkg/Ip6Dxe/Ip6Mld.c deleted file mode 100644 index 4a418fade5..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Mld.c +++ /dev/null @@ -1,908 +0,0 @@ -/** @file - Multicast Listener Discovery support routines. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -/** - Create a IP6_MLD_GROUP list entry node and record to IP6 service binding data. - - @param[in, out] IpSb Points to IP6 service binding instance. - @param[in] MulticastAddr The IPv6 multicast address to be recorded. - @param[in] DelayTimer The maximum allowed delay before sending a responding - report, in units of milliseconds. - @return The created IP6_ML_GROUP list entry or NULL. - -**/ -IP6_MLD_GROUP * -Ip6CreateMldEntry ( - IN OUT IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *MulticastAddr, - IN UINT32 DelayTimer - ) -{ - IP6_MLD_GROUP *Entry; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr)); - - Entry = AllocatePool (sizeof (IP6_MLD_GROUP)); - if (Entry != NULL) { - Entry->RefCnt = 1; - Entry->DelayTimer = DelayTimer; - Entry->SendByUs = FALSE; - IP6_COPY_ADDRESS (&Entry->Address, MulticastAddr); - InsertTailList (&IpSb->MldCtrl.Groups, &Entry->Link); - } - - return Entry; -} - -/** - Search a IP6_MLD_GROUP list entry node from a list array. - - @param[in] IpSb Points to IP6 service binding instance. - @param[in] MulticastAddr The IPv6 multicast address to be searched. - - @return The found IP6_ML_GROUP list entry or NULL. - -**/ -IP6_MLD_GROUP * -Ip6FindMldEntry ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *MulticastAddr - ) -{ - LIST_ENTRY *Entry; - IP6_MLD_GROUP *Group; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr)); - - NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) { - Group = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link); - if (EFI_IP6_EQUAL (MulticastAddr, &Group->Address)) { - return Group; - } - } - - return NULL; -} - -/** - Count the number of IP6 multicast groups that are mapped to the - same MAC address. Several IP6 multicast address may be mapped to - the same MAC address. - - @param[in] MldCtrl The MLD control block to search in. - @param[in] Mac The MAC address to search. - - @return The number of the IP6 multicast group that mapped to the same - multicast group Mac. - -**/ -INTN -Ip6FindMac ( - IN IP6_MLD_SERVICE_DATA *MldCtrl, - IN EFI_MAC_ADDRESS *Mac - ) -{ - LIST_ENTRY *Entry; - IP6_MLD_GROUP *Group; - INTN Count; - - Count = 0; - - NET_LIST_FOR_EACH (Entry, &MldCtrl->Groups) { - Group = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link); - - if (NET_MAC_EQUAL (&Group->Mac, Mac, sizeof (EFI_MAC_ADDRESS))) { - Count++; - } - } - - return Count; -} - -/** - Generate MLD report message and send it out to MulticastAddr. - - @param[in] IpSb The IP service to send the packet. - @param[in] Interface The IP interface to send the packet. - If NULL, a system interface will be selected. - @param[in] MulticastAddr The specific IPv6 multicast address to which - the message sender is listening. - - @retval EFI_OUT_OF_RESOURCES There are not sufficient resources to complete the - operation. - @retval EFI_SUCCESS The MLD report message was successfully sent out. - -**/ -EFI_STATUS -Ip6SendMldReport ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *Interface OPTIONAL, - IN EFI_IPv6_ADDRESS *MulticastAddr - ) -{ - IP6_MLD_HEAD *MldHead; - NET_BUF *Packet; - EFI_IP6_HEADER Head; - UINT16 PayloadLen; - UINTN OptionLen; - UINT8 *Options; - EFI_STATUS Status; - UINT16 HeadChecksum; - UINT16 PseudoChecksum; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr)); - - // - // Generate the packet to be sent - // IPv6 basic header + Hop by Hop option + MLD message - // - - OptionLen = 0; - Status = Ip6FillHopByHop (NULL, &OptionLen, IP6_ICMP); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - PayloadLen = (UINT16) (OptionLen + sizeof (IP6_MLD_HEAD)); - Packet = NetbufAlloc (sizeof (EFI_IP6_HEADER) + (UINT32) PayloadLen); - if (Packet == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Create the basic IPv6 header. - // RFC3590: Use link-local address as source address if it is available, - // otherwise use the unspecified address. - // - Head.FlowLabelL = 0; - Head.FlowLabelH = 0; - Head.PayloadLength = HTONS (PayloadLen); - Head.NextHeader = IP6_HOP_BY_HOP; - Head.HopLimit = 1; - IP6_COPY_ADDRESS (&Head.DestinationAddress, MulticastAddr); - - // - // If Link-Local address is not ready, we use unspecified address. - // - IP6_COPY_ADDRESS (&Head.SourceAddress, &IpSb->LinkLocalAddr); - - NetbufReserve (Packet, sizeof (EFI_IP6_HEADER)); - - // - // Fill a IPv6 Router Alert option in a Hop-by-Hop Options Header - // - Options = NetbufAllocSpace (Packet, (UINT32) OptionLen, FALSE); - ASSERT (Options != NULL); - Status = Ip6FillHopByHop (Options, &OptionLen, IP6_ICMP); - if (EFI_ERROR (Status)) { - NetbufFree (Packet); - Packet = NULL; - return Status; - } - - // - // Fill in MLD message - Report - // - MldHead = (IP6_MLD_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_MLD_HEAD), FALSE); - ASSERT (MldHead != NULL); - ZeroMem (MldHead, sizeof (IP6_MLD_HEAD)); - MldHead->Head.Type = ICMP_V6_LISTENER_REPORT; - MldHead->Head.Code = 0; - IP6_COPY_ADDRESS (&MldHead->Group, MulticastAddr); - - HeadChecksum = NetblockChecksum ((UINT8 *) MldHead, sizeof (IP6_MLD_HEAD)); - PseudoChecksum = NetIp6PseudoHeadChecksum ( - &Head.SourceAddress, - &Head.DestinationAddress, - IP6_ICMP, - sizeof (IP6_MLD_HEAD) - ); - - MldHead->Head.Checksum = (UINT16) ~NetAddChecksum (HeadChecksum, PseudoChecksum); - - // - // Transmit the packet - // - return Ip6Output (IpSb, Interface, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL); -} - -/** - Generate MLD Done message and send it out to MulticastAddr. - - @param[in] IpSb The IP service to send the packet. - @param[in] MulticastAddr The specific IPv6 multicast address to which - the message sender is ceasing to listen. - - @retval EFI_OUT_OF_RESOURCES There are not sufficient resources to complete the - operation. - @retval EFI_SUCCESS The MLD report message was successfully sent out. - -**/ -EFI_STATUS -Ip6SendMldDone ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *MulticastAddr - ) -{ - IP6_MLD_HEAD *MldHead; - NET_BUF *Packet; - EFI_IP6_HEADER Head; - UINT16 PayloadLen; - UINTN OptionLen; - UINT8 *Options; - EFI_STATUS Status; - EFI_IPv6_ADDRESS Destination; - UINT16 HeadChecksum; - UINT16 PseudoChecksum; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (MulticastAddr != NULL && IP6_IS_MULTICAST (MulticastAddr)); - - // - // Generate the packet to be sent - // IPv6 basic header + Hop by Hop option + MLD message - // - - OptionLen = 0; - Status = Ip6FillHopByHop (NULL, &OptionLen, IP6_ICMP); - ASSERT (Status == EFI_BUFFER_TOO_SMALL); - - PayloadLen = (UINT16) (OptionLen + sizeof (IP6_MLD_HEAD)); - Packet = NetbufAlloc (sizeof (EFI_IP6_HEADER) + (UINT32) PayloadLen); - if (Packet == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Create the basic IPv6 header. - // - Head.FlowLabelL = 0; - Head.FlowLabelH = 0; - Head.PayloadLength = HTONS (PayloadLen); - Head.NextHeader = IP6_HOP_BY_HOP; - Head.HopLimit = 1; - - // - // If Link-Local address is not ready, we use unspecified address. - // - IP6_COPY_ADDRESS (&Head.SourceAddress, &IpSb->LinkLocalAddr); - - Ip6SetToAllNodeMulticast (TRUE, IP6_LINK_LOCAL_SCOPE, &Destination); - IP6_COPY_ADDRESS (&Head.DestinationAddress, &Destination); - - NetbufReserve (Packet, sizeof (EFI_IP6_HEADER)); - - // - // Fill a IPv6 Router Alert option in a Hop-by-Hop Options Header - // - Options = NetbufAllocSpace (Packet, (UINT32) OptionLen, FALSE); - ASSERT (Options != NULL); - Status = Ip6FillHopByHop (Options, &OptionLen, IP6_ICMP); - if (EFI_ERROR (Status)) { - NetbufFree (Packet); - Packet = NULL; - return Status; - } - - // - // Fill in MLD message - Done - // - MldHead = (IP6_MLD_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_MLD_HEAD), FALSE); - ASSERT (MldHead != NULL); - ZeroMem (MldHead, sizeof (IP6_MLD_HEAD)); - MldHead->Head.Type = ICMP_V6_LISTENER_DONE; - MldHead->Head.Code = 0; - IP6_COPY_ADDRESS (&MldHead->Group, MulticastAddr); - - HeadChecksum = NetblockChecksum ((UINT8 *) MldHead, sizeof (IP6_MLD_HEAD)); - PseudoChecksum = NetIp6PseudoHeadChecksum ( - &Head.SourceAddress, - &Head.DestinationAddress, - IP6_ICMP, - sizeof (IP6_MLD_HEAD) - ); - - MldHead->Head.Checksum = (UINT16) ~NetAddChecksum (HeadChecksum, PseudoChecksum); - - // - // Transmit the packet - // - return Ip6Output (IpSb, NULL, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL); -} - -/** - Init the MLD data of the IP6 service instance. Configure - MNP to receive ALL SYSTEM multicast. - - @param[in] IpSb The IP6 service whose MLD is to be initialized. - - @retval EFI_OUT_OF_RESOURCES There are not sufficient resourcet to complete the - operation. - @retval EFI_SUCCESS The MLD module successfully initialized. - -**/ -EFI_STATUS -Ip6InitMld ( - IN IP6_SERVICE *IpSb - ) -{ - EFI_IPv6_ADDRESS AllNodes; - IP6_MLD_GROUP *Group; - EFI_STATUS Status; - - // - // Join the link-scope all-nodes multicast address (FF02::1). - // This address is started in Idle Listener state and never transitions to - // another state, and never sends a Report or Done for that address. - // - - Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes); - - Group = Ip6CreateMldEntry (IpSb, &AllNodes, (UINT32) IP6_INFINIT_LIFETIME); - if (Group == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = Ip6GetMulticastMac (IpSb->Mnp, &AllNodes, &Group->Mac); - if (EFI_ERROR (Status)) { - goto ERROR; - } - - // - // Configure MNP to receive all-nodes multicast - // - Status = IpSb->Mnp->Groups (IpSb->Mnp, TRUE, &Group->Mac); - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - goto ERROR; - } - - return EFI_SUCCESS; - -ERROR: - RemoveEntryList (&Group->Link); - FreePool (Group); - return Status; -} - -/** - Add a group address to the array of group addresses. - The caller should make sure that no duplicated address - existed in the array. - - @param[in, out] IpInstance Points to an IP6_PROTOCOL instance. - @param[in] Group The IP6 multicast address to add. - - @retval EFI_OUT_OF_RESOURCES There are not sufficient resources to complete - the operation. - @retval EFI_SUCESS The address is added to the group address array. - -**/ -EFI_STATUS -Ip6CombineGroups ( - IN OUT IP6_PROTOCOL *IpInstance, - IN EFI_IPv6_ADDRESS *Group - ) -{ - EFI_IPv6_ADDRESS *GroupList; - - NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE); - ASSERT (Group != NULL && IP6_IS_MULTICAST (Group)); - - IpInstance->GroupCount++; - - GroupList = AllocatePool (IpInstance->GroupCount * sizeof (EFI_IPv6_ADDRESS)); - if (GroupList == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (IpInstance->GroupCount > 1) { - ASSERT (IpInstance->GroupList != NULL); - - CopyMem ( - GroupList, - IpInstance->GroupList, - (IpInstance->GroupCount - 1) * sizeof (EFI_IPv6_ADDRESS) - ); - - FreePool (IpInstance->GroupList); - } - - IP6_COPY_ADDRESS (GroupList + (IpInstance->GroupCount - 1), Group); - - IpInstance->GroupList = GroupList; - - return EFI_SUCCESS; -} - -/** - Remove a group address from the array of group addresses. - Although the function doesn't assume the byte order of Group, - the network byte order is used by the caller. - - @param[in, out] IpInstance Points to an IP6_PROTOCOL instance. - @param[in] Group The IP6 multicast address to remove. - - @retval EFI_NOT_FOUND Cannot find the to be removed group address. - @retval EFI_SUCCESS The group address was successfully removed. - -**/ -EFI_STATUS -Ip6RemoveGroup ( - IN OUT IP6_PROTOCOL *IpInstance, - IN EFI_IPv6_ADDRESS *Group - ) -{ - UINT32 Index; - UINT32 Count; - - Count = IpInstance->GroupCount; - - for (Index = 0; Index < Count; Index++) { - if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, Group)) { - break; - } - } - - if (Index == Count) { - return EFI_NOT_FOUND; - } - - while (Index < Count - 1) { - IP6_COPY_ADDRESS (IpInstance->GroupList + Index, IpInstance->GroupList + Index + 1); - Index++; - } - - ASSERT (IpInstance->GroupCount > 0); - IpInstance->GroupCount--; - - return EFI_SUCCESS; -} - -/** - Join the multicast group on behalf of this IP6 service binding instance. - - @param[in] IpSb The IP6 service binding instance. - @param[in] Interface Points to an IP6_INTERFACE structure. - @param[in] Address The group address to join. - - @retval EFI_SUCCESS Successfully join the multicast group. - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. - @retval Others Failed to join the multicast group. - -**/ -EFI_STATUS -Ip6JoinGroup ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *Interface, - IN EFI_IPv6_ADDRESS *Address - ) -{ - IP6_MLD_GROUP *Group; - EFI_STATUS Status; - - Group = Ip6FindMldEntry (IpSb, Address); - if (Group != NULL) { - Group->RefCnt++; - return EFI_SUCCESS; - } - - // - // Repeat the report once or twcie after short delays [Unsolicited Report Interval] (default:10s) - // Simulate this operation as a Multicast-Address-Specific Query was received for that addresss. - // - Group = Ip6CreateMldEntry (IpSb, Address, IP6_UNSOLICITED_REPORT_INTERVAL); - if (Group == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Group->SendByUs = TRUE; - - Status = Ip6GetMulticastMac (IpSb->Mnp, Address, &Group->Mac); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = IpSb->Mnp->Groups (IpSb->Mnp, TRUE, &Group->Mac); - if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { - goto ERROR; - } - - // - // Send unsolicited report when a node starts listening to a multicast address - // - Status = Ip6SendMldReport (IpSb, Interface, Address); - if (EFI_ERROR (Status)) { - goto ERROR; - } - - return EFI_SUCCESS; - -ERROR: - RemoveEntryList (&Group->Link); - FreePool (Group); - return Status; -} - -/** - Leave the IP6 multicast group. - - @param[in] IpSb The IP6 service binding instance. - @param[in] Address The group address to leave. - - @retval EFI_NOT_FOUND The IP6 service instance isn't in the group. - @retval EFI_SUCCESS Successfully leave the multicast group.. - @retval Others Failed to leave the multicast group. - -**/ -EFI_STATUS -Ip6LeaveGroup ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Address - ) -{ - IP6_MLD_GROUP *Group; - EFI_STATUS Status; - - Group = Ip6FindMldEntry (IpSb, Address); - if (Group == NULL) { - return EFI_NOT_FOUND; - } - - // - // If more than one instance is in the group, decrease - // the RefCnt then return. - // - if ((Group->RefCnt > 0) && (--Group->RefCnt > 0)) { - return EFI_SUCCESS; - } - - // - // If multiple IP6 group addresses are mapped to the same - // multicast MAC address, don't configure the MNP to leave - // the MAC. - // - if (Ip6FindMac (&IpSb->MldCtrl, &Group->Mac) == 1) { - Status = IpSb->Mnp->Groups (IpSb->Mnp, FALSE, &Group->Mac); - if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { - return Status; - } - } - - // - // Send a leave report if we are the last node to report - // - if (Group->SendByUs) { - Status = Ip6SendMldDone (IpSb, Address); - if (EFI_ERROR (Status)) { - return Status; - } - } - - RemoveEntryList (&Group->Link); - FreePool (Group); - - return EFI_SUCCESS; -} - -/** - Worker function for EfiIp6Groups(). The caller - should make sure that the parameters are valid. - - @param[in] IpInstance The IP6 child to change the setting. - @param[in] JoinFlag TRUE to join the group, otherwise leave it. - @param[in] GroupAddress The target group address. If NULL, leave all - the group addresses. - - @retval EFI_ALREADY_STARTED Wants to join the group, but is already a member of it - @retval EFI_OUT_OF_RESOURCES Failed to allocate sufficient resources. - @retval EFI_DEVICE_ERROR Failed to set the group configuraton. - @retval EFI_SUCCESS Successfully updated the group setting. - @retval EFI_NOT_FOUND Try to leave the group which it isn't a member. - -**/ -EFI_STATUS -Ip6Groups ( - IN IP6_PROTOCOL *IpInstance, - IN BOOLEAN JoinFlag, - IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL - ) -{ - EFI_STATUS Status; - IP6_SERVICE *IpSb; - UINT32 Index; - EFI_IPv6_ADDRESS *Group; - - IpSb = IpInstance->Service; - - if (JoinFlag) { - ASSERT (GroupAddress != NULL); - - for (Index = 0; Index < IpInstance->GroupCount; Index++) { - if (EFI_IP6_EQUAL (IpInstance->GroupList + Index, GroupAddress)) { - return EFI_ALREADY_STARTED; - } - } - - Status = Ip6JoinGroup (IpSb, IpInstance->Interface, GroupAddress); - if (!EFI_ERROR (Status)) { - return Ip6CombineGroups (IpInstance, GroupAddress); - } - - return Status; - } - - // - // Leave the group. Leave all the groups if GroupAddress is NULL. - // - for (Index = IpInstance->GroupCount; Index > 0; Index--) { - Group = IpInstance->GroupList + (Index - 1); - - if ((GroupAddress == NULL) || EFI_IP6_EQUAL (Group, GroupAddress)) { - Status = Ip6LeaveGroup (IpInstance->Service, Group); - if (EFI_ERROR (Status)) { - return Status; - } - - Ip6RemoveGroup (IpInstance, Group); - - if (IpInstance->GroupCount == 0) { - ASSERT (Index == 1); - FreePool (IpInstance->GroupList); - IpInstance->GroupList = NULL; - } - - if (GroupAddress != NULL) { - return EFI_SUCCESS; - } - } - } - - return ((GroupAddress != NULL) ? EFI_NOT_FOUND : EFI_SUCCESS); -} - -/** - Set a random value of the delay timer for the multicast address from the range - [0, Maximum Response Delay]. If a timer for any address is already - running, it is reset to the new random value only if the requested - Maximum Response Delay is less than the remaining value of the - running timer. If the Query packet specifies a Maximum Response - Delay of zero, each timer is effectively set to zero, and the action - specified below for timer expiration is performed immediately. - - @param[in] IpSb The IP6 service binding instance. - @param[in] MaxRespDelay The Maximum Response Delay, in milliseconds. - @param[in] MulticastAddr The multicast address. - @param[in, out] Group Points to a IP6_MLD_GROUP list entry node. - - @retval EFI_SUCCESS The delay timer is successfully updated or - timer expiration is performed immediately. - @retval Others Failed to send out MLD report message. - -**/ -EFI_STATUS -Ip6UpdateDelayTimer ( - IN IP6_SERVICE *IpSb, - IN UINT16 MaxRespDelay, - IN EFI_IPv6_ADDRESS *MulticastAddr, - IN OUT IP6_MLD_GROUP *Group - ) -{ - UINT32 Delay; - - // - // If the Query packet specifies a Maximum Response Delay of zero, perform timer - // expiration immediately. - // - if (MaxRespDelay == 0) { - Group->DelayTimer = 0; - return Ip6SendMldReport (IpSb, NULL, MulticastAddr); - } - - Delay = (UINT32) (MaxRespDelay / 1000); - - // - // Sets a delay timer to a random value selected from the range [0, Maximum Response Delay] - // If a timer is already running, resets it if the request Maximum Response Delay - // is less than the remaining value of the running timer. - // - if (Group->DelayTimer == 0 || Delay < Group->DelayTimer) { - Group->DelayTimer = Delay / 4294967295UL * NET_RANDOM (NetRandomInitSeed ()); - } - - return EFI_SUCCESS; -} - -/** - Process the Multicast Listener Query message. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the MLD query packet. - @param[in] Packet The content of the MLD query packet with IP head - removed. - - @retval EFI_SUCCESS The MLD query packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessMldQuery ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - EFI_IPv6_ADDRESS AllNodes; - IP6_MLD_GROUP *Group; - IP6_MLD_HEAD MldPacket; - LIST_ENTRY *Entry; - EFI_STATUS Status; - - Status = EFI_INVALID_PARAMETER; - - // - // Check the validity of the packet, generic query or specific query - // - if (!NetIp6IsUnspecifiedAddr (&Head->SourceAddress) && !NetIp6IsLinkLocalAddr (&Head->SourceAddress)) { - goto Exit; - } - - if (Head->HopLimit != 1 || !IP6_IS_MULTICAST (&Head->DestinationAddress)) { - goto Exit; - } - - // - // The Packet points to MLD report raw data without Hop-By-Hop option. - // - NetbufCopy (Packet, 0, sizeof (IP6_MLD_HEAD), (UINT8 *) &MldPacket); - MldPacket.MaxRespDelay = NTOHS (MldPacket.MaxRespDelay); - - Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes); - if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &AllNodes)) { - // - // Receives a Multicast-Address-Specific Query, check it firstly - // - if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &MldPacket.Group)) { - goto Exit; - } - // - // The node is not listening but it receives the specific query. Just return. - // - Group = Ip6FindMldEntry (IpSb, &MldPacket.Group); - if (Group == NULL) { - Status = EFI_SUCCESS; - goto Exit; - } - - Status = Ip6UpdateDelayTimer ( - IpSb, - MldPacket.MaxRespDelay, - &MldPacket.Group, - Group - ); - goto Exit; - } - - // - // Receives a General Query, sets a delay timer for each multicast address it is listening - // - NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) { - Group = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link); - Status = Ip6UpdateDelayTimer (IpSb, MldPacket.MaxRespDelay, &Group->Address, Group); - if (EFI_ERROR (Status)) { - goto Exit; - } - } - - Status = EFI_SUCCESS; - -Exit: - NetbufFree (Packet); - return Status; -} - -/** - Process the Multicast Listener Report message. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the MLD report packet. - @param[in] Packet The content of the MLD report packet with IP head - removed. - - @retval EFI_SUCCESS The MLD report packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - -**/ -EFI_STATUS -Ip6ProcessMldReport ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_MLD_HEAD MldPacket; - IP6_MLD_GROUP *Group; - EFI_STATUS Status; - - Status = EFI_INVALID_PARAMETER; - - // - // Validate the incoming message, if invalid, drop it. - // - if (!NetIp6IsUnspecifiedAddr (&Head->SourceAddress) && !NetIp6IsLinkLocalAddr (&Head->SourceAddress)) { - goto Exit; - } - - if (Head->HopLimit != 1 || !IP6_IS_MULTICAST (&Head->DestinationAddress)) { - goto Exit; - } - - // - // The Packet points to MLD report raw data without Hop-By-Hop option. - // - NetbufCopy (Packet, 0, sizeof (IP6_MLD_HEAD), (UINT8 *) &MldPacket); - if (!EFI_IP6_EQUAL (&Head->DestinationAddress, &MldPacket.Group)) { - goto Exit; - } - - Group = Ip6FindMldEntry (IpSb, &MldPacket.Group); - if (Group == NULL) { - goto Exit; - } - - // - // The report is sent by another node, stop its own timer relates to the multicast address and clear - // - - if (!Group->SendByUs) { - Group->DelayTimer = 0; - } - - Status = EFI_SUCCESS; - -Exit: - NetbufFree (Packet); - return Status; -} - -/** - The heartbeat timer of MLD module. It sends out a solicited MLD report when - DelayTimer expires. - - @param[in] IpSb The IP6 service binding instance. - -**/ -VOID -Ip6MldTimerTicking ( - IN IP6_SERVICE *IpSb - ) -{ - IP6_MLD_GROUP *Group; - LIST_ENTRY *Entry; - - // - // Send solicited report when timer expires - // - NET_LIST_FOR_EACH (Entry, &IpSb->MldCtrl.Groups) { - Group = NET_LIST_USER_STRUCT (Entry, IP6_MLD_GROUP, Link); - if ((Group->DelayTimer > 0) && (--Group->DelayTimer == 0)) { - Ip6SendMldReport (IpSb, NULL, &Group->Address); - } - } -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Mld.h b/Core/NetworkPkg/Ip6Dxe/Ip6Mld.h deleted file mode 100644 index e69f5d56b5..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Mld.h +++ /dev/null @@ -1,198 +0,0 @@ -/** @file - Multicast Listener Discovery support routines. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_MLD_H__ -#define __EFI_IP6_MLD_H__ - -#define IP6_UNSOLICITED_REPORT_INTERVAL 10 - -#pragma pack(1) -typedef struct { - IP6_ICMP_HEAD Head; - UINT16 MaxRespDelay; - UINT16 Reserved; - EFI_IPv6_ADDRESS Group; -} IP6_MLD_HEAD; -#pragma pack() - -// -// The status of multicast group. It isn't necessary to maintain -// explicit state of host state diagram. A group with finity -// DelayTime (less than 0xffffffff) is in "delaying listener" state. otherwise, it is in -// "idle listener" state. -// -typedef struct { - LIST_ENTRY Link; - INTN RefCnt; - EFI_IPv6_ADDRESS Address; - UINT32 DelayTimer; - BOOLEAN SendByUs; - EFI_MAC_ADDRESS Mac; -} IP6_MLD_GROUP; - -// -// The MLD status. Each IP6 service instance has a MLD_SERVICE_DATA -// attached. The Mldv1QuerySeen remember whether the server on this -// connected network is v1 or v2. -// -typedef struct { - INTN Mldv1QuerySeen; - LIST_ENTRY Groups; -} IP6_MLD_SERVICE_DATA; - -/** - Search a IP6_MLD_GROUP list entry node from a list array. - - @param[in] IpSb Points to an IP6 service binding instance. - @param[in] MulticastAddr The IPv6 multicast address to be searched. - - @return The found IP6_ML_GROUP list entry or NULL. - -**/ -IP6_MLD_GROUP * -Ip6FindMldEntry ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *MulticastAddr - ); - -/** - Init the MLD data of the IP6 service instance, configure - MNP to receive ALL SYSTEM multicasts. - - @param[in] IpSb The IP6 service whose MLD is to be initialized. - - @retval EFI_OUT_OF_RESOURCES There are not sufficient resources to complete the - operation. - @retval EFI_SUCCESS The MLD module successfully initialized. - -**/ -EFI_STATUS -Ip6InitMld ( - IN IP6_SERVICE *IpSb - ); - -/** - Join the multicast group on behalf of this IP6 service binding instance. - - @param[in] IpSb The IP6 service binding instance. - @param[in] Interface Points to an IP6_INTERFACE structure. - @param[in] Address The group address to join. - - @retval EFI_SUCCESS Successfully joined the multicast group. - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. - @retval Others Failed to join the multicast group. - -**/ -EFI_STATUS -Ip6JoinGroup ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *Interface, - IN EFI_IPv6_ADDRESS *Address - ); - -/** - Leave the IP6 multicast group. - - @param[in] IpSb The IP6 service binding instance. - @param[in] Address The group address to leave. - - @retval EFI_NOT_FOUND The IP6 service instance isn't in the group. - @retval EFI_SUCCESS Successfully left the multicast group. - @retval Others Failed to leave the multicast group. - -**/ -EFI_STATUS -Ip6LeaveGroup ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Address - ); - -/** - Worker function for EfiIp6Groups(). The caller - should verify that the parameters are valid. - - @param[in] IpInstance The IP6 child to change the setting. - @param[in] JoinFlag TRUE to join the group, otherwise leave it. - @param[in] GroupAddress The target group address. If NULL, leave all - the group addresses. - - @retval EFI_ALREADY_STARTED Wants to join the group, but is already a member of it. - @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources. - @retval EFI_DEVICE_ERROR Failed to set the group configuraton. - @retval EFI_SUCCESS Successfully updated the group setting. - @retval EFI_NOT_FOUND Tried to leave a group of whom it isn't a member. - -**/ -EFI_STATUS -Ip6Groups ( - IN IP6_PROTOCOL *IpInstance, - IN BOOLEAN JoinFlag, - IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL - ); - -/** - Process the Multicast Listener Query message. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the MLD query packet. - @param[in] Packet The content of the MLD query packet with IP head - removed. - - @retval EFI_SUCCESS The MLD query packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessMldQuery ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - -/** - Process the Multicast Listener Report message. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the MLD report packet. - @param[in] Packet The content of the MLD report packet with IP head - removed. - - @retval EFI_SUCCESS The MLD report packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - -**/ -EFI_STATUS -Ip6ProcessMldReport ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - - -/** - The heartbeat timer of the MLD module. It sends out solicited MLD report when - DelayTimer expires. - - @param[in] IpSb The IP6 service binding instance. - -**/ -VOID -Ip6MldTimerTicking ( - IN IP6_SERVICE *IpSb - ); - -#endif - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Nd.c b/Core/NetworkPkg/Ip6Dxe/Ip6Nd.c deleted file mode 100644 index a3f49bb2da..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Nd.c +++ /dev/null @@ -1,3155 +0,0 @@ -/** @file - Implementation of Neighbor Discovery support routines. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -EFI_MAC_ADDRESS mZeroMacAddress; - -/** - Update the ReachableTime in IP6 service binding instance data, in milliseconds. - - @param[in, out] IpSb Points to the IP6_SERVICE. - -**/ -VOID -Ip6UpdateReachableTime ( - IN OUT IP6_SERVICE *IpSb - ) -{ - UINT32 Random; - - Random = (NetRandomInitSeed () / 4294967295UL) * IP6_RANDOM_FACTOR_SCALE; - Random = Random + IP6_MIN_RANDOM_FACTOR_SCALED; - IpSb->ReachableTime = (IpSb->BaseReachableTime * Random) / IP6_RANDOM_FACTOR_SCALE; -} - -/** - Build a array of EFI_IP6_NEIGHBOR_CACHE to be returned to the caller. The number - of EFI_IP6_NEIGHBOR_CACHE is also returned. - - @param[in] IpInstance The pointer to IP6_PROTOCOL instance. - @param[out] NeighborCount The number of returned neighbor cache entries. - @param[out] NeighborCache The pointer to the array of EFI_IP6_NEIGHBOR_CACHE. - - @retval EFI_SUCCESS The EFI_IP6_NEIGHBOR_CACHE successfully built. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the route table. - -**/ -EFI_STATUS -Ip6BuildEfiNeighborCache ( - IN IP6_PROTOCOL *IpInstance, - OUT UINT32 *NeighborCount, - OUT EFI_IP6_NEIGHBOR_CACHE **NeighborCache - ) -{ - IP6_NEIGHBOR_ENTRY *Neighbor; - LIST_ENTRY *Entry; - IP6_SERVICE *IpSb; - UINT32 Count; - EFI_IP6_NEIGHBOR_CACHE *EfiNeighborCache; - EFI_IP6_NEIGHBOR_CACHE *NeighborCacheTmp; - - NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE); - ASSERT (NeighborCount != NULL && NeighborCache != NULL); - - IpSb = IpInstance->Service; - Count = 0; - - NET_LIST_FOR_EACH (Entry, &IpSb->NeighborTable) { - Count++; - } - - if (Count == 0) { - return EFI_SUCCESS; - } - - NeighborCacheTmp = AllocatePool (Count * sizeof (EFI_IP6_NEIGHBOR_CACHE)); - if (NeighborCacheTmp == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - *NeighborCount = Count; - Count = 0; - - NET_LIST_FOR_EACH (Entry, &IpSb->NeighborTable) { - Neighbor = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, Link); - - EfiNeighborCache = NeighborCacheTmp + Count; - - EfiNeighborCache->State = Neighbor->State; - IP6_COPY_ADDRESS (&EfiNeighborCache->Neighbor, &Neighbor->Neighbor); - IP6_COPY_LINK_ADDRESS (&EfiNeighborCache->LinkAddress, &Neighbor->LinkAddress); - - Count++; - } - - ASSERT (*NeighborCount == Count); - *NeighborCache = NeighborCacheTmp; - - return EFI_SUCCESS; -} - -/** - Build a array of EFI_IP6_ADDRESS_INFO to be returned to the caller. The number - of prefix entries is also returned. - - @param[in] IpInstance The pointer to IP6_PROTOCOL instance. - @param[out] PrefixCount The number of returned prefix entries. - @param[out] PrefixTable The pointer to the array of PrefixTable. - - @retval EFI_SUCCESS The prefix table successfully built. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the prefix table. - -**/ -EFI_STATUS -Ip6BuildPrefixTable ( - IN IP6_PROTOCOL *IpInstance, - OUT UINT32 *PrefixCount, - OUT EFI_IP6_ADDRESS_INFO **PrefixTable - ) -{ - LIST_ENTRY *Entry; - IP6_SERVICE *IpSb; - UINT32 Count; - IP6_PREFIX_LIST_ENTRY *PrefixList; - EFI_IP6_ADDRESS_INFO *EfiPrefix; - EFI_IP6_ADDRESS_INFO *PrefixTableTmp; - - NET_CHECK_SIGNATURE (IpInstance, IP6_PROTOCOL_SIGNATURE); - ASSERT (PrefixCount != NULL && PrefixTable != NULL); - - IpSb = IpInstance->Service; - Count = 0; - - NET_LIST_FOR_EACH (Entry, &IpSb->OnlinkPrefix) { - Count++; - } - - if (Count == 0) { - return EFI_SUCCESS; - } - - PrefixTableTmp = AllocatePool (Count * sizeof (EFI_IP6_ADDRESS_INFO)); - if (PrefixTableTmp == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - *PrefixCount = Count; - Count = 0; - - NET_LIST_FOR_EACH (Entry, &IpSb->OnlinkPrefix) { - PrefixList = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link); - EfiPrefix = PrefixTableTmp + Count; - IP6_COPY_ADDRESS (&EfiPrefix->Address, &PrefixList->Prefix); - EfiPrefix->PrefixLength = PrefixList->PrefixLength; - - Count++; - } - - ASSERT (*PrefixCount == Count); - *PrefixTable = PrefixTableTmp; - - return EFI_SUCCESS; -} - -/** - Allocate and initialize a IP6 prefix list entry. - - @param[in] IpSb The pointer to IP6_SERVICE instance. - @param[in] OnLinkOrAuto If TRUE, the entry is created for the on link prefix list. - Otherwise, it is created for the autoconfiguration prefix list. - @param[in] ValidLifetime The length of time in seconds that the prefix - is valid for the purpose of on-link determination. - @param[in] PreferredLifetime The length of time in seconds that addresses - generated from the prefix via stateless address - autoconfiguration remain preferred. - @param[in] PrefixLength The prefix length of the Prefix. - @param[in] Prefix The prefix address. - - @return NULL if it failed to allocate memory for the prefix node. Otherwise, point - to the created or existing prefix list entry. - -**/ -IP6_PREFIX_LIST_ENTRY * -Ip6CreatePrefixListEntry ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN OnLinkOrAuto, - IN UINT32 ValidLifetime, - IN UINT32 PreferredLifetime, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *Prefix - ) -{ - IP6_PREFIX_LIST_ENTRY *PrefixEntry; - IP6_ROUTE_ENTRY *RtEntry; - LIST_ENTRY *ListHead; - LIST_ENTRY *Entry; - IP6_PREFIX_LIST_ENTRY *TmpPrefixEntry; - - if (Prefix == NULL || PreferredLifetime > ValidLifetime || PrefixLength > IP6_PREFIX_MAX) { - return NULL; - } - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - PrefixEntry = Ip6FindPrefixListEntry ( - IpSb, - OnLinkOrAuto, - PrefixLength, - Prefix - ); - if (PrefixEntry != NULL) { - PrefixEntry->RefCnt ++; - return PrefixEntry; - } - - PrefixEntry = AllocatePool (sizeof (IP6_PREFIX_LIST_ENTRY)); - if (PrefixEntry == NULL) { - return NULL; - } - - PrefixEntry->RefCnt = 1; - PrefixEntry->ValidLifetime = ValidLifetime; - PrefixEntry->PreferredLifetime = PreferredLifetime; - PrefixEntry->PrefixLength = PrefixLength; - IP6_COPY_ADDRESS (&PrefixEntry->Prefix, Prefix); - - ListHead = OnLinkOrAuto ? &IpSb->OnlinkPrefix : &IpSb->AutonomousPrefix; - - // - // Create a direct route entry for on-link prefix and insert to route area. - // - if (OnLinkOrAuto) { - RtEntry = Ip6CreateRouteEntry (Prefix, PrefixLength, NULL); - if (RtEntry == NULL) { - FreePool (PrefixEntry); - return NULL; - } - - RtEntry->Flag = IP6_DIRECT_ROUTE; - InsertHeadList (&IpSb->RouteTable->RouteArea[PrefixLength], &RtEntry->Link); - IpSb->RouteTable->TotalNum++; - } - - // - // Insert the prefix entry in the order that a prefix with longer prefix length - // is put ahead in the list. - // - NET_LIST_FOR_EACH (Entry, ListHead) { - TmpPrefixEntry = NET_LIST_USER_STRUCT(Entry, IP6_PREFIX_LIST_ENTRY, Link); - - if (TmpPrefixEntry->PrefixLength < PrefixEntry->PrefixLength) { - break; - } - } - - NetListInsertBefore (Entry, &PrefixEntry->Link); - - return PrefixEntry; -} - -/** - Destroy a IP6 prefix list entry. - - @param[in] IpSb The pointer to IP6_SERVICE instance. - @param[in] PrefixEntry The to be destroyed prefix list entry. - @param[in] OnLinkOrAuto If TRUE, the entry is removed from on link prefix list. - Otherwise remove from autoconfiguration prefix list. - @param[in] ImmediateDelete If TRUE, remove the entry directly. - Otherwise, check the reference count to see whether - it should be removed. - -**/ -VOID -Ip6DestroyPrefixListEntry ( - IN IP6_SERVICE *IpSb, - IN IP6_PREFIX_LIST_ENTRY *PrefixEntry, - IN BOOLEAN OnLinkOrAuto, - IN BOOLEAN ImmediateDelete - ) -{ - LIST_ENTRY *Entry; - IP6_INTERFACE *IpIf; - EFI_STATUS Status; - - if ((!ImmediateDelete) && (PrefixEntry->RefCnt > 0) && ((--PrefixEntry->RefCnt) > 0)) { - return ; - } - - if (OnLinkOrAuto) { - // - // Remove the direct route for onlink prefix from route table. - // - do { - Status = Ip6DelRoute ( - IpSb->RouteTable, - &PrefixEntry->Prefix, - PrefixEntry->PrefixLength, - NULL - ); - } while (Status != EFI_NOT_FOUND); - } else { - // - // Remove the corresponding addresses generated from this autonomous prefix. - // - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE); - - Ip6RemoveAddr (IpSb, &IpIf->AddressList, &IpIf->AddressCount, &PrefixEntry->Prefix, PrefixEntry->PrefixLength); - } - } - - RemoveEntryList (&PrefixEntry->Link); - FreePool (PrefixEntry); -} - -/** - Search the list array to find an IP6 prefix list entry. - - @param[in] IpSb The pointer to IP6_SERVICE instance. - @param[in] OnLinkOrAuto If TRUE, the search the link prefix list, - Otherwise search the autoconfiguration prefix list. - @param[in] PrefixLength The prefix length of the Prefix - @param[in] Prefix The prefix address. - - @return NULL if cannot find the IP6 prefix list entry. Otherwise, return the - pointer to the IP6 prefix list entry. - -**/ -IP6_PREFIX_LIST_ENTRY * -Ip6FindPrefixListEntry ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN OnLinkOrAuto, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *Prefix - ) -{ - IP6_PREFIX_LIST_ENTRY *PrefixList; - LIST_ENTRY *Entry; - LIST_ENTRY *ListHead; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (Prefix != NULL); - - if (OnLinkOrAuto) { - ListHead = &IpSb->OnlinkPrefix; - } else { - ListHead = &IpSb->AutonomousPrefix; - } - - NET_LIST_FOR_EACH (Entry, ListHead) { - PrefixList = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link); - if (PrefixLength != 255) { - // - // Perform exactly prefix match. - // - if (PrefixList->PrefixLength == PrefixLength && - NetIp6IsNetEqual (&PrefixList->Prefix, Prefix, PrefixLength)) { - return PrefixList; - } - } else { - // - // Perform the longest prefix match. The list is already sorted with - // the longest length prefix put at the head of the list. - // - if (NetIp6IsNetEqual (&PrefixList->Prefix, Prefix, PrefixList->PrefixLength)) { - return PrefixList; - } - } - } - - return NULL; -} - -/** - Release the resource in the prefix list table, and destroy the list entry and - corresponding addresses or route entries. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] ListHead The list entry head of the prefix list table. - -**/ -VOID -Ip6CleanPrefixListTable ( - IN IP6_SERVICE *IpSb, - IN LIST_ENTRY *ListHead - ) -{ - IP6_PREFIX_LIST_ENTRY *PrefixList; - BOOLEAN OnLink; - - OnLink = (BOOLEAN) (ListHead == &IpSb->OnlinkPrefix); - - while (!IsListEmpty (ListHead)) { - PrefixList = NET_LIST_HEAD (ListHead, IP6_PREFIX_LIST_ENTRY, Link); - Ip6DestroyPrefixListEntry (IpSb, PrefixList, OnLink, TRUE); - } -} - -/** - Callback function when address resolution is finished. It will cancel - all the queued frames if the address resolution failed, or transmit them - if the request succeeded. - - @param[in] Context The context of the callback, a pointer to IP6_NEIGHBOR_ENTRY. - -**/ -VOID -Ip6OnArpResolved ( - IN VOID *Context - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_NEIGHBOR_ENTRY *ArpQue; - IP6_SERVICE *IpSb; - IP6_LINK_TX_TOKEN *Token; - EFI_STATUS Status; - BOOLEAN Sent; - - ArpQue = (IP6_NEIGHBOR_ENTRY *) Context; - if ((ArpQue == NULL) || (ArpQue->Interface == NULL)) { - return ; - } - - IpSb = ArpQue->Interface->Service; - if ((IpSb == NULL) || (IpSb->Signature != IP6_SERVICE_SIGNATURE)) { - return ; - } - - // - // ARP resolve failed for some reason. Release all the frame - // and ARP queue itself. Ip6FreeArpQue will call the frame's - // owner back. - // - if (NET_MAC_EQUAL (&ArpQue->LinkAddress, &mZeroMacAddress, IpSb->SnpMode.HwAddressSize)) { - Ip6FreeNeighborEntry (IpSb, ArpQue, FALSE, TRUE, EFI_NO_MAPPING, NULL, NULL); - return ; - } - - // - // ARP resolve succeeded, Transmit all the frame. - // - Sent = FALSE; - NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) { - RemoveEntryList (Entry); - - Token = NET_LIST_USER_STRUCT (Entry, IP6_LINK_TX_TOKEN, Link); - IP6_COPY_LINK_ADDRESS (&Token->DstMac, &ArpQue->LinkAddress); - - // - // Insert the tx token before transmitting it via MNP as the FrameSentDpc - // may be called before Mnp->Transmit returns which will remove this tx - // token from the SentFrames list. Remove it from the list if the returned - // Status of Mnp->Transmit is not EFI_SUCCESS as in this case the - // FrameSentDpc won't be queued. - // - InsertTailList (&ArpQue->Interface->SentFrames, &Token->Link); - - Status = IpSb->Mnp->Transmit (IpSb->Mnp, &Token->MnpToken); - if (EFI_ERROR (Status)) { - RemoveEntryList (&Token->Link); - Token->CallBack (Token->Packet, Status, 0, Token->Context); - - Ip6FreeLinkTxToken (Token); - continue; - } else { - Sent = TRUE; - } - } - - // - // Free the ArpQue only but not the whole neighbor entry. - // - Ip6FreeNeighborEntry (IpSb, ArpQue, FALSE, FALSE, EFI_SUCCESS, NULL, NULL); - - if (Sent && (ArpQue->State == EfiNeighborStale)) { - ArpQue->State = EfiNeighborDelay; - ArpQue->Ticks = (UINT32) IP6_GET_TICKS (IP6_DELAY_FIRST_PROBE_TIME); - } -} - -/** - Allocate and initialize an IP6 neighbor cache entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] CallBack The callback function to be called when - address resolution is finished. - @param[in] Ip6Address Points to the IPv6 address of the neighbor. - @param[in] LinkAddress Points to the MAC address of the neighbor. - Ignored if NULL. - - @return NULL if failed to allocate memory for the neighbor cache entry. - Otherwise, point to the created neighbor cache entry. - -**/ -IP6_NEIGHBOR_ENTRY * -Ip6CreateNeighborEntry ( - IN IP6_SERVICE *IpSb, - IN IP6_ARP_CALLBACK CallBack, - IN EFI_IPv6_ADDRESS *Ip6Address, - IN EFI_MAC_ADDRESS *LinkAddress OPTIONAL - ) -{ - IP6_NEIGHBOR_ENTRY *Entry; - IP6_DEFAULT_ROUTER *DefaultRouter; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (Ip6Address!= NULL); - - Entry = AllocateZeroPool (sizeof (IP6_NEIGHBOR_ENTRY)); - if (Entry == NULL) { - return NULL; - } - - Entry->RefCnt = 1; - Entry->IsRouter = FALSE; - Entry->ArpFree = FALSE; - Entry->Dynamic = FALSE; - Entry->State = EfiNeighborInComplete; - Entry->Transmit = IP6_MAX_MULTICAST_SOLICIT + 1; - Entry->CallBack = CallBack; - Entry->Interface = NULL; - - InitializeListHead (&Entry->Frames); - - IP6_COPY_ADDRESS (&Entry->Neighbor, Ip6Address); - - if (LinkAddress != NULL) { - IP6_COPY_LINK_ADDRESS (&Entry->LinkAddress, LinkAddress); - } else { - IP6_COPY_LINK_ADDRESS (&Entry->LinkAddress, &mZeroMacAddress); - } - - InsertHeadList (&IpSb->NeighborTable, &Entry->Link); - - // - // If corresponding default router entry exists, establish the relationship. - // - DefaultRouter = Ip6FindDefaultRouter (IpSb, Ip6Address); - if (DefaultRouter != NULL) { - DefaultRouter->NeighborCache = Entry; - } - - return Entry; -} - -/** - Search a IP6 neighbor cache entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Ip6Address Points to the IPv6 address of the neighbor. - - @return NULL if it failed to find the matching neighbor cache entry. - Otherwise, point to the found neighbor cache entry. - -**/ -IP6_NEIGHBOR_ENTRY * -Ip6FindNeighborEntry ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Ip6Address - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_NEIGHBOR_ENTRY *Neighbor; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (Ip6Address != NULL); - - NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->NeighborTable) { - Neighbor = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, Link); - if (EFI_IP6_EQUAL (Ip6Address, &Neighbor->Neighbor)) { - RemoveEntryList (Entry); - InsertHeadList (&IpSb->NeighborTable, Entry); - - return Neighbor; - } - } - - return NULL; -} - -/** - Free a IP6 neighbor cache entry and remove all the frames on the address - resolution queue that pass the FrameToCancel. That is, either FrameToCancel - is NULL, or it returns true for the frame. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] NeighborCache The to be free neighbor cache entry. - @param[in] SendIcmpError If TRUE, send out ICMP error. - @param[in] FullFree If TRUE, remove the neighbor cache entry. - Otherwise remove the pending frames. - @param[in] IoStatus The status returned to the cancelled frames' - callback function. - @param[in] FrameToCancel Function to select which frame to cancel. - This is an optional parameter that may be NULL. - @param[in] Context Opaque parameter to the FrameToCancel. - Ignored if FrameToCancel is NULL. - - @retval EFI_INVALID_PARAMETER The input parameter is invalid. - @retval EFI_SUCCESS The operation finished successfully. - -**/ -EFI_STATUS -Ip6FreeNeighborEntry ( - IN IP6_SERVICE *IpSb, - IN IP6_NEIGHBOR_ENTRY *NeighborCache, - IN BOOLEAN SendIcmpError, - IN BOOLEAN FullFree, - IN EFI_STATUS IoStatus, - IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, - IN VOID *Context OPTIONAL - ) -{ - IP6_LINK_TX_TOKEN *TxToken; - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_DEFAULT_ROUTER *DefaultRouter; - - // - // If FrameToCancel fails, the token will not be released. - // To avoid the memory leak, stop this usage model. - // - if (FullFree && FrameToCancel != NULL) { - return EFI_INVALID_PARAMETER; - } - - NET_LIST_FOR_EACH_SAFE (Entry, Next, &NeighborCache->Frames) { - TxToken = NET_LIST_USER_STRUCT (Entry, IP6_LINK_TX_TOKEN, Link); - - if (SendIcmpError && !IP6_IS_MULTICAST (&TxToken->Packet->Ip.Ip6->DestinationAddress)) { - Ip6SendIcmpError ( - IpSb, - TxToken->Packet, - NULL, - &TxToken->Packet->Ip.Ip6->SourceAddress, - ICMP_V6_DEST_UNREACHABLE, - ICMP_V6_ADDR_UNREACHABLE, - NULL - ); - } - - if ((FrameToCancel == NULL) || FrameToCancel (TxToken, Context)) { - RemoveEntryList (Entry); - TxToken->CallBack (TxToken->Packet, IoStatus, 0, TxToken->Context); - Ip6FreeLinkTxToken (TxToken); - } - } - - if (NeighborCache->ArpFree && IsListEmpty (&NeighborCache->Frames)) { - RemoveEntryList (&NeighborCache->ArpList); - NeighborCache->ArpFree = FALSE; - } - - if (FullFree) { - if (NeighborCache->IsRouter) { - DefaultRouter = Ip6FindDefaultRouter (IpSb, &NeighborCache->Neighbor); - if (DefaultRouter != NULL) { - Ip6DestroyDefaultRouter (IpSb, DefaultRouter); - } - } - - RemoveEntryList (&NeighborCache->Link); - FreePool (NeighborCache); - } - - return EFI_SUCCESS; -} - -/** - Allocate and initialize an IP6 default router entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Ip6Address The IPv6 address of the default router. - @param[in] RouterLifetime The lifetime associated with the default - router, in units of seconds. - - @return NULL if it failed to allocate memory for the default router node. - Otherwise, point to the created default router node. - -**/ -IP6_DEFAULT_ROUTER * -Ip6CreateDefaultRouter ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Ip6Address, - IN UINT16 RouterLifetime - ) -{ - IP6_DEFAULT_ROUTER *Entry; - IP6_ROUTE_ENTRY *RtEntry; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (Ip6Address != NULL); - - Entry = AllocatePool (sizeof (IP6_DEFAULT_ROUTER)); - if (Entry == NULL) { - return NULL; - } - - Entry->RefCnt = 1; - Entry->Lifetime = RouterLifetime; - Entry->NeighborCache = Ip6FindNeighborEntry (IpSb, Ip6Address); - IP6_COPY_ADDRESS (&Entry->Router, Ip6Address); - - // - // Add a default route into route table with both Destination and PrefixLength set to zero. - // - RtEntry = Ip6CreateRouteEntry (NULL, 0, Ip6Address); - if (RtEntry == NULL) { - FreePool (Entry); - return NULL; - } - - InsertHeadList (&IpSb->RouteTable->RouteArea[0], &RtEntry->Link); - IpSb->RouteTable->TotalNum++; - - InsertTailList (&IpSb->DefaultRouterList, &Entry->Link); - - return Entry; -} - -/** - Destroy an IP6 default router entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] DefaultRouter The to be destroyed IP6_DEFAULT_ROUTER. - -**/ -VOID -Ip6DestroyDefaultRouter ( - IN IP6_SERVICE *IpSb, - IN IP6_DEFAULT_ROUTER *DefaultRouter - ) -{ - EFI_STATUS Status; - - RemoveEntryList (&DefaultRouter->Link); - - // - // Update the Destination Cache - all entries using the time-out router as next-hop - // should perform next-hop determination again. - // - do { - Status = Ip6DelRoute (IpSb->RouteTable, NULL, 0, &DefaultRouter->Router); - } while (Status != EFI_NOT_FOUND); - - FreePool (DefaultRouter); -} - -/** - Clean an IP6 default router list. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - -**/ -VOID -Ip6CleanDefaultRouterList ( - IN IP6_SERVICE *IpSb - ) -{ - IP6_DEFAULT_ROUTER *DefaultRouter; - - while (!IsListEmpty (&IpSb->DefaultRouterList)) { - DefaultRouter = NET_LIST_HEAD (&IpSb->DefaultRouterList, IP6_DEFAULT_ROUTER, Link); - Ip6DestroyDefaultRouter (IpSb, DefaultRouter); - } -} - -/** - Search a default router node from an IP6 default router list. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Ip6Address The IPv6 address of the to be searched default router node. - - @return NULL if it failed to find the matching default router node. - Otherwise, point to the found default router node. - -**/ -IP6_DEFAULT_ROUTER * -Ip6FindDefaultRouter ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Ip6Address - ) -{ - LIST_ENTRY *Entry; - IP6_DEFAULT_ROUTER *DefaultRouter; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (Ip6Address != NULL); - - NET_LIST_FOR_EACH (Entry, &IpSb->DefaultRouterList) { - DefaultRouter = NET_LIST_USER_STRUCT (Entry, IP6_DEFAULT_ROUTER, Link); - if (EFI_IP6_EQUAL (Ip6Address, &DefaultRouter->Router)) { - return DefaultRouter; - } - } - - return NULL; -} - -/** - The function to be called after DAD (Duplicate Address Detection) is performed. - - @param[in] IsDadPassed If TRUE, the DAD operation succeed. Otherwise, the DAD operation failed. - @param[in] IpIf Points to the IP6_INTERFACE. - @param[in] DadEntry The DAD entry which already performed DAD. - -**/ -VOID -Ip6OnDADFinished ( - IN BOOLEAN IsDadPassed, - IN IP6_INTERFACE *IpIf, - IN IP6_DAD_ENTRY *DadEntry - ) -{ - IP6_SERVICE *IpSb; - IP6_ADDRESS_INFO *AddrInfo; - EFI_DHCP6_PROTOCOL *Dhcp6; - UINT16 OptBuf[4]; - EFI_DHCP6_PACKET_OPTION *Oro; - EFI_DHCP6_RETRANSMISSION InfoReqReXmit; - EFI_IPv6_ADDRESS AllNodes; - - IpSb = IpIf->Service; - AddrInfo = DadEntry->AddressInfo; - - if (IsDadPassed) { - // - // DAD succeed. - // - if (NetIp6IsLinkLocalAddr (&AddrInfo->Address)) { - ASSERT (!IpSb->LinkLocalOk); - - IP6_COPY_ADDRESS (&IpSb->LinkLocalAddr, &AddrInfo->Address); - IpSb->LinkLocalOk = TRUE; - IpIf->Configured = TRUE; - - // - // Check whether DHCP6 need to be started. - // - Dhcp6 = IpSb->Ip6ConfigInstance.Dhcp6; - - if (IpSb->Dhcp6NeedStart) { - Dhcp6->Start (Dhcp6); - IpSb->Dhcp6NeedStart = FALSE; - } - - if (IpSb->Dhcp6NeedInfoRequest) { - // - // Set the exta options to send. Here we only want the option request option - // with DNS SERVERS. - // - Oro = (EFI_DHCP6_PACKET_OPTION *) OptBuf; - Oro->OpCode = HTONS (DHCP6_OPT_ORO); - Oro->OpLen = HTONS (2); - *((UINT16 *) &Oro->Data[0]) = HTONS (DHCP6_OPT_DNS_SERVERS); - - InfoReqReXmit.Irt = 4; - InfoReqReXmit.Mrc = 64; - InfoReqReXmit.Mrt = 60; - InfoReqReXmit.Mrd = 0; - - Dhcp6->InfoRequest ( - Dhcp6, - TRUE, - Oro, - 0, - NULL, - &InfoReqReXmit, - IpSb->Ip6ConfigInstance.Dhcp6Event, - Ip6ConfigOnDhcp6Reply, - &IpSb->Ip6ConfigInstance - ); - } - - // - // Add an on-link prefix for link-local address. - // - Ip6CreatePrefixListEntry ( - IpSb, - TRUE, - (UINT32) IP6_INFINIT_LIFETIME, - (UINT32) IP6_INFINIT_LIFETIME, - IP6_LINK_LOCAL_PREFIX_LENGTH, - &IpSb->LinkLocalAddr - ); - - } else { - // - // Global scope unicast address. - // - Ip6AddAddr (IpIf, AddrInfo); - - // - // Add an on-link prefix for this address. - // - Ip6CreatePrefixListEntry ( - IpSb, - TRUE, - AddrInfo->ValidLifetime, - AddrInfo->PreferredLifetime, - AddrInfo->PrefixLength, - &AddrInfo->Address - ); - - IpIf->Configured = TRUE; - } - } else { - // - // Leave the group we joined before. - // - Ip6LeaveGroup (IpSb, &DadEntry->Destination); - } - - if (DadEntry->Callback != NULL) { - DadEntry->Callback (IsDadPassed, &AddrInfo->Address, DadEntry->Context); - } - - if (!IsDadPassed && NetIp6IsLinkLocalAddr (&AddrInfo->Address)) { - FreePool (AddrInfo); - RemoveEntryList (&DadEntry->Link); - FreePool (DadEntry); - // - // Leave link-scope all-nodes multicast address (FF02::1) - // - Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes); - Ip6LeaveGroup (IpSb, &AllNodes); - // - // Disable IP operation since link-local address is a duplicate address. - // - IpSb->LinkLocalDadFail = TRUE; - IpSb->Mnp->Configure (IpSb->Mnp, NULL); - gBS->SetTimer (IpSb->Timer, TimerCancel, 0); - gBS->SetTimer (IpSb->FasterTimer, TimerCancel, 0); - return ; - } - - if (!IsDadPassed || NetIp6IsLinkLocalAddr (&AddrInfo->Address)) { - // - // Free the AddressInfo we hold if DAD fails or it is a link-local address. - // - FreePool (AddrInfo); - } - - RemoveEntryList (&DadEntry->Link); - FreePool (DadEntry); -} - -/** - Create a DAD (Duplicate Address Detection) entry and queue it to be performed. - - @param[in] IpIf Points to the IP6_INTERFACE. - @param[in] AddressInfo The address information which needs DAD performed. - @param[in] Callback The callback routine that will be called after DAD - is performed. This is an optional parameter that - may be NULL. - @param[in] Context The opaque parameter for a DAD callback routine. - This is an optional parameter that may be NULL. - - @retval EFI_SUCCESS The DAD entry was created and queued. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory to complete the - operation. - - -**/ -EFI_STATUS -Ip6InitDADProcess ( - IN IP6_INTERFACE *IpIf, - IN IP6_ADDRESS_INFO *AddressInfo, - IN IP6_DAD_CALLBACK Callback OPTIONAL, - IN VOID *Context OPTIONAL - ) -{ - IP6_DAD_ENTRY *Entry; - EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS *DadXmits; - IP6_SERVICE *IpSb; - EFI_STATUS Status; - UINT32 MaxDelayTick; - - NET_CHECK_SIGNATURE (IpIf, IP6_INTERFACE_SIGNATURE); - ASSERT (AddressInfo != NULL); - - // - // Do nothing if we have already started DAD on the address. - // - if (Ip6FindDADEntry (IpIf->Service, &AddressInfo->Address, NULL) != NULL) { - return EFI_SUCCESS; - } - - Status = EFI_SUCCESS; - IpSb = IpIf->Service; - DadXmits = &IpSb->Ip6ConfigInstance.DadXmits; - - // - // Allocate the resources and insert info - // - Entry = AllocatePool (sizeof (IP6_DAD_ENTRY)); - if (Entry == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Map the incoming unicast address to solicited-node multicast address - // - Ip6CreateSNMulticastAddr (&AddressInfo->Address, &Entry->Destination); - - // - // Join in the solicited-node multicast address. - // - Status = Ip6JoinGroup (IpSb, IpIf, &Entry->Destination); - if (EFI_ERROR (Status)) { - FreePool (Entry); - return Status; - } - - Entry->Signature = IP6_DAD_ENTRY_SIGNATURE; - Entry->MaxTransmit = DadXmits->DupAddrDetectTransmits; - Entry->Transmit = 0; - Entry->Receive = 0; - MaxDelayTick = IP6_MAX_RTR_SOLICITATION_DELAY / IP6_TIMER_INTERVAL_IN_MS; - Entry->RetransTick = (MaxDelayTick * ((NET_RANDOM (NetRandomInitSeed ()) % 5) + 1)) / 5; - Entry->AddressInfo = AddressInfo; - Entry->Callback = Callback; - Entry->Context = Context; - InsertTailList (&IpIf->DupAddrDetectList, &Entry->Link); - - if (Entry->MaxTransmit == 0) { - // - // DAD is disabled on this interface, immediately mark this DAD successful. - // - Ip6OnDADFinished (TRUE, IpIf, Entry); - } - - return EFI_SUCCESS; -} - -/** - Search IP6_DAD_ENTRY from the Duplicate Address Detection List. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Target The address information which needs DAD performed . - @param[out] Interface If not NULL, output the IP6 interface that configures - the tentative address. - - @return NULL if failed to find the matching DAD entry. - Otherwise, point to the found DAD entry. - -**/ -IP6_DAD_ENTRY * -Ip6FindDADEntry ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Target, - OUT IP6_INTERFACE **Interface OPTIONAL - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Entry2; - IP6_INTERFACE *IpIf; - IP6_DAD_ENTRY *DupAddrDetect; - IP6_ADDRESS_INFO *AddrInfo; - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link); - - NET_LIST_FOR_EACH (Entry2, &IpIf->DupAddrDetectList) { - DupAddrDetect = NET_LIST_USER_STRUCT_S (Entry2, IP6_DAD_ENTRY, Link, IP6_DAD_ENTRY_SIGNATURE); - AddrInfo = DupAddrDetect->AddressInfo; - if (EFI_IP6_EQUAL (&AddrInfo->Address, Target)) { - if (Interface != NULL) { - *Interface = IpIf; - } - return DupAddrDetect; - } - } - } - - return NULL; -} - -/** - Generate router solicit message and send it out to Destination Address or - All Router Link Local scope multicast address. - - @param[in] IpSb The IP service to send the packet. - @param[in] Interface If not NULL, points to the IP6 interface to send - the packet. - @param[in] SourceAddress If not NULL, the source address of the message. - @param[in] DestinationAddress If not NULL, the destination address of the message. - @param[in] SourceLinkAddress If not NULL, the MAC address of the source. - A source link-layer address option will be appended - to the message. - - @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the - operation. - @retval EFI_SUCCESS The router solicit message was successfully sent. - -**/ -EFI_STATUS -Ip6SendRouterSolicit ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *Interface OPTIONAL, - IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, - IN EFI_IPv6_ADDRESS *DestinationAddress OPTIONAL, - IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL - ) -{ - NET_BUF *Packet; - EFI_IP6_HEADER Head; - IP6_ICMP_INFORMATION_HEAD *IcmpHead; - IP6_ETHER_ADDR_OPTION *LinkLayerOption; - UINT16 PayloadLen; - IP6_INTERFACE *IpIf; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - IpIf = Interface; - if (IpIf == NULL && IpSb->DefaultInterface != NULL) { - IpIf = IpSb->DefaultInterface; - } - - // - // Generate the packet to be sent - // - - PayloadLen = (UINT16) sizeof (IP6_ICMP_INFORMATION_HEAD); - if (SourceLinkAddress != NULL) { - PayloadLen += sizeof (IP6_ETHER_ADDR_OPTION); - } - - Packet = NetbufAlloc (sizeof (EFI_IP6_HEADER) + (UINT32) PayloadLen); - if (Packet == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Create the basic IPv6 header. - // - Head.FlowLabelL = 0; - Head.FlowLabelH = 0; - Head.PayloadLength = HTONS (PayloadLen); - Head.NextHeader = IP6_ICMP; - Head.HopLimit = IP6_HOP_LIMIT; - - if (SourceAddress != NULL) { - IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress); - } else { - ZeroMem (&Head.SourceAddress, sizeof (EFI_IPv6_ADDRESS)); - } - - - if (DestinationAddress != NULL) { - IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress); - } else { - Ip6SetToAllNodeMulticast (TRUE, IP6_LINK_LOCAL_SCOPE, &Head.DestinationAddress); - } - - NetbufReserve (Packet, sizeof (EFI_IP6_HEADER)); - - // - // Fill in the ICMP header, and Source link-layer address if contained. - // - - IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE); - ASSERT (IcmpHead != NULL); - ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD)); - IcmpHead->Head.Type = ICMP_V6_ROUTER_SOLICIT; - IcmpHead->Head.Code = 0; - - LinkLayerOption = NULL; - if (SourceLinkAddress != NULL) { - LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) NetbufAllocSpace ( - Packet, - sizeof (IP6_ETHER_ADDR_OPTION), - FALSE - ); - ASSERT (LinkLayerOption != NULL); - LinkLayerOption->Type = Ip6OptionEtherSource; - LinkLayerOption->Length = (UINT8) sizeof (IP6_ETHER_ADDR_OPTION); - CopyMem (LinkLayerOption->EtherAddr, SourceLinkAddress, 6); - } - - // - // Transmit the packet - // - return Ip6Output (IpSb, IpIf, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL); -} - -/** - Generate a Neighbor Advertisement message and send it out to Destination Address. - - @param[in] IpSb The IP service to send the packet. - @param[in] SourceAddress The source address of the message. - @param[in] DestinationAddress The destination address of the message. - @param[in] TargetIp6Address The target address field in the Neighbor Solicitation - message that prompted this advertisement. - @param[in] TargetLinkAddress The MAC address for the target, i.e. the sender - of the advertisement. - @param[in] IsRouter If TRUE, indicates the sender is a router. - @param[in] Override If TRUE, indicates the advertisement should override - an existing cache entry and update the MAC address. - @param[in] Solicited If TRUE, indicates the advertisement was sent - in response to a Neighbor Solicitation from - the Destination address. - - @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the - operation. - @retval EFI_SUCCESS The Neighbor Advertise message was successfully sent. - -**/ -EFI_STATUS -Ip6SendNeighborAdvertise ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *SourceAddress, - IN EFI_IPv6_ADDRESS *DestinationAddress, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *TargetLinkAddress, - IN BOOLEAN IsRouter, - IN BOOLEAN Override, - IN BOOLEAN Solicited - ) -{ - NET_BUF *Packet; - EFI_IP6_HEADER Head; - IP6_ICMP_INFORMATION_HEAD *IcmpHead; - IP6_ETHER_ADDR_OPTION *LinkLayerOption; - EFI_IPv6_ADDRESS *Target; - UINT16 PayloadLen; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - // - // The Neighbor Advertisement message must include a Target link-layer address option - // when responding to multicast solicitation and should include such option when - // responding to unicast solicitation. It also must include such option as unsolicited - // advertisement. - // - ASSERT (DestinationAddress != NULL && TargetIp6Address != NULL && TargetLinkAddress != NULL); - - PayloadLen = (UINT16) (sizeof (IP6_ICMP_INFORMATION_HEAD) + sizeof (EFI_IPv6_ADDRESS) + sizeof (IP6_ETHER_ADDR_OPTION)); - - // - // Generate the packet to be sent - // - - Packet = NetbufAlloc (sizeof (EFI_IP6_HEADER) + (UINT32) PayloadLen); - if (Packet == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Create the basic IPv6 header. - // - Head.FlowLabelL = 0; - Head.FlowLabelH = 0; - Head.PayloadLength = HTONS (PayloadLen); - Head.NextHeader = IP6_ICMP; - Head.HopLimit = IP6_HOP_LIMIT; - - IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress); - IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress); - - NetbufReserve (Packet, sizeof (EFI_IP6_HEADER)); - - // - // Fill in the ICMP header, Target address, and Target link-layer address. - // Set the Router flag, Solicited flag and Override flag. - // - - IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE); - ASSERT (IcmpHead != NULL); - ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD)); - IcmpHead->Head.Type = ICMP_V6_NEIGHBOR_ADVERTISE; - IcmpHead->Head.Code = 0; - - if (IsRouter) { - IcmpHead->Fourth |= IP6_IS_ROUTER_FLAG; - } - - if (Solicited) { - IcmpHead->Fourth |= IP6_SOLICITED_FLAG; - } - - if (Override) { - IcmpHead->Fourth |= IP6_OVERRIDE_FLAG; - } - - Target = (EFI_IPv6_ADDRESS *) NetbufAllocSpace (Packet, sizeof (EFI_IPv6_ADDRESS), FALSE); - ASSERT (Target != NULL); - IP6_COPY_ADDRESS (Target, TargetIp6Address); - - LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) NetbufAllocSpace ( - Packet, - sizeof (IP6_ETHER_ADDR_OPTION), - FALSE - ); - ASSERT (LinkLayerOption != NULL); - LinkLayerOption->Type = Ip6OptionEtherTarget; - LinkLayerOption->Length = 1; - CopyMem (LinkLayerOption->EtherAddr, TargetLinkAddress, 6); - - // - // Transmit the packet - // - return Ip6Output (IpSb, NULL, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL); -} - -/** - Generate the Neighbor Solicitation message and send it to the Destination Address. - - @param[in] IpSb The IP service to send the packet - @param[in] SourceAddress The source address of the message. - @param[in] DestinationAddress The destination address of the message. - @param[in] TargetIp6Address The IP address of the target of the solicitation. - It must not be a multicast address. - @param[in] SourceLinkAddress The MAC address for the sender. If not NULL, - a source link-layer address option will be appended - to the message. - - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the - operation. - @retval EFI_SUCCESS The Neighbor Advertise message was successfully sent. - -**/ -EFI_STATUS -Ip6SendNeighborSolicit ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *SourceAddress, - IN EFI_IPv6_ADDRESS *DestinationAddress, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL - ) -{ - NET_BUF *Packet; - EFI_IP6_HEADER Head; - IP6_ICMP_INFORMATION_HEAD *IcmpHead; - IP6_ETHER_ADDR_OPTION *LinkLayerOption; - EFI_IPv6_ADDRESS *Target; - BOOLEAN IsDAD; - UINT16 PayloadLen; - IP6_NEIGHBOR_ENTRY *Neighbor; - - // - // Check input parameters - // - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - if (DestinationAddress == NULL || TargetIp6Address == NULL) { - return EFI_INVALID_PARAMETER; - } - - IsDAD = FALSE; - - if (SourceAddress == NULL || (SourceAddress != NULL && NetIp6IsUnspecifiedAddr (SourceAddress))) { - IsDAD = TRUE; - } - - // - // The Neighbor Solicitation message should include a source link-layer address option - // if the solicitation is not sent by performing DAD - Duplicate Address Detection. - // Otherwise must not include it. - // - PayloadLen = (UINT16) (sizeof (IP6_ICMP_INFORMATION_HEAD) + sizeof (EFI_IPv6_ADDRESS)); - - if (!IsDAD) { - if (SourceLinkAddress == NULL) { - return EFI_INVALID_PARAMETER; - } - - PayloadLen = (UINT16) (PayloadLen + sizeof (IP6_ETHER_ADDR_OPTION)); - } - - // - // Generate the packet to be sent - // - - Packet = NetbufAlloc (sizeof (EFI_IP6_HEADER) + (UINT32) PayloadLen); - if (Packet == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Create the basic IPv6 header - // - Head.FlowLabelL = 0; - Head.FlowLabelH = 0; - Head.PayloadLength = HTONS (PayloadLen); - Head.NextHeader = IP6_ICMP; - Head.HopLimit = IP6_HOP_LIMIT; - - if (SourceAddress != NULL) { - IP6_COPY_ADDRESS (&Head.SourceAddress, SourceAddress); - } else { - ZeroMem (&Head.SourceAddress, sizeof (EFI_IPv6_ADDRESS)); - } - - IP6_COPY_ADDRESS (&Head.DestinationAddress, DestinationAddress); - - NetbufReserve (Packet, sizeof (EFI_IP6_HEADER)); - - // - // Fill in the ICMP header, Target address, and Source link-layer address. - // - IcmpHead = (IP6_ICMP_INFORMATION_HEAD *) NetbufAllocSpace (Packet, sizeof (IP6_ICMP_INFORMATION_HEAD), FALSE); - ASSERT (IcmpHead != NULL); - ZeroMem (IcmpHead, sizeof (IP6_ICMP_INFORMATION_HEAD)); - IcmpHead->Head.Type = ICMP_V6_NEIGHBOR_SOLICIT; - IcmpHead->Head.Code = 0; - - Target = (EFI_IPv6_ADDRESS *) NetbufAllocSpace (Packet, sizeof (EFI_IPv6_ADDRESS), FALSE); - ASSERT (Target != NULL); - IP6_COPY_ADDRESS (Target, TargetIp6Address); - - LinkLayerOption = NULL; - if (!IsDAD) { - - // - // Fill in the source link-layer address option - // - LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) NetbufAllocSpace ( - Packet, - sizeof (IP6_ETHER_ADDR_OPTION), - FALSE - ); - ASSERT (LinkLayerOption != NULL); - LinkLayerOption->Type = Ip6OptionEtherSource; - LinkLayerOption->Length = 1; - CopyMem (LinkLayerOption->EtherAddr, SourceLinkAddress, 6); - } - - // - // Create a Neighbor Cache entry in the INCOMPLETE state when performing - // address resolution. - // - if (!IsDAD && Ip6IsSNMulticastAddr (DestinationAddress)) { - Neighbor = Ip6FindNeighborEntry (IpSb, TargetIp6Address); - if (Neighbor == NULL) { - Neighbor = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, TargetIp6Address, NULL); - ASSERT (Neighbor != NULL); - } - } - - // - // Transmit the packet - // - return Ip6Output (IpSb, IpSb->DefaultInterface, NULL, Packet, &Head, NULL, 0, Ip6SysPacketSent, NULL); -} - -/** - Process the Neighbor Solicitation message. The message may be sent for Duplicate - Address Detection or Address Resolution. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the message. - @param[in] Packet The content of the message with IP head removed. - - @retval EFI_SUCCESS The packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval EFI_ICMP_ERROR The packet indicates that DAD is failed. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessNeighborSolicit ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_INFORMATION_HEAD Icmp; - EFI_IPv6_ADDRESS Target; - IP6_ETHER_ADDR_OPTION LinkLayerOption; - BOOLEAN IsDAD; - BOOLEAN IsUnicast; - BOOLEAN IsMaintained; - IP6_DAD_ENTRY *DupAddrDetect; - IP6_INTERFACE *IpIf; - IP6_NEIGHBOR_ENTRY *Neighbor; - BOOLEAN Solicited; - BOOLEAN UpdateCache; - EFI_IPv6_ADDRESS Dest; - UINT16 OptionLen; - UINT8 *Option; - BOOLEAN Provided; - EFI_STATUS Status; - VOID *MacAddress; - - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - NetbufCopy (Packet, sizeof (Icmp), sizeof (Target), Target.Addr); - - // - // Perform Message Validation: - // The IP Hop Limit field has a value of 255, i.e., the packet - // could not possibly have been forwarded by a router. - // ICMP Code is 0. - // Target Address is not a multicast address. - // - Status = EFI_INVALID_PARAMETER; - - if (Head->HopLimit != IP6_HOP_LIMIT || Icmp.Head.Code != 0 || !NetIp6IsValidUnicast (&Target)) { - goto Exit; - } - - // - // ICMP length is 24 or more octets. - // - OptionLen = 0; - if (Head->PayloadLength < IP6_ND_LENGTH) { - goto Exit; - } else { - OptionLen = (UINT16) (Head->PayloadLength - IP6_ND_LENGTH); - if (OptionLen != 0) { - Option = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL); - ASSERT (Option != NULL); - - // - // All included options should have a length that is greater than zero. - // - if (!Ip6IsNDOptionValid (Option, OptionLen)) { - goto Exit; - } - } - } - - IsDAD = NetIp6IsUnspecifiedAddr (&Head->SourceAddress); - IsUnicast = (BOOLEAN) !Ip6IsSNMulticastAddr (&Head->DestinationAddress); - IsMaintained = Ip6IsOneOfSetAddress (IpSb, &Target, &IpIf, NULL); - - Provided = FALSE; - if (OptionLen >= sizeof (IP6_ETHER_ADDR_OPTION)) { - NetbufCopy ( - Packet, - IP6_ND_LENGTH, - sizeof (IP6_ETHER_ADDR_OPTION), - (UINT8 *) &LinkLayerOption - ); - // - // The solicitation for neighbor discovery should include a source link-layer - // address option. If the option is not recognized, silently ignore it. - // - if (LinkLayerOption.Type == Ip6OptionEtherSource) { - if (IsDAD) { - // - // If the IP source address is the unspecified address, the source - // link-layer address option must not be included in the message. - // - goto Exit; - } - - Provided = TRUE; - } - } - - // - // If the IP source address is the unspecified address, the IP - // destination address is a solicited-node multicast address. - // - if (IsDAD && IsUnicast) { - goto Exit; - } - - // - // If the target address is tentative, and the source address is a unicast address, - // the solicitation's sender is performing address resolution on the target; - // the solicitation should be silently ignored. - // - if (!IsDAD && !IsMaintained) { - goto Exit; - } - - // - // If received unicast neighbor solicitation but destination is not this node, - // drop the packet. - // - if (IsUnicast && !IsMaintained) { - goto Exit; - } - - // - // In DAD, when target address is a tentative address, - // process the received neighbor solicitation message but not send out response. - // - if (IsDAD && !IsMaintained) { - DupAddrDetect = Ip6FindDADEntry (IpSb, &Target, &IpIf); - if (DupAddrDetect != NULL) { - // - // Check the MAC address of the incoming packet. - // - if (IpSb->RecvRequest.MnpToken.Packet.RxData == NULL) { - goto Exit; - } - - MacAddress = IpSb->RecvRequest.MnpToken.Packet.RxData->SourceAddress; - if (MacAddress != NULL) { - if (CompareMem ( - MacAddress, - &IpSb->SnpMode.CurrentAddress, - IpSb->SnpMode.HwAddressSize - ) != 0) { - // - // The NS is from another node to performing DAD on the same address. - // Fail DAD for the tentative address. - // - Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect); - Status = EFI_ICMP_ERROR; - } else { - // - // The below layer loopback the NS we sent. Record it and wait for more. - // - DupAddrDetect->Receive++; - Status = EFI_SUCCESS; - } - } - } - goto Exit; - } - - // - // If the solicitation does not contain a link-layer address, DO NOT create or - // update the neighbor cache entries. - // - if (Provided) { - Neighbor = Ip6FindNeighborEntry (IpSb, &Head->SourceAddress); - UpdateCache = FALSE; - - if (Neighbor == NULL) { - Neighbor = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, &Head->SourceAddress, NULL); - if (Neighbor == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - UpdateCache = TRUE; - } else { - if (CompareMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6) != 0) { - UpdateCache = TRUE; - } - } - - if (UpdateCache) { - Neighbor->State = EfiNeighborStale; - Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - CopyMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6); - // - // Send queued packets if exist. - // - Neighbor->CallBack ((VOID *) Neighbor); - } - } - - // - // Sends a Neighbor Advertisement as response. - // Set the Router flag to zero since the node is a host. - // If the source address of the solicitation is unspeicifed, and target address - // is one of the maintained address, reply a unsolicited multicast advertisement. - // - if (IsDAD && IsMaintained) { - Solicited = FALSE; - Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &Dest); - } else { - Solicited = TRUE; - IP6_COPY_ADDRESS (&Dest, &Head->SourceAddress); - } - - Status = Ip6SendNeighborAdvertise ( - IpSb, - &Target, - &Dest, - &Target, - &IpSb->SnpMode.CurrentAddress, - FALSE, - TRUE, - Solicited - ); -Exit: - NetbufFree (Packet); - return Status; -} - -/** - Process the Neighbor Advertisement message. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the message. - @param[in] Packet The content of the message with IP head removed. - - @retval EFI_SUCCESS The packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval EFI_ICMP_ERROR The packet indicates that DAD is failed. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessNeighborAdvertise ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_INFORMATION_HEAD Icmp; - EFI_IPv6_ADDRESS Target; - IP6_ETHER_ADDR_OPTION LinkLayerOption; - BOOLEAN Provided; - INTN Compare; - IP6_NEIGHBOR_ENTRY *Neighbor; - IP6_DEFAULT_ROUTER *DefaultRouter; - BOOLEAN Solicited; - BOOLEAN IsRouter; - BOOLEAN Override; - IP6_DAD_ENTRY *DupAddrDetect; - IP6_INTERFACE *IpIf; - UINT16 OptionLen; - UINT8 *Option; - EFI_STATUS Status; - - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - NetbufCopy (Packet, sizeof (Icmp), sizeof (Target), Target.Addr); - - // - // Validate the incoming Neighbor Advertisement - // - Status = EFI_INVALID_PARAMETER; - // - // The IP Hop Limit field has a value of 255, i.e., the packet - // could not possibly have been forwarded by a router. - // ICMP Code is 0. - // Target Address is not a multicast address. - // - if (Head->HopLimit != IP6_HOP_LIMIT || Icmp.Head.Code != 0 || !NetIp6IsValidUnicast (&Target)) { - goto Exit; - } - - // - // ICMP length is 24 or more octets. - // - Provided = FALSE; - OptionLen = 0; - if (Head->PayloadLength < IP6_ND_LENGTH) { - goto Exit; - } else { - OptionLen = (UINT16) (Head->PayloadLength - IP6_ND_LENGTH); - if (OptionLen != 0) { - Option = NetbufGetByte (Packet, IP6_ND_LENGTH, NULL); - ASSERT (Option != NULL); - - // - // All included options should have a length that is greater than zero. - // - if (!Ip6IsNDOptionValid (Option, OptionLen)) { - goto Exit; - } - } - } - - // - // If the IP destination address is a multicast address, Solicited Flag is ZERO. - // - Solicited = FALSE; - if ((Icmp.Fourth & IP6_SOLICITED_FLAG) == IP6_SOLICITED_FLAG) { - Solicited = TRUE; - } - if (IP6_IS_MULTICAST (&Head->DestinationAddress) && Solicited) { - goto Exit; - } - - // - // DAD - Check whether the Target is one of our tentative address. - // - DupAddrDetect = Ip6FindDADEntry (IpSb, &Target, &IpIf); - if (DupAddrDetect != NULL) { - // - // DAD fails, some other node is using this address. - // - NetbufFree (Packet); - Ip6OnDADFinished (FALSE, IpIf, DupAddrDetect); - return EFI_ICMP_ERROR; - } - - // - // Search the Neighbor Cache for the target's entry. If no entry exists, - // the advertisement should be silently discarded. - // - Neighbor = Ip6FindNeighborEntry (IpSb, &Target); - if (Neighbor == NULL) { - goto Exit; - } - - // - // Get IsRouter Flag and Override Flag - // - IsRouter = FALSE; - Override = FALSE; - if ((Icmp.Fourth & IP6_IS_ROUTER_FLAG) == IP6_IS_ROUTER_FLAG) { - IsRouter = TRUE; - } - if ((Icmp.Fourth & IP6_OVERRIDE_FLAG) == IP6_OVERRIDE_FLAG) { - Override = TRUE; - } - - // - // Check whether link layer option is included. - // - if (OptionLen >= sizeof (IP6_ETHER_ADDR_OPTION)) { - NetbufCopy ( - Packet, - IP6_ND_LENGTH, - sizeof (IP6_ETHER_ADDR_OPTION), - (UINT8 *) &LinkLayerOption - ); - - if (LinkLayerOption.Type == Ip6OptionEtherTarget) { - Provided = TRUE; - } - } - - Compare = 0; - if (Provided) { - Compare = CompareMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6); - } - - if (!Neighbor->IsRouter && IsRouter) { - DefaultRouter = Ip6FindDefaultRouter (IpSb, &Target); - if (DefaultRouter != NULL) { - DefaultRouter->NeighborCache = Neighbor; - } - } - - if (Neighbor->State == EfiNeighborInComplete) { - // - // If the target's Neighbor Cache entry is in INCOMPLETE state and no - // Target Link-Layer address option is included while link layer has - // address, the message should be silently discarded. - // - if (!Provided) { - goto Exit; - } - // - // Update the Neighbor Cache - // - CopyMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6); - if (Solicited) { - Neighbor->State = EfiNeighborReachable; - Neighbor->Ticks = IP6_GET_TICKS (IpSb->ReachableTime); - } else { - Neighbor->State = EfiNeighborStale; - Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - // - // Send any packets queued for the neighbor awaiting address resolution. - // - Neighbor->CallBack ((VOID *) Neighbor); - } - - Neighbor->IsRouter = IsRouter; - - } else { - if (!Override && Compare != 0) { - // - // When the Override Flag is clear and supplied link-layer address differs from - // that in the cache, if the state of the entry is not REACHABLE, ignore the - // message. Otherwise set it to STALE but do not update the entry in any - // other way. - // - if (Neighbor->State == EfiNeighborReachable) { - Neighbor->State = EfiNeighborStale; - Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - } - } else { - if (Compare != 0) { - CopyMem (Neighbor->LinkAddress.Addr, LinkLayerOption.EtherAddr, 6); - } - // - // Update the entry's state - // - if (Solicited) { - Neighbor->State = EfiNeighborReachable; - Neighbor->Ticks = IP6_GET_TICKS (IpSb->ReachableTime); - } else { - if (Compare != 0) { - Neighbor->State = EfiNeighborStale; - Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - } - } - - // - // When IsRouter is changed from TRUE to FALSE, remove the router from the - // Default Router List and remove the Destination Cache entries for all destinations - // using the neighbor as a router. - // - if (Neighbor->IsRouter && !IsRouter) { - DefaultRouter = Ip6FindDefaultRouter (IpSb, &Target); - if (DefaultRouter != NULL) { - Ip6DestroyDefaultRouter (IpSb, DefaultRouter); - } - } - - Neighbor->IsRouter = IsRouter; - } - } - - if (Neighbor->State == EfiNeighborReachable) { - Neighbor->CallBack ((VOID *) Neighbor); - } - - Status = EFI_SUCCESS; - -Exit: - NetbufFree (Packet); - return Status; -} - -/** - Process the Router Advertisement message according to RFC4861. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the message. - @param[in] Packet The content of the message with the IP head removed. - - @retval EFI_SUCCESS The packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the - operation. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessRouterAdvertise ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_INFORMATION_HEAD Icmp; - UINT32 ReachableTime; - UINT32 RetransTimer; - UINT16 RouterLifetime; - UINT16 Offset; - UINT8 Type; - UINT8 Length; - IP6_ETHER_ADDR_OPTION LinkLayerOption; - UINT32 Fourth; - UINT8 CurHopLimit; - BOOLEAN Mflag; - BOOLEAN Oflag; - IP6_DEFAULT_ROUTER *DefaultRouter; - IP6_NEIGHBOR_ENTRY *NeighborCache; - EFI_MAC_ADDRESS LinkLayerAddress; - IP6_MTU_OPTION MTUOption; - IP6_PREFIX_INFO_OPTION PrefixOption; - IP6_PREFIX_LIST_ENTRY *PrefixList; - BOOLEAN OnLink; - BOOLEAN Autonomous; - EFI_IPv6_ADDRESS StatelessAddress; - EFI_STATUS Status; - UINT16 OptionLen; - UINT8 *Option; - INTN Result; - - Status = EFI_INVALID_PARAMETER; - - if (IpSb->Ip6ConfigInstance.Policy != Ip6ConfigPolicyAutomatic) { - // - // Skip the process below as it's not required under the current policy. - // - goto Exit; - } - - NetbufCopy (Packet, 0, sizeof (Icmp), (UINT8 *) &Icmp); - - // - // Validate the incoming Router Advertisement - // - - // - // The IP source address must be a link-local address - // - if (!NetIp6IsLinkLocalAddr (&Head->SourceAddress)) { - goto Exit; - } - // - // The IP Hop Limit field has a value of 255, i.e. the packet - // could not possibly have been forwarded by a router. - // ICMP Code is 0. - // ICMP length (derived from the IP length) is 16 or more octets. - // - if (Head->HopLimit != IP6_HOP_LIMIT || Icmp.Head.Code != 0 || - Head->PayloadLength < IP6_RA_LENGTH) { - goto Exit; - } - - // - // All included options have a length that is greater than zero. - // - OptionLen = (UINT16) (Head->PayloadLength - IP6_RA_LENGTH); - if (OptionLen != 0) { - Option = NetbufGetByte (Packet, IP6_RA_LENGTH, NULL); - ASSERT (Option != NULL); - - if (!Ip6IsNDOptionValid (Option, OptionLen)) { - goto Exit; - } - } - - // - // Process Fourth field. - // In Router Advertisement, Fourth is composed of CurHopLimit (8bit), M flag, O flag, - // and Router Lifetime (16 bit). - // - - Fourth = NTOHL (Icmp.Fourth); - CopyMem (&RouterLifetime, &Fourth, sizeof (UINT16)); - - // - // If the source address already in the default router list, update it. - // Otherwise create a new entry. - // A Lifetime of zero indicates that the router is not a default router. - // - DefaultRouter = Ip6FindDefaultRouter (IpSb, &Head->SourceAddress); - if (DefaultRouter == NULL) { - if (RouterLifetime != 0) { - DefaultRouter = Ip6CreateDefaultRouter (IpSb, &Head->SourceAddress, RouterLifetime); - if (DefaultRouter == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - } - } else { - if (RouterLifetime != 0) { - DefaultRouter->Lifetime = RouterLifetime; - // - // Check the corresponding neighbor cache entry here. - // - if (DefaultRouter->NeighborCache == NULL) { - DefaultRouter->NeighborCache = Ip6FindNeighborEntry (IpSb, &Head->SourceAddress); - } - } else { - // - // If the address is in the host's default router list and the router lifetime is zero, - // immediately time-out the entry. - // - Ip6DestroyDefaultRouter (IpSb, DefaultRouter); - } - } - - CurHopLimit = *((UINT8 *) &Fourth + 3); - if (CurHopLimit != 0) { - IpSb->CurHopLimit = CurHopLimit; - } - - Mflag = FALSE; - Oflag = FALSE; - if ((*((UINT8 *) &Fourth + 2) & IP6_M_ADDR_CONFIG_FLAG) == IP6_M_ADDR_CONFIG_FLAG) { - Mflag = TRUE; - } else { - if ((*((UINT8 *) &Fourth + 2) & IP6_O_CONFIG_FLAG) == IP6_O_CONFIG_FLAG) { - Oflag = TRUE; - } - } - - if (Mflag || Oflag) { - // - // Use Ip6Config to get available addresses or other configuration from DHCP. - // - Ip6ConfigStartStatefulAutoConfig (&IpSb->Ip6ConfigInstance, Oflag); - } - - // - // Process Reachable Time and Retrans Timer fields. - // - NetbufCopy (Packet, sizeof (Icmp), sizeof (UINT32), (UINT8 *) &ReachableTime); - NetbufCopy (Packet, sizeof (Icmp) + sizeof (UINT32), sizeof (UINT32), (UINT8 *) &RetransTimer); - ReachableTime = NTOHL (ReachableTime); - RetransTimer = NTOHL (RetransTimer); - - if (ReachableTime != 0 && ReachableTime != IpSb->BaseReachableTime) { - // - // If new value is not unspecified and differs from the previous one, record it - // in BaseReachableTime and recompute a ReachableTime. - // - IpSb->BaseReachableTime = ReachableTime; - Ip6UpdateReachableTime (IpSb); - } - - if (RetransTimer != 0) { - IpSb->RetransTimer = RetransTimer; - } - - // - // IsRouter flag must be set to TRUE if corresponding neighbor cache entry exists. - // - NeighborCache = Ip6FindNeighborEntry (IpSb, &Head->SourceAddress); - if (NeighborCache != NULL) { - NeighborCache->IsRouter = TRUE; - } - - // - // If an valid router advertisment is received, stops router solicitation. - // - IpSb->RouterAdvertiseReceived = TRUE; - - // - // The only defined options that may appear are the Source - // Link-Layer Address, Prefix information and MTU options. - // All included options have a length that is greater than zero. - // - Offset = 16; - while (Offset < Head->PayloadLength) { - NetbufCopy (Packet, Offset, sizeof (UINT8), &Type); - switch (Type) { - case Ip6OptionEtherSource: - // - // Update the neighbor cache - // - NetbufCopy (Packet, Offset, sizeof (IP6_ETHER_ADDR_OPTION), (UINT8 *) &LinkLayerOption); - if (LinkLayerOption.Length <= 0) { - goto Exit; - } - - ZeroMem (&LinkLayerAddress, sizeof (EFI_MAC_ADDRESS)); - CopyMem (&LinkLayerAddress, LinkLayerOption.EtherAddr, 6); - - if (NeighborCache == NULL) { - NeighborCache = Ip6CreateNeighborEntry ( - IpSb, - Ip6OnArpResolved, - &Head->SourceAddress, - &LinkLayerAddress - ); - if (NeighborCache == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - NeighborCache->IsRouter = TRUE; - NeighborCache->State = EfiNeighborStale; - NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - } else { - Result = CompareMem (&LinkLayerAddress, &NeighborCache->LinkAddress, 6); - - // - // If the link-local address is the same as that already in the cache, - // the cache entry's state remains unchanged. Otherwise update the - // reachability state to STALE. - // - if ((NeighborCache->State == EfiNeighborInComplete) || (Result != 0)) { - CopyMem (&NeighborCache->LinkAddress, &LinkLayerAddress, 6); - - NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - - if (NeighborCache->State == EfiNeighborInComplete) { - // - // Send queued packets if exist. - // - NeighborCache->State = EfiNeighborStale; - NeighborCache->CallBack ((VOID *) NeighborCache); - } else { - NeighborCache->State = EfiNeighborStale; - } - } - } - - Offset = (UINT16) (Offset + (UINT16) LinkLayerOption.Length * 8); - break; - case Ip6OptionPrefixInfo: - NetbufCopy (Packet, Offset, sizeof (IP6_PREFIX_INFO_OPTION), (UINT8 *) &PrefixOption); - if (PrefixOption.Length != 4) { - goto Exit; - } - PrefixOption.ValidLifetime = NTOHL (PrefixOption.ValidLifetime); - PrefixOption.PreferredLifetime = NTOHL (PrefixOption.PreferredLifetime); - - // - // Get L and A flag, recorded in the lower 2 bits of Reserved1 - // - OnLink = FALSE; - if ((PrefixOption.Reserved1 & IP6_ON_LINK_FLAG) == IP6_ON_LINK_FLAG) { - OnLink = TRUE; - } - Autonomous = FALSE; - if ((PrefixOption.Reserved1 & IP6_AUTO_CONFIG_FLAG) == IP6_AUTO_CONFIG_FLAG) { - Autonomous = TRUE; - } - - // - // If the prefix is the link-local prefix, silently ignore the prefix option. - // - if (PrefixOption.PrefixLength == IP6_LINK_LOCAL_PREFIX_LENGTH && - NetIp6IsLinkLocalAddr (&PrefixOption.Prefix) - ) { - Offset += sizeof (IP6_PREFIX_INFO_OPTION); - break; - } - // - // Do following if on-link flag is set according to RFC4861. - // - if (OnLink) { - PrefixList = Ip6FindPrefixListEntry ( - IpSb, - TRUE, - PrefixOption.PrefixLength, - &PrefixOption.Prefix - ); - // - // Create a new entry for the prefix, if the ValidLifetime is zero, - // silently ignore the prefix option. - // - if (PrefixList == NULL && PrefixOption.ValidLifetime != 0) { - PrefixList = Ip6CreatePrefixListEntry ( - IpSb, - TRUE, - PrefixOption.ValidLifetime, - PrefixOption.PreferredLifetime, - PrefixOption.PrefixLength, - &PrefixOption.Prefix - ); - if (PrefixList == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - } else if (PrefixList != NULL) { - if (PrefixOption.ValidLifetime != 0) { - PrefixList->ValidLifetime = PrefixOption.ValidLifetime; - } else { - // - // If the prefix exists and incoming ValidLifetime is zero, immediately - // remove the prefix. - Ip6DestroyPrefixListEntry (IpSb, PrefixList, OnLink, TRUE); - } - } - } - - // - // Do following if Autonomous flag is set according to RFC4862. - // - if (Autonomous && PrefixOption.PreferredLifetime <= PrefixOption.ValidLifetime) { - PrefixList = Ip6FindPrefixListEntry ( - IpSb, - FALSE, - PrefixOption.PrefixLength, - &PrefixOption.Prefix - ); - // - // Create a new entry for the prefix, and form an address by prefix + interface id - // If the sum of the prefix length and interface identifier length - // does not equal 128 bits, the Prefix Information option MUST be ignored. - // - if (PrefixList == NULL && - PrefixOption.ValidLifetime != 0 && - PrefixOption.PrefixLength + IpSb->InterfaceIdLen * 8 == 128 - ) { - // - // Form the address in network order. - // - CopyMem (&StatelessAddress, &PrefixOption.Prefix, sizeof (UINT64)); - CopyMem (&StatelessAddress.Addr[8], IpSb->InterfaceId, sizeof (UINT64)); - - // - // If the address is not yet in the assigned address list, adds it into. - // - if (!Ip6IsOneOfSetAddress (IpSb, &StatelessAddress, NULL, NULL)) { - // - // And also not in the DAD process, check its uniqeness firstly. - // - if (Ip6FindDADEntry (IpSb, &StatelessAddress, NULL) == NULL) { - Status = Ip6SetAddress ( - IpSb->DefaultInterface, - &StatelessAddress, - FALSE, - PrefixOption.PrefixLength, - PrefixOption.ValidLifetime, - PrefixOption.PreferredLifetime, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - goto Exit; - } - } - } - - // - // Adds the prefix option to stateless prefix option list. - // - PrefixList = Ip6CreatePrefixListEntry ( - IpSb, - FALSE, - PrefixOption.ValidLifetime, - PrefixOption.PreferredLifetime, - PrefixOption.PrefixLength, - &PrefixOption.Prefix - ); - if (PrefixList == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - } else if (PrefixList != NULL) { - - // - // Reset the preferred lifetime of the address if the advertised prefix exists. - // Perform specific action to valid lifetime together. - // - PrefixList->PreferredLifetime = PrefixOption.PreferredLifetime; - if ((PrefixOption.ValidLifetime > 7200) || - (PrefixOption.ValidLifetime > PrefixList->ValidLifetime)) { - // - // If the received Valid Lifetime is greater than 2 hours or - // greater than RemainingLifetime, set the valid lifetime of the - // corresponding address to the advertised Valid Lifetime. - // - PrefixList->ValidLifetime = PrefixOption.ValidLifetime; - - } else if (PrefixList->ValidLifetime <= 7200) { - // - // If RemainingLifetime is less than or equls to 2 hours, ignore the - // Prefix Information option with regards to the valid lifetime. - // TODO: If this option has been authenticated, set the valid lifetime. - // - } else { - // - // Otherwise, reset the valid lifetime of the corresponding - // address to 2 hours. - // - PrefixList->ValidLifetime = 7200; - } - } - } - - Offset += sizeof (IP6_PREFIX_INFO_OPTION); - break; - case Ip6OptionMtu: - NetbufCopy (Packet, Offset, sizeof (IP6_MTU_OPTION), (UINT8 *) &MTUOption); - if (MTUOption.Length != 1) { - goto Exit; - } - - // - // Use IPv6 minimum link MTU 1280 bytes as the maximum packet size in order - // to omit implementation of Path MTU Discovery. Thus ignore the MTU option - // in Router Advertisement. - // - - Offset += sizeof (IP6_MTU_OPTION); - break; - default: - // - // Silently ignore unrecognized options - // - NetbufCopy (Packet, Offset + sizeof (UINT8), sizeof (UINT8), &Length); - if (Length <= 0) { - goto Exit; - } - - Offset = (UINT16) (Offset + (UINT16) Length * 8); - break; - } - } - - Status = EFI_SUCCESS; - -Exit: - NetbufFree (Packet); - return Status; -} - -/** - Process the ICMPv6 redirect message. Find the instance, then update - its route cache. - - @param[in] IpSb The IP6 service binding instance that received - the packet. - @param[in] Head The IP head of the received ICMPv6 packet. - @param[in] Packet The content of the ICMPv6 redirect packet with - the IP head removed. - - @retval EFI_INVALID_PARAMETER The parameter is invalid. - @retval EFI_OUT_OF_RESOURCES Insuffcient resources to complete the - operation. - @retval EFI_SUCCESS Successfully updated the route caches. - -**/ -EFI_STATUS -Ip6ProcessRedirect ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ) -{ - IP6_ICMP_INFORMATION_HEAD *Icmp; - EFI_IPv6_ADDRESS *Target; - EFI_IPv6_ADDRESS *IcmpDest; - UINT8 *Option; - UINT16 OptionLen; - IP6_ROUTE_ENTRY *RouteEntry; - IP6_ROUTE_CACHE_ENTRY *RouteCache; - IP6_NEIGHBOR_ENTRY *NeighborCache; - INT32 Length; - UINT8 OptLen; - IP6_ETHER_ADDR_OPTION *LinkLayerOption; - EFI_MAC_ADDRESS Mac; - UINT32 Index; - BOOLEAN IsRouter; - EFI_STATUS Status; - INTN Result; - - Status = EFI_INVALID_PARAMETER; - - Icmp = (IP6_ICMP_INFORMATION_HEAD *) NetbufGetByte (Packet, 0, NULL); - if (Icmp == NULL) { - goto Exit; - } - - // - // Validate the incoming Redirect message - // - - // - // The IP Hop Limit field has a value of 255, i.e. the packet - // could not possibly have been forwarded by a router. - // ICMP Code is 0. - // ICMP length (derived from the IP length) is 40 or more octets. - // - if (Head->HopLimit != IP6_HOP_LIMIT || Icmp->Head.Code != 0 || - Head->PayloadLength < IP6_REDITECT_LENGTH) { - goto Exit; - } - - // - // The IP source address must be a link-local address - // - if (!NetIp6IsLinkLocalAddr (&Head->SourceAddress)) { - goto Exit; - } - - // - // The dest of this ICMP redirect message is not us. - // - if (!Ip6IsOneOfSetAddress (IpSb, &Head->DestinationAddress, NULL, NULL)) { - goto Exit; - } - - // - // All included options have a length that is greater than zero. - // - OptionLen = (UINT16) (Head->PayloadLength - IP6_REDITECT_LENGTH); - if (OptionLen != 0) { - Option = NetbufGetByte (Packet, IP6_REDITECT_LENGTH, NULL); - ASSERT (Option != NULL); - - if (!Ip6IsNDOptionValid (Option, OptionLen)) { - goto Exit; - } - } - - Target = (EFI_IPv6_ADDRESS *) (Icmp + 1); - IcmpDest = Target + 1; - - // - // The ICMP Destination Address field in the redirect message does not contain - // a multicast address. - // - if (IP6_IS_MULTICAST (IcmpDest)) { - goto Exit; - } - - // - // The ICMP Target Address is either a link-local address (when redirected to - // a router) or the same as the ICMP Destination Address (when redirected to - // the on-link destination). - // - IsRouter = (BOOLEAN) !EFI_IP6_EQUAL (Target, IcmpDest); - if (!NetIp6IsLinkLocalAddr (Target) && IsRouter) { - goto Exit; - } - - // - // Check the options. The only interested option here is the target-link layer - // address option. - // - Length = Packet->TotalSize - 40; - Option = (UINT8 *) (IcmpDest + 1); - LinkLayerOption = NULL; - while (Length > 0) { - switch (*Option) { - case Ip6OptionEtherTarget: - - LinkLayerOption = (IP6_ETHER_ADDR_OPTION *) Option; - OptLen = LinkLayerOption->Length; - if (OptLen != 1) { - // - // For ethernet, the length must be 1. - // - goto Exit; - } - break; - - default: - - OptLen = *(Option + 1); - if (OptLen == 0) { - // - // A length of 0 is invalid. - // - goto Exit; - } - break; - } - - Length -= 8 * OptLen; - Option += 8 * OptLen; - } - - if (Length != 0) { - goto Exit; - } - - // - // The IP source address of the Redirect is the same as the current - // first-hop router for the specified ICMP Destination Address. - // - RouteCache = Ip6FindRouteCache (IpSb->RouteTable, IcmpDest, &Head->DestinationAddress); - if (RouteCache != NULL) { - if (!EFI_IP6_EQUAL (&RouteCache->NextHop, &Head->SourceAddress)) { - // - // The source of this Redirect message must match the NextHop of the - // corresponding route cache entry. - // - goto Exit; - } - - // - // Update the NextHop. - // - IP6_COPY_ADDRESS (&RouteCache->NextHop, Target); - - if (!IsRouter) { - RouteEntry = (IP6_ROUTE_ENTRY *) RouteCache->Tag; - RouteEntry->Flag = RouteEntry->Flag | IP6_DIRECT_ROUTE; - } - - } else { - // - // Get the Route Entry. - // - RouteEntry = Ip6FindRouteEntry (IpSb->RouteTable, IcmpDest, NULL); - if (RouteEntry == NULL) { - RouteEntry = Ip6CreateRouteEntry (IcmpDest, 0, NULL); - if (RouteEntry == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - } - - if (!IsRouter) { - RouteEntry->Flag = IP6_DIRECT_ROUTE; - } - - // - // Create a route cache for this. - // - RouteCache = Ip6CreateRouteCacheEntry ( - IcmpDest, - &Head->DestinationAddress, - Target, - (UINTN) RouteEntry - ); - if (RouteCache == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Exit; - } - - // - // Insert the newly created route cache entry. - // - Index = IP6_ROUTE_CACHE_HASH (IcmpDest, &Head->DestinationAddress); - InsertHeadList (&IpSb->RouteTable->Cache.CacheBucket[Index], &RouteCache->Link); - } - - // - // Try to locate the neighbor cache for the Target. - // - NeighborCache = Ip6FindNeighborEntry (IpSb, Target); - - if (LinkLayerOption != NULL) { - if (NeighborCache == NULL) { - // - // Create a neighbor cache for the Target. - // - ZeroMem (&Mac, sizeof (EFI_MAC_ADDRESS)); - CopyMem (&Mac, LinkLayerOption->EtherAddr, 6); - NeighborCache = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, Target, &Mac); - if (NeighborCache == NULL) { - // - // Just report a success here. The neighbor cache can be created in - // some other place. - // - Status = EFI_SUCCESS; - goto Exit; - } - - NeighborCache->State = EfiNeighborStale; - NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - } else { - Result = CompareMem (LinkLayerOption->EtherAddr, &NeighborCache->LinkAddress, 6); - - // - // If the link-local address is the same as that already in the cache, - // the cache entry's state remains unchanged. Otherwise update the - // reachability state to STALE. - // - if ((NeighborCache->State == EfiNeighborInComplete) || (Result != 0)) { - CopyMem (&NeighborCache->LinkAddress, LinkLayerOption->EtherAddr, 6); - - NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - - if (NeighborCache->State == EfiNeighborInComplete) { - // - // Send queued packets if exist. - // - NeighborCache->State = EfiNeighborStale; - NeighborCache->CallBack ((VOID *) NeighborCache); - } else { - NeighborCache->State = EfiNeighborStale; - } - } - } - } - - if (NeighborCache != NULL && IsRouter) { - // - // The Target is a router, set IsRouter to TRUE. - // - NeighborCache->IsRouter = TRUE; - } - - Status = EFI_SUCCESS; - -Exit: - NetbufFree (Packet); - return Status; -} - -/** - Add Neighbor cache entries. It is a work function for EfiIp6Neighbors(). - - @param[in] IpSb The IP6 service binding instance. - @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, and if a - corresponding cache entry already existed, EFI_ACCESS_DENIED - will be returned. - - @retval EFI_SUCCESS The neighbor cache entry has been added. - @retval EFI_OUT_OF_RESOURCES Could not add the entry to the neighbor cache - due to insufficient resources. - @retval EFI_NOT_FOUND 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). - -**/ -EFI_STATUS -Ip6AddNeighbor ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, - IN UINT32 Timeout, - IN BOOLEAN Override - ) -{ - IP6_NEIGHBOR_ENTRY *Neighbor; - - Neighbor = Ip6FindNeighborEntry (IpSb, TargetIp6Address); - if (Neighbor != NULL) { - if (!Override) { - return EFI_ACCESS_DENIED; - } else { - if (TargetLinkAddress != NULL) { - IP6_COPY_LINK_ADDRESS (&Neighbor->LinkAddress, TargetLinkAddress); - } - } - } else { - if (TargetLinkAddress == NULL) { - return EFI_NOT_FOUND; - } - - Neighbor = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, TargetIp6Address, TargetLinkAddress); - if (Neighbor == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - Neighbor->State = EfiNeighborReachable; - - if (Timeout != 0) { - Neighbor->Ticks = IP6_GET_TICKS (Timeout / TICKS_PER_MS); - Neighbor->Dynamic = TRUE; - } else { - Neighbor->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - } - - return EFI_SUCCESS; -} - -/** - Delete or update Neighbor cache entries. It is a work function for EfiIp6Neighbors(). - - @param[in] IpSb The IP6 service binding instance. - @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, and if a - corresponding cache entry already existed, EFI_ACCESS_DENIED - will be returned. - - @retval EFI_SUCCESS The neighbor cache entry has been updated or deleted. - @retval EFI_NOT_FOUND This entry is not in the neighbor cache. - -**/ -EFI_STATUS -Ip6DelNeighbor ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, - IN UINT32 Timeout, - IN BOOLEAN Override - ) -{ - IP6_NEIGHBOR_ENTRY *Neighbor; - - Neighbor = Ip6FindNeighborEntry (IpSb, TargetIp6Address); - if (Neighbor == NULL) { - return EFI_NOT_FOUND; - } - - RemoveEntryList (&Neighbor->Link); - FreePool (Neighbor); - - return EFI_SUCCESS; -} - -/** - The heartbeat timer of ND module in IP6_TIMER_INTERVAL_IN_MS milliseconds. - This time routine handles DAD module and neighbor state transition. - It is also responsible for sending out router solicitations. - - @param[in] Event The IP6 service instance's heartbeat timer. - @param[in] Context The IP6 service instance. - -**/ -VOID -EFIAPI -Ip6NdFasterTimerTicking ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - LIST_ENTRY *Entry2; - IP6_INTERFACE *IpIf; - IP6_DELAY_JOIN_LIST *DelayNode; - EFI_IPv6_ADDRESS Source; - IP6_DAD_ENTRY *DupAddrDetect; - EFI_STATUS Status; - IP6_NEIGHBOR_ENTRY *NeighborCache; - EFI_IPv6_ADDRESS Destination; - IP6_SERVICE *IpSb; - BOOLEAN Flag; - - IpSb = (IP6_SERVICE *) Context; - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - ZeroMem (&Source, sizeof (EFI_IPv6_ADDRESS)); - - // - // A host SHOULD transmit up to MAX_RTR_SOLICITATIONS (3) Router - // Solicitation messages, each separated by at least - // RTR_SOLICITATION_INTERVAL (4) seconds. - // - if ((IpSb->Ip6ConfigInstance.Policy == Ip6ConfigPolicyAutomatic) && - !IpSb->RouterAdvertiseReceived && - IpSb->SolicitTimer > 0 - ) { - if ((IpSb->Ticks == 0) || (--IpSb->Ticks == 0)) { - Status = Ip6SendRouterSolicit (IpSb, NULL, NULL, NULL, NULL); - if (!EFI_ERROR (Status)) { - IpSb->SolicitTimer--; - IpSb->Ticks = (UINT32) IP6_GET_TICKS (IP6_RTR_SOLICITATION_INTERVAL); - } - } - } - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link); - - // - // Process the delay list to join the solicited-node multicast address. - // - NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DelayJoinList) { - DelayNode = NET_LIST_USER_STRUCT (Entry2, IP6_DELAY_JOIN_LIST, Link); - if ((DelayNode->DelayTime == 0) || (--DelayNode->DelayTime == 0)) { - // - // The timer expires, init the duplicate address detection. - // - Ip6InitDADProcess ( - DelayNode->Interface, - DelayNode->AddressInfo, - DelayNode->DadCallback, - DelayNode->Context - ); - - // - // Remove the delay node - // - RemoveEntryList (&DelayNode->Link); - FreePool (DelayNode); - } - } - - // - // Process the duplicate address detection list. - // - NET_LIST_FOR_EACH_SAFE (Entry2, Next, &IpIf->DupAddrDetectList) { - DupAddrDetect = NET_LIST_USER_STRUCT (Entry2, IP6_DAD_ENTRY, Link); - - if ((DupAddrDetect->RetransTick == 0) || (--DupAddrDetect->RetransTick == 0)) { - // - // The timer expires, check the remaining transmit counts. - // - if (DupAddrDetect->Transmit < DupAddrDetect->MaxTransmit) { - // - // Send the Neighbor Solicitation message with - // Source - unspecified address, destination - solicited-node multicast address - // Target - the address to be validated - // - Status = Ip6SendNeighborSolicit ( - IpSb, - NULL, - &DupAddrDetect->Destination, - &DupAddrDetect->AddressInfo->Address, - NULL - ); - if (EFI_ERROR (Status)) { - return; - } - - DupAddrDetect->Transmit++; - DupAddrDetect->RetransTick = IP6_GET_TICKS (IpSb->RetransTimer); - } else { - // - // All required solicitation has been sent out, and the RetransTime after the last - // Neighbor Solicit is elapsed, finish the DAD process. - // - Flag = FALSE; - if ((DupAddrDetect->Receive == 0) || - (DupAddrDetect->Transmit <= DupAddrDetect->Receive)) { - Flag = TRUE; - } - - Ip6OnDADFinished (Flag, IpIf, DupAddrDetect); - } - } - } - } - - // - // Polling the state of Neighbor cache - // - NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->NeighborTable) { - NeighborCache = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, Link); - - switch (NeighborCache->State) { - case EfiNeighborInComplete: - if (NeighborCache->Ticks > 0) { - --NeighborCache->Ticks; - } - - // - // Retransmit Neighbor Solicitation messages approximately every - // RetransTimer milliseconds while awaiting a response. - // - if (NeighborCache->Ticks == 0) { - if (NeighborCache->Transmit > 1) { - // - // Send out multicast neighbor solicitation for address resolution. - // After last neighbor solicitation message has been sent out, wait - // for RetransTimer and then remove entry if no response is received. - // - Ip6CreateSNMulticastAddr (&NeighborCache->Neighbor, &Destination); - Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source); - if (EFI_ERROR (Status)) { - return; - } - - Status = Ip6SendNeighborSolicit ( - IpSb, - &Source, - &Destination, - &NeighborCache->Neighbor, - &IpSb->SnpMode.CurrentAddress - ); - if (EFI_ERROR (Status)) { - return; - } - } - - // - // Update the retransmit times. - // - if (NeighborCache->Transmit > 0) { - --NeighborCache->Transmit; - NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer); - } - } - - if (NeighborCache->Transmit == 0) { - // - // Timeout, send ICMP destination unreachable packet and then remove entry - // - Status = Ip6FreeNeighborEntry ( - IpSb, - NeighborCache, - TRUE, - TRUE, - EFI_ICMP_ERROR, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - return; - } - } - - break; - - case EfiNeighborReachable: - // - // This entry is inserted by EfiIp6Neighbors() as static entry - // and will not timeout. - // - if (!NeighborCache->Dynamic && (NeighborCache->Ticks == IP6_INFINIT_LIFETIME)) { - break; - } - - if ((NeighborCache->Ticks == 0) || (--NeighborCache->Ticks == 0)) { - if (NeighborCache->Dynamic) { - // - // This entry is inserted by EfiIp6Neighbors() as dynamic entry - // and will be deleted after timeout. - // - Status = Ip6FreeNeighborEntry ( - IpSb, - NeighborCache, - FALSE, - TRUE, - EFI_TIMEOUT, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - return; - } - } else { - NeighborCache->State = EfiNeighborStale; - NeighborCache->Ticks = (UINT32) IP6_INFINIT_LIFETIME; - } - } - - break; - - case EfiNeighborDelay: - if ((NeighborCache->Ticks == 0) || (--NeighborCache->Ticks == 0)) { - - NeighborCache->State = EfiNeighborProbe; - NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer); - NeighborCache->Transmit = IP6_MAX_UNICAST_SOLICIT + 1; - // - // Send out unicast neighbor solicitation for Neighbor Unreachability Detection - // - Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source); - if (EFI_ERROR (Status)) { - return; - } - - Status = Ip6SendNeighborSolicit ( - IpSb, - &Source, - &NeighborCache->Neighbor, - &NeighborCache->Neighbor, - &IpSb->SnpMode.CurrentAddress - ); - if (EFI_ERROR (Status)) { - return; - } - - NeighborCache->Transmit--; - } - - break; - - case EfiNeighborProbe: - if (NeighborCache->Ticks > 0) { - --NeighborCache->Ticks; - } - - // - // Retransmit Neighbor Solicitation messages approximately every - // RetransTimer milliseconds while awaiting a response. - // - if (NeighborCache->Ticks == 0) { - if (NeighborCache->Transmit > 1) { - // - // Send out unicast neighbor solicitation for Neighbor Unreachability - // Detection. After last neighbor solicitation message has been sent out, - // wait for RetransTimer and then remove entry if no response is received. - // - Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source); - if (EFI_ERROR (Status)) { - return; - } - - Status = Ip6SendNeighborSolicit ( - IpSb, - &Source, - &NeighborCache->Neighbor, - &NeighborCache->Neighbor, - &IpSb->SnpMode.CurrentAddress - ); - if (EFI_ERROR (Status)) { - return; - } - } - - // - // Update the retransmit times. - // - if (NeighborCache->Transmit > 0) { - --NeighborCache->Transmit; - NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer); - } - } - - if (NeighborCache->Transmit == 0) { - // - // Delete the neighbor entry. - // - Status = Ip6FreeNeighborEntry ( - IpSb, - NeighborCache, - FALSE, - TRUE, - EFI_TIMEOUT, - NULL, - NULL - ); - if (EFI_ERROR (Status)) { - return; - } - } - - break; - - default: - break; - } - } -} - -/** - The heartbeat timer of ND module in 1 second. This time routine handles following - things: 1) maitain default router list; 2) maintain prefix options; - 3) maintain route caches. - - @param[in] IpSb The IP6 service binding instance. - -**/ -VOID -Ip6NdTimerTicking ( - IN IP6_SERVICE *IpSb - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_DEFAULT_ROUTER *DefaultRouter; - IP6_PREFIX_LIST_ENTRY *PrefixOption; - UINT8 Index; - IP6_ROUTE_CACHE_ENTRY *RouteCache; - - // - // Decrease the lifetime of default router, if expires remove it from default router list. - // - NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->DefaultRouterList) { - DefaultRouter = NET_LIST_USER_STRUCT (Entry, IP6_DEFAULT_ROUTER, Link); - if (DefaultRouter->Lifetime != IP6_INF_ROUTER_LIFETIME) { - if ((DefaultRouter->Lifetime == 0) || (--DefaultRouter->Lifetime == 0)) { - Ip6DestroyDefaultRouter (IpSb, DefaultRouter); - } - } - } - - // - // Decrease Valid lifetime and Preferred lifetime of Prefix options and corresponding addresses. - // - NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->AutonomousPrefix) { - PrefixOption = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link); - if (PrefixOption->ValidLifetime != (UINT32) IP6_INFINIT_LIFETIME) { - if ((PrefixOption->ValidLifetime > 0) && (--PrefixOption->ValidLifetime > 0)) { - if ((PrefixOption->PreferredLifetime != (UINT32) IP6_INFINIT_LIFETIME) && - (PrefixOption->PreferredLifetime > 0) - ) { - --PrefixOption->PreferredLifetime; - } - } else { - Ip6DestroyPrefixListEntry (IpSb, PrefixOption, FALSE, TRUE); - } - } - } - - NET_LIST_FOR_EACH_SAFE (Entry, Next, &IpSb->OnlinkPrefix) { - PrefixOption = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link); - if (PrefixOption->ValidLifetime != (UINT32) IP6_INFINIT_LIFETIME) { - if ((PrefixOption->ValidLifetime == 0) || (--PrefixOption->ValidLifetime == 0)) { - Ip6DestroyPrefixListEntry (IpSb, PrefixOption, TRUE, TRUE); - } - } - } - - // - // Each bucket of route cache can contain at most IP6_ROUTE_CACHE_MAX entries. - // Remove the entries at the tail of the bucket. These entries - // are likely to be used least. - // Reclaim frequency is set to 1 second. - // - for (Index = 0; Index < IP6_ROUTE_CACHE_HASH_SIZE; Index++) { - while (IpSb->RouteTable->Cache.CacheNum[Index] > IP6_ROUTE_CACHE_MAX) { - Entry = NetListRemoveTail (&IpSb->RouteTable->Cache.CacheBucket[Index]); - if (Entry == NULL) { - break; - } - - RouteCache = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_CACHE_ENTRY, Link); - Ip6FreeRouteCacheEntry (RouteCache); - ASSERT (IpSb->RouteTable->Cache.CacheNum[Index] > 0); - IpSb->RouteTable->Cache.CacheNum[Index]--; - } - } -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Nd.h b/Core/NetworkPkg/Ip6Dxe/Ip6Nd.h deleted file mode 100644 index 982203ca5f..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Nd.h +++ /dev/null @@ -1,749 +0,0 @@ -/** @file - Definition of Neighbor Discovery support routines. - - Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_ND_H__ -#define __EFI_IP6_ND_H__ - -#define IP6_GET_TICKS(Ms) (((Ms) + IP6_TIMER_INTERVAL_IN_MS - 1) / IP6_TIMER_INTERVAL_IN_MS) - -enum { - IP6_INF_ROUTER_LIFETIME = 0xFFFF, - - IP6_MAX_RTR_SOLICITATION_DELAY = 1000, ///< 1000 milliseconds - IP6_MAX_RTR_SOLICITATIONS = 3, - IP6_RTR_SOLICITATION_INTERVAL = 4000, - - IP6_MIN_RANDOM_FACTOR_SCALED = 1, - IP6_MAX_RANDOM_FACTOR_SCALED = 3, - IP6_RANDOM_FACTOR_SCALE = 2, - - IP6_MAX_MULTICAST_SOLICIT = 3, - IP6_MAX_UNICAST_SOLICIT = 3, - IP6_MAX_ANYCAST_DELAY_TIME = 1, - IP6_MAX_NEIGHBOR_ADV = 3, - IP6_REACHABLE_TIME = 30000, - IP6_RETRANS_TIMER = 1000, - IP6_DELAY_FIRST_PROBE_TIME = 5000, - - IP6_MIN_LINK_MTU = 1280, - IP6_MAX_LINK_MTU = 1500, - - IP6_IS_ROUTER_FLAG = 0x80, - IP6_SOLICITED_FLAG = 0x40, - IP6_OVERRIDE_FLAG = 0x20, - - IP6_M_ADDR_CONFIG_FLAG = 0x80, - IP6_O_CONFIG_FLAG = 0x40, - - IP6_ON_LINK_FLAG = 0x80, - IP6_AUTO_CONFIG_FLAG = 0x40, - - IP6_ND_LENGTH = 24, - IP6_RA_LENGTH = 16, - IP6_REDITECT_LENGTH = 40, - IP6_DAD_ENTRY_SIGNATURE = SIGNATURE_32 ('I', 'P', 'D', 'E') -}; - -typedef -VOID -(*IP6_ARP_CALLBACK) ( - VOID *Context - ); - -typedef struct _IP6_ETHE_ADDR_OPTION { - UINT8 Type; - UINT8 Length; - UINT8 EtherAddr[6]; -} IP6_ETHER_ADDR_OPTION; - -typedef struct _IP6_MTU_OPTION { - UINT8 Type; - UINT8 Length; - UINT16 Reserved; - UINT32 Mtu; -} IP6_MTU_OPTION; - -typedef struct _IP6_PREFIX_INFO_OPTION { - UINT8 Type; - UINT8 Length; - UINT8 PrefixLength; - UINT8 Reserved1; - UINT32 ValidLifetime; - UINT32 PreferredLifetime; - UINT32 Reserved2; - EFI_IPv6_ADDRESS Prefix; -} IP6_PREFIX_INFO_OPTION; - -typedef -VOID -(*IP6_DAD_CALLBACK) ( - IN BOOLEAN IsDadPassed, - IN EFI_IPv6_ADDRESS *TargetAddress, - IN VOID *Context - ); - -typedef struct _IP6_DAD_ENTRY { - UINT32 Signature; - LIST_ENTRY Link; - UINT32 MaxTransmit; - UINT32 Transmit; - UINT32 Receive; - UINT32 RetransTick; - IP6_ADDRESS_INFO *AddressInfo; - EFI_IPv6_ADDRESS Destination; - IP6_DAD_CALLBACK Callback; - VOID *Context; -} IP6_DAD_ENTRY; - -typedef struct _IP6_DELAY_JOIN_LIST { - LIST_ENTRY Link; - UINT32 DelayTime; ///< in tick per 50 milliseconds - IP6_INTERFACE *Interface; - IP6_ADDRESS_INFO *AddressInfo; - IP6_DAD_CALLBACK DadCallback; - VOID *Context; -} IP6_DELAY_JOIN_LIST; - -typedef struct _IP6_NEIGHBOR_ENTRY { - LIST_ENTRY Link; - LIST_ENTRY ArpList; - INTN RefCnt; - BOOLEAN IsRouter; - BOOLEAN ArpFree; - BOOLEAN Dynamic; - EFI_IPv6_ADDRESS Neighbor; - EFI_MAC_ADDRESS LinkAddress; - EFI_IP6_NEIGHBOR_STATE State; - UINT32 Transmit; - UINT32 Ticks; - - LIST_ENTRY Frames; - IP6_INTERFACE *Interface; - IP6_ARP_CALLBACK CallBack; -} IP6_NEIGHBOR_ENTRY; - -typedef struct _IP6_DEFAULT_ROUTER { - LIST_ENTRY Link; - INTN RefCnt; - UINT16 Lifetime; - EFI_IPv6_ADDRESS Router; - IP6_NEIGHBOR_ENTRY *NeighborCache; -} IP6_DEFAULT_ROUTER; - -typedef struct _IP6_PREFIX_LIST_ENTRY { - LIST_ENTRY Link; - INTN RefCnt; - UINT32 ValidLifetime; - UINT32 PreferredLifetime; - UINT8 PrefixLength; - EFI_IPv6_ADDRESS Prefix; -} IP6_PREFIX_LIST_ENTRY; - -/** - Build a array of EFI_IP6_NEIGHBOR_CACHE to be returned to the caller. The number - of EFI_IP6_NEIGHBOR_CACHE is also returned. - - @param[in] IpInstance The pointer to IP6_PROTOCOL instance. - @param[out] NeighborCount The number of returned neighbor cache entries. - @param[out] NeighborCache The pointer to the array of EFI_IP6_NEIGHBOR_CACHE. - - @retval EFI_SUCCESS The EFI_IP6_NEIGHBOR_CACHE successfully built. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the route table. - -**/ -EFI_STATUS -Ip6BuildEfiNeighborCache ( - IN IP6_PROTOCOL *IpInstance, - OUT UINT32 *NeighborCount, - OUT EFI_IP6_NEIGHBOR_CACHE **NeighborCache - ); - -/** - Build a array of EFI_IP6_ADDRESS_INFO to be returned to the caller. The number - of prefix entries is also returned. - - @param[in] IpInstance The pointer to IP6_PROTOCOL instance. - @param[out] PrefixCount The number of returned prefix entries. - @param[out] PrefixTable The pointer to the array of PrefixTable. - - @retval EFI_SUCCESS The prefix table successfully built. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the prefix table. - -**/ -EFI_STATUS -Ip6BuildPrefixTable ( - IN IP6_PROTOCOL *IpInstance, - OUT UINT32 *PrefixCount, - OUT EFI_IP6_ADDRESS_INFO **PrefixTable - ); - -/** - Allocate and initialize an IP6 default router entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Ip6Address The IPv6 address of the default router. - @param[in] RouterLifetime The lifetime associated with the default - router, in units of seconds. - - @return NULL if it failed to allocate memory for the default router node. - Otherwise, point to the created default router node. - -**/ -IP6_DEFAULT_ROUTER * -Ip6CreateDefaultRouter ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Ip6Address, - IN UINT16 RouterLifetime - ); - -/** - Destroy an IP6 default router entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] DefaultRouter The to be destroyed IP6_DEFAULT_ROUTER. - -**/ -VOID -Ip6DestroyDefaultRouter ( - IN IP6_SERVICE *IpSb, - IN IP6_DEFAULT_ROUTER *DefaultRouter - ); - -/** - Clean an IP6 default router list. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - -**/ -VOID -Ip6CleanDefaultRouterList ( - IN IP6_SERVICE *IpSb - ); - -/** - Search a default router node from an IP6 default router list. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Ip6Address The IPv6 address of the to be searched default router node. - - @return NULL if it failed to find the matching default router node. - Otherwise, point to the found default router node. - -**/ -IP6_DEFAULT_ROUTER * -Ip6FindDefaultRouter ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Ip6Address - ); - -/** - The function to be called after DAD (Duplicate Address Detection) is performed. - - @param[in] IsDadPassed If TRUE, the DAD operation succeed. Otherwise, the DAD operation failed. - @param[in] IpIf Points to the IP6_INTERFACE. - @param[in] DadEntry The DAD entry which already performed DAD. - -**/ -VOID -Ip6OnDADFinished ( - IN BOOLEAN IsDadPassed, - IN IP6_INTERFACE *IpIf, - IN IP6_DAD_ENTRY *DadEntry - ); - -/** - Create a DAD (Duplicate Address Detection) entry and queue it to be performed. - - @param[in] IpIf Points to the IP6_INTERFACE. - @param[in] AddressInfo The address information which needs DAD performed. - @param[in] Callback The callback routine that will be called after DAD - is performed. This is an optional parameter that - may be NULL. - @param[in] Context The opaque parameter for a DAD callback routine. - This is an optional parameter that may be NULL. - - @retval EFI_SUCCESS The DAD entry was created and queued. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory to complete the - operation. - - -**/ -EFI_STATUS -Ip6InitDADProcess ( - IN IP6_INTERFACE *IpIf, - IN IP6_ADDRESS_INFO *AddressInfo, - IN IP6_DAD_CALLBACK Callback OPTIONAL, - IN VOID *Context OPTIONAL - ); - -/** - Search IP6_DAD_ENTRY from the Duplicate Address Detection List. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Target The address information which needs DAD performed . - @param[out] Interface If not NULL, output the IP6 interface that configures - the tentative address. - - @return NULL if failed to find the matching DAD entry. - Otherwise, point to the found DAD entry. - -**/ -IP6_DAD_ENTRY * -Ip6FindDADEntry ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Target, - OUT IP6_INTERFACE **Interface OPTIONAL - ); - -/** - Allocate and initialize a IP6 prefix list entry. - - @param[in] IpSb The pointer to IP6_SERVICE instance. - @param[in] OnLinkOrAuto If TRUE, the entry is created for the on link prefix list. - Otherwise, it is created for the autoconfiguration prefix list. - @param[in] ValidLifetime The length of time in seconds that the prefix - is valid for the purpose of on-link determination. - @param[in] PreferredLifetime The length of time in seconds that addresses - generated from the prefix via stateless address - autoconfiguration remain preferred. - @param[in] PrefixLength The prefix length of the Prefix. - @param[in] Prefix The prefix address. - - @return NULL if it failed to allocate memory for the prefix node. Otherwise, point - to the created or existing prefix list entry. - -**/ -IP6_PREFIX_LIST_ENTRY * -Ip6CreatePrefixListEntry ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN OnLinkOrAuto, - IN UINT32 ValidLifetime, - IN UINT32 PreferredLifetime, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *Prefix - ); - -/** - Destroy a IP6 prefix list entry. - - @param[in] IpSb The pointer to IP6_SERVICE instance. - @param[in] PrefixEntry The to be destroyed prefix list entry. - @param[in] OnLinkOrAuto If TRUE, the entry is removed from on link prefix list. - Otherwise remove from autoconfiguration prefix list. - @param[in] ImmediateDelete If TRUE, remove the entry directly. - Otherwise, check the reference count to see whether - it should be removed. - -**/ -VOID -Ip6DestroyPrefixListEntry ( - IN IP6_SERVICE *IpSb, - IN IP6_PREFIX_LIST_ENTRY *PrefixEntry, - IN BOOLEAN OnLinkOrAuto, - IN BOOLEAN ImmediateDelete - ); - -/** - Search the list array to find an IP6 prefix list entry. - - @param[in] IpSb The pointer to IP6_SERVICE instance. - @param[in] OnLinkOrAuto If TRUE, the search the link prefix list, - Otherwise search the autoconfiguration prefix list. - @param[in] PrefixLength The prefix length of the Prefix - @param[in] Prefix The prefix address. - - @return NULL if cannot find the IP6 prefix list entry. Otherwise, return the - pointer to the IP6 prefix list entry. - -**/ -IP6_PREFIX_LIST_ENTRY * -Ip6FindPrefixListEntry ( - IN IP6_SERVICE *IpSb, - IN BOOLEAN OnLinkOrAuto, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *Prefix - ); - -/** - Release the resource in prefix list table, and destroy the list entry and - corresponding addresses or route entries. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] ListHead The list entry head of the prefix list table. - -**/ -VOID -Ip6CleanPrefixListTable ( - IN IP6_SERVICE *IpSb, - IN LIST_ENTRY *ListHead - ); - -/** - Allocate and initialize an IP6 neighbor cache entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] CallBack The callback function to be called when - address resolution is finished. - @param[in] Ip6Address Points to the IPv6 address of the neighbor. - @param[in] LinkAddress Points to the MAC address of the neighbor. - Ignored if NULL. - - @return NULL if failed to allocate memory for the neighbor cache entry. - Otherwise, point to the created neighbor cache entry. - -**/ -IP6_NEIGHBOR_ENTRY * -Ip6CreateNeighborEntry ( - IN IP6_SERVICE *IpSb, - IN IP6_ARP_CALLBACK CallBack, - IN EFI_IPv6_ADDRESS *Ip6Address, - IN EFI_MAC_ADDRESS *LinkAddress OPTIONAL - ); - -/** - Search a IP6 neighbor cache entry. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] Ip6Address Points to the IPv6 address of the neighbor. - - @return NULL if it failed to find the matching neighbor cache entry. - Otherwise, point to the found neighbor cache entry. - -**/ -IP6_NEIGHBOR_ENTRY * -Ip6FindNeighborEntry ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Ip6Address - ); - -/** - Free a IP6 neighbor cache entry and remove all the frames on the address - resolution queue that pass the FrameToCancel. That is, either FrameToCancel - is NULL, or it returns true for the frame. - - @param[in] IpSb The pointer to the IP6_SERVICE instance. - @param[in] NeighborCache The to be free neighbor cache entry. - @param[in] SendIcmpError If TRUE, send out ICMP error. - @param[in] FullFree If TRUE, remove the neighbor cache entry. - Otherwise remove the pending frames. - @param[in] IoStatus The status returned to the cancelled frames' - callback function. - @param[in] FrameToCancel Function to select which frame to cancel. - This is an optional parameter that may be NULL. - @param[in] Context Opaque parameter to the FrameToCancel. - Ignored if FrameToCancel is NULL. - - @retval EFI_INVALID_PARAMETER The input parameter is invalid. - @retval EFI_SUCCESS The operation finished successfully. - -**/ -EFI_STATUS -Ip6FreeNeighborEntry ( - IN IP6_SERVICE *IpSb, - IN IP6_NEIGHBOR_ENTRY *NeighborCache, - IN BOOLEAN SendIcmpError, - IN BOOLEAN FullFree, - IN EFI_STATUS IoStatus, - IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, - IN VOID *Context OPTIONAL - ); - -/** - Add Neighbor cache entries. It is a work function for EfiIp6Neighbors(). - - @param[in] IpSb The IP6 service binding instance. - @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, and if a - corresponding cache entry already existed, EFI_ACCESS_DENIED - will be returned. - - @retval EFI_SUCCESS The neighbor cache entry has been added. - @retval EFI_OUT_OF_RESOURCES Could not add the entry to the neighbor cache - due to insufficient resources. - @retval EFI_NOT_FOUND 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). - -**/ -EFI_STATUS -Ip6AddNeighbor ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, - IN UINT32 Timeout, - IN BOOLEAN Override - ); - -/** - Delete or update Neighbor cache entries. It is a work function for EfiIp6Neighbors(). - - @param[in] IpSb The IP6 service binding instance. - @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, and if a - corresponding cache entry already existed, EFI_ACCESS_DENIED - will be returned. - - @retval EFI_SUCCESS The neighbor cache entry has been updated or deleted. - @retval EFI_NOT_FOUND This entry is not in the neighbor cache. - -**/ -EFI_STATUS -Ip6DelNeighbor ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL, - IN UINT32 Timeout, - IN BOOLEAN Override - ); - -/** - Process the Neighbor Solicitation message. The message may be sent for Duplicate - Address Detection or Address Resolution. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the message. - @param[in] Packet The content of the message with IP head removed. - - @retval EFI_SUCCESS The packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval EFI_ICMP_ERROR The packet indicates that DAD is failed. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessNeighborSolicit ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - -/** - Process the Neighbor Advertisement message. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the message. - @param[in] Packet The content of the message with IP head removed. - - @retval EFI_SUCCESS The packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval EFI_ICMP_ERROR The packet indicates that DAD is failed. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessNeighborAdvertise ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - -/** - Process the Router Advertisement message according to RFC4861. - - @param[in] IpSb The IP service that received the packet. - @param[in] Head The IP head of the message. - @param[in] Packet The content of the message with the IP head removed. - - @retval EFI_SUCCESS The packet processed successfully. - @retval EFI_INVALID_PARAMETER The packet is invalid. - @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the operation. - @retval Others Failed to process the packet. - -**/ -EFI_STATUS -Ip6ProcessRouterAdvertise ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - -/** - Process the ICMPv6 redirect message. Find the instance, then update - its route cache. - - @param[in] IpSb The IP6 service binding instance that received - the packet. - @param[in] Head The IP head of the received ICMPv6 packet. - @param[in] Packet The content of the ICMPv6 redirect packet with - the IP head removed. - - @retval EFI_INVALID_PARAMETER The parameter is invalid. - @retval EFI_OUT_OF_RESOURCES Insuffcient resources to complete the - operation. - @retval EFI_SUCCESS Successfully updated the route caches. - -**/ -EFI_STATUS -Ip6ProcessRedirect ( - IN IP6_SERVICE *IpSb, - IN EFI_IP6_HEADER *Head, - IN NET_BUF *Packet - ); - -/** - Generate router solicit message and send it out to Destination Address or - All Router Link Local scope multicast address. - - @param[in] IpSb The IP service to send the packet. - @param[in] Interface If not NULL, points to the IP6 interface to send - the packet. - @param[in] SourceAddress If not NULL, the source address of the message. - @param[in] DestinationAddress If not NULL, the destination address of the message. - @param[in] SourceLinkAddress If not NULL, the MAC address of the source. - A source link-layer address option will be appended - to the message. - - @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the operation. - @retval EFI_SUCCESS The router solicit message was successfully sent. - -**/ -EFI_STATUS -Ip6SendRouterSolicit ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *Interface OPTIONAL, - IN EFI_IPv6_ADDRESS *SourceAddress OPTIONAL, - IN EFI_IPv6_ADDRESS *DestinationAddress OPTIONAL, - IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL - ); - -/** - Generate the Neighbor Solicitation message and send it to the Destination Address. - - @param[in] IpSb The IP service to send the packet - @param[in] SourceAddress The source address of the message. - @param[in] DestinationAddress The destination address of the message. - @param[in] TargetIp6Address The IP address of the target of the solicitation. - It must not be a multicast address. - @param[in] SourceLinkAddress The MAC address for the sender. If not NULL, - a source link-layer address option will be appended - to the message. - - @retval EFI_INVALID_PARAMETER Any input parameter is invalid. - @retval EFI_OUT_OF_RESOURCES Insufficient resources to complete the - operation. - @retval EFI_SUCCESS The Neighbor Advertise message was successfully sent. - -**/ -EFI_STATUS -Ip6SendNeighborSolicit ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *SourceAddress, - IN EFI_IPv6_ADDRESS *DestinationAddress, - IN EFI_IPv6_ADDRESS *TargetIp6Address, - IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL - ); - -/** - Set the interface's address. This will trigger the DAD process for the - address to set. To set an already set address, the lifetimes wil be - updated to the new value passed in. - - @param[in] Interface The interface to set the address. - @param[in] Ip6Addr The interface's to be assigned IPv6 address. - @param[in] IsAnycast If TRUE, the unicast IPv6 address is anycast. - Otherwise, it is not anycast. - @param[in] PrefixLength The prefix length of the Ip6Addr. - @param[in] ValidLifetime The valid lifetime for this address. - @param[in] PreferredLifetime The preferred lifetime for this address. - @param[in] DadCallback The caller's callback to trigger when DAD finishes. - This is an optional parameter that may be NULL. - @param[in] Context The context that will be passed to DadCallback. - This is an optional parameter that may be NULL. - - @retval EFI_SUCCESS The interface is scheduled to be configured with - the specified address. - @retval EFI_OUT_OF_RESOURCES Failed to set the interface's address due to - lack of resources. - -**/ -EFI_STATUS -Ip6SetAddress ( - IN IP6_INTERFACE *Interface, - IN EFI_IPv6_ADDRESS *Ip6Addr, - IN BOOLEAN IsAnycast, - IN UINT8 PrefixLength, - IN UINT32 ValidLifetime, - IN UINT32 PreferredLifetime, - IN IP6_DAD_CALLBACK DadCallback OPTIONAL, - IN VOID *Context OPTIONAL - ); - -/** - The heartbeat timer of ND module in IP6_TIMER_INTERVAL_IN_MS milliseconds. - This time routine handles DAD module and neighbor state transition. - It is also responsible for sending out router solicitations. - - @param[in] Event The IP6 service instance's heartbeat timer. - @param[in] Context The IP6 service instance. - -**/ -VOID -EFIAPI -Ip6NdFasterTimerTicking ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - The heartbeat timer of ND module in 1 second. This time routine handles following - things: 1) maitain default router list; 2) maintain prefix options; - 3) maintain route caches. - - @param[in] IpSb The IP6 service binding instance. - -**/ -VOID -Ip6NdTimerTicking ( - IN IP6_SERVICE *IpSb - ); - -/** - Callback function when address resolution is finished. It will cancel - all the queued frames if the address resolution failed, or transmit them - if the request succeeded. - - @param[in] Context The context of the callback, a pointer to IP6_NEIGHBOR_ENTRY. - -**/ -VOID -Ip6OnArpResolved ( - IN VOID *Context - ); - -/** - Update the ReachableTime in IP6 service binding instance data, in milliseconds. - - @param[in, out] IpSb Points to the IP6_SERVICE. - -**/ -VOID -Ip6UpdateReachableTime ( - IN OUT IP6_SERVICE *IpSb - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6NvData.h b/Core/NetworkPkg/Ip6Dxe/Ip6NvData.h deleted file mode 100644 index 09177613fb..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6NvData.h +++ /dev/null @@ -1,69 +0,0 @@ -/** @file - NVData structure used by the IP6 configuration component. - - Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef _IP6_NV_DATA_H_ -#define _IP6_NV_DATA_H_ - -#include - -#define FORMID_MAIN_FORM 1 -#define FORMID_MANUAL_CONFIG_FORM 2 -#define FORMID_HEAD_FORM 3 - -#define IP6_POLICY_AUTO 0 -#define IP6_POLICY_MANUAL 1 -#define DAD_MAX_TRANSMIT_COUNT 10 - -#define KEY_INTERFACE_ID 0x101 -#define KEY_MANUAL_ADDRESS 0x102 -#define KEY_GATEWAY_ADDRESS 0x103 -#define KEY_DNS_ADDRESS 0x104 -#define KEY_SAVE_CHANGES 0x105 -#define KEY_SAVE_CONFIG_CHANGES 0x106 -#define KEY_IGNORE_CONFIG_CHANGES 0x107 -#define KEY_GET_CURRENT_SETTING 0x108 - -#define HOST_ADDRESS_LABEL 0x9000 -#define ROUTE_TABLE_LABEL 0xa000 -#define GATEWAY_ADDRESS_LABEL 0xb000 -#define DNS_ADDRESS_LABEL 0xc000 -#define LABEL_END 0xffff - -#define INTERFACE_ID_STR_MIN_SIZE 1 -#define INTERFACE_ID_STR_MAX_SIZE 23 -#define INTERFACE_ID_STR_STORAGE 25 -#define IP6_STR_MAX_SIZE 40 -#define ADDRESS_STR_MIN_SIZE 2 -#define ADDRESS_STR_MAX_SIZE 255 - -/// -/// IP6_CONFIG_IFR_NVDATA contains the IP6 configure -/// parameters for that NIC. -/// -#pragma pack(1) -typedef struct { - UINT8 IfType; ///< interface type - UINT8 Padding[3]; - UINT32 Policy; ///< manual or automatic - UINT32 DadTransmitCount; ///< dad transmits count - CHAR16 InterfaceId[INTERFACE_ID_STR_STORAGE]; ///< alternative interface id - CHAR16 ManualAddress[ADDRESS_STR_MAX_SIZE]; ///< IP addresses - CHAR16 GatewayAddress[ADDRESS_STR_MAX_SIZE]; ///< Gateway address - CHAR16 DnsAddress[ADDRESS_STR_MAX_SIZE]; ///< DNS server address -} IP6_CONFIG_IFR_NVDATA; -#pragma pack() - -#endif - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Option.c b/Core/NetworkPkg/Ip6Dxe/Ip6Option.c deleted file mode 100644 index 21d28b6942..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Option.c +++ /dev/null @@ -1,758 +0,0 @@ -/** @file - IP6 option support functions and routines. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -/** - Validate the IP6 option format for both the packets we received - and that we will transmit. It will compute the ICMPv6 error message fields - if the option is malformatted. - - @param[in] IpSb The IP6 service data. - @param[in] Packet The to be validated packet. - @param[in] Option The first byte of the option. - @param[in] OptionLen The length of the whole option. - @param[in] Pointer Identifies the octet offset within - the invoking packet where the error was detected. - - - @retval TRUE The option is properly formatted. - @retval FALSE The option is malformatted. - -**/ -BOOLEAN -Ip6IsOptionValid ( - IN IP6_SERVICE *IpSb, - IN NET_BUF *Packet, - IN UINT8 *Option, - IN UINT8 OptionLen, - IN UINT32 Pointer - ) -{ - UINT8 Offset; - UINT8 OptionType; - - Offset = 0; - - while (Offset < OptionLen) { - OptionType = *(Option + Offset); - - switch (OptionType) { - case Ip6OptionPad1: - // - // It is a Pad1 option - // - Offset++; - break; - case Ip6OptionPadN: - // - // It is a PadN option - // - Offset = (UINT8) (Offset + *(Option + Offset + 1) + 2); - break; - case Ip6OptionRouterAlert: - // - // It is a Router Alert Option - // - Offset += 4; - break; - default: - // - // The highest-order two bits specify the action must be taken if - // the processing IPv6 node does not recognize the option type. - // - switch (OptionType & Ip6OptionMask) { - case Ip6OptionSkip: - Offset = (UINT8) (Offset + *(Option + Offset + 1)); - break; - case Ip6OptionDiscard: - return FALSE; - case Ip6OptionParameterProblem: - Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER); - Ip6SendIcmpError ( - IpSb, - Packet, - NULL, - &Packet->Ip.Ip6->SourceAddress, - ICMP_V6_PARAMETER_PROBLEM, - 2, - &Pointer - ); - return FALSE; - case Ip6OptionMask: - if (!IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { - Pointer = Pointer + Offset + sizeof (EFI_IP6_HEADER); - Ip6SendIcmpError ( - IpSb, - Packet, - NULL, - &Packet->Ip.Ip6->SourceAddress, - ICMP_V6_PARAMETER_PROBLEM, - 2, - &Pointer - ); - } - - return FALSE; - break; - } - - break; - } - - } - - return TRUE; -} - -/** - Validate the IP6 option format for both the packets we received - and that we will transmit. It supports the defined options in Neighbor - Discovery messages. - - @param[in] Option The first byte of the option. - @param[in] OptionLen The length of the whole option. - - @retval TRUE The option is properly formatted. - @retval FALSE The option is malformatted. - -**/ -BOOLEAN -Ip6IsNDOptionValid ( - IN UINT8 *Option, - IN UINT16 OptionLen - ) -{ - UINT16 Offset; - UINT8 OptionType; - UINT16 Length; - - Offset = 0; - - while (Offset < OptionLen) { - OptionType = *(Option + Offset); - Length = (UINT16) (*(Option + Offset + 1) * 8); - - switch (OptionType) { - case Ip6OptionPrefixInfo: - if (Length != 32) { - return FALSE; - } - - break; - - case Ip6OptionMtu: - if (Length != 8) { - return FALSE; - } - - break; - - default: - // - // Check the length of Ip6OptionEtherSource, Ip6OptionEtherTarget, and - // Ip6OptionRedirected here. For unrecognized options, silently ignore - // and continue processsing the message. - // - if (Length == 0) { - return FALSE; - } - - break; - } - - Offset = (UINT16) (Offset + Length); - } - - return TRUE; -} - - -/** - Validate whether the NextHeader is a known valid protocol or one of the user configured - protocols from the upper layer. - - @param[in] IpSb The IP6 service instance. - @param[in] NextHeader The next header field. - - @retval TRUE The NextHeader is a known valid protocol or user configured. - @retval FALSE The NextHeader is not a known valid protocol. - -**/ -BOOLEAN -Ip6IsValidProtocol ( - IN IP6_SERVICE *IpSb, - IN UINT8 NextHeader - ) -{ - LIST_ENTRY *Entry; - IP6_PROTOCOL *IpInstance; - - if (NextHeader == EFI_IP_PROTO_TCP || - NextHeader == EFI_IP_PROTO_UDP || - NextHeader == IP6_ICMP || - NextHeader == IP6_ESP - ) { - return TRUE; - } - - if (IpSb == NULL) { - return FALSE; - } - - if (IpSb->Signature != IP6_SERVICE_SIGNATURE) { - return FALSE; - } - - NET_LIST_FOR_EACH (Entry, &IpSb->Children) { - IpInstance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE); - if (IpInstance->State == IP6_STATE_CONFIGED) { - if (IpInstance->ConfigData.DefaultProtocol == NextHeader) { - return TRUE; - } - } - } - - return FALSE; -} - -/** - Validate the IP6 extension header format for both the packets we received - and that we will transmit. It will compute the ICMPv6 error message fields - if the option is mal-formatted. - - @param[in] IpSb The IP6 service instance. This is an optional parameter. - @param[in] Packet The data of the packet. Ignored if NULL. - @param[in] NextHeader The next header field in IPv6 basic header. - @param[in] ExtHdrs The first byte of the option. - @param[in] ExtHdrsLen The length of the whole option. - @param[in] Rcvd The option is from the packet we received if TRUE, - otherwise, the option we want to transmit. - @param[out] FormerHeader The offset of NextHeader which points to Fragment - Header when we received, of the ExtHdrs. - Ignored if we transmit. - @param[out] LastHeader The pointer of NextHeader of the last extension - header processed by IP6. - @param[out] RealExtsLen The length of extension headers processed by IP6 layer. - This is an optional parameter that may be NULL. - @param[out] UnFragmentLen The length of unfragmented length of extension headers. - This is an optional parameter that may be NULL. - @param[out] Fragmented Indicate whether the packet is fragmented. - This is an optional parameter that may be NULL. - - @retval TRUE The option is properly formatted. - @retval FALSE The option is malformatted. - -**/ -BOOLEAN -Ip6IsExtsValid ( - IN IP6_SERVICE *IpSb OPTIONAL, - IN NET_BUF *Packet OPTIONAL, - IN UINT8 *NextHeader, - IN UINT8 *ExtHdrs, - IN UINT32 ExtHdrsLen, - IN BOOLEAN Rcvd, - OUT UINT32 *FormerHeader OPTIONAL, - OUT UINT8 **LastHeader, - OUT UINT32 *RealExtsLen OPTIONAL, - OUT UINT32 *UnFragmentLen OPTIONAL, - OUT BOOLEAN *Fragmented OPTIONAL - ) -{ - UINT32 Pointer; - UINT32 Offset; - UINT8 *Option; - UINT8 OptionLen; - BOOLEAN Flag; - UINT8 CountD; - UINT8 CountA; - IP6_FRAGMENT_HEADER *FragmentHead; - UINT16 FragmentOffset; - IP6_ROUTING_HEADER *RoutingHead; - - if (RealExtsLen != NULL) { - *RealExtsLen = 0; - } - - if (UnFragmentLen != NULL) { - *UnFragmentLen = 0; - } - - if (Fragmented != NULL) { - *Fragmented = FALSE; - } - - *LastHeader = NextHeader; - - if (ExtHdrs == NULL && ExtHdrsLen == 0) { - return TRUE; - } - - if ((ExtHdrs == NULL && ExtHdrsLen != 0) || (ExtHdrs != NULL && ExtHdrsLen == 0)) { - return FALSE; - } - - Pointer = 0; - Offset = 0; - Flag = FALSE; - CountD = 0; - CountA = 0; - - while (Offset <= ExtHdrsLen) { - - switch (*NextHeader) { - case IP6_HOP_BY_HOP: - if (Offset != 0) { - if (!Rcvd) { - return FALSE; - } - // - // Hop-by-Hop Options header is restricted to appear immediately after an IPv6 header only. - // If not, generate a ICMP parameter problem message with code value of 1. - // - if (Pointer == 0) { - Pointer = sizeof (EFI_IP6_HEADER); - } else { - Pointer = Offset + sizeof (EFI_IP6_HEADER); - } - - if ((IpSb != NULL) && (Packet != NULL) && - !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { - Ip6SendIcmpError ( - IpSb, - Packet, - NULL, - &Packet->Ip.Ip6->SourceAddress, - ICMP_V6_PARAMETER_PROBLEM, - 1, - &Pointer - ); - } - return FALSE; - } - - Flag = TRUE; - - // - // Fall through - // - case IP6_DESTINATION: - if (*NextHeader == IP6_DESTINATION) { - CountD++; - } - - if (CountD > 2) { - return FALSE; - } - - NextHeader = ExtHdrs + Offset; - Pointer = Offset; - - Offset++; - Option = ExtHdrs + Offset; - OptionLen = (UINT8) ((*Option + 1) * 8 - 2); - Option++; - Offset++; - - if (IpSb != NULL && Packet != NULL && !Ip6IsOptionValid (IpSb, Packet, Option, OptionLen, Offset)) { - return FALSE; - } - - Offset = Offset + OptionLen; - - if (Flag) { - if (UnFragmentLen != NULL) { - *UnFragmentLen = Offset; - } - - Flag = FALSE; - } - - break; - - case IP6_ROUTING: - NextHeader = ExtHdrs + Offset; - RoutingHead = (IP6_ROUTING_HEADER *) NextHeader; - - // - // Type 0 routing header is defined in RFC2460 and deprecated in RFC5095. - // Thus all routing types are processed as unrecognized. - // - if (RoutingHead->SegmentsLeft == 0) { - // - // Ignore the routing header and proceed to process the next header. - // - Offset = Offset + (RoutingHead->HeaderLen + 1) * 8; - - if (UnFragmentLen != NULL) { - *UnFragmentLen = Offset; - } - - } else { - // - // Discard the packet and send an ICMP Parameter Problem, Code 0, message - // to the packet's source address, pointing to the unrecognized routing - // type. - // - Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER); - if ((IpSb != NULL) && (Packet != NULL) && - !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { - Ip6SendIcmpError ( - IpSb, - Packet, - NULL, - &Packet->Ip.Ip6->SourceAddress, - ICMP_V6_PARAMETER_PROBLEM, - 0, - &Pointer - ); - } - - return FALSE; - } - - break; - - case IP6_FRAGMENT: - - // - // RFC2402, AH header should after fragment header. - // - if (CountA > 1) { - return FALSE; - } - - // - // RFC2460, ICMP Parameter Problem message with code 0 should be sent - // if the length of a fragment is not a multiple of 8 octets and the M - // flag of that fragment is 1, pointing to the Payload length field of the - // fragment packet. - // - if (IpSb != NULL && Packet != NULL && (ExtHdrsLen % 8) != 0) { - // - // Check whether it is the last fragment. - // - FragmentHead = (IP6_FRAGMENT_HEADER *) (ExtHdrs + Offset); - if (FragmentHead == NULL) { - return FALSE; - } - - FragmentOffset = NTOHS (FragmentHead->FragmentOffset); - - if (((FragmentOffset & 0x1) == 0x1) && - !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { - Pointer = sizeof (UINT32); - Ip6SendIcmpError ( - IpSb, - Packet, - NULL, - &Packet->Ip.Ip6->SourceAddress, - ICMP_V6_PARAMETER_PROBLEM, - 0, - &Pointer - ); - return FALSE; - } - } - - if (Fragmented != NULL) { - *Fragmented = TRUE; - } - - if (Rcvd && FormerHeader != NULL) { - *FormerHeader = (UINT32) (NextHeader - ExtHdrs); - } - - NextHeader = ExtHdrs + Offset; - Offset = Offset + 8; - break; - - case IP6_AH: - if (++CountA > 1) { - return FALSE; - } - - Option = ExtHdrs + Offset; - NextHeader = Option; - Option++; - // - // RFC2402, Payload length is specified in 32-bit words, minus "2". - // - OptionLen = (UINT8) ((*Option + 2) * 4); - Offset = Offset + OptionLen; - break; - - case IP6_NO_NEXT_HEADER: - *LastHeader = NextHeader; - return FALSE; - break; - - default: - if (Ip6IsValidProtocol (IpSb, *NextHeader)) { - - *LastHeader = NextHeader; - - if (RealExtsLen != NULL) { - *RealExtsLen = Offset; - } - - return TRUE; - } - - // - // The Next Header value is unrecognized by the node, discard the packet and - // send an ICMP parameter problem message with code value of 1. - // - if (Offset == 0) { - // - // The Next Header directly follows IPv6 basic header. - // - Pointer = 6; - } else { - if (Pointer == 0) { - Pointer = sizeof (EFI_IP6_HEADER); - } else { - Pointer = Offset + sizeof (EFI_IP6_HEADER); - } - } - - if ((IpSb != NULL) && (Packet != NULL) && - !IP6_IS_MULTICAST (&Packet->Ip.Ip6->DestinationAddress)) { - Ip6SendIcmpError ( - IpSb, - Packet, - NULL, - &Packet->Ip.Ip6->SourceAddress, - ICMP_V6_PARAMETER_PROBLEM, - 1, - &Pointer - ); - } - return FALSE; - } - } - - *LastHeader = NextHeader; - - if (RealExtsLen != NULL) { - *RealExtsLen = Offset; - } - - return TRUE; -} - -/** - Generate an IPv6 router alert option in network order and output it through Buffer. - - @param[out] Buffer Points to a buffer to record the generated option. - @param[in, out] BufferLen The length of Buffer, in bytes. - @param[in] NextHeader The 8-bit selector indicates the type of header - immediately following the Hop-by-Hop Options header. - - @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to contain the generated - option. BufferLen is updated for the required size. - - @retval EFI_SUCCESS The option is generated and filled in to Buffer. - -**/ -EFI_STATUS -Ip6FillHopByHop ( - OUT UINT8 *Buffer, - IN OUT UINTN *BufferLen, - IN UINT8 NextHeader - ) -{ - UINT8 BufferArray[8]; - - if (*BufferLen < 8) { - *BufferLen = 8; - return EFI_BUFFER_TOO_SMALL; - } - - // - // Form the Hop-By-Hop option in network order. - // NextHeader (1 octet) + HdrExtLen (1 octet) + RouterAlertOption(4 octets) + PadN - // The Hdr Ext Len is the length in 8-octet units, and does not including the first 8 octets. - // - ZeroMem (BufferArray, sizeof (BufferArray)); - BufferArray[0] = NextHeader; - BufferArray[2] = 0x5; - BufferArray[3] = 0x2; - BufferArray[6] = 1; - - CopyMem (Buffer, BufferArray, sizeof (BufferArray)); - return EFI_SUCCESS; -} - -/** - Insert a Fragment Header to the Extension headers and output it in UpdatedExtHdrs. - - @param[in] IpSb The IP6 service instance to transmit the packet. - @param[in] NextHeader The extension header type of first extension header. - @param[in] LastHeader The extension header type of last extension header. - @param[in] ExtHdrs The length of the original extension header. - @param[in] ExtHdrsLen The length of the extension headers. - @param[in] FragmentOffset The fragment offset of the data following the header. - @param[out] UpdatedExtHdrs The updated ExtHdrs with Fragment header inserted. - It's caller's responsibility to free this buffer. - - @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lake of - resource. - @retval EFI_UNSUPPORTED The extension header specified in ExtHdrs is not - supported currently. - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -Ip6FillFragmentHeader ( - IN IP6_SERVICE *IpSb, - IN UINT8 NextHeader, - IN UINT8 LastHeader, - IN UINT8 *ExtHdrs, - IN UINT32 ExtHdrsLen, - IN UINT16 FragmentOffset, - OUT UINT8 **UpdatedExtHdrs - ) -{ - UINT32 Length; - UINT8 *Buffer; - UINT32 FormerHeader; - UINT32 Offset; - UINT32 Part1Len; - UINT32 HeaderLen; - UINT8 Current; - IP6_FRAGMENT_HEADER FragmentHead; - - if (UpdatedExtHdrs == NULL) { - return EFI_INVALID_PARAMETER; - } - - Length = ExtHdrsLen + sizeof (IP6_FRAGMENT_HEADER); - Buffer = AllocatePool (Length); - if (Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Offset = 0; - Part1Len = 0; - FormerHeader = 0; - Current = NextHeader; - - while ((ExtHdrs != NULL) && (Offset <= ExtHdrsLen)) { - switch (NextHeader) { - case IP6_ROUTING: - case IP6_HOP_BY_HOP: - case IP6_DESTINATION: - Current = NextHeader; - NextHeader = *(ExtHdrs + Offset); - - if ((Current == IP6_DESTINATION) && (NextHeader != IP6_ROUTING)) { - // - // Destination Options header should occur at most twice, once before - // a Routing header and once before the upper-layer header. Here we - // find the one before the upper-layer header. Insert the Fragment - // Header before it. - // - CopyMem (Buffer, ExtHdrs, Part1Len); - *(Buffer + FormerHeader) = IP6_FRAGMENT; - // - // Exit the loop. - // - Offset = ExtHdrsLen + 1; - break; - } - - - FormerHeader = Offset; - HeaderLen = (*(ExtHdrs + Offset + 1) + 1) * 8; - Part1Len = Part1Len + HeaderLen; - Offset = Offset + HeaderLen; - break; - - case IP6_FRAGMENT: - Current = NextHeader; - - if (Part1Len != 0) { - CopyMem (Buffer, ExtHdrs, Part1Len); - } - - *(Buffer + FormerHeader) = IP6_FRAGMENT; - - // - // Exit the loop. - // - Offset = ExtHdrsLen + 1; - break; - - case IP6_AH: - Current = NextHeader; - NextHeader = *(ExtHdrs + Offset); - // - // RFC2402, Payload length is specified in 32-bit words, minus "2". - // - HeaderLen = (*(ExtHdrs + Offset + 1) + 2) * 4; - Part1Len = Part1Len + HeaderLen; - Offset = Offset + HeaderLen; - break; - - default: - if (Ip6IsValidProtocol (IpSb, NextHeader)) { - Current = NextHeader; - CopyMem (Buffer, ExtHdrs, Part1Len); - *(Buffer + FormerHeader) = IP6_FRAGMENT; - // - // Exit the loop. - // - Offset = ExtHdrsLen + 1; - break; - } - - FreePool (Buffer); - return EFI_UNSUPPORTED; - } - } - - // - // Append the Fragment header. If the fragment offset indicates the fragment - // is the first fragment. - // - if ((FragmentOffset & IP6_FRAGMENT_OFFSET_MASK) == 0) { - FragmentHead.NextHeader = Current; - } else { - FragmentHead.NextHeader = LastHeader; - } - - FragmentHead.Reserved = 0; - FragmentHead.FragmentOffset = HTONS (FragmentOffset); - FragmentHead.Identification = mIp6Id; - - CopyMem (Buffer + Part1Len, &FragmentHead, sizeof (IP6_FRAGMENT_HEADER)); - - if ((ExtHdrs != NULL) && (Part1Len < ExtHdrsLen)) { - // - // Append the part2 (fragmentable part) of Extension headers - // - CopyMem ( - Buffer + Part1Len + sizeof (IP6_FRAGMENT_HEADER), - ExtHdrs + Part1Len, - ExtHdrsLen - Part1Len - ); - } - - *UpdatedExtHdrs = Buffer; - - return EFI_SUCCESS; -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Option.h b/Core/NetworkPkg/Ip6Dxe/Ip6Option.h deleted file mode 100644 index 242ec51c10..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Option.h +++ /dev/null @@ -1,191 +0,0 @@ -/** @file - Definition of IP6 option process routines. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_OPTION_H__ -#define __EFI_IP6_OPTION_H__ - -#define IP6_FRAGMENT_OFFSET_MASK (~0x3) - -typedef struct _IP6_FRAGMENT_HEADER { - UINT8 NextHeader; - UINT8 Reserved; - UINT16 FragmentOffset; - UINT32 Identification; -} IP6_FRAGMENT_HEADER; - -typedef struct _IP6_ROUTING_HEADER { - UINT8 NextHeader; - UINT8 HeaderLen; - UINT8 RoutingType; - UINT8 SegmentsLeft; -} IP6_ROUTING_HEADER; - -typedef enum { - Ip6OptionPad1 = 0, - Ip6OptionPadN = 1, - Ip6OptionRouterAlert = 5, - Ip6OptionSkip = 0, - Ip6OptionDiscard = 0x40, - Ip6OptionParameterProblem = 0x80, - Ip6OptionMask = 0xc0, - - Ip6OptionEtherSource = 1, - Ip6OptionEtherTarget = 2, - Ip6OptionPrefixInfo = 3, - Ip6OptionRedirected = 4, - Ip6OptionMtu = 5 -} IP6_OPTION_TYPE; - -/** - Validate the IP6 extension header format for both the packets we received - and that we will transmit. It will compute the ICMPv6 error message fields - if the option is mal-formatted. - - @param[in] IpSb The IP6 service instance. This is an optional parameter. - @param[in] Packet The data of the packet. Ignored if NULL. - @param[in] NextHeader The next header field in IPv6 basic header. - @param[in] ExtHdrs The first byte of the option. - @param[in] ExtHdrsLen The length of the whole option. - @param[in] Rcvd The option is from the packet we received if TRUE, - otherwise, the option we want to transmit. - @param[out] FormerHeader The offset of NextHeader which points to Fragment - Header when we received, of the ExtHdrs. - Ignored if we transmit. - @param[out] LastHeader The pointer of NextHeader of the last extension - header processed by IP6. - @param[out] RealExtsLen The length of extension headers processed by IP6 layer. - This is an optional parameter that may be NULL. - @param[out] UnFragmentLen The length of unfragmented length of extension headers. - This is an optional parameter that may be NULL. - @param[out] Fragmented Indicate whether the packet is fragmented. - This is an optional parameter that may be NULL. - - @retval TRUE The option is properly formatted. - @retval FALSE The option is malformatted. - -**/ -BOOLEAN -Ip6IsExtsValid ( - IN IP6_SERVICE *IpSb OPTIONAL, - IN NET_BUF *Packet OPTIONAL, - IN UINT8 *NextHeader, - IN UINT8 *ExtHdrs, - IN UINT32 ExtHdrsLen, - IN BOOLEAN Rcvd, - OUT UINT32 *FormerHeader OPTIONAL, - OUT UINT8 **LastHeader, - OUT UINT32 *RealExtsLen OPTIONAL, - OUT UINT32 *UnFragmentLen OPTIONAL, - OUT BOOLEAN *Fragmented OPTIONAL - ); - -/** - Generate an IPv6 router alert option in network order and output it through Buffer. - - @param[out] Buffer Points to a buffer to record the generated option. - @param[in, out] BufferLen The length of Buffer, in bytes. - @param[in] NextHeader The 8-bit selector indicates the type of header - immediately following the Hop-by-Hop Options header. - - @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to contain the generated - option. BufferLen is updated for the required size. - - @retval EFI_SUCCESS The option is generated and filled in to Buffer. - -**/ -EFI_STATUS -Ip6FillHopByHop ( - OUT UINT8 *Buffer, - IN OUT UINTN *BufferLen, - IN UINT8 NextHeader - ); - -/** - Insert a Fragment Header to the Extension headers and output it in UpdatedExtHdrs. - - @param[in] IpSb The IP6 service instance to transmit the packet. - @param[in] NextHeader The extension header type of first extension header. - @param[in] LastHeader The extension header type of last extension header. - @param[in] ExtHdrs The length of the original extension header. - @param[in] ExtHdrsLen The length of the extension headers. - @param[in] FragmentOffset The fragment offset of the data following the header. - @param[out] UpdatedExtHdrs The updated ExtHdrs with Fragment header inserted. - It's caller's responsibility to free this buffer. - - @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lake of - resource. - @retval EFI_UNSUPPORTED The extension header specified in ExtHdrs is not - supported currently. - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -Ip6FillFragmentHeader ( - IN IP6_SERVICE *IpSb, - IN UINT8 NextHeader, - IN UINT8 LastHeader, - IN UINT8 *ExtHdrs, - IN UINT32 ExtHdrsLen, - IN UINT16 FragmentOffset, - OUT UINT8 **UpdatedExtHdrs - ); - -/** - Copy the extension headers from the original to buffer. A Fragment header is - appended to the end. - - @param[in] NextHeader The 8-bit selector indicates the type of - the fragment header's next header. - @param[in] ExtHdrs The length of the original extension header. - @param[in] LastHeader The pointer of next header of last extension header. - @param[in] FragmentOffset The fragment offset of the data following the header. - @param[in] UnFragmentHdrLen The length of unfragmented length of extension headers. - @param[in, out] Buf The buffer to copy options to. - @param[in, out] BufLen The length of the buffer. - - @retval EFI_SUCCESS The options are copied over. - @retval EFI_BUFFER_TOO_SMALL The buffer caller provided is too small. - -**/ -EFI_STATUS -Ip6CopyExts ( - IN UINT8 NextHeader, - IN UINT8 *ExtHdrs, - IN UINT8 *LastHeader, - IN UINT16 FragmentOffset, - IN UINT32 UnFragmentHdrLen, - IN OUT UINT8 *Buf, - IN OUT UINT32 *BufLen - ); - -/** - Validate the IP6 option format for both the packets we received - and that we will transmit. It supports the defined options in Neighbor - Discovery messages. - - @param[in] Option The first byte of the option. - @param[in] OptionLen The length of the whole option. - - @retval TRUE The option is properly formatted. - @retval FALSE The option is malformatted. - -**/ -BOOLEAN -Ip6IsNDOptionValid ( - IN UINT8 *Option, - IN UINT16 OptionLen - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Output.c b/Core/NetworkPkg/Ip6Dxe/Ip6Output.c deleted file mode 100644 index 8330e37935..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Output.c +++ /dev/null @@ -1,1091 +0,0 @@ -/** @file - The internal functions and routines to transmit the IP6 packet. - - Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -UINT32 mIp6Id; - -/** - Output all the available source addresses to a list entry head SourceList. The - number of source addresses are also returned. - - @param[in] IpSb Points to an IP6 service binding instance. - @param[out] SourceList The list entry head of all source addresses. - It is the caller's responsibility to free the - resources. - @param[out] SourceCount The number of source addresses. - - @retval EFI_SUCCESS The source addresses were copied to a list entry head - SourceList. - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to complete the operation. - -**/ -EFI_STATUS -Ip6CandidateSource ( - IN IP6_SERVICE *IpSb, - OUT LIST_ENTRY *SourceList, - OUT UINT32 *SourceCount - ) -{ - IP6_INTERFACE *IpIf; - LIST_ENTRY *Entry; - LIST_ENTRY *Entry2; - IP6_ADDRESS_INFO *AddrInfo; - IP6_ADDRESS_INFO *Copy; - - *SourceCount = 0; - - if (IpSb->LinkLocalOk) { - Copy = AllocatePool (sizeof (IP6_ADDRESS_INFO)); - if (Copy == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Copy->Signature = IP6_ADDR_INFO_SIGNATURE; - IP6_COPY_ADDRESS (&Copy->Address, &IpSb->LinkLocalAddr); - Copy->IsAnycast = FALSE; - Copy->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH; - Copy->ValidLifetime = (UINT32) IP6_INFINIT_LIFETIME; - Copy->PreferredLifetime = (UINT32) IP6_INFINIT_LIFETIME; - - InsertTailList (SourceList, &Copy->Link); - (*SourceCount)++; - } - - NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) { - IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link); - - NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) { - AddrInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE); - - if (AddrInfo->IsAnycast) { - // - // Never use an anycast address. - // - continue; - } - - Copy = AllocateCopyPool (sizeof (IP6_ADDRESS_INFO), AddrInfo); - if (Copy == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - InsertTailList (SourceList, &Copy->Link); - (*SourceCount)++; - } - } - - return EFI_SUCCESS; -} - -/** - Calculate how many bits are the same between two IPv6 addresses. - - @param[in] AddressA Points to an IPv6 address. - @param[in] AddressB Points to another IPv6 address. - - @return The common bits of the AddressA and AddressB. - -**/ -UINT8 -Ip6CommonPrefixLen ( - IN EFI_IPv6_ADDRESS *AddressA, - IN EFI_IPv6_ADDRESS *AddressB - ) -{ - UINT8 Count; - UINT8 Index; - UINT8 ByteA; - UINT8 ByteB; - UINT8 NumBits; - - Count = 0; - Index = 0; - - while (Index < 16) { - ByteA = AddressA->Addr[Index]; - ByteB = AddressB->Addr[Index]; - - if (ByteA == ByteB) { - Count += 8; - Index++; - continue; - } - - // - // Check how many bits are common between the two bytes. - // - NumBits = 8; - ByteA = (UINT8) (ByteA ^ ByteB); - - while (ByteA != 0) { - NumBits--; - ByteA = (UINT8) (ByteA >> 1); - } - - return (UINT8) (Count + NumBits); - } - - return Count; -} - -/** - Output all the available source addresses to a list entry head SourceList. The - number of source addresses are also returned. - - @param[in] IpSb Points to a IP6 service binding instance. - @param[in] Destination The IPv6 destination address. - @param[out] Source The selected IPv6 source address according to - the Destination. - - @retval EFI_SUCCESS The source addresses were copied to a list entry - head SourceList. - @retval EFI_NO_MAPPING The IPv6 stack is not auto configured. - -**/ -EFI_STATUS -Ip6SelectSourceAddress ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Destination, - OUT EFI_IPv6_ADDRESS *Source - ) -{ - EFI_STATUS Status; - LIST_ENTRY SourceList; - UINT32 SourceCount; - UINT8 ScopeD; - LIST_ENTRY *Entry; - IP6_ADDRESS_INFO *AddrInfo; - IP6_PREFIX_LIST_ENTRY *Prefix; - UINT8 LastCommonLength; - UINT8 CurrentCommonLength; - EFI_IPv6_ADDRESS *TmpAddress; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - Status = EFI_SUCCESS; - InitializeListHead (&SourceList); - - if (!IpSb->LinkLocalOk) { - return EFI_NO_MAPPING; - } - - // - // Rule 1: Prefer same address. - // - if (Ip6IsOneOfSetAddress (IpSb, Destination, NULL, NULL)) { - IP6_COPY_ADDRESS (Source, Destination); - goto Exit; - } - - // - // Rule 2: Prefer appropriate scope. - // - if (IP6_IS_MULTICAST (Destination)) { - ScopeD = (UINT8) (Destination->Addr[1] >> 4); - } else if (NetIp6IsLinkLocalAddr (Destination)) { - ScopeD = 0x2; - } else { - ScopeD = 0xE; - } - - if (ScopeD <= 0x2) { - // - // Return the link-local address if it exists - // One IP6_SERVICE only has one link-local address. - // - IP6_COPY_ADDRESS (Source, &IpSb->LinkLocalAddr); - goto Exit; - } - - // - // All candidate source addresses are global unicast address. - // - Ip6CandidateSource (IpSb, &SourceList, &SourceCount); - - if (SourceCount == 0) { - Status = EFI_NO_MAPPING; - goto Exit; - } - - IP6_COPY_ADDRESS (Source, &IpSb->LinkLocalAddr); - - if (SourceCount == 1) { - goto Exit; - } - - // - // Rule 3: Avoid deprecated addresses. - // TODO: check the "deprecated" state of the stateful configured address - // - NET_LIST_FOR_EACH (Entry, &IpSb->AutonomousPrefix) { - Prefix = NET_LIST_USER_STRUCT (Entry, IP6_PREFIX_LIST_ENTRY, Link); - if (Prefix->PreferredLifetime == 0) { - Ip6RemoveAddr (NULL, &SourceList, &SourceCount, &Prefix->Prefix, Prefix->PrefixLength); - - if (SourceCount == 1) { - goto Exit; - } - } - } - - // - // TODO: Rule 4: Prefer home addresses. - // TODO: Rule 5: Prefer outgoing interface. - // TODO: Rule 6: Prefer matching label. - // TODO: Rule 7: Prefer public addresses. - // - - // - // Rule 8: Use longest matching prefix. - // - LastCommonLength = Ip6CommonPrefixLen (Source, Destination); - TmpAddress = NULL; - - for (Entry = SourceList.ForwardLink; Entry != &SourceList; Entry = Entry->ForwardLink) { - AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE); - - CurrentCommonLength = Ip6CommonPrefixLen (&AddrInfo->Address, Destination); - if (CurrentCommonLength > LastCommonLength) { - LastCommonLength = CurrentCommonLength; - TmpAddress = &AddrInfo->Address; - } - } - - if (TmpAddress != NULL) { - IP6_COPY_ADDRESS (Source, TmpAddress); - } - -Exit: - - Ip6RemoveAddr (NULL, &SourceList, &SourceCount, NULL, 0); - - return Status; -} - -/** - Select an interface to send the packet generated in the IP6 driver - itself: that is, not by the requests of the IP6 child's consumer. Such - packets include the ICMPv6 echo replies and other ICMPv6 error packets. - - @param[in] IpSb The IP4 service that wants to send the packets. - @param[in] Destination The destination of the packet. - @param[in, out] Source The source of the packet. - - @return NULL if no proper interface is found, otherwise, the interface that - can be used to send the system packet from. - -**/ -IP6_INTERFACE * -Ip6SelectInterface ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Destination, - IN OUT EFI_IPv6_ADDRESS *Source - ) -{ - EFI_STATUS Status; - EFI_IPv6_ADDRESS SelectedSource; - IP6_INTERFACE *IpIf; - BOOLEAN Exist; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - ASSERT (Destination != NULL && Source != NULL); - - if (NetIp6IsUnspecifiedAddr (Destination)) { - return NULL; - } - - if (!NetIp6IsUnspecifiedAddr (Source)) { - Exist = Ip6IsOneOfSetAddress (IpSb, Source, &IpIf, NULL); - ASSERT (Exist); - - return IpIf; - } - - // - // If source is unspecified, select a source according to the destination. - // - Status = Ip6SelectSourceAddress (IpSb, Destination, &SelectedSource); - if (EFI_ERROR (Status)) { - return IpSb->DefaultInterface; - } - - Ip6IsOneOfSetAddress (IpSb, &SelectedSource, &IpIf, NULL); - IP6_COPY_ADDRESS (Source, &SelectedSource); - - return IpIf; -} - -/** - The default callback function for the system generated packet. - It will free the packet. - - @param[in] Packet The packet that transmitted. - @param[in] IoStatus The result of the transmission, succeeded or failed. - @param[in] LinkFlag Not used when transmitted. Check IP6_FRAME_CALLBACK - for reference. - @param[in] Context The context provided by us. - -**/ -VOID -Ip6SysPacketSent ( - NET_BUF *Packet, - EFI_STATUS IoStatus, - UINT32 LinkFlag, - VOID *Context - ) -{ - NetbufFree (Packet); - Packet = NULL; -} - -/** - Prefix an IP6 basic head and unfragmentable extension headers and a fragment header - to the Packet. Used for IP6 fragmentation. - - @param[in] IpSb The IP6 service instance to transmit the packet. - @param[in] Packet The packet to prefix the IP6 header to. - @param[in] Head The caller supplied header. - @param[in] FragmentOffset The fragment offset of the data following the header. - @param[in] ExtHdrs The length of the original extension header. - @param[in] ExtHdrsLen The length of the extension headers. - @param[in] LastHeader The pointer of next header of last extension header. - @param[in] HeadLen The length of the unfragmented part of the IP6 header. - - @retval EFI_BAD_BUFFER_SIZE There is no enough room in the head space of - Packet. - @retval EFI_SUCCESS The operation performed successfully. - -**/ -EFI_STATUS -Ip6PrependHead ( - IN IP6_SERVICE *IpSb, - IN NET_BUF *Packet, - IN EFI_IP6_HEADER *Head, - IN UINT16 FragmentOffset, - IN UINT8 *ExtHdrs, - IN UINT32 ExtHdrsLen, - IN UINT8 LastHeader, - IN UINT32 HeadLen - ) -{ - UINT32 Len; - UINT32 UnFragExtHdrsLen; - EFI_IP6_HEADER *PacketHead; - UINT8 *UpdatedExtHdrs; - EFI_STATUS Status; - UINT8 NextHeader; - - UpdatedExtHdrs = NULL; - - // - // HeadLen is the length of the fixed part of the sequences of fragments, i.e. - // the unfragment part. - // - PacketHead = (EFI_IP6_HEADER *) NetbufAllocSpace (Packet, HeadLen, NET_BUF_HEAD); - if (PacketHead == NULL) { - return EFI_BAD_BUFFER_SIZE; - } - - // - // Set the head up, convert the host byte order to network byte order - // - CopyMem (PacketHead, Head, sizeof (EFI_IP6_HEADER)); - PacketHead->PayloadLength = HTONS ((UINT16) (Packet->TotalSize - sizeof (EFI_IP6_HEADER))); - Packet->Ip.Ip6 = PacketHead; - - Len = HeadLen - sizeof (EFI_IP6_HEADER); - UnFragExtHdrsLen = Len - sizeof (IP6_FRAGMENT_HEADER); - - if (UnFragExtHdrsLen == 0) { - PacketHead->NextHeader = IP6_FRAGMENT; - } - - // - // Append the extension headers: firstly copy the unfragmentable headers, then append - // fragmentation header. - // - if ((FragmentOffset & IP6_FRAGMENT_OFFSET_MASK) == 0) { - NextHeader = Head->NextHeader; - } else { - NextHeader = PacketHead->NextHeader; - } - - Status = Ip6FillFragmentHeader ( - IpSb, - NextHeader, - LastHeader, - ExtHdrs, - ExtHdrsLen, - FragmentOffset, - &UpdatedExtHdrs - ); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem ( - (UINT8 *) (PacketHead + 1), - UpdatedExtHdrs, - UnFragExtHdrsLen + sizeof (IP6_FRAGMENT_HEADER) - ); - - FreePool (UpdatedExtHdrs); - return EFI_SUCCESS; -} - -/** - Transmit an IP6 packet. The packet comes either from the IP6 - child's consumer (IpInstance != NULL) or the IP6 driver itself - (IpInstance == NULL). It will route the packet, fragment it, - then transmit all the fragments through an interface. - - @param[in] IpSb The IP6 service instance to transmit the packet. - @param[in] Interface The IP6 interface to transmit the packet. Ignored - if NULL. - @param[in] IpInstance The IP6 child that issues the transmission. It is - NULL if the packet is from the system. - @param[in] Packet The user data to send, excluding the IP header. - @param[in] Head The caller supplied header. The caller should set - the following header fields: NextHeader, HopLimit, - Src, Dest, FlowLabel, PayloadLength. This function - will fill in the Ver, TrafficClass. - @param[in] ExtHdrs The extension headers to append to the IPv6 basic - header. - @param[in] ExtHdrsLen The length of the extension headers. - @param[in] Callback The callback function to issue when transmission - completed. - @param[in] Context The opaque context for the callback. - - @retval EFI_INVALID_PARAMETER Any input parameter or the packet is invalid. - @retval EFI_NO_MAPPING There is no interface to the destination. - @retval EFI_NOT_FOUND There is no route to the destination. - @retval EFI_SUCCESS The packet successfully transmitted. - @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lack of - resources. - @retval Others Failed to transmit the packet. - -**/ -EFI_STATUS -Ip6Output ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *Interface OPTIONAL, - IN IP6_PROTOCOL *IpInstance OPTIONAL, - IN NET_BUF *Packet, - IN EFI_IP6_HEADER *Head, - IN UINT8 *ExtHdrs, - IN UINT32 ExtHdrsLen, - IN IP6_FRAME_CALLBACK Callback, - IN VOID *Context - ) -{ - IP6_INTERFACE *IpIf; - EFI_IPv6_ADDRESS NextHop; - IP6_NEIGHBOR_ENTRY *NeighborCache; - IP6_ROUTE_CACHE_ENTRY *RouteCache; - EFI_STATUS Status; - UINT32 Mtu; - UINT32 HeadLen; - UINT16 FragmentOffset; - UINT8 *LastHeader; - UINT32 UnFragmentLen; - UINT32 UnFragmentHdrsLen; - UINT32 FragmentHdrsLen; - UINT16 *Checksum; - UINT16 PacketChecksum; - UINT16 PseudoChecksum; - UINT32 Index; - UINT32 PacketLen; - UINT32 RealExtLen; - UINT32 Offset; - NET_BUF *TmpPacket; - NET_BUF *Fragment; - UINT32 Num; - UINT8 *Buf; - EFI_IP6_HEADER *PacketHead; - IP6_ICMP_HEAD *IcmpHead; - IP6_TXTOKEN_WRAP *Wrap; - IP6_ROUTE_ENTRY *RouteEntry; - UINT8 *UpdatedExtHdrs; - UINT8 NextHeader; - UINT8 LastHeaderBackup; - BOOLEAN FragmentHeadInserted; - UINT8 *ExtHdrsBackup; - UINT8 NextHeaderBackup; - EFI_IPv6_ADDRESS Source; - EFI_IPv6_ADDRESS Destination; - - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - // - // RFC2460: Each extension header is an integer multiple of 8 octets long, - // in order to retain 8-octet alignment for subsequent headers. - // - if ((ExtHdrsLen & 0x7) != 0) { - return EFI_INVALID_PARAMETER; - } - - LastHeader = NULL; - - Ip6IsExtsValid ( - NULL, - NULL, - &Head->NextHeader, - ExtHdrs, - ExtHdrsLen, - FALSE, - NULL, - &LastHeader, - NULL, - NULL, - NULL - ); - - // - // Select an interface/source for system packet, application - // should select them itself. - // - IpIf = Interface; - if (IpIf == NULL) { - // - // IpInstance->Interface is NULL when IpInstance is configured with both stationaddress - // and destinationaddress is unspecified. - // - if (IpInstance == NULL || IpInstance->Interface == NULL) { - IpIf = Ip6SelectInterface (IpSb, &Head->DestinationAddress, &Head->SourceAddress); - if (IpInstance != NULL) { - IpInstance->Interface = IpIf; - } - } else { - IpIf = IpInstance->Interface; - } - } - - if (IpIf == NULL) { - return EFI_NO_MAPPING; - } - - // - // Update the common field in Head here. - // - Head->Version = 6; - Head->TrafficClassL = 0; - Head->TrafficClassH = 0; - - Checksum = NULL; - NextHeader = *LastHeader; - - switch (NextHeader) { - case EFI_IP_PROTO_UDP: - Packet->Udp = (EFI_UDP_HEADER *) NetbufGetByte (Packet, 0, NULL); - ASSERT (Packet->Udp != NULL); - if (Packet->Udp->Checksum == 0) { - Checksum = &Packet->Udp->Checksum; - } - break; - - case EFI_IP_PROTO_TCP: - Packet->Tcp = (TCP_HEAD *) NetbufGetByte (Packet, 0, NULL); - ASSERT (Packet->Tcp != NULL); - if (Packet->Tcp->Checksum == 0) { - Checksum = &Packet->Tcp->Checksum; - } - break; - - case IP6_ICMP: - // - // Don't send ICMP packet to an IPv6 anycast address. - // - if (Ip6IsAnycast (IpSb, &Head->DestinationAddress)) { - return EFI_INVALID_PARAMETER; - } - - IcmpHead = (IP6_ICMP_HEAD *) NetbufGetByte (Packet, 0, NULL); - ASSERT (IcmpHead != NULL); - if (IcmpHead->Checksum == 0) { - Checksum = &IcmpHead->Checksum; - } - break; - - default: - break; - } - - if (Checksum != NULL) { - // - // Calculate the checksum for upper layer protocol if it is not calculated due to lack of - // IPv6 source address. - // - PacketChecksum = NetbufChecksum (Packet); - PseudoChecksum = NetIp6PseudoHeadChecksum ( - &Head->SourceAddress, - &Head->DestinationAddress, - NextHeader, - Packet->TotalSize - ); - *Checksum = (UINT16) ~NetAddChecksum (PacketChecksum, PseudoChecksum); - } - - Status = Ip6IpSecProcessPacket ( - IpSb, - &Head, - LastHeader, // no need get the lasthead value for output - &Packet, - &ExtHdrs, - &ExtHdrsLen, - EfiIPsecOutBound, - Context - ); - - if (EFI_ERROR(Status)) { - return Status; - } - - LastHeader = NULL; - // - // Check incoming parameters. - // - if (!Ip6IsExtsValid ( - IpSb, - Packet, - &Head->NextHeader, - ExtHdrs, - ExtHdrsLen, - FALSE, - NULL, - &LastHeader, - &RealExtLen, - &UnFragmentHdrsLen, - NULL - )) { - return EFI_INVALID_PARAMETER; - } - - if ((RealExtLen & 0x7) != 0) { - return EFI_INVALID_PARAMETER; - } - - LastHeaderBackup = *LastHeader; - - // - // Perform next hop determination: - // For multicast packets, the next-hop is always the destination address and - // is considered to be on-link. - // - if (IP6_IS_MULTICAST (&Head->DestinationAddress)) { - IP6_COPY_ADDRESS (&NextHop, &Head->DestinationAddress); - } else { - // - // For unicast packets, use a combination of the Destination Cache, the Prefix List - // and the Default Router List to determine the IP address of the appropriate next hop. - // - - NeighborCache = Ip6FindNeighborEntry (IpSb, &Head->DestinationAddress); - if (NeighborCache != NULL) { - // - // Hit Neighbor Cache. - // - IP6_COPY_ADDRESS (&NextHop, &Head->DestinationAddress); - } else { - // - // Not in Neighbor Cache, check Router cache - // - RouteCache = Ip6Route (IpSb, &Head->DestinationAddress, &Head->SourceAddress); - if (RouteCache == NULL) { - return EFI_NOT_FOUND; - } - - IP6_COPY_ADDRESS (&NextHop, &RouteCache->NextHop); - Ip6FreeRouteCacheEntry (RouteCache); - } - } - - // - // Examines the Neighbor Cache for link-layer information about that neighbor. - // DO NOT create neighbor cache if neighbor is itself - when reporting ICMP error. - // - if (!IP6_IS_MULTICAST (&NextHop) && !EFI_IP6_EQUAL (&Head->DestinationAddress, &Head->SourceAddress)) { - NeighborCache = Ip6FindNeighborEntry (IpSb, &NextHop); - if (NeighborCache == NULL) { - NeighborCache = Ip6CreateNeighborEntry (IpSb, Ip6OnArpResolved, &NextHop, NULL); - - if (NeighborCache == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Send out multicast neighbor solicitation for address resolution immediately. - // - Ip6CreateSNMulticastAddr (&NeighborCache->Neighbor, &Destination); - Status = Ip6SelectSourceAddress (IpSb, &NeighborCache->Neighbor, &Source); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = Ip6SendNeighborSolicit ( - IpSb, - &Source, - &Destination, - &NeighborCache->Neighbor, - &IpSb->SnpMode.CurrentAddress - ); - if (EFI_ERROR (Status)) { - return Status; - } - - --NeighborCache->Transmit; - NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer) + 1; - } - - NeighborCache->Interface = IpIf; - } - - UpdatedExtHdrs = NULL; - ExtHdrsBackup = NULL; - NextHeaderBackup = 0; - FragmentHeadInserted = FALSE; - - // - // Check whether we received Packet Too Big message for the packet sent to the - // Destination. If yes include a Fragment Header in the subsequent packets. - // - RouteEntry = Ip6FindRouteEntry ( - IpSb->RouteTable, - &Head->DestinationAddress, - NULL - ); - if (RouteEntry != NULL) { - if ((RouteEntry->Flag & IP6_PACKET_TOO_BIG) == IP6_PACKET_TOO_BIG) { - - // - // FragmentHead is inserted after Hop-by-Hop Options header, Destination - // Options header (first occur), Routing header, and before Fragment header, - // Authentication header, Encapsulating Security Payload header, and - // Destination Options header (last occur), and upper-layer header. - // - Status = Ip6FillFragmentHeader ( - IpSb, - Head->NextHeader, - LastHeaderBackup, - ExtHdrs, - ExtHdrsLen, - 0, - &UpdatedExtHdrs - ); - if (EFI_ERROR (Status)) { - return Status; - } - - if ((ExtHdrs == NULL) && (ExtHdrsLen == 0)) { - NextHeaderBackup = Head->NextHeader; - Head->NextHeader = IP6_FRAGMENT; - } - - ExtHdrsBackup = ExtHdrs; - ExtHdrs = UpdatedExtHdrs; - ExtHdrsLen = ExtHdrsLen + sizeof (IP6_FRAGMENT_HEADER); - RealExtLen = RealExtLen + sizeof (IP6_FRAGMENT_HEADER); - - mIp6Id++; - - FragmentHeadInserted = TRUE; - } - - Ip6FreeRouteEntry (RouteEntry); - } - - // - // OK, selected the source and route, fragment the packet then send - // them. Tag each fragment other than the first one as spawn from it. - // Each extension header is an integer multiple of 8 octets long, in - // order to retain 8-octet alignment for subsequent headers. - // - Mtu = IpSb->MaxPacketSize + sizeof (EFI_IP6_HEADER); - HeadLen = sizeof (EFI_IP6_HEADER) + RealExtLen; - - if (Packet->TotalSize + HeadLen > Mtu) { - // - // Remove the inserted Fragment Header since we need fragment the packet. - // - if (FragmentHeadInserted) { - ExtHdrs = ExtHdrsBackup; - ExtHdrsLen = ExtHdrsLen - sizeof (IP6_FRAGMENT_HEADER); - - if ((ExtHdrs == NULL) && (ExtHdrsLen == 0)) { - Head->NextHeader = NextHeaderBackup; - } - } - - FragmentHdrsLen = ExtHdrsLen - UnFragmentHdrsLen; - - // - // The packet is beyond the maximum which can be described through the - // fragment offset field in Fragment header. - // - if ((((Packet->TotalSize + FragmentHdrsLen) >> 3) & (~0x1fff)) != 0) { - Status = EFI_BAD_BUFFER_SIZE; - goto Error; - } - - if (FragmentHdrsLen != 0) { - // - // Append the fragmentable extension hdrs before the upper layer payload - // to form a new NET_BUF. This NET_BUF contains all the buffer which will - // be fragmented below. - // - TmpPacket = NetbufGetFragment (Packet, 0, Packet->TotalSize, FragmentHdrsLen); - ASSERT (TmpPacket != NULL); - - // - // Allocate the space to contain the fragmentable hdrs and copy the data. - // - Buf = NetbufAllocSpace (TmpPacket, FragmentHdrsLen, TRUE); - ASSERT (Buf != NULL); - CopyMem (Buf, ExtHdrs + UnFragmentHdrsLen, FragmentHdrsLen); - - // - // Free the old Packet. - // - NetbufFree (Packet); - Packet = TmpPacket; - } - - // - // The unfragment part which appears in every fragmented IPv6 packet includes - // the IPv6 header, the unfragmentable extension hdrs and the fragment header. - // - UnFragmentLen = sizeof (EFI_IP6_HEADER) + UnFragmentHdrsLen + sizeof (IP6_FRAGMENT_HEADER); - - // - // Mtu now is the length of the fragment part in a full-length fragment. - // - Mtu = (Mtu - UnFragmentLen) & (~0x07); - Num = (Packet->TotalSize + Mtu - 1) / Mtu; - - for (Index = 0, Offset = 0, PacketLen = Mtu; Index < Num; Index++) { - // - // Get fragment from the Packet, append UnFragnmentLen spare buffer - // before the fragmented data, the corresponding data is filled in later. - // - Fragment = NetbufGetFragment (Packet, Offset, PacketLen, UnFragmentLen); - if (Fragment == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - FragmentOffset = (UINT16) ((UINT16) Offset | 0x1); - if (Index == Num - 1){ - // - // The last fragment, clear the M flag. - // - FragmentOffset &= (~0x1); - } - - Status = Ip6PrependHead ( - IpSb, - Fragment, - Head, - FragmentOffset, - ExtHdrs, - ExtHdrsLen, - LastHeaderBackup, - UnFragmentLen - ); - ASSERT (Status == EFI_SUCCESS); - - Status = Ip6SendFrame ( - IpIf, - IpInstance, - Fragment, - &NextHop, - Ip6SysPacketSent, - Packet - ); - if (EFI_ERROR (Status)) { - goto Error; - } - - // - // The last fragment of upper layer packet, update the IP6 token status. - // - if ((Index == Num -1) && (Context != NULL)) { - Wrap = (IP6_TXTOKEN_WRAP *) Context; - Wrap->Token->Status = Status; - } - - Offset += PacketLen; - PacketLen = Packet->TotalSize - Offset; - if (PacketLen > Mtu) { - PacketLen = Mtu; - } - } - - NetbufFree (Packet); - mIp6Id++; - - if (UpdatedExtHdrs != NULL) { - FreePool (UpdatedExtHdrs); - } - - return EFI_SUCCESS; - } - - // - // Need not fragment the packet, send it in one frame. - // - PacketHead = (EFI_IP6_HEADER *) NetbufAllocSpace (Packet, HeadLen, NET_BUF_HEAD); - if (PacketHead == NULL) { - Status = EFI_BAD_BUFFER_SIZE; - goto Error; - } - - CopyMem (PacketHead, Head, sizeof (EFI_IP6_HEADER)); - Packet->Ip.Ip6 = PacketHead; - - if (ExtHdrs != NULL) { - Buf = (UINT8 *) (PacketHead + 1); - CopyMem (Buf, ExtHdrs, ExtHdrsLen); - } - - if (UpdatedExtHdrs != NULL) { - // - // A Fragment Header is inserted to the packet, update the payload length. - // - PacketHead->PayloadLength = (UINT16) (NTOHS (PacketHead->PayloadLength) + - sizeof (IP6_FRAGMENT_HEADER)); - PacketHead->PayloadLength = HTONS (PacketHead->PayloadLength); - FreePool (UpdatedExtHdrs); - } - - return Ip6SendFrame ( - IpIf, - IpInstance, - Packet, - &NextHop, - Callback, - Context - ); - -Error: - if (UpdatedExtHdrs != NULL) { - FreePool (UpdatedExtHdrs); - } - Ip6CancelPacket (IpIf, Packet, Status); - return Status; -} - -/** - The filter function to find a packet and all its fragments. - The packet's fragments have their Context set to the packet. - - @param[in] Frame The frames hold by the low level interface. - @param[in] Context Context to the function, which is the packet. - - @retval TRUE This is the packet to cancel or its fragments. - @retval FALSE This is an unrelated packet. - -**/ -BOOLEAN -Ip6CancelPacketFragments ( - IN IP6_LINK_TX_TOKEN *Frame, - IN VOID *Context - ) -{ - if ((Frame->Packet == (NET_BUF *) Context) || (Frame->Context == Context)) { - return TRUE; - } - - return FALSE; -} - -/** - Remove all the frames on the interface that pass the FrameToCancel, - either queued on ARP queues or that have already been delivered to - MNP and not yet recycled. - - @param[in] Interface Interface to remove the frames from. - @param[in] IoStatus The transmit status returned to the frames' callback. - @param[in] FrameToCancel Function to select the frame to cancel; NULL to select all. - @param[in] Context Opaque parameters passed to FrameToCancel. Ignored if - FrameToCancel is NULL. - -**/ -VOID -Ip6CancelFrames ( - IN IP6_INTERFACE *Interface, - IN EFI_STATUS IoStatus, - IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, - IN VOID *Context OPTIONAL - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_LINK_TX_TOKEN *Token; - IP6_SERVICE *IpSb; - IP6_NEIGHBOR_ENTRY *ArpQue; - EFI_STATUS Status; - - IpSb = Interface->Service; - NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE); - - // - // Cancel all the pending frames on ARP requests - // - NET_LIST_FOR_EACH_SAFE (Entry, Next, &Interface->ArpQues) { - ArpQue = NET_LIST_USER_STRUCT (Entry, IP6_NEIGHBOR_ENTRY, ArpList); - - Status = Ip6FreeNeighborEntry ( - IpSb, - ArpQue, - FALSE, - FALSE, - IoStatus, - FrameToCancel, - Context - ); - ASSERT_EFI_ERROR (Status); - } - - // - // Cancel all the frames that have been delivered to MNP - // but not yet recycled. - // - NET_LIST_FOR_EACH_SAFE (Entry, Next, &Interface->SentFrames) { - Token = NET_LIST_USER_STRUCT (Entry, IP6_LINK_TX_TOKEN, Link); - - if ((FrameToCancel == NULL) || FrameToCancel (Token, Context)) { - IpSb->Mnp->Cancel (IpSb->Mnp, &Token->MnpToken); - } - } -} - -/** - Cancel the Packet and all its fragments. - - @param[in] IpIf The interface from which the Packet is sent. - @param[in] Packet The Packet to cancel. - @param[in] IoStatus The status returns to the sender. - -**/ -VOID -Ip6CancelPacket ( - IN IP6_INTERFACE *IpIf, - IN NET_BUF *Packet, - IN EFI_STATUS IoStatus - ) -{ - Ip6CancelFrames (IpIf, IoStatus, Ip6CancelPacketFragments, Packet); -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Output.h b/Core/NetworkPkg/Ip6Dxe/Ip6Output.h deleted file mode 100644 index 80abe858e6..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Output.h +++ /dev/null @@ -1,141 +0,0 @@ -/** @file - The internal functions and routines to transmit the IP6 packet. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_OUTPUT_H__ -#define __EFI_IP6_OUTPUT_H__ - -extern UINT32 mIp6Id; - -/** - Output all the available source addresses to the list entry head SourceList. The - number of source addresses are also returned. - - @param[in] IpSb Points to a IP6 service binding instance. - @param[in] Destination The IPv6 destination address. - @param[out] Source The selected IPv6 source address according to - the Destination. - - @retval EFI_SUCCESS The source addresses were copied to the list entry - head SourceList. - @retval EFI_NO_MAPPING The IPv6 stack is not auto configured. - -**/ -EFI_STATUS -Ip6SelectSourceAddress ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Destination, - OUT EFI_IPv6_ADDRESS *Source - ); - -/** - The default callback function for system generated packet. - It will free the packet. - - @param[in] Packet The packet that transmitted. - @param[in] IoStatus The result of the transmission: succeeded or failed. - @param[in] LinkFlag Not used when transmission. Check IP6_FRAME_CALLBACK - for reference. - @param[in] Context The context provided by us. - -**/ -VOID -Ip6SysPacketSent ( - NET_BUF *Packet, - EFI_STATUS IoStatus, - UINT32 LinkFlag, - VOID *Context - ); - -/** - Transmit an IP6 packet. The packet comes either from the IP6 - child's consumer (IpInstance != NULL) or the IP6 driver itself - (IpInstance == NULL). It will route the packet, fragment it, - then transmit all the fragments through an interface. - - @param[in] IpSb The IP6 service instance to transmit the packet. - @param[in] Interface The IP6 interface to transmit the packet. Ignored - if NULL. - @param[in] IpInstance The IP6 child that issues the transmission. It is - NULL if the packet is from the system. - @param[in] Packet The user data to send, excluding the IP header. - @param[in] Head The caller supplied header. The caller should set - the following header fields: NextHeader, HopLimit, - Src, Dest, FlowLabel, PayloadLength. This function - will fill in the Ver, TrafficClass. - @param[in] ExtHdrs The extension headers to append to the IPv6 basic - header. - @param[in] ExtHdrsLen The length of the extension headers. - @param[in] Callback The callback function to issue when transmission - completed. - @param[in] Context The opaque context for the callback. - - @retval EFI_INVALID_PARAMETER Any input parameter or the packet is invalid. - @retval EFI_NO_MAPPING There is no interface to the destination. - @retval EFI_NOT_FOUND There is no route to the destination. - @retval EFI_SUCCESS The packet successfully transmitted. - @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lack of - resources. - @retval Others Failed to transmit the packet. - -**/ -EFI_STATUS -Ip6Output ( - IN IP6_SERVICE *IpSb, - IN IP6_INTERFACE *Interface OPTIONAL, - IN IP6_PROTOCOL *IpInstance OPTIONAL, - IN NET_BUF *Packet, - IN EFI_IP6_HEADER *Head, - IN UINT8 *ExtHdrs, - IN UINT32 ExtHdrsLen, - IN IP6_FRAME_CALLBACK Callback, - IN VOID *Context - ); - -/** - Remove all the frames on the interface that pass the FrameToCancel, - either queued on ARP queues, or that have already been delivered to - MNP and not yet recycled. - - @param[in] Interface Interface to remove the frames from. - @param[in] IoStatus The transmit status returned to the frames' callback. - @param[in] FrameToCancel Function to select the frame to cancel; NULL to select all. - @param[in] Context Opaque parameters passed to FrameToCancel. Ignored if - FrameToCancel is NULL. - -**/ -VOID -Ip6CancelFrames ( - IN IP6_INTERFACE *Interface, - IN EFI_STATUS IoStatus, - IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, - IN VOID *Context OPTIONAL - ); - -/** - Cancel the Packet and all its fragments. - - @param[in] IpIf The interface from which the Packet is sent. - @param[in] Packet The Packet to cancel. - @param[in] IoStatus The status returns to the sender. - -**/ -VOID -Ip6CancelPacket ( - IN IP6_INTERFACE *IpIf, - IN NET_BUF *Packet, - IN EFI_STATUS IoStatus - ); - -#endif diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Route.c b/Core/NetworkPkg/Ip6Dxe/Ip6Route.c deleted file mode 100644 index 3e47fa4cc6..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Route.c +++ /dev/null @@ -1,635 +0,0 @@ -/** @file - The functions and routines to handle the route caches and route table. - - Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "Ip6Impl.h" - -/** - This is the worker function for IP6_ROUTE_CACHE_HASH(). It calculates the value - as the index of the route cache bucket according to the prefix of two IPv6 addresses. - - @param[in] Ip1 The IPv6 address. - @param[in] Ip2 The IPv6 address. - - @return The hash value of the prefix of two IPv6 addresses. - -**/ -UINT32 -Ip6RouteCacheHash ( - IN EFI_IPv6_ADDRESS *Ip1, - IN EFI_IPv6_ADDRESS *Ip2 - ) -{ - UINT32 Prefix1; - UINT32 Prefix2; - - Prefix1 = *((UINT32 *) ((UINTN *) (Ip1))); - Prefix2 = *((UINT32 *) ((UINTN *) (Ip2))); - - return ((UINT32) (Prefix1 ^ Prefix2) % IP6_ROUTE_CACHE_HASH_SIZE); -} - -/** - Allocate a route entry then initialize it with the Destination/PrefixLength - and Gateway. - - @param[in] Destination The IPv6 destination address. This is an optional - parameter that may be NULL. - @param[in] PrefixLength The destination network's prefix length. - @param[in] GatewayAddress The next hop address. This is an optional parameter - that may be NULL. - - @return NULL if failed to allocate memeory; otherwise, the newly created route entry. - -**/ -IP6_ROUTE_ENTRY * -Ip6CreateRouteEntry ( - IN EFI_IPv6_ADDRESS *Destination OPTIONAL, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL - ) -{ - IP6_ROUTE_ENTRY *RtEntry; - - RtEntry = AllocateZeroPool (sizeof (IP6_ROUTE_ENTRY)); - - if (RtEntry == NULL) { - return NULL; - } - - RtEntry->RefCnt = 1; - RtEntry->Flag = 0; - RtEntry->PrefixLength = PrefixLength; - - if (Destination != NULL) { - IP6_COPY_ADDRESS (&RtEntry->Destination, Destination); - } - - if (GatewayAddress != NULL) { - IP6_COPY_ADDRESS (&RtEntry->NextHop, GatewayAddress); - } - - return RtEntry; -} - -/** - Free the route table entry. It is reference counted. - - @param[in, out] RtEntry The route entry to free. - -**/ -VOID -Ip6FreeRouteEntry ( - IN OUT IP6_ROUTE_ENTRY *RtEntry - ) -{ - ASSERT ((RtEntry != NULL) && (RtEntry->RefCnt > 0)); - - if (--RtEntry->RefCnt == 0) { - FreePool (RtEntry); - } -} - -/** - Search the route table for a most specific match to the Dst. It searches - from the longest route area (prefix length == 128) to the shortest route area - (default routes). In each route area, it will first search the instance's - route table, then the default route table. This is required per the following - requirements: - 1. IP search the route table for a most specific match. - 2. The local route entries have precedence over the default route entry. - - @param[in] RtTable The route table to search from. - @param[in] Destination The destionation address to search. If NULL, search - the route table by NextHop. - @param[in] NextHop The next hop address. If NULL, search the route table - by Destination. - - @return NULL if no route matches the Dst. Otherwise, the point to the - @return most specific route to the Dst. - -**/ -IP6_ROUTE_ENTRY * -Ip6FindRouteEntry ( - IN IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Destination OPTIONAL, - IN EFI_IPv6_ADDRESS *NextHop OPTIONAL - ) -{ - LIST_ENTRY *Entry; - IP6_ROUTE_ENTRY *RtEntry; - INTN Index; - - ASSERT (Destination != NULL || NextHop != NULL); - - RtEntry = NULL; - - for (Index = IP6_PREFIX_MAX; Index >= 0; Index--) { - NET_LIST_FOR_EACH (Entry, &RtTable->RouteArea[Index]) { - RtEntry = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_ENTRY, Link); - - if (Destination != NULL) { - if (NetIp6IsNetEqual (Destination, &RtEntry->Destination, RtEntry->PrefixLength)) { - NET_GET_REF (RtEntry); - return RtEntry; - } - } else if (NextHop != NULL) { - if (NetIp6IsNetEqual (NextHop, &RtEntry->NextHop, RtEntry->PrefixLength)) { - NET_GET_REF (RtEntry); - return RtEntry; - } - } - - } - } - - return NULL; -} - -/** - Allocate and initialize a IP6 route cache entry. - - @param[in] Dst The destination address. - @param[in] Src The source address. - @param[in] GateWay The next hop address. - @param[in] Tag The tag from the caller. This marks all the cache entries - spawned from one route table entry. - - @return NULL if failed to allocate memory for the cache. Otherwise, point - to the created route cache entry. - -**/ -IP6_ROUTE_CACHE_ENTRY * -Ip6CreateRouteCacheEntry ( - IN EFI_IPv6_ADDRESS *Dst, - IN EFI_IPv6_ADDRESS *Src, - IN EFI_IPv6_ADDRESS *GateWay, - IN UINTN Tag - ) -{ - IP6_ROUTE_CACHE_ENTRY *RtCacheEntry; - - RtCacheEntry = AllocatePool (sizeof (IP6_ROUTE_CACHE_ENTRY)); - - if (RtCacheEntry == NULL) { - return NULL; - } - - RtCacheEntry->RefCnt = 1; - RtCacheEntry->Tag = Tag; - - IP6_COPY_ADDRESS (&RtCacheEntry->Destination, Dst); - IP6_COPY_ADDRESS (&RtCacheEntry->Source, Src); - IP6_COPY_ADDRESS (&RtCacheEntry->NextHop, GateWay); - - return RtCacheEntry; -} - -/** - Free the route cache entry. It is reference counted. - - @param[in, out] RtCacheEntry The route cache entry to free. - -**/ -VOID -Ip6FreeRouteCacheEntry ( - IN OUT IP6_ROUTE_CACHE_ENTRY *RtCacheEntry - ) -{ - ASSERT (RtCacheEntry->RefCnt > 0); - - if (--RtCacheEntry->RefCnt == 0) { - FreePool (RtCacheEntry); - } -} - -/** - Find a route cache with the destination and source address. This is - used by the ICMPv6 redirect messasge process. - - @param[in] RtTable The route table to search the cache for. - @param[in] Dest The destination address. - @param[in] Src The source address. - - @return NULL if no route entry to the (Dest, Src). Otherwise, the pointer - to the correct route cache entry. - -**/ -IP6_ROUTE_CACHE_ENTRY * -Ip6FindRouteCache ( - IN IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Dest, - IN EFI_IPv6_ADDRESS *Src - ) -{ - LIST_ENTRY *Entry; - IP6_ROUTE_CACHE_ENTRY *RtCacheEntry; - UINT32 Index; - - Index = IP6_ROUTE_CACHE_HASH (Dest, Src); - - NET_LIST_FOR_EACH (Entry, &RtTable->Cache.CacheBucket[Index]) { - RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_CACHE_ENTRY, Link); - - if (EFI_IP6_EQUAL (Dest, &RtCacheEntry->Destination)&& EFI_IP6_EQUAL (Src, &RtCacheEntry->Source)) { - NET_GET_REF (RtCacheEntry); - return RtCacheEntry; - } - } - - return NULL; -} - -/** - Build an array of EFI_IP6_ROUTE_TABLE to be returned to the caller. The number - of EFI_IP6_ROUTE_TABLE is also returned. - - @param[in] RouteTable The pointer of IP6_ROUTE_TABLE internal used. - @param[out] EfiRouteCount The number of returned route entries. - @param[out] EfiRouteTable The pointer to the array of EFI_IP6_ROUTE_TABLE. - If NULL, only the route entry count is returned. - - @retval EFI_SUCCESS The EFI_IP6_ROUTE_TABLE successfully built. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the route table. - -**/ -EFI_STATUS -Ip6BuildEfiRouteTable ( - IN IP6_ROUTE_TABLE *RouteTable, - OUT UINT32 *EfiRouteCount, - OUT EFI_IP6_ROUTE_TABLE **EfiRouteTable OPTIONAL - ) -{ - LIST_ENTRY *Entry; - IP6_ROUTE_ENTRY *RtEntry; - EFI_IP6_ROUTE_TABLE *EfiTable; - UINT32 Count; - INT32 Index; - - ASSERT (EfiRouteCount != NULL); - - Count = RouteTable->TotalNum; - *EfiRouteCount = Count; - - if ((EfiRouteTable == NULL) || (Count == 0)) { - return EFI_SUCCESS; - } - - if (*EfiRouteTable == NULL) { - *EfiRouteTable = AllocatePool (sizeof (EFI_IP6_ROUTE_TABLE) * Count); - if (*EfiRouteTable == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - - EfiTable = *EfiRouteTable; - - // - // Copy the route entry to EFI route table. - // - Count = 0; - - for (Index = IP6_PREFIX_MAX; Index >= 0; Index--) { - - NET_LIST_FOR_EACH (Entry, &(RouteTable->RouteArea[Index])) { - RtEntry = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_ENTRY, Link); - - Ip6CopyAddressByPrefix ( - &EfiTable[Count].Destination, - &RtEntry->Destination, - RtEntry->PrefixLength - ); - - IP6_COPY_ADDRESS (&EfiTable[Count].Gateway, &RtEntry->NextHop); - EfiTable[Count].PrefixLength = RtEntry->PrefixLength; - - Count++; - } - } - - ASSERT (Count == RouteTable->TotalNum); - - return EFI_SUCCESS; -} - -/** - Create an empty route table. This includes its internal route cache. - - @return NULL if failed to allocate memory for the route table. Otherwise, - the point to newly created route table. - -**/ -IP6_ROUTE_TABLE * -Ip6CreateRouteTable ( - VOID - ) -{ - IP6_ROUTE_TABLE *RtTable; - UINT32 Index; - - RtTable = AllocatePool (sizeof (IP6_ROUTE_TABLE)); - if (RtTable == NULL) { - return NULL; - } - - RtTable->RefCnt = 1; - RtTable->TotalNum = 0; - - for (Index = 0; Index <= IP6_PREFIX_MAX; Index++) { - InitializeListHead (&RtTable->RouteArea[Index]); - } - - for (Index = 0; Index < IP6_ROUTE_CACHE_HASH_SIZE; Index++) { - InitializeListHead (&RtTable->Cache.CacheBucket[Index]); - RtTable->Cache.CacheNum[Index] = 0; - } - - return RtTable; -} - -/** - Free the route table and its associated route cache. Route - table is reference counted. - - @param[in, out] RtTable The route table to free. - -**/ -VOID -Ip6CleanRouteTable ( - IN OUT IP6_ROUTE_TABLE *RtTable - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_ROUTE_ENTRY *RtEntry; - IP6_ROUTE_CACHE_ENTRY *RtCacheEntry; - UINT32 Index; - - ASSERT (RtTable->RefCnt > 0); - - if (--RtTable->RefCnt > 0) { - return ; - } - - // - // Free all the route table entry and its route cache. - // - for (Index = 0; Index <= IP6_PREFIX_MAX; Index++) { - NET_LIST_FOR_EACH_SAFE (Entry, Next, &RtTable->RouteArea[Index]) { - RtEntry = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_ENTRY, Link); - RemoveEntryList (Entry); - Ip6FreeRouteEntry (RtEntry); - } - } - - for (Index = 0; Index < IP6_ROUTE_CACHE_HASH_SIZE; Index++) { - NET_LIST_FOR_EACH_SAFE (Entry, Next, &RtTable->Cache.CacheBucket[Index]) { - RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_CACHE_ENTRY, Link); - RemoveEntryList (Entry); - Ip6FreeRouteCacheEntry (RtCacheEntry); - } - } - - FreePool (RtTable); -} - -/** - Remove all the cache entries bearing the Tag. When a route cache - entry is created, it is tagged with the address of route entry - from which it is spawned. When a route entry is deleted, the cache - entries spawned from it are also deleted. - - @param[in] RtCache Route cache to remove the entries from. - @param[in] Tag The Tag of the entries to remove. - -**/ -VOID -Ip6PurgeRouteCache ( - IN IP6_ROUTE_CACHE *RtCache, - IN UINTN Tag - ) -{ - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_ROUTE_CACHE_ENTRY *RtCacheEntry; - UINT32 Index; - - for (Index = 0; Index < IP6_ROUTE_CACHE_HASH_SIZE; Index++) { - NET_LIST_FOR_EACH_SAFE (Entry, Next, &RtCache->CacheBucket[Index]) { - - RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_CACHE_ENTRY, Link); - - if (RtCacheEntry->Tag == Tag) { - RemoveEntryList (Entry); - Ip6FreeRouteCacheEntry (RtCacheEntry); - } - } - } -} - -/** - Add a route entry to the route table. It is the help function for EfiIp6Routes. - - @param[in, out] RtTable Route table to add route to. - @param[in] Destination The destination of the network. - @param[in] PrefixLength The PrefixLength of the destination. - @param[in] GatewayAddress The next hop address. - - @retval EFI_ACCESS_DENIED The same route already exists. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the entry. - @retval EFI_SUCCESS The route was added successfully. - -**/ -EFI_STATUS -Ip6AddRoute ( - IN OUT IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Destination, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *GatewayAddress - ) -{ - LIST_ENTRY *ListHead; - LIST_ENTRY *Entry; - IP6_ROUTE_ENTRY *Route; - - ListHead = &RtTable->RouteArea[PrefixLength]; - - // - // First check whether the route exists - // - NET_LIST_FOR_EACH (Entry, ListHead) { - Route = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_ENTRY, Link); - - if (NetIp6IsNetEqual (Destination, &Route->Destination, PrefixLength) && - EFI_IP6_EQUAL (GatewayAddress, &Route->NextHop)) { - return EFI_ACCESS_DENIED; - } - } - - // - // Create a route entry and insert it to the route area. - // - Route = Ip6CreateRouteEntry (Destination, PrefixLength, GatewayAddress); - - if (Route == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (NetIp6IsUnspecifiedAddr (GatewayAddress)) { - Route->Flag = IP6_DIRECT_ROUTE; - } - - InsertHeadList (ListHead, &Route->Link); - RtTable->TotalNum++; - - return EFI_SUCCESS; -} - -/** - Remove a route entry and all the route caches spawn from it. - It is the help function for EfiIp6Routes. - - @param[in, out] RtTable The route table to remove the route from. - @param[in] Destination The destination network. - @param[in] PrefixLength The PrefixLength of the Destination. - @param[in] GatewayAddress The next hop address. - - @retval EFI_SUCCESS The route entry was successfully removed. - @retval EFI_NOT_FOUND There is no route entry in the table with that - property. - -**/ -EFI_STATUS -Ip6DelRoute ( - IN OUT IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Destination, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *GatewayAddress - ) -{ - LIST_ENTRY *ListHead; - LIST_ENTRY *Entry; - LIST_ENTRY *Next; - IP6_ROUTE_ENTRY *Route; - UINT32 TotalNum; - - ListHead = &RtTable->RouteArea[PrefixLength]; - TotalNum = RtTable->TotalNum; - - NET_LIST_FOR_EACH_SAFE (Entry, Next, ListHead) { - Route = NET_LIST_USER_STRUCT (Entry, IP6_ROUTE_ENTRY, Link); - - if (Destination != NULL && !NetIp6IsNetEqual (Destination, &Route->Destination, PrefixLength)) { - continue; - } - if (GatewayAddress != NULL && !EFI_IP6_EQUAL (GatewayAddress, &Route->NextHop)) { - continue; - } - - Ip6PurgeRouteCache (&RtTable->Cache, (UINTN) Route); - RemoveEntryList (Entry); - Ip6FreeRouteEntry (Route); - - ASSERT (RtTable->TotalNum > 0); - RtTable->TotalNum--; - } - - return TotalNum == RtTable->TotalNum ? EFI_NOT_FOUND : EFI_SUCCESS; -} - -/** - Search the route table to route the packet. Return/create a route - cache if there is a route to the destination. - - @param[in] IpSb The IP6 service data. - @param[in] Dest The destination address to search for. - @param[in] Src The source address to search for. - - @return NULL if it failed to route the packet. Otherwise, a route cache - entry that can be used to route packets. - -**/ -IP6_ROUTE_CACHE_ENTRY * -Ip6Route ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Dest, - IN EFI_IPv6_ADDRESS *Src - ) -{ - IP6_ROUTE_TABLE *RtTable; - LIST_ENTRY *ListHead; - IP6_ROUTE_CACHE_ENTRY *RtCacheEntry; - IP6_ROUTE_ENTRY *RtEntry; - EFI_IPv6_ADDRESS NextHop; - UINT32 Index; - - RtTable = IpSb->RouteTable; - - ASSERT (RtTable != NULL); - - // - // Search the destination cache in IP6_ROUTE_TABLE. - // - Index = IP6_ROUTE_CACHE_HASH (Dest, Src); - ListHead = &RtTable->Cache.CacheBucket[Index]; - - RtCacheEntry = Ip6FindRouteCache (RtTable, Dest, Src); - - // - // If found, promote the cache entry to the head of the hash bucket. - // - if (RtCacheEntry != NULL) { - RemoveEntryList (&RtCacheEntry->Link); - InsertHeadList (ListHead, &RtCacheEntry->Link); - return RtCacheEntry; - } - - // - // Search the route table for the most specific route - // - RtEntry = Ip6FindRouteEntry (RtTable, Dest, NULL); - if (RtEntry == NULL) { - return NULL; - } - - // - // Found a route to the Dest, if it is a direct route, the packet - // will be send directly to the destination, such as for connected - // network. Otherwise, it is an indirect route, the packet will be - // send the next hop router. - // - if ((RtEntry->Flag & IP6_DIRECT_ROUTE) == IP6_DIRECT_ROUTE) { - IP6_COPY_ADDRESS (&NextHop, Dest); - } else { - IP6_COPY_ADDRESS (&NextHop, &RtEntry->NextHop); - } - - Ip6FreeRouteEntry (RtEntry); - - // - // Create a route cache entry, and tag it as spawned from this route entry - // - RtCacheEntry = Ip6CreateRouteCacheEntry (Dest, Src, &NextHop, (UINTN) RtEntry); - - if (RtCacheEntry == NULL) { - return NULL; - } - - InsertHeadList (ListHead, &RtCacheEntry->Link); - NET_GET_REF (RtCacheEntry); - RtTable->Cache.CacheNum[Index]++; - - return RtCacheEntry; -} - diff --git a/Core/NetworkPkg/Ip6Dxe/Ip6Route.h b/Core/NetworkPkg/Ip6Dxe/Ip6Route.h deleted file mode 100644 index d81e07b19c..0000000000 --- a/Core/NetworkPkg/Ip6Dxe/Ip6Route.h +++ /dev/null @@ -1,299 +0,0 @@ -/** @file - EFI IP6 route table and route cache table defintions. - - Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which accompanies this distribution. The full text of the license may be found at - http://opensource.org/licenses/bsd-license.php. - - THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#ifndef __EFI_IP6_ROUTE_H__ -#define __EFI_IP6_ROUTE_H__ - -#define IP6_DIRECT_ROUTE 0x00000001 -#define IP6_PACKET_TOO_BIG 0x00000010 - -#define IP6_ROUTE_CACHE_HASH_SIZE 31 -/// -/// Max NO. of cache entry per hash bucket -/// -#define IP6_ROUTE_CACHE_MAX 32 - -#define IP6_ROUTE_CACHE_HASH(Ip1, Ip2) Ip6RouteCacheHash ((Ip1), (Ip2)) - -typedef struct { - LIST_ENTRY Link; - INTN RefCnt; - UINT32 Flag; - UINT8 PrefixLength; - EFI_IPv6_ADDRESS Destination; - EFI_IPv6_ADDRESS NextHop; -} IP6_ROUTE_ENTRY; - -typedef struct { - LIST_ENTRY Link; - INTN RefCnt; - UINTN Tag; - EFI_IPv6_ADDRESS Destination; - EFI_IPv6_ADDRESS Source; - EFI_IPv6_ADDRESS NextHop; -} IP6_ROUTE_CACHE_ENTRY; - -typedef struct { - LIST_ENTRY CacheBucket[IP6_ROUTE_CACHE_HASH_SIZE]; - UINT8 CacheNum[IP6_ROUTE_CACHE_HASH_SIZE]; -} IP6_ROUTE_CACHE; - -// -// Each IP6 instance has its own route table. Each ServiceBinding -// instance has a default route table and default address. -// -// All the route table entries with the same prefix length are linked -// together in one route area. For example, RouteArea[0] contains -// the default routes. A route table also contains a route cache. -// - -typedef struct _IP6_ROUTE_TABLE { - INTN RefCnt; - UINT32 TotalNum; - LIST_ENTRY RouteArea[IP6_PREFIX_NUM]; - IP6_ROUTE_CACHE Cache; -} IP6_ROUTE_TABLE; - -/** - This is the worker function for IP6_ROUTE_CACHE_HASH(). It calculates the value - as the index of the route cache bucket according to the prefix of two IPv6 addresses. - - @param[in] Ip1 The IPv6 address. - @param[in] Ip2 The IPv6 address. - - @return The hash value of the prefix of two IPv6 addresses. - -**/ -UINT32 -Ip6RouteCacheHash ( - IN EFI_IPv6_ADDRESS *Ip1, - IN EFI_IPv6_ADDRESS *Ip2 - ); - -/** - Allocate and initialize an IP6 route cache entry. - - @param[in] Dst The destination address. - @param[in] Src The source address. - @param[in] GateWay The next hop address. - @param[in] Tag The tag from the caller. This marks all the cache entries - spawned from one route table entry. - - @return NULL if it failed to allocate memory for the cache. Otherwise, point - to the created route cache entry. - -**/ -IP6_ROUTE_CACHE_ENTRY * -Ip6CreateRouteCacheEntry ( - IN EFI_IPv6_ADDRESS *Dst, - IN EFI_IPv6_ADDRESS *Src, - IN EFI_IPv6_ADDRESS *GateWay, - IN UINTN Tag - ); - -/** - Free the route cache entry. It is reference counted. - - @param[in, out] RtCacheEntry The route cache entry to free. - -**/ -VOID -Ip6FreeRouteCacheEntry ( - IN OUT IP6_ROUTE_CACHE_ENTRY *RtCacheEntry - ); - -/** - Find a route cache with the destination and source address. This is - used by the ICMPv6 redirect messasge process. - - @param[in] RtTable The route table to search the cache for. - @param[in] Dest The destination address. - @param[in] Src The source address. - - @return NULL if no route entry to the (Dest, Src). Otherwise, point - to the correct route cache entry. - -**/ -IP6_ROUTE_CACHE_ENTRY * -Ip6FindRouteCache ( - IN IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Dest, - IN EFI_IPv6_ADDRESS *Src - ); - -/** - Build a array of EFI_IP6_ROUTE_TABLE to be returned to the caller. The number - of EFI_IP6_ROUTE_TABLE is also returned. - - @param[in] RouteTable The pointer of IP6_ROUTE_TABLE internal used. - @param[out] EfiRouteCount The number of returned route entries. - @param[out] EfiRouteTable The pointer to the array of EFI_IP6_ROUTE_TABLE. - If NULL, only the route entry count is returned. - - @retval EFI_SUCCESS The EFI_IP6_ROUTE_TABLE successfully built. - @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the route table. - -**/ -EFI_STATUS -Ip6BuildEfiRouteTable ( - IN IP6_ROUTE_TABLE *RouteTable, - OUT UINT32 *EfiRouteCount, - OUT EFI_IP6_ROUTE_TABLE **EfiRouteTable OPTIONAL - ); - -/** - Create an empty route table, includes its internal route cache. - - @return NULL if failed to allocate memory for the route table. Otherwise, - the point to newly created route table. - -**/ -IP6_ROUTE_TABLE * -Ip6CreateRouteTable ( - VOID - ); - -/** - Free the route table and its associated route cache. Route - table is reference counted. - - @param[in, out] RtTable The route table to free. - -**/ -VOID -Ip6CleanRouteTable ( - IN OUT IP6_ROUTE_TABLE *RtTable - ); - -/** - Allocate a route entry then initialize it with the Destination/PrefixLength - and Gateway. - - @param[in] Destination The IPv6 destination address. This is an optional - parameter that may be NULL. - @param[in] PrefixLength The destination network's prefix length. - @param[in] GatewayAddress The next hop address. This is optional parameter - that may be NULL. - - @return NULL if it failed to allocate memeory. Otherwise, the newly created route entry. - -**/ -IP6_ROUTE_ENTRY * -Ip6CreateRouteEntry ( - IN EFI_IPv6_ADDRESS *Destination OPTIONAL, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL - ); - -/** - Search the route table for a most specific match to the Dst. It searches - from the longest route area (prefix length == 128) to the shortest route area - (default routes). In each route area, it will first search the instance's - route table, then the default route table. This is required per the following - requirements: - 1. IP search the route table for a most specific match. - 2. The local route entries have precedence over the default route entry. - - @param[in] RtTable The route table to search from. - @param[in] Destination The destionation address to search. If NULL, search - the route table by NextHop. - @param[in] NextHop The next hop address. If NULL, search the route table - by Destination. - - @return NULL if no route matches the Dst. Otherwise the point to the - most specific route to the Dst. - -**/ -IP6_ROUTE_ENTRY * -Ip6FindRouteEntry ( - IN IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Destination OPTIONAL, - IN EFI_IPv6_ADDRESS *NextHop OPTIONAL - ); - -/** - Free the route table entry. It is reference counted. - - @param[in, out] RtEntry The route entry to free. - -**/ -VOID -Ip6FreeRouteEntry ( - IN OUT IP6_ROUTE_ENTRY *RtEntry - ); - -/** - Add a route entry to the route table. It is the help function for EfiIp6Routes. - - @param[in, out] RtTable Route table to add route to. - @param[in] Destination The destination of the network. - @param[in] PrefixLength The PrefixLength of the destination. - @param[in] GatewayAddress The next hop address. - - @retval EFI_ACCESS_DENIED The same route already exists. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the entry. - @retval EFI_SUCCESS The route was added successfully. - -**/ -EFI_STATUS -Ip6AddRoute ( - IN OUT IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Destination, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *GatewayAddress - ); - -/** - Remove a route entry and all the route caches spawn from it. - It is the help function for EfiIp6Routes. - - @param[in, out] RtTable The route table to remove the route from. - @param[in] Destination The destination network. - @param[in] PrefixLength The PrefixLength of the Destination. - @param[in] GatewayAddress The next hop address. - - @retval EFI_SUCCESS Successfully removed the route entry. - @retval EFI_NOT_FOUND There is no route entry in the table with that - properity. - -**/ -EFI_STATUS -Ip6DelRoute ( - IN OUT IP6_ROUTE_TABLE *RtTable, - IN EFI_IPv6_ADDRESS *Destination, - IN UINT8 PrefixLength, - IN EFI_IPv6_ADDRESS *GatewayAddress - ); - -/** - Search the route table to route the packet. Return/create a route - cache if there is a route to the destination. - - @param[in] IpSb The IP6 service data. - @param[in] Dest The destination address to search for. - @param[in] Src The source address to search for. - - @return NULL if failed to route packet. Otherwise, a route cache - entry that can be used to route packet. - -**/ -IP6_ROUTE_CACHE_ENTRY * -Ip6Route ( - IN IP6_SERVICE *IpSb, - IN EFI_IPv6_ADDRESS *Dest, - IN EFI_IPv6_ADDRESS *Src - ); - -#endif -- cgit v1.2.3