[dpdk-dev,v2,1/2] net/e1000: fix flex type filter
Checks
Commit Message
Fix bug in parse the flex info of wrong use local
variable index which will cause filter fail, and some
error in calculation mask.
Fixes: 7cd77faf7129 ("net/igb: parse flow API flex filter")
Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
Changes in v2:
add more log for details and fix patch check warning.
---
drivers/net/e1000/igb_flow.c | 57 +++++++++++++++++++++++++++++++-------------
1 file changed, 41 insertions(+), 16 deletions(-)
Comments
On 6/16/2017 6:04 AM, Wei Zhao wrote:
> Fix bug in parse the flex info of wrong use local
> variable index which will cause filter fail, and some
> error in calculation mask.
>
> Fixes: 7cd77faf7129 ("net/igb: parse flow API flex filter")
>
> Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
Series applied to dpdk-next-net/master, thanks.
@@ -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;