summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Stt.c
diff options
context:
space:
mode:
authorShashank Ram <rams@vmware.com>2017-11-20 15:06:14 -0800
committerAlin Gabriel Serdean <aserdean@ovn.org>2017-11-28 14:46:57 +0200
commita9e6958101d082dbbdc096d01a803ab3a3eca549 (patch)
treef1ab1f649e5d086dc979eb8214da33379fec0b2e /datapath-windows/ovsext/Stt.c
parent8a7903c632ef940bcacaa7da7330e871912a6985 (diff)
downloadopenvswitch-a9e6958101d082dbbdc096d01a803ab3a3eca549.tar.gz
datapath-windows: Account for VLAN tag in tunnel Decap
Decap functions for tunneling protocols do not compute the packet header offsets correctly when there is a VLAN tag in the L2 header. This results in incorrect checksum computation causing the packet to be dropped. This patch adds support to account for the VLAN tag in the packet if its present, and makes use of the OvsExtractLayers() function to correctly compute the header offsets for different layers. Testing done: - Tested Geneve, STT, Vxlan and Gre and verified that there are no regressions. - Verified that packets with VLAN tags are correctly handled in the decap code of all tunneling protocols. Previously, this would result in packet drops due to invalid checksums being computed. - Verified that non-VLAN tagged packets are handled correctly. Signed-off-by: Shashank Ram <rams@vmware.com> Acked-by: Anand Kumar <kumaranand@vmware.com> Signed-off-by: Alin Gabriel Serdean <aserdean@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Stt.c')
-rw-r--r--datapath-windows/ovsext/Stt.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/datapath-windows/ovsext/Stt.c b/datapath-windows/ovsext/Stt.c
index f98070f33..8eb71676a 100644
--- a/datapath-windows/ovsext/Stt.c
+++ b/datapath-windows/ovsext/Stt.c
@@ -415,9 +415,23 @@ ret_error:
*----------------------------------------------------------------------------
*/
static __inline NDIS_STATUS
-OvsValidateTCPChecksum(PNET_BUFFER_LIST curNbl, PNET_BUFFER curNb)
+OvsValidateTCPChecksum(PNET_BUFFER_LIST curNbl,
+ PNET_BUFFER curNb,
+ POVS_PACKET_HDR_INFO layers)
{
+ PUINT8 buf;
+ PMDL curMdl;
NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
+ NDIS_STATUS status;
+
+ curMdl = NET_BUFFER_CURRENT_MDL(curNb);
+ buf = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl, LowPagePriority)
+ + NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
+ if (!buf) {
+ status = NDIS_STATUS_INVALID_PACKET;
+ return status;
+ }
+
csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
TcpIpChecksumNetBufferListInfo);
@@ -433,23 +447,22 @@ OvsValidateTCPChecksum(PNET_BUFFER_LIST curNbl, PNET_BUFFER curNb)
return NDIS_STATUS_SUCCESS;
}
- EthHdr *eth = (EthHdr *)NdisGetDataBuffer(curNb, sizeof(EthHdr),
- NULL, 1, 0);
- if (eth == NULL) {
+ EthHdr *ethHdr = (EthHdr *)buf;
+ if (ethHdr == NULL) {
return NDIS_STATUS_RESOURCES;
}
- if (eth->Type == ntohs(NDIS_ETH_TYPE_IPV4)) {
- IPHdr *ip = (IPHdr *)((PCHAR)eth + sizeof *eth);
- UINT32 l4Payload = ntohs(ip->tot_len) - ip->ihl * 4;
- TCPHdr *tcp = (TCPHdr *)((PCHAR)ip + ip->ihl * 4);
+ if (ethHdr->Type == ntohs(NDIS_ETH_TYPE_IPV4)) {
+ IPHdr *ipHdr = (IPHdr *)(buf + layers->l3Offset);
+ UINT32 l4Payload = ntohs(ipHdr->tot_len) - ipHdr->ihl * 4;
+ TCPHdr *tcp = (TCPHdr *)(buf + layers->l4Offset);
checkSum = tcp->check;
tcp->check = 0;
- tcp->check = IPPseudoChecksum(&ip->saddr, &ip->daddr,
+ tcp->check = IPPseudoChecksum(&ipHdr->saddr, &ipHdr->daddr,
IPPROTO_TCP, (UINT16)l4Payload);
tcp->check = CalculateChecksumNB(curNb, (UINT16)(l4Payload),
- sizeof(EthHdr) + ip->ihl * 4);
+ layers->l4Offset);
if (checkSum != tcp->check) {
return NDIS_STATUS_INVALID_PACKET;
}
@@ -912,18 +925,24 @@ OvsDecapStt(POVS_SWITCH_CONTEXT switchContext,
SttHdr *sttHdr;
char *sttBuf[STT_HDR_LEN];
UINT32 advanceCnt, hdrLen;
+ OVS_PACKET_HDR_INFO layers = { 0 };
+
+ status = OvsExtractLayers(curNbl, &layers);
+ if (status != NDIS_STATUS_SUCCESS) {
+ return status;
+ }
curNb = NET_BUFFER_LIST_FIRST_NB(curNbl);
ASSERT(NET_BUFFER_NEXT_NB(curNb) == NULL);
/* Validate the TCP Checksum */
- status = OvsValidateTCPChecksum(curNbl, curNb);
+ status = OvsValidateTCPChecksum(curNbl, curNb, &layers);
if (status != NDIS_STATUS_SUCCESS) {
return status;
}
/* Skip Eth header */
- hdrLen = sizeof(EthHdr);
+ hdrLen = layers.l3Offset;
NdisAdvanceNetBufferDataStart(curNb, hdrLen, FALSE, NULL);
advanceCnt = hdrLen;
@@ -996,7 +1015,6 @@ OvsDecapStt(POVS_SWITCH_CONTEXT switchContext,
tunKey->pad = 0;
/* Handle ECN */
- OVS_PACKET_HDR_INFO layers = {0};
if (0 != ipHdr->tos) {
status = OvsExtractLayers(*newNbl, &layers);
if (status != NDIS_STATUS_SUCCESS) {