aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_ipt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_ipt.c')
-rw-r--r--net/sched/act_ipt.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index b8c50600697a..378c1c976058 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -31,8 +31,10 @@
31#define IPT_TAB_MASK 15 31#define IPT_TAB_MASK 15
32 32
33static int ipt_net_id; 33static int ipt_net_id;
34static struct tc_action_ops act_ipt_ops;
34 35
35static int xt_net_id; 36static int xt_net_id;
37static struct tc_action_ops act_xt_ops;
36 38
37static int ipt_init_target(struct xt_entry_target *t, char *table, 39static int ipt_init_target(struct xt_entry_target *t, char *table,
38 unsigned int hook) 40 unsigned int hook)
@@ -90,8 +92,8 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
90}; 92};
91 93
92static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, 94static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
93 struct nlattr *est, struct tc_action *a, int ovr, 95 struct nlattr *est, struct tc_action **a,
94 int bind) 96 const struct tc_action_ops *ops, int ovr, int bind)
95{ 97{
96 struct nlattr *tb[TCA_IPT_MAX + 1]; 98 struct nlattr *tb[TCA_IPT_MAX + 1];
97 struct tcf_ipt *ipt; 99 struct tcf_ipt *ipt;
@@ -118,19 +120,19 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
118 120
119 if (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) { 121 if (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) {
120 if (exists) 122 if (exists)
121 tcf_hash_release(a, bind); 123 tcf_hash_release(*a, bind);
122 return -EINVAL; 124 return -EINVAL;
123 } 125 }
124 126
125 td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]); 127 td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
126 if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) { 128 if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) {
127 if (exists) 129 if (exists)
128 tcf_hash_release(a, bind); 130 tcf_hash_release(*a, bind);
129 return -EINVAL; 131 return -EINVAL;
130 } 132 }
131 133
132 if (!exists) { 134 if (!exists) {
133 ret = tcf_hash_create(tn, index, est, a, sizeof(*ipt), bind, 135 ret = tcf_hash_create(tn, index, est, a, ops, bind,
134 false); 136 false);
135 if (ret) 137 if (ret)
136 return ret; 138 return ret;
@@ -138,13 +140,11 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
138 } else { 140 } else {
139 if (bind)/* dont override defaults */ 141 if (bind)/* dont override defaults */
140 return 0; 142 return 0;
141 tcf_hash_release(a, bind); 143 tcf_hash_release(*a, bind);
142 144
143 if (!ovr) 145 if (!ovr)
144 return -EEXIST; 146 return -EEXIST;
145 } 147 }
146 ipt = to_ipt(a);
147
148 hook = nla_get_u32(tb[TCA_IPT_HOOK]); 148 hook = nla_get_u32(tb[TCA_IPT_HOOK]);
149 149
150 err = -ENOMEM; 150 err = -ENOMEM;
@@ -163,6 +163,8 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
163 if (err < 0) 163 if (err < 0)
164 goto err3; 164 goto err3;
165 165
166 ipt = to_ipt(*a);
167
166 spin_lock_bh(&ipt->tcf_lock); 168 spin_lock_bh(&ipt->tcf_lock);
167 if (ret != ACT_P_CREATED) { 169 if (ret != ACT_P_CREATED) {
168 ipt_destroy_target(ipt->tcfi_t); 170 ipt_destroy_target(ipt->tcfi_t);
@@ -174,7 +176,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
174 ipt->tcfi_hook = hook; 176 ipt->tcfi_hook = hook;
175 spin_unlock_bh(&ipt->tcf_lock); 177 spin_unlock_bh(&ipt->tcf_lock);
176 if (ret == ACT_P_CREATED) 178 if (ret == ACT_P_CREATED)
177 tcf_hash_insert(tn, a); 179 tcf_hash_insert(tn, *a);
178 return ret; 180 return ret;
179 181
180err3: 182err3:
@@ -183,33 +185,33 @@ err2:
183 kfree(tname); 185 kfree(tname);
184err1: 186err1:
185 if (ret == ACT_P_CREATED) 187 if (ret == ACT_P_CREATED)
186 tcf_hash_cleanup(a, est); 188 tcf_hash_cleanup(*a, est);
187 return err; 189 return err;
188} 190}
189 191
190static int tcf_ipt_init(struct net *net, struct nlattr *nla, 192static int tcf_ipt_init(struct net *net, struct nlattr *nla,
191 struct nlattr *est, struct tc_action *a, int ovr, 193 struct nlattr *est, struct tc_action **a, int ovr,
192 int bind) 194 int bind)
193{ 195{
194 struct tc_action_net *tn = net_generic(net, ipt_net_id); 196 struct tc_action_net *tn = net_generic(net, ipt_net_id);
195 197
196 return __tcf_ipt_init(tn, nla, est, a, ovr, bind); 198 return __tcf_ipt_init(tn, nla, est, a, &act_ipt_ops, ovr, bind);
197} 199}
198 200
199static int tcf_xt_init(struct net *net, struct nlattr *nla, 201static int tcf_xt_init(struct net *net, struct nlattr *nla,
200 struct nlattr *est, struct tc_action *a, int ovr, 202 struct nlattr *est, struct tc_action **a, int ovr,
201 int bind) 203 int bind)
202{ 204{
203 struct tc_action_net *tn = net_generic(net, xt_net_id); 205 struct tc_action_net *tn = net_generic(net, xt_net_id);
204 206
205 return __tcf_ipt_init(tn, nla, est, a, ovr, bind); 207 return __tcf_ipt_init(tn, nla, est, a, &act_xt_ops, ovr, bind);
206} 208}
207 209
208static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a, 210static int tcf_ipt(struct sk_buff *skb, const struct tc_action *a,
209 struct tcf_result *res) 211 struct tcf_result *res)
210{ 212{
211 int ret = 0, result = 0; 213 int ret = 0, result = 0;
212 struct tcf_ipt *ipt = a->priv; 214 struct tcf_ipt *ipt = to_ipt(a);
213 struct xt_action_param par; 215 struct xt_action_param par;
214 216
215 if (skb_unclone(skb, GFP_ATOMIC)) 217 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,
259 int ref) 261 int ref)
260{ 262{
261 unsigned char *b = skb_tail_pointer(skb); 263 unsigned char *b = skb_tail_pointer(skb);
262 struct tcf_ipt *ipt = a->priv; 264 struct tcf_ipt *ipt = to_ipt(a);
263 struct xt_entry_target *t; 265 struct xt_entry_target *t;
264 struct tcf_t tm; 266 struct tcf_t tm;
265 struct tc_cnt c; 267 struct tc_cnt c;
@@ -299,14 +301,14 @@ nla_put_failure:
299 301
300static int tcf_ipt_walker(struct net *net, struct sk_buff *skb, 302static int tcf_ipt_walker(struct net *net, struct sk_buff *skb,
301 struct netlink_callback *cb, int type, 303 struct netlink_callback *cb, int type,
302 struct tc_action *a) 304 const struct tc_action_ops *ops)
303{ 305{
304 struct tc_action_net *tn = net_generic(net, ipt_net_id); 306 struct tc_action_net *tn = net_generic(net, ipt_net_id);
305 307
306 return tcf_generic_walker(tn, skb, cb, type, a); 308 return tcf_generic_walker(tn, skb, cb, type, ops);
307} 309}
308 310
309static int tcf_ipt_search(struct net *net, struct tc_action *a, u32 index) 311static int tcf_ipt_search(struct net *net, struct tc_action **a, u32 index)
310{ 312{
311 struct tc_action_net *tn = net_generic(net, ipt_net_id); 313 struct tc_action_net *tn = net_generic(net, ipt_net_id);
312 314
@@ -323,6 +325,7 @@ static struct tc_action_ops act_ipt_ops = {
323 .init = tcf_ipt_init, 325 .init = tcf_ipt_init,
324 .walk = tcf_ipt_walker, 326 .walk = tcf_ipt_walker,
325 .lookup = tcf_ipt_search, 327 .lookup = tcf_ipt_search,
328 .size = sizeof(struct tcf_ipt),
326}; 329};
327 330
328static __net_init int ipt_init_net(struct net *net) 331static __net_init int ipt_init_net(struct net *net)
@@ -348,14 +351,14 @@ static struct pernet_operations ipt_net_ops = {
348 351
349static int tcf_xt_walker(struct net *net, struct sk_buff *skb, 352static int tcf_xt_walker(struct net *net, struct sk_buff *skb,
350 struct netlink_callback *cb, int type, 353 struct netlink_callback *cb, int type,
351 struct tc_action *a) 354 const struct tc_action_ops *ops)
352{ 355{
353 struct tc_action_net *tn = net_generic(net, xt_net_id); 356 struct tc_action_net *tn = net_generic(net, xt_net_id);
354 357
355 return tcf_generic_walker(tn, skb, cb, type, a); 358 return tcf_generic_walker(tn, skb, cb, type, ops);
356} 359}
357 360
358static int tcf_xt_search(struct net *net, struct tc_action *a, u32 index) 361static int tcf_xt_search(struct net *net, struct tc_action **a, u32 index)
359{ 362{
360 struct tc_action_net *tn = net_generic(net, xt_net_id); 363 struct tc_action_net *tn = net_generic(net, xt_net_id);
361 364
@@ -372,6 +375,7 @@ static struct tc_action_ops act_xt_ops = {
372 .init = tcf_xt_init, 375 .init = tcf_xt_init,
373 .walk = tcf_xt_walker, 376 .walk = tcf_xt_walker,
374 .lookup = tcf_xt_search, 377 .lookup = tcf_xt_search,
378 .size = sizeof(struct tcf_ipt),
375}; 379};
376 380
377static __net_init int xt_init_net(struct net *net) 381static __net_init int xt_init_net(struct net *net)