diff options
-rw-r--r-- | extensions/GNUmakefile.in | 12 | ||||
-rw-r--r-- | extensions/libxt_set.h | 7 | ||||
-rw-r--r-- | include/ip6tables.h | 8 | ||||
-rw-r--r-- | include/iptables.h | 10 | ||||
-rw-r--r-- | include/xtables.h.in | 3 | ||||
-rw-r--r-- | ip6tables-multi.c | 5 | ||||
-rw-r--r-- | ip6tables-restore.c | 6 | ||||
-rw-r--r-- | ip6tables-save.c | 4 | ||||
-rw-r--r-- | ip6tables-standalone.c | 2 | ||||
-rw-r--r-- | ip6tables.c | 30 | ||||
-rw-r--r-- | iptables-multi.c | 6 | ||||
-rw-r--r-- | iptables-restore.c | 10 | ||||
-rw-r--r-- | iptables-save.c | 4 | ||||
-rw-r--r-- | iptables-standalone.c | 4 | ||||
-rw-r--r-- | iptables-xml.c | 2 | ||||
-rw-r--r-- | iptables.c | 32 | ||||
-rw-r--r-- | xtables.c | 66 |
17 files changed, 123 insertions, 88 deletions
diff --git a/extensions/GNUmakefile.in b/extensions/GNUmakefile.in index b96bd11f..0e562fb5 100644 --- a/extensions/GNUmakefile.in +++ b/extensions/GNUmakefile.in @@ -127,8 +127,8 @@ initext4.c: .initext4.dd for i in ${initext_func}; do \ echo "extern void lib$${i}_init(void);" >>$@; \ done; \ - echo "void init_extensions(void);" >>$@; \ - echo "void init_extensions(void)" >>$@; \ + echo "void init_extensions4(void);" >>$@; \ + echo "void init_extensions4(void)" >>$@; \ echo "{" >>$@; \ for i in ${initext_func}; do \ echo " ""lib$${i}_init();" >>$@; \ @@ -143,8 +143,8 @@ initext6.c: .initext6.dd for i in ${initext6_func}; do \ echo "extern void lib$${i}_init(void);" >>$@; \ done; \ - echo "void init_extensions(void);" >>$@; \ - echo "void init_extensions(void)" >>$@; \ + echo "void init_extensions6(void);" >>$@; \ + echo "void init_extensions6(void)" >>$@; \ echo "{" >>$@; \ for i in ${initext6_func}; do \ echo " ""lib$${i}_init();" >>$@; \ @@ -155,8 +155,8 @@ initext6.c: .initext6.dd # # Manual pages # -ex_matches = $(sort $(shell echo $(1) | LC_ALL=POSIX grep -Eo '\b[[:alnum:]_]+\b')) -ex_targets = $(sort $(shell echo $(1) | LC_ALL=POSIX grep -Eo '\b[[:alnum:]_]+\b')) +ex_matches = $(sort $(shell echo $(1) | LC_ALL=POSIX grep -Eo '\b[[:lower:][:digit:]_]+\b')) +ex_targets = $(sort $(shell echo $(1) | LC_ALL=POSIX grep -Eo '\b[[:upper:][:digit:]_]+\b')) man_run = \ ${AM_VERBOSE_GEN} \ for ext in $(1); do \ diff --git a/extensions/libxt_set.h b/extensions/libxt_set.h index 6b936911..4ac84fa9 100644 --- a/extensions/libxt_set.h +++ b/extensions/libxt_set.h @@ -114,7 +114,7 @@ parse_dirs_v0(const char *opt_arg, struct xt_set_info_v0 *info) if (tmp) xtables_error(PARAMETER_PROBLEM, "Can't be more src/dst options than %i.", - IPSET_DIM_MAX - 1); + IPSET_DIM_MAX); free(saved); } @@ -124,9 +124,8 @@ parse_dirs(const char *opt_arg, struct xt_set_info *info) { char *saved = strdup(opt_arg); char *ptr, *tmp = saved; - int i = 0; - while (i < (IPSET_DIM_MAX - 1) && tmp != NULL) { + while (info->dim < IPSET_DIM_MAX && tmp != NULL) { info->dim++; ptr = strsep(&tmp, ","); if (strncmp(ptr, "src", 3) == 0) @@ -139,7 +138,7 @@ parse_dirs(const char *opt_arg, struct xt_set_info *info) if (tmp) xtables_error(PARAMETER_PROBLEM, "Can't be more src/dst options than %i.", - IPSET_DIM_MAX - 1); + IPSET_DIM_MAX); free(saved); } diff --git a/include/ip6tables.h b/include/ip6tables.h index ca0f9a05..e976361f 100644 --- a/include/ip6tables.h +++ b/include/ip6tables.h @@ -10,10 +10,10 @@ extern int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **handle); -extern int for_each_chain(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *), int verbose, int builtinstoo, struct ip6tc_handle *handle); -extern int flush_entries(const ip6t_chainlabel chain, int verbose, struct ip6tc_handle *handle); -extern int delete_chain(const ip6t_chainlabel chain, int verbose, struct ip6tc_handle *handle); -void print_rule(const struct ip6t_entry *e, struct ip6tc_handle *h, const char *chain, int counters); +extern int for_each_chain6(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *), int verbose, int builtinstoo, struct ip6tc_handle *handle); +extern int flush_entries6(const ip6t_chainlabel chain, int verbose, struct ip6tc_handle *handle); +extern int delete_chain6(const ip6t_chainlabel chain, int verbose, struct ip6tc_handle *handle); +void print_rule6(const struct ip6t_entry *e, struct ip6tc_handle *h, const char *chain, int counters); extern struct xtables_globals ip6tables_globals; diff --git a/include/iptables.h b/include/iptables.h index 84211c32..65b32909 100644 --- a/include/iptables.h +++ b/include/iptables.h @@ -7,15 +7,15 @@ #include <iptables/internal.h> /* Your shared library should call one of these. */ -extern int do_command(int argc, char *argv[], char **table, +extern int do_command4(int argc, char *argv[], char **table, struct iptc_handle **handle); -extern int delete_chain(const ipt_chainlabel chain, int verbose, +extern int delete_chain4(const ipt_chainlabel chain, int verbose, struct iptc_handle *handle); -extern int flush_entries(const ipt_chainlabel chain, int verbose, +extern int flush_entries4(const ipt_chainlabel chain, int verbose, struct iptc_handle *handle); -extern int for_each_chain(int (*fn)(const ipt_chainlabel, int, struct iptc_handle *), +extern int for_each_chain4(int (*fn)(const ipt_chainlabel, int, struct iptc_handle *), int verbose, int builtinstoo, struct iptc_handle *handle); -extern void print_rule(const struct ipt_entry *e, +extern void print_rule4(const struct ipt_entry *e, struct iptc_handle *handle, const char *chain, int counters); /* kernel revision handling */ diff --git a/include/xtables.h.in b/include/xtables.h.in index 14d7b043..3bdf7248 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -379,7 +379,8 @@ extern void xtables_save_string(const char *value); # undef _init # define _init _INIT # endif - extern void init_extensions(void); + extern void init_extensions4(void); + extern void init_extensions6(void); #else # define _init __attribute__((constructor)) _INIT #endif diff --git a/ip6tables-multi.c b/ip6tables-multi.c index 7e6603f8..40ce37bf 100644 --- a/ip6tables-multi.c +++ b/ip6tables-multi.c @@ -2,10 +2,7 @@ #include <stdlib.h> #include <string.h> #include "xshared.h" - -int ip6tables_main(int argc, char **argv); -int ip6tables_save_main(int argc, char **argv); -int ip6tables_restore_main(int argc, char **argv); +#include "ip6tables-multi.h" static const struct subcommand multi6_subcommands[] = { {"ip6tables", ip6tables_main}, diff --git a/ip6tables-restore.c b/ip6tables-restore.c index 10c3acfc..5531d6e3 100644 --- a/ip6tables-restore.c +++ b/ip6tables-restore.c @@ -137,7 +137,7 @@ int main(int argc, char *argv[]) exit(1); } #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) - init_extensions(); + init_extensions6(); #endif while ((c = getopt_long(argc, argv, "bcvthnM:", options, NULL)) != -1) { @@ -226,12 +226,12 @@ int main(int argc, char *argv[]) if (noflush == 0) { DEBUGP("Cleaning all chains of table '%s'\n", table); - for_each_chain(flush_entries, verbose, 1, + for_each_chain6(flush_entries6, verbose, 1, handle); DEBUGP("Deleting all user-defined chains " "of table '%s'\n", table); - for_each_chain(delete_chain, verbose, 0, + for_each_chain6(delete_chain6, verbose, 0, handle); } diff --git a/ip6tables-save.c b/ip6tables-save.c index c3b8ec0d..d9ecc62d 100644 --- a/ip6tables-save.c +++ b/ip6tables-save.c @@ -109,7 +109,7 @@ static int do_output(const char *tablename) /* Dump out rules */ e = ip6tc_first_rule(chain, h); while(e) { - print_rule(e, h, chain, show_counters); + print_rule6(e, h, chain, show_counters); e = ip6tc_next_rule(e, h); } } @@ -149,7 +149,7 @@ int main(int argc, char *argv[]) exit(1); } #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) - init_extensions(); + init_extensions6(); #endif while ((c = getopt_long(argc, argv, "bcdt:", options, NULL)) != -1) { diff --git a/ip6tables-standalone.c b/ip6tables-standalone.c index 8661bd9c..7d346840 100644 --- a/ip6tables-standalone.c +++ b/ip6tables-standalone.c @@ -59,7 +59,7 @@ main(int argc, char *argv[]) } #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) - init_extensions(); + init_extensions6(); #endif ret = do_command6(argc, argv, &table, &handle); diff --git a/ip6tables.c b/ip6tables.c index 3beeddf6..f9909f13 100644 --- a/ip6tables.c +++ b/ip6tables.c @@ -127,12 +127,6 @@ static struct option original_opts[] = { {NULL}, }; -/* we need this for ip6tables-restore. ip6tables-restore.c sets line to the - * current line of the input file, in order to give a more precise error - * message. ip6tables itself doesn't need this, so it is initialized to the - * magic number of -1 */ -int line = -1; - void ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); struct xtables_globals ip6tables_globals = { .option_offset = 0, @@ -859,7 +853,7 @@ check_entry(const ip6t_chainlabel chain, struct ip6t_entry *fw, } int -for_each_chain(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *), +for_each_chain6(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *), int verbose, int builtinstoo, struct ip6tc_handle *handle) { int ret = 1; @@ -895,11 +889,11 @@ for_each_chain(int (*fn)(const ip6t_chainlabel, int, struct ip6tc_handle *), } int -flush_entries(const ip6t_chainlabel chain, int verbose, +flush_entries6(const ip6t_chainlabel chain, int verbose, struct ip6tc_handle *handle) { if (!chain) - return for_each_chain(flush_entries, verbose, 1, handle); + return for_each_chain6(flush_entries6, verbose, 1, handle); if (verbose) fprintf(stdout, "Flushing chain `%s'\n", chain); @@ -911,7 +905,7 @@ zero_entries(const ip6t_chainlabel chain, int verbose, struct ip6tc_handle *handle) { if (!chain) - return for_each_chain(zero_entries, verbose, 1, handle); + return for_each_chain6(zero_entries, verbose, 1, handle); if (verbose) fprintf(stdout, "Zeroing chain `%s'\n", chain); @@ -919,11 +913,11 @@ zero_entries(const ip6t_chainlabel chain, int verbose, } int -delete_chain(const ip6t_chainlabel chain, int verbose, +delete_chain6(const ip6t_chainlabel chain, int verbose, struct ip6tc_handle *handle) { if (!chain) - return for_each_chain(delete_chain, verbose, 0, handle); + return for_each_chain6(delete_chain6, verbose, 0, handle); if (verbose) fprintf(stdout, "Deleting chain `%s'\n", chain); @@ -1083,7 +1077,7 @@ static void print_ip(const char *prefix, const struct in6_addr *ip, /* We want this to be readable, so only print out neccessary fields. * Because that's the kind of world I want to live in. */ -void print_rule(const struct ip6t_entry *e, +void print_rule6(const struct ip6t_entry *e, struct ip6tc_handle *h, const char *chain, int counters) { const struct ip6t_entry_target *t; @@ -1215,7 +1209,7 @@ list_rules(const ip6t_chainlabel chain, int rulenum, int counters, while(e) { num++; if (!rulenum || num == rulenum) - print_rule(e, handle, this, counters); + print_rule6(e, handle, this, counters); e = ip6tc_next_rule(e, handle); } found = 1; @@ -1425,11 +1419,11 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand cs.jumpto = ""; cs.argv = argv; - /* re-set optind to 0 in case do_command gets called + /* re-set optind to 0 in case do_command6 gets called * a second time */ optind = 0; - /* clear mflags in case do_command gets called a second time + /* clear mflags in case do_command6 gets called a second time * (we clear the global list of all matches for security)*/ for (m = xtables_matches; m; m = m->next) m->mflags = 0; @@ -1953,7 +1947,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand *handle); break; case CMD_FLUSH: - ret = flush_entries(chain, cs.options&OPT_VERBOSE, *handle); + ret = flush_entries6(chain, cs.options&OPT_VERBOSE, *handle); break; case CMD_ZERO: ret = zero_entries(chain, cs.options&OPT_VERBOSE, *handle); @@ -1994,7 +1988,7 @@ int do_command6(int argc, char *argv[], char **table, struct ip6tc_handle **hand ret = ip6tc_create_chain(chain, *handle); break; case CMD_DELETE_CHAIN: - ret = delete_chain(chain, cs.options&OPT_VERBOSE, *handle); + ret = delete_chain6(chain, cs.options&OPT_VERBOSE, *handle); break; case CMD_RENAME_CHAIN: ret = ip6tc_rename_chain(chain, newname, *handle); diff --git a/iptables-multi.c b/iptables-multi.c index 754b5873..14579e00 100644 --- a/iptables-multi.c +++ b/iptables-multi.c @@ -2,11 +2,7 @@ #include <stdlib.h> #include <string.h> #include "xshared.h" - -int iptables_main(int argc, char **argv); -int iptables_save_main(int argc, char **argv); -int iptables_restore_main(int argc, char **argv); -int iptables_xml_main(int argc, char **argv); +#include "iptables-multi.h" static const struct subcommand multi4_subcommands[] = { {"iptables", iptables_main}, diff --git a/iptables-restore.c b/iptables-restore.c index c2cc58c8..e4f0604f 100644 --- a/iptables-restore.c +++ b/iptables-restore.c @@ -140,7 +140,7 @@ main(int argc, char *argv[]) exit(1); } #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) - init_extensions(); + init_extensions4(); #endif while ((c = getopt_long(argc, argv, "bcvthnM:T:", options, NULL)) != -1) { @@ -233,12 +233,12 @@ main(int argc, char *argv[]) if (noflush == 0) { DEBUGP("Cleaning all chains of table '%s'\n", table); - for_each_chain(flush_entries, verbose, 1, + for_each_chain4(flush_entries4, verbose, 1, handle); DEBUGP("Deleting all user-defined chains " "of table '%s'\n", table); - for_each_chain(delete_chain, verbose, 0, + for_each_chain4(delete_chain4, verbose, 0, handle); } @@ -438,13 +438,13 @@ main(int argc, char *argv[]) } } - DEBUGP("calling do_command(%u, argv, &%s, handle):\n", + DEBUGP("calling do_command4(%u, argv, &%s, handle):\n", newargc, curtable); for (a = 0; a < newargc; a++) DEBUGP("argv[%u]: %s\n", a, newargv[a]); - ret = do_command(newargc, newargv, + ret = do_command4(newargc, newargv, &newargv[2], &handle); free_argv(); diff --git a/iptables-save.c b/iptables-save.c index 3e3ec43c..dee17528 100644 --- a/iptables-save.c +++ b/iptables-save.c @@ -107,7 +107,7 @@ static int do_output(const char *tablename) /* Dump out rules */ e = iptc_first_rule(chain, h); while(e) { - print_rule(e, h, chain, show_counters); + print_rule4(e, h, chain, show_counters); e = iptc_next_rule(e, h); } } @@ -149,7 +149,7 @@ main(int argc, char *argv[]) exit(1); } #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) - init_extensions(); + init_extensions4(); #endif while ((c = getopt_long(argc, argv, "bcdt:", options, NULL)) != -1) { diff --git a/iptables-standalone.c b/iptables-standalone.c index 1f60e314..b0859464 100644 --- a/iptables-standalone.c +++ b/iptables-standalone.c @@ -59,10 +59,10 @@ main(int argc, char *argv[]) exit(1); } #if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) - init_extensions(); + init_extensions4(); #endif - ret = do_command(argc, argv, &table, &handle); + ret = do_command4(argc, argv, &table, &handle); if (ret) { ret = iptc_commit(handle); iptc_free(handle); diff --git a/iptables-xml.c b/iptables-xml.c index 57c7486d..dc3cd4f2 100644 --- a/iptables-xml.c +++ b/iptables-xml.c @@ -844,7 +844,7 @@ main(int argc, char *argv[]) } } - DEBUGP("calling do_command(%u, argv, &%s, handle):\n", + DEBUGP("calling do_command4(%u, argv, &%s, handle):\n", newargc, curTable); for (a = 0; a < newargc; a++) @@ -126,12 +126,6 @@ static struct option original_opts[] = { {NULL}, }; -/* we need this for iptables-restore. iptables-restore.c sets line to the - * current line of the input file, in order to give a more precise error - * message. iptables itself doesn't need this, so it is initialized to the - * magic number of -1 */ -int line = -1; - void iptables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); struct xtables_globals iptables_globals = { @@ -862,7 +856,7 @@ check_entry(const ipt_chainlabel chain, struct ipt_entry *fw, } int -for_each_chain(int (*fn)(const ipt_chainlabel, int, struct iptc_handle *), +for_each_chain4(int (*fn)(const ipt_chainlabel, int, struct iptc_handle *), int verbose, int builtinstoo, struct iptc_handle *handle) { int ret = 1; @@ -898,11 +892,11 @@ for_each_chain(int (*fn)(const ipt_chainlabel, int, struct iptc_handle *), } int -flush_entries(const ipt_chainlabel chain, int verbose, +flush_entries4(const ipt_chainlabel chain, int verbose, struct iptc_handle *handle) { if (!chain) - return for_each_chain(flush_entries, verbose, 1, handle); + return for_each_chain4(flush_entries4, verbose, 1, handle); if (verbose) fprintf(stdout, "Flushing chain `%s'\n", chain); @@ -914,7 +908,7 @@ zero_entries(const ipt_chainlabel chain, int verbose, struct iptc_handle *handle) { if (!chain) - return for_each_chain(zero_entries, verbose, 1, handle); + return for_each_chain4(zero_entries, verbose, 1, handle); if (verbose) fprintf(stdout, "Zeroing chain `%s'\n", chain); @@ -922,11 +916,11 @@ zero_entries(const ipt_chainlabel chain, int verbose, } int -delete_chain(const ipt_chainlabel chain, int verbose, +delete_chain4(const ipt_chainlabel chain, int verbose, struct iptc_handle *handle) { if (!chain) - return for_each_chain(delete_chain, verbose, 0, handle); + return for_each_chain4(delete_chain4, verbose, 0, handle); if (verbose) fprintf(stdout, "Deleting chain `%s'\n", chain); @@ -1101,7 +1095,7 @@ static void print_ip(const char *prefix, uint32_t ip, /* We want this to be readable, so only print out neccessary fields. * Because that's the kind of world I want to live in. */ -void print_rule(const struct ipt_entry *e, +void print_rule4(const struct ipt_entry *e, struct iptc_handle *h, const char *chain, int counters) { const struct ipt_entry_target *t; @@ -1224,7 +1218,7 @@ list_rules(const ipt_chainlabel chain, int rulenum, int counters, while(e) { num++; if (!rulenum || num == rulenum) - print_rule(e, handle, this, counters); + print_rule4(e, handle, this, counters); e = iptc_next_rule(e, handle); } found = 1; @@ -1429,7 +1423,7 @@ static void command_match(struct iptables_command_state *cs) xtables_error(OTHER_PROBLEM, "can't alloc memory!"); } -int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle) +int do_command4(int argc, char *argv[], char **table, struct iptc_handle **handle) { struct iptables_command_state cs; struct ipt_entry *e = NULL; @@ -1453,11 +1447,11 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle cs.jumpto = ""; cs.argv = argv; - /* re-set optind to 0 in case do_command gets called + /* re-set optind to 0 in case do_command4 gets called * a second time */ optind = 0; - /* clear mflags in case do_command gets called a second time + /* clear mflags in case do_command4 gets called a second time * (we clear the global list of all matches for security)*/ for (m = xtables_matches; m; m = m->next) m->mflags = 0; @@ -1989,7 +1983,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle *handle); break; case CMD_FLUSH: - ret = flush_entries(chain, cs.options&OPT_VERBOSE, *handle); + ret = flush_entries4(chain, cs.options&OPT_VERBOSE, *handle); break; case CMD_ZERO: ret = zero_entries(chain, cs.options&OPT_VERBOSE, *handle); @@ -2030,7 +2024,7 @@ int do_command(int argc, char *argv[], char **table, struct iptc_handle **handle ret = iptc_create_chain(chain, *handle); break; case CMD_DELETE_CHAIN: - ret = delete_chain(chain, cs.options&OPT_VERBOSE, *handle); + ret = delete_chain4(chain, cs.options&OPT_VERBOSE, *handle); break; case CMD_RENAME_CHAIN: ret = iptc_rename_chain(chain, newname, *handle); @@ -58,6 +58,12 @@ #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" #endif +/* we need this for ip6?tables-restore. ip6?tables-restore.c sets line to the + * current line of the input file, in order to give a more precise error + * message. ip6?tables itself doesn't need this, so it is initialized to the + * magic number of -1 */ +int line = -1; + void basic_exit_err(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); struct xtables_globals *xt_params = NULL; @@ -157,10 +163,18 @@ static const char *xtables_libdir; /* the path to command to load kernel module */ const char *xtables_modprobe_program; -/* Keeping track of external matches and targets: linked lists. */ +/* Keep track of matches/targets pending full registration: linked lists. */ +struct xtables_match *xtables_pending_matches; +struct xtables_target *xtables_pending_targets; + +/* Keep track of fully registered external matches/targets: linked lists. */ struct xtables_match *xtables_matches; struct xtables_target *xtables_targets; +/* Fully register a match/target which was previously partially registered. */ +static void xtables_fully_register_pending_match(struct xtables_match *me); +static void xtables_fully_register_pending_target(struct xtables_target *me); + void xtables_init(void) { xtables_libdir = getenv("XTABLES_LIBDIR"); @@ -539,6 +553,7 @@ struct xtables_match * xtables_find_match(const char *name, enum xtables_tryload tryload, struct xtables_rule_match **matches) { + struct xtables_match **dptr; struct xtables_match *ptr; const char *icmp6 = "icmp6"; @@ -554,6 +569,18 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, (strcmp(name,"icmp6") == 0) ) name = icmp6; + /* Trigger delayed initialization */ + for (dptr = &xtables_pending_matches; *dptr; ) { + if (strcmp(name, (*dptr)->name) == 0) { + ptr = *dptr; + *dptr = (*dptr)->next; + ptr->next = NULL; + xtables_fully_register_pending_match(ptr); + } else { + dptr = &((*dptr)->next); + } + } + for (ptr = xtables_matches; ptr; ptr = ptr->next) { if (strcmp(name, ptr->name) == 0) { struct xtables_match *clone; @@ -619,6 +646,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, struct xtables_target * xtables_find_target(const char *name, enum xtables_tryload tryload) { + struct xtables_target **dptr; struct xtables_target *ptr; /* Standard target? */ @@ -629,6 +657,18 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) || strcmp(name, XTC_LABEL_RETURN) == 0) name = "standard"; + /* Trigger delayed initialization */ + for (dptr = &xtables_pending_targets; *dptr; ) { + if (strcmp(name, (*dptr)->name) == 0) { + ptr = *dptr; + *dptr = (*dptr)->next; + ptr->next = NULL; + xtables_fully_register_pending_target(ptr); + } else { + dptr = &((*dptr)->next); + } + } + for (ptr = xtables_targets; ptr; ptr = ptr->next) { if (strcmp(name, ptr->name) == 0) break; @@ -740,8 +780,6 @@ static void xtables_check_options(const char *name, const struct option *opt) void xtables_register_match(struct xtables_match *me) { - struct xtables_match **i, *old; - if (me->version == NULL) { fprintf(stderr, "%s: match %s<%u> is missing a version\n", xt_params->program_name, me->name, me->revision); @@ -777,6 +815,15 @@ void xtables_register_match(struct xtables_match *me) if (me->family != afinfo->family && me->family != AF_UNSPEC) return; + /* place on linked list of matches pending full registration */ + me->next = xtables_pending_matches; + xtables_pending_matches = me; +} + +static void xtables_fully_register_pending_match(struct xtables_match *me) +{ + struct xtables_match **i, *old; + old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL); if (old) { if (old->revision == me->revision && @@ -830,8 +877,6 @@ void xtables_register_matches(struct xtables_match *match, unsigned int n) void xtables_register_target(struct xtables_target *me) { - struct xtables_target *old; - if (me->version == NULL) { fprintf(stderr, "%s: target %s<%u> is missing a version\n", xt_params->program_name, me->name, me->revision); @@ -867,6 +912,15 @@ void xtables_register_target(struct xtables_target *me) if (me->family != afinfo->family && me->family != AF_UNSPEC) return; + /* place on linked list of targets pending full registration */ + me->next = xtables_pending_targets; + xtables_pending_targets = me; +} + +static void xtables_fully_register_pending_target(struct xtables_target *me) +{ + struct xtables_target *old; + old = xtables_find_target(me->name, XTF_DURING_LOAD); if (old) { struct xtables_target **i; @@ -1323,7 +1377,7 @@ void xtables_ipparse_any(const char *name, struct in_addr **addrpp, const char *xtables_ip6addr_to_numeric(const struct in6_addr *addrp) { - /* 0000:0000:0000:0000:0000:000.000.000.000 + /* 0000:0000:0000:0000:0000:0000:000.000.000.000 * 0000:0000:0000:0000:0000:0000:0000:0000 */ static char buf[50+1]; return inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); |