Commit 1d17568e authored by Davide Caratti's avatar Davide Caratti Committed by Paolo Abeni
Browse files

net/sched: cls_flower: add support for matching tunnel control flags



extend cls_flower to match TUNNEL_FLAGS_PRESENT bits in tunnel metadata.

Suggested-by: default avatarIlya Maximets <i.maximets@ovn.org>
Acked-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarDavide Caratti <dcaratti@redhat.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 668b6a2e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -554,6 +554,9 @@ enum {
	TCA_FLOWER_KEY_SPI,		/* be32 */
	TCA_FLOWER_KEY_SPI_MASK,	/* be32 */

	TCA_FLOWER_KEY_ENC_FLAGS,	/* u32 */
	TCA_FLOWER_KEY_ENC_FLAGS_MASK,	/* u32 */

	__TCA_FLOWER_MAX,
};

+55 −1
Original line number Diff line number Diff line
@@ -41,6 +41,12 @@
#define TCA_FLOWER_KEY_CT_FLAGS_MASK \
		(TCA_FLOWER_KEY_CT_FLAGS_MAX - 1)

#define TUNNEL_FLAGS_PRESENT (\
	_BITUL(IP_TUNNEL_CSUM_BIT) |		\
	_BITUL(IP_TUNNEL_DONT_FRAGMENT_BIT) |	\
	_BITUL(IP_TUNNEL_OAM_BIT) |		\
	_BITUL(IP_TUNNEL_CRIT_OPT_BIT))

struct fl_flow_key {
	struct flow_dissector_key_meta meta;
	struct flow_dissector_key_control control;
@@ -75,6 +81,7 @@ struct fl_flow_key {
	struct flow_dissector_key_l2tpv3 l2tpv3;
	struct flow_dissector_key_ipsec ipsec;
	struct flow_dissector_key_cfm cfm;
	struct flow_dissector_key_enc_flags enc_flags;
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */

struct fl_flow_mask_range {
@@ -732,6 +739,10 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
	[TCA_FLOWER_KEY_SPI_MASK]	= { .type = NLA_U32 },
	[TCA_FLOWER_L2_MISS]		= NLA_POLICY_MAX(NLA_U8, 1),
	[TCA_FLOWER_KEY_CFM]		= { .type = NLA_NESTED },
	[TCA_FLOWER_KEY_ENC_FLAGS]	= NLA_POLICY_MASK(NLA_U32,
							  TUNNEL_FLAGS_PRESENT),
	[TCA_FLOWER_KEY_ENC_FLAGS_MASK]	= NLA_POLICY_MASK(NLA_U32,
							  TUNNEL_FLAGS_PRESENT),
};

static const struct nla_policy
@@ -1825,6 +1836,21 @@ static int fl_set_key_cfm(struct nlattr **tb,
	return 0;
}

static int fl_set_key_enc_flags(struct nlattr **tb, u32 *flags_key,
				u32 *flags_mask, struct netlink_ext_ack *extack)
{
	/* mask is mandatory for flags */
	if (NL_REQ_ATTR_CHECK(extack, NULL, tb, TCA_FLOWER_KEY_ENC_FLAGS_MASK)) {
		NL_SET_ERR_MSG(extack, "missing enc_flags mask");
		return -EINVAL;
	}

	*flags_key = nla_get_u32(tb[TCA_FLOWER_KEY_ENC_FLAGS]);
	*flags_mask = nla_get_u32(tb[TCA_FLOWER_KEY_ENC_FLAGS_MASK]);

	return 0;
}

static int fl_set_key(struct net *net, struct nlattr **tb,
		      struct fl_flow_key *key, struct fl_flow_key *mask,
		      struct netlink_ext_ack *extack)
@@ -2059,9 +2085,16 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
	if (ret)
		return ret;

	if (tb[TCA_FLOWER_KEY_FLAGS])
	if (tb[TCA_FLOWER_KEY_FLAGS]) {
		ret = fl_set_key_flags(tb, &key->control.flags,
				       &mask->control.flags, extack);
		if (ret)
			return ret;
	}

	if (tb[TCA_FLOWER_KEY_ENC_FLAGS])
		ret = fl_set_key_enc_flags(tb, &key->enc_flags.flags,
					   &mask->enc_flags.flags, extack);

	return ret;
}
@@ -2175,6 +2208,8 @@ static void fl_init_dissector(struct flow_dissector *dissector,
			     FLOW_DISSECTOR_KEY_IPSEC, ipsec);
	FL_KEY_SET_IF_MASKED(mask, keys, cnt,
			     FLOW_DISSECTOR_KEY_CFM, cfm);
	FL_KEY_SET_IF_MASKED(mask, keys, cnt,
			     FLOW_DISSECTOR_KEY_ENC_FLAGS, enc_flags);

	skb_flow_dissector_init(dissector, keys, cnt);
}
@@ -3291,6 +3326,22 @@ static int fl_dump_key_cfm(struct sk_buff *skb,
	return err;
}

static int fl_dump_key_enc_flags(struct sk_buff *skb,
				 struct flow_dissector_key_enc_flags *key,
				 struct flow_dissector_key_enc_flags *mask)
{
	if (!memchr_inv(mask, 0, sizeof(*mask)))
		return 0;

	if (nla_put_u32(skb, TCA_FLOWER_KEY_ENC_FLAGS, key->flags))
		return -EMSGSIZE;

	if (nla_put_u32(skb, TCA_FLOWER_KEY_ENC_FLAGS_MASK, mask->flags))
		return -EMSGSIZE;

	return 0;
}

static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type,
			       struct flow_dissector_key_enc_opts *enc_opts)
{
@@ -3592,6 +3643,9 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net,
	if (fl_dump_key_cfm(skb, &key->cfm, &mask->cfm))
		goto nla_put_failure;

	if (fl_dump_key_enc_flags(skb, &key->enc_flags, &mask->enc_flags))
		goto nla_put_failure;

	return 0;

nla_put_failure: