diff options
Diffstat (limited to 'net/sched/act_ipt.c')
-rw-r--r-- | net/sched/act_ipt.c | 46 |
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 | ||
41 | static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) | 41 | static 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 | ||
70 | static void ipt_destroy_target(struct ipt_entry_target *t) | 68 | static 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 | ||
77 | static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) | 79 | static 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; |