diff mbox

[ovs-dev,v7,1/4] datapath-windows: Add support for NAT in conntrack

Message ID 20170509225950.9404-1-linyi@vmware.com
State Changes Requested
Headers show

Commit Message

Yin Lin May 9, 2017, 10:59 p.m. UTC
From: Anand Kumar <kumaranand@vmware.com>

Add support for parsing netlink attributes related to NAT
in conntrack.

Co-Authored-by: Anand Kumar <kumaranand@vmware.com>
Co-Authored-by: Darrell Ball <dlu998@gmail.com>
Signed-off-by: Yin Lin <linyi@vmware.com>
---
 datapath-windows/ovsext/Conntrack.c | 73 ++++++++++++++++++++++++++++++++++++-
 datapath-windows/ovsext/Conntrack.h | 17 +++++++++
 datapath-windows/ovsext/Flow.c      |  4 +-
 3 files changed, 90 insertions(+), 4 deletions(-)

Comments

Sairam Venugopal May 16, 2017, 9:37 p.m. UTC | #1
Not sure why the "From: Anand Kumar <kumaranand@vmware.com>” shows up in the commit description.

Since they are already listed as co-author, it should be safe to remove this.

Acked-by: Sairam Venugopal <vsairam@vmware.com>







On 5/9/17, 3:59 PM, "ovs-dev-bounces@openvswitch.org on behalf of Yin Lin" <ovs-dev-bounces@openvswitch.org on behalf of linyi@vmware.com> wrote:

>From: Anand Kumar <kumaranand@vmware.com>

>

>Add support for parsing netlink attributes related to NAT

>in conntrack.

>

>Co-Authored-by: Anand Kumar <kumaranand@vmware.com>

>Co-Authored-by: Darrell Ball <dlu998@gmail.com>

>Signed-off-by: Yin Lin <linyi@vmware.com>

>---

> datapath-windows/ovsext/Conntrack.c | 73 ++++++++++++++++++++++++++++++++++++-

> datapath-windows/ovsext/Conntrack.h | 17 +++++++++

> datapath-windows/ovsext/Flow.c      |  4 +-

> 3 files changed, 90 insertions(+), 4 deletions(-)

>

>diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c

>index dce0c1b..9824368 100644

>--- a/datapath-windows/ovsext/Conntrack.c

>+++ b/datapath-windows/ovsext/Conntrack.c

>@@ -645,7 +645,8 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,

>               UINT16 zone,

>               MD_MARK *mark,

>               MD_LABELS *labels,

>-              PCHAR helper)

>+              PCHAR helper,

>+              PNAT_ACTION_INFO natInfo)

> {

>     NDIS_STATUS status = NDIS_STATUS_SUCCESS;

>     POVS_CT_ENTRY entry = NULL;

>@@ -654,6 +655,9 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,

>     UINT64 currentTime;

>     NdisGetCurrentSystemTime((LARGE_INTEGER *) &currentTime);

> 

>+    /* XXX: Not referenced for now */

>+    UNREFERENCED_PARAMETER(natInfo);

>+

>     /* Retrieve the Conntrack Key related fields from packet */

>     OvsCtSetupLookupCtx(key, zone, &ctx, curNbl, layers->l4Offset);

> 

>@@ -730,11 +734,14 @@ OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,

>     MD_MARK *mark = NULL;

>     MD_LABELS *labels = NULL;

>     PCHAR helper = NULL;

>+    NAT_ACTION_INFO natActionInfo;

>     PNET_BUFFER_LIST curNbl = fwdCtx->curNbl;

>     OVS_PACKET_HDR_INFO *layers = &fwdCtx->layers;

>     PNET_BUFFER_LIST newNbl = NULL;

>+    NAT_ACTION_INFO natActionInfo;

>     NDIS_STATUS status;

> 

>+    memset(&natActionInfo, 0, sizeof natActionInfo);

>     status = OvsDetectCtPacket(fwdCtx, key, &newNbl);

>     if (status != NDIS_STATUS_SUCCESS) {

>         return status;

>@@ -757,6 +764,68 @@ OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,

>     if (ctAttr) {

>         labels = NlAttrGet(ctAttr);

>     }

>+    natActionInfo.natAction = NAT_ACTION_NONE;

>+    ctAttr = NlAttrFindNested(a, OVS_CT_ATTR_NAT);

>+    if (ctAttr) {

>+        /* Pares Nested NAT attributes. */

>+        PNL_ATTR natAttr;

>+        unsigned int left;

>+        BOOLEAN hasMinIp = FALSE;

>+        BOOLEAN hasMinPort = FALSE;

>+        BOOLEAN hasMaxIp = FALSE;

>+        BOOLEAN hasMaxPort = FALSE;

>+        NL_NESTED_FOR_EACH_UNSAFE (natAttr, left, ctAttr) {

>+            enum ovs_nat_attr sub_type_nest = NlAttrType(natAttr);

>+            switch(sub_type_nest) {

>+            case OVS_NAT_ATTR_SRC:

>+            case OVS_NAT_ATTR_DST:

>+                natActionInfo.natAction |=

>+                    ((sub_type_nest == OVS_NAT_ATTR_SRC)

>+                        ? NAT_ACTION_SRC : NAT_ACTION_DST);

>+                break;

>+            case OVS_NAT_ATTR_IP_MIN:

>+                memcpy(&natActionInfo.minAddr,

>+                       NlAttrData(natAttr), natAttr->nlaLen - NLA_HDRLEN);

>+                hasMinIp = TRUE;

>+                break;

>+            case OVS_NAT_ATTR_IP_MAX:

>+                memcpy(&natActionInfo.maxAddr,

>+                       NlAttrData(natAttr), natAttr->nlaLen - NLA_HDRLEN);

>+                hasMaxIp = TRUE;

>+                break;

>+            case OVS_NAT_ATTR_PROTO_MIN:

>+                natActionInfo.minPort = NlAttrGetU16(natAttr);

>+                hasMinPort = TRUE;

>+                break;

>+            case OVS_NAT_ATTR_PROTO_MAX:

>+                natActionInfo.maxPort = NlAttrGetU16(natAttr);

>+                hasMaxPort = TRUE;

>+                break;

>+            case OVS_NAT_ATTR_PERSISTENT:

>+            case OVS_NAT_ATTR_PROTO_HASH:

>+            case OVS_NAT_ATTR_PROTO_RANDOM:

>+                break;

>+            }

>+        }

>+        if (natActionInfo.natAction == NAT_ACTION_NONE) {

>+            natActionInfo.natAction = NAT_ACTION_REVERSE;

>+        }

>+        if (hasMinIp && !hasMaxIp) {

>+            memcpy(&natActionInfo.maxAddr,

>+                   &natActionInfo.minAddr,

>+                   sizeof(natActionInfo.maxAddr));

>+        }

>+        if (hasMinPort && !hasMaxPort) {

>+            natActionInfo.maxPort = natActionInfo.minPort;

>+        }

>+        if (hasMinPort || hasMaxPort) {

>+            if (natActionInfo.natAction & NAT_ACTION_SRC) {

>+                natActionInfo.natAction |= NAT_ACTION_SRC_PORT;

>+            } else if (natActionInfo.natAction & NAT_ACTION_DST) {

>+                natActionInfo.natAction |= NAT_ACTION_DST_PORT;

>+            }

>+        }

>+    }

>     ctAttr = NlAttrFindNested(a, OVS_CT_ATTR_HELPER);

>     if (ctAttr) {

>         helper = NlAttrGetString(ctAttr);

>@@ -776,7 +845,7 @@ OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,

>     }

>     /* If newNbl is not allocated, use the current Nbl*/

>     status = OvsCtExecute_(newNbl != NULL ? newNbl : curNbl, key, layers,

>-                           commit, force, zone, mark, labels, helper);

>+                           commit, force, zone, mark, labels, helper, &natActionInfo);

>     return status;

> }

> 

>diff --git a/datapath-windows/ovsext/Conntrack.h b/datapath-windows/ovsext/Conntrack.h

>index 87d7eeb..1ad289f 100644

>--- a/datapath-windows/ovsext/Conntrack.h

>+++ b/datapath-windows/ovsext/Conntrack.h

>@@ -68,6 +68,15 @@ typedef struct MD_LABELS {

>     struct ovs_key_ct_labels mask;

> } MD_LABELS;

> 

>+typedef enum NAT_ACTION {

>+    NAT_ACTION_NONE = 0,

>+    NAT_ACTION_REVERSE = 1 << 0,

>+    NAT_ACTION_SRC = 1 << 1,

>+    NAT_ACTION_SRC_PORT = 1 << 2,

>+    NAT_ACTION_DST = 1 << 3,

>+    NAT_ACTION_DST_PORT = 1 << 4,

>+};

>+

> typedef struct _OVS_CT_KEY {

>     struct ct_endpoint src;

>     struct ct_endpoint dst;

>@@ -110,6 +119,14 @@ typedef struct OvsConntrackKeyLookupCtx {

>     BOOLEAN         related;

> } OvsConntrackKeyLookupCtx;

> 

>+typedef struct _NAT_ACTION_INFO {

>+    struct ct_addr minAddr;

>+    struct ct_addr maxAddr;

>+    uint16_t minPort;

>+    uint16_t maxPort;

>+    uint16_t natAction;

>+} NAT_ACTION_INFO, *PNAT_ACTION_INFO;

>+

> #define CT_HASH_TABLE_SIZE ((UINT32)1 << 10)

> #define CT_HASH_TABLE_MASK (CT_HASH_TABLE_SIZE - 1)

> #define CT_INTERVAL_SEC 10000000LL //1s

>diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c

>index 96ff9fa..4396cee 100644

>--- a/datapath-windows/ovsext/Flow.c

>+++ b/datapath-windows/ovsext/Flow.c

>@@ -3086,9 +3086,9 @@ OvsProbeSupportedFeature(POVS_MESSAGE msgIn,

>         }

>     } else if (keyAttrs[OVS_KEY_ATTR_CT_STATE]) {

>         UINT32 state = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_CT_STATE]);

>-        if (state & OVS_CS_F_DST_NAT || state & OVS_CS_F_SRC_NAT) {

>+        if (!state) {

>             status = STATUS_INVALID_PARAMETER;

>-            OVS_LOG_ERROR("Contrack NAT is not supported:%d", state);

>+            OVS_LOG_ERROR("Invalid state specified.");

>         }

>     } else if (keyAttrs[OVS_KEY_ATTR_CT_ZONE]) {

>         UINT16 zone = (NlAttrGetU16(keyAttrs[OVS_KEY_ATTR_CT_ZONE]));

>-- 

>2.10.2.windows.1

>

>_______________________________________________

>dev mailing list

>dev@openvswitch.org

>https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff mbox

Patch

diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
index dce0c1b..9824368 100644
--- a/datapath-windows/ovsext/Conntrack.c
+++ b/datapath-windows/ovsext/Conntrack.c
@@ -645,7 +645,8 @@  OvsCtExecute_(PNET_BUFFER_LIST curNbl,
               UINT16 zone,
               MD_MARK *mark,
               MD_LABELS *labels,
-              PCHAR helper)
+              PCHAR helper,
+              PNAT_ACTION_INFO natInfo)
 {
     NDIS_STATUS status = NDIS_STATUS_SUCCESS;
     POVS_CT_ENTRY entry = NULL;
@@ -654,6 +655,9 @@  OvsCtExecute_(PNET_BUFFER_LIST curNbl,
     UINT64 currentTime;
     NdisGetCurrentSystemTime((LARGE_INTEGER *) &currentTime);
 
+    /* XXX: Not referenced for now */
+    UNREFERENCED_PARAMETER(natInfo);
+
     /* Retrieve the Conntrack Key related fields from packet */
     OvsCtSetupLookupCtx(key, zone, &ctx, curNbl, layers->l4Offset);
 
@@ -730,11 +734,14 @@  OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,
     MD_MARK *mark = NULL;
     MD_LABELS *labels = NULL;
     PCHAR helper = NULL;
+    NAT_ACTION_INFO natActionInfo;
     PNET_BUFFER_LIST curNbl = fwdCtx->curNbl;
     OVS_PACKET_HDR_INFO *layers = &fwdCtx->layers;
     PNET_BUFFER_LIST newNbl = NULL;
+    NAT_ACTION_INFO natActionInfo;
     NDIS_STATUS status;
 
+    memset(&natActionInfo, 0, sizeof natActionInfo);
     status = OvsDetectCtPacket(fwdCtx, key, &newNbl);
     if (status != NDIS_STATUS_SUCCESS) {
         return status;
@@ -757,6 +764,68 @@  OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,
     if (ctAttr) {
         labels = NlAttrGet(ctAttr);
     }
+    natActionInfo.natAction = NAT_ACTION_NONE;
+    ctAttr = NlAttrFindNested(a, OVS_CT_ATTR_NAT);
+    if (ctAttr) {
+        /* Pares Nested NAT attributes. */
+        PNL_ATTR natAttr;
+        unsigned int left;
+        BOOLEAN hasMinIp = FALSE;
+        BOOLEAN hasMinPort = FALSE;
+        BOOLEAN hasMaxIp = FALSE;
+        BOOLEAN hasMaxPort = FALSE;
+        NL_NESTED_FOR_EACH_UNSAFE (natAttr, left, ctAttr) {
+            enum ovs_nat_attr sub_type_nest = NlAttrType(natAttr);
+            switch(sub_type_nest) {
+            case OVS_NAT_ATTR_SRC:
+            case OVS_NAT_ATTR_DST:
+                natActionInfo.natAction |=
+                    ((sub_type_nest == OVS_NAT_ATTR_SRC)
+                        ? NAT_ACTION_SRC : NAT_ACTION_DST);
+                break;
+            case OVS_NAT_ATTR_IP_MIN:
+                memcpy(&natActionInfo.minAddr,
+                       NlAttrData(natAttr), natAttr->nlaLen - NLA_HDRLEN);
+                hasMinIp = TRUE;
+                break;
+            case OVS_NAT_ATTR_IP_MAX:
+                memcpy(&natActionInfo.maxAddr,
+                       NlAttrData(natAttr), natAttr->nlaLen - NLA_HDRLEN);
+                hasMaxIp = TRUE;
+                break;
+            case OVS_NAT_ATTR_PROTO_MIN:
+                natActionInfo.minPort = NlAttrGetU16(natAttr);
+                hasMinPort = TRUE;
+                break;
+            case OVS_NAT_ATTR_PROTO_MAX:
+                natActionInfo.maxPort = NlAttrGetU16(natAttr);
+                hasMaxPort = TRUE;
+                break;
+            case OVS_NAT_ATTR_PERSISTENT:
+            case OVS_NAT_ATTR_PROTO_HASH:
+            case OVS_NAT_ATTR_PROTO_RANDOM:
+                break;
+            }
+        }
+        if (natActionInfo.natAction == NAT_ACTION_NONE) {
+            natActionInfo.natAction = NAT_ACTION_REVERSE;
+        }
+        if (hasMinIp && !hasMaxIp) {
+            memcpy(&natActionInfo.maxAddr,
+                   &natActionInfo.minAddr,
+                   sizeof(natActionInfo.maxAddr));
+        }
+        if (hasMinPort && !hasMaxPort) {
+            natActionInfo.maxPort = natActionInfo.minPort;
+        }
+        if (hasMinPort || hasMaxPort) {
+            if (natActionInfo.natAction & NAT_ACTION_SRC) {
+                natActionInfo.natAction |= NAT_ACTION_SRC_PORT;
+            } else if (natActionInfo.natAction & NAT_ACTION_DST) {
+                natActionInfo.natAction |= NAT_ACTION_DST_PORT;
+            }
+        }
+    }
     ctAttr = NlAttrFindNested(a, OVS_CT_ATTR_HELPER);
     if (ctAttr) {
         helper = NlAttrGetString(ctAttr);
@@ -776,7 +845,7 @@  OvsExecuteConntrackAction(OvsForwardingContext *fwdCtx,
     }
     /* If newNbl is not allocated, use the current Nbl*/
     status = OvsCtExecute_(newNbl != NULL ? newNbl : curNbl, key, layers,
-                           commit, force, zone, mark, labels, helper);
+                           commit, force, zone, mark, labels, helper, &natActionInfo);
     return status;
 }
 
diff --git a/datapath-windows/ovsext/Conntrack.h b/datapath-windows/ovsext/Conntrack.h
index 87d7eeb..1ad289f 100644
--- a/datapath-windows/ovsext/Conntrack.h
+++ b/datapath-windows/ovsext/Conntrack.h
@@ -68,6 +68,15 @@  typedef struct MD_LABELS {
     struct ovs_key_ct_labels mask;
 } MD_LABELS;
 
+typedef enum NAT_ACTION {
+    NAT_ACTION_NONE = 0,
+    NAT_ACTION_REVERSE = 1 << 0,
+    NAT_ACTION_SRC = 1 << 1,
+    NAT_ACTION_SRC_PORT = 1 << 2,
+    NAT_ACTION_DST = 1 << 3,
+    NAT_ACTION_DST_PORT = 1 << 4,
+};
+
 typedef struct _OVS_CT_KEY {
     struct ct_endpoint src;
     struct ct_endpoint dst;
@@ -110,6 +119,14 @@  typedef struct OvsConntrackKeyLookupCtx {
     BOOLEAN         related;
 } OvsConntrackKeyLookupCtx;
 
+typedef struct _NAT_ACTION_INFO {
+    struct ct_addr minAddr;
+    struct ct_addr maxAddr;
+    uint16_t minPort;
+    uint16_t maxPort;
+    uint16_t natAction;
+} NAT_ACTION_INFO, *PNAT_ACTION_INFO;
+
 #define CT_HASH_TABLE_SIZE ((UINT32)1 << 10)
 #define CT_HASH_TABLE_MASK (CT_HASH_TABLE_SIZE - 1)
 #define CT_INTERVAL_SEC 10000000LL //1s
diff --git a/datapath-windows/ovsext/Flow.c b/datapath-windows/ovsext/Flow.c
index 96ff9fa..4396cee 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -3086,9 +3086,9 @@  OvsProbeSupportedFeature(POVS_MESSAGE msgIn,
         }
     } else if (keyAttrs[OVS_KEY_ATTR_CT_STATE]) {
         UINT32 state = NlAttrGetU32(keyAttrs[OVS_KEY_ATTR_CT_STATE]);
-        if (state & OVS_CS_F_DST_NAT || state & OVS_CS_F_SRC_NAT) {
+        if (!state) {
             status = STATUS_INVALID_PARAMETER;
-            OVS_LOG_ERROR("Contrack NAT is not supported:%d", state);
+            OVS_LOG_ERROR("Invalid state specified.");
         }
     } else if (keyAttrs[OVS_KEY_ATTR_CT_ZONE]) {
         UINT16 zone = (NlAttrGetU16(keyAttrs[OVS_KEY_ATTR_CT_ZONE]));