hwmon: add TI ads7871 a/d converter driver
[safe/jmp/linux-2.6] / net / sched / ematch.c
index d2b480f..5e37da9 100644 (file)
@@ -71,7 +71,7 @@
  *
  *      static void __exit exit_my_ematch(void)
  *      {
- *             return tcf_em_unregister(&my_ops);
+ *             tcf_em_unregister(&my_ops);
  *      }
  *
  *      module_init(init_my_ematch);
@@ -82,6 +82,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -154,23 +155,11 @@ EXPORT_SYMBOL(tcf_em_register);
  *
  * Returns -ENOENT if no matching ematch was found.
  */
-int tcf_em_unregister(struct tcf_ematch_ops *ops)
+void tcf_em_unregister(struct tcf_ematch_ops *ops)
 {
-       int err = 0;
-       struct tcf_ematch_ops *e;
-
        write_lock(&ematch_mod_lock);
-       list_for_each_entry(e, &ematch_ops, link) {
-               if (e == ops) {
-                       list_del(&e->link);
-                       goto out;
-               }
-       }
-
-       err = -ENOENT;
-out:
+       list_del(&ops->link);
        write_unlock(&ematch_mod_lock);
-       return err;
 }
 EXPORT_SYMBOL(tcf_em_unregister);
 
@@ -224,7 +213,7 @@ static int tcf_em_validate(struct tcf_proto *tp,
 
                if (em->ops == NULL) {
                        err = -ENOENT;
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
                        __rtnl_unlock();
                        request_module("ematch-kind-%u", em_hdr->kind);
                        rtnl_lock();
@@ -282,6 +271,11 @@ errout:
        return err;
 }
 
+static const struct nla_policy em_policy[TCA_EMATCH_TREE_MAX + 1] = {
+       [TCA_EMATCH_TREE_HDR]   = { .len = sizeof(struct tcf_ematch_tree_hdr) },
+       [TCA_EMATCH_TREE_LIST]  = { .type = NLA_NESTED },
+};
+
 /**
  * tcf_em_tree_validate - validate ematch config TLV and build ematch tree
  *
@@ -307,12 +301,11 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
        struct tcf_ematch_tree_hdr *tree_hdr;
        struct tcf_ematch *em;
 
-       if (!nla) {
-               memset(tree, 0, sizeof(*tree));
+       memset(tree, 0, sizeof(*tree));
+       if (!nla)
                return 0;
-       }
 
-       err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, NULL);
+       err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, em_policy);
        if (err < 0)
                goto errout;
 
@@ -323,10 +316,6 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
        if (rt_hdr == NULL || rt_list == NULL)
                goto errout;
 
-       if (nla_len(rt_hdr) < sizeof(*tree_hdr) ||
-           nla_len(rt_list) < sizeof(*rt_match))
-               goto errout;
-
        tree_hdr = nla_data(rt_hdr);
        memcpy(&tree->hdr, tree_hdr, sizeof(*tree_hdr));
 
@@ -409,7 +398,7 @@ void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree)
                if (em->ops) {
                        if (em->ops->destroy)
                                em->ops->destroy(tp, em);
-                       else if (!tcf_em_is_simple(em) && em->data)
+                       else if (!tcf_em_is_simple(em))
                                kfree((void *) em->data);
                        module_put(em->ops->owner);
                }
@@ -417,6 +406,7 @@ void tcf_em_tree_destroy(struct tcf_proto *tp, struct tcf_ematch_tree *tree)
 
        tree->hdr.nmatches = 0;
        kfree(tree->matches);
+       tree->matches = NULL;
 }
 EXPORT_SYMBOL(tcf_em_tree_destroy);
 
@@ -436,14 +426,18 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
 {
        int i;
        u8 *tail;
-       struct nlattr *top_start = (struct nlattr *)skb_tail_pointer(skb);
+       struct nlattr *top_start;
        struct nlattr *list_start;
 
-       NLA_PUT(skb, tlv, 0, NULL);
+       top_start = nla_nest_start(skb, tlv);
+       if (top_start == NULL)
+               goto nla_put_failure;
+
        NLA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
 
-       list_start = (struct nlattr *)skb_tail_pointer(skb);
-       NLA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL);
+       list_start = nla_nest_start(skb, TCA_EMATCH_TREE_LIST);
+       if (list_start == NULL)
+               goto nla_put_failure;
 
        tail = skb_tail_pointer(skb);
        for (i = 0; i < tree->hdr.nmatches; i++) {
@@ -470,8 +464,8 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
                match_start->nla_len = tail - (u8 *)match_start;
        }
 
-       list_start->nla_len = tail - (u8 *)list_start;
-       top_start->nla_len = tail - (u8 *)top_start;
+       nla_nest_end(skb, list_start);
+       nla_nest_end(skb, top_start);
 
        return 0;
 
@@ -533,7 +527,8 @@ pop_stack:
 
 stack_overflow:
        if (net_ratelimit())
-               printk("Local stack overflow, increase NET_EMATCH_STACK\n");
+               printk(KERN_WARNING "tc ematch: local stack overflow,"
+                       " increase NET_EMATCH_STACK\n");
        return -1;
 }
 EXPORT_SYMBOL(__tcf_em_tree_match);