common/cnxk: fix IPv6 extension header parsing
PATCH 1/1 common/cnxk: fix IPv6 extension header parsing
From: Satheesh Paul <[email protected]>
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")
Signed-off-by Satheesh Paul <[email protected]>
Reviewed-by Kiran Kumar K <[email protected]>
--- 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(-)
drivers/common/cnxk/roc_npc.h +11 -0
@@ -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 ;
drivers/common/cnxk/roc_npc_parse.c +109 -41
182 lines not on this page · raw message
drivers/common/cnxk/roc_npc_priv.h +1 -1
@@ -466,7 +466,7 @@ int npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alluint64_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);
drivers/common/cnxk/roc_npc_utils.c +2 -2
@@ -384,7 +384,7 @@ npc_hash_field_get(struct npc_xtract_info *xinfo, const struct roc_npc_flow_itemint 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];
Signature · 1 line
2.35.3
Jerin Jacob
AppliedQuoted 7 lines · On Wed, Feb 22, 2023 at 9:35 AM <[email protected]> wrote:
From: Satheesh Paul <[email protected]>
RTE_FLOW_ITEM_TYPE_IPV6_EXTandRTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXTpattern items can be specified following aRTE_FLOW_ITEM_TYPE_IPV6. Modified layer C parsing logic to handle this.
Quoted 5 lines
Fixes a800675b06f9 ("net/cnxk: support IPv6 fragment flow pattern item")Signed-off-by Satheesh Paul <[email protected]>Reviewed-by Kiran Kumar K <[email protected]>
Applied to dpdk-next-net-mrvl/for-next-net. Thanks
Quoted 256 lines
--- 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(-)drivers/common/cnxk/roc_npc.h +11
-0@@ -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 ;drivers/common/cnxk/roc_npc_parse.c +109
-41@@ -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 ;drivers/common/cnxk/roc_npc_priv.h +1
-1@@ -466,7 +466,7 @@ int npc_program_mcam(struct npc *npc, struct npc_parse_state *pst, bool mcam_alluint64_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);drivers/common/cnxk/roc_npc_utils.c +2
-3@@ -384,7 +384,7 @@ npc_hash_field_get(struct npc_xtract_info *xinfo, const struct roc_npc_flow_itemint 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