Skip to content

Commit 913b47d

Browse files
vbnogueiradavem330
authored andcommitted
net/sched: Introduce tc block netdev tracking infra
This commit makes tc blocks track which ports have been added to them. And, with that, we'll be able to use this new information to send packets to the block's ports. Which will be done in the patch #3 of this series. Suggested-by: Jiri Pirko <[email protected]> Co-developed-by: Jamal Hadi Salim <[email protected]> Signed-off-by: Jamal Hadi Salim <[email protected]> Co-developed-by: Pedro Tammela <[email protected]> Signed-off-by: Pedro Tammela <[email protected]> Signed-off-by: Victor Nogueira <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b1dffcf commit 913b47d

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

include/net/sch_generic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <net/gen_stats.h>
2020
#include <net/rtnetlink.h>
2121
#include <net/flow_offload.h>
22+
#include <linux/xarray.h>
2223

2324
struct Qdisc_ops;
2425
struct qdisc_walker;
@@ -456,6 +457,7 @@ struct tcf_chain {
456457
};
457458

458459
struct tcf_block {
460+
struct xarray ports; /* datapath accessible */
459461
/* Lock protects tcf_block and lifetime-management data of chains
460462
* attached to the block (refcnt, action_refcnt, explicitly_created).
461463
*/

net/sched/cls_api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ static void tcf_block_destroy(struct tcf_block *block)
531531
{
532532
mutex_destroy(&block->lock);
533533
mutex_destroy(&block->proto_destroy_lock);
534+
xa_destroy(&block->ports);
534535
kfree_rcu(block, rcu);
535536
}
536537

@@ -1002,6 +1003,7 @@ static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q,
10021003
refcount_set(&block->refcnt, 1);
10031004
block->net = net;
10041005
block->index = block_index;
1006+
xa_init(&block->ports);
10051007

10061008
/* Don't store q pointer for blocks which are shared */
10071009
if (!tcf_block_shared(block))

net/sched/sch_api.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,43 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
11801180
return 0;
11811181
}
11821182

1183+
static int qdisc_block_add_dev(struct Qdisc *sch, struct net_device *dev,
1184+
struct netlink_ext_ack *extack)
1185+
{
1186+
const struct Qdisc_class_ops *cl_ops = sch->ops->cl_ops;
1187+
struct tcf_block *block;
1188+
int err;
1189+
1190+
block = cl_ops->tcf_block(sch, TC_H_MIN_INGRESS, NULL);
1191+
if (block) {
1192+
err = xa_insert(&block->ports, dev->ifindex, dev, GFP_KERNEL);
1193+
if (err) {
1194+
NL_SET_ERR_MSG(extack,
1195+
"ingress block dev insert failed");
1196+
return err;
1197+
}
1198+
}
1199+
1200+
block = cl_ops->tcf_block(sch, TC_H_MIN_EGRESS, NULL);
1201+
if (block) {
1202+
err = xa_insert(&block->ports, dev->ifindex, dev, GFP_KERNEL);
1203+
if (err) {
1204+
NL_SET_ERR_MSG(extack,
1205+
"Egress block dev insert failed");
1206+
goto err_out;
1207+
}
1208+
}
1209+
1210+
return 0;
1211+
1212+
err_out:
1213+
block = cl_ops->tcf_block(sch, TC_H_MIN_INGRESS, NULL);
1214+
if (block)
1215+
xa_erase(&block->ports, dev->ifindex);
1216+
1217+
return err;
1218+
}
1219+
11831220
static int qdisc_block_indexes_set(struct Qdisc *sch, struct nlattr **tca,
11841221
struct netlink_ext_ack *extack)
11851222
{
@@ -1350,6 +1387,10 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
13501387
qdisc_hash_add(sch, false);
13511388
trace_qdisc_create(ops, dev, parent);
13521389

1390+
err = qdisc_block_add_dev(sch, dev, extack);
1391+
if (err)
1392+
goto err_out4;
1393+
13531394
return sch;
13541395

13551396
err_out4:

net/sched/sch_generic.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,9 @@ static void qdisc_free_cb(struct rcu_head *head)
10511051
static void __qdisc_destroy(struct Qdisc *qdisc)
10521052
{
10531053
const struct Qdisc_ops *ops = qdisc->ops;
1054+
struct net_device *dev = qdisc_dev(qdisc);
1055+
const struct Qdisc_class_ops *cops;
1056+
struct tcf_block *block;
10541057

10551058
#ifdef CONFIG_NET_SCHED
10561059
qdisc_hash_del(qdisc);
@@ -1061,11 +1064,24 @@ static void __qdisc_destroy(struct Qdisc *qdisc)
10611064

10621065
qdisc_reset(qdisc);
10631066

1067+
cops = ops->cl_ops;
1068+
if (ops->ingress_block_get) {
1069+
block = cops->tcf_block(qdisc, TC_H_MIN_INGRESS, NULL);
1070+
if (block)
1071+
xa_erase(&block->ports, dev->ifindex);
1072+
}
1073+
1074+
if (ops->egress_block_get) {
1075+
block = cops->tcf_block(qdisc, TC_H_MIN_EGRESS, NULL);
1076+
if (block)
1077+
xa_erase(&block->ports, dev->ifindex);
1078+
}
1079+
10641080
if (ops->destroy)
10651081
ops->destroy(qdisc);
10661082

10671083
module_put(ops->owner);
1068-
netdev_put(qdisc_dev(qdisc), &qdisc->dev_tracker);
1084+
netdev_put(dev, &qdisc->dev_tracker);
10691085

10701086
trace_qdisc_destroy(qdisc);
10711087

0 commit comments

Comments
 (0)