[ovs-dev] [PATCH v3 4/4] datapath-windows: Conntrack - Enable FTP support

Alin Serdean aserdean at cloudbasesolutions.com
Tue Dec 20 17:09:04 UTC 2016


Acked-by: Alin Gabriel Serdean <aserdean at cloudbasesolutions.com>


> -----Original Message-----
> From: ovs-dev-bounces at openvswitch.org [mailto:ovs-dev-
> bounces at openvswitch.org] On Behalf Of Sairam Venugopal
> Sent: Saturday, December 17, 2016 12:28 AM
> To: dev at openvswitch.org
> Subject: [ovs-dev] [PATCH v3 4/4] 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 at vmware.com>
> ---
>  datapath-windows/ovsext/Conntrack.c       | 61
> ++++++++++++++++++++++++++++++-
>  datapath-windows/ovsext/Conntrack.h       |  8 ++++
>  datapath-windows/ovsext/Netlink/Netlink.c | 16 ++++++++  datapath-
> windows/ovsext/Netlink/Netlink.h |  1 +
>  datapath-windows/ovsext/Switch.c          |  8 ++++
>  5 files changed, 92 insertions(+), 2 deletions(-)
> 
> diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-
> windows/ovsext/Conntrack.c
> index 70c32a4..53d2cf9 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 7f1ec6f..af99885 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 2432205..a63f066 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 363f575..964c0e5 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 db023e9..138a656 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");
> --
> 2.9.0.windows.1
> 
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev


More information about the dev mailing list