[ovs-dev] [PATCH v2] datapath-windows: Add original conntrack tuple to FlowKey

Sairam Venugopal vsairam at vmware.com
Fri Jun 2 17:37:22 UTC 2017


Add the original tuple to Flow Key. In case of ICMP and UDP, default the
parent entry to NULL until related connections is supported.

Signed-off-by: Sairam Venugopal <vsairam at vmware.com>
---
 datapath-windows/ovsext/Conntrack.c  | 35 ++++++++++++++++++++-----
 datapath-windows/ovsext/DpInternal.h |  1 +
 datapath-windows/ovsext/Flow.c       | 50 ++++++++++++++++++++++++++++++++++--
 3 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
index dce0c1b..609ae5a 100644
--- a/datapath-windows/ovsext/Conntrack.c
+++ b/datapath-windows/ovsext/Conntrack.c
@@ -198,7 +198,7 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl,
             }
 
             state |= OVS_CS_F_NEW;
-            POVS_CT_ENTRY parentEntry = NULL;
+            POVS_CT_ENTRY parentEntry;
             parentEntry = OvsCtRelatedLookup(ctx->key, currentTime);
             if (parentEntry != NULL) {
                 state |= OVS_CS_F_RELATED;
@@ -209,10 +209,10 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl,
                 if (!entry) {
                     return NULL;
                 }
-                /* If this is related entry, then update parent */
-                if (parentEntry != NULL) {
-                    entry->parent = parentEntry;
-                }
+
+                /* Set parent entry for related FTP connections */
+                entry->parent = parentEntry;
+
                 OvsCtAddEntry(entry, ctx, currentTime);
                 *entryCreated = TRUE;
             }
@@ -235,6 +235,9 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl,
                 if (!entry) {
                     return NULL;
                 }
+
+                /* XXX Add support for ICMP-Related */
+                entry->parent = NULL;
                 OvsCtAddEntry(entry, ctx, currentTime);
                 *entryCreated = TRUE;
             }
@@ -250,6 +253,9 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl,
                 if (!entry) {
                     return NULL;
                 }
+
+                /* Default UDP related to NULL until TFTP is supported */
+                entry->parent = NULL;
                 OvsCtAddEntry(entry, ctx, currentTime);
                 *entryCreated = TRUE;
             }
@@ -586,8 +592,8 @@ OvsProcessConntrackEntry(PNET_BUFFER_LIST curNbl,
         } else {
             POVS_CT_ENTRY parentEntry;
             parentEntry = OvsCtRelatedLookup(ctx->key, currentTime);
+            entry->parent = parentEntry;
             if (parentEntry != NULL) {
-                entry->parent = parentEntry;
                 state |= OVS_CS_F_RELATED;
             }
         }
@@ -702,6 +708,23 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
         }
     }
 
+    /* Add original tuple information to flow Key */
+    if (entry && entry->key.dl_type == ntohs(ETH_TYPE_IPV4)) {
+        OVS_CT_KEY *ctKey;
+        if (entry->parent != NULL) {
+            POVS_CT_ENTRY parent = entry->parent;
+            ctKey = &parent->key;
+        } else {
+            ctKey = &entry->key;
+        }
+
+        key->ct.tuple_ipv4.ipv4_src = ctKey->src.addr.ipv4_aligned;
+        key->ct.tuple_ipv4.ipv4_dst = ctKey->dst.addr.ipv4_aligned;
+        key->ct.tuple_ipv4.src_port = ctKey->src.port;
+        key->ct.tuple_ipv4.dst_port = ctKey->dst.port;
+        key->ct.tuple_ipv4.ipv4_proto = ctKey->nw_proto;
+    }
+
     if (entryCreated && entry) {
         OvsPostCtEventEntry(entry, OVS_EVENT_CT_NEW);
     }
diff --git a/datapath-windows/ovsext/DpInternal.h b/datapath-windows/ovsext/DpInternal.h
index 9d1a783..743891c 100644
--- a/datapath-windows/ovsext/DpInternal.h
+++ b/datapath-windows/ovsext/DpInternal.h
@@ -199,6 +199,7 @@ typedef __declspec(align(8)) struct OvsFlowKey {
         UINT32 mark;
         UINT32 state;
         struct ovs_key_ct_labels labels;
+        struct ovs_key_ct_tuple_ipv4 tuple_ipv4;
     } ct;                        /* Connection Tracking Flags */
 } OvsFlowKey;
 
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index 96ff9fa..80f5676 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -180,6 +180,10 @@ const NL_POLICY nlFlowKeyPolicy[] = {
     [OVS_KEY_ATTR_CT_LABELS] = {.type = NL_A_UNSPEC,
                                 .minLen = sizeof(struct ovs_key_ct_labels),
                                 .maxLen = sizeof(struct ovs_key_ct_labels),
+                                .optional = TRUE},
+    [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4] = {.type = NL_A_UNSPEC,
+                                .minLen = sizeof(struct ovs_key_ct_tuple_ipv4),
+                                .maxLen = sizeof(struct ovs_key_ct_tuple_ipv4),
                                 .optional = TRUE}
 };
 const UINT32 nlFlowKeyPolicyLen = ARRAY_SIZE(nlFlowKeyPolicy);
@@ -887,6 +891,12 @@ MapFlowKeyToNlKey(PNL_BUFFER nlBuf,
         rc = STATUS_UNSUCCESSFUL;
         goto done;
     }
+    if (!NlMsgPutTailUnspec(nlBuf, OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4,
+                            (PCHAR)(&flowKey->ct.tuple_ipv4),
+                            sizeof(struct ovs_key_ct_tuple_ipv4))) {
+        rc = STATUS_UNSUCCESSFUL;
+        goto done;
+    }
 
     if (flowKey->dpHash) {
         if (!NlMsgPutTailU32(nlBuf, OVS_KEY_ATTR_DP_HASH,
@@ -1447,7 +1457,15 @@ _MapKeyAttrToFlowPut(PNL_ATTR *keyAttrs,
     if (keyAttrs[OVS_KEY_ATTR_CT_LABELS]) {
         const struct ovs_key_ct_labels *ct_labels;
         ct_labels = NlAttrGet(keyAttrs[OVS_KEY_ATTR_CT_LABELS]);
-        RtlCopyMemory(&destKey->ct.labels, ct_labels, sizeof(struct ovs_key_ct_labels));
+        NdisMoveMemory(&destKey->ct.labels, ct_labels,
+                       sizeof(struct ovs_key_ct_labels));
+    }
+
+    if (keyAttrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]) {
+        const struct ovs_key_ct_tuple_ipv4 *tuple_ipv4;
+        tuple_ipv4 = NlAttrGet(keyAttrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]);
+        NdisMoveMemory(&destKey->ct.tuple_ipv4, tuple_ipv4,
+                       sizeof(struct ovs_key_ct_tuple_ipv4));
     }
 
     /* ===== L2 headers ===== */
@@ -1988,7 +2006,15 @@ OvsGetFlowMetadata(OvsFlowKey *key,
     if (keyAttrs[OVS_KEY_ATTR_CT_LABELS]) {
         const struct ovs_key_ct_labels *ct_labels;
         ct_labels = NlAttrGet(keyAttrs[OVS_KEY_ATTR_CT_LABELS]);
-        RtlCopyMemory(&key->ct.labels, ct_labels, sizeof(struct ovs_key_ct_labels));
+        NdisMoveMemory(&key->ct.labels, ct_labels,
+                       sizeof(struct ovs_key_ct_labels));
+    }
+
+    if (keyAttrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]) {
+        const struct ovs_key_ct_tuple_ipv4 *tuple_ipv4;
+        tuple_ipv4 = NlAttrGet(keyAttrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]);
+        NdisMoveMemory(&key->ct.tuple_ipv4, tuple_ipv4,
+                       sizeof(struct ovs_key_ct_tuple_ipv4));
     }
 
     return status;
@@ -2461,6 +2487,8 @@ FlowEqual(OvsFlow *srcFlow,
             srcFlow->key.ct.mark == dstKey->ct.mark &&
             !memcmp(&srcFlow->key.ct.labels, &dstKey->ct.labels,
                     sizeof(struct ovs_key_ct_labels)) &&
+            !memcmp(&srcFlow->key.ct.tuple_ipv4, &dstKey->ct.tuple_ipv4,
+                    sizeof(struct ovs_key_ct_tuple_ipv4)) &&
             FlowMemoryEqual((UINT64 *)((UINT8 *)&srcFlow->key + offset),
                             (UINT64 *) dstStart,
                             size));
@@ -2573,6 +2601,13 @@ OvsLookupFlow(OVS_DATAPATH *datapath,
                                            0);
             *hash = OvsJhashWords((UINT32*)hash, 1, lblHash);
         }
+        if (key->ct.tuple_ipv4.ipv4_src) {
+            UINT32 tupleHash = OvsJhashBytes(
+                                &key->ct.tuple_ipv4,
+                                sizeof(struct ovs_key_ct_tuple_ipv4),
+                                0);
+            *hash = OvsJhashWords((UINT32*)hash, 1, tupleHash);
+        }
     }
 
     head = &datapath->flowTable[HASH_BUCKET(*hash)];
@@ -2745,6 +2780,9 @@ ReportFlowInfo(OvsFlow *flow,
     NdisMoveMemory(&info->key.ct.labels,
                    &flow->key.ct.labels,
                    sizeof(struct ovs_key_ct_labels));
+    NdisMoveMemory(&info->key.ct.tuple_ipv4,
+                   &flow->key.ct.tuple_ipv4,
+                   sizeof(struct ovs_key_ct_tuple_ipv4));
 
     return status;
 }
@@ -3005,6 +3043,7 @@ OvsFlowKeyAttrSize(void)
          + NlAttrTotalSize(2)   /* OVS_KEY_ATTR_CT_ZONE */
          + NlAttrTotalSize(4)   /* OVS_KEY_ATTR_CT_MARK */
          + NlAttrTotalSize(16)  /* OVS_KEY_ATTR_CT_LABELS */
+         + NlAttrTotalSize(13)  /* OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4 */
          + NlAttrTotalSize(12)  /* OVS_KEY_ATTR_ETHERNET */
          + NlAttrTotalSize(2)   /* OVS_KEY_ATTR_ETHERTYPE */
          + NlAttrTotalSize(4)   /* OVS_KEY_ATTR_VLAN */
@@ -3109,6 +3148,13 @@ OvsProbeSupportedFeature(POVS_MESSAGE msgIn,
             OVS_LOG_ERROR("Invalid ct label specified.");
             status = STATUS_INVALID_PARAMETER;
         }
+    } else if (keyAttrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]) {
+        const struct ovs_key_ct_tuple_ipv4 *ct_tuple_ipv4;
+        ct_tuple_ipv4 = NlAttrGet(keyAttrs[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]);
+        if (!ct_tuple_ipv4) {
+            OVS_LOG_ERROR("Invalid ct_tuple_ipv4.");
+            status = STATUS_INVALID_PARAMETER;
+        }
     } else {
         OVS_LOG_ERROR("Feature not supported.");
         status = STATUS_INVALID_PARAMETER;
-- 
2.9.0.windows.1



More information about the dev mailing list