diff mbox

[ovs-dev,v2,4/5] datapath-windows: Add support for OVS_KEY_ATTR_UDP set action

Message ID 20170106193210.7896-4-aserdean@cloudbasesolutions.com
State Superseded
Headers show

Commit Message

Alin Serdean Jan. 6, 2017, 7:33 p.m. UTC
This patch adds support for set action with OVS_KEY_ATTR_UDP attribute
(change UDP source or destination port).

If the source or destination UDP port was changed, update the UDP checksum.

A sample flow can look like the following:
set(udp(src=67,dst=68))

Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
---
v2: no change
---
 datapath-windows/ovsext/Actions.c | 48 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

Comments

Alin Serdean Jan. 10, 2017, 4:51 p.m. UTC | #1
Udp checksum should not be updated in the case it was 0. I will add the changes in the next version.

Thanks,
Alin.

> -----Original Message-----
> From: Alin Serdean
> Sent: Friday, January 6, 2017 9:34 PM
> To: dev@openvswitch.org
> Cc: Alin Serdean <aserdean@cloudbasesolutions.com>
> Subject: [PATCH v2 4/5] datapath-windows: Add support for
> OVS_KEY_ATTR_UDP set action
> 
> This patch adds support for set action with OVS_KEY_ATTR_UDP attribute
> (change UDP source or destination port).
> 
> If the source or destination UDP port was changed, update the UDP
> checksum.
>
diff mbox

Patch

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 467bfbc..a09afdd 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -1306,7 +1306,6 @@  OvsUpdateEthHeader(OvsForwardingContext *ovsFwdCtx,
     return NDIS_STATUS_SUCCESS;
 }
 
-
 /*
  *----------------------------------------------------------------------------
  * OvsGetHeaderBySize --
@@ -1382,6 +1381,48 @@  PUINT8 OvsGetHeaderBySize(OvsForwardingContext *ovsFwdCtx,
     return start + curMdlOffset;
 }
 
+/*
+ *----------------------------------------------------------------------------
+ * OvsUpdateUdpPorts --
+ *      Updates the UDP source or destination port in ovsFwdCtx.curNbl inline
+ *      based on the specified key.
+ *----------------------------------------------------------------------------
+ */
+static __inline NDIS_STATUS
+OvsUpdateUdpPorts(OvsForwardingContext *ovsFwdCtx,
+                  const struct ovs_key_udp *udpAttr)
+{
+    PUINT8 bufferStart;
+    OVS_PACKET_HDR_INFO *layers = &ovsFwdCtx->layers;
+    UDPHdr *udpHdr = NULL;
+
+    ASSERT(layers->value != 0);
+
+    if (!layers->isUdp) {
+        ovsActionStats.noCopiedNbl++;
+        return NDIS_STATUS_FAILURE;
+    }
+
+    bufferStart = OvsGetHeaderBySize(ovsFwdCtx, layers->l7Offset);
+    if (!bufferStart) {
+        return NDIS_STATUS_RESOURCES;
+    }
+
+    udpHdr = (UDPHdr *)(bufferStart + layers->l4Offset);
+
+    if (udpHdr->source != udpAttr->udp_src) {
+        udpHdr->check = ChecksumUpdate16(udpHdr->check, udpHdr->source,
+                                         udpAttr->udp_src);
+        udpHdr->source = udpAttr->udp_src;
+    }
+    if (udpHdr->dest != udpAttr->udp_dst) {
+        udpHdr->check = ChecksumUpdate16(udpHdr->check, udpHdr->dest,
+                                         udpAttr->udp_dst);
+        udpHdr->dest = udpAttr->udp_dst;
+    }
+
+    return NDIS_STATUS_SUCCESS;
+}
 
 /*
  *----------------------------------------------------------------------------
@@ -1525,6 +1566,11 @@  OvsExecuteSetAction(OvsForwardingContext *ovsFwdCtx,
         break;
     }
 
+    case OVS_KEY_ATTR_UDP:
+        status = OvsUpdateUdpPorts(ovsFwdCtx,
+            NlAttrGetUnspec(a, sizeof(struct ovs_key_udp)));
+        break;
+
     default:
         OVS_LOG_INFO("Unhandled attribute %#x", type);
         break;