History

net/sched: flower: Add supprt for matching on QinQ vlan headers

As support dissecting of QinQ inner and outer vlan headers, user can add rules to match on QinQ vlan headers.

Jianbo Liu committed 8 years ago

Commit d64efd01 parent d3069512 files · +55 −14Browse files

Unified · Split

2 files
  1. include/uapi/linux/pkt_cls.h +4 −0
  2. net/sched/cls_flower.c +51 −14
include/uapi/linux/pkt_cls.h+4−0
@@ -469,6 +469,10 @@ enum { · 468 unmodified lines
469469 TCA_FLOWER_KEY_IP_TTL, /* u8 */
470470 TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
471471
472+ TCA_FLOWER_KEY_CVLAN_ID, /* be16 */
473+ TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */
474+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */
475+
472476 __TCA_FLOWER_MAX,
473477 };
474478
net/sched/cls_flower.c+51−14
@@ -35,6 +35,7 @@ struct fl_flow_key { · 34 unmodified lines
3535 struct flow_dissector_key_basic basic;
3636 struct flow_dissector_key_eth_addrs eth;
3737 struct flow_dissector_key_vlan vlan;
38+ struct flow_dissector_key_vlan cvlan;
3839 union {
3940 struct flow_dissector_key_ipv4_addrs ipv4;
4041 struct flow_dissector_key_ipv6_addrs ipv6;
@@ -449,6 +450,9 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { · 408 unmodified lines
449450 [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },
450451 [TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 },
451452 [TCA_FLOWER_KEY_IP_TTL_MASK] = { .type = NLA_U8 },
453+ [TCA_FLOWER_KEY_CVLAN_ID] = { .type = NLA_U16 },
454+ [TCA_FLOWER_KEY_CVLAN_PRIO] = { .type = NLA_U8 },
455+ [TCA_FLOWER_KEY_CVLAN_ETH_TYPE] = { .type = NLA_U16 },
452456 };
453457
454458 static void fl_set_key_val(struct nlattr **tb,
@@ -501,19 +505,20 @@ static int fl_set_key_mpls(struct nlattr **tb, · 46 unmodified lines
501505
502506 static void fl_set_key_vlan(struct nlattr **tb,
503507 __be16 ethertype,
508+ int vlan_id_key, int vlan_prio_key,
504509 struct flow_dissector_key_vlan *key_val,
505510 struct flow_dissector_key_vlan *key_mask)
506511 {
507512 #define VLAN_PRIORITY_MASK 0x7
508513
509− if (tb[TCA_FLOWER_KEY_VLAN_ID]) {
514+ if (tb[vlan_id_key]) {
510515 key_val->vlan_id =
511− nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ID]) & VLAN_VID_MASK;
516+ nla_get_u16(tb[vlan_id_key]) & VLAN_VID_MASK;
512517 key_mask->vlan_id = VLAN_VID_MASK;
513518 }
514− if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {
519+ if (tb[vlan_prio_key]) {
515520 key_val->vlan_priority =
516− nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]) &
521+ nla_get_u8(tb[vlan_prio_key]) &
517522 VLAN_PRIORITY_MASK;
518523 key_mask->vlan_priority = VLAN_PRIORITY_MASK;
519524 }
@@ -596,11 +601,25 @@ static int fl_set_key(struct net *net, struct nlattr **tb, · 76 unmodified lines
596601 ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_ETH_TYPE]);
597602
598603 if (eth_type_vlan(ethertype)) {
599− fl_set_key_vlan(tb, ethertype, &key->vlan, &mask->vlan);
600− fl_set_key_val(tb, &key->basic.n_proto,
601− TCA_FLOWER_KEY_VLAN_ETH_TYPE,
602− &mask->basic.n_proto, TCA_FLOWER_UNSPEC,
603− sizeof(key->basic.n_proto));
604+ fl_set_key_vlan(tb, ethertype, TCA_FLOWER_KEY_VLAN_ID,
605+ TCA_FLOWER_KEY_VLAN_PRIO, &key->vlan,
606+ &mask->vlan);
607+
608+ ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
609+ if (eth_type_vlan(ethertype)) {
610+ fl_set_key_vlan(tb, ethertype,
611+ TCA_FLOWER_KEY_CVLAN_ID,
612+ TCA_FLOWER_KEY_CVLAN_PRIO,
613+ &key->cvlan, &mask->cvlan);
614+ fl_set_key_val(tb, &key->basic.n_proto,
615+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
616+ &mask->basic.n_proto,
617+ TCA_FLOWER_UNSPEC,
618+ sizeof(key->basic.n_proto));
619+ } else {
620+ key->basic.n_proto = ethertype;
621+ mask->basic.n_proto = cpu_to_be16(~0);
622+ }
604623 } else {
605624 key->basic.n_proto = ethertype;
606625 mask->basic.n_proto = cpu_to_be16(~0);
@@ -825,6 +844,8 @@ static void fl_init_dissector(struct fl_flow_mask *mask) · 218 unmodified lines
825844 FLOW_DISSECTOR_KEY_MPLS, mpls);
826845 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
827846 FLOW_DISSECTOR_KEY_VLAN, vlan);
847+ FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
848+ FLOW_DISSECTOR_KEY_CVLAN, cvlan);
828849 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
829850 FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);
830851 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
@@ -1201,6 +1222,7 @@ static int fl_dump_key_ip(struct sk_buff *skb, · 370 unmodified lines
12011222 }
12021223
12031224 static int fl_dump_key_vlan(struct sk_buff *skb,
1225+ int vlan_id_key, int vlan_prio_key,
12041226 struct flow_dissector_key_vlan *vlan_key,
12051227 struct flow_dissector_key_vlan *vlan_mask)
12061228 {
@@ -1209,13 +1231,13 @@ static int fl_dump_key_vlan(struct sk_buff *skb, · 2 unmodified lines
12091231 if (!memchr_inv(vlan_mask, 0, sizeof(*vlan_mask)))
12101232 return 0;
12111233 if (vlan_mask->vlan_id) {
1212− err = nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ID,
1234+ err = nla_put_u16(skb, vlan_id_key,
12131235 vlan_key->vlan_id);
12141236 if (err)
12151237 return err;
12161238 }
12171239 if (vlan_mask->vlan_priority) {
1218− err = nla_put_u8(skb, TCA_FLOWER_KEY_VLAN_PRIO,
1240+ err = nla_put_u8(skb, vlan_prio_key,
12191241 vlan_key->vlan_priority);
12201242 if (err)
12211243 return err;
@@ -1310,13 +1332,28 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, · 88 unmodified lines
13101332 if (fl_dump_key_mpls(skb, &key->mpls, &mask->mpls))
13111333 goto nla_put_failure;
13121334
1313− if (fl_dump_key_vlan(skb, &key->vlan, &mask->vlan))
1335+ if (fl_dump_key_vlan(skb, TCA_FLOWER_KEY_VLAN_ID,
1336+ TCA_FLOWER_KEY_VLAN_PRIO, &key->vlan, &mask->vlan))
13141337 goto nla_put_failure;
13151338
1316− if (mask->vlan.vlan_tpid &&
1317− nla_put_be16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE, key->basic.n_proto))
1339+ if (fl_dump_key_vlan(skb, TCA_FLOWER_KEY_CVLAN_ID,
1340+ TCA_FLOWER_KEY_CVLAN_PRIO,
1341+ &key->cvlan, &mask->cvlan) ||
1342+ (mask->cvlan.vlan_tpid &&
1343+ nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE,
1344+ key->cvlan.vlan_tpid)))
13181345 goto nla_put_failure;
13191346
1347+ if (mask->cvlan.vlan_tpid) {
1348+ if (nla_put_be16(skb, TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
1349+ key->basic.n_proto))
1350+ goto nla_put_failure;
1351+ } else if (mask->vlan.vlan_tpid) {
1352+ if (nla_put_be16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE,
1353+ key->basic.n_proto))
1354+ goto nla_put_failure;
1355+ }
1356+
13201357 if ((key->basic.n_proto == htons(ETH_P_IP) ||
13211358 key->basic.n_proto == htons(ETH_P_IPV6)) &&
13221359 (fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,