netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Patch net] net_sched: walk through all child classes in tc_bind_tclass()
@ 2020-01-24  1:27 Cong Wang
  2020-01-27  9:53 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Cong Wang @ 2020-01-24  1:27 UTC (permalink / raw)
  To: netdev; +Cc: Cong Wang, Jamal Hadi Salim, Jiri Pirko

In a complex TC class hierarchy like this:

tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit         \
  avpkt 1000 cell 8
tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit  \
  rate 6Mbit weight 0.6Mbit prio 8 allot 1514 cell 8 maxburst 20      \
  avpkt 1000 bounded

tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 80 0xffff flowid 1:3
tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 25 0xffff flowid 1:4

tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit  \
  rate 5Mbit weight 0.5Mbit prio 5 allot 1514 cell 8 maxburst 20      \
  avpkt 1000
tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit  \
  rate 3Mbit weight 0.3Mbit prio 5 allot 1514 cell 8 maxburst 20      \
  avpkt 1000

where filters are installed on qdisc 1:0, so we can't merely
search from class 1:1 when creating class 1:3 and class 1:4. We have
to walk through all the child classes of the direct parent qdisc.
Otherwise we would miss filters those need reverse binding.

Fixes: 07d79fc7d94e ("net_sched: add reverse binding for tc class")
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 net/sched/sch_api.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 943ad3425380..50794125bf02 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1910,22 +1910,24 @@ static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
 	return 0;
 }
 
-static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
-			   unsigned long new_cl)
+struct tc_bind_class_args {
+	struct qdisc_walker w;
+	unsigned long new_cl;
+	u32 portid;
+	u32 clid;
+};
+
+static int tc_bind_class_walker(struct Qdisc *q, unsigned long cl,
+				struct qdisc_walker *w)
 {
+	struct tc_bind_class_args *a = (struct tc_bind_class_args *)w;
 	const struct Qdisc_class_ops *cops = q->ops->cl_ops;
 	struct tcf_block *block;
 	struct tcf_chain *chain;
-	unsigned long cl;
 
-	cl = cops->find(q, portid);
-	if (!cl)
-		return;
-	if (!cops->tcf_block)
-		return;
 	block = cops->tcf_block(q, cl, NULL);
 	if (!block)
-		return;
+		return 0;
 	for (chain = tcf_get_next_chain(block, NULL);
 	     chain;
 	     chain = tcf_get_next_chain(block, chain)) {
@@ -1936,12 +1938,29 @@ static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
 			struct tcf_bind_args arg = {};
 
 			arg.w.fn = tcf_node_bind;
-			arg.classid = clid;
+			arg.classid = a->clid;
 			arg.base = cl;
-			arg.cl = new_cl;
+			arg.cl = a->new_cl;
 			tp->ops->walk(tp, &arg.w, true);
 		}
 	}
+
+	return 0;
+}
+
+static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
+			   unsigned long new_cl)
+{
+	const struct Qdisc_class_ops *cops = q->ops->cl_ops;
+	struct tc_bind_class_args args = {};
+
+	if (!cops->tcf_block)
+		return;
+	args.portid = portid;
+	args.clid = clid;
+	args.new_cl = new_cl;
+	args.w.fn = tc_bind_class_walker;
+	q->ops->cl_ops->walk(q, &args.w);
 }
 
 #else
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Patch net] net_sched: walk through all child classes in tc_bind_tclass()
  2020-01-24  1:27 [Patch net] net_sched: walk through all child classes in tc_bind_tclass() Cong Wang
@ 2020-01-27  9:53 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2020-01-27  9:53 UTC (permalink / raw)
  To: xiyou.wangcong; +Cc: netdev, jhs, jiri

From: Cong Wang <xiyou.wangcong@gmail.com>
Date: Thu, 23 Jan 2020 17:27:08 -0800

> In a complex TC class hierarchy like this:
> 
> tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit         \
>   avpkt 1000 cell 8
> tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit  \
>   rate 6Mbit weight 0.6Mbit prio 8 allot 1514 cell 8 maxburst 20      \
>   avpkt 1000 bounded
> 
> tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
>   sport 80 0xffff flowid 1:3
> tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
>   sport 25 0xffff flowid 1:4
> 
> tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit  \
>   rate 5Mbit weight 0.5Mbit prio 5 allot 1514 cell 8 maxburst 20      \
>   avpkt 1000
> tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit  \
>   rate 3Mbit weight 0.3Mbit prio 5 allot 1514 cell 8 maxburst 20      \
>   avpkt 1000
> 
> where filters are installed on qdisc 1:0, so we can't merely
> search from class 1:1 when creating class 1:3 and class 1:4. We have
> to walk through all the child classes of the direct parent qdisc.
> Otherwise we would miss filters those need reverse binding.
> 
> Fixes: 07d79fc7d94e ("net_sched: add reverse binding for tc class")
> Cc: Jamal Hadi Salim <jhs@mojatatu.com>
> Cc: Jiri Pirko <jiri@resnulli.us>
> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>

Applied and queued up for -stable.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-01-27  9:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-24  1:27 [Patch net] net_sched: walk through all child classes in tc_bind_tclass() Cong Wang
2020-01-27  9:53 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).