[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