summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac51
-rw-r--r--extensions/libip6t_DNPT.c4
-rw-r--r--extensions/libip6t_MASQUERADE.man30
-rw-r--r--extensions/libip6t_SNPT.c4
-rw-r--r--extensions/libip6t_mh.man2
-rw-r--r--extensions/libipt_LOG.man34
-rw-r--r--extensions/libxt_CLASSIFY.c4
-rw-r--r--extensions/libxt_CT.c4
-rw-r--r--extensions/libxt_DNAT.man (renamed from extensions/libipt_DNAT.man)15
-rw-r--r--extensions/libxt_LOG.man (renamed from extensions/libip6t_LOG.man)6
-rw-r--r--extensions/libxt_MASQUERADE.man (renamed from extensions/libipt_MASQUERADE.man)10
-rw-r--r--extensions/libxt_NETMAP.man (renamed from extensions/libipt_NETMAP.man)2
-rw-r--r--extensions/libxt_NFQUEUE.c63
-rw-r--r--extensions/libxt_NFQUEUE.man7
-rw-r--r--extensions/libxt_RATEEST.c4
-rw-r--r--extensions/libxt_REDIRECT.man (renamed from extensions/libipt_REDIRECT.man)13
-rw-r--r--extensions/libxt_SNAT.man (renamed from extensions/libipt_SNAT.man)15
-rw-r--r--extensions/libxt_addrtype.c2
-rw-r--r--extensions/libxt_policy.c4
-rw-r--r--extensions/libxt_rateest.c4
-rw-r--r--extensions/libxt_set.c222
-rw-r--r--extensions/libxt_set.man41
-rw-r--r--extensions/libxt_statistic.c4
-rw-r--r--include/linux/netfilter/ipset/ip_set.h52
-rw-r--r--include/linux/netfilter/xt_NFQUEUE.h9
-rw-r--r--include/linux/netfilter/xt_set.h9
-rw-r--r--iptables/.gitignore1
-rw-r--r--iptables/Makefile.am11
-rw-r--r--iptables/ip6tables.8.in9
-rw-r--r--iptables/ip6tables.c17
-rw-r--r--iptables/iptables-extensions.8.tmpl.in (renamed from iptables/iptables-extensions.8.in)2
-rw-r--r--iptables/iptables.8.in9
-rw-r--r--iptables/iptables.c17
-rw-r--r--iptables/xshared.c33
-rw-r--r--iptables/xshared.h2
-rw-r--r--libxtables/xtables.c22
36 files changed, 599 insertions, 139 deletions
diff --git a/configure.ac b/configure.ac
index d165d52c..d2094945 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,10 +49,11 @@ AC_ARG_ENABLE([devel],
[Install Xtables development headers]),
[enable_devel="$enableval"], [enable_devel="yes"])
AC_ARG_ENABLE([libipq],
- AS_HELP_STRING([--enable-libipq], [Build and install libipq]))
+ AS_HELP_STRING([--enable-libipq], [Build and install libipq]),
+ [enable_libipq="$enableval"], [enable_libipq="no"])
AC_ARG_ENABLE([bpf-compiler],
AS_HELP_STRING([--enable-bpf-compiler], [Build bpf compiler]),
- [enable_bpfc="yes"])
+ [enable_bpfc="yes"], [enable_bpfc="no"])
AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH],
[Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]),
[pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig'])
@@ -111,6 +112,20 @@ if [[ -n "$ksourcedir" ]]; then
fi;
pkgdatadir='${datadir}/xtables';
+define([EXPAND_VARIABLE],
+[$2=[$]$1
+if test $prefix = 'NONE'; then
+ prefix="/usr/local"
+fi
+while true; do
+ case "[$]$2" in
+ *\[$]* ) eval "$2=[$]$2" ;;
+ *) break ;;
+ esac
+done
+eval "$2=[$]$2"
+])dnl EXPAND_VARIABLE
+
AC_SUBST([regular_CFLAGS])
AC_SUBST([regular_CPPFLAGS])
AC_SUBST([noundef_LDFLAGS])
@@ -127,9 +142,41 @@ AC_SUBST([libxtables_vmajor])
AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile
iptables/Makefile iptables/xtables.pc
+ iptables/iptables.8 iptables/ip6tables.8
+ iptables/iptables-extensions.8.tmpl
libipq/Makefile libipq/libipq.pc
libiptc/Makefile libiptc/libiptc.pc
libiptc/libip4tc.pc libiptc/libip6tc.pc
libxtables/Makefile utils/Makefile
include/xtables-version.h include/iptables/internal.h])
AC_OUTPUT
+
+
+EXPAND_VARIABLE(xtlibdir, e_xtlibdir)
+EXPAND_VARIABLE(pkgconfigdir, e_pkgconfigdir)
+
+echo "
+Iptables Configuration:
+ IPv4 support: ${enable_ipv4}
+ IPv6 support: ${enable_ipv6}
+ Devel support: ${enable_devel}
+ IPQ support: ${enable_libipq}
+ Large file support: ${enable_largefile}
+ BPF utils support: ${enable_bpfc}
+
+Build parameters:
+ Put plugins into executable (static): ${enable_static}
+ Support plugins via dlopen (shared): ${enable_shared}
+ Installation prefix (--prefix): ${prefix}
+ Xtables extension directory: ${e_xtlibdir}
+ Pkg-config directory: ${e_pkgconfigdir}"
+
+if [[ -n "$ksourcedir" ]]; then
+ echo " Kernel source directory: ${ksourcedir}"
+fi;
+if [[ -n "$kbuilddir" ]]; then
+ echo " Kernel build directory: ${kbuilddir}"
+fi;
+
+echo " Host: ${host}
+ GCC binary: ${CC}"
diff --git a/extensions/libip6t_DNPT.c b/extensions/libip6t_DNPT.c
index 703adf60..a442de6d 100644
--- a/extensions/libip6t_DNPT.c
+++ b/extensions/libip6t_DNPT.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2012-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <stdio.h>
#include <string.h>
#include <xtables.h>
diff --git a/extensions/libip6t_MASQUERADE.man b/extensions/libip6t_MASQUERADE.man
deleted file mode 100644
index c63d826b..00000000
--- a/extensions/libip6t_MASQUERADE.man
+++ /dev/null
@@ -1,30 +0,0 @@
-This target is only valid in the
-.B nat
-table, in the
-.B POSTROUTING
-chain. It should only be used with dynamically assigned IPv6 (dialup)
-connections: if you have a static IP address, you should use the SNAT
-target. Masquerading is equivalent to specifying a mapping to the IP
-address of the interface the packet is going out, but also has the
-effect that connections are
-.I forgotten
-when the interface goes down. This is the correct behavior when the
-next dialup is unlikely to have the same interface address (and hence
-any established connections are lost anyway).
-.TP
-\fB\-\-to\-ports\fP \fIport\fP[\fB\-\fP\fIport\fP]
-This specifies a range of source ports to use, overriding the default
-.B SNAT
-source port-selection heuristics (see above). This is only valid
-if the rule also specifies
-\fB\-p tcp\fP
-or
-\fB\-p udp\fP.
-.TP
-\fB\-\-random\fP
-Randomize source port mapping
-If option
-\fB\-\-random\fP
-is used then port mapping will be randomized.
-.RS
-.PP
diff --git a/extensions/libip6t_SNPT.c b/extensions/libip6t_SNPT.c
index 7ed80b20..4f10de03 100644
--- a/extensions/libip6t_SNPT.c
+++ b/extensions/libip6t_SNPT.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2012-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <stdio.h>
#include <string.h>
#include <xtables.h>
diff --git a/extensions/libip6t_mh.man b/extensions/libip6t_mh.man
index 4559e783..8ec08c6f 100644
--- a/extensions/libip6t_mh.man
+++ b/extensions/libip6t_mh.man
@@ -8,5 +8,5 @@ a numeric MH
.IR type
or one of the MH type names shown by the command
.nf
- ip6tables \-p ipv6\-mh \-h
+ ip6tables \-p mh \-h
.fi
diff --git a/extensions/libipt_LOG.man b/extensions/libipt_LOG.man
deleted file mode 100644
index f2574f88..00000000
--- a/extensions/libipt_LOG.man
+++ /dev/null
@@ -1,34 +0,0 @@
-Turn on kernel logging of matching packets. When this option is set
-for a rule, the Linux kernel will print some information on all
-matching packets (like most IP header fields) via the kernel log
-(where it can be read with
-.I dmesg
-or
-.IR syslogd (8)).
-This is a "non-terminating target", i.e. rule traversal continues at
-the next rule. So if you want to LOG the packets you refuse, use two
-separate rules with the same matching criteria, first using target LOG
-then DROP (or REJECT).
-.TP
-\fB\-\-log\-level\fP \fIlevel\fP
-Level of logging, which can be (system-specific) numeric or a mnemonic.
-Possible values are (in decreasing order of priority): \fBemerg\fP,
-\fBalert\fP, \fBcrit\fP, \fBerror\fP, \fBwarning\fP, \fBnotice\fP, \fBinfo\fP
-or \fBdebug\fP.
-.TP
-\fB\-\-log\-prefix\fP \fIprefix\fP
-Prefix log messages with the specified prefix; up to 29 letters long,
-and useful for distinguishing messages in the logs.
-.TP
-\fB\-\-log\-tcp\-sequence\fP
-Log TCP sequence numbers. This is a security risk if the log is
-readable by users.
-.TP
-\fB\-\-log\-tcp\-options\fP
-Log options from the TCP packet header.
-.TP
-\fB\-\-log\-ip\-options\fP
-Log options from the IP packet header.
-.TP
-\fB\-\-log\-uid\fP
-Log the userid of the process which generated the packet.
diff --git a/extensions/libxt_CLASSIFY.c b/extensions/libxt_CLASSIFY.c
index ee0f9e1c..e04657ae 100644
--- a/extensions/libxt_CLASSIFY.c
+++ b/extensions/libxt_CLASSIFY.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2003-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <stdio.h>
#include <xtables.h>
#include <linux/netfilter/xt_CLASSIFY.h>
diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c
index a576a953..c8437b6c 100644
--- a/extensions/libxt_CT.c
+++ b/extensions/libxt_CT.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2010-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <stdio.h>
#include <string.h>
#include <xtables.h>
diff --git a/extensions/libipt_DNAT.man b/extensions/libxt_DNAT.man
index d5ded35b..225274ff 100644
--- a/extensions/libipt_DNAT.man
+++ b/extensions/libxt_DNAT.man
@@ -7,20 +7,17 @@ and
chains, and user-defined chains which are only called from those
chains. It specifies that the destination address of the packet
should be modified (and all future packets in this connection will
-also be mangled), and rules should cease being examined. It takes one
-type of option:
+also be mangled), and rules should cease being examined. It takes the
+following options:
.TP
\fB\-\-to\-destination\fP [\fIipaddr\fP[\fB\-\fP\fIipaddr\fP]][\fB:\fP\fIport\fP[\fB\-\fP\fIport\fP]]
which can specify a single new destination IP address, an inclusive
-range of IP addresses, and optionally, a port range (which is only
-valid if the rule also specifies
-\fB\-p tcp\fP
-or
-\fB\-p udp\fP).
+range of IP addresses. Optionally a port range,
+if the rule also specifies one of the following protocols:
+\fBtcp\fP, \fBudp\fP, \fBdccp\fP or \fBsctp\fP.
If no port range is specified, then the destination port will never be
modified. If no IP address is specified then only the destination port
will be modified.
-
In Kernels up to 2.6.10 you can add several \-\-to\-destination options. For
those kernels, if you specify more than one destination address, either via an
address range or multiple \-\-to\-destination options, a simple round-robin (one
@@ -37,3 +34,5 @@ is used then port mapping will be randomized (kernel >= 2.6.22).
Gives a client the same source-/destination-address for each connection.
This supersedes the SAME target. Support for persistent mappings is available
from 2.6.29-rc2.
+.TP
+IPv6 support available since Linux kernels >= 3.7.
diff --git a/extensions/libip6t_LOG.man b/extensions/libxt_LOG.man
index 0a486404..6d3a83a4 100644
--- a/extensions/libip6t_LOG.man
+++ b/extensions/libxt_LOG.man
@@ -1,9 +1,9 @@
Turn on kernel logging of matching packets. When this option is set
for a rule, the Linux kernel will print some information on all
-matching packets (like most IPv6 IPv6-header fields) via the kernel log
+matching packets (like most IP/IPv6 header fields) via the kernel log
(where it can be read with
.I dmesg
-or
+or
.IR syslogd (8)).
This is a "non-terminating target", i.e. rule traversal continues at
the next rule. So if you want to LOG the packets you refuse, use two
@@ -28,7 +28,7 @@ readable by users.
Log options from the TCP packet header.
.TP
\fB\-\-log\-ip\-options\fP
-Log options from the IPv6 packet header.
+Log options from the IP/IPv6 packet header.
.TP
\fB\-\-log\-uid\fP
Log the userid of the process which generated the packet.
diff --git a/extensions/libipt_MASQUERADE.man b/extensions/libxt_MASQUERADE.man
index 2dae9640..c9e39501 100644
--- a/extensions/libipt_MASQUERADE.man
+++ b/extensions/libxt_MASQUERADE.man
@@ -16,15 +16,13 @@ any established connections are lost anyway).
This specifies a range of source ports to use, overriding the default
.B SNAT
source port-selection heuristics (see above). This is only valid
-if the rule also specifies
-\fB\-p tcp\fP
-or
-\fB\-p udp\fP.
+if the rule also specifies one of the following protocols:
+\fBtcp\fP, \fBudp\fP, \fBdccp\fP or \fBsctp\fP.
.TP
\fB\-\-random\fP
Randomize source port mapping
If option
\fB\-\-random\fP
is used then port mapping will be randomized (kernel >= 2.6.21).
-.RS
-.PP
+.TP
+IPv6 support available since Linux kernels >= 3.7.
diff --git a/extensions/libipt_NETMAP.man b/extensions/libxt_NETMAP.man
index a7e90b8d..06507db7 100644
--- a/extensions/libipt_NETMAP.man
+++ b/extensions/libxt_NETMAP.man
@@ -7,3 +7,5 @@ table.
Network address to map to. The resulting address will be constructed in the
following way: All 'one' bits in the mask are filled in from the new `address'.
All bits that are zero in the mask are filled in from the original address.
+.TP
+IPv6 support available since Linux kernels >= 3.7.
diff --git a/extensions/libxt_NFQUEUE.c b/extensions/libxt_NFQUEUE.c
index 8c2f6999..0c869187 100644
--- a/extensions/libxt_NFQUEUE.c
+++ b/extensions/libxt_NFQUEUE.c
@@ -13,8 +13,10 @@ enum {
O_QUEUE_NUM = 0,
O_QUEUE_BALANCE,
O_QUEUE_BYPASS,
+ O_QUEUE_CPU_FANOUT,
F_QUEUE_NUM = 1 << O_QUEUE_NUM,
F_QUEUE_BALANCE = 1 << O_QUEUE_BALANCE,
+ F_QUEUE_CPU_FANOUT = 1 << O_QUEUE_CPU_FANOUT,
};
static void NFQUEUE_help(void)
@@ -37,7 +39,15 @@ static void NFQUEUE_help_v2(void)
{
NFQUEUE_help_v1();
printf(
-" --queue-bypass Bypass Queueing if no queue instance exists.\n");
+" --queue-bypass Bypass Queueing if no queue instance exists.\n"
+" --queue-cpu-fanout Use current CPU (no hashing)\n");
+}
+
+static void NFQUEUE_help_v3(void)
+{
+ NFQUEUE_help_v2();
+ printf(
+" --queue-cpu-fanout Use current CPU (no hashing)\n");
}
#define s struct xt_NFQ_info
@@ -48,6 +58,8 @@ static const struct xt_option_entry NFQUEUE_opts[] = {
{.name = "queue-balance", .id = O_QUEUE_BALANCE,
.type = XTTYPE_UINT16RC, .excl = F_QUEUE_NUM},
{.name = "queue-bypass", .id = O_QUEUE_BYPASS, .type = XTTYPE_NONE},
+ {.name = "queue-cpu-fanout", .id = O_QUEUE_CPU_FANOUT,
+ .type = XTTYPE_NONE, .also = F_QUEUE_BALANCE},
XTOPT_TABLEEND,
};
#undef s
@@ -92,6 +104,18 @@ static void NFQUEUE_parse_v2(struct xt_option_call *cb)
}
}
+static void NFQUEUE_parse_v3(struct xt_option_call *cb)
+{
+ struct xt_NFQ_info_v3 *info = cb->data;
+
+ NFQUEUE_parse_v2(cb);
+ switch (cb->entry->id) {
+ case O_QUEUE_CPU_FANOUT:
+ info->flags |= NFQ_FLAG_CPU_FANOUT;
+ break;
+ }
+}
+
static void NFQUEUE_print(const void *ip,
const struct xt_entry_target *target, int numeric)
{
@@ -120,10 +144,20 @@ static void NFQUEUE_print_v2(const void *ip,
const struct xt_NFQ_info_v2 *info = (void *) target->data;
NFQUEUE_print_v1(ip, target, numeric);
- if (info->bypass)
+ if (info->bypass & NFQ_FLAG_BYPASS)
printf(" bypass");
}
+static void NFQUEUE_print_v3(const void *ip,
+ const struct xt_entry_target *target, int numeric)
+{
+ const struct xt_NFQ_info_v3 *info = (void *)target->data;
+
+ NFQUEUE_print_v2(ip, target, numeric);
+ if (info->flags & NFQ_FLAG_CPU_FANOUT)
+ printf(" cpu-fanout");
+}
+
static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target)
{
const struct xt_NFQ_info *tinfo =
@@ -151,10 +185,20 @@ static void NFQUEUE_save_v2(const void *ip, const struct xt_entry_target *target
NFQUEUE_save_v1(ip, target);
- if (info->bypass)
+ if (info->bypass & NFQ_FLAG_BYPASS)
printf(" --queue-bypass");
}
+static void NFQUEUE_save_v3(const void *ip,
+ const struct xt_entry_target *target)
+{
+ const struct xt_NFQ_info_v3 *info = (void *)target->data;
+
+ NFQUEUE_save_v2(ip, target);
+ if (info->flags & NFQ_FLAG_CPU_FANOUT)
+ printf(" --queue-cpu-fanout");
+}
+
static void NFQUEUE_init_v1(struct xt_entry_target *t)
{
struct xt_NFQ_info_v1 *tinfo = (void *)t->data;
@@ -199,6 +243,19 @@ static struct xtables_target nfqueue_targets[] = {
.save = NFQUEUE_save_v2,
.x6_parse = NFQUEUE_parse_v2,
.x6_options = NFQUEUE_opts,
+},{
+ .family = NFPROTO_UNSPEC,
+ .revision = 3,
+ .name = "NFQUEUE",
+ .version = XTABLES_VERSION,
+ .size = XT_ALIGN(sizeof(struct xt_NFQ_info_v3)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v3)),
+ .help = NFQUEUE_help_v3,
+ .init = NFQUEUE_init_v1,
+ .print = NFQUEUE_print_v3,
+ .save = NFQUEUE_save_v3,
+ .x6_parse = NFQUEUE_parse_v3,
+ .x6_options = NFQUEUE_opts,
}
};
diff --git a/extensions/libxt_NFQUEUE.man b/extensions/libxt_NFQUEUE.man
index f11e0c89..7a991291 100644
--- a/extensions/libxt_NFQUEUE.man
+++ b/extensions/libxt_NFQUEUE.man
@@ -23,3 +23,10 @@ Packets belonging to the same connection are put into the same nfqueue.
By default, if no userspace program is listening on an NFQUEUE, then all packets that are to be queued
are dropped. When this option is used, the NFQUEUE rule behaves like ACCEPT instead, and the packet
will move on to the next table.
+.PP
+.TP
+\fB\-\-queue\-cpu-fanout\fP
+Available starting Linux kernel 3.10. When used together with
+\fB--queue-balance\fP this will use the CPU ID as an index to map packets to
+the queues. The idea is that you can improve performance if there's a queue
+per CPU. This requires \fB--queue-balance\fP to be specified.
diff --git a/extensions/libxt_RATEEST.c b/extensions/libxt_RATEEST.c
index acdefb90..449ceab6 100644
--- a/extensions/libxt_RATEEST.c
+++ b/extensions/libxt_RATEEST.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2008-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
diff --git a/extensions/libipt_REDIRECT.man b/extensions/libxt_REDIRECT.man
index 90ab19d7..3400a6df 100644
--- a/extensions/libipt_REDIRECT.man
+++ b/extensions/libxt_REDIRECT.man
@@ -7,19 +7,18 @@ and
chains, and user-defined chains which are only called from those
chains. It redirects the packet to the machine itself by changing the
destination IP to the primary address of the incoming interface
-(locally-generated packets are mapped to the 127.0.0.1 address).
+(locally-generated packets are mapped to the localhost address,
+127.0.0.1 for IPv4 and ::1 for IPv6).
.TP
\fB\-\-to\-ports\fP \fIport\fP[\fB\-\fP\fIport\fP]
This specifies a destination port or range of ports to use: without
this, the destination port is never altered. This is only valid
-if the rule also specifies
-\fB\-p tcp\fP
-or
-\fB\-p udp\fP.
+if the rule also specifies one of the following protocols:
+\fBtcp\fP, \fBudp\fP, \fBdccp\fP or \fBsctp\fP.
.TP
\fB\-\-random\fP
If option
\fB\-\-random\fP
is used then port mapping will be randomized (kernel >= 2.6.22).
-.RS
-.PP
+.TP
+IPv6 support available starting Linux kernels >= 3.7.
diff --git a/extensions/libipt_SNAT.man b/extensions/libxt_SNAT.man
index 093b09c4..f0620a21 100644
--- a/extensions/libipt_SNAT.man
+++ b/extensions/libxt_SNAT.man
@@ -7,21 +7,18 @@ and
chains, and user-defined chains which are only called from those
chains. It specifies that the source address of the packet should be
modified (and all future packets in this connection will also be
-mangled), and rules should cease being examined. It takes one type
-of option:
+mangled), and rules should cease being examined. It takes the
+following options:
.TP
\fB\-\-to\-source\fP [\fIipaddr\fP[\fB\-\fP\fIipaddr\fP]][\fB:\fP\fIport\fP[\fB\-\fP\fIport\fP]]
which can specify a single new source IP address, an inclusive range
-of IP addresses, and optionally, a port range (which is only valid if
-the rule also specifies
-\fB\-p tcp\fP
-or
-\fB\-p udp\fP).
+of IP addresses. Optionally a port range,
+if the rule also specifies one of the following protocols:
+\fBtcp\fP, \fBudp\fP, \fBdccp\fP or \fBsctp\fP.
If no port range is specified, then source ports below 512 will be
mapped to other ports below 512: those between 512 and 1023 inclusive
will be mapped to ports below 1024, and other ports will be mapped to
1024 or above. Where possible, no port alteration will occur.
-
In Kernels up to 2.6.10, you can add several \-\-to\-source options. For those
kernels, if you specify more than one source address, either via an address
range or multiple \-\-to\-source options, a simple round-robin (one after another
@@ -44,3 +41,5 @@ Kernels prior to 2.6.36-rc1 don't have the ability to
in the
.B INPUT
chain.
+.TP
+IPv6 support available since Linux kernels >= 3.7.
diff --git a/extensions/libxt_addrtype.c b/extensions/libxt_addrtype.c
index e8a85456..e5d3033c 100644
--- a/extensions/libxt_addrtype.c
+++ b/extensions/libxt_addrtype.c
@@ -1,4 +1,6 @@
/* Shared library add-on to iptables to add addrtype matching support
+ *
+ * Copyright (c) 2003-2013 Patrick McHardy <kaber@trash.net>
*
* This program is released under the terms of GNU GPL */
#include <stdio.h>
diff --git a/extensions/libxt_policy.c b/extensions/libxt_policy.c
index 54ec2294..0a64a80c 100644
--- a/extensions/libxt_policy.c
+++ b/extensions/libxt_policy.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2005-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
diff --git a/extensions/libxt_rateest.c b/extensions/libxt_rateest.c
index 185a8135..fb244121 100644
--- a/extensions/libxt_rateest.c
+++ b/extensions/libxt_rateest.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2008-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
diff --git a/extensions/libxt_set.c b/extensions/libxt_set.c
index e0111568..2cb9e78a 100644
--- a/extensions/libxt_set.c
+++ b/extensions/libxt_set.c
@@ -289,6 +289,214 @@ set_save_v2(const void *ip, const struct xt_entry_match *match)
printf(" --return-nomatch");
}
+/* Revision 3 */
+static void
+set_help_v3(void)
+{
+ printf("set match options:\n"
+ " [!] --match-set name flags [--return-nomatch]\n"
+ " [! --update-counters] [! --update-subcounters]\n"
+ " [[!] --packets-eq value | --packets-lt value | --packets-gt value\n"
+ " [[!] --bytes-eq value | --bytes-lt value | --bytes-gt value\n"
+ " 'name' is the set name from to match,\n"
+ " 'flags' are the comma separated list of\n"
+ " 'src' and 'dst' specifications.\n");
+}
+
+static const struct option set_opts_v3[] = {
+ {.name = "match-set", .has_arg = true, .val = '1'},
+ {.name = "set", .has_arg = true, .val = '2'},
+ {.name = "return-nomatch", .has_arg = false, .val = '3'},
+ {.name = "update-counters", .has_arg = false, .val = '4'},
+ {.name = "packets-eq", .has_arg = true, .val = '5'},
+ {.name = "packets-lt", .has_arg = true, .val = '6'},
+ {.name = "packets-gt", .has_arg = true, .val = '7'},
+ {.name = "bytes-eq", .has_arg = true, .val = '8'},
+ {.name = "bytes-lt", .has_arg = true, .val = '9'},
+ {.name = "bytes-gt", .has_arg = true, .val = '0'},
+ {.name = "update-subcounters", .has_arg = false, .val = 'a'},
+ XT_GETOPT_TABLEEND,
+};
+
+static uint64_t
+parse_counter(const char *opt)
+{
+ uintmax_t value;
+
+ if (!xtables_strtoul(opt, NULL, &value, 0, UINT64_MAX))
+ xtables_error(PARAMETER_PROBLEM,
+ "Cannot parse %s as a counter value\n",
+ opt);
+ return (uint64_t)value;
+}
+
+static int
+set_parse_v3(int c, char **argv, int invert, unsigned int *flags,
+ const void *entry, struct xt_entry_match **match)
+{
+ struct xt_set_info_match_v3 *info =
+ (struct xt_set_info_match_v3 *) (*match)->data;
+
+ switch (c) {
+ case 'a':
+ if (invert)
+ info->flags |= IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE;
+ break;
+ case '0':
+ if (info->bytes.op != IPSET_COUNTER_NONE)
+ xtables_error(PARAMETER_PROBLEM,
+ "only one of the --bytes-[eq|lt|gt]"
+ " is allowed\n");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "--bytes-gt option cannot be inverted\n");
+ info->bytes.op = IPSET_COUNTER_GT;
+ info->bytes.value = parse_counter(optarg);
+ break;
+ case '9':
+ if (info->bytes.op != IPSET_COUNTER_NONE)
+ xtables_error(PARAMETER_PROBLEM,
+ "only one of the --bytes-[eq|lt|gt]"
+ " is allowed\n");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "--bytes-lt option cannot be inverted\n");
+ info->bytes.op = IPSET_COUNTER_LT;
+ info->bytes.value = parse_counter(optarg);
+ break;
+ case '8':
+ if (info->bytes.op != IPSET_COUNTER_NONE)
+ xtables_error(PARAMETER_PROBLEM,
+ "only one of the --bytes-[eq|lt|gt]"
+ " is allowed\n");
+ info->bytes.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ;
+ info->bytes.value = parse_counter(optarg);
+ break;
+ case '7':
+ if (info->packets.op != IPSET_COUNTER_NONE)
+ xtables_error(PARAMETER_PROBLEM,
+ "only one of the --packets-[eq|lt|gt]"
+ " is allowed\n");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "--packets-gt option cannot be inverted\n");
+ info->packets.op = IPSET_COUNTER_GT;
+ info->packets.value = parse_counter(optarg);
+ break;
+ case '6':
+ if (info->packets.op != IPSET_COUNTER_NONE)
+ xtables_error(PARAMETER_PROBLEM,
+ "only one of the --packets-[eq|lt|gt]"
+ " is allowed\n");
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "--packets-lt option cannot be inverted\n");
+ info->packets.op = IPSET_COUNTER_LT;
+ info->packets.value = parse_counter(optarg);
+ break;
+ case '5':
+ if (info->packets.op != IPSET_COUNTER_NONE)
+ xtables_error(PARAMETER_PROBLEM,
+ "only one of the --packets-[eq|lt|gt]"
+ " is allowed\n");
+ info->packets.op = invert ? IPSET_COUNTER_NE : IPSET_COUNTER_EQ;
+ info->packets.value = parse_counter(optarg);
+ break;
+ case '4':
+ if (invert)
+ info->flags |= IPSET_FLAG_SKIP_COUNTER_UPDATE;
+ break;
+ case '3':
+ if (invert)
+ xtables_error(PARAMETER_PROBLEM,
+ "--return-nomatch flag cannot be inverted\n");
+ info->flags |= IPSET_FLAG_RETURN_NOMATCH;
+ break;
+ case '2':
+ fprintf(stderr,
+ "--set option deprecated, please use --match-set\n");
+ case '1': /* --match-set <set> <flag>[,<flag> */
+ if (info->match_set.dim)
+ xtables_error(PARAMETER_PROBLEM,
+ "--match-set can be specified only once");
+ if (invert)
+ info->match_set.flags |= IPSET_INV_MATCH;
+
+ if (!argv[optind]
+ || argv[optind][0] == '-'
+ || argv[optind][0] == '!')
+ xtables_error(PARAMETER_PROBLEM,
+ "--match-set requires two args.");
+
+ if (strlen(optarg) > IPSET_MAXNAMELEN - 1)
+ xtables_error(PARAMETER_PROBLEM,
+ "setname `%s' too long, max %d characters.",
+ optarg, IPSET_MAXNAMELEN - 1);
+
+ get_set_byname(optarg, &info->match_set);
+ parse_dirs(argv[optind], &info->match_set);
+ DEBUGP("parse: set index %u\n", info->match_set.index);
+ optind++;
+
+ *flags = 1;
+ break;
+ }
+
+ return 1;
+}
+
+static void
+set_printv3_counter(const struct ip_set_counter_match *c, const char *name,
+ const char *sep)
+{
+ switch (c->op) {
+ case IPSET_COUNTER_EQ:
+ printf(" %s%s-eq %llu", sep, name, c->value);
+ break;
+ case IPSET_COUNTER_NE:
+ printf(" ! %s%s-eq %llu", sep, name, c->value);
+ break;
+ case IPSET_COUNTER_LT:
+ printf(" %s%s-lt %llu", sep, name, c->value);
+ break;
+ case IPSET_COUNTER_GT:
+ printf(" %s%s-gt %llu", sep, name, c->value);
+ break;
+ }
+}
+
+static void
+set_print_v3_matchinfo(const struct xt_set_info_match_v3 *info,
+ const char *opt, const char *sep)
+{
+ print_match(opt, &info->match_set);
+ if (info->flags & IPSET_FLAG_RETURN_NOMATCH)
+ printf(" %sreturn-nomatch", sep);
+ if ((info->flags & IPSET_FLAG_SKIP_COUNTER_UPDATE))
+ printf(" ! %supdate-counters", sep);
+ if ((info->flags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE))
+ printf(" ! %supdate-subcounters", sep);
+ set_printv3_counter(&info->packets, "packets", sep);
+ set_printv3_counter(&info->bytes, "bytes", sep);
+}
+
+/* Prints out the matchinfo. */
+static void
+set_print_v3(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+ const struct xt_set_info_match_v3 *info = (const void *)match->data;
+
+ set_print_v3_matchinfo(info, "match-set", "");
+}
+
+static void
+set_save_v3(const void *ip, const struct xt_entry_match *match)
+{
+ const struct xt_set_info_match_v3 *info = (const void *)match->data;
+
+ set_print_v3_matchinfo(info, "--match-set", "--");
+}
+
static struct xtables_match set_mt_reg[] = {
{
.name = "set",
@@ -332,6 +540,20 @@ static struct xtables_match set_mt_reg[] = {
.save = set_save_v2,
.extra_opts = set_opts_v2,
},
+ {
+ .name = "set",
+ .revision = 3,
+ .version = XTABLES_VERSION,
+ .family = NFPROTO_UNSPEC,
+ .size = XT_ALIGN(sizeof(struct xt_set_info_match_v3)),
+ .userspacesize = XT_ALIGN(sizeof(struct xt_set_info_match_v3)),
+ .help = set_help_v3,
+ .parse = set_parse_v3,
+ .final_check = set_check_v0,
+ .print = set_print_v3,
+ .save = set_save_v3,
+ .extra_opts = set_opts_v3,
+ },
};
void _init(void)
diff --git a/extensions/libxt_set.man b/extensions/libxt_set.man
index ac60f148..7012ef2e 100644
--- a/extensions/libxt_set.man
+++ b/extensions/libxt_set.man
@@ -15,11 +15,48 @@ the set type of the specified set is single dimension (for example ipmap),
then the command will match packets for which the source address can be
found in the specified set.
.TP
-\fB\-\-return\-\-nomatch\fP
-If the \fB\-\-return\-\-nomatch\fP option is specified and the set type
+\fB\-\-return\-nomatch\fP
+If the \fB\-\-return\-nomatch\fP option is specified and the set type
supports the \fBnomatch\fP flag, then the matching is reversed: a match
with an element flagged with \fBnomatch\fP returns \fBtrue\fP, while a
match with a plain element returns \fBfalse\fP.
+.TP
+\fB!\fP \fB\-\-update\-counters\fP
+If the \fB\-\-update\-counters\fP flag is negated, then the packet and
+byte counters of the matching element in the set won't be updated. Default
+the packet and byte counters are updated.
+.TP
+\fB!\fP \fB\-\-update\-subcounters\fP
+If the \fB\-\-update\-subcounters\fP flag is negated, then the packet and
+byte counters of the matching element in the member set of a list type of
+set won't be updated. Default the packet and byte counters are updated.
+.TP
+[\fB!\fP] \fB\-\-packets\-eq\fP \fIvalue\fP
+If the packet is matched an element in the set, match only if the
+packet counter of the element matches the given value too.
+.TP
+\fB\-\-packets\-lt\fP \fIvalue\fP
+If the packet is matched an element in the set, match only if the
+packet counter of the element is less than the given value as well.
+.TP
+\fB\-\-packets\-gt\fP \fIvalue\fP
+If the packet is matched an element in the set, match only if the
+packet counter of the element is greater than the given value as well.
+.TP
+[\fB!\fP] \fB\-bytes\-eq\fP \fIvalue\fP
+If the packet is matched an element in the set, match only if the
+byte counter of the element matches the given value too.
+.TP
+\fB\-\-bytes\-lt\fP \fIvalue\fP
+If the packet is matched an element in the set, match only if the
+byte counter of the element is less than the given value as well.
+.TP
+\fB\-\-bytes\-gt\fP \fIvalue\fP
+If the packet is matched an element in the set, match only if the
+byte counter of the element is greater than the given value as well.
+.PP
+The packet and byte counters related options and flags are ignored
+when the set was defined without counter support.
.PP
The option \fB\-\-match\-set\fP can be replaced by \fB\-\-set\fP if that does
not clash with an option of other extensions.
diff --git a/extensions/libxt_statistic.c b/extensions/libxt_statistic.c
index c23805fb..b6ae5f5c 100644
--- a/extensions/libxt_statistic.c
+++ b/extensions/libxt_statistic.c
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2006-2013 Patrick McHardy <kaber@trash.net>
+ */
+
#include <math.h>
#include <stdio.h>
#include <string.h>
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index fff191d6..eb9123e6 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -1,6 +1,3 @@
-#ifndef _IP_SET_H
-#define _IP_SET_H
-
/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
* Patrick Schaaf <bof@bof.de>
* Martin Josefsson <gandalf@wlug.westbo.se>
@@ -10,6 +7,9 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#ifndef _UAPI_IP_SET_H
+#define _UAPI_IP_SET_H
+
#include <linux/types.h>
@@ -108,6 +108,8 @@ enum {
IPSET_ATTR_CIDR2,
IPSET_ATTR_IP2_TO,
IPSET_ATTR_IFACE,
+ IPSET_ATTR_BYTES,
+ IPSET_ATTR_PACKETS,
__IPSET_ATTR_ADT_MAX,
};
#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1)
@@ -137,12 +139,13 @@ enum ipset_errno {
IPSET_ERR_REFERENCED,
IPSET_ERR_IPADDR_IPV4,
IPSET_ERR_IPADDR_IPV6,
+ IPSET_ERR_COUNTER,
/* Type specific error codes */
IPSET_ERR_TYPE_SPECIFIC = 4352,
};
-/* Flags at command level */
+/* Flags at command level or match/target flags, lower half of cmdattrs */
enum ipset_cmd_flags {
IPSET_FLAG_BIT_EXIST = 0,
IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST),
@@ -150,14 +153,30 @@ enum ipset_cmd_flags {
IPSET_FLAG_LIST_SETNAME = (1 << IPSET_FLAG_BIT_LIST_SETNAME),
IPSET_FLAG_BIT_LIST_HEADER = 2,
IPSET_FLAG_LIST_HEADER = (1 << IPSET_FLAG_BIT_LIST_HEADER),
+ IPSET_FLAG_BIT_SKIP_COUNTER_UPDATE = 3,
+ IPSET_FLAG_SKIP_COUNTER_UPDATE =
+ (1 << IPSET_FLAG_BIT_SKIP_COUNTER_UPDATE),
+ IPSET_FLAG_BIT_SKIP_SUBCOUNTER_UPDATE = 4,
+ IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE =
+ (1 << IPSET_FLAG_BIT_SKIP_SUBCOUNTER_UPDATE),
+ IPSET_FLAG_BIT_MATCH_COUNTERS = 5,
+ IPSET_FLAG_MATCH_COUNTERS = (1 << IPSET_FLAG_BIT_MATCH_COUNTERS),
+ IPSET_FLAG_BIT_RETURN_NOMATCH = 7,
+ IPSET_FLAG_RETURN_NOMATCH = (1 << IPSET_FLAG_BIT_RETURN_NOMATCH),
+ IPSET_FLAG_CMD_MAX = 15,
};
-/* Flags at CADT attribute level */
+/* Flags at CADT attribute level, upper half of cmdattrs */
enum ipset_cadt_flags {
IPSET_FLAG_BIT_BEFORE = 0,
IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE),
IPSET_FLAG_BIT_PHYSDEV = 1,
IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV),
+ IPSET_FLAG_BIT_NOMATCH = 2,
+ IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH),
+ IPSET_FLAG_BIT_WITH_COUNTERS = 3,
+ IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
+ IPSET_FLAG_CADT_MAX = 15,
};
/* Commands with settype-specific attributes */
@@ -186,6 +205,7 @@ enum ip_set_dim {
* If changed, new revision of iptables match/target is required.
*/
IPSET_DIM_MAX = 6,
+ /* Backward compatibility: set match revision 2 */
IPSET_BIT_RETURN_NOMATCH = 7,
};
@@ -198,6 +218,18 @@ enum ip_set_kopt {
IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
};
+enum {
+ IPSET_COUNTER_NONE = 0,
+ IPSET_COUNTER_EQ,
+ IPSET_COUNTER_NE,
+ IPSET_COUNTER_LT,
+ IPSET_COUNTER_GT,
+};
+
+struct ip_set_counter_match {
+ __u8 op;
+ __u64 value;
+};
/* Interface to iptables/ip6tables */
@@ -210,8 +242,8 @@ union ip_set_name_index {
#define IP_SET_OP_GET_BYNAME 0x00000006 /* Get set index by name */
struct ip_set_req_get_set {
- unsigned op;
- unsigned version;
+ unsigned int op;
+ unsigned int version;
union ip_set_name_index set;
};
@@ -220,8 +252,8 @@ struct ip_set_req_get_set {
#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */
struct ip_set_req_version {
- unsigned op;
- unsigned version;
+ unsigned int op;
+ unsigned int version;
};
-#endif /*_IP_SET_H */
+#endif /* _UAPI_IP_SET_H */
diff --git a/include/linux/netfilter/xt_NFQUEUE.h b/include/linux/netfilter/xt_NFQUEUE.h
index 9eafdbbb..8bb5fe65 100644
--- a/include/linux/netfilter/xt_NFQUEUE.h
+++ b/include/linux/netfilter/xt_NFQUEUE.h
@@ -26,4 +26,13 @@ struct xt_NFQ_info_v2 {
__u16 bypass;
};
+struct xt_NFQ_info_v3 {
+ __u16 queuenum;
+ __u16 queues_total;
+ __u16 flags;
+#define NFQ_FLAG_BYPASS 0x01 /* for compatibility with v2 */
+#define NFQ_FLAG_CPU_FANOUT 0x02 /* use current CPU (no hashing) */
+#define NFQ_FLAG_MASK 0x03
+};
+
#endif /* _XT_NFQ_TARGET_H */
diff --git a/include/linux/netfilter/xt_set.h b/include/linux/netfilter/xt_set.h
index e3a9978f..964d3d42 100644
--- a/include/linux/netfilter/xt_set.h
+++ b/include/linux/netfilter/xt_set.h
@@ -62,4 +62,13 @@ struct xt_set_info_target_v2 {
__u32 timeout;
};
+/* Revision 3 match */
+
+struct xt_set_info_match_v3 {
+ struct xt_set_info match_set;
+ struct ip_set_counter_match packets;
+ struct ip_set_counter_match bytes;
+ __u32 flags;
+};
+
#endif /*_XT_SET_H*/
diff --git a/iptables/.gitignore b/iptables/.gitignore
index 4fc63aa4..c9c31788 100644
--- a/iptables/.gitignore
+++ b/iptables/.gitignore
@@ -6,6 +6,7 @@
/iptables
/iptables.8
/iptables-extensions.8
+/iptables-extensions.8.tmpl
/iptables-save
/iptables-restore
/iptables-static
diff --git a/iptables/Makefile.am b/iptables/Makefile.am
index 61e78db9..46d24630 100644
--- a/iptables/Makefile.am
+++ b/iptables/Makefile.am
@@ -38,15 +38,8 @@ if ENABLE_IPV6
v6_sbin_links = ip6tables ip6tables-restore ip6tables-save
endif
-iptables.8: ${srcdir}/iptables.8.in
- ${AM_VERBOSE_GEN} sed -e 's/@PACKAGE_AND_VERSION@/${PACKAGE} ${PACKAGE_VERSION}/g' $< >$@;
-
-ip6tables.8: ${srcdir}/ip6tables.8.in
- ${AM_VERBOSE_GEN} sed -e 's/@PACKAGE_AND_VERSION@/${PACKAGE} ${PACKAGE_VERSION}/g' $< >$@;
-
-iptables-extensions.8: ${srcdir}/iptables-extensions.8.in ../extensions/matches.man ../extensions/targets.man
- ${AM_VERBOSE_GEN} sed -e \
- 's/@PACKAGE_AND_VERSION@/${PACKAGE} ${PACKAGE_VERSION}/g' \
+iptables-extensions.8: ${srcdir}/iptables-extensions.8.tmpl ../extensions/matches.man ../extensions/targets.man
+ ${AM_VERBOSE_GEN} sed \
-e '/@MATCH@/ r ../extensions/matches.man' \
-e '/@TARGET@/ r ../extensions/targets.man' $< >$@;
diff --git a/iptables/ip6tables.8.in b/iptables/ip6tables.8.in
index 86348548..5b2a7d76 100644
--- a/iptables/ip6tables.8.in
+++ b/iptables/ip6tables.8.in
@@ -1,4 +1,4 @@
-.TH IP6TABLES 8 "" "@PACKAGE_AND_VERSION@" "@PACKAGE_AND_VERSION@"
+.TH IP6TABLES 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
.\"
.\" Man page written by Andras Kis-Szabo <kisza@sch.bme.hu>
.\" It is based on iptables man page.
@@ -363,6 +363,13 @@ For appending, insertion, deletion and replacement, this causes
detailed information on the rule or rules to be printed. \fB\-v\fP may be
specified multiple times to possibly emit more detailed debug statements.
.TP
+\fB\-w\fP, \fB\-\-wait\fP
+Wait for the xtables lock.
+To prevent multiple instances of the program from running concurrently,
+an attempt will be made to obtain an exclusive lock at launch. By default,
+the program will exit if the lock cannot be obtained. This option will
+make the program wait until the exclusive lock can be obtained.
+.TP
\fB\-n\fP, \fB\-\-numeric\fP
Numeric output.
IP addresses and port numbers will be printed in numeric format.
diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
index c8d34e2d..eededee1 100644
--- a/iptables/ip6tables.c
+++ b/iptables/ip6tables.c
@@ -102,6 +102,7 @@ static struct option original_opts[] = {
{.name = "numeric", .has_arg = 0, .val = 'n'},
{.name = "out-interface", .has_arg = 1, .val = 'o'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
+ {.name = "wait", .has_arg = 0, .val = 'w'},
{.name = "exact", .has_arg = 0, .val = 'x'},
{.name = "version", .has_arg = 0, .val = 'V'},
{.name = "help", .has_arg = 2, .val = 'h'},
@@ -257,6 +258,7 @@ 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 wait for the xtables lock\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"*/
@@ -1293,6 +1295,7 @@ int do_command6(int argc, char *argv[], char **table, struct xtc_handle **handle
struct in6_addr *smasks = NULL, *dmasks = NULL;
int verbose = 0;
+ bool wait = false;
const char *chain = NULL;
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
@@ -1328,7 +1331,7 @@ int do_command6(int argc, char *argv[], char **table, struct xtc_handle **handle
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:bvnt: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:bvwnt:m:xc:g:46",
opts, NULL)) != -1) {
switch (cs.c) {
/*
@@ -1573,6 +1576,10 @@ int do_command6(int argc, char *argv[], char **table, struct xtc_handle **handle
verbose++;
break;
+ case 'w':
+ wait = true;
+ break;
+
case 'm':
command_match(&cs);
break;
@@ -1724,6 +1731,14 @@ int do_command6(int argc, char *argv[], char **table, struct xtc_handle **handle
"chain name `%s' too long (must be under %u chars)",
chain, XT_EXTENSION_MAXNAMELEN);
+ /* Attempt to acquire the xtables lock */
+ if (!xtables_lock(wait)) {
+ fprintf(stderr, "Another app is currently holding the xtables lock. "
+ "Perhaps you want to use the -w option?\n");
+ xtables_free_opts(1);
+ exit(RESOURCE_PROBLEM);
+ }
+
/* only allocate handle if we weren't called with a handle */
if (!*handle)
*handle = ip6tc_init(*table);
diff --git a/iptables/iptables-extensions.8.in b/iptables/iptables-extensions.8.tmpl.in
index 9ec3fb0b..99d89a1f 100644
--- a/iptables/iptables-extensions.8.in
+++ b/iptables/iptables-extensions.8.tmpl.in
@@ -1,4 +1,4 @@
-.TH iptables-extensions 8 "" "@PACKAGE_AND_VERSION@" "@PACKAGE_AND_VERSION@"
+.TH iptables-extensions 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
.SH NAME
iptables-extensions \(em list of extensions in the standard iptables distribution
.SH SYNOPSIS
diff --git a/iptables/iptables.8.in b/iptables/iptables.8.in
index 9643705f..6f310039 100644
--- a/iptables/iptables.8.in
+++ b/iptables/iptables.8.in
@@ -1,4 +1,4 @@
-.TH IPTABLES 8 "" "@PACKAGE_AND_VERSION@" "@PACKAGE_AND_VERSION@"
+.TH IPTABLES 8 "" "@PACKAGE_STRING@" "@PACKAGE_STRING@"
.\"
.\" Man page written by Herve Eychenne <rv@wallfire.org> (May 1999)
.\" It is based on ipchains page.
@@ -351,6 +351,13 @@ For appending, insertion, deletion and replacement, this causes
detailed information on the rule or rules to be printed. \fB\-v\fP may be
specified multiple times to possibly emit more detailed debug statements.
.TP
+\fB\-w\fP, \fB\-\-wait\fP
+Wait for the xtables lock.
+To prevent multiple instances of the program from running concurrently,
+an attempt will be made to obtain an exclusive lock at launch. By default,
+the program will exit if the lock cannot be obtained. This option will
+make the program wait until the exclusive lock can be obtained.
+.TP
\fB\-n\fP, \fB\-\-numeric\fP
Numeric output.
IP addresses and port numbers will be printed in numeric format.
diff --git a/iptables/iptables.c b/iptables/iptables.c
index 79fa37b1..f857bebc 100644
--- a/iptables/iptables.c
+++ b/iptables/iptables.c
@@ -99,6 +99,7 @@ static struct option original_opts[] = {
{.name = "numeric", .has_arg = 0, .val = 'n'},
{.name = "out-interface", .has_arg = 1, .val = 'o'},
{.name = "verbose", .has_arg = 0, .val = 'v'},
+ {.name = "wait", .has_arg = 0, .val = 'w'},
{.name = "exact", .has_arg = 0, .val = 'x'},
{.name = "fragments", .has_arg = 0, .val = 'f'},
{.name = "version", .has_arg = 0, .val = 'V'},
@@ -251,6 +252,7 @@ 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 wait for the xtables lock\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"
@@ -1289,6 +1291,7 @@ int do_command4(int argc, char *argv[], char **table, struct xtc_handle **handle
struct in_addr *daddrs = NULL, *dmasks = NULL;
int verbose = 0;
+ bool wait = false;
const char *chain = NULL;
const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
const char *policy = NULL, *newname = NULL;
@@ -1324,7 +1327,7 @@ int do_command4(int argc, char *argv[], char **table, struct xtc_handle **handle
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:fbvnt: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:fbvwnt:m:xc:g:46",
opts, NULL)) != -1) {
switch (cs.c) {
/*
@@ -1567,6 +1570,10 @@ int do_command4(int argc, char *argv[], char **table, struct xtc_handle **handle
verbose++;
break;
+ case 'w':
+ wait = true;
+ break;
+
case 'm':
command_match(&cs);
break;
@@ -1721,6 +1728,14 @@ int do_command4(int argc, char *argv[], char **table, struct xtc_handle **handle
"chain name `%s' too long (must be under %u chars)",
chain, XT_EXTENSION_MAXNAMELEN);
+ /* Attempt to acquire the xtables lock */
+ if (!xtables_lock(wait)) {
+ fprintf(stderr, "Another app is currently holding the xtables lock. "
+ "Perhaps you want to use the -w option?\n");
+ xtables_free_opts(1);
+ exit(RESOURCE_PROBLEM);
+ }
+
/* only allocate handle if we weren't called with a handle */
if (!*handle)
*handle = iptc_init(*table);
diff --git a/iptables/xshared.c b/iptables/xshared.c
index e61c28c8..6c9992ed 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -6,9 +6,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
#include <xtables.h>
#include "xshared.h"
+#define XT_SOCKET_NAME "xtables"
+#define XT_SOCKET_LEN 8
+
/*
* Print out any special helps. A user might like to be able to add a --help
* to the commandline, and see expected results. So we call help for all
@@ -236,3 +242,30 @@ void xs_init_match(struct xtables_match *match)
if (match->init != NULL)
match->init(match->m);
}
+
+bool xtables_lock(bool wait)
+{
+ int i = 0, ret, xt_socket;
+ struct sockaddr_un xt_addr;
+
+ memset(&xt_addr, 0, sizeof(xt_addr));
+ xt_addr.sun_family = AF_UNIX;
+ strcpy(xt_addr.sun_path+1, XT_SOCKET_NAME);
+ xt_socket = socket(AF_UNIX, SOCK_STREAM, 0);
+ /* If we can't even create a socket, fall back to prior (lockless) behavior */
+ if (xt_socket < 0)
+ return true;
+
+ while (1) {
+ ret = bind(xt_socket, (struct sockaddr*)&xt_addr,
+ offsetof(struct sockaddr_un, sun_path)+XT_SOCKET_LEN);
+ if (ret == 0)
+ return true;
+ else if (wait == false)
+ return false;
+ if (++i % 2 == 0)
+ fprintf(stderr, "Another app is currently holding the xtables lock; "
+ "waiting for it to exit...\n");
+ sleep(1);
+ }
+}
diff --git a/iptables/xshared.h b/iptables/xshared.h
index b804aafe..1e2b9b8e 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -2,6 +2,7 @@
#define IPTABLES_XSHARED_H 1
#include <limits.h>
+#include <stdbool.h>
#include <stdint.h>
#include <netinet/in.h>
#include <net/if.h>
@@ -83,6 +84,7 @@ extern struct xtables_match *load_proto(struct iptables_command_state *);
extern int subcmd_main(int, char **, const struct subcommand *);
extern void xs_init_target(struct xtables_target *);
extern void xs_init_match(struct xtables_match *);
+extern bool xtables_lock(bool wait);
extern const struct xtables_afinfo *afinfo;
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 009ab911..ebc77b6c 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -305,8 +305,8 @@ static char *get_modprobe(void)
{
int procfile;
char *ret;
+ int count;
-#define PROCFILE_BUFSIZ 1024
procfile = open(PROC_SYS_MODPROBE, O_RDONLY);
if (procfile < 0)
return NULL;
@@ -316,19 +316,19 @@ static char *get_modprobe(void)
exit(1);
}
- ret = malloc(PROCFILE_BUFSIZ);
+ ret = malloc(PATH_MAX);
if (ret) {
- memset(ret, 0, PROCFILE_BUFSIZ);
- switch (read(procfile, ret, PROCFILE_BUFSIZ)) {
- case -1: goto fail;
- case PROCFILE_BUFSIZ: goto fail; /* Partial read. Wierd */
+ count = read(procfile, ret, PATH_MAX);
+ if (count > 0 && count < PATH_MAX)
+ {
+ if (ret[count - 1] == '\n')
+ ret[count - 1] = '\0';
+ else
+ ret[count] = '\0';
+ close(procfile);
+ return ret;
}
- if (ret[strlen(ret)-1]=='\n')
- ret[strlen(ret)-1]=0;
- close(procfile);
- return ret;
}
- fail:
free(ret);
close(procfile);
return NULL;