1. Sync the latest network stack. Add NetLibCreateIPv4DPathNode () in netlib library.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Misc.c
index fdd64ef..2eaf0cc 100644 (file)
@@ -23,6 +23,8 @@ Abstract:
 \r
 #include "Tcp4Main.h"\r
 \r
+#include <Library/DevicePathLib.h>\r
+\r
 NET_LIST_ENTRY  mTcpRunQue = {\r
   &mTcpRunQue,\r
   &mTcpRunQue\r
@@ -423,6 +425,7 @@ TcpCloneTcb (
   )\r
 {\r
   TCP_CB               *Clone;\r
+  TCP4_SERVICE_DATA  *TcpService;\r
 \r
   Clone = NetAllocatePool (sizeof (TCP_CB));\r
 \r
@@ -451,6 +454,19 @@ TcpCloneTcb (
 \r
   ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpPcb = Clone;\r
 \r
+  //\r
+  // Open the device path on the handle where service binding resides on.\r
+  //\r
+  TcpService = ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpService;\r
+  gBS->OpenProtocol (\r
+         TcpService->ControllerHandle,\r
+         &gEfiDevicePathProtocolGuid,\r
+         (VOID **) &Clone->Sk->ParentDevicePath,\r
+         TcpService->DriverBindingHandle,\r
+         Clone->Sk->SockHandle,\r
+         EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
+         );\r
+\r
   return Clone;\r
 }\r
 \r
@@ -530,6 +546,15 @@ TcpSetState (
   case TCP_ESTABLISHED:\r
 \r
     SockConnEstablished (Tcb->Sk);\r
+\r
+    if (Tcb->Parent != NULL) {\r
+      //\r
+      // A new connection is accepted by a listening socket, install\r
+      // the device path.\r
+      //\r
+      TcpInstallDevicePath (Tcb->Sk);\r
+    }\r
+\r
     break;\r
 \r
   case TCP_CLOSED:\r
@@ -1091,3 +1116,65 @@ TcpClearVariableData (
   Tcp4Service->MacString = NULL;\r
 }\r
 \r
+EFI_STATUS\r
+TcpInstallDevicePath (\r
+  IN SOCKET *Sock\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Install the device path protocol on the TCP instance.\r
+\r
+Arguments:\r
+\r
+  Sock - Pointer to the socket representing the TCP instance.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS - The device path protocol is installed.\r
+  other       - Failed to install the device path protocol.\r
+\r
+--*/\r
+{\r
+  TCP4_PROTO_DATA    *TcpProto;\r
+  TCP4_SERVICE_DATA  *TcpService;\r
+  TCP_CB             *Tcb;\r
+  IPv4_DEVICE_PATH   Ip4DPathNode;\r
+  EFI_STATUS         Status;\r
+\r
+  TcpProto   = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
+  TcpService = TcpProto->TcpService;\r
+  Tcb        = TcpProto->TcpPcb;\r
+\r
+  NetLibCreateIPv4DPathNode (\r
+    &Ip4DPathNode,\r
+    TcpService->ControllerHandle,\r
+    Tcb->LocalEnd.Ip,\r
+    NTOHS (Tcb->LocalEnd.Port),\r
+    Tcb->RemoteEnd.Ip,\r
+    NTOHS (Tcb->RemoteEnd.Port),\r
+    EFI_IP_PROTO_TCP,\r
+    Tcb->UseDefaultAddr\r
+    );\r
+\r
+  Sock->DevicePath = AppendDevicePathNode (\r
+                     Sock->ParentDevicePath,\r
+                     (EFI_DEVICE_PATH_PROTOCOL *) &Ip4DPathNode\r
+                     );\r
+  if (Sock->DevicePath == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &Sock->SockHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  Sock->DevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    NetFreePool (Sock->DevicePath);\r
+  }\r
+\r
+  return Status;\r
+}\r