Skip to content

Commit 2c4616b

Browse files
pweisongovsrobot
authored andcommitted
datapath-windows: Merge split dis-continuous net-buf.
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 patch to merge the split dis-continuous net-buf. Reported-at: openvswitch/ovs-issues#323 Signed-off-by: Wilson Peng <pweisong@vmware.com> Signed-off-by: 0-day Robot <robot@bytheb.org>
1 parent 8f3d6c1 commit 2c4616b

File tree

5 files changed

+33
-18
lines changed

5 files changed

+33
-18
lines changed

datapath-windows/ovsext/Actions.c

+8
Original file line numberDiff line numberDiff line change
@@ -2414,6 +2414,14 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
24142414
}
24152415

24162416
PNET_BUFFER_LIST oldNbl = ovsFwdCtx.curNbl;
2417+
if (layers->value != 0 && layers->isIPv4 && layers->l7Offset != 0) {
2418+
PUINT8 bufferStart = NULL;
2419+
bufferStart = OvsGetHeaderBySize(&ovsFwdCtx, layers->l7Offset);
2420+
if (!bufferStart) {
2421+
dropReason = L"OVS-Netbuf reallocated failed";
2422+
goto dropit;
2423+
}
2424+
}
24172425
status = OvsExecuteConntrackAction(&ovsFwdCtx, key,
24182426
(const PNL_ATTR)a);
24192427
if (status != NDIS_STATUS_SUCCESS) {

datapath-windows/ovsext/BufferMgmt.c

+15-15
Original file line numberDiff line numberDiff line change
@@ -1106,24 +1106,24 @@ GetIpHeaderInfo(PNET_BUFFER_LIST curNbl,
11061106
const POVS_PACKET_HDR_INFO hdrInfo,
11071107
UINT32 *hdrSize)
11081108
{
1109-
EthHdr *eth;
1110-
IPHdr *ipHdr;
1111-
IPv6Hdr *ipv6Hdr;
1112-
PNET_BUFFER curNb;
1113-
1114-
curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
1115-
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
1116-
eth = (EthHdr *)NdisGetDataBuffer(curNb,
1117-
hdrInfo->l4Offset,
1118-
NULL, 1, 0);
1119-
if (eth == NULL) {
1120-
return NDIS_STATUS_INVALID_PACKET;
1121-
}
1122-
11231109
if (hdrInfo->isIPv6) {
1124-
ipv6Hdr = (IPv6Hdr *)((PCHAR)eth + hdrInfo->l3Offset);
11251110
*hdrSize = (UINT32)(hdrInfo->l4Offset);
11261111
} else {
1112+
EthHdr *eth;
1113+
IPHdr *ipHdr;
1114+
CHAR tempBuf[MAX_IPV4_PKT_HDR_LEN];
1115+
PNET_BUFFER curNb;
1116+
1117+
curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
1118+
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
1119+
1120+
NdisZeroMemory(tempBuf, MAX_IPV4_PKT_HDR_LEN);
1121+
eth = (EthHdr *)NdisGetDataBuffer(curNb,
1122+
hdrInfo->l4Offset,
1123+
(PVOID)tempBuf, 1, 0);
1124+
if (eth == NULL) {
1125+
return NDIS_STATUS_INVALID_PACKET;
1126+
}
11271127
ipHdr = (IPHdr *)((PCHAR)eth + hdrInfo->l3Offset);
11281128
*hdrSize = (UINT32)(hdrInfo->l3Offset + (ipHdr->ihl * 4));
11291129
}

datapath-windows/ovsext/Conntrack.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ OvsGetTcpHeader(PNET_BUFFER_LIST nbl,
683683
TCPHdr *tcp;
684684
VOID *dest = storage;
685685
uint16_t ipv6ExtLength = 0;
686+
CHAR tempBuf[MAX_IPV4_PKT_HDR_LEN];
686687

687688
if (layers->isIPv6) {
688689
ipv6Hdr = NdisGetDataBuffer(NET_BUFFER_LIST_FIRST_NB(nbl),
@@ -701,9 +702,10 @@ OvsGetTcpHeader(PNET_BUFFER_LIST nbl,
701702
return storage;
702703
}
703704
} else {
705+
NdisZeroMemory(tempBuf, MAX_IPV4_PKT_HDR_LEN);
704706
ipHdr = NdisGetDataBuffer(NET_BUFFER_LIST_FIRST_NB(nbl),
705707
layers->l4Offset + sizeof(TCPHdr),
706-
NULL, 1 /*no align*/, 0);
708+
(PVOID)tempBuf, 1 /*no align*/, 0);
707709
if (ipHdr == NULL) {
708710
return NULL;
709711
}

datapath-windows/ovsext/IpFragment.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,14 @@ OvsIpv4Reassemble(POVS_SWITCH_CONTEXT switchContext,
153153
PNET_BUFFER_LIST newNbl = NULL;
154154
UINT16 ipHdrLen, packetHeader;
155155
UINT32 packetLen;
156+
CHAR tempBuf[MAX_IPV4_PKT_HDR_LEN];
156157

157158
curNb = NET_BUFFER_LIST_FIRST_NB(*curNbl);
158159
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
159160

161+
NdisZeroMemory(tempBuf, MAX_IPV4_PKT_HDR_LEN);
160162
eth = (EthHdr*)NdisGetDataBuffer(curNb, layers->l4Offset,
161-
NULL, 1, 0);
163+
(PVOID)tempBuf, 1, 0);
162164
if (eth == NULL) {
163165
return NDIS_STATUS_INVALID_PACKET;
164166
}
@@ -253,12 +255,14 @@ OvsProcessIpv4Fragment(POVS_SWITCH_CONTEXT switchContext,
253255
POVS_IPFRAG_ENTRY entry;
254256
POVS_FRAGMENT_LIST fragStorage;
255257
LOCK_STATE_EX htLockState;
258+
CHAR tempBuf[MAX_IPV4_PKT_HDR_LEN];
256259

257260
curNb = NET_BUFFER_LIST_FIRST_NB(*curNbl);
258261
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
259262

263+
NdisZeroMemory(tempBuf, MAX_IPV4_PKT_HDR_LEN);
260264
eth = (EthHdr*)NdisGetDataBuffer(curNb, layers->l4Offset,
261-
NULL, 1, 0);
265+
(PVOID)tempBuf, 1, 0);
262266
if (eth == NULL) {
263267
return NDIS_STATUS_INVALID_PACKET;
264268
}

datapath-windows/ovsext/PacketParser.h

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define __PACKET_PARSER_H_ 1
1919

2020
#define MIN_IPV4_HLEN 20
21+
#define MAX_IPV4_PKT_HDR_LEN (ETH_MAX_HEADER_LEN + MAX_IPV4_HLEN)
2122

2223
#include "precomp.h"
2324
#include "NetProto.h"

0 commit comments

Comments
 (0)