diff options
author | Shashank Ram <rams@vmware.com> | 2017-11-20 15:06:14 -0800 |
---|---|---|
committer | Alin Gabriel Serdean <aserdean@ovn.org> | 2017-11-28 14:46:57 +0200 |
commit | a9e6958101d082dbbdc096d01a803ab3a3eca549 (patch) | |
tree | f1ab1f649e5d086dc979eb8214da33379fec0b2e /datapath-windows/ovsext/Vxlan.c | |
parent | 8a7903c632ef940bcacaa7da7330e871912a6985 (diff) | |
download | openvswitch-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/Vxlan.c')
-rw-r--r-- | datapath-windows/ovsext/Vxlan.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c index f66a7e57f..47c734e1e 100644 --- a/datapath-windows/ovsext/Vxlan.c +++ b/datapath-windows/ovsext/Vxlan.c @@ -391,11 +391,17 @@ OvsDecapVxlan(POVS_SWITCH_CONTEXT switchContext, UINT32 tunnelSize, packetLength; PUINT8 bufferStart; NDIS_STATUS status; + OVS_PACKET_HDR_INFO layers = { 0 }; + + status = OvsExtractLayers(curNbl, &layers); + if (status != NDIS_STATUS_SUCCESS) { + return status; + } /* Check the length of the UDP payload */ curNb = NET_BUFFER_LIST_FIRST_NB(curNbl); packetLength = NET_BUFFER_DATA_LENGTH(curNb); - tunnelSize = OvsGetVxlanTunHdrSize(); + tunnelSize = OvsGetVxlanTunHdrSizeFromLayers(&layers); if (packetLength < tunnelSize) { return NDIS_STATUS_INVALID_LENGTH; } @@ -424,13 +430,13 @@ OvsDecapVxlan(POVS_SWITCH_CONTEXT switchContext, ethHdr = (EthHdr *)bufferStart; /* XXX: Handle IP options. */ - ipHdr = (IPHdr *)((PCHAR)ethHdr + sizeof *ethHdr); + ipHdr = (IPHdr *)(bufferStart + layers.l3Offset); tunKey->src = ipHdr->saddr; tunKey->dst = ipHdr->daddr; tunKey->tos = ipHdr->tos; tunKey->ttl = ipHdr->ttl; tunKey->pad = 0; - udpHdr = (UDPHdr *)((PCHAR)ipHdr + sizeof *ipHdr); + udpHdr = (UDPHdr *)(bufferStart + layers.l4Offset); /* Validate if NIC has indicated checksum failure. */ status = OvsValidateUDPChecksum(curNbl, udpHdr->check == 0); @@ -442,7 +448,7 @@ OvsDecapVxlan(POVS_SWITCH_CONTEXT switchContext, if (udpHdr->check != 0) { tunKey->flags |= OVS_TNL_F_CSUM; status = OvsCalculateUDPChecksum(curNbl, curNb, ipHdr, udpHdr, - packetLength); + packetLength, &layers); if (status != NDIS_STATUS_SUCCESS) { goto dropNbl; } |