X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcDhcp6.c;h=8003f314910ef015dfa032dbe61a94ffadbcbdf8;hp=111224cea2e2ae53452bd90c2b4c7b56cacd5ea5;hb=0ab90add0f525eb9c91ce4bc2357298c4f357d09;hpb=8f586b85c3f617ba802e663b4b3b303e06140863 diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c index 111224cea2..8003f31491 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c @@ -2,7 +2,7 @@ Functions implementation related with DHCPv6 for UefiPxeBc Driver. (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -793,8 +793,8 @@ PxeBcRequestBootService ( Status = PxeBc->UdpRead ( PxeBc, - EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP, - &Private->StationIp, + EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP | EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP, + NULL, &SrcPort, &Private->ServerIp, &DestPort, @@ -1280,7 +1280,7 @@ PxeBcCheckRouteTable ( } // - // Find out the gateway address which can route the message whcih send to ServerIp. + // Find out the gateway address which can route the message which send to ServerIp. // for (Index = 0; Index < Ip6ModeData.RouteCount; Index++) { if (NetIp6IsNetEqual (&Private->ServerIp.v6, &Ip6ModeData.RouteTable[Index].Destination, Ip6ModeData.RouteTable[Index].PrefixLength)) { @@ -1376,18 +1376,19 @@ PxeBcRegisterIp6Address ( EFI_IP6_CONFIG_MANUAL_ADDRESS CfgAddr; EFI_IPv6_ADDRESS GatewayAddr; UINTN DataSize; - EFI_EVENT TimeOutEvt; EFI_EVENT MappedEvt; EFI_STATUS Status; - UINT64 DadTriggerTime; - EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits; + BOOLEAN NoGateway; + EFI_IPv6_ADDRESS *Ip6Addr; + UINTN Index; Status = EFI_SUCCESS; - TimeOutEvt = NULL; MappedEvt = NULL; + Ip6Addr = NULL; DataSize = sizeof (EFI_IP6_CONFIG_POLICY); Ip6Cfg = Private->Ip6Cfg; Ip6 = Private->Ip6; + NoGateway = FALSE; ZeroMem (&CfgAddr, sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); CopyMem (&CfgAddr.Address, Address, sizeof (EFI_IPv6_ADDRESS)); @@ -1402,7 +1403,7 @@ PxeBcRegisterIp6Address ( // Status = PxeBcCheckRouteTable (Private, PXEBC_IP6_ROUTE_TABLE_TIMEOUT, &GatewayAddr); if (EFI_ERROR (Status)) { - goto ON_EXIT; + NoGateway = TRUE; } // @@ -1424,34 +1425,6 @@ PxeBcRegisterIp6Address ( goto ON_EXIT; } - // - // Get Duplicate Address Detection Transmits count. - // - DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS); - Status = Ip6Cfg->GetData ( - Ip6Cfg, - Ip6ConfigDataTypeDupAddrDetectTransmits, - &DataSize, - &DadXmits - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - // - // Create a timer as setting address timeout event since DAD in IP6 driver. - // - Status = gBS->CreateEvent ( - EVT_TIMER, - TPL_CALLBACK, - NULL, - NULL, - &TimeOutEvt - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - // // Create a notify event to set address flag when DAD if IP6 driver succeeded. // @@ -1466,6 +1439,7 @@ PxeBcRegisterIp6Address ( goto ON_EXIT; } + Private->IsAddressOk = FALSE; Status = Ip6Cfg->RegisterDataNotify ( Ip6Cfg, Ip6ConfigDataTypeManualAddress, @@ -1483,27 +1457,58 @@ PxeBcRegisterIp6Address ( ); if (EFI_ERROR(Status) && Status != EFI_NOT_READY) { goto ON_EXIT; - } + } else if (Status == EFI_NOT_READY) { + // + // Poll the network until the asynchronous process is finished. + // + while (!Private->IsAddressOk) { + Ip6->Poll (Ip6); + } + // + // Check whether the IP6 address setting is successed. + // + DataSize = 0; + Status = Ip6Cfg->GetData ( + Ip6Cfg, + Ip6ConfigDataTypeManualAddress, + &DataSize, + NULL + ); + if (Status != EFI_BUFFER_TOO_SMALL || DataSize == 0) { + Status = EFI_DEVICE_ERROR; + goto ON_EXIT; + } - // - // Start the 5 secondes timer to wait for setting address. - // - Status = EFI_NO_MAPPING; - DadTriggerTime = TICKS_PER_SECOND * DadXmits.DupAddrDetectTransmits + PXEBC_DAD_ADDITIONAL_DELAY; - gBS->SetTimer (TimeOutEvt, TimerRelative, DadTriggerTime); + Ip6Addr = AllocatePool (DataSize); + if (Ip6Addr == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Ip6Cfg->GetData ( + Ip6Cfg, + Ip6ConfigDataTypeManualAddress, + &DataSize, + (VOID*) Ip6Addr + ); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto ON_EXIT; + } - while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) { - Ip6->Poll (Ip6); - if (Private->IsAddressOk) { - Status = EFI_SUCCESS; - break; + for (Index = 0; Index < DataSize / sizeof (EFI_IPv6_ADDRESS); Index++) { + if (CompareMem (Ip6Addr + Index, Address, sizeof (EFI_IPv6_ADDRESS)) == 0) { + break; + } + } + if (Index == DataSize / sizeof (EFI_IPv6_ADDRESS)) { + Status = EFI_ABORTED; + goto ON_EXIT; } } - + // // Set the default gateway address back if needed. // - if (!NetIp6IsUnspecifiedAddr (&GatewayAddr)) { + if (!NoGateway && !NetIp6IsUnspecifiedAddr (&GatewayAddr)) { Status = Ip6Cfg->SetData ( Ip6Cfg, Ip6ConfigDataTypeGateway, @@ -1524,8 +1529,8 @@ ON_EXIT: ); gBS->CloseEvent (MappedEvt); } - if (TimeOutEvt != NULL) { - gBS->CloseEvent (TimeOutEvt); + if (Ip6Addr != NULL) { + FreePool (Ip6Addr); } return Status; } @@ -1805,7 +1810,6 @@ PxeBcDhcp6Discover ( UINT8 *RequestOpt; UINT8 *DiscoverOpt; UINTN ReadSize; - UINT16 OpFlags; UINT16 OpCode; UINT16 OpLen; UINT32 Xid; @@ -1816,7 +1820,6 @@ PxeBcDhcp6Discover ( Request = Private->Dhcp6Request; SrcPort = PXEBC_BS_DISCOVER_PORT; DestPort = PXEBC_BS_DISCOVER_PORT; - OpFlags = 0; if (!UseBis && Layer != NULL) { *Layer &= EFI_PXE_BASE_CODE_BOOT_LAYER_MASK; @@ -1860,7 +1863,7 @@ PxeBcDhcp6Discover ( Status = PxeBc->UdpWrite ( PxeBc, - OpFlags, + 0, &Private->ServerIp, &DestPort, NULL, @@ -1897,8 +1900,8 @@ PxeBcDhcp6Discover ( Status = PxeBc->UdpRead ( PxeBc, - OpFlags, - &Private->StationIp, + EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP, + NULL, &SrcPort, &Private->ServerIp, &DestPort, @@ -2070,7 +2073,7 @@ PxeBcDhcp6Sarr ( return Status; } - ASSERT (Mode.Ia->State == Dhcp6Bound); + ASSERT ((Mode.Ia != NULL) && (Mode.Ia->State == Dhcp6Bound)); // // DHCP6 doesn't have an option to specify the router address on the subnet, the only way to get the // router address in IP6 is the router discovery mechanism (the RS and RA, which only be handled when @@ -2079,7 +2082,12 @@ PxeBcDhcp6Sarr ( // to find a valid router address. // CopyMem (&Private->TmpStationIp.v6, &Mode.Ia->IaAddress[0].IpAddress, sizeof (EFI_IPv6_ADDRESS)); - + if (Mode.ClientId != NULL) { + FreePool (Mode.ClientId); + } + if (Mode.Ia != NULL) { + FreePool (Mode.Ia); + } // // Check the selected offer whether BINL retry is needed. //