net_sched: move tc_action into tcf_common
[cascardo/linux.git] / net / sched / act_ipt.c
index b8c5060..378c1c9 100644 (file)
 #define IPT_TAB_MASK     15
 
 static int ipt_net_id;
+static struct tc_action_ops act_ipt_ops;
 
 static int xt_net_id;
+static struct tc_action_ops act_xt_ops;
 
 static int ipt_init_target(struct xt_entry_target *t, char *table,
                           unsigned int hook)
@@ -90,8 +92,8 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
 };
 
 static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
-                         struct nlattr *est, struct tc_action *a, int ovr,
-                         int bind)
+                         struct nlattr *est, struct tc_action **a,
+                         const struct tc_action_ops *ops, int ovr, int bind)
 {
        struct nlattr *tb[TCA_IPT_MAX + 1];
        struct tcf_ipt *ipt;
@@ -118,19 +120,19 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
 
        if (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) {
                if (exists)
-                       tcf_hash_release(a, bind);
+                       tcf_hash_release(*a, bind);
                return -EINVAL;
        }
 
        td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
        if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) {
                if (exists)
-                       tcf_hash_release(a, bind);
+                       tcf_hash_release(*a, bind);
                return -EINVAL;
        }
 
        if (!exists) {
-               ret = tcf_hash_create(tn, index, est, a, sizeof(*ipt), bind,
+               ret = tcf_hash_create(tn, index, est, a, ops, bind,
                                      false);
                if (ret)
                        return ret;
@@ -138,13 +140,11 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
        } else {
                if (bind)/* dont override defaults */
                        return 0;
-               tcf_hash_release(a, bind);
+               tcf_hash_release(*a, bind);
 
                if (!ovr)
                        return -EEXIST;
        }
-       ipt = to_ipt(a);
-
        hook = nla_get_u32(tb[TCA_IPT_HOOK]);
 
        err = -ENOMEM;
@@ -163,6 +163,8 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
        if (err < 0)
                goto err3;
 
+       ipt = to_ipt(*a);
+
        spin_lock_bh(&ipt->tcf_lock);
        if (ret != ACT_P_CREATED) {
                ipt_destroy_target(ipt->tcfi_t);
@@ -174,7 +176,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
        ipt->tcfi_hook  = hook;
        spin_unlock_bh(&ipt->tcf_lock);
        if (ret == ACT_P_CREATED)
-               tcf_hash_insert(tn, a);
+               tcf_hash_insert(tn, *a);
        return ret;
 
 err3:
@@ -183,33 +185,33 @@ err2:
        kfree(tname);
 err1:
        if (ret == ACT_P_CREATED)
-               tcf_hash_cleanup(a, est);
+               tcf_hash_cleanup(*a, est);
        return err;
 }
 
 static int tcf_ipt_init(struct net *net, struct nlattr *nla,
-                       struct nlattr *est, struct tc_action *a, int ovr,
+                       struct nlattr *est, struct tc_action **a, int ovr,
                        int bind)
 {
        struct tc_action_net *tn = net_generic(net, ipt_net_id);
 
-       return __tcf_ipt_init(tn, nla, est, a, ovr, bind);
+       return __tcf_ipt_init(tn, nla, est, a, &act_ipt_ops, ovr, bind);
 }
 
 static int tcf_xt_init(struct net *net, struct nlattr *nla,
-                      struct nlattr *est, struct tc_action *a, int ovr,
+                      struct nlattr *est, struct tc_action **a, int ovr,
                       int bind)
 {
        struct tc_action_net *tn = net_generic(net, xt_net_id);
 
-       return __tcf_ipt_init(tn, nla, est, a, ovr, bind);
+       return __tcf_ipt_init(tn, nla, est, a, &act_xt_ops, ovr, bind);
 }
 
 static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,
                   struct tcf_result *res)
 {
        int ret = 0, result = 0;
-       struct tcf_ipt *ipt = a->priv;
+       struct tcf_ipt *ipt = to_ipt(a);
        struct xt_action_param par;
 
        if (skb_unclone(skb, GFP_ATOMIC))
@@ -259,7 +261,7 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind,
                        int ref)
 {
        unsigned char *b = skb_tail_pointer(skb);
-       struct tcf_ipt *ipt = a->priv;
+       struct tcf_ipt *ipt = to_ipt(a);
        struct xt_entry_target *t;
        struct tcf_t tm;
        struct tc_cnt c;
@@ -299,14 +301,14 @@ nla_put_failure:
 
 static int tcf_ipt_walker(struct net *net, struct sk_buff *skb,
                          struct netlink_callback *cb, int type,
-                         struct tc_action *a)
+                         const struct tc_action_ops *ops)
 {
        struct tc_action_net *tn = net_generic(net, ipt_net_id);
 
-       return tcf_generic_walker(tn, skb, cb, type, a);
+       return tcf_generic_walker(tn, skb, cb, type, ops);
 }
 
-static int tcf_ipt_search(struct net *net, struct tc_action *a, u32 index)
+static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index)
 {
        struct tc_action_net *tn = net_generic(net, ipt_net_id);
 
@@ -323,6 +325,7 @@ static struct tc_action_ops act_ipt_ops = {
        .init           =       tcf_ipt_init,
        .walk           =       tcf_ipt_walker,
        .lookup         =       tcf_ipt_search,
+       .size           =       sizeof(struct tcf_ipt),
 };
 
 static __net_init int ipt_init_net(struct net *net)
@@ -348,14 +351,14 @@ static struct pernet_operations ipt_net_ops = {
 
 static int tcf_xt_walker(struct net *net, struct sk_buff *skb,
                         struct netlink_callback *cb, int type,
-                        struct tc_action *a)
+                        const struct tc_action_ops *ops)
 {
        struct tc_action_net *tn = net_generic(net, xt_net_id);
 
-       return tcf_generic_walker(tn, skb, cb, type, a);
+       return tcf_generic_walker(tn, skb, cb, type, ops);
 }
 
-static int tcf_xt_search(struct net *net, struct tc_action *a, u32 index)
+static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index)
 {
        struct tc_action_net *tn = net_generic(net, xt_net_id);
 
@@ -372,6 +375,7 @@ static struct tc_action_ops act_xt_ops = {
        .init           =       tcf_xt_init,
        .walk           =       tcf_xt_walker,
        .lookup         =       tcf_xt_search,
+       .size           =       sizeof(struct tcf_ipt),
 };
 
 static __net_init int xt_init_net(struct net *net)