]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/UefiPxeBcDxe/PxeBcSupport.c
NetworkPkg/UefiPxeBcDxe: Configure the ARP Instance/RouteTable with new address
[mirror_edk2.git] / NetworkPkg / UefiPxeBcDxe / PxeBcSupport.c
index dfc79a067b9b9572cff4c7f981b617de2e48a992..4b6f8c9c7feff899abe478e69962476b0d2f8790 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Support functions implementation for UefiPxeBc Driver.\r
 \r
-  Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
@@ -36,17 +36,19 @@ PxeBcFlushStationIp (
 {\r
   EFI_PXE_BASE_CODE_MODE   *Mode;\r
   EFI_STATUS               Status;\r
+  EFI_ARP_CONFIG_DATA      ArpConfigData;\r
 \r
   Mode   = Private->PxeBc.Mode;\r
   Status = EFI_SUCCESS;\r
+  ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));\r
 \r
-  if (Mode->UsingIpv6) {\r
-\r
-    if (StationIp != NULL) {\r
-      CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
-      CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
-    }\r
-\r
+  if (Mode->UsingIpv6 && StationIp != NULL) {\r
+    //\r
+    // Overwrite Udp6CfgData/Ip6CfgData StationAddress.\r
+    //\r
+    CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
+    CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));\r
+    \r
     //\r
     // Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.\r
     //\r
@@ -61,27 +63,55 @@ PxeBcFlushStationIp (
     Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);\r
   } else {\r
     if (StationIp != NULL) {\r
+      //\r
+      // Reconfigure the ARP instance with station Ip address.\r
+      //\r
+      ArpConfigData.SwAddressType   = 0x0800;\r
+      ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS);\r
+      ArpConfigData.StationAddress = StationIp;\r
+\r
+      Private->Arp->Configure (Private->Arp, NULL);\r
+      Private->Arp->Configure (Private->Arp, &ArpConfigData);\r
+\r
+      //\r
+      // Overwrite Udp4CfgData/Ip4CfgData StationAddress.\r
+      //\r
       CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
       CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));\r
     }\r
     \r
     if (SubnetMask != NULL) {\r
+      //\r
+      // Overwrite Udp4CfgData/Ip4CfgData SubnetMask.\r
+      //\r
       CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
       CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
     }\r
 \r
-    //\r
-    // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.\r
-    //\r
-    Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);\r
-    Private->Ip4->Configure (Private->Ip4, NULL);\r
-\r
-    Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);\r
-    if (EFI_ERROR (Status)) {\r
-      goto ON_EXIT;\r
+    if (StationIp != NULL && SubnetMask != NULL) {\r
+      //\r
+      // Updated the route table.\r
+      //\r
+      Mode->RouteTableEntries                = 1;\r
+      Mode->RouteTable[0].IpAddr.Addr[0]     = StationIp->Addr[0] & SubnetMask->Addr[0];\r
+      Mode->RouteTable[0].SubnetMask.Addr[0] = SubnetMask->Addr[0];\r
+      Mode->RouteTable[0].GwAddr.Addr[0]     = 0;\r
     }\r
+    \r
+    if (StationIp != NULL || SubnetMask != NULL) {\r
+      //\r
+      // Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.\r
+      //\r
+      Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);\r
+      Private->Ip4->Configure (Private->Ip4, NULL);\r
 \r
-    Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);\r
+      Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);\r
+      if (EFI_ERROR (Status)) {\r
+        goto ON_EXIT;\r
+      }\r
+\r
+      Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);\r
+    }\r
   }\r
 \r
 ON_EXIT:\r
@@ -257,8 +287,7 @@ PxeBcIcmpErrorDpcHandle (
     //\r
     // The return status should be recognized as EFI_ICMP_ERROR.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (EFI_IP4 (RxData->Header->SourceAddress) != 0 &&\r
@@ -268,25 +297,20 @@ PxeBcIcmpErrorDpcHandle (
     //\r
     // The source address of the received packet should be a valid unicast address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (!EFI_IP4_EQUAL (&RxData->Header->DestinationAddress, &Mode->StationIp.v4)) {\r
     //\r
     // The destination address of the received packet should be equal to the host address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  if (RxData->Header->Protocol != EFI_IP_PROTO_ICMP) {\r
-    //\r
-    // The protocol value in the header of the receveid packet should be EFI_IP_PROTO_ICMP.\r
-    //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
+  \r
+  //\r
+  // The protocol has been configured to only receive ICMP packet.\r
+  //\r
+  ASSERT (RxData->Header->Protocol == EFI_IP_PROTO_ICMP);\r
 \r
   Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
 \r
@@ -298,8 +322,7 @@ PxeBcIcmpErrorDpcHandle (
     //\r
     // The type of the receveid ICMP message should be ICMP_ERROR_MESSAGE.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   //\r
@@ -326,6 +349,9 @@ PxeBcIcmpErrorDpcHandle (
     IcmpError += CopiedLen;\r
   }\r
 \r
+ON_RECYCLE:\r
+  gBS->SignalEvent (RxData->RecycleSignal);\r
+\r
 ON_EXIT:\r
   Private->IcmpToken.Status = EFI_NOT_READY;\r
   Ip4->Receive (Ip4, &Private->IcmpToken);\r
@@ -395,16 +421,14 @@ PxeBcIcmp6ErrorDpcHandle (
     //\r
     // The return status should be recognized as EFI_ICMP_ERROR.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (!NetIp6IsValidUnicast (&RxData->Header->SourceAddress)) {\r
     //\r
     // The source address of the received packet should be a valid unicast address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   if (!NetIp6IsUnspecifiedAddr (&Mode->StationIp.v6) &&\r
@@ -412,17 +436,13 @@ PxeBcIcmp6ErrorDpcHandle (
     //\r
     // The destination address of the received packet should be equal to the host address.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
-  if (RxData->Header->NextHeader != IP6_ICMP) {\r
-    //\r
-    // The nextheader in the header of the receveid packet should be IP6_ICMP.\r
-    //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
-  }\r
+  //\r
+  // The protocol has been configured to only receive ICMP packet.\r
+  //\r
+  ASSERT (RxData->Header->NextHeader == IP6_ICMP);\r
 \r
   Type = *((UINT8 *) RxData->FragmentTable[0].FragmentBuffer);\r
 \r
@@ -433,8 +453,7 @@ PxeBcIcmp6ErrorDpcHandle (
     //\r
     // The type of the receveid packet should be an ICMP6 error message.\r
     //\r
-    gBS->SignalEvent (RxData->RecycleSignal);\r
-    goto ON_EXIT;\r
+    goto ON_RECYCLE;\r
   }\r
 \r
   //\r
@@ -461,6 +480,9 @@ PxeBcIcmp6ErrorDpcHandle (
     Icmp6Error += CopiedLen;\r
   }\r
 \r
+ON_RECYCLE:\r
+  gBS->SignalEvent (RxData->RecycleSignal);\r
+  \r
 ON_EXIT:\r
   Private->Icmp6Token.Status = EFI_NOT_READY;\r
   Ip6->Receive (Ip6, &Private->Icmp6Token);\r