From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 76DF842383; Wed, 11 Jan 2023 17:58:40 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6983140A7D; Wed, 11 Jan 2023 17:58:40 +0100 (CET) Received: from mail-vk1-f173.google.com (mail-vk1-f173.google.com [209.85.221.173]) by mails.dpdk.org (Postfix) with ESMTP id 271A0400D4; Wed, 11 Jan 2023 17:58:38 +0100 (CET) Received: by mail-vk1-f173.google.com with SMTP id 6so7506887vkz.0; Wed, 11 Jan 2023 08:58:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=76iwXJzCMBpZ09fp1KZ8ddMucTqhsVKwiUm0zcebquU=; b=LdfD4BEYCeVVDc0VCCZniBzO4DsK25hjjpu5UflvJtkCyLFk2Bp5yknX3VvqB+NaE0 wumLe9RRGEfp/FsjsgeKvNeHZSLEmw2yqcpde+60BHcz0ya+PkBSKHsMi7fnnfSFQHpx R71UYlCAQscMOMEZ0mYcJEiEBElpudj8m5S8n4ZsvDyOAQ3LMnI916M7PfoGllau1cEa 89BPgFIEbiYBN2NZtvsTh9sjkwsvGQkJAs6L4IY3iMnlKhgLxRfXA7fRNOKpCh6QPo5R +P8b2XLPpNt+rtb/sWOg2FkhoAAnLLpxpH6droL2I+A8TVj7Tb2tiihuNJvQHczmFg+5 taBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=76iwXJzCMBpZ09fp1KZ8ddMucTqhsVKwiUm0zcebquU=; b=0IN+nbywpCTE6ojjPAVi94xEnZYcx8owcrn8/kqpCRDVkaiinRtQ9og8rM4Smqdm7R k+kgU/uSoholq1Ea9/T79Wd9pUqvXz2arzJIdZcmbQ++rJvw87LxWr9bx4iHW1TvqDkG Z3kayHipXHxhZotcpXOVXexHHtjTnVS3ZnNX3mM9lp8Zh/ql+G7aHY/75bBFS2D9VE9A cqjIPcam62leNGtX0ABwXJgm4sV4ELZeuIgD+I5Pb9pDNehEmQ6dIns6k9rHJpqs7+8f Sr/apI0RcBP2WwO1uBJOQSipMEOnXA59wjHl8po7rGdVe9yoXYF0qYOeIwDv8YecynQe 1WQw== X-Gm-Message-State: AFqh2kpXvxxq2aGo+BzM6fLZLOY02xw67VdiZ5MbJUw7nRnArTeuRfzI +6v+bmVyvAOfT+kG1GOcgQMXapVJxUVOMYnAKa8= X-Google-Smtp-Source: AMrXdXvrQFZvxWwLCaDsN3VmXjGZLS+gkujsTvun3subZWcEKWtrhVV9OixPQA4DXOvn0Klna1V2Ysquc1Yv4M8QYqE= X-Received: by 2002:a05:6122:198f:b0:3d5:27c3:854d with SMTP id bv15-20020a056122198f00b003d527c3854dmr8426695vkb.20.1673456317469; Wed, 11 Jan 2023 08:58:37 -0800 (PST) MIME-Version: 1.0 References: <20221201042011.2977887-1-psatheesh@marvell.com> <20230111053814.979400-1-psatheesh@marvell.com> <20230111053814.979400-4-psatheesh@marvell.com> In-Reply-To: <20230111053814.979400-4-psatheesh@marvell.com> From: Jerin Jacob Date: Wed, 11 Jan 2023 22:28:11 +0530 Message-ID: Subject: Re: [dpdk-dev] [PATCH v2 4/4] common/cnxk: fix dual VLAN parsing issue To: psatheesh@marvell.com Cc: Nithin Dabilpuram , Kiran Kumar K , Sunil Kumar Kori , Satha Rao , dev@dpdk.org, stable@dpdk.org Content-Type: text/plain; charset="UTF-8" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org On Wed, Jan 11, 2023 at 11:09 AM wrote: > > From: Satheesh Paul > > Flow parsing was not handling pattern matching on the > fields of inner VLAN even though MKEX profile could be > extracting inner VLAN fields. Code has been modified > to handle matching fields on two VLAN tags. > > Fixes: c34ea71b878 ("common/cnxk: add NPC parsing API") > Cc: stable@dpdk.org > > Signed-off-by: Satheesh Paul > Reviewed-by: Kiran Kumar K Series applied to dpdk-next-net-mrvl/for-next-net. Thanks > --- > drivers/common/cnxk/roc_npc_parse.c | 240 +++++++++++++++++++++------- > drivers/common/cnxk/roc_npc_priv.h | 16 +- > drivers/common/cnxk/roc_npc_utils.c | 2 +- > 3 files changed, 186 insertions(+), 72 deletions(-) > > diff --git a/drivers/common/cnxk/roc_npc_parse.c b/drivers/common/cnxk/roc_npc_parse.c > index c1af5f3087..d8f9271fa8 100644 > --- a/drivers/common/cnxk/roc_npc_parse.c > +++ b/drivers/common/cnxk/roc_npc_parse.c > @@ -239,10 +239,185 @@ npc_parse_la(struct npc_parse_state *pst) > > #define NPC_MAX_SUPPORTED_VLANS 3 > > +static int > +npc_parse_vlan_count(const struct roc_npc_item_info *pattern, > + const struct roc_npc_item_info **pattern_list, > + const struct roc_npc_flow_item_vlan **vlan_items, int *vlan_count) > +{ > + *vlan_count = 0; > + while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) { > + if (*vlan_count > NPC_MAX_SUPPORTED_VLANS - 1) > + return NPC_ERR_PATTERN_NOTSUP; > + > + /* 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; > + } > + > + pattern_list[*vlan_count] = pattern; > + vlan_items[*vlan_count] = pattern->spec; > + (*vlan_count)++; > + > + pattern++; > + pattern = npc_parse_skip_void_and_any_items(pattern); > + } > + > + return 0; > +} > + > +static int > +npc_parse_vlan_ltype_get(struct npc_parse_state *pst, > + const struct roc_npc_flow_item_vlan **vlan_item, int vlan_count, > + int *ltype, int *lflags) > +{ > + switch (vlan_count) { > + case 1: > + *ltype = NPC_LT_LB_CTAG; > + if (vlan_item[0] && vlan_item[0]->has_more_vlan) > + *ltype = NPC_LT_LB_STAG_QINQ; > + break; > + case 2: > + if (vlan_item[1] && vlan_item[1]->has_more_vlan) { > + if (!(pst->npc->keyx_supp_nmask[pst->nix_intf] & > + 0x3ULL << NPC_LFLAG_LB_OFFSET)) > + return NPC_ERR_PATTERN_NOTSUP; > + > + /* This lflag value will match either one of > + * NPC_F_LB_L_WITH_STAG_STAG, > + * NPC_F_LB_L_WITH_QINQ_CTAG, > + * NPC_F_LB_L_WITH_QINQ_QINQ and > + * NPC_F_LB_L_WITH_ITAG (0b0100 to 0b0111). For > + * NPC_F_LB_L_WITH_ITAG, ltype is NPC_LT_LB_ETAG > + * hence will not match. > + */ > + > + *lflags = NPC_F_LB_L_WITH_QINQ_CTAG & NPC_F_LB_L_WITH_QINQ_QINQ & > + NPC_F_LB_L_WITH_STAG_STAG; > + } > + *ltype = NPC_LT_LB_STAG_QINQ; > + break; > + case 3: > + if (vlan_item[2] && vlan_item[2]->has_more_vlan) > + return NPC_ERR_PATTERN_NOTSUP; > + if (!(pst->npc->keyx_supp_nmask[pst->nix_intf] & 0x3ULL << NPC_LFLAG_LB_OFFSET)) > + return NPC_ERR_PATTERN_NOTSUP; > + *ltype = NPC_LT_LB_STAG_QINQ; > + *lflags = NPC_F_STAG_STAG_CTAG; > + break; > + default: > + return NPC_ERR_PATTERN_NOTSUP; > + } > + > + return 0; > +} > + > +static int > +npc_update_vlan_parse_state(struct npc_parse_state *pst, const struct roc_npc_item_info *pattern, > + int lid, int lt, uint8_t lflags, int vlan_count) > +{ > + uint8_t vlan_spec[NPC_MAX_SUPPORTED_VLANS * sizeof(struct roc_vlan_hdr)]; > + uint8_t vlan_mask[NPC_MAX_SUPPORTED_VLANS * sizeof(struct roc_vlan_hdr)]; > + int rc = 0, i, offset = NPC_TPID_LENGTH; > + struct npc_parse_item_info parse_info; > + char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; > + > + memset(vlan_spec, 0, sizeof(struct roc_vlan_hdr) * NPC_MAX_SUPPORTED_VLANS); > + memset(vlan_mask, 0, sizeof(struct roc_vlan_hdr) * NPC_MAX_SUPPORTED_VLANS); > + memset(&parse_info, 0, sizeof(parse_info)); > + > + if (vlan_count > 2) > + vlan_count = 2; > + > + for (i = 0; i < vlan_count; i++) { > + if (pattern[i].spec) > + memcpy(vlan_spec + offset, pattern[i].spec, sizeof(struct roc_vlan_hdr)); > + if (pattern[i].mask) > + memcpy(vlan_mask + offset, pattern[i].mask, sizeof(struct roc_vlan_hdr)); > + > + offset += 4; > + } > + > + parse_info.def_mask = NULL; > + parse_info.spec = vlan_spec; > + parse_info.mask = vlan_mask; > + parse_info.def_mask = NULL; > + parse_info.hw_hdr_len = 0; > + > + lid = NPC_LID_LB; > + parse_info.hw_mask = hw_mask; > + > + if (lt == NPC_LT_LB_CTAG) > + parse_info.len = sizeof(struct roc_vlan_hdr) + NPC_TPID_LENGTH; > + > + if (lt == NPC_LT_LB_STAG_QINQ) > + parse_info.len = sizeof(struct roc_vlan_hdr) * 2 + NPC_TPID_LENGTH; > + > + memset(hw_mask, 0, sizeof(hw_mask)); > + > + parse_info.hw_mask = &hw_mask; > + npc_get_hw_supp_mask(pst, &parse_info, lid, lt); > + > + rc = npc_mask_is_supported(parse_info.mask, parse_info.hw_mask, parse_info.len); > + if (!rc) > + return NPC_ERR_INVALID_MASK; > + > + /* Point pattern to last item consumed */ > + pst->pattern = pattern; > + return npc_update_parse_state(pst, &parse_info, lid, lt, lflags); > +} > + > +static int > +npc_parse_lb_vlan(struct npc_parse_state *pst) > +{ > + const struct roc_npc_flow_item_vlan *vlan_items[NPC_MAX_SUPPORTED_VLANS]; > + const struct roc_npc_item_info *pattern_list[NPC_MAX_SUPPORTED_VLANS]; > + const struct roc_npc_item_info *last_pattern; > + int vlan_count = 0, rc = 0; > + int lid, lt, lflags; > + > + lid = NPC_LID_LB; > + lflags = 0; > + last_pattern = pst->pattern; > + > + rc = npc_parse_vlan_count(pst->pattern, pattern_list, vlan_items, &vlan_count); > + if (rc) > + return rc; > + > + rc = npc_parse_vlan_ltype_get(pst, vlan_items, vlan_count, <, &lflags); > + if (rc) > + return rc; > + > + if (vlan_count == 3) { > + if (pattern_list[2]->spec != NULL && pattern_list[2]->mask != NULL && > + pattern_list[2]->last != NULL) > + return NPC_ERR_PATTERN_NOTSUP; > + > + /* Matching can be done only for two tags. */ > + vlan_count = 2; > + last_pattern++; > + } > + > + rc = npc_update_vlan_parse_state(pst, pattern_list[0], lid, lt, lflags, vlan_count); > + if (rc) > + return rc; > + > + if (vlan_count > 1) > + pst->pattern = last_pattern + vlan_count; > + > + return 0; > +} > + > int > npc_parse_lb(struct npc_parse_state *pst) > { > - const struct roc_npc_flow_item_vlan *vlan_item[NPC_MAX_SUPPORTED_VLANS]; > const struct roc_npc_item_info *pattern = pst->pattern; > const struct roc_npc_item_info *last_pattern; > const struct roc_npc_flow_item_raw *raw_spec; > @@ -251,7 +426,6 @@ npc_parse_lb(struct npc_parse_state *pst) > char hw_mask[NPC_MAX_EXTRACT_HW_LEN]; > struct npc_parse_item_info info; > int lid, lt, lflags, len = 0; > - int nr_vlans = 0; > int rc; > > info.def_mask = NULL; > @@ -268,68 +442,10 @@ npc_parse_lb(struct npc_parse_state *pst) > /* RTE vlan is either 802.1q or 802.1ad, > * this maps to either CTAG/STAG. We need to decide > * based on number of VLANS present. Matching is > - * supported on first tag only. > + * supported on first two tags. > */ > - info.hw_mask = NULL; > - info.len = sizeof(vlan_item[0]->hdr); > - > - pattern = pst->pattern; > - while (pattern->type == ROC_NPC_ITEM_TYPE_VLAN) { > - if (nr_vlans > NPC_MAX_SUPPORTED_VLANS - 1) > - return NPC_ERR_PATTERN_NOTSUP; > - > - vlan_item[nr_vlans] = pattern->spec; > - nr_vlans++; > > - /* Basic validation of Second/Third vlan item */ > - if (nr_vlans > 1) { > - rc = npc_parse_item_basic(pattern, &info); > - if (rc != 0) > - return rc; > - } > - last_pattern = pattern; > - pattern++; > - pattern = npc_parse_skip_void_and_any_items(pattern); > - } > - > - switch (nr_vlans) { > - case 1: > - lt = NPC_LT_LB_CTAG; > - if (vlan_item[0] && vlan_item[0]->has_more_vlan) > - lt = NPC_LT_LB_STAG_QINQ; > - break; > - case 2: > - if (vlan_item[1] && vlan_item[1]->has_more_vlan) { > - if (!(pst->npc->keyx_supp_nmask[pst->nix_intf] & > - 0x3ULL << NPC_LFLAG_LB_OFFSET)) > - return NPC_ERR_PATTERN_NOTSUP; > - > - /* This lflag value will match either one of > - * NPC_F_LB_L_WITH_STAG_STAG, > - * NPC_F_LB_L_WITH_QINQ_CTAG, > - * NPC_F_LB_L_WITH_QINQ_QINQ and > - * NPC_F_LB_L_WITH_ITAG (0b0100 to 0b0111). For > - * NPC_F_LB_L_WITH_ITAG, ltype is NPC_LT_LB_ETAG > - * hence will not match. > - */ > - > - lflags = NPC_F_LB_L_WITH_QINQ_CTAG & > - NPC_F_LB_L_WITH_QINQ_QINQ & > - NPC_F_LB_L_WITH_STAG_STAG; > - } else { > - lflags = NPC_F_LB_L_WITH_CTAG; > - } > - lt = NPC_LT_LB_STAG_QINQ; > - break; > - case 3: > - if (vlan_item[2] && vlan_item[2]->has_more_vlan) > - return NPC_ERR_PATTERN_NOTSUP; > - lt = NPC_LT_LB_STAG_QINQ; > - lflags = NPC_F_STAG_STAG_CTAG; > - break; > - default: > - return NPC_ERR_PATTERN_NOTSUP; > - } > + return npc_parse_lb_vlan(pst); > } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_E_TAG) { > /* we can support ETAG and match a subsequent CTAG > * without any matching support. > diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h > index fe19329a7f..2a7d3137fb 100644 > --- a/drivers/common/cnxk/roc_npc_priv.h > +++ b/drivers/common/cnxk/roc_npc_priv.h > @@ -418,17 +418,15 @@ int npc_mcam_alloc_entry(struct npc *npc, struct roc_npc_flow *mcam, > int npc_mcam_alloc_entries(struct mbox *mbox, int ref_mcam, int *alloc_entry, int req_count, > int prio, int *resp_count, bool is_conti); > > -int npc_mcam_ena_dis_entry(struct npc *npc, struct roc_npc_flow *mcam, > - bool enable); > +int npc_mcam_ena_dis_entry(struct npc *npc, struct roc_npc_flow *mcam, bool enable); > int npc_mcam_write_entry(struct mbox *mbox, struct roc_npc_flow *mcam); > int npc_flow_enable_all_entries(struct npc *npc, bool enable); > -int npc_update_parse_state(struct npc_parse_state *pst, > - struct npc_parse_item_info *info, int lid, int lt, > - uint8_t flags); > -void npc_get_hw_supp_mask(struct npc_parse_state *pst, > - struct npc_parse_item_info *info, int lid, int lt); > -int npc_parse_item_basic(const struct roc_npc_item_info *item, > - struct npc_parse_item_info *info); > +int npc_update_parse_state(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid, > + int lt, uint8_t flags); > +void npc_get_hw_supp_mask(struct npc_parse_state *pst, struct npc_parse_item_info *info, int lid, > + int lt); > +int npc_mask_is_supported(const char *mask, const char *hw_mask, int len); > +int npc_parse_item_basic(const struct roc_npc_item_info *item, struct npc_parse_item_info *info); > int npc_parse_meta_items(struct npc_parse_state *pst); > int npc_parse_mark_item(struct npc_parse_state *pst); > int npc_parse_pre_l2(struct npc_parse_state *pst); > diff --git a/drivers/common/cnxk/roc_npc_utils.c b/drivers/common/cnxk/roc_npc_utils.c > index 8bdabc116d..fda3073cba 100644 > --- a/drivers/common/cnxk/roc_npc_utils.c > +++ b/drivers/common/cnxk/roc_npc_utils.c > @@ -88,7 +88,7 @@ npc_get_hw_supp_mask(struct npc_parse_state *pst, > } > } > > -static inline int > +inline int > npc_mask_is_supported(const char *mask, const char *hw_mask, int len) > { > /* > -- > 2.35.3 >