X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FIp4Dxe%2FIp4Output.c;h=1716f43576f2a4c888b37d1546d9fa3ff2d45bfa;hp=1a925cf9369874f93e5f7a7c2c740674f84398cc;hb=d1102dba7210b95e41d06c2338a22ba6af248645;hpb=e48e37fce2611df7a52aff271835ff72ee396d9b diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c index 1a925cf936..1716f43576 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c @@ -1,7 +1,8 @@ /** @file + Transmit the IP4 packet. -Copyright (c) 2005 - 2006, Intel Corporation -All rights reserved. This program and the accompanying materials +Copyright (c) 2005 - 2018, 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 which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php @@ -9,15 +10,6 @@ http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -Module Name: - - Ip4Output.c - -Abstract: - - Transmit the IP4 packet - - **/ #include "Ip4Impl.h" @@ -29,14 +21,14 @@ UINT16 mIp4Id; Prepend an IP4 head to the Packet. It will copy the options and build the IP4 header fields. Used for IP4 fragmentation. - @param Packet The packet to prepend IP4 header to - @param Head The caller supplied header. The caller should set - the following header fields: Tos, TotalLen, Id, - Fragment, Ttl, Protocol, Src and Dst. All the fields - are in host byte order. This function will fill in - the Ver, HeadLen, and checksum. - @param Option The orginal IP4 option to copy from - @param OptLen The length of the IP4 option + @param Packet The packet to prepend IP4 header to + @param Head The caller supplied header. The caller should set + the following header fields: Tos, TotalLen, Id, + Fragment, Ttl, Protocol, Src and Dst. All the fields + are in host byte order. This function will fill in + the Ver, HeadLen, and checksum. + @param Option The orginal IP4 option to copy from + @param OptLen The length of the IP4 option @retval EFI_BAD_BUFFER_SIZE There is no enought room in the head space of Packet. @@ -45,10 +37,10 @@ UINT16 mIp4Id; **/ EFI_STATUS Ip4PrependHead ( - IN NET_BUF *Packet, - IN IP4_HEAD *Head, - IN UINT8 *Option, - IN UINT32 OptLen + IN OUT NET_BUF *Packet, + IN IP4_HEAD *Head, + IN UINT8 *Option, + IN UINT32 OptLen ) { UINT32 HeadLen; @@ -65,7 +57,7 @@ Ip4PrependHead ( Ip4CopyOption (Option, OptLen, FirstFragment, NULL, &Len); HeadLen = IP4_MIN_HEADLEN + Len; - ASSERT (((Len %4) == 0) && (HeadLen <= IP4_MAX_HEADLEN)); + ASSERT (((Len % 4) == 0) && (HeadLen <= IP4_MAX_HEADLEN)); PacketHead = (IP4_HEAD *) NetbufAllocSpace (Packet, HeadLen, NET_BUF_HEAD); @@ -81,7 +73,7 @@ Ip4PrependHead ( PacketHead->Ver = 4; PacketHead->HeadLen = (UINT8) (HeadLen >> 2); PacketHead->Tos = Head->Tos; - PacketHead->TotalLen = HTONS (Packet->TotalSize); + PacketHead->TotalLen = HTONS ((UINT16) Packet->TotalSize); PacketHead->Id = HTONS (Head->Id); PacketHead->Fragment = HTONS (Head->Fragment); PacketHead->Checksum = 0; @@ -91,7 +83,7 @@ Ip4PrependHead ( PacketHead->Dst = HTONL (Head->Dst); PacketHead->Checksum = (UINT16) (~NetblockChecksum ((UINT8 *) PacketHead, HeadLen)); - Packet->Ip = PacketHead; + Packet->Ip.Ip4 = PacketHead; return EFI_SUCCESS; } @@ -101,12 +93,12 @@ Ip4PrependHead ( itself, that is, not by the requests of IP4 child's consumer. Such packets include the ICMP echo replies, and other ICMP error packets. - @param IpSb The IP4 service that wants to send the packets. - @param Dst The destination of the packet - @param Src The source of the packet + @param[in] IpSb The IP4 service that wants to send the packets. + @param[in] Dst The destination of the packet + @param[in] Src The source of the packet @return NULL if no proper interface is found, otherwise the interface that - @return can be used to send the system packet from. + can be used to send the system packet from. **/ IP4_INTERFACE * @@ -170,8 +162,6 @@ Ip4SelectInterface ( for reference. @param Context The context provided by us - @return None - **/ VOID Ip4SysPacketSent ( @@ -192,35 +182,39 @@ Ip4SysPacketSent ( (IpInstance == NULL). It will route the packet, fragment it, then transmit all the fragments through some interface. - @param IpSb The IP4 service instance to transmit the packet - @param IpInstance The IP4 child that issues the transmission. It is + @param[in] IpSb The IP4 service instance to transmit the packet + @param[in] IpInstance The IP4 child that issues the transmission. It is NULL if the packet is from the system. - @param Packet The user data to send, excluding the IP header. - @param Head The caller supplied header. The caller should set - the following header fields: Tos, TotalLen, Id, tl, + @param[in] Packet The user data to send, excluding the IP header. + @param[in] Head The caller supplied header. The caller should set + the following header fields: Tos, TotalLen, Id, tl, Fragment, Protocol, Src and Dst. All the fields are in host byte order. This function will fill in the Ver, HeadLen, Fragment, and checksum. The Fragment only need to include the DF flag. Ip4Output will compute the MF and offset for you. - @param Option The original option to append to the IP headers - @param OptLen The length of the option - @param GateWay The next hop address to transmit packet to. + @param[in] Option The original option to append to the IP headers + @param[in] OptLen The length of the option + @param[in] GateWay The next hop address to transmit packet to. 255.255.255.255 means broadcast. - @param Callback The callback function to issue when transmission + @param[in] Callback The callback function to issue when transmission completed. - @param Context The opaque context for the callback + @param[in] Context The opaque context for the callback @retval EFI_NO_MAPPING There is no interface to the destination. @retval EFI_NOT_FOUND There is no route to the destination @retval EFI_SUCCESS The packet is successfully transmitted. + @retval EFI_BAD_BUFFER_SIZE The length of the IPv4 header + option length + + total data length is greater than MTU (or greater + than the maximum packet size if Token.Packet.TxData. + OverrideData.DoNotFragment is TRUE.) @retval Others Failed to transmit the packet. **/ EFI_STATUS Ip4Output ( IN IP4_SERVICE *IpSb, - IN IP4_PROTOCOL *IpInstance, OPTIONAL + IN IP4_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN IP4_HEAD *Head, IN UINT8 *Option, @@ -241,6 +235,7 @@ Ip4Output ( UINT32 Offset; UINT32 Mtu; UINT32 Num; + BOOLEAN RawData; // // Select an interface/source for system packet, application @@ -261,55 +256,93 @@ Ip4Output ( } // - // Route the packet unless overrided, that is, GateWay isn't zero. + // Before IPsec process, prepared the IP head. + // If Ip4Output is transmitting RawData, don't update IPv4 header. // - if (GateWay == IP4_ALLZERO_ADDRESS) { - Dest = Head->Dst; + HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03)); - if (IP4_IS_BROADCAST (Ip4GetNetCast (Dest, IpIf)) || (Dest == IP4_ALLONE_ADDRESS)) { - // - // Set the gateway to local broadcast if the Dest is - // is the broadcast address for the connected network - // or it is local broadcast. - // - GateWay = IP4_ALLONE_ADDRESS; + if ((IpInstance != NULL) && IpInstance->ConfigData.RawData) { + RawData = TRUE; + } else { + Head->HeadLen = (UINT8) (HeadLen >> 2); + Head->Id = mIp4Id++; + Head->Ver = 4; + RawData = FALSE; + } - } else if (IP4_IS_MULTICAST (Dest)) { - // - // Set the gateway to the destination if it is an multicast - // address. The IP4_INTERFACE won't consult ARP to send local - // broadcast and multicast. - // - GateWay = Head->Dst; + // + // Call IPsec process. + // + Status = Ip4IpSecProcessPacket ( + IpSb, + &Head, + &Packet, + &Option, + &OptLen, + EfiIPsecOutBound, + Context + ); + + if (EFI_ERROR(Status)) { + return Status; + } + Dest = Head->Dst; + if (IP4_IS_BROADCAST (Ip4GetNetCast (Dest, IpIf)) || (Dest == IP4_ALLONE_ADDRESS)) { + // + // Set the gateway to local broadcast if the Dest is + // the broadcast address for the connected network or + // it is local broadcast. + // + GateWay = IP4_ALLONE_ADDRESS; + + } else if (IP4_IS_MULTICAST (Dest)) { + // + // Set the gateway to the destination if it is an multicast + // address. The IP4_INTERFACE won't consult ARP to send local + // broadcast and multicast. + // + GateWay = Head->Dst; + + } else if (GateWay == IP4_ALLZERO_ADDRESS) { + // + // Route the packet unless overrided, that is, GateWay isn't zero. + // + if (IpInstance == NULL) { + CacheEntry = Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head->Src); } else { + CacheEntry = Ip4Route (IpInstance->RouteTable, Head->Dst, Head->Src); // - // Consult the route table to route the packet + // If failed to route the packet by using the instance's route table, + // try to use the default route table. // - if (IpInstance == NULL) { - CacheEntry = Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head->Src); - } else { - CacheEntry = Ip4Route (IpInstance->RouteTable, Head->Dst, Head->Src); - } - if (CacheEntry == NULL) { - return EFI_NOT_FOUND; + CacheEntry = Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head->Src); } + } - GateWay = CacheEntry->NextHop; - Ip4FreeRouteCacheEntry (CacheEntry); + if (CacheEntry == NULL) { + return EFI_NOT_FOUND; } + + GateWay = CacheEntry->NextHop; + Ip4FreeRouteCacheEntry (CacheEntry); } // // OK, selected the source and route, fragment the packet then send // them. Tag each fragment other than the first one as spawn from it. // - Mtu = IpSb->SnpMode.MaxPacketSize; - HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03)); - Head->Id = mIp4Id++; + Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD); if (Packet->TotalSize + HeadLen > Mtu) { + // + // Fragmentation is diabled for RawData mode. + // + if (RawData) { + return EFI_BAD_BUFFER_SIZE; + } + // // Packet is fragmented from the tail to the head, that is, the // first frame sent is the last fragment of the packet. The first @@ -414,18 +447,17 @@ ON_ERROR: The filter function to find a packet and all its fragments. The packet's fragments have their Context set to the packet. - @param Frame The frames hold by the low level interface - @param Context Context to the function, which is the packet. + @param[in] Frame The frames hold by the low level interface + @param[in] Context Context to the function, which is the packet. @retval TRUE This is the packet to cancel or its fragments. @retval FALSE This is unrelated packet. **/ -STATIC BOOLEAN Ip4CancelPacketFragments ( - IP4_LINK_TX_TOKEN *Frame, - VOID *Context + IN IP4_LINK_TX_TOKEN *Frame, + IN VOID *Context ) { if ((Frame->Packet == (NET_BUF *) Context) || (Frame->Context == Context)) { @@ -443,8 +475,6 @@ Ip4CancelPacketFragments ( @param Packet The Packet to cancel @param IoStatus The status returns to the sender. - @return None - **/ VOID Ip4CancelPacket (