diff mbox

[ovs-dev,v2,1/3] datapath-windows: Add UDP checksum verifications for VXLAN

Message ID 1464106460-5100-1-git-send-email-aserdean@cloudbasesolutions.com
State Accepted
Headers show

Commit Message

Alin Serdean May 24, 2016, 4:14 p.m. UTC
Introduce UDP checksum if it was specified in the tunnel information
on Tx.

Set the tunnel checksum information flag on the flow if the
UDP checksum was non zero on the Rx.

Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
---
v2: Address comments
---
 datapath-windows/ovsext/Vxlan.c | 43 +++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

Comments

Paul Boca May 25, 2016, 8:07 p.m. UTC | #1
Acked-by: Paul-Daniel Boca <pboca@cloudbasesolutions.com>


> -----Original Message-----

> From: dev [mailto:dev-bounces@openvswitch.org] On Behalf Of Alin Serdean

> Sent: Tuesday, May 24, 2016 7:14 PM

> To: dev@openvswitch.org

> Subject: [ovs-dev] [PATCH v2 1/3] datapath-windows: Add UDP checksum

> verifications for VXLAN

> 

> Introduce UDP checksum if it was specified in the tunnel information

> on Tx.

> 

> Set the tunnel checksum information flag on the flow if the

> UDP checksum was non zero on the Rx.

> 

> Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>

> ---

> v2: Address comments

> ---

>  datapath-windows/ovsext/Vxlan.c | 43 +++++++++++++++++++++++++++++++--

> --------

>  1 file changed, 33 insertions(+), 10 deletions(-)

> 

> diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-

> windows/ovsext/Vxlan.c

> index 20214cb..520f313 100644

> --- a/datapath-windows/ovsext/Vxlan.c

> +++ b/datapath-windows/ovsext/Vxlan.c

> @@ -192,6 +192,7 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,

>      UINT32 headRoom = OvsGetVxlanTunHdrSize();

>      UINT32 packetLength;

>      ULONG mss = 0;

> +    NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;

> 

>      /*

>       * XXX: the assumption currently is that the NBL is owned by OVS, and

> @@ -230,7 +231,6 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,

>              OVS_LOG_ERROR("Unable to copy NBL");

>              return NDIS_STATUS_FAILURE;

>          }

> -        NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;

>          csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,

>                                                TcpIpChecksumNetBufferListInfo);

>          status = OvsApplySWChecksumOnNB(layers, *newNbl, &csumInfo);

> @@ -249,7 +249,8 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,

>          }

> 

>          curMdl = NET_BUFFER_CURRENT_MDL(curNb);

> -        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,

> LowPagePriority);

> +        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,

> +                                                           LowPagePriority);

>          if (!bufferStart) {

>              status = NDIS_STATUS_RESOURCES;

>              goto ret_error;

> @@ -257,7 +258,8 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,

> 

>          bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);

>          if (NET_BUFFER_NEXT_NB(curNb)) {

> -            OVS_LOG_TRACE("nb length %u next %u",

> NET_BUFFER_DATA_LENGTH(curNb),

> +            OVS_LOG_TRACE("nb length %u next %u",

> +                          NET_BUFFER_DATA_LENGTH(curNb),

>                            NET_BUFFER_DATA_LENGTH(curNb->Next));

>          }

> 

> @@ -288,7 +290,6 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,

>          ipHdr->daddr = fwdInfo->dstIpAddr;

> 

>          ipHdr->check = 0;

> -        ipHdr->check = IPChecksum((UINT8 *)ipHdr, sizeof *ipHdr, 0);

> 

>          /* UDP header */

>          udpHdr = (UDPHdr *)((PCHAR)ipHdr + sizeof *ipHdr);

> @@ -296,7 +297,13 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,

>          udpHdr->dest = htons(vportVxlan->dstPort);

>          udpHdr->len = htons(NET_BUFFER_DATA_LENGTH(curNb) - headRoom +

>                              sizeof *udpHdr + sizeof *vxlanHdr);

> -        udpHdr->check = 0;

> +

> +        if (tunKey->flags & OVS_TNL_F_CSUM) {

> +            udpHdr->check = IPPseudoChecksum(&ipHdr->saddr, &ipHdr->daddr,

> +                                             IPPROTO_UDP, ntohs(udpHdr->len));

> +        } else {

> +            udpHdr->check = 0;

> +        }

> 

>          /* VXLAN header */

>          vxlanHdr = (VXLANHdr *)((PCHAR)udpHdr + sizeof *udpHdr);

> @@ -308,6 +315,17 @@ OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,

>          vxlanHdr->instanceID = 1;

>          vxlanHdr->reserved2 = 0;

>      }

> +

> +    csumInfo.Value = 0;

> +    csumInfo.Transmit.IpHeaderChecksum = 1;

> +    csumInfo.Transmit.IsIPv4 = 1;

> +    if (tunKey->flags & OVS_TNL_F_CSUM) {

> +        csumInfo.Transmit.UdpChecksum = 1;

> +    }

> +    NET_BUFFER_LIST_INFO(curNbl,

> +                         TcpIpChecksumNetBufferListInfo) = csumInfo.Value;

> +

> +

>      return STATUS_SUCCESS;

> 

>  ret_error:

> @@ -466,7 +484,9 @@ OvsDecapVxlan(POVS_SWITCH_CONTEXT

> switchContext,

> 

>      /* Calculate and verify UDP checksum if NIC didn't do it. */

>      if (udpHdr->check != 0) {

> -        status = OvsCalculateUDPChecksum(curNbl, curNb, ipHdr, udpHdr,

> packetLength);

> +        tunKey->flags |= OVS_TNL_F_CSUM;

> +        status = OvsCalculateUDPChecksum(curNbl, curNb, ipHdr, udpHdr,

> +                                         packetLength);

>          if (status != NDIS_STATUS_SUCCESS) {

>              goto dropNbl;

>          }

> @@ -474,10 +494,10 @@ OvsDecapVxlan(POVS_SWITCH_CONTEXT

> switchContext,

> 

>      vxlanHdr = (VXLANHdr *)((PCHAR)udpHdr + sizeof *udpHdr);

>      if (vxlanHdr->instanceID) {

> -        tunKey->flags = OVS_TNL_F_KEY;

> +        tunKey->flags |= OVS_TNL_F_KEY;

>          tunKey->tunnelId = VXLAN_VNI_TO_TUNNELID(vxlanHdr->vxlanID);

>      } else {

> -        tunKey->flags = 0;

> +        tunKey->flags &= ~OVS_TNL_F_KEY;

>          tunKey->tunnelId = 0;

>      }

> 

> @@ -520,6 +540,9 @@ OvsSlowPathDecapVxlan(const PNET_BUFFER_LIST

> packet,

>          udp = OvsGetUdp(packet, layers.l4Offset, &udpStorage);

>          if (udp) {

>              layers.l7Offset = layers.l4Offset + sizeof *udp;

> +            if (udp->check != 0) {

> +                tunnelKey->flags |= OVS_TNL_F_CSUM;

> +            }

>          } else {

>              break;

>          }

> @@ -535,10 +558,10 @@ OvsSlowPathDecapVxlan(const PNET_BUFFER_LIST

> packet,

>              tunnelKey->ttl = nh->ttl;

>              tunnelKey->tos = nh->tos;

>              if (VxlanHeader->instanceID) {

> -                tunnelKey->flags = OVS_TNL_F_KEY;

> +                tunnelKey->flags |= OVS_TNL_F_KEY;

>                  tunnelKey->tunnelId = VXLAN_VNI_TO_TUNNELID(VxlanHeader-

> >vxlanID);

>              } else {

> -                tunnelKey->flags = 0;

> +                tunnelKey->flags &= ~OVS_TNL_F_KEY;

>                  tunnelKey->tunnelId = 0;

>              }

>          } else {

> --

> 1.9.5.msysgit.0

> _______________________________________________

> dev mailing list

> dev@openvswitch.org

> http://openvswitch.org/mailman/listinfo/dev
Ben Pfaff June 1, 2016, 5:35 p.m. UTC | #2
On Tue, May 24, 2016 at 04:14:19PM +0000, Alin Serdean wrote:
> Introduce UDP checksum if it was specified in the tunnel information
> on Tx.
> 
> Set the tunnel checksum information flag on the flow if the
> UDP checksum was non zero on the Rx.
> 
> Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>

Applied, thanks!
diff mbox

Patch

diff --git a/datapath-windows/ovsext/Vxlan.c b/datapath-windows/ovsext/Vxlan.c
index 20214cb..520f313 100644
--- a/datapath-windows/ovsext/Vxlan.c
+++ b/datapath-windows/ovsext/Vxlan.c
@@ -192,6 +192,7 @@  OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
     UINT32 headRoom = OvsGetVxlanTunHdrSize();
     UINT32 packetLength;
     ULONG mss = 0;
+    NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
 
     /*
      * XXX: the assumption currently is that the NBL is owned by OVS, and
@@ -230,7 +231,6 @@  OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
             OVS_LOG_ERROR("Unable to copy NBL");
             return NDIS_STATUS_FAILURE;
         }
-        NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
         csumInfo.Value = NET_BUFFER_LIST_INFO(curNbl,
                                               TcpIpChecksumNetBufferListInfo);
         status = OvsApplySWChecksumOnNB(layers, *newNbl, &csumInfo);
@@ -249,7 +249,8 @@  OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
         }
 
         curMdl = NET_BUFFER_CURRENT_MDL(curNb);
-        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl, LowPagePriority);
+        bufferStart = (PUINT8)MmGetSystemAddressForMdlSafe(curMdl,
+                                                           LowPagePriority);
         if (!bufferStart) {
             status = NDIS_STATUS_RESOURCES;
             goto ret_error;
@@ -257,7 +258,8 @@  OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
 
         bufferStart += NET_BUFFER_CURRENT_MDL_OFFSET(curNb);
         if (NET_BUFFER_NEXT_NB(curNb)) {
-            OVS_LOG_TRACE("nb length %u next %u", NET_BUFFER_DATA_LENGTH(curNb),
+            OVS_LOG_TRACE("nb length %u next %u",
+                          NET_BUFFER_DATA_LENGTH(curNb),
                           NET_BUFFER_DATA_LENGTH(curNb->Next));
         }
 
@@ -288,7 +290,6 @@  OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
         ipHdr->daddr = fwdInfo->dstIpAddr;
 
         ipHdr->check = 0;
-        ipHdr->check = IPChecksum((UINT8 *)ipHdr, sizeof *ipHdr, 0);
 
         /* UDP header */
         udpHdr = (UDPHdr *)((PCHAR)ipHdr + sizeof *ipHdr);
@@ -296,7 +297,13 @@  OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
         udpHdr->dest = htons(vportVxlan->dstPort);
         udpHdr->len = htons(NET_BUFFER_DATA_LENGTH(curNb) - headRoom +
                             sizeof *udpHdr + sizeof *vxlanHdr);
-        udpHdr->check = 0;
+
+        if (tunKey->flags & OVS_TNL_F_CSUM) {
+            udpHdr->check = IPPseudoChecksum(&ipHdr->saddr, &ipHdr->daddr,
+                                             IPPROTO_UDP, ntohs(udpHdr->len));
+        } else {
+            udpHdr->check = 0;
+        }
 
         /* VXLAN header */
         vxlanHdr = (VXLANHdr *)((PCHAR)udpHdr + sizeof *udpHdr);
@@ -308,6 +315,17 @@  OvsDoEncapVxlan(POVS_VPORT_ENTRY vport,
         vxlanHdr->instanceID = 1;
         vxlanHdr->reserved2 = 0;
     }
+
+    csumInfo.Value = 0;
+    csumInfo.Transmit.IpHeaderChecksum = 1;
+    csumInfo.Transmit.IsIPv4 = 1;
+    if (tunKey->flags & OVS_TNL_F_CSUM) {
+        csumInfo.Transmit.UdpChecksum = 1;
+    }
+    NET_BUFFER_LIST_INFO(curNbl,
+                         TcpIpChecksumNetBufferListInfo) = csumInfo.Value;
+
+
     return STATUS_SUCCESS;
 
 ret_error:
@@ -466,7 +484,9 @@  OvsDecapVxlan(POVS_SWITCH_CONTEXT switchContext,
 
     /* Calculate and verify UDP checksum if NIC didn't do it. */
     if (udpHdr->check != 0) {
-        status = OvsCalculateUDPChecksum(curNbl, curNb, ipHdr, udpHdr, packetLength);
+        tunKey->flags |= OVS_TNL_F_CSUM;
+        status = OvsCalculateUDPChecksum(curNbl, curNb, ipHdr, udpHdr,
+                                         packetLength);
         if (status != NDIS_STATUS_SUCCESS) {
             goto dropNbl;
         }
@@ -474,10 +494,10 @@  OvsDecapVxlan(POVS_SWITCH_CONTEXT switchContext,
 
     vxlanHdr = (VXLANHdr *)((PCHAR)udpHdr + sizeof *udpHdr);
     if (vxlanHdr->instanceID) {
-        tunKey->flags = OVS_TNL_F_KEY;
+        tunKey->flags |= OVS_TNL_F_KEY;
         tunKey->tunnelId = VXLAN_VNI_TO_TUNNELID(vxlanHdr->vxlanID);
     } else {
-        tunKey->flags = 0;
+        tunKey->flags &= ~OVS_TNL_F_KEY;
         tunKey->tunnelId = 0;
     }
 
@@ -520,6 +540,9 @@  OvsSlowPathDecapVxlan(const PNET_BUFFER_LIST packet,
         udp = OvsGetUdp(packet, layers.l4Offset, &udpStorage);
         if (udp) {
             layers.l7Offset = layers.l4Offset + sizeof *udp;
+            if (udp->check != 0) {
+                tunnelKey->flags |= OVS_TNL_F_CSUM;
+            }
         } else {
             break;
         }
@@ -535,10 +558,10 @@  OvsSlowPathDecapVxlan(const PNET_BUFFER_LIST packet,
             tunnelKey->ttl = nh->ttl;
             tunnelKey->tos = nh->tos;
             if (VxlanHeader->instanceID) {
-                tunnelKey->flags = OVS_TNL_F_KEY;
+                tunnelKey->flags |= OVS_TNL_F_KEY;
                 tunnelKey->tunnelId = VXLAN_VNI_TO_TUNNELID(VxlanHeader->vxlanID);
             } else {
-                tunnelKey->flags = 0;
+                tunnelKey->flags &= ~OVS_TNL_F_KEY;
                 tunnelKey->tunnelId = 0;
             }
         } else {