On 2022-07-29 5:53 PM, Ilya Maximets wrote:
'wc.masks.tunnel.metadata.present.len' must be a mask for the same
field in the flow key, but in the tc_flower structure it's the real
length of metadata masks.
That is correctly handled for the individual opt->length, setting all
the masks to 0x1f like it's done in the tun_metadata_to_geneve_mask__(),
but not handled for the main 'len' field.
Fix that by setting the mask to 0xff like it's done during the flow
translation in xlate_actions() and during the flow dump in the
tun_metadata_from_geneve_nlattr().
Extra checks and comments added around the code to better explain
what is going on.
Fixes: a468645c6d33 ("lib/tc: add geneve with option match offload")
Signed-off-by: Ilya Maximets <[email protected]>
---
lib/netdev-offload-tc.c | 7 +++++--
lib/tc.c | 13 ++++++++++---
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 29d0e63eb..750cc5682 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -606,8 +606,9 @@ flower_tun_opt_to_match(struct match *match, struct
tc_flower *flower)
len -= sizeof(struct geneve_opt) + opt->length * 4;
}
- match->wc.masks.tunnel.metadata.present.len =
- flower->mask.tunnel.metadata.present.len;
+ /* In the 'flower' mask len is an actual length, not the mask.
+ * But in 'match' it is an actual mask and should be an exact match. */
+ match->wc.masks.tunnel.metadata.present.len = 0xff;
match->wc.masks.tunnel.flags |= FLOW_TNL_F_UDPIF;
}
@@ -1574,6 +1575,8 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
len -= sizeof(struct geneve_opt) + opt->length * 4;
}
+ /* Copying from the key and not from the mask, since in the 'flower'
+ * the length for a mask is not a mask, but the actual length. */
flower->mask.tunnel.metadata.present.len = tnl->metadata.present.len;
}
diff --git a/lib/tc.c b/lib/tc.c
index 25e66b5c5..0f3f27c11 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -721,15 +721,17 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key,
const struct geneve_opt *opt, *opt_mask;
int len, cnt = 0;
+ if (key->present.len != mask->present.len) {
+ goto bad_length;
+ }
+
len = key->present.len;
while (len) {
opt = &key->opts.gnv[cnt];
opt_mask = &mask->opts.gnv[cnt];
if (opt->length != opt_mask->length) {
- VLOG_ERR_RL(&error_rl,
- "failed to parse tun options; key/mask length differ");
- return EINVAL;
+ goto bad_length;
}
cnt += sizeof(struct geneve_opt) / 4 + opt->length;
@@ -737,6 +739,11 @@ flower_tun_geneve_opt_check_len(struct tun_metadata *key,
}
return 0;
+
+bad_length:
+ VLOG_ERR_RL(&error_rl,
+ "failed to parse tun options; key/mask length differ");
+ return EINVAL;
}
static int
reviewed and tested the series with some tunnel traffic.
same test I did on prev patchset.
thanks
Reviewed-by: Roi Dayan <[email protected]>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev