diff options
Diffstat (limited to 'iptables/ip6tables-restore.c')
-rw-r--r-- | iptables/ip6tables-restore.c | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c index dc0acb05..8a47f09c 100644 --- a/iptables/ip6tables-restore.c +++ b/iptables/ip6tables-restore.c @@ -15,6 +15,7 @@ #include <stdio.h> #include <stdlib.h> #include "ip6tables.h" +#include "xshared.h" #include "xtables.h" #include "libiptc/libip6tc.h" #include "ip6tables-multi.h" @@ -25,17 +26,23 @@ #define DEBUGP(x, args...) #endif -static int counters = 0, verbose = 0, noflush = 0; +static int counters = 0, verbose = 0, noflush = 0, wait = 0; + +static struct timeval wait_interval = { + .tv_sec = 1, +}; /* Keeping track of external matches and targets. */ static const struct option options[] = { - {.name = "counters", .has_arg = false, .val = 'c'}, - {.name = "verbose", .has_arg = false, .val = 'v'}, - {.name = "test", .has_arg = false, .val = 't'}, - {.name = "help", .has_arg = false, .val = 'h'}, - {.name = "noflush", .has_arg = false, .val = 'n'}, - {.name = "modprobe", .has_arg = true, .val = 'M'}, - {.name = "table", .has_arg = true, .val = 'T'}, + {.name = "counters", .has_arg = 0, .val = 'c'}, + {.name = "verbose", .has_arg = 0, .val = 'v'}, + {.name = "test", .has_arg = 0, .val = 't'}, + {.name = "help", .has_arg = 0, .val = 'h'}, + {.name = "noflush", .has_arg = 0, .val = 'n'}, + {.name = "modprobe", .has_arg = 1, .val = 'M'}, + {.name = "table", .has_arg = 1, .val = 'T'}, + {.name = "wait", .has_arg = 2, .val = 'w'}, + {.name = "wait-interval", .has_arg = 2, .val = 'W'}, {NULL}, }; @@ -43,14 +50,16 @@ static void print_usage(const char *name, const char *version) __attribute__((no static void print_usage(const char *name, const char *version) { - fprintf(stderr, "Usage: %s [-c] [-v] [-t] [-h] [-n] [-T table] [-M command]\n" + fprintf(stderr, "Usage: %s [-c] [-v] [-t] [-h] [-n] [-w secs] [-W usecs] [-T table] [-M command]\n" " [ --counters ]\n" " [ --verbose ]\n" " [ --test ]\n" " [ --help ]\n" " [ --noflush ]\n" + " [ --wait=<seconds>\n" + " [ --wait-interval=<usecs>\n" " [ --table=<TABLE> ]\n" - " [ --modprobe=<command> ]\n", name); + " [ --modprobe=<command> ]\n", name); exit(1); } @@ -181,7 +190,7 @@ int ip6tables_restore_main(int argc, char *argv[]) { struct xtc_handle *handle = NULL; char buffer[10240]; - int c; + int c, lock; char curtable[XT_TABLE_MAXNAMELEN + 1]; FILE *in; int in_table = 0, testing = 0; @@ -189,6 +198,7 @@ int ip6tables_restore_main(int argc, char *argv[]) const struct xtc_ops *ops = &ip6tc_ops; line = 0; + lock = XT_LOCK_NOT_ACQUIRED; ip6tables_globals.program_name = "ip6tables-restore"; c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6); @@ -203,7 +213,7 @@ int ip6tables_restore_main(int argc, char *argv[]) init_extensions6(); #endif - while ((c = getopt_long(argc, argv, "bcvthnM:T:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "bcvthnwWM:T:", options, NULL)) != -1) { switch (c) { case 'b': fprintf(stderr, "-b/--binary option is not implemented\n"); @@ -224,6 +234,12 @@ int ip6tables_restore_main(int argc, char *argv[]) case 'n': noflush = 1; break; + case 'w': + wait = parse_wait_time(argc, argv); + break; + case 'W': + parse_wait_interval(argc, argv, &wait_interval); + break; case 'M': xtables_modprobe_program = optarg; break; @@ -268,8 +284,23 @@ int ip6tables_restore_main(int argc, char *argv[]) DEBUGP("Not calling commit, testing\n"); ret = 1; } + + /* Done with the current table, release the lock. */ + if (lock >= 0) { + xtables_unlock(lock); + lock = XT_LOCK_NOT_ACQUIRED; + } + in_table = 0; } else if ((buffer[0] == '*') && (!in_table)) { + /* Acquire a lock before we create a new table handle */ + lock = xtables_lock(wait, &wait_interval); + if (lock == XT_LOCK_BUSY) { + fprintf(stderr, "Another app is currently holding the xtables lock. " + "Perhaps you want to use the -w option?\n"); + exit(RESOURCE_PROBLEM); + } + /* New table */ char *table; |