[ovs-dev] [PATCH v7 4/6] datapath-windows: Support for OVS_ACTION_ATTR_HASH attribute

Sorin Vinturis svinturis at cloudbasesolutions.com
Thu Mar 24 16:53:50 UTC 2016


Signed-off-by: Sorin Vinturis <svinturis at cloudbasesolutions.com>
Acked-by: Sairam Venugopal <vsairam at vmware.com>
---
 datapath-windows/ovsext/Actions.c    | 38 ++++++++++++++++++++++++++++++++++++
 datapath-windows/ovsext/DpInternal.h |  1 +
 datapath-windows/ovsext/Flow.c       | 14 +++++++++++++
 3 files changed, 53 insertions(+)

diff --git a/datapath-windows/ovsext/Actions.c b/datapath-windows/ovsext/Actions.c
index 199f680..a91454d 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 be8ac25..bf56836 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 9993e49..a82b51b 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;
 }
-- 
1.9.0.msysgit.0



More information about the dev mailing list