4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Implementation of EFI_IP6_PROTOCOL protocol interfaces.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync http://opensource.org/licenses/bsd-license.php.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#include "Ip6Impl.h"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_IPSEC2_PROTOCOL *mIpSec = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_IP6_PROTOCOL mEfiIp6ProtocolTemplete = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6GetModeData,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Configure,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Groups,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Routes,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Neighbors,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Transmit,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Receive,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Cancel,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Poll
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The GetModeData() function returns the current operational mode data for this driver instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The data fields in EFI_IP6_MODE_DATA are read only. This function is used optionally to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync retrieve the operational mode data of underlying networks or drivers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Ip6ModeData Pointer to the EFI IPv6 Protocol mode data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] MnpConfigData Pointer to the managed network configuration data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] SnpModeData Pointer to the simple network mode data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The operation completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The required mode data could not be allocated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6GetModeData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_IP6_MODE_DATA *Ip6ModeData OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_INTERFACE *IpIf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_CONFIG_DATA *Config;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (This == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIf = IpInstance->Interface;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // IsStarted is "whether the EfiIp6Configure has been called".
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // IsConfigured is "whether the station address has been configured"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->IsStarted = (BOOLEAN) (IpInstance->State == IP6_STATE_CONFIGED);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->MaxPacketSize = IpSb->MaxPacketSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&Ip6ModeData->ConfigData, &IpInstance->ConfigData, sizeof (EFI_IP6_CONFIG_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->IsConfigured = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->AddressCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->AddressList = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->GroupCount = IpInstance->GroupCount;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->GroupTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->RouteCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->RouteTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->NeighborCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->NeighborCache = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->PrefixCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->PrefixTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->IcmpTypeCount = 23;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->IcmpTypeList = AllocateCopyPool (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->IcmpTypeCount * sizeof (EFI_IP6_ICMP_TYPE),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mIp6SupportedIcmp
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->IcmpTypeList == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Error;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the currently configured IPv6 addresses and corresponding prefix lengths.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6BuildEfiAddressList (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->AddressCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->AddressList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Error;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the current station address for this IP child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If UseAnyStationAddress is set to TRUE, IP6 driver will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // select a source address from its address list. Otherwise use the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // StationAddress in config data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->IsStarted) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config = &Ip6ModeData->ConfigData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpIf->Configured || NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->IsConfigured = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->IsConfigured = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Build a EFI route table for user from the internal route table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6BuildEfiRouteTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RouteTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->RouteCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->RouteTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Error;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->IsConfigured) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the joined multicast group addresses.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->GroupCount != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ModeData->GroupTable = AllocateCopyPool (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->GroupCount * sizeof (EFI_IPv6_ADDRESS),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->GroupList
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->GroupTable == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Error;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the neighbor cache entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6BuildEfiNeighborCache (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->NeighborCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->NeighborCache
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Error;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return the prefix table entries
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6BuildPrefixTable (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->PrefixCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Ip6ModeData->PrefixTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Error;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get fresh mode data from MNP, since underlying media status may change
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpSb->Mnp->GetModeData (IpSb->Mnp, MnpConfigData, SnpModeData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncError:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->AddressList != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData->AddressList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->GroupTable != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData->GroupTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->RouteTable != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData->RouteTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->NeighborCache != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData->NeighborCache);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->PrefixTable != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData->PrefixTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ModeData->IcmpTypeList != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Ip6ModeData->IcmpTypeList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Validate that Ipv6 address is OK to be used as station address or next hop address/ neighbor.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP6 service instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Ip The IPv6 address to validate.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Flag If TRUE, validate if the address is OK to be used
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync as station address. If FALSE, validate if the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address is OK to be used as the next hop address/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync neighbor.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The Ip address is valid and could be used.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE Invalid Ip address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6IsValidAddress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *Ip,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN Flag
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!NetIp6IsUnspecifiedAddr (Ip)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!NetIp6IsValidUnicast(Ip)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6IsOneOfSetAddress (IpSb, Ip, NULL, NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Flag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Flag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return (BOOLEAN) !Flag;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Validate whether the value of protocol is illegal or not. Protocol is the 'Next Header' field
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in the last IPv6 extension header, or basic IPv6 header is there's no extension header.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Protocol Default value of 'Next Header'
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval TRUE The protocol is illegal.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval FALSE The protocol is legal.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOLEAN
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6IsIllegalProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 Protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Protocol == IP6_HOP_BY_HOP || Protocol == EFI_IP_PROTO_ICMP || Protocol == IP4_PROTO_IGMP) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Protocol == 41 || Protocol == 43 || Protocol == 44 || Protocol == 59 || Protocol == 60 || Protocol == 124) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Intiialize the IP6_PROTOCOL structure to the unconfigured states.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP6 service instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpInstance The IP6 child instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6InitProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP6_PROTOCOL *IpInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT ((IpSb != NULL) && (IpInstance != NULL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (IpInstance, sizeof (IP6_PROTOCOL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->Signature = IP6_PROTOCOL_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->State = IP6_STATE_UNCONFIGED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->Service = IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->GroupList = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (&IpInstance->Ip6Proto, &mEfiIp6ProtocolTemplete, sizeof (EFI_IP6_PROTOCOL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetMapInit (&IpInstance->RxTokens);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetMapInit (&IpInstance->TxTokens);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpInstance->Received);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpInstance->Delivered);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiInitializeLock (&IpInstance->RecycleLock, TPL_NOTIFY);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Configure the IP6 child. If the child is already configured,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync change the configuration parameter. Otherwise, configure it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for the first time. The caller should validate the configuration
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync before deliver them to it. It also don't do configure NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpInstance The IP6 child to configure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Config The configure data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP6 child is successfully configured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Failed to free the pending transive or to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync configure underlying MNP, or other errors.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NO_MAPPING The IP6 child is configured to use the default
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address, but the default address hasn't been
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync configured. The IP6 child doesn't need to be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync reconfigured when the default address is configured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES No more memory space is available.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other Other error occurs.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6ConfigProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP6_PROTOCOL *IpInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_CONFIG_DATA *Config
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_INTERFACE *IpIf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_CONFIG_DATA *Current;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_ADDRESS_INFO *AddressInfo;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN StationZero;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN DestZero;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IPv6_ADDRESS Source;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN AddrOk;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Current = &IpInstance->ConfigData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // User is changing packet filters. It must be stopped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // before the station address can be changed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State == IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Cancel all the pending transmit/receive from upper layer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6Cancel (IpInstance, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set up the interface.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync StationZero = NetIp6IsUnspecifiedAddr (&Config->StationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DestZero = NetIp6IsUnspecifiedAddr (&Config->DestinationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StationZero && DestZero) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // StationAddress is still zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_GET_REF (IpSb->DefaultInterface);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->Interface = IpSb->DefaultInterface;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (&IpSb->DefaultInterface->IpInstances, &IpInstance->AddrLink);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->State = IP6_STATE_CONFIGED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (StationZero && !DestZero) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6SelectSourceAddress (IpSb, &Config->DestinationAddress, &Source);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Source, &Config->StationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync AddrOk = Ip6IsOneOfSetAddress (IpSb, &Source, &IpIf, &AddressInfo);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (AddrOk) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (AddressInfo != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->PrefixLength = AddressInfo->PrefixLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The specified source address is not one of the addresses IPv6 maintains.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_GET_REF (IpIf);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->Interface = IpIf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (&IpIf->IpInstances, &IpInstance->AddrLink);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (Current, Config, sizeof (EFI_IP6_CONFIG_DATA));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Current->StationAddress, &Source);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->State = IP6_STATE_CONFIGED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Clean up the IP6 child, and release all the resources used by it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in, out] IpInstance The IP6 child to clean up.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The IP6 child is cleaned up.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Some resources failed to be released.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6CleanProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN OUT IP6_PROTOCOL *IpInstance
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Ip6Cancel (IpInstance, NULL))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Ip6Groups (IpInstance, FALSE, NULL))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Some packets haven't been recycled. It is because either the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // user forgets to recycle the packets, or because the callback
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // hasn't been called. Just leave it alone.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!IsListEmpty (&IpInstance->Delivered)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->Interface != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&IpInstance->AddrLink);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanInterface (IpInstance->Interface, IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->Interface = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->GroupList != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpInstance->GroupList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->GroupList = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->GroupCount = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetMapClean (&IpInstance->TxTokens);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetMapClean (&IpInstance->RxTokens);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Configure the MNP parameter used by IP. The IP driver uses one MNP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync child to transmit/receive frames. By default, it configures MNP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to receive unicast/multicast/broadcast. Also, it will enable/disable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the promiscuous receive according to whether there is IP child
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync enable that or not. If Force is FALSE, it will iterate through
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync all the IP children to check whether the promiscuous receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync setting has been changed. If it hasn't been changed, it won't
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync reconfigure the MNP. If Force is TRUE, the MNP is configured
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync whether that is changed or not.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP6 service instance that is to be changed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Force Force the configuration or not.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The MNP successfully configured/reconfigured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Configuration failed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6ServiceConfigMnp (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN Force
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIST_ENTRY *Entry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync LIST_ENTRY *ProtoEntry;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_INTERFACE *IpIf;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN Reconfig;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN PromiscReceive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reconfig = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PromiscReceive = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Force) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Iterate through the IP children to check whether promiscuous
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // receive setting has been changed. Update the interface's receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // filter also.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIf = NET_LIST_USER_STRUCT (Entry, IP6_INTERFACE, Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIf->PromiscRecv = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_LIST_FOR_EACH (ProtoEntry, &IpIf->IpInstances) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = NET_LIST_USER_STRUCT (ProtoEntry, IP6_PROTOCOL, AddrLink);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->ConfigData.AcceptPromiscuous) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpIf->PromiscRecv = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PromiscReceive = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If promiscuous receive isn't changed, it isn't necessary to reconfigure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (PromiscReceive == IpSb->MnpConfigData.EnablePromiscuousReceive) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Reconfig = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpConfigData.EnablePromiscuousReceive = PromiscReceive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpSb->Mnp->Configure (IpSb->Mnp, &IpSb->MnpConfigData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // recover the original configuration if failed to set the configure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status) && Reconfig) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpConfigData.EnablePromiscuousReceive = (BOOLEAN) !PromiscReceive;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Assigns an IPv6 address and subnet mask to this EFI IPv6 Protocol driver instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Configure() function is used to set, change, or reset the operational parameters and filter
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync settings for this EFI IPv6 Protocol instance. Until these parameters have been set, no network traffic
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync can be sent or received by this instance. Once the parameters have been reset (by calling this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync function with Ip6ConfigData set to NULL), no more traffic can be sent or received until these
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync parameters have been set again. Each EFI IPv6 Protocol instance can be started and stopped
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync independently of each other by enabling or disabling their receive filter settings with the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Configure() function.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If Ip6ConfigData.StationAddress is a valid non-zero IPv6 unicast address, it is required
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to be one of the currently configured IPv6 addresses listed in the EFI IPv6 drivers, or else
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_INVALID_PARAMETER will be returned. If Ip6ConfigData.StationAddress is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync unspecified, the IPv6 driver will bind a source address according to the source address selection
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync algorithm. Clients could frequently call GetModeData() to check get currently configured IPv6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address list in the EFI IPv6 driver. If both Ip6ConfigData.StationAddress and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ConfigData.Destination are unspecified, when transmitting the packet afterwards, the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync source address filled in each outgoing IPv6 packet is decided based on the destination of this packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If operational parameters are reset or changed, any pending transmit and receive requests will be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cancelled. Their completion token status will be set to EFI_ABORTED and their events will be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Ip6ConfigData Pointer to the EFI IPv6 Protocol configuration data structure.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If NULL, reset the configuration data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The driver instance was successfully opened.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Ip6ConfigData.StationAddress is neither zero nor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a unicast IPv6 address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Ip6ConfigData.StationAddress is neither zero nor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync one of the configured IP addresses in the EFI IPv6 driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Ip6ConfigData.DefaultProtocol is illegal.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The EFI IPv6 Protocol driver instance data could not be allocated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NO_MAPPING The IPv6 driver was responsible for choosing a source address for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync this instance, but no source address was available for use.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED The interface is already open and must be stopped before the IPv6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync address or prefix length can be changed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The EFI IPv6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Protocol driver instance was not opened.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED Default protocol specified through
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ConfigData.DefaulProtocol isn't supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Configure (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_CONFIG_DATA *Ip6ConfigData OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_CONFIG_DATA *Current;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First, validate the parameters
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (This == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Validate the configuration first.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ConfigData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the station address is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Ip6IsValidAddress (IpSb, &Ip6ConfigData->StationAddress, TRUE)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the default protocol is valid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6IsIllegalProtocol (Ip6ConfigData->DefaultProtocol)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // User can only update packet filters when already configured.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If it wants to change the station address, it must configure(NULL)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the instance firstly.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State == IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Current = &IpInstance->ConfigData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_IP6_EQUAL (&Current->StationAddress, &Ip6ConfigData->StationAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (&Current->StationAddress) && IP6_NO_MAPPING (IpInstance)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NO_MAPPING;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Configure the instance or clean it up.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6ConfigData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ConfigProtocol (IpInstance, Ip6ConfigData);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6CleanProtocol (IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't change the state if it is DESTORY, consider the following
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // valid sequence: Mnp is unloaded-->Ip Stopped-->Udp Stopped,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Configure (ThisIp, NULL). If the state is changed to UNCONFIGED,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the unload fails miserably.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State == IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->State = IP6_STATE_UNCONFIGED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the MNP's configure data. Ip6ServiceConfigMnp will check
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // whether it is necessary to reconfigure the MNP.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ServiceConfigMnp (IpInstance->Service, FALSE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the variable data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6SetVariableData (IpInstance->Service);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Joins and leaves multicast groups.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Groups() function is used to join and leave multicast group sessions. Joining a group will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync enable reception of matching multicast packets. Leaving a group will disable reception of matching
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync multicast packets. Source-Specific Multicast isn't required to be supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If JoinFlag is FALSE and GroupAddress is NULL, all joined groups will be left.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] JoinFlag Set to TRUE to join the multicast group session, and FALSE to leave.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] GroupAddress Pointer to the IPv6 multicast address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This is an optional parameter that may be NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The operation completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER One or more of the following is TRUE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - JoinFlag is TRUE and GroupAddress is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - GroupAddress is not NULL and *GroupAddress is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync not a multicast IPv6 address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - GroupAddress is not NULL and *GroupAddress is in the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync range of SSM destination address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED This instance has not been started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES System resources could not be allocated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED This EFI IPv6 Protocol implementation does not support multicast groups.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED The group address is already in the group table (when
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync JoinFlag is TRUE).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The group address is not in the group table (when JoinFlag is FALSE).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Groups (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN JoinFlag,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *GroupAddress OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((This == NULL) || (JoinFlag && GroupAddress == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (GroupAddress != NULL && !IP6_IS_MULTICAST (GroupAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State != IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_EXIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6Groups (IpInstance, JoinFlag, GroupAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_EXIT:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Adds and deletes routing table entries.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Routes() function adds a route to, or deletes a route from, the routing table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Routes are determined by comparing the leftmost PrefixLength bits of Destination with
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the destination IPv6 address arithmetically. The gateway address must be on the same subnet as the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync configured station address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The default route is added with Destination and PrefixLegth both set to all zeros. The
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync default route matches all destination IPv6 addresses that do not match any other routes.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync All EFI IPv6 Protocol instances share a routing table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DeleteRoute Set to TRUE to delete this route from the routing table. Set to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FALSE to add this route to the routing table. Destination,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PrefixLength and Gateway are used as the key to each
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync route entry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Destination The address prefix of the subnet that needs to be routed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This is an optional parameter that may be NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] PrefixLength The prefix length of Destination. Ignored if Destination
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] GatewayAddress The unicast gateway IPv6 address for this route.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This is an optional parameter that may be NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The operation completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED The driver instance has not been started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - When DeleteRoute is TRUE, both Destination and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GatewayAddress are NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - When DeleteRoute is FALSE, either Destination or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GatewayAddress is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - *GatewayAddress is not a valid unicast IPv6 address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - *GatewayAddress is one of the local configured IPv6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync addresses.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND This route is not in the routing table (when DeleteRoute is TRUE).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The route is already defined in the routing table (when
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DeleteRoute is FALSE).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Routes (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN DeleteRoute,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *Destination OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT8 PrefixLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((This == NULL) || (PrefixLength >= IP6_PREFIX_NUM)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State != IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DeleteRoute && (Destination == NULL) && (GatewayAddress == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!DeleteRoute && (Destination == NULL || GatewayAddress == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (GatewayAddress != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Ip6IsValidAddress (IpSb, GatewayAddress, FALSE)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!NetIp6IsUnspecifiedAddr (GatewayAddress) &&
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync !NetIp6IsNetEqual (GatewayAddress, &IpInstance->ConfigData.StationAddress, PrefixLength)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update the route table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DeleteRoute) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6DelRoute (IpSb->RouteTable, Destination, PrefixLength, GatewayAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6AddRoute (IpSb->RouteTable, Destination, PrefixLength, GatewayAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Add or delete Neighbor cache entries.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Neighbors() function is used to add, update, or delete an entry from neighbor cache.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IPv6 neighbor cache entries are typically inserted and updated by the network protocol driver as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync network traffic is processed. Most neighbor cache entries will timeout and be deleted if the network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync traffic stops. Neighbor cache entries that were inserted by Neighbors() may be static (will not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync timeout) or dynamic (will timeout).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The implementation should follow the neighbor cache timeout mechanism which is defined in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RFC4861. The default neighbor cache timeout value should be tuned for the expected network
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync environment
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] DeleteFlag Set to TRUE to delete the specified cache entry, set to FALSE to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync add (or update, if it already exists and Override is TRUE) the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync specified cache entry. TargetIp6Address is used as the key
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync to find the requested cache entry.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] TargetIp6Address Pointer to the Target IPv6 address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] TargetLinkAddress Pointer to the link-layer address of the target. Ignored if NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Timeout Time in 100-ns units that this entry will remain in the neighbor
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cache, it will be deleted after Timeout. A value of zero means that
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the entry is permanent. A non-zero value means that the entry is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync dynamic.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Override If TRUE, the cached link-layer address of the matching entry will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync be overridden and updated; if FALSE, EFI_ACCESS_DENIED
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync will be returned if a corresponding cache entry already existed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data has been queued for transmission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED This instance has not been started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - TargetIpAddress is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - *TargetLinkAddress is invalid when not NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - *TargetIpAddress is not a valid unicast IPv6 address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - *TargetIpAddress is one of the local configured IPv6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync addresses.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Could not add the entry to the neighbor cache.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND This entry is not in the neighbor cache (when DeleteFlag is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TRUE or when DeleteFlag is FALSE while
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TargetLinkAddress is NULL.).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The to-be-added entry is already defined in the neighbor cache,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and that entry is tagged as un-overridden (when Override
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is FALSE).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Neighbors (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN DeleteFlag,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IPv6_ADDRESS *TargetIp6Address,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_MAC_ADDRESS *TargetLinkAddress OPTIONAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Timeout,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN BOOLEAN Override
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (This == NULL || TargetIp6Address == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (TargetIp6Address)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Ip6IsValidAddress (IpSb, TargetIp6Address, FALSE)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TargetLinkAddress != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!Ip6IsValidLinkAddress (IpSb, TargetLinkAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Ip6IsOneOfSetAddress (IpSb, TargetIp6Address, NULL, NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State != IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DeleteFlag) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6DelNeighbor (IpInstance->Service, TargetIp6Address, TargetLinkAddress, Timeout, Override);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6AddNeighbor (IpInstance->Service, TargetIp6Address, TargetLinkAddress, Timeout, Override);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Check whether the user's token or event has already
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync been enqueue on IP6's list.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Map The container of either user's transmit or receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Item Current item to check against.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The Token to check againist.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The token or event has already been enqueued in IP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The current item isn't the same token/event as the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6TokenExist (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_MAP *Map,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_MAP_ITEM *Item,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_COMPLETION_TOKEN *Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_COMPLETION_TOKEN *TokenInItem;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token = (EFI_IP6_COMPLETION_TOKEN *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TokenInItem = (EFI_IP6_COMPLETION_TOKEN *) Item->Key;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Token == TokenInItem || Token->Event == TokenInItem->Event) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ACCESS_DENIED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Validate the user's token against the current station address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Token User's token to validate.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Some parameters are invalid.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BAD_BUFFER_SIZE The user's option/data is too long.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The token is OK.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6TxTokenValid (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_COMPLETION_TOKEN *Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_TRANSMIT_DATA *TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 Index;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT32 DataLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Token == NULL || Token->Event == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = Token->Packet.TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData == NULL || (TxData->ExtHdrsLength != 0 && TxData->ExtHdrs == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->FragmentCount == 0 || TxData->DataLength == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for (DataLength = 0, Index = 0; Index < TxData->FragmentCount; Index++) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->FragmentTable[Index].FragmentLength == 0 || TxData->FragmentTable[Index].FragmentBuffer == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataLength += TxData->FragmentTable[Index].FragmentLength;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->DataLength != DataLength) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // TODO: Token.Packet.TxData.DataLength is too short to transmit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // return EFI_BUFFER_TOO_SMALL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Token.Packet.TxData.DataLength is beyond the maximum that which can be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // described through the Fragment Offset field in Fragment header when performing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // fragmentation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->DataLength > 64 * 1024) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_BAD_BUFFER_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The callback function for the net buffer which wraps the user's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync transmit token. Although this function seems simple, there
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are some subtle aspects.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync When user requests the IP to transmit a packet by passing it a
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync token, the token is wrapped in an IP6_TXTOKEN_WRAP and the data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is wrapped in an net buffer. The net buffer's Free function is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync set to Ip6FreeTxToken. The Token and token wrap are added to the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP child's TxToken map. Then the buffer is passed to Ip6Output for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync transmission. If an error happened before that, the buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is freed, which in turn frees the token wrap. The wrap may
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync have been added to the TxToken map or not, and the user's event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync shouldn't be fired because we are still in the EfiIp6Transmit. If
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the buffer has been sent by Ip6Output, it should be removed from
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the TxToken map and user's event signaled. The token wrap and buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are bound together. Check the comments in Ip6Output for information
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync about IP fragmentation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The token's wrap.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6FreeTxToken (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_TXTOKEN_WRAP *Wrap;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NET_MAP_ITEM *Item;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap = (IP6_TXTOKEN_WRAP *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Signal IpSecRecycleEvent to inform IPsec free the memory
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Wrap->IpSecRecycleSignal != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SignalEvent (Wrap->IpSecRecycleSignal);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Find the token in the instance's map. EfiIp6Transmit put the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // token to the map. If that failed, NetMapFindKey will return NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Item = NetMapFindKey (&Wrap->IpInstance->TxTokens, Wrap->Token);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Item != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetMapRemoveItem (&Wrap->IpInstance->TxTokens, Item, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Wrap->Sent) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SignalEvent (Wrap->Token->Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Dispatch the DPC queued by the NotifyFunction of Token->Event.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DispatchDpc ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Wrap);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The callback function to Ip6Output to update the transmit status.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Packet The user's transmit packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IoStatus The result of the transmission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Flag Not used during transmission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The token's wrap.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncVOID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6OnPacketSent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_BUF *Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_STATUS IoStatus,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINT32 Flag,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_TXTOKEN_WRAP *Wrap;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This is the transmission request from upper layer,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // not the IP6 driver itself.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap = (IP6_TXTOKEN_WRAP *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Token->Status = IoStatus;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Wrap->Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Places outgoing data packets into the transmit queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Transmit() function places a sending request in the transmit queue of this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI IPv6 Protocol instance. Whenever the packet in the token is sent out or some
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync errors occur, the event in the token will be signaled, and the status is updated.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Token Pointer to the transmit token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The data has been queued for transmission.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED This instance has not been started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NO_MAPPING The IPv6 driver was responsible for choosing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync a source address for this transmission,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync but no source address was available for use.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER One or more of the following is TRUE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Event is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Packet.TxData is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Packet.ExtHdrsLength is not zero and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token.Packet.ExtHdrs is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Packet.FragmentCount is zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - One or more of the Token.Packet.TxData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FragmentTable[].FragmentLength fields is zero.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - One or more of the Token.Packet.TxData.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FragmentTable[].FragmentBuffer fields is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Packet.TxData.DataLength is zero or not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync equal to the sum of fragment lengths.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Packet.TxData.DestinationAddress is non
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync zero when DestinationAddress is configured as
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync non-zero when doing Configure() for this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI IPv6 protocol instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Packet.TxData.DestinationAddress is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync unspecified when DestinationAddress is unspecified
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync when doing Configure() for this EFI IPv6 protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The transmit completion token with the same Token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Event was already in the transmit queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The completion token could not be queued because
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the transmit queue is full.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND Not route is found to destination address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Could not queue the transmit data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BUFFER_TOO_SMALL Token.Packet.TxData.TotalDataLength is too
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync short to transmit.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_BAD_BUFFER_SIZE If Token.Packet.TxData.DataLength is beyond the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync maximum that which can be described through the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Fragment Offset field in Fragment header when
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync performing fragmentation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Transmit (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_COMPLETION_TOKEN *Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_CONFIG_DATA *Config;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_HEADER Head;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_TRANSMIT_DATA *TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_OVERRIDE_DATA *Override;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_TXTOKEN_WRAP *Wrap;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 *ExtHdrs;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check input parameters.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (This == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtHdrs = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6TxTokenValid (Token);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State != IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config = &IpInstance->ConfigData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the token or signal already existed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (NetMapIterate (&IpInstance->TxTokens, Ip6TokenExist, Token))) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ACCESS_DENIED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Build the IP header, fill in the information from ConfigData or OverrideData
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&Head, sizeof(EFI_IP6_HEADER));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData = Token->Packet.TxData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Head.SourceAddress, &Config->StationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Head.DestinationAddress, &Config->DestinationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (&TxData->DestinationAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (!NetIp6IsUnspecifiedAddr (&Config->StationAddress));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // StationAddress is unspecified only when ConfigData.Dest is unspecified.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Use TxData.Dest to override the DestinationAddress.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!NetIp6IsUnspecifiedAddr (&Config->DestinationAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (&Config->StationAddress)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6SelectSourceAddress (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &TxData->DestinationAddress,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Head.SourceAddress
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_COPY_ADDRESS (&Head.DestinationAddress, &TxData->DestinationAddress);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill in Head infos.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.NextHeader = Config->DefaultProtocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->ExtHdrsLength != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.NextHeader = TxData->NextHeader;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->OverrideData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Override = TxData->OverrideData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.NextHeader = Override->Protocol;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.HopLimit = Override->HopLimit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.FlowLabelL = HTONS ((UINT16) Override->FlowLabel);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.FlowLabelH = (UINT8) ((Override->FlowLabel >> 16) & 0x0F);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.HopLimit = Config->HopLimit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.FlowLabelL = HTONS ((UINT16) Config->FlowLabel);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.FlowLabelH = (UINT8) ((Config->FlowLabel >> 16) & 0x0F);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Head.PayloadLength = HTONS ((UINT16) (TxData->ExtHdrsLength + TxData->DataLength));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // OK, it survives all the validation check. Wrap the token in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // a IP6_TXTOKEN_WRAP and the data in a netbuf
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap = AllocateZeroPool (sizeof (IP6_TXTOKEN_WRAP));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Wrap == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->IpInstance = IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Token = Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Sent = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Life = IP6_US_TO_SEC (Config->TransmitTimeout);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Packet = NetbufFromExt (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (NET_FRAGMENT *) TxData->FragmentTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData->FragmentCount,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_MAX_HEADLEN,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6FreeTxToken,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Wrap->Packet == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (Wrap);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token->Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetMapInsertTail (&IpInstance->TxTokens, Token, Wrap);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // NetbufFree will call Ip6FreeTxToken, which in turn will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // free the IP6_TXTOKEN_WRAP. Now, the token wrap hasn't been
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // enqueued.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Wrap->Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Allocate a new buffer to store IPv6 extension headers to avoid updating
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the original data in EFI_IP6_COMPLETION_TOKEN.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (TxData->ExtHdrsLength != 0 && TxData->ExtHdrs != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtHdrs = (UINT8 *) AllocateCopyPool (TxData->ExtHdrsLength, TxData->ExtHdrs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ExtHdrs == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Mark the packet sent before output it. Mark it not sent again if the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // returned status is not EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Sent = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6Output (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Packet,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &Head,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ExtHdrs,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TxData->ExtHdrsLength,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6OnPacketSent,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap->Sent = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetbufFree (Wrap->Packet);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (ExtHdrs != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (ExtHdrs);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Places a receiving request into the receiving queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Receive() function places a completion token into the receive packet queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function is always asynchronous.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Token.Event field in the completion token must be filled in by the caller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and cannot be NULL. When the receive operation completes, the EFI IPv6 Protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync driver updates the Token.Status and Token.Packet.RxData fields and the Token.Event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Current Udp implementation creates an IP child for each Udp child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync It initates a asynchronous receive immediately no matter whether
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync there is no mapping or not. Therefore, disable the returning EFI_NO_MAPPING for now.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync To enable it, the following check must be performed:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetIp6IsUnspecifiedAddr (&Config->StationAddress) && IP6_NO_MAPPING (IpInstance)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NO_MAPPING;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Token Pointer to a token that is associated with the receive data descriptor.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The receive completion token was cached.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED This EFI IPv6 Protocol instance has not been started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NO_MAPPING When IP6 driver responsible for binding source address to this instance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while no source address is available for use.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync - Token.Event is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The receive completion token could not be queued due to a lack of system
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync resources (usually memory).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The EFI IPv6 Protocol instance has been reset to startup defaults.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The receive completion token with the same Token.Event was already
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync in the receive queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY The receive request could not be queued because the receive queue is full.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Receive (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_COMPLETION_TOKEN *Token
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (This == NULL || Token == NULL || Token->Event == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State != IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether the toke is already on the receive queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetMapIterate (&IpInstance->RxTokens, Ip6TokenExist, Token);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_ACCESS_DENIED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Queue the token then check whether there is pending received packet.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetMapInsertTail (&IpInstance->RxTokens, Token, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6InstanceDeliverPacket (IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Dispatch the DPC queued by the NotifyFunction of this instane's receive
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // event.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DispatchDpc ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cancel the transmitted but not recycled packet. If a matching
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync token is found, it will call Ip6CancelPacket to cancel the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync packet. Ip6CancelPacket cancels all the fragments of the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync packet. When all the fragments are freed, the IP6_TXTOKEN_WRAP
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is deleted from the Map, and user's event is signalled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Because Ip6CancelPacket and other functions are all called in
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync line, after Ip6CancelPacket returns, the Item has been freed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Map The IP6 child's transmit queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Item The current transmitted packet to test.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The user's token to cancel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Continue to check the next Item.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The user's Token (Token != NULL) is cancelled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6CancelTxTokens (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_MAP *Map,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_MAP_ITEM *Item,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_COMPLETION_TOKEN *Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_TXTOKEN_WRAP *Wrap;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token = (EFI_IP6_COMPLETION_TOKEN *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Return EFI_SUCCESS to check the next item in the map if
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // this one doesn't match.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Token != NULL) && (Token != Item->Key)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Wrap = (IP6_TXTOKEN_WRAP *) Item->Value;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Wrap != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't access the Item, Wrap and Token's members after this point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Item and wrap has been freed. And we no longer own the Token.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CancelPacket (Wrap->IpInstance->Interface, Wrap->Packet, EFI_ABORTED);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If only one item is to be cancel, return EFI_ABORTED to stop
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // iterating the map any more.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Token != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cancel the receive request. This is simple, because
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync it is only enqueued in our local receive map.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Map The IP6 child's receive queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Item Current receive request to cancel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The user's token to cancel.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Continue to check the next receive request on the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ABORTED The user's token (token != NULL) has been
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cancelled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6CancelRxTokens (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_MAP *Map,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN NET_MAP_ITEM *Item,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN VOID *Context
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_COMPLETION_TOKEN *Token;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_COMPLETION_TOKEN *This;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token = (EFI_IP6_COMPLETION_TOKEN *) Context;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This = Item->Key;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Token != NULL) && (Token != This)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetMapRemoveItem (Map, Item, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->Status = EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->Packet.RxData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SignalEvent (This->Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Token != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ABORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Cancel the user's receive/transmit request. It is the worker function of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EfiIp6Cancel API.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpInstance The IP6 child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Token The token to cancel. If NULL, all token will be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync cancelled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The token is cancelled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND The token isn't found on either the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync transmit/receive queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR Not all tokens are cancelled when Token is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6Cancel (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_PROTOCOL *IpInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // First check the transmitted packet. Ip6CancelTxTokens returns
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // EFI_ABORTED to mean that the token has been cancelled when
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // token != NULL. So, return EFI_SUCCESS for this condition.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetMapIterate (&IpInstance->TxTokens, Ip6CancelTxTokens, Token);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Token != NULL) && (Status == EFI_ABORTED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check the receive queue. Ip6CancelRxTokens also returns EFI_ABORT
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // for Token!=NULL and it is cancelled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetMapIterate (&IpInstance->RxTokens, Ip6CancelRxTokens, Token);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Dispatch the DPCs queued by the NotifyFunction of the canceled rx token's
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // events.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DispatchDpc ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((Token != NULL) && (Status == EFI_ABORTED)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // OK, if the Token is found when Token != NULL, the NetMapIterate
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will return EFI_ABORTED, which has been interrupted as EFI_SUCCESS.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Token != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_FOUND;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If Token == NULL, cancel all the tokens. return error if not
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // all of them are cancelled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!NetMapIsEmpty (&IpInstance->TxTokens) || !NetMapIsEmpty (&IpInstance->RxTokens)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Abort an asynchronous transmit or receive request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Cancel() function is used to abort a pending transmit or receive request.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync If the token is in the transmit or receive request queues, after calling this
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync function, Token->Status will be set to EFI_ABORTED, and then Token->Event will
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync be signaled. If the token is not in one of the queues, which usually means the
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync asynchronous operation has completed, this function will not signal the token,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and EFI_NOT_FOUND is returned.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Token Pointer to a token that has been issued by
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_PROTOCOL.Transmit() or
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_PROTOCOL.Receive(). If NULL, all pending
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync tokens are aborted. Type EFI_IP6_COMPLETION_TOKEN is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync defined in EFI_IP6_PROTOCOL.Transmit().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The asynchronous I/O request was aborted and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Token->Event was signaled. When Token is NULL, all
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync pending requests were aborted, and their events were signaled.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED This instance has not been started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O request was
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync not found in the transmit or receive queue. It has either completed
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync or was not issued by Transmit() and Receive().
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Cancel (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_COMPLETION_TOKEN *Token OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (This == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State != IP6_STATE_CONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6Cancel (IpInstance, Token);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Polls for incoming data packets, and processes outgoing data packets.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The Poll() function polls for incoming data packets and processes outgoing data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync packets. Network drivers and applications can call the EFI_IP6_PROTOCOL.Poll()
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync function to increase the rate that data packets are moved between the communications
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync device and the transmit and receive queues.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync In some systems the periodic timer event may not poll the underlying communications
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync device fast enough to transmit and/or receive all data packets without missing
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync incoming packets or dropping outgoing packets. Drivers and applications that are
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync experiencing packet loss should try calling the EFI_IP6_PROTOCOL.Poll() function
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync more often.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Pointer to the EFI_IP6_PROTOCOL instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Incoming or outgoing data was processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_STARTED This EFI IPv6 Protocol instance has not been started.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER This is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR An unexpected system error or network error occurred.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_NOT_READY No incoming or outgoing data was processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive queue.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Consider increasing the polling rate.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEfiIp6Poll (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_IP6_PROTOCOL *This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MANAGED_NETWORK_PROTOCOL *Mnp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (This == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IpInstance->Service;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State == IP6_STATE_UNCONFIGED) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_NOT_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Mnp = IpInstance->Service->Mnp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Don't lock the Poll function to enable the deliver of
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the packet polled up.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Mnp->Poll (Mnp);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync