datapath-windows: Support for OVS_ACTION_ATTR_HASH attribute
authorSorin Vinturis <svinturis@cloudbasesolutions.com>
Fri, 25 Mar 2016 14:49:27 +0000 (14:49 +0000)
committerBen Pfaff <blp@ovn.org>
Fri, 25 Mar 2016 15:24:36 +0000 (08:24 -0700)
Signed-off-by: Sorin Vinturis <svinturis@cloudbasesolutions.com>
Acked-by: Sairam Venugopal <vsairam@vmware.com>
Acked-by: Nithin Raju <nithin@vmware.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
datapath-windows/ovsext/Actions.c
datapath-windows/ovsext/DpInternal.h
datapath-windows/ovsext/Flow.c

index 199f680..a91454d 100644 (file)
@@ -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"
@@ -1571,6 +1572,27 @@ OvsExecuteRecirc(OvsForwardingContext *ovsFwdCtx,
     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 --
@@ -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
index be8ac25..bf56836 100644 (file)
@@ -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))
index 9993e49..a82b51b 100644 (file)
@@ -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;
 }