As support dissecting of QinQ inner and outer vlan headers, user can add rules to match on QinQ vlan headers.
Unified · Split
| @@ -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 | ||
| @@ -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 | ||
| 454 | static void fl_set_key_val(struct nlattr **tb, | 458 | 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 | |||
| 501 | 505 | ||
| 502 | static void fl_set_key_vlan(struct nlattr **tb, | 506 | static 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 0x7 | 512 | #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 | ||
| 1203 | static int fl_dump_key_vlan(struct sk_buff *skb, | 1224 | static 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, |