summaryrefslogtreecommitdiffstats
path: root/iptables/iptables.c
diff options
context:
space:
mode:
authorSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>2016-06-23 18:44:06 -0600
committerPablo Neira Ayuso <pablo@netfilter.org>2016-07-03 11:15:59 +0200
commite8f857a5a1514c3e7d0d8ea0f7d2d571f0e37bd1 (patch)
tree6c7c36a3601fb0660797bf5edb1f68a29dae9934 /iptables/iptables.c
parent2d2b5e046aa56a518160716a9ddf9df53fc79c1f (diff)
xtables: Add an interval option for xtables lock wait
ip[6]tables currently waits for 1 second for the xtables lock to be freed if the -w option is used. We have seen that the lock is held much less than that resulting in unnecessary delay when trying to acquire the lock. This problem is even severe in case of latency sensitive applications. Introduce a new option 'W' to specify the wait interval in microseconds. If this option is not specified, the command sleeps for 1 second by default. v1->v2: Change behavior to take millisecond sleep as an argument to -w as suggested by Pablo. Also maintain current behavior for -w to sleep for 1 second as mentioned by Liping. v2->v3: Move the millisecond behavior to a new option as suggested by Pablo. v3->v4: Use select instead of usleep. Sleep every iteration for the time specified in the "-W" argument. Update man page. v4->v5: Fix compilation error when enabling nftables v5->v6: Simplify -W so it only takes the interval wait in microseconds. Bail out if -W is specific but -w is not. Joint work with Pablo Neira. Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'iptables/iptables.c')
-rw-r--r--iptables/iptables.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 91617c24..540d1116 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -100,6 +100,7 @@ static struct option original_opts[] = {
{.name = "out-interface", .has_arg = 1, .val = 'o'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
{.name = "wait", .has_arg = 2, .val = 'w'},
+ {.name = "wait-interval", .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'},
@@ -253,7 +254,9 @@ 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 [seconds] wait for the xtables lock\n"
+" --wait -w [seconds] maximum wait to acquire xtables lock before give up\n"
+" --wait-interval -W [usecs] wait time to try to acquire xtables lock\n"
+" default is 1 second\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 +1321,10 @@ int do_command4(int argc, char *argv[], char **table,
unsigned int nsaddrs = 0, ndaddrs = 0;
struct in_addr *saddrs = NULL, *smasks = NULL;
struct in_addr *daddrs = NULL, *dmasks = NULL;
-
+ struct timeval wait_interval = {
+ .tv_sec = 1,
+ };
+ bool wait_interval_set = false;
int verbose = 0;
int wait = 0;
const char *chain = NULL;
@@ -1355,7 +1361,7 @@ int do_command4(int argc, char *argv[], char **table,
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:fbvw::nt: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::W::nt:m:xc:g:46",
opts, NULL)) != -1) {
switch (cs.c) {
/*
@@ -1609,6 +1615,23 @@ int do_command4(int argc, char *argv[], char **table,
"wait seconds not numeric");
break;
+ case 'W':
+ if (restore) {
+ xtables_error(PARAMETER_PROBLEM,
+ "You cannot use `-W' from "
+ "iptables-restore");
+ }
+ if (optarg)
+ parse_wait_interval(optarg, &wait_interval);
+ else if (optind < argc &&
+ argv[optind][0] != '-' &&
+ argv[optind][0] != '!')
+ parse_wait_interval(argv[optind++],
+ &wait_interval);
+
+ wait_interval_set = true;
+ break;
+
case 'm':
command_match(&cs);
break;
@@ -1709,6 +1732,10 @@ int do_command4(int argc, char *argv[], char **table,
cs.invert = FALSE;
}
+ if (!wait && wait_interval_set)
+ xtables_error(PARAMETER_PROBLEM,
+ "--wait-interval only makes sense with --wait\n");
+
if (strcmp(*table, "nat") == 0 &&
((policy != NULL && strcmp(policy, "DROP") == 0) ||
(cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0)))
@@ -1759,7 +1786,7 @@ int do_command4(int argc, char *argv[], char **table,
generic_opt_check(command, cs.options);
/* Attempt to acquire the xtables lock */
- if (!restore && !xtables_lock(wait)) {
+ if (!restore && !xtables_lock(wait, &wait_interval)) {
fprintf(stderr, "Another app is currently holding the xtables lock. ");
if (wait == 0)
fprintf(stderr, "Perhaps you want to use the -w option?\n");