[RFC,1/2] ethdev: fix GENEVE option item conversion

Message ID 20240417072304.3260172-2-michaelba@nvidia.com (mailing list archive)
State New
Delegated to: Ferruh Yigit
Headers
Series ethdev: update GENEVE option item structure |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Michael Baum April 17, 2024, 7:23 a.m. UTC
  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(-)
  

Patch

diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7ab1100ea0..2803507462 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -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);