]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/sched/sch_api.c
Merge branch 'imm.timestamp' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux.git] / net / sched / sch_api.c
index 1047825d9f48d546fe1339a25f3f86979e7ac801..50794125bf0240031c142045d09b429cf945029f 100644 (file)
@@ -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