From 28b3e3ba0db5f10f875679d2a1535e13e4994e0e Mon Sep 17 00:00:00 2001 From: Jinjun Gao Date: Tue, 30 Jun 2020 19:47:57 +0800 Subject: datapath-windows: Add CTA_HELP and CTA_TUPLE_MASTER Add helper and master if existing to a conntrack entry: 1, For CTA_HELP, only support FTP/TFTP; 2, For CTA_TUPLE_MASTER, only support FTP. Signed-off-by: Jinjun Gao Signed-off-by: Alin Gabriel Serdean --- datapath-windows/ovsext/Conntrack-related.c | 5 ++- datapath-windows/ovsext/Conntrack.c | 50 +++++++++++++++++++++++++---- datapath-windows/ovsext/Conntrack.h | 1 + 3 files changed, 48 insertions(+), 8 deletions(-) (limited to 'datapath-windows') diff --git a/datapath-windows/ovsext/Conntrack-related.c b/datapath-windows/ovsext/Conntrack-related.c index 950be98e9..a5bba5cf8 100644 --- a/datapath-windows/ovsext/Conntrack-related.c +++ b/datapath-windows/ovsext/Conntrack-related.c @@ -47,8 +47,11 @@ OvsCtRelatedKeyAreSame(OVS_CT_KEY incomingKey, OVS_CT_KEY entryKey) } /* FTP ACTIVE - Server initiates the connection */ + /* Some ftp server, such as pyftpdlib, may use random (>1024) data port + * except 20. In this case, the incomingKey's src port is different with + * entryKey's src port. + */ if ((incomingKey.src.addr.ipv4 == entryKey.src.addr.ipv4) && - (incomingKey.src.port == entryKey.src.port) && (incomingKey.dst.addr.ipv4 == entryKey.dst.addr.ipv4) && (incomingKey.dst.port == entryKey.dst.port) && (incomingKey.dl_type == entryKey.dl_type) && diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c index 55917c43f..d0655911b 100644 --- a/datapath-windows/ovsext/Conntrack.c +++ b/datapath-windows/ovsext/Conntrack.c @@ -246,7 +246,6 @@ OvsPostCtEventEntry(POVS_CT_ENTRY entry, UINT8 type) { OVS_CT_EVENT_ENTRY ctEventEntry = {0}; NdisMoveMemory(&ctEventEntry.entry, entry, sizeof(OVS_CT_ENTRY)); - ctEventEntry.entry.parent = NULL; ctEventEntry.type = type; OvsPostCtEvent(&ctEventEntry); } @@ -480,6 +479,9 @@ OvsCtEntryDelete(POVS_CT_ENTRY entry, BOOLEAN forceDelete) RemoveEntryList(&entry->link); OVS_RELEASE_SPIN_LOCK(&(entry->lock), irql); NdisFreeSpinLock(&(entry->lock)); + if (entry->helper_name) { + OvsFreeMemoryWithTag(entry->helper_name, OVS_CT_POOL_TAG); + } OvsFreeMemoryWithTag(entry, OVS_CT_POOL_TAG); NdisInterlockedDecrement((PLONG)&ctTotalEntries); return; @@ -883,6 +885,7 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx, BOOLEAN triggerUpdateEvent = FALSE; BOOLEAN entryCreated = FALSE; POVS_CT_ENTRY entry = NULL; + POVS_CT_ENTRY parent = NULL; PNET_BUFFER_LIST curNbl = fwdCtx->curNbl; OvsConntrackKeyLookupCtx ctx = { 0 }; LOCK_STATE_EX lockStateTable; @@ -959,8 +962,6 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx, if (OvsDetectFtpPacket(key)) { /* FTP parser will always be loaded */ - UNREFERENCED_PARAMETER(helper); - status = OvsCtHandleFtp(curNbl, key, layers, currentTime, entry, (ntohs(key->ipKey.l4.tpDst) == IPPORT_FTP)); if (status != NDIS_STATUS_SUCCESS) { @@ -968,10 +969,25 @@ OvsCtExecute_(OvsForwardingContext *fwdCtx, } } + 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); + if (!entry->helper_name) { + OVS_LOG_ERROR("Error while allocating memory"); + OVS_RELEASE_SPIN_LOCK(&(entry->lock), irql); + return NDIS_STATUS_RESOURCES; + } + memcpy(entry->helper_name, helper, strlen(helper) + 1); + } + /* Add original tuple information to flow Key */ if (entry->key.dl_type == ntohs(ETH_TYPE_IPV4)) { - if (entry->parent != NULL) { - POVS_CT_ENTRY parent = entry->parent; + if (parent != NULL) { OVS_ACQUIRE_SPIN_LOCK(&(parent->lock), irql); OvsCtUpdateTuple(key, &parent->key); OVS_RELEASE_SPIN_LOCK(&(parent->lock), irql); @@ -1042,8 +1058,8 @@ OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx, if (helper == NULL) { return NDIS_STATUS_INVALID_PARAMETER; } - if (strcmp("ftp", helper) != 0) { - /* Only support FTP */ + if (strcmp("ftp", helper) != 0 && strcmp("tftp", helper) != 0) { + /* Only support FTP/TFTP */ return NDIS_STATUS_NOT_SUPPORTED; } break; @@ -1683,6 +1699,26 @@ OvsCreateNlMsgFromCtEntry(POVS_CT_ENTRY entry, } } + if (entry->helper_name) { + UINT32 offset; + offset = NlMsgStartNested(&nlBuf, CTA_HELP); + if (!offset) { + return NDIS_STATUS_FAILURE; + } + if (!NlMsgPutTailString(&nlBuf, CTA_HELP_NAME, entry->helper_name)) { + return STATUS_INVALID_BUFFER_SIZE; + } + NlMsgEndNested(&nlBuf, offset); + } + + if (entry->parent) { + status = MapCtKeyTupleToNl(&nlBuf, CTA_TUPLE_MASTER, + &((POVS_CT_ENTRY)entry->parent)->key); + if (status != NDIS_STATUS_SUCCESS) { + return STATUS_UNSUCCESSFUL; + } + } + /* CTA_STATUS is required but not implemented. Default to 0 */ if (!NlMsgPutTailU32(&nlBuf, CTA_STATUS, 0)) { return STATUS_INVALID_BUFFER_SIZE; diff --git a/datapath-windows/ovsext/Conntrack.h b/datapath-windows/ovsext/Conntrack.h index b0932186a..bbbf49c11 100644 --- a/datapath-windows/ovsext/Conntrack.h +++ b/datapath-windows/ovsext/Conntrack.h @@ -109,6 +109,7 @@ typedef struct OVS_CT_ENTRY { struct ovs_key_ct_labels labels; NAT_ACTION_INFO natInfo; PVOID parent; /* Points to main connection */ + PCHAR helper_name; } OVS_CT_ENTRY, *POVS_CT_ENTRY; typedef struct OVS_CT_REL_ENTRY { -- cgit v1.2.1