On 25/04/2023 9:32, Roi Dayan wrote:
> From: Gavin Li <[email protected]>
>
> Add TC offload support for filtering vxlan tunnels with gbp option
>
> Signed-off-by: Gavin Li <[email protected]>
> Reviewed-by: Gavi Teitz <[email protected]>
> Reviewed-by: Roi Dayan <[email protected]>
> ---
> acinclude.m4 | 7 ++++++
> include/linux/pkt_cls.h | 17 +++++++++++--
> lib/netdev-offload-tc.c | 17 +++++++++++++
> lib/tc.c | 54 ++++++++++++++++++++++++++++++++++++++++-
> lib/tc.h | 7 ++++++
> 5 files changed, 99 insertions(+), 3 deletions(-)
>
> diff --git a/acinclude.m4 b/acinclude.m4
> index ac1eab790041..dbf80a8896f4 100644
> --- a/acinclude.m4
> +++ b/acinclude.m4
> @@ -211,6 +211,13 @@ AC_DEFUN([OVS_CHECK_LINUX_TC], [
> ])],
> [AC_DEFINE([HAVE_TCA_STATS_PKT64], [1],
> [Define to 1 if TCA_STATS_PKT64 is available.])])
> +
> + AC_COMPILE_IFELSE([
> + AC_LANG_PROGRAM([#include <linux/pkt_cls.h>], [
> + int x = TCA_FLOWER_KEY_ENC_OPTS_VXLAN;
> + ])],
> + [AC_DEFINE([HAVE_TCA_FLOWER_KEY_ENC_OPTS_VXLAN], [1],
> + [Define to 1 if TCA_FLOWER_KEY_ENC_OPTS_VXLAN is
> available.])])
> ])
>
> dnl OVS_CHECK_LINUX_SCTP_CT
> diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
> index a8cd8db5bf88..cf2af59096a2 100644
> --- a/include/linux/pkt_cls.h
> +++ b/include/linux/pkt_cls.h
> @@ -1,7 +1,7 @@
> #ifndef __LINUX_PKT_CLS_WRAPPER_H
> #define __LINUX_PKT_CLS_WRAPPER_H 1
>
> -#if defined(__KERNEL__) || defined(HAVE_TCA_ACT_FLAGS_SKIP_HW)
> +#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_ENC_OPTS_VXLAN)
> #include_next <linux/pkt_cls.h>
> #else
>
> @@ -273,6 +273,10 @@ enum {
> * TCA_TUNNEL_KEY_ENC_OPTS_GENEVE
> * attributes
> */
> + TCA_FLOWER_KEY_ENC_OPTS_VXLAN, /* Nested
> + * TCA_TUNNEL_KEY_ENC_OPTS_VXLAN
> + * attributes
> + */
> __TCA_FLOWER_KEY_ENC_OPTS_MAX,
> };
>
> @@ -290,6 +294,15 @@ enum {
> #define TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX \
> (__TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX - 1)
>
> +enum {
> + TCA_FLOWER_KEY_ENC_OPT_VXLAN_UNSPEC,
> + TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, /* u32 */
> + __TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX,
> +};
> +
> +#define TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX \
> + (__TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX - 1)
> +
> enum {
> TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
> TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
> @@ -307,6 +320,6 @@ enum {
>
> #define TCA_MATCHALL_MAX (__TCA_MATCHALL_MAX - 1)
>
> -#endif /* __KERNEL__ || !HAVE_TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST */
> +#endif /* __KERNEL__ || HAVE_TCA_FLOWER_KEY_ENC_OPTS_VXLAN */
>
> #endif /* __LINUX_PKT_CLS_WRAPPER_H */
> diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
> index c9662081fc60..ba4179cd8693 100644
> --- a/lib/netdev-offload-tc.c
> +++ b/lib/netdev-offload-tc.c
> @@ -1230,6 +1230,15 @@ parse_tc_flower_to_match(const struct netdev *netdev,
> match_set_tun_tp_dst_masked(match, flower->key.tunnel.tp_dst,
> flower->mask.tunnel.tp_dst);
> }
> + if (flower->mask.tunnel.gbp.id) {
> + match_set_tun_gbp_id_masked(match, flower->key.tunnel.gbp.id,
> + flower->mask.tunnel.gbp.id);
> + }
> + if (flower->mask.tunnel.gbp.flags) {
> + match_set_tun_gbp_flags_masked(match,
> + flower->key.tunnel.gbp.flags,
> + flower->mask.tunnel.gbp.flags);
> + }
>
> if (!strcmp(netdev_get_type(netdev), "geneve")) {
> flower_tun_opt_to_match(match, flower);
> @@ -2189,6 +2198,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match
> *match,
> flower.key.tunnel.ttl = tnl->ip_ttl;
> flower.key.tunnel.tp_src = tnl->tp_src;
> flower.key.tunnel.tp_dst = tnl->tp_dst;
> + flower.key.tunnel.gbp.id = tnl->gbp_id;
> + flower.key.tunnel.gbp.flags = tnl->gbp_flags;
> + flower.key.tunnel.gbp.id_present = !!tnl_mask->gbp_id;
>
> flower.mask.tunnel.ipv4.ipv4_src = tnl_mask->ip_src;
> flower.mask.tunnel.ipv4.ipv4_dst = tnl_mask->ip_dst;
> @@ -2203,6 +2215,9 @@ netdev_tc_flow_put(struct netdev *netdev, struct match
> *match,
> * 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.mask.tunnel.gbp.id = tnl_mask->gbp_id;
> + flower.mask.tunnel.gbp.flags = tnl_mask->gbp_flags;
> + flower.mask.tunnel.gbp.id_present = !!tnl_mask->gbp_id;
>
> memset(&tnl_mask->ip_src, 0, sizeof tnl_mask->ip_src);
> memset(&tnl_mask->ip_dst, 0, sizeof tnl_mask->ip_dst);
> @@ -2214,6 +2229,8 @@ netdev_tc_flow_put(struct netdev *netdev, struct match
> *match,
> memset(&tnl_mask->tp_dst, 0, sizeof tnl_mask->tp_dst);
>
> memset(&tnl_mask->tun_id, 0, sizeof tnl_mask->tun_id);
> + memset(&tnl_mask->gbp_id, 0, sizeof tnl_mask->gbp_id);
> + memset(&tnl_mask->gbp_flags, 0, sizeof tnl_mask->gbp_flags);
> tnl_mask->flags &= ~FLOW_TNL_F_KEY;
>
> /* XXX: This is wrong! We're ignoring DF and CSUM flags
> configuration
> diff --git a/lib/tc.c b/lib/tc.c
> index 87615e979f1a..e72fa4235198 100644
> --- a/lib/tc.c
> +++ b/lib/tc.c
> @@ -38,6 +38,7 @@
> #include "byte-order.h"
> #include "netlink-socket.h"
> #include "netlink.h"
> +#include "odp-util.h"
> #include "openvswitch/ofpbuf.h"
> #include "openvswitch/util.h"
> #include "openvswitch/vlog.h"
> @@ -696,6 +697,38 @@ nl_parse_geneve_key(const struct nlattr *in_nlattr,
> return 0;
> }
>
> +static int
> +nl_parse_vxlan_key(const struct nlattr *in_nlattr,
> + struct tc_flower_tunnel *tunnel)
> +{
> + const struct ofpbuf *msg;
> + struct nlattr *nla;
> + struct ofpbuf buf;
> + uint32_t gbp_raw;
> + size_t left;
> +
> + nl_attr_get_nested(in_nlattr, &buf);
> + msg = &buf;
> +
> + NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, 0, 0), msg->size) {
> + uint16_t type = nl_attr_type(nla);
> +
> + switch (type) {
> + case TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP:
> + gbp_raw = nl_attr_get_u32(nla);
> + odp_decode_gbp_raw(gbp_raw, &tunnel->gbp.id,
> + &tunnel->gbp.flags);
> + tunnel->gbp.id_present = true;
> + break;
> + default:
> + VLOG_ERR_RL(&error_rl, "failed to parse vxlan tun options");
> + return EINVAL;
> + }
> + }
> +
> + return 0;
> +}
> +
> static int
> nl_parse_flower_tunnel_opts(struct nlattr *options,
> struct tc_flower_tunnel *tunnel)
> @@ -718,6 +751,13 @@ nl_parse_flower_tunnel_opts(struct nlattr *options,
> return err;
> }
>
> + break;
> + case TCA_FLOWER_KEY_ENC_OPTS_VXLAN:
> + err = nl_parse_vxlan_key(nla, tunnel);
> + if (err) {
> + return err;
> + }
> +
> break;
> }
> }
> @@ -3439,11 +3479,12 @@ nl_msg_put_flower_tunnel_opts(struct ofpbuf *request,
> uint16_t type,
> int len, cnt = 0;
>
> len = metadata->present.len;
> - if (!len) {
> + if (!len && !tunnel->gbp.id_present) {
> return;
> }
>
> outer = nl_msg_start_nested(request, type);
> + /* Geneve */
> while (len) {
> opt = &metadata->opts.gnv[cnt];
> inner = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_GENEVE);
> @@ -3459,6 +3500,17 @@ nl_msg_put_flower_tunnel_opts(struct ofpbuf *request,
> uint16_t type,
>
> nl_msg_end_nested(request, inner);
> }
> +
> + /* VxLAN GBP */
> + if (tunnel->gbp.id_present) {
> + uint32_t gbp_raw;
> +
> + gbp_raw = odp_encode_gbp_raw(tunnel->gbp.flags, tunnel->gbp.id);
> + inner = nl_msg_start_nested(request, TCA_FLOWER_KEY_ENC_OPTS_VXLAN);
> +
> + nl_msg_put_u32(request, TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, gbp_raw);
> + nl_msg_end_nested(request, inner);
> + }
> nl_msg_end_nested(request, outer);
> }
>
> diff --git a/lib/tc.h b/lib/tc.h
> index b9d449677ed9..95fff37b9b61 100644
> --- a/lib/tc.h
> +++ b/lib/tc.h
> @@ -105,6 +105,12 @@ struct tc_cookie {
> size_t len;
> };
>
> +struct tc_tunnel_gbp {
> + ovs_be16 id;
> + uint8_t flags;
> + bool id_present;
> +};
> +
> struct tc_flower_tunnel {
> struct {
> ovs_be32 ipv4_src;
> @@ -118,6 +124,7 @@ struct tc_flower_tunnel {
> uint8_t ttl;
> ovs_be16 tp_src;
> ovs_be16 tp_dst;
> + struct tc_tunnel_gbp gbp;
> ovs_be64 id;
> struct tun_metadata metadata;
> };
Hi,
Got email from the bot about compile issue with the compat
starting with this patch. We will check it and send v2.
Thanks,
Roi
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev