};
struct xtables_args args = {
.family = AF_INET6,
- .wait_interval.tv_sec = 1,
};
struct ip6t_entry *e = NULL;
unsigned int nsaddrs = 0, ndaddrs = 0;
int verbose = 0;
int wait = 0;
- struct timeval wait_interval = {
- .tv_sec = 1,
- };
const char *chain = NULL;
const char *policy = NULL, *newname = NULL;
unsigned int rulenum = 0, command = 0;
newname = p.newname;
verbose = p.verbose;
wait = args.wait;
- wait_interval = args.wait_interval;
nsaddrs = args.s.naddrs;
ndaddrs = args.d.naddrs;
saddrs = args.s.addr.v6;
/* Attempt to acquire the xtables lock */
if (!restore)
- xtables_lock_or_exit(wait, &wait_interval);
+ xtables_lock_or_exit(wait);
/* only allocate handle if we weren't called with a handle */
if (!*handle)
make the program wait (indefinitely or for optional \fIseconds\fP) until
the exclusive lock can be obtained.
.TP
-\fB\-W\fP, \fB\-\-wait-interval\fP \fImicroseconds\fP
-Interval to wait per each iteration.
-When running latency sensitive applications, waiting for the xtables lock
-for extended durations may not be acceptable. This option will make each
-iteration take the amount of time specified. The default interval is
-1 second. This option only works with \fB\-w\fP.
-.TP
\fB\-M\fP, \fB\-\-modprobe\fP \fImodprobe_program\fP
Specify the path to the modprobe program. By default, iptables-restore will
inspect /proc/sys/kernel/modprobe to determine the executable's path.
static int counters, verbose, noflush, wait;
-static struct timeval wait_interval = {
- .tv_sec = 1,
-};
-
/* Keeping track of external matches and targets. */
static const struct option options[] = {
{.name = "counters", .has_arg = 0, .val = 'c'},
" [ --help ]\n"
" [ --noflush ]\n"
" [ --wait=<seconds>\n"
- " [ --wait-interval=<usecs>\n"
" [ --table=<TABLE> ]\n"
" [ --modprobe=<command> ]\n", name);
}
FILE *in;
int in_table = 0, testing = 0;
const char *tablename = NULL;
+ bool wait_interval_set = false;
line = 0;
lock = XT_LOCK_NOT_ACQUIRED;
wait = parse_wait_time(argc, argv);
break;
case 'W':
- parse_wait_interval(argc, argv, &wait_interval);
+ parse_wait_interval(argc, argv);
+ wait_interval_set = true;
break;
case 'M':
xtables_modprobe_program = optarg;
}
else in = stdin;
- if (!wait_interval.tv_sec && !wait) {
+ if (wait_interval_set && !wait) {
fprintf(stderr, "Option --wait-interval requires option --wait\n");
exit(1);
}
in_table = 0;
} else if ((buffer[0] == '*') && (!in_table)) {
/* Acquire a lock before we create a new table handle */
- lock = xtables_lock_or_exit(wait, &wait_interval);
+ lock = xtables_lock_or_exit(wait);
/* New table */
char *table;
make the program wait (indefinitely or for optional \fIseconds\fP) until
the exclusive lock can be obtained.
.TP
-\fB\-W\fP, \fB\-\-wait-interval\fP \fImicroseconds\fP
-Interval to wait per each iteration.
-When running latency sensitive applications, waiting for the xtables lock
-for extended durations may not be acceptable. This option will make each
-iteration take the amount of time specified. The default interval is
-1 second. This option only works with \fB\-w\fP.
-.TP
\fB\-n\fP, \fB\-\-numeric\fP
Numeric output.
IP addresses and port numbers will be printed in numeric format.
};
struct xtables_args args = {
.family = AF_INET,
- .wait_interval.tv_sec = 1,
};
struct ipt_entry *e = NULL;
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,
- };
int verbose = 0;
int wait = 0;
const char *chain = NULL;
newname = p.newname;
verbose = p.verbose;
wait = args.wait;
- wait_interval = args.wait_interval;
nsaddrs = args.s.naddrs;
ndaddrs = args.d.naddrs;
saddrs = args.s.addr.v4;
/* Attempt to acquire the xtables lock */
if (!restore)
- xtables_lock_or_exit(wait, &wait_interval);
+ xtables_lock_or_exit(wait);
/* only allocate handle if we weren't called with a handle */
if (!*handle)
set -e
-# make sure wait and wait-interval options are accepted
+# make sure wait options are accepted
clean_tempfile()
{
$XT_MULTI iptables-save -f $tmpfile
$XT_MULTI iptables-restore $tmpfile
$XT_MULTI iptables-restore -w 5 $tmpfile
-$XT_MULTI iptables-restore -w 5 -W 1 $tmpfile
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <xtables.h>
#include <math.h>
+#include <signal.h>
#include "xshared.h"
/*
match->init(match->m);
}
-static int xtables_lock(int wait, struct timeval *wait_interval)
+static void alarm_ignore(int i) {
+}
+
+static int xtables_lock(int wait)
{
- struct timeval time_left, wait_time;
+ struct sigaction sigact_alarm;
const char *lock_file;
- int fd, i = 0;
-
- time_left.tv_sec = wait;
- time_left.tv_usec = 0;
+ int fd;
lock_file = getenv("XTABLES_LOCKFILE");
if (lock_file == NULL || lock_file[0] == '\0')
return XT_LOCK_FAILED;
}
- if (wait == -1) {
- if (flock(fd, LOCK_EX) == 0)
- return fd;
-
- fprintf(stderr, "Can't lock %s: %s\n", lock_file,
- strerror(errno));
- return XT_LOCK_BUSY;
+ if (wait != -1) {
+ sigact_alarm.sa_handler = alarm_ignore;
+ sigact_alarm.sa_flags = SA_RESETHAND;
+ sigemptyset(&sigact_alarm.sa_mask);
+ sigaction(SIGALRM, &sigact_alarm, NULL);
+ alarm(wait);
}
- while (1) {
- if (flock(fd, LOCK_EX | LOCK_NB) == 0)
- return fd;
- else if (timercmp(&time_left, wait_interval, <))
- return XT_LOCK_BUSY;
+ if (flock(fd, LOCK_EX) == 0)
+ return fd;
- if (++i % 10 == 0) {
- fprintf(stderr, "Another app is currently holding the xtables lock; "
- "still %lds %ldus time ahead to have a chance to grab the lock...\n",
- time_left.tv_sec, time_left.tv_usec);
- }
-
- wait_time = *wait_interval;
- select(0, NULL, NULL, NULL, &wait_time);
- timersub(&time_left, wait_interval, &time_left);
+ if (errno == EINTR) {
+ errno = EWOULDBLOCK;
}
+
+ fprintf(stderr, "Can't lock %s: %s\n", lock_file,
+ strerror(errno));
+ return XT_LOCK_BUSY;
}
void xtables_unlock(int lock)
close(lock);
}
-int xtables_lock_or_exit(int wait, struct timeval *wait_interval)
+int xtables_lock_or_exit(int wait)
{
- int lock = xtables_lock(wait, wait_interval);
+ int lock = xtables_lock(wait);
if (lock == XT_LOCK_FAILED) {
xtables_free_opts(1);
return wait;
}
-void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval)
+void parse_wait_interval(int argc, char *argv[])
{
const char *arg;
unsigned int usec;
"too long usec wait %u > 999999 usec",
usec);
- wait_interval->tv_sec = 0;
- wait_interval->tv_usec = usec;
+ fprintf(stderr, "Ignoring deprecated --wait-interval option.\n");
return;
}
xtables_error(PARAMETER_PROBLEM, "wait interval not numeric");
" --table -t table table to manipulate (default: `filter')\n"
" --verbose -v verbose mode\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"
-" interval to wait for xtables lock\n"
-" default is 1 second\n"
" --line-numbers print line numbers when listing\n"
" --exact -x expand numbers (display exact values)\n");
"iptables-restore");
}
- parse_wait_interval(argc, argv, &args->wait_interval);
+ parse_wait_interval(argc, argv);
wait_interval_set = true;
break;
#include <stdint.h>
#include <netinet/in.h>
#include <net/if.h>
-#include <sys/time.h>
#include <linux/netfilter_arp/arp_tables.h>
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
XT_LOCK_NOT_ACQUIRED = -3,
};
extern void xtables_unlock(int lock);
-extern int xtables_lock_or_exit(int wait, struct timeval *tv);
+extern int xtables_lock_or_exit(int wait);
int parse_wait_time(int argc, char *argv[]);
-void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval);
+void parse_wait_interval(int argc, char *argv[]);
int parse_counters(const char *string, struct xt_counters *ctr);
bool tokenize_rule_counters(char **bufferp, char **pcnt, char **bcnt, int line);
bool xs_has_arg(int argc, char *argv[]);
const char *arp_htype, *arp_ptype;
unsigned long long pcnt_cnt, bcnt_cnt;
int wait;
- struct timeval wait_interval;
};
struct xt_cmd_parse_ops {