From patchwork Mon May 8 22:38:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yin Lin X-Patchwork-Id: 759833 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wMHV70rWdz9s4s for ; Tue, 9 May 2017 08:38:55 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id E25DEB75; Mon, 8 May 2017 22:38:51 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id C22305AA for ; Mon, 8 May 2017 22:38:50 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from EX13-EDG-OU-002.vmware.com (ex13-edg-ou-002.vmware.com [208.91.0.190]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 6D411155 for ; Mon, 8 May 2017 22:38:49 +0000 (UTC) Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX13-EDG-OU-002.vmware.com (10.113.208.156) with Microsoft SMTP Server id 15.0.1156.6; Mon, 8 May 2017 15:38:15 -0700 Received: from linyi-win10.vmware.com (htb-1s-eng-dhcp177.eng.vmware.com [10.33.78.177]) by sc9-mailhost3.vmware.com (Postfix) with ESMTP id 3143F404B2; Mon, 8 May 2017 15:38:48 -0700 (PDT) From: Yin Lin To: Date: Mon, 8 May 2017 15:38:42 -0700 Message-ID: <20170508223845.5580-1-linyi@vmware.com> X-Mailer: git-send-email 2.10.2.windows.1 MIME-Version: 1.0 Received-SPF: None (EX13-EDG-OU-002.vmware.com: linyi@vmware.com does not designate permitted sender hosts) X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Yin Lin Subject: [ovs-dev] [PATCH v6 1/4] datapath-windows: Add support for NAT in conntrack X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Anand Kumar Add support for parsing netlink attributes related to NAT in conntrack. Co-Authored-by: Anand Kumar Co-Authored-by: Darrell Ball Signed-off-by: Yin Lin --- 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 *) ¤tTime); + /* 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]));