summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datapath-windows/ovsext/Conntrack.c61
-rw-r--r--datapath-windows/ovsext/Conntrack.h8
-rw-r--r--datapath-windows/ovsext/Netlink/Netlink.c16
-rw-r--r--datapath-windows/ovsext/Netlink/Netlink.h1
-rw-r--r--datapath-windows/ovsext/Switch.c8
5 files changed, 92 insertions, 2 deletions
diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
index 70c32a48f..53d2cf922 100644
--- a/datapath-windows/ovsext/Conntrack.c
+++ b/datapath-windows/ovsext/Conntrack.c
@@ -192,11 +192,21 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl,
}
state |= OVS_CS_F_NEW;
+ POVS_CT_ENTRY parentEntry = NULL;
+ parentEntry = OvsCtRelatedLookup(ctx->key, currentTime);
+ if (parentEntry != NULL) {
+ state |= OVS_CS_F_RELATED;
+ }
+
if (commit) {
entry = OvsConntrackCreateTcpEntry(tcp, curNbl, currentTime);
if (!entry) {
return NULL;
}
+ /* If this is related entry, then update parent */
+ if (parentEntry != NULL) {
+ entry->parent = parentEntry;
+ }
OvsCtAddEntry(entry, ctx, currentTime);
}
@@ -492,6 +502,13 @@ OvsCtSetupLookupCtx(OvsFlowKey *flowKey,
return NDIS_STATUS_SUCCESS;
}
+static __inline BOOLEAN
+OvsDetectFtpPacket(OvsFlowKey *key) {
+ return (key->ipKey.nwProto == IPPROTO_TCP &&
+ (ntohs(key->ipKey.l4.tpDst) == IPPORT_FTP ||
+ ntohs(key->ipKey.l4.tpSrc) == IPPORT_FTP));
+}
+
/*
*----------------------------------------------------------------------------
* OvsProcessConntrackEntry
@@ -542,6 +559,21 @@ OvsProcessConntrackEntry(PNET_BUFFER_LIST curNbl,
break;
}
}
+
+ if (key->ipKey.nwProto == IPPROTO_TCP && entry) {
+ /* Update the related bit if there is a parent */
+ if (entry->parent) {
+ state |= OVS_CS_F_RELATED;
+ } else {
+ POVS_CT_ENTRY parentEntry;
+ parentEntry = OvsCtRelatedLookup(ctx->key, currentTime);
+ if (parentEntry != NULL) {
+ entry->parent = parentEntry;
+ state |= OVS_CS_F_RELATED;
+ }
+ }
+ }
+
/* Copy mark and label from entry into flowKey. If actions specify
different mark and label, update the flowKey. */
if (entry != NULL) {
@@ -592,7 +624,8 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
BOOLEAN commit,
UINT16 zone,
MD_MARK *mark,
- MD_LABELS *labels)
+ MD_LABELS *labels,
+ PCHAR helper)
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
POVS_CT_ENTRY entry = NULL;
@@ -629,6 +662,17 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
OvsConntrackSetLabels(key, entry, &labels->value, &labels->mask);
}
+ if (entry && 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) {
+ OVS_LOG_ERROR("Error while parsing the FTP packet");
+ }
+ }
+
NdisReleaseRWLock(ovsConntrackLockObj, &lockState);
return status;
@@ -651,6 +695,8 @@ OvsExecuteConntrackAction(PNET_BUFFER_LIST curNbl,
UINT16 zone = 0;
MD_MARK *mark = NULL;
MD_LABELS *labels = NULL;
+ PCHAR helper = NULL;
+
NDIS_STATUS status;
status = OvsDetectCtPacket(key);
@@ -674,9 +720,20 @@ OvsExecuteConntrackAction(PNET_BUFFER_LIST curNbl,
if (ctAttr) {
labels = NlAttrGet(ctAttr);
}
+ ctAttr = NlAttrFindNested(a, OVS_CT_ATTR_HELPER);
+ if (ctAttr) {
+ helper = NlAttrGetString(ctAttr);
+ if (helper == NULL) {
+ return NDIS_STATUS_INVALID_PARAMETER;
+ }
+ if (strcmp("ftp", helper) != 0) {
+ /* Only support FTP */
+ return NDIS_STATUS_NOT_SUPPORTED;
+ }
+ }
status = OvsCtExecute_(curNbl, key, layers,
- commit, zone, mark, labels);
+ commit, zone, mark, labels, helper);
return status;
}
diff --git a/datapath-windows/ovsext/Conntrack.h b/datapath-windows/ovsext/Conntrack.h
index 7f1ec6f52..af9988510 100644
--- a/datapath-windows/ovsext/Conntrack.h
+++ b/datapath-windows/ovsext/Conntrack.h
@@ -85,6 +85,7 @@ typedef struct OVS_CT_ENTRY {
UINT32 mark;
UINT64 timestampStart;
struct ovs_key_ct_labels labels;
+ PVOID parent; /* Points to main connection */
} OVS_CT_ENTRY, *POVS_CT_ENTRY;
typedef struct OVS_CT_REL_ENTRY {
@@ -200,4 +201,11 @@ NDIS_STATUS OvsCtRelatedEntryCreate(UINT8 ipProto,
POVS_CT_ENTRY parent);
POVS_CT_ENTRY OvsCtRelatedLookup(OVS_CT_KEY key, UINT64 currentTime);
+NDIS_STATUS OvsCtHandleFtp(PNET_BUFFER_LIST curNbl,
+ OvsFlowKey *key,
+ OVS_PACKET_HDR_INFO *layers,
+ UINT64 currentTime,
+ POVS_CT_ENTRY entry,
+ BOOLEAN request);
+
#endif /* __OVS_CONNTRACK_H_ */
diff --git a/datapath-windows/ovsext/Netlink/Netlink.c b/datapath-windows/ovsext/Netlink/Netlink.c
index 24322053c..a63f06623 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.c
+++ b/datapath-windows/ovsext/Netlink/Netlink.c
@@ -992,6 +992,22 @@ NlAttrGetU64(const PNL_ATTR nla)
/*
* ---------------------------------------------------------------------------
+ * Returns the string value in 'nla''s payload.
+ * Returns NULL if it is not a proper '\0' terminated string.
+ * ---------------------------------------------------------------------------
+ */
+PCHAR
+NlAttrGetString(const PNL_ATTR nla)
+{
+ ASSERT(nla->nlaLen >= NLA_HDRLEN);
+ if (!memchr(NlAttrGet(nla), '\0', nla->nlaLen - NLA_HDRLEN)) {
+ return NULL;
+ }
+ return NlAttrGet(nla);
+}
+
+/*
+ * ---------------------------------------------------------------------------
* Validate the netlink attribute against the policy
* ---------------------------------------------------------------------------
*/
diff --git a/datapath-windows/ovsext/Netlink/Netlink.h b/datapath-windows/ovsext/Netlink/Netlink.h
index 363f57501..964c0e5f5 100644
--- a/datapath-windows/ovsext/Netlink/Netlink.h
+++ b/datapath-windows/ovsext/Netlink/Netlink.h
@@ -138,6 +138,7 @@ UINT8 NlAttrGetU8(const PNL_ATTR nla);
UINT16 NlAttrGetU16(const PNL_ATTR nla);
UINT32 NlAttrGetU32(const PNL_ATTR nla);
UINT64 NlAttrGetU64(const PNL_ATTR nla);
+PCHAR NlAttrGetString(const PNL_ATTR nla);
const PNL_ATTR NlAttrFind__(const PNL_ATTR attrs,
UINT32 size, UINT16 type);
const PNL_ATTR NlAttrFindNested(const PNL_ATTR nla,
diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c
index db023e987..138a656ce 100644
--- a/datapath-windows/ovsext/Switch.c
+++ b/datapath-windows/ovsext/Switch.c
@@ -225,6 +225,13 @@ OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle,
goto create_switch_done;
}
+ status = OvsInitCtRelated(switchContext);
+ if (status != STATUS_SUCCESS) {
+ OvsUninitSwitchContext(switchContext);
+ OVS_LOG_ERROR("Exit: Failed to initialize Connection tracking");
+ goto create_switch_done;
+ }
+
*switchContextOut = switchContext;
create_switch_done:
@@ -257,6 +264,7 @@ OvsExtDetach(NDIS_HANDLE filterModuleContext)
OvsCleanupIpHelper();
OvsCleanupSttDefragmentation();
OvsCleanupConntrack();
+ OvsCleanupCtRelated();
/* This completes the cleanup, and a new attach can be handled now. */
OVS_LOG_TRACE("Exit: OvsDetach Successfully");