Skip to content

Commit e68988b

Browse files
Sairam Venugopalshettyg
authored andcommitted
datapath-windows: Conntrack - Enable FTP support
Enable the support for tracking FTP connections in the Connection tracker. This checks an incoming ftp control connection to extract the related data connection. When a matching data connection arrives, it would then update the connection entry to point to the original control connection. Signed-off-by: Sairam Venugopal <vsairam@vmware.com> Acked-by: Alin Gabriel Serdean <aserdean@cloudbasesolutions.com> Signed-off-by: Gurucharan Shetty <guru@ovn.org>
1 parent 7fd123b commit e68988b

5 files changed

Lines changed: 92 additions & 2 deletions

File tree

datapath-windows/ovsext/Conntrack.c

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,21 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl,
192192
}
193193

194194
state |= OVS_CS_F_NEW;
195+
POVS_CT_ENTRY parentEntry = NULL;
196+
parentEntry = OvsCtRelatedLookup(ctx->key, currentTime);
197+
if (parentEntry != NULL) {
198+
state |= OVS_CS_F_RELATED;
199+
}
200+
195201
if (commit) {
196202
entry = OvsConntrackCreateTcpEntry(tcp, curNbl, currentTime);
197203
if (!entry) {
198204
return NULL;
199205
}
206+
/* If this is related entry, then update parent */
207+
if (parentEntry != NULL) {
208+
entry->parent = parentEntry;
209+
}
200210
OvsCtAddEntry(entry, ctx, currentTime);
201211
}
202212

@@ -492,6 +502,13 @@ OvsCtSetupLookupCtx(OvsFlowKey *flowKey,
492502
return NDIS_STATUS_SUCCESS;
493503
}
494504

505+
static __inline BOOLEAN
506+
OvsDetectFtpPacket(OvsFlowKey *key) {
507+
return (key->ipKey.nwProto == IPPROTO_TCP &&
508+
(ntohs(key->ipKey.l4.tpDst) == IPPORT_FTP ||
509+
ntohs(key->ipKey.l4.tpSrc) == IPPORT_FTP));
510+
}
511+
495512
/*
496513
*----------------------------------------------------------------------------
497514
* OvsProcessConntrackEntry
@@ -542,6 +559,21 @@ OvsProcessConntrackEntry(PNET_BUFFER_LIST curNbl,
542559
break;
543560
}
544561
}
562+
563+
if (key->ipKey.nwProto == IPPROTO_TCP && entry) {
564+
/* Update the related bit if there is a parent */
565+
if (entry->parent) {
566+
state |= OVS_CS_F_RELATED;
567+
} else {
568+
POVS_CT_ENTRY parentEntry;
569+
parentEntry = OvsCtRelatedLookup(ctx->key, currentTime);
570+
if (parentEntry != NULL) {
571+
entry->parent = parentEntry;
572+
state |= OVS_CS_F_RELATED;
573+
}
574+
}
575+
}
576+
545577
/* Copy mark and label from entry into flowKey. If actions specify
546578
different mark and label, update the flowKey. */
547579
if (entry != NULL) {
@@ -592,7 +624,8 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
592624
BOOLEAN commit,
593625
UINT16 zone,
594626
MD_MARK *mark,
595-
MD_LABELS *labels)
627+
MD_LABELS *labels,
628+
PCHAR helper)
596629
{
597630
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
598631
POVS_CT_ENTRY entry = NULL;
@@ -629,6 +662,17 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
629662
OvsConntrackSetLabels(key, entry, &labels->value, &labels->mask);
630663
}
631664

665+
if (entry && OvsDetectFtpPacket(key)) {
666+
/* FTP parser will always be loaded */
667+
UNREFERENCED_PARAMETER(helper);
668+
669+
status = OvsCtHandleFtp(curNbl, key, layers, currentTime, entry,
670+
(ntohs(key->ipKey.l4.tpDst) == IPPORT_FTP));
671+
if (status != NDIS_STATUS_SUCCESS) {
672+
OVS_LOG_ERROR("Error while parsing the FTP packet");
673+
}
674+
}
675+
632676
NdisReleaseRWLock(ovsConntrackLockObj, &lockState);
633677

634678
return status;
@@ -651,6 +695,8 @@ OvsExecuteConntrackAction(PNET_BUFFER_LIST curNbl,
651695
UINT16 zone = 0;
652696
MD_MARK *mark = NULL;
653697
MD_LABELS *labels = NULL;
698+
PCHAR helper = NULL;
699+
654700
NDIS_STATUS status;
655701

656702
status = OvsDetectCtPacket(key);
@@ -674,9 +720,20 @@ OvsExecuteConntrackAction(PNET_BUFFER_LIST curNbl,
674720
if (ctAttr) {
675721
labels = NlAttrGet(ctAttr);
676722
}
723+
ctAttr = NlAttrFindNested(a, OVS_CT_ATTR_HELPER);
724+
if (ctAttr) {
725+
helper = NlAttrGetString(ctAttr);
726+
if (helper == NULL) {
727+
return NDIS_STATUS_INVALID_PARAMETER;
728+
}
729+
if (strcmp("ftp", helper) != 0) {
730+
/* Only support FTP */
731+
return NDIS_STATUS_NOT_SUPPORTED;
732+
}
733+
}
677734

678735
status = OvsCtExecute_(curNbl, key, layers,
679-
commit, zone, mark, labels);
736+
commit, zone, mark, labels, helper);
680737
return status;
681738
}
682739

datapath-windows/ovsext/Conntrack.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ typedef struct OVS_CT_ENTRY {
8585
UINT32 mark;
8686
UINT64 timestampStart;
8787
struct ovs_key_ct_labels labels;
88+
PVOID parent; /* Points to main connection */
8889
} OVS_CT_ENTRY, *POVS_CT_ENTRY;
8990

9091
typedef struct OVS_CT_REL_ENTRY {
@@ -200,4 +201,11 @@ NDIS_STATUS OvsCtRelatedEntryCreate(UINT8 ipProto,
200201
POVS_CT_ENTRY parent);
201202
POVS_CT_ENTRY OvsCtRelatedLookup(OVS_CT_KEY key, UINT64 currentTime);
202203

204+
NDIS_STATUS OvsCtHandleFtp(PNET_BUFFER_LIST curNbl,
205+
OvsFlowKey *key,
206+
OVS_PACKET_HDR_INFO *layers,
207+
UINT64 currentTime,
208+
POVS_CT_ENTRY entry,
209+
BOOLEAN request);
210+
203211
#endif /* __OVS_CONNTRACK_H_ */

datapath-windows/ovsext/Netlink/Netlink.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,22 @@ NlAttrGetU64(const PNL_ATTR nla)
990990
return NL_ATTR_GET_AS(nla, UINT64);
991991
}
992992

993+
/*
994+
* ---------------------------------------------------------------------------
995+
* Returns the string value in 'nla''s payload.
996+
* Returns NULL if it is not a proper '\0' terminated string.
997+
* ---------------------------------------------------------------------------
998+
*/
999+
PCHAR
1000+
NlAttrGetString(const PNL_ATTR nla)
1001+
{
1002+
ASSERT(nla->nlaLen >= NLA_HDRLEN);
1003+
if (!memchr(NlAttrGet(nla), '\0', nla->nlaLen - NLA_HDRLEN)) {
1004+
return NULL;
1005+
}
1006+
return NlAttrGet(nla);
1007+
}
1008+
9931009
/*
9941010
* ---------------------------------------------------------------------------
9951011
* Validate the netlink attribute against the policy

datapath-windows/ovsext/Netlink/Netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ UINT8 NlAttrGetU8(const PNL_ATTR nla);
138138
UINT16 NlAttrGetU16(const PNL_ATTR nla);
139139
UINT32 NlAttrGetU32(const PNL_ATTR nla);
140140
UINT64 NlAttrGetU64(const PNL_ATTR nla);
141+
PCHAR NlAttrGetString(const PNL_ATTR nla);
141142
const PNL_ATTR NlAttrFind__(const PNL_ATTR attrs,
142143
UINT32 size, UINT16 type);
143144
const PNL_ATTR NlAttrFindNested(const PNL_ATTR nla,

datapath-windows/ovsext/Switch.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,13 @@ OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle,
225225
goto create_switch_done;
226226
}
227227

228+
status = OvsInitCtRelated(switchContext);
229+
if (status != STATUS_SUCCESS) {
230+
OvsUninitSwitchContext(switchContext);
231+
OVS_LOG_ERROR("Exit: Failed to initialize Connection tracking");
232+
goto create_switch_done;
233+
}
234+
228235
*switchContextOut = switchContext;
229236

230237
create_switch_done:
@@ -257,6 +264,7 @@ OvsExtDetach(NDIS_HANDLE filterModuleContext)
257264
OvsCleanupIpHelper();
258265
OvsCleanupSttDefragmentation();
259266
OvsCleanupConntrack();
267+
OvsCleanupCtRelated();
260268
/* This completes the cleanup, and a new attach can be handled now. */
261269

262270
OVS_LOG_TRACE("Exit: OvsDetach Successfully");

0 commit comments

Comments
 (0)