diff options
39 files changed, 208 insertions, 283 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 46d0cb1ad340..8daeb496ba7a 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -234,6 +234,23 @@ struct xt_target_param { | |||
234 | const void *targinfo; | 234 | const void *targinfo; |
235 | }; | 235 | }; |
236 | 236 | ||
237 | /** | ||
238 | * struct xt_tgchk_param - parameters for target extensions' | ||
239 | * checkentry functions | ||
240 | * | ||
241 | * @entryinfo: the family-specific rule data | ||
242 | * (struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry) | ||
243 | * | ||
244 | * Other fields see above. | ||
245 | */ | ||
246 | struct xt_tgchk_param { | ||
247 | const char *table; | ||
248 | void *entryinfo; | ||
249 | const struct xt_target *target; | ||
250 | void *targinfo; | ||
251 | unsigned int hook_mask; | ||
252 | }; | ||
253 | |||
237 | struct xt_match | 254 | struct xt_match |
238 | { | 255 | { |
239 | struct list_head list; | 256 | struct list_head list; |
@@ -291,11 +308,7 @@ struct xt_target | |||
291 | hook_mask is a bitmask of hooks from which it can be | 308 | hook_mask is a bitmask of hooks from which it can be |
292 | called. */ | 309 | called. */ |
293 | /* Should return true or false. */ | 310 | /* Should return true or false. */ |
294 | bool (*checkentry)(const char *tablename, | 311 | bool (*checkentry)(const struct xt_tgchk_param *); |
295 | const void *entry, | ||
296 | const struct xt_target *target, | ||
297 | void *targinfo, | ||
298 | unsigned int hook_mask); | ||
299 | 312 | ||
300 | /* Called when entry of this type deleted. */ | 313 | /* Called when entry of this type deleted. */ |
301 | void (*destroy)(const struct xt_target *target, void *targinfo); | 314 | void (*destroy)(const struct xt_target *target, void *targinfo); |
@@ -376,10 +389,8 @@ extern void xt_unregister_matches(struct xt_match *match, unsigned int n); | |||
376 | 389 | ||
377 | extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family, | 390 | extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family, |
378 | unsigned int size, u_int8_t proto, bool inv_proto); | 391 | unsigned int size, u_int8_t proto, bool inv_proto); |
379 | extern int xt_check_target(const struct xt_target *target, unsigned short family, | 392 | extern int xt_check_target(struct xt_tgchk_param *, u_int8_t family, |
380 | unsigned int size, const char *table, unsigned int hook, | 393 | unsigned int size, u_int8_t proto, bool inv_proto); |
381 | unsigned short proto, int inv_proto, | ||
382 | const void *entry, void *targinfo); | ||
383 | 394 | ||
384 | extern struct xt_table *xt_register_table(struct net *net, | 395 | extern struct xt_table *xt_register_table(struct net *net, |
385 | struct xt_table *table, | 396 | struct xt_table *table, |
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 568a690f6a62..d45e29cd1cfb 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h | |||
@@ -310,9 +310,9 @@ extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb, | |||
310 | #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg)) | 310 | #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg)) |
311 | /* True if the hook mask denotes that the rule is in a base chain, | 311 | /* True if the hook mask denotes that the rule is in a base chain, |
312 | * used in the check() functions */ | 312 | * used in the check() functions */ |
313 | #define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) | 313 | #define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS)) |
314 | /* Clear the bit in the hook mask that tells if the rule is on a base chain */ | 314 | /* Clear the bit in the hook mask that tells if the rule is on a base chain */ |
315 | #define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) | 315 | #define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS)) |
316 | /* True if the target is not a standard target */ | 316 | /* True if the target is not a standard target */ |
317 | #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) | 317 | #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) |
318 | 318 | ||
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c index fc94699f719e..76584cd72e57 100644 --- a/net/bridge/netfilter/ebt_arpreply.c +++ b/net/bridge/netfilter/ebt_arpreply.c | |||
@@ -57,20 +57,16 @@ ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
57 | return info->target; | 57 | return info->target; |
58 | } | 58 | } |
59 | 59 | ||
60 | static bool | 60 | static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par) |
61 | ebt_arpreply_tg_check(const char *tablename, const void *entry, | ||
62 | const struct xt_target *target, void *data, | ||
63 | unsigned int hookmask) | ||
64 | { | 61 | { |
65 | const struct ebt_arpreply_info *info = data; | 62 | const struct ebt_arpreply_info *info = par->targinfo; |
66 | const struct ebt_entry *e = entry; | 63 | const struct ebt_entry *e = par->entryinfo; |
67 | 64 | ||
68 | if (BASE_CHAIN && info->target == EBT_RETURN) | 65 | if (BASE_CHAIN && info->target == EBT_RETURN) |
69 | return false; | 66 | return false; |
70 | if (e->ethproto != htons(ETH_P_ARP) || | 67 | if (e->ethproto != htons(ETH_P_ARP) || |
71 | e->invflags & EBT_IPROTO) | 68 | e->invflags & EBT_IPROTO) |
72 | return false; | 69 | return false; |
73 | CLEAR_BASE_CHAIN_BIT; | ||
74 | return true; | 70 | return true; |
75 | } | 71 | } |
76 | 72 | ||
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c index bb5d79e0beea..6b49ea9e31fb 100644 --- a/net/bridge/netfilter/ebt_dnat.c +++ b/net/bridge/netfilter/ebt_dnat.c | |||
@@ -26,19 +26,20 @@ ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
26 | return info->target; | 26 | return info->target; |
27 | } | 27 | } |
28 | 28 | ||
29 | static bool | 29 | static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par) |
30 | ebt_dnat_tg_check(const char *tablename, const void *entry, | ||
31 | const struct xt_target *target, void *data, | ||
32 | unsigned int hookmask) | ||
33 | { | 30 | { |
34 | const struct ebt_nat_info *info = data; | 31 | const struct ebt_nat_info *info = par->targinfo; |
32 | unsigned int hook_mask; | ||
35 | 33 | ||
36 | if (BASE_CHAIN && info->target == EBT_RETURN) | 34 | if (BASE_CHAIN && info->target == EBT_RETURN) |
37 | return false; | 35 | return false; |
38 | CLEAR_BASE_CHAIN_BIT; | 36 | |
39 | if ( (strcmp(tablename, "nat") || | 37 | hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS); |
40 | (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && | 38 | if ((strcmp(par->table, "nat") != 0 || |
41 | (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) | 39 | (hook_mask & ~((1 << NF_BR_PRE_ROUTING) | |
40 | (1 << NF_BR_LOCAL_OUT)))) && | ||
41 | (strcmp(par->table, "broute") != 0 || | ||
42 | hook_mask & ~(1 << NF_BR_BROUTING))) | ||
42 | return false; | 43 | return false; |
43 | if (INVALID_TARGET) | 44 | if (INVALID_TARGET) |
44 | return false; | 45 | return false; |
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index 87de5fccb2f1..3d33c608906a 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c | |||
@@ -24,12 +24,9 @@ | |||
24 | 24 | ||
25 | static DEFINE_SPINLOCK(ebt_log_lock); | 25 | static DEFINE_SPINLOCK(ebt_log_lock); |
26 | 26 | ||
27 | static bool | 27 | static bool ebt_log_tg_check(const struct xt_tgchk_param *par) |
28 | ebt_log_tg_check(const char *table, const void *entry, | ||
29 | const struct xt_target *target, void *data, | ||
30 | unsigned int hook_mask) | ||
31 | { | 28 | { |
32 | struct ebt_log_info *info = data; | 29 | struct ebt_log_info *info = par->targinfo; |
33 | 30 | ||
34 | if (info->bitmask & ~EBT_LOG_MASK) | 31 | if (info->bitmask & ~EBT_LOG_MASK) |
35 | return false; | 32 | return false; |
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c index aafc456c3c3b..2fee7e8e2e93 100644 --- a/net/bridge/netfilter/ebt_mark.c +++ b/net/bridge/netfilter/ebt_mark.c | |||
@@ -36,18 +36,14 @@ ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
36 | return info->target | ~EBT_VERDICT_BITS; | 36 | return info->target | ~EBT_VERDICT_BITS; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool ebt_mark_tg_check(const struct xt_tgchk_param *par) |
40 | ebt_mark_tg_check(const char *table, const void *e, | ||
41 | const struct xt_target *target, void *data, | ||
42 | unsigned int hookmask) | ||
43 | { | 40 | { |
44 | const struct ebt_mark_t_info *info = data; | 41 | const struct ebt_mark_t_info *info = par->targinfo; |
45 | int tmp; | 42 | int tmp; |
46 | 43 | ||
47 | tmp = info->target | ~EBT_VERDICT_BITS; | 44 | tmp = info->target | ~EBT_VERDICT_BITS; |
48 | if (BASE_CHAIN && tmp == EBT_RETURN) | 45 | if (BASE_CHAIN && tmp == EBT_RETURN) |
49 | return false; | 46 | return false; |
50 | CLEAR_BASE_CHAIN_BIT; | ||
51 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) | 47 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) |
52 | return false; | 48 | return false; |
53 | tmp = info->target & ~EBT_VERDICT_BITS; | 49 | tmp = info->target & ~EBT_VERDICT_BITS; |
diff --git a/net/bridge/netfilter/ebt_nflog.c b/net/bridge/netfilter/ebt_nflog.c index 6a28d994cf7d..2a63d996dd4e 100644 --- a/net/bridge/netfilter/ebt_nflog.c +++ b/net/bridge/netfilter/ebt_nflog.c | |||
@@ -35,12 +35,9 @@ ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
35 | return EBT_CONTINUE; | 35 | return EBT_CONTINUE; |
36 | } | 36 | } |
37 | 37 | ||
38 | static bool | 38 | static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par) |
39 | ebt_nflog_tg_check(const char *table, const void *e, | ||
40 | const struct xt_target *target, void *data, | ||
41 | unsigned int hookmask) | ||
42 | { | 39 | { |
43 | struct ebt_nflog_info *info = data; | 40 | struct ebt_nflog_info *info = par->targinfo; |
44 | 41 | ||
45 | if (info->flags & ~EBT_NFLOG_MASK) | 42 | if (info->flags & ~EBT_NFLOG_MASK) |
46 | return false; | 43 | return false; |
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c index 0cfe2fad9404..c8a49f7a57ba 100644 --- a/net/bridge/netfilter/ebt_redirect.c +++ b/net/bridge/netfilter/ebt_redirect.c | |||
@@ -32,18 +32,19 @@ ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
32 | return info->target; | 32 | return info->target; |
33 | } | 33 | } |
34 | 34 | ||
35 | static bool | 35 | static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par) |
36 | ebt_redirect_tg_check(const char *tablename, const void *e, | ||
37 | const struct xt_target *target, void *data, | ||
38 | unsigned int hookmask) | ||
39 | { | 36 | { |
40 | const struct ebt_redirect_info *info = data; | 37 | const struct ebt_redirect_info *info = par->targinfo; |
38 | unsigned int hook_mask; | ||
41 | 39 | ||
42 | if (BASE_CHAIN && info->target == EBT_RETURN) | 40 | if (BASE_CHAIN && info->target == EBT_RETURN) |
43 | return false; | 41 | return false; |
44 | CLEAR_BASE_CHAIN_BIT; | 42 | |
45 | if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && | 43 | hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS); |
46 | (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) | 44 | if ((strcmp(par->table, "nat") != 0 || |
45 | hook_mask & ~(1 << NF_BR_PRE_ROUTING)) && | ||
46 | (strcmp(par->table, "broute") != 0 || | ||
47 | hook_mask & ~(1 << NF_BR_BROUTING))) | ||
47 | return false; | 48 | return false; |
48 | if (INVALID_TARGET) | 49 | if (INVALID_TARGET) |
49 | return false; | 50 | return false; |
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c index f55960eee996..8d04d4c302bd 100644 --- a/net/bridge/netfilter/ebt_snat.c +++ b/net/bridge/netfilter/ebt_snat.c | |||
@@ -42,18 +42,14 @@ out: | |||
42 | return info->target | ~EBT_VERDICT_BITS; | 42 | return info->target | ~EBT_VERDICT_BITS; |
43 | } | 43 | } |
44 | 44 | ||
45 | static bool | 45 | static bool ebt_snat_tg_check(const struct xt_tgchk_param *par) |
46 | ebt_snat_tg_check(const char *tablename, const void *e, | ||
47 | const struct xt_target *target, void *data, | ||
48 | unsigned int hookmask) | ||
49 | { | 46 | { |
50 | const struct ebt_nat_info *info = data; | 47 | const struct ebt_nat_info *info = par->targinfo; |
51 | int tmp; | 48 | int tmp; |
52 | 49 | ||
53 | tmp = info->target | ~EBT_VERDICT_BITS; | 50 | tmp = info->target | ~EBT_VERDICT_BITS; |
54 | if (BASE_CHAIN && tmp == EBT_RETURN) | 51 | if (BASE_CHAIN && tmp == EBT_RETURN) |
55 | return false; | 52 | return false; |
56 | CLEAR_BASE_CHAIN_BIT; | ||
57 | 53 | ||
58 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) | 54 | if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) |
59 | return false; | 55 | return false; |
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index bfedf12cbf41..2c6d6823e703 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
@@ -254,12 +254,9 @@ ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
254 | return EBT_CONTINUE; | 254 | return EBT_CONTINUE; |
255 | } | 255 | } |
256 | 256 | ||
257 | static bool | 257 | static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par) |
258 | ebt_ulog_tg_check(const char *table, const void *entry, | ||
259 | const struct xt_target *target, void *data, | ||
260 | unsigned int hookmask) | ||
261 | { | 258 | { |
262 | struct ebt_ulog_info *uloginfo = data; | 259 | struct ebt_ulog_info *uloginfo = par->targinfo; |
263 | 260 | ||
264 | if (uloginfo->nlgroup > 31) | 261 | if (uloginfo->nlgroup > 31) |
265 | return false; | 262 | return false; |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index a1156bab4a03..cf823c21c166 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -363,9 +363,10 @@ ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par, | |||
363 | } | 363 | } |
364 | 364 | ||
365 | static inline int | 365 | static inline int |
366 | ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, | 366 | ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par, |
367 | const char *name, unsigned int hookmask, unsigned int *cnt) | 367 | unsigned int *cnt) |
368 | { | 368 | { |
369 | const struct ebt_entry *e = par->entryinfo; | ||
369 | struct xt_target *watcher; | 370 | struct xt_target *watcher; |
370 | size_t left = ((char *)e + e->target_offset) - (char *)w; | 371 | size_t left = ((char *)e + e->target_offset) - (char *)w; |
371 | int ret; | 372 | int ret; |
@@ -383,9 +384,10 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, | |||
383 | return -ENOENT; | 384 | return -ENOENT; |
384 | w->u.watcher = watcher; | 385 | w->u.watcher = watcher; |
385 | 386 | ||
386 | ret = xt_check_target(watcher, NFPROTO_BRIDGE, w->watcher_size, | 387 | par->target = watcher; |
387 | name, hookmask, e->ethproto, e->invflags & EBT_IPROTO, | 388 | par->targinfo = w->data; |
388 | e, w->data); | 389 | ret = xt_check_target(par, NFPROTO_BRIDGE, w->watcher_size, |
390 | e->ethproto, e->invflags & EBT_IPROTO); | ||
389 | if (ret < 0) { | 391 | if (ret < 0) { |
390 | module_put(watcher->me); | 392 | module_put(watcher->me); |
391 | return ret; | 393 | return ret; |
@@ -619,6 +621,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
619 | size_t gap; | 621 | size_t gap; |
620 | int ret; | 622 | int ret; |
621 | struct xt_mtchk_param mtpar; | 623 | struct xt_mtchk_param mtpar; |
624 | struct xt_tgchk_param tgpar; | ||
622 | 625 | ||
623 | /* don't mess with the struct ebt_entries */ | 626 | /* don't mess with the struct ebt_entries */ |
624 | if (e->bitmask == 0) | 627 | if (e->bitmask == 0) |
@@ -660,14 +663,14 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
660 | } | 663 | } |
661 | i = 0; | 664 | i = 0; |
662 | 665 | ||
663 | mtpar.table = name; | 666 | mtpar.table = tgpar.table = name; |
664 | mtpar.entryinfo = e; | 667 | mtpar.entryinfo = tgpar.entryinfo = e; |
665 | mtpar.hook_mask = hookmask; | 668 | mtpar.hook_mask = tgpar.hook_mask = hookmask; |
666 | ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i); | 669 | ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i); |
667 | if (ret != 0) | 670 | if (ret != 0) |
668 | goto cleanup_matches; | 671 | goto cleanup_matches; |
669 | j = 0; | 672 | j = 0; |
670 | ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j); | 673 | ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j); |
671 | if (ret != 0) | 674 | if (ret != 0) |
672 | goto cleanup_watchers; | 675 | goto cleanup_watchers; |
673 | t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); | 676 | t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); |
@@ -703,9 +706,10 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, | |||
703 | goto cleanup_watchers; | 706 | goto cleanup_watchers; |
704 | } | 707 | } |
705 | 708 | ||
706 | ret = xt_check_target(target, NFPROTO_BRIDGE, t->target_size, | 709 | tgpar.target = target; |
707 | name, hookmask, e->ethproto, e->invflags & EBT_IPROTO, | 710 | tgpar.targinfo = t->data; |
708 | e, t->data); | 711 | ret = xt_check_target(&tgpar, NFPROTO_BRIDGE, t->target_size, |
712 | e->ethproto, e->invflags & EBT_IPROTO); | ||
709 | if (ret < 0) { | 713 | if (ret < 0) { |
710 | module_put(target->me); | 714 | module_put(target->me); |
711 | goto cleanup_watchers; | 715 | goto cleanup_watchers; |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 5b631ad74b5f..b3238d0101cc 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -457,16 +457,18 @@ static inline int check_entry(struct arpt_entry *e, const char *name) | |||
457 | 457 | ||
458 | static inline int check_target(struct arpt_entry *e, const char *name) | 458 | static inline int check_target(struct arpt_entry *e, const char *name) |
459 | { | 459 | { |
460 | struct arpt_entry_target *t; | 460 | struct arpt_entry_target *t = arpt_get_target(e); |
461 | struct xt_target *target; | ||
462 | int ret; | 461 | int ret; |
463 | 462 | struct xt_tgchk_param par = { | |
464 | t = arpt_get_target(e); | 463 | .table = name, |
465 | target = t->u.kernel.target; | 464 | .entryinfo = e, |
466 | 465 | .target = t->u.kernel.target, | |
467 | ret = xt_check_target(target, NFPROTO_ARP, | 466 | .targinfo = t->data, |
468 | t->u.target_size - sizeof(*t), | 467 | .hook_mask = e->comefrom, |
469 | name, e->comefrom, 0, 0, e, t->data); | 468 | }; |
469 | |||
470 | ret = xt_check_target(&par, NFPROTO_ARP, | ||
471 | t->u.target_size - sizeof(*t), 0, false); | ||
470 | if (ret < 0) { | 472 | if (ret < 0) { |
471 | duprintf("arp_tables: check failed for `%s'.\n", | 473 | duprintf("arp_tables: check failed for `%s'.\n", |
472 | t->u.kernel.target->name); | 474 | t->u.kernel.target->name); |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index 0bf81b353694..b0d5b1d0a769 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -54,11 +54,9 @@ target(struct sk_buff *skb, const struct xt_target_param *par) | |||
54 | return mangle->target; | 54 | return mangle->target; |
55 | } | 55 | } |
56 | 56 | ||
57 | static bool | 57 | static bool checkentry(const struct xt_tgchk_param *par) |
58 | checkentry(const char *tablename, const void *e, const struct xt_target *target, | ||
59 | void *targinfo, unsigned int hook_mask) | ||
60 | { | 58 | { |
61 | const struct arpt_mangle *mangle = targinfo; | 59 | const struct arpt_mangle *mangle = par->targinfo; |
62 | 60 | ||
63 | if (mangle->flags & ~ARPT_MANGLE_MASK || | 61 | if (mangle->flags & ~ARPT_MANGLE_MASK || |
64 | !(mangle->flags & ARPT_MANGLE_MASK)) | 62 | !(mangle->flags & ARPT_MANGLE_MASK)) |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 0f8ecf390229..e592c54d4992 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -655,15 +655,18 @@ err: | |||
655 | 655 | ||
656 | static int check_target(struct ipt_entry *e, const char *name) | 656 | static int check_target(struct ipt_entry *e, const char *name) |
657 | { | 657 | { |
658 | struct ipt_entry_target *t; | 658 | struct ipt_entry_target *t = ipt_get_target(e); |
659 | struct xt_target *target; | 659 | struct xt_tgchk_param par = { |
660 | .table = name, | ||
661 | .entryinfo = e, | ||
662 | .target = t->u.kernel.target, | ||
663 | .targinfo = t->data, | ||
664 | .hook_mask = e->comefrom, | ||
665 | }; | ||
660 | int ret; | 666 | int ret; |
661 | 667 | ||
662 | t = ipt_get_target(e); | 668 | ret = xt_check_target(&par, NFPROTO_IPV4, t->u.target_size - sizeof(*t), |
663 | target = t->u.kernel.target; | 669 | e->ip.proto, e->ip.invflags & IPT_INV_PROTO); |
664 | ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), | ||
665 | name, e->comefrom, e->ip.proto, | ||
666 | e->ip.invflags & IPT_INV_PROTO, e, t->data); | ||
667 | if (ret < 0) { | 670 | if (ret < 0) { |
668 | duprintf("ip_tables: check failed for `%s'.\n", | 671 | duprintf("ip_tables: check failed for `%s'.\n", |
669 | t->u.kernel.target->name); | 672 | t->u.kernel.target->name); |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 67e8aa8f34f2..6c7254e02561 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -347,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
347 | return XT_CONTINUE; | 347 | return XT_CONTINUE; |
348 | } | 348 | } |
349 | 349 | ||
350 | static bool | 350 | static bool clusterip_tg_check(const struct xt_tgchk_param *par) |
351 | clusterip_tg_check(const char *tablename, const void *e_void, | ||
352 | const struct xt_target *target, void *targinfo, | ||
353 | unsigned int hook_mask) | ||
354 | { | 351 | { |
355 | struct ipt_clusterip_tgt_info *cipinfo = targinfo; | 352 | struct ipt_clusterip_tgt_info *cipinfo = par->targinfo; |
356 | const struct ipt_entry *e = e_void; | 353 | const struct ipt_entry *e = par->entryinfo; |
357 | 354 | ||
358 | struct clusterip_config *config; | 355 | struct clusterip_config *config; |
359 | 356 | ||
@@ -404,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void, | |||
404 | } | 401 | } |
405 | cipinfo->config = config; | 402 | cipinfo->config = config; |
406 | 403 | ||
407 | if (nf_ct_l3proto_try_module_get(target->family) < 0) { | 404 | if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { |
408 | printk(KERN_WARNING "can't load conntrack support for " | 405 | printk(KERN_WARNING "can't load conntrack support for " |
409 | "proto=%u\n", target->family); | 406 | "proto=%u\n", par->target->family); |
410 | return false; | 407 | return false; |
411 | } | 408 | } |
412 | 409 | ||
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index e37f181e8298..f7e2fa0974dc 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -93,13 +93,10 @@ ecn_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
93 | return XT_CONTINUE; | 93 | return XT_CONTINUE; |
94 | } | 94 | } |
95 | 95 | ||
96 | static bool | 96 | static bool ecn_tg_check(const struct xt_tgchk_param *par) |
97 | ecn_tg_check(const char *tablename, const void *e_void, | ||
98 | const struct xt_target *target, void *targinfo, | ||
99 | unsigned int hook_mask) | ||
100 | { | 97 | { |
101 | const struct ipt_ECN_info *einfo = targinfo; | 98 | const struct ipt_ECN_info *einfo = par->targinfo; |
102 | const struct ipt_entry *e = e_void; | 99 | const struct ipt_entry *e = par->entryinfo; |
103 | 100 | ||
104 | if (einfo->operation & IPT_ECN_OP_MASK) { | 101 | if (einfo->operation & IPT_ECN_OP_MASK) { |
105 | printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", | 102 | printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", |
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index e9942aed35ae..fc6ce04a3e35 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c | |||
@@ -440,12 +440,9 @@ log_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
440 | return XT_CONTINUE; | 440 | return XT_CONTINUE; |
441 | } | 441 | } |
442 | 442 | ||
443 | static bool | 443 | static bool log_tg_check(const struct xt_tgchk_param *par) |
444 | log_tg_check(const char *tablename, const void *e, | ||
445 | const struct xt_target *target, void *targinfo, | ||
446 | unsigned int hook_mask) | ||
447 | { | 444 | { |
448 | const struct ipt_log_info *loginfo = targinfo; | 445 | const struct ipt_log_info *loginfo = par->targinfo; |
449 | 446 | ||
450 | if (loginfo->level >= 8) { | 447 | if (loginfo->level >= 8) { |
451 | pr_debug("LOG: level %u >= 8\n", loginfo->level); | 448 | pr_debug("LOG: level %u >= 8\n", loginfo->level); |
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c index e0d9d49b79ee..f389f60cb105 100644 --- a/net/ipv4/netfilter/ipt_MASQUERADE.c +++ b/net/ipv4/netfilter/ipt_MASQUERADE.c | |||
@@ -31,12 +31,9 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT"); | |||
31 | static DEFINE_RWLOCK(masq_lock); | 31 | static DEFINE_RWLOCK(masq_lock); |
32 | 32 | ||
33 | /* FIXME: Multiple targets. --RR */ | 33 | /* FIXME: Multiple targets. --RR */ |
34 | static bool | 34 | static bool masquerade_tg_check(const struct xt_tgchk_param *par) |
35 | masquerade_tg_check(const char *tablename, const void *e, | ||
36 | const struct xt_target *target, void *targinfo, | ||
37 | unsigned int hook_mask) | ||
38 | { | 35 | { |
39 | const struct nf_nat_multi_range_compat *mr = targinfo; | 36 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
40 | 37 | ||
41 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 38 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
42 | pr_debug("masquerade_check: bad MAP_IPS.\n"); | 39 | pr_debug("masquerade_check: bad MAP_IPS.\n"); |
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c index cf18f23b3460..7c29582d4ec8 100644 --- a/net/ipv4/netfilter/ipt_NETMAP.c +++ b/net/ipv4/netfilter/ipt_NETMAP.c | |||
@@ -22,12 +22,9 @@ MODULE_LICENSE("GPL"); | |||
22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); | 22 | MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); |
23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); | 23 | MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); |
24 | 24 | ||
25 | static bool | 25 | static bool netmap_tg_check(const struct xt_tgchk_param *par) |
26 | netmap_tg_check(const char *tablename, const void *e, | ||
27 | const struct xt_target *target, void *targinfo, | ||
28 | unsigned int hook_mask) | ||
29 | { | 26 | { |
30 | const struct nf_nat_multi_range_compat *mr = targinfo; | 27 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
31 | 28 | ||
32 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { | 29 | if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { |
33 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); | 30 | pr_debug("NETMAP:check: bad MAP_IPS.\n"); |
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c index 23adb09ddfb4..698e5e78685b 100644 --- a/net/ipv4/netfilter/ipt_REDIRECT.c +++ b/net/ipv4/netfilter/ipt_REDIRECT.c | |||
@@ -26,12 +26,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | |||
26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); | 26 | MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); |
27 | 27 | ||
28 | /* FIXME: Take multiple ranges --RR */ | 28 | /* FIXME: Take multiple ranges --RR */ |
29 | static bool | 29 | static bool redirect_tg_check(const struct xt_tgchk_param *par) |
30 | redirect_tg_check(const char *tablename, const void *e, | ||
31 | const struct xt_target *target, void *targinfo, | ||
32 | unsigned int hook_mask) | ||
33 | { | 30 | { |
34 | const struct nf_nat_multi_range_compat *mr = targinfo; | 31 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
35 | 32 | ||
36 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { | 33 | if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { |
37 | pr_debug("redirect_check: bad MAP_IPS.\n"); | 34 | pr_debug("redirect_check: bad MAP_IPS.\n"); |
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index b36071bb1077..0b4b6e0ff2b9 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c | |||
@@ -175,13 +175,10 @@ reject_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
175 | return NF_DROP; | 175 | return NF_DROP; |
176 | } | 176 | } |
177 | 177 | ||
178 | static bool | 178 | static bool reject_tg_check(const struct xt_tgchk_param *par) |
179 | reject_tg_check(const char *tablename, const void *e_void, | ||
180 | const struct xt_target *target, void *targinfo, | ||
181 | unsigned int hook_mask) | ||
182 | { | 179 | { |
183 | const struct ipt_reject_info *rejinfo = targinfo; | 180 | const struct ipt_reject_info *rejinfo = par->targinfo; |
184 | const struct ipt_entry *e = e_void; | 181 | const struct ipt_entry *e = par->entryinfo; |
185 | 182 | ||
186 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { | 183 | if (rejinfo->with == IPT_ICMP_ECHOREPLY) { |
187 | printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); | 184 | printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); |
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c index 05cbfd2f7470..6d76aae90cc0 100644 --- a/net/ipv4/netfilter/ipt_TTL.c +++ b/net/ipv4/netfilter/ipt_TTL.c | |||
@@ -59,12 +59,9 @@ ttl_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
59 | return XT_CONTINUE; | 59 | return XT_CONTINUE; |
60 | } | 60 | } |
61 | 61 | ||
62 | static bool | 62 | static bool ttl_tg_check(const struct xt_tgchk_param *par) |
63 | ttl_tg_check(const char *tablename, const void *e, | ||
64 | const struct xt_target *target, void *targinfo, | ||
65 | unsigned int hook_mask) | ||
66 | { | 63 | { |
67 | const struct ipt_TTL_info *info = targinfo; | 64 | const struct ipt_TTL_info *info = par->targinfo; |
68 | 65 | ||
69 | if (info->mode > IPT_TTL_MAXMODE) { | 66 | if (info->mode > IPT_TTL_MAXMODE) { |
70 | printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", | 67 | printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 46c0df0dc2dc..18a2826b57c6 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -313,12 +313,9 @@ static void ipt_logfn(u_int8_t pf, | |||
313 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); | 313 | ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); |
314 | } | 314 | } |
315 | 315 | ||
316 | static bool | 316 | static bool ulog_tg_check(const struct xt_tgchk_param *par) |
317 | ulog_tg_check(const char *tablename, const void *e, | ||
318 | const struct xt_target *target, void *targinfo, | ||
319 | unsigned int hookmask) | ||
320 | { | 317 | { |
321 | const struct ipt_ulog_info *loginfo = targinfo; | 318 | const struct ipt_ulog_info *loginfo = par->targinfo; |
322 | 319 | ||
323 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { | 320 | if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { |
324 | pr_debug("ipt_ULOG: prefix term %i\n", | 321 | pr_debug("ipt_ULOG: prefix term %i\n", |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index 83170ff131f9..bea54a685109 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -128,13 +128,9 @@ ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par) | |||
128 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); | 128 | return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); |
129 | } | 129 | } |
130 | 130 | ||
131 | static bool ipt_snat_checkentry(const char *tablename, | 131 | static bool ipt_snat_checkentry(const struct xt_tgchk_param *par) |
132 | const void *entry, | ||
133 | const struct xt_target *target, | ||
134 | void *targinfo, | ||
135 | unsigned int hook_mask) | ||
136 | { | 132 | { |
137 | const struct nf_nat_multi_range_compat *mr = targinfo; | 133 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
138 | 134 | ||
139 | /* Must be a valid range */ | 135 | /* Must be a valid range */ |
140 | if (mr->rangesize != 1) { | 136 | if (mr->rangesize != 1) { |
@@ -144,13 +140,9 @@ static bool ipt_snat_checkentry(const char *tablename, | |||
144 | return true; | 140 | return true; |
145 | } | 141 | } |
146 | 142 | ||
147 | static bool ipt_dnat_checkentry(const char *tablename, | 143 | static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par) |
148 | const void *entry, | ||
149 | const struct xt_target *target, | ||
150 | void *targinfo, | ||
151 | unsigned int hook_mask) | ||
152 | { | 144 | { |
153 | const struct nf_nat_multi_range_compat *mr = targinfo; | 145 | const struct nf_nat_multi_range_compat *mr = par->targinfo; |
154 | 146 | ||
155 | /* Must be a valid range */ | 147 | /* Must be a valid range */ |
156 | if (mr->rangesize != 1) { | 148 | if (mr->rangesize != 1) { |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index ee0986cdbd66..ca14fb8bd362 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -679,15 +679,19 @@ err: | |||
679 | 679 | ||
680 | static int check_target(struct ip6t_entry *e, const char *name) | 680 | static int check_target(struct ip6t_entry *e, const char *name) |
681 | { | 681 | { |
682 | struct ip6t_entry_target *t; | 682 | struct ip6t_entry_target *t = ip6t_get_target(e); |
683 | struct xt_target *target; | 683 | struct xt_tgchk_param par = { |
684 | .table = name, | ||
685 | .entryinfo = e, | ||
686 | .target = t->u.kernel.target, | ||
687 | .targinfo = t->data, | ||
688 | .hook_mask = e->comefrom, | ||
689 | }; | ||
684 | int ret; | 690 | int ret; |
685 | 691 | ||
686 | t = ip6t_get_target(e); | 692 | t = ip6t_get_target(e); |
687 | target = t->u.kernel.target; | 693 | ret = xt_check_target(&par, NFPROTO_IPV6, t->u.target_size - sizeof(*t), |
688 | ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t), | 694 | e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO); |
689 | name, e->comefrom, e->ipv6.proto, | ||
690 | e->ipv6.invflags & IP6T_INV_PROTO, e, t->data); | ||
691 | if (ret < 0) { | 695 | if (ret < 0) { |
692 | duprintf("ip_tables: check failed for `%s'.\n", | 696 | duprintf("ip_tables: check failed for `%s'.\n", |
693 | t->u.kernel.target->name); | 697 | t->u.kernel.target->name); |
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c index ac759a54f2c6..27b5adf670a2 100644 --- a/net/ipv6/netfilter/ip6t_HL.c +++ b/net/ipv6/netfilter/ip6t_HL.c | |||
@@ -54,12 +54,9 @@ hl_tg6(struct sk_buff *skb, const struct xt_target_param *par) | |||
54 | return XT_CONTINUE; | 54 | return XT_CONTINUE; |
55 | } | 55 | } |
56 | 56 | ||
57 | static bool | 57 | static bool hl_tg6_check(const struct xt_tgchk_param *par) |
58 | hl_tg6_check(const char *tablename, const void *entry, | ||
59 | const struct xt_target *target, void *targinfo, | ||
60 | unsigned int hook_mask) | ||
61 | { | 58 | { |
62 | const struct ip6t_HL_info *info = targinfo; | 59 | const struct ip6t_HL_info *info = par->targinfo; |
63 | 60 | ||
64 | if (info->mode > IP6T_HL_MAXMODE) { | 61 | if (info->mode > IP6T_HL_MAXMODE) { |
65 | printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", | 62 | printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", |
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index a31d3ecd1fc9..caa441d09567 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c | |||
@@ -453,12 +453,9 @@ log_tg6(struct sk_buff *skb, const struct xt_target_param *par) | |||
453 | } | 453 | } |
454 | 454 | ||
455 | 455 | ||
456 | static bool | 456 | static bool log_tg6_check(const struct xt_tgchk_param *par) |
457 | log_tg6_check(const char *tablename, const void *entry, | ||
458 | const struct xt_target *target, void *targinfo, | ||
459 | unsigned int hook_mask) | ||
460 | { | 457 | { |
461 | const struct ip6t_log_info *loginfo = targinfo; | 458 | const struct ip6t_log_info *loginfo = par->targinfo; |
462 | 459 | ||
463 | if (loginfo->level >= 8) { | 460 | if (loginfo->level >= 8) { |
464 | pr_debug("LOG: level %u >= 8\n", loginfo->level); | 461 | pr_debug("LOG: level %u >= 8\n", loginfo->level); |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index 1d5f3a70ed09..0981b4ccb8b1 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -213,13 +213,10 @@ reject_tg6(struct sk_buff *skb, const struct xt_target_param *par) | |||
213 | return NF_DROP; | 213 | return NF_DROP; |
214 | } | 214 | } |
215 | 215 | ||
216 | static bool | 216 | static bool reject_tg6_check(const struct xt_tgchk_param *par) |
217 | reject_tg6_check(const char *tablename, const void *entry, | ||
218 | const struct xt_target *target, void *targinfo, | ||
219 | unsigned int hook_mask) | ||
220 | { | 217 | { |
221 | const struct ip6t_reject_info *rejinfo = targinfo; | 218 | const struct ip6t_reject_info *rejinfo = par->targinfo; |
222 | const struct ip6t_entry *e = entry; | 219 | const struct ip6t_entry *e = par->entryinfo; |
223 | 220 | ||
224 | if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { | 221 | if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { |
225 | printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); | 222 | printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 817ab14f7cd6..f29513cd1399 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -471,35 +471,35 @@ int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr, | |||
471 | EXPORT_SYMBOL_GPL(xt_compat_match_to_user); | 471 | EXPORT_SYMBOL_GPL(xt_compat_match_to_user); |
472 | #endif /* CONFIG_COMPAT */ | 472 | #endif /* CONFIG_COMPAT */ |
473 | 473 | ||
474 | int xt_check_target(const struct xt_target *target, unsigned short family, | 474 | int xt_check_target(struct xt_tgchk_param *par, u_int8_t family, |
475 | unsigned int size, const char *table, unsigned int hook_mask, | 475 | unsigned int size, u_int8_t proto, bool inv_proto) |
476 | unsigned short proto, int inv_proto, const void *entry, | ||
477 | void *targinfo) | ||
478 | { | 476 | { |
479 | if (XT_ALIGN(target->targetsize) != size) { | 477 | if (XT_ALIGN(par->target->targetsize) != size) { |
480 | printk("%s_tables: %s target: invalid size %Zu != %u\n", | 478 | printk("%s_tables: %s target: invalid size %Zu != %u\n", |
481 | xt_prefix[family], target->name, | 479 | xt_prefix[family], par->target->name, |
482 | XT_ALIGN(target->targetsize), size); | 480 | XT_ALIGN(par->target->targetsize), size); |
483 | return -EINVAL; | 481 | return -EINVAL; |
484 | } | 482 | } |
485 | if (target->table && strcmp(target->table, table)) { | 483 | if (par->target->table != NULL && |
484 | strcmp(par->target->table, par->table) != 0) { | ||
486 | printk("%s_tables: %s target: only valid in %s table, not %s\n", | 485 | printk("%s_tables: %s target: only valid in %s table, not %s\n", |
487 | xt_prefix[family], target->name, target->table, table); | 486 | xt_prefix[family], par->target->name, |
487 | par->target->table, par->table); | ||
488 | return -EINVAL; | 488 | return -EINVAL; |
489 | } | 489 | } |
490 | if (target->hooks && (hook_mask & ~target->hooks) != 0) { | 490 | if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) { |
491 | printk("%s_tables: %s target: bad hook_mask %#x/%#x\n", | 491 | printk("%s_tables: %s target: bad hook_mask %#x/%#x\n", |
492 | xt_prefix[family], target->name, hook_mask, | 492 | xt_prefix[family], par->target->name, par->hook_mask, |
493 | target->hooks); | 493 | par->target->hooks); |
494 | return -EINVAL; | 494 | return -EINVAL; |
495 | } | 495 | } |
496 | if (target->proto && (target->proto != proto || inv_proto)) { | 496 | if (par->target->proto && (par->target->proto != proto || inv_proto)) { |
497 | printk("%s_tables: %s target: only valid for protocol %u\n", | 497 | printk("%s_tables: %s target: only valid for protocol %u\n", |
498 | xt_prefix[family], target->name, target->proto); | 498 | xt_prefix[family], par->target->name, |
499 | par->target->proto); | ||
499 | return -EINVAL; | 500 | return -EINVAL; |
500 | } | 501 | } |
501 | if (target->checkentry != NULL && | 502 | if (par->target->checkentry != NULL && !par->target->checkentry(par)) |
502 | !target->checkentry(table, entry, target, targinfo, hook_mask)) | ||
503 | return -EINVAL; | 503 | return -EINVAL; |
504 | return 0; | 504 | return 0; |
505 | } | 505 | } |
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c index 95ed267328a7..8fc9f35e67df 100644 --- a/net/netfilter/xt_CONNMARK.c +++ b/net/netfilter/xt_CONNMARK.c | |||
@@ -112,18 +112,15 @@ connmark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
112 | return XT_CONTINUE; | 112 | return XT_CONTINUE; |
113 | } | 113 | } |
114 | 114 | ||
115 | static bool | 115 | static bool connmark_tg_check_v0(const struct xt_tgchk_param *par) |
116 | connmark_tg_check_v0(const char *tablename, const void *entry, | ||
117 | const struct xt_target *target, void *targinfo, | ||
118 | unsigned int hook_mask) | ||
119 | { | 116 | { |
120 | const struct xt_connmark_target_info *matchinfo = targinfo; | 117 | const struct xt_connmark_target_info *matchinfo = par->targinfo; |
121 | 118 | ||
122 | if (matchinfo->mode == XT_CONNMARK_RESTORE) { | 119 | if (matchinfo->mode == XT_CONNMARK_RESTORE) { |
123 | if (strcmp(tablename, "mangle") != 0) { | 120 | if (strcmp(par->table, "mangle") != 0) { |
124 | printk(KERN_WARNING "CONNMARK: restore can only be " | 121 | printk(KERN_WARNING "CONNMARK: restore can only be " |
125 | "called from \"mangle\" table, not \"%s\"\n", | 122 | "called from \"mangle\" table, not \"%s\"\n", |
126 | tablename); | 123 | par->table); |
127 | return false; | 124 | return false; |
128 | } | 125 | } |
129 | } | 126 | } |
@@ -131,22 +128,19 @@ connmark_tg_check_v0(const char *tablename, const void *entry, | |||
131 | printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); | 128 | printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); |
132 | return false; | 129 | return false; |
133 | } | 130 | } |
134 | if (nf_ct_l3proto_try_module_get(target->family) < 0) { | 131 | if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { |
135 | printk(KERN_WARNING "can't load conntrack support for " | 132 | printk(KERN_WARNING "can't load conntrack support for " |
136 | "proto=%u\n", target->family); | 133 | "proto=%u\n", par->target->family); |
137 | return false; | 134 | return false; |
138 | } | 135 | } |
139 | return true; | 136 | return true; |
140 | } | 137 | } |
141 | 138 | ||
142 | static bool | 139 | static bool connmark_tg_check(const struct xt_tgchk_param *par) |
143 | connmark_tg_check(const char *tablename, const void *entry, | ||
144 | const struct xt_target *target, void *targinfo, | ||
145 | unsigned int hook_mask) | ||
146 | { | 140 | { |
147 | if (nf_ct_l3proto_try_module_get(target->family) < 0) { | 141 | if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { |
148 | printk(KERN_WARNING "cannot load conntrack support for " | 142 | printk(KERN_WARNING "cannot load conntrack support for " |
149 | "proto=%u\n", target->family); | 143 | "proto=%u\n", par->target->family); |
150 | return false; | 144 | return false; |
151 | } | 145 | } |
152 | return true; | 146 | return true; |
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c index 2211a2cef280..2041a3d4b4d8 100644 --- a/net/netfilter/xt_CONNSECMARK.c +++ b/net/netfilter/xt_CONNSECMARK.c | |||
@@ -85,16 +85,14 @@ connsecmark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
85 | return XT_CONTINUE; | 85 | return XT_CONTINUE; |
86 | } | 86 | } |
87 | 87 | ||
88 | static bool | 88 | static bool connsecmark_tg_check(const struct xt_tgchk_param *par) |
89 | connsecmark_tg_check(const char *tablename, const void *entry, | ||
90 | const struct xt_target *target, void *targinfo, | ||
91 | unsigned int hook_mask) | ||
92 | { | 89 | { |
93 | const struct xt_connsecmark_target_info *info = targinfo; | 90 | const struct xt_connsecmark_target_info *info = par->targinfo; |
94 | 91 | ||
95 | if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { | 92 | if (strcmp(par->table, "mangle") != 0 && |
93 | strcmp(par->table, "security") != 0) { | ||
96 | printk(KERN_INFO PFX "target only valid in the \'mangle\' " | 94 | printk(KERN_INFO PFX "target only valid in the \'mangle\' " |
97 | "or \'security\' tables, not \'%s\'.\n", tablename); | 95 | "or \'security\' tables, not \'%s\'.\n", par->table); |
98 | return false; | 96 | return false; |
99 | } | 97 | } |
100 | 98 | ||
@@ -108,9 +106,9 @@ connsecmark_tg_check(const char *tablename, const void *entry, | |||
108 | return false; | 106 | return false; |
109 | } | 107 | } |
110 | 108 | ||
111 | if (nf_ct_l3proto_try_module_get(target->family) < 0) { | 109 | if (nf_ct_l3proto_try_module_get(par->target->family) < 0) { |
112 | printk(KERN_WARNING "can't load conntrack support for " | 110 | printk(KERN_WARNING "can't load conntrack support for " |
113 | "proto=%u\n", target->family); | 111 | "proto=%u\n", par->target->family); |
114 | return false; | 112 | return false; |
115 | } | 113 | } |
116 | return true; | 114 | return true; |
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c index c78e80afdf3d..6a347e768f86 100644 --- a/net/netfilter/xt_DSCP.c +++ b/net/netfilter/xt_DSCP.c | |||
@@ -61,15 +61,12 @@ dscp_tg6(struct sk_buff *skb, const struct xt_target_param *par) | |||
61 | return XT_CONTINUE; | 61 | return XT_CONTINUE; |
62 | } | 62 | } |
63 | 63 | ||
64 | static bool | 64 | static bool dscp_tg_check(const struct xt_tgchk_param *par) |
65 | dscp_tg_check(const char *tablename, const void *e_void, | ||
66 | const struct xt_target *target, void *targinfo, | ||
67 | unsigned int hook_mask) | ||
68 | { | 65 | { |
69 | const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp; | 66 | const struct xt_DSCP_info *info = par->targinfo; |
70 | 67 | ||
71 | if (dscp > XT_DSCP_MAX) { | 68 | if (info->dscp > XT_DSCP_MAX) { |
72 | printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp); | 69 | printk(KERN_WARNING "DSCP: dscp %x out of range\n", info->dscp); |
73 | return false; | 70 | return false; |
74 | } | 71 | } |
75 | return true; | 72 | return true; |
@@ -95,12 +92,10 @@ tos_tg_v0(struct sk_buff *skb, const struct xt_target_param *par) | |||
95 | return XT_CONTINUE; | 92 | return XT_CONTINUE; |
96 | } | 93 | } |
97 | 94 | ||
98 | static bool | 95 | static bool tos_tg_check_v0(const struct xt_tgchk_param *par) |
99 | tos_tg_check_v0(const char *tablename, const void *e_void, | ||
100 | const struct xt_target *target, void *targinfo, | ||
101 | unsigned int hook_mask) | ||
102 | { | 96 | { |
103 | const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos; | 97 | const struct ipt_tos_target_info *info = par->targinfo; |
98 | const uint8_t tos = info->tos; | ||
104 | 99 | ||
105 | if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT && | 100 | if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT && |
106 | tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST && | 101 | tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST && |
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c index 27d03f396117..123ee0ba78c6 100644 --- a/net/netfilter/xt_MARK.c +++ b/net/netfilter/xt_MARK.c | |||
@@ -66,12 +66,9 @@ mark_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
66 | return XT_CONTINUE; | 66 | return XT_CONTINUE; |
67 | } | 67 | } |
68 | 68 | ||
69 | static bool | 69 | static bool mark_tg_check_v0(const struct xt_tgchk_param *par) |
70 | mark_tg_check_v0(const char *tablename, const void *entry, | ||
71 | const struct xt_target *target, void *targinfo, | ||
72 | unsigned int hook_mask) | ||
73 | { | 70 | { |
74 | const struct xt_mark_target_info *markinfo = targinfo; | 71 | const struct xt_mark_target_info *markinfo = par->targinfo; |
75 | 72 | ||
76 | if (markinfo->mark > 0xffffffff) { | 73 | if (markinfo->mark > 0xffffffff) { |
77 | printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); | 74 | printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); |
@@ -80,12 +77,9 @@ mark_tg_check_v0(const char *tablename, const void *entry, | |||
80 | return true; | 77 | return true; |
81 | } | 78 | } |
82 | 79 | ||
83 | static bool | 80 | static bool mark_tg_check_v1(const struct xt_tgchk_param *par) |
84 | mark_tg_check_v1(const char *tablename, const void *entry, | ||
85 | const struct xt_target *target, void *targinfo, | ||
86 | unsigned int hook_mask) | ||
87 | { | 81 | { |
88 | const struct xt_mark_target_info_v1 *markinfo = targinfo; | 82 | const struct xt_mark_target_info_v1 *markinfo = par->targinfo; |
89 | 83 | ||
90 | if (markinfo->mode != XT_MARK_SET | 84 | if (markinfo->mode != XT_MARK_SET |
91 | && markinfo->mode != XT_MARK_AND | 85 | && markinfo->mode != XT_MARK_AND |
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c index 3218ad63bd1d..56ee4f118b59 100644 --- a/net/netfilter/xt_NFLOG.c +++ b/net/netfilter/xt_NFLOG.c | |||
@@ -36,12 +36,9 @@ nflog_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
36 | return XT_CONTINUE; | 36 | return XT_CONTINUE; |
37 | } | 37 | } |
38 | 38 | ||
39 | static bool | 39 | static bool nflog_tg_check(const struct xt_tgchk_param *par) |
40 | nflog_tg_check(const char *tablename, const void *entry, | ||
41 | const struct xt_target *target, void *targetinfo, | ||
42 | unsigned int hookmask) | ||
43 | { | 40 | { |
44 | const struct xt_nflog_info *info = targetinfo; | 41 | const struct xt_nflog_info *info = par->targinfo; |
45 | 42 | ||
46 | if (info->flags & ~XT_NFLOG_MASK) | 43 | if (info->flags & ~XT_NFLOG_MASK) |
47 | return false; | 44 | return false; |
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c index 92e33524f784..edf4ab1f30ff 100644 --- a/net/netfilter/xt_RATEEST.c +++ b/net/netfilter/xt_RATEEST.c | |||
@@ -84,14 +84,9 @@ xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
84 | return XT_CONTINUE; | 84 | return XT_CONTINUE; |
85 | } | 85 | } |
86 | 86 | ||
87 | static bool | 87 | static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) |
88 | xt_rateest_tg_checkentry(const char *tablename, | ||
89 | const void *entry, | ||
90 | const struct xt_target *target, | ||
91 | void *targinfo, | ||
92 | unsigned int hook_mask) | ||
93 | { | 88 | { |
94 | struct xt_rateest_target_info *info = targinfo; | 89 | struct xt_rateest_target_info *info = par->targinfo; |
95 | struct xt_rateest *est; | 90 | struct xt_rateest *est; |
96 | struct { | 91 | struct { |
97 | struct nlattr opt; | 92 | struct nlattr opt; |
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c index ad05214e3809..e5777227192c 100644 --- a/net/netfilter/xt_SECMARK.c +++ b/net/netfilter/xt_SECMARK.c | |||
@@ -80,16 +80,14 @@ static bool checkentry_selinux(struct xt_secmark_target_info *info) | |||
80 | return true; | 80 | return true; |
81 | } | 81 | } |
82 | 82 | ||
83 | static bool | 83 | static bool secmark_tg_check(const struct xt_tgchk_param *par) |
84 | secmark_tg_check(const char *tablename, const void *entry, | ||
85 | const struct xt_target *target, void *targinfo, | ||
86 | unsigned int hook_mask) | ||
87 | { | 84 | { |
88 | struct xt_secmark_target_info *info = targinfo; | 85 | struct xt_secmark_target_info *info = par->targinfo; |
89 | 86 | ||
90 | if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { | 87 | if (strcmp(par->table, "mangle") != 0 && |
88 | strcmp(par->table, "security") != 0) { | ||
91 | printk(KERN_INFO PFX "target only valid in the \'mangle\' " | 89 | printk(KERN_INFO PFX "target only valid in the \'mangle\' " |
92 | "or \'security\' tables, not \'%s\'.\n", tablename); | 90 | "or \'security\' tables, not \'%s\'.\n", par->table); |
93 | return false; | 91 | return false; |
94 | } | 92 | } |
95 | 93 | ||
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index e08762d9b0ff..4f3b1f808795 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
@@ -237,16 +237,13 @@ static inline bool find_syn_match(const struct xt_entry_match *m) | |||
237 | return false; | 237 | return false; |
238 | } | 238 | } |
239 | 239 | ||
240 | static bool | 240 | static bool tcpmss_tg4_check(const struct xt_tgchk_param *par) |
241 | tcpmss_tg4_check(const char *tablename, const void *entry, | ||
242 | const struct xt_target *target, void *targinfo, | ||
243 | unsigned int hook_mask) | ||
244 | { | 241 | { |
245 | const struct xt_tcpmss_info *info = targinfo; | 242 | const struct xt_tcpmss_info *info = par->targinfo; |
246 | const struct ipt_entry *e = entry; | 243 | const struct ipt_entry *e = par->entryinfo; |
247 | 244 | ||
248 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && | 245 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && |
249 | (hook_mask & ~((1 << NF_INET_FORWARD) | | 246 | (par->hook_mask & ~((1 << NF_INET_FORWARD) | |
250 | (1 << NF_INET_LOCAL_OUT) | | 247 | (1 << NF_INET_LOCAL_OUT) | |
251 | (1 << NF_INET_POST_ROUTING))) != 0) { | 248 | (1 << NF_INET_POST_ROUTING))) != 0) { |
252 | printk("xt_TCPMSS: path-MTU clamping only supported in " | 249 | printk("xt_TCPMSS: path-MTU clamping only supported in " |
@@ -260,16 +257,13 @@ tcpmss_tg4_check(const char *tablename, const void *entry, | |||
260 | } | 257 | } |
261 | 258 | ||
262 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) | 259 | #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) |
263 | static bool | 260 | static bool tcpmss_tg6_check(const struct xt_tgchk_param *par) |
264 | tcpmss_tg6_check(const char *tablename, const void *entry, | ||
265 | const struct xt_target *target, void *targinfo, | ||
266 | unsigned int hook_mask) | ||
267 | { | 261 | { |
268 | const struct xt_tcpmss_info *info = targinfo; | 262 | const struct xt_tcpmss_info *info = par->targinfo; |
269 | const struct ip6t_entry *e = entry; | 263 | const struct ip6t_entry *e = par->entryinfo; |
270 | 264 | ||
271 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && | 265 | if (info->mss == XT_TCPMSS_CLAMP_PMTU && |
272 | (hook_mask & ~((1 << NF_INET_FORWARD) | | 266 | (par->hook_mask & ~((1 << NF_INET_FORWARD) | |
273 | (1 << NF_INET_LOCAL_OUT) | | 267 | (1 << NF_INET_LOCAL_OUT) | |
274 | (1 << NF_INET_POST_ROUTING))) != 0) { | 268 | (1 << NF_INET_POST_ROUTING))) != 0) { |
275 | printk("xt_TCPMSS: path-MTU clamping only supported in " | 269 | printk("xt_TCPMSS: path-MTU clamping only supported in " |
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index f08c49ea4bdc..1340c2fa3621 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c | |||
@@ -59,14 +59,9 @@ tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par) | |||
59 | return NF_DROP; | 59 | return NF_DROP; |
60 | } | 60 | } |
61 | 61 | ||
62 | static bool | 62 | static bool tproxy_tg_check(const struct xt_tgchk_param *par) |
63 | tproxy_tg_check(const char *tablename, | ||
64 | const void *entry, | ||
65 | const struct xt_target *target, | ||
66 | void *targetinfo, | ||
67 | unsigned int hook_mask) | ||
68 | { | 63 | { |
69 | const struct ipt_ip *i = entry; | 64 | const struct ipt_ip *i = par->entryinfo; |
70 | 65 | ||
71 | if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP) | 66 | if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP) |
72 | && !(i->invflags & IPT_INV_PROTO)) | 67 | && !(i->invflags & IPT_INV_PROTO)) |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 89791a56429a..a54dc3f8234f 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,9 +50,14 @@ 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, NULL, t->data); | 55 | par.target = target; |
56 | par.targinfo = t->data; | ||
57 | par.hook_mask = hook; | ||
58 | |||
59 | ret = xt_check_target(&par, NFPROTO_IPV4, | ||
60 | t->u.target_size - sizeof(*t), 0, false); | ||
55 | if (ret < 0) { | 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; |