NetworkPkg/UefiPxeBcDxe: Configure the ARP Instance/RouteTable with new address

After completed a DHCP D.O.R.A process and got the new address, the ARP Instance
and RouteTable should be configured so as to avoid the later Pxe.Arp failure.

Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
This commit is contained in:
Jiaxin Wu 2018-03-13 16:53:18 +08:00
parent 07bd82d42b
commit 2f1b849dc8
2 changed files with 52 additions and 40 deletions

View File

@ -2003,7 +2003,6 @@ EfiPxeBcSetStationIP (
EFI_STATUS Status; EFI_STATUS Status;
PXEBC_PRIVATE_DATA *Private; PXEBC_PRIVATE_DATA *Private;
EFI_PXE_BASE_CODE_MODE *Mode; EFI_PXE_BASE_CODE_MODE *Mode;
EFI_ARP_CONFIG_DATA ArpConfigData;
if (This == NULL) { if (This == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
@ -2043,27 +2042,6 @@ EfiPxeBcSetStationIP (
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto ON_EXIT; goto ON_EXIT;
} }
} else if (!Mode->UsingIpv6 && NewStationIp != NULL) {
//
// Configure the corresponding ARP with the IPv4 address.
//
ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));
ArpConfigData.SwAddressType = 0x0800;
ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS);
ArpConfigData.StationAddress = &NewStationIp->v4;
Private->Arp->Configure (Private->Arp, NULL);
Private->Arp->Configure (Private->Arp, &ArpConfigData);
if (NewSubnetMask != NULL) {
Mode->RouteTableEntries = 1;
Mode->RouteTable[0].IpAddr.Addr[0] = NewStationIp->Addr[0] & NewSubnetMask->Addr[0];
Mode->RouteTable[0].SubnetMask.Addr[0] = NewSubnetMask->Addr[0];
Mode->RouteTable[0].GwAddr.Addr[0] = 0;
}
Private->IsAddressOk = TRUE;
} }
if (NewStationIp != NULL) { if (NewStationIp != NULL) {
@ -2077,6 +2055,10 @@ EfiPxeBcSetStationIP (
} }
Status = PxeBcFlushStationIp (Private, NewStationIp, NewSubnetMask); Status = PxeBcFlushStationIp (Private, NewStationIp, NewSubnetMask);
if (!EFI_ERROR (Status)) {
Private->IsAddressOk = TRUE;
}
ON_EXIT: ON_EXIT:
return Status; return Status;
} }

View File

@ -1,7 +1,7 @@
/** @file /** @file
Support functions implementation for UefiPxeBc Driver. Support functions implementation for UefiPxeBc Driver.
Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR> Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
@ -36,17 +36,19 @@ PxeBcFlushStationIp (
{ {
EFI_PXE_BASE_CODE_MODE *Mode; EFI_PXE_BASE_CODE_MODE *Mode;
EFI_STATUS Status; EFI_STATUS Status;
EFI_ARP_CONFIG_DATA ArpConfigData;
Mode = Private->PxeBc.Mode; Mode = Private->PxeBc.Mode;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
ZeroMem (&ArpConfigData, sizeof (EFI_ARP_CONFIG_DATA));
if (Mode->UsingIpv6) { if (Mode->UsingIpv6 && StationIp != NULL) {
//
if (StationIp != NULL) { // Overwrite Udp6CfgData/Ip6CfgData StationAddress.
CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS)); //
CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS)); CopyMem (&Private->Udp6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
} CopyMem (&Private->Ip6CfgData.StationAddress, StationIp, sizeof (EFI_IPv6_ADDRESS));
// //
// Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address. // Reconfigure the Ip6 instance to capture background ICMP6 packets with new station Ip address.
// //
@ -61,27 +63,55 @@ PxeBcFlushStationIp (
Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token); Status = Private->Ip6->Receive (Private->Ip6, &Private->Icmp6Token);
} else { } else {
if (StationIp != NULL) { if (StationIp != NULL) {
//
// Reconfigure the ARP instance with station Ip address.
//
ArpConfigData.SwAddressType = 0x0800;
ArpConfigData.SwAddressLength = (UINT8) sizeof (EFI_IPv4_ADDRESS);
ArpConfigData.StationAddress = StationIp;
Private->Arp->Configure (Private->Arp, NULL);
Private->Arp->Configure (Private->Arp, &ArpConfigData);
//
// Overwrite Udp4CfgData/Ip4CfgData StationAddress.
//
CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Private->Udp4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Private->Ip4CfgData.StationAddress, StationIp, sizeof (EFI_IPv4_ADDRESS));
} }
if (SubnetMask != NULL) { if (SubnetMask != NULL) {
//
// Overwrite Udp4CfgData/Ip4CfgData SubnetMask.
//
CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Private->Udp4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS)); CopyMem (&Private->Ip4CfgData.SubnetMask, SubnetMask, sizeof (EFI_IPv4_ADDRESS));
} }
// if (StationIp != NULL && SubnetMask != NULL) {
// Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address. //
// // Updated the route table.
Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken); //
Private->Ip4->Configure (Private->Ip4, NULL); Mode->RouteTableEntries = 1;
Mode->RouteTable[0].IpAddr.Addr[0] = StationIp->Addr[0] & SubnetMask->Addr[0];
Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData); Mode->RouteTable[0].SubnetMask.Addr[0] = SubnetMask->Addr[0];
if (EFI_ERROR (Status)) { Mode->RouteTable[0].GwAddr.Addr[0] = 0;
goto ON_EXIT;
} }
if (StationIp != NULL || SubnetMask != NULL) {
//
// Reconfigure the Ip4 instance to capture background ICMP packets with new station Ip address.
//
Private->Ip4->Cancel (Private->Ip4, &Private->IcmpToken);
Private->Ip4->Configure (Private->Ip4, NULL);
Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken); Status = Private->Ip4->Configure (Private->Ip4, &Private->Ip4CfgData);
if (EFI_ERROR (Status)) {
goto ON_EXIT;
}
Status = Private->Ip4->Receive (Private->Ip4, &Private->IcmpToken);
}
} }
ON_EXIT: ON_EXIT: