Skip to content

Commit

Permalink
datapath-windows: Merge split dis-continuous net-buf.
Browse files Browse the repository at this point in the history
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: openvswitch/ovs-issues#323
Signed-off-by: Wilson Peng <[email protected]>
Signed-off-by: 0-day Robot <[email protected]>
  • Loading branch information
pweisong authored and ovsrobot committed Jul 17, 2024
1 parent 903aa8f commit 6941a76
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 6 deletions.
7 changes: 7 additions & 0 deletions datapath-windows/ovsext/Actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
16 changes: 13 additions & 3 deletions datapath-windows/ovsext/BufferMgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1110,12 +1110,22 @@ GetIpHeaderInfo(PNET_BUFFER_LIST curNbl,
IPHdr *ipHdr;
IPv6Hdr *ipv6Hdr;
PNET_BUFFER curNb;
CHAR tempBuf[MAX_IPV4_HLEN];

curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
eth = (EthHdr *)NdisGetDataBuffer(curNb,
hdrInfo->l4Offset,
NULL, 1, 0);

if (hdrInfo->isIPv6) {
eth = (EthHdr *)NdisGetDataBuffer(curNb,
hdrInfo->l4Offset,
NULL, 1, 0);
} else {
NdisZeroMemory(tempBuf, MAX_IPV4_HLEN);
eth = (EthHdr *)NdisGetDataBuffer(curNb,
hdrInfo->l4Offset,
(PVOID)tempBuf, 1, 0);
}

if (eth == NULL) {
return NDIS_STATUS_INVALID_PACKET;
}
Expand Down
4 changes: 3 additions & 1 deletion datapath-windows/ovsext/Conntrack.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,7 @@ OvsGetTcpHeader(PNET_BUFFER_LIST nbl,
TCPHdr *tcp;
VOID *dest = storage;
uint16_t ipv6ExtLength = 0;
CHAR tempBuf[MAX_IPV4_HLEN];

if (layers->isIPv6) {
ipv6Hdr = NdisGetDataBuffer(NET_BUFFER_LIST_FIRST_NB(nbl),
Expand All @@ -701,9 +702,10 @@ OvsGetTcpHeader(PNET_BUFFER_LIST nbl,
return storage;
}
} else {
NdisZeroMemory(tempBuf, MAX_IPV4_HLEN);
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;
}
Expand Down
8 changes: 6 additions & 2 deletions datapath-windows/ovsext/IpFragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,14 @@ OvsIpv4Reassemble(POVS_SWITCH_CONTEXT switchContext,
PNET_BUFFER_LIST newNbl = NULL;
UINT16 ipHdrLen, packetHeader;
UINT32 packetLen;
CHAR tempBuf[MAX_IPV4_HLEN];

curNb = NET_BUFFER_LIST_FIRST_NB(*curNbl);
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);

NdisZeroMemory(tempBuf, MAX_IPV4_HLEN);
eth = (EthHdr*)NdisGetDataBuffer(curNb, layers->l4Offset,
NULL, 1, 0);
(PVOID)tempBuf, 1, 0);
if (eth == NULL) {
return NDIS_STATUS_INVALID_PACKET;
}
Expand Down Expand Up @@ -253,12 +255,14 @@ OvsProcessIpv4Fragment(POVS_SWITCH_CONTEXT switchContext,
POVS_IPFRAG_ENTRY entry;
POVS_FRAGMENT_LIST fragStorage;
LOCK_STATE_EX htLockState;
CHAR tempBuf[MAX_IPV4_HLEN];

curNb = NET_BUFFER_LIST_FIRST_NB(*curNbl);
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);

NdisZeroMemory(tempBuf, MAX_IPV4_HLEN);
eth = (EthHdr*)NdisGetDataBuffer(curNb, layers->l4Offset,
NULL, 1, 0);
(PVOID)tempBuf, 1, 0);
if (eth == NULL) {
return NDIS_STATUS_INVALID_PACKET;
}
Expand Down

0 comments on commit 6941a76

Please sign in to comment.