Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.25-rc7 /net/sched/ematch.c

Filename:/net/sched/ematch.c
Lines Added:55
Lines Deleted:49
Also changed in: (Previous) 2.6.25-rc6  2.6.25-rc5  2.6.25-rc4  2.6.25-rc3  2.6.25-rc2  2.6.25-rc1 
(Following) 2.6.25-rc8  2.6.25-rc9  2.6.25  2.6.27-git8  2.6.27-git9  2.6.27-git10 

Location
[  2.6.25-rc7
  [  net
    [  sched
       o  ematch.c

Patch

diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index f3a104e..5e6f82e 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -141,6 +141,7 @@ errout:
    write_unlock(&ematch_mod_lock);
    return err;
 }
+EXPORT_SYMBOL(tcf_em_register);
 
 /**
  * tcf_em_unregister - unregster and extended match
@@ -171,6 +172,7 @@ out:
    write_unlock(&ematch_mod_lock);
    return err;
 }
+EXPORT_SYMBOL(tcf_em_unregister);
 
 static inline struct tcf_ematch * tcf_em_get_match(struct tcf_ematch_tree *tree,
                      int index)
@@ -181,11 +183,11 @@ static inline struct tcf_ematch * tcf_em_get_match(struct tcf_ematch_tree *tree,
 
 static int tcf_em_validate(struct tcf_proto *tp,
             struct tcf_ematch_tree_hdr *tree_hdr,
-            struct tcf_ematch *em, struct rtattr *rta, int idx)
+            struct tcf_ematch *em, struct nlattr *nla, int idx)
 {
    int err = -EINVAL;
-   struct tcf_ematch_hdr *em_hdr = RTA_DATA(rta);
-   int data_len = RTA_PAYLOAD(rta) - sizeof(*em_hdr);
+   struct tcf_ematch_hdr *em_hdr = nla_data(nla);
+   int data_len = nla_len(nla) - sizeof(*em_hdr);
    void *data = (void *) em_hdr + sizeof(*em_hdr);
 
    if (!TCF_EM_REL_VALID(em_hdr->flags))
@@ -280,15 +282,20 @@ 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
  *
  * @tp: classifier kind handle
- * @rta: ematch tree configuration TLV
+ * @nla: ematch tree configuration TLV
  * @tree: destination ematch tree variable to store the resulting
  *        ematch tree.
  *
- * This function validates the given configuration TLV @rta and builds an
+ * This function validates the given configuration TLV @nla and builds an
  * ematch tree in @tree. The resulting tree must later be copied into
  * the private classifier data using tcf_em_tree_change(). You MUST NOT
  * provide the ematch tree variable of the private classifier data directly,
@@ -296,45 +303,42 @@ errout:
  *
  * Returns a negative error code if the configuration TLV contains errors.
  */
-int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
+int tcf_em_tree_validate(struct tcf_proto *tp, struct nlattr *nla,
           struct tcf_ematch_tree *tree)
 {
-   int idx, list_len, matches_len, err = -EINVAL;
-   struct rtattr *tb[TCA_EMATCH_TREE_MAX];
-   struct rtattr *rt_match, *rt_hdr, *rt_list;
+   int idx, list_len, matches_len, err;
+   struct nlattr *tb[TCA_EMATCH_TREE_MAX + 1];
+   struct nlattr *rt_match, *rt_hdr, *rt_list;
    struct tcf_ematch_tree_hdr *tree_hdr;
    struct tcf_ematch *em;
 
-   if (!rta) {
-      memset(tree, 0, sizeof(*tree));
+   memset(tree, 0, sizeof(*tree));
+   if (!nla)
       return 0;
-   }
 
-   if (rtattr_parse_nested(tb, TCA_EMATCH_TREE_MAX, rta) < 0)
+   err = nla_parse_nested(tb, TCA_EMATCH_TREE_MAX, nla, em_policy);
+   if (err < 0)
       goto errout;
 
-   rt_hdr = tb[TCA_EMATCH_TREE_HDR-1];
-   rt_list = tb[TCA_EMATCH_TREE_LIST-1];
+   err = -EINVAL;
+   rt_hdr = tb[TCA_EMATCH_TREE_HDR];
+   rt_list = tb[TCA_EMATCH_TREE_LIST];
 
    if (rt_hdr == NULL || rt_list == NULL)
       goto errout;
 
-   if (RTA_PAYLOAD(rt_hdr) < sizeof(*tree_hdr) ||
-       RTA_PAYLOAD(rt_list) < sizeof(*rt_match))
-      goto errout;
-
-   tree_hdr = RTA_DATA(rt_hdr);
+   tree_hdr = nla_data(rt_hdr);
    memcpy(&tree->hdr, tree_hdr, sizeof(*tree_hdr));
 
-   rt_match = RTA_DATA(rt_list);
-   list_len = RTA_PAYLOAD(rt_list);
+   rt_match = nla_data(rt_list);
+   list_len = nla_len(rt_list);
    matches_len = tree_hdr->nmatches * sizeof(*em);
 
    tree->matches = kzalloc(matches_len, GFP_KERNEL);
    if (tree->matches == NULL)
       goto errout;
 
-   /* We do not use rtattr_parse_nested here because the maximum
+   /* We do not use nla_parse_nested here because the maximum
     * number of attributes is unknown. This saves us the allocation
     * for a tb buffer which would serve no purpose at all.
     *
@@ -342,16 +346,16 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
     * provided, their type must be incremental from 1 to n. Even
     * if it does not serve any real purpose, a failure of sticking
     * to this policy will result in parsing failure. */
-   for (idx = 0; RTA_OK(rt_match, list_len); idx++) {
+   for (idx = 0; nla_ok(rt_match, list_len); idx++) {
       err = -EINVAL;
 
-      if (rt_match->rta_type != (idx + 1))
+      if (rt_match->nla_type != (idx + 1))
          goto errout_abort;
 
       if (idx >= tree_hdr->nmatches)
          goto errout_abort;
 
-      if (RTA_PAYLOAD(rt_match) < sizeof(struct tcf_ematch_hdr))
+      if (nla_len(rt_match) < sizeof(struct tcf_ematch_hdr))
          goto errout_abort;
 
       em = tcf_em_get_match(tree, idx);
@@ -360,7 +364,7 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta,
       if (err < 0)
          goto errout_abort;
 
-      rt_match = RTA_NEXT(rt_match, list_len);
+      rt_match = nla_next(rt_match, &list_len);
    }
 
    /* Check if the number of matches provided by userspace actually
@@ -380,6 +384,7 @@ errout_abort:
    tcf_em_tree_destroy(tp, tree);
    return err;
 }
+EXPORT_SYMBOL(tcf_em_tree_validate);
 
 /**
  * tcf_em_tree_destroy - destroy an ematch tree
@@ -404,7 +409,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);
       }
@@ -412,7 +417,9 @@ 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);
 
 /**
  * tcf_em_tree_dump - dump ematch tree into a rtnl message
@@ -430,18 +437,22 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
 {
    int i;
    u8 *tail;
-   struct rtattr *top_start = (struct rtattr *)skb_tail_pointer(skb);
-   struct rtattr *list_start;
+   struct nlattr *top_start;
+   struct nlattr *list_start;
 
-   RTA_PUT(skb, tlv, 0, NULL);
-   RTA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
+   top_start = nla_nest_start(skb, tlv);
+   if (top_start == NULL)
+      goto nla_put_failure;
 
-   list_start = (struct rtattr *)skb_tail_pointer(skb);
-   RTA_PUT(skb, TCA_EMATCH_TREE_LIST, 0, NULL);
+   NLA_PUT(skb, TCA_EMATCH_TREE_HDR, sizeof(tree->hdr), &tree->hdr);
+
+   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++) {
-      struct rtattr *match_start = (struct rtattr *)tail;
+      struct nlattr *match_start = (struct nlattr *)tail;
       struct tcf_ematch *em = tcf_em_get_match(tree, i);
       struct tcf_ematch_hdr em_hdr = {
          .kind = em->ops ? em->ops->kind : TCF_EM_CONTAINER,
@@ -449,29 +460,30 @@ int tcf_em_tree_dump(struct sk_buff *skb, struct tcf_ematch_tree *tree, int tlv)
          .flags = em->flags
       };
 
-      RTA_PUT(skb, i+1, sizeof(em_hdr), &em_hdr);
+      NLA_PUT(skb, i+1, sizeof(em_hdr), &em_hdr);
 
       if (em->ops && em->ops->dump) {
          if (em->ops->dump(skb, em) < 0)
-            goto rtattr_failure;
+            goto nla_put_failure;
       } else if (tcf_em_is_container(em) || tcf_em_is_simple(em)) {
          u32 u = em->data;
-         RTA_PUT_NOHDR(skb, sizeof(u), &u);
+         nla_put_nohdr(skb, sizeof(u), &u);
       } else if (em->datalen > 0)
-         RTA_PUT_NOHDR(skb, em->datalen, (void *) em->data);
+         nla_put_nohdr(skb, em->datalen, (void *) em->data);
 
       tail = skb_tail_pointer(skb);
-      match_start->rta_len = tail - (u8 *)match_start;
+      match_start->nla_len = tail - (u8 *)match_start;
    }
 
-   list_start->rta_len = tail - (u8 *)list_start;
-   top_start->rta_len = tail - (u8 *)top_start;
+   nla_nest_end(skb, list_start);
+   nla_nest_end(skb, top_start);
 
    return 0;
 
-rtattr_failure:
+nla_put_failure:
    return -1;
 }
+EXPORT_SYMBOL(tcf_em_tree_dump);
 
 static inline int tcf_em_match(struct sk_buff *skb, struct tcf_ematch *em,
                 struct tcf_pkt_info *info)
@@ -529,10 +541,4 @@ stack_overflow:
       printk("Local stack overflow, increase NET_EMATCH_STACK\n");
    return -1;
 }
-
-EXPORT_SYMBOL(tcf_em_register);
-EXPORT_SYMBOL(tcf_em_unregister);
-EXPORT_SYMBOL(tcf_em_tree_validate);
-EXPORT_SYMBOL(tcf_em_tree_destroy);
-EXPORT_SYMBOL(tcf_em_tree_dump);
 EXPORT_SYMBOL(__tcf_em_tree_match);


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.