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
469 TCA_FLOWER_KEY_IP_TTL, /* u8 */469 TCA_FLOWER_KEY_IP_TTL, /* u8 */
470 TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */470 TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
471 471
472 TCA_FLOWER_KEY_CVLAN_ID, /* be16 */
473 TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */
474 TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */
475
472 __TCA_FLOWER_MAX,476 __TCA_FLOWER_MAX,
473};477};
474 478
net/sched/cls_flower.c+51−14
@@ -35,6 +35,7 @@ struct fl_flow_key { · 34 unmodified lines
35 struct flow_dissector_key_basic basic;35 struct flow_dissector_key_basic basic;
36 struct flow_dissector_key_eth_addrs eth;36 struct flow_dissector_key_eth_addrs eth;
37 struct flow_dissector_key_vlan vlan;37 struct flow_dissector_key_vlan vlan;
38 struct flow_dissector_key_vlan cvlan;
38 union {39 union {
39 struct flow_dissector_key_ipv4_addrs ipv4;40 struct flow_dissector_key_ipv4_addrs ipv4;
40 struct flow_dissector_key_ipv6_addrs ipv6;41 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
449 [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },450 [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },
450 [TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 },451 [TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 },
451 [TCA_FLOWER_KEY_IP_TTL_MASK] = { .type = NLA_U8 },452 [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 },
452};456};
453 457
454static void fl_set_key_val(struct nlattr **tb,458static void fl_set_key_val(struct nlattr **tb,
@@ -501,19 +505,20 @@ static int fl_set_key_mpls(struct nlattr **tb, · 46 unmodified lines
501 505
502static void fl_set_key_vlan(struct nlattr **tb,506static void fl_set_key_vlan(struct nlattr **tb,
503 __be16 ethertype,507 __be16 ethertype,
508 int vlan_id_key, int vlan_prio_key,
504 struct flow_dissector_key_vlan *key_val,509 struct flow_dissector_key_vlan *key_val,
505 struct flow_dissector_key_vlan *key_mask)510 struct flow_dissector_key_vlan *key_mask)
506{511{
507#define VLAN_PRIORITY_MASK 0x7512#define VLAN_PRIORITY_MASK 0x7
508 513
509 if (tb[TCA_FLOWER_KEY_VLAN_ID]) {514 if (tb[vlan_id_key]) {
510 key_val->vlan_id =515 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;
512 key_mask->vlan_id = VLAN_VID_MASK;517 key_mask->vlan_id = VLAN_VID_MASK;
513 }518 }
514 if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) {519 if (tb[vlan_prio_key]) {
515 key_val->vlan_priority =520 key_val->vlan_priority =
516 nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]) &521 nla_get_u8(tb[vlan_prio_key]) &
517 VLAN_PRIORITY_MASK;522 VLAN_PRIORITY_MASK;
518 key_mask->vlan_priority = VLAN_PRIORITY_MASK;523 key_mask->vlan_priority = VLAN_PRIORITY_MASK;
519 }524 }
@@ -596,11 +601,25 @@ static int fl_set_key(struct net *net, struct nlattr **tb, · 76 unmodified lines
596 ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_ETH_TYPE]);601 ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_ETH_TYPE]);
597 602
598 if (eth_type_vlan(ethertype)) {603 if (eth_type_vlan(ethertype)) {
599 fl_set_key_vlan(tb, ethertype, &key->vlan, &mask->vlan);604 fl_set_key_vlan(tb, ethertype, TCA_FLOWER_KEY_VLAN_ID,
600 fl_set_key_val(tb, &key->basic.n_proto,605 TCA_FLOWER_KEY_VLAN_PRIO, &key->vlan,
601 TCA_FLOWER_KEY_VLAN_ETH_TYPE,606 &mask->vlan);
602 &mask->basic.n_proto, TCA_FLOWER_UNSPEC,607
603 sizeof(key->basic.n_proto));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 }
604 } else {623 } else {
605 key->basic.n_proto = ethertype;624 key->basic.n_proto = ethertype;
606 mask->basic.n_proto = cpu_to_be16(~0);625 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
825 FLOW_DISSECTOR_KEY_MPLS, mpls);844 FLOW_DISSECTOR_KEY_MPLS, mpls);
826 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,845 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
827 FLOW_DISSECTOR_KEY_VLAN, vlan);846 FLOW_DISSECTOR_KEY_VLAN, vlan);
847 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
848 FLOW_DISSECTOR_KEY_CVLAN, cvlan);
828 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,849 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
829 FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);850 FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id);
830 FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,851 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
1201}1222}
1202 1223
1203static int fl_dump_key_vlan(struct sk_buff *skb,1224static int fl_dump_key_vlan(struct sk_buff *skb,
1225 int vlan_id_key, int vlan_prio_key,
1204 struct flow_dissector_key_vlan *vlan_key,1226 struct flow_dissector_key_vlan *vlan_key,
1205 struct flow_dissector_key_vlan *vlan_mask)1227 struct flow_dissector_key_vlan *vlan_mask)
1206{1228{
@@ -1209,13 +1231,13 @@ static int fl_dump_key_vlan(struct sk_buff *skb, · 2 unmodified lines
1209 if (!memchr_inv(vlan_mask, 0, sizeof(*vlan_mask)))1231 if (!memchr_inv(vlan_mask, 0, sizeof(*vlan_mask)))
1210 return 0;1232 return 0;
1211 if (vlan_mask->vlan_id) {1233 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,
1213 vlan_key->vlan_id);1235 vlan_key->vlan_id);
1214 if (err)1236 if (err)
1215 return err;1237 return err;
1216 }1238 }
1217 if (vlan_mask->vlan_priority) {1239 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,
1219 vlan_key->vlan_priority);1241 vlan_key->vlan_priority);
1220 if (err)1242 if (err)
1221 return err;1243 return err;
@@ -1310,13 +1332,28 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, · 88 unmodified lines
1310 if (fl_dump_key_mpls(skb, &key->mpls, &mask->mpls))1332 if (fl_dump_key_mpls(skb, &key->mpls, &mask->mpls))
1311 goto nla_put_failure;1333 goto nla_put_failure;
1312 1334
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))
1314 goto nla_put_failure;1337 goto nla_put_failure;
1315 1338
1316 if (mask->vlan.vlan_tpid &&1339 if (fl_dump_key_vlan(skb, TCA_FLOWER_KEY_CVLAN_ID,
1317 nla_put_be16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE, key->basic.n_proto))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)))
1318 goto nla_put_failure;1345 goto nla_put_failure;
1319 1346
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
1320 if ((key->basic.n_proto == htons(ETH_P_IP) ||1357 if ((key->basic.n_proto == htons(ETH_P_IP) ||
1321 key->basic.n_proto == htons(ETH_P_IPV6)) &&1358 key->basic.n_proto == htons(ETH_P_IPV6)) &&
1322 (fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,1359 (fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,