summaryrefslogtreecommitdiff
path: root/datapath-windows/ovsext/Conntrack.c
diff options
context:
space:
mode:
authorldejing <ldejing@vmware.com>2022-09-16 15:52:51 +0800
committerAlin-Gabriel Serdean <aserdean@ovn.org>2022-09-20 02:27:20 +0300
commit54a618f0bd83431a18307a312e5b41e401538bbc (patch)
tree6b83b320e1b26858b8e3cadfe12f0468c3524968 /datapath-windows/ovsext/Conntrack.c
parent7a9dc1950f6a6c06f184b734a9f3a24b918088d7 (diff)
downloadopenvswitch-54a618f0bd83431a18307a312e5b41e401538bbc.tar.gz
datapath-windows: Alg support for ftp and tftp in conntrack
This patch mainly support alg field in ct action when process ftp/tftp traffic. Tftp with alg mainly parse the tftp packet (IPv4/IPv6), extract connect info from the tftp packet and create the related connection. For ftp, previous version has supported process of ftp traffic. However, previous version regard traffic from or to port 21 as ftp traffic, this is incorrect in some scenario. This version adds alg field in ct for ftp traffic, we could use ct(alg=ftp) to process any ftp traffic from/to any port. IPv4/IPv6. Test cases: 1) ftp ipv4/ipv6 use alg field in the normal and nat scenario. 2) tftp ipv4/ipv6 use alg field in the normal and nat scenario. Signed-off-by: ldejing <ldejing@vmware.com> Signed-off-by: Alin-Gabriel Serdean <aserdean@ovn.org>
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);