summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datapath-windows/ovsext/Actions.c38
-rw-r--r--datapath-windows/ovsext/DpInternal.h1
-rw-r--r--datapath-windows/ovsext/Flow.c14
3 files changed, 53 insertions, 0 deletions
diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 199f6804e..a91454da1 100644
--- a/datapath-windows/ovsext/Actions.c
+++ b/datapath-windows/ovsext/Actions.c
@@ -21,6 +21,7 @@
#include "Event.h"
#include "Flow.h"
#include "Gre.h"
+#include "Jhash.h"
#include "Mpls.h"
#include "NetProto.h"
#include "Offload.h"
@@ -1573,6 +1574,27 @@ OvsExecuteRecirc(OvsForwardingContext *ovsFwdCtx,
/*
* --------------------------------------------------------------------------
+ * OvsExecuteHash --
+ * The function updates datapath hash read from userspace.
+ * --------------------------------------------------------------------------
+ */
+VOID
+OvsExecuteHash(OvsFlowKey *key,
+ const PNL_ATTR attr)
+{
+ struct ovs_action_hash *hash_act = NlAttrData(attr);
+ UINT32 hash = 0;
+
+ hash = (UINT32)OvsHashFlow(key);
+ hash = OvsJhashWords(&hash, 1, hash_act->hash_basis);
+ if (!hash)
+ hash = 1;
+
+ key->dpHash = hash;
+}
+
+/*
+ * --------------------------------------------------------------------------
* OvsDoExecuteActions --
* Interpret and execute the specified 'actions' on the specified packet
* 'curNbl'. The expectation is that if the packet needs to be dropped
@@ -1748,6 +1770,22 @@ OvsDoExecuteActions(POVS_SWITCH_CONTEXT switchContext,
break;
}
+ case OVS_ACTION_ATTR_HASH:
+ {
+ if (ovsFwdCtx.destPortsSizeOut > 0 || ovsFwdCtx.tunnelTxNic != NULL
+ || ovsFwdCtx.tunnelRxNic != NULL) {
+ status = OvsOutputBeforeSetAction(&ovsFwdCtx);
+ if (status != NDIS_STATUS_SUCCESS) {
+ dropReason = L"OVS-adding destination failed";
+ goto dropit;
+ }
+ }
+
+ OvsExecuteHash(key, (const PNL_ATTR)a);
+
+ break;
+ }
+
case OVS_ACTION_ATTR_RECIRC:
{
if (ovsFwdCtx.destPortsSizeOut > 0 || ovsFwdCtx.tunnelTxNic != NULL
diff --git a/datapath-windows/ovsext/DpInternal.h b/datapath-windows/ovsext/DpInternal.h
index be8ac2547..bf568362f 100644
--- a/datapath-windows/ovsext/DpInternal.h
+++ b/datapath-windows/ovsext/DpInternal.h
@@ -166,6 +166,7 @@ typedef __declspec(align(8)) struct OvsFlowKey {
MplsKey mplsKey; /* size 8 */
};
UINT32 recircId; /* Recirculation ID. */
+ UINT32 dpHash; /* Datapath calculated hash value. */
} OvsFlowKey;
#define OVS_WIN_TUNNEL_KEY_SIZE (sizeof (OvsIPv4TunnelKey))
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index 9993e49ba..a82b51b0d 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -850,6 +850,14 @@ MapFlowKeyToNlKey(PNL_BUFFER nlBuf,
goto done;
}
+ if (flowKey->dpHash) {
+ if (!NlMsgPutTailU32(nlBuf, OVS_KEY_ATTR_DP_HASH,
+ flowKey->dpHash)) {
+ rc = STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+ }
+
/* Ethernet header */
RtlCopyMemory(&(ethKey.eth_src), flowKey->l2.dlSrc, ETH_ADDR_LEN);
RtlCopyMemory(&(ethKey.eth_dst), flowKey->l2.dlDst, ETH_ADDR_LEN);
@@ -1377,6 +1385,11 @@ _MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs,
destKey->l2.keyLen += sizeof(destKey->recircId);
}
+ if (keyAttrs[OVS_KEY_ATTR_DP_HASH]) {
+ destKey->dpHash = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_DP_HASH]);
+ destKey->l2.keyLen += sizeof(destKey->dpHash);
+ }
+
/* ===== L2 headers ===== */
destKey->l2.inPort = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_IN_PORT]);
@@ -2269,6 +2282,7 @@ ReportFlowInfo(OvsFlow *flow,
}
info->key.recircId = flow->key.recircId;
+ info->key.dpHash = flow->key.dpHash;
return status;
}