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.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index d1263b3c96c3..0453d79ebf57 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -40,6 +40,7 @@ static struct tcf_hashinfo ipt_hash_info = {
40 40
41static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) 41static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
42{ 42{
43 struct xt_tgchk_param par;
43 struct xt_target *target; 44 struct xt_target *target;
44 int ret = 0; 45 int ret = 0;
45 46
@@ -49,29 +50,30 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
49 return -ENOENT; 50 return -ENOENT;
50 51
51 t->u.kernel.target = target; 52 t->u.kernel.target = target;
52 53 par.table = table;
53 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 54 par.entryinfo = NULL;
54 table, hook, 0, 0); 55 par.target = target;
55 if (ret) { 56 par.targinfo = t->data;
57 par.hook_mask = hook;
58 par.family = NFPROTO_IPV4;
59
60 ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
61 if (ret < 0) {
56 module_put(t->u.kernel.target->me); 62 module_put(t->u.kernel.target->me);
57 return ret; 63 return ret;
58 } 64 }
59 if (t->u.kernel.target->checkentry 65 return 0;
60 && !t->u.kernel.target->checkentry(table, NULL,
61 t->u.kernel.target, t->data,
62 hook)) {
63 module_put(t->u.kernel.target->me);
64 ret = -EINVAL;
65 }
66
67 return ret;
68} 66}
69 67
70static void ipt_destroy_target(struct ipt_entry_target *t) 68static void ipt_destroy_target(struct ipt_entry_target *t)
71{ 69{
72 if (t->u.kernel.target->destroy) 70 struct xt_tgdtor_param par = {
73 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 71 .target = t->u.kernel.target,
74 module_put(t->u.kernel.target->me); 72 .targinfo = t->data,
73 };
74 if (par.target->destroy != NULL)
75 par.target->destroy(&par);
76 module_put(par.target->me);
75} 77}
76 78
77static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) 79static int tcf_ipt_release(struct tcf_ipt *ipt, int bind)
@@ -196,6 +198,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
196{ 198{
197 int ret = 0, result = 0; 199 int ret = 0, result = 0;
198 struct tcf_ipt *ipt = a->priv; 200 struct tcf_ipt *ipt = a->priv;
201 struct xt_target_param par;
199 202
200 if (skb_cloned(skb)) { 203 if (skb_cloned(skb)) {
201 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 204 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -211,10 +214,13 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
211 /* yes, we have to worry about both in and out dev 214 /* yes, we have to worry about both in and out dev
212 worry later - danger - this API seems to have changed 215 worry later - danger - this API seems to have changed
213 from earlier kernels */ 216 from earlier kernels */
214 ret = ipt->tcfi_t->u.kernel.target->target(skb, skb->dev, NULL, 217 par.in = skb->dev;
215 ipt->tcfi_hook, 218 par.out = NULL;
216 ipt->tcfi_t->u.kernel.target, 219 par.hooknum = ipt->tcfi_hook;
217 ipt->tcfi_t->data); 220 par.target = ipt->tcfi_t->u.kernel.target;
221 par.targinfo = ipt->tcfi_t->data;
222 ret = par.target->target(skb, &par);
223
218 switch (ret) { 224 switch (ret) {
219 case NF_ACCEPT: 225 case NF_ACCEPT:
220 result = TC_ACT_OK; 226 result = TC_ACT_OK;