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 <[email protected]> --- 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 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
