* [dpdk-dev] [PATCH v2 1/2] ethdev: add L2TPv3 over IP header to flow API @ 2019-12-16 10:15 Rory Sexton 2019-12-16 10:15 ` [dpdk-dev] [PATCH v2 2/2] net/i40e: support FDIR for L2TPv3 over IP Rory Sexton 0 siblings, 1 reply; 4+ messages in thread From: Rory Sexton @ 2019-12-16 10:15 UTC (permalink / raw) To: dev, orika, adrien.mazarguil, beilei.xing, qi.z.zhang Cc: Rory Sexton, Dariusz Jagus This patch adds the new flow item RTE_FLOW_ITEM_TYPE_L2TPV3OIP to flow API to match a L2TPv3 over IP header. This patch supports only L2TPv3 over IP header format which is different to L2TPv2/L2TPv3 over UDP. The difference in header formats between L2TPv3 over IP and L2TP over UDP require a separate implementation for each. Signed-off-by: Rory Sexton <rory.sexton@intel.com> Signed-off-by: Dariusz Jagus <dariuszx.jagus@intel.com> --- app/test-pmd/cmdline_flow.c | 33 ++++++++++++++++++++++++++++++ doc/guides/prog_guide/rte_flow.rst | 8 ++++++++ lib/librte_ethdev/rte_flow.c | 1 + lib/librte_ethdev/rte_flow.h | 29 +++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 1 deletion(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 99dade7d8..72a792d93 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -213,6 +213,8 @@ enum index { ITEM_TAG, ITEM_TAG_DATA, ITEM_TAG_INDEX, + ITEM_L2TPV3OIP, + ITEM_L2TPV3OIP_SESSION_ID, /* Validate/create actions. */ ACTIONS, @@ -746,6 +748,7 @@ static const enum index next_item[] = { ITEM_PPPOE_PROTO_ID, ITEM_HIGIG2, ITEM_TAG, + ITEM_L2TPV3OIP, END_SET, ZERO, }; @@ -1030,6 +1033,12 @@ static const enum index item_tag[] = { ZERO, }; +static const enum index item_l2tpv3oip[] = { + ITEM_L2TPV3OIP_SESSION_ID, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -2593,6 +2602,22 @@ static const struct token token_list[] = { NEXT_ENTRY(ITEM_PARAM_IS)), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_tag, index)), }, + [ITEM_L2TPV3OIP] = { + .name = "l2tpv3oip", + .help = "match L2TPv3 over IP header", + .priv = PRIV_ITEM(L2TPV3OIP, + sizeof(struct rte_flow_item_l2tpv3oip)), + .next = NEXT(item_l2tpv3oip), + .call = parse_vc, + }, + [ITEM_L2TPV3OIP_SESSION_ID] = { + .name = "session_id", + .help = "session identifier", + .next = NEXT(item_l2tpv3oip, NEXT_ENTRY(UNSIGNED), item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv3oip, + session_id)), + }, + /* Validate/create actions. */ [ACTIONS] = { .name = "actions", @@ -6238,6 +6263,10 @@ flow_item_default_mask(const struct rte_flow_item *item) break; case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID: mask = &rte_flow_item_pppoe_proto_id_mask; + break; + case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: + mask = &rte_flow_item_l2tpv3oip_mask; + break; default: break; } @@ -6327,6 +6356,10 @@ cmd_set_raw_parsed(const struct buffer *in) case RTE_FLOW_ITEM_TYPE_GENEVE: size = sizeof(struct rte_flow_item_geneve); break; + case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: + size = sizeof(struct rte_flow_item_l2tpv3oip); + proto = 0x73; + break; default: printf("Error - Not supported item\n"); *total_size = 0; diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index a254c81ef..d4cef4621 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1336,6 +1336,14 @@ Broadcom switches. - Default ``mask`` matches classification and vlan. +Item: ``L2TPV3OIP`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Matches a L2TPv3 over IP header. + +- ``session_id``: L2TPv3 over IP session identifier. +- Default ``mask`` matches session_id only. + Actions ~~~~~~~ diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c index 87a3e8c4c..4d130be77 100644 --- a/lib/librte_ethdev/rte_flow.c +++ b/lib/librte_ethdev/rte_flow.c @@ -93,6 +93,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = { MK_FLOW_ITEM(IGMP, sizeof(struct rte_flow_item_igmp)), MK_FLOW_ITEM(AH, sizeof(struct rte_flow_item_ah)), MK_FLOW_ITEM(HIGIG2, sizeof(struct rte_flow_item_higig2_hdr)), + MK_FLOW_ITEM(L2TPV3OIP, sizeof(struct rte_flow_item_l2tpv3oip)), }; /** Generate flow_action[] entry. */ diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h index 452d359a1..8c7f6c12a 100644 --- a/lib/librte_ethdev/rte_flow.h +++ b/lib/librte_ethdev/rte_flow.h @@ -502,7 +502,7 @@ enum rte_flow_item_type { */ RTE_FLOW_ITEM_TYPE_HIGIG2, - /* + /** * [META] * * Matches a tag value. @@ -510,6 +510,16 @@ enum rte_flow_item_type { * See struct rte_flow_item_tag. */ RTE_FLOW_ITEM_TYPE_TAG, + + /** + * Matches a L2TPv3 over IP header. + * + * Configure flow for L2TPv3 over IP packets. + * + * See struct rte_flow_item_l2tpv3oip. + */ + RTE_FLOW_ITEM_TYPE_L2TPV3OIP, + }; /** @@ -1373,6 +1383,23 @@ static const struct rte_flow_item_tag rte_flow_item_tag_mask = { }; #endif +/** + * RTE_FLOW_ITEM_TYPE_L2TPV3OIP. + * + * Matches a L2TPv3 over IP header. + */ +struct rte_flow_item_l2tpv3oip { + rte_be32_t session_id; /**< Session ID. */ +}; + +/** Default mask for RTE_FLOW_ITEM_TYPE_L2TPV3OIP. */ +#ifndef __cplusplus +static const struct rte_flow_item_l2tpv3oip rte_flow_item_l2tpv3oip_mask = { + .session_id = RTE_BE32(UINT32_MAX), +}; +#endif + + /** * @warning * @b EXPERIMENTAL: this structure may change without prior notice -- 2.17.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [dpdk-dev] [PATCH v2 2/2] net/i40e: support FDIR for L2TPv3 over IP 2019-12-16 10:15 [dpdk-dev] [PATCH v2 1/2] ethdev: add L2TPv3 over IP header to flow API Rory Sexton @ 2019-12-16 10:15 ` Rory Sexton 2019-12-25 3:12 ` Xing, Beilei 0 siblings, 1 reply; 4+ messages in thread From: Rory Sexton @ 2019-12-16 10:15 UTC (permalink / raw) To: dev, orika, adrien.mazarguil, beilei.xing, qi.z.zhang Cc: Rory Sexton, Dariusz Jagus Adding FDIR support for L2TPv3 over IP header matching and adding a new customized pctype for l2tpv3 over IP. Signed-off-by: Rory Sexton <rory.sexton@intel.com> Signed-off-by: Dariusz Jagus <dariuszx.jagus@intel.com> --- doc/guides/testpmd_app_ug/testpmd_funcs.rst | 4 ++ drivers/net/i40e/i40e_ethdev.c | 11 +++- drivers/net/i40e/i40e_ethdev.h | 48 ++++++++++++----- drivers/net/i40e/i40e_fdir.c | 40 +++++++++++++-- drivers/net/i40e/i40e_flow.c | 57 +++++++++++++++++++++ 5 files changed, 141 insertions(+), 19 deletions(-) diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 73ef0b41d..5e6935829 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3954,6 +3954,10 @@ This section lists supported pattern items and their attributes, if any. - ``proto_id {unsigned}``: PPP protocol identifier. +- ``l2tpv3oip``: match L2TPv3 over IP header. + + - ``session_id {unsigned}``: L2TPv3 over IP session identifier. + Actions list ^^^^^^^^^^^^ diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 5999c964b..80a46916c 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -12351,6 +12351,14 @@ i40e_update_customized_pctype(struct rte_eth_dev *dev, uint8_t *pkg, new_pctype = i40e_find_customized_pctype(pf, I40E_CUSTOMIZED_GTPU); + else if (!strcmp(name, "IPV4_L2TPV3")) + new_pctype = + i40e_find_customized_pctype(pf, + I40E_CUSTOMIZED_IPV4_L2TPV3); + else if (!strcmp(name, "IPV6_L2TPV3")) + new_pctype = + i40e_find_customized_pctype(pf, + I40E_CUSTOMIZED_IPV6_L2TPV3); if (new_pctype) { if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) { new_pctype->pctype = pctype_value; @@ -12544,7 +12552,8 @@ i40e_update_customized_ptype(struct rte_eth_dev *dev, uint8_t *pkg, RTE_PTYPE_TUNNEL_GRENAT; in_tunnel = true; } else if (!strncasecmp(name, "L2TPV2CTL", 9) || - !strncasecmp(name, "L2TPV2", 6)) { + !strncasecmp(name, "L2TPV2", 6) || + !strncasecmp(name, "L2TPV3", 6)) { ptype_mapping[i].sw_ptype |= RTE_PTYPE_TUNNEL_L2TP; in_tunnel = true; diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 295ad593b..5b6d43556 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -508,24 +508,43 @@ struct i40e_raw_flow { uint32_t length; }; +/* A structure used to define the input for L2TPv3 over IP flow */ +struct i40e_l2tpv3oip_flow { + uint32_t session_id; /* Session ID in big endian. */ +}; + +/* A structure used to define the input for L2TPv3 over IPv4 flow */ +struct i40e_ipv4_l2tpv3oip_flow { + struct rte_eth_ipv4_flow ip4; + uint32_t session_id; /* Session ID in big endian. */ +}; + +/* A structure used to define the input for L2TPv3 over IPv6 flow */ +struct i40e_ipv6_l2tpv3oip_flow { + struct rte_eth_ipv6_flow ip6; + uint32_t session_id; /* Session ID in big endian. */ +}; + /* * A union contains the inputs for all types of flow * items in flows need to be in big endian */ union i40e_fdir_flow { - struct rte_eth_l2_flow l2_flow; - struct rte_eth_udpv4_flow udp4_flow; - struct rte_eth_tcpv4_flow tcp4_flow; - struct rte_eth_sctpv4_flow sctp4_flow; - struct rte_eth_ipv4_flow ip4_flow; - struct rte_eth_udpv6_flow udp6_flow; - struct rte_eth_tcpv6_flow tcp6_flow; - struct rte_eth_sctpv6_flow sctp6_flow; - struct rte_eth_ipv6_flow ipv6_flow; - struct i40e_gtp_flow gtp_flow; - struct i40e_gtp_ipv4_flow gtp_ipv4_flow; - struct i40e_gtp_ipv6_flow gtp_ipv6_flow; - struct i40e_raw_flow raw_flow; + struct rte_eth_l2_flow l2_flow; + struct rte_eth_udpv4_flow udp4_flow; + struct rte_eth_tcpv4_flow tcp4_flow; + struct rte_eth_sctpv4_flow sctp4_flow; + struct rte_eth_ipv4_flow ip4_flow; + struct rte_eth_udpv6_flow udp6_flow; + struct rte_eth_tcpv6_flow tcp6_flow; + struct rte_eth_sctpv6_flow sctp6_flow; + struct rte_eth_ipv6_flow ipv6_flow; + struct i40e_gtp_flow gtp_flow; + struct i40e_gtp_ipv4_flow gtp_ipv4_flow; + struct i40e_gtp_ipv6_flow gtp_ipv6_flow; + struct i40e_raw_flow raw_flow; + struct i40e_ipv4_l2tpv3oip_flow ip6_l2tpv3oip_flow; + struct i40e_ipv6_l2tpv3oip_flow ip4_l2tpv3oip_flow; }; enum i40e_fdir_ip_type { @@ -542,6 +561,7 @@ struct i40e_fdir_flow_ext { uint16_t dst_id; /* VF ID, available when is_vf is 1*/ bool inner_ip; /* If there is inner ip */ enum i40e_fdir_ip_type iip_type; /* ip type for inner ip */ + enum i40e_fdir_ip_type oip_type; /* ip type for outer ip */ bool customized_pctype; /* If customized pctype is used */ bool pkt_template; /* If raw packet template is used */ }; @@ -897,6 +917,8 @@ enum i40e_new_pctype { I40E_CUSTOMIZED_GTPU_IPV4, I40E_CUSTOMIZED_GTPU_IPV6, I40E_CUSTOMIZED_GTPU, + I40E_CUSTOMIZED_IPV4_L2TPV3, + I40E_CUSTOMIZED_IPV6_L2TPV3, I40E_CUSTOMIZED_MAX, }; diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index dee007daa..2fc099517 100644 --- a/drivers/net/i40e/i40e_fdir.c +++ b/drivers/net/i40e/i40e_fdir.c @@ -33,6 +33,10 @@ #define IPV6_ADDR_LEN 16 #endif +#ifndef IPPROTO_L2TP +#define IPPROTO_L2TP 115 +#endif + #define I40E_FDIR_PKT_LEN 512 #define I40E_FDIR_IP_DEFAULT_LEN 420 #define I40E_FDIR_IP_DEFAULT_TTL 0x40 @@ -1026,7 +1030,12 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP || pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER || pctype == I40E_FILTER_PCTYPE_FRAG_IPV4 || - is_customized_pctype) { + ((is_customized_pctype) && + ((cus_pctype->index == I40E_CUSTOMIZED_GTPC) || + (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4) || + (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6) || + (cus_pctype->index == I40E_CUSTOMIZED_GTPU) || + (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3)))) { ip = (struct rte_ipv4_hdr *)raw_pkt; *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); @@ -1054,12 +1063,16 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 || cus_pctype->index == I40E_CUSTOMIZED_GTPU) ip->next_proto_id = IPPROTO_UDP; + else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3) + ip->next_proto_id = IPPROTO_L2TP; len += sizeof(struct rte_ipv4_hdr); } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP || pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP || pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP || pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || - pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) { + pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 || + ((is_customized_pctype) && + (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3))) { ip6 = (struct rte_ipv6_hdr *)raw_pkt; *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); @@ -1069,9 +1082,12 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, I40E_FDIR_IPv6_TC_OFFSET)); ip6->payload_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN); - ip6->proto = fdir_input->flow.ipv6_flow.proto ? - fdir_input->flow.ipv6_flow.proto : - next_proto[fdir_input->pctype]; + if (!is_customized_pctype) + ip6->proto = fdir_input->flow.ipv6_flow.proto ? + fdir_input->flow.ipv6_flow.proto : + next_proto[fdir_input->pctype]; + else if (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3) + ip6->proto = IPPROTO_L2TP; ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ? fdir_input->flow.ipv6_flow.hop_limits : I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS; @@ -1115,6 +1131,7 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, struct rte_flow_item_gtp *gtp; struct rte_ipv4_hdr *gtp_ipv4; struct rte_ipv6_hdr *gtp_ipv6; + struct rte_flow_item_l2tpv3oip *l2tpv3oip; uint8_t size, dst = 0; uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/ int len; @@ -1285,6 +1302,19 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, } else payload = (unsigned char *)gtp + sizeof(struct rte_flow_item_gtp); + } else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3 || + cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3) { + l2tpv3oip = (struct rte_flow_item_l2tpv3oip *)(raw_pkt + + len); + + if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3) + l2tpv3oip->session_id = + fdir_input->flow.ip4_l2tpv3oip_flow.session_id; + else + l2tpv3oip->session_id = + fdir_input->flow.ip6_l2tpv3oip_flow.session_id; + payload = (unsigned char *)l2tpv3oip + + sizeof(struct rte_flow_item_l2tpv3oip); } } else { PMD_DRV_LOG(ERR, "unknown pctype %u.", diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 61021037c..9cb28532e 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -1615,6 +1615,20 @@ static enum rte_flow_item_type pattern_qinq_1[] = { RTE_FLOW_ITEM_TYPE_END, }; +static enum rte_flow_item_type pattern_fdir_ipv4_l2tpv3oip[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_L2TPV3OIP, + RTE_FLOW_ITEM_TYPE_END, +}; + +static enum rte_flow_item_type pattern_fdir_ipv6_l2tpv3oip[] = { + RTE_FLOW_ITEM_TYPE_ETH, + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_L2TPV3OIP, + RTE_FLOW_ITEM_TYPE_END, +}; + static struct i40e_valid_pattern i40e_supported_patterns[] = { /* Ethertype */ { pattern_ethertype, i40e_flow_parse_ethertype_filter }, @@ -1795,6 +1809,9 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = { { pattern_fdir_ipv6_gtpu, i40e_flow_parse_gtp_filter }, /* QINQ */ { pattern_qinq_1, i40e_flow_parse_qinq_filter }, + /* L2TPv3 over IP */ + { pattern_fdir_ipv4_l2tpv3oip, i40e_flow_parse_fdir_filter }, + { pattern_fdir_ipv6_l2tpv3oip, i40e_flow_parse_fdir_filter }, }; #define NEXT_ITEM_OF_ACTION(act, actions, index) \ @@ -2420,6 +2437,15 @@ i40e_flow_fdir_get_pctype_value(struct i40e_pf *pf, cus_pctype = i40e_find_customized_pctype(pf, I40E_CUSTOMIZED_GTPU_IPV6); break; + case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: + if (filter->input.flow_ext.oip_type == I40E_FDIR_IPTYPE_IPV4) + cus_pctype = i40e_find_customized_pctype(pf, + I40E_CUSTOMIZED_IPV4_L2TPV3); + else if (filter->input.flow_ext.oip_type == + I40E_FDIR_IPTYPE_IPV6) + cus_pctype = i40e_find_customized_pctype(pf, + I40E_CUSTOMIZED_IPV6_L2TPV3); + break; default: PMD_DRV_LOG(ERR, "Unsupported item type"); break; @@ -2461,6 +2487,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, const struct rte_flow_item_gtp *gtp_spec, *gtp_mask; const struct rte_flow_item_raw *raw_spec, *raw_mask; const struct rte_flow_item_vf *vf_spec; + const struct rte_flow_item_l2tpv3oip *l2tpv3oip_spec, *l2tpv3oip_mask; uint8_t pctype = 0; uint64_t input_set = I40E_INSET_NONE; @@ -3012,6 +3039,36 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, return -rte_errno; } break; + case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: + l2tpv3oip_spec = item->spec; + l2tpv3oip_mask = item->mask; + + if (!l2tpv3oip_spec || !l2tpv3oip_mask) + break; + + if (l2tpv3oip_mask->session_id != UINT32_MAX) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid L2TPv3 mask"); + return -rte_errno; + } + + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { + filter->input.flow.ip4_l2tpv3oip_flow.session_id + = l2tpv3oip_spec->session_id; + filter->input.flow_ext.oip_type = + I40E_FDIR_IPTYPE_IPV4; + } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { + filter->input.flow.ip6_l2tpv3oip_flow.session_id + = l2tpv3oip_spec->session_id; + filter->input.flow_ext.oip_type = + I40E_FDIR_IPTYPE_IPV6; + } + + filter->input.flow_ext.customized_pctype = true; + cus_proto = item_type; + break; default: break; } -- 2.17.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [dpdk-dev] [PATCH v2 2/2] net/i40e: support FDIR for L2TPv3 over IP 2019-12-16 10:15 ` [dpdk-dev] [PATCH v2 2/2] net/i40e: support FDIR for L2TPv3 over IP Rory Sexton @ 2019-12-25 3:12 ` Xing, Beilei 2020-01-07 15:25 ` Sexton, Rory 0 siblings, 1 reply; 4+ messages in thread From: Xing, Beilei @ 2019-12-25 3:12 UTC (permalink / raw) To: Sexton, Rory, dev, orika, adrien.mazarguil, Zhang, Qi Z; +Cc: Jagus, DariuszX > -----Original Message----- > From: Sexton, Rory > Sent: Monday, December 16, 2019 6:15 PM > To: dev@dpdk.org; orika@mellanox.com; adrien.mazarguil@6wind.com; Xing, > Beilei <beilei.xing@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com> > Cc: Sexton, Rory <rory.sexton@intel.com>; Jagus, DariuszX > <dariuszx.jagus@intel.com> > Subject: [PATCH v2 2/2] net/i40e: support FDIR for L2TPv3 over IP > > Adding FDIR support for L2TPv3 over IP header matching and adding a new > customized pctype for l2tpv3 over IP. > > Signed-off-by: Rory Sexton <rory.sexton@intel.com> > Signed-off-by: Dariusz Jagus <dariuszx.jagus@intel.com> > --- Version change is needed here. > doc/guides/testpmd_app_ug/testpmd_funcs.rst | 4 ++ > drivers/net/i40e/i40e_ethdev.c | 11 +++- > drivers/net/i40e/i40e_ethdev.h | 48 ++++++++++++----- > drivers/net/i40e/i40e_fdir.c | 40 +++++++++++++-- > drivers/net/i40e/i40e_flow.c | 57 +++++++++++++++++++++ > 5 files changed, 141 insertions(+), 19 deletions(-) > > diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > index 73ef0b41d..5e6935829 100644 > --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > @@ -3954,6 +3954,10 @@ This section lists supported pattern items and their > attributes, if any. > > - ``proto_id {unsigned}``: PPP protocol identifier. > > +- ``l2tpv3oip``: match L2TPv3 over IP header. > + > + - ``session_id {unsigned}``: L2TPv3 over IP session identifier. > + It should not be a part of this patch, which is focus on i40e PMD. > Actions list > ^^^^^^^^^^^^ > > diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c > index 5999c964b..80a46916c 100644 > --- a/drivers/net/i40e/i40e_ethdev.c > +++ b/drivers/net/i40e/i40e_ethdev.c > @@ -12351,6 +12351,14 @@ i40e_update_customized_pctype(struct > rte_eth_dev *dev, uint8_t *pkg, > new_pctype = > i40e_find_customized_pctype(pf, > I40E_CUSTOMIZED_GTPU); > + else if (!strcmp(name, "IPV4_L2TPV3")) > + new_pctype = > + i40e_find_customized_pctype(pf, > + > I40E_CUSTOMIZED_IPV4_L2TPV3); > + else if (!strcmp(name, "IPV6_L2TPV3")) > + new_pctype = > + i40e_find_customized_pctype(pf, > + > I40E_CUSTOMIZED_IPV6_L2TPV3); > if (new_pctype) { > if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) { > new_pctype->pctype = pctype_value; > @@ -12544,7 +12552,8 @@ i40e_update_customized_ptype(struct > rte_eth_dev *dev, uint8_t *pkg, > RTE_PTYPE_TUNNEL_GRENAT; > in_tunnel = true; > } else if (!strncasecmp(name, "L2TPV2CTL", 9) > || > - !strncasecmp(name, "L2TPV2", 6)) { > + !strncasecmp(name, "L2TPV2", 6) || > + !strncasecmp(name, "L2TPV3", 6)) { > ptype_mapping[i].sw_ptype |= > RTE_PTYPE_TUNNEL_L2TP; > in_tunnel = true; > diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h > index 295ad593b..5b6d43556 100644 > --- a/drivers/net/i40e/i40e_ethdev.h > +++ b/drivers/net/i40e/i40e_ethdev.h > @@ -508,24 +508,43 @@ struct i40e_raw_flow { > uint32_t length; > }; > > +/* A structure used to define the input for L2TPv3 over IP flow */ > +struct i40e_l2tpv3oip_flow { > + uint32_t session_id; /* Session ID in big endian. */ }; Is this structure needed? > + > +/* A structure used to define the input for L2TPv3 over IPv4 flow */ > +struct i40e_ipv4_l2tpv3oip_flow { > + struct rte_eth_ipv4_flow ip4; > + uint32_t session_id; /* Session ID in big endian. */ }; > + > +/* A structure used to define the input for L2TPv3 over IPv6 flow */ > +struct i40e_ipv6_l2tpv3oip_flow { > + struct rte_eth_ipv6_flow ip6; > + uint32_t session_id; /* Session ID in big endian. */ }; > + > /* > * A union contains the inputs for all types of flow > * items in flows need to be in big endian > */ > union i40e_fdir_flow { > - struct rte_eth_l2_flow l2_flow; > - struct rte_eth_udpv4_flow udp4_flow; > - struct rte_eth_tcpv4_flow tcp4_flow; > - struct rte_eth_sctpv4_flow sctp4_flow; > - struct rte_eth_ipv4_flow ip4_flow; > - struct rte_eth_udpv6_flow udp6_flow; > - struct rte_eth_tcpv6_flow tcp6_flow; > - struct rte_eth_sctpv6_flow sctp6_flow; > - struct rte_eth_ipv6_flow ipv6_flow; > - struct i40e_gtp_flow gtp_flow; > - struct i40e_gtp_ipv4_flow gtp_ipv4_flow; > - struct i40e_gtp_ipv6_flow gtp_ipv6_flow; > - struct i40e_raw_flow raw_flow; > + struct rte_eth_l2_flow l2_flow; > + struct rte_eth_udpv4_flow udp4_flow; > + struct rte_eth_tcpv4_flow tcp4_flow; > + struct rte_eth_sctpv4_flow sctp4_flow; > + struct rte_eth_ipv4_flow ip4_flow; > + struct rte_eth_udpv6_flow udp6_flow; > + struct rte_eth_tcpv6_flow tcp6_flow; > + struct rte_eth_sctpv6_flow sctp6_flow; > + struct rte_eth_ipv6_flow ipv6_flow; > + struct i40e_gtp_flow gtp_flow; > + struct i40e_gtp_ipv4_flow gtp_ipv4_flow; > + struct i40e_gtp_ipv6_flow gtp_ipv6_flow; > + struct i40e_raw_flow raw_flow; > + struct i40e_ipv4_l2tpv3oip_flow ip6_l2tpv3oip_flow; > + struct i40e_ipv6_l2tpv3oip_flow ip4_l2tpv3oip_flow; > }; > > enum i40e_fdir_ip_type { > @@ -542,6 +561,7 @@ struct i40e_fdir_flow_ext { > uint16_t dst_id; /* VF ID, available when is_vf is 1*/ > bool inner_ip; /* If there is inner ip */ > enum i40e_fdir_ip_type iip_type; /* ip type for inner ip */ > + enum i40e_fdir_ip_type oip_type; /* ip type for outer ip */ > bool customized_pctype; /* If customized pctype is used */ > bool pkt_template; /* If raw packet template is used */ }; @@ -897,6 > +917,8 @@ enum i40e_new_pctype { > I40E_CUSTOMIZED_GTPU_IPV4, > I40E_CUSTOMIZED_GTPU_IPV6, > I40E_CUSTOMIZED_GTPU, > + I40E_CUSTOMIZED_IPV4_L2TPV3, > + I40E_CUSTOMIZED_IPV6_L2TPV3, > I40E_CUSTOMIZED_MAX, > }; > > diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c index > dee007daa..2fc099517 100644 > --- a/drivers/net/i40e/i40e_fdir.c > +++ b/drivers/net/i40e/i40e_fdir.c > @@ -33,6 +33,10 @@ > #define IPV6_ADDR_LEN 16 > #endif > > +#ifndef IPPROTO_L2TP > +#define IPPROTO_L2TP 115 > +#endif > + > #define I40E_FDIR_PKT_LEN 512 > #define I40E_FDIR_IP_DEFAULT_LEN 420 > #define I40E_FDIR_IP_DEFAULT_TTL 0x40 > @@ -1026,7 +1030,12 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, > pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP || > pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER || > pctype == I40E_FILTER_PCTYPE_FRAG_IPV4 || > - is_customized_pctype) { > + ((is_customized_pctype) && > + ((cus_pctype->index == I40E_CUSTOMIZED_GTPC) || > + (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4) || > + (cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6) || > + (cus_pctype->index == I40E_CUSTOMIZED_GTPU) || > + (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3)))) { > ip = (struct rte_ipv4_hdr *)raw_pkt; > > *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); > @@ -1054,12 +1063,16 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, > cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 > || > cus_pctype->index == I40E_CUSTOMIZED_GTPU) > ip->next_proto_id = IPPROTO_UDP; > + else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3) > + ip->next_proto_id = IPPROTO_L2TP; > len += sizeof(struct rte_ipv4_hdr); > } else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP || > pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP || > pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP || > pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER || > - pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) { > + pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 || > + ((is_customized_pctype) && > + (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3))) { > ip6 = (struct rte_ipv6_hdr *)raw_pkt; > > *ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV6); > @@ -1069,9 +1082,12 @@ i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf, > I40E_FDIR_IPv6_TC_OFFSET)); > ip6->payload_len = > rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN); > - ip6->proto = fdir_input->flow.ipv6_flow.proto ? > - fdir_input->flow.ipv6_flow.proto : > - next_proto[fdir_input->pctype]; > + if (!is_customized_pctype) > + ip6->proto = fdir_input->flow.ipv6_flow.proto ? > + fdir_input->flow.ipv6_flow.proto : > + next_proto[fdir_input->pctype]; > + else if (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3) > + ip6->proto = IPPROTO_L2TP; > ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ? > fdir_input->flow.ipv6_flow.hop_limits : > I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS; > @@ -1115,6 +1131,7 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, > struct rte_flow_item_gtp *gtp; > struct rte_ipv4_hdr *gtp_ipv4; > struct rte_ipv6_hdr *gtp_ipv6; > + struct rte_flow_item_l2tpv3oip *l2tpv3oip; > uint8_t size, dst = 0; > uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/ > int len; > @@ -1285,6 +1302,19 @@ i40e_flow_fdir_construct_pkt(struct i40e_pf *pf, > } else > payload = (unsigned char *)gtp + > sizeof(struct rte_flow_item_gtp); > + } else if (cus_pctype->index == > I40E_CUSTOMIZED_IPV4_L2TPV3 || > + cus_pctype->index == > I40E_CUSTOMIZED_IPV6_L2TPV3) { > + l2tpv3oip = (struct rte_flow_item_l2tpv3oip > *)(raw_pkt > + + len); > + > + if (cus_pctype->index == > I40E_CUSTOMIZED_IPV4_L2TPV3) > + l2tpv3oip->session_id = > + fdir_input- > >flow.ip4_l2tpv3oip_flow.session_id; > + else > + l2tpv3oip->session_id = > + fdir_input- > >flow.ip6_l2tpv3oip_flow.session_id; > + payload = (unsigned char *)l2tpv3oip + > + sizeof(struct rte_flow_item_l2tpv3oip); > } > } else { > PMD_DRV_LOG(ERR, "unknown pctype %u.", diff --git > a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index > 61021037c..9cb28532e 100644 > --- a/drivers/net/i40e/i40e_flow.c > +++ b/drivers/net/i40e/i40e_flow.c > @@ -1615,6 +1615,20 @@ static enum rte_flow_item_type pattern_qinq_1[] = > { > RTE_FLOW_ITEM_TYPE_END, > }; > > +static enum rte_flow_item_type pattern_fdir_ipv4_l2tpv3oip[] = { > + RTE_FLOW_ITEM_TYPE_ETH, > + RTE_FLOW_ITEM_TYPE_IPV4, > + RTE_FLOW_ITEM_TYPE_L2TPV3OIP, > + RTE_FLOW_ITEM_TYPE_END, > +}; > + > +static enum rte_flow_item_type pattern_fdir_ipv6_l2tpv3oip[] = { > + RTE_FLOW_ITEM_TYPE_ETH, > + RTE_FLOW_ITEM_TYPE_IPV6, > + RTE_FLOW_ITEM_TYPE_L2TPV3OIP, > + RTE_FLOW_ITEM_TYPE_END, > +}; > + > static struct i40e_valid_pattern i40e_supported_patterns[] = { > /* Ethertype */ > { pattern_ethertype, i40e_flow_parse_ethertype_filter }, @@ -1795,6 > +1809,9 @@ static struct i40e_valid_pattern i40e_supported_patterns[] = { > { pattern_fdir_ipv6_gtpu, i40e_flow_parse_gtp_filter }, > /* QINQ */ > { pattern_qinq_1, i40e_flow_parse_qinq_filter }, > + /* L2TPv3 over IP */ > + { pattern_fdir_ipv4_l2tpv3oip, i40e_flow_parse_fdir_filter }, > + { pattern_fdir_ipv6_l2tpv3oip, i40e_flow_parse_fdir_filter }, > }; > > #define NEXT_ITEM_OF_ACTION(act, actions, index) \ > @@ -2420,6 +2437,15 @@ i40e_flow_fdir_get_pctype_value(struct i40e_pf > *pf, > cus_pctype = i40e_find_customized_pctype(pf, > > I40E_CUSTOMIZED_GTPU_IPV6); > break; > + case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: > + if (filter->input.flow_ext.oip_type == I40E_FDIR_IPTYPE_IPV4) > + cus_pctype = i40e_find_customized_pctype(pf, > + > I40E_CUSTOMIZED_IPV4_L2TPV3); > + else if (filter->input.flow_ext.oip_type == > + I40E_FDIR_IPTYPE_IPV6) > + cus_pctype = i40e_find_customized_pctype(pf, > + > I40E_CUSTOMIZED_IPV6_L2TPV3); > + break; > default: > PMD_DRV_LOG(ERR, "Unsupported item type"); > break; > @@ -2461,6 +2487,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev > *dev, > const struct rte_flow_item_gtp *gtp_spec, *gtp_mask; > const struct rte_flow_item_raw *raw_spec, *raw_mask; > const struct rte_flow_item_vf *vf_spec; > + const struct rte_flow_item_l2tpv3oip *l2tpv3oip_spec, > *l2tpv3oip_mask; > > uint8_t pctype = 0; > uint64_t input_set = I40E_INSET_NONE; > @@ -3012,6 +3039,36 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev > *dev, > return -rte_errno; > } > break; > + case RTE_FLOW_ITEM_TYPE_L2TPV3OIP: > + l2tpv3oip_spec = item->spec; > + l2tpv3oip_mask = item->mask; > + > + if (!l2tpv3oip_spec || !l2tpv3oip_mask) > + break; > + > + if (l2tpv3oip_mask->session_id != UINT32_MAX) { > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ITEM, > + item, > + "Invalid L2TPv3 mask"); > + return -rte_errno; > + } > + > + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) { > + filter- > >input.flow.ip4_l2tpv3oip_flow.session_id > + = l2tpv3oip_spec->session_id; > + filter->input.flow_ext.oip_type = > + I40E_FDIR_IPTYPE_IPV4; > + } else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) { > + filter- > >input.flow.ip6_l2tpv3oip_flow.session_id > + = l2tpv3oip_spec->session_id; > + filter->input.flow_ext.oip_type = > + I40E_FDIR_IPTYPE_IPV6; > + } > + > + filter->input.flow_ext.customized_pctype = true; > + cus_proto = item_type; > + break; > default: > break; > } > -- > 2.17.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [dpdk-dev] [PATCH v2 2/2] net/i40e: support FDIR for L2TPv3 over IP 2019-12-25 3:12 ` Xing, Beilei @ 2020-01-07 15:25 ` Sexton, Rory 0 siblings, 0 replies; 4+ messages in thread From: Sexton, Rory @ 2020-01-07 15:25 UTC (permalink / raw) To: Xing, Beilei, dev, orika, adrien.mazarguil, Zhang, Qi Z; +Cc: Jagus, DariuszX Hi Beilei, I have resolved all comments below in v3 of patch. Rory > > Adding FDIR support for L2TPv3 over IP header matching and adding a > > new customized pctype for l2tpv3 over IP. > > > > Signed-off-by: Rory Sexton <rory.sexton@intel.com> > > Signed-off-by: Dariusz Jagus <dariuszx.jagus@intel.com> > > --- > > Version change is needed here. > Thanks for noting, will fix this. Just getting familiar with the mailing list process. > > diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > > b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > > index 73ef0b41d..5e6935829 100644 > > --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst > > +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst > > @@ -3954,6 +3954,10 @@ This section lists supported pattern items and > > their attributes, if any. > > > > - ``proto_id {unsigned}``: PPP protocol identifier. > > > > +- ``l2tpv3oip``: match L2TPv3 over IP header. > > + > > + - ``session_id {unsigned}``: L2TPv3 over IP session identifier. > > + > > It should not be a part of this patch, which is focus on i40e PMD. > Good point. Moving this change to separate patch where testpmd changes are applied. > > diff --git a/drivers/net/i40e/i40e_ethdev.h > > b/drivers/net/i40e/i40e_ethdev.h index 295ad593b..5b6d43556 100644 > > --- a/drivers/net/i40e/i40e_ethdev.h > > +++ b/drivers/net/i40e/i40e_ethdev.h > > @@ -508,24 +508,43 @@ struct i40e_raw_flow { > > uint32_t length; > > }; > > > > +/* A structure used to define the input for L2TPv3 over IP flow */ > > +struct i40e_l2tpv3oip_flow { > > + uint32_t session_id; /* Session ID in big endian. */ }; > > Is this structure needed? > This is unused so will remove it. ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-01-07 15:25 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2019-12-16 10:15 [dpdk-dev] [PATCH v2 1/2] ethdev: add L2TPv3 over IP header to flow API Rory Sexton 2019-12-16 10:15 ` [dpdk-dev] [PATCH v2 2/2] net/i40e: support FDIR for L2TPv3 over IP Rory Sexton 2019-12-25 3:12 ` Xing, Beilei 2020-01-07 15:25 ` Sexton, Rory
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).