[ovs-dev] [PATCH v9 1/4] datapath-windows: Add support for NAT in conntrack
Yin Lin
linyi at vmware.com
Fri Jun 9 22:16:04 UTC 2017
From: Anand Kumar <kumaranand at vmware.com>
Add support for parsing netlink attributes related to NAT
in conntrack.
Co-Authored-by: Yin Lin <linyi at vmware.com>
Co-Authored-by: Darrell Ball <dlu998 at gmail.com>
Signed-off-by: Anand Kumar <kumaranand at vmware.com>
Signed-off-by: Yin Lin <linyi at vmware.com>
Signed-off-by: Darrell Ball <dlu998 at gmail.com>
---
datapath-windows/ovsext/Conntrack.c | 83 ++++++++++++++++++++++++++++++++++++-
datapath-windows/ovsext/Conntrack.h | 17 ++++++++
datapath-windows/ovsext/Flow.c | 4 +-
3 files changed, 100 insertions(+), 4 deletions(-)
diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
index 609ae5a..6b3435c 100644
--- a/datapath-windows/ovsext/Conntrack.c
+++ b/datapath-windows/ovsext/Conntrack.c
@@ -651,7 +651,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;
@@ -660,6 +661,9 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
UINT64 currentTime;
NdisGetCurrentSystemTime((LARGE_INTEGER *) ¤tTime);
+ /* XXX: Not referenced for now */
+ UNREFERENCED_PARAMETER(natInfo);
+
/* Retrieve the Conntrack Key related fields from packet */
OvsCtSetupLookupCtx(key, zone, &ctx, curNbl, layers->l4Offset);
@@ -753,11 +757,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;
@@ -780,6 +787,78 @@ 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:
+ if (natAttr->nlaLen < NLA_HDRLEN) {
+ OVS_LOG_ERROR("Incorrect header length for "
+ "OVS_NAT_ATTR_IP_MIN message.");
+ break;
+ }
+ memcpy(&natActionInfo.minAddr,
+ NlAttrData(natAttr), natAttr->nlaLen - NLA_HDRLEN);
+ hasMinIp = TRUE;
+ break;
+ case OVS_NAT_ATTR_IP_MAX:
+ if (natAttr->nlaLen < NLA_HDRLEN) {
+ OVS_LOG_ERROR("Incorrect header length for "
+ "OVS_NAT_ATTR_IP_MAX message.");
+ break;
+ }
+ 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);
@@ -799,7 +878,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 80f5676..60f9b1c 100644
--- a/datapath-windows/ovsext/Flow.c
+++ b/datapath-windows/ovsext/Flow.c
@@ -3125,9 +3125,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
More information about the dev
mailing list