]> git.proxmox.com Git - mirror_ovs.git/commitdiff
datapath-windows: Add support for OVS_KEY_ATTR_TCP set action
authorAlin Serdean <aserdean@cloudbasesolutions.com>
Thu, 26 Jan 2017 23:43:39 +0000 (23:43 +0000)
committerGurucharan Shetty <guru@ovn.org>
Fri, 27 Jan 2017 21:53:11 +0000 (13:53 -0800)
This patch adds support for set action with OVS_KEY_ATTR_TCP attribute
(change TCP source or destination port).

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

A sample flow can look like the following:
set(tcp(src=80,dst=443))

Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com>
Acked-by: Sairam Venugopal <vsairam@vmware.com>
Signed-off-by: Gurucharan Shetty <guru@ovn.org>
datapath-windows/ovsext/Actions.c

index 3dfcc68271c6c35fe50531b1c14a6d7d6847d531..bce37f8dcdab2e909d4f6d750705ca4f8392b779 100644 (file)
@@ -1428,6 +1428,49 @@ OvsUpdateUdpPorts(OvsForwardingContext *ovsFwdCtx,
     return NDIS_STATUS_SUCCESS;
 }
 
+/*
+ *----------------------------------------------------------------------------
+ * OvsUpdateTcpPorts --
+ *      Updates the TCP source or destination port in ovsFwdCtx.curNbl inline
+ *      based on the specified key.
+ *----------------------------------------------------------------------------
+ */
+static __inline NDIS_STATUS
+OvsUpdateTcpPorts(OvsForwardingContext *ovsFwdCtx,
+                  const struct ovs_key_tcp *tcpAttr)
+{
+    PUINT8 bufferStart;
+    OVS_PACKET_HDR_INFO *layers = &ovsFwdCtx->layers;
+    TCPHdr *tcpHdr = NULL;
+
+    ASSERT(layers->value != 0);
+
+    if (!layers->isTcp) {
+        ovsActionStats.noCopiedNbl++;
+        return NDIS_STATUS_FAILURE;
+    }
+
+    bufferStart = OvsGetHeaderBySize(ovsFwdCtx, layers->l7Offset);
+    if (!bufferStart) {
+        return NDIS_STATUS_RESOURCES;
+    }
+
+    tcpHdr = (TCPHdr *)(bufferStart + layers->l4Offset);
+
+    if (tcpHdr->source != tcpAttr->tcp_src) {
+        tcpHdr->check = ChecksumUpdate16(tcpHdr->check, tcpHdr->source,
+                                         tcpAttr->tcp_src);
+        tcpHdr->source = tcpAttr->tcp_src;
+    }
+    if (tcpHdr->dest != tcpAttr->tcp_dst) {
+        tcpHdr->check = ChecksumUpdate16(tcpHdr->check, tcpHdr->dest,
+                                         tcpAttr->tcp_dst);
+        tcpHdr->dest = tcpAttr->tcp_dst;
+    }
+
+    return NDIS_STATUS_SUCCESS;
+}
+
 /*
  *----------------------------------------------------------------------------
  * OvsUpdateIPv4Header --
@@ -1575,6 +1618,11 @@ OvsExecuteSetAction(OvsForwardingContext *ovsFwdCtx,
             NlAttrGetUnspec(a, sizeof(struct ovs_key_udp)));
         break;
 
+    case OVS_KEY_ATTR_TCP:
+        status = OvsUpdateTcpPorts(ovsFwdCtx,
+            NlAttrGetUnspec(a, sizeof(struct ovs_key_tcp)));
+        break;
+
     default:
         OVS_LOG_INFO("Unhandled attribute %#x", type);
         break;