History

net/sched: cls_flower: Add support for matching on flags

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.

Or Gerlitz committed 9 years ago

Commit faa3ffc1 parent d26aac22 files · +83 −0Browse files

Unified · Split

2 files
  1. include/uapi/linux/pkt_cls.h +7 −0
  2. net/sched/cls_flower.c +76 −0
include/uapi/linux/pkt_cls.h+7−0
@@ -458,11 +458,18 @@ enum { · 457 unmodified lines
458 TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK, /* be16 */458 TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK, /* be16 */
459 TCA_FLOWER_KEY_ENC_UDP_DST_PORT, /* be16 */459 TCA_FLOWER_KEY_ENC_UDP_DST_PORT, /* be16 */
460 TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, /* be16 */460 TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, /* be16 */
461
462 TCA_FLOWER_KEY_FLAGS, /* be32 */
463 TCA_FLOWER_KEY_FLAGS_MASK, /* be32 */
461 __TCA_FLOWER_MAX,464 __TCA_FLOWER_MAX,
462};465};
463 466
464#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)467#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
465 468
469enum {
470 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
471};
472
466/* Match-all classifier */473/* Match-all classifier */
467 474
468enum {475enum {
net/sched/cls_flower.c+76−0
@@ -386,6 +386,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { · 385 unmodified lines
386 [TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK] = { .type = NLA_U16 },386 [TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK] = { .type = NLA_U16 },
387 [TCA_FLOWER_KEY_ENC_UDP_DST_PORT] = { .type = NLA_U16 },387 [TCA_FLOWER_KEY_ENC_UDP_DST_PORT] = { .type = NLA_U16 },
388 [TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK] = { .type = NLA_U16 },388 [TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK] = { .type = NLA_U16 },
389 [TCA_FLOWER_KEY_FLAGS] = { .type = NLA_U32 },
390 [TCA_FLOWER_KEY_FLAGS_MASK] = { .type = NLA_U32 },
389};391};
390 392
391static void fl_set_key_val(struct nlattr **tb,393static void fl_set_key_val(struct nlattr **tb,
@@ -420,6 +422,39 @@ static void fl_set_key_vlan(struct nlattr **tb, · 28 unmodified lines
420 }422 }
421}423}
422 424
425static void fl_set_key_flag(u32 flower_key, u32 flower_mask,
426 u32 *dissector_key, u32 *dissector_mask,
427 u32 flower_flag_bit, u32 dissector_flag_bit)
428{
429 if (flower_mask & flower_flag_bit) {
430 *dissector_mask |= dissector_flag_bit;
431 if (flower_key & flower_flag_bit)
432 *dissector_key |= dissector_flag_bit;
433 }
434}
435
436static void fl_set_key_flags(struct nlattr **tb,
437 u32 *flags_key, u32 *flags_mask)
438{
439 u32 key, mask;
440
441 if (!tb[TCA_FLOWER_KEY_FLAGS])
442 return;
443
444 key = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS]));
445
446 if (!tb[TCA_FLOWER_KEY_FLAGS_MASK])
447 mask = ~0;
448 else
449 mask = be32_to_cpu(nla_get_u32(tb[TCA_FLOWER_KEY_FLAGS_MASK]));
450
451 *flags_key = 0;
452 *flags_mask = 0;
453
454 fl_set_key_flag(key, mask, flags_key, flags_mask,
455 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT);
456}
457
423static int fl_set_key(struct net *net, struct nlattr **tb,458static int fl_set_key(struct net *net, struct nlattr **tb,
424 struct fl_flow_key *key, struct fl_flow_key *mask)459 struct fl_flow_key *key, struct fl_flow_key *mask)
425{460{
@@ -546,6 +581,8 @@ static int fl_set_key(struct net *net, struct nlattr **tb, · 120 unmodified lines
546 &mask->enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,581 &mask->enc_tp.dst, TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK,
547 sizeof(key->enc_tp.dst));582 sizeof(key->enc_tp.dst));
548 583
584 fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);
585
549 return 0;586 return 0;
550}587}
551 588
@@ -880,6 +917,42 @@ static int fl_dump_key_vlan(struct sk_buff *skb, · 328 unmodified lines
880 return 0;917 return 0;
881}918}
882 919
920static void fl_get_key_flag(u32 dissector_key, u32 dissector_mask,
921 u32 *flower_key, u32 *flower_mask,
922 u32 flower_flag_bit, u32 dissector_flag_bit)
923{
924 if (dissector_mask & dissector_flag_bit) {
925 *flower_mask |= flower_flag_bit;
926 if (dissector_key & dissector_flag_bit)
927 *flower_key |= flower_flag_bit;
928 }
929}
930
931static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask)
932{
933 u32 key, mask;
934 __be32 _key, _mask;
935 int err;
936
937 if (!memchr_inv(&flags_mask, 0, sizeof(flags_mask)))
938 return 0;
939
940 key = 0;
941 mask = 0;
942
943 fl_get_key_flag(flags_key, flags_mask, &key, &mask,
944 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, FLOW_DIS_IS_FRAGMENT);
945
946 _key = cpu_to_be32(key);
947 _mask = cpu_to_be32(mask);
948
949 err = nla_put(skb, TCA_FLOWER_KEY_FLAGS, 4, &_key);
950 if (err)
951 return err;
952
953 return nla_put(skb, TCA_FLOWER_KEY_FLAGS_MASK, 4, &_mask);
954}
955
883static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,956static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
884 struct sk_buff *skb, struct tcmsg *t)957 struct sk_buff *skb, struct tcmsg *t)
885{958{
@@ -1015,6 +1088,9 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, · 129 unmodified lines
1015 sizeof(key->enc_tp.dst)))1088 sizeof(key->enc_tp.dst)))
1016 goto nla_put_failure;1089 goto nla_put_failure;
1017 1090
1091 if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
1092 goto nla_put_failure;
1093
1018 nla_put_u32(skb, TCA_FLOWER_FLAGS, f->flags);1094 nla_put_u32(skb, TCA_FLOWER_FLAGS, f->flags);
1019 1095
1020 if (tcf_exts_dump(skb, &f->exts))1096 if (tcf_exts_dump(skb, &f->exts))