summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Conntrack.c
diff options
context:
space:
mode:
Diffstat (limited to 'datapath-windows/ovsext/Conntrack.c')
-rw-r--r--datapath-windows/ovsext/Conntrack.c77
1 files changed, 61 insertions, 16 deletions
diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
index 471bf961b..1f3929894 100644
--- a/datapath-windows/ovsext/Conntrack.c
+++ b/datapath-windows/ovsext/Conntrack.c
@@ -874,13 +874,25 @@ OvsCtSetupLookupCtx(OvsFlowKey *flowKey,
return NDIS_STATUS_INVALID_PACKET;
}
+ /* It's only designed for unNat traffic, when reverse traffic comes,
+ * find the unNat table, if found the nat entry, based on the nat entry
+ * restore the conntrack, it will be stored in the ctx->key and then use the
+ * ctx->key lookup the conntrack table to find the corresponded
+ * entry with the traffic.*/
natEntry = OvsNatLookup(&ctx->key, TRUE);
if (natEntry) {
- /* Translate address first for reverse NAT */
+ /* initial direction 20::1 -> 20::9, reverse direction 21::3 -> 20::1
+ * 20::9 could be regarded as nat ip, before convert, ctx->key value
+ * is "21::3 -> 20::1", after convert, ctx->key value is
+ * "20::9->20::1" */
ctx->key = natEntry->ctEntry->key;
OvsCtKeyReverse(&ctx->key);
} else {
- if (flowKey->l2.dlType == htons(ETH_TYPE_IPV4)) {
+ if (OvsNatLookup(&ctx->key, FALSE)) {
+ /* Do nothing here, this branch here used to exclude traffic
+ * described in https://github.com/openvswitch/ovs-issues/issues/237
+ * */
+ } else if (flowKey->l2.dlType == htons(ETH_TYPE_IPV4)) {
OvsPickupCtTupleAsLookupKey(&(ctx->key), zone, flowKey);
}
}
@@ -903,6 +915,18 @@ OvsDetectFtp6Packet(OvsFlowKey *key) {
ntohs(key->ipv6Key.l4.tpSrc) == IPPORT_FTP));
}
+static __inline BOOLEAN
+OvsDetectTftpPacket(OvsFlowKey *key) {
+ return (key->ipKey.nwProto == IPPROTO_UDP &&
+ (ntohs(key->ipKey.l4.tpDst) == IPPORT_TFTP));
+}
+
+static __inline BOOLEAN
+OvsDetectTftp6Packet(OvsFlowKey *key) {
+ return (key->ipv6Key.nwProto == IPPROTO_UDP &&
+ (ntohs(key->ipv6Key.l4.tpDst) == IPPORT_TFTP));
+}
+
/*
*----------------------------------------------------------------------------
* OvsProcessConntrackEntry
@@ -989,7 +1013,9 @@ OvsProcessConntrackEntry(OvsForwardingContext *fwdCtx,
if (entry) {
NdisAcquireSpinLock(&(entry->lock));
if ((layers->isIPv6 && key->ipv6Key.nwProto == IPPROTO_TCP) ||
- (!(layers->isIPv6) && key->ipKey.nwProto == IPPROTO_TCP)) {
+ (!(layers->isIPv6) && key->ipKey.nwProto == IPPROTO_TCP) ||
+ (layers->isIPv6 && key->ipv6Key.nwProto == IPPROTO_UDP) ||
+ (!(layers->isIPv6) && key->ipKey.nwProto == IPPROTO_UDP)) {
/* Update the related bit if there is a parent */
if (entry->parent) {
state |= OVS_CS_F_RELATED;
@@ -1156,12 +1182,11 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx,
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
BOOLEAN triggerUpdateEvent = FALSE;
BOOLEAN entryCreated = FALSE;
- BOOLEAN isFtpPacket = FALSE;
- BOOLEAN isFtpRequestDirection = FALSE;
POVS_CT_ENTRY entry = NULL;
POVS_CT_ENTRY parent = NULL;
PNET_BUFFER_LIST curNbl = fwdCtx->curNbl;
OvsConntrackKeyLookupCtx ctx = { 0 };
+ CT_HELPER_METHOD helpMethod = CT_HELPER_NONE;
LOCK_STATE_EX lockStateTable;
UINT64 currentTime;
NdisGetCurrentSystemTime((LARGE_INTEGER *) &currentTime);
@@ -1241,32 +1266,52 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx,
OvsCtSetMarkLabel(key, entry, mark, labels, &triggerUpdateEvent);
+ if (helper && RtlEqualMemory(helper, "ftp", sizeof("ftp"))) {
+ helpMethod = CT_HELPER_FTP;
+ } else if (helper && RtlEqualMemory(helper, "tftp", sizeof("tftp"))) {
+ helpMethod = CT_HELPER_TFTP;
+ }
+
+ /* This code section was added to compatible with the old version,
+ * because old version regard all traffic to port 21 as ftp traffic,
+ * no need to add alg field in ct. Thus, the code was added to keep the
+ * same behavior for ftp and tftp.*/
if (layers->isIPv6) {
- isFtpPacket = OvsDetectFtp6Packet(key);
- if (ntohs(key->ipv6Key.l4.tpDst) == IPPORT_FTP) {
- isFtpRequestDirection = TRUE;
+ if (OvsDetectFtp6Packet(key)) {
+ helpMethod = CT_HELPER_FTP;
+ }
+
+ if (OvsDetectTftp6Packet(key)) {
+ helpMethod = CT_HELPER_TFTP;
}
} else {
- isFtpPacket = OvsDetectFtpPacket(key);
- if (ntohs(key->ipKey.l4.tpDst) == IPPORT_FTP) {
- isFtpRequestDirection = TRUE;
+ if (OvsDetectFtpPacket(key)) {
+ helpMethod = CT_HELPER_FTP;
+ }
+
+ if (OvsDetectTftpPacket(key)) {
+ helpMethod = CT_HELPER_TFTP;
}
}
- if (isFtpPacket) {
- /* FTP parser will always be loaded */
- status = OvsCtHandleFtp(curNbl, key, layers, currentTime, entry,
- isFtpRequestDirection);
+ if (helpMethod == CT_HELPER_FTP) {
+ status = OvsCtHandleFtp(curNbl, key, layers, currentTime, entry);
if (status != NDIS_STATUS_SUCCESS) {
OVS_LOG_ERROR("Error while parsing the FTP packet");
}
}
+ if (helpMethod == CT_HELPER_TFTP) {
+ status = OvsCtHandleTftp(curNbl, key, layers, currentTime, entry);
+ if (status != NDIS_STATUS_SUCCESS) {
+ OVS_LOG_ERROR("Error while parsing the TFTP packet");
+ }
+ }
+
parent = entry->parent;
/* The entry should have the same helper name with parent's */
if (!entry->helper_name &&
(helper || (parent && parent->helper_name))) {
-
helper = helper ? helper : parent->helper_name;
entry->helper_name = OvsAllocateMemoryWithTag(strlen(helper) + 1,
OVS_CT_POOL_TAG);