Message ID | 20170609221607.100932-1-linyi@vmware.com |
---|---|
State | Accepted |
Headers | show |
On 9 June 2017 at 15:16, Yin Lin <linyi@vmware.com> wrote: > From: Anand Kumar <kumaranand@vmware.com> > > Add support for parsing netlink attributes related to NAT > in conntrack. > > Co-Authored-by: Yin Lin <linyi@vmware.com> > Co-Authored-by: Darrell Ball <dlu998@gmail.com> > Signed-off-by: Anand Kumar <kumaranand@vmware.com> > Signed-off-by: Yin Lin <linyi@vmware.com> > Signed-off-by: Darrell Ball <dlu998@gmail.com> > Thanks. I applied the series. In the future, please include any Acked-by's when you re-spin a series. > --- > 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 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev >
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]));