netdev_tc_flow_put() ignores the tunnel.tp_dst mask. That results in the exact match on the value. TC supports the masked match on this field and it does return the mask back during the flow dump even if it wasn't provided initially. OVS should correctly handle that. There is a problem though. Some drivers (mlx5) doesn't support offloading if the destination port is not an exact match [1].
Keeping the logic as-is for now, but making it explicit and somewhat documented in the comment, so it is clear what is happening and we can revisit this in the future. [1] https://patchwork.ozlabs.org/project/openvswitch/patch/20220704224505.1117988-3-i.maxim...@ovn.org/#2927396 Signed-off-by: Ilya Maximets <i.maxim...@ovn.org> --- lib/netdev-offload-tc.c | 8 +++++++- lib/tc.c | 13 ++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 750cc5682..336507d59 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -1115,7 +1115,8 @@ parse_tc_flower_to_match(struct tc_flower *flower, flower->mask.tunnel.ttl); } if (flower->key.tunnel.tp_dst) { - match_set_tun_tp_dst(match, flower->key.tunnel.tp_dst); + match_set_tun_tp_dst_masked(match, flower->key.tunnel.tp_dst, + flower->mask.tunnel.tp_dst); } if (flower->key.tunnel.metadata.present.len) { flower_tun_opt_to_match(match, flower); @@ -1989,6 +1990,11 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match, flower.mask.tunnel.ipv6.ipv6_dst = tnl_mask->ipv6_dst; flower.mask.tunnel.tos = tnl_mask->ip_tos; flower.mask.tunnel.ttl = tnl_mask->ip_ttl; + /* XXX: We should be setting the mask from 'tnl_mask->tp_dst' here, but + * some hardware drivers (mlx5) doesn't support masked matches and will + * refuse to offload such flows keeping them in software path. + * Degrading the flow down to exact match for now as a workaround. */ + flower.mask.tunnel.tp_dst = OVS_BE16_MAX; flower.mask.tunnel.id = (tnl->flags & FLOW_TNL_F_KEY) ? tnl_mask->tun_id : 0; flower_match_to_tun_opt(&flower, tnl, tnl_mask); flower.tunnel = true; diff --git a/lib/tc.c b/lib/tc.c index 0f3f27c11..7006e5e01 100644 --- a/lib/tc.c +++ b/lib/tc.c @@ -411,6 +411,8 @@ static const struct nl_policy tca_flower_policy[] = { .optional = true, }, [TCA_FLOWER_KEY_ENC_UDP_DST_PORT] = { .type = NL_A_U16, .optional = true, }, + [TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK] = { .type = NL_A_U16, + .optional = true, }, [TCA_FLOWER_KEY_FLAGS] = { .type = NL_A_BE32, .optional = true, }, [TCA_FLOWER_KEY_FLAGS_MASK] = { .type = NL_A_BE32, .optional = true, }, [TCA_FLOWER_KEY_IP_TTL] = { .type = NL_A_U8, @@ -781,7 +783,9 @@ nl_parse_flower_tunnel(struct nlattr **attrs, struct tc_flower *flower) flower->key.tunnel.ipv6.ipv6_dst = nl_attr_get_in6_addr(attrs[TCA_FLOWER_KEY_ENC_IPV6_DST]); } - if (attrs[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]) { + if (attrs[TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK]) { + flower->mask.tunnel.tp_dst = + nl_attr_get_be16(attrs[TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK]); flower->key.tunnel.tp_dst = nl_attr_get_be16(attrs[TCA_FLOWER_KEY_ENC_UDP_DST_PORT]); } @@ -3388,13 +3392,14 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) struct in6_addr *ipv6_dst_mask = &flower->mask.tunnel.ipv6.ipv6_dst; struct in6_addr *ipv6_src = &flower->key.tunnel.ipv6.ipv6_src; struct in6_addr *ipv6_dst = &flower->key.tunnel.ipv6.ipv6_dst; - ovs_be16 tp_dst = flower->key.tunnel.tp_dst; ovs_be32 id = be64_to_be32(flower->key.tunnel.id); + ovs_be16 tp_dst = flower->key.tunnel.tp_dst; uint8_t tos = flower->key.tunnel.tos; uint8_t ttl = flower->key.tunnel.ttl; uint8_t tos_mask = flower->mask.tunnel.tos; uint8_t ttl_mask = flower->mask.tunnel.ttl; ovs_be64 id_mask = flower->mask.tunnel.id; + ovs_be16 tp_dst_mask = flower->mask.tunnel.tp_dst; if (ipv4_dst_mask || ipv4_src_mask) { nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, @@ -3420,8 +3425,10 @@ nl_msg_put_flower_tunnel(struct ofpbuf *request, struct tc_flower *flower) nl_msg_put_u8(request, TCA_FLOWER_KEY_ENC_IP_TTL, ttl); nl_msg_put_u8(request, TCA_FLOWER_KEY_ENC_IP_TTL_MASK, ttl_mask); } - if (tp_dst) { + if (tp_dst_mask) { nl_msg_put_be16(request, TCA_FLOWER_KEY_ENC_UDP_DST_PORT, tp_dst); + nl_msg_put_be16(request, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, + tp_dst_mask); } if (id_mask) { nl_msg_put_be32(request, TCA_FLOWER_KEY_ENC_KEY_ID, id); -- 2.34.3 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev