[dpdk-dev] [PATCH] net/ice: fix tunnel type match word handling

Ye Xiaolong xiaolong.ye at intel.com
Wed May 20 08:01:45 CEST 2020


On 05/18, Qi Zhang wrote:
>Use a common function when selecting the proper word and mask match for
>a tunnel type when programming switch rules.
>
>Store switch recipe field mask as little endian, which avoids needing to
>convert back to big endian after reading recipe from FW.
>
>Obtain word mask from FW recipe.
>
>Fix word matching element and index pairing.
>
>Fixes: fed0c5ca5f19 ("net/ice/base: support programming a new switch recipe")
>Cc: stable at dpdk.org
>
>Signed-off-by: Dan Nowlin <dan.nowlin at intel.com>
>Signed-off-by: Qi Zhang <qi.z.zhang at intel.com>
>---
> drivers/net/ice/base/ice_osdep.h         |  1 +
> drivers/net/ice/base/ice_protocol_type.h |  1 +
> drivers/net/ice/base/ice_switch.c        | 89 ++++++++++++++++++++------------
> 3 files changed, 59 insertions(+), 32 deletions(-)
>
>diff --git a/drivers/net/ice/base/ice_osdep.h b/drivers/net/ice/base/ice_osdep.h
>index c70f5f8a7..881bf5ddc 100644
>--- a/drivers/net/ice/base/ice_osdep.h
>+++ b/drivers/net/ice/base/ice_osdep.h
>@@ -78,6 +78,7 @@ typedef uint64_t        s64;
> #define CPU_TO_BE16(o) rte_cpu_to_be_16(o)
> #define CPU_TO_BE32(o) rte_cpu_to_be_32(o)
> #define CPU_TO_BE64(o) rte_cpu_to_be_64(o)
>+#define BE16_TO_CPU(o) rte_be_to_cpu_16(o)
> 
> #define NTOHS(a) rte_be_to_cpu_16(a)
> #define NTOHL(a) rte_be_to_cpu_32(a)
>diff --git a/drivers/net/ice/base/ice_protocol_type.h b/drivers/net/ice/base/ice_protocol_type.h
>index 46cd77e68..30233b9c4 100644
>--- a/drivers/net/ice/base/ice_protocol_type.h
>+++ b/drivers/net/ice/base/ice_protocol_type.h
>@@ -163,6 +163,7 @@ enum ice_prot_id {
> 
> #define ICE_MDID_SIZE 2
> #define ICE_TUN_FLAG_MDID 21
>+#define ICE_TUN_FLAG_MDID_OFF (ICE_MDID_SIZE * ICE_TUN_FLAG_MDID)
> #define ICE_TUN_FLAG_MASK 0xFF
> #define ICE_TUN_FLAG_FV_IND 2
> 
>diff --git a/drivers/net/ice/base/ice_switch.c b/drivers/net/ice/base/ice_switch.c
>index 17fbd26da..5f0986fcf 100644
>--- a/drivers/net/ice/base/ice_switch.c
>+++ b/drivers/net/ice/base/ice_switch.c
>@@ -945,6 +945,8 @@ ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
> 					  rg_entry->fv_idx[i], &prot, &off);
> 			lkup_exts->fv_words[fv_word_idx].prot_id = prot;
> 			lkup_exts->fv_words[fv_word_idx].off = off;
>+			lkup_exts->field_mask[fv_word_idx] =
>+				rg_entry->fv_mask[i];
> 			fv_word_idx++;
> 		}
> 		/* populate rg_list with the data from the child entry of this
>@@ -5253,20 +5255,23 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
> 
> 		/* if number of words we are looking for match */
> 		if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
>-			struct ice_fv_word *a = lkup_exts->fv_words;
>-			struct ice_fv_word *b = recp[i].lkup_exts.fv_words;
>-			u16 *c = recp[i].lkup_exts.field_mask;
>-			u16 *d = lkup_exts->field_mask;
>+			struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
>+			struct ice_fv_word *be = lkup_exts->fv_words;
>+			u16 *cr = recp[i].lkup_exts.field_mask;
>+			u16 *de = lkup_exts->field_mask;
> 			bool found = true;
>-			u8 p, q;
>-
>-			for (p = 0; p < lkup_exts->n_val_words; p++) {
>-				for (q = 0; q < recp[i].lkup_exts.n_val_words;
>-				     q++) {
>-					if (a[p].off == b[q].off &&
>-					    a[p].prot_id == b[q].prot_id &&
>-					    d[p] == c[q])
>-						/* Found the "p"th word in the
>+			u8 pe, qr;
>+
>+			/* ar, cr, and qr are related to the recipe words, while
>+			 * be, de and pe are related to the lookup words
>+			 */
>+			for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
>+				for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
>+				     qr++) {
>+					if (ar[qr].off == be[pe].off &&
>+					    ar[qr].prot_id == be[pe].prot_id &&
>+					    cr[qr] == de[pe])
>+						/* Found the "pe"th word in the
> 						 * given recipe
> 						 */
> 						break;
>@@ -5277,7 +5282,7 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
> 				 * So break out from this loop and try the next
> 				 * recipe
> 				 */
>-				if (q >= recp[i].lkup_exts.n_val_words) {
>+				if (qr >= recp[i].lkup_exts.n_val_words) {
> 					found = false;
> 					break;
> 				}
>@@ -5285,7 +5290,8 @@ static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
> 			/* If for "i"th recipe the found was never set to false
> 			 * then it means we found our match
> 			 */
>-			if (tun_type == recp[i].tun_type && found)
>+			if ((tun_type == recp[i].tun_type ||
>+			     tun_type == ICE_SW_TUN_AND_NON_TUN) && found)
> 				return i; /* Return the recipe ID */
> 		}
> 	}
>@@ -5339,7 +5345,8 @@ ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
> 				ice_prot_ext[rule->type].offs[j];
> 			lkup_exts->fv_words[word].prot_id =
> 				ice_prot_id_tbl[rule->type].protocol_id;
>-			lkup_exts->field_mask[word] = ((u16 *)&rule->m_u)[j];
>+			lkup_exts->field_mask[word] =
>+				BE16_TO_CPU(((__be16 *)&rule->m_u)[j]);
> 			word++;
> 		}
> 
>@@ -5455,11 +5462,7 @@ ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list,
> 
> 					/* Store index of field vector */
> 					rg->fv_idx[i] = j;
>-					/* Mask is given by caller as big
>-					 * endian, but sent to FW as little
>-					 * endian
>-					 */
>-					rg->fv_mask[i] = mask << 8 | mask >> 8;
>+					rg->fv_mask[i] = mask;
> 					break;
> 				}
> 
>@@ -5941,6 +5944,27 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
> }
> 
> /**
>+ * ice_tun_type_match_mask - determine if tun type needs a match mask
>+ * @tun_type: tunnel type
>+ * @mask: mask to be used for the tunnel
>+ */
>+static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
>+{
>+	switch (tun_type) {
>+	case ICE_SW_TUN_VXLAN_GPE:
>+	case ICE_SW_TUN_NVGRE:
>+	case ICE_SW_TUN_UDP:
>+	case ICE_ALL_TUNNELS:
>+		*mask = ICE_TUN_FLAG_MASK;
>+		return true;
>+
>+	default:
>+		*mask = 0;
>+		return false;
>+	}
>+}
>+
>+/**
>  * ice_add_special_words - Add words that are not protocols, such as metadata
>  * @rinfo: other information regarding the rule e.g. priority and action info
>  * @lkup_exts: lookup word structure
>@@ -5949,17 +5973,18 @@ static enum ice_status
> ice_add_special_words(struct ice_adv_rule_info *rinfo,
> 		      struct ice_prot_lkup_ext *lkup_exts)
> {
>+	u16 mask;
>+
> 	/* If this is a tunneled packet, then add recipe index to match the
> 	 * tunnel bit in the packet metadata flags.
> 	 */
>-	if (rinfo->tun_type != ICE_NON_TUN) {
>+	if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
> 		if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
> 			u8 word = lkup_exts->n_val_words++;
> 
> 			lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
>-			lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID *
>-				ICE_MDID_SIZE;
>-			lkup_exts->field_mask[word] = ICE_TUN_FLAG_MASK;
>+			lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
>+			lkup_exts->field_mask[word] = mask;
> 		} else {
> 			return ICE_ERR_MAX_LIMIT;
> 		}
>@@ -6099,6 +6124,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
> 	enum ice_status status = ICE_SUCCESS;
> 	struct ice_sw_recipe *rm;
> 	bool match_tun = false;
>+	u16 mask;
> 	u8 i;
> 
> 	if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt)
>@@ -6156,14 +6182,13 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
> 	if (status)
> 		goto err_unroll;
> 
>-	/* There is only profile for UDP tunnels. So, it is necessary to use a
>-	 * metadata ID flag to differentiate different tunnel types. A separate
>-	 * recipe needs to be used for the metadata.
>+	/* For certain tunnel types it is necessary to use a metadata ID flag to
>+	 * differentiate different tunnel types. A separate recipe needs to be
>+	 * used for the metadata.
> 	 */
>-	if ((rinfo->tun_type == ICE_SW_TUN_VXLAN_GPE ||
>-	     rinfo->tun_type == ICE_SW_TUN_GENEVE ||
>-	     rinfo->tun_type == ICE_SW_TUN_VXLAN) && rm->n_grp_count > 1)
>-		match_tun = true;
>+	if (ice_tun_type_match_word(rinfo->tun_type,  &mask) &&
>+	    rm->n_grp_count > 1)
>+		match_tun = mask;
> 
> 	/* set the recipe priority if specified */
> 	rm->priority = (u8)rinfo->priority;
>-- 
>2.13.6
>

Applied to dpdk-next-net-intel, Thanks.


More information about the dev mailing list