[dpdk-dev] [PATCH 1/2] net/e1000: fix flex type filter

Wei Zhao wei.zhao1 at intel.com
Fri Jun 16 05:15:04 CEST 2017


Fix bug in parse the flex info of wrong use local
varible index which will cause filter fail.

Fixes: 7cd77faf7129 ("net/igb: parse flow API flex filter")

Signed-off-by: Wei Zhao <wei.zhao1 at intel.com>
---
 drivers/net/e1000/igb_flow.c | 57 +++++++++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 16 deletions(-)

diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
index ce48c0d..98538e6 100644
--- a/drivers/net/e1000/igb_flow.c
+++ b/drivers/net/e1000/igb_flow.c
@@ -77,6 +77,8 @@
 		}						\
 	} while (0)
 
+#define	IGB_FLEX_RAW_NUM	12
+
 /**
  * Please aware there's an asumption for all the parsers.
  * rte_flow_item is using big endian, rte_flow_attr and
@@ -1043,8 +1045,11 @@ cons_parse_flex_filter(const struct rte_flow_attr *attr,
 	const struct rte_flow_item_raw *raw_spec;
 	const struct rte_flow_item_raw *raw_mask;
 	const struct rte_flow_action_queue *act_q;
-	uint32_t index, i, offset, total_offset = 0;
-	int32_t shift;
+	uint32_t index, i, offset, total_offset;
+	uint32_t max_offset = 0;
+	int32_t shift, j, raw_index = 0;
+	int32_t relative[IGB_FLEX_RAW_NUM] = {0};
+	int32_t	raw_offset[IGB_FLEX_RAW_NUM] = {0};
 
 	if (!pattern) {
 		rte_flow_error_set(error, EINVAL,
@@ -1105,8 +1110,8 @@ cons_parse_flex_filter(const struct rte_flow_attr *attr,
 	else
 		offset = 0;
 
-	for (index = 0; index < raw_spec->length; index++) {
-		if (raw_mask->pattern[index] != 0xFF) {
+	for (j = 0; j < raw_spec->length; j++) {
+		if (raw_mask->pattern[j] != 0xFF) {
 			memset(filter, 0, sizeof(struct rte_eth_flex_filter));
 			rte_flow_error_set(error, EINVAL,
 					RTE_FLOW_ERROR_TYPE_ITEM,
@@ -1115,6 +1120,21 @@ cons_parse_flex_filter(const struct rte_flow_attr *attr,
 		}
 	}
 
+	total_offset = 0;
+
+	if (raw_spec->relative) {
+		for (j = raw_index; j > 0; j--) {
+			total_offset += raw_offset[j - 1];
+			if (!relative[j - 1])
+				break;
+		}
+		if (total_offset + raw_spec->length + offset > max_offset)
+			max_offset = total_offset + raw_spec->length + offset;
+	} else {
+		if (raw_spec->length + offset > max_offset)
+			max_offset = raw_spec->length + offset;
+	}
+
 	if ((raw_spec->length + offset + total_offset) >
 			RTE_FLEX_FILTER_MAXLEN) {
 		memset(filter, 0, sizeof(struct rte_eth_flex_filter));
@@ -1125,30 +1145,35 @@ cons_parse_flex_filter(const struct rte_flow_attr *attr,
 	}
 
 	if (raw_spec->relative == 0) {
-		for (index = 0; index < raw_spec->length; index++)
-			filter->bytes[index] = raw_spec->pattern[index];
-		index = offset / CHAR_BIT;
+		for (j = 0; j < raw_spec->length; j++)
+			filter->bytes[offset + j] =
+			raw_spec->pattern[j];
+		j = offset / CHAR_BIT;
+		shift = offset % CHAR_BIT;
 	} else {
-		for (index = 0; index < raw_spec->length; index++)
-			filter->bytes[total_offset + index] =
-				raw_spec->pattern[index];
-		index = (total_offset + offset) / CHAR_BIT;
+		for (j = 0; j < raw_spec->length; j++)
+			filter->bytes[total_offset + offset + j] =
+				raw_spec->pattern[j];
+		j = (total_offset + offset) / CHAR_BIT;
+		shift = (total_offset + offset) % CHAR_BIT;
 	}
 
 	i = 0;
 
-	for (shift = offset % CHAR_BIT; shift < CHAR_BIT; shift++) {
-		filter->mask[index] |= (0x80 >> shift);
+	for ( ; shift < CHAR_BIT; shift++) {
+		filter->mask[j] |= (0x80 >> shift);
 		i++;
 		if (i == raw_spec->length)
 			break;
 		if (shift == (CHAR_BIT - 1)) {
-			index++;
+			j++;
 			shift = -1;
 		}
 	}
 
-	total_offset += offset + raw_spec->length;
+	relative[raw_index] = raw_spec->relative;
+	raw_offset[raw_index] = offset + raw_spec->length;
+	raw_index++;
 
 	/* check if the next not void item is RAW */
 	index++;
@@ -1167,7 +1192,7 @@ cons_parse_flex_filter(const struct rte_flow_attr *attr,
 		goto item_loop;
 	}
 
-	filter->len = RTE_ALIGN(total_offset, 8);
+	filter->len = RTE_ALIGN(max_offset, 8);
 
 	/* parse action */
 	index = 0;
-- 
2.7.4



More information about the dev mailing list