Skip to content

Commit

Permalink
net/sched: cls_flower: Add support for matching on flags
Browse files Browse the repository at this point in the history
Add UAPI to provide set of flags for matching, where the flags
provided from user-space are mapped to flow-dissector flags.

The 1st flag allows to match on whether the packet is an
IP fragment and corresponds to the FLOW_DIS_IS_FRAGMENT flag.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Or Gerlitz authored and David S. Miller committed Dec 8, 2016
1 parent d26aac2 commit faa3ffc
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
7 changes: 7 additions & 0 deletions include/uapi/linux/pkt_cls.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,18 @@ enum {
TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK, /* be16 */
TCA_FLOWER_KEY_ENC_UDP_DST_PORT, /* be16 */
TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, /* be16 */

TCA_FLOWER_KEY_FLAGS, /* be32 */
TCA_FLOWER_KEY_FLAGS_MASK, /* be32 */
__TCA_FLOWER_MAX,
};

#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)

enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
};

/* Match-all classifier */

enum {
Expand Down
76 changes: 76 additions & 0 deletions net/sched/cls_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
[TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_ENC_UDP_DST_PORT] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_FLAGS] = { .type = NLA_U32 },
[TCA_FLOWER_KEY_FLAGS_MASK] = { .type = NLA_U32 },
};

static void fl_set_key_val(struct nlattr **tb,
Expand Down Expand Up @@ -420,6 +422,39 @@ static void fl_set_key_vlan(struct nlattr **tb,
}
}

static void fl_set_key_flag(u32 flower_key, u32 flower_mask,
u32 *dissector_key, u32 *dissector_mask,
u32 flower_flag_bit, u32 dissector_flag_bit)
{
if (flower_mask & flower_flag_bit) {
*dissector_mask |= dissector_flag_bit;
if (flower_key & flower_flag_bit)
*dissector_key |= dissector_flag_bit;
}
}

static void fl_set_key_flags(struct nlattr **tb,
u32 *flags_key, u32 *flags_mask)
{
u32 key, mask;

if (!tb[TCA_FLOWER_KEY_FLAGS])
return;

key = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS]));

if (!tb[TCA_FLOWER_KEY_FLAGS_MASK])
mask = ~0;
else
mask = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS_MASK]));

*flags_key = 0;
*flags_mask = 0;

fl_set_key_flag(key, mask, flags_key, flags_mask,
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT);
}

static int fl_set_key(struct net *net, struct nlattr **tb,
struct fl_flow_key *key, struct fl_flow_key *mask)
{
Expand Down Expand Up @@ -546,6 +581,8 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
&mask->enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
sizeof(key->enc_tp.dst));

fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);

return 0;
}

Expand Down Expand Up @@ -880,6 +917,42 @@ static int fl_dump_key_vlan(struct sk_buff *skb,
return 0;
}

static void fl_get_key_flag(u32 dissector_key, u32 dissector_mask,
u32 *flower_key, u32 *flower_mask,
u32 flower_flag_bit, u32 dissector_flag_bit)
{
if (dissector_mask & dissector_flag_bit) {
*flower_mask |= flower_flag_bit;
if (dissector_key & dissector_flag_bit)
*flower_key |= flower_flag_bit;
}
}

static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask)
{
u32 key, mask;
__be32 _key, _mask;
int err;

if (!memchr_inv(&flags_mask, 0, sizeof(flags_mask)))
return 0;

key = 0;
mask = 0;

fl_get_key_flag(flags_key, flags_mask, &key, &mask,
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT);

_key = cpu_to_be32(key);
_mask = cpu_to_be32(mask);

err = nla_put(skb, TCA_FLOWER_KEY_FLAGS, 4, &_key);
if (err)
return err;

return nla_put(skb, TCA_FLOWER_KEY_FLAGS_MASK, 4, &_mask);
}

static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
struct sk_buff *skb, struct tcmsg *t)
{
Expand Down Expand Up @@ -1015,6 +1088,9 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
sizeof(key->enc_tp.dst)))
goto nla_put_failure;

if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
goto nla_put_failure;

nla_put_u32(skb, TCA_FLOWER_FLAGS, f->flags);

if (tcf_exts_dump(skb, &f->exts))
Expand Down

0 comments on commit faa3ffc

Please sign in to comment.