4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/** @file
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The driver binding and service binding protocol for IP6 driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2009 - 2011, 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_DRIVER_BINDING_PROTOCOL gIp6DriverBinding = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6DriverBindingSupported,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6DriverBindingStart,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6DriverBindingStop,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0xa,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync};
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This is the declaration of an EFI image entry point. This entry point is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync both device drivers and bus drivers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The entry point for IP6 driver which installs the driver
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync binding and component name protocol on its image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The firmware allocated handle for the UEFI image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SystemTable A pointer to the EFI System Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The operation completed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6DriverEntryPoint (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SYSTEM_TABLE *SystemTable
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EfiLibInstallDriverBindingComponentName2 (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SystemTable,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gIp6DriverBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gIp6ComponentName,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gIp6ComponentName2
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Test to see if this driver supports ControllerHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ControllerHandle Handle of device to test.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] RemainingDevicePath Optional parameter use to pick a specific child
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync device to start.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS This driver supports this device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED This driver is already running on this device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other This driver does not support this device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6DriverBindingSupported (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Test for the MNP service binding Protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiManagedNetworkServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_TEST_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Clean up an IP6 service binding instance. It releases all
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the resource allocated by the instance. The instance may be
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync partly initialized, or partly destroyed. If a resource is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync destroyed, it is marked as that in case the destory failed and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync being called again later.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] IpSb The IP6 service binding instance to clean up.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The resource used by the instance are cleaned up.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Others Failed to clean up some of the resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6CleanService (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN IP6_SERVICE *IpSb
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IPv6_ADDRESS AllNodes;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_NEIGHBOR_ENTRY *NeighborCache;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ConfigCleanInstance (&IpSb->Ip6ConfigInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Leave link-scope all-nodes multicast address (FF02::1)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6SetToAllNodeMulticast (FALSE, IP6_LINK_LOCAL_SCOPE, &AllNodes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6LeaveGroup (IpSb, &AllNodes);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->DefaultInterface != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanInterface (IpSb->DefaultInterface, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->DefaultInterface = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanDefaultRouterList (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanPrefixListTable (IpSb, &IpSb->OnlinkPrefix);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanPrefixListTable (IpSb, &IpSb->AutonomousPrefix);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->RouteTable != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanRouteTable (IpSb->RouteTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RouteTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->InterfaceId != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpSb->InterfaceId);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->InterfaceId = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanAssembleTable (&IpSb->Assemble);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->MnpChildHandle != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->Mnp != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Mnp->Cancel (IpSb->Mnp, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Mnp->Configure (IpSb->Mnp, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiManagedNetworkProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Controller
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Mnp = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NetLibDestroyServiceChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Image,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiManagedNetworkServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpChildHandle = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->RecvRequest.MnpToken.Event != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpSb->RecvRequest.MnpToken.Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->Timer != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SetTimer (IpSb->Timer, TimerCancel, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpSb->Timer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Timer = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->FasterTimer != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->SetTimer (IpSb->FasterTimer, TimerCancel, 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpSb->FasterTimer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->FasterTimer = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free the Neighbor Discovery resources
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!IsListEmpty (&IpSb->NeighborTable)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NeighborCache = NET_LIST_HEAD (&IpSb->NeighborTable, IP6_NEIGHBOR_ENTRY, Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6FreeNeighborEntry (IpSb, NeighborCache, FALSE, TRUE, EFI_SUCCESS, NULL, NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Create a new IP6 driver service binding protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Controller The controller that has MNP service binding
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The IP6 driver's image handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[out] Service The variable to receive the newly created IP6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync service.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS A new IP6 service binding private is created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6CreateService (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OUT IP6_SERVICE **Service
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_MANAGED_NETWORK_CONFIG_DATA *Config;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_CONFIG_DATA_ITEM *DataItem;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (Service != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Service = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // allocate a service private data then initialize all the filed to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // empty resources, so if any thing goes wrong when allocating
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // resources, Ip6CleanService can be called to clean it up.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = AllocateZeroPool (sizeof (IP6_SERVICE));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Signature = IP6_SERVICE_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->ServiceBinding.CreateChild = Ip6ServiceBindingCreateChild;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->ServiceBinding.DestroyChild = Ip6ServiceBindingDestroyChild;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->State = IP6_SERVICE_UNSTARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->InDestroy = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->NumChildren = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpSb->Children);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpSb->Interfaces);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->DefaultInterface = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RouteTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RecvRequest.Signature = IP6_LINK_RX_SIGNATURE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RecvRequest.CallBack = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RecvRequest.Context = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MnpToken = &IpSb->RecvRequest.MnpToken;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MnpToken->Event = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MnpToken->Status = EFI_NOT_READY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync MnpToken->Packet.RxData = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CreateAssembleTable (&IpSb->Assemble);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MldCtrl.Mldv1QuerySeen = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpSb->MldCtrl.Groups);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&IpSb->LinkLocalAddr, sizeof (EFI_IPv6_ADDRESS));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->LinkLocalOk = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->LinkLocalDadFail = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Dhcp6NeedStart = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Dhcp6NeedInfoRequest = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->CurHopLimit = IP6_HOP_LIMIT;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->LinkMTU = IP6_MIN_LINK_MTU;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->BaseReachableTime = IP6_REACHABLE_TIME;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6UpdateReachableTime (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // RFC4861 RETRANS_TIMER: 1,000 milliseconds
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RetransTimer = IP6_RETRANS_TIMER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RoundRobin = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpSb->NeighborTable);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpSb->DefaultRouterList);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpSb->OnlinkPrefix);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InitializeListHead (&IpSb->AutonomousPrefix);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->InterfaceIdLen = IP6_IF_ID_LEN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->InterfaceId = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RouterAdvertiseReceived = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->SolicitTimer = IP6_MAX_RTR_SOLICITATIONS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Ticks = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Image = ImageHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Controller = Controller;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpChildHandle = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Mnp = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config = &IpSb->MnpConfigData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->ReceivedQueueTimeoutValue = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->TransmitQueueTimeoutValue = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->ProtocolTypeFilter = IP6_ETHER_PROTO;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->EnableUnicastReceive = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->EnableMulticastReceive = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->EnableBroadcastReceive = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->EnablePromiscuousReceive = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->FlushQueuesOnReset = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->EnableReceiveTimestamps = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Config->DisableBackgroundPolling = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&IpSb->SnpMode, sizeof (EFI_SIMPLE_NETWORK_MODE));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Timer = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->FasterTimer = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&IpSb->Ip6ConfigInstance, sizeof (IP6_CONFIG_INSTANCE));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MacString = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create various resources. First create the route table, timer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // event, MNP token event and MNP child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->RouteTable = Ip6CreateRouteTable ();
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->RouteTable == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_NOTIFY_SIGNAL | EVT_TIMER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_CALLBACK,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6TimerTicking,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->Timer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_NOTIFY_SIGNAL | EVT_TIMER,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_CALLBACK,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6NdFasterTimerTicking,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->FasterTimer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetLibCreateServiceChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiManagedNetworkServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->MnpChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiManagedNetworkProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) (&IpSb->Mnp),
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ImageHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Controller,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_BY_DRIVER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ServiceConfigMnp (IpSb, TRUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &IpSb->SnpMode);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MaxPacketSize = IP6_MIN_LINK_MTU - sizeof (EFI_IP6_HEADER);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NetLibGetVlanId (IpSb->Controller) != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // This is a VLAN device, reduce MTU by VLAN tag length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MaxPacketSize -= NET_VLAN_TAG_LEN;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->OldMaxPacketSize = IpSb->MaxPacketSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Currently only ETHERNET is supported in IPv6 stack, since
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // link local address requires an IEEE 802 48-bit MACs for
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // EUI-64 format interface identifier mapping.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->SnpMode.IfType != NET_IFTYPE_ETHERNET) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6InitMld (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The timer expires every 100 (IP6_TIMER_INTERVAL_IN_MS) milliseconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer (IpSb->FasterTimer, TimerPeriodic, TICKS_PER_MS * IP6_TIMER_INTERVAL_IN_MS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // The timer expires every 1000 (IP6_ONE_SECOND_IN_MS) milliseconds.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->SetTimer (IpSb->Timer, TimerPeriodic, TICKS_PER_MS * IP6_ONE_SECOND_IN_MS);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->CreateEvent (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EVT_NOTIFY_SIGNAL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync TPL_NOTIFY,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6OnFrameReceived,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->RecvRequest,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &MnpToken->Event
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ReceiveFrame (Ip6AcceptFrame, IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &IpSb->MacString);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ConfigInitInstance (&IpSb->Ip6ConfigInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->DefaultInterface = Ip6CreateInterface (IpSb, TRUE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->DefaultInterface == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // If there is any manual address, set it.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataItem = &IpSb->Ip6ConfigInstance.DataItem[Ip6ConfigDataTypeManualAddress];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (DataItem->Data.Ptr != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataItem->SetData (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->Ip6ConfigInstance,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataItem->DataSize,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DataItem->Data.Ptr
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertHeadList (&IpSb->Interfaces, &IpSb->DefaultInterface->Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync *Service = IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_ERROR:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanService (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Start this driver on ControllerHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ControllerHandle Handle of device to bind driver to.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] RemainingDevicePath Optional parameter used to pick a specific child
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync device to start.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES This driver is added to ControllerHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other This driver does not support this device.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6DriverBindingStart (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Test for the Ip6 service binding protocol
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_TEST_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Status == EFI_SUCCESS) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_ALREADY_STARTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6CreateService (ControllerHandle, This->DriverBindingHandle, &IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IpSb != NULL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install the Ip6ServiceBinding Protocol onto ControlerHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->ServiceBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ConfigProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->Ip6ConfigInstance.Ip6Config,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanService (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize the IP6 ID
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mIp6Id = NET_RANDOM (NetRandomInitSeed ());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6SetVariableData (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Stop this driver on ControllerHandle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ControllerHandle Handle of device to stop driver on.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync of children is zero, stop the entire bus driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if NumberOfChildren is 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The device was stopped.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6DriverBindingStop (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_DRIVER_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ControllerHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN UINTN NumberOfChildren,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_HANDLE NicHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync BOOLEAN IsDhcp6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INTN State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsDhcp6 = FALSE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiDhcp6ProtocolGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NicHandle != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // DriverBindingStop is triggered by the uninstallation of the EFI DHCPv6
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Protocol used by Ip6Config.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IsDhcp6 = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (NicHandle == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NicHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &ServiceBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This->DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NicHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_GET_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IP6_SERVICE_FROM_PROTOCOL (ServiceBinding);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->InDestroy) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IsDhcp6) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6ConfigDestroyDhcp6 (&IpSb->Ip6ConfigInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseEvent (IpSb->Ip6ConfigInstance.Dhcp6Event);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->Ip6ConfigInstance.Dhcp6Event = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (NumberOfChildren == 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->InDestroy = TRUE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync State = IpSb->State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->State = IP6_SERVICE_DESTROY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Clear the variable data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6ClearVariableData (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6CleanService (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->State = State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto Exit;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NicHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ServiceBindingProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBinding,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ConfigProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpSb->Ip6ConfigInstance.Ip6Config,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT_EFI_ERROR (Status);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // NumberOfChildren is not zero, destroy all IP6 children instances.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync while (!IsListEmpty (&IpSb->Children)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = NET_LIST_HEAD (&IpSb->Children, IP6_PROTOCOL, Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->NumChildren != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncExit:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Creates a child handle with a set of I/O services.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ChildHandle Pointer to the handle of the child to create. If
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync it is NULL, then a new handle is created. If it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync is not NULL, then the I/O services are added to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the existing child handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The child handle was created with the I/O services.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_OUT_OF_RESOURCES There are not enough resources availabe to create
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the child.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other The child handle was not created.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6ServiceBindingCreateChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SERVICE_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE *ChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync VOID *Mnp;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((This == NULL) || (ChildHandle == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IP6_SERVICE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpSb->LinkLocalDadFail) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_DEVICE_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = AllocatePool (sizeof (IP6_PROTOCOL));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance == NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_OUT_OF_RESOURCES;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6InitProtocol (IpSb, IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Install Ip6 onto ChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInstance->Ip6Proto,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->Handle = *ChildHandle;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Open the Managed Network protocol BY_CHILD.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiManagedNetworkProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &Mnp,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIp6DriverBinding.DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->Handle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->UninstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInstance->Ip6Proto,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Insert it into the service binding instance.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync InsertTailList (&IpSb->Children, &IpInstance->Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->NumChildren++;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_ERROR:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6CleanProtocol (IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync/**
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Destroys a child handle with a set of I/O services.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] This Protocol instance pointer.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ChildHandle Handle of the child to destroy.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCES The I/O services were removed from the child
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync handle.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED The child handle does not support the I/O services
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync that are being removed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_INVALID_PARAMETER Child handle is NULL.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_ACCESS_DENIED The child handle could not be destroyed because
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync its I/O services are being used.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval other The child handle was not destroyed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync**/
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_STATUS
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFIAPI
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncIp6ServiceBindingDestroyChild (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_SERVICE_BINDING_PROTOCOL *This,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IN EFI_HANDLE ChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync )
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync{
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_STATUS Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_SERVICE *IpSb;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IP6_PROTOCOL *IpInstance;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_IP6_PROTOCOL *Ip6;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_TPL OldTpl;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync INTN State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((This == NULL) || (ChildHandle == NULL)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve the private context data structures
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb = IP6_SERVICE_FROM_PROTOCOL (This);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->OpenProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync (VOID **) &Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIp6DriverBinding.DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_OPEN_PROTOCOL_GET_PROTOCOL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_UNSUPPORTED;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance = IP6_INSTANCE_FROM_PROTOCOL (Ip6);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->Service != IpSb) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_INVALID_PARAMETER;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // A child can be destroyed more than once. For example,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ip6DriverBindingStop will destory all of its children.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // when UDP driver is being stopped, it will destory all
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // the IP child it opens.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (IpInstance->State == IP6_STATE_DESTROY) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync State = IpInstance->State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->State = IP6_STATE_DESTROY;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Close the Managed Network protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->CloseProtocol (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->MnpChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiManagedNetworkProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gIp6DriverBinding.DriverBindingHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Uninstall the IP6 protocol first. Many thing happens during
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // this:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 1. The consumer of the IP6 protocol will be stopped if it
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // opens the protocol BY_DRIVER. For eaxmple, if MNP driver is
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // stopped, IP driver's stop function will be called, and uninstall
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // EFI_IP6_PROTOCOL will trigger the UDP's stop function. This
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // makes it possible to create the network stack bottom up, and
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // stop it top down.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // 2. the upper layer will recycle the received packet. The recycle
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // event's TPL is higher than this function. The recycle events
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // will be called back before preceeding. If any packets not recycled,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // that means there is a resource leak.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync //
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->UninstallProtocolInterface (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &IpInstance->Ip6Proto
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Ip6CleanProtocol (IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6SetVariableData (IpSb);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (EFI_ERROR (Status)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->InstallMultipleProtocolInterfaces (
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &ChildHandle,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync &gEfiIp6ProtocolGuid,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Ip6,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync NULL
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync );
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync goto ON_ERROR;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync }
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync RemoveEntryList (&IpInstance->Link);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ASSERT (IpSb->NumChildren > 0);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpSb->NumChildren--;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FreePool (IpInstance);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return EFI_SUCCESS;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncON_ERROR:
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync IpInstance->State = State;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync gBS->RestoreTPL (OldTpl);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync return Status;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync}