diff -Nru iptables-1.8.5/configure iptables-1.8.7/configure --- iptables-1.8.5/configure 2020-06-03 11:07:27.000000000 +0000 +++ iptables-1.8.7/configure 2021-01-15 22:10:41.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for iptables 1.8.5. +# Generated by GNU Autoconf 2.69 for iptables 1.8.7. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ # Identity of this package. PACKAGE_NAME='iptables' PACKAGE_TARNAME='iptables' -PACKAGE_VERSION='1.8.5' -PACKAGE_STRING='iptables 1.8.5' +PACKAGE_VERSION='1.8.7' +PACKAGE_STRING='iptables 1.8.7' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -632,6 +632,7 @@ am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +XT_LOCK_NAME libxtables_vmajor libxtables_vage libxtables_vcurrent @@ -1405,7 +1406,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures iptables 1.8.5 to adapt to many kinds of systems. +\`configure' configures iptables 1.8.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1476,7 +1477,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of iptables 1.8.5:";; + short | recursive ) echo "Configuration of iptables 1.8.7:";; esac cat <<\_ACEOF @@ -1627,7 +1628,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -iptables configure 1.8.5 +iptables configure 1.8.7 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2175,7 +2176,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by iptables $as_me 1.8.5, which was +It was created by iptables $as_me 1.8.7, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2525,8 +2526,8 @@ # See libtool.info "Libtool's versioning system" -libxtables_vcurrent=15 -libxtables_vage=3 +libxtables_vcurrent=16 +libxtables_vage=4 ac_aux_dir= for ac_dir in build-aux "$srcdir"/build-aux; do @@ -3046,7 +3047,7 @@ # Define the identity of the package. PACKAGE='iptables' - VERSION='1.8.5' + VERSION='1.8.7' cat >>confdefs.h <<_ACEOF @@ -13284,6 +13285,8 @@ #define XT_LOCK_NAME "${xt_lock_name}" _ACEOF +XT_LOCK_NAME="${xt_lock_name}" + ac_config_files="$ac_config_files Makefile extensions/GNUmakefile include/Makefile iptables/Makefile iptables/xtables.pc iptables/iptables.8 iptables/iptables-extensions.8.tmpl iptables/iptables-save.8 iptables/iptables-restore.8 iptables/iptables-apply.8 iptables/iptables-xml.1 libipq/Makefile libipq/libipq.pc libiptc/Makefile libiptc/libiptc.pc libiptc/libip4tc.pc libiptc/libip6tc.pc libxtables/Makefile utils/Makefile include/xtables-version.h iptables/xtables-monitor.8 utils/nfnl_osf.8 utils/nfbpf_compile.8" @@ -13877,7 +13880,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by iptables $as_me 1.8.5, which was +This file was extended by iptables $as_me 1.8.7, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13943,7 +13946,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -iptables config.status 1.8.5 +iptables config.status 1.8.7 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru iptables-1.8.5/configure.ac iptables-1.8.7/configure.ac --- iptables-1.8.5/configure.ac 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/configure.ac 2021-01-15 22:03:39.000000000 +0000 @@ -1,9 +1,9 @@ -AC_INIT([iptables], [1.8.5]) +AC_INIT([iptables], [1.8.7]) # See libtool.info "Libtool's versioning system" -libxtables_vcurrent=15 -libxtables_vage=3 +libxtables_vcurrent=16 +libxtables_vage=4 AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) @@ -219,6 +219,7 @@ AC_DEFINE_UNQUOTED([XT_LOCK_NAME], "${xt_lock_name}", [Location of the iptables lock file]) +AC_SUBST([XT_LOCK_NAME], "${xt_lock_name}") AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile iptables/Makefile iptables/xtables.pc diff -Nru iptables-1.8.5/debian/changelog iptables-1.8.7/debian/changelog --- iptables-1.8.5/debian/changelog 2020-11-18 01:06:27.000000000 +0000 +++ iptables-1.8.7/debian/changelog 2021-02-16 15:16:08.000000000 +0000 @@ -1,3 +1,49 @@ +iptables (1.8.7-1ubuntu2) hirsute; urgency=medium + + * No change rebuild with fixed ownership. + + -- Dimitri John Ledkov Tue, 16 Feb 2021 15:16:08 +0000 + +iptables (1.8.7-1ubuntu1) hirsute; urgency=medium + + * Merge from Debian unstable. Remaining changes: + - debian/control: correct Breaks/Replaces for ipt_kernel_headers.h + move from libiptc-dev to libip4tc-dev + - debian/control: add linuxdoc-tools dep + - 9000-howtos.patch: add howtos/ and install them + - 9002-libxt_recent-Add-support-for-reap-option.patch: Some changes are + upstream, patch needed for additional reap option checks. + - debian/iptables-dev.doc-base.netfilter-extensions, + debian/iptables-dev.doc-base.netfilter-hacking, + debian/iptables.doc-base.nat, debian/iptables.doc-base.packet-filter: + add howtos + - Demote nftables from Recommends to Suggests for hirsute. + - autopkgtest: allow-stderr on command9 to fix regression + * Dropped changes, included upstream: + - d/p/9003-iptables_nft_fix_basechain_policy_configuration.patch: Backport + patch from upstream to fix basechain policy configuration when it + wasn't explicitly set. + - d/p/9004-ebtables-fix-for-broken-chain-rename.patch: Backport patch + from upstream to fix improper use of errno to indicate failure when + renaming an existing chain. + + -- Alex Murray Wed, 10 Feb 2021 14:20:27 +1030 + +iptables (1.8.7-1) unstable; urgency=medium + + * [6343d36] New upstream version 1.8.7 (Closes: #975028) + * [b633a41] d/libxtables12.symbols: refresh file + + -- Arturo Borrero Gonzalez Sun, 17 Jan 2021 19:05:22 +0100 + +iptables (1.8.6-1) unstable; urgency=medium + + * [9caffe9] New upstream version 1.8.6 + * [424bda6] d/patches: drop 0000-upstream-fix-xtables-translate.patch + * [6436087] src:iptables: drop unused manual pages + + -- Arturo Borrero Gonzalez Mon, 09 Nov 2020 11:38:43 +0100 + iptables (1.8.5-3ubuntu4) hirsute; urgency=medium * Fix regression in ebtables when renaming a chain (LP: #1904192) diff -Nru iptables-1.8.5/debian/iptables.manpages iptables-1.8.7/debian/iptables.manpages --- iptables-1.8.5/debian/iptables.manpages 2020-06-04 11:36:54.000000000 +0000 +++ iptables-1.8.7/debian/iptables.manpages 2021-01-17 17:57:14.000000000 +0000 @@ -1,5 +1,2 @@ -debian/xtables-compat.8 -debian/xtables-multi.8 -debian/xtables-translate.8 iptables/*.8 utils/nfnl_osf.8 diff -Nru iptables-1.8.5/debian/libxtables12.symbols iptables-1.8.7/debian/libxtables12.symbols --- iptables-1.8.5/debian/libxtables12.symbols 2020-07-07 08:36:08.000000000 +0000 +++ iptables-1.8.7/debian/libxtables12.symbols 2021-01-17 18:04:44.000000000 +0000 @@ -60,6 +60,7 @@ xtables_options_xfrm@Base 1.6.0+snapshot20161117 xtables_param_act@Base 1.6.0+snapshot20161117 xtables_parse_interface@Base 1.6.0+snapshot20161117 + xtables_parse_mac_and_mask@Base 1.8.7 xtables_parse_port@Base 1.6.0+snapshot20161117 xtables_parse_protocol@Base 1.6.0+snapshot20161117 xtables_parse_val_mask@Base 1.8.0 @@ -69,6 +70,7 @@ xtables_print_mac_and_mask@Base 1.8.2 xtables_print_num@Base 1.6.0+snapshot20161117 xtables_print_val_mask@Base 1.8.0 + xtables_print_well_known_mac_and_mask@Base 1.8.7 xtables_realloc@Base 1.6.0+snapshot20161117 xtables_register_match@Base 1.6.0+snapshot20161117 xtables_register_matches@Base 1.6.0+snapshot20161117 diff -Nru iptables-1.8.5/debian/patches/0000-upstream-fix-xtables-translate.patch iptables-1.8.7/debian/patches/0000-upstream-fix-xtables-translate.patch --- iptables-1.8.5/debian/patches/0000-upstream-fix-xtables-translate.patch 2020-07-07 08:36:08.000000000 +0000 +++ iptables-1.8.7/debian/patches/0000-upstream-fix-xtables-translate.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -From 2757c0b5e5fbbf569695469b331453cecefdf069 Mon Sep 17 00:00:00 2001 -From: Arturo Borrero Gonzalez -Date: Tue, 16 Jun 2020 11:20:42 +0200 -Subject: xtables-translate: don't fail if help was requested - -If the user called `iptables-translate -h` then we have CMD_NONE and we should gracefully handle -this case in do_command_xlate(). - -Before this patch, you would see: - - user@debian:~$ sudo iptables-translate -h - [..] - nft Unsupported command? - user@debian:~$ echo $? - 1 - -After this patch: - - user@debian:~$ sudo iptables-translate -h - [..] - user@debian:~$ echo $? - 0 - -Fixes: d4409d449c10fa ("nft: Don't exit early after printing help texts") -Acked-by: Phil Sutter -Signed-off-by: Arturo Borrero Gonzalez ---- - iptables/xtables-translate.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c -index 5aa42496..363c8be1 100644 ---- a/iptables/xtables-translate.c -+++ b/iptables/xtables-translate.c -@@ -249,7 +249,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], - - cs.restore = restore; - -- if (!restore) -+ if (!restore && p.command != CMD_NONE) - printf("nft "); - - switch (p.command) { -@@ -310,6 +310,9 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], - break; - case CMD_SET_POLICY: - break; -+ case CMD_NONE: -+ ret = 1; -+ break; - default: - /* We should never reach this... */ - printf("Unsupported command?\n"); --- -cgit v1.2.3 - diff -Nru iptables-1.8.5/debian/patches/9003-iptables_nft_fix_basechain_policy_configuration.patch iptables-1.8.7/debian/patches/9003-iptables_nft_fix_basechain_policy_configuration.patch --- iptables-1.8.5/debian/patches/9003-iptables_nft_fix_basechain_policy_configuration.patch 2020-11-03 01:27:18.000000000 +0000 +++ iptables-1.8.7/debian/patches/9003-iptables_nft_fix_basechain_policy_configuration.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -Backport of upstream patch: -From 0bd7a8eaf3582159490ab355b1217a4e42ed021f Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Fri, 2 Oct 2020 13:44:36 +0200 -Subject: iptables-nft: fix basechain policy configuration - -Previous to this patch, the basechain policy could not be properly -configured if it wasn't explictly set when loading the ruleset, leading -to iptables-nft-restore (and ip6tables-nft-restore) trying to send an -invalid ruleset to the kernel. - -Signed-off-by: Arturo Borrero Gonzalez -Signed-off-by: Pablo Neira Ayuso ---- - iptables/nft.c | 6 ++++- - .../testcases/nft-only/0008-basechain-policy_0 | 29 ++++++++++++++++++++++ - 2 files changed, 34 insertions(+), 1 deletion(-) - create mode 100755 iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 - ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -685,7 +685,9 @@ nft_chain_builtin_alloc(const struct bui - nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain->name); - nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM, chain->hook); - nftnl_chain_set_u32(c, NFTNL_CHAIN_PRIO, chain->prio); -- nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy); -+ if (policy >= 0) -+ nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy); -+ - nftnl_chain_set_str(c, NFTNL_CHAIN_TYPE, chain->type); - - return c; -@@ -928,6 +930,8 @@ int nft_chain_set(struct nft_handle *h, - c = nft_chain_new(h, table, chain, NF_DROP, counters); - else if (strcmp(policy, "ACCEPT") == 0) - c = nft_chain_new(h, table, chain, NF_ACCEPT, counters); -+ else if (strcmp(policy, "-") == 0) -+ c = nft_chain_new(h, table, chain, -1, counters); - else - errno = EINVAL; - ---- /dev/null -+++ b/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 -@@ -0,0 +1,29 @@ -+#!/bin/bash -+ -+[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } -+set -e -+ -+$XT_MULTI iptables -t raw -P OUTPUT DROP -+ -+# make sure iptables-nft-restore can correctly handle basechain policies when -+# they aren't set with --noflush -+# -+$XT_MULTI iptables-restore --noflush < -Date: Tue, 17 Nov 2020 11:38:27 +0100 -Subject: ebtables: Fix for broken chain renaming - -Loading extensions pollutes 'errno' value, hence before using it to -indicate failure it should be sanitized. This was done by the called -function before the parsing/netlink split and not migrated by accident. -Move it into calling code to clarify the connection. - -Fixes: a7f1e208cdf9c ("nft: split parsing from netlink commands") -Signed-off-by: Phil Sutter ---- - iptables/nft.c | 3 --- - iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 | 4 ++++ - iptables/xtables-eb.c | 1 + - 3 files changed, 5 insertions(+), 3 deletions(-) - ---- a/iptables/nft.c -+++ b/iptables/nft.c -@@ -1940,9 +1940,6 @@ int nft_chain_user_rename(struct nft_han - - nft_xt_builtin_init(h, table); - -- /* Config load changed errno. Ensure genuine info for our callers. */ -- errno = 0; -- - /* Find the old chain to be renamed */ - c = nft_chain_find(h, table, chain); - if (c == NULL) { ---- a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 -+++ b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 -@@ -86,4 +86,8 @@ if [ $? -eq 0 ]; then - exit 1 - fi - -+$XT_MULTI ebtables -t filter -E FOO BAZ || exit 1 -+$XT_MULTI ebtables -t filter -L | grep -q FOO && exit 1 -+$XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1 -+ - $XT_MULTI ebtables -t $t -F || exit 0 ---- a/iptables/xtables-eb.c -+++ b/iptables/xtables-eb.c -@@ -853,6 +853,7 @@ int do_commandeb(struct nft_handle *h, i - else if (strchr(argv[optind], ' ') != NULL) - xtables_error(PARAMETER_PROBLEM, "Use of ' ' not allowed in chain names"); - -+ errno = 0; - ret = nft_cmd_chain_user_rename(h, chain, *table, - argv[optind]); - if (ret != 0 && errno == ENOENT) diff -Nru iptables-1.8.5/debian/patches/series iptables-1.8.7/debian/patches/series --- iptables-1.8.5/debian/patches/series 2020-11-18 01:06:27.000000000 +0000 +++ iptables-1.8.7/debian/patches/series 2021-02-10 03:50:27.000000000 +0000 @@ -1,5 +1,2 @@ -0000-upstream-fix-xtables-translate.patch 9000-howtos.patch 9002-libxt_recent-Add-support-for-reap-option.patch -9003-iptables_nft_fix_basechain_policy_configuration.patch -9004-ebtables-fix-for-broken-chain-rename.patch diff -Nru iptables-1.8.5/debian/xtables-compat.8 iptables-1.8.7/debian/xtables-compat.8 --- iptables-1.8.5/debian/xtables-compat.8 2020-06-04 11:36:54.000000000 +0000 +++ iptables-1.8.7/debian/xtables-compat.8 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -.\" -.\" (C) Copyright 2016-2017, Arturo Borrero Gonzalez -.\" -.\" %%%LICENSE_START(GPLv2+_DOC_FULL) -.\" This is free documentation; you can redistribute it and/or -.\" modify it under the terms of the GNU General Public License as -.\" published by the Free Software Foundation; either version 2 of -.\" the License, or (at your option) any later version. -.\" -.\" The GNU General Public License's references to "object code" -.\" and "executables" are to be interpreted as the output of any -.\" document formatting or typesetting system, including -.\" intermediate and printed output. -.\" -.\" This manual is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public -.\" License along with this manual; if not, see -.\" . -.\" %%%LICENSE_END -.\" -.TH XTABLES-COMPAT 8 "Feb 25, 2017" - -.SH NAME -xtables-compat \- compat tools to migrate from iptables to nftables - -.SH DESCRIPTION -\fBxtables-compat\fP is set of tools to help the system administrator migrate the -ruleset from \fBiptables(8)\fP, \fBip6tables(8)\fP, \fBarptables(8)\fP, and -\fBebtables(8)\fP to \fBnftables(8)\fP. - -The \fBxtables-compat\fP set is composed of several commands: -.IP \[bu] 2 -iptables-compat -.IP \[bu] -iptables-compat-save -.IP \[bu] -iptables-compat-restore -.IP \[bu] -ip6tables-compat -.IP \[bu] -ip6tables-compat-save -.IP \[bu] -ip6tables-compat-restore -.IP \[bu] -arptables-compat -.IP \[bu] -ebtables-compat - -These tools use the libxtables framework extensions and hook to the nf_tables -kernel subsystem using the \fBnft_compat\fP module. - -.SH USAGE -The compat tools set allows you to manage the nf_tables backend using the -native syntax of \fBiptables(8)\fP, \fBip6tables(8)\fP, \fBarptables(8)\fP, and -\fBebtables(8)\fP. - -You should use the compat tools exactly the same way as you would use the -corresponding original tool. - -Adding a rule will result in that rule being added to the nf_tables kernel -subsystem instead. -Listing the ruleset will use the nf_tables backend as well. - -When these tools were designed, the main idea was to replace each legacy binary -with a symlink to the corresponding compat tool, for example: - -.nf - /sbin/iptables --> /usr/sbin/iptables-compat - /sbin/ip6tables --> /usr/sbin/ip6tables-compat - /sbin/arptables --> /usr/sbin/arptables-compat - /sbin/ebtables --> /usr/sbin/ebtables-compat -.fi - -.SH EXAMPLES -One basic example is creating the skeleton ruleset in nf_tables from the -compat tools, in a fresh machine: - -.nf - root@machine:~# iptables-compat -L - [...] - root@machine:~# ip6tables-compat -L - [...] - root@machine:~# arptables-compat -L - [...] - root@machine:~# ebtables-compat -L - [...] - root@machine:~# nft list ruleset - table ip filter { - chain INPUT { - type filter hook input priority 0; policy accept; - } - - chain FORWARD { - type filter hook forward priority 0; policy accept; - } - - chain OUTPUT { - type filter hook output priority 0; policy accept; - } - } - table ip6 filter { - chain INPUT { - type filter hook input priority 0; policy accept; - } - - chain FORWARD { - type filter hook forward priority 0; policy accept; - } - - chain OUTPUT { - type filter hook output priority 0; policy accept; - } - } - table bridge filter { - chain INPUT { - type filter hook input priority -200; policy accept; - } - - chain FORWARD { - type filter hook forward priority -200; policy accept; - } - - chain OUTPUT { - type filter hook output priority -200; policy accept; - } - } - table arp filter { - chain INPUT { - type filter hook input priority 0; policy accept; - } - - chain FORWARD { - type filter hook forward priority 0; policy accept; - } - - chain OUTPUT { - type filter hook output priority 0; policy accept; - } - } -.fi - -(please note that in fresh machines, listing the ruleset for the first time -results in all tables an chain being created). - -To migrate your complete filter ruleset, in the case of \fBiptables(8)\fP, -you would use: - -.nf - root@machine:~# iptables-save > myruleset # reads from x_tables - root@machine:~# iptables-compat-restore myruleset # writes to nf_tables -.fi - - -.SH LIMITATIONS -You should use \fBLinux kernel >= 4.2\fP. - -Some (few) extensions may be not supported (or fully-supported) for whatever -reason (for example, they were considered obsolete). - -To get up-to-date information about this, please head to -\fBhttp://wiki.nftables.org/\fP. - -.SH SEE ALSO -\fBnft(8)\fP, \fBxtables-translate(8)\fP - -.SH AUTHORS -The nftables framework is written by the Netfilter project -(https://www.netfilter.org). - -This manual page was written by Arturo Borrero Gonzalez - for the Debian project, but may be used by others. - -This documentation is free/libre under the terms of the GPLv2+. diff -Nru iptables-1.8.5/debian/xtables-multi.8 iptables-1.8.7/debian/xtables-multi.8 --- iptables-1.8.5/debian/xtables-multi.8 2020-06-04 11:36:54.000000000 +0000 +++ iptables-1.8.7/debian/xtables-multi.8 1970-01-01 00:00:00.000000000 +0000 @@ -1,83 +0,0 @@ -.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) -.\" -.\" Standard preamble: -.\" ======================================================================== -.de Sp \" Vertical space (when we can't use .PP) -.if t .sp .5v -.if n .sp -.. -.de Vb \" Begin verbatim text -.ft CW -.nf -.ne \\$1 -.. -.de Ve \" End verbatim text -.ft R -.fi -.. -.\" Set up some character translations and predefined strings. \*(-- will -.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left -.\" double quote, and \*(R" will give a right double quote. \*(C+ will -.\" give a nicer C++. Capital omega is used to do unbreakable dashes and -.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, -.\" nothing in troff, for use with C<>. -.tr \(*W- -.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' -.ie n \{\ -. ds -- \(*W- -. ds PI pi -. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch -. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch -. ds L" "" -. ds R" "" -. ds C` "" -. ds C' "" -'br\} -.el\{\ -. ds -- \|\(em\| -. ds PI \(*p -. ds L" `` -. ds R" '' -'br\} -.\" -.\" Escape single quotes in literal strings from groff's Unicode transform. -.ie \n(.g .ds Aq \(aq -.el .ds Aq ' -.\" -.\" If the F register is turned on, we'll generate index entries on stderr for -.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index -.\" entries marked with X<> in POD. Of course, you'll have to process the -.\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" -.. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX -.. -.\} -.\" ======================================================================== -.\" -.IX Title "XTABLES-MULTI 8" -.TH XTABLES-MULTI 8 "2012-10-27" "xtables 1.4.16.3" "xtables-multi" -.\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\" way too many mistakes in technical documents. -.if n .ad l -.nh -.SH "NAME" -xtables\-multi \- xtables multi\-link binary for netfilter's iptables and ip6tables -.SH "SYNOPSIS" -.IX Header "SYNOPSIS" -.Vb 1 -\& n/a -.Ve -.SH "DESCRIPTION" -.IX Header "DESCRIPTION" -xtables-multi has no official man page. It is a binary that behaves -according to the name it is called by. \fB\s-1SEE\s0 \s-1ALSO\s0\fR lists the names. -.SH "SEE ALSO" -.IX Header "SEE ALSO" -\&\fIiptables\fR\|(8), \fIip6tables\fR\|(8), \fIiptables\-save\fR\|(8), \fIip6tables\-save\fR\|(8), \fIiptables\-restore\fR\|(8), \fIip6tables\-restore\fR\|(8) diff -Nru iptables-1.8.5/debian/xtables-translate.8 iptables-1.8.7/debian/xtables-translate.8 --- iptables-1.8.5/debian/xtables-translate.8 2020-06-04 11:36:54.000000000 +0000 +++ iptables-1.8.7/debian/xtables-translate.8 1970-01-01 00:00:00.000000000 +0000 @@ -1,134 +0,0 @@ -.\" -.\" (C) Copyright 2018, Arturo Borrero Gonzalez -.\" -.\" %%%LICENSE_START(GPLv2+_DOC_FULL) -.\" This is free documentation; you can redistribute it and/or -.\" modify it under the terms of the GNU General Public License as -.\" published by the Free Software Foundation; either version 2 of -.\" the License, or (at your option) any later version. -.\" -.\" The GNU General Public License's references to "object code" -.\" and "executables" are to be interpreted as the output of any -.\" document formatting or typesetting system, including -.\" intermediate and printed output. -.\" -.\" This manual is distributed in the hope that it will be useful, -.\" but WITHOUT ANY WARRANTY; without even the implied warranty of -.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -.\" GNU General Public License for more details. -.\" -.\" You should have received a copy of the GNU General Public -.\" License along with this manual; if not, see -.\" . -.\" %%%LICENSE_END -.\" -.TH XTABLES-TRANSLATE 8 "Mar 16, 2018" - -.SH NAME -xtables-translate \- translation tools to migrate from iptables to nftables - -.SH DESCRIPTION -There is a set of tools to help the system administrator translate a given -ruleset from \fBiptables(8)\fP and \fBip6tables(8)\fP to \fBnftables(8)\fP. - -The available commands are: - -.IP \[bu] 2 -iptables-translate -.IP \[bu] -iptables-restore-translate -.IP \[bu] 2 -ip6tables-translate -.IP \[bu] -ip6tables-restore-translate - -.SH USAGE -They take as input the original \fBiptables(8)\fP/\fBip6tables(8)\fP syntax and -output the native \fBnftables(8)\fP syntax. - -The \fBiptables-restore-translate\fP tool reads a ruleset in the syntax -produced by \fBiptables-save(8)\fP. Likewise, the -\fBip6tables-restore-translate\fP tool reads one produced by -\fBip6tables-save(8)\fP. - -The \fBiptables-translate\fP reads a command line as if it was entered to -\fBiptables(8)\fP, and \fBip6tables-translate\fP reads a command like as if it -was entered to \fBip6tables(8)\fP. - -.SH EXAMPLES -Basic operation examples. - -Single command translation: - -.nf -root@machine:~# iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT -nft add rule ip filter INPUT tcp dport 22 ct state new counter accept - -root@machine:~# ip6tables-translate -A FORWARD -i eth0 -o eth3 -p udp -m multiport --dports 111,222 -j ACCEPT -nft add rule ip6 filter FORWARD iifname eth0 oifname eth3 meta l4proto udp udp dport { 111,222} counter accept -.fi - -Whole ruleset translation: - -.nf -root@machine:~# iptables-save > save.txt -root@machine:~# cat save.txt -# Generated by iptables-save v1.6.0 on Sat Dec 24 14:26:40 2016 -*filter -:INPUT ACCEPT [5166:1752111] -:FORWARD ACCEPT [0:0] -:OUTPUT ACCEPT [5058:628693] --A FORWARD -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT -COMMIT -# Completed on Sat Dec 24 14:26:40 2016 - -root@machine:~# iptables-restore-translate -f save.txt -# Translated by iptables-restore-translate v1.6.0 on Sat Dec 24 14:26:59 2016 -add table ip filter -add chain ip filter INPUT { type filter hook input priority 0; } -add chain ip filter FORWARD { type filter hook forward priority 0; } -add chain ip filter OUTPUT { type filter hook output priority 0; } -add rule ip filter FORWARD tcp dport 22 ct state new counter accept - -root@machine:~# iptables-restore-translate -f save.txt > ruleset.nft -root@machine:~# nft -f ruleset.nft -root@machine:~# nft list ruleset -table ip filter { - chain INPUT { - type filter hook input priority 0; policy accept; - } - - chain FORWARD { - type filter hook forward priority 0; policy accept; - tcp dport ssh ct state new counter packets 0 bytes 0 accept - } - - chain OUTPUT { - type filter hook output priority 0; policy accept; - } -} -.fi - - -.SH LIMITATIONS -Some (few) extensions may be not supported (or fully-supported) for whatever -reason (for example, they were considered obsolete, or we didn't have the time -to work on them). - -There are no translations available for \fBebtables(8)\fP and -\fBarptables(8)\fP. - -To get up-to-date information about this, please head to -\fBhttps://wiki.nftables.org/\fP. - -.SH SEE ALSO -\fBnft(8)\fP, \fBxtables-compat(8)\fP - -.SH AUTHORS -The nftables framework is written by the Netfilter project -(https://www.netfilter.org). - -This manual page was written by Arturo Borrero Gonzalez -. - -This documentation is free/libre under the terms of the GPLv2+. diff -Nru iptables-1.8.5/extensions/GNUmakefile.in iptables-1.8.7/extensions/GNUmakefile.in --- iptables-1.8.5/extensions/GNUmakefile.in 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/GNUmakefile.in 2021-01-15 22:03:39.000000000 +0000 @@ -79,7 +79,7 @@ .SECONDARY: -.PHONY: all install clean distclean FORCE +.PHONY: all install uninstall clean distclean FORCE all: ${targets} @@ -92,6 +92,19 @@ cp -P ${symlinks_install} "${DESTDIR}${xtlibdir}/"; \ fi; +uninstall: + dir=${DESTDIR}${xtlibdir}; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || { \ + test -z "${targets_install}" || ( \ + cd "$$dir" && rm -f ${targets_install} \ + ); \ + test -z "${symlinks_install}" || ( \ + cd "$$dir" && rm -f ${symlinks_install} \ + ); \ + rmdir -p --ignore-fail-on-non-empty "$$dir"; \ + } + clean: rm -f *.o *.oo *.so *.a {matches,targets}.man initext.c initext4.c initext6.c initextb.c initexta.c; rm -f .*.d .*.dd; diff -Nru iptables-1.8.5/extensions/libarpt_mangle.c iptables-1.8.7/extensions/libarpt_mangle.c --- iptables-1.8.5/extensions/libarpt_mangle.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libarpt_mangle.c 2021-01-15 22:03:39.000000000 +0000 @@ -130,15 +130,6 @@ { } -static void print_mac(const unsigned char *mac, int l) -{ - int j; - - for (j = 0; j < l; j++) - printf("%02x%s", mac[j], - (j==l-1) ? "" : ":"); -} - static const char *ipaddr_to(const struct in_addr *addrp, int numeric) { if (numeric) @@ -159,7 +150,7 @@ } if (m->flags & ARPT_MANGLE_SDEV) { printf(" --mangle-mac-s "); - print_mac((unsigned char *)m->src_devaddr, 6); + xtables_print_mac((unsigned char *)m->src_devaddr); } if (m->flags & ARPT_MANGLE_TIP) { printf(" --mangle-ip-d %s", @@ -167,7 +158,7 @@ } if (m->flags & ARPT_MANGLE_TDEV) { printf(" --mangle-mac-d "); - print_mac((unsigned char *)m->tgt_devaddr, 6); + xtables_print_mac((unsigned char *)m->tgt_devaddr); } if (m->target != NF_ACCEPT) { printf(" --mangle-target %s", diff -Nru iptables-1.8.5/extensions/libebt_arp.c iptables-1.8.7/extensions/libebt_arp.c --- iptables-1.8.5/extensions/libebt_arp.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libebt_arp.c 2021-01-15 22:03:39.000000000 +0000 @@ -161,54 +161,6 @@ *addr = *addr & *msk; } -static int brarp_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask) -{ - char *p; - int i; - struct ether_addr *addr = NULL; - - static const unsigned char mac_type_unicast[ETH_ALEN]; - static const unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0}; - static const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; - static const unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; - static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0}; - static const unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255}; - - if (strcasecmp(from, "Unicast") == 0) { - memcpy(to, mac_type_unicast, ETH_ALEN); - memcpy(mask, msk_type_unicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Multicast") == 0) { - memcpy(to, mac_type_multicast, ETH_ALEN); - memcpy(mask, mac_type_multicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Broadcast") == 0) { - memcpy(to, mac_type_broadcast, ETH_ALEN); - memcpy(mask, mac_type_broadcast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "BGA") == 0) { - memcpy(to, mac_type_bridge_group, ETH_ALEN); - memcpy(mask, msk_type_bridge_group, ETH_ALEN); - return 0; - } - if ( (p = strrchr(from, '/')) != NULL) { - *p = '\0'; - if (!(addr = ether_aton(p + 1))) - return -1; - memcpy(mask, addr, ETH_ALEN); - } else - memset(mask, 0xff, ETH_ALEN); - if (!(addr = ether_aton(from))) - return -1; - memcpy(to, addr, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) - to[i] &= mask[i]; - return 0; -} - static int brarp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) @@ -317,7 +269,7 @@ else arpinfo->invflags |= EBT_ARP_DST_MAC; } - if (brarp_get_mac_and_mask(optarg, maddr, mmask)) + if (xtables_parse_mac_and_mask(optarg, maddr, mmask)) xtables_error(PARAMETER_PROBLEM, "Problem with ARP MAC address argument"); break; case ARP_GRAT: diff -Nru iptables-1.8.5/extensions/libebt_stp.c iptables-1.8.7/extensions/libebt_stp.c --- iptables-1.8.5/extensions/libebt_stp.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libebt_stp.c 2021-01-15 22:03:39.000000000 +0000 @@ -150,54 +150,6 @@ printf("%u:%u ", l, u); } -static int brstp_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask) -{ - char *p; - int i; - struct ether_addr *addr = NULL; - - static const unsigned char mac_type_unicast[ETH_ALEN]; - static const unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0}; - static const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; - static const unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; - static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0}; - static const unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255}; - - if (strcasecmp(from, "Unicast") == 0) { - memcpy(to, mac_type_unicast, ETH_ALEN); - memcpy(mask, msk_type_unicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Multicast") == 0) { - memcpy(to, mac_type_multicast, ETH_ALEN); - memcpy(mask, mac_type_multicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Broadcast") == 0) { - memcpy(to, mac_type_broadcast, ETH_ALEN); - memcpy(mask, mac_type_broadcast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "BGA") == 0) { - memcpy(to, mac_type_bridge_group, ETH_ALEN); - memcpy(mask, msk_type_bridge_group, ETH_ALEN); - return 0; - } - if ( (p = strrchr(from, '/')) != NULL) { - *p = '\0'; - if (!(addr = ether_aton(p + 1))) - return -1; - memcpy(mask, addr, ETH_ALEN); - } else - memset(mask, 0xff, ETH_ALEN); - if (!(addr = ether_aton(from))) - return -1; - memcpy(to, addr, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) - to[i] &= mask[i]; - return 0; -} - static int brstp_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_match **match) @@ -280,15 +232,15 @@ xtables_error(PARAMETER_PROBLEM, "Bad --stp-forward-delay range"); break; case EBT_STP_ROOTADDR: - if (brstp_get_mac_and_mask(argv[optind-1], - (unsigned char *)stpinfo->config.root_addr, - (unsigned char *)stpinfo->config.root_addrmsk)) + if (xtables_parse_mac_and_mask(argv[optind-1], + stpinfo->config.root_addr, + stpinfo->config.root_addrmsk)) xtables_error(PARAMETER_PROBLEM, "Bad --stp-root-addr address"); break; case EBT_STP_SENDERADDR: - if (brstp_get_mac_and_mask(argv[optind-1], - (unsigned char *)stpinfo->config.sender_addr, - (unsigned char *)stpinfo->config.sender_addrmsk)) + if (xtables_parse_mac_and_mask(argv[optind-1], + stpinfo->config.sender_addr, + stpinfo->config.sender_addrmsk)) xtables_error(PARAMETER_PROBLEM, "Bad --stp-sender-addr address"); break; default: diff -Nru iptables-1.8.5/extensions/libip6t_REJECT.man iptables-1.8.7/extensions/libip6t_REJECT.man --- iptables-1.8.5/extensions/libip6t_REJECT.man 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libip6t_REJECT.man 2021-01-15 22:03:39.000000000 +0000 @@ -30,3 +30,23 @@ hosts (which won't accept your mail otherwise). \fBtcp\-reset\fP can only be used with kernel versions 2.6.14 or later. +.PP +\fIWarning:\fP You should not indiscriminately apply the REJECT target to +packets whose connection state is classified as INVALID; instead, you should +only DROP these. +.PP +Consider a source host transmitting a packet P, with P experiencing so much +delay along its path that the source host issues a retransmission, P_2, with +P_2 being successful in reaching its destination and advancing the connection +state normally. It is conceivable that the late-arriving P may be considered +not to be associated with any connection tracking entry. Generating a reject +response for a packet so classed would then terminate the healthy connection. +.PP +So, instead of: +.PP +-A INPUT ... -j REJECT +.PP +do consider using: +.PP +-A INPUT ... -m conntrack --ctstate INVALID -j DROP +-A INPUT ... -j REJECT diff -Nru iptables-1.8.5/extensions/libipt_icmp.c iptables-1.8.7/extensions/libipt_icmp.c --- iptables-1.8.5/extensions/libipt_icmp.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libipt_icmp.c 2021-01-15 22:03:39.000000000 +0000 @@ -256,6 +256,11 @@ if (!type_xlate_print(xl, info->type, info->code[0], info->code[1])) return 0; + } else { + /* '-m icmp --icmp-type any' is a noop by itself, + * but it eats a (mandatory) previous '-p icmp' so + * emit it here */ + xt_xlate_add(xl, "ip protocol icmp"); } return 1; } diff -Nru iptables-1.8.5/extensions/libipt_icmp.txlate iptables-1.8.7/extensions/libipt_icmp.txlate --- iptables-1.8.5/extensions/libipt_icmp.txlate 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libipt_icmp.txlate 2021-01-15 22:03:39.000000000 +0000 @@ -6,3 +6,6 @@ iptables-translate -t filter -A INPUT -m icmp ! --icmp-type 3 -j ACCEPT nft add rule ip filter INPUT icmp type != destination-unreachable counter accept + +iptables-translate -t filter -A INPUT -m icmp --icmp-type any -j ACCEPT +nft add rule ip filter INPUT ip protocol icmp counter accept diff -Nru iptables-1.8.5/extensions/libipt_REJECT.man iptables-1.8.7/extensions/libipt_REJECT.man --- iptables-1.8.5/extensions/libipt_REJECT.man 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libipt_REJECT.man 2021-01-15 22:03:39.000000000 +0000 @@ -30,3 +30,23 @@ hosts (which won't accept your mail otherwise). .IP (*) Using icmp\-admin\-prohibited with kernels that do not support it will result in a plain DROP instead of REJECT +.PP +\fIWarning:\fP You should not indiscriminately apply the REJECT target to +packets whose connection state is classified as INVALID; instead, you should +only DROP these. +.PP +Consider a source host transmitting a packet P, with P experiencing so much +delay along its path that the source host issues a retransmission, P_2, with +P_2 being successful in reaching its destination and advancing the connection +state normally. It is conceivable that the late-arriving P may be considered +not to be associated with any connection tracking entry. Generating a reject +response for a packet so classed would then terminate the healthy connection. +.PP +So, instead of: +.PP +-A INPUT ... -j REJECT +.PP +do consider using: +.PP +-A INPUT ... -m conntrack --ctstate INVALID -j DROP +-A INPUT ... -j REJECT diff -Nru iptables-1.8.5/extensions/libxt_conntrack.c iptables-1.8.7/extensions/libxt_conntrack.c --- iptables-1.8.5/extensions/libxt_conntrack.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libxt_conntrack.c 2021-01-15 22:03:39.000000000 +0000 @@ -1249,11 +1249,19 @@ } if (sinfo->match_flags & XT_CONNTRACK_STATE) { - xt_xlate_add(xl, "%sct state %s", space, - sinfo->invert_flags & XT_CONNTRACK_STATE ? - "!= " : ""); - state_xlate_print(xl, sinfo->state_mask); - space = " "; + if ((sinfo->state_mask & XT_CONNTRACK_STATE_SNAT) || + (sinfo->state_mask & XT_CONNTRACK_STATE_DNAT)) { + xt_xlate_add(xl, "%sct status %s%s", space, + sinfo->invert_flags & XT_CONNTRACK_STATUS ? "!=" : "", + sinfo->state_mask & XT_CONNTRACK_STATE_SNAT ? "snat" : "dnat"); + space = " "; + } else { + xt_xlate_add(xl, "%sct state %s", space, + sinfo->invert_flags & XT_CONNTRACK_STATE ? + "!= " : ""); + state_xlate_print(xl, sinfo->state_mask); + space = " "; + } } if (sinfo->match_flags & XT_CONNTRACK_STATUS) { diff -Nru iptables-1.8.5/extensions/libxt_conntrack.txlate iptables-1.8.7/extensions/libxt_conntrack.txlate --- iptables-1.8.5/extensions/libxt_conntrack.txlate 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libxt_conntrack.txlate 2021-01-15 22:03:39.000000000 +0000 @@ -42,3 +42,10 @@ iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW --ctproto tcp --ctorigsrc 192.168.0.1 --ctorigdst 192.168.0.1 --ctreplsrc 192.168.0.1 --ctrepldst 192.168.0.1 --ctorigsrcport 12 --ctorigdstport 14 --ctreplsrcport 16 --ctrepldstport 18 --ctexpire 10 --ctstatus SEEN_REPLY --ctdir ORIGINAL -j ACCEPT nft add rule ip filter INPUT ct direction original ct original protocol 6 ct state new ct status seen-reply ct expiration 10 ct original saddr 192.168.0.1 ct original daddr 192.168.0.1 ct reply saddr 192.168.0.1 ct reply daddr 192.168.0.1 ct original proto-src 12 ct original proto-dst 14 ct reply proto-src 16 ct reply proto-dst 18 counter accept + +iptables-translate -t filter -A INPUT -m conntrack --ctstate SNAT -j ACCEPT +nft add rule ip filter INPUT ct status snat counter accept + +iptables-translate -t filter -A INPUT -m conntrack --ctstate DNAT -j ACCEPT +nft add rule ip filter INPUT ct status dnat counter accept + diff -Nru iptables-1.8.5/extensions/libxt_dccp.c iptables-1.8.7/extensions/libxt_dccp.c --- iptables-1.8.5/extensions/libxt_dccp.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libxt_dccp.c 2021-01-15 22:03:39.000000000 +0000 @@ -76,6 +76,9 @@ [DCCP_PKT_INVALID] = "INVALID", }; +/* Bits for type values 11-15 */ +#define INVALID_OTHER_TYPE_MASK 0xf800 + static uint16_t parse_dccp_types(const char *typestring) { @@ -95,6 +98,9 @@ xtables_error(PARAMETER_PROBLEM, "Unknown DCCP type `%s'", ptr); } + if (typemask & (1 << DCCP_PKT_INVALID)) + typemask |= INVALID_OTHER_TYPE_MASK; + free(buffer); return typemask; @@ -193,9 +199,13 @@ if (numeric) printf("%u", i); - else + else { printf("%s", dccp_pkt_types[i]); + if (i == DCCP_PKT_INVALID) + break; + } + types &= ~(1 << i); } } @@ -288,6 +298,7 @@ [DCCP_PKT_RESET] = "reset", [DCCP_PKT_SYNC] = "sync", [DCCP_PKT_SYNCACK] = "syncack", + [DCCP_PKT_INVALID] = "10-15", }; static int dccp_type_xlate(const struct xt_dccp_info *einfo, @@ -296,10 +307,10 @@ bool have_type = false, set_need = false; uint16_t types = einfo->typemask; - if (types & (1 << DCCP_PKT_INVALID)) - return 0; - - xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : ""); + if (types & INVALID_OTHER_TYPE_MASK) { + types &= ~INVALID_OTHER_TYPE_MASK; + types |= 1 << DCCP_PKT_INVALID; + } if ((types != 0) && !(types == (types & -types))) { xt_xlate_add(xl, "{"); @@ -335,34 +346,37 @@ char *space = ""; int ret = 1; - xt_xlate_add(xl, "dccp "); - if (einfo->flags & XT_DCCP_SRC_PORTS) { + xt_xlate_add(xl, "dccp sport%s %u", + einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "", + einfo->spts[0]); + if (einfo->spts[0] != einfo->spts[1]) - xt_xlate_add(xl, "sport%s %u-%u", - einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "", - einfo->spts[0], einfo->spts[1]); - else - xt_xlate_add(xl, "sport%s %u", - einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "", - einfo->spts[0]); + xt_xlate_add(xl, "-%u", einfo->spts[1]); + space = " "; } if (einfo->flags & XT_DCCP_DEST_PORTS) { + xt_xlate_add(xl, "%sdccp dport%s %u", space, + einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "", + einfo->dpts[0]); + if (einfo->dpts[0] != einfo->dpts[1]) - xt_xlate_add(xl, "%sdport%s %u-%u", space, - einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "", - einfo->dpts[0], einfo->dpts[1]); - else - xt_xlate_add(xl, "%sdport%s %u", space, - einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "", - einfo->dpts[0]); + xt_xlate_add(xl, "-%u", einfo->dpts[1]); + + space = " "; } - if (einfo->flags & XT_DCCP_TYPE) + if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) { + xt_xlate_add(xl, "%sdccp type%s ", space, + einfo->invflags & XT_DCCP_TYPE ? " !=" : ""); ret = dccp_type_xlate(einfo, xl); + space = " "; + } + + /* FIXME: no dccp option support in nftables yet */ if (einfo->flags & XT_DCCP_OPTION) ret = 0; diff -Nru iptables-1.8.5/extensions/libxt_dccp.txlate iptables-1.8.7/extensions/libxt_dccp.txlate --- iptables-1.8.5/extensions/libxt_dccp.txlate 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libxt_dccp.txlate 2021-01-15 22:03:39.000000000 +0000 @@ -7,8 +7,14 @@ iptables-translate -A INPUT -p dccp -m dccp ! --dport 100 nft add rule ip filter INPUT dccp dport != 100 counter -iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK -nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack} counter +iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE +nft add rule ip filter INPUT dccp type close counter + +iptables-translate -A INPUT -p dccp -m dccp --dccp-types INVALID +nft add rule ip filter INPUT dccp type 10-15 counter + +iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK,INVALID +nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15} counter iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100 -nft add rule ip filter INPUT dccp sport 200 dport 100 counter +nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter diff -Nru iptables-1.8.5/extensions/libxt_mac.c iptables-1.8.7/extensions/libxt_mac.c --- iptables-1.8.5/extensions/libxt_mac.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/extensions/libxt_mac.c 2021-01-15 22:03:39.000000000 +0000 @@ -37,15 +37,6 @@ macinfo->invert = 1; } -static void print_mac(const unsigned char *macaddress) -{ - unsigned int i; - - printf(" %02X", macaddress[0]); - for (i = 1; i < ETH_ALEN; ++i) - printf(":%02X", macaddress[i]); -} - static void mac_print(const void *ip, const struct xt_entry_match *match, int numeric) { @@ -56,7 +47,7 @@ if (info->invert) printf(" !"); - print_mac(info->srcaddr); + xtables_print_mac(info->srcaddr); } static void mac_save(const void *ip, const struct xt_entry_match *match) @@ -66,8 +57,8 @@ if (info->invert) printf(" !"); - printf(" --mac-source"); - print_mac(info->srcaddr); + printf(" --mac-source "); + xtables_print_mac(info->srcaddr); } static void print_mac_xlate(const unsigned char *macaddress, diff -Nru iptables-1.8.5/include/Makefile.am iptables-1.8.7/include/Makefile.am --- iptables-1.8.5/include/Makefile.am 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/include/Makefile.am 2021-01-15 22:03:39.000000000 +0000 @@ -10,3 +10,8 @@ nobase_include_HEADERS += \ libiptc/ipt_kernel_headers.h libiptc/libiptc.h \ libiptc/libip6tc.h libiptc/libxtc.h libiptc/xtcshared.h + +uninstall-hook: + dir=${includedir}/libiptc; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || rmdir -p --ignore-fail-on-non-empty "$$dir" diff -Nru iptables-1.8.5/include/Makefile.in iptables-1.8.7/include/Makefile.in --- iptables-1.8.5/include/Makefile.in 2020-06-03 11:07:28.000000000 +0000 +++ iptables-1.8.7/include/Makefile.in 2021-01-15 22:10:43.000000000 +0000 @@ -241,6 +241,7 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +XT_LOCK_NAME = @XT_LOCK_NAME@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -596,8 +597,9 @@ ps-am: uninstall-am: uninstall-includeHEADERS uninstall-nobase_includeHEADERS - -.MAKE: install-am install-strip + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook +.MAKE: install-am install-strip uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ clean-libtool cscopelist-am ctags ctags-am distclean \ @@ -611,12 +613,17 @@ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-includeHEADERS \ + uninstall-am uninstall-hook uninstall-includeHEADERS \ uninstall-nobase_includeHEADERS .PRECIOUS: Makefile +uninstall-hook: + dir=${includedir}/libiptc; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || rmdir -p --ignore-fail-on-non-empty "$$dir" + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -Nru iptables-1.8.5/include/xtables.h iptables-1.8.7/include/xtables.h --- iptables-1.8.5/include/xtables.h 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/include/xtables.h 2021-01-15 22:03:39.000000000 +0000 @@ -557,6 +557,9 @@ #define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab)) extern void xtables_print_num(uint64_t number, unsigned int format); +extern int xtables_parse_mac_and_mask(const char *from, void *to, void *mask); +extern int xtables_print_well_known_mac_and_mask(const void *mac, + const void *mask); extern void xtables_print_mac(const unsigned char *macaddress); extern void xtables_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask); diff -Nru iptables-1.8.5/iptables/ip6tables.c iptables-1.8.7/iptables/ip6tables.c --- iptables-1.8.5/iptables/ip6tables.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/ip6tables.c 2021-01-15 22:03:39.000000000 +0000 @@ -45,10 +45,6 @@ #include "ip6tables-multi.h" #include "xshared.h" -#define NUMBER_OF_OPT ARRAY_SIZE(optflags) -static const char optflags[] -= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c'}; - static const char unsupported_rev[] = " [unsupported revision]"; static struct option original_opts[] = { @@ -100,36 +96,6 @@ .compat_rev = xtables_compatible_revision, }; -/* Table of legal combinations of commands and options. If any of the - * given commands make an option legal, that option is legal (applies to - * CMD_LIST and CMD_ZERO only). - * Key: - * + compulsory - * x illegal - * optional - */ - -static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = -/* Well, it's better than "Re: Linux vs FreeBSD" */ -{ - /* -n -s -d -p -j -v -x -i -o --line -c */ -/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '}, -/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'}, -/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x'}, -/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '}, -/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '}, -/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x'}, -/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, -/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, -/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, -/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, -/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' '}, -/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, -/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x'}, -/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, -/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'}, -}; - static const unsigned int inverse_for_options[NUMBER_OF_OPT] = { /* -n */ 0, @@ -264,51 +230,6 @@ exit(status); } -static void -generic_opt_check(int command, int options) -{ - int i, j, legal = 0; - - /* Check that commands are valid with options. Complicated by the - * fact that if an option is legal with *any* command given, it is - * legal overall (ie. -z and -l). - */ - for (i = 0; i < NUMBER_OF_OPT; i++) { - legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */ - - for (j = 0; j < NUMBER_OF_CMD; j++) { - if (!(command & (1< 1; option >>= 1, ptr++); - - return *ptr; -} - /* * All functions starting with "parse" should succeed, otherwise * the program fails. diff -Nru iptables-1.8.5/iptables/iptables.8.in iptables-1.8.7/iptables/iptables.8.in --- iptables-1.8.5/iptables/iptables.8.in 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/iptables.8.in 2021-01-15 22:03:39.000000000 +0000 @@ -397,6 +397,14 @@ \fB\-\-modprobe=\fP\fIcommand\fP When adding or inserting rules into a chain, use \fIcommand\fP to load any necessary modules (targets, match extensions, etc). + +.SH LOCK FILE +iptables uses the \fI@XT_LOCK_NAME@\fP file to take an exclusive lock at +launch. + +The \fBXTABLES_LOCKFILE\fP environment variable can be used to override +the default setting. + .SH MATCH AND TARGET EXTENSIONS .PP iptables can use extended packet matching and target modules. diff -Nru iptables-1.8.5/iptables/iptables.c iptables-1.8.7/iptables/iptables.c --- iptables-1.8.5/iptables/iptables.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/iptables.c 2021-01-15 22:03:39.000000000 +0000 @@ -41,11 +41,6 @@ #include #include "xshared.h" -#define OPT_FRAGMENT 0x00800U -#define NUMBER_OF_OPT ARRAY_SIZE(optflags) -static const char optflags[] -= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'}; - static const char unsupported_rev[] = " [unsupported revision]"; static struct option original_opts[] = { @@ -99,36 +94,6 @@ .compat_rev = xtables_compatible_revision, }; -/* Table of legal combinations of commands and options. If any of the - * given commands make an option legal, that option is legal (applies to - * CMD_LIST and CMD_ZERO only). - * Key: - * + compulsory - * x illegal - * optional - */ - -static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = -/* Well, it's better than "Re: Linux vs FreeBSD" */ -{ - /* -n -s -d -p -j -v -x -i -o --line -c -f */ -/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '}, -/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '}, -/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '}, -/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '}, -/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x','x'}, -/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x'}, -/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '}, -}; - static const int inverse_for_options[NUMBER_OF_OPT] = { /* -n */ 0, @@ -263,51 +228,6 @@ exit(status); } -static void -generic_opt_check(int command, int options) -{ - int i, j, legal = 0; - - /* Check that commands are valid with options. Complicated by the - * fact that if an option is legal with *any* command given, it is - * legal overall (ie. -z and -l). - */ - for (i = 0; i < NUMBER_OF_OPT; i++) { - legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */ - - for (j = 0; j < NUMBER_OF_CMD; j++) { - if (!(command & (1< 1; option >>= 1, ptr++); - - return *ptr; -} - /* * All functions starting with "parse" should succeed, otherwise * the program fails. diff -Nru iptables-1.8.5/iptables/Makefile.am iptables-1.8.7/iptables/Makefile.am --- iptables-1.8.5/iptables/Makefile.am 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/Makefile.am 2021-01-15 22:03:39.000000000 +0000 @@ -38,7 +38,7 @@ nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \ xtables-monitor.c nft-cache.c \ xtables-arp-standalone.c xtables-arp.c \ - nft-bridge.c nft-cmd.c \ + nft-bridge.c nft-cmd.c nft-chain.c \ xtables-eb-standalone.c xtables-eb.c \ xtables-eb-translate.c \ xtables-translate.c @@ -56,7 +56,7 @@ ip6tables-save.8 iptables-extensions.8 \ iptables-apply.8 ip6tables-apply.8 -sbin_SCRIPT = iptables-apply +sbin_SCRIPTS = iptables-apply if ENABLE_NFTABLES man_MANS += xtables-nft.8 xtables-translate.8 xtables-legacy.8 \ @@ -67,6 +67,10 @@ ebtables-nft.8 endif CLEANFILES = iptables.8 xtables-monitor.8 \ + iptables-xml.1 iptables-apply.8 \ + iptables-extensions.8 iptables-extensions.8.tmpl \ + iptables-restore.8 iptables-save.8 \ + iptables-restore-translate.8 ip6tables-restore-translate.8 \ iptables-translate.8 ip6tables-translate.8 vx_bin_links = iptables-xml @@ -111,3 +115,26 @@ for i in ${v6_sbin_links}; do ${LN_S} -f xtables-legacy-multi "${DESTDIR}${sbindir}/$$i"; done; for i in ${x_sbin_links}; do ${LN_S} -f xtables-nft-multi "${DESTDIR}${sbindir}/$$i"; done; ${LN_S} -f iptables-apply "${DESTDIR}${sbindir}/ip6tables-apply" + +uninstall-hook: + dir=${DESTDIR}${bindir}; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || { \ + test -z "${vx_bin_links}" || ( \ + cd "$$dir" && rm -f ${vx_bin_links} \ + ) \ + } + dir=${DESTDIR}${sbindir}; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || { \ + test -z "${v4_sbin_links}" || ( \ + cd "$$dir" && rm -f ${v4_sbin_links} \ + ); \ + test -z "${v6_sbin_links}" || ( \ + cd "$$dir" && rm -f ${v6_sbin_links} \ + ); \ + test -z "${x_sbin_links}" || ( \ + cd "$$dir" && rm -f ${x_sbin_links} \ + ); \ + ( cd "$$dir" && rm -f ip6tables-apply ); \ + } diff -Nru iptables-1.8.5/iptables/Makefile.in iptables-1.8.7/iptables/Makefile.in --- iptables-1.8.5/iptables/Makefile.in 2020-06-03 11:07:28.000000000 +0000 +++ iptables-1.8.7/iptables/Makefile.in 2021-01-15 22:10:43.000000000 +0000 @@ -17,6 +17,7 @@ # -*- Makefile -*- + VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ @@ -123,8 +124,9 @@ iptables-xml.1 xtables-monitor.8 CONFIG_CLEAN_VPATH_FILES = @ENABLE_NFTABLES_TRUE@am__EXEEXT_1 = xtables-nft-multi$(EXEEXT) -am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" \ - "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgconfigdir)" +am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sbindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" \ + "$(DESTDIR)$(pkgconfigdir)" PROGRAMS = $(sbin_PROGRAMS) am__xtables_legacy_multi_SOURCES_DIST = xtables-legacy-multi.c \ iptables-xml.c iptables-standalone.c iptables.c \ @@ -156,8 +158,8 @@ xtables-standalone.c xtables.c nft.c nft-shared.c nft-ipv4.c \ nft-ipv6.c nft-arp.c xtables-monitor.c nft-cache.c \ xtables-arp-standalone.c xtables-arp.c nft-bridge.c nft-cmd.c \ - xtables-eb-standalone.c xtables-eb.c xtables-eb-translate.c \ - xtables-translate.c xshared.c + nft-chain.c xtables-eb-standalone.c xtables-eb.c \ + xtables-eb-translate.c xtables-translate.c xshared.c @ENABLE_NFTABLES_TRUE@am_xtables_nft_multi_OBJECTS = xtables_nft_multi-xtables-nft-multi.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-iptables-xml.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-save.$(OBJEXT) \ @@ -175,6 +177,7 @@ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-arp.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-bridge.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-cmd.$(OBJEXT) \ +@ENABLE_NFTABLES_TRUE@ xtables_nft_multi-nft-chain.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb-standalone.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb.$(OBJEXT) \ @ENABLE_NFTABLES_TRUE@ xtables_nft_multi-xtables-eb-translate.$(OBJEXT) \ @@ -197,6 +200,34 @@ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(xtables_nft_multi_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +SCRIPTS = $(sbin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -226,6 +257,7 @@ ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po \ + ./$(DEPDIR)/xtables_nft_multi-nft-chain.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po \ ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po \ @@ -271,33 +303,6 @@ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } man1dir = $(mandir)/man1 man8dir = $(mandir)/man8 NROFF = nroff @@ -396,6 +401,7 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +XT_LOCK_NAME = @XT_LOCK_NAME@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -493,8 +499,8 @@ @ENABLE_NFTABLES_TRUE@ nft-ipv6.c nft-arp.c xtables-monitor.c \ @ENABLE_NFTABLES_TRUE@ nft-cache.c xtables-arp-standalone.c \ @ENABLE_NFTABLES_TRUE@ xtables-arp.c nft-bridge.c nft-cmd.c \ -@ENABLE_NFTABLES_TRUE@ xtables-eb-standalone.c xtables-eb.c \ -@ENABLE_NFTABLES_TRUE@ xtables-eb-translate.c \ +@ENABLE_NFTABLES_TRUE@ nft-chain.c xtables-eb-standalone.c \ +@ENABLE_NFTABLES_TRUE@ xtables-eb.c xtables-eb-translate.c \ @ENABLE_NFTABLES_TRUE@ xtables-translate.c xshared.c @ENABLE_NFTABLES_TRUE@xtables_nft_multi_CFLAGS = ${AM_CFLAGS} \ @ENABLE_NFTABLES_TRUE@ $(am__append_8) -DENABLE_NFTABLES \ @@ -513,8 +519,12 @@ iptables-xml.1 ip6tables.8 ip6tables-restore.8 \ ip6tables-save.8 iptables-extensions.8 iptables-apply.8 \ ip6tables-apply.8 $(am__append_10) -sbin_SCRIPT = iptables-apply +sbin_SCRIPTS = iptables-apply CLEANFILES = iptables.8 xtables-monitor.8 \ + iptables-xml.1 iptables-apply.8 \ + iptables-extensions.8 iptables-extensions.8.tmpl \ + iptables-restore.8 iptables-save.8 \ + iptables-restore-translate.8 ip6tables-restore-translate.8 \ iptables-translate.8 ip6tables-translate.8 vx_bin_links = iptables-xml @@ -644,6 +654,41 @@ xtables-nft-multi$(EXEEXT): $(xtables_nft_multi_OBJECTS) $(xtables_nft_multi_DEPENDENCIES) $(EXTRA_xtables_nft_multi_DEPENDENCIES) @rm -f xtables-nft-multi$(EXEEXT) $(AM_V_CCLD)$(xtables_nft_multi_LINK) $(xtables_nft_multi_OBJECTS) $(xtables_nft_multi_LDADD) $(LIBS) +install-sbinSCRIPTS: $(sbin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(sbin_SCRIPTS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_SCRIPTS)'; test -n "$(sbindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(sbindir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -664,6 +709,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-arp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-cache.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-chain.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po@am__quote@ # am--include-marker @@ -1074,6 +1120,20 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -c -o xtables_nft_multi-nft-cmd.obj `if test -f 'nft-cmd.c'; then $(CYGPATH_W) 'nft-cmd.c'; else $(CYGPATH_W) '$(srcdir)/nft-cmd.c'; fi` +xtables_nft_multi-nft-chain.o: nft-chain.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -MT xtables_nft_multi-nft-chain.o -MD -MP -MF $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo -c -o xtables_nft_multi-nft-chain.o `test -f 'nft-chain.c' || echo '$(srcdir)/'`nft-chain.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo $(DEPDIR)/xtables_nft_multi-nft-chain.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nft-chain.c' object='xtables_nft_multi-nft-chain.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -c -o xtables_nft_multi-nft-chain.o `test -f 'nft-chain.c' || echo '$(srcdir)/'`nft-chain.c + +xtables_nft_multi-nft-chain.obj: nft-chain.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -MT xtables_nft_multi-nft-chain.obj -MD -MP -MF $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo -c -o xtables_nft_multi-nft-chain.obj `if test -f 'nft-chain.c'; then $(CYGPATH_W) 'nft-chain.c'; else $(CYGPATH_W) '$(srcdir)/nft-chain.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xtables_nft_multi-nft-chain.Tpo $(DEPDIR)/xtables_nft_multi-nft-chain.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nft-chain.c' object='xtables_nft_multi-nft-chain.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -c -o xtables_nft_multi-nft-chain.obj `if test -f 'nft-chain.c'; then $(CYGPATH_W) 'nft-chain.c'; else $(CYGPATH_W) '$(srcdir)/nft-chain.c'; fi` + xtables_nft_multi-xtables-eb-standalone.o: xtables-eb-standalone.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xtables_nft_multi_CFLAGS) $(CFLAGS) -MT xtables_nft_multi-xtables-eb-standalone.o -MD -MP -MF $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Tpo -c -o xtables_nft_multi-xtables-eb-standalone.o `test -f 'xtables-eb-standalone.c' || echo '$(srcdir)/'`xtables-eb-standalone.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Tpo $(DEPDIR)/xtables_nft_multi-xtables-eb-standalone.Po @@ -1345,9 +1405,9 @@ check-am: all-am check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am -all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) +all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(MANS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgconfigdir)"; do \ + for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) @@ -1402,6 +1462,7 @@ -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po + -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-chain.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po @@ -1442,7 +1503,7 @@ install-dvi-am: -install-exec-am: install-sbinPROGRAMS +install-exec-am: install-sbinPROGRAMS install-sbinSCRIPTS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am @@ -1479,6 +1540,7 @@ -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-arp.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-bridge.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cache.Po + -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-chain.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-cmd.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv4.Po -rm -f ./$(DEPDIR)/xtables_nft_multi-nft-ipv6.Po @@ -1514,11 +1576,13 @@ ps-am: uninstall-am: uninstall-man uninstall-pkgconfigDATA \ - uninstall-sbinPROGRAMS - + uninstall-sbinPROGRAMS uninstall-sbinSCRIPTS + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook uninstall-man: uninstall-man1 uninstall-man8 -.MAKE: all check install install-am install-exec-am install-strip +.MAKE: all check install install-am install-exec-am install-strip \ + uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ @@ -1529,13 +1593,14 @@ install-exec-am install-exec-hook install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-man8 install-pdf install-pdf-am install-pkgconfigDATA \ - install-ps install-ps-am install-sbinPROGRAMS install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-man \ - uninstall-man1 uninstall-man8 uninstall-pkgconfigDATA \ - uninstall-sbinPROGRAMS + install-ps install-ps-am install-sbinPROGRAMS \ + install-sbinSCRIPTS install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-hook uninstall-man uninstall-man1 \ + uninstall-man8 uninstall-pkgconfigDATA uninstall-sbinPROGRAMS \ + uninstall-sbinSCRIPTS .PRECIOUS: Makefile @@ -1558,6 +1623,29 @@ for i in ${x_sbin_links}; do ${LN_S} -f xtables-nft-multi "${DESTDIR}${sbindir}/$$i"; done; ${LN_S} -f iptables-apply "${DESTDIR}${sbindir}/ip6tables-apply" +uninstall-hook: + dir=${DESTDIR}${bindir}; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || { \ + test -z "${vx_bin_links}" || ( \ + cd "$$dir" && rm -f ${vx_bin_links} \ + ) \ + } + dir=${DESTDIR}${sbindir}; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || { \ + test -z "${v4_sbin_links}" || ( \ + cd "$$dir" && rm -f ${v4_sbin_links} \ + ); \ + test -z "${v6_sbin_links}" || ( \ + cd "$$dir" && rm -f ${v6_sbin_links} \ + ); \ + test -z "${x_sbin_links}" || ( \ + cd "$$dir" && rm -f ${x_sbin_links} \ + ); \ + ( cd "$$dir" && rm -f ip6tables-apply ); \ + } + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff -Nru iptables-1.8.5/iptables/nft-arp.c iptables-1.8.7/iptables/nft-arp.c --- iptables-1.8.5/iptables/nft-arp.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-arp.c 2021-01-15 22:03:39.000000000 +0000 @@ -134,34 +134,34 @@ int ret = 0; if (fw->arp.iniface[0] != '\0') { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_IN); + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_IN); add_iniface(r, fw->arp.iniface, op); } if (fw->arp.outiface[0] != '\0') { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_VIA_OUT); + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_VIA_OUT); add_outiface(r, fw->arp.outiface, op); } if (fw->arp.arhrd != 0 || - fw->arp.invflags & ARPT_INV_ARPHRD) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHRD); + fw->arp.invflags & IPT_INV_ARPHRD) { + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHRD); add_payload(r, offsetof(struct arphdr, ar_hrd), 2, NFT_PAYLOAD_NETWORK_HEADER); add_cmp_u16(r, fw->arp.arhrd, op); } if (fw->arp.arpro != 0 || - fw->arp.invflags & ARPT_INV_ARPPRO) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPPRO); + fw->arp.invflags & IPT_INV_PROTO) { + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_PROTO); add_payload(r, offsetof(struct arphdr, ar_pro), 2, NFT_PAYLOAD_NETWORK_HEADER); add_cmp_u16(r, fw->arp.arpro, op); } if (fw->arp.arhln != 0 || - fw->arp.invflags & ARPT_INV_ARPHLN) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPHLN); + fw->arp.invflags & IPT_INV_ARPHLN) { + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPHLN); add_proto(r, offsetof(struct arphdr, ar_hln), 1, fw->arp.arhln, op); } @@ -169,16 +169,17 @@ add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, NFT_CMP_EQ); if (fw->arp.arpop != 0 || - fw->arp.invflags & ARPT_INV_ARPOP) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_ARPOP); + fw->arp.invflags & IPT_INV_ARPOP) { + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_ARPOP); add_payload(r, offsetof(struct arphdr, ar_op), 2, NFT_PAYLOAD_NETWORK_HEADER); add_cmp_u16(r, fw->arp.arpop, op); } if (need_devaddr(&fw->arp.src_devaddr)) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR); - add_addr(r, sizeof(struct arphdr), + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCDEVADDR); + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + sizeof(struct arphdr), &fw->arp.src_devaddr.addr, &fw->arp.src_devaddr.mask, fw->arp.arhln, op); @@ -187,17 +188,19 @@ if (fw->arp.src.s_addr != 0 || fw->arp.smsk.s_addr != 0 || - fw->arp.invflags & ARPT_INV_SRCIP) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCIP); - add_addr(r, sizeof(struct arphdr) + fw->arp.arhln, + fw->arp.invflags & IPT_INV_SRCIP) { + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCIP); + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + sizeof(struct arphdr) + fw->arp.arhln, &fw->arp.src.s_addr, &fw->arp.smsk.s_addr, sizeof(struct in_addr), op); } if (need_devaddr(&fw->arp.tgt_devaddr)) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR); - add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr), + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_TGTDEVADDR); + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr), &fw->arp.tgt_devaddr.addr, &fw->arp.tgt_devaddr.mask, fw->arp.arhln, op); @@ -205,9 +208,10 @@ if (fw->arp.tgt.s_addr != 0 || fw->arp.tmsk.s_addr != 0 || - fw->arp.invflags & ARPT_INV_TGTIP) { - op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTIP); - add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln, + fw->arp.invflags & IPT_INV_DSTIP) { + op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_DSTIP); + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + fw->arp.arhln, &fw->arp.tgt.s_addr, &fw->arp.tmsk.s_addr, sizeof(struct in_addr), op); } @@ -236,28 +240,6 @@ return ret; } -static uint16_t ipt_to_arpt_flags(uint8_t invflags) -{ - uint16_t result = 0; - - if (invflags & IPT_INV_VIA_IN) - result |= ARPT_INV_VIA_IN; - - if (invflags & IPT_INV_VIA_OUT) - result |= ARPT_INV_VIA_OUT; - - if (invflags & IPT_INV_SRCIP) - result |= ARPT_INV_SRCIP; - - if (invflags & IPT_INV_DSTIP) - result |= ARPT_INV_TGTIP; - - if (invflags & IPT_INV_PROTO) - result |= ARPT_INV_ARPPRO; - - return result; -} - static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e, void *data) { @@ -269,7 +251,7 @@ fw->arp.outiface, fw->arp.outiface_mask, &flags); - fw->arp.invflags |= ipt_to_arpt_flags(flags); + fw->arp.invflags |= flags; } static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto, @@ -303,7 +285,8 @@ memcpy(info->mask, ctx->bitwise.mask, ETH_ALEN); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - memset(info->mask, 0xff, ETH_ALEN); + memset(info->mask, 0xff, + min(ctx->payload.len, ETH_ALEN)); } return inv; @@ -325,33 +308,33 @@ fw->arp.arhrd = ar_hrd; fw->arp.arhrd_mask = 0xffff; if (inv) - fw->arp.invflags |= ARPT_INV_ARPHRD; + fw->arp.invflags |= IPT_INV_ARPHRD; break; case offsetof(struct arphdr, ar_pro): get_cmp_data(e, &ar_pro, sizeof(ar_pro), &inv); fw->arp.arpro = ar_pro; fw->arp.arpro_mask = 0xffff; if (inv) - fw->arp.invflags |= ARPT_INV_ARPPRO; + fw->arp.invflags |= IPT_INV_PROTO; break; case offsetof(struct arphdr, ar_op): get_cmp_data(e, &ar_op, sizeof(ar_op), &inv); fw->arp.arpop = ar_op; fw->arp.arpop_mask = 0xffff; if (inv) - fw->arp.invflags |= ARPT_INV_ARPOP; + fw->arp.invflags |= IPT_INV_ARPOP; break; case offsetof(struct arphdr, ar_hln): get_cmp_data(e, &ar_hln, sizeof(ar_hln), &inv); fw->arp.arhln = ar_hln; fw->arp.arhln_mask = 0xff; if (inv) - fw->arp.invflags |= ARPT_INV_ARPOP; + fw->arp.invflags |= IPT_INV_ARPOP; break; default: if (ctx->payload.offset == sizeof(struct arphdr)) { if (nft_arp_parse_devaddr(ctx, e, &fw->arp.src_devaddr)) - fw->arp.invflags |= ARPT_INV_SRCDEVADDR; + fw->arp.invflags |= IPT_INV_SRCDEVADDR; } else if (ctx->payload.offset == sizeof(struct arphdr) + fw->arp.arhln) { get_cmp_data(e, &addr, sizeof(addr), &inv); @@ -360,16 +343,18 @@ parse_mask_ipv4(ctx, &fw->arp.smsk); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - fw->arp.smsk.s_addr = 0xffffffff; + memset(&fw->arp.smsk, 0xff, + min(ctx->payload.len, + sizeof(struct in_addr))); } if (inv) - fw->arp.invflags |= ARPT_INV_SRCIP; + fw->arp.invflags |= IPT_INV_SRCIP; } else if (ctx->payload.offset == sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr)) { if (nft_arp_parse_devaddr(ctx, e, &fw->arp.tgt_devaddr)) - fw->arp.invflags |= ARPT_INV_TGTDEVADDR; + fw->arp.invflags |= IPT_INV_TGTDEVADDR; } else if (ctx->payload.offset == sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr) + @@ -380,11 +365,13 @@ parse_mask_ipv4(ctx, &fw->arp.tmsk); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - fw->arp.tmsk.s_addr = 0xffffffff; + memset(&fw->arp.tmsk, 0xff, + min(ctx->payload.len, + sizeof(struct in_addr))); } if (inv) - fw->arp.invflags |= ARPT_INV_TGTIP; + fw->arp.invflags |= IPT_INV_DSTIP; } break; } @@ -439,7 +426,7 @@ else strcat(iface, "any"); } if (print_iface) { - printf("%s%s-i %s", sep, fw->arp.invflags & ARPT_INV_VIA_IN ? + printf("%s%s-i %s", sep, fw->arp.invflags & IPT_INV_VIA_IN ? "! " : "", iface); sep = " "; } @@ -457,13 +444,13 @@ else strcat(iface, "any"); } if (print_iface) { - printf("%s%s-o %s", sep, fw->arp.invflags & ARPT_INV_VIA_OUT ? + printf("%s%s-o %s", sep, fw->arp.invflags & IPT_INV_VIA_OUT ? "! " : "", iface); sep = " "; } if (fw->arp.smsk.s_addr != 0L) { - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCIP + printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCIP ? "! " : ""); if (format & FMT_NUMERIC) sprintf(buf, "%s", addr_to_dotted(&(fw->arp.src))); @@ -480,7 +467,7 @@ break; if (i == ARPT_DEV_ADDR_LEN_MAX) goto after_devsrc; - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_SRCDEVADDR + printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCDEVADDR ? "! " : ""); printf("--src-mac "); xtables_print_mac_and_mask((unsigned char *)fw->arp.src_devaddr.addr, @@ -489,7 +476,7 @@ after_devsrc: if (fw->arp.tmsk.s_addr != 0L) { - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTIP + printf("%s%s", sep, fw->arp.invflags & IPT_INV_DSTIP ? "! " : ""); if (format & FMT_NUMERIC) sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt))); @@ -506,7 +493,7 @@ break; if (i == ARPT_DEV_ADDR_LEN_MAX) goto after_devdst; - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_TGTDEVADDR + printf("%s%s", sep, fw->arp.invflags & IPT_INV_TGTDEVADDR ? "! " : ""); printf("--dst-mac "); xtables_print_mac_and_mask((unsigned char *)fw->arp.tgt_devaddr.addr, @@ -516,7 +503,7 @@ after_devdst: if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6) { - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHLN + printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHLN ? "! " : ""); printf("--h-length %d", fw->arp.arhln); if (fw->arp.arhln_mask != 255) @@ -527,7 +514,7 @@ if (fw->arp.arpop_mask != 0) { int tmp = ntohs(fw->arp.arpop); - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPOP + printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPOP ? "! " : ""); if (tmp <= NUMOPCODES && !(format & FMT_NUMERIC)) printf("--opcode %s", arp_opcodes[tmp-1]); @@ -542,7 +529,7 @@ if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) { uint16_t tmp = ntohs(fw->arp.arhrd); - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPHRD + printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHRD ? "! " : ""); if (tmp == 1 && !(format & FMT_NUMERIC)) printf("--h-type %s", "Ethernet"); @@ -556,7 +543,7 @@ if (fw->arp.arpro_mask != 0) { int tmp = ntohs(fw->arp.arpro); - printf("%s%s", sep, fw->arp.invflags & ARPT_INV_ARPPRO + printf("%s%s", sep, fw->arp.invflags & IPT_INV_PROTO ? "! " : ""); if (tmp == 0x0800 && !(format & FMT_NUMERIC)) printf("--proto-type %s", "IPv4"); diff -Nru iptables-1.8.5/iptables/nft-arp.h iptables-1.8.7/iptables/nft-arp.h --- iptables-1.8.5/iptables/nft-arp.h 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-arp.h 2021-01-15 22:03:39.000000000 +0000 @@ -4,4 +4,11 @@ extern char *arp_opcodes[]; #define NUMOPCODES 9 +/* define invflags which won't collide with IPT ones */ +#define IPT_INV_SRCDEVADDR 0x0080 +#define IPT_INV_TGTDEVADDR 0x0100 +#define IPT_INV_ARPHLN 0x0200 +#define IPT_INV_ARPOP 0x0400 +#define IPT_INV_ARPHRD 0x0800 + #endif diff -Nru iptables-1.8.5/iptables/nft-bridge.c iptables-1.8.7/iptables/nft-bridge.c --- iptables-1.8.5/iptables/nft-bridge.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-bridge.c 2021-01-15 22:03:39.000000000 +0000 @@ -58,44 +58,11 @@ } } -static void ebt_print_mac(const unsigned char *mac) -{ - int j; - - for (j = 0; j < ETH_ALEN; j++) - printf("%02x%s", mac[j], (j==ETH_ALEN-1) ? "" : ":"); -} - -static bool mac_all_ones(const unsigned char *mac) -{ - static const char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - return memcmp(mac, hlpmsk, sizeof(hlpmsk)) == 0; -} - /* Put the mac address into 6 (ETH_ALEN) bytes returns 0 on success. */ static void ebt_print_mac_and_mask(const unsigned char *mac, const unsigned char *mask) { - - if (!memcmp(mac, eb_mac_type_unicast, 6) && - !memcmp(mask, eb_msk_type_unicast, 6)) - printf("Unicast"); - else if (!memcmp(mac, eb_mac_type_multicast, 6) && - !memcmp(mask, eb_msk_type_multicast, 6)) - printf("Multicast"); - else if (!memcmp(mac, eb_mac_type_broadcast, 6) && - !memcmp(mask, eb_msk_type_broadcast, 6)) - printf("Broadcast"); - else if (!memcmp(mac, eb_mac_type_bridge_group, 6) && - !memcmp(mask, eb_msk_type_bridge_group, 6)) - printf("BGA"); - else { - ebt_print_mac(mac); - if (!mac_all_ones(mask)) { - printf("/"); - ebt_print_mac(mask); - } - } + if (xtables_print_well_known_mac_and_mask(mac, mask)) + xtables_print_mac_and_mask(mac, mask); } static void add_logical_iniface(struct nftnl_rule *r, char *iface, uint32_t op) @@ -159,20 +126,16 @@ if (fw->bitmask & EBT_ISOURCE) { op = nft_invflags2cmp(fw->invflags, EBT_ISOURCE); - add_payload(r, offsetof(struct ethhdr, h_source), 6, - NFT_PAYLOAD_LL_HEADER); - if (!mac_all_ones(fw->sourcemsk)) - add_bitwise(r, fw->sourcemsk, 6); - add_cmp_ptr(r, op, fw->sourcemac, 6); + add_addr(r, NFT_PAYLOAD_LL_HEADER, + offsetof(struct ethhdr, h_source), + fw->sourcemac, fw->sourcemsk, ETH_ALEN, op); } if (fw->bitmask & EBT_IDEST) { op = nft_invflags2cmp(fw->invflags, EBT_IDEST); - add_payload(r, offsetof(struct ethhdr, h_dest), 6, - NFT_PAYLOAD_LL_HEADER); - if (!mac_all_ones(fw->destmsk)) - add_bitwise(r, fw->destmsk, 6); - add_cmp_ptr(r, op, fw->destmac, 6); + add_addr(r, NFT_PAYLOAD_LL_HEADER, + offsetof(struct ethhdr, h_dest), + fw->destmac, fw->destmsk, ETH_ALEN, op); } if ((fw->bitmask & EBT_NOPROTO) == 0) { @@ -258,7 +221,8 @@ memcpy(fw->destmsk, ctx->bitwise.mask, ETH_ALEN); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - memset(&fw->destmsk, 0xff, ETH_ALEN); + memset(&fw->destmsk, 0xff, + min(ctx->payload.len, ETH_ALEN)); } fw->bitmask |= EBT_IDEST; break; @@ -272,7 +236,8 @@ memcpy(fw->sourcemsk, ctx->bitwise.mask, ETH_ALEN); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - memset(&fw->sourcemsk, 0xff, ETH_ALEN); + memset(&fw->sourcemsk, 0xff, + min(ctx->payload.len, ETH_ALEN)); } fw->bitmask |= EBT_ISOURCE; break; diff -Nru iptables-1.8.5/iptables/nft.c iptables-1.8.7/iptables/nft.c --- iptables-1.8.5/iptables/nft.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft.c 2021-01-15 22:03:39.000000000 +0000 @@ -265,7 +265,6 @@ struct list_head head; enum obj_update_type type:8; uint8_t skip:1; - uint8_t implicit:1; unsigned int seq; union { struct nftnl_table *table; @@ -350,7 +349,6 @@ case NFT_COMPAT_RULE_SAVE: case NFT_COMPAT_RULE_ZERO: case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE: - case NFT_COMPAT_TABLE_NEW: assert(0); break; } @@ -389,10 +387,11 @@ return batch_add(h, type, s); } -static int batch_chain_add(struct nft_handle *h, enum obj_update_type type, +static struct obj_update * +batch_chain_add(struct nft_handle *h, enum obj_update_type type, struct nftnl_chain *c) { - return batch_add(h, type, c) ? 0 : -1; + return batch_add(h, type, c); } static struct obj_update * @@ -645,19 +644,13 @@ }, }; -static bool nft_table_initialized(const struct nft_handle *h, - enum nft_table_type type) -{ - return h->cache->table[type].initialized; -} - static int nft_table_builtin_add(struct nft_handle *h, const struct builtin_table *_t) { struct nftnl_table *t; int ret; - if (nft_table_initialized(h, _t->type)) + if (h->cache->table[_t->type].exists) return 0; t = nftnl_table_alloc(); @@ -685,7 +678,9 @@ nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain->name); nftnl_chain_set_u32(c, NFTNL_CHAIN_HOOKNUM, chain->hook); nftnl_chain_set_u32(c, NFTNL_CHAIN_PRIO, chain->prio); - nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy); + if (policy >= 0) + nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, policy); + nftnl_chain_set_str(c, NFTNL_CHAIN_TYPE, chain->type); return c; @@ -693,7 +688,8 @@ static void nft_chain_builtin_add(struct nft_handle *h, const struct builtin_table *table, - const struct builtin_chain *chain) + const struct builtin_chain *chain, + bool fake) { struct nftnl_chain *c; @@ -701,8 +697,9 @@ if (c == NULL) return; - batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c); - nftnl_chain_list_add_tail(c, h->cache->table[table->type].chains); + if (!fake) + batch_chain_add(h, NFT_COMPAT_CHAIN_ADD, c); + nft_cache_add_chain(h, table, c); } /* find if built-in table already exists */ @@ -746,49 +743,64 @@ static void nft_chain_builtin_init(struct nft_handle *h, const struct builtin_table *table) { - struct nftnl_chain_list *list; - struct nftnl_chain *c; int i; /* Initialize built-in chains if they don't exist yet */ for (i=0; i < NF_INET_NUMHOOKS && table->chains[i].name != NULL; i++) { - list = nft_chain_list_get(h, table->name, - table->chains[i].name); - if (!list) + if (nft_chain_find(h, table->name, table->chains[i].name)) continue; - c = nftnl_chain_list_lookup_byname(list, table->chains[i].name); - if (c != NULL) - continue; - - nft_chain_builtin_add(h, table, &table->chains[i]); + nft_chain_builtin_add(h, table, &table->chains[i], false); } } -static int nft_xt_builtin_init(struct nft_handle *h, const char *table) +static const struct builtin_table * +nft_xt_builtin_table_init(struct nft_handle *h, const char *table) { const struct builtin_table *t; if (!h->cache_init) - return 0; + return NULL; t = nft_table_builtin_find(h, table); if (t == NULL) - return -1; + return NULL; + + if (nft_table_builtin_add(h, t) < 0) + return NULL; + + return t; +} + +static int nft_xt_builtin_init(struct nft_handle *h, const char *table, + const char *chain) +{ + const struct builtin_table *t; + const struct builtin_chain *c; - if (nft_table_initialized(h, t->type)) + if (!h->cache_init) return 0; - if (nft_table_builtin_add(h, t) < 0) + t = nft_xt_builtin_table_init(h, table); + if (!t) return -1; if (h->cache_req.level < NFT_CL_CHAINS) return 0; - nft_chain_builtin_init(h, t); + if (!chain) { + nft_chain_builtin_init(h, t); + return 0; + } + + c = nft_chain_builtin_find(t, chain); + if (!c) + return -1; - h->cache->table[t->type].initialized = true; + if (h->cache->table[t->type].base_chains[c->hook]) + return 0; + nft_chain_builtin_add(h, t, c, false); return 0; } @@ -800,6 +812,40 @@ return nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM) != NULL; } +static int __nft_xt_fake_builtin_chains(struct nft_handle *h, + const char *table, void *data) +{ + const char *chain = data ? *(const char **)data : NULL; + const struct builtin_table *t; + struct nft_chain **bcp; + int i; + + t = nft_table_builtin_find(h, table); + if (!t) + return -1; + + bcp = h->cache->table[t->type].base_chains; + for (i = 0; i < NF_INET_NUMHOOKS && t->chains[i].name; i++) { + if (bcp[t->chains[i].hook]) + continue; + + if (chain && strcmp(chain, t->chains[i].name)) + continue; + + nft_chain_builtin_add(h, t, &t->chains[i], true); + } + return 0; +} + +int nft_xt_fake_builtin_chains(struct nft_handle *h, + const char *table, const char *chain) +{ + if (table) + return __nft_xt_fake_builtin_chains(h, table, &chain); + + return nft_for_each_table(h, __nft_xt_fake_builtin_chains, &chain); +} + int nft_restart(struct nft_handle *h) { mnl_socket_close(h->nl); @@ -892,7 +938,7 @@ } /* if this built-in table does not exists, create it */ - nft_table_builtin_add(h, _t); + nft_xt_builtin_init(h, table, chain); _c = nft_chain_builtin_find(_t, chain); if (_c != NULL) { @@ -920,7 +966,6 @@ const struct xt_counters *counters) { struct nftnl_chain *c = NULL; - int ret; nft_fn = nft_chain_set; @@ -928,16 +973,19 @@ c = nft_chain_new(h, table, chain, NF_DROP, counters); else if (strcmp(policy, "ACCEPT") == 0) c = nft_chain_new(h, table, chain, NF_ACCEPT, counters); + else if (strcmp(policy, "-") == 0) + c = nft_chain_new(h, table, chain, -1, counters); else errno = EINVAL; if (c == NULL) return 0; - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c); + if (!batch_chain_add(h, NFT_COMPAT_CHAIN_UPDATE, c)) + return 0; /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; + return 1; } static int __add_match(struct nftnl_expr *e, struct xt_entry_match *m) @@ -1400,17 +1448,14 @@ return NULL; } -static struct nftnl_chain * -nft_chain_find(struct nft_handle *h, const char *table, const char *chain); - int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose) { - struct nftnl_chain *c; + struct nft_chain *c; int type; - nft_xt_builtin_init(h, table); + nft_xt_builtin_init(h, table, chain); nft_fn = nft_rule_append; @@ -1437,7 +1482,7 @@ errno = ENOENT; return 0; } - nftnl_chain_rule_add_tail(r, c); + nftnl_chain_rule_add_tail(r, c->nftnl); } return 1; @@ -1559,61 +1604,44 @@ [NF_ACCEPT] = "ACCEPT", }; -int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list) +int nft_chain_save(struct nft_chain *nc, void *data) { - struct nft_family_ops *ops = h->ops; - struct nftnl_chain_list_iter *iter; - struct nftnl_chain *c; - - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) - return 0; - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { - const char *policy = NULL; - - if (nft_chain_builtin(c)) { - uint32_t pol = NF_ACCEPT; - - if (nftnl_chain_get(c, NFTNL_CHAIN_POLICY)) - pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); - policy = policy_name[pol]; - } else if (h->family == NFPROTO_BRIDGE) { - if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) { - uint32_t pol; - - pol = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); - policy = policy_name[pol]; - } else { - policy = "RETURN"; - } - } - - if (ops->save_chain) - ops->save_chain(c, policy); + struct nftnl_chain *c = nc->nftnl; + struct nft_handle *h = data; + const char *policy = NULL; - c = nftnl_chain_list_iter_next(iter); + if (nftnl_chain_is_set(c, NFTNL_CHAIN_POLICY)) { + policy = policy_name[nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY)]; + } else if (nft_chain_builtin(c)) { + policy = "ACCEPT"; + } else if (h->family == NFPROTO_BRIDGE) { + policy = "RETURN"; } - nftnl_chain_list_iter_destroy(iter); + if (h->ops->save_chain) + h->ops->save_chain(c, policy); - return 1; + return 0; } -static int nft_chain_save_rules(struct nft_handle *h, - struct nftnl_chain *c, unsigned int format) +struct nft_rule_save_data { + struct nft_handle *h; + unsigned int format; +}; + +static int nft_rule_save_cb(struct nft_chain *c, void *data) { + struct nft_rule_save_data *d = data; struct nftnl_rule_iter *iter; struct nftnl_rule *r; - iter = nftnl_rule_iter_create(c); + iter = nftnl_rule_iter_create(c->nftnl); if (iter == NULL) return 1; r = nftnl_rule_iter_next(iter); while (r != NULL) { - nft_rule_print_save(h, r, NFT_RULE_APPEND, format); + nft_rule_print_save(d->h, r, NFT_RULE_APPEND, d->format); r = nftnl_rule_iter_next(iter); } @@ -1623,29 +1651,13 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format) { - struct nftnl_chain_list_iter *iter; - struct nftnl_chain_list *list; - struct nftnl_chain *c; - int ret = 0; - - list = nft_chain_list_get(h, table, NULL); - if (!list) - return 0; - - iter = nftnl_chain_list_iter_create(list); - if (!iter) - return 0; - - c = nftnl_chain_list_iter_next(iter); - while (c) { - ret = nft_chain_save_rules(h, c, format); - if (ret != 0) - break; - - c = nftnl_chain_list_iter_next(iter); - } + struct nft_rule_save_data d = { + .h = h, + .format = format, + }; + int ret; - nftnl_chain_list_iter_destroy(iter); + ret = nft_chain_foreach(h, table, nft_rule_save_cb, &d); /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; @@ -1667,7 +1679,7 @@ static void __nft_rule_flush(struct nft_handle *h, const char *table, - const char *chain, bool verbose, bool implicit) + const char *chain, bool verbose, bool skip) { struct obj_update *obj; struct nftnl_rule *r; @@ -1689,31 +1701,46 @@ return; } - obj->implicit = implicit; + obj->skip = skip; +} + +struct nft_rule_flush_data { + struct nft_handle *h; + const char *table; + bool verbose; +}; + +static int nft_rule_flush_cb(struct nft_chain *c, void *data) +{ + const char *chain = nftnl_chain_get_str(c->nftnl, NFTNL_CHAIN_NAME); + struct nft_rule_flush_data *d = data; + + batch_chain_flush(d->h, d->table, chain); + __nft_rule_flush(d->h, d->table, chain, d->verbose, false); + flush_rule_cache(d->h, d->table, c); + return 0; } int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, bool verbose) { - struct nftnl_chain_list_iter *iter; - struct nftnl_chain_list *list; - struct nftnl_chain *c = NULL; + struct nft_rule_flush_data d = { + .h = h, + .table = table, + .verbose = verbose, + }; + struct nft_chain *c = NULL; int ret = 0; - nft_xt_builtin_init(h, table); - nft_fn = nft_rule_flush; - if (chain || verbose) { - list = nft_chain_list_get(h, table, chain); - if (list == NULL) { - ret = 1; - goto err; - } - } + if (chain || verbose) + nft_xt_builtin_init(h, table, chain); + else if (!nft_table_find(h, table)) + return 1; if (chain) { - c = nftnl_chain_list_lookup_byname(list, chain); + c = nft_chain_find(h, table, chain); if (!c) { errno = ENOENT; return 0; @@ -1727,36 +1754,20 @@ return 1; } - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) { - ret = 1; - goto err; - } - - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { - chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); + ret = nft_chain_foreach(h, table, nft_rule_flush_cb, &d); - batch_chain_flush(h, table, chain); - __nft_rule_flush(h, table, chain, verbose, false); - flush_rule_cache(h, table, c); - c = nftnl_chain_list_iter_next(iter); - } - nftnl_chain_list_iter_destroy(iter); -err: /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; } int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table) { - struct nftnl_chain_list *list; + const struct builtin_table *t; struct nftnl_chain *c; - int ret; nft_fn = nft_chain_user_add; - nft_xt_builtin_init(h, table); + t = nft_xt_builtin_table_init(h, table); if (nft_chain_exists(h, table, chain)) { errno = EEXIST; @@ -1772,31 +1783,27 @@ if (h->family == NFPROTO_BRIDGE) nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT); - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); + if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c)) + return 0; - list = nft_chain_list_get(h, table, chain); - if (list) - nftnl_chain_list_add(c, list); + nft_cache_add_chain(h, t, c); /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; + return 1; } int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table) { - struct nftnl_chain_list *list; + const struct builtin_table *t; + struct obj_update *obj; struct nftnl_chain *c; + struct nft_chain *nc; bool created = false; - int ret; - c = nft_chain_find(h, table, chain); - if (c) { - /* Apparently -n still flushes existing user defined - * chains that are redefined. - */ - if (h->noflush) - __nft_rule_flush(h, table, chain, false, true); - } else { + t = nft_xt_builtin_table_init(h, table); + + nc = nft_chain_find(h, table, chain); + if (!nc) { c = nftnl_chain_alloc(); if (!c) return 0; @@ -1804,22 +1811,29 @@ nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table); nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain); created = true; - } - if (h->family == NFPROTO_BRIDGE) - nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT); + nft_cache_add_chain(h, t, c); + } else { + c = nc->nftnl; - if (!created) - return 1; + /* If the chain should vanish meanwhile, kernel genid changes + * and the transaction is refreshed enabling the chain add + * object. With the handle still set, kernel interprets it as a + * chain replace job and errors since it is not found anymore. + */ + nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); + } - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); + __nft_rule_flush(h, table, chain, false, created); + + obj = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); + if (!obj) + return 0; - list = nft_chain_list_get(h, table, chain); - if (list) - nftnl_chain_list_add(c, list); + obj->skip = !created; /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; + return 1; } /* From linux/netlink.h */ @@ -1833,11 +1847,11 @@ int builtin_err; }; -static int __nft_chain_user_del(struct nftnl_chain *c, void *data) +static int __nft_chain_user_del(struct nft_chain *nc, void *data) { struct chain_user_del_data *d = data; + struct nftnl_chain *c = nc->nftnl; struct nft_handle *h = d->handle; - int ret; /* don't delete built-in chain */ if (nft_chain_builtin(c)) @@ -1847,13 +1861,17 @@ fprintf(stdout, "Deleting chain `%s'\n", nftnl_chain_get_str(c, NFTNL_CHAIN_NAME)); + /* XXX This triggers a fast lookup from the kernel. */ nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c); - if (ret) + if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_DEL, c)) return -1; - nftnl_chain_list_del(c); + /* nftnl_chain is freed when deleting the batch object */ + nc->nftnl = NULL; + + nft_chain_list_del(nc); + nft_chain_free(nc); return 0; } @@ -1864,18 +1882,13 @@ .handle = h, .verbose = verbose, }; - struct nftnl_chain_list *list; - struct nftnl_chain *c; + struct nft_chain *c; int ret = 0; nft_fn = nft_chain_user_del; - list = nft_chain_list_get(h, table, chain); - if (list == NULL) - return 0; - if (chain) { - c = nftnl_chain_list_lookup_byname(list, chain); + c = nft_chain_find(h, table, chain); if (!c) { errno = ENOENT; return 0; @@ -1887,24 +1900,12 @@ goto out; } - ret = nftnl_chain_list_foreach(list, __nft_chain_user_del, &d); + ret = nft_chain_foreach(h, table, __nft_chain_user_del, &d); out: /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; } -static struct nftnl_chain * -nft_chain_find(struct nft_handle *h, const char *table, const char *chain) -{ - struct nftnl_chain_list *list; - - list = nft_chain_list_get(h, table, chain); - if (list == NULL) - return NULL; - - return nftnl_chain_list_lookup_byname(list, chain); -} - bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain) { @@ -1924,8 +1925,8 @@ const char *table, const char *newname) { struct nftnl_chain *c; + struct nft_chain *nc; uint64_t handle; - int ret; nft_fn = nft_chain_user_rename; @@ -1934,18 +1935,13 @@ return 0; } - nft_xt_builtin_init(h, table); - - /* Config load changed errno. Ensure genuine info for our callers. */ - errno = 0; - /* Find the old chain to be renamed */ - c = nft_chain_find(h, table, chain); - if (c == NULL) { + nc = nft_chain_find(h, table, chain); + if (nc == NULL) { errno = ENOENT; return 0; } - handle = nftnl_chain_get_u64(c, NFTNL_CHAIN_HANDLE); + handle = nftnl_chain_get_u64(nc->nftnl, NFTNL_CHAIN_HANDLE); /* Now prepare the new name for the chain */ c = nftnl_chain_alloc(); @@ -1956,73 +1952,37 @@ nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, newname); nftnl_chain_set_u64(c, NFTNL_CHAIN_HANDLE, handle); - ret = batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c); + if (!batch_chain_add(h, NFT_COMPAT_CHAIN_RENAME, c)) + return 0; /* the core expects 1 for success and 0 for error */ - return ret == 0 ? 1 : 0; + return 1; } bool nft_table_find(struct nft_handle *h, const char *tablename) { - struct nftnl_table_list_iter *iter; - struct nftnl_table_list *list; - struct nftnl_table *t; - bool ret = false; - - list = nftnl_table_list_get(h); - if (list == NULL) - goto err; - - iter = nftnl_table_list_iter_create(list); - if (iter == NULL) - goto err; - - t = nftnl_table_list_iter_next(iter); - while (t != NULL) { - const char *this_tablename = - nftnl_table_get(t, NFTNL_TABLE_NAME); - - if (strcmp(tablename, this_tablename) == 0) { - ret = true; - break; - } - - t = nftnl_table_list_iter_next(iter); - } - - nftnl_table_list_iter_destroy(iter); + const struct builtin_table *t; -err: - return ret; + t = nft_table_builtin_find(h, tablename); + return t ? h->cache->table[t->type].exists : false; } int nft_for_each_table(struct nft_handle *h, int (*func)(struct nft_handle *h, const char *tablename, void *data), void *data) { - struct nftnl_table_list *list; - struct nftnl_table_list_iter *iter; - struct nftnl_table *t; - - list = nftnl_table_list_get(h); - if (list == NULL) - return -1; - - iter = nftnl_table_list_iter_create(list); - if (iter == NULL) - return -1; + int i; - t = nftnl_table_list_iter_next(iter); - while (t != NULL) { - const char *tablename = - nftnl_table_get(t, NFTNL_TABLE_NAME); + for (i = 0; i < NFT_TABLE_MAX; i++) { + if (h->tables[i].name == NULL) + continue; - func(h, tablename, data); + if (!h->cache->table[h->tables[i].type].exists) + continue; - t = nftnl_table_list_iter_next(iter); + func(h, h->tables[i].name, data); } - nftnl_table_list_iter_destroy(iter); return 0; } @@ -2049,7 +2009,7 @@ _t = nft_table_builtin_find(h, table); assert(_t); - h->cache->table[_t->type].initialized = false; + h->cache->table[_t->type].exists = false; flush_chain_cache(h, table); @@ -2058,52 +2018,21 @@ int nft_table_flush(struct nft_handle *h, const char *table) { - struct nftnl_table_list_iter *iter; - struct nftnl_table_list *list; - struct nftnl_table *t; - bool exists = false; + const struct builtin_table *t; int ret = 0; nft_fn = nft_table_flush; - list = nftnl_table_list_get(h); - if (list == NULL) { - ret = -1; - goto err_out; - } - - iter = nftnl_table_list_iter_create(list); - if (iter == NULL) { - ret = -1; - goto err_table_list; - } - - t = nftnl_table_list_iter_next(iter); - while (t != NULL) { - const char *table_name = - nftnl_table_get_str(t, NFTNL_TABLE_NAME); + t = nft_table_builtin_find(h, table); + if (!t) + return 0; - if (strcmp(table_name, table) == 0) { - exists = true; - break; - } + ret = __nft_table_flush(h, table, h->cache->table[t->type].exists); - t = nftnl_table_list_iter_next(iter); - } - - ret = __nft_table_flush(h, table, exists); - nftnl_table_list_iter_destroy(iter); -err_table_list: -err_out: /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; } -void nft_table_new(struct nft_handle *h, const char *table) -{ - nft_xt_builtin_init(h, table); -} - static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r) { struct obj_update *obj; @@ -2161,9 +2090,10 @@ } static struct nftnl_rule * -nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, +nft_rule_find(struct nft_handle *h, struct nft_chain *nc, struct nftnl_rule *rule, int rulenum) { + struct nftnl_chain *c = nc->nftnl; struct nftnl_rule *r; struct nftnl_rule_iter *iter; bool found = false; @@ -2192,8 +2122,8 @@ int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *rule, bool verbose) { - struct nftnl_chain *c; struct nftnl_rule *r; + struct nft_chain *c; nft_fn = nft_rule_check; @@ -2218,8 +2148,8 @@ const char *table, struct nftnl_rule *rule, bool verbose) { int ret = 0; - struct nftnl_chain *c; struct nftnl_rule *r; + struct nft_chain *c; nft_fn = nft_rule_delete; @@ -2279,9 +2209,9 @@ bool verbose) { struct nftnl_rule *r = NULL; - struct nftnl_chain *c; + struct nft_chain *c; - nft_xt_builtin_init(h, table); + nft_xt_builtin_init(h, table, chain); nft_fn = nft_rule_insert; @@ -2314,7 +2244,7 @@ if (r) nftnl_chain_rule_insert_at(new_rule, r); else - nftnl_chain_rule_add(new_rule, c); + nftnl_chain_rule_add(new_rule, c->nftnl); return 1; err: @@ -2325,8 +2255,8 @@ const char *table, int rulenum, bool verbose) { int ret = 0; - struct nftnl_chain *c; struct nftnl_rule *r; + struct nft_chain *c; nft_fn = nft_rule_delete_num; @@ -2353,8 +2283,8 @@ int rulenum, bool verbose) { int ret = 0; - struct nftnl_chain *c; struct nftnl_rule *r; + struct nft_chain *c; nft_fn = nft_rule_replace; @@ -2433,8 +2363,9 @@ } static void __nft_print_header(struct nft_handle *h, - struct nftnl_chain *c, unsigned int format) + struct nft_chain *nc, unsigned int format) { + struct nftnl_chain *c = nc->nftnl; const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); bool basechain = !!nftnl_chain_get(c, NFTNL_CHAIN_HOOKNUM); uint32_t refs = nftnl_chain_get_u32(c, NFTNL_CHAIN_USE); @@ -2452,55 +2383,64 @@ &ctrs, basechain, refs - entries, entries); } +struct nft_rule_list_cb_data { + struct nft_handle *h; + unsigned int format; + int rulenum; + bool found; + bool save_fmt; + void (*cb)(struct nft_handle *h, struct nftnl_rule *r, + unsigned int num, unsigned int format); +}; + +static int nft_rule_list_cb(struct nft_chain *c, void *data) +{ + struct nft_rule_list_cb_data *d = data; + + if (!d->save_fmt) { + if (d->found) + printf("\n"); + d->found = true; + + __nft_print_header(d->h, c, d->format); + } + + return __nft_rule_list(d->h, c->nftnl, d->rulenum, d->format, d->cb); +} + int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, int rulenum, unsigned int format) { const struct nft_family_ops *ops = h->ops; - struct nftnl_chain_list *list; - struct nftnl_chain_list_iter *iter; - struct nftnl_chain *c; - bool found = false; + struct nft_rule_list_cb_data d = { + .h = h, + .format = format, + .rulenum = rulenum, + .cb = ops->print_rule, + }; + struct nft_chain *c; - nft_xt_builtin_init(h, table); + nft_xt_fake_builtin_chains(h, table, chain); nft_assert_table_compatible(h, table, chain); - list = nft_chain_list_get(h, table, chain); - if (!list) - return 0; - if (chain) { - c = nftnl_chain_list_lookup_byname(list, chain); + c = nft_chain_find(h, table, chain); if (!c) return 0; - if (!rulenum) { - if (ops->print_table_header) - ops->print_table_header(table); - __nft_print_header(h, c, format); - } - __nft_rule_list(h, c, rulenum, format, ops->print_rule); + if (rulenum) + d.save_fmt = true; /* skip header printing */ + else if (ops->print_table_header) + ops->print_table_header(table); + + nft_rule_list_cb(c, &d); return 1; } - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) - return 0; - if (ops->print_table_header) ops->print_table_header(table); - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { - if (found) - printf("\n"); - - __nft_print_header(h, c, format); - __nft_rule_list(h, c, rulenum, format, ops->print_rule); - - found = true; - c = nftnl_chain_list_iter_next(iter); - } - nftnl_chain_list_iter_destroy(iter); + nft_chain_foreach(h, table, nft_rule_list_cb, &d); return 1; } @@ -2511,8 +2451,44 @@ nft_rule_print_save(h, r, NFT_RULE_APPEND, format); } -static int __nftnl_rule_list_chain_save(struct nftnl_chain *c, void *data) +int nft_chain_foreach(struct nft_handle *h, const char *table, + int (*cb)(struct nft_chain *c, void *data), + void *data) +{ + const struct builtin_table *t; + struct nft_chain_list *list; + struct nft_chain *c, *c_bak; + int i, ret; + + t = nft_table_builtin_find(h, table); + if (!t) + return -1; + + for (i = 0; i < NF_INET_NUMHOOKS; i++) { + c = h->cache->table[t->type].base_chains[i]; + if (!c) + continue; + + ret = cb(c, data); + if (ret < 0) + return ret; + } + + list = h->cache->table[t->type].chains; + if (!list) + return -1; + + list_for_each_entry_safe(c, c_bak, &list->list, head) { + ret = cb(c, data); + if (ret < 0) + return ret; + } + return 0; +} + +static int nft_rule_list_chain_save(struct nft_chain *nc, void *data) { + struct nftnl_chain *c = nc->nftnl; const char *chain_name = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); uint32_t policy = nftnl_chain_get_u32(c, NFTNL_CHAIN_POLICY); int *counters = data; @@ -2533,70 +2509,43 @@ return 0; } -static int -nftnl_rule_list_chain_save(struct nft_handle *h, const char *chain, - struct nftnl_chain_list *list, int counters) -{ - struct nftnl_chain *c; - - if (chain) { - c = nftnl_chain_list_lookup_byname(list, chain); - if (!c) - return 0; - - __nftnl_rule_list_chain_save(c, &counters); - return 1; - } - - nftnl_chain_list_foreach(list, __nftnl_rule_list_chain_save, &counters); - return 1; -} - int nft_rule_list_save(struct nft_handle *h, const char *chain, const char *table, int rulenum, int counters) { - struct nftnl_chain_list *list; - struct nftnl_chain_list_iter *iter; - unsigned int format = 0; - struct nftnl_chain *c; + struct nft_rule_list_cb_data d = { + .h = h, + .rulenum = rulenum, + .save_fmt = true, + .cb = list_save, + }; + struct nft_chain *c; int ret = 0; - nft_xt_builtin_init(h, table); + nft_xt_fake_builtin_chains(h, table, chain); nft_assert_table_compatible(h, table, chain); - list = nft_chain_list_get(h, table, chain); - if (!list) - return 0; - - /* Dump policies and custom chains first */ - if (!rulenum) - nftnl_rule_list_chain_save(h, chain, list, counters); - if (counters < 0) - format = FMT_C_COUNTS; + d.format = FMT_C_COUNTS; else if (counters == 0) - format = FMT_NOCOUNTS; + d.format = FMT_NOCOUNTS; if (chain) { - c = nftnl_chain_list_lookup_byname(list, chain); + c = nft_chain_find(h, table, chain); if (!c) return 0; - return __nft_rule_list(h, c, rulenum, format, list_save); + if (!rulenum) + nft_rule_list_chain_save(c, &counters); + + return nft_rule_list_cb(c, &d); } - /* Now dump out rules in this table */ - iter = nftnl_chain_list_iter_create(list); - if (iter == NULL) - return 0; + /* Dump policies and custom chains first */ + nft_chain_foreach(h, table, nft_rule_list_chain_save, &counters); - c = nftnl_chain_list_iter_next(iter); - while (c != NULL) { - ret = __nft_rule_list(h, c, rulenum, format, list_save); - c = nftnl_chain_list_iter_next(iter); - } - nftnl_chain_list_iter_destroy(iter); - return ret; + /* Now dump out rules in this table */ + ret = nft_chain_foreach(h, table, nft_rule_list_cb, &d); + return ret == 0 ? 1 : 0; } int nft_rule_zero_counters(struct nft_handle *h, const char *chain, @@ -2604,7 +2553,7 @@ { struct iptables_command_state cs = {}; struct nftnl_rule *r, *new_rule; - struct nftnl_chain *c; + struct nft_chain *c; int ret = 0; nft_fn = nft_rule_delete; @@ -2735,7 +2684,6 @@ case NFT_COMPAT_RULE_SAVE: case NFT_COMPAT_RULE_ZERO: case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE: - case NFT_COMPAT_TABLE_NEW: assert(0); break; } @@ -2747,18 +2695,13 @@ static void nft_refresh_transaction(struct nft_handle *h) { const char *tablename, *chainname; - const struct nftnl_chain *c; + const struct nft_chain *c; struct obj_update *n, *tmp; bool exists; h->error.lineno = 0; list_for_each_entry_safe(n, tmp, &h->obj_list, head) { - if (n->implicit) { - batch_obj_del(h, n); - continue; - } - switch (n->type) { case NFT_COMPAT_TABLE_FLUSH: tablename = nftnl_table_get_str(n->table, NFTNL_TABLE_NAME); @@ -2784,14 +2727,22 @@ c = nft_chain_find(h, tablename, chainname); if (c) { - /* -restore -n flushes existing rules from redefined user-chain */ - __nft_rule_flush(h, tablename, - chainname, false, true); n->skip = 1; } else if (!c) { n->skip = 0; } break; + case NFT_COMPAT_RULE_FLUSH: + tablename = nftnl_rule_get_str(n->rule, NFTNL_RULE_TABLE); + if (!tablename) + continue; + + chainname = nftnl_rule_get_str(n->rule, NFTNL_RULE_CHAIN); + if (!chainname) + continue; + + n->skip = !nft_chain_find(h, tablename, chainname); + break; case NFT_COMPAT_TABLE_ADD: case NFT_COMPAT_CHAIN_ADD: case NFT_COMPAT_CHAIN_ZERO: @@ -2803,7 +2754,6 @@ case NFT_COMPAT_RULE_INSERT: case NFT_COMPAT_RULE_REPLACE: case NFT_COMPAT_RULE_DELETE: - case NFT_COMPAT_RULE_FLUSH: case NFT_COMPAT_SET_ADD: case NFT_COMPAT_RULE_LIST: case NFT_COMPAT_RULE_CHECK: @@ -2811,7 +2761,6 @@ case NFT_COMPAT_RULE_SAVE: case NFT_COMPAT_RULE_ZERO: case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE: - case NFT_COMPAT_TABLE_NEW: break; } } @@ -2835,9 +2784,10 @@ h->nft_genid++; list_for_each_entry(n, &h->obj_list, head) { - - if (n->skip) + if (n->skip) { + n->seq = 0; continue; + } n->seq = seq++; switch (n->type) { @@ -2915,7 +2865,6 @@ case NFT_COMPAT_RULE_SAVE: case NFT_COMPAT_RULE_ZERO: case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE: - case NFT_COMPAT_TABLE_NEW: assert(0); } @@ -3043,7 +2992,7 @@ int ebt_set_user_chain_policy(struct nft_handle *h, const char *table, const char *chain, const char *policy) { - struct nftnl_chain *c = nft_chain_find(h, table, chain); + struct nft_chain *c = nft_chain_find(h, table, chain); int pval; if (!c) @@ -3058,14 +3007,15 @@ else return 0; - nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, pval); + nftnl_chain_set_u32(c->nftnl, NFTNL_CHAIN_POLICY, pval); return 1; } static void nft_bridge_commit_prepare(struct nft_handle *h) { const struct builtin_table *t; - struct nftnl_chain_list *list; + struct nft_chain_list *list; + struct nft_chain *c; int i; for (i = 0; i < NFT_TABLE_MAX; i++) { @@ -3078,7 +3028,9 @@ if (!list) continue; - nftnl_chain_list_foreach(list, ebt_add_policy_rule, h); + list_for_each_entry(c, &list->list, head) { + ebt_add_policy_rule(c->nftnl, h); + } } } @@ -3178,12 +3130,8 @@ ret = ebt_set_user_chain_policy(h, cmd->table, cmd->chain, cmd->policy); break; - case NFT_COMPAT_TABLE_NEW: - nft_xt_builtin_init(h, cmd->table); - ret = 1; - break; case NFT_COMPAT_SET_ADD: - nft_xt_builtin_init(h, cmd->table); + nft_xt_builtin_table_init(h, cmd->table); batch_set_add(h, NFT_COMPAT_SET_ADD, cmd->obj.set); ret = 1; break; @@ -3390,8 +3338,9 @@ bool verbose; }; -static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data) +static int __nft_chain_zero_counters(struct nft_chain *nc, void *data) { + struct nftnl_chain *c = nc->nftnl; struct chain_zero_data *d = data; struct nft_handle *h = d->handle; struct nftnl_rule_iter *iter; @@ -3399,14 +3348,14 @@ if (d->verbose) fprintf(stdout, "Zeroing chain `%s'\n", - nftnl_chain_get_str(c, NFTNL_CHAIN_NAME)); + nftnl_chain_get_str(c, NFTNL_CHAIN_NAME)); if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) { /* zero base chain counters. */ nftnl_chain_set_u64(c, NFTNL_CHAIN_PACKETS, 0); nftnl_chain_set_u64(c, NFTNL_CHAIN_BYTES, 0); nftnl_chain_unset(c, NFTNL_CHAIN_HANDLE); - if (batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c)) + if (!batch_chain_add(h, NFT_COMPAT_CHAIN_ZERO, c)) return -1; } @@ -3464,20 +3413,15 @@ int nft_chain_zero_counters(struct nft_handle *h, const char *chain, const char *table, bool verbose) { - struct nftnl_chain_list *list; struct chain_zero_data d = { .handle = h, .verbose = verbose, }; - struct nftnl_chain *c; + struct nft_chain *c; int ret = 0; - list = nft_chain_list_get(h, table, chain); - if (list == NULL) - goto err; - if (chain) { - c = nftnl_chain_list_lookup_byname(list, chain); + c = nft_chain_find(h, table, chain); if (!c) { errno = ENOENT; return 0; @@ -3487,7 +3431,7 @@ goto err; } - ret = nftnl_chain_list_foreach(list, __nft_chain_zero_counters, &d); + ret = nft_chain_foreach(h, table, __nft_chain_zero_counters, &d); err: /* the core expects 1 for success and 0 for error */ return ret == 0 ? 1 : 0; @@ -3537,8 +3481,9 @@ return nftnl_expr_foreach(rule, nft_is_expr_compatible, NULL); } -static int nft_is_chain_compatible(struct nftnl_chain *c, void *data) +static int nft_is_chain_compatible(struct nft_chain *nc, void *data) { + struct nftnl_chain *c = nc->nftnl; const struct builtin_table *table; const struct builtin_chain *chain; const char *tname, *cname, *type; @@ -3576,16 +3521,13 @@ bool nft_is_table_compatible(struct nft_handle *h, const char *table, const char *chain) { - struct nftnl_chain_list *clist; - - clist = nft_chain_list_get(h, table, chain); - if (clist == NULL) - return false; + if (chain) { + struct nft_chain *c = nft_chain_find(h, table, chain); - if (nftnl_chain_list_foreach(clist, nft_is_chain_compatible, h)) - return false; + return c && !nft_is_chain_compatible(c, h); + } - return true; + return !nft_chain_foreach(h, table, nft_is_chain_compatible, h); } void nft_assert_table_compatible(struct nft_handle *h, diff -Nru iptables-1.8.5/iptables/nft-cache.c iptables-1.8.7/iptables/nft-cache.c --- iptables-1.8.5/iptables/nft-cache.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-cache.c 2021-01-15 22:03:39.000000000 +0000 @@ -24,6 +24,7 @@ #include "nft.h" #include "nft-cache.h" +#include "nft-chain.h" static void cache_chain_list_insert(struct list_head *list, const char *name) { @@ -109,57 +110,51 @@ static int nftnl_table_list_cb(const struct nlmsghdr *nlh, void *data) { - struct nftnl_table *t; - struct nftnl_table_list *list = data; + struct nftnl_table *nftnl = nftnl_table_alloc(); + const struct builtin_table *t; + struct nft_handle *h = data; + const char *name; - t = nftnl_table_alloc(); - if (t == NULL) - goto err; + if (!nftnl) + return MNL_CB_OK; - if (nftnl_table_nlmsg_parse(nlh, t) < 0) + if (nftnl_table_nlmsg_parse(nlh, nftnl) < 0) goto out; - nftnl_table_list_add_tail(t, list); + name = nftnl_table_get_str(nftnl, NFTNL_TABLE_NAME); + if (!name) + goto out; - return MNL_CB_OK; + t = nft_table_builtin_find(h, name); + if (!t) + goto out; + + h->cache->table[t->type].exists = true; out: - nftnl_table_free(t); -err: + nftnl_table_free(nftnl); return MNL_CB_OK; } static int fetch_table_cache(struct nft_handle *h) { - char buf[16536]; struct nlmsghdr *nlh; - struct nftnl_table_list *list; + char buf[16536]; int i, ret; - if (h->cache->tables) - return 0; - - list = nftnl_table_list_alloc(); - if (list == NULL) - return 0; - nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family, NLM_F_DUMP, h->seq); - ret = mnl_talk(h, nlh, nftnl_table_list_cb, list); + ret = mnl_talk(h, nlh, nftnl_table_list_cb, h); if (ret < 0 && errno == EINTR) assert(nft_restart(h) >= 0); - h->cache->tables = list; - for (i = 0; i < NFT_TABLE_MAX; i++) { enum nft_table_type type = h->tables[i].type; if (!h->tables[i].name) continue; - h->cache->table[type].chains = nftnl_chain_list_alloc(); - if (!h->cache->table[type].chains) - return 0; + h->cache->table[type].chains = nft_chain_list_alloc(); h->cache->table[type].sets = nftnl_set_list_alloc(); if (!h->cache->table[type].sets) @@ -169,6 +164,83 @@ return 1; } +static uint32_t djb_hash(const char *key) +{ + uint32_t i, hash = 5381; + + for (i = 0; i < strlen(key); i++) + hash = ((hash << 5) + hash) + key[i]; + + return hash; +} + +static struct hlist_head *chain_name_hlist(struct nft_handle *h, + const struct builtin_table *t, + const char *chain) +{ + int key = djb_hash(chain) % CHAIN_NAME_HSIZE; + + return &h->cache->table[t->type].chains->names[key]; +} + +struct nft_chain * +nft_chain_find(struct nft_handle *h, const char *table, const char *chain) +{ + const struct builtin_table *t; + struct hlist_node *node; + struct nft_chain *c; + + t = nft_table_builtin_find(h, table); + if (!t) + return NULL; + + hlist_for_each_entry(c, node, chain_name_hlist(h, t, chain), hnode) { + if (!strcmp(nftnl_chain_get_str(c->nftnl, NFTNL_CHAIN_NAME), + chain)) + return c; + } + return NULL; +} + +int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t, + struct nftnl_chain *c) +{ + const char *cname = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); + struct nft_chain *nc = nft_chain_alloc(c); + + if (nftnl_chain_is_set(c, NFTNL_CHAIN_HOOKNUM)) { + uint32_t hooknum = nftnl_chain_get_u32(c, NFTNL_CHAIN_HOOKNUM); + + if (hooknum >= NF_INET_NUMHOOKS) { + nft_chain_free(nc); + return -EINVAL; + } + + if (h->cache->table[t->type].base_chains[hooknum]) { + nft_chain_free(nc); + return -EEXIST; + } + + h->cache->table[t->type].base_chains[hooknum] = nc; + } else { + struct nft_chain_list *clist = h->cache->table[t->type].chains; + struct list_head *pos = &clist->list; + struct nft_chain *cur; + const char *n; + + list_for_each_entry(cur, &clist->list, head) { + n = nftnl_chain_get_str(cur->nftnl, NFTNL_CHAIN_NAME); + if (strcmp(cname, n) <= 0) { + pos = &cur->head; + break; + } + } + list_add_tail(&nc->head, pos); + } + hlist_add_head(&nc->hnode, chain_name_hlist(h, t, cname)); + return 0; +} + struct nftnl_chain_list_cb_data { struct nft_handle *h; const struct builtin_table *t; @@ -178,10 +250,9 @@ { struct nftnl_chain_list_cb_data *d = data; const struct builtin_table *t = d->t; - struct nftnl_chain_list *list; struct nft_handle *h = d->h; - const char *tname, *cname; struct nftnl_chain *c; + const char *tname; c = nftnl_chain_alloc(); if (c == NULL) @@ -200,14 +271,9 @@ goto out; } - list = h->cache->table[t->type].chains; - cname = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); - - if (nftnl_chain_list_lookup_byname(list, cname)) + if (nft_cache_add_chain(h, t, c)) goto out; - nftnl_chain_list_add_tail(c, list); - return MNL_CB_OK; out: nftnl_chain_free(c); @@ -423,8 +489,9 @@ return MNL_CB_OK; } -static int nft_rule_list_update(struct nftnl_chain *c, void *data) +static int nft_rule_list_update(struct nft_chain *nc, void *data) { + struct nftnl_chain *c = nc->nftnl; struct nft_handle *h = data; char buf[16536]; struct nlmsghdr *nlh; @@ -464,21 +531,16 @@ { int i; - if (t) { - struct nftnl_chain_list *list = - h->cache->table[t->type].chains; - - return nftnl_chain_list_foreach(list, nft_rule_list_update, h); - } + if (t) + return nft_chain_foreach(h, t->name, nft_rule_list_update, h); for (i = 0; i < NFT_TABLE_MAX; i++) { - enum nft_table_type type = h->tables[i].type; if (!h->tables[i].name) continue; - if (nftnl_chain_list_foreach(h->cache->table[type].chains, - nft_rule_list_update, h)) + if (nft_chain_foreach(h, h->tables[i].name, + nft_rule_list_update, h)) return -1; } return 0; @@ -511,14 +573,14 @@ if (req->level >= NFT_CL_TABLES) fetch_table_cache(h); if (req->level == NFT_CL_FAKE) - return; + goto genid_check; if (req->level >= NFT_CL_CHAINS) fetch_chain_cache(h, t, chains); if (req->level >= NFT_CL_SETS) fetch_set_cache(h, t, NULL); if (req->level >= NFT_CL_RULES) fetch_rule_cache(h, t); - +genid_check: mnl_genid_get(h, &genid_check); if (h->nft_genid != genid_check) { flush_cache(h, h->cache, NULL); @@ -544,31 +606,25 @@ return 0; } -static int __flush_rule_cache(struct nftnl_chain *c, void *data) +static int __flush_rule_cache(struct nft_chain *c, void *data) { - return nftnl_rule_foreach(c, ____flush_rule_cache, NULL); + return nftnl_rule_foreach(c->nftnl, ____flush_rule_cache, NULL); } int flush_rule_cache(struct nft_handle *h, const char *table, - struct nftnl_chain *c) + struct nft_chain *c) { - const struct builtin_table *t; - if (c) return __flush_rule_cache(c, NULL); - t = nft_table_builtin_find(h, table); - if (!t || !h->cache->table[t->type].chains) - return 0; - - return nftnl_chain_list_foreach(h->cache->table[t->type].chains, - __flush_rule_cache, NULL); + nft_chain_foreach(h, table, __flush_rule_cache, NULL); + return 0; } -static int __flush_chain_cache(struct nftnl_chain *c, void *data) +static int __flush_chain_cache(struct nft_chain *c, void *data) { - nftnl_chain_list_del(c); - nftnl_chain_free(c); + nft_chain_list_del(c); + nft_chain_free(c); return 0; } @@ -581,6 +637,19 @@ return 0; } +static void flush_base_chain_cache(struct nft_chain **base_chains) +{ + int i; + + for (i = 0; i < NF_INET_NUMHOOKS; i++) { + if (!base_chains[i]) + continue; + hlist_del(&base_chains[i]->hnode); + nft_chain_free(base_chains[i]); + base_chains[i] = NULL; + } +} + static int flush_cache(struct nft_handle *h, struct nft_cache *c, const char *tablename) { @@ -591,9 +660,10 @@ table = nft_table_builtin_find(h, tablename); if (!table) return 0; - if (c->table[table->type].chains) - nftnl_chain_list_foreach(c->table[table->type].chains, - __flush_chain_cache, NULL); + + flush_base_chain_cache(c->table[table->type].base_chains); + nft_chain_foreach(h, tablename, __flush_chain_cache, NULL); + if (c->table[table->type].sets) nftnl_set_list_foreach(c->table[table->type].sets, __flush_set_cache, NULL); @@ -604,18 +674,18 @@ if (h->tables[i].name == NULL) continue; + flush_base_chain_cache(c->table[i].base_chains); if (c->table[i].chains) { - nftnl_chain_list_free(c->table[i].chains); + nft_chain_list_free(c->table[i].chains); c->table[i].chains = NULL; } + if (c->table[i].sets) { nftnl_set_list_free(c->table[i].sets); c->table[i].sets = NULL; } - } - if (c->tables) { - nftnl_table_list_free(c->tables); - c->tables = NULL; + + c->table[i].exists = false; } return 1; @@ -689,11 +759,6 @@ } } -struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h) -{ - return h->cache->tables; -} - struct nftnl_set_list * nft_set_list_get(struct nft_handle *h, const char *table, const char *set) { @@ -705,16 +770,3 @@ return h->cache->table[t->type].sets; } - -struct nftnl_chain_list * -nft_chain_list_get(struct nft_handle *h, const char *table, const char *chain) -{ - const struct builtin_table *t; - - t = nft_table_builtin_find(h, table); - if (!t) - return NULL; - - return h->cache->table[t->type].chains; -} - diff -Nru iptables-1.8.5/iptables/nft-cache.h iptables-1.8.7/iptables/nft-cache.h --- iptables-1.8.5/iptables/nft-cache.h 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-cache.h 2021-01-15 22:03:39.000000000 +0000 @@ -2,7 +2,9 @@ #define _NFT_CACHE_H_ struct nft_handle; +struct nft_chain; struct nft_cmd; +struct builtin_table; void nft_cache_level_set(struct nft_handle *h, int level, const struct nft_cmd *cmd); @@ -10,13 +12,15 @@ void nft_release_cache(struct nft_handle *h); void flush_chain_cache(struct nft_handle *h, const char *tablename); int flush_rule_cache(struct nft_handle *h, const char *table, - struct nftnl_chain *c); + struct nft_chain *c); void nft_cache_build(struct nft_handle *h); +int nft_cache_add_chain(struct nft_handle *h, const struct builtin_table *t, + struct nftnl_chain *c); + +struct nft_chain * +nft_chain_find(struct nft_handle *h, const char *table, const char *chain); -struct nftnl_chain_list * -nft_chain_list_get(struct nft_handle *h, const char *table, const char *chain); struct nftnl_set_list * nft_set_list_get(struct nft_handle *h, const char *table, const char *set); -struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h); #endif /* _NFT_CACHE_H_ */ diff -Nru iptables-1.8.5/iptables/nft-chain.c iptables-1.8.7/iptables/nft-chain.c --- iptables-1.8.5/iptables/nft-chain.c 1970-01-01 00:00:00.000000000 +0000 +++ iptables-1.8.7/iptables/nft-chain.c 2021-01-15 22:03:39.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 Red Hat GmbH. Author: Phil Sutter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +#include "nft-chain.h" + +struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl) +{ + struct nft_chain *c = xtables_malloc(sizeof(*c)); + + INIT_LIST_HEAD(&c->head); + c->nftnl = nftnl; + + return c; +} + +void nft_chain_free(struct nft_chain *c) +{ + if (c->nftnl) + nftnl_chain_free(c->nftnl); + free(c); +} + +struct nft_chain_list *nft_chain_list_alloc(void) +{ + struct nft_chain_list *list = xtables_malloc(sizeof(*list)); + int i; + + INIT_LIST_HEAD(&list->list); + for (i = 0; i < CHAIN_NAME_HSIZE; i++) + INIT_HLIST_HEAD(&list->names[i]); + + return list; +} + +void nft_chain_list_del(struct nft_chain *c) +{ + list_del(&c->head); + hlist_del(&c->hnode); +} + +void nft_chain_list_free(struct nft_chain_list *list) +{ + struct nft_chain *c, *c2; + + list_for_each_entry_safe(c, c2, &list->list, head) { + nft_chain_list_del(c); + nft_chain_free(c); + } + free(list); +} diff -Nru iptables-1.8.5/iptables/nft-chain.h iptables-1.8.7/iptables/nft-chain.h --- iptables-1.8.5/iptables/nft-chain.h 1970-01-01 00:00:00.000000000 +0000 +++ iptables-1.8.7/iptables/nft-chain.h 2021-01-15 22:03:39.000000000 +0000 @@ -0,0 +1,29 @@ +#ifndef _NFT_CHAIN_H_ +#define _NFT_CHAIN_H_ + +#include +#include + +struct nft_handle; + +struct nft_chain { + struct list_head head; + struct hlist_node hnode; + struct nftnl_chain *nftnl; +}; + +#define CHAIN_NAME_HSIZE 512 + +struct nft_chain_list { + struct list_head list; + struct hlist_head names[CHAIN_NAME_HSIZE]; +}; + +struct nft_chain *nft_chain_alloc(struct nftnl_chain *nftnl); +void nft_chain_free(struct nft_chain *c); + +struct nft_chain_list *nft_chain_list_alloc(void); +void nft_chain_list_free(struct nft_chain_list *list); +void nft_chain_list_del(struct nft_chain *c); + +#endif /* _NFT_CHAIN_H_ */ diff -Nru iptables-1.8.5/iptables/nft-cmd.c iptables-1.8.7/iptables/nft-cmd.c --- iptables-1.8.5/iptables/nft-cmd.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-cmd.c 2021-01-15 22:03:39.000000000 +0000 @@ -311,10 +311,15 @@ return 1; } -int nft_cmd_table_flush(struct nft_handle *h, const char *table) +int nft_cmd_table_flush(struct nft_handle *h, const char *table, bool verbose) { struct nft_cmd *cmd; + if (verbose) { + return nft_cmd_rule_flush(h, NULL, table, verbose) && + nft_cmd_chain_user_del(h, NULL, table, verbose); + } + cmd = nft_cmd_new(h, NFT_COMPAT_TABLE_FLUSH, table, NULL, NULL, -1, false); if (!cmd) @@ -388,8 +393,3 @@ return 1; } - -void nft_cmd_table_new(struct nft_handle *h, const char *table) -{ - nft_cmd_new(h, NFT_COMPAT_TABLE_NEW, table, NULL, NULL, -1, false); -} diff -Nru iptables-1.8.5/iptables/nft-cmd.h iptables-1.8.7/iptables/nft-cmd.h --- iptables-1.8.5/iptables/nft-cmd.h 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-cmd.h 2021-01-15 22:03:39.000000000 +0000 @@ -65,7 +65,7 @@ int nft_cmd_rule_replace(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose); -int nft_cmd_table_flush(struct nft_handle *h, const char *table); +int nft_cmd_table_flush(struct nft_handle *h, const char *table, bool verbose); int nft_cmd_chain_restore(struct nft_handle *h, const char *chain, const char *table); int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain, diff -Nru iptables-1.8.5/iptables/nft.h iptables-1.8.7/iptables/nft.h --- iptables-1.8.5/iptables/nft.h 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft.h 2021-01-15 22:03:39.000000000 +0000 @@ -4,14 +4,15 @@ #include "xshared.h" #include "nft-shared.h" #include "nft-cache.h" +#include "nft-chain.h" #include "nft-cmd.h" #include enum nft_table_type { - NFT_TABLE_FILTER = 0, - NFT_TABLE_MANGLE, - NFT_TABLE_RAW, + NFT_TABLE_MANGLE = 0, NFT_TABLE_SECURITY, + NFT_TABLE_RAW, + NFT_TABLE_FILTER, NFT_TABLE_NAT, }; #define NFT_TABLE_MAX (NFT_TABLE_NAT + 1) @@ -38,11 +39,11 @@ }; struct nft_cache { - struct nftnl_table_list *tables; struct { - struct nftnl_chain_list *chains; + struct nft_chain *base_chains[NF_INET_NUMHOOKS]; + struct nft_chain_list *chains; struct nftnl_set_list *sets; - bool initialized; + bool exists; } table[NFT_TABLE_MAX]; }; @@ -68,7 +69,6 @@ NFT_COMPAT_RULE_SAVE, NFT_COMPAT_RULE_ZERO, NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE, - NFT_COMPAT_TABLE_NEW, }; struct cache_chain { @@ -135,8 +135,8 @@ bool nft_table_find(struct nft_handle *h, const char *tablename); int nft_table_purge_chains(struct nft_handle *h, const char *table, struct nftnl_chain_list *list); int nft_table_flush(struct nft_handle *h, const char *table); -void nft_table_new(struct nft_handle *h, const char *table); const struct builtin_table *nft_table_builtin_find(struct nft_handle *h, const char *table); +int nft_xt_fake_builtin_chains(struct nft_handle *h, const char *table, const char *chain); /* * Operations with chains. @@ -144,7 +144,7 @@ struct nftnl_chain; int nft_chain_set(struct nft_handle *h, const char *table, const char *chain, const char *policy, const struct xt_counters *counters); -int nft_chain_save(struct nft_handle *h, struct nftnl_chain_list *list); +int nft_chain_save(struct nft_chain *c, void *data); int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *table); int nft_chain_user_del(struct nft_handle *h, const char *chain, const char *table, bool verbose); int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table); @@ -154,6 +154,9 @@ bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain); void nft_bridge_chain_postprocess(struct nft_handle *h, struct nftnl_chain *c); +int nft_chain_foreach(struct nft_handle *h, const char *table, + int (*cb)(struct nft_chain *c, void *data), + void *data); /* diff -Nru iptables-1.8.5/iptables/nft-ipv4.c iptables-1.8.7/iptables/nft-ipv4.c --- iptables-1.8.5/iptables/nft-ipv4.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-ipv4.c 2021-01-15 22:03:39.000000000 +0000 @@ -50,13 +50,15 @@ if (cs->fw.ip.src.s_addr || cs->fw.ip.smsk.s_addr || cs->fw.ip.invflags & IPT_INV_SRCIP) { op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_SRCIP); - add_addr(r, offsetof(struct iphdr, saddr), + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + offsetof(struct iphdr, saddr), &cs->fw.ip.src.s_addr, &cs->fw.ip.smsk.s_addr, sizeof(struct in_addr), op); } if (cs->fw.ip.dst.s_addr || cs->fw.ip.dmsk.s_addr || cs->fw.ip.invflags & IPT_INV_DSTIP) { op = nft_invflags2cmp(cs->fw.ip.invflags, IPT_INV_DSTIP); - add_addr(r, offsetof(struct iphdr, daddr), + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + offsetof(struct iphdr, daddr), &cs->fw.ip.dst.s_addr, &cs->fw.ip.dmsk.s_addr, sizeof(struct in_addr), op); } @@ -199,7 +201,8 @@ parse_mask_ipv4(ctx, &cs->fw.ip.smsk); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - cs->fw.ip.smsk.s_addr = 0xffffffff; + memset(&cs->fw.ip.smsk, 0xff, + min(ctx->payload.len, sizeof(struct in_addr))); } if (inv) @@ -212,7 +215,8 @@ parse_mask_ipv4(ctx, &cs->fw.ip.dmsk); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - cs->fw.ip.dmsk.s_addr = 0xffffffff; + memset(&cs->fw.ip.dmsk, 0xff, + min(ctx->payload.len, sizeof(struct in_addr))); } if (inv) diff -Nru iptables-1.8.5/iptables/nft-ipv6.c iptables-1.8.7/iptables/nft-ipv6.c --- iptables-1.8.5/iptables/nft-ipv6.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-ipv6.c 2021-01-15 22:03:39.000000000 +0000 @@ -51,7 +51,8 @@ !IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.smsk) || (cs->fw6.ipv6.invflags & IPT_INV_SRCIP)) { op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_SRCIP); - add_addr(r, offsetof(struct ip6_hdr, ip6_src), + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + offsetof(struct ip6_hdr, ip6_src), &cs->fw6.ipv6.src, &cs->fw6.ipv6.smsk, sizeof(struct in6_addr), op); } @@ -59,7 +60,8 @@ !IN6_IS_ADDR_UNSPECIFIED(&cs->fw6.ipv6.dmsk) || (cs->fw6.ipv6.invflags & IPT_INV_DSTIP)) { op = nft_invflags2cmp(cs->fw6.ipv6.invflags, IPT_INV_DSTIP); - add_addr(r, offsetof(struct ip6_hdr, ip6_dst), + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + offsetof(struct ip6_hdr, ip6_dst), &cs->fw6.ipv6.dst, &cs->fw6.ipv6.dmsk, sizeof(struct in6_addr), op); } @@ -146,7 +148,8 @@ parse_mask_ipv6(ctx, &cs->fw6.ipv6.smsk); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - memset(&cs->fw6.ipv6.smsk, 0xff, sizeof(struct in6_addr)); + memset(&cs->fw6.ipv6.smsk, 0xff, + min(ctx->payload.len, sizeof(struct in6_addr))); } if (inv) @@ -159,7 +162,8 @@ parse_mask_ipv6(ctx, &cs->fw6.ipv6.dmsk); ctx->flags &= ~NFT_XT_CTX_BITWISE; } else { - memset(&cs->fw6.ipv6.dmsk, 0xff, sizeof(struct in6_addr)); + memset(&cs->fw6.ipv6.dmsk, 0xff, + min(ctx->payload.len, sizeof(struct in6_addr))); } if (inv) diff -Nru iptables-1.8.5/iptables/nft-shared.c iptables-1.8.7/iptables/nft-shared.c --- iptables-1.8.5/iptables/nft-shared.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-shared.c 2021-01-15 22:03:39.000000000 +0000 @@ -20,7 +20,6 @@ #include -#include #include #include @@ -162,20 +161,26 @@ add_cmp_ptr(r, op, iface, iface_len + 1); } -void add_addr(struct nftnl_rule *r, int offset, +void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset, void *data, void *mask, size_t len, uint32_t op) { - const char *m = mask; + const unsigned char *m = mask; + bool bitwise = false; int i; - add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER); - for (i = 0; i < len; i++) { - if (m[i] != 0xff) + if (m[i] != 0xff) { + bitwise = m[i] != 0; break; + } } - if (i != len) + if (!bitwise) + len = i; + + add_payload(r, offset, len, base); + + if (bitwise) add_bitwise(r, mask, len); add_cmp_ptr(r, op, data, len); diff -Nru iptables-1.8.5/iptables/nft-shared.h iptables-1.8.7/iptables/nft-shared.h --- iptables-1.8.5/iptables/nft-shared.h 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/nft-shared.h 2021-01-15 22:03:39.000000000 +0000 @@ -8,6 +8,7 @@ #include #include +#include #include "xshared.h" @@ -121,7 +122,7 @@ void add_cmp_u32(struct nftnl_rule *r, uint32_t val, uint32_t op); void add_iniface(struct nftnl_rule *r, char *iface, uint32_t op); void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op); -void add_addr(struct nftnl_rule *r, int offset, +void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset, void *data, void *mask, size_t len, uint32_t op); void add_proto(struct nftnl_rule *r, int offset, size_t len, uint8_t proto, uint32_t op); @@ -225,7 +226,8 @@ int (*chain_restore)(struct nft_handle *h, const char *chain, const char *table); - int (*table_flush)(struct nft_handle *h, const char *table); + int (*table_flush)(struct nft_handle *h, const char *table, + bool verbose); int (*do_command)(struct nft_handle *h, int argc, char *argv[], char **table, bool restore); @@ -246,4 +248,8 @@ const struct nft_xt_restore_parse *p); void nft_check_xt_legacy(int family, bool is_ipt_save); + +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define max(x, y) ((x) > (y) ? (x) : (y)) + #endif diff -Nru iptables-1.8.5/iptables/tests/shell/run-tests.sh iptables-1.8.7/iptables/tests/shell/run-tests.sh --- iptables-1.8.5/iptables/tests/shell/run-tests.sh 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/run-tests.sh 2021-01-15 22:03:39.000000000 +0000 @@ -4,6 +4,21 @@ TESTDIR="./$(dirname $0)/" RETURNCODE_SEPARATOR="_" +usage() { + cat <&2 exit 1 @@ -50,6 +65,10 @@ VALGRIND=y shift ;; + -h|--help) + usage + exit 0 + ;; *${RETURNCODE_SEPARATOR}+([0-9])) SINGLE+=" $1" VERBOSE=y diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 iptables-1.8.7/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 --- iptables-1.8.5/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 2021-01-15 22:03:39.000000000 +0000 @@ -86,4 +86,8 @@ exit 1 fi +$XT_MULTI ebtables -t filter -E FOO BAZ || exit 1 +$XT_MULTI ebtables -t filter -L | grep -q FOO && exit 1 +$XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1 + $XT_MULTI ebtables -t $t -F || exit 0 diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 iptables-1.8.7/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 --- iptables-1.8.5/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 2021-01-15 22:03:39.000000000 +0000 @@ -70,8 +70,8 @@ :INPUT ACCEPT :FORWARD DROP :OUTPUT ACCEPT -:foo ACCEPT :bar RETURN +:foo ACCEPT -A INPUT -p IPv4 -i lo -j ACCEPT -A FORWARD -j foo -A OUTPUT -s Broadcast -j DROP diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 iptables-1.8.7/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 --- iptables-1.8.5/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 2021-01-15 22:03:39.000000000 +0000 @@ -230,21 +230,8 @@ $XT_MULTI iptables-save -t $table | grep -v '^#' >> "$tmpfile" done -case "$XT_MULTI" in -*xtables-nft-multi) - # nft-multi displays chain names in different order, work around this for now - tmpfile2=$(mktemp) - sort "$tmpfile" > "$tmpfile2" - sort $(dirname "$0")/dumps/ipt-save-completed.txt > "$tmpfile" - diff -u $tmpfile $tmpfile2 - RET=$? - rm -f "$tmpfile2" - ;; -*) - diff -u $tmpfile $(dirname "$0")/dumps/ipt-save-completed.txt - RET=$? - ;; -esac +diff -u $tmpfile $(dirname "$0")/dumps/ipt-save-completed.txt +RET=$? rm -f "$tmpfile" diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 iptables-1.8.7/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 --- iptables-1.8.5/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -#!/bin/sh - -# make sure error return codes are as expected useful cases -# (e.g. commands to check ruleset state) - -global_rc=0 - -cmd() { # (rc, cmd, [args ...]) - rc_exp=$1; shift - - $XT_MULTI "$@" - rc=$? - - [ $rc -eq $rc_exp ] || { - echo "---> expected $rc_exp, got $rc for command '$@'" - global_rc=1 - } -} - -# test chain creation -cmd 0 ip6tables -N foo -cmd 1 ip6tables -N foo -# iptables-nft allows this - bug or feature? -#cmd 2 ip6tables -N "invalid name" - -# test rule adding -cmd 0 ip6tables -A INPUT -j ACCEPT -cmd 1 ip6tables -A noexist -j ACCEPT -cmd 2 ip6tables -I INPUT -j foobar - -# test rule checking -cmd 0 ip6tables -C INPUT -j ACCEPT -cmd 1 ip6tables -C FORWARD -j ACCEPT -cmd 1 ip6tables -C nonexist -j ACCEPT -cmd 2 ip6tables -C INPUT -j foobar -cmd 2 ip6tables -C INPUT -m foobar -j ACCEPT -cmd 3 ip6tables -t foobar -C INPUT -j ACCEPT - -exit $global_rc diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/iptables/0004-return-codes_0 iptables-1.8.7/iptables/tests/shell/testcases/iptables/0004-return-codes_0 --- iptables-1.8.5/iptables/tests/shell/testcases/iptables/0004-return-codes_0 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/iptables/0004-return-codes_0 2021-01-15 22:03:39.000000000 +0000 @@ -13,75 +13,84 @@ msg_exp="$1"; shift } - msg="$($XT_MULTI "$@" 2>&1 >/dev/null)" - rc=$? - - [ $rc -eq $rc_exp ] || { - echo "---> expected return code $rc_exp, got $rc for command '$@'" - global_rc=1 - } - - [ -n "$msg_exp" ] || return - grep -q "$msg_exp" <<< $msg || { - echo "---> expected error message '$msg_exp', got '$msg' for command '$@'" - global_rc=1 - } + for ipt in iptables ip6tables; do + msg="$($XT_MULTI $ipt "$@" 2>&1 >/dev/null)" + rc=$? + + [ $rc -eq $rc_exp ] || { + echo "---> expected return code $rc_exp, got $rc for command '$ipt $@'" + global_rc=1 + } + + [ -n "$msg_exp" ] || continue + msg_exp_full="${ipt}$msg_exp" + grep -q "$msg_exp_full" <<< $msg || { + echo "---> expected error message '$msg_exp_full', got '$msg' for command '$ipt $@'" + global_rc=1 + } + done } -EEXIST_F="File exists." -EEXIST="Chain already exists." -ENOENT="No chain/target/match by that name." -E2BIG_I="Index of insertion too big." -E2BIG_D="Index of deletion too big." -E2BIG_R="Index of replacement too big." -EBADRULE="Bad rule (does a matching rule exist in that chain?)." -ENOTGT="Couldn't load target \`foobar':No such file or directory" -ENOMTH="Couldn't load match \`foobar':No such file or directory" -ENOTBL="can't initialize iptables table \`foobar': Table does not exist" +EEXIST_F=": File exists." +EEXIST=": Chain already exists." +ENOENT=": No chain/target/match by that name." +E2BIG_I=": Index of insertion too big." +E2BIG_D=": Index of deletion too big." +E2BIG_R=": Index of replacement too big." +EBADRULE=": Bad rule (does a matching rule exist in that chain?)." +#ENOTGT=" v[0-9\.]* [^ ]*: Couldn't load target \`foobar':No such file or directory" +ENOMTH=" v[0-9\.]* [^ ]*: Couldn't load match \`foobar':No such file or directory" +ENOTBL=": can't initialize iptables table \`foobar': Table does not exist" # test chain creation -cmd 0 iptables -N foo -cmd 1 "$EEXIST" iptables -N foo +cmd 0 -N foo +cmd 1 "$EEXIST" -N foo # iptables-nft allows this - bug or feature? -#cmd 2 iptables -N "invalid name" +#cmd 2 -N "invalid name" # test chain flushing/zeroing -cmd 0 iptables -F foo -cmd 0 iptables -Z foo -cmd 1 "$ENOENT" iptables -F bar -cmd 1 "$ENOENT" iptables -Z bar +cmd 0 -F foo +cmd 0 -Z foo +cmd 1 "$ENOENT" -F bar +cmd 1 "$ENOENT" -Z bar # test chain rename -cmd 0 iptables -E foo bar -cmd 1 "$EEXIST_F" iptables -E foo bar -cmd 1 "$ENOENT" iptables -E foo bar2 -cmd 0 iptables -N foo2 -cmd 1 "$EEXIST_F" iptables -E foo2 bar +cmd 0 -E foo bar +cmd 1 "$EEXIST_F" -E foo bar +cmd 1 "$ENOENT" -E foo bar2 +cmd 0 -N foo2 +cmd 1 "$EEXIST_F" -E foo2 bar # test rule adding -cmd 0 iptables -A INPUT -j ACCEPT -cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT -cmd 2 "" iptables -I INPUT -j foobar -cmd 2 "" iptables -R INPUT 1 -j foobar -cmd 2 "" iptables -D INPUT -j foobar +cmd 0 -A INPUT -j ACCEPT +cmd 1 "$ENOENT" -A noexist -j ACCEPT +# next three differ: +# legacy: Couldn't load target `foobar':No such file or directory +# nft: Chain 'foobar' does not exist +cmd 2 "" -I INPUT -j foobar +cmd 2 "" -R INPUT 1 -j foobar +cmd 2 "" -D INPUT -j foobar +cmd 1 "$EBADRULE" -D INPUT -p tcp --dport 22 -j ACCEPT # test rulenum commands -cmd 1 "$E2BIG_I" iptables -I INPUT 23 -j ACCEPT -cmd 1 "$E2BIG_D" iptables -D INPUT 23 -cmd 1 "$E2BIG_R" iptables -R INPUT 23 -j ACCEPT -cmd 1 "$ENOENT" iptables -I nonexist 23 -j ACCEPT -cmd 1 "$ENOENT" iptables -D nonexist 23 -cmd 1 "$ENOENT" iptables -R nonexist 23 -j ACCEPT +cmd 1 "$E2BIG_I" -I INPUT 23 -j ACCEPT +cmd 1 "$E2BIG_D" -D INPUT 23 +cmd 1 "$E2BIG_R" -R INPUT 23 -j ACCEPT +cmd 1 "$ENOENT" -I nonexist 23 -j ACCEPT +cmd 1 "$ENOENT" -D nonexist 23 +cmd 1 "$ENOENT" -R nonexist 23 -j ACCEPT # test rule checking -cmd 0 iptables -C INPUT -j ACCEPT -cmd 1 "$EBADRULE" iptables -C FORWARD -j ACCEPT -cmd 1 "$BADRULE" iptables -C nonexist -j ACCEPT -cmd 2 "$ENOMTH" iptables -C INPUT -m foobar -j ACCEPT +cmd 0 -C INPUT -j ACCEPT +cmd 1 "$EBADRULE" -C FORWARD -j ACCEPT +cmd 1 "$BADRULE" -C nonexist -j ACCEPT +cmd 2 "$ENOMTH" -C INPUT -m foobar -j ACCEPT # messages of those don't match, but iptables-nft ones are actually nicer. -#cmd 2 "$ENOTGT" iptables -C INPUT -j foobar -#cmd 3 "$ENOTBL" iptables -t foobar -C INPUT -j ACCEPT -cmd 2 "" iptables -C INPUT -j foobar -cmd 3 "" iptables -t foobar -C INPUT -j ACCEPT +# legacy: Couldn't load target `foobar':No such file or directory +# nft: Chain 'foobar' does not exist +cmd 2 "" -C INPUT -j foobar +# legacy: can't initialize ip6tables table `foobar': Table does not exist (do you need to insmod?) +# nft: table 'foobar' does not exist +cmd 3 "" -t foobar -C INPUT -j ACCEPT exit $global_rc diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 iptables-1.8.7/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 --- iptables-1.8.5/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/ipt-restore/0007-flush-noflush_0 2021-01-15 22:03:39.000000000 +0000 @@ -18,7 +18,7 @@ :POSTROUTING ACCEPT [0:0] -A POSTROUTING -j ACCEPT COMMIT" -diff -u -Z <(echo -e "$EXPECT" | sort) <($XT_MULTI iptables-save | grep -v '^#' | sort) +diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables-save | grep -v '^#') $XT_MULTI iptables-restore </dev/null || { echo "skip for missing strace"; exit 0; } + +RULESET="$( + echo "*filter" + for ((i = 0; i < 100; i++)); do + echo "-A FORWARD -m conntrack --ctstate NEW" + done + echo "COMMIT" +)" + +cmd="$XT_MULTI iptables-restore" +socketcount=$(strace -esocket $cmd <<< "$RULESET" 2>&1 | wc -l) + +# unpatched iptables-restore would open 111 sockets, +# patched only 12 but keep a certain margin for future changes +[[ $socketcount -lt 20 ]] diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt iptables-1.8.7/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt --- iptables-1.8.5/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/ipt-save/dumps/ipt-save-filter.txt 2021-01-15 22:03:39.000000000 +0000 @@ -40,8 +40,8 @@ -A OUTPUT -s 127.0.0.1/32 -d 127.0.0.1/32 -o lo -j ACCEPT -A OUTPUT -o wlan0 -j wlanout -A OUTPUT -j block --A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:F1:05:A0:E0 -j RETURN --A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:F1:05:99:85 -j RETURN +-A WLAN -s 192.168.200.4/32 -m mac --mac-source 00:00:f1:05:a0:e0 -j RETURN +-A WLAN -s 192.168.200.9/32 -m mac --mac-source 00:00:f1:05:99:85 -j RETURN -A WLAN -m limit --limit 12/min -j LOG --log-prefix "UNKNOWN WLAN dropped:" -A WLAN -j DROP -A accept_log -i ppp0 -p tcp -m tcp --tcp-flags SYN,RST,ACK SYN -m limit --limit 1/sec -j LOG --log-prefix "TCPConnect on ppp0:" diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 iptables-1.8.7/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 --- iptables-1.8.5/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 1970-01-01 00:00:00.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/nft-only/0007-mid-restore-flush_0 2021-01-15 22:03:39.000000000 +0000 @@ -0,0 +1,23 @@ +#!/bin/bash + +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +nft -v >/dev/null || { echo "skip $XT_MULTI (no nft)"; exit 0; } + +coproc $XT_MULTI iptables-restore --noflush + +cat >&"${COPROC[1]}" <&"${COPROC[1]}" +sleep 1 + +[[ -n $COPROC_PID ]] && kill $COPROC_PID +wait diff -Nru iptables-1.8.5/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 iptables-1.8.7/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 --- iptables-1.8.5/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 1970-01-01 00:00:00.000000000 +0000 +++ iptables-1.8.7/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 2021-01-15 22:03:39.000000000 +0000 @@ -0,0 +1,29 @@ +#!/bin/bash + +[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } +set -e + +$XT_MULTI iptables -t raw -P OUTPUT DROP + +# make sure iptables-nft-restore can correctly handle basechain policies when +# they aren't set with --noflush +# +$XT_MULTI iptables-restore --noflush < illegal, 1 => legal, 0 => undecided. */ + + for (j = 0; j < NUMBER_OF_CMD; j++) { + if (!(command & (1< 1; option >>= 1, ptr++) + ; + + return *ptr; +} diff -Nru iptables-1.8.5/iptables/xshared.h iptables-1.8.7/iptables/xshared.h --- iptables-1.8.5/iptables/xshared.h 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xshared.h 2021-01-15 22:03:39.000000000 +0000 @@ -30,15 +30,20 @@ OPT_VIANAMEOUT = 1 << 8, OPT_LINENUMBERS = 1 << 9, OPT_COUNTERS = 1 << 10, + OPT_FRAGMENT = 1 << 11, /* below are for arptables only */ - OPT_S_MAC = 1 << 11, - OPT_D_MAC = 1 << 12, - OPT_H_LENGTH = 1 << 13, - OPT_OPCODE = 1 << 14, - OPT_H_TYPE = 1 << 15, - OPT_P_TYPE = 1 << 16, + OPT_S_MAC = 1 << 12, + OPT_D_MAC = 1 << 13, + OPT_H_LENGTH = 1 << 14, + OPT_OPCODE = 1 << 15, + OPT_H_TYPE = 1 << 16, + OPT_P_TYPE = 1 << 17, }; +#define NUMBER_OF_OPT ARRAY_SIZE(optflags) +static const char optflags[] += { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f', 2, 3, 'l', 4, 5, 6 }; + enum { CMD_NONE = 0, CMD_INSERT = 1 << 0, @@ -216,4 +221,7 @@ const int othercmds, int invert); int parse_rulenumber(const char *rule); +void generic_opt_check(int command, int options); +char opt2char(int option); + #endif /* IPTABLES_XSHARED_H */ diff -Nru iptables-1.8.5/iptables/xtables-arp.c iptables-1.8.7/iptables/xtables-arp.c --- iptables-1.8.5/iptables/xtables-arp.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-arp.c 2021-01-15 22:03:39.000000000 +0000 @@ -53,10 +53,6 @@ #include "nft-arp.h" #include -#define NUMBER_OF_OPT 16 -static const char optflags[NUMBER_OF_OPT] -= { 'n', 's', 'd', 2, 3, 7, 8, 4, 5, 6, 'j', 'v', 'i', 'o', '0', 'c'}; - static struct option original_opts[] = { { "append", 1, 0, 'A' }, { "delete", 1, 0, 'D' }, @@ -113,74 +109,29 @@ static int inverse_for_options[] = { /* -n */ 0, -/* -s */ ARPT_INV_SRCIP, -/* -d */ ARPT_INV_TGTIP, +/* -s */ IPT_INV_SRCIP, +/* -d */ IPT_INV_DSTIP, /* -p */ 0, /* -j */ 0, /* -v */ 0, /* -x */ 0, -/* -i */ ARPT_INV_VIA_IN, -/* -o */ ARPT_INV_VIA_OUT, +/* -i */ IPT_INV_VIA_IN, +/* -o */ IPT_INV_VIA_OUT, /*--line*/ 0, /* -c */ 0, -/* 2 */ ARPT_INV_SRCDEVADDR, -/* 3 */ ARPT_INV_TGTDEVADDR, -/* -l */ ARPT_INV_ARPHLN, -/* 4 */ ARPT_INV_ARPOP, -/* 5 */ ARPT_INV_ARPHRD, -/* 6 */ ARPT_INV_ARPPRO, +/* -f */ 0, +/* 2 */ IPT_INV_SRCDEVADDR, +/* 3 */ IPT_INV_TGTDEVADDR, +/* -l */ IPT_INV_ARPHLN, +/* 4 */ IPT_INV_ARPOP, +/* 5 */ IPT_INV_ARPHRD, +/* 6 */ IPT_INV_PROTO, }; /***********************************************/ /* ARPTABLES SPECIFIC NEW FUNCTIONS ADDED HERE */ /***********************************************/ -static unsigned char mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0}; -static unsigned char msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0}; -static unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; -static unsigned char msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; -static unsigned char mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; -static unsigned char msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; - -/* - * put the mac address into 6 (ETH_ALEN) bytes - */ -static int getmac_and_mask(char *from, char *to, char *mask) -{ - char *p; - int i; - struct ether_addr *addr; - - if (strcasecmp(from, "Unicast") == 0) { - memcpy(to, mac_type_unicast, ETH_ALEN); - memcpy(mask, msk_type_unicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Multicast") == 0) { - memcpy(to, mac_type_multicast, ETH_ALEN); - memcpy(mask, msk_type_multicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Broadcast") == 0) { - memcpy(to, mac_type_broadcast, ETH_ALEN); - memcpy(mask, msk_type_broadcast, ETH_ALEN); - return 0; - } - if ( (p = strrchr(from, '/')) != NULL) { - *p = '\0'; - if (!(addr = ether_aton(p + 1))) - return -1; - memcpy(mask, addr, ETH_ALEN); - } else - memset(mask, 0xff, ETH_ALEN); - if (!(addr = ether_aton(from))) - return -1; - memcpy(to, addr, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) - to[i] &= mask[i]; - return 0; -} - static int getlength_and_mask(char *from, uint8_t *to, uint8_t *mask) { char *p, *buffer; @@ -327,15 +278,6 @@ } } -static char -opt2char(int option) -{ - const char *ptr; - for (ptr = optflags; option > 1; option >>= 1, ptr++); - - return *ptr; -} - static int check_inverse(const char option[], int *invert, int *optidx, int argc) { @@ -686,7 +628,7 @@ check_inverse(optarg, &invert, &optind, argc); set_option(&options, OPT_S_MAC, &cs.arp.arp.invflags, invert); - if (getmac_and_mask(argv[optind - 1], + if (xtables_parse_mac_and_mask(argv[optind - 1], cs.arp.arp.src_devaddr.addr, cs.arp.arp.src_devaddr.mask)) xtables_error(PARAMETER_PROBLEM, "Problem with specified " "source mac"); @@ -697,7 +639,7 @@ set_option(&options, OPT_D_MAC, &cs.arp.arp.invflags, invert); - if (getmac_and_mask(argv[optind - 1], + if (xtables_parse_mac_and_mask(argv[optind - 1], cs.arp.arp.tgt_devaddr.addr, cs.arp.arp.tgt_devaddr.mask)) xtables_error(PARAMETER_PROBLEM, "Problem with specified " "destination mac"); @@ -901,7 +843,7 @@ &dmasks, &ndaddrs); if ((nsaddrs > 1 || ndaddrs > 1) && - (cs.arp.arp.invflags & (ARPT_INV_SRCIP | ARPT_INV_TGTIP))) + (cs.arp.arp.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP))) xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple" " source or destination IP addresses"); diff -Nru iptables-1.8.5/iptables/xtables.c iptables-1.8.7/iptables/xtables.c --- iptables-1.8.5/iptables/xtables.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables.c 2021-01-15 22:03:39.000000000 +0000 @@ -43,11 +43,6 @@ #include "nft-shared.h" #include "nft.h" -#define OPT_FRAGMENT 0x00800U -#define NUMBER_OF_OPT ARRAY_SIZE(optflags) -static const char optflags[] -= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c', 'f'}; - static struct option original_opts[] = { {.name = "append", .has_arg = 1, .val = 'A'}, {.name = "delete", .has_arg = 1, .val = 'D'}, @@ -99,36 +94,6 @@ .compat_rev = nft_compatible_revision, }; -/* Table of legal combinations of commands and options. If any of the - * given commands make an option legal, that option is legal (applies to - * CMD_LIST and CMD_ZERO only). - * Key: - * + compulsory - * x illegal - * optional - */ - -static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = -/* Well, it's better than "Re: Linux vs FreeBSD" */ -{ - /* -n -s -d -p -j -v -x -i -o --line -c -f */ -/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '}, -/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '}, -/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '}, -/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' '}, -/*LIST*/ {' ','x','x','x','x',' ',' ','x','x',' ','x','x'}, -/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x'}, -/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x'}, -/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' '}, -}; - static const int inverse_for_options[NUMBER_OF_OPT] = { /* -n */ 0, @@ -262,51 +227,6 @@ exit(status); } -static void -generic_opt_check(int command, int options) -{ - int i, j, legal = 0; - - /* Check that commands are valid with options. Complicated by the - * fact that if an option is legal with *any* command given, it is - * legal overall (ie. -z and -l). - */ - for (i = 0; i < NUMBER_OF_OPT; i++) { - legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */ - - for (j = 0; j < NUMBER_OF_CMD; j++) { - if (!(command & (1< 1; option >>= 1, ptr++); - - return *ptr; -} - /* * All functions starting with "parse" should succeed, otherwise * the program fails. diff -Nru iptables-1.8.5/iptables/xtables-eb.c iptables-1.8.7/iptables/xtables-eb.c --- iptables-1.8.5/iptables/xtables-eb.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-eb.c 2021-01-15 22:03:39.000000000 +0000 @@ -55,57 +55,6 @@ * 1: the inverse '!' of the option has already been specified */ int ebt_invert = 0; -unsigned char eb_mac_type_unicast[ETH_ALEN] = {0,0,0,0,0,0}; -unsigned char eb_msk_type_unicast[ETH_ALEN] = {1,0,0,0,0,0}; -unsigned char eb_mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; -unsigned char eb_msk_type_multicast[ETH_ALEN] = {1,0,0,0,0,0}; -unsigned char eb_mac_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; -unsigned char eb_msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255}; -unsigned char eb_mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0}; -unsigned char eb_msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255}; - -int ebt_get_mac_and_mask(const char *from, unsigned char *to, - unsigned char *mask) -{ - char *p; - int i; - struct ether_addr *addr = NULL; - - if (strcasecmp(from, "Unicast") == 0) { - memcpy(to, eb_mac_type_unicast, ETH_ALEN); - memcpy(mask, eb_msk_type_unicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Multicast") == 0) { - memcpy(to, eb_mac_type_multicast, ETH_ALEN); - memcpy(mask, eb_msk_type_multicast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "Broadcast") == 0) { - memcpy(to, eb_mac_type_broadcast, ETH_ALEN); - memcpy(mask, eb_msk_type_broadcast, ETH_ALEN); - return 0; - } - if (strcasecmp(from, "BGA") == 0) { - memcpy(to, eb_mac_type_bridge_group, ETH_ALEN); - memcpy(mask, eb_msk_type_bridge_group, ETH_ALEN); - return 0; - } - if ( (p = strrchr(from, '/')) != NULL) { - *p = '\0'; - if (!(addr = ether_aton(p + 1))) - return -1; - memcpy(mask, addr, ETH_ALEN); - } else - memset(mask, 0xff, ETH_ALEN); - if (!(addr = ether_aton(from))) - return -1; - memcpy(to, addr, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) - to[i] &= mask[i]; - return 0; -} - static int ebt_check_inverse2(const char option[], int argc, char **argv) { if (!option) @@ -853,6 +802,7 @@ else if (strchr(argv[optind], ' ') != NULL) xtables_error(PARAMETER_PROBLEM, "Use of ' ' not allowed in chain names"); + errno = 0; ret = nft_cmd_chain_user_rename(h, chain, *table, argv[optind]); if (ret != 0 && errno == ENOENT) @@ -1037,7 +987,9 @@ if (ebt_check_inverse2(optarg, argc, argv)) cs.eb.invflags |= EBT_ISOURCE; - if (ebt_get_mac_and_mask(optarg, cs.eb.sourcemac, cs.eb.sourcemsk)) + if (xtables_parse_mac_and_mask(optarg, + cs.eb.sourcemac, + cs.eb.sourcemsk)) xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg); cs.eb.bitmask |= EBT_SOURCEMAC; break; @@ -1046,7 +998,9 @@ if (ebt_check_inverse2(optarg, argc, argv)) cs.eb.invflags |= EBT_IDEST; - if (ebt_get_mac_and_mask(optarg, cs.eb.destmac, cs.eb.destmsk)) + if (xtables_parse_mac_and_mask(optarg, + cs.eb.destmac, + cs.eb.destmsk)) xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg); cs.eb.bitmask |= EBT_DESTMAC; break; @@ -1155,7 +1109,7 @@ /*case 7 :*/ /* atomic-init */ /*case 10:*/ /* atomic-save */ case 11: /* init-table */ - nft_cmd_table_flush(h, *table); + nft_cmd_table_flush(h, *table, false); return 1; /* replace->command = c; diff -Nru iptables-1.8.5/iptables/xtables-eb-translate.c iptables-1.8.7/iptables/xtables-eb-translate.c --- iptables-1.8.5/iptables/xtables-eb-translate.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-eb-translate.c 2021-01-15 22:03:39.000000000 +0000 @@ -397,7 +397,9 @@ if (ebt_check_inverse2(optarg, argc, argv)) cs.eb.invflags |= EBT_ISOURCE; - if (ebt_get_mac_and_mask(optarg, cs.eb.sourcemac, cs.eb.sourcemsk)) + if (xtables_parse_mac_and_mask(optarg, + cs.eb.sourcemac, + cs.eb.sourcemsk)) xtables_error(PARAMETER_PROBLEM, "Problem with specified source mac '%s'", optarg); cs.eb.bitmask |= EBT_SOURCEMAC; break; @@ -406,7 +408,9 @@ if (ebt_check_inverse2(optarg, argc, argv)) cs.eb.invflags |= EBT_IDEST; - if (ebt_get_mac_and_mask(optarg, cs.eb.destmac, cs.eb.destmsk)) + if (xtables_parse_mac_and_mask(optarg, + cs.eb.destmac, + cs.eb.destmsk)) xtables_error(PARAMETER_PROBLEM, "Problem with specified destination mac '%s'", optarg); cs.eb.bitmask |= EBT_DESTMAC; break; diff -Nru iptables-1.8.5/iptables/xtables-monitor.c iptables-1.8.7/iptables/xtables-monitor.c --- iptables-1.8.5/iptables/xtables-monitor.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-monitor.c 2021-01-15 22:03:39.000000000 +0000 @@ -93,6 +93,8 @@ if (arg->nfproto && arg->nfproto != family) goto err_free; + arg->h->ops = nft_family_ops_lookup(family); + if (arg->is_event) printf(" EVENT: "); switch (family) { @@ -104,6 +106,7 @@ printf("-0 "); break; default: + puts(""); goto err_free; } @@ -225,12 +228,12 @@ exit(EXIT_FAILURE); } - nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, NLM_F_DUMP, 0); + nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family, 0, 0); nftnl_rule_set_u32(r, NFTNL_RULE_FAMILY, family); nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain); nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table); - nftnl_rule_set_u64(r, NFTNL_RULE_POSITION, handle); + nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE, handle); nftnl_rule_nlmsg_build_payload(nlh, r); nftnl_rule_free(r); @@ -246,24 +249,21 @@ } portid = mnl_socket_get_portid(nl); - if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { - perror("mnl_socket_send"); - exit(EXIT_FAILURE); - } + if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) { + perror("mnl_socket_send"); + exit(EXIT_FAILURE); + } ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); - while (ret > 0) { + if (ret > 0) { args->is_event = false; - ret = mnl_cb_run(buf, ret, 0, portid, rule_cb, args); - if (ret <= 0) - break; - ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); - } - if (ret == -1) { - perror("error"); - exit(EXIT_FAILURE); - } - mnl_socket_close(nl); + ret = mnl_cb_run(buf, ret, 0, portid, rule_cb, args); + } + if (ret == -1) { + perror("error"); + exit(EXIT_FAILURE); + } + mnl_socket_close(nl); } static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *args) @@ -274,14 +274,14 @@ uint32_t mark; char name[IFNAMSIZ]; - printf("PACKET: %d %08x ", args->nfproto, nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID)); + family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY); + printf("PACKET: %d %08x ", family, nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID)); if (nftnl_trace_is_set(nlt, NFTNL_TRACE_IIF)) printf("IN=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_IIF), name)); if (nftnl_trace_is_set(nlt, NFTNL_TRACE_OIF)) printf("OUT=%s ", if_indextoname(nftnl_trace_get_u32(nlt, NFTNL_TRACE_OIF), name)); - family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY); nfproto = family; if (nftnl_trace_is_set(nlt, NFTNL_TRACE_NFPROTO)) { nfproto = nftnl_trace_get_u32(nlt, NFTNL_TRACE_NFPROTO); @@ -306,6 +306,9 @@ printf("MACDST=%s ", ether_ntoa((const void *)eh->h_dest)); printf("MACPROTO=%04x ", ntohs(eh->h_proto)); break; + case ARPHRD_LOOPBACK: + printf("LOOPBACK "); + break; default: printf("LL=0x%x ", type); for (i = 0 ; i < len; i++) @@ -434,9 +437,18 @@ mark = nftnl_trace_get_u32(nlt, NFTNL_TRACE_MARK); if (mark) printf("MARK=0x%x ", mark); + puts(""); } -static void print_verdict(struct nftnl_trace *nlt, uint32_t verdict) +static void trace_print_hdr(const struct nftnl_trace *nlt) +{ + printf(" TRACE: %d %08x %s:%s", nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY), + nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID), + nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE), + nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN)); +} + +static void print_verdict(const struct nftnl_trace *nlt, uint32_t verdict) { const char *chain; @@ -497,38 +509,41 @@ arg->nfproto != nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY)) goto err_free; - printf(" TRACE: %d %08x %s:%s", nftnl_trace_get_u32(nlt, NFTNL_TABLE_FAMILY), - nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID), - nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE), - nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN)); - switch (nftnl_trace_get_u32(nlt, NFTNL_TRACE_TYPE)) { case NFT_TRACETYPE_RULE: verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT); - printf(":rule:0x%llx:", (unsigned long long)nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE)); - print_verdict(nlt, verdict); - if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) - trace_print_rule(nlt, arg); if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) || nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER)) trace_print_packet(nlt, arg); + + if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) { + trace_print_hdr(nlt); + printf(":rule:0x%" PRIx64":", nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE)); + print_verdict(nlt, verdict); + printf(" "); + trace_print_rule(nlt, arg); + } break; case NFT_TRACETYPE_POLICY: + trace_print_hdr(nlt); printf(":policy:"); verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY); print_verdict(nlt, verdict); + puts(""); break; case NFT_TRACETYPE_RETURN: + trace_print_hdr(nlt); printf(":return:"); trace_print_return(nlt); + puts(""); break; } - puts(""); err_free: nftnl_trace_free(nlt); err: + fflush(stdout); return MNL_CB_OK; } diff -Nru iptables-1.8.5/iptables/xtables-restore.c iptables-1.8.7/iptables/xtables-restore.c --- iptables-1.8.5/iptables/xtables-restore.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-restore.c 2021-01-15 22:03:39.000000000 +0000 @@ -61,7 +61,6 @@ static const struct nft_xt_restore_cb restore_cb = { .commit = nft_commit, .abort = nft_abort, - .table_new = nft_cmd_table_new, .table_flush = nft_cmd_table_flush, .do_command = do_commandx, .chain_set = nft_cmd_chain_set, @@ -135,7 +134,7 @@ if (h->noflush == 0) { DEBUGP("Cleaning all chains of table '%s'\n", table); if (cb->table_flush) - cb->table_flush(h, table); + cb->table_flush(h, table, verbose); } ret = 1; @@ -260,7 +259,7 @@ struct nft_xt_restore_state state = {}; char buffer[10240] = {}; - if (!h->noflush) + if (!verbose && !h->noflush) nft_cache_level_set(h, NFT_CL_FAKE, NULL); line = 0; @@ -410,7 +409,6 @@ static const struct nft_xt_restore_cb ebt_restore_cb = { .commit = nft_bridge_commit, - .table_new = nft_cmd_table_new, .table_flush = nft_cmd_table_flush, .do_command = do_commandeb, .chain_set = nft_cmd_chain_set, @@ -456,7 +454,6 @@ static const struct nft_xt_restore_cb arp_restore_cb = { .commit = nft_commit, - .table_new = nft_cmd_table_new, .table_flush = nft_cmd_table_flush, .do_command = do_commandarp, .chain_set = nft_cmd_chain_set, diff -Nru iptables-1.8.5/iptables/xtables-save.c iptables-1.8.7/iptables/xtables-save.c --- iptables-1.8.5/iptables/xtables-save.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-save.c 2021-01-15 22:03:39.000000000 +0000 @@ -68,7 +68,6 @@ static int __do_output(struct nft_handle *h, const char *tablename, void *data) { - struct nftnl_chain_list *chain_list; struct do_output_data *d = data; time_t now; @@ -81,10 +80,6 @@ return 0; } - chain_list = nft_chain_list_get(h, tablename, NULL); - if (!chain_list) - return 0; - now = time(NULL); printf("# Generated by %s v%s on %s", prog_name, prog_vers, ctime(&now)); @@ -92,7 +87,7 @@ printf("*%s\n", tablename); /* Dump out chain names first, * thereby preventing dependency conflicts */ - nft_chain_save(h, chain_list); + nft_chain_foreach(h, tablename, nft_chain_save, h); nft_rule_save(h, tablename, d->format); if (d->commit) printf("COMMIT\n"); @@ -241,6 +236,7 @@ nft_cache_level_set(&h, NFT_CL_RULES, NULL); nft_cache_build(&h); + nft_xt_fake_builtin_chains(&h, tablename, NULL); ret = do_output(&h, tablename, &d); nft_fini(&h); diff -Nru iptables-1.8.5/iptables/xtables-standalone.c iptables-1.8.7/iptables/xtables-standalone.c --- iptables-1.8.5/iptables/xtables-standalone.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-standalone.c 2021-01-15 22:03:39.000000000 +0000 @@ -75,14 +75,10 @@ xtables_fini(); if (!ret) { - if (errno == EINVAL) { - fprintf(stderr, "iptables: %s. " - "Run `dmesg' for more information.\n", - nft_strerror(errno)); - } else { - fprintf(stderr, "iptables: %s.\n", - nft_strerror(errno)); - } + fprintf(stderr, "%s: %s.%s\n", progname, nft_strerror(errno), + (errno == EINVAL ? + " Run `dmesg' for more information." : "")); + if (errno == EAGAIN) exit(RESOURCE_PROBLEM); } diff -Nru iptables-1.8.5/iptables/xtables-translate.c iptables-1.8.7/iptables/xtables-translate.c --- iptables-1.8.5/iptables/xtables-translate.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables/xtables-translate.c 2021-01-15 22:03:39.000000000 +0000 @@ -249,7 +249,7 @@ cs.restore = restore; - if (!restore) + if (!restore && p.command != CMD_NONE) printf("nft "); switch (p.command) { @@ -310,13 +310,16 @@ break; case CMD_SET_POLICY: break; + case CMD_NONE: + ret = 1; + break; default: /* We should never reach this... */ printf("Unsupported command?\n"); exit(1); } - xtables_rule_matches_free(&cs.matches); + nft_clear_iptables_command_state(&cs); if (h->family == AF_INET) { free(args.s.addr.v4); diff -Nru iptables-1.8.5/iptables-test.py iptables-1.8.7/iptables-test.py --- iptables-1.8.5/iptables-test.py 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/iptables-test.py 2021-01-15 22:03:39.000000000 +0000 @@ -310,7 +310,7 @@ # def main(): parser = argparse.ArgumentParser(description='Run iptables tests') - parser.add_argument('filename', nargs='?', + parser.add_argument('filename', nargs='*', metavar='path/to/file.t', help='Run only this test') parser.add_argument('-H', '--host', action='store_true', @@ -359,13 +359,20 @@ return if args.filename: - file_list = [args.filename] + file_list = args.filename else: file_list = [os.path.join(EXTENSIONS_PATH, i) for i in os.listdir(EXTENSIONS_PATH) if i.endswith('.t')] file_list.sort() + if not args.netns: + try: + import unshare + unshare.unshare(unshare.CLONE_NEWNET) + except: + print("Cannot run in own namespace, connectivity might break") + for filename in file_list: file_tests, file_passed = run_test_file(filename, args.netns) if file_tests: diff -Nru iptables-1.8.5/libipq/Makefile.in iptables-1.8.7/libipq/Makefile.in --- iptables-1.8.5/libipq/Makefile.in 2020-06-03 11:07:29.000000000 +0000 +++ iptables-1.8.7/libipq/Makefile.in 2021-01-15 22:10:43.000000000 +0000 @@ -275,6 +275,7 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +XT_LOCK_NAME = @XT_LOCK_NAME@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru iptables-1.8.5/libiptc/libiptc.c iptables-1.8.7/libiptc/libiptc.c --- iptables-1.8.5/libiptc/libiptc.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/libiptc/libiptc.c 2021-01-15 22:03:39.000000000 +0000 @@ -1169,7 +1169,7 @@ else foot->target.verdict = RETURN; /* set policy-counters */ - memcpy(&foot->e.counters, &c->counters, sizeof(STRUCT_COUNTERS)); + foot->e.counters = c->counters; return 0; } diff -Nru iptables-1.8.5/libiptc/Makefile.in iptables-1.8.7/libiptc/Makefile.in --- iptables-1.8.5/libiptc/Makefile.in 2020-06-03 11:07:29.000000000 +0000 +++ iptables-1.8.7/libiptc/Makefile.in 2021-01-15 22:10:43.000000000 +0000 @@ -282,6 +282,7 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +XT_LOCK_NAME = @XT_LOCK_NAME@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru iptables-1.8.5/libxtables/Makefile.in iptables-1.8.7/libxtables/Makefile.in --- iptables-1.8.5/libxtables/Makefile.in 2020-06-03 11:07:29.000000000 +0000 +++ iptables-1.8.7/libxtables/Makefile.in 2021-01-15 22:10:43.000000000 +0000 @@ -282,6 +282,7 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +XT_LOCK_NAME = @XT_LOCK_NAME@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru iptables-1.8.5/libxtables/xtables.c iptables-1.8.7/libxtables/xtables.c --- iptables-1.8.5/libxtables/xtables.c 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/libxtables/xtables.c 2021-01-15 22:03:39.000000000 +0000 @@ -203,9 +203,12 @@ struct xtables_target *xtables_targets; /* Fully register a match/target which was previously partially registered. */ -static bool xtables_fully_register_pending_match(struct xtables_match *me); -static bool xtables_fully_register_pending_target(struct xtables_target *me); +static bool xtables_fully_register_pending_match(struct xtables_match *me, + struct xtables_match *prev); +static bool xtables_fully_register_pending_target(struct xtables_target *me, + struct xtables_target *prev); +#ifndef NO_SHARED_LIBS /* registry for loaded shared objects to close later */ struct dlreg { struct dlreg *next; @@ -237,6 +240,7 @@ dlreg = next; } } +#endif void xtables_init(void) { @@ -267,7 +271,9 @@ void xtables_fini(void) { +#ifndef NO_SHARED_LIBS dlreg_free(); +#endif } void xtables_set_nfproto(uint8_t nfproto) @@ -658,6 +664,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, struct xtables_rule_match **matches) { + struct xtables_match *prev = NULL; struct xtables_match **dptr; struct xtables_match *ptr; const char *icmp6 = "icmp6"; @@ -679,8 +686,12 @@ if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { ptr = *dptr; *dptr = (*dptr)->next; - if (xtables_fully_register_pending_match(ptr)) + if (xtables_fully_register_pending_match(ptr, prev)) { + prev = ptr; + continue; + } else if (prev) { continue; + } *dptr = ptr; } dptr = &((*dptr)->next); @@ -774,6 +785,7 @@ struct xtables_target * xtables_find_target(const char *name, enum xtables_tryload tryload) { + struct xtables_target *prev = NULL; struct xtables_target **dptr; struct xtables_target *ptr; @@ -790,8 +802,12 @@ if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { ptr = *dptr; *dptr = (*dptr)->next; - if (xtables_fully_register_pending_target(ptr)) + if (xtables_fully_register_pending_target(ptr, prev)) { + prev = ptr; + continue; + } else if (prev) { continue; + } *dptr = ptr; } dptr = &((*dptr)->next); @@ -944,8 +960,14 @@ } } +static int xtables_match_prefer(const struct xtables_match *a, + const struct xtables_match *b); + void xtables_register_match(struct xtables_match *me) { + struct xtables_match **pos; + bool seen_myself = false; + if (me->next) { fprintf(stderr, "%s: match \"%s\" already registered\n", xt_params->program_name, me->name); @@ -997,10 +1019,34 @@ if (me->extra_opts != NULL) xtables_check_options(me->name, me->extra_opts); - - /* place on linked list of matches pending full registration */ - me->next = xtables_pending_matches; - xtables_pending_matches = me; + /* order into linked list of matches pending full registration */ + for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) { + /* group by name and family */ + if (strcmp(me->name, (*pos)->name) || + me->family != (*pos)->family) { + if (seen_myself) + break; /* end of own group, append to it */ + continue; + } + /* found own group */ + seen_myself = true; + if (xtables_match_prefer(me, *pos) >= 0) + break; /* put preferred items first in group */ + } + /* if own group was not found, prepend item */ + if (!*pos && !seen_myself) + pos = &xtables_pending_matches; + + me->next = *pos; + *pos = me; +#ifdef DEBUG + printf("%s: inserted match %s (family %d, revision %d):\n", + __func__, me->name, me->family, me->revision); + for (pos = &xtables_pending_matches; *pos; pos = &(*pos)->next) { + printf("%s:\tmatch %s (family %d, revision %d)\n", __func__, + (*pos)->name, (*pos)->family, (*pos)->revision); + } +#endif } /** @@ -1064,64 +1110,27 @@ b->revision, b->family); } -static bool xtables_fully_register_pending_match(struct xtables_match *me) +static bool xtables_fully_register_pending_match(struct xtables_match *me, + struct xtables_match *prev) { - struct xtables_match **i, *old, *pos = NULL; + struct xtables_match **i; const char *rn; - int compare; /* See if new match can be used. */ rn = (me->real_name != NULL) ? me->real_name : me->name; if (!compatible_match_revision(rn, me->revision)) return false; - old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL); - while (old) { - compare = xtables_match_prefer(old, me); - if (compare == 0) { - fprintf(stderr, - "%s: match `%s' already registered.\n", - xt_params->program_name, me->name); - exit(1); - } - - /* Now we have two (or more) options, check compatibility. */ - rn = (old->real_name != NULL) ? old->real_name : old->name; - if (compare > 0) { - /* Kernel tells old isn't compatible anymore??? */ - if (!compatible_match_revision(rn, old->revision)) { - /* Delete old one. */ - for (i = &xtables_matches; *i != old;) - i = &(*i)->next; - *i = old->next; - } - pos = old; - old = old->next; - if (!old) - break; - if (!extension_cmp(me->name, old->name, old->family)) - break; - continue; - } - - /* Found right old */ - pos = old; - break; - } - - if (!pos) { + if (!prev) { /* Append to list. */ for (i = &xtables_matches; *i; i = &(*i)->next); - } else if (compare < 0) { - /* Prepend it */ - for (i = &xtables_matches; *i != pos; i = &(*i)->next); - } else if (compare > 0) { + } else { /* Append it */ - i = &pos->next; - pos = pos->next; + i = &prev->next; + prev = prev->next; } - me->next = pos; + me->next = prev; *i = me; me->m = NULL; @@ -1132,13 +1141,17 @@ void xtables_register_matches(struct xtables_match *match, unsigned int n) { - do { - xtables_register_match(&match[--n]); - } while (n > 0); + int i; + + for (i = 0; i < n; i++) + xtables_register_match(&match[i]); } void xtables_register_target(struct xtables_target *me) { + struct xtables_target **pos; + bool seen_myself = false; + if (me->next) { fprintf(stderr, "%s: target \"%s\" already registered\n", xt_params->program_name, me->name); @@ -1194,16 +1207,40 @@ if (me->family != afinfo->family && me->family != AF_UNSPEC) return; - /* place on linked list of targets pending full registration */ - me->next = xtables_pending_targets; - xtables_pending_targets = me; + /* order into linked list of targets pending full registration */ + for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) { + /* group by name */ + if (!extension_cmp(me->name, (*pos)->name, (*pos)->family)) { + if (seen_myself) + break; /* end of own group, append to it */ + continue; + } + /* found own group */ + seen_myself = true; + if (xtables_target_prefer(me, *pos) >= 0) + break; /* put preferred items first in group */ + } + /* if own group was not found, prepend item */ + if (!*pos && !seen_myself) + pos = &xtables_pending_targets; + + me->next = *pos; + *pos = me; +#ifdef DEBUG + printf("%s: inserted target %s (family %d, revision %d):\n", + __func__, me->name, me->family, me->revision); + for (pos = &xtables_pending_targets; *pos; pos = &(*pos)->next) { + printf("%s:\ttarget %s (family %d, revision %d)\n", __func__, + (*pos)->name, (*pos)->family, (*pos)->revision); + } +#endif } -static bool xtables_fully_register_pending_target(struct xtables_target *me) +static bool xtables_fully_register_pending_target(struct xtables_target *me, + struct xtables_target *prev) { - struct xtables_target **i, *old, *pos = NULL; + struct xtables_target **i; const char *rn; - int compare; if (strcmp(me->name, "standard") != 0) { /* See if new target can be used. */ @@ -1212,54 +1249,17 @@ return false; } - old = xtables_find_target(me->name, XTF_DURING_LOAD); - while (old) { - compare = xtables_target_prefer(old, me); - if (compare == 0) { - fprintf(stderr, - "%s: target `%s' already registered.\n", - xt_params->program_name, me->name); - exit(1); - } - - /* Now we have two (or more) options, check compatibility. */ - rn = (old->real_name != NULL) ? old->real_name : old->name; - if (compare > 0) { - /* Kernel tells old isn't compatible anymore??? */ - if (!compatible_target_revision(rn, old->revision)) { - /* Delete old one. */ - for (i = &xtables_targets; *i != old;) - i = &(*i)->next; - *i = old->next; - } - pos = old; - old = old->next; - if (!old) - break; - if (!extension_cmp(me->name, old->name, old->family)) - break; - continue; - } - - /* Found right old */ - pos = old; - break; - } - - if (!pos) { + if (!prev) { /* Prepend to list. */ i = &xtables_targets; - pos = xtables_targets; - } else if (compare < 0) { - /* Prepend it */ - for (i = &xtables_targets; *i != pos; i = &(*i)->next); - } else if (compare > 0) { + prev = xtables_targets; + } else { /* Append it */ - i = &pos->next; - pos = pos->next; + i = &prev->next; + prev = prev->next; } - me->next = pos; + me->next = prev; *i = me; me->t = NULL; @@ -1270,9 +1270,10 @@ void xtables_register_targets(struct xtables_target *target, unsigned int n) { - do { - xtables_register_target(&target[--n]); - } while (n > 0); + int i; + + for (i = 0; i < n; i++) + xtables_register_target(&target[i]); } /* receives a list of xtables_rule_match, release them */ @@ -2136,6 +2137,79 @@ printf(FMT("%4lluT ","%lluT "), (unsigned long long)number); } +#include + +static const unsigned char mac_type_unicast[ETH_ALEN] = {}; +static const unsigned char msk_type_unicast[ETH_ALEN] = {1}; +static const unsigned char mac_type_multicast[ETH_ALEN] = {1}; +static const unsigned char msk_type_multicast[ETH_ALEN] = {1}; +#define ALL_ONE_MAC {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} +static const unsigned char mac_type_broadcast[ETH_ALEN] = ALL_ONE_MAC; +static const unsigned char msk_type_broadcast[ETH_ALEN] = ALL_ONE_MAC; +static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01, 0x80, 0xc2}; +static const unsigned char msk_type_bridge_group[ETH_ALEN] = ALL_ONE_MAC; +#undef ALL_ONE_MAC + +int xtables_parse_mac_and_mask(const char *from, void *to, void *mask) +{ + char *p; + int i; + struct ether_addr *addr = NULL; + + if (strcasecmp(from, "Unicast") == 0) { + memcpy(to, mac_type_unicast, ETH_ALEN); + memcpy(mask, msk_type_unicast, ETH_ALEN); + return 0; + } + if (strcasecmp(from, "Multicast") == 0) { + memcpy(to, mac_type_multicast, ETH_ALEN); + memcpy(mask, msk_type_multicast, ETH_ALEN); + return 0; + } + if (strcasecmp(from, "Broadcast") == 0) { + memcpy(to, mac_type_broadcast, ETH_ALEN); + memcpy(mask, msk_type_broadcast, ETH_ALEN); + return 0; + } + if (strcasecmp(from, "BGA") == 0) { + memcpy(to, mac_type_bridge_group, ETH_ALEN); + memcpy(mask, msk_type_bridge_group, ETH_ALEN); + return 0; + } + if ( (p = strrchr(from, '/')) != NULL) { + *p = '\0'; + if (!(addr = ether_aton(p + 1))) + return -1; + memcpy(mask, addr, ETH_ALEN); + } else + memset(mask, 0xff, ETH_ALEN); + if (!(addr = ether_aton(from))) + return -1; + memcpy(to, addr, ETH_ALEN); + for (i = 0; i < ETH_ALEN; i++) + ((char *)to)[i] &= ((char *)mask)[i]; + return 0; +} + +int xtables_print_well_known_mac_and_mask(const void *mac, const void *mask) +{ + if (!memcmp(mac, mac_type_unicast, ETH_ALEN) && + !memcmp(mask, msk_type_unicast, ETH_ALEN)) + printf("Unicast"); + else if (!memcmp(mac, mac_type_multicast, ETH_ALEN) && + !memcmp(mask, msk_type_multicast, ETH_ALEN)) + printf("Multicast"); + else if (!memcmp(mac, mac_type_broadcast, ETH_ALEN) && + !memcmp(mask, msk_type_broadcast, ETH_ALEN)) + printf("Broadcast"); + else if (!memcmp(mac, mac_type_bridge_group, ETH_ALEN) && + !memcmp(mask, msk_type_bridge_group, ETH_ALEN)) + printf("BGA"); + else + return -1; + return 0; +} + void xtables_print_mac(const unsigned char *macaddress) { unsigned int i; diff -Nru iptables-1.8.5/Makefile.in iptables-1.8.7/Makefile.in --- iptables-1.8.5/Makefile.in 2020-06-03 11:07:28.000000000 +0000 +++ iptables-1.8.7/Makefile.in 2021-01-15 22:10:43.000000000 +0000 @@ -316,6 +316,7 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +XT_LOCK_NAME = @XT_LOCK_NAME@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ diff -Nru iptables-1.8.5/utils/Makefile.am iptables-1.8.7/utils/Makefile.am --- iptables-1.8.5/utils/Makefile.am 2020-06-03 10:32:01.000000000 +0000 +++ iptables-1.8.7/utils/Makefile.am 2021-01-15 22:03:39.000000000 +0000 @@ -14,6 +14,11 @@ pkgdata_DATA += pf.os nfnl_osf_LDADD = ${libnfnetlink_LIBS} + +uninstall-hook: + dir=${DESTDIR}${pkgdatadir}; { \ + test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ + } || rmdir -p --ignore-fail-on-non-empty "$$dir" endif if ENABLE_BPFC diff -Nru iptables-1.8.5/utils/Makefile.in iptables-1.8.7/utils/Makefile.in --- iptables-1.8.5/utils/Makefile.in 2020-06-03 11:07:29.000000000 +0000 +++ iptables-1.8.7/utils/Makefile.in 2021-01-15 22:10:43.000000000 +0000 @@ -293,6 +293,7 @@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +XT_LOCK_NAME = @XT_LOCK_NAME@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ @@ -710,6 +711,7 @@ maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." +@HAVE_LIBNFNETLINK_FALSE@uninstall-hook: clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ @@ -785,10 +787,11 @@ uninstall-am: uninstall-man uninstall-pkgdataDATA \ uninstall-sbinPROGRAMS - + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) uninstall-hook uninstall-man: uninstall-man8 -.MAKE: install-am install-strip +.MAKE: install-am install-strip uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ clean-generic clean-libtool clean-sbinPROGRAMS cscopelist-am \ @@ -803,12 +806,18 @@ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-man \ - uninstall-man8 uninstall-pkgdataDATA uninstall-sbinPROGRAMS + tags tags-am uninstall uninstall-am uninstall-hook \ + uninstall-man uninstall-man8 uninstall-pkgdataDATA \ + uninstall-sbinPROGRAMS .PRECIOUS: Makefile +@HAVE_LIBNFNETLINK_TRUE@uninstall-hook: +@HAVE_LIBNFNETLINK_TRUE@ dir=${DESTDIR}${pkgdatadir}; { \ +@HAVE_LIBNFNETLINK_TRUE@ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; \ +@HAVE_LIBNFNETLINK_TRUE@ } || rmdir -p --ignore-fail-on-non-empty "$$dir" + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: