X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fsched%2Fcls_api.c;h=e76951381194d26a494c099c4905b2f74cfd1598;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=a48b75d54fb94f2e5146c914dab0eb7c9aab85f4;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index a48b75d54..e76951381 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -11,6 +11,7 @@ * Changes: * * Eduardo J. Blanco :990222: kmod support + * */ #include @@ -36,6 +37,12 @@ #include #include +#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);