VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / net / sched / cls_api.c
index a48b75d..e769513 100644 (file)
@@ -11,6 +11,7 @@
  * Changes:
  *
  * Eduardo J. Blanco <ejbs@netlabs.com.uy> :990222: kmod support
+ *
  */
 
 #include <asm/uaccess.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
 
+#if 0 /* control */
+#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
+#else
+#define DPRINTK(format,args...)
+#endif
+
 /* The list of all installed classifier types */
 
 static struct tcf_proto_ops *tcf_proto_base;
@@ -132,7 +139,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
        struct tcf_proto_ops *tp_ops;
        struct Qdisc_class_ops *cops;
        unsigned long cl = 0;
-       unsigned long fh;
+       unsigned long fh, fh_s;
        int err;
 
        if (prio == 0) {
@@ -229,24 +236,24 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                        kfree(tp);
                        goto errout;
                }
-               write_lock(&qdisc_tree_lock);
-               spin_lock_bh(&dev->queue_lock);
+
+               qdisc_lock_tree(dev);
                tp->next = *back;
                *back = tp;
-               spin_unlock_bh(&dev->queue_lock);
-               write_unlock(&qdisc_tree_lock);
+               qdisc_unlock_tree(dev);
+
        } else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind))
                goto errout;
 
-       fh = tp->ops->get(tp, t->tcm_handle);
+       fh_s = fh = tp->ops->get(tp, t->tcm_handle);
 
        if (fh == 0) {
                if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
-                       write_lock(&qdisc_tree_lock);
-                       spin_lock_bh(&dev->queue_lock);
+                       qdisc_lock_tree(dev);
                        *back = tp->next;
-                       spin_unlock_bh(&dev->queue_lock);
-                       write_unlock(&qdisc_tree_lock);
+                       qdisc_unlock_tree(dev);
+
+                       tfilter_notify(skb, n, tp, fh_s, RTM_DELTFILTER);
                        tcf_destroy(tp);
                        err = 0;
                        goto errout;
@@ -264,6 +271,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
                        break;
                case RTM_DELTFILTER:
                        err = tp->ops->delete(tp, fh);
+                       if (err == 0)
+                               tfilter_notify(skb, n, tp, fh_s, RTM_DELTFILTER);
                        goto errout;
                case RTM_GETTFILTER:
                        err = tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER);
@@ -284,6 +293,19 @@ errout:
        return err;
 }
 
+unsigned long tcf_set_class(struct tcf_proto *tp, unsigned long *clp, 
+                           unsigned long cl)
+{
+       unsigned long old_cl;
+
+       tcf_tree_lock(tp);
+       old_cl = __cls_set_class(clp, cl);
+       tcf_tree_unlock(tp);
+
+       return old_cl;
+}
+
+
 static int
 tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
              u32 pid, u32 seq, unsigned flags, int event)
@@ -298,11 +320,14 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh,
        tcm->tcm_family = AF_UNSPEC;
        tcm->tcm_ifindex = tp->q->dev->ifindex;
        tcm->tcm_parent = tp->classid;
-       tcm->tcm_handle = 0;
        tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
        RTA_PUT(skb, TCA_KIND, IFNAMSIZ, tp->ops->kind);
-       if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0)
-               goto rtattr_failure;
+       tcm->tcm_handle = fh;
+       if (RTM_DELTFILTER != event) {
+               tcm->tcm_handle = 0;
+               if (tp->ops->dump && tp->ops->dump(tp, fh, skb, tcm) < 0)
+                       goto rtattr_failure;
+       }
        nlh->nlmsg_len = skb->tail - b;
        return skb->len;
 
@@ -362,7 +387,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
        if ((dev = dev_get_by_index(tcm->tcm_ifindex)) == NULL)
                return skb->len;
 
-       read_lock(&qdisc_tree_lock);
+       read_lock_bh(&qdisc_tree_lock);
        if (!tcm->tcm_parent)
                q = dev->qdisc_sleeping;
        else
@@ -419,7 +444,7 @@ errout:
        if (cl)
                cops->put(q, cl);
 out:
-       read_unlock(&qdisc_tree_lock);
+       read_unlock_bh(&qdisc_tree_lock);
        dev_put(dev);
        return skb->len;
 }
@@ -446,3 +471,4 @@ subsys_initcall(tc_filter_init);
 
 EXPORT_SYMBOL(register_tcf_proto_ops);
 EXPORT_SYMBOL(unregister_tcf_proto_ops);
+EXPORT_SYMBOL(tcf_set_class);