netsched: Allow meta match on vlan tag on receive
[safe/jmp/linux-2.6] / net / sched / act_ipt.c
index 79ea193..082c520 100644 (file)
@@ -40,6 +40,7 @@ static struct tcf_hashinfo ipt_hash_info = {
 
 static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
 {
+       struct xt_tgchk_param par;
        struct xt_target *target;
        int ret = 0;
 
@@ -49,9 +50,14 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
                return -ENOENT;
 
        t->u.kernel.target = target;
-
-       ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
-                             table, hook, 0, 0, NULL, t->data);
+       par.table     = table;
+       par.entryinfo = NULL;
+       par.target    = target;
+       par.targinfo  = t->data;
+       par.hook_mask = hook;
+       par.family    = NFPROTO_IPV4;
+
+       ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
        if (ret < 0) {
                module_put(t->u.kernel.target->me);
                return ret;
@@ -61,9 +67,13 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
 
 static void ipt_destroy_target(struct ipt_entry_target *t)
 {
-       if (t->u.kernel.target->destroy)
-               t->u.kernel.target->destroy(t->u.kernel.target, t->data);
-       module_put(t->u.kernel.target->me);
+       struct xt_tgdtor_param par = {
+               .target   = t->u.kernel.target,
+               .targinfo = t->data,
+       };
+       if (par.target->destroy != NULL)
+               par.target->destroy(&par);
+       module_put(par.target->me);
 }
 
 static int tcf_ipt_release(struct tcf_ipt *ipt, int bind)
@@ -126,8 +136,8 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
        if (!pc) {
                pc = tcf_hash_create(index, est, a, sizeof(*ipt), bind,
                                     &ipt_idx_gen, &ipt_hash_info);
-               if (unlikely(!pc))
-                       return -ENOMEM;
+               if (IS_ERR(pc))
+                   return PTR_ERR(pc);
                ret = ACT_P_CREATED;
        } else {
                if (!ovr) {
@@ -188,6 +198,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
 {
        int ret = 0, result = 0;
        struct tcf_ipt *ipt = a->priv;
+       struct xt_target_param par;
 
        if (skb_cloned(skb)) {
                if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -203,10 +214,13 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
        /* yes, we have to worry about both in and out dev
         worry later - danger - this API seems to have changed
         from earlier kernels */
-       ret = ipt->tcfi_t->u.kernel.target->target(skb, skb->dev, NULL,
-                                                  ipt->tcfi_hook,
-                                                  ipt->tcfi_t->u.kernel.target,
-                                                  ipt->tcfi_t->data);
+       par.in       = skb->dev;
+       par.out      = NULL;
+       par.hooknum  = ipt->tcfi_hook;
+       par.target   = ipt->tcfi_t->u.kernel.target;
+       par.targinfo = ipt->tcfi_t->data;
+       ret = par.target->target(skb, &par);
+
        switch (ret) {
        case NF_ACCEPT:
                result = TC_ACT_OK;