#include "Event.h"
#include "Flow.h"
#include "Gre.h"
+#include "Jhash.h"
#include "Mpls.h"
#include "NetProto.h"
#include "Offload.h"
return NDIS_STATUS_SUCCESS;
}
+/*
+ * --------------------------------------------------------------------------
+ * 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 --
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
MplsKey mplsKey; /* size 8 */
};
UINT32 recircId; /* Recirculation ID. */
+ UINT32 dpHash; /* Datapath calculated hash value. */
} OvsFlowKey;
#define OVS_WIN_TUNNEL_KEY_SIZE (sizeof (OvsIPv4TunnelKey))
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);
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]);
}
info->key.recircId = flow->key.recircId;
+ info->key.dpHash = flow->key.dpHash;
return status;
}