> -----Original Message----- > From: Sexton, Rory <rory.sex...@intel.com> > Sent: Wednesday, December 4, 2019 6:11 AM > To: dev@dpdk.org > Cc: Zhang, Qi Z <qi.z.zh...@intel.com>; Xing, Beilei <beilei.x...@intel.com>; > Sexton, Rory <rory.sex...@intel.com>; adrien.mazarg...@6wind.com; Jagus, > DariuszX <dariuszx.ja...@intel.com> > Subject: [PATCH] net/i40e: Add new customized pctype for l2tpv3 It's not only add new customized pctype, but mainly enable FDIR for l2ipv3, so how about " net/i40e: support FDIR for L2TPv3"?
Detailed commit log is also needed. > > Signed-off-by: Rory Sexton <rory.sex...@intel.com> > Signed-off-by: Dariusz Jagus <dariuszx.ja...@intel.com> > --- > drivers/net/i40e/i40e_ethdev.c | 11 ++++++- > drivers/net/i40e/i40e_ethdev.h | 9 ++++++ > drivers/net/i40e/i40e_fdir.c | 34 +++++++++++++++++---- > drivers/net/i40e/i40e_flow.c | 55 > ++++++++++++++++++++++++++++++++++ > 4 files changed, 103 insertions(+), 6 deletions(-) > > 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..569a5a1e5 100644 > --- a/drivers/net/i40e/i40e_ethdev.h > +++ b/drivers/net/i40e/i40e_ethdev.h > @@ -508,6 +508,11 @@ struct i40e_raw_flow { > uint32_t length; > }; > > +/* A structure used to define the input for L2TPv3 flow */ struct > +i40e_l2tpv3_flow { Seems missed struct rte_eth_ipv4_flow or struct rte_eth_ipv6_flow here? > + 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 @@ -526,6 +531,7 @@ union > i40e_fdir_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_l2tpv3_flow l2tpv3_flow; > }; > > enum i40e_fdir_ip_type { > @@ -542,6 +548,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 > +904,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..b18301eec 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_l2tpv3 *l2tpv3; > 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,13 @@ 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) { > + l2tpv3 = (struct rte_flow_item_l2tpv3 *)(raw_pkt + len); > + l2tpv3->session_id = > + fdir_input->flow.l2tpv3_flow.session_id; > + payload = (unsigned char *)l2tpv3 + > + sizeof(struct rte_flow_item_l2tpv3); > } > } 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..2a5d1d0b6 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_l2tpv3[] = { > + RTE_FLOW_ITEM_TYPE_ETH, > + RTE_FLOW_ITEM_TYPE_IPV4, > + RTE_FLOW_ITEM_TYPE_L2TPV3, > + RTE_FLOW_ITEM_TYPE_END, > +}; > + > +static enum rte_flow_item_type pattern_fdir_ipv6_l2tpv3[] = { > + RTE_FLOW_ITEM_TYPE_ETH, > + RTE_FLOW_ITEM_TYPE_IPV6, > + RTE_FLOW_ITEM_TYPE_L2TPV3, > + 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 */ > + { pattern_fdir_ipv4_l2tpv3, i40e_flow_parse_fdir_filter }, > + { pattern_fdir_ipv6_l2tpv3, 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_L2TPV3: > + 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_l2tpv3 *l2tpv3_spec, *l2tpv3_mask; > > uint8_t pctype = 0; > uint64_t input_set = I40E_INSET_NONE; > @@ -3012,6 +3039,34 @@ i40e_flow_parse_fdir_pattern(struct > rte_eth_dev *dev, > return -rte_errno; > } > break; > + case RTE_FLOW_ITEM_TYPE_L2TPV3: > + l2tpv3_spec = item->spec; > + l2tpv3_mask = item->mask; > + > + if (!l2tpv3_spec || !l2tpv3_mask) > + break; > + > + if (l2tpv3_mask->session_id != UINT32_MAX) { > + rte_flow_error_set(error, EINVAL, > + RTE_FLOW_ERROR_TYPE_ITEM, > + item, > + "Invalid L2TPv3 mask"); > + return -rte_errno; > + } > + > + filter->input.flow.l2tpv3_flow.session_id = > + l2tpv3_spec->session_id; > + > + if (l3 == RTE_FLOW_ITEM_TYPE_IPV4) > + filter->input.flow_ext.oip_type = > + I40E_FDIR_IPTYPE_IPV4; > + else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6) > + 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