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.
Unified · Split
| @@ -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 | ||
| 469 | enum { | ||
| 470 | TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), | ||
| 471 | }; | ||
| 472 | |||
| 466 | /* Match-all classifier */ | 473 | /* Match-all classifier */ |
| 467 | 474 | ||
| 468 | enum { | 475 | enum { |
| @@ -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 | ||
| 391 | static void fl_set_key_val(struct nlattr **tb, | 393 | static 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 | ||
| 425 | static 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 | |||
| 436 | static 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 | |||
| 423 | static int fl_set_key(struct net *net, struct nlattr **tb, | 458 | static 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 | ||
| 920 | static 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 | |||
| 931 | static 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 | |||
| 883 | static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, | 956 | static 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)) |