From e371cc146dfac1680e69112a01a3f7d121998c37 Mon Sep 17 00:00:00 2001 From: Jiaxin Wu Date: Thu, 20 Aug 2015 06:47:13 +0000 Subject: MdeModulePkg: Fix default router table and interface missing error Ip4StartAutoConfig() will always free its default router table and interface, which may cause IP instance missing its correct default interface. e.g. when the policy is dhcp, and one child is configured to use default address. Cc: Ye Ting Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiaxin Wu Reviwed-by: Ye Ting git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18245 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/Network/Ip4Dxe/Ip4Config2Impl.c | 74 ++++++++++++---------- MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c | 4 ++ MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c | 2 + MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h | 2 + 4 files changed, 49 insertions(+), 33 deletions(-) (limited to 'MdeModulePkg') diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c index caf84fb7a5..637d7cd659 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c @@ -149,6 +149,7 @@ Ip4Config2OnPolicyChanged ( // Start the dhcp configuration. // if (NewPolicy == Ip4Config2PolicyDhcp) { + IpSb->Reconfig = TRUE; Ip4StartAutoConfig (&IpSb->Ip4Config2Instance); } @@ -463,7 +464,7 @@ Ip4Config2OnDhcp4SbInstalled ( /** Set the station address and subnetmask for the default interface. - @param[in] Instance The pointer to the IP4 config2 instance data. + @param[in] IpSb The pointer to the IP4 service binding instance. @param[in] StationAddress Ip address to be set. @param[in] SubnetMask Subnet to be set. @@ -473,13 +474,12 @@ Ip4Config2OnDhcp4SbInstalled ( **/ EFI_STATUS Ip4Config2SetDefaultAddr ( - IN IP4_CONFIG2_INSTANCE *Instance, + IN IP4_SERVICE *IpSb, IN IP4_ADDR StationAddress, IN IP4_ADDR SubnetMask ) { EFI_STATUS Status; - IP4_SERVICE *IpSb; IP4_INTERFACE *IpIf; IP4_PROTOCOL *Ip4Instance; EFI_ARP_PROTOCOL *Arp; @@ -487,7 +487,6 @@ Ip4Config2SetDefaultAddr ( IP4_ADDR Subnet; IP4_ROUTE_TABLE *RouteTable; - IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); IpIf = IpSb->DefaultInterface; ASSERT (IpIf != NULL); @@ -496,35 +495,37 @@ Ip4Config2SetDefaultAddr ( return EFI_SUCCESS; } - // - // The default address is changed, free the previous interface first. - // - if (IpSb->DefaultRouteTable != NULL) { - Ip4FreeRouteTable (IpSb->DefaultRouteTable); - IpSb->DefaultRouteTable = NULL; - } + if (IpSb->Reconfig) { + // + // The default address is changed, free the previous interface first. + // + if (IpSb->DefaultRouteTable != NULL) { + Ip4FreeRouteTable (IpSb->DefaultRouteTable); + IpSb->DefaultRouteTable = NULL; + } - Ip4CancelReceive (IpSb->DefaultInterface); - Ip4FreeInterface (IpSb->DefaultInterface, NULL); - IpSb->DefaultInterface = NULL; - // - // Create new default interface and route table. - // - IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image); - if (IpIf == NULL) { - return EFI_OUT_OF_RESOURCES; - } + Ip4CancelReceive (IpSb->DefaultInterface); + Ip4FreeInterface (IpSb->DefaultInterface, NULL); + IpSb->DefaultInterface = NULL; + // + // Create new default interface and route table. + // + IpIf = Ip4CreateInterface (IpSb->Mnp, IpSb->Controller, IpSb->Image); + if (IpIf == NULL) { + return EFI_OUT_OF_RESOURCES; + } - RouteTable = Ip4CreateRouteTable (); - if (RouteTable == NULL) { - Ip4FreeInterface (IpIf, NULL); - return EFI_OUT_OF_RESOURCES; + RouteTable = Ip4CreateRouteTable (); + if (RouteTable == NULL) { + Ip4FreeInterface (IpIf, NULL); + return EFI_OUT_OF_RESOURCES; + } + + IpSb->DefaultInterface = IpIf; + InsertHeadList (&IpSb->Interfaces, &IpIf->Link); + IpSb->DefaultRouteTable = RouteTable; + Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb); } - - IpSb->DefaultInterface = IpIf; - InsertHeadList (&IpSb->Interfaces, &IpIf->Link); - IpSb->DefaultRouteTable = RouteTable; - Ip4ReceiveFrame (IpIf, NULL, Ip4AccpetFrame, IpSb); if (IpSb->State == IP4_SERVICE_CONFIGED) { IpSb->State = IP4_SERVICE_UNSTARTED; @@ -578,6 +579,8 @@ Ip4Config2SetDefaultAddr ( ); IpSb->State = IP4_SERVICE_CONFIGED; + IpSb->Reconfig = FALSE; + return EFI_SUCCESS; } @@ -604,7 +607,9 @@ Ip4Config2SetDefaultIf ( EFI_STATUS Status; IP4_SERVICE *IpSb; - Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask); + IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); + + Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask); if (EFI_ERROR (Status)) { return Status; } @@ -612,7 +617,6 @@ Ip4Config2SetDefaultIf ( // // Create a route if there is a default router. // - IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); if (GatewayAddress != IP4_ALLZERO_ADDRESS) { Ip4AddRoute ( IpSb->DefaultRouteTable, @@ -1071,6 +1075,9 @@ Ip4Config2SetMaunualAddress ( IP4_ADDR StationAddress; IP4_ADDR SubnetMask; VOID *Ptr; + IP4_SERVICE *IpSb; + + IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance); ASSERT (Instance->DataItem[Ip4Config2DataTypeManualAddress].Status != EFI_NOT_READY); @@ -1105,7 +1112,8 @@ Ip4Config2SetMaunualAddress ( StationAddress = EFI_NTOHL (NewAddress.Address); SubnetMask = EFI_NTOHL (NewAddress.SubnetMask); - Status = Ip4Config2SetDefaultAddr (Instance, StationAddress, SubnetMask); + IpSb->Reconfig = TRUE; + Status = Ip4Config2SetDefaultAddr (IpSb, StationAddress, SubnetMask); if (EFI_ERROR (Status)) { goto ON_EXIT; } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c index 4d3ccec610..d8ab948457 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c @@ -211,6 +211,8 @@ Ip4CreateService ( IpSb->Timer = NULL; IpSb->ReconfigEvent = NULL; + + IpSb->Reconfig = FALSE; IpSb->MediaPresent = TRUE; @@ -396,6 +398,8 @@ Ip4CleanService ( IpSb->ReconfigEvent = NULL; } + IpSb->Reconfig = FALSE; + if (IpSb->MacString != NULL) { FreePool (IpSb->MacString); } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c index ac8fb1a7b0..b9a294b199 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c @@ -584,6 +584,8 @@ Ip4AutoReconfigCallBackDpc ( if (IpSb->State > IP4_SERVICE_UNSTARTED) { IpSb->State = IP4_SERVICE_UNSTARTED; } + + IpSb->Reconfig = TRUE; Ip4StartAutoConfig (&IpSb->Ip4Config2Instance); diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h index 4bb0089413..a1a76bd612 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h @@ -205,6 +205,8 @@ struct _IP4_SERVICE { EFI_EVENT ReconfigEvent; + BOOLEAN Reconfig; + // // Underlying media present status. // -- cgit v1.2.3