summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Actions.c
diff options
context:
space:
mode:
authorAlin Serdean <aserdean@cloudbasesolutions.com>2017-01-26 23:41:46 +0000
committerGurucharan Shetty <guru@ovn.org>2017-01-27 13:53:09 -0800
commitdd71a1dd979fd68ea53adfd92f367d88894c6311 (patch)
tree72c86b0d2a75fe39682121090d500fe4bab59a88 /datapath-windows/ovsext/Actions.c
parent1a2bea5d586e281ab8b821b9ed711afec80dc3bc (diff)
downloadopenvswitch-dd71a1dd979fd68ea53adfd92f367d88894c6311.tar.gz
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. A sample flow can look like the following: set(udp(src=67,dst=68)) Signed-off-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Acked-by: Sairam Venugopal <vsairam@vmware.com> Signed-off-by: Gurucharan Shetty <guru@ovn.org>
Diffstat (limited to 'datapath-windows/ovsext/Actions.c')
-rw-r--r--datapath-windows/ovsext/Actions.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 467bfbc82..3dfcc6827 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,52 @@ 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->check) {
+ 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;
+ }
+ } else {
+ udpHdr->source = udpAttr->udp_src;
+ udpHdr->dest = udpAttr->udp_dst;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
/*
*----------------------------------------------------------------------------
@@ -1525,6 +1570,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;