]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4Output.c
index ed8da7813285e34aa263d801b393718d0f2764ed..5eb3814089cbe0f90a1ededd97997d9637aff7b1 100644 (file)
@@ -1,14 +1,8 @@
 /** @file\r
   Transmit the IP4 packet.\r
-  \r
-Copyright (c) 2005 - 2009, Intel Corporation.<BR>\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
 \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -204,6 +198,10 @@ Ip4SysPacketSent (
   @retval EFI_NO_MAPPING       There is no interface to the destination.\r
   @retval EFI_NOT_FOUND        There is no route to the destination\r
   @retval EFI_SUCCESS          The packet is successfully transmitted.\r
+  @retval EFI_BAD_BUFFER_SIZE  The length of the IPv4 header + option length +\r
+                               total data length is greater than MTU (or greater\r
+                               than the maximum packet size if Token.Packet.TxData.\r
+                               OverrideData.DoNotFragment is TRUE.)\r
   @retval Others               Failed to transmit the packet.\r
 \r
 **/\r
@@ -231,6 +229,7 @@ Ip4Output (
   UINT32                    Offset;\r
   UINT32                    Mtu;\r
   UINT32                    Num;\r
+  BOOLEAN                   RawData;\r
 \r
   //\r
   // Select an interface/source for system packet, application\r
@@ -251,55 +250,29 @@ Ip4Output (
   }\r
 \r
   //\r
-  // Route the packet unless overrided, that is, GateWay isn't zero.\r
+  // Before IPsec process, prepared the IP head.\r
+  // If Ip4Output is transmitting RawData, don't update IPv4 header.\r
   //\r
-  if (GateWay == IP4_ALLZERO_ADDRESS) {\r
-    Dest = Head->Dst;\r
+  HeadLen = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
 \r
-    if (IP4_IS_BROADCAST (Ip4GetNetCast (Dest, IpIf)) || (Dest == IP4_ALLONE_ADDRESS)) {\r
-      //\r
-      // Set the gateway to local broadcast if the Dest is\r
-      // the broadcast address for the connected network or\r
-      // it is local broadcast.\r
-      //\r
-      GateWay = IP4_ALLONE_ADDRESS;\r
-\r
-    } else if (IP4_IS_MULTICAST (Dest)) {\r
-      //\r
-      // Set the gateway to the destination if it is an multicast\r
-      // address. The IP4_INTERFACE won't consult ARP to send local\r
-      // broadcast and multicast.\r
-      //\r
-      GateWay = Head->Dst;\r
-\r
-    } else {\r
-      //\r
-      // Consult the route table to route the packet\r
-      //\r
-      if (IpInstance == NULL) {\r
-        CacheEntry = Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head->Src);\r
-      } else {\r
-        CacheEntry = Ip4Route (IpInstance->RouteTable, Head->Dst, Head->Src);\r
-      }\r
-\r
-      if (CacheEntry == NULL) {\r
-        return EFI_NOT_FOUND;\r
-      }\r
-\r
-      GateWay = CacheEntry->NextHop;\r
-      Ip4FreeRouteCacheEntry (CacheEntry);\r
-    }\r
+  if ((IpInstance != NULL) && IpInstance->ConfigData.RawData) {\r
+    RawData        = TRUE;\r
+  } else {\r
+    Head->HeadLen  = (UINT8) (HeadLen >> 2);\r
+    Head->Id       = mIp4Id++;\r
+    Head->Ver      = 4;\r
+    RawData        = FALSE;\r
   }\r
 \r
   //\r
-  // TODO: currently Option/OptLen are not included into encryption scope.\r
+  // Call IPsec process.\r
   //\r
   Status = Ip4IpSecProcessPacket (\r
-             IpSb, \r
-             Head, \r
-             &Packet, \r
-             Option, \r
-             OptLen, \r
+             IpSb,\r
+             &Head,\r
+             &Packet,\r
+             &Option,\r
+             &OptLen,\r
              EfiIPsecOutBound,\r
              Context\r
              );\r
@@ -308,15 +281,62 @@ Ip4Output (
     return Status;\r
   }\r
 \r
+  Dest = Head->Dst;\r
+  if (IP4_IS_BROADCAST (Ip4GetNetCast (Dest, IpIf)) || (Dest == IP4_ALLONE_ADDRESS)) {\r
+    //\r
+    // Set the gateway to local broadcast if the Dest is\r
+    // the broadcast address for the connected network or\r
+    // it is local broadcast.\r
+    //\r
+    GateWay = IP4_ALLONE_ADDRESS;\r
+\r
+  } else if (IP4_IS_MULTICAST (Dest)) {\r
+    //\r
+    // Set the gateway to the destination if it is an multicast\r
+    // address. The IP4_INTERFACE won't consult ARP to send local\r
+    // broadcast and multicast.\r
+    //\r
+    GateWay = Head->Dst;\r
+\r
+  } else if (GateWay == IP4_ALLZERO_ADDRESS) {\r
+    //\r
+    // Route the packet unless overrided, that is, GateWay isn't zero.\r
+    //\r
+    if (IpInstance == NULL) {\r
+      CacheEntry = Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head->Src, IpIf->SubnetMask, TRUE);\r
+    } else {\r
+      CacheEntry = Ip4Route (IpInstance->RouteTable, Head->Dst, Head->Src, IpIf->SubnetMask, FALSE);\r
+      //\r
+      // If failed to route the packet by using the instance's route table,\r
+      // try to use the default route table.\r
+      //\r
+      if (CacheEntry == NULL) {\r
+        CacheEntry = Ip4Route (IpSb->DefaultRouteTable, Head->Dst, Head->Src, IpIf->SubnetMask, TRUE);\r
+      }\r
+    }\r
+\r
+    if (CacheEntry == NULL) {\r
+      return EFI_NOT_FOUND;\r
+    }\r
+\r
+    GateWay = CacheEntry->NextHop;\r
+    Ip4FreeRouteCacheEntry (CacheEntry);\r
+  }\r
+\r
   //\r
   // OK, selected the source and route, fragment the packet then send\r
   // them. Tag each fragment other than the first one as spawn from it.\r
   //\r
-  Mtu            = IpSb->MaxPacketSize;\r
-  HeadLen        = sizeof (IP4_HEAD) + ((OptLen + 3) & (~0x03));\r
-  Head->Id       = mIp4Id++;\r
+  Mtu = IpSb->MaxPacketSize + sizeof (IP4_HEAD);\r
 \r
   if (Packet->TotalSize + HeadLen > Mtu) {\r
+    //\r
+    // Fragmentation is diabled for RawData mode.\r
+    //\r
+    if (RawData) {\r
+      return EFI_BAD_BUFFER_SIZE;\r
+    }\r
+\r
     //\r
     // Packet is fragmented from the tail to the head, that is, the\r
     // first frame sent is the last fragment of the packet. The first\r
@@ -360,7 +380,8 @@ Ip4Output (
                  Fragment,\r
                  GateWay,\r
                  Ip4SysPacketSent,\r
-                 Packet\r
+                 Packet,\r
+                 IpSb\r
                  );\r
 \r
       if (EFI_ERROR (Status)) {\r
@@ -403,7 +424,7 @@ Ip4Output (
   //    upper layer's packets.\r
   //\r
   Ip4PrependHead (Packet, Head, Option, OptLen);\r
-  Status = Ip4SendFrame (IpIf, IpInstance, Packet, GateWay, Callback, Context);\r
+  Status = Ip4SendFrame (IpIf, IpInstance, Packet, GateWay, Callback, Context, IpSb);\r
 \r
   if (EFI_ERROR (Status)) {\r
     goto ON_ERROR;\r