[RFC,1/2] ethdev: fix GENEVE option item conversion
Checks
Commit Message
The "rte_flow_conv()" function, enables, among other things, to copy
item list.
For GENEVE option item, the function copies it without considering deep
copy. It copies the "data" pointer without copying the pointed values.
This patch adds deep copy for after regular copy.
Fixes: 2b4c72b4d10d ("ethdev: introduce GENEVE header TLV option item")
Cc: shirik@nvidia.com
Signed-off-by: Michael Baum <michaelba@nvidia.com>
---
lib/ethdev/rte_flow.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
@@ -622,6 +622,7 @@ rte_flow_conv_item_spec(void *buf, const size_t size,
switch (item->type) {
union {
const struct rte_flow_item_raw *raw;
+ const struct rte_flow_item_geneve_opt *geneve_opt;
} spec;
union {
const struct rte_flow_item_raw *raw;
@@ -631,10 +632,13 @@ rte_flow_conv_item_spec(void *buf, const size_t size,
} mask;
union {
const struct rte_flow_item_raw *raw;
+ const struct rte_flow_item_geneve_opt *geneve_opt;
} src;
union {
struct rte_flow_item_raw *raw;
+ struct rte_flow_item_geneve_opt *geneve_opt;
} dst;
+ void *deep_src;
size_t tmp;
case RTE_FLOW_ITEM_TYPE_RAW:
@@ -663,13 +667,30 @@ rte_flow_conv_item_spec(void *buf, const size_t size,
tmp = last.raw->length & mask.raw->length;
if (tmp) {
off = RTE_ALIGN_CEIL(off, sizeof(*dst.raw->pattern));
- if (size >= off + tmp)
- dst.raw->pattern = rte_memcpy
- ((void *)((uintptr_t)dst.raw + off),
- src.raw->pattern, tmp);
+ if (size >= off + tmp) {
+ deep_src = (void *)((uintptr_t)dst.raw + off);
+ dst.raw->pattern = rte_memcpy(deep_src,
+ src.raw->pattern,
+ tmp);
+ }
off += tmp;
}
break;
+ case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
+ off = rte_flow_conv_copy(buf, data, size,
+ rte_flow_desc_item, item->type);
+ spec.geneve_opt = item->spec;
+ src.geneve_opt = data;
+ dst.geneve_opt = buf;
+ tmp = spec.geneve_opt->option_len << 2;
+ if (size > 0 && src.geneve_opt->data) {
+ deep_src = (void *)((uintptr_t)(dst.geneve_opt + 1));
+ dst.geneve_opt->data = rte_memcpy(deep_src,
+ src.geneve_opt->data,
+ tmp);
+ }
+ off += tmp;
+ break;
default:
off = rte_flow_conv_copy(buf, data, size,
rte_flow_desc_item, item->type);