[ovs-dev] [ovs-dev v2] datapath-windows: Add CTA_HELP and CTA_TUPLE_MASTER

Jinjun Gao jinjung at vmware.com
Tue Jun 30 11:47:57 UTC 2020


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 <jinjung at vmware.com>
---
v2:
  1, Add CTA_TUPLE_MASTER support in CT event subscribe/report system.
  2, Release CT entry lock in fail path.
  3, Add more comments.
---
 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(-)

diff --git a/datapath-windows/ovsext/Conntrack-related.c b/datapath-windows/ovsext/Conntrack-related.c
index 950be98..a5bba5c 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 55917c4..d065591 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 b093218..bbbf49c 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 {
--
2.7.4



More information about the dev mailing list