[SRU][F:linux-bluefield][PATCH v1 1/1] UBUNTU: net: sched: allow flower to match vxlan options

Thadeu Lima de Souza Cascardo cascardo at canonical.com
Fri Mar 31 21:30:03 UTC 2023


Subject: [SRU][F:linux-bluefield][PATCH v1 1/1] UBUNTU: net: sched: allow flower to match vxlan options

What is up with the UBUNTU: prefix here? This is not required and should not be
added on commits coming from upstream.

Cascardo.

On Fri, Mar 31, 2023 at 05:41:58AM +0000, Tony Duan wrote:
> From: Xin Long <lucien.xin at gmail.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/2013422
> 
> This patch is to allow matching gbp option in vxlan.
> 
> The options can be described in the form GBP/GBP_MASK,
> where GBP is represented as a 32bit hexadecimal value.
> Different from geneve, only one option can be set. And
> also, geneve options and vxlan options can't be set at
> the same time.
> 
>   # ip link add name vxlan0 type vxlan dstport 0 external
>   # tc qdisc add dev vxlan0 ingress
>   # tc filter add dev vxlan0 protocol ip parent ffff: \
>       flower \
>         enc_src_ip 10.0.99.192 \
>         enc_dst_ip 10.0.99.193 \
>         enc_key_id 11 \
>         vxlan_opts 01020304/ffffffff \
>         ip_proto udp \
>         action mirred egress redirect dev eth0
> 
> v1->v2:
>   - add .strict_start_type for enc_opts_policy as Jakub noticed.
>   - use Duplicate instead of Wrong in err msg for extack as Jakub
>     suggested.
> 
> Signed-off-by: Xin Long <lucien.xin at gmail.com>
> Signed-off-by: David S. Miller <davem at davemloft.net>
> (cherry picked from commit d8f9dfae49ce4ffb772dc10dd6578dc815b34c12)
> Signed-off-by: Tony Duan <yifeid at nvidia.com>
> ---
>  include/uapi/linux/pkt_cls.h |  13 +++++
>  net/sched/cls_flower.c       | 109 +++++++++++++++++++++++++++++++++++
>  2 files changed, 122 insertions(+)
> 
> diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
> index b089c2dfb249..117b9922f409 100644
> --- a/include/uapi/linux/pkt_cls.h
> +++ b/include/uapi/linux/pkt_cls.h
> @@ -577,6 +577,10 @@ enum {
>  					 * TCA_FLOWER_KEY_ENC_OPT_GENEVE_
>  					 * attributes
>  					 */
> +	TCA_FLOWER_KEY_ENC_OPTS_VXLAN,	/* Nested
> +					 * TCA_FLOWER_KEY_ENC_OPT_VXLAN_
> +					 * attributes
> +					 */
>  	__TCA_FLOWER_KEY_ENC_OPTS_MAX,
>  };
>  
> @@ -594,6 +598,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),
> diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
> index 0b428f5ca73b..27017350df58 100644
> --- a/net/sched/cls_flower.c
> +++ b/net/sched/cls_flower.c
> @@ -23,6 +23,7 @@
>  #include <net/ip.h>
>  #include <net/flow_dissector.h>
>  #include <net/geneve.h>
> +#include <net/vxlan.h>
>  
>  #include <net/dst.h>
>  #include <net/dst_metadata.h>
> @@ -709,7 +710,10 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
>  
>  static const struct nla_policy
>  enc_opts_policy[TCA_FLOWER_KEY_ENC_OPTS_MAX + 1] = {
> +	[TCA_FLOWER_KEY_ENC_OPTS_UNSPEC]        = {
> +		.strict_start_type = TCA_FLOWER_KEY_ENC_OPTS_VXLAN },
>  	[TCA_FLOWER_KEY_ENC_OPTS_GENEVE]        = { .type = NLA_NESTED },
> +	[TCA_FLOWER_KEY_ENC_OPTS_VXLAN]         = { .type = NLA_NESTED },
>  };
>  
>  static const struct nla_policy
> @@ -720,6 +724,11 @@ geneve_opt_policy[TCA_FLOWER_KEY_ENC_OPT_GENEVE_MAX + 1] = {
>  						       .len = 128 },
>  };
>  
> +static const struct nla_policy
> +vxlan_opt_policy[TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1] = {
> +	[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]         = { .type = NLA_U32 },
> +};
> +
>  static void fl_set_key_val(struct nlattr **tb,
>  			   void *val, int val_type,
>  			   void *mask, int mask_type, int len)
> @@ -957,6 +966,41 @@ static int fl_set_geneve_opt(const struct nlattr *nla, struct fl_flow_key *key,
>  	return sizeof(struct geneve_opt) + data_len;
>  }
>  
> +static int fl_set_vxlan_opt(const struct nlattr *nla, struct fl_flow_key *key,
> +			    int depth, int option_len,
> +			    struct netlink_ext_ack *extack)
> +{
> +	struct nlattr *tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX + 1];
> +	struct vxlan_metadata *md;
> +	int err;
> +
> +	md = (struct vxlan_metadata *)&key->enc_opts.data[key->enc_opts.len];
> +	memset(md, 0xff, sizeof(*md));
> +
> +	if (!depth)
> +		return sizeof(*md);
> +
> +	if (nla_type(nla) != TCA_FLOWER_KEY_ENC_OPTS_VXLAN) {
> +		NL_SET_ERR_MSG(extack, "Non-vxlan option type for mask");
> +		return -EINVAL;
> +	}
> +
> +	err = nla_parse_nested(tb, TCA_FLOWER_KEY_ENC_OPT_VXLAN_MAX, nla,
> +			       vxlan_opt_policy, extack);
> +	if (err < 0)
> +		return err;
> +
> +	if (!option_len && !tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]) {
> +		NL_SET_ERR_MSG(extack, "Missing tunnel key vxlan option gbp");
> +		return -EINVAL;
> +	}
> +
> +	if (tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP])
> +		md->gbp = nla_get_u32(tb[TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP]);
> +
> +	return sizeof(*md);
> +}
> +
>  static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
>  			  struct fl_flow_key *mask,
>  			  struct netlink_ext_ack *extack)
> @@ -987,6 +1031,11 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
>  			  nla_len(tb[TCA_FLOWER_KEY_ENC_OPTS]), key_depth) {
>  		switch (nla_type(nla_opt_key)) {
>  		case TCA_FLOWER_KEY_ENC_OPTS_GENEVE:
> +			if (key->enc_opts.dst_opt_type &&
> +			    key->enc_opts.dst_opt_type != TUNNEL_GENEVE_OPT) {
> +				NL_SET_ERR_MSG(extack, "Duplicate type for geneve options");
> +				return -EINVAL;
> +			}
>  			option_len = 0;
>  			key->enc_opts.dst_opt_type = TUNNEL_GENEVE_OPT;
>  			option_len = fl_set_geneve_opt(nla_opt_key, key,
> @@ -1012,6 +1061,39 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key,
>  				return -EINVAL;
>  			}
>  
> +			if (msk_depth)
> +				nla_opt_msk = nla_next(nla_opt_msk, &msk_depth);
> +			break;
> +		case TCA_FLOWER_KEY_ENC_OPTS_VXLAN:
> +			if (key->enc_opts.dst_opt_type) {
> +				NL_SET_ERR_MSG(extack, "Duplicate type for vxlan options");
> +				return -EINVAL;
> +			}
> +			option_len = 0;
> +			key->enc_opts.dst_opt_type = TUNNEL_VXLAN_OPT;
> +			option_len = fl_set_vxlan_opt(nla_opt_key, key,
> +						      key_depth, option_len,
> +						      extack);
> +			if (option_len < 0)
> +				return option_len;
> +
> +			key->enc_opts.len += option_len;
> +			/* At the same time we need to parse through the mask
> +			 * in order to verify exact and mask attribute lengths.
> +			 */
> +			mask->enc_opts.dst_opt_type = TUNNEL_VXLAN_OPT;
> +			option_len = fl_set_vxlan_opt(nla_opt_msk, mask,
> +						      msk_depth, option_len,
> +						      extack);
> +			if (option_len < 0)
> +				return option_len;
> +
> +			mask->enc_opts.len += option_len;
> +			if (key->enc_opts.len != mask->enc_opts.len) {
> +				NL_SET_ERR_MSG(extack, "Key and mask miss aligned");
> +				return -EINVAL;
> +			}
> +
>  			if (msk_depth)
>  				nla_opt_msk = nla_next(nla_opt_msk, &msk_depth);
>  			break;
> @@ -2222,6 +2304,28 @@ static int fl_dump_key_geneve_opt(struct sk_buff *skb,
>  	return -EMSGSIZE;
>  }
>  
> +static int fl_dump_key_vxlan_opt(struct sk_buff *skb,
> +				 struct flow_dissector_key_enc_opts *enc_opts)
> +{
> +	struct vxlan_metadata *md;
> +	struct nlattr *nest;
> +
> +	nest = nla_nest_start_noflag(skb, TCA_FLOWER_KEY_ENC_OPTS_VXLAN);
> +	if (!nest)
> +		goto nla_put_failure;
> +
> +	md = (struct vxlan_metadata *)&enc_opts->data[0];
> +	if (nla_put_u32(skb, TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP, md->gbp))
> +		goto nla_put_failure;
> +
> +	nla_nest_end(skb, nest);
> +	return 0;
> +
> +nla_put_failure:
> +	nla_nest_cancel(skb, nest);
> +	return -EMSGSIZE;
> +}
> +
>  static int fl_dump_key_ct(struct sk_buff *skb,
>  			  struct flow_dissector_key_ct *key,
>  			  struct flow_dissector_key_ct *mask)
> @@ -2275,6 +2379,11 @@ static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type,
>  		if (err)
>  			goto nla_put_failure;
>  		break;
> +	case TUNNEL_VXLAN_OPT:
> +		err = fl_dump_key_vxlan_opt(skb, enc_opts);
> +		if (err)
> +			goto nla_put_failure;
> +		break;
>  	default:
>  		goto nla_put_failure;
>  	}
> -- 
> 2.25.1
> 
> 
> -- 
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team



More information about the kernel-team mailing list