diff mbox series

[ovs-dev,ovs-dev,v1,1/1] datapath-windows: Merge split dis-continuous net-buf.

Message ID 20240715095954.49436-1-svc.ovs-community@vmware.com
State Superseded
Headers show
Series [ovs-dev,ovs-dev,v1,1/1] datapath-windows: Merge split dis-continuous net-buf. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed

Commit Message

Wilson Peng July 15, 2024, 9:59 a.m. UTC
From: Wilson Peng <pweisong@vmware.com>

NdisGetDataBuffer() is called without providing a buffer to copy packet
data in case it is not contiguous.  So, it fails in some scenarios
where the packet is handled by the general network stack before OVS
and headers become split in multiple buffers.

In the fix it will supply the stack buffer to copy packet data when
call NdisGetDataBuffer().

In the conntrack Action process, it will do OvsPartialCopyNBL firstly
with the size of layers l7offsets. If the header is split the header
will be merged to one continuous buffer.

But IPV6 traffic is not handed in this case.

Reported-at: https://github.com/openvswitch/ovs-issues/issues/323
Signed-off-by: Wilson Peng <pweisong@vmware.com>
---
 datapath-windows/ovsext/Actions.c      | 7 +++++++
 datapath-windows/ovsext/BufferMgmt.c   | 4 +++-
 datapath-windows/ovsext/Conntrack.c    | 6 +++++-
 datapath-windows/ovsext/IpFragment.c   | 8 ++++++--
 datapath-windows/ovsext/PacketParser.h | 1 +
 5 files changed, 22 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 97029b0f4..4bc2a6b65 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -2414,6 +2414,13 @@  OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
             }
 
             PNET_BUFFER_LIST oldNbl = ovsFwdCtx.curNbl;
+            PUINT8 bufferStart = NULL;
+
+            bufferStart = OvsGetHeaderBySize(&ovsFwdCtx, layers->l7Offset);
+            if (!bufferStart) {
+                 dropReason = L"OVS-Netbuf reallocated failed";
+                 goto dropit;
+            }
             status = OvsExecuteConntrackAction(&ovsFwdCtx, key,
                                                (const PNL_ATTR)a);
             if (status != NDIS_STATUS_SUCCESS) {
diff --git a/datapath-windows/ovsext/BufferMgmt.c b/datapath-windows/ovsext/BufferMgmt.c
index 5c52757a0..b01f69fdf 100644
--- a/datapath-windows/ovsext/BufferMgmt.c
+++ b/datapath-windows/ovsext/BufferMgmt.c
@@ -1110,12 +1110,14 @@  GetIpHeaderInfo(PNET_BUFFER_LIST curNbl,
     IPHdr *ipHdr;
     IPv6Hdr *ipv6Hdr;
     PNET_BUFFER curNb;
+    CHAR tempBuf[MAX_IP_HEADER_LEN];
 
     curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
     ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
+    NdisZeroMemory(tempBuf, MAX_IP_HEADER_LEN);
     eth = (EthHdr *)NdisGetDataBuffer(curNb,
                                       hdrInfo->l4Offset,
-                                      NULL, 1, 0);
+                                      (PVOID)tempBuf, 1, 0);
     if (eth == NULL) {
         return NDIS_STATUS_INVALID_PACKET;
     }
diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
index 39ba5cc10..0e7ecb855 100644
--- a/datapath-windows/ovsext/Conntrack.c
+++ b/datapath-windows/ovsext/Conntrack.c
@@ -683,6 +683,7 @@  OvsGetTcpHeader(PNET_BUFFER_LIST nbl,
     TCPHdr *tcp;
     VOID *dest = storage;
     uint16_t ipv6ExtLength = 0;
+    CHAR tempBuf[MAX_IP_HEADER_LEN];
 
     if (layers->isIPv6) {
         ipv6Hdr = NdisGetDataBuffer(NET_BUFFER_LIST_FIRST_NB(nbl),
@@ -701,9 +702,10 @@  OvsGetTcpHeader(PNET_BUFFER_LIST nbl,
             return storage;
         }
     } else {
+        NdisZeroMemory(tempBuf, MAX_IP_HEADER_LEN);
         ipHdr = NdisGetDataBuffer(NET_BUFFER_LIST_FIRST_NB(nbl),
                                   layers->l4Offset + sizeof(TCPHdr),
-                                  NULL, 1 /*no align*/, 0);
+                                  (PVOID)tempBuf, 1 /*no align*/, 0);
         if (ipHdr == NULL) {
             return NULL;
         }
@@ -1202,6 +1204,8 @@  OvsCtExecute_(OvsForwardingContext *fwdCtx,
     UINT64 currentTime;
     NdisGetCurrentSystemTime((LARGE_INTEGER *) &currentTime);
 
+
+    curNbl = fwdCtx->curNbl;
     /* Retrieve the Conntrack Key related fields from packet */
     OvsCtSetupLookupCtx(key, zone, &ctx, curNbl, layers->l4Offset);
 
diff --git a/datapath-windows/ovsext/IpFragment.c b/datapath-windows/ovsext/IpFragment.c
index afb8e50d6..54b6c9e41 100644
--- a/datapath-windows/ovsext/IpFragment.c
+++ b/datapath-windows/ovsext/IpFragment.c
@@ -153,12 +153,14 @@  OvsIpv4Reassemble(POVS_SWITCH_CONTEXT switchContext,
     PNET_BUFFER_LIST newNbl = NULL;
     UINT16 ipHdrLen, packetHeader;
     UINT32 packetLen;
+    CHAR tempBuf[MAX_IP_HEADER_LEN];
 
     curNb = NET_BUFFER_LIST_FIRST_NB(*curNbl);
     ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
 
+    NdisZeroMemory(tempBuf, MAX_IP_HEADER_LEN);
     eth = (EthHdr*)NdisGetDataBuffer(curNb, layers->l4Offset,
-                                     NULL, 1, 0);
+                                     (PVOID)tempBuf, 1, 0);
     if (eth == NULL) {
         return NDIS_STATUS_INVALID_PACKET;
     }
@@ -253,12 +255,14 @@  OvsProcessIpv4Fragment(POVS_SWITCH_CONTEXT switchContext,
     POVS_IPFRAG_ENTRY entry;
     POVS_FRAGMENT_LIST fragStorage;
     LOCK_STATE_EX htLockState;
+    CHAR tempBuf[MAX_IP_HEADER_LEN];
 
     curNb = NET_BUFFER_LIST_FIRST_NB(*curNbl);
     ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
 
+    NdisZeroMemory(tempBuf, MAX_IP_HEADER_LEN);
     eth = (EthHdr*)NdisGetDataBuffer(curNb, layers->l4Offset,
-                                     NULL, 1, 0);
+                                     (PVOID)tempBuf, 1, 0);
     if (eth == NULL) {
         return NDIS_STATUS_INVALID_PACKET;
     }
diff --git a/datapath-windows/ovsext/PacketParser.h b/datapath-windows/ovsext/PacketParser.h
index 0d5c0a6cb..775c93026 100644
--- a/datapath-windows/ovsext/PacketParser.h
+++ b/datapath-windows/ovsext/PacketParser.h
@@ -18,6 +18,7 @@ 
 #define __PACKET_PARSER_H_ 1
 
 #define MIN_IPV4_HLEN 20
+#define MAX_IP_HEADER_LEN 80
 
 #include "precomp.h"
 #include "NetProto.h"