Blame SOURCES/iptables-1.4.21-wait_seconds.patch

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