diff options
Diffstat (limited to 'net/sched/sch_api.c')
| -rw-r--r-- | net/sched/sch_api.c | 47 | 
1 files changed, 34 insertions, 13 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 1047825d9f48..50794125bf02 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -1891,8 +1891,9 @@ static int tclass_del_notify(struct net *net,  struct tcf_bind_args {  	struct tcf_walker w; -	u32 classid; +	unsigned long base;  	unsigned long cl; +	u32 classid;  };  static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg) @@ -1903,28 +1904,30 @@ static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg)  		struct Qdisc *q = tcf_block_q(tp->chain->block);  		sch_tree_lock(q); -		tp->ops->bind_class(n, a->classid, a->cl); +		tp->ops->bind_class(n, a->classid, a->cl, q, a->base);  		sch_tree_unlock(q);  	}  	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)) { @@ -1935,11 +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.cl = new_cl; +			arg.classid = a->clid; +			arg.base = 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  |