diff options
-rw-r--r-- | datapath-windows/ovsext/Actions.c | 38 | ||||
-rw-r--r-- | datapath-windows/ovsext/DpInternal.h | 1 | ||||
-rw-r--r-- | datapath-windows/ovsext/Flow.c | 14 |
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; } |