* [PATCH net-next 0/5] Introduce matching on double vlan/QinQ headers for TC flower
@ 2018-06-30 9:53 Jianbo Liu
2018-06-30 9:53 ` [PATCH net-next 1/5] net/flow_dissector: Save vlan ethertype from headers Jianbo Liu
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Jianbo Liu @ 2018-06-30 9:53 UTC (permalink / raw)
To: netdev, davem, jiri; +Cc: Jianbo Liu
Currently TC flower supports only one vlan tag, it doesn't match on both outer
and inner vlan headers for QinQ. To do this, we add support to get both outer
and inner vlan headers for flow dissector, and then TC flower do matching on
those information.
We also plan to extend TC command to support this feature. We add new
cvlan_id/cvlan_prio/cvlan_ethtype keywords for inner vlan header. The existing
vlan_id/vlan_prio/vlan_ethtype are for outer vlan header, and vlan_ethtype must
be 802.1q or 802.1ad.
The examples for command and output are as the following.
# tc filter add dev ens1f1 parent ffff: protocol 802.1ad pref 33 \
flower vlan_id 1000 vlan_ethtype 802.1q \
cvlan_id 100 cvlan_ethtype ipv4 \
action vlan pop \
action vlan pop \
action mirred egress redirect dev ens1f1_0
# tc filter show dev ens1f1 ingress
filter protocol 802.1ad pref 33 flower chain 0
filter protocol 802.1ad pref 33 flower chain 0 handle 0x1
vlan_id 1000
vlan_ethtype 802.1Q
cvlan_id 100
cvlan_ethtype ip
eth_type ipv4
in_hw
...
Jianbo Liu (5):
net/flow_dissector: Save vlan ethertype from headers
net/sched: flower: Add support for matching on vlan ethertype
net/flow_dissector: Add support for QinQ dissection
net/sched: flower: Dump the ethertype encapsulated in vlan
net/sched: flower: Add supprt for matching on QinQ vlan headers
include/net/flow_dissector.h | 4 ++-
include/uapi/linux/pkt_cls.h | 4 +++
net/core/flow_dissector.c | 34 +++++++++++----------
net/sched/cls_flower.c | 70 ++++++++++++++++++++++++++++++++++++--------
4 files changed, 83 insertions(+), 29 deletions(-)
--
2.9.5
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH net-next 1/5] net/flow_dissector: Save vlan ethertype from headers 2018-06-30 9:53 [PATCH net-next 0/5] Introduce matching on double vlan/QinQ headers for TC flower Jianbo Liu @ 2018-06-30 9:53 ` Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 2/5] net/sched: flower: Add support for matching on vlan ethertype Jianbo Liu ` (3 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Jianbo Liu @ 2018-06-30 9:53 UTC (permalink / raw) To: netdev, davem, jiri Cc: Jianbo Liu, Jiri Pirko, Simon Horman, Jakub Kicinski, Tom Herbert, Paolo Abeni, John Crispin, Sven Eckelmann, WANG Cong, David Ahern, Jon Maloy Change vlan dissector key to save vlan tpid to support both 802.1Q and 802.1AD ethertype. Signed-off-by: Jianbo Liu <jianbol@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> --- include/net/flow_dissector.h | 2 +- net/core/flow_dissector.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index adc24df5..8f89968 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -47,7 +47,7 @@ struct flow_dissector_key_tags { struct flow_dissector_key_vlan { u16 vlan_id:12, vlan_priority:3; - u16 padding; + __be16 vlan_tpid; }; struct flow_dissector_key_mpls { diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 4fc1e84..e068ccf 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -751,6 +751,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb, const struct vlan_hdr *vlan; struct vlan_hdr _vlan; bool vlan_tag_present = skb && skb_vlan_tag_present(skb); + __be16 saved_vlan_tpid = proto; if (vlan_tag_present) proto = skb->protocol; @@ -789,6 +790,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb, (ntohs(vlan->h_vlan_TCI) & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; } + key_vlan->vlan_tpid = saved_vlan_tpid; } fdret = FLOW_DISSECT_RET_PROTO_AGAIN; -- 2.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 2/5] net/sched: flower: Add support for matching on vlan ethertype 2018-06-30 9:53 [PATCH net-next 0/5] Introduce matching on double vlan/QinQ headers for TC flower Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 1/5] net/flow_dissector: Save vlan ethertype from headers Jianbo Liu @ 2018-06-30 9:53 ` Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 3/5] net/flow_dissector: Add support for QinQ dissection Jianbo Liu ` (2 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Jianbo Liu @ 2018-06-30 9:53 UTC (permalink / raw) To: netdev, davem, jiri; +Cc: Jianbo Liu, Jamal Hadi Salim, Cong Wang As flow dissector stores vlan ethertype, tc flower now can match on that. It is to make preparation for supporting QinQ. Signed-off-by: Jianbo Liu <jianbol@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> --- net/sched/cls_flower.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 4e74508..e6774af 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -483,6 +483,7 @@ static int fl_set_key_mpls(struct nlattr **tb, } static void fl_set_key_vlan(struct nlattr **tb, + __be16 ethertype, struct flow_dissector_key_vlan *key_val, struct flow_dissector_key_vlan *key_mask) { @@ -499,6 +500,8 @@ static void fl_set_key_vlan(struct nlattr **tb, VLAN_PRIORITY_MASK; key_mask->vlan_priority = VLAN_PRIORITY_MASK; } + key_val->vlan_tpid = ethertype; + key_mask->vlan_tpid = cpu_to_be16(~0); } static void fl_set_key_flag(u32 flower_key, u32 flower_mask, @@ -575,8 +578,8 @@ static int fl_set_key(struct net *net, struct nlattr **tb, if (tb[TCA_FLOWER_KEY_ETH_TYPE]) { ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_ETH_TYPE]); - if (ethertype == htons(ETH_P_8021Q)) { - fl_set_key_vlan(tb, &key->vlan, &mask->vlan); + if (eth_type_vlan(ethertype)) { + fl_set_key_vlan(tb, ethertype, &key->vlan, &mask->vlan); fl_set_key_val(tb, &key->basic.n_proto, TCA_FLOWER_KEY_VLAN_ETH_TYPE, &mask->basic.n_proto, TCA_FLOWER_UNSPEC, -- 2.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 3/5] net/flow_dissector: Add support for QinQ dissection 2018-06-30 9:53 [PATCH net-next 0/5] Introduce matching on double vlan/QinQ headers for TC flower Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 1/5] net/flow_dissector: Save vlan ethertype from headers Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 2/5] net/sched: flower: Add support for matching on vlan ethertype Jianbo Liu @ 2018-06-30 9:53 ` Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 4/5] net/sched: flower: Dump the ethertype encapsulated in vlan Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 5/5] net/sched: flower: Add supprt for matching on QinQ vlan headers Jianbo Liu 4 siblings, 0 replies; 7+ messages in thread From: Jianbo Liu @ 2018-06-30 9:53 UTC (permalink / raw) To: netdev, davem, jiri Cc: Jianbo Liu, Jiri Pirko, Jon Maloy, Simon Horman, Tom Herbert, Paolo Abeni, John Crispin, Sven Eckelmann, WANG Cong, David Ahern Dissect the QinQ packets to get both outer and inner vlan information, then store to the extended flow keys. Signed-off-by: Jianbo Liu <jianbol@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> --- include/net/flow_dissector.h | 2 ++ net/core/flow_dissector.c | 32 +++++++++++++++++--------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h index 8f89968..c644067 100644 --- a/include/net/flow_dissector.h +++ b/include/net/flow_dissector.h @@ -206,6 +206,7 @@ enum flow_dissector_key_id { FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */ FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */ FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */ + FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_flow_vlan */ FLOW_DISSECTOR_KEY_MAX, }; @@ -237,6 +238,7 @@ struct flow_keys { struct flow_dissector_key_basic basic; struct flow_dissector_key_tags tags; struct flow_dissector_key_vlan vlan; + struct flow_dissector_key_vlan cvlan; struct flow_dissector_key_keyid keyid; struct flow_dissector_key_ports ports; struct flow_dissector_key_addrs addrs; diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index e068ccf..09360ae 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c @@ -589,7 +589,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb, struct flow_dissector_key_tags *key_tags; struct flow_dissector_key_vlan *key_vlan; enum flow_dissect_ret fdret; - bool skip_vlan = false; + enum flow_dissector_key_id dissector_vlan = FLOW_DISSECTOR_KEY_MAX; int num_hdrs = 0; u8 ip_proto = 0; bool ret; @@ -748,15 +748,14 @@ bool __skb_flow_dissect(const struct sk_buff *skb, } case htons(ETH_P_8021AD): case htons(ETH_P_8021Q): { - const struct vlan_hdr *vlan; + const struct vlan_hdr *vlan = NULL; struct vlan_hdr _vlan; - bool vlan_tag_present = skb && skb_vlan_tag_present(skb); __be16 saved_vlan_tpid = proto; - if (vlan_tag_present) + if (dissector_vlan == FLOW_DISSECTOR_KEY_MAX && + skb && skb_vlan_tag_present(skb)) { proto = skb->protocol; - - if (!vlan_tag_present || eth_type_vlan(skb->protocol)) { + } else { vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan); if (!vlan) { @@ -766,20 +765,23 @@ bool __skb_flow_dissect(const struct sk_buff *skb, proto = vlan->h_vlan_encapsulated_proto; nhoff += sizeof(*vlan); - if (skip_vlan) { - fdret = FLOW_DISSECT_RET_PROTO_AGAIN; - break; - } } - skip_vlan = true; - if (dissector_uses_key(flow_dissector, - FLOW_DISSECTOR_KEY_VLAN)) { + if (dissector_vlan == FLOW_DISSECTOR_KEY_MAX) { + dissector_vlan = FLOW_DISSECTOR_KEY_VLAN; + } else if (dissector_vlan == FLOW_DISSECTOR_KEY_VLAN) { + dissector_vlan = FLOW_DISSECTOR_KEY_CVLAN; + } else { + fdret = FLOW_DISSECT_RET_PROTO_AGAIN; + break; + } + + if (dissector_uses_key(flow_dissector, dissector_vlan)) { key_vlan = skb_flow_dissector_target(flow_dissector, - FLOW_DISSECTOR_KEY_VLAN, + dissector_vlan, target_container); - if (vlan_tag_present) { + if (!vlan) { key_vlan->vlan_id = skb_vlan_tag_get_id(skb); key_vlan->vlan_priority = (skb_vlan_tag_get_prio(skb) >> VLAN_PRIO_SHIFT); -- 2.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 4/5] net/sched: flower: Dump the ethertype encapsulated in vlan 2018-06-30 9:53 [PATCH net-next 0/5] Introduce matching on double vlan/QinQ headers for TC flower Jianbo Liu ` (2 preceding siblings ...) 2018-06-30 9:53 ` [PATCH net-next 3/5] net/flow_dissector: Add support for QinQ dissection Jianbo Liu @ 2018-06-30 9:53 ` Jianbo Liu 2018-06-30 12:54 ` kbuild test robot 2018-06-30 9:53 ` [PATCH net-next 5/5] net/sched: flower: Add supprt for matching on QinQ vlan headers Jianbo Liu 4 siblings, 1 reply; 7+ messages in thread From: Jianbo Liu @ 2018-06-30 9:53 UTC (permalink / raw) To: netdev, davem, jiri; +Cc: Jianbo Liu, Jamal Hadi Salim, Cong Wang Currently the encapsulated ethertype is not dumped as it's the same as TCA_FLOWER_KEY_ETH_TYPE keyvalue. But the dumping result is inconsistent with input, we add dumping it with TCA_FLOWER_KEY_VLAN_ETH_TYPE. Signed-off-by: Jianbo Liu <jianbol@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> --- net/sched/cls_flower.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index e6774af..30f3e18 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -1255,6 +1255,10 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, if (fl_dump_key_vlan(skb, &key->vlan, &mask->vlan)) goto nla_put_failure; + if (mask->vlan.vlan_tpid && + nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE, key->basic.n_proto)) + goto nla_put_failure; + if ((key->basic.n_proto == htons(ETH_P_IP) || key->basic.n_proto == htons(ETH_P_IPV6)) && (fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO, -- 2.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net-next 4/5] net/sched: flower: Dump the ethertype encapsulated in vlan 2018-06-30 9:53 ` [PATCH net-next 4/5] net/sched: flower: Dump the ethertype encapsulated in vlan Jianbo Liu @ 2018-06-30 12:54 ` kbuild test robot 0 siblings, 0 replies; 7+ messages in thread From: kbuild test robot @ 2018-06-30 12:54 UTC (permalink / raw) To: Jianbo Liu Cc: kbuild-all, netdev, davem, jiri, Jianbo Liu, Jamal Hadi Salim, Cong Wang Hi Jianbo, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on net-next/master] url: https://github.com/0day-ci/linux/commits/Jianbo-Liu/net-flow_dissector-Save-vlan-ethertype-from-headers/20180630-180158 reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) net/sched/cls_flower.c:544:15: sparse: cast to restricted __be32 net/sched/cls_flower.c:544:15: sparse: cast to restricted __be32 net/sched/cls_flower.c:544:15: sparse: cast to restricted __be32 net/sched/cls_flower.c:544:15: sparse: cast to restricted __be32 net/sched/cls_flower.c:544:15: sparse: cast to restricted __be32 net/sched/cls_flower.c:544:15: sparse: cast to restricted __be32 net/sched/cls_flower.c:545:16: sparse: cast to restricted __be32 net/sched/cls_flower.c:545:16: sparse: cast to restricted __be32 net/sched/cls_flower.c:545:16: sparse: cast to restricted __be32 net/sched/cls_flower.c:545:16: sparse: cast to restricted __be32 net/sched/cls_flower.c:545:16: sparse: cast to restricted __be32 net/sched/cls_flower.c:545:16: sparse: cast to restricted __be32 include/linux/slab.h:631:13: sparse: undefined identifier '__builtin_mul_overflow' include/linux/slab.h:631:13: sparse: not a function <noident> >> net/sched/cls_flower.c:1317:70: sparse: incorrect type in argument 3 (different base types) @@ expected unsigned short [unsigned] [usertype] value @@ got short [unsigned] [usertype] value @@ net/sched/cls_flower.c:1317:70: expected unsigned short [unsigned] [usertype] value net/sched/cls_flower.c:1317:70: got restricted __be16 [usertype] n_proto include/linux/slab.h:631:13: sparse: call with no type! vim +1317 net/sched/cls_flower.c 1264 1265 static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, 1266 struct sk_buff *skb, struct tcmsg *t) 1267 { 1268 struct cls_fl_filter *f = fh; 1269 struct nlattr *nest; 1270 struct fl_flow_key *key, *mask; 1271 1272 if (!f) 1273 return skb->len; 1274 1275 t->tcm_handle = f->handle; 1276 1277 nest = nla_nest_start(skb, TCA_OPTIONS); 1278 if (!nest) 1279 goto nla_put_failure; 1280 1281 if (f->res.classid && 1282 nla_put_u32(skb, TCA_FLOWER_CLASSID, f->res.classid)) 1283 goto nla_put_failure; 1284 1285 key = &f->key; 1286 mask = &f->mask->key; 1287 1288 if (mask->indev_ifindex) { 1289 struct net_device *dev; 1290 1291 dev = __dev_get_by_index(net, key->indev_ifindex); 1292 if (dev && nla_put_string(skb, TCA_FLOWER_INDEV, dev->name)) 1293 goto nla_put_failure; 1294 } 1295 1296 if (!tc_skip_hw(f->flags)) 1297 fl_hw_update_stats(tp, f); 1298 1299 if (fl_dump_key_val(skb, key->eth.dst, TCA_FLOWER_KEY_ETH_DST, 1300 mask->eth.dst, TCA_FLOWER_KEY_ETH_DST_MASK, 1301 sizeof(key->eth.dst)) || 1302 fl_dump_key_val(skb, key->eth.src, TCA_FLOWER_KEY_ETH_SRC, 1303 mask->eth.src, TCA_FLOWER_KEY_ETH_SRC_MASK, 1304 sizeof(key->eth.src)) || 1305 fl_dump_key_val(skb, &key->basic.n_proto, TCA_FLOWER_KEY_ETH_TYPE, 1306 &mask->basic.n_proto, TCA_FLOWER_UNSPEC, 1307 sizeof(key->basic.n_proto))) 1308 goto nla_put_failure; 1309 1310 if (fl_dump_key_mpls(skb, &key->mpls, &mask->mpls)) 1311 goto nla_put_failure; 1312 1313 if (fl_dump_key_vlan(skb, &key->vlan, &mask->vlan)) 1314 goto nla_put_failure; 1315 1316 if (mask->vlan.vlan_tpid && > 1317 nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE, key->basic.n_proto)) 1318 goto nla_put_failure; 1319 1320 if ((key->basic.n_proto == htons(ETH_P_IP) || 1321 key->basic.n_proto == htons(ETH_P_IPV6)) && 1322 (fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO, 1323 &mask->basic.ip_proto, TCA_FLOWER_UNSPEC, 1324 sizeof(key->basic.ip_proto)) || 1325 fl_dump_key_ip(skb, &key->ip, &mask->ip))) 1326 goto nla_put_failure; 1327 1328 if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS && 1329 (fl_dump_key_val(skb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC, 1330 &mask->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC_MASK, 1331 sizeof(key->ipv4.src)) || 1332 fl_dump_key_val(skb, &key->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST, 1333 &mask->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST_MASK, 1334 sizeof(key->ipv4.dst)))) 1335 goto nla_put_failure; 1336 else if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS && 1337 (fl_dump_key_val(skb, &key->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC, 1338 &mask->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC_MASK, 1339 sizeof(key->ipv6.src)) || 1340 fl_dump_key_val(skb, &key->ipv6.dst, TCA_FLOWER_KEY_IPV6_DST, 1341 &mask->ipv6.dst, TCA_FLOWER_KEY_IPV6_DST_MASK, 1342 sizeof(key->ipv6.dst)))) 1343 goto nla_put_failure; 1344 1345 if (key->basic.ip_proto == IPPROTO_TCP && 1346 (fl_dump_key_val(skb, &key->tp.src, TCA_FLOWER_KEY_TCP_SRC, 1347 &mask->tp.src, TCA_FLOWER_KEY_TCP_SRC_MASK, 1348 sizeof(key->tp.src)) || 1349 fl_dump_key_val(skb, &key->tp.dst, TCA_FLOWER_KEY_TCP_DST, 1350 &mask->tp.dst, TCA_FLOWER_KEY_TCP_DST_MASK, 1351 sizeof(key->tp.dst)) || 1352 fl_dump_key_val(skb, &key->tcp.flags, TCA_FLOWER_KEY_TCP_FLAGS, 1353 &mask->tcp.flags, TCA_FLOWER_KEY_TCP_FLAGS_MASK, 1354 sizeof(key->tcp.flags)))) 1355 goto nla_put_failure; 1356 else if (key->basic.ip_proto == IPPROTO_UDP && 1357 (fl_dump_key_val(skb, &key->tp.src, TCA_FLOWER_KEY_UDP_SRC, 1358 &mask->tp.src, TCA_FLOWER_KEY_UDP_SRC_MASK, 1359 sizeof(key->tp.src)) || 1360 fl_dump_key_val(skb, &key->tp.dst, TCA_FLOWER_KEY_UDP_DST, 1361 &mask->tp.dst, TCA_FLOWER_KEY_UDP_DST_MASK, 1362 sizeof(key->tp.dst)))) 1363 goto nla_put_failure; 1364 else if (key->basic.ip_proto == IPPROTO_SCTP && 1365 (fl_dump_key_val(skb, &key->tp.src, TCA_FLOWER_KEY_SCTP_SRC, 1366 &mask->tp.src, TCA_FLOWER_KEY_SCTP_SRC_MASK, 1367 sizeof(key->tp.src)) || 1368 fl_dump_key_val(skb, &key->tp.dst, TCA_FLOWER_KEY_SCTP_DST, 1369 &mask->tp.dst, TCA_FLOWER_KEY_SCTP_DST_MASK, 1370 sizeof(key->tp.dst)))) 1371 goto nla_put_failure; 1372 else if (key->basic.n_proto == htons(ETH_P_IP) && 1373 key->basic.ip_proto == IPPROTO_ICMP && 1374 (fl_dump_key_val(skb, &key->icmp.type, 1375 TCA_FLOWER_KEY_ICMPV4_TYPE, &mask->icmp.type, 1376 TCA_FLOWER_KEY_ICMPV4_TYPE_MASK, 1377 sizeof(key->icmp.type)) || 1378 fl_dump_key_val(skb, &key->icmp.code, 1379 TCA_FLOWER_KEY_ICMPV4_CODE, &mask->icmp.code, 1380 TCA_FLOWER_KEY_ICMPV4_CODE_MASK, 1381 sizeof(key->icmp.code)))) 1382 goto nla_put_failure; 1383 else if (key->basic.n_proto == htons(ETH_P_IPV6) && 1384 key->basic.ip_proto == IPPROTO_ICMPV6 && 1385 (fl_dump_key_val(skb, &key->icmp.type, 1386 TCA_FLOWER_KEY_ICMPV6_TYPE, &mask->icmp.type, 1387 TCA_FLOWER_KEY_ICMPV6_TYPE_MASK, 1388 sizeof(key->icmp.type)) || 1389 fl_dump_key_val(skb, &key->icmp.code, 1390 TCA_FLOWER_KEY_ICMPV6_CODE, &mask->icmp.code, 1391 TCA_FLOWER_KEY_ICMPV6_CODE_MASK, 1392 sizeof(key->icmp.code)))) 1393 goto nla_put_failure; 1394 else if ((key->basic.n_proto == htons(ETH_P_ARP) || 1395 key->basic.n_proto == htons(ETH_P_RARP)) && 1396 (fl_dump_key_val(skb, &key->arp.sip, 1397 TCA_FLOWER_KEY_ARP_SIP, &mask->arp.sip, 1398 TCA_FLOWER_KEY_ARP_SIP_MASK, 1399 sizeof(key->arp.sip)) || 1400 fl_dump_key_val(skb, &key->arp.tip, 1401 TCA_FLOWER_KEY_ARP_TIP, &mask->arp.tip, 1402 TCA_FLOWER_KEY_ARP_TIP_MASK, 1403 sizeof(key->arp.tip)) || 1404 fl_dump_key_val(skb, &key->arp.op, 1405 TCA_FLOWER_KEY_ARP_OP, &mask->arp.op, 1406 TCA_FLOWER_KEY_ARP_OP_MASK, 1407 sizeof(key->arp.op)) || 1408 fl_dump_key_val(skb, key->arp.sha, TCA_FLOWER_KEY_ARP_SHA, 1409 mask->arp.sha, TCA_FLOWER_KEY_ARP_SHA_MASK, 1410 sizeof(key->arp.sha)) || 1411 fl_dump_key_val(skb, key->arp.tha, TCA_FLOWER_KEY_ARP_THA, 1412 mask->arp.tha, TCA_FLOWER_KEY_ARP_THA_MASK, 1413 sizeof(key->arp.tha)))) 1414 goto nla_put_failure; 1415 1416 if (key->enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS && 1417 (fl_dump_key_val(skb, &key->enc_ipv4.src, 1418 TCA_FLOWER_KEY_ENC_IPV4_SRC, &mask->enc_ipv4.src, 1419 TCA_FLOWER_KEY_ENC_IPV4_SRC_MASK, 1420 sizeof(key->enc_ipv4.src)) || 1421 fl_dump_key_val(skb, &key->enc_ipv4.dst, 1422 TCA_FLOWER_KEY_ENC_IPV4_DST, &mask->enc_ipv4.dst, 1423 TCA_FLOWER_KEY_ENC_IPV4_DST_MASK, 1424 sizeof(key->enc_ipv4.dst)))) 1425 goto nla_put_failure; 1426 else if (key->enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS && 1427 (fl_dump_key_val(skb, &key->enc_ipv6.src, 1428 TCA_FLOWER_KEY_ENC_IPV6_SRC, &mask->enc_ipv6.src, 1429 TCA_FLOWER_KEY_ENC_IPV6_SRC_MASK, 1430 sizeof(key->enc_ipv6.src)) || 1431 fl_dump_key_val(skb, &key->enc_ipv6.dst, 1432 TCA_FLOWER_KEY_ENC_IPV6_DST, 1433 &mask->enc_ipv6.dst, 1434 TCA_FLOWER_KEY_ENC_IPV6_DST_MASK, 1435 sizeof(key->enc_ipv6.dst)))) 1436 goto nla_put_failure; 1437 1438 if (fl_dump_key_val(skb, &key->enc_key_id, TCA_FLOWER_KEY_ENC_KEY_ID, 1439 &mask->enc_key_id, TCA_FLOWER_UNSPEC, 1440 sizeof(key->enc_key_id)) || 1441 fl_dump_key_val(skb, &key->enc_tp.src, 1442 TCA_FLOWER_KEY_ENC_UDP_SRC_PORT, 1443 &mask->enc_tp.src, 1444 TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK, 1445 sizeof(key->enc_tp.src)) || 1446 fl_dump_key_val(skb, &key->enc_tp.dst, 1447 TCA_FLOWER_KEY_ENC_UDP_DST_PORT, 1448 &mask->enc_tp.dst, 1449 TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK, 1450 sizeof(key->enc_tp.dst))) 1451 goto nla_put_failure; 1452 1453 if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags)) 1454 goto nla_put_failure; 1455 1456 if (f->flags && nla_put_u32(skb, TCA_FLOWER_FLAGS, f->flags)) 1457 goto nla_put_failure; 1458 1459 if (tcf_exts_dump(skb, &f->exts)) 1460 goto nla_put_failure; 1461 1462 nla_nest_end(skb, nest); 1463 1464 if (tcf_exts_dump_stats(skb, &f->exts) < 0) 1465 goto nla_put_failure; 1466 1467 return skb->len; 1468 1469 nla_put_failure: 1470 nla_nest_cancel(skb, nest); 1471 return -1; 1472 } 1473 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net-next 5/5] net/sched: flower: Add supprt for matching on QinQ vlan headers 2018-06-30 9:53 [PATCH net-next 0/5] Introduce matching on double vlan/QinQ headers for TC flower Jianbo Liu ` (3 preceding siblings ...) 2018-06-30 9:53 ` [PATCH net-next 4/5] net/sched: flower: Dump the ethertype encapsulated in vlan Jianbo Liu @ 2018-06-30 9:53 ` Jianbo Liu 4 siblings, 0 replies; 7+ messages in thread From: Jianbo Liu @ 2018-06-30 9:53 UTC (permalink / raw) To: netdev, davem, jiri; +Cc: Jianbo Liu, Jamal Hadi Salim, Cong Wang As support dissecting of QinQ inner and outer vlan headers, user can add rules to match on QinQ vlan headers. Signed-off-by: Jianbo Liu <jianbol@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> --- include/uapi/linux/pkt_cls.h | 4 +++ net/sched/cls_flower.c | 65 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h index 84e4c1d..c4262d9 100644 --- a/include/uapi/linux/pkt_cls.h +++ b/include/uapi/linux/pkt_cls.h @@ -469,6 +469,10 @@ enum { TCA_FLOWER_KEY_IP_TTL, /* u8 */ TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */ + TCA_FLOWER_KEY_CVLAN_ID, /* be16 */ + TCA_FLOWER_KEY_CVLAN_PRIO, /* u8 */ + TCA_FLOWER_KEY_CVLAN_ETH_TYPE, /* be16 */ + __TCA_FLOWER_MAX, }; diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 30f3e18..e3ecffd 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -35,6 +35,7 @@ struct fl_flow_key { struct flow_dissector_key_basic basic; struct flow_dissector_key_eth_addrs eth; struct flow_dissector_key_vlan vlan; + struct flow_dissector_key_vlan cvlan; union { struct flow_dissector_key_ipv4_addrs ipv4; struct flow_dissector_key_ipv6_addrs ipv6; @@ -432,6 +433,9 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { [TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 }, [TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 }, [TCA_FLOWER_KEY_IP_TTL_MASK] = { .type = NLA_U8 }, + [TCA_FLOWER_KEY_CVLAN_ID] = { .type = NLA_U16 }, + [TCA_FLOWER_KEY_CVLAN_PRIO] = { .type = NLA_U8 }, + [TCA_FLOWER_KEY_CVLAN_ETH_TYPE] = { .type = NLA_U16 }, }; static void fl_set_key_val(struct nlattr **tb, @@ -484,19 +488,20 @@ static int fl_set_key_mpls(struct nlattr **tb, static void fl_set_key_vlan(struct nlattr **tb, __be16 ethertype, + int vlan_id_key, int vlan_prio_key, struct flow_dissector_key_vlan *key_val, struct flow_dissector_key_vlan *key_mask) { #define VLAN_PRIORITY_MASK 0x7 - if (tb[TCA_FLOWER_KEY_VLAN_ID]) { + if (tb[vlan_id_key]) { key_val->vlan_id = - nla_get_u16(tb[TCA_FLOWER_KEY_VLAN_ID]) & VLAN_VID_MASK; + nla_get_u16(tb[vlan_id_key]) & VLAN_VID_MASK; key_mask->vlan_id = VLAN_VID_MASK; } - if (tb[TCA_FLOWER_KEY_VLAN_PRIO]) { + if (tb[vlan_prio_key]) { key_val->vlan_priority = - nla_get_u8(tb[TCA_FLOWER_KEY_VLAN_PRIO]) & + nla_get_u8(tb[vlan_prio_key]) & VLAN_PRIORITY_MASK; key_mask->vlan_priority = VLAN_PRIORITY_MASK; } @@ -579,11 +584,25 @@ static int fl_set_key(struct net *net, struct nlattr **tb, ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_ETH_TYPE]); if (eth_type_vlan(ethertype)) { - fl_set_key_vlan(tb, ethertype, &key->vlan, &mask->vlan); - fl_set_key_val(tb, &key->basic.n_proto, - TCA_FLOWER_KEY_VLAN_ETH_TYPE, - &mask->basic.n_proto, TCA_FLOWER_UNSPEC, - sizeof(key->basic.n_proto)); + fl_set_key_vlan(tb, ethertype, TCA_FLOWER_KEY_VLAN_ID, + TCA_FLOWER_KEY_VLAN_PRIO, &key->vlan, + &mask->vlan); + + ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]); + if (eth_type_vlan(ethertype)) { + fl_set_key_vlan(tb, ethertype, + TCA_FLOWER_KEY_CVLAN_ID, + TCA_FLOWER_KEY_CVLAN_PRIO, + &key->cvlan, &mask->cvlan); + fl_set_key_val(tb, &key->basic.n_proto, + TCA_FLOWER_KEY_CVLAN_ETH_TYPE, + &mask->basic.n_proto, + TCA_FLOWER_UNSPEC, + sizeof(key->basic.n_proto)); + } else { + key->basic.n_proto = ethertype; + mask->basic.n_proto = cpu_to_be16(~0); + } } else { key->basic.n_proto = ethertype; mask->basic.n_proto = cpu_to_be16(~0); @@ -809,6 +828,8 @@ static void fl_init_dissector(struct fl_flow_mask *mask) FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, FLOW_DISSECTOR_KEY_VLAN, vlan); FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, + FLOW_DISSECTOR_KEY_CVLAN, cvlan); + FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, FLOW_DISSECTOR_KEY_ENC_KEYID, enc_key_id); FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, enc_ipv4); @@ -1143,6 +1164,7 @@ static int fl_dump_key_ip(struct sk_buff *skb, } static int fl_dump_key_vlan(struct sk_buff *skb, + int vlan_id_key, int vlan_prio_key, struct flow_dissector_key_vlan *vlan_key, struct flow_dissector_key_vlan *vlan_mask) { @@ -1151,13 +1173,13 @@ static int fl_dump_key_vlan(struct sk_buff *skb, if (!memchr_inv(vlan_mask, 0, sizeof(*vlan_mask))) return 0; if (vlan_mask->vlan_id) { - err = nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ID, + err = nla_put_u16(skb, vlan_id_key, vlan_key->vlan_id); if (err) return err; } if (vlan_mask->vlan_priority) { - err = nla_put_u8(skb, TCA_FLOWER_KEY_VLAN_PRIO, + err = nla_put_u8(skb, vlan_prio_key, vlan_key->vlan_priority); if (err) return err; @@ -1252,13 +1274,28 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh, if (fl_dump_key_mpls(skb, &key->mpls, &mask->mpls)) goto nla_put_failure; - if (fl_dump_key_vlan(skb, &key->vlan, &mask->vlan)) + if (fl_dump_key_vlan(skb, TCA_FLOWER_KEY_VLAN_ID, + TCA_FLOWER_KEY_VLAN_PRIO, &key->vlan, &mask->vlan)) goto nla_put_failure; - if (mask->vlan.vlan_tpid && - nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE, key->basic.n_proto)) + if (fl_dump_key_vlan(skb, TCA_FLOWER_KEY_CVLAN_ID, + TCA_FLOWER_KEY_CVLAN_PRIO, + &key->cvlan, &mask->cvlan) || + (mask->cvlan.vlan_tpid && + nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE, + key->cvlan.vlan_tpid))) goto nla_put_failure; + if (mask->cvlan.vlan_tpid) { + if (nla_put_u16(skb, TCA_FLOWER_KEY_CVLAN_ETH_TYPE, + key->basic.n_proto)) + goto nla_put_failure; + } else if (mask->vlan.vlan_tpid) { + if (nla_put_u16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE, + key->basic.n_proto)) + goto nla_put_failure; + } + if ((key->basic.n_proto == htons(ETH_P_IP) || key->basic.n_proto == htons(ETH_P_IPV6)) && (fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO, -- 2.9.5 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-06-30 12:40 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-06-30 9:53 [PATCH net-next 0/5] Introduce matching on double vlan/QinQ headers for TC flower Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 1/5] net/flow_dissector: Save vlan ethertype from headers Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 2/5] net/sched: flower: Add support for matching on vlan ethertype Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 3/5] net/flow_dissector: Add support for QinQ dissection Jianbo Liu 2018-06-30 9:53 ` [PATCH net-next 4/5] net/sched: flower: Dump the ethertype encapsulated in vlan Jianbo Liu 2018-06-30 12:54 ` kbuild test robot 2018-06-30 9:53 ` [PATCH net-next 5/5] net/sched: flower: Add supprt for matching on QinQ vlan headers Jianbo Liu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox