diff options
author | Subash Abhinov Kasiviswanathan <subashab@codeaurora.org> | 2016-06-23 18:44:06 -0600 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-07-03 11:15:59 +0200 |
commit | e8f857a5a1514c3e7d0d8ea0f7d2d571f0e37bd1 (patch) | |
tree | 6c7c36a3601fb0660797bf5edb1f68a29dae9934 /iptables/iptables.c | |
parent | 2d2b5e046aa56a518160716a9ddf9df53fc79c1f (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.c | 35 |
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"); |