On Wed, Feb 22, 2023 at 9:35 AM <psathe...@marvell.com> wrote: > > From: Satheesh Paul <psathe...@marvell.com> > > RTE_FLOW_ITEM_TYPE_IPV6_EXT and RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT > pattern items can be specified following a RTE_FLOW_ITEM_TYPE_IPV6. > Modified layer C parsing logic to handle this. > > Fixes: a800675b06f9 ("net/cnxk: support IPv6 fragment flow pattern item") > Cc: sta...@dpdk.org > > Signed-off-by: Satheesh Paul <psathe...@marvell.com> > Reviewed-by: Kiran Kumar K <kirankum...@marvell.com>
Applied to dpdk-next-net-mrvl/for-next-net. Thanks > --- > drivers/common/cnxk/roc_npc.h | 11 ++ > drivers/common/cnxk/roc_npc_parse.c | 150 ++++++++++++++++++++-------- > drivers/common/cnxk/roc_npc_priv.h | 2 +- > drivers/common/cnxk/roc_npc_utils.c | 4 +- > 4 files changed, 123 insertions(+), 44 deletions(-) > > diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h > index cea627e16c..5e07e26a91 100644 > --- a/drivers/common/cnxk/roc_npc.h > +++ b/drivers/common/cnxk/roc_npc.h > @@ -123,6 +123,17 @@ struct roc_ipv6_hdr { > uint8_t dst_addr[16]; /**< IP address of destination host(s). */ > } __plt_packed; > > +struct roc_ipv6_fragment_ext { > + uint8_t next_header; /**< Next header type */ > + uint8_t reserved; /**< Reserved */ > + uint16_t frag_data; /**< All fragmentation data */ > + uint32_t id; /**< Packet ID */ > +} __plt_packed; > + > +struct roc_flow_item_ipv6_ext { > + uint8_t next_hdr; /**< Next header. */ > +}; > + > struct roc_npc_flow_item_ipv6 { > struct roc_ipv6_hdr hdr; /**< IPv6 header definition. */ > uint32_t has_hop_ext : 1; > diff --git a/drivers/common/cnxk/roc_npc_parse.c > b/drivers/common/cnxk/roc_npc_parse.c > index 085fb4618f..f746b9cb6d 100644 > --- a/drivers/common/cnxk/roc_npc_parse.c > +++ b/drivers/common/cnxk/roc_npc_parse.c > @@ -664,41 +664,123 @@ npc_handle_ipv6ext_attr(const struct > roc_npc_flow_item_ipv6 *ipv6_spec, > } > > static int > -npc_process_ipv6_item(const struct roc_npc_flow_item_ipv6 *ipv6_spec, > - const struct roc_npc_flow_item_ipv6 *ipv6_mask, struct > npc_parse_state *pst) > +npc_process_ipv6_item(struct npc_parse_state *pst) > { > - uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN]; > - struct npc_parse_item_info info; > - int rc, lid, lt; > - uint8_t flags = 0; > + uint8_t ipv6_hdr_mask[sizeof(struct roc_ipv6_hdr) + sizeof(struct > roc_ipv6_fragment_ext)]; > + uint8_t ipv6_hdr_buf[sizeof(struct roc_ipv6_hdr) + sizeof(struct > roc_ipv6_fragment_ext)]; > + const struct roc_npc_flow_item_ipv6 *ipv6_spec, *ipv6_mask; > + const struct roc_npc_item_info *pattern = pst->pattern; > + int offset = 0, rc = 0, lid, item_count = 0; > + struct npc_parse_item_info parse_info; > + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; > + uint8_t flags = 0, ltype; > + > + memset(ipv6_hdr_buf, 0, sizeof(ipv6_hdr_buf)); > + memset(ipv6_hdr_mask, 0, sizeof(ipv6_hdr_mask)); > + > + ipv6_spec = pst->pattern->spec; > + ipv6_mask = pst->pattern->mask; > + > + parse_info.def_mask = NULL; > + parse_info.spec = ipv6_hdr_buf; > + parse_info.mask = ipv6_hdr_mask; > + parse_info.def_mask = NULL; > + parse_info.hw_hdr_len = 0; > + parse_info.len = sizeof(ipv6_spec->hdr); > + > + pst->set_ipv6ext_ltype_mask = true; > > - info.def_mask = NULL; > - info.hw_mask = &hw_mask; > - info.spec = NULL; > - info.mask = NULL; > - info.hw_hdr_len = 0; > lid = NPC_LID_LC; > + ltype = NPC_LT_LC_IP6; > + > + if (pattern->type == ROC_NPC_ITEM_TYPE_IPV6) { > + item_count++; > + if (ipv6_spec) { > + memcpy(ipv6_hdr_buf, &ipv6_spec->hdr, sizeof(struct > roc_ipv6_hdr)); > + rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags); > + if (rc) > + return rc; > + } > + if (ipv6_mask) > + memcpy(ipv6_hdr_mask, &ipv6_mask->hdr, sizeof(struct > roc_ipv6_hdr)); > + } > > - lt = NPC_LT_LC_IP6; > - if (ipv6_spec) { > - rc = npc_handle_ipv6ext_attr(ipv6_spec, pst, &flags); > - if (rc) > - return rc; > + offset = sizeof(struct roc_ipv6_hdr); > + > + while (pattern->type != ROC_NPC_ITEM_TYPE_END) { > + /* Don't support ranges */ > + if (pattern->last != NULL) > + return NPC_ERR_INVALID_RANGE; > + > + /* If spec is NULL, both mask and last must be NULL, this > + * makes it to match ANY value (eq to mask = 0). > + * Setting either mask or last without spec is > + * an error > + */ > + if (pattern->spec == NULL) { > + if (pattern->last != NULL && pattern->mask != NULL) > + return NPC_ERR_INVALID_SPEC; > + } > + /* Either one ROC_NPC_ITEM_TYPE_IPV6_EXT or > + * one ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT is supported > + * following an ROC_NPC_ITEM_TYPE_IPV6 item. > + */ > + if (pattern->type == ROC_NPC_ITEM_TYPE_IPV6_EXT) { > + item_count++; > + ltype = NPC_LT_LC_IP6_EXT; > + parse_info.len = > + sizeof(struct roc_ipv6_hdr) + sizeof(struct > roc_flow_item_ipv6_ext); > + if (pattern->spec) > + memcpy(ipv6_hdr_buf + offset, pattern->spec, > + sizeof(struct roc_flow_item_ipv6_ext)); > + if (pattern->mask) > + memcpy(ipv6_hdr_mask + offset, pattern->mask, > + sizeof(struct roc_flow_item_ipv6_ext)); > + break; > + } else if (pattern->type == ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT) { > + item_count++; > + ltype = NPC_LT_LC_IP6_EXT; > + flags = NPC_F_LC_U_IP6_FRAG; > + parse_info.len = > + sizeof(struct roc_ipv6_hdr) + sizeof(struct > roc_ipv6_fragment_ext); > + if (pattern->spec) > + memcpy(ipv6_hdr_buf + offset, pattern->spec, > + sizeof(struct roc_ipv6_fragment_ext)); > + if (pattern->mask) > + memcpy(ipv6_hdr_mask + offset, pattern->mask, > + sizeof(struct roc_ipv6_fragment_ext)); > + > + break; > + } > + > + pattern++; > + pattern = npc_parse_skip_void_and_any_items(pattern); > } > - info.len = sizeof(ipv6_spec->hdr); > > - npc_get_hw_supp_mask(pst, &info, lid, lt); > - rc = npc_parse_item_basic(pst->pattern, &info); > + memset(hw_mask, 0, sizeof(hw_mask)); > > - if (rc != 0) > - return rc; > + parse_info.hw_mask = &hw_mask; > + npc_get_hw_supp_mask(pst, &parse_info, lid, ltype); > + > + rc = npc_mask_is_supported(parse_info.mask, parse_info.hw_mask, > parse_info.len); > + if (!rc) > + return NPC_ERR_INVALID_MASK; > > - rc = npc_update_parse_state(pst, &info, lid, lt, flags); > + rc = npc_update_parse_state(pst, &parse_info, lid, ltype, flags); > if (rc) > return rc; > > - if (pst->npc->hash_extract_cap) > - return npc_process_ipv6_field_hash(ipv6_spec, ipv6_mask, pst); > + if (pst->npc->hash_extract_cap) { > + rc = npc_process_ipv6_field_hash(parse_info.spec, > parse_info.mask, pst, ltype); > + if (rc) > + return rc; > + } > + > + /* npc_update_parse_state() increments pattern once. > + * Check if additional increment is required. > + */ > + if (item_count == 2) > + pst->pattern++; > > return 0; > } > @@ -706,7 +788,6 @@ npc_process_ipv6_item(const struct roc_npc_flow_item_ipv6 > *ipv6_spec, > int > npc_parse_lc(struct npc_parse_state *pst) > { > - const struct roc_npc_flow_item_ipv6 *ipv6_spec, *ipv6_mask; > const struct roc_npc_flow_item_raw *raw_spec; > uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN]; > uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN]; > @@ -731,25 +812,12 @@ npc_parse_lc(struct npc_parse_state *pst) > info.len = pst->pattern->size; > break; > case ROC_NPC_ITEM_TYPE_IPV6: > - ipv6_spec = pst->pattern->spec; > - ipv6_mask = pst->pattern->mask; > - return npc_process_ipv6_item(ipv6_spec, ipv6_mask, pst); > - case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4: > - lt = NPC_LT_LC_ARP; > - info.len = pst->pattern->size; > - break; > case ROC_NPC_ITEM_TYPE_IPV6_EXT: > - lid = NPC_LID_LC; > - lt = NPC_LT_LC_IP6_EXT; > - info.len = pst->pattern->size; > - info.hw_hdr_len = 40; > - break; > case ROC_NPC_ITEM_TYPE_IPV6_FRAG_EXT: > - lid = NPC_LID_LC; > - lt = NPC_LT_LC_IP6_EXT; > - flags = NPC_F_LC_U_IP6_FRAG; > + return npc_process_ipv6_item(pst); > + case ROC_NPC_ITEM_TYPE_ARP_ETH_IPV4: > + lt = NPC_LT_LC_ARP; > info.len = pst->pattern->size; > - info.hw_hdr_len = 40; > break; > case ROC_NPC_ITEM_TYPE_L3_CUSTOM: > lt = NPC_LT_LC_CUSTOM0; > diff --git a/drivers/common/cnxk/roc_npc_priv.h > b/drivers/common/cnxk/roc_npc_priv.h > index 9c21934add..08d763eeb4 100644 > --- a/drivers/common/cnxk/roc_npc_priv.h > +++ b/drivers/common/cnxk/roc_npc_priv.h > @@ -466,7 +466,7 @@ int npc_program_mcam(struct npc *npc, struct > npc_parse_state *pst, bool mcam_all > uint64_t npc_get_kex_capability(struct npc *npc); > int npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 > *ipv6_spec, > const struct roc_npc_flow_item_ipv6 > *ipv6_mask, > - struct npc_parse_state *pst); > + struct npc_parse_state *pst, uint8_t type); > int npc_rss_free_grp_get(struct npc *npc, uint32_t *grp); > int npc_rss_action_configure(struct roc_npc *roc_npc, const struct > roc_npc_action_rss *rss, > uint8_t *alg_idx, uint32_t *rss_grp, uint32_t > mcam_id); > diff --git a/drivers/common/cnxk/roc_npc_utils.c > b/drivers/common/cnxk/roc_npc_utils.c > index f4f9cc0916..a507df994f 100644 > --- a/drivers/common/cnxk/roc_npc_utils.c > +++ b/drivers/common/cnxk/roc_npc_utils.c > @@ -384,7 +384,7 @@ npc_hash_field_get(struct npc_xtract_info *xinfo, const > struct roc_npc_flow_item > int > npc_process_ipv6_field_hash(const struct roc_npc_flow_item_ipv6 *ipv6_spec, > const struct roc_npc_flow_item_ipv6 *ipv6_mask, > - struct npc_parse_state *pst) > + struct npc_parse_state *pst, uint8_t ltype) > { > struct npc_lid_lt_xtract_info *lid_lt_xinfo; > uint8_t hash_field[ROC_IPV6_ADDR_LEN]; > @@ -397,7 +397,7 @@ npc_process_ipv6_field_hash(const struct > roc_npc_flow_item_ipv6 *ipv6_spec, > memset(hash_field, 0, sizeof(hash_field)); > > intf = pst->nix_intf; > - lid_lt_xinfo = &pst->npc->prx_dxcfg[intf][NPC_LID_LC][NPC_LT_LC_IP6]; > + lid_lt_xinfo = &pst->npc->prx_dxcfg[intf][NPC_LID_LC][ltype]; > > for (i = 0; i < NPC_MAX_LD; i++) { > xinfo = &lid_lt_xinfo->xtract[i]; > -- > 2.35.3 >