You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
288 lines
11 KiB
288 lines
11 KiB
twoerner: Adapted version of the upstream patch for 1.4.21 |
|
|
|
|
|
From aaa4ace72ba1d195bbf436134a336816c33f7bd0 Mon Sep 17 00:00:00 2001 |
|
From: Jiri Popelka <jpopelka@redhat.com> |
|
Date: Fri, 4 Jul 2014 15:50:41 +0200 |
|
Subject: iptables: add optional [seconds] argument to -w |
|
|
|
This patch adds an optional numeric argument |
|
to -w option (added with 93587a0) so one can |
|
specify how long to wait for an exclusive lock. |
|
|
|
If the value isn't specified it works as before, |
|
i.e. program waits indefinitely. |
|
|
|
If user specifies it, program exits after |
|
the given time interval passes. |
|
|
|
This patch also adds the -w/--wait to nftables |
|
compat code, so the parser doesn't complain. |
|
|
|
[ In the original patch, iptables-compat -w X was not working, |
|
I have fixed by adding the dummy code not to break scripts |
|
using the new optional argument --pablo ] |
|
|
|
Signed-off-by: Jiri Popelka <jpopelka@redhat.com> |
|
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
|
|
|
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c |
|
index 2ebfd6c..8db13b4 100644 |
|
--- a/iptables/ip6tables.c |
|
+++ b/iptables/ip6tables.c |
|
@@ -102,7 +102,7 @@ static struct option original_opts[] = { |
|
{.name = "numeric", .has_arg = 0, .val = 'n'}, |
|
{.name = "out-interface", .has_arg = 1, .val = 'o'}, |
|
{.name = "verbose", .has_arg = 0, .val = 'v'}, |
|
- {.name = "wait", .has_arg = 0, .val = 'w'}, |
|
+ {.name = "wait", .has_arg = 2, .val = 'w'}, |
|
{.name = "exact", .has_arg = 0, .val = 'x'}, |
|
{.name = "version", .has_arg = 0, .val = 'V'}, |
|
{.name = "help", .has_arg = 2, .val = 'h'}, |
|
@@ -258,7 +258,7 @@ exit_printhelp(const struct xtables_rule_match *matches) |
|
" network interface name ([+] for wildcard)\n" |
|
" --table -t table table to manipulate (default: `filter')\n" |
|
" --verbose -v verbose mode\n" |
|
-" --wait -w wait for the xtables lock\n" |
|
+" --wait -w [seconds] wait for the xtables lock\n" |
|
" --line-numbers print line numbers when listing\n" |
|
" --exact -x expand numbers (display exact values)\n" |
|
/*"[!] --fragment -f match second or further fragments only\n"*/ |
|
@@ -1322,7 +1322,7 @@ int do_command6(int argc, char *argv[], char **table, |
|
struct in6_addr *smasks = NULL, *dmasks = NULL; |
|
|
|
int verbose = 0; |
|
- bool wait = false; |
|
+ int wait = 0; |
|
const char *chain = NULL; |
|
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL; |
|
const char *policy = NULL, *newname = NULL; |
|
@@ -1358,7 +1358,7 @@ int do_command6(int argc, char *argv[], char **table, |
|
|
|
opts = xt_params->orig_opts; |
|
while ((cs.c = getopt_long(argc, argv, |
|
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvwnt:m:xc:g:46", |
|
+ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvw::nt:m:xc:g:46", |
|
opts, NULL)) != -1) { |
|
switch (cs.c) { |
|
/* |
|
@@ -1602,7 +1602,16 @@ int do_command6(int argc, char *argv[], char **table, |
|
"You cannot use `-w' from " |
|
"ip6tables-restore"); |
|
} |
|
- wait = true; |
|
+ wait = -1; |
|
+ if (optarg) { |
|
+ if (sscanf(optarg, "%i", &wait) != 1) |
|
+ xtables_error(PARAMETER_PROBLEM, |
|
+ "wait seconds not numeric"); |
|
+ } else if (optind < argc && argv[optind][0] != '-' |
|
+ && argv[optind][0] != '!') |
|
+ if (sscanf(argv[optind++], "%i", &wait) != 1) |
|
+ xtables_error(PARAMETER_PROBLEM, |
|
+ "wait seconds not numeric"); |
|
break; |
|
|
|
case 'm': |
|
@@ -1753,8 +1762,11 @@ int do_command6(int argc, char *argv[], char **table, |
|
|
|
/* Attempt to acquire the xtables lock */ |
|
if (!restore && !xtables_lock(wait)) { |
|
- fprintf(stderr, "Another app is currently holding the xtables lock. " |
|
- "Perhaps you want to use the -w option?\n"); |
|
+ fprintf(stderr, "Another app is currently holding the xtables lock. "); |
|
+ if (wait == 0) |
|
+ fprintf(stderr, "Perhaps you want to use the -w option?\n"); |
|
+ else |
|
+ fprintf(stderr, "Stopped waiting after %ds.\n", wait); |
|
xtables_free_opts(1); |
|
exit(RESOURCE_PROBLEM); |
|
} |
|
diff --git a/iptables/iptables.8.in b/iptables/iptables.8.in |
|
index 8ef222e..ceba5dc 100644 |
|
--- a/iptables/iptables.8.in |
|
+++ b/iptables/iptables.8.in |
|
@@ -361,12 +361,13 @@ For appending, insertion, deletion and replacement, this causes |
|
detailed information on the rule or rules to be printed. \fB\-v\fP may be |
|
specified multiple times to possibly emit more detailed debug statements. |
|
.TP |
|
-\fB\-w\fP, \fB\-\-wait\fP |
|
+\fB\-w\fP, \fB\-\-wait\fP [\fIseconds\fP] |
|
Wait for the xtables lock. |
|
To prevent multiple instances of the program from running concurrently, |
|
an attempt will be made to obtain an exclusive lock at launch. By default, |
|
the program will exit if the lock cannot be obtained. This option will |
|
-make the program wait until the exclusive lock can be obtained. |
|
+make the program wait (indefinitely or for optional \fIseconds\fP) until |
|
+the exclusive lock can be obtained. |
|
.TP |
|
\fB\-n\fP, \fB\-\-numeric\fP |
|
Numeric output. |
|
diff --git a/iptables/iptables.c b/iptables/iptables.c |
|
index 471bff0..88953c4 100644 |
|
--- a/iptables/iptables.c |
|
+++ b/iptables/iptables.c |
|
@@ -99,7 +99,7 @@ static struct option original_opts[] = { |
|
{.name = "numeric", .has_arg = 0, .val = 'n'}, |
|
{.name = "out-interface", .has_arg = 1, .val = 'o'}, |
|
{.name = "verbose", .has_arg = 0, .val = 'v'}, |
|
- {.name = "wait", .has_arg = 0, .val = 'w'}, |
|
+ {.name = "wait", .has_arg = 2, .val = 'w'}, |
|
{.name = "exact", .has_arg = 0, .val = 'x'}, |
|
{.name = "fragments", .has_arg = 0, .val = 'f'}, |
|
{.name = "version", .has_arg = 0, .val = 'V'}, |
|
@@ -252,7 +252,7 @@ exit_printhelp(const struct xtables_rule_match *matches) |
|
" network interface name ([+] for wildcard)\n" |
|
" --table -t table table to manipulate (default: `filter')\n" |
|
" --verbose -v verbose mode\n" |
|
-" --wait -w wait for the xtables lock\n" |
|
+" --wait -w [seconds] wait for the xtables lock\n" |
|
" --line-numbers print line numbers when listing\n" |
|
" --exact -x expand numbers (display exact values)\n" |
|
"[!] --fragment -f match second or further fragments only\n" |
|
@@ -1318,7 +1318,7 @@ int do_command4(int argc, char *argv[], char **table, |
|
struct in_addr *daddrs = NULL, *dmasks = NULL; |
|
|
|
int verbose = 0; |
|
- bool wait = false; |
|
+ int wait = 0; |
|
const char *chain = NULL; |
|
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL; |
|
const char *policy = NULL, *newname = NULL; |
|
@@ -1351,10 +1351,9 @@ int do_command4(int argc, char *argv[], char **table, |
|
/* Suppress error messages: we may add new options if we |
|
demand-load a protocol. */ |
|
opterr = 0; |
|
- |
|
opts = xt_params->orig_opts; |
|
while ((cs.c = getopt_long(argc, argv, |
|
- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvwnt:m:xc:g:46", |
|
+ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::nt:m:xc:g:46", |
|
opts, NULL)) != -1) { |
|
switch (cs.c) { |
|
/* |
|
@@ -1596,7 +1595,16 @@ int do_command4(int argc, char *argv[], char **table, |
|
"You cannot use `-w' from " |
|
"iptables-restore"); |
|
} |
|
- wait = true; |
|
+ wait = -1; |
|
+ if (optarg) { |
|
+ if (sscanf(optarg, "%i", &wait) != 1) |
|
+ xtables_error(PARAMETER_PROBLEM, |
|
+ "wait seconds not numeric"); |
|
+ } else if (optind < argc && argv[optind][0] != '-' |
|
+ && argv[optind][0] != '!') |
|
+ if (sscanf(argv[optind++], "%i", &wait) != 1) |
|
+ xtables_error(PARAMETER_PROBLEM, |
|
+ "wait seconds not numeric"); |
|
break; |
|
|
|
case 'm': |
|
@@ -1750,8 +1758,11 @@ int do_command4(int argc, char *argv[], char **table, |
|
|
|
/* Attempt to acquire the xtables lock */ |
|
if (!restore && !xtables_lock(wait)) { |
|
- fprintf(stderr, "Another app is currently holding the xtables lock. " |
|
- "Perhaps you want to use the -w option?\n"); |
|
+ fprintf(stderr, "Another app is currently holding the xtables lock. "); |
|
+ if (wait == 0) |
|
+ fprintf(stderr, "Perhaps you want to use the -w option?\n"); |
|
+ else |
|
+ fprintf(stderr, "Stopped waiting after %ds.\n", wait); |
|
xtables_free_opts(1); |
|
exit(RESOURCE_PROBLEM); |
|
} |
|
diff --git a/iptables/xshared.c b/iptables/xshared.c |
|
index 6c9992e..b18022e 100644 |
|
--- a/iptables/xshared.c |
|
+++ b/iptables/xshared.c |
|
@@ -243,10 +243,11 @@ void xs_init_match(struct xtables_match *match) |
|
match->init(match->m); |
|
} |
|
|
|
-bool xtables_lock(bool wait) |
|
+bool xtables_lock(int wait) |
|
{ |
|
int i = 0, ret, xt_socket; |
|
struct sockaddr_un xt_addr; |
|
+ int waited = 0; |
|
|
|
memset(&xt_addr, 0, sizeof(xt_addr)); |
|
xt_addr.sun_family = AF_UNIX; |
|
@@ -261,11 +262,12 @@ bool xtables_lock(bool wait) |
|
offsetof(struct sockaddr_un, sun_path)+XT_SOCKET_LEN); |
|
if (ret == 0) |
|
return true; |
|
- else if (wait == false) |
|
+ else if (wait >= 0 && waited >= wait) |
|
return false; |
|
if (++i % 2 == 0) |
|
fprintf(stderr, "Another app is currently holding the xtables lock; " |
|
- "waiting for it to exit...\n"); |
|
+ "waiting (%ds) for it to exit...\n", waited); |
|
+ waited++; |
|
sleep(1); |
|
} |
|
} |
|
diff --git a/iptables/xshared.h b/iptables/xshared.h |
|
index 27c5b78..40dd915 100644 |
|
--- a/iptables/xshared.h |
|
+++ b/iptables/xshared.h |
|
@@ -84,7 +84,7 @@ extern struct xtables_match *load_proto(struct iptables_command_state *); |
|
extern int subcmd_main(int, char **, const struct subcommand *); |
|
extern void xs_init_target(struct xtables_target *); |
|
extern void xs_init_match(struct xtables_match *); |
|
-extern bool xtables_lock(bool wait); |
|
+extern bool xtables_lock(int wait); |
|
|
|
extern const struct xtables_afinfo *afinfo; |
|
|
|
#diff --git a/iptables/xtables.c b/iptables/xtables.c |
|
#index 45a5ac6..d661dd1 100644 |
|
#--- a/iptables/xtables.c |
|
#+++ b/iptables/xtables.c |
|
#@@ -85,6 +85,7 @@ static struct option original_opts[] = { |
|
# {.name = "numeric", .has_arg = 0, .val = 'n'}, |
|
# {.name = "out-interface", .has_arg = 1, .val = 'o'}, |
|
# {.name = "verbose", .has_arg = 0, .val = 'v'}, |
|
#+ {.name = "wait", .has_arg = 2, .val = 'w'}, |
|
# {.name = "exact", .has_arg = 0, .val = 'x'}, |
|
# {.name = "fragments", .has_arg = 0, .val = 'f'}, |
|
# {.name = "version", .has_arg = 0, .val = 'V'}, |
|
#@@ -683,6 +684,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, |
|
# { |
|
# struct iptables_command_state cs; |
|
# int verbose = 0; |
|
#+ int wait = 0; |
|
# const char *chain = NULL; |
|
# const char *policy = NULL, *newname = NULL; |
|
# unsigned int rulenum = 0, command = 0; |
|
#@@ -722,7 +724,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, |
|
# |
|
# opts = xt_params->orig_opts; |
|
# while ((cs.c = getopt_long(argc, argv, |
|
#- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:xc:g:46", |
|
#+ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::nt:m:xc:g:46", |
|
# opts, NULL)) != -1) { |
|
# switch (cs.c) { |
|
# /* |
|
#@@ -1007,6 +1009,15 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, |
|
# "You cannot use `-w' from " |
|
# "iptables-restore"); |
|
# } |
|
#+ if (optarg) { |
|
#+ if (sscanf(optarg, "%i", &wait) != 1) |
|
#+ xtables_error(PARAMETER_PROBLEM, |
|
#+ "wait seconds not numeric"); |
|
#+ } else if (optind < argc && argv[optind][0] != '-' |
|
#+ && argv[optind][0] != '!') |
|
#+ if (sscanf(argv[optind++], "%i", &wait) != 1) |
|
#+ xtables_error(PARAMETER_PROBLEM, |
|
#+ "wait seconds not numeric"); |
|
# break; |
|
# |
|
# case '0': |
|
-- |
|
cgit v0.10.2 |
|
|
|
|