Blame SOURCES/iptables-1.4.21-wait_seconds.patch

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