The value is right-justified after the string parsing with
parse_int_string(), i.e. it is in BE byte order and aligned
to the right side of the array.
For example, the 0x10011 value in a 4-byte field will look
like 0x00 0x01 0x00 0x11.
However, value copy to the resulted ofpact is performed
from the start of the memory. So, in case the destination
size is smaller than the original field size, incorrect
part of the value will be copied.
In the 0x00 0x01 0x00 0x11 example above, if the copy is
performed to a 3-byte field, the first 3 bytes will be
copied, which are 0x00 0x01 0x00 instead of 0x01 0x00 0x11.
This leads to a problem where NXM_NX_REG3[0..16]=0x10011
turns into NXM_NX_REG3[0..16]=0x100 after the parsing.
Fix that by offsetting the starting position to the size
difference in bytes similarly to how it is done in
learn_parse_load_immediate().
Fixes: 21b2fa617126 ("ofp-parse: Allow match field names in actions and
brackets in matches.")
Reported-at:
https://mail.openvswitch.org/pipermail/ovs-discuss/2022-November/052100.html
Reported-by: Thomas Lee <[email protected]>
Signed-off-by: Ilya Maximets <[email protected]>
---
lib/learn.c | 4 +++-
tests/learn.at | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/lib/learn.c b/lib/learn.c
index a40209ec0..cfd762527 100644
--- a/lib/learn.c
+++ b/lib/learn.c
@@ -310,9 +310,11 @@ learn_parse_spec(const char *orig, char *name, char *value,
/* Push value last, as this may reallocate 'spec'! */
unsigned int imm_bytes = DIV_ROUND_UP(dst.n_bits, 8);
+ unsigned int offset = dst.field->n_bytes - imm_bytes;
uint8_t *src_imm = ofpbuf_put_zeros(ofpacts,
OFPACT_ALIGN(imm_bytes));
- memcpy(src_imm, &imm, imm_bytes);
+
+ memcpy(src_imm, (uint8_t *) &imm + offset, imm_bytes);
free(error);
return NULL;
diff --git a/tests/learn.at b/tests/learn.at
index 5f1d6df9d..d127fed34 100644
--- a/tests/learn.at
+++ b/tests/learn.at
@@ -6,7 +6,7 @@ actions=learn()
actions=learn(send_flow_rem)
actions=learn(delete_learned)
actions=learn(send_flow_rem,delete_learned)
-actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
output:NXM_OF_IN_PORT[], load:10->NXM_NX_REG0[5..10])
+actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],
NXM_NX_REG3[3..19]=0x10011, output:NXM_OF_IN_PORT[],
load:10->NXM_NX_REG0[5..10])
actions=learn(table=1,idle_timeout=10, hard_timeout=20, fin_idle_timeout=5,
fin_hard_timeout=10, priority=10, cookie=0xfedcba9876543210,
in_port=99,eth_dst=eth_src,load:in_port->reg1[16..31])
actions=learn(limit=4096)
actions=learn(limit=4096,result_dst=reg0[0])
@@ -18,7 +18,7 @@ OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1)
OFPT_FLOW_MOD (xid=0x2): ADD actions=learn(table=1,send_flow_rem)
OFPT_FLOW_MOD (xid=0x3): ADD actions=learn(table=1,delete_learned)
OFPT_FLOW_MOD (xid=0x4): ADD
actions=learn(table=1,send_flow_rem,delete_learned)
-OFPT_FLOW_MOD (xid=0x5): ADD
actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[],load:0xa->NXM_NX_REG0[5..10])
+OFPT_FLOW_MOD (xid=0x5): ADD
actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],NXM_NX_REG3[3..19]=0x10011,output:NXM_OF_IN_PORT[],load:0xa->NXM_NX_REG0[5..10])
OFPT_FLOW_MOD (xid=0x6): ADD
actions=learn(table=1,idle_timeout=10,hard_timeout=20,fin_idle_timeout=5,fin_hard_timeout=10,priority=10,cookie=0xfedcba9876543210,in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
OFPT_FLOW_MOD (xid=0x7): ADD actions=learn(table=1,limit=4096)
OFPT_FLOW_MOD (xid=0x8): ADD
actions=learn(table=1,limit=4096,result_dst=NXM_NX_REG0[0])
--
2.37.3
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev