Commit af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37f

Authored by Jan Engelhardt
Committed by Patrick McHardy
1 parent 7eb3558655

netfilter: xtables: move extension arguments into compound structure (5/6)

This patch does this for target extensions' checkentry functions.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>

Showing 39 changed files with 208 additions and 283 deletions Side-by-side Diff

include/linux/netfilter/x_tables.h
... ... @@ -234,6 +234,23 @@
234 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 254 struct xt_match
238 255 {
239 256 struct list_head list;
... ... @@ -291,11 +308,7 @@
291 308 hook_mask is a bitmask of hooks from which it can be
292 309 called. */
293 310 /* Should return true or false. */
294   - bool (*checkentry)(const char *tablename,
295   - const void *entry,
296   - const struct xt_target *target,
297   - void *targinfo,
298   - unsigned int hook_mask);
  311 + bool (*checkentry)(const struct xt_tgchk_param *);
299 312  
300 313 /* Called when entry of this type deleted. */
301 314 void (*destroy)(const struct xt_target *target, void *targinfo);
... ... @@ -376,10 +389,8 @@
376 389  
377 390 extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family,
378 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,
380   - unsigned int size, const char *table, unsigned int hook,
381   - unsigned short proto, int inv_proto,
382   - const void *entry, void *targinfo);
  392 +extern int xt_check_target(struct xt_tgchk_param *, u_int8_t family,
  393 + unsigned int size, u_int8_t proto, bool inv_proto);
383 394  
384 395 extern struct xt_table *xt_register_table(struct net *net,
385 396 struct xt_table *table,
include/linux/netfilter_bridge/ebtables.h
... ... @@ -310,9 +310,9 @@
310 310 #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg))
311 311 /* True if the hook mask denotes that the rule is in a base chain,
312 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 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 316 /* True if the target is not a standard target */
317 317 #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
318 318  
net/bridge/netfilter/ebt_arpreply.c
... ... @@ -57,20 +57,16 @@
57 57 return info->target;
58 58 }
59 59  
60   -static bool
61   -ebt_arpreply_tg_check(const char *tablename, const void *entry,
62   - const struct xt_target *target, void *data,
63   - unsigned int hookmask)
  60 +static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
64 61 {
65   - const struct ebt_arpreply_info *info = data;
66   - const struct ebt_entry *e = entry;
  62 + const struct ebt_arpreply_info *info = par->targinfo;
  63 + const struct ebt_entry *e = par->entryinfo;
67 64  
68 65 if (BASE_CHAIN && info->target == EBT_RETURN)
69 66 return false;
70 67 if (e->ethproto != htons(ETH_P_ARP) ||
71 68 e->invflags & EBT_IPROTO)
72 69 return false;
73   - CLEAR_BASE_CHAIN_BIT;
74 70 return true;
75 71 }
76 72  
net/bridge/netfilter/ebt_dnat.c
... ... @@ -26,19 +26,20 @@
26 26 return info->target;
27 27 }
28 28  
29   -static bool
30   -ebt_dnat_tg_check(const char *tablename, const void *entry,
31   - const struct xt_target *target, void *data,
32   - unsigned int hookmask)
  29 +static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
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 34 if (BASE_CHAIN && info->target == EBT_RETURN)
37 35 return false;
38   - CLEAR_BASE_CHAIN_BIT;
39   - if ( (strcmp(tablename, "nat") ||
40   - (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) &&
41   - (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
  36 +
  37 + hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
  38 + if ((strcmp(par->table, "nat") != 0 ||
  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 43 return false;
43 44 if (INVALID_TARGET)
44 45 return false;
net/bridge/netfilter/ebt_log.c
... ... @@ -24,12 +24,9 @@
24 24  
25 25 static DEFINE_SPINLOCK(ebt_log_lock);
26 26  
27   -static bool
28   -ebt_log_tg_check(const char *table, const void *entry,
29   - const struct xt_target *target, void *data,
30   - unsigned int hook_mask)
  27 +static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
31 28 {
32   - struct ebt_log_info *info = data;
  29 + struct ebt_log_info *info = par->targinfo;
33 30  
34 31 if (info->bitmask & ~EBT_LOG_MASK)
35 32 return false;
net/bridge/netfilter/ebt_mark.c
... ... @@ -36,18 +36,14 @@
36 36 return info->target | ~EBT_VERDICT_BITS;
37 37 }
38 38  
39   -static bool
40   -ebt_mark_tg_check(const char *table, const void *e,
41   - const struct xt_target *target, void *data,
42   - unsigned int hookmask)
  39 +static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
43 40 {
44   - const struct ebt_mark_t_info *info = data;
  41 + const struct ebt_mark_t_info *info = par->targinfo;
45 42 int tmp;
46 43  
47 44 tmp = info->target | ~EBT_VERDICT_BITS;
48 45 if (BASE_CHAIN && tmp == EBT_RETURN)
49 46 return false;
50   - CLEAR_BASE_CHAIN_BIT;
51 47 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
52 48 return false;
53 49 tmp = info->target & ~EBT_VERDICT_BITS;
net/bridge/netfilter/ebt_nflog.c
... ... @@ -35,12 +35,9 @@
35 35 return EBT_CONTINUE;
36 36 }
37 37  
38   -static bool
39   -ebt_nflog_tg_check(const char *table, const void *e,
40   - const struct xt_target *target, void *data,
41   - unsigned int hookmask)
  38 +static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
42 39 {
43   - struct ebt_nflog_info *info = data;
  40 + struct ebt_nflog_info *info = par->targinfo;
44 41  
45 42 if (info->flags & ~EBT_NFLOG_MASK)
46 43 return false;
net/bridge/netfilter/ebt_redirect.c
... ... @@ -32,18 +32,19 @@
32 32 return info->target;
33 33 }
34 34  
35   -static bool
36   -ebt_redirect_tg_check(const char *tablename, const void *e,
37   - const struct xt_target *target, void *data,
38   - unsigned int hookmask)
  35 +static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
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 40 if (BASE_CHAIN && info->target == EBT_RETURN)
43 41 return false;
44   - CLEAR_BASE_CHAIN_BIT;
45   - if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) &&
46   - (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
  42 +
  43 + hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
  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 48 return false;
48 49 if (INVALID_TARGET)
49 50 return false;
net/bridge/netfilter/ebt_snat.c
... ... @@ -42,18 +42,14 @@
42 42 return info->target | ~EBT_VERDICT_BITS;
43 43 }
44 44  
45   -static bool
46   -ebt_snat_tg_check(const char *tablename, const void *e,
47   - const struct xt_target *target, void *data,
48   - unsigned int hookmask)
  45 +static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
49 46 {
50   - const struct ebt_nat_info *info = data;
  47 + const struct ebt_nat_info *info = par->targinfo;
51 48 int tmp;
52 49  
53 50 tmp = info->target | ~EBT_VERDICT_BITS;
54 51 if (BASE_CHAIN && tmp == EBT_RETURN)
55 52 return false;
56   - CLEAR_BASE_CHAIN_BIT;
57 53  
58 54 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
59 55 return false;
net/bridge/netfilter/ebt_ulog.c
... ... @@ -254,12 +254,9 @@
254 254 return EBT_CONTINUE;
255 255 }
256 256  
257   -static bool
258   -ebt_ulog_tg_check(const char *table, const void *entry,
259   - const struct xt_target *target, void *data,
260   - unsigned int hookmask)
  257 +static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
261 258 {
262   - struct ebt_ulog_info *uloginfo = data;
  259 + struct ebt_ulog_info *uloginfo = par->targinfo;
263 260  
264 261 if (uloginfo->nlgroup > 31)
265 262 return false;
net/bridge/netfilter/ebtables.c
... ... @@ -363,9 +363,10 @@
363 363 }
364 364  
365 365 static inline int
366   -ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
367   - const char *name, unsigned int hookmask, unsigned int *cnt)
  366 +ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
  367 + unsigned int *cnt)
368 368 {
  369 + const struct ebt_entry *e = par->entryinfo;
369 370 struct xt_target *watcher;
370 371 size_t left = ((char *)e + e->target_offset) - (char *)w;
371 372 int ret;
... ... @@ -383,9 +384,10 @@
383 384 return -ENOENT;
384 385 w->u.watcher = watcher;
385 386  
386   - ret = xt_check_target(watcher, NFPROTO_BRIDGE, w->watcher_size,
387   - name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
388   - e, w->data);
  387 + par->target = watcher;
  388 + par->targinfo = w->data;
  389 + ret = xt_check_target(par, NFPROTO_BRIDGE, w->watcher_size,
  390 + e->ethproto, e->invflags & EBT_IPROTO);
389 391 if (ret < 0) {
390 392 module_put(watcher->me);
391 393 return ret;
... ... @@ -619,6 +621,7 @@
619 621 size_t gap;
620 622 int ret;
621 623 struct xt_mtchk_param mtpar;
  624 + struct xt_tgchk_param tgpar;
622 625  
623 626 /* don't mess with the struct ebt_entries */
624 627 if (e->bitmask == 0)
625 628  
... ... @@ -660,14 +663,14 @@
660 663 }
661 664 i = 0;
662 665  
663   - mtpar.table = name;
664   - mtpar.entryinfo = e;
665   - mtpar.hook_mask = hookmask;
  666 + mtpar.table = tgpar.table = name;
  667 + mtpar.entryinfo = tgpar.entryinfo = e;
  668 + mtpar.hook_mask = tgpar.hook_mask = hookmask;
666 669 ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
667 670 if (ret != 0)
668 671 goto cleanup_matches;
669 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 674 if (ret != 0)
672 675 goto cleanup_watchers;
673 676 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
... ... @@ -703,9 +706,10 @@
703 706 goto cleanup_watchers;
704 707 }
705 708  
706   - ret = xt_check_target(target, NFPROTO_BRIDGE, t->target_size,
707   - name, hookmask, e->ethproto, e->invflags & EBT_IPROTO,
708   - e, t->data);
  709 + tgpar.target = target;
  710 + tgpar.targinfo = t->data;
  711 + ret = xt_check_target(&tgpar, NFPROTO_BRIDGE, t->target_size,
  712 + e->ethproto, e->invflags & EBT_IPROTO);
709 713 if (ret < 0) {
710 714 module_put(target->me);
711 715 goto cleanup_watchers;
net/ipv4/netfilter/arp_tables.c
... ... @@ -457,16 +457,18 @@
457 457  
458 458 static inline int check_target(struct arpt_entry *e, const char *name)
459 459 {
460   - struct arpt_entry_target *t;
461   - struct xt_target *target;
  460 + struct arpt_entry_target *t = arpt_get_target(e);
462 461 int ret;
  462 + struct xt_tgchk_param par = {
  463 + .table = name,
  464 + .entryinfo = e,
  465 + .target = t->u.kernel.target,
  466 + .targinfo = t->data,
  467 + .hook_mask = e->comefrom,
  468 + };
463 469  
464   - t = arpt_get_target(e);
465   - target = t->u.kernel.target;
466   -
467   - ret = xt_check_target(target, NFPROTO_ARP,
468   - t->u.target_size - sizeof(*t),
469   - name, e->comefrom, 0, 0, e, t->data);
  470 + ret = xt_check_target(&par, NFPROTO_ARP,
  471 + t->u.target_size - sizeof(*t), 0, false);
470 472 if (ret < 0) {
471 473 duprintf("arp_tables: check failed for `%s'.\n",
472 474 t->u.kernel.target->name);
net/ipv4/netfilter/arpt_mangle.c
... ... @@ -54,11 +54,9 @@
54 54 return mangle->target;
55 55 }
56 56  
57   -static bool
58   -checkentry(const char *tablename, const void *e, const struct xt_target *target,
59   - void *targinfo, unsigned int hook_mask)
  57 +static bool checkentry(const struct xt_tgchk_param *par)
60 58 {
61   - const struct arpt_mangle *mangle = targinfo;
  59 + const struct arpt_mangle *mangle = par->targinfo;
62 60  
63 61 if (mangle->flags & ~ARPT_MANGLE_MASK ||
64 62 !(mangle->flags & ARPT_MANGLE_MASK))
net/ipv4/netfilter/ip_tables.c
... ... @@ -655,15 +655,18 @@
655 655  
656 656 static int check_target(struct ipt_entry *e, const char *name)
657 657 {
658   - struct ipt_entry_target *t;
659   - struct xt_target *target;
  658 + struct ipt_entry_target *t = ipt_get_target(e);
  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 666 int ret;
661 667  
662   - t = ipt_get_target(e);
663   - target = t->u.kernel.target;
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);
  668 + ret = xt_check_target(&par, NFPROTO_IPV4, t->u.target_size - sizeof(*t),
  669 + e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
667 670 if (ret < 0) {
668 671 duprintf("ip_tables: check failed for `%s'.\n",
669 672 t->u.kernel.target->name);
net/ipv4/netfilter/ipt_CLUSTERIP.c
... ... @@ -347,13 +347,10 @@
347 347 return XT_CONTINUE;
348 348 }
349 349  
350   -static bool
351   -clusterip_tg_check(const char *tablename, const void *e_void,
352   - const struct xt_target *target, void *targinfo,
353   - unsigned int hook_mask)
  350 +static bool clusterip_tg_check(const struct xt_tgchk_param *par)
354 351 {
355   - struct ipt_clusterip_tgt_info *cipinfo = targinfo;
356   - const struct ipt_entry *e = e_void;
  352 + struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
  353 + const struct ipt_entry *e = par->entryinfo;
357 354  
358 355 struct clusterip_config *config;
359 356  
360 357  
... ... @@ -404,9 +401,9 @@
404 401 }
405 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 405 printk(KERN_WARNING "can't load conntrack support for "
409   - "proto=%u\n", target->family);
  406 + "proto=%u\n", par->target->family);
410 407 return false;
411 408 }
412 409  
net/ipv4/netfilter/ipt_ECN.c
... ... @@ -93,13 +93,10 @@
93 93 return XT_CONTINUE;
94 94 }
95 95  
96   -static bool
97   -ecn_tg_check(const char *tablename, const void *e_void,
98   - const struct xt_target *target, void *targinfo,
99   - unsigned int hook_mask)
  96 +static bool ecn_tg_check(const struct xt_tgchk_param *par)
100 97 {
101   - const struct ipt_ECN_info *einfo = targinfo;
102   - const struct ipt_entry *e = e_void;
  98 + const struct ipt_ECN_info *einfo = par->targinfo;
  99 + const struct ipt_entry *e = par->entryinfo;
103 100  
104 101 if (einfo->operation & IPT_ECN_OP_MASK) {
105 102 printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
net/ipv4/netfilter/ipt_LOG.c
... ... @@ -440,12 +440,9 @@
440 440 return XT_CONTINUE;
441 441 }
442 442  
443   -static bool
444   -log_tg_check(const char *tablename, const void *e,
445   - const struct xt_target *target, void *targinfo,
446   - unsigned int hook_mask)
  443 +static bool log_tg_check(const struct xt_tgchk_param *par)
447 444 {
448   - const struct ipt_log_info *loginfo = targinfo;
  445 + const struct ipt_log_info *loginfo = par->targinfo;
449 446  
450 447 if (loginfo->level >= 8) {
451 448 pr_debug("LOG: level %u >= 8\n", loginfo->level);
net/ipv4/netfilter/ipt_MASQUERADE.c
... ... @@ -31,12 +31,9 @@
31 31 static DEFINE_RWLOCK(masq_lock);
32 32  
33 33 /* FIXME: Multiple targets. --RR */
34   -static bool
35   -masquerade_tg_check(const char *tablename, const void *e,
36   - const struct xt_target *target, void *targinfo,
37   - unsigned int hook_mask)
  34 +static bool masquerade_tg_check(const struct xt_tgchk_param *par)
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 38 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
42 39 pr_debug("masquerade_check: bad MAP_IPS.\n");
net/ipv4/netfilter/ipt_NETMAP.c
... ... @@ -22,12 +22,9 @@
22 22 MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
23 23 MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
24 24  
25   -static bool
26   -netmap_tg_check(const char *tablename, const void *e,
27   - const struct xt_target *target, void *targinfo,
28   - unsigned int hook_mask)
  25 +static bool netmap_tg_check(const struct xt_tgchk_param *par)
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 29 if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
33 30 pr_debug("NETMAP:check: bad MAP_IPS.\n");
net/ipv4/netfilter/ipt_REDIRECT.c
... ... @@ -26,12 +26,9 @@
26 26 MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
27 27  
28 28 /* FIXME: Take multiple ranges --RR */
29   -static bool
30   -redirect_tg_check(const char *tablename, const void *e,
31   - const struct xt_target *target, void *targinfo,
32   - unsigned int hook_mask)
  29 +static bool redirect_tg_check(const struct xt_tgchk_param *par)
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 33 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
37 34 pr_debug("redirect_check: bad MAP_IPS.\n");
net/ipv4/netfilter/ipt_REJECT.c
... ... @@ -175,13 +175,10 @@
175 175 return NF_DROP;
176 176 }
177 177  
178   -static bool
179   -reject_tg_check(const char *tablename, const void *e_void,
180   - const struct xt_target *target, void *targinfo,
181   - unsigned int hook_mask)
  178 +static bool reject_tg_check(const struct xt_tgchk_param *par)
182 179 {
183   - const struct ipt_reject_info *rejinfo = targinfo;
184   - const struct ipt_entry *e = e_void;
  180 + const struct ipt_reject_info *rejinfo = par->targinfo;
  181 + const struct ipt_entry *e = par->entryinfo;
185 182  
186 183 if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
187 184 printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
net/ipv4/netfilter/ipt_TTL.c
... ... @@ -59,12 +59,9 @@
59 59 return XT_CONTINUE;
60 60 }
61 61  
62   -static bool
63   -ttl_tg_check(const char *tablename, const void *e,
64   - const struct xt_target *target, void *targinfo,
65   - unsigned int hook_mask)
  62 +static bool ttl_tg_check(const struct xt_tgchk_param *par)
66 63 {
67   - const struct ipt_TTL_info *info = targinfo;
  64 + const struct ipt_TTL_info *info = par->targinfo;
68 65  
69 66 if (info->mode > IPT_TTL_MAXMODE) {
70 67 printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
net/ipv4/netfilter/ipt_ULOG.c
... ... @@ -313,12 +313,9 @@
313 313 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
314 314 }
315 315  
316   -static bool
317   -ulog_tg_check(const char *tablename, const void *e,
318   - const struct xt_target *target, void *targinfo,
319   - unsigned int hookmask)
  316 +static bool ulog_tg_check(const struct xt_tgchk_param *par)
320 317 {
321   - const struct ipt_ulog_info *loginfo = targinfo;
  318 + const struct ipt_ulog_info *loginfo = par->targinfo;
322 319  
323 320 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
324 321 pr_debug("ipt_ULOG: prefix term %i\n",
net/ipv4/netfilter/nf_nat_rule.c
... ... @@ -128,13 +128,9 @@
128 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,
132   - const void *entry,
133   - const struct xt_target *target,
134   - void *targinfo,
135   - unsigned int hook_mask)
  131 +static bool ipt_snat_checkentry(const struct xt_tgchk_param *par)
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 135 /* Must be a valid range */
140 136 if (mr->rangesize != 1) {
141 137  
... ... @@ -144,13 +140,9 @@
144 140 return true;
145 141 }
146 142  
147   -static bool ipt_dnat_checkentry(const char *tablename,
148   - const void *entry,
149   - const struct xt_target *target,
150   - void *targinfo,
151   - unsigned int hook_mask)
  143 +static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par)
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 147 /* Must be a valid range */
156 148 if (mr->rangesize != 1) {
net/ipv6/netfilter/ip6_tables.c
... ... @@ -679,15 +679,19 @@
679 679  
680 680 static int check_target(struct ip6t_entry *e, const char *name)
681 681 {
682   - struct ip6t_entry_target *t;
683   - struct xt_target *target;
  682 + struct ip6t_entry_target *t = ip6t_get_target(e);
  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 690 int ret;
685 691  
686 692 t = ip6t_get_target(e);
687   - target = t->u.kernel.target;
688   - ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t),
689   - name, e->comefrom, e->ipv6.proto,
690   - e->ipv6.invflags & IP6T_INV_PROTO, e, t->data);
  693 + ret = xt_check_target(&par, NFPROTO_IPV6, t->u.target_size - sizeof(*t),
  694 + e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
691 695 if (ret < 0) {
692 696 duprintf("ip_tables: check failed for `%s'.\n",
693 697 t->u.kernel.target->name);
net/ipv6/netfilter/ip6t_HL.c
... ... @@ -54,12 +54,9 @@
54 54 return XT_CONTINUE;
55 55 }
56 56  
57   -static bool
58   -hl_tg6_check(const char *tablename, const void *entry,
59   - const struct xt_target *target, void *targinfo,
60   - unsigned int hook_mask)
  57 +static bool hl_tg6_check(const struct xt_tgchk_param *par)
61 58 {
62   - const struct ip6t_HL_info *info = targinfo;
  59 + const struct ip6t_HL_info *info = par->targinfo;
63 60  
64 61 if (info->mode > IP6T_HL_MAXMODE) {
65 62 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
net/ipv6/netfilter/ip6t_LOG.c
... ... @@ -453,12 +453,9 @@
453 453 }
454 454  
455 455  
456   -static bool
457   -log_tg6_check(const char *tablename, const void *entry,
458   - const struct xt_target *target, void *targinfo,
459   - unsigned int hook_mask)
  456 +static bool log_tg6_check(const struct xt_tgchk_param *par)
460 457 {
461   - const struct ip6t_log_info *loginfo = targinfo;
  458 + const struct ip6t_log_info *loginfo = par->targinfo;
462 459  
463 460 if (loginfo->level >= 8) {
464 461 pr_debug("LOG: level %u >= 8\n", loginfo->level);
net/ipv6/netfilter/ip6t_REJECT.c
... ... @@ -213,13 +213,10 @@
213 213 return NF_DROP;
214 214 }
215 215  
216   -static bool
217   -reject_tg6_check(const char *tablename, const void *entry,
218   - const struct xt_target *target, void *targinfo,
219   - unsigned int hook_mask)
  216 +static bool reject_tg6_check(const struct xt_tgchk_param *par)
220 217 {
221   - const struct ip6t_reject_info *rejinfo = targinfo;
222   - const struct ip6t_entry *e = entry;
  218 + const struct ip6t_reject_info *rejinfo = par->targinfo;
  219 + const struct ip6t_entry *e = par->entryinfo;
223 220  
224 221 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
225 222 printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
net/netfilter/x_tables.c
... ... @@ -471,35 +471,35 @@
471 471 EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
472 472 #endif /* CONFIG_COMPAT */
473 473  
474   -int xt_check_target(const struct xt_target *target, unsigned short family,
475   - unsigned int size, const char *table, unsigned int hook_mask,
476   - unsigned short proto, int inv_proto, const void *entry,
477   - void *targinfo)
  474 +int xt_check_target(struct xt_tgchk_param *par, u_int8_t family,
  475 + unsigned int size, u_int8_t proto, bool inv_proto)
478 476 {
479   - if (XT_ALIGN(target->targetsize) != size) {
  477 + if (XT_ALIGN(par->target->targetsize) != size) {
480 478 printk("%s_tables: %s target: invalid size %Zu != %u\n",
481   - xt_prefix[family], target->name,
482   - XT_ALIGN(target->targetsize), size);
  479 + xt_prefix[family], par->target->name,
  480 + XT_ALIGN(par->target->targetsize), size);
483 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 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 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 491 printk("%s_tables: %s target: bad hook_mask %#x/%#x\n",
492   - xt_prefix[family], target->name, hook_mask,
493   - target->hooks);
  492 + xt_prefix[family], par->target->name, par->hook_mask,
  493 + par->target->hooks);
494 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 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 500 return -EINVAL;
500 501 }
501   - if (target->checkentry != NULL &&
502   - !target->checkentry(table, entry, target, targinfo, hook_mask))
  502 + if (par->target->checkentry != NULL && !par->target->checkentry(par))
503 503 return -EINVAL;
504 504 return 0;
505 505 }
net/netfilter/xt_CONNMARK.c
... ... @@ -112,18 +112,15 @@
112 112 return XT_CONTINUE;
113 113 }
114 114  
115   -static bool
116   -connmark_tg_check_v0(const char *tablename, const void *entry,
117   - const struct xt_target *target, void *targinfo,
118   - unsigned int hook_mask)
  115 +static bool connmark_tg_check_v0(const struct xt_tgchk_param *par)
119 116 {
120   - const struct xt_connmark_target_info *matchinfo = targinfo;
  117 + const struct xt_connmark_target_info *matchinfo = par->targinfo;
121 118  
122 119 if (matchinfo->mode == XT_CONNMARK_RESTORE) {
123   - if (strcmp(tablename, "mangle") != 0) {
  120 + if (strcmp(par->table, "mangle") != 0) {
124 121 printk(KERN_WARNING "CONNMARK: restore can only be "
125 122 "called from \"mangle\" table, not \"%s\"\n",
126   - tablename);
  123 + par->table);
127 124 return false;
128 125 }
129 126 }
130 127  
131 128  
132 129  
133 130  
... ... @@ -131,22 +128,19 @@
131 128 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
132 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 132 printk(KERN_WARNING "can't load conntrack support for "
136   - "proto=%u\n", target->family);
  133 + "proto=%u\n", par->target->family);
137 134 return false;
138 135 }
139 136 return true;
140 137 }
141 138  
142   -static bool
143   -connmark_tg_check(const char *tablename, const void *entry,
144   - const struct xt_target *target, void *targinfo,
145   - unsigned int hook_mask)
  139 +static bool connmark_tg_check(const struct xt_tgchk_param *par)
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 142 printk(KERN_WARNING "cannot load conntrack support for "
149   - "proto=%u\n", target->family);
  143 + "proto=%u\n", par->target->family);
150 144 return false;
151 145 }
152 146 return true;
net/netfilter/xt_CONNSECMARK.c
... ... @@ -85,16 +85,14 @@
85 85 return XT_CONTINUE;
86 86 }
87 87  
88   -static bool
89   -connsecmark_tg_check(const char *tablename, const void *entry,
90   - const struct xt_target *target, void *targinfo,
91   - unsigned int hook_mask)
  88 +static bool connsecmark_tg_check(const struct xt_tgchk_param *par)
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 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 96 return false;
99 97 }
100 98  
101 99  
... ... @@ -108,9 +106,9 @@
108 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 110 printk(KERN_WARNING "can't load conntrack support for "
113   - "proto=%u\n", target->family);
  111 + "proto=%u\n", par->target->family);
114 112 return false;
115 113 }
116 114 return true;
net/netfilter/xt_DSCP.c
... ... @@ -61,15 +61,12 @@
61 61 return XT_CONTINUE;
62 62 }
63 63  
64   -static bool
65   -dscp_tg_check(const char *tablename, const void *e_void,
66   - const struct xt_target *target, void *targinfo,
67   - unsigned int hook_mask)
  64 +static bool dscp_tg_check(const struct xt_tgchk_param *par)
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) {
72   - printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp);
  68 + if (info->dscp > XT_DSCP_MAX) {
  69 + printk(KERN_WARNING "DSCP: dscp %x out of range\n", info->dscp);
73 70 return false;
74 71 }
75 72 return true;
76 73  
... ... @@ -95,12 +92,10 @@
95 92 return XT_CONTINUE;
96 93 }
97 94  
98   -static bool
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)
  95 +static bool tos_tg_check_v0(const struct xt_tgchk_param *par)
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 100 if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT &&
106 101 tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST &&
net/netfilter/xt_MARK.c
... ... @@ -66,12 +66,9 @@
66 66 return XT_CONTINUE;
67 67 }
68 68  
69   -static bool
70   -mark_tg_check_v0(const char *tablename, const void *entry,
71   - const struct xt_target *target, void *targinfo,
72   - unsigned int hook_mask)
  69 +static bool mark_tg_check_v0(const struct xt_tgchk_param *par)
73 70 {
74   - const struct xt_mark_target_info *markinfo = targinfo;
  71 + const struct xt_mark_target_info *markinfo = par->targinfo;
75 72  
76 73 if (markinfo->mark > 0xffffffff) {
77 74 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
78 75  
... ... @@ -80,12 +77,9 @@
80 77 return true;
81 78 }
82 79  
83   -static bool
84   -mark_tg_check_v1(const char *tablename, const void *entry,
85   - const struct xt_target *target, void *targinfo,
86   - unsigned int hook_mask)
  80 +static bool mark_tg_check_v1(const struct xt_tgchk_param *par)
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 84 if (markinfo->mode != XT_MARK_SET
91 85 && markinfo->mode != XT_MARK_AND
net/netfilter/xt_NFLOG.c
... ... @@ -36,12 +36,9 @@
36 36 return XT_CONTINUE;
37 37 }
38 38  
39   -static bool
40   -nflog_tg_check(const char *tablename, const void *entry,
41   - const struct xt_target *target, void *targetinfo,
42   - unsigned int hookmask)
  39 +static bool nflog_tg_check(const struct xt_tgchk_param *par)
43 40 {
44   - const struct xt_nflog_info *info = targetinfo;
  41 + const struct xt_nflog_info *info = par->targinfo;
45 42  
46 43 if (info->flags & ~XT_NFLOG_MASK)
47 44 return false;
net/netfilter/xt_RATEEST.c
... ... @@ -84,14 +84,9 @@
84 84 return XT_CONTINUE;
85 85 }
86 86  
87   -static bool
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)
  87 +static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
93 88 {
94   - struct xt_rateest_target_info *info = targinfo;
  89 + struct xt_rateest_target_info *info = par->targinfo;
95 90 struct xt_rateest *est;
96 91 struct {
97 92 struct nlattr opt;
net/netfilter/xt_SECMARK.c
... ... @@ -80,16 +80,14 @@
80 80 return true;
81 81 }
82 82  
83   -static bool
84   -secmark_tg_check(const char *tablename, const void *entry,
85   - const struct xt_target *target, void *targinfo,
86   - unsigned int hook_mask)
  83 +static bool secmark_tg_check(const struct xt_tgchk_param *par)
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 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 91 return false;
94 92 }
95 93  
net/netfilter/xt_TCPMSS.c
... ... @@ -237,16 +237,13 @@
237 237 return false;
238 238 }
239 239  
240   -static bool
241   -tcpmss_tg4_check(const char *tablename, const void *entry,
242   - const struct xt_target *target, void *targinfo,
243   - unsigned int hook_mask)
  240 +static bool tcpmss_tg4_check(const struct xt_tgchk_param *par)
244 241 {
245   - const struct xt_tcpmss_info *info = targinfo;
246   - const struct ipt_entry *e = entry;
  242 + const struct xt_tcpmss_info *info = par->targinfo;
  243 + const struct ipt_entry *e = par->entryinfo;
247 244  
248 245 if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
249   - (hook_mask & ~((1 << NF_INET_FORWARD) |
  246 + (par->hook_mask & ~((1 << NF_INET_FORWARD) |
250 247 (1 << NF_INET_LOCAL_OUT) |
251 248 (1 << NF_INET_POST_ROUTING))) != 0) {
252 249 printk("xt_TCPMSS: path-MTU clamping only supported in "
253 250  
254 251  
... ... @@ -260,16 +257,13 @@
260 257 }
261 258  
262 259 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
263   -static bool
264   -tcpmss_tg6_check(const char *tablename, const void *entry,
265   - const struct xt_target *target, void *targinfo,
266   - unsigned int hook_mask)
  260 +static bool tcpmss_tg6_check(const struct xt_tgchk_param *par)
267 261 {
268   - const struct xt_tcpmss_info *info = targinfo;
269   - const struct ip6t_entry *e = entry;
  262 + const struct xt_tcpmss_info *info = par->targinfo;
  263 + const struct ip6t_entry *e = par->entryinfo;
270 264  
271 265 if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
272   - (hook_mask & ~((1 << NF_INET_FORWARD) |
  266 + (par->hook_mask & ~((1 << NF_INET_FORWARD) |
273 267 (1 << NF_INET_LOCAL_OUT) |
274 268 (1 << NF_INET_POST_ROUTING))) != 0) {
275 269 printk("xt_TCPMSS: path-MTU clamping only supported in "
net/netfilter/xt_TPROXY.c
... ... @@ -59,14 +59,9 @@
59 59 return NF_DROP;
60 60 }
61 61  
62   -static bool
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)
  62 +static bool tproxy_tg_check(const struct xt_tgchk_param *par)
68 63 {
69   - const struct ipt_ip *i = entry;
  64 + const struct ipt_ip *i = par->entryinfo;
70 65  
71 66 if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
72 67 && !(i->invflags & IPT_INV_PROTO))
... ... @@ -40,6 +40,7 @@
40 40  
41 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 44 struct xt_target *target;
44 45 int ret = 0;
45 46  
46 47  
... ... @@ -49,9 +50,14 @@
49 50 return -ENOENT;
50 51  
51 52 t->u.kernel.target = target;
  53 + par.table = table;
  54 + par.entryinfo = NULL;
  55 + par.target = target;
  56 + par.targinfo = t->data;
  57 + par.hook_mask = hook;
52 58  
53   - ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
54   - table, hook, 0, 0, NULL, t->data);
  59 + ret = xt_check_target(&par, NFPROTO_IPV4,
  60 + t->u.target_size - sizeof(*t), 0, false);
55 61 if (ret < 0) {
56 62 module_put(t->u.kernel.target->me);
57 63 return ret;