From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Permerror (SPF Permanent Error: Two or more type TXT spf records found.) identity=mailfrom; client-ip=192.55.52.88; helo=mga01.intel.com; envelope-from=ting.ye@intel.com; receiver=edk2-devel@lists.01.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id B8A8A21106FCB for ; Fri, 31 Aug 2018 01:47:32 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Aug 2018 01:47:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,309,1531810800"; d="scan'208";a="76976469" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by FMSMGA003.fm.intel.com with ESMTP; 31 Aug 2018 01:47:25 -0700 Received: from fmsmsx101.amr.corp.intel.com (10.18.124.199) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Fri, 31 Aug 2018 01:47:21 -0700 Received: from shsmsx152.ccr.corp.intel.com (10.239.6.52) by fmsmsx101.amr.corp.intel.com (10.18.124.199) with Microsoft SMTP Server (TLS) id 14.3.319.2; Fri, 31 Aug 2018 01:47:21 -0700 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.240]) by SHSMSX152.ccr.corp.intel.com ([169.254.6.150]) with mapi id 14.03.0319.002; Fri, 31 Aug 2018 16:46:45 +0800 From: "Ye, Ting" To: "Fu, Siyuan" , "edk2-devel@lists.01.org" CC: "Wu, Jiaxin" Thread-Topic: [PATCH v2] MdeModulePkg/Network: Add 32bit subnet mask support for IP4 PXE boot. Thread-Index: AQHUP3WnvnR5/yrb7EanOnMXAwd/GaTZiOSQ Date: Fri, 31 Aug 2018 08:46:44 +0000 Message-ID: References: <20180829085234.39220-1-siyuan.fu@intel.com> In-Reply-To: <20180829085234.39220-1-siyuan.fu@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v2] MdeModulePkg/Network: Add 32bit subnet mask support for IP4 PXE boot. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Aug 2018 08:47:33 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Siyuan, Please fix below typo when check in the patch. "...cancelled" Callback function when ARP request are finished. It will cancelled @@ -814= ,6 +897,7 @@ Ip4OnArpResolvedDpc ( Also do we need define a macro for "0xFFFFFFFF"/"0xFFFFFFFFu" used in Mtftp= 4 and ifconfig? Reviewed-by: Ye Ting =20 Thanks, Ting -----Original Message----- From: Fu, Siyuan=20 Sent: Wednesday, August 29, 2018 4:53 PM To: edk2-devel@lists.01.org Cc: Ye, Ting ; Wu, Jiaxin Subject: [PATCH v2] MdeModulePkg/Network: Add 32bit subnet mask support for= IP4 PXE boot. V2 update: The original patch has a problem, that if an IP child which not using defau= lt address is configured with /32 subnet mask, while the gateway is configu= red to the default route table, then the gateway won't take effect on that = IP child. This patch fixed the problem. This patch updates IP4 stack to support 32bit subnet mask in PXE boot proce= ss. When 32bit subnet mask is used, the IP4 driver couldn't use the subnet mask= to determine whether destination IP address is on-link or not, so it will = always try to send all the packets to the destination IP address directly f= irst, if failed it will continue to try the default gateway. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Fu Siyuan Cc: Ye Ting Cc: Wu Jiaxin --- MdeModulePkg/Include/Library/NetLib.h | 5 +- MdeModulePkg/Library/DxeNetLib/DxeNetLib.c | 13 +- .../Universal/Network/Ip4Dxe/Ip4Common.h | 2 +- MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c | 117 ++++++++++++++++-- MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.h | 5 +- .../Universal/Network/Ip4Dxe/Ip4Impl.c | 2 +- .../Universal/Network/Ip4Dxe/Ip4Output.c | 11 +- .../Universal/Network/Ip4Dxe/Ip4Route.c | 26 +++- .../Universal/Network/Ip4Dxe/Ip4Route.h | 9 +- .../Universal/Network/Mtftp4Dxe/Mtftp4Impl.c | 6 +- 10 files changed, 163 insertions(+), 33 deletions(-) diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/L= ibrary/NetLib.h index ef7bc429c1..b7ef99c7b5 100644 --- a/MdeModulePkg/Include/Library/NetLib.h +++ b/MdeModulePkg/Include/Library/NetLib.h @@ -422,8 +422,9 @@ NetGetIpClass ( =20 If all bits of the host address of IP are 0 or 1, IP is also not a valid= unicast address, except when the originator is one of the endpoints of a point-to-point l= ink with a 31-bit - mask (RFC3021). - + mask (RFC3021), or a 32bit NetMask (all 0xFF) is used for special networ= k environment (e.g. + PPP link). + =20 @param[in] Ip The IP to check against. @param[in] NetMask The mask of the IP. =20 diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Libr= ary/DxeNetLib/DxeNetLib.c index bf8f5523e6..63f4724062 100644 --- a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c +++ b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c @@ -654,8 +654,9 @@ NetGetIpClass ( =20 If all bits of the host address of IP are 0 or 1, IP is also not a valid= unicast address, except when the originator is one of the endpoints of a point-to-point l= ink with a 31-bit - mask (RFC3021). - + mask (RFC3021), or a 32bit NetMask (all 0xFF) is used for special networ= k environment (e.g. + PPP link). + =20 @param[in] Ip The IP to check against. @param[in] NetMask The mask of the IP. =20 @@ -669,18 +670,20 @@ NetIp4IsUnicast ( IN IP4_ADDR NetMask ) { + INTN MaskLength; + =20 ASSERT (NetMask !=3D 0); =20 if (Ip =3D=3D 0 || IP4_IS_LOCAL_BROADCAST (Ip)) { return FALSE; } =20 - if (NetGetMaskLength (NetMask) !=3D 31) { + MaskLength =3D NetGetMaskLength (NetMask); ASSERT ((MaskLength >=3D 0)= =20 + && (MaskLength <=3D IP4_MASK_NUM)); if (MaskLength < 31) { if (((Ip &~NetMask) =3D=3D ~NetMask) || ((Ip &~NetMask) =3D=3D 0)) { return FALSE; } - } else { - return TRUE; } =20 return TRUE; diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h b/MdeModuleP= kg/Universal/Network/Ip4Dxe/Ip4Common.h index e0fffc9d0d..994a81f4de 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h @@ -55,7 +55,7 @@ typedef struct _IP4_SERVICE IP4_SERVICE; /// Compose the fragment field to be used in the IP4 header. /// #define IP4_HEAD_FRAGMENT_FIELD(Df, Mf, Offset) \ - ((UINT16)(((Df) ? 0x4000 : 0) | ((Mf) ? 0x2000 : 0) | (((Offset) >> 3)= & 0x1fff))) + ((UINT16)(((Df) ? IP4_HEAD_DF_MASK : 0) | ((Mf) ? IP4_HEAD_MF_MASK=20 + : 0) | (((Offset) >> 3) & IP4_HEAD_OFFSET_MASK))) =20 #define IP4_LAST_FRAGMENT(FragmentField) \ (((FragmentField) & IP4_HEAD_MF_MASK) =3D=3D 0) diff --git a/Mde= ModulePkg/Universal/Network/Ip4Dxe/Ip4If.c b/MdeModulePkg/Universal/Network= /Ip4Dxe/Ip4If.c index 6e0e3290c7..b0172283b7 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c @@ -138,6 +138,7 @@ Ip4CancelFrameArp ( @param[in] CallBack Call back function to execute if transmiss= ion finished. @param[in] Context Opaque parameter to the call back. + @param[in] IpSb The pointer to the IP4 service binding ins= tance. =20 @retval Token The wrapped token if succeed @retval NULL The wrapped token if NULL @@ -149,7 +150,8 @@ Ip4WrapLinkTxToken ( IN IP4_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN IP4_FRAME_CALLBACK CallBack, - IN VOID *Context + IN VOID *Context, + IN IP4_SERVICE *IpSb ) { EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken; @@ -170,6 +172,7 @@ Ip4= WrapLinkTxToken ( =20 Token->Interface =3D Interface; Token->IpInstance =3D IpInstance; + Token->IpSb =3D IpSb; Token->CallBack =3D CallBack; Token->Packet =3D Packet; Token->Context =3D Context; @@ -792,6 +795,86 @@ Ip4FreeInterface ( return EFI_SUCCESS; } =20 +/** + This function tries to send all the queued frames in ArpQue to the=20 +default gateway if + the ARP resolve for direct destination address is failed when using /32 = subnet mask. + + @param[in] ArpQue The ARP queue of a failed request. + =20 + @retval EFI_SUCCESS All the queued frames have been send to th= e default route. + @retval Others Failed to send the queued frames. + =20 +**/ +EFI_STATUS +Ip4SendFrameToDefaultRoute ( + IN IP4_ARP_QUE *ArpQue + ) +{ + LIST_ENTRY *Entry; + LIST_ENTRY *Next; + IP4_ROUTE_CACHE_ENTRY *RtCacheEntry; + IP4_LINK_TX_TOKEN *Token; + IP4_ADDR Gateway; + EFI_STATUS Status; + IP4_ROUTE_ENTRY *DefaultRoute; + =20 + // + // ARP resolve failed when using /32 subnet mask. + // + NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) { + RemoveEntryList (Entry); + Token =3D NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link); + ASSERT (Token->Interface->SubnetMask =3D=3D IP4_ALLONE_ADDRESS); + // + // Find the default gateway IP address. The default route was saved to= the RtCacheEntry->Tag in Ip4Route(). + // + RtCacheEntry =3D NULL; + if (Token->IpInstance !=3D NULL) { + RtCacheEntry =3D Ip4FindRouteCache (Token->IpInstance->RouteTable, N= TOHL (ArpQue->Ip), Token->Interface->Ip); + } + if (RtCacheEntry =3D=3D NULL) { + RtCacheEntry =3D Ip4FindRouteCache (Token->IpSb->DefaultRouteTable, = NTOHL (ArpQue->Ip), Token->Interface->Ip); + } + if (RtCacheEntry =3D=3D NULL) { + Status=3D EFI_NO_MAPPING; + goto ON_ERROR; + } + DefaultRoute =3D (IP4_ROUTE_ENTRY*)RtCacheEntry->Tag; + if (DefaultRoute =3D=3D NULL) { + Status=3D EFI_NO_MAPPING; + goto ON_ERROR; + } + // + // Try to send the frame to the default route. + // + Gateway =3D DefaultRoute->NextHop; + if (ArpQue->Ip =3D=3D Gateway) { + // + // ARP resolve for the default route is failed, return error to call= er.=20 + // + Status=3D EFI_NO_MAPPING; + goto ON_ERROR; + } + RtCacheEntry->NextHop =3D Gateway; + Status =3D Ip4SendFrame (Token->Interface,Token->IpInstance,Token->Pac= ket,Gateway,Token->CallBack,Token->Context,Token->IpSb); + if (EFI_ERROR (Status)) { + Status=3D EFI_NO_MAPPING; + goto ON_ERROR; + } + Ip4FreeRouteCacheEntry (RtCacheEntry); } + + return EFI_SUCCESS; + =20 +ON_ERROR: + if (RtCacheEntry !=3D NULL) { + Ip4FreeRouteCacheEntry (RtCacheEntry); + } + Token->CallBack (Token->IpInstance, Token->Packet, Status, 0,=20 +Token->Context); + Ip4FreeLinkTxToken (Token); + return Status; +} + =20 /** Callback function when ARP request are finished. It will cancelled @@ -8= 14,6 +897,7 @@ Ip4OnArpResolvedDpc ( IP4_INTERFACE *Interface; IP4_LINK_TX_TOKEN *Token; EFI_STATUS Status; + EFI_STATUS IoStatus; =20 ArpQue =3D (IP4_ARP_QUE *) Context; NET_CHECK_SIGNATURE (ArpQue, IP4_FRAME_ARP_SIGNATURE); @@ -821,14 +905,2= 3 @@ Ip4OnArpResolvedDpc ( RemoveEntryList (&ArpQue->Link); =20 // - // ARP resolve failed for some reason. Release all the frame - // and ARP queue itself. Ip4FreeArpQue will call the frame's - // owner back. + // ARP resolve failed for some reason.=20 // if (NET_MAC_EQUAL (&ArpQue->Mac, &mZeroMacAddress, ArpQue->Interface->Hw= addrLen)) { - Ip4FreeArpQue (ArpQue, EFI_NO_MAPPING); - - return ; + if (ArpQue->Interface->SubnetMask !=3D IP4_ALLONE_ADDRESS) { + // + // Release all the frame and ARP queue itself. Ip4FreeArpQue will ca= ll the frame's + // owner back. + // + IoStatus =3D EFI_NO_MAPPING; + } else { + // + // ARP resolve failed when using 32bit subnet mask, try to send the = packets to the + // default route. + // + IoStatus =3D Ip4SendFrameToDefaultRoute (ArpQue); + } + goto ON_EXIT; } =20 // @@ -836,6 +929,7 @@ Ip4OnArpResolvedDpc ( // queue. It isn't necessary for us to cache the ARP binding because // we always check the ARP cache first before transmit. // + IoStatus =3D EFI_SUCCESS; Interface =3D ArpQue->Interface; =20 NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) { @@ -863,7 +957,8= @@ Ip4OnArpResolvedDpc ( } } =20 - Ip4FreeArpQue (ArpQue, EFI_SUCCESS); +ON_EXIT: + Ip4FreeArpQue (ArpQue, IoStatus); } =20 /** @@ -957,6 +1052,7 @@ Ip4OnFrameSent ( to. @param[in] CallBack Function to call back when transmit finish= ed. @param[in] Context Opaque parameter to the call back. + @param[in] IpSb The pointer to the IP4 service binding ins= tance. =20 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to send the fr= ame @retval EFI_NO_MAPPING Can't resolve the MAC for the nexthop @@ -971,7 +1067,8 @@ Ip4SendFrame ( IN NET_BUF *Packet, IN IP4_ADDR NextHop, IN IP4_FRAME_CALLBACK CallBack, - IN VOID *Context + IN VOID *Context, + IN IP4_SERVICE *IpSb ) { IP4_LINK_TX_TOKEN *Token; @@ -982,7 +1079,7 @@ Ip4SendFrame ( =20 ASSERT (Interface->Configured); =20 - Token =3D Ip4WrapLinkTxToken (Interface, IpInstance, Packet, CallBack, C= ontext); + Token =3D Ip4WrapLinkTxToken (Interface, IpInstance, Packet, CallBack,=20 + Context, IpSb); =20 if (Token =3D=3D NULL) { return EFI_OUT_OF_RESOURCES; diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.h b/MdeModulePkg/U= niversal/Network/Ip4Dxe/Ip4If.h index 909837131e..36e4ab3f7a 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.h @@ -79,6 +79,7 @@ typedef struct { LIST_ENTRY Link; =20 IP4_INTERFACE *Interface; + IP4_SERVICE *IpSb; =20 IP4_PROTOCOL *IpInstance; IP4_FRAME_CALLBACK CallBack; @@ -262,6 +263,7 @@ Ip4FreeInterface ( to. @param[in] CallBack Function to call back when transmit finish= ed. @param[in] Context Opaque parameter to the call back. + @param[in] IpSb The pointer to the IP4 service binding ins= tance. =20 @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to send the fr= ame @retval EFI_NO_MAPPING Can't resolve the MAC for the nexthop @@ -276,7 +278,8 @@ Ip4SendFrame ( IN NET_BUF *Packet, IN IP4_ADDR NextHop, IN IP4_FRAME_CALLBACK CallBack, - IN VOID *Context + IN VOID *Context, + IN IP4_SERVICE *IpSb ); =20 /** diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c b/MdeModulePkg= /Universal/Network/Ip4Dxe/Ip4Impl.c index 6a26143e30..7c27db6753 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c @@ -1259,7 +1259,7 @@ EfiIp4Routes ( // the gateway address must be a unicast on the connected network if not= zero. // if ((Nexthop !=3D IP4_ALLZERO_ADDRESS) && - (!IP4_NET_EQUAL (Nexthop, IpIf->Ip, IpIf->SubnetMask) || + ((IpIf->SubnetMask !=3D IP4_ALLONE_ADDRESS && !IP4_NET_EQUAL=20 + (Nexthop, IpIf->Ip, IpIf->SubnetMask)) || IP4_IS_BROADCAST (Ip4GetNetCast (Nexthop, IpIf)))) { =20 Status =3D EFI_INVALID_PARAMETER; diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c b/MdeModuleP= kg/Universal/Network/Ip4Dxe/Ip4Output.c index 1716f43576..6b759d8d10 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c @@ -309,15 +309,15 @@ Ip4Output ( // Route the packet unless overrided, that is, GateWay isn't zero. // if (IpInstance =3D=3D NULL) { - CacheEntry =3D Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head->S= rc); + CacheEntry =3D Ip4Route (IpSb->DefaultRouteTable, Head->Dst,=20 + Head->Src, IpIf->SubnetMask, TRUE); } else { - CacheEntry =3D Ip4Route (IpInstance->RouteTable, Head->Dst, Head->Sr= c); + CacheEntry =3D Ip4Route (IpInstance->RouteTable, Head->Dst,=20 + Head->Src, IpIf->SubnetMask, FALSE); // // If failed to route the packet by using the instance's route table= , // try to use the default route table. // if (CacheEntry =3D=3D NULL) { - CacheEntry =3D Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head-= >Src); + CacheEntry =3D Ip4Route (IpSb->DefaultRouteTable, Head->Dst,=20 + Head->Src, IpIf->SubnetMask, TRUE); } } =20 @@ -386,7 +386,8 @@ Ip4Output ( Fragment, GateWay, Ip4SysPacketSent, - Packet + Packet, + IpSb ); =20 if (EFI_ERROR (Status)) { @@ -429,7 +430,7 @@ Ip4Output ( // upper layer's packets. // Ip4PrependHead (Packet, Head, Option, OptLen); - Status =3D Ip4SendFrame (IpIf, IpInstance, Packet, GateWay, Callback, Co= ntext); + Status =3D Ip4SendFrame (IpIf, IpInstance, Packet, GateWay, Callback,=20 + Context, IpSb); =20 if (EFI_ERROR (Status)) { goto ON_ERROR; diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.c b/MdeModulePk= g/Universal/Network/Ip4Dxe/Ip4Route.c index d240d5343a..120345836b 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.c @@ -494,6 +494,11 @@ Ip4FindRouteEntry ( @param[in] RtTable The route table to search from @param[in] Dest The destination address to search for @param[in] Src The source address to search for + @param[in] SubnetMask The subnet mask of the Src address, th= is field is + used to check if the station is using = /32 subnet. + @param[in] AlwaysTryDestAddr Always try to use the dest address as = next hop even + though we can't find a matching route = entry. This + field is only valid when using /32 sub= net. =20 @return NULL if failed to route packet, otherwise a route cache entry that can be used to route packet. @@ -503,7 +508,9 @@ IP4_ROUTE_CACHE_ENTRY * Ip4Route ( IN IP4_ROUTE_TABLE *RtTable, IN IP4_ADDR Dest, - IN IP4_ADDR Src + IN IP4_ADDR Src, + IN IP4_ADDR SubnetMask, + IN BOOLEAN AlwaysTryDestAddr ) { LIST_ENTRY *Head; @@ -535,7 +542,11 @@ Ip4Route ( RtEntry =3D Ip4FindRouteEntry (RtTable, Dest); =20 if (RtEntry =3D=3D NULL) { - return NULL; + if (SubnetMask !=3D IP4_ALLONE_ADDRESS) { + return NULL; + } else if (!AlwaysTryDestAddr) { + return NULL; + } } =20 // @@ -544,16 +555,23 @@ Ip4Route ( // network. Otherwise, it is an indirect route, the packet will be // sent to the next hop router. // - if ((RtEntry->Flag & IP4_DIRECT_ROUTE) !=3D 0) { + // When using /32 subnet mask, the packet will always be sent to the=20 + direct // destination first, if we can't find a matching route cache. + // + if (SubnetMask =3D=3D IP4_ALLONE_ADDRESS || ((RtEntry->Flag &=20 + IP4_DIRECT_ROUTE) !=3D 0)) { NextHop =3D Dest; } else { NextHop =3D RtEntry->NextHop; } =20 - Ip4FreeRouteEntry (RtEntry); + if (RtEntry !=3D NULL) { + Ip4FreeRouteEntry (RtEntry); + } =20 // // Create a route cache entry, and tag it as spawned from this route ent= ry + // For /32 subnet mask, the default route in RtEntry will be used if=20 + failed // to send the packet to driect destination address. // RtCacheEntry =3D Ip4CreateRouteCacheEntry (Dest, Src, NextHop, (UINTN) R= tEntry); =20 diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.h b/MdeModulePk= g/Universal/Network/Ip4Dxe/Ip4Route.h index 6269f4ceda..764c85a70f 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.h @@ -194,6 +194,11 @@ Ip4FreeRouteCacheEntry ( @param[in] RtTable The route table to search from @param[in] Dest The destination address to search for @param[in] Src The source address to search for + @param[in] SubnetMask The subnet mask of the Src address, th= is field is + used to check if the station is using = /32 subnet. + @param[in] AlwaysTryDestAddr Always try to use the dest address as = next hop even + though we can't find a matching route = entry. This + field is only valid when using /32 sub= net. =20 @return NULL if failed to route packet, otherwise a route cache entry that can be used to route packet. @@ -203,7 +208,9 @@ IP4_ROUTE_CACHE_ENTRY * Ip4Route ( IN IP4_ROUTE_TABLE *RtTable, IN IP4_ADDR Dest, - IN IP4_ADDR Src + IN IP4_ADDR Src, + IN IP4_ADDR SubnetMask, + IN BOOLEAN AlwaysTryDestAddr ); =20 /** diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeMod= ulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c index d5a1a8c303..03903640b8 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c @@ -509,8 +509,9 @@ Mtftp4Start ( goto ON_ERROR; } =20 + gBS->RestoreTPL(OldTpl); + if (Token->Event !=3D NULL) { - gBS->RestoreTPL (OldTpl); return EFI_SUCCESS; } =20 @@ -522,7 +523,6 @@ Mtftp4Start ( This->Poll (This); } =20 - gBS->RestoreTPL (OldTpl); return Token->Status; =20 ON_ERROR: @@ -682,7 +682,7 @@ EfiMtftp4Configure ( } =20 if ((Gateway !=3D 0) && - (!IP4_NET_EQUAL (Gateway, Ip, Netmask) || (Netmask !=3D 0 && !NetI= p4IsUnicast (Gateway, Netmask)))) { + ((Netmask !=3D 0xFFFFFFFF && !IP4_NET_EQUAL (Gateway, Ip,=20 + Netmask)) || (Netmask !=3D 0 && !NetIp4IsUnicast (Gateway, Netmask)))) { =20 return EFI_INVALID_PARAMETER; } -- 2.18.0.windows.1