commit 882fcd5ce470e347e136ae6e0facd78f27125e0a Author: MSVSphere Packaging Team Date: Fri Mar 29 15:48:06 2024 +0300 import iptables-1.8.5-11.el8_9 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0be74d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/iptables-1.8.5.tar.bz2 diff --git a/.iptables.metadata b/.iptables.metadata new file mode 100644 index 0000000..dee2066 --- /dev/null +++ b/.iptables.metadata @@ -0,0 +1 @@ +f177a58d0a71b00d68ef5792ae4676bcc0ad29e6 SOURCES/iptables-1.8.5.tar.bz2 diff --git a/SOURCES/0001-build-resolve-iptables-apply-not-getting-installed.patch b/SOURCES/0001-build-resolve-iptables-apply-not-getting-installed.patch new file mode 100644 index 0000000..22ed228 --- /dev/null +++ b/SOURCES/0001-build-resolve-iptables-apply-not-getting-installed.patch @@ -0,0 +1,41 @@ +From 4806ba770a3aaadd0a3975ac1ea92dff3ea87ee4 Mon Sep 17 00:00:00 2001 +From: Jan Engelhardt +Date: Wed, 3 Jun 2020 15:38:48 +0200 +Subject: [PATCH] build: resolve iptables-apply not getting installed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +ip6tables-apply gets installed but iptables-apply does not. +That is wrong. + +» make install DESTDIR=$PWD/r +» find r -name "*app*" +r/usr/local/sbin/ip6tables-apply +r/usr/local/share/man/man8/iptables-apply.8 +r/usr/local/share/man/man8/ip6tables-apply.8 + +Fixes: v1.8.5~87 +Signed-off-by: Jan Engelhardt +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit d4ed0c741fc789bb09d977d74d30875fdd50d08b) +--- + iptables/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/Makefile.am b/iptables/Makefile.am +index dc66b3cc09c08..2024dbf5cb88c 100644 +--- a/iptables/Makefile.am ++++ b/iptables/Makefile.am +@@ -56,7 +56,7 @@ man_MANS = iptables.8 iptables-restore.8 iptables-save.8 \ + 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 \ +-- +2.40.0 + diff --git a/SOURCES/0002-xtables-translate-don-t-fail-if-help-was-requested.patch b/SOURCES/0002-xtables-translate-don-t-fail-if-help-was-requested.patch new file mode 100644 index 0000000..429ebc4 --- /dev/null +++ b/SOURCES/0002-xtables-translate-don-t-fail-if-help-was-requested.patch @@ -0,0 +1,57 @@ +From eaad1950f1952733c2770b29b593613cfe9af8a8 Mon Sep 17 00:00:00 2001 +From: Arturo Borrero Gonzalez +Date: Tue, 16 Jun 2020 11:20:42 +0200 +Subject: [PATCH] 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 +(cherry picked from commit 2757c0b5e5fbbf569695469b331453cecefdf069) +--- + 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 5aa42496b5a48..363c8be15b3fa 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"); +-- +2.40.0 + diff --git a/SOURCES/0003-xtables-translate-Use-proper-clear_cs-function.patch b/SOURCES/0003-xtables-translate-Use-proper-clear_cs-function.patch new file mode 100644 index 0000000..a66c5d0 --- /dev/null +++ b/SOURCES/0003-xtables-translate-Use-proper-clear_cs-function.patch @@ -0,0 +1,30 @@ +From d9497b521e6f512f27bd1d4a88086f50418cb7b8 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 16 Jun 2020 13:06:26 +0200 +Subject: [PATCH] xtables-translate: Use proper clear_cs function + +Avoid memleaks by performing a full free of any allocated data in local +iptables_command_state variable. + +Signed-off-by: Phil Sutter +(cherry picked from commit 63fa2b1cb98be66990912d7eb42eab5440437087) +--- + iptables/xtables-translate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index 363c8be15b3fa..575fb320dc408 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -319,7 +319,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], + exit(1); + } + +- xtables_rule_matches_free(&cs.matches); ++ nft_clear_iptables_command_state(&cs); + + if (h->family == AF_INET) { + free(args.s.addr.v4); +-- +2.40.0 + diff --git a/SOURCES/0004-libxtables-compiler-warning-fixes-for-NO_SHARED_LIBS.patch b/SOURCES/0004-libxtables-compiler-warning-fixes-for-NO_SHARED_LIBS.patch new file mode 100644 index 0000000..8948172 --- /dev/null +++ b/SOURCES/0004-libxtables-compiler-warning-fixes-for-NO_SHARED_LIBS.patch @@ -0,0 +1,55 @@ +From 94fcba7825b121cbb7d3ff73f4e80a798feccdee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= +Date: Tue, 23 Jun 2020 16:09:02 -0700 +Subject: [PATCH] libxtables: compiler warning fixes for NO_SHARED_LIBS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes two issues with NO_SHARED_LIBS: + - #include is ifdef'ed out and thus dlclose() + triggers an undeclared function compiler warning + - dlreg_add() is unused and thus triggers an unused + function warning + +Test: builds without warnings +Signed-off-by: Maciej Żenczykowski +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit 6cb8af1ff3951e47def7a16db39289dc9d9c61fe) +--- + libxtables/xtables.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 7fe42580f9b70..8907ba2069be7 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -206,6 +206,7 @@ struct xtables_target *xtables_targets; + static bool xtables_fully_register_pending_match(struct xtables_match *me); + static bool xtables_fully_register_pending_target(struct xtables_target *me); + ++#ifndef NO_SHARED_LIBS + /* registry for loaded shared objects to close later */ + struct dlreg { + struct dlreg *next; +@@ -237,6 +238,7 @@ static void dlreg_free(void) + dlreg = next; + } + } ++#endif + + void xtables_init(void) + { +@@ -267,7 +269,9 @@ void xtables_init(void) + + void xtables_fini(void) + { ++#ifndef NO_SHARED_LIBS + dlreg_free(); ++#endif + } + + void xtables_set_nfproto(uint8_t nfproto) +-- +2.40.0 + diff --git a/SOURCES/0005-extensions-libxt_conntrack-provide-translation-for-D.patch b/SOURCES/0005-extensions-libxt_conntrack-provide-translation-for-D.patch new file mode 100644 index 0000000..0131684 --- /dev/null +++ b/SOURCES/0005-extensions-libxt_conntrack-provide-translation-for-D.patch @@ -0,0 +1,63 @@ +From 0323122f6a3ef9ab2ded571685d3c64851c6df86 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Wed, 22 Jul 2020 13:04:34 +0200 +Subject: [PATCH] extensions: libxt_conntrack: provide translation for DNAT and + SNAT --ctstate + +iptables-translate -t filter -A INPUT -m conntrack --ctstate DNAT -j ACCEPT +nft add rule ip filter INPUT ct status dnat counter accept + +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit 26ec09bf6b9b674a7e3a65fc9c12599bd81dfe0f) +--- + extensions/libxt_conntrack.c | 18 +++++++++++++----- + extensions/libxt_conntrack.txlate | 7 +++++++ + 2 files changed, 20 insertions(+), 5 deletions(-) + +diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c +index 6f3503933e664..7734509c9af84 100644 +--- a/extensions/libxt_conntrack.c ++++ b/extensions/libxt_conntrack.c +@@ -1249,11 +1249,19 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, + } + + 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 --git a/extensions/libxt_conntrack.txlate b/extensions/libxt_conntrack.txlate +index 8a3d0181c71ef..d374f8a035f00 100644 +--- a/extensions/libxt_conntrack.txlate ++++ b/extensions/libxt_conntrack.txlate +@@ -42,3 +42,10 @@ nft add rule ip filter INPUT ct direction original counter accept + + 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 ++ +-- +2.40.0 + diff --git a/SOURCES/0006-nft-Drop-pointless-nft_xt_builtin_init-call.patch b/SOURCES/0006-nft-Drop-pointless-nft_xt_builtin_init-call.patch new file mode 100644 index 0000000..eded898 --- /dev/null +++ b/SOURCES/0006-nft-Drop-pointless-nft_xt_builtin_init-call.patch @@ -0,0 +1,30 @@ +From 13abbdd7789da8616a903b5b8dc5ff69fb2af2c7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 10 Jul 2020 21:12:34 +0200 +Subject: [PATCH] nft: Drop pointless nft_xt_builtin_init() call + +When renaming a chain, either everything is in place already or the +command will bail anyway. So just drop this superfluous call. + +Signed-off-by: Phil Sutter +(cherry picked from commit 7a700c47fe121c65c550ab24de3284abbb1e82f8) +--- + iptables/nft.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 0c5a74fc232c6..e795d4ae6d241 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -1934,8 +1934,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain, + return 0; + } + +- nft_xt_builtin_init(h, table); +- + /* Config load changed errno. Ensure genuine info for our callers. */ + errno = 0; + +-- +2.40.0 + diff --git a/SOURCES/0007-nft-Fix-command-name-in-ip6tables-error-message.patch b/SOURCES/0007-nft-Fix-command-name-in-ip6tables-error-message.patch new file mode 100644 index 0000000..40b80f2 --- /dev/null +++ b/SOURCES/0007-nft-Fix-command-name-in-ip6tables-error-message.patch @@ -0,0 +1,44 @@ +From a58c38e4c579f409669b5ab82d3b039528a129af Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 7 Aug 2020 13:48:28 +0200 +Subject: [PATCH] nft: Fix command name in ip6tables error message + +Upon errors, ip6tables-nft would prefix its error messages with +'iptables:' instead of 'ip6tables:'. Turns out the command name was +hard-coded, use 'progname' variable instead. +While being at it, merge the two mostly identical fprintf() calls into +one. + +Signed-off-by: Phil Sutter +Acked-by: Pablo Neira Ayuso +(cherry picked from commit 3be40dcfb5af1438b6abdbda45a1e3b59c104e13) +--- + iptables/xtables-standalone.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/iptables/xtables-standalone.c b/iptables/xtables-standalone.c +index dd6fb7919d2e1..7b71db62f1ea6 100644 +--- a/iptables/xtables-standalone.c ++++ b/iptables/xtables-standalone.c +@@ -75,14 +75,10 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) + 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); + } +-- +2.40.0 + diff --git a/SOURCES/0008-tests-shell-Merge-and-extend-return-codes-test.patch b/SOURCES/0008-tests-shell-Merge-and-extend-return-codes-test.patch new file mode 100644 index 0000000..166b335 --- /dev/null +++ b/SOURCES/0008-tests-shell-Merge-and-extend-return-codes-test.patch @@ -0,0 +1,208 @@ +From 529dee8412eb216a2432e063136ede732edb9cc1 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 6 Aug 2020 18:52:34 +0200 +Subject: [PATCH] tests: shell: Merge and extend return codes test + +Merge scripts for iptables and ip6tables, they were widely identical. +Also extend the test by one check (removing a non-existent rule with +valid chain and target) and quote the error messages where differences +are deliberately ignored. + +Signed-off-by: Phil Sutter +Acked-by: Pablo Neira Ayuso +(cherry picked from commit cd3e83d1b04fd2683f0fb06e496ee5be08a96b4f) +--- + .../testcases/ip6tables/0004-return-codes_0 | 39 ------ + .../testcases/iptables/0004-return-codes_0 | 113 ++++++++++-------- + 2 files changed, 61 insertions(+), 91 deletions(-) + delete mode 100755 iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 + +diff --git a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 b/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 +deleted file mode 100755 +index c583b0ebd97c3..0000000000000 +--- a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 ++++ /dev/null +@@ -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 --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 +index f730bede1f612..dcd9dfd3c0806 100755 +--- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 ++++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 +@@ -13,75 +13,84 @@ cmd() { # (rc, msg, cmd, [args ...]) + msg_exp="$1"; shift + } + +- msg="$($XT_MULTI "$@" 2>&1 >/dev/null)" +- rc=$? ++ 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 '$@'" +- global_rc=1 +- } ++ [ $rc -eq $rc_exp ] || { ++ echo "---> expected return code $rc_exp, got $rc for command '$ipt $@'" ++ 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 +- } ++ [ -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 +-- +2.40.0 + diff --git a/SOURCES/0009-xtables-monitor-Fix-ip6tables-rule-printing.patch b/SOURCES/0009-xtables-monitor-Fix-ip6tables-rule-printing.patch new file mode 100644 index 0000000..42646cd --- /dev/null +++ b/SOURCES/0009-xtables-monitor-Fix-ip6tables-rule-printing.patch @@ -0,0 +1,37 @@ +From fe5db6f78145aeac1b18d21c38c178b99cd7c04a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 7 Aug 2020 16:42:07 +0200 +Subject: [PATCH] xtables-monitor: Fix ip6tables rule printing + +When printing an ip6tables rule event, false family ops are used as they +are initially looked up for AF_INET and reused no matter the current +rule's family. In practice, this means that nft_rule_print_save() calls +the wrong rule_to_cs, save_rule and clear_cs callbacks. Therefore, if a +rule specifies a source or destination address, the address is not +printed. + +Fix this by performing a family lookup each time rule_cb is called. + +Signed-off-by: Phil Sutter +Acked-by: Pablo Neira Ayuso +(cherry picked from commit ca69b0290dc509d72118f0a054a5c740cb913875) +--- + iptables/xtables-monitor.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 57def83e2eea0..4008cc00d4694 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -93,6 +93,8 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) + 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) { +-- +2.40.0 + diff --git a/SOURCES/0010-nft-cache-Check-consistency-with-NFT_CL_FAKE-too.patch b/SOURCES/0010-nft-cache-Check-consistency-with-NFT_CL_FAKE-too.patch new file mode 100644 index 0000000..01ca6c6 --- /dev/null +++ b/SOURCES/0010-nft-cache-Check-consistency-with-NFT_CL_FAKE-too.patch @@ -0,0 +1,39 @@ +From 895077fbd8f11b717fd414a02d22dae99d94b390 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 29 Jul 2020 15:39:31 +0200 +Subject: [PATCH] nft: cache: Check consistency with NFT_CL_FAKE, too + +Athough this cache level fetches table names only, it shouldn't skip the +consistency check. + +Fixes: f42bfb344af82 ("nft: cache: Re-establish cache consistency check") +Signed-off-by: Phil Sutter +(cherry picked from commit b531365ce32f386d91c6a0bbc80ec4076e4babdd) +--- + iptables/nft-cache.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c +index 638b18bc7e382..434cc10b82ce7 100644 +--- a/iptables/nft-cache.c ++++ b/iptables/nft-cache.c +@@ -511,14 +511,14 @@ __nft_build_cache(struct nft_handle *h) + 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); +-- +2.40.0 + diff --git a/SOURCES/0011-nft-Fix-for-broken-address-mask-match-detection.patch b/SOURCES/0011-nft-Fix-for-broken-address-mask-match-detection.patch new file mode 100644 index 0000000..7a0fb26 --- /dev/null +++ b/SOURCES/0011-nft-Fix-for-broken-address-mask-match-detection.patch @@ -0,0 +1,59 @@ +From ba2da85b5a8940035f57dd395205c726c0c68ec7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 28 Sep 2020 18:57:18 +0200 +Subject: [PATCH] nft: Fix for broken address mask match detection + +Trying to decide whether a bitwise expression is needed to match parts +of a source or destination address only, add_addr() checks if all bytes +in 'mask' are 0xff or not. The check is apparently broken though as each +byte in 'mask' is cast to a signed char before comparing against 0xff, +therefore the bitwise is always added: + +| # ./bad/iptables-nft -A foo -s 10.0.0.1 -j ACCEPT +| # ./good/iptables-nft -A foo -s 10.0.0.2 -j ACCEPT +| # nft --debug=netlink list chain ip filter foo +| ip filter foo 5 +| [ payload load 4b @ network header + 12 => reg 1 ] +| [ bitwise reg 1 = (reg=1 & 0xffffffff ) ^ 0x00000000 ] +| [ cmp eq reg 1 0x0100000a ] +| [ counter pkts 0 bytes 0 ] +| [ immediate reg 0 accept ] +| +| ip filter foo 6 5 +| [ payload load 4b @ network header + 12 => reg 1 ] +| [ cmp eq reg 1 0x0200000a ] +| [ counter pkts 0 bytes 0 ] +| [ immediate reg 0 accept ] +| +| table ip filter { +| chain foo { +| ip saddr 10.0.0.1 counter packets 0 bytes 0 accept +| ip saddr 10.0.0.2 counter packets 0 bytes 0 accept +| } +| } + +Fix the cast, safe an extra op and gain 100% performance in ideal cases. + +Fixes: 56859380eb328 ("xtables-compat: avoid unneeded bitwise ops") +Signed-off-by: Phil Sutter +(cherry picked from commit 72ed608bf1ea550ac13b5b880afc7ad3ffa0afd0) +--- + iptables/nft-shared.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index c5a8f3fcc051d..7741d23befc5a 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -165,7 +165,7 @@ void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op) + void add_addr(struct nftnl_rule *r, int offset, + void *data, void *mask, size_t len, uint32_t op) + { +- const char *m = mask; ++ const unsigned char *m = mask; + int i; + + add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER); +-- +2.40.0 + diff --git a/SOURCES/0012-extensions-libipt_icmp-Fix-translation-of-type-any.patch b/SOURCES/0012-extensions-libipt_icmp-Fix-translation-of-type-any.patch new file mode 100644 index 0000000..4a2cbe8 --- /dev/null +++ b/SOURCES/0012-extensions-libipt_icmp-Fix-translation-of-type-any.patch @@ -0,0 +1,51 @@ +From e674863343bf3233d2d1cdd9e17adad5381796a9 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 6 Oct 2020 19:07:19 +0200 +Subject: [PATCH] extensions: libipt_icmp: Fix translation of type 'any' + +By itself, '-m icmp --icmp-type any' is a noop, it matches any icmp +types. Yet nft_ipv4_xlate() does not emit an 'ip protocol' match if +there's an extension with same name present in the rule. Luckily, legacy +iptables demands icmp match to be prepended by '-p icmp', so we can +assume this is present and just emit the 'ip protocol' match from icmp +xlate callback. + +Fixes: aa158ca0fda65 ("extensions: libipt_icmp: Add translation to nft") +Signed-off-by: Phil Sutter +Reviewed-by: Florian Westphal +(cherry picked from commit ad4b17b98bbedf93d2182a4dc9a37e9cf3adfe1b) +--- + extensions/libipt_icmp.c | 5 +++++ + extensions/libipt_icmp.txlate | 3 +++ + 2 files changed, 8 insertions(+) + +diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c +index e76257c54708c..e5e236613f39f 100644 +--- a/extensions/libipt_icmp.c ++++ b/extensions/libipt_icmp.c +@@ -256,6 +256,11 @@ static int icmp_xlate(struct xt_xlate *xl, + 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 --git a/extensions/libipt_icmp.txlate b/extensions/libipt_icmp.txlate +index 434f8cc4eb1ae..a2aec8e26df75 100644 +--- a/extensions/libipt_icmp.txlate ++++ b/extensions/libipt_icmp.txlate +@@ -6,3 +6,6 @@ nft add rule ip filter INPUT icmp type destination-unreachable counter accept + + 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 +-- +2.40.0 + diff --git a/SOURCES/0013-libxtables-Make-sure-extensions-register-in-revision.patch b/SOURCES/0013-libxtables-Make-sure-extensions-register-in-revision.patch new file mode 100644 index 0000000..de9e4b7 --- /dev/null +++ b/SOURCES/0013-libxtables-Make-sure-extensions-register-in-revision.patch @@ -0,0 +1,127 @@ +From 4616623e18cb1868960194cd7f695969c594a35b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 21 Sep 2020 13:42:06 +0200 +Subject: [PATCH] libxtables: Make sure extensions register in revision order + +Insert extensions into pending lists in ordered fashion: Group by +extension name (and, for matches, family) and order groups by descending +revision number. + +This allows to simplify the later full registration considerably. Since +that involves kernel compatibility checks, the extra cycles here pay off +eventually. + +Signed-off-by: Phil Sutter +(cherry picked from commit b3ac87038f4e45141831d9ab485a2f627daba3f1) +--- + libxtables/xtables.c | 71 +++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 64 insertions(+), 7 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 8907ba2069be7..de52e3e2bbc15 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -948,8 +948,14 @@ static void xtables_check_options(const char *name, const struct option *opt) + } + } + ++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); +@@ -1001,10 +1007,34 @@ void xtables_register_match(struct xtables_match *me) + 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 + } + + /** +@@ -1143,6 +1173,9 @@ void xtables_register_matches(struct xtables_match *match, unsigned int n) + + 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); +@@ -1198,9 +1231,33 @@ void xtables_register_target(struct xtables_target *me) + 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) +-- +2.40.0 + diff --git a/SOURCES/0014-libxtables-Simplify-pending-extension-registration.patch b/SOURCES/0014-libxtables-Simplify-pending-extension-registration.patch new file mode 100644 index 0000000..f35466b --- /dev/null +++ b/SOURCES/0014-libxtables-Simplify-pending-extension-registration.patch @@ -0,0 +1,240 @@ +From 4b5e9e71fbad66aef1db079905cba2db032a7515 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 18 Sep 2020 18:48:14 +0200 +Subject: [PATCH] libxtables: Simplify pending extension registration + +Assuming that pending extensions are sorted by first name and family, +then descending revision, the decision where to insert a newly +registered extension may be simplified by memorizing the previous +registration (which obviously is of same name and family and higher +revision). + +As a side-effect, fix for unsupported old extension revisions lingering +in pending extension list forever and being retried with every use of +the given extension. Any revision being rejected by the kernel may +safely be dropped iff a previous (read: higher) revision was accepted +already. + +Yet another side-effect of this change is the removal of an unwanted +recursion by xtables_fully_register_pending_*() into itself via +xtables_find_*(). + +Signed-off-by: Phil Sutter +(cherry picked from commit a1eaaceb0460b338294e40bdd5bc5186320a478c) +--- + libxtables/xtables.c | 128 +++++++++++-------------------------------- + 1 file changed, 33 insertions(+), 95 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index de52e3e2bbc15..10d4e70328500 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -203,8 +203,10 @@ struct xtables_match *xtables_matches; + 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 */ +@@ -662,6 +664,7 @@ struct xtables_match * + 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"; +@@ -683,8 +686,12 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, + 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); +@@ -778,6 +785,7 @@ xtables_find_match_revision(const char *name, enum xtables_tryload tryload, + 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; + +@@ -794,8 +802,12 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + 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); +@@ -1098,64 +1110,27 @@ static int xtables_target_prefer(const struct xtables_target *a, + 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; +@@ -1260,11 +1235,11 @@ void xtables_register_target(struct xtables_target *me) + #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. */ +@@ -1273,54 +1248,17 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me) + 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; +-- +2.40.0 + diff --git a/SOURCES/0015-libxtables-Register-multiple-extensions-in-ascending.patch b/SOURCES/0015-libxtables-Register-multiple-extensions-in-ascending.patch new file mode 100644 index 0000000..0657227 --- /dev/null +++ b/SOURCES/0015-libxtables-Register-multiple-extensions-in-ascending.patch @@ -0,0 +1,51 @@ +From 1ae06e3a2da1c21a75b55609b99d1ab3ef6cf709 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 22 Sep 2020 20:01:15 +0200 +Subject: [PATCH] libxtables: Register multiple extensions in ascending order + +The newly introduced ordered insert algorithm in +xtables_register_{match,target}() works best if extensions of same name +are passed in ascending revisions. Since this is the case in about all +extensions' arrays, iterate over them from beginning to end. + +Signed-off-by: Phil Sutter +(cherry picked from commit b5f1a3beac1d1f2b96c8be8ebec450f5ea758090) +--- + libxtables/xtables.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 10d4e70328500..7152c6576cd63 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -1141,9 +1141,10 @@ static bool xtables_fully_register_pending_match(struct xtables_match *me, + + 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) +@@ -1269,9 +1270,10 @@ static bool xtables_fully_register_pending_target(struct xtables_target *me, + + 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 */ +-- +2.40.0 + diff --git a/SOURCES/0016-nft-Make-batch_add_chain-return-the-added-batch-obje.patch b/SOURCES/0016-nft-Make-batch_add_chain-return-the-added-batch-obje.patch new file mode 100644 index 0000000..72d9782 --- /dev/null +++ b/SOURCES/0016-nft-Make-batch_add_chain-return-the-added-batch-obje.patch @@ -0,0 +1,161 @@ +From 99bf566bfcabce101940b28a12f61c637ccfb489 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 3 Oct 2020 17:46:09 +0200 +Subject: [PATCH] nft: Make batch_add_chain() return the added batch object + +Do this so in a later patch the 'skip' field can be adjusted. + +While being at it, simplify a few callers and eliminate the need for a +'ret' variable. + +Signed-off-by: Phil Sutter +Reviewed-by: Florian Westphal +(cherry picked from commit 0d77e64e8d9b8a3984b01a4951524dc40f61f4b6) +--- + iptables/nft.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index e795d4ae6d241..ec5f7457e4784 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -389,10 +389,11 @@ batch_set_add(struct nft_handle *h, enum obj_update_type type, + 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 * +@@ -920,7 +921,6 @@ int nft_chain_set(struct nft_handle *h, const char *table, + const struct xt_counters *counters) + { + struct nftnl_chain *c = NULL; +- int ret; + + nft_fn = nft_chain_set; + +@@ -934,10 +934,11 @@ int nft_chain_set(struct nft_handle *h, const char *table, + 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) +@@ -1752,7 +1753,6 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl + { + struct nftnl_chain_list *list; + struct nftnl_chain *c; +- int ret; + + nft_fn = nft_chain_user_add; + +@@ -1772,14 +1772,15 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl + 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); + + /* 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) +@@ -1787,7 +1788,6 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table + struct nftnl_chain_list *list; + struct nftnl_chain *c; + bool created = false; +- int ret; + + c = nft_chain_find(h, table, chain); + if (c) { +@@ -1812,14 +1812,15 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table + if (!created) + return 1; + +- 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); + + /* the core expects 1 for success and 0 for error */ +- return ret == 0 ? 1 : 0; ++ return 1; + } + + /* From linux/netlink.h */ +@@ -1837,7 +1838,6 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data) + { + struct chain_user_del_data *d = data; + struct nft_handle *h = d->handle; +- int ret; + + /* don't delete built-in chain */ + if (nft_chain_builtin(c)) +@@ -1849,8 +1849,7 @@ static int __nft_chain_user_del(struct nftnl_chain *c, void *data) + + /* 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); +@@ -1925,7 +1924,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain, + { + struct nftnl_chain *c; + uint64_t handle; +- int ret; + + nft_fn = nft_chain_user_rename; + +@@ -1954,10 +1952,11 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain, + 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) +@@ -3404,7 +3403,7 @@ static int __nft_chain_zero_counters(struct nftnl_chain *c, void *data) + 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; + } + +-- +2.40.0 + diff --git a/SOURCES/0017-nft-Fix-error-reporting-for-refreshed-transactions.patch b/SOURCES/0017-nft-Fix-error-reporting-for-refreshed-transactions.patch new file mode 100644 index 0000000..13425ce --- /dev/null +++ b/SOURCES/0017-nft-Fix-error-reporting-for-refreshed-transactions.patch @@ -0,0 +1,41 @@ +From 8ab5e29f192187bc12a2064036cf406de60b2cd5 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 5 Oct 2020 15:54:35 +0200 +Subject: [PATCH] nft: Fix error reporting for refreshed transactions + +When preparing a batch from the list of batch objects in nft_action(), +the sequence number used for each object is stored within that object +for later matching against returned error messages. Though if the +transaction has to be refreshed, some of those objects may be skipped, +other objects take over their sequence number and errors are matched to +skipped objects. Avoid this by resetting the skipped object's sequence +number to zero. + +Fixes: 58d7de0181f61 ("xtables: handle concurrent ruleset modifications") +Signed-off-by: Phil Sutter +Reviewed-by: Florian Westphal +(cherry picked from commit e98b825a037807bf6c918eb66ee9682cc4c46183) +--- + iptables/nft.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index ec5f7457e4784..d3eb0840a9fc0 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -2832,9 +2832,10 @@ static int nft_action(struct nft_handle *h, int action) + 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) { +-- +2.40.0 + diff --git a/SOURCES/0018-nft-Fix-for-concurrent-noflush-restore-calls.patch b/SOURCES/0018-nft-Fix-for-concurrent-noflush-restore-calls.patch new file mode 100644 index 0000000..2045934 --- /dev/null +++ b/SOURCES/0018-nft-Fix-for-concurrent-noflush-restore-calls.patch @@ -0,0 +1,235 @@ +From 412c52e9ab9d5d1d1a1e5e09a122cca43895451a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 5 Oct 2020 16:06:49 +0200 +Subject: [PATCH] nft: Fix for concurrent noflush restore calls + +Transaction refresh was broken with regards to nft_chain_restore(): It +created a rule flush batch object only if the chain was found in cache +and a chain add object only if the chain was not found. Yet with +concurrent ruleset updates, one has to expect both situations: + +* If a chain vanishes, the rule flush job must be skipped and instead + the chain add job become active. + +* If a chain appears, the chain add job must be skipped and instead + rules flushed. + +Change the code accordingly: Create both batch objects and set their +'skip' field depending on the situation in cache and adjust both in +nft_refresh_transaction(). + +As a side-effect, the implicit rule flush becomes explicit and all +handling of implicit batch jobs is dropped along with the related field +indicating such. + +Reuse the 'implicit' parameter of __nft_rule_flush() to control the +initial 'skip' field value instead. + +A subtle caveat is vanishing of existing chains: Creating the chain add +job based on the chain in cache causes a netlink message containing that +chain's handle which the kernel dislikes. Therefore unset the chain's +handle in that case. + +Fixes: 58d7de0181f61 ("xtables: handle concurrent ruleset modifications") +Signed-off-by: Phil Sutter +(cherry picked from commit dac904bdcd9a18aabafee7275ccf0c2bd53800f3) +--- + iptables/nft.c | 58 ++++++++++--------- + .../ipt-restore/0016-concurrent-restores_0 | 53 +++++++++++++++++ + 2 files changed, 83 insertions(+), 28 deletions(-) + create mode 100755 iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 + +diff --git a/iptables/nft.c b/iptables/nft.c +index d3eb0840a9fc0..bdb633a82a655 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -265,7 +265,6 @@ struct obj_update { + 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; +@@ -1668,7 +1667,7 @@ struct nftnl_set *nft_set_batch_lookup_byid(struct nft_handle *h, + + 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; +@@ -1690,7 +1689,7 @@ __nft_rule_flush(struct nft_handle *h, const char *table, + return; + } + +- obj->implicit = implicit; ++ obj->skip = skip; + } + + int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, +@@ -1786,17 +1785,12 @@ int nft_chain_user_add(struct nft_handle *h, const char *chain, const char *tabl + int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table) + { + struct nftnl_chain_list *list; ++ struct obj_update *obj; + struct nftnl_chain *c; + bool created = false; + + 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 { ++ if (!c) { + c = nftnl_chain_alloc(); + if (!c) + return 0; +@@ -1804,20 +1798,26 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table + 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); ++ list = nft_chain_list_get(h, table, chain); ++ if (list) ++ nftnl_chain_list_add(c, list); ++ } else { ++ /* 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); ++ } + +- if (!created) +- return 1; ++ __nft_rule_flush(h, table, chain, false, created); + +- if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c)) ++ 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 1; +@@ -2751,11 +2751,6 @@ static void nft_refresh_transaction(struct nft_handle *h) + 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); +@@ -2781,14 +2776,22 @@ static void nft_refresh_transaction(struct nft_handle *h) + + 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: +@@ -2800,7 +2803,6 @@ static void nft_refresh_transaction(struct nft_handle *h) + 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: +diff --git a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 +new file mode 100755 +index 0000000000000..53ec12fa368af +--- /dev/null ++++ b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 +@@ -0,0 +1,53 @@ ++#!/bin/bash ++ ++set -e ++ ++RS="*filter ++:INPUT ACCEPT [12024:3123388] ++:FORWARD ACCEPT [0:0] ++:OUTPUT ACCEPT [12840:2144421] ++:FOO - [0:0] ++:BAR0 - [0:0] ++:BAR1 - [0:0] ++:BAR2 - [0:0] ++:BAR3 - [0:0] ++:BAR4 - [0:0] ++:BAR5 - [0:0] ++:BAR6 - [0:0] ++:BAR7 - [0:0] ++:BAR8 - [0:0] ++:BAR9 - [0:0] ++" ++ ++RS1="$RS ++-X BAR3 ++-X BAR6 ++-X BAR9 ++-A FOO -s 9.9.0.1/32 -j BAR1 ++-A FOO -s 9.9.0.2/32 -j BAR2 ++-A FOO -s 9.9.0.4/32 -j BAR4 ++-A FOO -s 9.9.0.5/32 -j BAR5 ++-A FOO -s 9.9.0.7/32 -j BAR7 ++-A FOO -s 9.9.0.8/32 -j BAR8 ++COMMIT ++" ++ ++RS2="$RS ++-X BAR2 ++-X BAR5 ++-X BAR7 ++-A FOO -s 9.9.0.1/32 -j BAR1 ++-A FOO -s 9.9.0.3/32 -j BAR3 ++-A FOO -s 9.9.0.4/32 -j BAR4 ++-A FOO -s 9.9.0.6/32 -j BAR6 ++-A FOO -s 9.9.0.8/32 -j BAR8 ++-A FOO -s 9.9.0.9/32 -j BAR9 ++COMMIT ++" ++ ++for n in $(seq 1 10); do ++ $XT_MULTI iptables-restore --noflush -w <<< "$RS1" & ++ $XT_MULTI iptables-restore --noflush -w <<< "$RS2" & ++ wait -n ++ wait -n ++done +-- +2.40.0 + diff --git a/SOURCES/0019-tests-shell-Improve-concurrent-noflush-restore-test-.patch b/SOURCES/0019-tests-shell-Improve-concurrent-noflush-restore-test-.patch new file mode 100644 index 0000000..7044aa3 --- /dev/null +++ b/SOURCES/0019-tests-shell-Improve-concurrent-noflush-restore-test-.patch @@ -0,0 +1,54 @@ +From bb80a77e8b0b2b557c4a2afd88446853e19236da Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 26 Oct 2020 17:25:03 +0100 +Subject: [PATCH] tests: shell: Improve concurrent noflush restore test a bit + +The described issue happens only if chain FOO does not exist at program +start so flush the ruleset after each iteration to make sure this is the +case. Sadly the bug is still not 100% reproducible on my testing VM. + +While being at it, add a paragraph describing what exact situation the +test is trying to provoke. + +Fixes: dac904bdcd9a1 ("nft: Fix for concurrent noflush restore calls") +Signed-off-by: Phil Sutter +(cherry picked from commit ed8c8b9316451a4499eeb592d2cf7d782bbe4e9a) +--- + .../ipt-restore/0016-concurrent-restores_0 | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 +index 53ec12fa368af..aa746ab458a3c 100755 +--- a/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 ++++ b/iptables/tests/shell/testcases/ipt-restore/0016-concurrent-restores_0 +@@ -1,5 +1,14 @@ + #!/bin/bash + ++# test for iptables-restore --noflush skipping an explicitly requested chain ++# flush because the chain did not exist when cache was fetched. In order to ++# expect for that chain to appear when refreshing the transaction (due to a ++# concurrent ruleset change), the chain flush job has to be present in batch ++# job list (although disabled at first). ++# The input line requesting chain flush is ':FOO - [0:0]'. RS1 and RS2 contents ++# are crafted to cause EBUSY when deleting the BAR* chains if FOO is not ++# flushed in the same transaction. ++ + set -e + + RS="*filter +@@ -45,7 +54,12 @@ RS2="$RS + COMMIT + " + ++NORS="*filter ++COMMIT ++" ++ + for n in $(seq 1 10); do ++ $XT_MULTI iptables-restore <<< "$NORS" + $XT_MULTI iptables-restore --noflush -w <<< "$RS1" & + $XT_MULTI iptables-restore --noflush -w <<< "$RS2" & + wait -n +-- +2.40.0 + diff --git a/SOURCES/0020-nft-Optimize-class-based-IP-prefix-matches.patch b/SOURCES/0020-nft-Optimize-class-based-IP-prefix-matches.patch new file mode 100644 index 0000000..43b98d6 --- /dev/null +++ b/SOURCES/0020-nft-Optimize-class-based-IP-prefix-matches.patch @@ -0,0 +1,149 @@ +From a48e8c5a7433c8f7d0f28ed321081b25f3b63a4a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 2 Oct 2020 09:44:38 +0200 +Subject: [PATCH] nft: Optimize class-based IP prefix matches + +Payload expression works on byte-boundaries, leverage this with suitable +prefix lengths. + +Signed-off-by: Phil Sutter +(cherry picked from commit 323259001d617ae359430a03ee3d3e7f107684e0) +--- + iptables/nft-arp.c | 11 ++++++++--- + iptables/nft-ipv4.c | 6 ++++-- + iptables/nft-ipv6.c | 6 ++++-- + iptables/nft-shared.c | 14 ++++++++++---- + iptables/nft-shared.h | 4 ++++ + 5 files changed, 30 insertions(+), 11 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index 67f4529d93652..952f0c6916e59 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -303,7 +303,8 @@ static bool nft_arp_parse_devaddr(struct nft_xt_ctx *ctx, + 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; +@@ -360,7 +361,9 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + 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) +@@ -380,7 +383,9 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + 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) +diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c +index afdecf9711e64..ce702041af0f4 100644 +--- a/iptables/nft-ipv4.c ++++ b/iptables/nft-ipv4.c +@@ -199,7 +199,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx, + 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 +213,8 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx, + 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 --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c +index 4008b7eab4f2a..c877ec6d10887 100644 +--- a/iptables/nft-ipv6.c ++++ b/iptables/nft-ipv6.c +@@ -146,7 +146,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx, + 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 +160,8 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx, + 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 --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 7741d23befc5a..545e9c60fa015 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -166,16 +166,22 @@ void add_addr(struct nftnl_rule *r, int offset, + void *data, void *mask, size_t len, uint32_t op) + { + 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, NFT_PAYLOAD_NETWORK_HEADER); ++ ++ if (bitwise) + add_bitwise(r, mask, len); + + add_cmp_ptr(r, op, data, len); +diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h +index 94437ffe7990c..811fb9a1ebe76 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -246,4 +246,8 @@ void xtables_restore_parse(struct nft_handle *h, + 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 +-- +2.40.0 + diff --git a/SOURCES/0021-ebtables-Optimize-masked-MAC-address-matches.patch b/SOURCES/0021-ebtables-Optimize-masked-MAC-address-matches.patch new file mode 100644 index 0000000..ed8b40c --- /dev/null +++ b/SOURCES/0021-ebtables-Optimize-masked-MAC-address-matches.patch @@ -0,0 +1,217 @@ +From 06f53a3a19c829417c4083fdbbbeba14c92c7b04 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 30 Oct 2020 14:08:33 +0100 +Subject: [PATCH] ebtables: Optimize masked MAC address matches + +Just like with class-based prefix matches in iptables-nft, optimize +masked MAC address matches if the mask is on a byte-boundary. + +To reuse the logic in add_addr(), extend it to accept the payload base +value via parameter. + +Signed-off-by: Phil Sutter +(cherry picked from commit 274cb05edc58d6fa982a34c84b2f4cf6acc3e335) +--- + iptables/nft-arp.c | 12 ++++++++---- + iptables/nft-bridge.c | 22 ++++++++++------------ + iptables/nft-ipv4.c | 6 ++++-- + iptables/nft-ipv6.c | 6 ++++-- + iptables/nft-shared.c | 5 ++--- + iptables/nft-shared.h | 3 ++- + 6 files changed, 30 insertions(+), 24 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index 952f0c6916e59..5dc38da831aa0 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -178,7 +178,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + + if (need_devaddr(&fw->arp.src_devaddr)) { + op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_SRCDEVADDR); +- add_addr(r, sizeof(struct arphdr), ++ add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, ++ sizeof(struct arphdr), + &fw->arp.src_devaddr.addr, + &fw->arp.src_devaddr.mask, + fw->arp.arhln, op); +@@ -189,7 +190,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + 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, ++ 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); + } +@@ -197,7 +199,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + + 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), ++ 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); +@@ -207,7 +210,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + 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, ++ 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); + } +diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c +index dbf11eb5e1fa8..c1a2c209cc1aa 100644 +--- a/iptables/nft-bridge.c ++++ b/iptables/nft-bridge.c +@@ -159,20 +159,16 @@ static int nft_bridge_add(struct nft_handle *h, + + 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 +254,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, + 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 +269,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, + 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 --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c +index ce702041af0f4..fdc15c6f04066 100644 +--- a/iptables/nft-ipv4.c ++++ b/iptables/nft-ipv4.c +@@ -50,13 +50,15 @@ static int nft_ipv4_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + + 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); + } +diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c +index c877ec6d10887..130ad3e6e7c44 100644 +--- a/iptables/nft-ipv6.c ++++ b/iptables/nft-ipv6.c +@@ -51,7 +51,8 @@ static int nft_ipv6_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + !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 @@ static int nft_ipv6_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + !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); + } +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 545e9c60fa015..10553ab26823b 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -20,7 +20,6 @@ + + #include + +-#include + #include + #include + +@@ -162,7 +161,7 @@ void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op) + 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 unsigned char *m = mask; +@@ -179,7 +178,7 @@ void add_addr(struct nftnl_rule *r, int offset, + if (!bitwise) + len = i; + +- add_payload(r, offset, len, NFT_PAYLOAD_NETWORK_HEADER); ++ add_payload(r, offset, len, base); + + if (bitwise) + add_bitwise(r, mask, len); +diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h +index 811fb9a1ebe76..6fc81d9ce08ef 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -8,6 +8,7 @@ + #include + + #include ++#include + + #include "xshared.h" + +@@ -121,7 +122,7 @@ void add_cmp_u16(struct nftnl_rule *r, uint16_t val, uint32_t op); + 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); +-- +2.40.0 + diff --git a/SOURCES/0022-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch b/SOURCES/0022-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch new file mode 100644 index 0000000..ca2df0d --- /dev/null +++ b/SOURCES/0022-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch @@ -0,0 +1,365 @@ +From f07a5fdd6c2a5ffe962ba77b8bfa08673f3b9408 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 10 Nov 2020 14:50:46 +0100 +Subject: [PATCH] tests/shell: Add test for bitwise avoidance fixes + +Masked address matching was recently improved to avoid bitwise +expression if the given mask covers full bytes. Make use of nft netlink +debug output to assert iptables-nft generates the right bytecode for +each situation. + +Signed-off-by: Phil Sutter +(cherry picked from commit 81a2e128512837b53e5b9ea501b6c8dc64eeca78) +--- + .../nft-only/0009-needless-bitwise_0 | 339 ++++++++++++++++++ + 1 file changed, 339 insertions(+) + create mode 100755 iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 + +diff --git a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +new file mode 100755 +index 0000000000000..c5c6e706a1029 +--- /dev/null ++++ b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +@@ -0,0 +1,339 @@ ++#!/bin/bash -x ++ ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++set -e ++ ++nft flush ruleset ++ ++( ++ echo "*filter" ++ for plen in "" 32 30 24 16 8 0; do ++ addr="10.1.2.3${plen:+/}$plen" ++ echo "-A OUTPUT -d $addr" ++ done ++ echo "COMMIT" ++) | $XT_MULTI iptables-restore ++ ++( ++ echo "*filter" ++ for plen in "" 128 124 120 112 88 80 64 48 16 8 0; do ++ addr="feed:c0ff:ee00:0102:0304:0506:0708:090A${plen:+/}$plen" ++ echo "-A OUTPUT -d $addr" ++ done ++ echo "COMMIT" ++) | $XT_MULTI ip6tables-restore ++ ++masks=" ++ff:ff:ff:ff:ff:ff ++ff:ff:ff:ff:ff:f0 ++ff:ff:ff:ff:ff:00 ++ff:ff:ff:ff:00:00 ++ff:ff:ff:00:00:00 ++ff:ff:00:00:00:00 ++ff:00:00:00:00:00 ++" ++( ++ echo "*filter" ++ for plen in "" 32 30 24 16 8 0; do ++ addr="10.1.2.3${plen:+/}$plen" ++ echo "-A OUTPUT -d $addr" ++ done ++ for mask in $masks; do ++ echo "-A OUTPUT --destination-mac fe:ed:00:c0:ff:ee/$mask" ++ done ++ echo "COMMIT" ++) | $XT_MULTI arptables-restore ++ ++( ++ echo "*filter" ++ for mask in $masks; do ++ echo "-A OUTPUT -d fe:ed:00:c0:ff:ee/$mask" ++ done ++ echo "COMMIT" ++) | $XT_MULTI ebtables-restore ++ ++EXPECT="ip filter OUTPUT 4 ++ [ payload load 4b @ network header + 16 => reg 1 ] ++ [ cmp eq reg 1 0x0302010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip filter OUTPUT 5 4 ++ [ payload load 4b @ network header + 16 => reg 1 ] ++ [ cmp eq reg 1 0x0302010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip filter OUTPUT 6 5 ++ [ payload load 4b @ network header + 16 => reg 1 ] ++ [ bitwise reg 1 = (reg=1 & 0xfcffffff ) ^ 0x00000000 ] ++ [ cmp eq reg 1 0x0002010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip filter OUTPUT 7 6 ++ [ payload load 3b @ network header + 16 => reg 1 ] ++ [ cmp eq reg 1 0x0002010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip filter OUTPUT 8 7 ++ [ payload load 2b @ network header + 16 => reg 1 ] ++ [ cmp eq reg 1 0x0000010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip filter OUTPUT 9 8 ++ [ payload load 1b @ network header + 16 => reg 1 ] ++ [ cmp eq reg 1 0x0000000a ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip filter OUTPUT 10 9 ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 4 ++ [ payload load 16b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 5 4 ++ [ payload load 16b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x0a090807 ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 6 5 ++ [ payload load 16b @ network header + 24 => reg 1 ] ++ [ bitwise reg 1 = (reg=1 & 0xffffffff 0xffffffff 0xffffffff 0xf0ffffff ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 7 6 ++ [ payload load 15b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 8 7 ++ [ payload load 14b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00000807 ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 9 8 ++ [ payload load 11b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00050403 ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 10 9 ++ [ payload load 10b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x00000403 ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 11 10 ++ [ payload load 8b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x020100ee ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 12 11 ++ [ payload load 6b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0xffc0edfe 0x000000ee ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 13 12 ++ [ payload load 2b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0x0000edfe ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 14 13 ++ [ payload load 1b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0x000000fe ] ++ [ counter pkts 0 bytes 0 ] ++ ++ip6 filter OUTPUT 15 14 ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 3 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 4b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0x0302010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 4 3 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 4b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0x0302010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 5 4 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 4b @ network header + 24 => reg 1 ] ++ [ bitwise reg 1 = (reg=1 & 0xfcffffff ) ^ 0x00000000 ] ++ [ cmp eq reg 1 0x0002010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 6 5 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 3b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0x0002010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 7 6 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 2b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0x0000010a ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 8 7 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 1b @ network header + 24 => reg 1 ] ++ [ cmp eq reg 1 0x0000000a ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 9 8 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 10 9 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 6b @ network header + 18 => reg 1 ] ++ [ cmp eq reg 1 0xc000edfe 0x0000eeff ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 11 10 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 6b @ network header + 18 => reg 1 ] ++ [ bitwise reg 1 = (reg=1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] ++ [ cmp eq reg 1 0xc000edfe 0x0000e0ff ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 12 11 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 5b @ network header + 18 => reg 1 ] ++ [ cmp eq reg 1 0xc000edfe 0x000000ff ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 13 12 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 4b @ network header + 18 => reg 1 ] ++ [ cmp eq reg 1 0xc000edfe ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 14 13 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 3b @ network header + 18 => reg 1 ] ++ [ cmp eq reg 1 0x0000edfe ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 15 14 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 2b @ network header + 18 => reg 1 ] ++ [ cmp eq reg 1 0x0000edfe ] ++ [ counter pkts 0 bytes 0 ] ++ ++arp filter OUTPUT 16 15 ++ [ payload load 2b @ network header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x00000100 ] ++ [ payload load 1b @ network header + 4 => reg 1 ] ++ [ cmp eq reg 1 0x00000006 ] ++ [ payload load 1b @ network header + 5 => reg 1 ] ++ [ cmp eq reg 1 0x00000004 ] ++ [ payload load 1b @ network header + 18 => reg 1 ] ++ [ cmp eq reg 1 0x000000fe ] ++ [ counter pkts 0 bytes 0 ] ++ ++bridge filter OUTPUT 4 ++ [ payload load 6b @ link header + 0 => reg 1 ] ++ [ cmp eq reg 1 0xc000edfe 0x0000eeff ] ++ [ counter pkts 0 bytes 0 ] ++ ++bridge filter OUTPUT 5 4 ++ [ payload load 6b @ link header + 0 => reg 1 ] ++ [ bitwise reg 1 = (reg=1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] ++ [ cmp eq reg 1 0xc000edfe 0x0000e0ff ] ++ [ counter pkts 0 bytes 0 ] ++ ++bridge filter OUTPUT 6 5 ++ [ payload load 5b @ link header + 0 => reg 1 ] ++ [ cmp eq reg 1 0xc000edfe 0x000000ff ] ++ [ counter pkts 0 bytes 0 ] ++ ++bridge filter OUTPUT 7 6 ++ [ payload load 4b @ link header + 0 => reg 1 ] ++ [ cmp eq reg 1 0xc000edfe ] ++ [ counter pkts 0 bytes 0 ] ++ ++bridge filter OUTPUT 8 7 ++ [ payload load 3b @ link header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x0000edfe ] ++ [ counter pkts 0 bytes 0 ] ++ ++bridge filter OUTPUT 9 8 ++ [ payload load 2b @ link header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x0000edfe ] ++ [ counter pkts 0 bytes 0 ] ++ ++bridge filter OUTPUT 10 9 ++ [ payload load 1b @ link header + 0 => reg 1 ] ++ [ cmp eq reg 1 0x000000fe ] ++ [ counter pkts 0 bytes 0 ] ++" ++ ++diff -u -Z <(echo "$EXPECT") <(nft --debug=netlink list ruleset | awk '/^table/{exit} {print}') +-- +2.40.0 + diff --git a/SOURCES/0023-ebtables-Fix-for-broken-chain-renaming.patch b/SOURCES/0023-ebtables-Fix-for-broken-chain-renaming.patch new file mode 100644 index 0000000..697a336 --- /dev/null +++ b/SOURCES/0023-ebtables-Fix-for-broken-chain-renaming.patch @@ -0,0 +1,61 @@ +From d4e535422a9f4908b6d4b331b9e9cffe7ef161f3 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 17 Nov 2020 11:38:27 +0100 +Subject: [PATCH] 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 +(cherry picked from commit 55b7c71dce7144f4dc0297c17abf0f04879ee247) +--- + 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(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index bdb633a82a655..bdf252198f155 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -1932,9 +1932,6 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain, + return 0; + } + +- /* 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) { +diff --git a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 +index 0c1eb4ca66f52..6f11bd12593dd 100755 +--- 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 +diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c +index 375a95d1d5c75..6df5839f07436 100644 +--- a/iptables/xtables-eb.c ++++ b/iptables/xtables-eb.c +@@ -853,6 +853,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, + 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) +-- +2.40.0 + diff --git a/SOURCES/0024-xtables-arp-Don-t-use-ARPT_INV_.patch b/SOURCES/0024-xtables-arp-Don-t-use-ARPT_INV_.patch new file mode 100644 index 0000000..9d2debc --- /dev/null +++ b/SOURCES/0024-xtables-arp-Don-t-use-ARPT_INV_.patch @@ -0,0 +1,374 @@ +From 38e8df1b4409387145c79fc358419d59b5ec3800 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 3 Nov 2020 12:21:29 +0100 +Subject: [PATCH] xtables-arp: Don't use ARPT_INV_* + +Arptables invflags are partly identical to IPT_INV_* ones but the bits +are differently assigned. Eliminate this incompatibility by definition +of the unique invflags in nft-arp.h on bits that don't collide with +IPT_INV_* ones, then use those in combination with IPT_INV_* ones in +arptables-specific code. + +Note that ARPT_INV_ARPPRO is replaced by IPT_INV_PROTO although these +are in fact different options - yet since '-p' option is not supported +by arptables, this does not lead to a collision. + +Signed-off-by: Phil Sutter +(cherry picked from commit 44457c0805905ea22b4ecf9156648e774dd29155) +--- + iptables/nft-arp.c | 92 ++++++++++++++++-------------------------- + iptables/nft-arp.h | 7 ++++ + iptables/xtables-arp.c | 22 +++++----- + 3 files changed, 53 insertions(+), 68 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index 5dc38da831aa0..c82ffdc95e300 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -134,34 +134,34 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + 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,15 +169,15 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + 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); ++ op = nft_invflags2cmp(fw->arp.invflags, IPT_INV_SRCDEVADDR); + add_addr(r, NFT_PAYLOAD_NETWORK_HEADER, + sizeof(struct arphdr), + &fw->arp.src_devaddr.addr, +@@ -188,8 +188,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + + 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); ++ 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, +@@ -198,7 +198,7 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + + + if (need_devaddr(&fw->arp.tgt_devaddr)) { +- op = nft_invflags2cmp(fw->arp.invflags, ARPT_INV_TGTDEVADDR); ++ 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, +@@ -208,8 +208,8 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + + 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); ++ 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, +@@ -240,28 +240,6 @@ static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + 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) + { +@@ -273,7 +251,7 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e, + 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, +@@ -330,33 +308,33 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + 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); +@@ -371,12 +349,12 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + } + + 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) + +@@ -393,7 +371,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + } + + if (inv) +- fw->arp.invflags |= ARPT_INV_TGTIP; ++ fw->arp.invflags |= IPT_INV_DSTIP; + } + break; + } +@@ -448,7 +426,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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 = " "; + } +@@ -466,13 +444,13 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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))); +@@ -489,7 +467,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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, +@@ -498,7 +476,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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))); +@@ -515,7 +493,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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, +@@ -525,7 +503,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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) +@@ -536,7 +514,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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]); +@@ -551,7 +529,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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"); +@@ -565,7 +543,7 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + 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 --git a/iptables/nft-arp.h b/iptables/nft-arp.h +index 3411fc3d7c7b3..0d93a31f563b1 100644 +--- a/iptables/nft-arp.h ++++ b/iptables/nft-arp.h +@@ -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 --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c +index 8632774dfb705..3a35dcd107e19 100644 +--- a/iptables/xtables-arp.c ++++ b/iptables/xtables-arp.c +@@ -113,22 +113,22 @@ struct xtables_globals arptables_globals = { + 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, ++/* 2 */ IPT_INV_SRCDEVADDR, ++/* 3 */ IPT_INV_TGTDEVADDR, ++/* -l */ IPT_INV_ARPHLN, ++/* 4 */ IPT_INV_ARPOP, ++/* 5 */ IPT_INV_ARPHRD, ++/* 6 */ IPT_INV_PROTO, + }; + + /***********************************************/ +@@ -901,7 +901,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, + &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"); + +-- +2.40.0 + diff --git a/SOURCES/0025-xshared-Merge-some-command-option-related-code.patch b/SOURCES/0025-xshared-Merge-some-command-option-related-code.patch new file mode 100644 index 0000000..7284b65 --- /dev/null +++ b/SOURCES/0025-xshared-Merge-some-command-option-related-code.patch @@ -0,0 +1,517 @@ +From 003b063b1b40503bc996a4f88c1941c91a0c550b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 30 Oct 2020 12:42:57 +0100 +Subject: [PATCH] xshared: Merge some command option-related code + +Add OPT_FRAGMENT define into the enum of other OPT_* defines at the +right position and adjust the arptables-specific ones that follow +accordingly. Appropriately adjust inverse_for_options array in +xtables-arp.c. + +Extend optflags from iptables.c by the arptables values for the sake of +completeness, then move it to xshared.h along with NUMBER_OF_OPT +definition. As a side-effect, this fixes for wrong ordering of entries +in arptables' 'optflags' copy. + +Add arptables-specific bits to commands_v_options table (the speicific +options are matches on ARP header fields, just treat them like '-s' +option. This is also just a cosmetic change, arptables doesn't have a +generic_opt_check() implementation and hence doesn't use such a table. + +With things potentially ready for common use, move commands_v_options +table along with generic_opt_check() and opt2char() into xshared.c and +drop the local (identical) implementations from iptables.c, ip6tables.c +xtables.c and xtables-arp.c. While doing so, fix ordering of entries in +that table: the row for CMD_ZERO_NUM was in the wrong position. Since +all moved rows though are identical, this had no effect in practice. + +Fixes: d960a991350ca ("xtables-arp: Integrate OPT_* defines into xshared.h") +Fixes: 384958620abab ("use nf_tables and nf_tables compatibility interface") +Signed-off-by: Phil Sutter +(cherry picked from commit 8bd4b4f79b5de483353a8c0d0962e71934b7bdd2) +--- + iptables/ip6tables.c | 79 ----------------------------------------- + iptables/iptables.c | 80 ------------------------------------------ + iptables/xshared.c | 74 ++++++++++++++++++++++++++++++++++++++ + iptables/xshared.h | 20 +++++++---- + iptables/xtables-arp.c | 14 +------- + iptables/xtables.c | 80 ------------------------------------------ + 6 files changed, 89 insertions(+), 258 deletions(-) + +diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c +index 576c2cf8b0d9f..c95355b091568 100644 +--- a/iptables/ip6tables.c ++++ b/iptables/ip6tables.c +@@ -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 @@ struct xtables_globals ip6tables_globals = { + .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 @@ ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...) + 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 --git a/iptables/iptables.c b/iptables/iptables.c +index 88ef6cf666d4b..7d6183116d265 100644 +--- a/iptables/iptables.c ++++ b/iptables/iptables.c +@@ -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 @@ struct xtables_globals iptables_globals = { + .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 @@ iptables_exit_error(enum xtables_exittype status, const char *msg, ...) + 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 --git a/iptables/xshared.c b/iptables/xshared.c +index c1d1371a6d54a..fe37c30a085d6 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -774,3 +774,77 @@ int parse_rulenumber(const char *rule) + + return rulenum; + } ++ ++/* 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 2 3 l 4 5 6 */ ++/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' ',' ',' ',' ',' ',' ',' ',' '}, ++/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' ',' ',' ',' ',' ',' ',' '}, ++/*DELETE_NUM*/{'x','x','x','x','x',' ','x','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','x','x','x','x','x','x'}, ++/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'}, ++/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'}, ++/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'}, ++/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'}, ++/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' ','x','x','x','x','x','x','x'}, ++/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'}, ++/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'}, ++/*ZERO_NUM*/ {'x','x','x','x','x',' ','x','x','x','x','x','x','x','x','x','x','x','x'}, ++/*CHECK*/ {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x',' ',' ',' ',' ',' ',' ',' '}, ++}; ++ ++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; ++} +diff --git a/iptables/xshared.h b/iptables/xshared.h +index c41bd054bf36f..9159b2b1f3768 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -30,15 +30,20 @@ enum { + 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 @@ void add_command(unsigned int *cmd, const int newcmd, + 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 --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c +index 3a35dcd107e19..0695504892b74 100644 +--- a/iptables/xtables-arp.c ++++ b/iptables/xtables-arp.c +@@ -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' }, +@@ -123,6 +119,7 @@ static int inverse_for_options[] = + /* -o */ IPT_INV_VIA_OUT, + /*--line*/ 0, + /* -c */ 0, ++/* -f */ 0, + /* 2 */ IPT_INV_SRCDEVADDR, + /* 3 */ IPT_INV_TGTDEVADDR, + /* -l */ IPT_INV_ARPHLN, +@@ -327,15 +324,6 @@ printhelp(void) + } + } + +-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) + { +diff --git a/iptables/xtables.c b/iptables/xtables.c +index 9d2e441e0b773..9779bd83d53b3 100644 +--- a/iptables/xtables.c ++++ b/iptables/xtables.c +@@ -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 @@ struct xtables_globals xtables_globals = { + .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 @@ xtables_exit_error(enum xtables_exittype status, const char *msg, ...) + 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. +-- +2.40.0 + diff --git a/SOURCES/0026-tests-shell-Test-for-fixed-extension-registration.patch b/SOURCES/0026-tests-shell-Test-for-fixed-extension-registration.patch new file mode 100644 index 0000000..aa7621f --- /dev/null +++ b/SOURCES/0026-tests-shell-Test-for-fixed-extension-registration.patch @@ -0,0 +1,52 @@ +From 8d0f11ea353caa254b65b4fde240e5d3a8fe12a7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 4 Dec 2020 17:44:51 +0100 +Subject: [PATCH] tests/shell: Test for fixed extension registration + +Use strace to look at iptables-restore behaviour with typically +problematic input (conntrack revision 0 is no longer supported by +current kernels) to make sure the fix in commit a1eaaceb0460b +("libxtables: Simplify pending extension registration") is still +effective. + +Signed-off-by: Phil Sutter +(cherry picked from commit 93d0c97e8b6713f51ba679e01a1338d4f9076e7c) +--- + .../0017-pointless-compat-checks_0 | 25 +++++++++++++++++++ + 1 file changed, 25 insertions(+) + create mode 100755 iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 + +diff --git a/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 +new file mode 100755 +index 0000000000000..cf73de32df409 +--- /dev/null ++++ b/iptables/tests/shell/testcases/ipt-restore/0017-pointless-compat-checks_0 +@@ -0,0 +1,25 @@ ++#!/bin/bash ++ ++# A bug in extension registration would leave unsupported older extension ++# revisions in pending list and get compatibility checked again for each rule ++# using them. With SELinux enabled, the resulting socket() call per rule leads ++# to significant slowdown (~50% performance in worst cases). ++ ++set -e ++ ++strace --version >/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 ]] +-- +2.40.0 + diff --git a/SOURCES/0027-extensions-dccp-Fix-for-DCCP-type-INVALID.patch b/SOURCES/0027-extensions-dccp-Fix-for-DCCP-type-INVALID.patch new file mode 100644 index 0000000..2fe9c6d --- /dev/null +++ b/SOURCES/0027-extensions-dccp-Fix-for-DCCP-type-INVALID.patch @@ -0,0 +1,176 @@ +From 8a10ad0e149cf1c6d0c34bd554a8e0a35cdf3e8d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 2 Dec 2020 13:37:06 +0100 +Subject: [PATCH] extensions: dccp: Fix for DCCP type 'INVALID' + +Support for matching on invalid DCCP type field values was pretty +broken: While RFC4340 declares any type value from 10 to 15 invalid, the +extension's type name 'INVALID' mapped to type value 10 only. Fix this +by introduction of INVALID_OTHER_TYPE_MASK which has the remaining +invalid type's bits set and apply it if bit 10 is set after parsing the +type list. When printing, stop searching type names after printing +'INVALID' - unless numeric output was requested. The latter prints all +actual type values. Since parsing types in numeric form is not +supported, changing the output should not break existing scripts. + +When translating into nftables syntax, the code returned prematurely if +'INVALID' was among the list of types - thereby emitting invalid syntax. +Instead print a real match for invalid types by use of a range +expression. + +While being at it, fix syntax of translator output: If only +'--dccp-types' was translated, the output contained an extra 'dccp'. On +the other hand, if '--sport' and '--dport' was present, a required +'dccp' between the translations of both was missing. + +Fixes: e40b11d7ef827 ("add support for new 'dccp' protocol match") +Fixes: c94a998724143 ("extensions: libxt_dccp: Add translation to nft") +Signed-off-by: Phil Sutter +(cherry picked from commit 4bcbc8e11a2764f4537dc405962f83cd072cccfe) +--- + extensions/libxt_dccp.c | 58 ++++++++++++++++++++++-------------- + extensions/libxt_dccp.txlate | 12 ++++++-- + 2 files changed, 45 insertions(+), 25 deletions(-) + +diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c +index 5e67c264db2a9..aea3e20be4818 100644 +--- a/extensions/libxt_dccp.c ++++ b/extensions/libxt_dccp.c +@@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = { + [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 @@ parse_dccp_types(const char *typestring) + 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 @@ print_types(uint16_t types, int inverted, int numeric) + + 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 @@ static const char *const dccp_pkt_types_xlate[] = { + [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 @@ static int dccp_type_xlate(const struct xt_dccp_info *einfo, + 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 @@ static int dccp_xlate(struct xt_xlate *xl, + 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 --git a/extensions/libxt_dccp.txlate b/extensions/libxt_dccp.txlate +index b47dc65f5bc4f..ea853f6acf627 100644 +--- a/extensions/libxt_dccp.txlate ++++ b/extensions/libxt_dccp.txlate +@@ -7,8 +7,14 @@ nft add rule ip filter INPUT dccp dport 100-200 counter + 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 +-- +2.40.0 + diff --git a/SOURCES/0028-xtables-monitor-fix-rule-printing.patch b/SOURCES/0028-xtables-monitor-fix-rule-printing.patch new file mode 100644 index 0000000..4dc5cc8 --- /dev/null +++ b/SOURCES/0028-xtables-monitor-fix-rule-printing.patch @@ -0,0 +1,85 @@ +From 524f17b1027cb3b6bd5484c644d4dc226d137d91 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Sat, 12 Dec 2020 16:15:32 +0100 +Subject: [PATCH] xtables-monitor: fix rule printing + +trace_print_rule does a rule dump. This prints unrelated rules +in the same chain. Instead the function should only request the +specific handle. + +Furthermore, flush output buffer afterwards so this plays nice when +output isn't a terminal. + +Signed-off-by: Florian Westphal +(cherry picked from commit 07af4da52ab3002c9cb510863b4eb7aaca4fb43b) +--- + iptables/xtables-monitor.c | 32 +++++++++++++++----------------- + 1 file changed, 15 insertions(+), 17 deletions(-) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 4008cc00d4694..364e600e1b38a 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -227,12 +227,12 @@ static void trace_print_rule(const struct nftnl_trace *nlt, struct cb_arg *args) + 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); + +@@ -248,24 +248,21 @@ static void trace_print_rule(const struct nftnl_trace *nlt, struct cb_arg *args) + } + + 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) +@@ -531,6 +528,7 @@ static int trace_cb(const struct nlmsghdr *nlh, struct cb_arg *arg) + err_free: + nftnl_trace_free(nlt); + err: ++ fflush(stdout); + return MNL_CB_OK; + } + +-- +2.40.0 + diff --git a/SOURCES/0029-xtables-monitor-fix-packet-family-protocol.patch b/SOURCES/0029-xtables-monitor-fix-packet-family-protocol.patch new file mode 100644 index 0000000..89b376b --- /dev/null +++ b/SOURCES/0029-xtables-monitor-fix-packet-family-protocol.patch @@ -0,0 +1,38 @@ +From 7de2651bdbbabfc08ef040d2cb9867c8375e3984 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Sat, 12 Dec 2020 16:15:33 +0100 +Subject: [PATCH] xtables-monitor: fix packet family protocol + +This prints the family passed on the command line (which might be 0). +Print the table family instead. + +Signed-off-by: Florian Westphal +(cherry picked from commit 946923b640afc2249cf98743ff60a97291108701) +--- + iptables/xtables-monitor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 364e600e1b38a..8850a12032d26 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -273,14 +273,14 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg + 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); +-- +2.40.0 + diff --git a/SOURCES/0030-xtables-monitor-print-packet-first.patch b/SOURCES/0030-xtables-monitor-print-packet-first.patch new file mode 100644 index 0000000..411c260 --- /dev/null +++ b/SOURCES/0030-xtables-monitor-print-packet-first.patch @@ -0,0 +1,101 @@ +From 46fffddb8ae11d3e46f55ca0bb356a2549671652 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Sat, 12 Dec 2020 16:15:34 +0100 +Subject: [PATCH] xtables-monitor: print packet first + +The trace mode should first print the packet that was received and +then the rule/verdict. + +Furthermore, the monitor did sometimes print an extra newline. + +After this patch, output is more consistent with nft monitor. + +Signed-off-by: Florian Westphal +(cherry picked from commit 180ba723d0b305fab9287d3bc5f845a43d9eb793) +--- + iptables/xtables-monitor.c | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 8850a12032d26..e6b6e76b9fdc9 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -106,6 +106,7 @@ static int rule_cb(const struct nlmsghdr *nlh, void *data) + printf("-0 "); + break; + default: ++ puts(""); + goto err_free; + } + +@@ -433,9 +434,18 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg + mark = nftnl_trace_get_u32(nlt, NFTNL_TRACE_MARK); + if (mark) + printf("MARK=0x%x ", mark); ++ puts(""); ++} ++ ++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(struct nftnl_trace *nlt, uint32_t verdict) ++static void print_verdict(const struct nftnl_trace *nlt, uint32_t verdict) + { + const char *chain; + +@@ -496,35 +506,37 @@ static int trace_cb(const struct nlmsghdr *nlh, struct cb_arg *arg) + 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: +-- +2.40.0 + diff --git a/SOURCES/0031-xtables-monitor.patch b/SOURCES/0031-xtables-monitor.patch new file mode 100644 index 0000000..39ae229 --- /dev/null +++ b/SOURCES/0031-xtables-monitor.patch @@ -0,0 +1,30 @@ +From bc9b418dc22fb7d81bfded431c74ea84f62340bd Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 14 Dec 2020 17:11:23 +0100 +Subject: [PATCH] xtables-monitor: + +'LL=0x304' is not very convenient, print LOOPBACK instead. + +Signed-off-by: Florian Westphal +(cherry picked from commit 98ed6f6fc6d97663a33de67afff60196052880b1) +--- + iptables/xtables-monitor.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index e6b6e76b9fdc9..4b9809805fb5b 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -306,6 +306,9 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg + 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++) +-- +2.40.0 + diff --git a/SOURCES/0032-nft-Fix-selective-chain-compatibility-checks.patch b/SOURCES/0032-nft-Fix-selective-chain-compatibility-checks.patch new file mode 100644 index 0000000..8a73ffb --- /dev/null +++ b/SOURCES/0032-nft-Fix-selective-chain-compatibility-checks.patch @@ -0,0 +1,41 @@ +From 06bf588263f81b0d254d49b584b26445a788638d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 23 Sep 2020 19:13:45 +0200 +Subject: [PATCH] nft: Fix selective chain compatibility checks + +Since commit 80251bc2a56ed ("nft: remove cache build calls"), 'chain' +parameter passed to nft_chain_list_get() is no longer effective. +Before, it was used to fetch only that single chain from kernel when +populating the cache. So the returned list of chains for which +compatibility checks are done would contain only that single chain. + +Re-establish the single chain compat checking by introducing a dedicated +code path to nft_is_chain_compatible() doing so. + +Fixes: 80251bc2a56ed ("nft: remove cache build calls") +Signed-off-by: Phil Sutter +(cherry picked from commit 694612adf87fb614f16a2b678f32745d5c9d7876) +--- + iptables/nft.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/iptables/nft.c b/iptables/nft.c +index bdf252198f155..7f87d46dcc44c 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3575,6 +3575,12 @@ bool nft_is_table_compatible(struct nft_handle *h, + { + struct nftnl_chain_list *clist; + ++ if (chain) { ++ struct nftnl_chain *c = nft_chain_find(h, table, chain); ++ ++ return c && !nft_is_chain_compatible(c, h); ++ } ++ + clist = nft_chain_list_get(h, table, chain); + if (clist == NULL) + return false; +-- +2.40.0 + diff --git a/SOURCES/0033-iptables-nft-fix-Z-option.patch b/SOURCES/0033-iptables-nft-fix-Z-option.patch new file mode 100644 index 0000000..f9e434b --- /dev/null +++ b/SOURCES/0033-iptables-nft-fix-Z-option.patch @@ -0,0 +1,104 @@ +From 4f52c310cf3854a64ef9a518c223e0581ec9a308 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 24 Feb 2021 11:08:02 +0100 +Subject: [PATCH] iptables-nft: fix -Z option + +it zeroes the rule counters, so it needs fully populated cache. +Add a test case to cover this. + +Fixes: 9d07514ac5c7a ("nft: calculate cache requirements from list of commands") +Signed-off-by: Florian Westphal +Acked-by: Phil Sutter +(cherry picked from commit 5f1fcacebf9b4529950b6e3f88327049a0ea7cd2) +--- + iptables/nft-cmd.c | 2 +- + .../testcases/iptables/0007-zero-counters_0 | 64 +++++++++++++++++++ + 2 files changed, 65 insertions(+), 1 deletion(-) + create mode 100755 iptables/tests/shell/testcases/iptables/0007-zero-counters_0 + +diff --git a/iptables/nft-cmd.c b/iptables/nft-cmd.c +index 9c0901e78703a..ed53c061edc6f 100644 +--- a/iptables/nft-cmd.c ++++ b/iptables/nft-cmd.c +@@ -185,7 +185,7 @@ int nft_cmd_chain_zero_counters(struct nft_handle *h, const char *chain, + if (!cmd) + return 0; + +- nft_cache_level_set(h, NFT_CL_CHAINS, cmd); ++ nft_cache_level_set(h, NFT_CL_RULES, cmd); + + return 1; + } +diff --git a/iptables/tests/shell/testcases/iptables/0007-zero-counters_0 b/iptables/tests/shell/testcases/iptables/0007-zero-counters_0 +new file mode 100755 +index 0000000000000..36da1907e3b22 +--- /dev/null ++++ b/iptables/tests/shell/testcases/iptables/0007-zero-counters_0 +@@ -0,0 +1,64 @@ ++#!/bin/bash ++ ++RC=0 ++COUNTR=$RANDOM$RANDOM ++ ++$XT_MULTI iptables-restore -c < +Date: Fri, 19 Feb 2021 16:54:57 +0100 +Subject: [PATCH] nft: Fix bitwise expression avoidance detection + +Byte-boundary prefix detection was too sloppy: Any data following the +first zero-byte was ignored. Add a follow-up loop making sure there are +no stray bits in the designated host part. + +Fixes: 323259001d617 ("nft: Optimize class-based IP prefix matches") +Signed-off-by: Phil Sutter +(cherry picked from commit 330f5df03ad589b46865ceedf2a54cf10a4225ba) +--- + iptables/nft-shared.c | 4 +++- + .../testcases/ip6tables/0004-address-masks_0 | 24 +++++++++++++++++++ + 2 files changed, 27 insertions(+), 1 deletion(-) + create mode 100755 iptables/tests/shell/testcases/ip6tables/0004-address-masks_0 + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 10553ab26823b..c1664b50f9383 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -166,7 +166,7 @@ void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset, + { + const unsigned char *m = mask; + bool bitwise = false; +- int i; ++ int i, j; + + for (i = 0; i < len; i++) { + if (m[i] != 0xff) { +@@ -174,6 +174,8 @@ void add_addr(struct nftnl_rule *r, enum nft_payload_bases base, int offset, + break; + } + } ++ for (j = i + 1; !bitwise && j < len; j++) ++ bitwise = !!m[j]; + + if (!bitwise) + len = i; +diff --git a/iptables/tests/shell/testcases/ip6tables/0004-address-masks_0 b/iptables/tests/shell/testcases/ip6tables/0004-address-masks_0 +new file mode 100755 +index 0000000000000..7eb42f08da975 +--- /dev/null ++++ b/iptables/tests/shell/testcases/ip6tables/0004-address-masks_0 +@@ -0,0 +1,24 @@ ++#!/bin/bash ++ ++set -e ++ ++$XT_MULTI ip6tables-restore < +Date: Tue, 2 Mar 2021 14:50:07 +0100 +Subject: [PATCH] xtables-translate: Fix translation of odd netmasks + +Iptables supports netmasks which are not prefixes to match on (or +ignore) arbitrary bits in an address. Yet nftables' prefix notation is +available for real prefixes only, so translation is not as trivial - +print bitmask syntax for those cases. + +Signed-off-by: Phil Sutter +(cherry picked from commit 46f9d3a9a61ee80fa94b7fa7b3b36045c92606ae) +--- + extensions/generic.txlate | 48 +++++++++++++++++++++++++++++++++++++ + extensions/libxt_standard.t | 12 ++++++++++ + iptables/nft-ipv4.c | 42 ++++++++++++++++++++++---------- + iptables/nft-ipv6.c | 19 ++++++++++++--- + 4 files changed, 106 insertions(+), 15 deletions(-) + +diff --git a/extensions/generic.txlate b/extensions/generic.txlate +index 0e256c3727559..9ae9a5b54c1b9 100644 +--- a/extensions/generic.txlate ++++ b/extensions/generic.txlate +@@ -10,6 +10,54 @@ nft insert rule ip filter INPUT iifname "iifname" ip saddr 10.0.0.0/8 counter + iptables-translate -A INPUT -i iif+ ! -d 10.0.0.0/8 + nft add rule ip filter INPUT iifname "iif*" ip daddr != 10.0.0.0/8 counter + ++iptables-translate -I INPUT -s 10.11.12.13/255.255.0.0 ++nft insert rule ip filter INPUT ip saddr 10.11.0.0/16 counter ++ ++iptables-translate -I INPUT -s 10.11.12.13/255.0.255.0 ++nft insert rule ip filter INPUT ip saddr & 255.0.255.0 == 10.0.12.0 counter ++ ++iptables-translate -I INPUT -s 10.11.12.13/0.255.0.255 ++nft insert rule ip filter INPUT ip saddr & 0.255.0.255 == 0.11.0.13 counter ++ ++iptables-translate -I INPUT ! -s 10.11.12.13/0.255.0.255 ++nft insert rule ip filter INPUT ip saddr & 0.255.0.255 != 0.11.0.13 counter ++ ++iptables-translate -I INPUT -s 0.0.0.0/16 ++nft insert rule ip filter INPUT ip saddr 0.0.0.0/16 counter ++ ++iptables-translate -I INPUT -s 0.0.0.0/0 ++nft insert rule ip filter INPUT counter ++ ++iptables-translate -I INPUT ! -s 0.0.0.0/0 ++nft insert rule ip filter INPUT ip saddr != 0.0.0.0/0 counter ++ ++ip6tables-translate -I INPUT -i iifname -s feed::/16 ++nft insert rule ip6 filter INPUT iifname "iifname" ip6 saddr feed::/16 counter ++ ++ip6tables-translate -A INPUT -i iif+ ! -d feed::/16 ++nft add rule ip6 filter INPUT iifname "iif*" ip6 daddr != feed::/16 counter ++ ++ip6tables-translate -I INPUT -s feed:babe::1/ffff:ff00:: ++nft insert rule ip6 filter INPUT ip6 saddr feed:ba00::/24 counter ++ ++ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/ffff:0:ffff:0:ffff:0:ffff:0 ++nft insert rule ip6 filter INPUT ip6 saddr & ffff:0:ffff:0:ffff:0:ffff:0 == feed:0:c0ff:0:c0be:0:5678:0 counter ++ ++ip6tables-translate -I INPUT -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff ++nft insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff == 0:babe:0:ee00:0:1234:0:90ab counter ++ ++ip6tables-translate -I INPUT ! -s feed:babe:c0ff:ee00:c0be:1234:5678:90ab/0:ffff:0:ffff:0:ffff:0:ffff ++nft insert rule ip6 filter INPUT ip6 saddr & 0:ffff:0:ffff:0:ffff:0:ffff != 0:babe:0:ee00:0:1234:0:90ab counter ++ ++ip6tables-translate -I INPUT -s ::/16 ++nft insert rule ip6 filter INPUT ip6 saddr ::/16 counter ++ ++ip6tables-translate -I INPUT -s ::/0 ++nft insert rule ip6 filter INPUT counter ++ ++ip6tables-translate -I INPUT ! -s ::/0 ++nft insert rule ip6 filter INPUT ip6 saddr != ::/0 counter ++ + ebtables-translate -I INPUT -i iname --logical-in ilogname -s 0:0:0:0:0:0 + nft insert rule bridge filter INPUT iifname "iname" meta ibrname "ilogname" ether saddr 00:00:00:00:00:00 counter + +diff --git a/extensions/libxt_standard.t b/extensions/libxt_standard.t +index 4313f7b7bac9d..56d6da2e5884e 100644 +--- a/extensions/libxt_standard.t ++++ b/extensions/libxt_standard.t +@@ -9,3 +9,15 @@ + -j ACCEPT;=;OK + -j RETURN;=;OK + ! -p 0 -j ACCEPT;=;FAIL ++-s 10.11.12.13/8;-s 10.0.0.0/8;OK ++-s 10.11.12.13/9;-s 10.0.0.0/9;OK ++-s 10.11.12.13/10;-s 10.0.0.0/10;OK ++-s 10.11.12.13/11;-s 10.0.0.0/11;OK ++-s 10.11.12.13/12;-s 10.0.0.0/12;OK ++-s 10.11.12.13/30;-s 10.11.12.12/30;OK ++-s 10.11.12.13/31;-s 10.11.12.12/31;OK ++-s 10.11.12.13/32;-s 10.11.12.13/32;OK ++-s 10.11.12.13/255.0.0.0;-s 10.0.0.0/8;OK ++-s 10.11.12.13/255.128.0.0;-s 10.0.0.0/9;OK ++-s 10.11.12.13/255.0.255.0;-s 10.0.12.0/255.0.255.0;OK ++-s 10.11.12.13/255.0.12.0;-s 10.0.12.0/255.0.12.0;OK +diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c +index fdc15c6f04066..0d32a30010519 100644 +--- a/iptables/nft-ipv4.c ++++ b/iptables/nft-ipv4.c +@@ -383,6 +383,32 @@ static void nft_ipv4_post_parse(int command, + " source or destination IP addresses"); + } + ++static void xlate_ipv4_addr(const char *selector, const struct in_addr *addr, ++ const struct in_addr *mask, ++ bool inv, struct xt_xlate *xl) ++{ ++ const char *op = inv ? "!= " : ""; ++ int cidr; ++ ++ if (!inv && !addr->s_addr && !mask->s_addr) ++ return; ++ ++ cidr = xtables_ipmask_to_cidr(mask); ++ switch (cidr) { ++ case -1: ++ /* inet_ntoa() is not reentrant */ ++ xt_xlate_add(xl, "%s & %s ", selector, inet_ntoa(*mask)); ++ xt_xlate_add(xl, "%s %s ", inv ? "!=" : "==", inet_ntoa(*addr)); ++ break; ++ case 32: ++ xt_xlate_add(xl, "%s %s%s ", selector, op, inet_ntoa(*addr)); ++ break; ++ default: ++ xt_xlate_add(xl, "%s %s%s/%d ", selector, op, inet_ntoa(*addr), ++ cidr); ++ } ++} ++ + static int nft_ipv4_xlate(const void *data, struct xt_xlate *xl) + { + const struct iptables_command_state *cs = data; +@@ -417,18 +443,10 @@ static int nft_ipv4_xlate(const void *data, struct xt_xlate *xl) + } + } + +- if (cs->fw.ip.src.s_addr != 0) { +- xt_xlate_add(xl, "ip saddr %s%s%s ", +- cs->fw.ip.invflags & IPT_INV_SRCIP ? "!= " : "", +- inet_ntoa(cs->fw.ip.src), +- xtables_ipmask_to_numeric(&cs->fw.ip.smsk)); +- } +- if (cs->fw.ip.dst.s_addr != 0) { +- xt_xlate_add(xl, "ip daddr %s%s%s ", +- cs->fw.ip.invflags & IPT_INV_DSTIP ? "!= " : "", +- inet_ntoa(cs->fw.ip.dst), +- xtables_ipmask_to_numeric(&cs->fw.ip.dmsk)); +- } ++ xlate_ipv4_addr("ip saddr", &cs->fw.ip.src, &cs->fw.ip.smsk, ++ cs->fw.ip.invflags & IPT_INV_SRCIP, xl); ++ xlate_ipv4_addr("ip daddr", &cs->fw.ip.dst, &cs->fw.ip.dmsk, ++ cs->fw.ip.invflags & IPT_INV_DSTIP, xl); + + ret = xlate_matches(cs, xl); + if (!ret) +diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c +index 130ad3e6e7c44..46008fc5e762a 100644 +--- a/iptables/nft-ipv6.c ++++ b/iptables/nft-ipv6.c +@@ -337,14 +337,27 @@ static void xlate_ipv6_addr(const char *selector, const struct in6_addr *addr, + const struct in6_addr *mask, + int invert, struct xt_xlate *xl) + { ++ const char *op = invert ? "!= " : ""; + char addr_str[INET6_ADDRSTRLEN]; ++ int cidr; + +- if (!invert && IN6_IS_ADDR_UNSPECIFIED(addr)) ++ if (!invert && IN6_IS_ADDR_UNSPECIFIED(addr) && IN6_IS_ADDR_UNSPECIFIED(mask)) + return; + + inet_ntop(AF_INET6, addr, addr_str, INET6_ADDRSTRLEN); +- xt_xlate_add(xl, "%s %s%s%s ", selector, invert ? "!= " : "", addr_str, +- xtables_ip6mask_to_numeric(mask)); ++ cidr = xtables_ip6mask_to_cidr(mask); ++ switch (cidr) { ++ case -1: ++ xt_xlate_add(xl, "%s & %s %s %s ", selector, ++ xtables_ip6addr_to_numeric(mask), ++ invert ? "!=" : "==", addr_str); ++ break; ++ case 128: ++ xt_xlate_add(xl, "%s %s%s ", selector, op, addr_str); ++ break; ++ default: ++ xt_xlate_add(xl, "%s %s%s/%d ", selector, op, addr_str, cidr); ++ } + } + + static int nft_ipv6_xlate(const void *data, struct xt_xlate *xl) +-- +2.40.0 + diff --git a/SOURCES/0036-extensions-libxt_conntrack-use-bitops-for-state-nega.patch b/SOURCES/0036-extensions-libxt_conntrack-use-bitops-for-state-nega.patch new file mode 100644 index 0000000..840f6da --- /dev/null +++ b/SOURCES/0036-extensions-libxt_conntrack-use-bitops-for-state-nega.patch @@ -0,0 +1,129 @@ +From db7d25c14b8db7f7ea514e1f81acb82fafb3c9d7 Mon Sep 17 00:00:00 2001 +From: Alexander Mikhalitsyn +Date: Thu, 1 Apr 2021 16:47:07 +0300 +Subject: [PATCH] extensions: libxt_conntrack: use bitops for state negation + +Currently, state_xlate_print function prints statemask as comma-separated sequence of enabled +statemask flags. But if we have inverted conntrack ctstate condition then we have to use more +complex expression because nft not supports syntax like "ct state != related,established". + +Reproducer: +$ iptables -A INPUT -d 127.0.0.1/32 -p tcp -m conntrack ! --ctstate RELATED,ESTABLISHED -j DROP +$ nft list ruleset +... +meta l4proto tcp ip daddr 127.0.0.1 ct state != related,established counter packets 0 bytes 0 drop +... + +it will fail if we try to load this rule: +$ nft -f nft_test +../nft_test:6:97-97: Error: syntax error, unexpected comma, expecting newline or semicolon + +Cc: Florian Westphal +Signed-off-by: Alexander Mikhalitsyn +Signed-off-by: Florian Westphal +(cherry picked from commit 18e334da7363ba186edb1700056e26ded27ca5ba) +--- + extensions/libxt_conntrack.c | 38 ++++++++++++++++++++----------- + extensions/libxt_conntrack.txlate | 5 +++- + 2 files changed, 29 insertions(+), 14 deletions(-) + +diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c +index 7734509c9af84..91f9e4aa994f8 100644 +--- a/extensions/libxt_conntrack.c ++++ b/extensions/libxt_conntrack.c +@@ -1148,30 +1148,43 @@ static void state_save(const void *ip, const struct xt_entry_match *match) + state_print_state(sinfo->statemask); + } + +-static void state_xlate_print(struct xt_xlate *xl, unsigned int statemask) ++static void state_xlate_print(struct xt_xlate *xl, unsigned int statemask, int inverted) + { + const char *sep = ""; ++ int one_flag_set; ++ ++ one_flag_set = !(statemask & (statemask - 1)); ++ ++ if (inverted && !one_flag_set) ++ xt_xlate_add(xl, "& ("); ++ else if (inverted) ++ xt_xlate_add(xl, "& "); + + if (statemask & XT_CONNTRACK_STATE_INVALID) { + xt_xlate_add(xl, "%s%s", sep, "invalid"); +- sep = ","; ++ sep = inverted && !one_flag_set ? "|" : ","; + } + if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_NEW)) { + xt_xlate_add(xl, "%s%s", sep, "new"); +- sep = ","; ++ sep = inverted && !one_flag_set ? "|" : ","; + } + if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_RELATED)) { + xt_xlate_add(xl, "%s%s", sep, "related"); +- sep = ","; ++ sep = inverted && !one_flag_set ? "|" : ","; + } + if (statemask & XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED)) { + xt_xlate_add(xl, "%s%s", sep, "established"); +- sep = ","; ++ sep = inverted && !one_flag_set ? "|" : ","; + } + if (statemask & XT_CONNTRACK_STATE_UNTRACKED) { + xt_xlate_add(xl, "%s%s", sep, "untracked"); +- sep = ","; ++ sep = inverted && !one_flag_set ? "|" : ","; + } ++ ++ if (inverted && !one_flag_set) ++ xt_xlate_add(xl, ") == 0"); ++ else if (inverted) ++ xt_xlate_add(xl, " == 0"); + } + + static int state_xlate(struct xt_xlate *xl, +@@ -1180,9 +1193,9 @@ static int state_xlate(struct xt_xlate *xl, + const struct xt_conntrack_mtinfo3 *sinfo = + (const void *)params->match->data; + +- xt_xlate_add(xl, "ct state %s", sinfo->invert_flags & XT_CONNTRACK_STATE ? +- "!= " : ""); +- state_xlate_print(xl, sinfo->state_mask); ++ xt_xlate_add(xl, "ct state "); ++ state_xlate_print(xl, sinfo->state_mask, ++ sinfo->invert_flags & XT_CONNTRACK_STATE); + xt_xlate_add(xl, " "); + return 1; + } +@@ -1256,10 +1269,9 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, + 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); ++ xt_xlate_add(xl, "%sct state ", space); ++ state_xlate_print(xl, sinfo->state_mask, ++ sinfo->invert_flags & XT_CONNTRACK_STATE); + space = " "; + } + } +diff --git a/extensions/libxt_conntrack.txlate b/extensions/libxt_conntrack.txlate +index d374f8a035f00..5ab85b177c396 100644 +--- a/extensions/libxt_conntrack.txlate ++++ b/extensions/libxt_conntrack.txlate +@@ -2,7 +2,10 @@ iptables-translate -t filter -A INPUT -m conntrack --ctstate NEW,RELATED -j ACCE + nft add rule ip filter INPUT ct state new,related counter accept + + ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate NEW,RELATED -j ACCEPT +-nft add rule ip6 filter INPUT ct state != new,related counter accept ++nft add rule ip6 filter INPUT ct state & (new|related) == 0 counter accept ++ ++ip6tables-translate -t filter -A INPUT -m conntrack ! --ctstate NEW -j ACCEPT ++nft add rule ip6 filter INPUT ct state & new == 0 counter accept + + iptables-translate -t filter -A INPUT -m conntrack --ctproto UDP -j ACCEPT + nft add rule ip filter INPUT ct original protocol 17 counter accept +-- +2.40.0 + diff --git a/SOURCES/0037-Eliminate-inet_aton-and-inet_ntoa.patch b/SOURCES/0037-Eliminate-inet_aton-and-inet_ntoa.patch new file mode 100644 index 0000000..6bd3b0e --- /dev/null +++ b/SOURCES/0037-Eliminate-inet_aton-and-inet_ntoa.patch @@ -0,0 +1,120 @@ +From ca4b90e5fc460fe522ceff2206ae5d32d32d2b40 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 27 Apr 2021 09:12:53 +0200 +Subject: [PATCH] Eliminate inet_aton() and inet_ntoa() + +Both functions are obsolete, replace them by equivalent calls to +inet_pton() and inet_ntop(). + +Signed-off-by: Phil Sutter +(cherry picked from commit acac2dbe64e5120394fa715bb5fe95c42d08b8b3) +--- + extensions/libebt_among.c | 6 ++++-- + iptables/nft-ipv4.c | 23 ++++++++++++++--------- + 2 files changed, 18 insertions(+), 11 deletions(-) + +diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c +index 2b9a1b6566684..7eb898f984bba 100644 +--- a/extensions/libebt_among.c ++++ b/extensions/libebt_among.c +@@ -66,7 +66,7 @@ parse_nft_among_pair(char *buf, struct nft_among_pair *pair, bool have_ip) + if (sep) { + *sep = '\0'; + +- if (!inet_aton(sep + 1, &pair->in)) ++ if (!inet_pton(AF_INET, sep + 1, &pair->in)) + xtables_error(PARAMETER_PROBLEM, + "Invalid IP address '%s'\n", sep + 1); + } +@@ -194,6 +194,7 @@ static void __bramong_print(struct nft_among_pair *pairs, + int cnt, bool inv, bool have_ip) + { + const char *isep = inv ? "! " : ""; ++ char abuf[INET_ADDRSTRLEN]; + int i; + + for (i = 0; i < cnt; i++) { +@@ -202,7 +203,8 @@ static void __bramong_print(struct nft_among_pair *pairs, + + printf("%s", ether_ntoa(&pairs[i].ether)); + if (pairs[i].in.s_addr != INADDR_ANY) +- printf("=%s", inet_ntoa(pairs[i].in)); ++ printf("=%s", inet_ntop(AF_INET, &pairs[i].in, ++ abuf, sizeof(abuf))); + } + printf(" "); + } +diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c +index 0d32a30010519..a5b835b1f681d 100644 +--- a/iptables/nft-ipv4.c ++++ b/iptables/nft-ipv4.c +@@ -136,7 +136,7 @@ static void get_frag(struct nft_xt_ctx *ctx, struct nftnl_expr *e, bool *inv) + + static const char *mask_to_str(uint32_t mask) + { +- static char mask_str[sizeof("255.255.255.255")]; ++ static char mask_str[INET_ADDRSTRLEN]; + uint32_t bits, hmask = ntohl(mask); + struct in_addr mask_addr = { + .s_addr = mask, +@@ -155,7 +155,7 @@ static const char *mask_to_str(uint32_t mask) + if (i >= 0) + sprintf(mask_str, "%u", i); + else +- sprintf(mask_str, "%s", inet_ntoa(mask_addr)); ++ inet_ntop(AF_INET, &mask_addr, mask_str, sizeof(mask_str)); + + return mask_str; + } +@@ -298,10 +298,13 @@ static void nft_ipv4_print_rule(struct nft_handle *h, struct nftnl_rule *r, + static void save_ipv4_addr(char letter, const struct in_addr *addr, + uint32_t mask, int invert) + { ++ char addrbuf[INET_ADDRSTRLEN]; ++ + if (!mask && !invert && !addr->s_addr) + return; + +- printf("%s-%c %s/%s ", invert ? "! " : "", letter, inet_ntoa(*addr), ++ printf("%s-%c %s/%s ", invert ? "! " : "", letter, ++ inet_ntop(AF_INET, addr, addrbuf, sizeof(addrbuf)), + mask_to_str(mask)); + } + +@@ -387,25 +390,27 @@ static void xlate_ipv4_addr(const char *selector, const struct in_addr *addr, + const struct in_addr *mask, + bool inv, struct xt_xlate *xl) + { ++ char mbuf[INET_ADDRSTRLEN], abuf[INET_ADDRSTRLEN]; + const char *op = inv ? "!= " : ""; + int cidr; + + if (!inv && !addr->s_addr && !mask->s_addr) + return; + ++ inet_ntop(AF_INET, addr, abuf, sizeof(abuf)); ++ + cidr = xtables_ipmask_to_cidr(mask); + switch (cidr) { + case -1: +- /* inet_ntoa() is not reentrant */ +- xt_xlate_add(xl, "%s & %s ", selector, inet_ntoa(*mask)); +- xt_xlate_add(xl, "%s %s ", inv ? "!=" : "==", inet_ntoa(*addr)); ++ xt_xlate_add(xl, "%s & %s %s %s ", selector, ++ inet_ntop(AF_INET, mask, mbuf, sizeof(mbuf)), ++ inv ? "!=" : "==", abuf); + break; + case 32: +- xt_xlate_add(xl, "%s %s%s ", selector, op, inet_ntoa(*addr)); ++ xt_xlate_add(xl, "%s %s%s ", selector, op, abuf); + break; + default: +- xt_xlate_add(xl, "%s %s%s/%d ", selector, op, inet_ntoa(*addr), +- cidr); ++ xt_xlate_add(xl, "%s %s%s/%d ", selector, op, abuf, cidr); + } + } + +-- +2.40.0 + diff --git a/SOURCES/0038-nft-arp-Make-use-of-ipv4_addr_to_string.patch b/SOURCES/0038-nft-arp-Make-use-of-ipv4_addr_to_string.patch new file mode 100644 index 0000000..52fe6ca --- /dev/null +++ b/SOURCES/0038-nft-arp-Make-use-of-ipv4_addr_to_string.patch @@ -0,0 +1,181 @@ +From ab2ec9ca900843d6cb9fa839a9afe0ea968ce263 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 27 Apr 2021 10:02:34 +0200 +Subject: [PATCH] nft-arp: Make use of ipv4_addr_to_string() + +This eliminates quite a bit of redundant code apart from also dropping +use of obsolete function gethostbyaddr(). + +Signed-off-by: Phil Sutter +(cherry picked from commit 1e984079817a3c804eae25dea937d63d18c57a6c) +--- + iptables/nft-arp.c | 99 ++++------------------------------------------ + iptables/xshared.c | 6 +-- + iptables/xshared.h | 3 ++ + 3 files changed, 14 insertions(+), 94 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index c82ffdc95e300..2a9387a18dffe 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -42,78 +42,6 @@ char *arp_opcodes[] = + "ARP_NAK", + }; + +-static char * +-addr_to_dotted(const struct in_addr *addrp) +-{ +- static char buf[20]; +- const unsigned char *bytep; +- +- bytep = (const unsigned char *) &(addrp->s_addr); +- sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]); +- return buf; +-} +- +-static char * +-addr_to_host(const struct in_addr *addr) +-{ +- struct hostent *host; +- +- if ((host = gethostbyaddr((char *) addr, +- sizeof(struct in_addr), AF_INET)) != NULL) +- return (char *) host->h_name; +- +- return (char *) NULL; +-} +- +-static char * +-addr_to_network(const struct in_addr *addr) +-{ +- struct netent *net; +- +- if ((net = getnetbyaddr((long) ntohl(addr->s_addr), AF_INET)) != NULL) +- return (char *) net->n_name; +- +- return (char *) NULL; +-} +- +-static char * +-addr_to_anyname(const struct in_addr *addr) +-{ +- char *name; +- +- if ((name = addr_to_host(addr)) != NULL || +- (name = addr_to_network(addr)) != NULL) +- return name; +- +- return addr_to_dotted(addr); +-} +- +-static char * +-mask_to_dotted(const struct in_addr *mask) +-{ +- int i; +- static char buf[22]; +- u_int32_t maskaddr, bits; +- +- maskaddr = ntohl(mask->s_addr); +- +- if (maskaddr == 0xFFFFFFFFL) +- /* we don't want to see "/32" */ +- return ""; +- +- i = 32; +- bits = 0xFFFFFFFEL; +- while (--i >= 0 && maskaddr != bits) +- bits <<= 1; +- if (i >= 0) +- sprintf(buf, "/%d", i); +- else +- /* mask was not a decent combination of 1's and 0's */ +- snprintf(buf, sizeof(buf), "/%s", addr_to_dotted(mask)); +- +- return buf; +-} +- + static bool need_devaddr(struct arpt_devaddr_info *info) + { + int i; +@@ -403,7 +331,6 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + unsigned int format) + { + const struct arpt_entry *fw = &cs->arp; +- char buf[BUFSIZ]; + char iface[IFNAMSIZ+2]; + const char *sep = ""; + int print_iface = 0; +@@ -450,15 +377,10 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + } + + if (fw->arp.smsk.s_addr != 0L) { +- printf("%s%s", sep, fw->arp.invflags & IPT_INV_SRCIP +- ? "! " : ""); +- if (format & FMT_NUMERIC) +- sprintf(buf, "%s", addr_to_dotted(&(fw->arp.src))); +- else +- sprintf(buf, "%s", addr_to_anyname(&(fw->arp.src))); +- strncat(buf, mask_to_dotted(&(fw->arp.smsk)), +- sizeof(buf) - strlen(buf) - 1); +- printf("-s %s", buf); ++ printf("%s%s-s %s", sep, ++ fw->arp.invflags & IPT_INV_SRCIP ? "! " : "", ++ ipv4_addr_to_string(&fw->arp.src, ++ &fw->arp.smsk, format)); + sep = " "; + } + +@@ -476,15 +398,10 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + after_devsrc: + + if (fw->arp.tmsk.s_addr != 0L) { +- printf("%s%s", sep, fw->arp.invflags & IPT_INV_DSTIP +- ? "! " : ""); +- if (format & FMT_NUMERIC) +- sprintf(buf, "%s", addr_to_dotted(&(fw->arp.tgt))); +- else +- sprintf(buf, "%s", addr_to_anyname(&(fw->arp.tgt))); +- strncat(buf, mask_to_dotted(&(fw->arp.tmsk)), +- sizeof(buf) - strlen(buf) - 1); +- printf("-d %s", buf); ++ printf("%s%s-d %s", sep, ++ fw->arp.invflags & IPT_INV_DSTIP ? "! " : "", ++ ipv4_addr_to_string(&fw->arp.tgt, ++ &fw->arp.tmsk, format)); + sep = " "; + } + +diff --git a/iptables/xshared.c b/iptables/xshared.c +index fe37c30a085d6..3bcf24735c8fb 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -545,9 +545,9 @@ void debug_print_argv(struct argv_store *store) + } + #endif + +-static const char *ipv4_addr_to_string(const struct in_addr *addr, +- const struct in_addr *mask, +- unsigned int format) ++const char *ipv4_addr_to_string(const struct in_addr *addr, ++ const struct in_addr *mask, ++ unsigned int format) + { + static char buf[BUFSIZ]; + +diff --git a/iptables/xshared.h b/iptables/xshared.h +index 9159b2b1f3768..1e86aba8b2375 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -206,6 +206,9 @@ void debug_print_argv(struct argv_store *store); + # define debug_print_argv(...) /* nothing */ + #endif + ++const char *ipv4_addr_to_string(const struct in_addr *addr, ++ const struct in_addr *mask, ++ unsigned int format); + void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format); + void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format); + +-- +2.40.0 + diff --git a/SOURCES/0039-extensions-SECMARK-Implement-revision-1.patch b/SOURCES/0039-extensions-SECMARK-Implement-revision-1.patch new file mode 100644 index 0000000..e1f0868 --- /dev/null +++ b/SOURCES/0039-extensions-SECMARK-Implement-revision-1.patch @@ -0,0 +1,177 @@ +From b16a9bc7fa224139763686d3ecc1741b891ac6ce Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 29 Apr 2021 15:28:59 +0200 +Subject: [PATCH] extensions: SECMARK: Implement revision 1 + +The changed data structure for communication with kernel allows to +exclude the field 'secid' which is populated on kernel side. Thus +this fixes the formerly always failing extension comparison breaking +rule check and rule delete by content. + +Signed-off-by: Phil Sutter +(cherry picked from commit 616800af0da86d151cb695f1376d5ec6ede6fa72) +--- + extensions/libxt_SECMARK.c | 90 +++++++++++++++++++++------- + extensions/libxt_SECMARK.t | 4 ++ + include/linux/netfilter/xt_SECMARK.h | 6 ++ + 3 files changed, 80 insertions(+), 20 deletions(-) + create mode 100644 extensions/libxt_SECMARK.t + +diff --git a/extensions/libxt_SECMARK.c b/extensions/libxt_SECMARK.c +index 6ba8606355daa..24249bd618ffe 100644 +--- a/extensions/libxt_SECMARK.c ++++ b/extensions/libxt_SECMARK.c +@@ -29,6 +29,13 @@ static const struct xt_option_entry SECMARK_opts[] = { + XTOPT_TABLEEND, + }; + ++static const struct xt_option_entry SECMARK_opts_v1[] = { ++ {.name = "selctx", .id = O_SELCTX, .type = XTTYPE_STRING, ++ .flags = XTOPT_MAND | XTOPT_PUT, ++ XTOPT_POINTER(struct xt_secmark_target_info_v1, secctx)}, ++ XTOPT_TABLEEND, ++}; ++ + static void SECMARK_parse(struct xt_option_call *cb) + { + struct xt_secmark_target_info *info = cb->data; +@@ -37,15 +44,23 @@ static void SECMARK_parse(struct xt_option_call *cb) + info->mode = SECMARK_MODE_SEL; + } + +-static void print_secmark(const struct xt_secmark_target_info *info) ++static void SECMARK_parse_v1(struct xt_option_call *cb) ++{ ++ struct xt_secmark_target_info_v1 *info = cb->data; ++ ++ xtables_option_parse(cb); ++ info->mode = SECMARK_MODE_SEL; ++} ++ ++static void print_secmark(__u8 mode, const char *secctx) + { +- switch (info->mode) { ++ switch (mode) { + case SECMARK_MODE_SEL: +- printf("selctx %s", info->secctx); ++ printf("selctx %s", secctx); + break; +- ++ + default: +- xtables_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", info->mode); ++ xtables_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", mode); + } + } + +@@ -56,7 +71,17 @@ static void SECMARK_print(const void *ip, const struct xt_entry_target *target, + (struct xt_secmark_target_info*)(target)->data; + + printf(" SECMARK "); +- print_secmark(info); ++ print_secmark(info->mode, info->secctx); ++} ++ ++static void SECMARK_print_v1(const void *ip, ++ const struct xt_entry_target *target, int numeric) ++{ ++ const struct xt_secmark_target_info_v1 *info = ++ (struct xt_secmark_target_info_v1 *)(target)->data; ++ ++ printf(" SECMARK "); ++ print_secmark(info->mode, info->secctx); + } + + static void SECMARK_save(const void *ip, const struct xt_entry_target *target) +@@ -65,24 +90,49 @@ static void SECMARK_save(const void *ip, const struct xt_entry_target *target) + (struct xt_secmark_target_info*)target->data; + + printf(" --"); +- print_secmark(info); ++ print_secmark(info->mode, info->secctx); + } + +-static struct xtables_target secmark_target = { +- .family = NFPROTO_UNSPEC, +- .name = "SECMARK", +- .version = XTABLES_VERSION, +- .revision = 0, +- .size = XT_ALIGN(sizeof(struct xt_secmark_target_info)), +- .userspacesize = XT_ALIGN(sizeof(struct xt_secmark_target_info)), +- .help = SECMARK_help, +- .print = SECMARK_print, +- .save = SECMARK_save, +- .x6_parse = SECMARK_parse, +- .x6_options = SECMARK_opts, ++static void SECMARK_save_v1(const void *ip, ++ const struct xt_entry_target *target) ++{ ++ const struct xt_secmark_target_info_v1 *info = ++ (struct xt_secmark_target_info_v1 *)target->data; ++ ++ printf(" --"); ++ print_secmark(info->mode, info->secctx); ++} ++ ++static struct xtables_target secmark_tg_reg[] = { ++ { ++ .family = NFPROTO_UNSPEC, ++ .name = "SECMARK", ++ .version = XTABLES_VERSION, ++ .revision = 0, ++ .size = XT_ALIGN(sizeof(struct xt_secmark_target_info)), ++ .userspacesize = XT_ALIGN(sizeof(struct xt_secmark_target_info)), ++ .help = SECMARK_help, ++ .print = SECMARK_print, ++ .save = SECMARK_save, ++ .x6_parse = SECMARK_parse, ++ .x6_options = SECMARK_opts, ++ }, ++ { ++ .family = NFPROTO_UNSPEC, ++ .name = "SECMARK", ++ .version = XTABLES_VERSION, ++ .revision = 1, ++ .size = XT_ALIGN(sizeof(struct xt_secmark_target_info_v1)), ++ .userspacesize = XT_ALIGN(offsetof(struct xt_secmark_target_info_v1, secid)), ++ .help = SECMARK_help, ++ .print = SECMARK_print_v1, ++ .save = SECMARK_save_v1, ++ .x6_parse = SECMARK_parse_v1, ++ .x6_options = SECMARK_opts_v1, ++ } + }; + + void _init(void) + { +- xtables_register_target(&secmark_target); ++ xtables_register_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg)); + } +diff --git a/extensions/libxt_SECMARK.t b/extensions/libxt_SECMARK.t +new file mode 100644 +index 0000000000000..39d4c09348bf4 +--- /dev/null ++++ b/extensions/libxt_SECMARK.t +@@ -0,0 +1,4 @@ ++:INPUT,FORWARD,OUTPUT ++*security ++-j SECMARK --selctx system_u:object_r:firewalld_exec_t:s0;=;OK ++-j SECMARK;;FAIL +diff --git a/include/linux/netfilter/xt_SECMARK.h b/include/linux/netfilter/xt_SECMARK.h +index 989092bd6274b..31760a286a854 100644 +--- a/include/linux/netfilter/xt_SECMARK.h ++++ b/include/linux/netfilter/xt_SECMARK.h +@@ -19,4 +19,10 @@ struct xt_secmark_target_info { + char secctx[SECMARK_SECCTX_MAX]; + }; + ++struct xt_secmark_target_info_v1 { ++ __u8 mode; ++ char secctx[SECMARK_SECCTX_MAX]; ++ __u32 secid; ++}; ++ + #endif /*_XT_SECMARK_H_target */ +-- +2.40.0 + diff --git a/SOURCES/0040-Use-proto_to_name-from-xshared-in-more-places.patch b/SOURCES/0040-Use-proto_to_name-from-xshared-in-more-places.patch new file mode 100644 index 0000000..dba5b70 --- /dev/null +++ b/SOURCES/0040-Use-proto_to_name-from-xshared-in-more-places.patch @@ -0,0 +1,156 @@ +From adc559b69fc2b8d95a7c3bae96ca12faa0ba5d1d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 17 Nov 2020 00:57:10 +0100 +Subject: [PATCH] Use proto_to_name() from xshared in more places + +Share the common proto name lookup code. While being at it, make proto +number variable 16bit, values may exceed 256. + +This aligns iptables-nft '-p' argument printing with legacy iptables. In +practice, this should make a difference only in corner cases. + +Signed-off-by: Phil Sutter +(cherry picked from commit 556f704458cdb509d395ddb7d2629987d60e762e) +--- + include/xtables.h | 2 +- + iptables/ip6tables.c | 22 +++++----------------- + iptables/iptables.c | 20 +++++--------------- + iptables/nft-shared.c | 6 +++--- + iptables/xshared.c | 2 +- + iptables/xshared.h | 2 +- + 6 files changed, 16 insertions(+), 38 deletions(-) + +diff --git a/include/xtables.h b/include/xtables.h +index 5044dd08e86d3..a7b36979398ba 100644 +--- a/include/xtables.h ++++ b/include/xtables.h +@@ -395,7 +395,7 @@ struct xtables_rule_match { + */ + struct xtables_pprot { + const char *name; +- uint8_t num; ++ uint16_t num; + }; + + enum xtables_tryload { +diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c +index c95355b091568..ce01ce8c04af6 100644 +--- a/iptables/ip6tables.c ++++ b/iptables/ip6tables.c +@@ -796,28 +796,16 @@ print_iface(char letter, const char *iface, const unsigned char *mask, + } + } + +-/* The ip6tables looks up the /etc/protocols. */ + static void print_proto(uint16_t proto, int invert) + { + if (proto) { +- unsigned int i; ++ const char *pname = proto_to_name(proto, 0); + const char *invertstr = invert ? " !" : ""; + +- const struct protoent *pent = getprotobynumber(proto); +- if (pent) { +- printf("%s -p %s", +- invertstr, pent->p_name); +- return; +- } +- +- for (i = 0; xtables_chain_protos[i].name != NULL; ++i) +- if (xtables_chain_protos[i].num == proto) { +- printf("%s -p %s", +- invertstr, xtables_chain_protos[i].name); +- return; +- } +- +- printf("%s -p %u", invertstr, proto); ++ if (pname) ++ printf("%s -p %s", invertstr, pname); ++ else ++ printf("%s -p %u", invertstr, proto); + } + } + +diff --git a/iptables/iptables.c b/iptables/iptables.c +index 7d6183116d265..514238d924780 100644 +--- a/iptables/iptables.c ++++ b/iptables/iptables.c +@@ -764,23 +764,13 @@ list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric, + static void print_proto(uint16_t proto, int invert) + { + if (proto) { +- unsigned int i; ++ const char *pname = proto_to_name(proto, 0); + const char *invertstr = invert ? " !" : ""; + +- const struct protoent *pent = getprotobynumber(proto); +- if (pent) { +- printf("%s -p %s", invertstr, pent->p_name); +- return; +- } +- +- for (i = 0; xtables_chain_protos[i].name != NULL; ++i) +- if (xtables_chain_protos[i].num == proto) { +- printf("%s -p %s", +- invertstr, xtables_chain_protos[i].name); +- return; +- } +- +- printf("%s -p %u", invertstr, proto); ++ if (pname) ++ printf("%s -p %s", invertstr, pname); ++ else ++ printf("%s -p %u", invertstr, proto); + } + } + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index c1664b50f9383..4253b08196d29 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -826,13 +826,13 @@ void save_rule_details(const struct iptables_command_state *cs, + } + + if (proto > 0) { +- const struct protoent *pent = getprotobynumber(proto); ++ const char *pname = proto_to_name(proto, 0); + + if (invflags & XT_INV_PROTO) + printf("! "); + +- if (pent) +- printf("-p %s ", pent->p_name); ++ if (pname) ++ printf("-p %s ", pname); + else + printf("-p %u ", proto); + } +diff --git a/iptables/xshared.c b/iptables/xshared.c +index 3bcf24735c8fb..9a17a8fdf11cd 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -48,7 +48,7 @@ void print_extension_helps(const struct xtables_target *t, + } + + const char * +-proto_to_name(uint8_t proto, int nolookup) ++proto_to_name(uint16_t proto, int nolookup) + { + unsigned int i; + +diff --git a/iptables/xshared.h b/iptables/xshared.h +index 1e86aba8b2375..7c881c56a25da 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -152,7 +152,7 @@ enum { + + extern void print_extension_helps(const struct xtables_target *, + const struct xtables_rule_match *); +-extern const char *proto_to_name(uint8_t, int); ++extern const char *proto_to_name(uint16_t, int); + extern int command_default(struct iptables_command_state *, + struct xtables_globals *); + extern struct xtables_match *load_proto(struct iptables_command_state *); +-- +2.40.0 + diff --git a/SOURCES/0041-extensions-sctp-Fix-nftables-translation.patch b/SOURCES/0041-extensions-sctp-Fix-nftables-translation.patch new file mode 100644 index 0000000..51b48cb --- /dev/null +++ b/SOURCES/0041-extensions-sctp-Fix-nftables-translation.patch @@ -0,0 +1,80 @@ +From 867ccfc5a9394b8a0957db9f2828befb7efabd7c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 4 May 2021 16:03:24 +0200 +Subject: [PATCH] extensions: sctp: Fix nftables translation + +If both sport and dport was present, incorrect nft syntax was generated. + +Fixes: defc7bd2bac89 ("extensions: libxt_sctp: Add translation to nft") +Signed-off-by: Phil Sutter +(cherry picked from commit a61282ec6a1697bfb40f19d13a28a74559050167) +--- + extensions/libxt_sctp.c | 10 ++++------ + extensions/libxt_sctp.txlate | 10 +++++----- + 2 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/extensions/libxt_sctp.c b/extensions/libxt_sctp.c +index 140de2653b1ef..ee4e99ebf11bf 100644 +--- a/extensions/libxt_sctp.c ++++ b/extensions/libxt_sctp.c +@@ -495,15 +495,13 @@ static int sctp_xlate(struct xt_xlate *xl, + if (!einfo->flags) + return 0; + +- xt_xlate_add(xl, "sctp "); +- + if (einfo->flags & XT_SCTP_SRC_PORTS) { + if (einfo->spts[0] != einfo->spts[1]) +- xt_xlate_add(xl, "sport%s %u-%u", ++ xt_xlate_add(xl, "sctp sport%s %u-%u", + einfo->invflags & XT_SCTP_SRC_PORTS ? " !=" : "", + einfo->spts[0], einfo->spts[1]); + else +- xt_xlate_add(xl, "sport%s %u", ++ xt_xlate_add(xl, "sctp sport%s %u", + einfo->invflags & XT_SCTP_SRC_PORTS ? " !=" : "", + einfo->spts[0]); + space = " "; +@@ -511,11 +509,11 @@ static int sctp_xlate(struct xt_xlate *xl, + + if (einfo->flags & XT_SCTP_DEST_PORTS) { + if (einfo->dpts[0] != einfo->dpts[1]) +- xt_xlate_add(xl, "%sdport%s %u-%u", space, ++ xt_xlate_add(xl, "%ssctp dport%s %u-%u", space, + einfo->invflags & XT_SCTP_DEST_PORTS ? " !=" : "", + einfo->dpts[0], einfo->dpts[1]); + else +- xt_xlate_add(xl, "%sdport%s %u", space, ++ xt_xlate_add(xl, "%ssctp dport%s %u", space, + einfo->invflags & XT_SCTP_DEST_PORTS ? " !=" : "", + einfo->dpts[0]); + } +diff --git a/extensions/libxt_sctp.txlate b/extensions/libxt_sctp.txlate +index 72f4641ab021c..0d6c59e183675 100644 +--- a/extensions/libxt_sctp.txlate ++++ b/extensions/libxt_sctp.txlate +@@ -23,16 +23,16 @@ iptables-translate -A INPUT -p sctp ! --dport 50:56 -j ACCEPT + nft add rule ip filter INPUT sctp dport != 50-56 counter accept + + iptables-translate -A INPUT -p sctp --dport 80 --sport 50 -j ACCEPT +-nft add rule ip filter INPUT sctp sport 50 dport 80 counter accept ++nft add rule ip filter INPUT sctp sport 50 sctp dport 80 counter accept + + iptables-translate -A INPUT -p sctp --dport 80:100 --sport 50 -j ACCEPT +-nft add rule ip filter INPUT sctp sport 50 dport 80-100 counter accept ++nft add rule ip filter INPUT sctp sport 50 sctp dport 80-100 counter accept + + iptables-translate -A INPUT -p sctp --dport 80 --sport 50:55 -j ACCEPT +-nft add rule ip filter INPUT sctp sport 50-55 dport 80 counter accept ++nft add rule ip filter INPUT sctp sport 50-55 sctp dport 80 counter accept + + iptables-translate -A INPUT -p sctp ! --dport 80:100 --sport 50 -j ACCEPT +-nft add rule ip filter INPUT sctp sport 50 dport != 80-100 counter accept ++nft add rule ip filter INPUT sctp sport 50 sctp dport != 80-100 counter accept + + iptables-translate -A INPUT -p sctp --dport 80 ! --sport 50:55 -j ACCEPT +-nft add rule ip filter INPUT sctp sport != 50-55 dport 80 counter accept ++nft add rule ip filter INPUT sctp sport != 50-55 sctp dport 80 counter accept +-- +2.40.0 + diff --git a/SOURCES/0042-extensions-sctp-Translate-chunk-types-option.patch b/SOURCES/0042-extensions-sctp-Translate-chunk-types-option.patch new file mode 100644 index 0000000..ea607d0 --- /dev/null +++ b/SOURCES/0042-extensions-sctp-Translate-chunk-types-option.patch @@ -0,0 +1,159 @@ +From 448d1ff5807a52ec34759a6dddd348c5f3e96704 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 4 May 2021 16:26:42 +0200 +Subject: [PATCH] extensions: sctp: Translate --chunk-types option + +The translation is not fully complete as it is not possible to map 'any' +match type into nft syntax with a single rule. Also, 'only' match type +translation is a bit poor as it explicitly lists all chunk types that +are supposed to be missing. + +Signed-off-by: Phil Sutter +(cherry picked from commit 5818be177110a09120dd8fe4bd2533acbf8da301) +--- + extensions/libxt_sctp.c | 91 ++++++++++++++++++++++++++++-------- + extensions/libxt_sctp.txlate | 6 +++ + 2 files changed, 78 insertions(+), 19 deletions(-) + +diff --git a/extensions/libxt_sctp.c b/extensions/libxt_sctp.c +index ee4e99ebf11bf..5d8ab85cacf42 100644 +--- a/extensions/libxt_sctp.c ++++ b/extensions/libxt_sctp.c +@@ -92,28 +92,29 @@ struct sctp_chunk_names { + const char *name; + unsigned int chunk_type; + const char *valid_flags; ++ const char *nftname; + }; + + /*'ALL' and 'NONE' will be treated specially. */ + static const struct sctp_chunk_names sctp_chunk_names[] +-= { { .name = "DATA", .chunk_type = 0, .valid_flags = "----IUBE"}, +- { .name = "INIT", .chunk_type = 1, .valid_flags = "--------"}, +- { .name = "INIT_ACK", .chunk_type = 2, .valid_flags = "--------"}, +- { .name = "SACK", .chunk_type = 3, .valid_flags = "--------"}, +- { .name = "HEARTBEAT", .chunk_type = 4, .valid_flags = "--------"}, +- { .name = "HEARTBEAT_ACK", .chunk_type = 5, .valid_flags = "--------"}, +- { .name = "ABORT", .chunk_type = 6, .valid_flags = "-------T"}, +- { .name = "SHUTDOWN", .chunk_type = 7, .valid_flags = "--------"}, +- { .name = "SHUTDOWN_ACK", .chunk_type = 8, .valid_flags = "--------"}, +- { .name = "ERROR", .chunk_type = 9, .valid_flags = "--------"}, +- { .name = "COOKIE_ECHO", .chunk_type = 10, .valid_flags = "--------"}, +- { .name = "COOKIE_ACK", .chunk_type = 11, .valid_flags = "--------"}, +- { .name = "ECN_ECNE", .chunk_type = 12, .valid_flags = "--------"}, +- { .name = "ECN_CWR", .chunk_type = 13, .valid_flags = "--------"}, +- { .name = "SHUTDOWN_COMPLETE", .chunk_type = 14, .valid_flags = "-------T"}, +- { .name = "ASCONF", .chunk_type = 193, .valid_flags = "--------"}, +- { .name = "ASCONF_ACK", .chunk_type = 128, .valid_flags = "--------"}, +- { .name = "FORWARD_TSN", .chunk_type = 192, .valid_flags = "--------"}, ++= { { .name = "DATA", .chunk_type = 0, .valid_flags = "----IUBE", .nftname = "data" }, ++ { .name = "INIT", .chunk_type = 1, .valid_flags = "--------", .nftname = "init" }, ++ { .name = "INIT_ACK", .chunk_type = 2, .valid_flags = "--------", .nftname = "init-ack" }, ++ { .name = "SACK", .chunk_type = 3, .valid_flags = "--------", .nftname = "sack" }, ++ { .name = "HEARTBEAT", .chunk_type = 4, .valid_flags = "--------", .nftname = "heartbeat" }, ++ { .name = "HEARTBEAT_ACK", .chunk_type = 5, .valid_flags = "--------", .nftname = "heartbeat-ack" }, ++ { .name = "ABORT", .chunk_type = 6, .valid_flags = "-------T", .nftname = "abort" }, ++ { .name = "SHUTDOWN", .chunk_type = 7, .valid_flags = "--------", .nftname = "shutdown" }, ++ { .name = "SHUTDOWN_ACK", .chunk_type = 8, .valid_flags = "--------", .nftname = "shutdown-ack" }, ++ { .name = "ERROR", .chunk_type = 9, .valid_flags = "--------", .nftname = "error" }, ++ { .name = "COOKIE_ECHO", .chunk_type = 10, .valid_flags = "--------", .nftname = "cookie-echo" }, ++ { .name = "COOKIE_ACK", .chunk_type = 11, .valid_flags = "--------", .nftname = "cookie-ack" }, ++ { .name = "ECN_ECNE", .chunk_type = 12, .valid_flags = "--------", .nftname = "ecne" }, ++ { .name = "ECN_CWR", .chunk_type = 13, .valid_flags = "--------", .nftname = "cwr" }, ++ { .name = "SHUTDOWN_COMPLETE", .chunk_type = 14, .valid_flags = "-------T", .nftname = "shutdown-complete" }, ++ { .name = "ASCONF", .chunk_type = 193, .valid_flags = "--------", .nftname = "asconf" }, ++ { .name = "ASCONF_ACK", .chunk_type = 128, .valid_flags = "--------", .nftname = "asconf-ack" }, ++ { .name = "FORWARD_TSN", .chunk_type = 192, .valid_flags = "--------", .nftname = "forward-tsn" }, + }; + + static void +@@ -485,12 +486,52 @@ static void sctp_save(const void *ip, const struct xt_entry_match *match) + } + } + ++static const char *sctp_xlate_chunk(struct xt_xlate *xl, const char *space, ++ const struct xt_sctp_info *einfo, ++ const struct sctp_chunk_names *scn) ++{ ++ bool inv = einfo->invflags & XT_SCTP_CHUNK_TYPES; ++ const struct xt_sctp_flag_info *flag_info = NULL; ++ int i; ++ ++ if (!scn->nftname) ++ return space; ++ ++ if (!SCTP_CHUNKMAP_IS_SET(einfo->chunkmap, scn->chunk_type)) { ++ if (einfo->chunk_match_type != SCTP_CHUNK_MATCH_ONLY) ++ return space; ++ ++ xt_xlate_add(xl, "%ssctp chunk %s %s", space, ++ scn->nftname, inv ? "exists" : "missing"); ++ return " "; ++ } ++ ++ for (i = 0; i < einfo->flag_count; i++) { ++ if (einfo->flag_info[i].chunktype == scn->chunk_type) { ++ flag_info = &einfo->flag_info[i]; ++ break; ++ } ++ } ++ ++ if (!flag_info) { ++ xt_xlate_add(xl, "%ssctp chunk %s %s", space, ++ scn->nftname, inv ? "missing" : "exists"); ++ return " "; ++ } ++ ++ xt_xlate_add(xl, "%ssctp chunk %s flags & 0x%x %s 0x%x", space, ++ scn->nftname, flag_info->flag_mask, ++ inv ? "!=" : "==", flag_info->flag); ++ ++ return " "; ++} ++ + static int sctp_xlate(struct xt_xlate *xl, + const struct xt_xlate_mt_params *params) + { + const struct xt_sctp_info *einfo = + (const struct xt_sctp_info *)params->match->data; +- char *space = ""; ++ const char *space = ""; + + if (!einfo->flags) + return 0; +@@ -516,6 +557,18 @@ static int sctp_xlate(struct xt_xlate *xl, + xt_xlate_add(xl, "%ssctp dport%s %u", space, + einfo->invflags & XT_SCTP_DEST_PORTS ? " !=" : "", + einfo->dpts[0]); ++ space = " "; ++ } ++ ++ if (einfo->flags & XT_SCTP_CHUNK_TYPES) { ++ int i; ++ ++ if (einfo->chunk_match_type == SCTP_CHUNK_MATCH_ANY) ++ return 0; ++ ++ for (i = 0; i < ARRAY_SIZE(sctp_chunk_names); i++) ++ space = sctp_xlate_chunk(xl, space, einfo, ++ &sctp_chunk_names[i]); + } + + return 1; +diff --git a/extensions/libxt_sctp.txlate b/extensions/libxt_sctp.txlate +index 0d6c59e183675..bb817525db8d8 100644 +--- a/extensions/libxt_sctp.txlate ++++ b/extensions/libxt_sctp.txlate +@@ -36,3 +36,9 @@ nft add rule ip filter INPUT sctp sport 50 sctp dport != 80-100 counter accept + + iptables-translate -A INPUT -p sctp --dport 80 ! --sport 50:55 -j ACCEPT + nft add rule ip filter INPUT sctp sport != 50-55 sctp dport 80 counter accept ++ ++iptables-translate -A INPUT -p sctp --chunk-types all INIT,DATA:iUbE,SACK,ABORT:T -j ACCEPT ++nft add rule ip filter INPUT sctp chunk data flags & 0xf == 0x5 sctp chunk init exists sctp chunk sack exists sctp chunk abort flags & 0x1 == 0x1 counter accept ++ ++iptables-translate -A INPUT -p sctp --chunk-types only SHUTDOWN_COMPLETE -j ACCEPT ++nft add rule ip filter INPUT sctp chunk data missing sctp chunk init missing sctp chunk init-ack missing sctp chunk sack missing sctp chunk heartbeat missing sctp chunk heartbeat-ack missing sctp chunk abort missing sctp chunk shutdown missing sctp chunk shutdown-ack missing sctp chunk error missing sctp chunk cookie-echo missing sctp chunk cookie-ack missing sctp chunk ecne missing sctp chunk cwr missing sctp chunk shutdown-complete exists sctp chunk asconf missing sctp chunk asconf-ack missing sctp chunk forward-tsn missing counter accept +-- +2.40.0 + diff --git a/SOURCES/0043-libxtables-Drop-leftover-variable-in-xtables_numeric.patch b/SOURCES/0043-libxtables-Drop-leftover-variable-in-xtables_numeric.patch new file mode 100644 index 0000000..945e366 --- /dev/null +++ b/SOURCES/0043-libxtables-Drop-leftover-variable-in-xtables_numeric.patch @@ -0,0 +1,33 @@ +From e9dd197e783556dcb514ec624c4f6efeb782e7c7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 13 Nov 2020 21:04:39 +0100 +Subject: [PATCH] libxtables: Drop leftover variable in + xtables_numeric_to_ip6addr() + +Variable 'err' was only used in removed debug code, so drop it as well. + +Fixes: 7f526c9373c17 ("libxtables: xtables: remove unnecessary debug code") +Signed-off-by: Phil Sutter +(cherry picked from commit 97fabae738a74bd04a7793e1199cd2b8a69122bc) +--- + libxtables/xtables.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 7152c6576cd63..7f40b6f1b327b 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -1812,9 +1812,8 @@ const char *xtables_ip6mask_to_numeric(const struct in6_addr *addrp) + struct in6_addr *xtables_numeric_to_ip6addr(const char *num) + { + static struct in6_addr ap; +- int err; + +- if ((err = inet_pton(AF_INET6, num, &ap)) == 1) ++ if (inet_pton(AF_INET6, num, &ap) == 1) + return ≈ + + return NULL; +-- +2.40.0 + diff --git a/SOURCES/0044-extensions-libebt_ip6-Drop-unused-variables.patch b/SOURCES/0044-extensions-libebt_ip6-Drop-unused-variables.patch new file mode 100644 index 0000000..f52bc58 --- /dev/null +++ b/SOURCES/0044-extensions-libebt_ip6-Drop-unused-variables.patch @@ -0,0 +1,49 @@ +From 89bd91cfdf6f81971324dca1b0df7c6c5537a2ab Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 13 Nov 2020 21:13:50 +0100 +Subject: [PATCH] extensions: libebt_ip6: Drop unused variables + +They are being assigned to but never read. + +Fixes: 5c8ce9c6aede0 ("ebtables-compat: add 'ip6' match extension") +Signed-off-by: Phil Sutter +(cherry picked from commit 8bb5bcae57c83066c224efa5fd29ed4822a766fc) +--- + extensions/libebt_ip6.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/extensions/libebt_ip6.c b/extensions/libebt_ip6.c +index b8a5a5d8c3a92..301bed9aadefd 100644 +--- a/extensions/libebt_ip6.c ++++ b/extensions/libebt_ip6.c +@@ -250,9 +250,8 @@ static void brip6_init(struct xt_entry_match *match) + static struct in6_addr *numeric_to_addr(const char *num) + { + static struct in6_addr ap; +- int err; + +- if ((err=inet_pton(AF_INET6, num, &ap)) == 1) ++ if (inet_pton(AF_INET6, num, &ap) == 1) + return ≈ + return (struct in6_addr *)NULL; + } +@@ -292,7 +291,6 @@ static void ebt_parse_ip6_address(char *address, struct in6_addr *addr, struct i + char buf[256]; + char *p; + int i; +- int err; + + strncpy(buf, address, sizeof(buf) - 1); + /* first the mask */ +@@ -309,7 +307,7 @@ static void ebt_parse_ip6_address(char *address, struct in6_addr *addr, struct i + if (!memcmp(msk, &in6addr_any, sizeof(in6addr_any))) + strcpy(buf, "::"); + +- if ((err=inet_pton(AF_INET6, buf, addr)) < 1) { ++ if (inet_pton(AF_INET6, buf, addr) < 1) { + xtables_error(PARAMETER_PROBLEM, "Invalid IPv6 Address '%s' specified", buf); + return; + } +-- +2.40.0 + diff --git a/SOURCES/0045-libxtables-Fix-memleak-in-xtopt_parse_hostmask.patch b/SOURCES/0045-libxtables-Fix-memleak-in-xtopt_parse_hostmask.patch new file mode 100644 index 0000000..912703b --- /dev/null +++ b/SOURCES/0045-libxtables-Fix-memleak-in-xtopt_parse_hostmask.patch @@ -0,0 +1,29 @@ +From e672c567d978bf99652a8c3681e105d5a212552f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 2 Jun 2021 11:04:30 +0200 +Subject: [PATCH] libxtables: Fix memleak in xtopt_parse_hostmask() + +The allocated hostmask duplicate needs to be freed again. + +Fixes: 66266abd17adc ("libxtables: XTTYPE_HOSTMASK support") +Signed-off-by: Phil Sutter +(cherry picked from commit ffe88f8f01263687e82ef4d3d2bdc0cb5444711e) +--- + libxtables/xtoptions.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libxtables/xtoptions.c b/libxtables/xtoptions.c +index d329f2ff7979e..0dcdf607f4678 100644 +--- a/libxtables/xtoptions.c ++++ b/libxtables/xtoptions.c +@@ -763,6 +763,7 @@ static void xtopt_parse_hostmask(struct xt_option_call *cb) + cb->arg = p; + xtopt_parse_plenmask(cb); + cb->arg = orig_arg; ++ free(work); + } + + static void xtopt_parse_ethermac(struct xt_option_call *cb) +-- +2.40.0 + diff --git a/SOURCES/0046-nft-Avoid-memleak-in-error-path-of-nft_cmd_new.patch b/SOURCES/0046-nft-Avoid-memleak-in-error-path-of-nft_cmd_new.patch new file mode 100644 index 0000000..07314fc --- /dev/null +++ b/SOURCES/0046-nft-Avoid-memleak-in-error-path-of-nft_cmd_new.patch @@ -0,0 +1,34 @@ +From bee29f2820cafde1e04ebef049bc4c40c4dbbe18 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 2 Jun 2021 11:55:20 +0200 +Subject: [PATCH] nft: Avoid memleak in error path of nft_cmd_new() + +If rule allocation fails, free the allocated 'cmd' before returning to +caller. + +Fixes: a7f1e208cdf9c ("nft: split parsing from netlink commands") +Signed-off-by: Phil Sutter +(cherry picked from commit eab75ed36a4f204ddab0c40ba42c5a300634d5c3) +--- + iptables/nft-cmd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/iptables/nft-cmd.c b/iptables/nft-cmd.c +index ed53c061edc6f..fd038503d87e1 100644 +--- a/iptables/nft-cmd.c ++++ b/iptables/nft-cmd.c +@@ -35,8 +35,10 @@ struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command, + + if (state) { + rule = nft_rule_new(h, chain, table, state); +- if (!rule) ++ if (!rule) { ++ nft_cmd_free(cmd); + return NULL; ++ } + + cmd->obj.rule = rule; + +-- +2.40.0 + diff --git a/SOURCES/0047-iptables-apply-Drop-unused-variable.patch b/SOURCES/0047-iptables-apply-Drop-unused-variable.patch new file mode 100644 index 0000000..514647e --- /dev/null +++ b/SOURCES/0047-iptables-apply-Drop-unused-variable.patch @@ -0,0 +1,29 @@ +From 2f80e6d896590f42c932de32ae8c3d597cbf940b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 2 Jun 2021 12:50:57 +0200 +Subject: [PATCH] iptables-apply: Drop unused variable + +It was assigned to but never read. + +Fixes: b45b4e3903414 ("iptables-apply: script and manpage update") +Signed-off-by: Phil Sutter +(cherry picked from commit 084671d5acaaf749648e828c2ed3b319de651764) +--- + iptables/iptables-apply | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/iptables/iptables-apply b/iptables/iptables-apply +index 4683b1b402d08..3a7df5e3cbc1f 100755 +--- a/iptables/iptables-apply ++++ b/iptables/iptables-apply +@@ -231,7 +231,6 @@ case "$MODE" in + "$RUNCMD" & + CMD_PID=$! + ( sleep "$TIMEOUT"; kill "$CMD_PID" 2>/dev/null; exit 0 ) & +- CMDTIMEOUT_PID=$! + if ! wait "$CMD_PID"; then + echo "failed." + echo "Error: unknown error running command: $RUNCMD" >&2 +-- +2.40.0 + diff --git a/SOURCES/0048-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch b/SOURCES/0048-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch new file mode 100644 index 0000000..01a2704 --- /dev/null +++ b/SOURCES/0048-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch @@ -0,0 +1,130 @@ +From 9a617399d5e0776b43f093b9d63d10f72e882fee Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 28 Jul 2021 17:53:53 +0200 +Subject: [PATCH] doc: ebtables-nft.8: Adjust for missing atomic-options + +Drop any reference to them (and the environment variable) but list them +in BUGS section hinting at ebtables-save and -restore tools. + +Fixes: 1939cbc25e6f5 ("doc: Adjust ebtables man page") +Signed-off-by: Phil Sutter +Acked-by: Pablo Neira Ayuso +(cherry picked from commit 765bf04ecc228783cb88c810c85bc0c769579c39) +--- + iptables/ebtables-nft.8 | 64 ++++++----------------------------------- + 1 file changed, 8 insertions(+), 56 deletions(-) + +diff --git a/iptables/ebtables-nft.8 b/iptables/ebtables-nft.8 +index 1fa5ad9388cc0..08e9766f2cc74 100644 +--- a/iptables/ebtables-nft.8 ++++ b/iptables/ebtables-nft.8 +@@ -44,12 +44,6 @@ ebtables \- Ethernet bridge frame table administration (nft-based) + .br + .BR "ebtables " [ -t " table ] " --init-table + .br +-.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-commit +-.br +-.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-init +-.br +-.BR "ebtables " [ -t " table ] [" --atomic-file " file] " --atomic-save +-.br + + .SH DESCRIPTION + .B ebtables +@@ -149,11 +143,9 @@ a table, the commands apply to the default filter table. + Only one command may be used on the command line at a time, except when + the commands + .BR -L " and " -Z +-are combined, the commands ++are combined or the commands + .BR -N " and " -P +-are combined, or when +-.B --atomic-file +-is used. ++are combined. + .TP + .B "-A, --append" + Append a rule to the end of the selected chain. +@@ -313,39 +305,6 @@ of the ebtables kernel table. + .TP + .B "--init-table" + Replace the current table data by the initial table data. +-.TP +-.B "--atomic-init" +-Copy the kernel's initial data of the table to the specified +-file. This can be used as the first action, after which rules are added +-to the file. The file can be specified using the +-.B --atomic-file +-command or through the +-.IR EBTABLES_ATOMIC_FILE " environment variable." +-.TP +-.B "--atomic-save" +-Copy the kernel's current data of the table to the specified +-file. This can be used as the first action, after which rules are added +-to the file. The file can be specified using the +-.B --atomic-file +-command or through the +-.IR EBTABLES_ATOMIC_FILE " environment variable." +-.TP +-.B "--atomic-commit" +-Replace the kernel table data with the data contained in the specified +-file. This is a useful command that allows you to load all your rules of a +-certain table into the kernel at once, saving the kernel a lot of precious +-time and allowing atomic updates of the tables. The file which contains +-the table data is constructed by using either the +-.B "--atomic-init" +-or the +-.B "--atomic-save" +-command to generate a starting file. After that, using the +-.B "--atomic-file" +-command when constructing rules or setting the +-.IR EBTABLES_ATOMIC_FILE " environment variable" +-allows you to extend the file and build the complete table before +-committing it to the kernel. This command can be very useful in boot scripts +-to populate the ebtables tables in a fast way. + .SS MISCELLANOUS COMMANDS + .TP + .B "-V, --version" +@@ -371,16 +330,6 @@ a target extension (see + .BR "TARGET EXTENSIONS" ")" + or a user-defined chain name. + .TP +-.B --atomic-file "\fIfile\fP" +-Let the command operate on the specified +-.IR file . +-The data of the table to +-operate on will be extracted from the file and the result of the operation +-will be saved back into the file. If specified, this option should come +-before the command specification. An alternative that should be preferred, +-is setting the +-.IR EBTABLES_ATOMIC_FILE " environment variable." +-.TP + .B -M, --modprobe "\fIprogram\fP" + When talking to the kernel, use this + .I program +@@ -1100,8 +1049,6 @@ arp message and the hardware address length in the arp header is 6 bytes. + .br + .SH FILES + .I /etc/ethertypes +-.SH ENVIRONMENT VARIABLES +-.I EBTABLES_ATOMIC_FILE + .SH MAILINGLISTS + .BR "" "See " http://netfilter.org/mailinglists.html + .SH BUGS +@@ -1109,7 +1056,12 @@ The version of ebtables this man page ships with does not support the + .B broute + table. Also there is no support for + .B string +-match. And finally, this list is probably not complete. ++match. Further, support for atomic-options ++.RB ( --atomic-file ", " --atomic-init ", " --atomic-save ", " --atomic-commit ) ++has not been implemented, although ++.BR ebtables-save " and " ebtables-restore ++might replace them entirely given the inherent atomicity of nftables. ++Finally, this list is probably not complete. + .SH SEE ALSO + .BR xtables-nft "(8), " iptables "(8), " ip (8) + .PP +-- +2.40.0 + diff --git a/SOURCES/0049-ebtables-Dump-atomic-waste.patch b/SOURCES/0049-ebtables-Dump-atomic-waste.patch new file mode 100644 index 0000000..4e4b1c5 --- /dev/null +++ b/SOURCES/0049-ebtables-Dump-atomic-waste.patch @@ -0,0 +1,102 @@ +From ec0a69df9ac073b1a6e951c08c049fec47a12b5c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 30 Jul 2021 12:25:10 +0200 +Subject: [PATCH] ebtables: Dump atomic waste + +With ebtables-nft.8 now educating people about the missing +functionality, get rid of atomic remains in source code. This eliminates +mostly comments except for --atomic-commit which was treated as alias of +--init-table. People not using the latter are probably trying to +atomic-commit from an atomic-file which in turn is not supported, so no +point keeping it. + +Signed-off-by: Phil Sutter +(cherry picked from commit 263186372dc4ae6a54a29bea644bcf1fc8dc3fc0) +--- + iptables/xtables-eb.c | 53 ------------------------------------------- + 1 file changed, 53 deletions(-) + +diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c +index 6df5839f07436..d07adad2d73c3 100644 +--- a/iptables/xtables-eb.c ++++ b/iptables/xtables-eb.c +@@ -262,10 +262,6 @@ struct option ebt_original_options[] = + { "new-chain" , required_argument, 0, 'N' }, + { "rename-chain" , required_argument, 0, 'E' }, + { "delete-chain" , optional_argument, 0, 'X' }, +- { "atomic-init" , no_argument , 0, 7 }, +- { "atomic-commit" , no_argument , 0, 8 }, +- { "atomic-file" , required_argument, 0, 9 }, +- { "atomic-save" , no_argument , 0, 10 }, + { "init-table" , no_argument , 0, 11 }, + { "concurrent" , no_argument , 0, 13 }, + { 0 } +@@ -371,10 +367,6 @@ static void print_help(const struct xtables_target *t, + "--new-chain -N chain : create a user defined chain\n" + "--rename-chain -E old new : rename a chain\n" + "--delete-chain -X [chain] : delete a user defined chain\n" +-"--atomic-commit : update the kernel w/t table contained in \n" +-"--atomic-init : put the initial kernel table into \n" +-"--atomic-save : put the current kernel table into \n" +-"--atomic-file file : set to file\n\n" + "Options:\n" + "--proto -p [!] proto : protocol hexadecimal, by name or LENGTH\n" + "--src -s [!] address[/mask]: source mac address\n" +@@ -1135,54 +1127,9 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, + "Use --Lmac2 with -L"); + flags |= LIST_MAC2; + break; +- case 8 : /* atomic-commit */ +-/* +- replace->command = c; +- if (OPT_COMMANDS) +- ebt_print_error2("Multiple commands are not allowed"); +- replace->flags |= OPT_COMMAND; +- if (!replace->filename) +- ebt_print_error2("No atomic file specified");*/ +- /* Get the information from the file */ +- /*ebt_get_table(replace, 0);*/ +- /* We don't want the kernel giving us its counters, +- * they would overwrite the counters extracted from +- * the file */ +- /*replace->num_counters = 0;*/ +- /* Make sure the table will be written to the kernel */ +- /*free(replace->filename); +- replace->filename = NULL; +- break;*/ +- /*case 7 :*/ /* atomic-init */ +- /*case 10:*/ /* atomic-save */ + case 11: /* init-table */ + nft_cmd_table_flush(h, *table); + return 1; +- /* +- replace->command = c; +- if (OPT_COMMANDS) +- ebt_print_error2("Multiple commands are not allowed"); +- if (c != 11 && !replace->filename) +- ebt_print_error2("No atomic file specified"); +- replace->flags |= OPT_COMMAND; +- { +- char *tmp = replace->filename;*/ +- +- /* Get the kernel table */ +- /*replace->filename = NULL; +- ebt_get_kernel_table(replace, c == 10 ? 0 : 1); +- replace->filename = tmp; +- } +- break; +- case 9 :*/ /* atomic */ +- /* +- if (OPT_COMMANDS) +- ebt_print_error2("--atomic has to come before the command");*/ +- /* A possible memory leak here, but this is not +- * executed in daemon mode */ +- /*replace->filename = (char *)malloc(strlen(optarg) + 1); +- strcpy(replace->filename, optarg); +- break; */ + case 13 : + break; + case 1 : +-- +2.40.0 + diff --git a/SOURCES/0050-nft-Fix-for-non-verbose-check-command.patch b/SOURCES/0050-nft-Fix-for-non-verbose-check-command.patch new file mode 100644 index 0000000..4f56750 --- /dev/null +++ b/SOURCES/0050-nft-Fix-for-non-verbose-check-command.patch @@ -0,0 +1,31 @@ +From 59c41217b2acc9409ba50a76a40aaa994c83f454 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 3 Aug 2021 10:55:20 +0200 +Subject: [PATCH] nft: Fix for non-verbose check command + +Check command was unconditionally verbose since v1.8.5. Make it respect +--verbose option again. + +Fixes: a7f1e208cdf9c ("nft: split parsing from netlink commands") +Signed-off-by: Phil Sutter +(cherry picked from commit 57d1422dbbc41c36ed2e9f6c67aa040c65a429a0) +--- + iptables/nft.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 7f87d46dcc44c..f8534c6cd56fb 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3160,7 +3160,7 @@ static int nft_prepare(struct nft_handle *h) + case NFT_COMPAT_RULE_CHECK: + assert_chain_exists(h, cmd->table, cmd->jumpto); + ret = nft_rule_check(h, cmd->chain, cmd->table, +- cmd->obj.rule, cmd->rulenum); ++ cmd->obj.rule, cmd->verbose); + break; + case NFT_COMPAT_RULE_ZERO: + ret = nft_rule_zero_counters(h, cmd->chain, cmd->table, +-- +2.40.0 + diff --git a/SOURCES/0051-extensions-hashlimit-Fix-tests-with-HZ-100.patch b/SOURCES/0051-extensions-hashlimit-Fix-tests-with-HZ-100.patch new file mode 100644 index 0000000..df411da --- /dev/null +++ b/SOURCES/0051-extensions-hashlimit-Fix-tests-with-HZ-100.patch @@ -0,0 +1,41 @@ +From 07cfafd077bbd247bf75c0a3399569af58a63915 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 9 Aug 2021 18:48:58 +0200 +Subject: [PATCH] extensions: hashlimit: Fix tests with HZ=100 + +With the kernel ticking at 100Hz, a limit of 1/day with burst 5 does not +overflow in kernel, making the test unstable depending on kernel config. +Change it to not overflow with 1000Hz either by increasing the burst +value by a factor of 100. + +Fixes: fcf9f6f25db11 ("extensions: libxt_hashlimit: add unit test") +Signed-off-by: Phil Sutter +(cherry picked from commit bef9dc575625a98a5e6ed8ca37e49031cdba5937) +--- + extensions/libxt_hashlimit.t | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/extensions/libxt_hashlimit.t b/extensions/libxt_hashlimit.t +index ccd0d1e6a2a1a..8369933786f68 100644 +--- a/extensions/libxt_hashlimit.t ++++ b/extensions/libxt_hashlimit.t +@@ -3,14 +3,12 @@ + -m hashlimit --hashlimit-above 1000000/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-above 1/min --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-above 1/hour --hashlimit-burst 5 --hashlimit-name mini1;=;OK +-# kernel says "xt_hashlimit: overflow, try lower: 864000000/5" +--m hashlimit --hashlimit-above 1/day --hashlimit-burst 5 --hashlimit-name mini1;;FAIL ++-m hashlimit --hashlimit-above 1/day --hashlimit-burst 500 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1000000/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/min --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/hour --hashlimit-burst 5 --hashlimit-name mini1;=;OK +-# kernel says "xt_hashlimit: overflow, try lower: 864000000/5" +--m hashlimit --hashlimit-upto 1/day --hashlimit-burst 5 --hashlimit-name mini1;;FAIL ++-m hashlimit --hashlimit-upto 1/day --hashlimit-burst 500 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode dstip --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK +-- +2.40.0 + diff --git a/SOURCES/0052-nft-Use-xtables_malloc-in-mnl_err_list_node_add.patch b/SOURCES/0052-nft-Use-xtables_malloc-in-mnl_err_list_node_add.patch new file mode 100644 index 0000000..7b4e6db --- /dev/null +++ b/SOURCES/0052-nft-Use-xtables_malloc-in-mnl_err_list_node_add.patch @@ -0,0 +1,31 @@ +From 71f9eda379a3d70b5b2cd9327e41ba5446c618e1 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 31 Aug 2021 12:26:20 +0200 +Subject: [PATCH] nft: Use xtables_malloc() in mnl_err_list_node_add() + +The function called malloc() without checking for memory allocation +failure. Simply replace the call by xtables_malloc() to fix that. + +Fixes: 4e2020952d6f9 ("xtables: use libnftnl batch API") +Signed-off-by: Phil Sutter +(cherry picked from commit ca11c7b7036b5821c17b8d08dc2a29f55b461a93) +--- + iptables/nft.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index f8534c6cd56fb..ba59cfb8c47af 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -143,7 +143,7 @@ struct mnl_err { + static void mnl_err_list_node_add(struct list_head *err_list, int error, + int seqnum) + { +- struct mnl_err *err = malloc(sizeof(struct mnl_err)); ++ struct mnl_err *err = xtables_malloc(sizeof(struct mnl_err)); + + err->seqnum = seqnum; + err->err = error; +-- +2.40.0 + diff --git a/SOURCES/0053-extensions-hashlimit-Fix-tests-with-HZ-1000.patch b/SOURCES/0053-extensions-hashlimit-Fix-tests-with-HZ-1000.patch new file mode 100644 index 0000000..48f4983 --- /dev/null +++ b/SOURCES/0053-extensions-hashlimit-Fix-tests-with-HZ-1000.patch @@ -0,0 +1,47 @@ +From c51304d536c3f91b58dc24b14131de157d741a9f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 8 Nov 2021 17:03:21 +0100 +Subject: [PATCH] extensions: hashlimit: Fix tests with HZ=1000 + +In an attempt to fix for failing hashlimit tests with HZ=100, the +expected failures were changed so they are expected to pass and the +parameters changed to seemingly fix them. Yet while the new parameters +worked on HZ=100 systems, with higher tick rates they didn't so the +observed problem moved from the test failing on HZ=100 to failing on +HZ=1000 instead. + +Kernel's error message "try lower: 864000000/5" turned out to be a red +herring: The burst value does not act as a dividor but a multiplier +instead, so in order to lower the overflow-checked value, a lower burst +value must be chosen. Inded, using a burst value of 1 makes the kernel +accept the rule in both HZ=100 and HZ=1000 configurations. + +Fixes: bef9dc575625a ("extensions: hashlimit: Fix tests with HZ=100") +Signed-off-by: Phil Sutter +(cherry picked from commit 1eab8e83aec0e6965f11f8cad460add1caeae629) +--- + extensions/libxt_hashlimit.t | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extensions/libxt_hashlimit.t b/extensions/libxt_hashlimit.t +index 8369933786f68..206d92935f2e2 100644 +--- a/extensions/libxt_hashlimit.t ++++ b/extensions/libxt_hashlimit.t +@@ -3,12 +3,12 @@ + -m hashlimit --hashlimit-above 1000000/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-above 1/min --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-above 1/hour --hashlimit-burst 5 --hashlimit-name mini1;=;OK +--m hashlimit --hashlimit-above 1/day --hashlimit-burst 500 --hashlimit-name mini1;=;OK ++-m hashlimit --hashlimit-above 1/day --hashlimit-burst 1 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1000000/sec --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/min --hashlimit-burst 5 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/hour --hashlimit-burst 5 --hashlimit-name mini1;=;OK +--m hashlimit --hashlimit-upto 1/day --hashlimit-burst 500 --hashlimit-name mini1;=;OK ++-m hashlimit --hashlimit-upto 1/day --hashlimit-burst 1 --hashlimit-name mini1;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode srcip --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK + -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 1 --hashlimit-mode dstip --hashlimit-name mini1 --hashlimit-htable-expire 2000;=;OK +-- +2.40.0 + diff --git a/SOURCES/0054-xshared-Merge-and-share-parse_chain.patch b/SOURCES/0054-xshared-Merge-and-share-parse_chain.patch new file mode 100644 index 0000000..86b2fb2 --- /dev/null +++ b/SOURCES/0054-xshared-Merge-and-share-parse_chain.patch @@ -0,0 +1,164 @@ +From 655e919be08b6ca9b5529f16c659ee93572b867d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 5 Apr 2019 13:21:19 +0200 +Subject: [PATCH] xshared: Merge and share parse_chain() + +Have a common routine to perform chain name checks, combining all +variants' requirements. + +Signed-off-by: Phil Sutter +(cherry picked from commit 1189d830ea4fd269da87761d400ebabca02e1ef3) + +Conflicts: + iptables/ip6tables.c + iptables/xshared.c +-> Context change due to missing commit 9dc50b5b8e441 + ("xshared: Merge invflags handling code"). +--- + iptables/ip6tables.c | 26 -------------------------- + iptables/iptables.c | 25 ------------------------- + iptables/xshared.c | 24 ++++++++++++++++++++++++ + iptables/xshared.h | 1 + + iptables/xtables.c | 9 +-------- + 5 files changed, 26 insertions(+), 59 deletions(-) + +diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c +index ce01ce8c04af6..6db91c807bcea 100644 +--- a/iptables/ip6tables.c ++++ b/iptables/ip6tables.c +@@ -248,32 +248,6 @@ static int is_exthdr(uint16_t proto) + proto == IPPROTO_DSTOPTS); + } + +-static void +-parse_chain(const char *chainname) +-{ +- const char *ptr; +- +- if (strlen(chainname) >= XT_EXTENSION_MAXNAMELEN) +- xtables_error(PARAMETER_PROBLEM, +- "chain name `%s' too long (must be under %u chars)", +- chainname, XT_EXTENSION_MAXNAMELEN); +- +- if (*chainname == '-' || *chainname == '!') +- xtables_error(PARAMETER_PROBLEM, +- "chain name not allowed to start " +- "with `%c'\n", *chainname); +- +- if (xtables_find_target(chainname, XTF_TRY_LOAD)) +- xtables_error(PARAMETER_PROBLEM, +- "chain name may not clash " +- "with target name\n"); +- +- for (ptr = chainname; *ptr; ptr++) +- if (isspace(*ptr)) +- xtables_error(PARAMETER_PROBLEM, +- "Invalid chain name `%s'", chainname); +-} +- + static void + set_option(unsigned int *options, unsigned int option, uint8_t *invflg, + int invert) +diff --git a/iptables/iptables.c b/iptables/iptables.c +index 514238d924780..a33416a887ed4 100644 +--- a/iptables/iptables.c ++++ b/iptables/iptables.c +@@ -239,31 +239,6 @@ iptables_exit_error(enum xtables_exittype status, const char *msg, ...) + + /* Christophe Burki wants `-p 6' to imply `-m tcp'. */ + +-static void +-parse_chain(const char *chainname) +-{ +- const char *ptr; +- +- if (strlen(chainname) >= XT_EXTENSION_MAXNAMELEN) +- xtables_error(PARAMETER_PROBLEM, +- "chain name `%s' too long (must be under %u chars)", +- chainname, XT_EXTENSION_MAXNAMELEN); +- +- if (*chainname == '-' || *chainname == '!') +- xtables_error(PARAMETER_PROBLEM, +- "chain name not allowed to start " +- "with `%c'\n", *chainname); +- +- if (xtables_find_target(chainname, XTF_TRY_LOAD)) +- xtables_error(PARAMETER_PROBLEM, +- "chain name may not clash " +- "with target name\n"); +- +- for (ptr = chainname; *ptr; ptr++) +- if (isspace(*ptr)) +- xtables_error(PARAMETER_PROBLEM, +- "Invalid chain name `%s'", chainname); +-} + + static void + set_option(unsigned int *options, unsigned int option, uint8_t *invflg, +diff --git a/iptables/xshared.c b/iptables/xshared.c +index 9a17a8fdf11cd..5ae158908b109 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -848,3 +848,27 @@ char opt2char(int option) + + return *ptr; + } ++ ++void parse_chain(const char *chainname) ++{ ++ const char *ptr; ++ ++ if (strlen(chainname) >= XT_EXTENSION_MAXNAMELEN) ++ xtables_error(PARAMETER_PROBLEM, ++ "chain name `%s' too long (must be under %u chars)", ++ chainname, XT_EXTENSION_MAXNAMELEN); ++ ++ if (*chainname == '-' || *chainname == '!') ++ xtables_error(PARAMETER_PROBLEM, ++ "chain name not allowed to start with `%c'\n", ++ *chainname); ++ ++ if (xtables_find_target(chainname, XTF_TRY_LOAD)) ++ xtables_error(PARAMETER_PROBLEM, ++ "chain name may not clash with target name\n"); ++ ++ for (ptr = chainname; *ptr; ptr++) ++ if (isspace(*ptr)) ++ xtables_error(PARAMETER_PROBLEM, ++ "Invalid chain name `%s'", chainname); ++} +diff --git a/iptables/xshared.h b/iptables/xshared.h +index 7c881c56a25da..10f6e0b5a0e98 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -223,6 +223,7 @@ char cmd2char(int option); + void add_command(unsigned int *cmd, const int newcmd, + const int othercmds, int invert); + int parse_rulenumber(const char *rule); ++void parse_chain(const char *chainname); + + void generic_opt_check(int command, int options); + char opt2char(int option); +diff --git a/iptables/xtables.c b/iptables/xtables.c +index 9779bd83d53b3..54f887f80497e 100644 +--- a/iptables/xtables.c ++++ b/iptables/xtables.c +@@ -587,14 +587,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], + break; + + case 'N': +- if (optarg && (*optarg == '-' || *optarg == '!')) +- xtables_error(PARAMETER_PROBLEM, +- "chain name not allowed to start " +- "with `%c'\n", *optarg); +- if (xtables_find_target(optarg, XTF_TRY_LOAD)) +- xtables_error(PARAMETER_PROBLEM, +- "chain name may not clash " +- "with target name\n"); ++ parse_chain(optarg); + add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE, + cs->invert); + p->chain = optarg; +-- +2.40.0 + diff --git a/SOURCES/0055-nft-shared-Drop-unused-function-print_proto.patch b/SOURCES/0055-nft-shared-Drop-unused-function-print_proto.patch new file mode 100644 index 0000000..5c808ac --- /dev/null +++ b/SOURCES/0055-nft-shared-Drop-unused-function-print_proto.patch @@ -0,0 +1,58 @@ +From e004e9e1d0e7ef4d9756d9f01feef8efef02300b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 6 Nov 2021 01:09:37 +0100 +Subject: [PATCH] nft-shared: Drop unused function print_proto() + +The last users vanished back in 2013. There is identical code in +save_rule_details(), but with only a single user there's not much point +in keeping the function. + +Fixes: cdc78b1d6bd7b ("nft: convert rule into a command state structure") +Signed-off-by: Phil Sutter +(cherry picked from commit cf14b92bc1a3f5040437234dffe5cf6aa59711a5) +--- + iptables/nft-shared.c | 15 --------------- + iptables/nft-shared.h | 1 - + 2 files changed, 16 deletions(-) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 4253b08196d29..f270f610a8f67 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -373,21 +373,6 @@ static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e) + ctx->h->ops->parse_match(match, ctx->cs); + } + +-void print_proto(uint16_t proto, int invert) +-{ +- const struct protoent *pent = getprotobynumber(proto); +- +- if (invert) +- printf("! "); +- +- if (pent) { +- printf("-p %s ", pent->p_name); +- return; +- } +- +- printf("-p %u ", proto); +-} +- + void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv) + { + uint32_t len; +diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h +index 6fc81d9ce08ef..519118a2daf6c 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -139,7 +139,6 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface, + int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface, + unsigned char *iniface_mask, char *outiface, + unsigned char *outiface_mask, uint8_t *invflags); +-void print_proto(uint16_t proto, int invert); + void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv); + void nft_rule_to_iptables_command_state(struct nft_handle *h, + const struct nftnl_rule *r, +-- +2.40.0 + diff --git a/SOURCES/0056-xshared-Make-load_proto-static.patch b/SOURCES/0056-xshared-Make-load_proto-static.patch new file mode 100644 index 0000000..6a58c34 --- /dev/null +++ b/SOURCES/0056-xshared-Make-load_proto-static.patch @@ -0,0 +1,48 @@ +From 9b1dc489369e19ffd78a69de31f4ac653070eaf8 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 6 Nov 2021 01:32:47 +0100 +Subject: [PATCH] xshared: Make load_proto() static + +The last outside users vanished ten years ago. + +Fixes: 449cdd6bcc8d1 ("src: combine default_command functions") +Signed-off-by: Phil Sutter +(cherry picked from commit 7213561d9d7a17c4db29c867b2607241941dae5a) + +Conflicts: + iptables/xshared.h +-> Context change due to missing commit 3664249f52030 + ("xshared: Eliminate iptables_command_state->invert"). +--- + iptables/xshared.c | 2 +- + iptables/xshared.h | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/iptables/xshared.c b/iptables/xshared.c +index 5ae158908b109..26e938309eab3 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -106,7 +106,7 @@ static bool should_load_proto(struct iptables_command_state *cs) + return !cs->proto_used; + } + +-struct xtables_match *load_proto(struct iptables_command_state *cs) ++static struct xtables_match *load_proto(struct iptables_command_state *cs) + { + if (!should_load_proto(cs)) + return NULL; +diff --git a/iptables/xshared.h b/iptables/xshared.h +index 10f6e0b5a0e98..d80c8beee1894 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -155,7 +155,6 @@ extern void print_extension_helps(const struct xtables_target *, + extern const char *proto_to_name(uint16_t, int); + extern int command_default(struct iptables_command_state *, + struct xtables_globals *); +-extern struct xtables_match *load_proto(struct iptables_command_state *); + extern int subcmd_main(int, char **, const struct subcommand *); + extern void xs_init_target(struct xtables_target *); + extern void xs_init_match(struct xtables_match *); +-- +2.40.0 + diff --git a/SOURCES/0057-extensions-libxt_NFLOG-fix-nflog-prefix-Python-test-.patch b/SOURCES/0057-extensions-libxt_NFLOG-fix-nflog-prefix-Python-test-.patch new file mode 100644 index 0000000..0d2994b --- /dev/null +++ b/SOURCES/0057-extensions-libxt_NFLOG-fix-nflog-prefix-Python-test-.patch @@ -0,0 +1,40 @@ +From 4572ecb1f222ec63f0d5669d0924d2cf1e879290 Mon Sep 17 00:00:00 2001 +From: Jeremy Sowden +Date: Fri, 1 Oct 2021 18:41:39 +0100 +Subject: [PATCH] extensions: libxt_NFLOG: fix `--nflog-prefix` Python + test-cases + +The `iptables-save` includes an extra space between `--nflog-prefix` and +the prefix. + +The maximum length of prefixes includes the trailing NUL character. + +NFLOG silently truncates prefixes which exceed the maximum length. + +Signed-off-by: Jeremy Sowden +Signed-off-by: Florian Westphal +(cherry picked from commit f0d02998883d2efcb316cd6f524e2f7b3c4d055b) +--- + extensions/libxt_NFLOG.t | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/extensions/libxt_NFLOG.t b/extensions/libxt_NFLOG.t +index 933fa22160e59..69b0255a891b1 100644 +--- a/extensions/libxt_NFLOG.t ++++ b/extensions/libxt_NFLOG.t +@@ -12,10 +12,8 @@ + -j NFLOG --nflog-size 4294967295;=;OK + -j NFLOG --nflog-size 4294967296;;FAIL + -j NFLOG --nflog-size -1;;FAIL +-# ERROR: cannot find: iptables -I INPUT -j NFLOG --nflog-prefix xxxxxx [...] +-# -j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;=;OK +-# ERROR: should fail: iptables -A INPUT -j NFLOG --nflog-prefix xxxxxxx [...] +-# -j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;;FAIL ++-j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;=;OK ++-j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;-j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;OK + -j NFLOG --nflog-threshold 1;=;OK + # ERROR: line 13 (should fail: iptables -A INPUT -j NFLOG --nflog-threshold 0 + # -j NFLOG --nflog-threshold 0;;FAIL +-- +2.40.0 + diff --git a/SOURCES/0058-extensions-libxt_NFLOG-remove-extra-space-when-savin.patch b/SOURCES/0058-extensions-libxt_NFLOG-remove-extra-space-when-savin.patch new file mode 100644 index 0000000..5bb97c9 --- /dev/null +++ b/SOURCES/0058-extensions-libxt_NFLOG-remove-extra-space-when-savin.patch @@ -0,0 +1,53 @@ +From c83d8cec2a2c70776ca569699983f0cf3e11fb99 Mon Sep 17 00:00:00 2001 +From: Jeremy Sowden +Date: Fri, 1 Oct 2021 18:41:40 +0100 +Subject: [PATCH] extensions: libxt_NFLOG: remove extra space when saving + targets with prefixes + +When printing out NFLOG targets an extra space was inserted between +`--nflog-prefix` and the prefix itself: + + $ sudo /usr/sbin/iptables -A INPUT -j NFLOG --nflog-prefix test + $ sudo /usr/sbin/iptables-save | grep NFLOG + -A INPUT -j NFLOG --nflog-prefix test + ^^ +Fixes: 73866357e4a7 ("iptables: do not print trailing whitespaces") +Signed-off-by: Jeremy Sowden +Signed-off-by: Florian Westphal +(cherry picked from commit 05286bab77a6e0f9502e8fb99e1c53ed15663f3f) +--- + extensions/libxt_NFLOG.c | 2 +- + extensions/libxt_NFLOG.t | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/extensions/libxt_NFLOG.c b/extensions/libxt_NFLOG.c +index 02a1b4aa35a3b..80c0263510f1e 100644 +--- a/extensions/libxt_NFLOG.c ++++ b/extensions/libxt_NFLOG.c +@@ -78,7 +78,7 @@ static void NFLOG_check(struct xt_fcheck_call *cb) + static void nflog_print(const struct xt_nflog_info *info, char *prefix) + { + if (info->prefix[0] != '\0') { +- printf(" %snflog-prefix ", prefix); ++ printf(" %snflog-prefix", prefix); + xtables_save_string(info->prefix); + } + if (info->group) +diff --git a/extensions/libxt_NFLOG.t b/extensions/libxt_NFLOG.t +index 69b0255a891b1..bc529b19fc3ff 100644 +--- a/extensions/libxt_NFLOG.t ++++ b/extensions/libxt_NFLOG.t +@@ -12,8 +12,8 @@ + -j NFLOG --nflog-size 4294967295;=;OK + -j NFLOG --nflog-size 4294967296;;FAIL + -j NFLOG --nflog-size -1;;FAIL +--j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;=;OK +--j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;-j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;OK ++-j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;=;OK ++-j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;-j NFLOG --nflog-prefix xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;OK + -j NFLOG --nflog-threshold 1;=;OK + # ERROR: line 13 (should fail: iptables -A INPUT -j NFLOG --nflog-threshold 0 + # -j NFLOG --nflog-threshold 0;;FAIL +-- +2.40.0 + diff --git a/SOURCES/0059-xshared-Fix-response-to-unprivileged-users.patch b/SOURCES/0059-xshared-Fix-response-to-unprivileged-users.patch new file mode 100644 index 0000000..04dd27f --- /dev/null +++ b/SOURCES/0059-xshared-Fix-response-to-unprivileged-users.patch @@ -0,0 +1,135 @@ +From 84d19c668db246556fac766cff8652ea6f3a4076 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 18 Jan 2022 22:39:08 +0100 +Subject: [PATCH] xshared: Fix response to unprivileged users + +Expected behaviour in both variants is: + +* Print help without error, append extension help if -m and/or -j + options are present +* Indicate lack of permissions in an error message for anything else + +With iptables-nft, this was broken basically from day 1. Shared use of +do_parse() then somewhat broke legacy: it started complaining about +inability to create a lock file. + +Fix this by making iptables-nft assume extension revision 0 is present +if permissions don't allow to verify. This is consistent with legacy. + +Second part is to exit directly after printing help - this avoids having +to make the following code "nop-aware" to prevent privileged actions. + +Signed-off-by: Phil Sutter +Reviewed-by: Florian Westphal +(cherry picked from commit 26ecdf53960658771c0fc582f72a4025e2887f75) + +Conflicts: + iptables/xshared.c +-> Adjusted to missing commit 62c3c93d4b0f5 + ("xshared: Move do_parse to shared space"). +--- + iptables/nft.c | 5 ++ + .../testcases/iptables/0008-unprivileged_0 | 60 +++++++++++++++++++ + iptables/xtables.c | 3 +- + 3 files changed, 66 insertions(+), 2 deletions(-) + create mode 100755 iptables/tests/shell/testcases/iptables/0008-unprivileged_0 + +diff --git a/iptables/nft.c b/iptables/nft.c +index ba59cfb8c47af..da9d24f5c86e2 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3294,6 +3294,11 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt) + err: + mnl_socket_close(nl); + ++ /* pretend revision 0 is valid if not permitted to check - ++ * this is required for printing extension help texts as user */ ++ if (ret < 0 && errno == EPERM && rev == 0) ++ return 1; ++ + return ret < 0 ? 0 : 1; + } + +diff --git a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 +new file mode 100755 +index 0000000000000..43e3bc8721dbd +--- /dev/null ++++ b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 +@@ -0,0 +1,60 @@ ++#!/bin/bash ++ ++# iptables may print match/target specific help texts ++# help output should work for unprivileged users ++ ++run() { ++ echo "running: $*" >&2 ++ runuser -u nobody -- "$@" ++} ++ ++grep_or_rc() { ++ declare -g rc ++ grep -q "$*" && return 0 ++ echo "missing in output: $*" >&2 ++ return 1 ++} ++ ++out=$(run $XT_MULTI iptables --help) ++let "rc+=$?" ++grep_or_rc "iptables -h (print this help information)" <<< "$out" ++let "rc+=$?" ++ ++out=$(run $XT_MULTI iptables -m limit --help) ++let "rc+=$?" ++grep_or_rc "limit match options:" <<< "$out" ++let "rc+=$?" ++ ++out=$(run $XT_MULTI iptables -p tcp --help) ++let "rc+=$?" ++grep_or_rc "tcp match options:" <<< "$out" ++let "rc+=$?" ++ ++out=$(run $XT_MULTI iptables -j DNAT --help) ++let "rc+=$?" ++grep_or_rc "DNAT target options:" <<< "$out" ++let "rc+=$?" ++ ++out=$(run $XT_MULTI iptables -p tcp -j DNAT --help) ++let "rc+=$?" ++grep_or_rc "tcp match options:" <<< "$out" ++let "rc+=$?" ++out=$(run $XT_MULTI iptables -p tcp -j DNAT --help) ++let "rc+=$?" ++grep_or_rc "DNAT target options:" <<< "$out" ++let "rc+=$?" ++ ++ ++run $XT_MULTI iptables -L 2>&1 | \ ++ grep_or_rc "Permission denied" ++let "rc+=$?" ++ ++run $XT_MULTI iptables -A FORWARD -p tcp --dport 123 2>&1 | \ ++ grep_or_rc "Permission denied" ++let "rc+=$?" ++ ++run $XT_MULTI iptables -A FORWARD -j DNAT --to-destination 1.2.3.4 2>&1 | \ ++ grep_or_rc "Permission denied" ++let "rc+=$?" ++ ++exit $rc +diff --git a/iptables/xtables.c b/iptables/xtables.c +index 54f887f80497e..7ef1702a0cd50 100644 +--- a/iptables/xtables.c ++++ b/iptables/xtables.c +@@ -637,8 +637,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], + XTF_TRY_LOAD, &cs->matches); + + printhelp(cs->matches); +- p->command = CMD_NONE; +- return; ++ exit(0); + + /* + * Option selection +-- +2.40.0 + diff --git a/SOURCES/0060-libxtables-Register-only-the-highest-revision-extens.patch b/SOURCES/0060-libxtables-Register-only-the-highest-revision-extens.patch new file mode 100644 index 0000000..e69372a --- /dev/null +++ b/SOURCES/0060-libxtables-Register-only-the-highest-revision-extens.patch @@ -0,0 +1,64 @@ +From da4e3255df89367a3fcf0625df2f161724ef591c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Feb 2022 17:39:24 +0100 +Subject: [PATCH] libxtables: Register only the highest revision extension + +When fully registering extensions, ignore all consecutive ones with same +name and family value. Since commit b3ac87038f4e4 ("libxtables: Make +sure extensions register in revision order"), one may safely assume the +list of pending extensions has highest revision numbers first. Since +iptables is only interested in the highest revision the kernel supports, +registration and compatibility checks may be skipped once the first +matching extension in pending list has validated. + +Signed-off-by: Phil Sutter +(cherry picked from commit 2dbb49d15fb44ddd521a734eca3be3f940b7c1ba) +--- + libxtables/xtables.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 7f40b6f1b327b..3f7b9768897ac 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -668,6 +668,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, + struct xtables_match **dptr; + struct xtables_match *ptr; + const char *icmp6 = "icmp6"; ++ bool found = false; + + if (strlen(name) >= XT_EXTENSION_MAXNAMELEN) + xtables_error(PARAMETER_PROBLEM, +@@ -686,7 +687,9 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, + if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { + ptr = *dptr; + *dptr = (*dptr)->next; +- if (xtables_fully_register_pending_match(ptr, prev)) { ++ if (!found && ++ xtables_fully_register_pending_match(ptr, prev)) { ++ found = true; + prev = ptr; + continue; + } else if (prev) { +@@ -788,6 +791,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + struct xtables_target *prev = NULL; + struct xtables_target **dptr; + struct xtables_target *ptr; ++ bool found = false; + + /* Standard target? */ + if (strcmp(name, "") == 0 +@@ -802,7 +806,9 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { + ptr = *dptr; + *dptr = (*dptr)->next; +- if (xtables_fully_register_pending_target(ptr, prev)) { ++ if (!found && ++ xtables_fully_register_pending_target(ptr, prev)) { ++ found = true; + prev = ptr; + continue; + } else if (prev) { +-- +2.40.0 + diff --git a/SOURCES/0061-Improve-error-messages-for-unsupported-extensions.patch b/SOURCES/0061-Improve-error-messages-for-unsupported-extensions.patch new file mode 100644 index 0000000..13b22c2 --- /dev/null +++ b/SOURCES/0061-Improve-error-messages-for-unsupported-extensions.patch @@ -0,0 +1,84 @@ +From 8da52ae6b1eabcbce070e25342c9b5b6f84cbf7f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Feb 2022 17:47:22 +0100 +Subject: [PATCH] Improve error messages for unsupported extensions + +If a given extension was not supported by the kernel, iptables would +print a rather confusing error message if extension parameters were +given: + +| # rm /lib/modules/$(uname -r)/kernel/net/netfilter/xt_LOG.ko +| # iptables -A FORWARD -j LOG --log-prefix foo +| iptables v1.8.7 (legacy): unknown option "--log-prefix" + +Avoid this by pretending extension revision 0 is always supported. It is +the same hack as used to successfully print extension help texts as +unprivileged user, extended to all error codes to serve privileged ones +as well. + +In addition, print a warning if kernel rejected revision 0 and it's not +a permissions problem. This helps users find out which extension in a +rule the kernel didn't like. + +Finally, the above commands result in these messages: + +| Warning: Extension LOG revision 0 not supported, missing kernel module? +| iptables: No chain/target/match by that name. + +Or, for iptables-nft: + +| Warning: Extension LOG revision 0 not supported, missing kernel module? +| iptables v1.8.7 (nf_tables): RULE_APPEND failed (No such file or directory): rule in chain FORWARD + +Signed-off-by: Phil Sutter +(cherry picked from commit 17534cb18ed0a5052dc45c117401251359dba6aa) +--- + iptables/nft.c | 12 +++++++++--- + libxtables/xtables.c | 7 ++++++- + 2 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index da9d24f5c86e2..2393940d7f64a 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3294,10 +3294,16 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt) + err: + mnl_socket_close(nl); + +- /* pretend revision 0 is valid if not permitted to check - +- * this is required for printing extension help texts as user */ +- if (ret < 0 && errno == EPERM && rev == 0) ++ /* pretend revision 0 is valid - ++ * this is required for printing extension help texts as user, also ++ * helps error messaging on unavailable kernel extension */ ++ if (ret < 0 && rev == 0) { ++ if (errno != EPERM) ++ fprintf(stderr, ++ "Warning: Extension %s revision 0 not supported, missing kernel module?\n", ++ name); + return 1; ++ } + + return ret < 0 ? 0 : 1; + } +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 3f7b9768897ac..6ded6cc720ea8 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -929,7 +929,12 @@ int xtables_compatible_revision(const char *name, uint8_t revision, int opt) + /* Definitely don't support this? */ + if (errno == ENOENT || errno == EPROTONOSUPPORT) { + close(sockfd); +- return 0; ++ /* Pretend revision 0 support for better error messaging */ ++ if (revision == 0) ++ fprintf(stderr, ++ "Warning: Extension %s revision 0 not supported, missing kernel module?\n", ++ name); ++ return (revision == 0); + } else if (errno == ENOPROTOOPT) { + close(sockfd); + /* Assume only revision 0 support (old kernel) */ +-- +2.40.0 + diff --git a/SOURCES/0062-nft-Simplify-immediate-parsing.patch b/SOURCES/0062-nft-Simplify-immediate-parsing.patch new file mode 100644 index 0000000..fff8e1e --- /dev/null +++ b/SOURCES/0062-nft-Simplify-immediate-parsing.patch @@ -0,0 +1,199 @@ +From 4f6e933bd26243e2e3c644544d609ada04d46873 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 1 Mar 2022 18:59:31 +0100 +Subject: [PATCH] nft: Simplify immediate parsing + +Implementations of parse_immediate callback are mostly trivial, the only +relevant part is access to family-specific parts of struct +iptables_command_state when setting goto flag for iptables and +ip6tables. Refactor them into simple set_goto_flag callbacks. + +Signed-off-by: Phil Sutter +Acked-by: Florian Westphal +(cherry picked from commit b5f2faea325a315bfb932ebc634f3298d4824cae) +--- + iptables/nft-arp.c | 9 --------- + iptables/nft-bridge.c | 9 --------- + iptables/nft-ipv4.c | 12 +++--------- + iptables/nft-ipv6.c | 12 +++--------- + iptables/nft-shared.c | 17 +++++++---------- + iptables/nft-shared.h | 2 +- + 6 files changed, 14 insertions(+), 47 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index 2a9387a18dffe..d55e06572b283 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -182,14 +182,6 @@ static void nft_arp_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e, + fw->arp.invflags |= flags; + } + +-static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto, +- void *data) +-{ +- struct iptables_command_state *cs = data; +- +- cs->jumpto = jumpto; +-} +- + static void parse_mask_ipv4(struct nft_xt_ctx *ctx, struct in_addr *mask) + { + mask->s_addr = ctx->bitwise.mask[0]; +@@ -552,7 +544,6 @@ struct nft_family_ops nft_family_ops_arp = { + .print_payload = NULL, + .parse_meta = nft_arp_parse_meta, + .parse_payload = nft_arp_parse_payload, +- .parse_immediate = nft_arp_parse_immediate, + .print_header = nft_arp_print_header, + .print_rule = nft_arp_print_rule, + .save_rule = nft_arp_save_rule, +diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c +index c1a2c209cc1aa..94febc9890674 100644 +--- a/iptables/nft-bridge.c ++++ b/iptables/nft-bridge.c +@@ -284,14 +284,6 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, + } + } + +-static void nft_bridge_parse_immediate(const char *jumpto, bool nft_goto, +- void *data) +-{ +- struct iptables_command_state *cs = data; +- +- cs->jumpto = jumpto; +-} +- + /* return 0 if saddr, 1 if daddr, -1 on error */ + static int + lookup_check_ether_payload(uint32_t base, uint32_t offset, uint32_t len) +@@ -922,7 +914,6 @@ struct nft_family_ops nft_family_ops_bridge = { + .print_payload = NULL, + .parse_meta = nft_bridge_parse_meta, + .parse_payload = nft_bridge_parse_payload, +- .parse_immediate = nft_bridge_parse_immediate, + .parse_lookup = nft_bridge_parse_lookup, + .parse_match = nft_bridge_parse_match, + .parse_target = nft_bridge_parse_target, +diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c +index a5b835b1f681d..76c76b67100ca 100644 +--- a/iptables/nft-ipv4.c ++++ b/iptables/nft-ipv4.c +@@ -241,15 +241,9 @@ static void nft_ipv4_parse_payload(struct nft_xt_ctx *ctx, + } + } + +-static void nft_ipv4_parse_immediate(const char *jumpto, bool nft_goto, +- void *data) ++static void nft_ipv4_set_goto_flag(struct iptables_command_state *cs) + { +- struct iptables_command_state *cs = data; +- +- cs->jumpto = jumpto; +- +- if (nft_goto) +- cs->fw.ip.flags |= IPT_F_GOTO; ++ cs->fw.ip.flags |= IPT_F_GOTO; + } + + static void print_fragment(unsigned int flags, unsigned int invflags, +@@ -473,7 +467,7 @@ struct nft_family_ops nft_family_ops_ipv4 = { + .is_same = nft_ipv4_is_same, + .parse_meta = nft_ipv4_parse_meta, + .parse_payload = nft_ipv4_parse_payload, +- .parse_immediate = nft_ipv4_parse_immediate, ++ .set_goto_flag = nft_ipv4_set_goto_flag, + .print_header = print_header, + .print_rule = nft_ipv4_print_rule, + .save_rule = nft_ipv4_save_rule, +diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c +index 46008fc5e762a..fac0f16cfe815 100644 +--- a/iptables/nft-ipv6.c ++++ b/iptables/nft-ipv6.c +@@ -180,15 +180,9 @@ static void nft_ipv6_parse_payload(struct nft_xt_ctx *ctx, + } + } + +-static void nft_ipv6_parse_immediate(const char *jumpto, bool nft_goto, +- void *data) ++static void nft_ipv6_set_goto_flag(struct iptables_command_state *cs) + { +- struct iptables_command_state *cs = data; +- +- cs->jumpto = jumpto; +- +- if (nft_goto) +- cs->fw6.ipv6.flags |= IP6T_F_GOTO; ++ cs->fw6.ipv6.flags |= IP6T_F_GOTO; + } + + static void nft_ipv6_print_rule(struct nft_handle *h, struct nftnl_rule *r, +@@ -415,7 +409,7 @@ struct nft_family_ops nft_family_ops_ipv6 = { + .is_same = nft_ipv6_is_same, + .parse_meta = nft_ipv6_parse_meta, + .parse_payload = nft_ipv6_parse_payload, +- .parse_immediate = nft_ipv6_parse_immediate, ++ .set_goto_flag = nft_ipv6_set_goto_flag, + .print_header = print_header, + .print_rule = nft_ipv6_print_rule, + .save_rule = nft_ipv6_save_rule, +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index f270f610a8f67..894407f7d9b57 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -495,9 +495,7 @@ static void nft_parse_counter(struct nftnl_expr *e, struct xt_counters *counters + static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) + { + const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN); +- const char *jumpto = NULL; +- bool nft_goto = false; +- void *data = ctx->cs; ++ struct iptables_command_state *cs = ctx->cs; + int verdict; + + if (nftnl_expr_is_set(e, NFTNL_EXPR_IMM_DATA)) { +@@ -520,23 +518,22 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) + /* Standard target? */ + switch(verdict) { + case NF_ACCEPT: +- jumpto = "ACCEPT"; ++ cs->jumpto = "ACCEPT"; + break; + case NF_DROP: +- jumpto = "DROP"; ++ cs->jumpto = "DROP"; + break; + case NFT_RETURN: +- jumpto = "RETURN"; ++ cs->jumpto = "RETURN"; + break;; + case NFT_GOTO: +- nft_goto = true; ++ if (ctx->h->ops->set_goto_flag) ++ ctx->h->ops->set_goto_flag(cs); + /* fall through */ + case NFT_JUMP: +- jumpto = chain; ++ cs->jumpto = chain; + break; + } +- +- ctx->h->ops->parse_immediate(jumpto, nft_goto, data); + } + + static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e) +diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h +index 519118a2daf6c..2c5f2cfc012d5 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -89,7 +89,7 @@ struct nft_family_ops { + void *data); + void (*parse_lookup)(struct nft_xt_ctx *ctx, struct nftnl_expr *e, + void *data); +- void (*parse_immediate)(const char *jumpto, bool nft_goto, void *data); ++ void (*set_goto_flag)(struct iptables_command_state *cs); + + void (*print_table_header)(const char *tablename); + void (*print_header)(unsigned int format, const char *chain, +-- +2.40.0 + diff --git a/SOURCES/0063-nft-Speed-up-immediate-parsing.patch b/SOURCES/0063-nft-Speed-up-immediate-parsing.patch new file mode 100644 index 0000000..1af0583 --- /dev/null +++ b/SOURCES/0063-nft-Speed-up-immediate-parsing.patch @@ -0,0 +1,119 @@ +From 1a3d13b637e71f1f207eda17f816c58a9425971e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 1 Mar 2022 19:46:21 +0100 +Subject: [PATCH] nft: Speed up immediate parsing + +Parsing of rules which jump to a chain pointlessly causes a call to +xtables_find_target() despite the code already knowing the outcome. + +Avoid the significant delay for rulesets with many chain jumps by +performing the (standard) target lookup only for accept/drop/return +verdicts. + +From a biased test-case on my VM: + +| # iptables-nft-save | grep -c -- '-j' +| 133943 +| # time ./old/iptables-nft-save >/dev/null +| real 0m45.566s +| user 0m1.308s +| sys 0m8.430s +| # time ./new/iptables-nft-save >/dev/null +| real 0m3.547s +| user 0m0.762s +| sys 0m2.476s + +Signed-off-by: Phil Sutter +Acked-by: Florian Westphal +(cherry picked from commit 07ee529f5a62838d68be59683be99bf6a7cda0f2) +--- + iptables/nft-bridge.c | 1 + + iptables/nft-shared.c | 37 ++++++++++++++++++------------------- + 2 files changed, 19 insertions(+), 19 deletions(-) + +diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c +index 94febc9890674..9cc6f87b28fe0 100644 +--- a/iptables/nft-bridge.c ++++ b/iptables/nft-bridge.c +@@ -539,6 +539,7 @@ static void nft_bridge_parse_target(struct xtables_target *t, void *data) + } + + cs->target = t; ++ cs->jumpto = t->name; + } + + static void nft_rule_to_ebtables_command_state(struct nft_handle *h, +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 894407f7d9b57..6c643a8c06aaa 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -496,6 +496,8 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) + { + const char *chain = nftnl_expr_get_str(e, NFTNL_EXPR_IMM_CHAIN); + struct iptables_command_state *cs = ctx->cs; ++ struct xt_entry_target *t; ++ uint32_t size; + int verdict; + + if (nftnl_expr_is_set(e, NFTNL_EXPR_IMM_DATA)) { +@@ -532,8 +534,21 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) + /* fall through */ + case NFT_JUMP: + cs->jumpto = chain; +- break; ++ /* fall through */ ++ default: ++ return; + } ++ ++ cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); ++ if (!cs->target) ++ return; ++ ++ size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size; ++ t = xtables_calloc(1, size); ++ t->u.target_size = size; ++ t->u.user.revision = cs->target->revision; ++ strcpy(t->u.user.name, cs->jumpto); ++ cs->target->t = t; + } + + static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e) +@@ -661,25 +676,8 @@ void nft_rule_to_iptables_command_state(struct nft_handle *h, + } + } + +- if (cs->target != NULL) { +- cs->jumpto = cs->target->name; +- } else if (cs->jumpto != NULL) { +- struct xt_entry_target *t; +- uint32_t size; +- +- cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD); +- if (!cs->target) +- return; +- +- size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size; +- t = xtables_calloc(1, size); +- t->u.target_size = size; +- t->u.user.revision = cs->target->revision; +- strcpy(t->u.user.name, cs->jumpto); +- cs->target->t = t; +- } else { ++ if (!cs->jumpto) + cs->jumpto = ""; +- } + } + + void nft_clear_iptables_command_state(struct iptables_command_state *cs) +@@ -968,6 +966,7 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data) + struct iptables_command_state *cs = data; + + cs->target = t; ++ cs->jumpto = t->name; + } + + void nft_check_xt_legacy(int family, bool is_ipt_save) +-- +2.40.0 + diff --git a/SOURCES/0064-xshared-Prefer-xtables_chain_protos-lookup-over-getp.patch b/SOURCES/0064-xshared-Prefer-xtables_chain_protos-lookup-over-getp.patch new file mode 100644 index 0000000..519887d --- /dev/null +++ b/SOURCES/0064-xshared-Prefer-xtables_chain_protos-lookup-over-getp.patch @@ -0,0 +1,104 @@ +From 38ddff6cd616cf9d6869bcf8fa3c01e186446cb4 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 1 Mar 2022 23:05:29 +0100 +Subject: [PATCH] xshared: Prefer xtables_chain_protos lookup over getprotoent + +When dumping a large ruleset, common protocol matches such as for TCP +port number significantly slow down rule printing due to repeated calls +for getprotobynumber(). The latter does not involve any caching, so +/etc/protocols is consulted over and over again. + +As a simple countermeasure, make functions converting between proto +number and name prefer the built-in list of "well-known" protocols. This +is not a perfect solution, repeated rules for protocol names libxtables +does not cache (e.g. igmp or dccp) will still be slow. Implementing +getprotoent() result caching could solve this. + +As a side-effect, explicit check for pseudo-protocol "all" may be +dropped as it is contained in the built-in list and therefore immutable. + +Also update xtables_chain_protos entries a bit to align with typical +/etc/protocols contents. The testsuite assumes those names, so the +preferred ones prior to this patch are indeed uncommon nowadays. + +Signed-off-by: Phil Sutter +Acked-by: Florian Westphal +(cherry picked from commit b6196c7504d4d41827cea86c167926125cdbf1f3) +--- + iptables/xshared.c | 8 ++++---- + libxtables/xtables.c | 19 ++++++------------- + 2 files changed, 10 insertions(+), 17 deletions(-) + +diff --git a/iptables/xshared.c b/iptables/xshared.c +index 26e938309eab3..f7581967efc28 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -52,16 +52,16 @@ proto_to_name(uint16_t proto, int nolookup) + { + unsigned int i; + ++ for (i = 0; xtables_chain_protos[i].name != NULL; ++i) ++ if (xtables_chain_protos[i].num == proto) ++ return xtables_chain_protos[i].name; ++ + if (proto && !nolookup) { + struct protoent *pent = getprotobynumber(proto); + if (pent) + return pent->p_name; + } + +- for (i = 0; xtables_chain_protos[i].name != NULL; ++i) +- if (xtables_chain_protos[i].num == proto) +- return xtables_chain_protos[i].name; +- + return NULL; + } + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 6ded6cc720ea8..cb380ad61ccb5 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -2077,10 +2077,11 @@ const struct xtables_pprot xtables_chain_protos[] = { + {"udp", IPPROTO_UDP}, + {"udplite", IPPROTO_UDPLITE}, + {"icmp", IPPROTO_ICMP}, +- {"icmpv6", IPPROTO_ICMPV6}, + {"ipv6-icmp", IPPROTO_ICMPV6}, ++ {"icmpv6", IPPROTO_ICMPV6}, + {"esp", IPPROTO_ESP}, + {"ah", IPPROTO_AH}, ++ {"mobility-header", IPPROTO_MH}, + {"ipv6-mh", IPPROTO_MH}, + {"mh", IPPROTO_MH}, + {"all", 0}, +@@ -2096,23 +2097,15 @@ xtables_parse_protocol(const char *s) + if (xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX)) + return proto; + +- /* first deal with the special case of 'all' to prevent +- * people from being able to redefine 'all' in nsswitch +- * and/or provoke expensive [not working] ldap/nis/... +- * lookups */ +- if (strcmp(s, "all") == 0) +- return 0; ++ for (i = 0; xtables_chain_protos[i].name != NULL; ++i) { ++ if (strcmp(s, xtables_chain_protos[i].name) == 0) ++ return xtables_chain_protos[i].num; ++ } + + pent = getprotobyname(s); + if (pent != NULL) + return pent->p_proto; + +- for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) { +- if (xtables_chain_protos[i].name == NULL) +- continue; +- if (strcmp(s, xtables_chain_protos[i].name) == 0) +- return xtables_chain_protos[i].num; +- } + xt_params->exit_err(PARAMETER_PROBLEM, + "unknown protocol \"%s\" specified", s); + return -1; +-- +2.40.0 + diff --git a/SOURCES/0065-libxtables-Fix-for-warning-in-xtables_ipmask_to_nume.patch b/SOURCES/0065-libxtables-Fix-for-warning-in-xtables_ipmask_to_nume.patch new file mode 100644 index 0000000..dc8f89f --- /dev/null +++ b/SOURCES/0065-libxtables-Fix-for-warning-in-xtables_ipmask_to_nume.patch @@ -0,0 +1,41 @@ +From f6915482a365373c5892752f87086740b84fe2d3 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 15 Mar 2022 12:17:25 +0100 +Subject: [PATCH] libxtables: Fix for warning in xtables_ipmask_to_numeric + +Gcc complains: + +| xtables.c: In function 'xtables_ipmask_to_numeric': +| xtables.c:1491:34: warning: '__builtin___sprintf_chk' may write a terminating nul past the end of the destination [-Wformat-overflow=] +| 1491 | sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); +| | ^ + +Indeed, xtables_ipaddr_to_numeric() returns a pointer to a 20 byte +buffer and xtables_ipmask_to_numeric() writes its content into a buffer +of same size at offset 1. Yet length of returned string is deterministic +as it is an IPv4 address. So shrink it to the minimum of 16 bytes which +eliminates the warning as well. + +Fixes: a96166c24eaac ("libxtables: add xtables_ip[6]mask_to_cidr") +Signed-off-by: Phil Sutter +(cherry picked from commit 0c8e253595bd80e4ddd73230d079e33cd5420b32) +--- + libxtables/xtables.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index cb380ad61ccb5..2e6c68292f16a 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -1389,7 +1389,7 @@ void xtables_param_act(unsigned int status, const char *p1, ...) + + const char *xtables_ipaddr_to_numeric(const struct in_addr *addrp) + { +- static char buf[20]; ++ static char buf[16]; + const unsigned char *bytep = (const void *)&addrp->s_addr; + + sprintf(buf, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]); +-- +2.40.0 + diff --git a/SOURCES/0066-nft-Reject-standard-targets-as-chain-names-when-rest.patch b/SOURCES/0066-nft-Reject-standard-targets-as-chain-names-when-rest.patch new file mode 100644 index 0000000..9155bdc --- /dev/null +++ b/SOURCES/0066-nft-Reject-standard-targets-as-chain-names-when-rest.patch @@ -0,0 +1,118 @@ +From 0a2bf490dde3b55fd2607976aa07a853a18e15f7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 16 Mar 2022 17:14:07 +0100 +Subject: [PATCH] nft: Reject standard targets as chain names when restoring + +Reuse parse_chain() called from do_parse() for '-N' and rename it for a +better description of what it does. + +Note that by itself, this patch will likely kill iptables-restore +performance for big rulesets due to the extra extension lookup for chain +lines. A following patch announcing those chains to libxtables will +alleviate that. + +Signed-off-by: Phil Sutter +Reviewed-by: Florian Westphal +(cherry picked from commit b1aee6b2238794446feba41778f88703784560f7) + +Conflicts: + iptables/xshared.c +-> Context change due to missing commit 9dc50b5b8e441 + ("xshared: Merge invflags handling code"). +-> Adjust to missing commits 62c3c93d4b0f5 + ("xshared: Move do_parse to shared space"), 9baf3bf0e77da + ("iptables: Use xtables' do_parse() function") and 5c2c2eea2fff3 + ("ip6tables: Use the shared do_parse, too"). +--- + iptables/ip6tables.c | 2 +- + iptables/iptables.c | 2 +- + iptables/xshared.c | 2 +- + iptables/xshared.h | 2 +- + iptables/xtables-restore.c | 5 +---- + iptables/xtables.c | 2 +- + 6 files changed, 6 insertions(+), 9 deletions(-) + +diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c +index 6db91c807bcea..897f30d5ef4b0 100644 +--- a/iptables/ip6tables.c ++++ b/iptables/ip6tables.c +@@ -1156,7 +1156,7 @@ int do_command6(int argc, char *argv[], char **table, + break; + + case 'N': +- parse_chain(optarg); ++ assert_valid_chain_name(optarg); + add_command(&command, CMD_NEW_CHAIN, CMD_NONE, + cs.invert); + chain = optarg; +diff --git a/iptables/iptables.c b/iptables/iptables.c +index a33416a887ed4..9964d14ed8195 100644 +--- a/iptables/iptables.c ++++ b/iptables/iptables.c +@@ -1153,7 +1153,7 @@ int do_command4(int argc, char *argv[], char **table, + break; + + case 'N': +- parse_chain(optarg); ++ assert_valid_chain_name(optarg); + add_command(&command, CMD_NEW_CHAIN, CMD_NONE, + cs.invert); + chain = optarg; +diff --git a/iptables/xshared.c b/iptables/xshared.c +index f7581967efc28..b052b849b2069 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -849,7 +849,7 @@ char opt2char(int option) + return *ptr; + } + +-void parse_chain(const char *chainname) ++void assert_valid_chain_name(const char *chainname) + { + const char *ptr; + +diff --git a/iptables/xshared.h b/iptables/xshared.h +index d80c8beee1894..c512f20afd33a 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -222,7 +222,7 @@ char cmd2char(int option); + void add_command(unsigned int *cmd, const int newcmd, + const int othercmds, int invert); + int parse_rulenumber(const char *rule); +-void parse_chain(const char *chainname); ++void assert_valid_chain_name(const char *chainname); + + void generic_opt_check(int command, int options); + char opt2char(int option); +diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c +index a3bb4f00e79c6..5d0e44843b285 100644 +--- a/iptables/xtables-restore.c ++++ b/iptables/xtables-restore.c +@@ -156,10 +156,7 @@ static void xtables_restore_parse_line(struct nft_handle *h, + "%s: line %u chain name invalid\n", + xt_params->program_name, line); + +- if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) +- xtables_error(PARAMETER_PROBLEM, +- "Invalid chain name `%s' (%u chars max)", +- chain, XT_EXTENSION_MAXNAMELEN - 1); ++ assert_valid_chain_name(chain); + + policy = strtok(NULL, " \t\n"); + DEBUGP("line %u, policy '%s'\n", line, policy); +diff --git a/iptables/xtables.c b/iptables/xtables.c +index 7ef1702a0cd50..3c7b3fc45b6f6 100644 +--- a/iptables/xtables.c ++++ b/iptables/xtables.c +@@ -587,7 +587,7 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], + break; + + case 'N': +- parse_chain(optarg); ++ assert_valid_chain_name(optarg); + add_command(&p->command, CMD_NEW_CHAIN, CMD_NONE, + cs->invert); + p->chain = optarg; +-- +2.40.0 + diff --git a/SOURCES/0067-libxtables-Implement-notargets-hash-table.patch b/SOURCES/0067-libxtables-Implement-notargets-hash-table.patch new file mode 100644 index 0000000..bce7ffc --- /dev/null +++ b/SOURCES/0067-libxtables-Implement-notargets-hash-table.patch @@ -0,0 +1,140 @@ +From 064d7af6927b7b47d13d7fa7ad815f99d83d5006 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 15 Dec 2020 15:40:56 +0100 +Subject: [PATCH] libxtables: Implement notargets hash table + +Target lookup is relatively costly due to the filesystem access. Avoid +this overhead in huge rulesets which contain many chain jumps by caching +the failed lookups into a hashtable for later. + +Signed-off-by: Phil Sutter +Acked-by: Florian Westphal +(cherry picked from commit f58b0d7406451afbb4b9b6c7888990c964fa7c79) +--- + libxtables/xtables.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 75 insertions(+) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 2e6c68292f16a..b2b3eddf78dbc 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #ifndef NO_SHARED_LIBS + #include +@@ -242,6 +243,71 @@ static void dlreg_free(void) + } + #endif + ++struct notarget { ++ struct hlist_node node; ++ char name[]; ++}; ++ ++#define NOTARGET_HSIZE 512 ++static struct hlist_head notargets[NOTARGET_HSIZE]; ++ ++static void notargets_hlist_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < NOTARGET_HSIZE; i++) ++ INIT_HLIST_HEAD(¬argets[i]); ++} ++ ++static void notargets_hlist_free(void) ++{ ++ struct hlist_node *pos, *n; ++ struct notarget *cur; ++ int i; ++ ++ for (i = 0; i < NOTARGET_HSIZE; i++) { ++ hlist_for_each_entry_safe(cur, pos, n, ¬argets[i], node) { ++ hlist_del(&cur->node); ++ free(cur); ++ } ++ } ++} ++ ++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 notarget *notargets_hlist_lookup(const char *name) ++{ ++ uint32_t key = djb_hash(name) % NOTARGET_HSIZE; ++ struct hlist_node *node; ++ struct notarget *cur; ++ ++ hlist_for_each_entry(cur, node, ¬argets[key], node) { ++ if (!strcmp(name, cur->name)) ++ return cur; ++ } ++ return NULL; ++} ++ ++static void notargets_hlist_insert(const char *name) ++{ ++ struct notarget *cur; ++ ++ if (!name) ++ return; ++ ++ cur = xtables_malloc(sizeof(*cur) + strlen(name) + 1); ++ strcpy(cur->name, name); ++ hlist_add_head(&cur->node, ¬argets[djb_hash(name) % NOTARGET_HSIZE]); ++} ++ + void xtables_init(void) + { + xtables_libdir = getenv("XTABLES_LIBDIR"); +@@ -267,6 +333,8 @@ void xtables_init(void) + return; + } + xtables_libdir = XTABLES_LIBDIR; ++ ++ notargets_hlist_init(); + } + + void xtables_fini(void) +@@ -274,6 +342,7 @@ void xtables_fini(void) + #ifndef NO_SHARED_LIBS + dlreg_free(); + #endif ++ notargets_hlist_free(); + } + + void xtables_set_nfproto(uint8_t nfproto) +@@ -800,6 +869,10 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + || strcmp(name, XTC_LABEL_QUEUE) == 0 + || strcmp(name, XTC_LABEL_RETURN) == 0) + name = "standard"; ++ /* known non-target? */ ++ else if (notargets_hlist_lookup(name) && ++ tryload != XTF_LOAD_MUST_SUCCEED) ++ return NULL; + + /* Trigger delayed initialization */ + for (dptr = &xtables_pending_targets; *dptr; ) { +@@ -865,6 +938,8 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + + if (ptr) + ptr->used = 1; ++ else ++ notargets_hlist_insert(name); + + return ptr; + } +-- +2.40.0 + diff --git a/SOURCES/0068-libxtables-Boost-rule-target-checks-by-announcing-ch.patch b/SOURCES/0068-libxtables-Boost-rule-target-checks-by-announcing-ch.patch new file mode 100644 index 0000000..dc5e7bc --- /dev/null +++ b/SOURCES/0068-libxtables-Boost-rule-target-checks-by-announcing-ch.patch @@ -0,0 +1,86 @@ +From 2fb92babbf460de158cc435f66c46f0642763193 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 4 Mar 2022 12:50:01 +0100 +Subject: [PATCH] libxtables: Boost rule target checks by announcing chain + names + +When restoring a ruleset, feed libxtables with chain names from +respective lines to avoid an extension search. + +While the user's intention is clear, this effectively disables the +sanity check for clashes with target extensions. But: + +* The check yielded only a warning and the clashing chain was finally + accepted. + +* Users crafting iptables dumps for feeding into iptables-restore likely + know what they're doing. + +Signed-off-by: Phil Sutter +Acked-by: Florian Westphal +(cherry picked from commit ac4c84cc63d3cc021ca532692885a644fcde4518) +--- + include/xtables.h | 3 +++ + iptables/iptables-restore.c | 1 + + iptables/xtables-restore.c | 1 + + libxtables/xtables.c | 6 ++++++ + 4 files changed, 11 insertions(+) + +diff --git a/include/xtables.h b/include/xtables.h +index a7b36979398ba..3c0d0f78e8d1a 100644 +--- a/include/xtables.h ++++ b/include/xtables.h +@@ -633,6 +633,9 @@ void xt_xlate_add_comment(struct xt_xlate *xl, const char *comment); + const char *xt_xlate_get_comment(struct xt_xlate *xl); + const char *xt_xlate_get(struct xt_xlate *xl); + ++/* informed target lookups */ ++void xtables_announce_chain(const char *name); ++ + #ifdef XTABLES_INTERNAL + + /* Shipped modules rely on this... */ +diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c +index cc2c2b8b10086..a34d95015c93c 100644 +--- a/iptables/iptables-restore.c ++++ b/iptables/iptables-restore.c +@@ -311,6 +311,7 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb, + cb->ops->strerror(errno)); + } + ++ xtables_announce_chain(chain); + ret = 1; + + } else if (in_table) { +diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c +index 5d0e44843b285..b3c8dbaa7e2cc 100644 +--- a/iptables/xtables-restore.c ++++ b/iptables/xtables-restore.c +@@ -156,6 +156,7 @@ static void xtables_restore_parse_line(struct nft_handle *h, + "%s: line %u chain name invalid\n", + xt_params->program_name, line); + ++ xtables_announce_chain(chain); + assert_valid_chain_name(chain); + + policy = strtok(NULL, " \t\n"); +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index b2b3eddf78dbc..803551053c15f 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -308,6 +308,12 @@ static void notargets_hlist_insert(const char *name) + hlist_add_head(&cur->node, ¬argets[djb_hash(name) % NOTARGET_HSIZE]); + } + ++void xtables_announce_chain(const char *name) ++{ ++ if (!notargets_hlist_lookup(name)) ++ notargets_hlist_insert(name); ++} ++ + void xtables_init(void) + { + xtables_libdir = getenv("XTABLES_LIBDIR"); +-- +2.40.0 + diff --git a/SOURCES/0069-nft-shared-update-context-register-for-bitwise-expre.patch b/SOURCES/0069-nft-shared-update-context-register-for-bitwise-expre.patch new file mode 100644 index 0000000..d9b7fe9 --- /dev/null +++ b/SOURCES/0069-nft-shared-update-context-register-for-bitwise-expre.patch @@ -0,0 +1,31 @@ +From ef0405f9267dc23f51bb2b84e63e31ba484f3196 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Thu, 21 Apr 2022 16:53:33 +0200 +Subject: [PATCH] nft-shared: update context register for bitwise expression + +Update the destination register, otherwise nft_parse_cmp() gives up on +interpreting the cmp expression when bitwise sreg != dreg. + +Fixes: 2c4a34c30cb4 ("iptables-compat: fix address prefix") +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit 4c70c42fe8d937a2ca2709daa9efe96275d194da) +--- + iptables/nft-shared.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 6c643a8c06aaa..2b934ffc17756 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -459,6 +459,8 @@ static void nft_parse_bitwise(struct nft_xt_ctx *ctx, struct nftnl_expr *e) + if (ctx->reg && reg != ctx->reg) + return; + ++ reg = nftnl_expr_get_u32(e, NFTNL_EXPR_BITWISE_DREG); ++ ctx->reg = reg; + data = nftnl_expr_get(e, NFTNL_EXPR_BITWISE_XOR, &len); + memcpy(ctx->bitwise.xor, data, len); + data = nftnl_expr_get(e, NFTNL_EXPR_BITWISE_MASK, &len); +-- +2.40.0 + diff --git a/SOURCES/0070-extensions-MARK-Drop-extra-newline-at-end-of-help.patch b/SOURCES/0070-extensions-MARK-Drop-extra-newline-at-end-of-help.patch new file mode 100644 index 0000000..f1fb0e9 --- /dev/null +++ b/SOURCES/0070-extensions-MARK-Drop-extra-newline-at-end-of-help.patch @@ -0,0 +1,29 @@ +From 1f7fa039057778f229c5190d816551bf75955d5a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 May 2022 18:00:14 +0200 +Subject: [PATCH] extensions: MARK: Drop extra newline at end of help + +Fixes: f4b737fb0c52a ("libxt_MARK r2") +Signed-off-by: Phil Sutter +(cherry picked from commit adbfec0b3e3275ea5e7c933b630756cf01a4f8c6) +--- + extensions/libxt_MARK.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c +index b765af6c35304..1536563d0f4c7 100644 +--- a/extensions/libxt_MARK.c ++++ b/extensions/libxt_MARK.c +@@ -77,8 +77,7 @@ static void mark_tg_help(void) + " --set-mark value[/mask] Clear bits in mask and OR value into nfmark\n" + " --and-mark bits Binary AND the nfmark with bits\n" + " --or-mark bits Binary OR the nfmark with bits\n" +-" --xor-mark bits Binary XOR the nfmark with bits\n" +-"\n"); ++" --xor-mark bits Binary XOR the nfmark with bits\n"); + } + + static void MARK_parse_v0(struct xt_option_call *cb) +-- +2.40.0 + diff --git a/SOURCES/0071-extensions-LOG-Document-log-macdecode-in-man-page.patch b/SOURCES/0071-extensions-LOG-Document-log-macdecode-in-man-page.patch new file mode 100644 index 0000000..2e09a68 --- /dev/null +++ b/SOURCES/0071-extensions-LOG-Document-log-macdecode-in-man-page.patch @@ -0,0 +1,28 @@ +From 32ae030336b73b57ebe0f5e74ea17e09834f3870 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 24 Mar 2022 11:06:24 +0100 +Subject: [PATCH] extensions: LOG: Document --log-macdecode in man page + +Help text already contains it, so no update needed there. + +Fixes: 127647892c7ca ("extensions: libipt_LOG/libip6t_LOG: support macdecode option") +Signed-off-by: Phil Sutter +(cherry picked from commit ce9195c6e2fa6c6daa3c34b94353a539237b3809) +--- + extensions/libxt_LOG.man | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/extensions/libxt_LOG.man b/extensions/libxt_LOG.man +index 354edf4cc2916..1d5071ba720b9 100644 +--- a/extensions/libxt_LOG.man ++++ b/extensions/libxt_LOG.man +@@ -30,3 +30,6 @@ Log options from the IP/IPv6 packet header. + .TP + \fB\-\-log\-uid\fP + Log the userid of the process which generated the packet. ++.TP ++\fB\-\-log\-macdecode\fP ++Log MAC addresses and protocol. +-- +2.40.0 + diff --git a/SOURCES/0072-nft-Fix-EPERM-handling-for-extensions-without-rev-0.patch b/SOURCES/0072-nft-Fix-EPERM-handling-for-extensions-without-rev-0.patch new file mode 100644 index 0000000..2d4c4ce --- /dev/null +++ b/SOURCES/0072-nft-Fix-EPERM-handling-for-extensions-without-rev-0.patch @@ -0,0 +1,65 @@ +From 26dc3496694dc71c95164b6885c7422196802c6d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 4 May 2022 11:19:16 +0200 +Subject: [PATCH] nft: Fix EPERM handling for extensions without rev 0 + +Treating revision 0 as compatible in EPERM case works fine as long as +there is a revision 0 of that extension defined in DSO. Fix the code for +others: Extend the EPERM handling to all revisions and keep the existing +warning for revision 0. + +Fixes: 17534cb18ed0a ("Improve error messages for unsupported extensions") +Signed-off-by: Phil Sutter +(cherry picked from commit 8468fd4f7c85c21ab375402bc80d0188412b6cbf) +--- + iptables/nft.c | 11 +++++++---- + .../shell/testcases/iptables/0008-unprivileged_0 | 6 ++++++ + 2 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 2393940d7f64a..c130369f78348 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3294,15 +3294,18 @@ int nft_compatible_revision(const char *name, uint8_t rev, int opt) + err: + mnl_socket_close(nl); + +- /* pretend revision 0 is valid - ++ /* ignore EPERM and errors for revision 0 - + * this is required for printing extension help texts as user, also + * helps error messaging on unavailable kernel extension */ +- if (ret < 0 && rev == 0) { +- if (errno != EPERM) ++ if (ret < 0) { ++ if (errno == EPERM) ++ return 1; ++ if (rev == 0) { + fprintf(stderr, + "Warning: Extension %s revision 0 not supported, missing kernel module?\n", + name); +- return 1; ++ return 1; ++ } + } + + return ret < 0 ? 0 : 1; +diff --git a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 +index 43e3bc8721dbd..983531fef4720 100755 +--- a/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 ++++ b/iptables/tests/shell/testcases/iptables/0008-unprivileged_0 +@@ -35,6 +35,12 @@ let "rc+=$?" + grep_or_rc "DNAT target options:" <<< "$out" + let "rc+=$?" + ++# TEE has no revision 0 ++out=$(run $XT_MULTI iptables -j TEE --help) ++let "rc+=$?" ++grep_or_rc "TEE target options:" <<< "$out" ++let "rc+=$?" ++ + out=$(run $XT_MULTI iptables -p tcp -j DNAT --help) + let "rc+=$?" + grep_or_rc "tcp match options:" <<< "$out" +-- +2.40.0 + diff --git a/SOURCES/0073-tests-shell-Check-overhead-in-iptables-save-and-rest.patch b/SOURCES/0073-tests-shell-Check-overhead-in-iptables-save-and-rest.patch new file mode 100644 index 0000000..29add61 --- /dev/null +++ b/SOURCES/0073-tests-shell-Check-overhead-in-iptables-save-and-rest.patch @@ -0,0 +1,61 @@ +From a40839b6c6d5d9742a5316ed3b4bd13516537ee1 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 2 Jun 2022 13:44:45 +0200 +Subject: [PATCH] tests: shell: Check overhead in iptables-save and -restore + +Some repeated calls have been reduced recently, assert this in a test +evaluating strace output. + +Signed-off-by: Phil Sutter +(cherry picked from commit 0416ae5dea134b33e22c97e68b64010d679debe1) +--- + .../shell/testcases/ipt-save/0007-overhead_0 | 37 +++++++++++++++++++ + 1 file changed, 37 insertions(+) + create mode 100755 iptables/tests/shell/testcases/ipt-save/0007-overhead_0 + +diff --git a/iptables/tests/shell/testcases/ipt-save/0007-overhead_0 b/iptables/tests/shell/testcases/ipt-save/0007-overhead_0 +new file mode 100755 +index 0000000000000..b86d71f209471 +--- /dev/null ++++ b/iptables/tests/shell/testcases/ipt-save/0007-overhead_0 +@@ -0,0 +1,37 @@ ++#!/bin/bash ++ ++# Test recent performance improvements in iptables-save due to reduced ++# overhead. ++ ++strace --version >/dev/null || { echo "skip for missing strace"; exit 0; } ++ ++RULESET=$( ++ echo "*filter" ++ for ((i = 0; i < 100; i++)); do ++ echo ":mychain$i -" ++ echo "-A FORWARD -p tcp --dport 22 -j mychain$i" ++ done ++ echo "COMMIT" ++) ++ ++RESTORE_STRACE=$(strace $XT_MULTI iptables-restore <<< "$RULESET" 2>&1 >/dev/null) ++SAVE_STRACE=$(strace $XT_MULTI iptables-save 2>&1 >/dev/null) ++ ++do_grep() { # (name, threshold, pattern) ++ local cnt=$(grep -c "$3") ++ [[ $cnt -le $2 ]] && return 0 ++ echo "ERROR: Too many $3 lookups for $1: $cnt > $2" ++ exit 1 ++} ++ ++# iptables prefers hard-coded protocol names instead of looking them up first ++ ++do_grep "$XT_MULTI iptables-restore" 0 /etc/protocols <<< "$RESTORE_STRACE" ++do_grep "$XT_MULTI iptables-save" 0 /etc/protocols <<< "$SAVE_STRACE" ++ ++# iptables-nft-save pointlessly checked whether chain jumps are targets ++ ++do_grep "$XT_MULTI iptables-restore" 10 libxt_ <<< "$RESTORE_STRACE" ++do_grep "$XT_MULTI iptables-save" 10 libxt_ <<< "$SAVE_STRACE" ++ ++exit 0 +-- +2.40.0 + diff --git a/SOURCES/0074-iptables-legacy-Drop-redundant-include-of-xtables-mu.patch b/SOURCES/0074-iptables-legacy-Drop-redundant-include-of-xtables-mu.patch new file mode 100644 index 0000000..4822d68 --- /dev/null +++ b/SOURCES/0074-iptables-legacy-Drop-redundant-include-of-xtables-mu.patch @@ -0,0 +1,33 @@ +From 88416b4ac4fabde5098f2ff22dc634e5e6f6da51 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 1 Jun 2022 19:29:28 +0200 +Subject: [PATCH] iptables-legacy: Drop redundant include of xtables-multi.h + +The header is included unconditionally first, so no point in doing it a +second time of ENABLE_NFTABLES is defined. + +Fixes: be70918eab26e ("xtables: rename xt-multi binaries to -nft, -legacy") +Signed-off-by: Phil Sutter +(cherry picked from commit ef5d0c68261611d72ccecb3ae05c24448fbc91f5) +--- + iptables/xtables-legacy-multi.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/iptables/xtables-legacy-multi.c b/iptables/xtables-legacy-multi.c +index 3b7905ff76b13..2c71931551b5c 100644 +--- a/iptables/xtables-legacy-multi.c ++++ b/iptables/xtables-legacy-multi.c +@@ -14,10 +14,6 @@ + #include "ip6tables-multi.h" + #endif + +-#ifdef ENABLE_NFTABLES +-#include "xtables-multi.h" +-#endif +- + static const struct subcommand multi_subcommands[] = { + #ifdef ENABLE_IPV4 + {"iptables", iptables_main}, +-- +2.40.0 + diff --git a/SOURCES/0075-tests-shell-Add-some-more-rules-to-0002-verbose-outp.patch b/SOURCES/0075-tests-shell-Add-some-more-rules-to-0002-verbose-outp.patch new file mode 100644 index 0000000..88cf7b4 --- /dev/null +++ b/SOURCES/0075-tests-shell-Add-some-more-rules-to-0002-verbose-outp.patch @@ -0,0 +1,55 @@ +From 9fb89d10d071076c3178749b4237c669db93aa39 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 20 May 2021 11:40:18 +0200 +Subject: [PATCH] tests: shell: Add some more rules to 0002-verbose-output_0 + +This increases coverage of function print_match() from 0 to 86.6%. + +Signed-off-by: Phil Sutter +(cherry picked from commit a219f8d407ee22d69bf74478b6c7331c602b28c6) +--- + .../testcases/ip6tables/0002-verbose-output_0 | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 b/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 +index 7b0e64686c6b6..7624cbab655ad 100755 +--- a/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 ++++ b/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 +@@ -9,12 +9,24 @@ RULE1='-i eth2 -o eth3 -s feed:babe::1 -d feed:babe::2 -j ACCEPT' + VOUT1='ACCEPT all opt in eth2 out eth3 feed:babe::1 -> feed:babe::2' + RULE2='-i eth2 -o eth3 -s feed:babe::4 -d feed:babe::5 -j ACCEPT' + VOUT2='ACCEPT all opt in eth2 out eth3 feed:babe::4 -> feed:babe::5' ++RULE3='-p icmpv6 -m icmp6 --icmpv6-type no-route' ++VOUT3=' ipv6-icmp opt in * out * ::/0 -> ::/0 ipv6-icmptype 1 code 0' ++RULE4='-m dst --dst-len 42 -m rt --rt-type 23' ++VOUT4=' all opt in * out * ::/0 -> ::/0 dst length:42 rt type:23' ++RULE5='-m frag --fragid 1337 -j LOG' ++VOUT5='LOG all opt in * out * ::/0 -> ::/0 frag id:1337 LOG flags 0 level 4' + + diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -A FORWARD $RULE1) + diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -I FORWARD 2 $RULE2) ++diff -u -Z <(echo -e "$VOUT3") <($XT_MULTI ip6tables -v -A FORWARD $RULE3) ++diff -u -Z <(echo -e "$VOUT4") <($XT_MULTI ip6tables -v -A FORWARD $RULE4) ++diff -u -Z <(echo -e "$VOUT5") <($XT_MULTI ip6tables -v -A FORWARD $RULE5) + + diff -u -Z <(echo -e "$VOUT1") <($XT_MULTI ip6tables -v -C FORWARD $RULE1) + diff -u -Z <(echo -e "$VOUT2") <($XT_MULTI ip6tables -v -C FORWARD $RULE2) ++diff -u -Z <(echo -e "$VOUT3") <($XT_MULTI ip6tables -v -C FORWARD $RULE3) ++diff -u -Z <(echo -e "$VOUT4") <($XT_MULTI ip6tables -v -C FORWARD $RULE4) ++diff -u -Z <(echo -e "$VOUT5") <($XT_MULTI ip6tables -v -C FORWARD $RULE5) + + EXPECT='Chain INPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination +@@ -23,6 +35,9 @@ Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination + 0 0 ACCEPT all eth2 eth3 feed:babe::1 feed:babe::2 + 0 0 ACCEPT all eth2 eth3 feed:babe::4 feed:babe::5 ++ 0 0 ipv6-icmp * * ::/0 ::/0 ipv6-icmptype 1 code 0 ++ 0 0 all * * ::/0 ::/0 dst length:42 rt type:23 ++ 0 0 LOG all * * ::/0 ::/0 frag id:1337 LOG flags 0 level 4 + + Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) + pkts bytes target prot opt in out source destination' +-- +2.40.0 + diff --git a/SOURCES/0076-extensions-string-Do-not-print-default-to-value.patch b/SOURCES/0076-extensions-string-Do-not-print-default-to-value.patch new file mode 100644 index 0000000..c2ce8fd --- /dev/null +++ b/SOURCES/0076-extensions-string-Do-not-print-default-to-value.patch @@ -0,0 +1,39 @@ +From 30c3d8d215c63b7d9244f853c94958a6194153b7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 8 Jun 2022 13:28:10 +0200 +Subject: [PATCH] extensions: string: Do not print default --to value + +Default value is UINT16_MAX, not 0. Fix the conditional printing. + +Fixes: c6fbf41cdd157 ("update string match to reflect new kernel implementation (Pablo Neira)") +Signed-off-by: Phil Sutter +(cherry picked from commit 1bfb1d916e467e2bcbc44ce1a50a2be5c12b7ef8) +--- + extensions/libxt_string.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extensions/libxt_string.c b/extensions/libxt_string.c +index 7c6366cbbf1b3..f6496f6403498 100644 +--- a/extensions/libxt_string.c ++++ b/extensions/libxt_string.c +@@ -269,7 +269,7 @@ string_print(const void *ip, const struct xt_entry_match *match, int numeric) + printf(" ALGO name %s", info->algo); + if (info->from_offset != 0) + printf(" FROM %u", info->from_offset); +- if (info->to_offset != 0) ++ if (info->to_offset != UINT16_MAX) + printf(" TO %u", info->to_offset); + if (revision > 0 && info->u.v1.flags & XT_STRING_FLAG_IGNORECASE) + printf(" ICASE"); +@@ -293,7 +293,7 @@ static void string_save(const void *ip, const struct xt_entry_match *match) + printf(" --algo %s", info->algo); + if (info->from_offset != 0) + printf(" --from %u", info->from_offset); +- if (info->to_offset != 0) ++ if (info->to_offset != UINT16_MAX) + printf(" --to %u", info->to_offset); + if (revision > 0 && info->u.v1.flags & XT_STRING_FLAG_IGNORECASE) + printf(" --icase"); +-- +2.40.0 + diff --git a/SOURCES/0077-xtables-monitor-add-missing-spaces-in-printed-str.patch b/SOURCES/0077-xtables-monitor-add-missing-spaces-in-printed-str.patch new file mode 100644 index 0000000..bf05e59 --- /dev/null +++ b/SOURCES/0077-xtables-monitor-add-missing-spaces-in-printed-str.patch @@ -0,0 +1,45 @@ +From 40096cbbdd59f0bd431395f69bd30ade35ec1427 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= +Date: Wed, 22 Jun 2022 21:56:47 +0200 +Subject: [PATCH] xtables-monitor: add missing spaces in printed str +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +when printing the ID and OPTs in iptables/xtables-monitor.c, a space is +missing after the string, thereby concatenating the number with the next +item in the printed PACKET line. + +Fixes: d26c538b9a549 ("xtables: add xtables-monitor") +Signed-off-by: Anton Luka Šijanec +Signed-off-by: Phil Sutter +(cherry picked from commit 6c12201b5ff08d9e1524477ff63bb8810198d638) +--- + iptables/xtables-monitor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 4b9809805fb5b..89c739d5aacd1 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -340,7 +340,7 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg + inet_ntop(AF_INET, &iph->daddr, addrbuf, sizeof(addrbuf)); + printf("DST=%s ", addrbuf); + +- printf("LEN=%d TOS=0x%x TTL=%d ID=%d", ntohs(iph->tot_len), iph->tos, iph->ttl, ntohs(iph->id)); ++ printf("LEN=%d TOS=0x%x TTL=%d ID=%d ", ntohs(iph->tot_len), iph->tos, iph->ttl, ntohs(iph->id)); + if (iph->frag_off & htons(0x8000)) + printf("CE "); + if (iph->frag_off & htons(IP_DF)) +@@ -363,7 +363,7 @@ static void trace_print_packet(const struct nftnl_trace *nlt, struct cb_arg *arg + printf("OPT ("); + for (i = 0; i < optsize; i++) + printf("%02X", op[i]); +- printf(")"); ++ printf(") "); + } + break; + } +-- +2.40.0 + diff --git a/SOURCES/0078-libxtables-Fix-unsupported-extension-warning-corner-.patch b/SOURCES/0078-libxtables-Fix-unsupported-extension-warning-corner-.patch new file mode 100644 index 0000000..de434d5 --- /dev/null +++ b/SOURCES/0078-libxtables-Fix-unsupported-extension-warning-corner-.patch @@ -0,0 +1,91 @@ +From a9527fc387066ed774bdce38598d21eb8e52d899 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 30 Jun 2022 18:04:39 +0200 +Subject: [PATCH] libxtables: Fix unsupported extension warning corner case + +Some extensions are not supported in revision 0 by user space anymore, +for those the warning in xtables_compatible_revision() does not print as +no revision 0 is tried. + +To fix this, one has to track if none of the user space supported +revisions were accepted by the kernel. Therefore add respective logic to +xtables_find_{target,match}(). + +Note that this does not lead to duplicated warnings for unsupported +extensions that have a revision 0 because xtables_compatible_revision() +returns true for them to allow for extension's help output. + +For the record, these ip6tables extensions are affected: set/SET, +socket, tos/TOS, TPROXY and SNAT. In addition to that, TEE is affected +for both families. + +Fixes: 17534cb18ed0a ("Improve error messages for unsupported extensions") +Signed-off-by: Phil Sutter +(cherry picked from commit 552c4a2f9e5706fef5f7abb27d1492a78bbb2a37) +--- + libxtables/xtables.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 803551053c15f..598e43988e1a3 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -744,6 +744,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, + struct xtables_match *ptr; + const char *icmp6 = "icmp6"; + bool found = false; ++ bool seen = false; + + if (strlen(name) >= XT_EXTENSION_MAXNAMELEN) + xtables_error(PARAMETER_PROBLEM, +@@ -762,6 +763,7 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, + if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { + ptr = *dptr; + *dptr = (*dptr)->next; ++ seen = true; + if (!found && + xtables_fully_register_pending_match(ptr, prev)) { + found = true; +@@ -775,6 +777,11 @@ xtables_find_match(const char *name, enum xtables_tryload tryload, + dptr = &((*dptr)->next); + } + ++ if (seen && !found) ++ fprintf(stderr, ++ "Warning: Extension %s is not supported, missing kernel module?\n", ++ name); ++ + for (ptr = xtables_matches; ptr; ptr = ptr->next) { + if (extension_cmp(name, ptr->name, ptr->family)) { + struct xtables_match *clone; +@@ -867,6 +874,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + struct xtables_target **dptr; + struct xtables_target *ptr; + bool found = false; ++ bool seen = false; + + /* Standard target? */ + if (strcmp(name, "") == 0 +@@ -885,6 +893,7 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + if (extension_cmp(name, (*dptr)->name, (*dptr)->family)) { + ptr = *dptr; + *dptr = (*dptr)->next; ++ seen = true; + if (!found && + xtables_fully_register_pending_target(ptr, prev)) { + found = true; +@@ -898,6 +907,11 @@ xtables_find_target(const char *name, enum xtables_tryload tryload) + dptr = &((*dptr)->next); + } + ++ if (seen && !found) ++ fprintf(stderr, ++ "Warning: Extension %s is not supported, missing kernel module?\n", ++ name); ++ + for (ptr = xtables_targets; ptr; ptr = ptr->next) { + if (extension_cmp(name, ptr->name, ptr->family)) { + struct xtables_target *clone; +-- +2.40.0 + diff --git a/SOURCES/0079-extensions-libxt_conntrack-remove-always-false-condi.patch b/SOURCES/0079-extensions-libxt_conntrack-remove-always-false-condi.patch new file mode 100644 index 0000000..8e7ffba --- /dev/null +++ b/SOURCES/0079-extensions-libxt_conntrack-remove-always-false-condi.patch @@ -0,0 +1,61 @@ +From f41e10de4d82377b01e0db057bde3e68159f7531 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Sat, 23 Jul 2022 20:25:49 +0200 +Subject: [PATCH] extensions: libxt_conntrack: remove always-false conditionals + +libxt_conntrack.c:1292: warning: the comparison will always evaluate as +false for the address of origsrc_addr will never be NULL [-Waddress] + +Signed-off-by: Florian Westphal +(cherry picked from commit e88085ac41b4c962e1d85dcc8dc6fa0d1f80dc12) +--- + extensions/libxt_conntrack.c | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c +index 91f9e4aa994f8..6ab5c99133d3c 100644 +--- a/extensions/libxt_conntrack.c ++++ b/extensions/libxt_conntrack.c +@@ -1297,9 +1297,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, + } + + if (sinfo->match_flags & XT_CONNTRACK_ORIGSRC) { +- if (&sinfo->origsrc_addr == 0L) +- return 0; +- + xt_xlate_add(xl, "%sct original saddr %s", space, + sinfo->invert_flags & XT_CONNTRACK_ORIGSRC ? + "!= " : ""); +@@ -1309,9 +1306,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, + } + + if (sinfo->match_flags & XT_CONNTRACK_ORIGDST) { +- if (&sinfo->origdst_addr == 0L) +- return 0; +- + xt_xlate_add(xl, "%sct original daddr %s", space, + sinfo->invert_flags & XT_CONNTRACK_ORIGDST ? + "!= " : ""); +@@ -1321,9 +1315,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, + } + + if (sinfo->match_flags & XT_CONNTRACK_REPLSRC) { +- if (&sinfo->replsrc_addr == 0L) +- return 0; +- + xt_xlate_add(xl, "%sct reply saddr %s", space, + sinfo->invert_flags & XT_CONNTRACK_REPLSRC ? + "!= " : ""); +@@ -1333,9 +1324,6 @@ static int _conntrack3_mt_xlate(struct xt_xlate *xl, + } + + if (sinfo->match_flags & XT_CONNTRACK_REPLDST) { +- if (&sinfo->repldst_addr == 0L) +- return 0; +- + xt_xlate_add(xl, "%sct reply daddr %s", space, + sinfo->invert_flags & XT_CONNTRACK_REPLDST ? + "!= " : ""); +-- +2.40.0 + diff --git a/SOURCES/0080-nft-un-break-among-match-with-concatenation.patch b/SOURCES/0080-nft-un-break-among-match-with-concatenation.patch new file mode 100644 index 0000000..40c3d66 --- /dev/null +++ b/SOURCES/0080-nft-un-break-among-match-with-concatenation.patch @@ -0,0 +1,958 @@ +From 2fd494ffd99924931206c93d5c6d2806df1718ef Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Thu, 22 Sep 2022 13:33:50 +0200 +Subject: [PATCH] nft: un-break among match with concatenation + +The kernel commit 88cccd908d51 ("netfilter: nf_tables: NFTA_SET_ELEM_KEY_END requires concat and interval flags") +breaks ebtables-nft 'among' emulation, it sets NFTA_SET_ELEM_KEY_END but +doesn't set the CONCAT flag. + +Update uapi header and also set CONCAT. + +Signed-off-by: Florian Westphal +(cherry picked from commit 32efb4ffc33ae874b3f26f3380e2184ad6ceb26f) +--- + include/linux/netfilter/nf_tables.h | 483 +++++++++++++++++++++++++++- + iptables/nft.c | 2 +- + 2 files changed, 476 insertions(+), 9 deletions(-) + +diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h +index 66dceee0ae307..e94d1fa554cb2 100644 +--- a/include/linux/netfilter/nf_tables.h ++++ b/include/linux/netfilter/nf_tables.h +@@ -8,6 +8,7 @@ + #define NFT_SET_MAXNAMELEN NFT_NAME_MAXLEN + #define NFT_OBJ_MAXNAMELEN NFT_NAME_MAXLEN + #define NFT_USERDATA_MAXLEN 256 ++#define NFT_OSF_MAXGENRELEN 16 + + /** + * enum nft_registers - nf_tables registers +@@ -47,6 +48,7 @@ enum nft_registers { + + #define NFT_REG_SIZE 16 + #define NFT_REG32_SIZE 4 ++#define NFT_REG32_COUNT (NFT_REG32_15 - NFT_REG32_00 + 1) + + /** + * enum nft_verdicts - nf_tables internal verdicts +@@ -131,7 +133,7 @@ enum nf_tables_msg_types { + * @NFTA_LIST_ELEM: list element (NLA_NESTED) + */ + enum nft_list_attributes { +- NFTA_LIST_UNPEC, ++ NFTA_LIST_UNSPEC, + NFTA_LIST_ELEM, + __NFTA_LIST_MAX + }; +@@ -143,12 +145,14 @@ enum nft_list_attributes { + * @NFTA_HOOK_HOOKNUM: netfilter hook number (NLA_U32) + * @NFTA_HOOK_PRIORITY: netfilter hook priority (NLA_U32) + * @NFTA_HOOK_DEV: netdevice name (NLA_STRING) ++ * @NFTA_HOOK_DEVS: list of netdevices (NLA_NESTED) + */ + enum nft_hook_attributes { + NFTA_HOOK_UNSPEC, + NFTA_HOOK_HOOKNUM, + NFTA_HOOK_PRIORITY, + NFTA_HOOK_DEV, ++ NFTA_HOOK_DEVS, + __NFTA_HOOK_MAX + }; + #define NFTA_HOOK_MAX (__NFTA_HOOK_MAX - 1) +@@ -160,7 +164,10 @@ enum nft_hook_attributes { + */ + enum nft_table_flags { + NFT_TABLE_F_DORMANT = 0x1, ++ NFT_TABLE_F_OWNER = 0x2, + }; ++#define NFT_TABLE_F_MASK (NFT_TABLE_F_DORMANT | \ ++ NFT_TABLE_F_OWNER) + + /** + * enum nft_table_attributes - nf_tables table netlink attributes +@@ -168,6 +175,8 @@ enum nft_table_flags { + * @NFTA_TABLE_NAME: name of the table (NLA_STRING) + * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32) + * @NFTA_TABLE_USE: number of chains in this table (NLA_U32) ++ * @NFTA_TABLE_USERDATA: user data (NLA_BINARY) ++ * @NFTA_TABLE_OWNER: owner of this table through netlink portID (NLA_U32) + */ + enum nft_table_attributes { + NFTA_TABLE_UNSPEC, +@@ -176,10 +185,21 @@ enum nft_table_attributes { + NFTA_TABLE_USE, + NFTA_TABLE_HANDLE, + NFTA_TABLE_PAD, ++ NFTA_TABLE_USERDATA, ++ NFTA_TABLE_OWNER, + __NFTA_TABLE_MAX + }; + #define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1) + ++enum nft_chain_flags { ++ NFT_CHAIN_BASE = (1 << 0), ++ NFT_CHAIN_HW_OFFLOAD = (1 << 1), ++ NFT_CHAIN_BINDING = (1 << 2), ++}; ++#define NFT_CHAIN_FLAGS (NFT_CHAIN_BASE | \ ++ NFT_CHAIN_HW_OFFLOAD | \ ++ NFT_CHAIN_BINDING) ++ + /** + * enum nft_chain_attributes - nf_tables chain netlink attributes + * +@@ -191,6 +211,9 @@ enum nft_table_attributes { + * @NFTA_CHAIN_USE: number of references to this chain (NLA_U32) + * @NFTA_CHAIN_TYPE: type name of the string (NLA_NUL_STRING) + * @NFTA_CHAIN_COUNTERS: counter specification of the chain (NLA_NESTED: nft_counter_attributes) ++ * @NFTA_CHAIN_FLAGS: chain flags ++ * @NFTA_CHAIN_ID: uniquely identifies a chain in a transaction (NLA_U32) ++ * @NFTA_CHAIN_USERDATA: user data (NLA_BINARY) + */ + enum nft_chain_attributes { + NFTA_CHAIN_UNSPEC, +@@ -203,6 +226,9 @@ enum nft_chain_attributes { + NFTA_CHAIN_TYPE, + NFTA_CHAIN_COUNTERS, + NFTA_CHAIN_PAD, ++ NFTA_CHAIN_FLAGS, ++ NFTA_CHAIN_ID, ++ NFTA_CHAIN_USERDATA, + __NFTA_CHAIN_MAX + }; + #define NFTA_CHAIN_MAX (__NFTA_CHAIN_MAX - 1) +@@ -218,6 +244,7 @@ enum nft_chain_attributes { + * @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64) + * @NFTA_RULE_USERDATA: user data (NLA_BINARY, NFT_USERDATA_MAXLEN) + * @NFTA_RULE_ID: uniquely identifies a rule in a transaction (NLA_U32) ++ * @NFTA_RULE_POSITION_ID: transaction unique identifier of the previous rule (NLA_U32) + */ + enum nft_rule_attributes { + NFTA_RULE_UNSPEC, +@@ -230,6 +257,8 @@ enum nft_rule_attributes { + NFTA_RULE_USERDATA, + NFTA_RULE_PAD, + NFTA_RULE_ID, ++ NFTA_RULE_POSITION_ID, ++ NFTA_RULE_CHAIN_ID, + __NFTA_RULE_MAX + }; + #define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1) +@@ -266,8 +295,10 @@ enum nft_rule_compat_attributes { + * @NFT_SET_INTERVAL: set contains intervals + * @NFT_SET_MAP: set is used as a dictionary + * @NFT_SET_TIMEOUT: set uses timeouts +- * @NFT_SET_EVAL: set contains expressions for evaluation ++ * @NFT_SET_EVAL: set can be updated from the evaluation path + * @NFT_SET_OBJECT: set contains stateful objects ++ * @NFT_SET_CONCAT: set contains a concatenation ++ * @NFT_SET_EXPR: set contains expressions + */ + enum nft_set_flags { + NFT_SET_ANONYMOUS = 0x1, +@@ -277,6 +308,8 @@ enum nft_set_flags { + NFT_SET_TIMEOUT = 0x10, + NFT_SET_EVAL = 0x20, + NFT_SET_OBJECT = 0x40, ++ NFT_SET_CONCAT = 0x80, ++ NFT_SET_EXPR = 0x100, + }; + + /** +@@ -294,14 +327,28 @@ enum nft_set_policies { + * enum nft_set_desc_attributes - set element description + * + * @NFTA_SET_DESC_SIZE: number of elements in set (NLA_U32) ++ * @NFTA_SET_DESC_CONCAT: description of field concatenation (NLA_NESTED) + */ + enum nft_set_desc_attributes { + NFTA_SET_DESC_UNSPEC, + NFTA_SET_DESC_SIZE, ++ NFTA_SET_DESC_CONCAT, + __NFTA_SET_DESC_MAX + }; + #define NFTA_SET_DESC_MAX (__NFTA_SET_DESC_MAX - 1) + ++/** ++ * enum nft_set_field_attributes - attributes of concatenated fields ++ * ++ * @NFTA_SET_FIELD_LEN: length of single field, in bits (NLA_U32) ++ */ ++enum nft_set_field_attributes { ++ NFTA_SET_FIELD_UNSPEC, ++ NFTA_SET_FIELD_LEN, ++ __NFTA_SET_FIELD_MAX ++}; ++#define NFTA_SET_FIELD_MAX (__NFTA_SET_FIELD_MAX - 1) ++ + /** + * enum nft_set_attributes - nf_tables set netlink attributes + * +@@ -320,6 +367,8 @@ enum nft_set_desc_attributes { + * @NFTA_SET_USERDATA: user data (NLA_BINARY) + * @NFTA_SET_OBJ_TYPE: stateful object type (NLA_U32: NFT_OBJECT_*) + * @NFTA_SET_HANDLE: set handle (NLA_U64) ++ * @NFTA_SET_EXPR: set expression (NLA_NESTED: nft_expr_attributes) ++ * @NFTA_SET_EXPRESSIONS: list of expressions (NLA_NESTED: nft_list_attributes) + */ + enum nft_set_attributes { + NFTA_SET_UNSPEC, +@@ -339,6 +388,8 @@ enum nft_set_attributes { + NFTA_SET_PAD, + NFTA_SET_OBJ_TYPE, + NFTA_SET_HANDLE, ++ NFTA_SET_EXPR, ++ NFTA_SET_EXPRESSIONS, + __NFTA_SET_MAX + }; + #define NFTA_SET_MAX (__NFTA_SET_MAX - 1) +@@ -347,9 +398,11 @@ enum nft_set_attributes { + * enum nft_set_elem_flags - nf_tables set element flags + * + * @NFT_SET_ELEM_INTERVAL_END: element ends the previous interval ++ * @NFT_SET_ELEM_CATCHALL: special catch-all element + */ + enum nft_set_elem_flags { + NFT_SET_ELEM_INTERVAL_END = 0x1, ++ NFT_SET_ELEM_CATCHALL = 0x2, + }; + + /** +@@ -363,6 +416,8 @@ enum nft_set_elem_flags { + * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY) + * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes) + * @NFTA_SET_ELEM_OBJREF: stateful object reference (NLA_STRING) ++ * @NFTA_SET_ELEM_KEY_END: closing key value (NLA_NESTED: nft_data) ++ * @NFTA_SET_ELEM_EXPRESSIONS: list of expressions (NLA_NESTED: nft_list_attributes) + */ + enum nft_set_elem_attributes { + NFTA_SET_ELEM_UNSPEC, +@@ -375,6 +430,8 @@ enum nft_set_elem_attributes { + NFTA_SET_ELEM_EXPR, + NFTA_SET_ELEM_PAD, + NFTA_SET_ELEM_OBJREF, ++ NFTA_SET_ELEM_KEY_END, ++ NFTA_SET_ELEM_EXPRESSIONS, + __NFTA_SET_ELEM_MAX + }; + #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1) +@@ -440,11 +497,13 @@ enum nft_data_attributes { + * + * @NFTA_VERDICT_CODE: nf_tables verdict (NLA_U32: enum nft_verdicts) + * @NFTA_VERDICT_CHAIN: jump target chain name (NLA_STRING) ++ * @NFTA_VERDICT_CHAIN_ID: jump target chain ID (NLA_U32) + */ + enum nft_verdict_attributes { + NFTA_VERDICT_UNSPEC, + NFTA_VERDICT_CODE, + NFTA_VERDICT_CHAIN, ++ NFTA_VERDICT_CHAIN_ID, + __NFTA_VERDICT_MAX + }; + #define NFTA_VERDICT_MAX (__NFTA_VERDICT_MAX - 1) +@@ -477,6 +536,20 @@ enum nft_immediate_attributes { + }; + #define NFTA_IMMEDIATE_MAX (__NFTA_IMMEDIATE_MAX - 1) + ++/** ++ * enum nft_bitwise_ops - nf_tables bitwise operations ++ * ++ * @NFT_BITWISE_BOOL: mask-and-xor operation used to implement NOT, AND, OR and ++ * XOR boolean operations ++ * @NFT_BITWISE_LSHIFT: left-shift operation ++ * @NFT_BITWISE_RSHIFT: right-shift operation ++ */ ++enum nft_bitwise_ops { ++ NFT_BITWISE_BOOL, ++ NFT_BITWISE_LSHIFT, ++ NFT_BITWISE_RSHIFT, ++}; ++ + /** + * enum nft_bitwise_attributes - nf_tables bitwise expression netlink attributes + * +@@ -485,16 +558,20 @@ enum nft_immediate_attributes { + * @NFTA_BITWISE_LEN: length of operands (NLA_U32) + * @NFTA_BITWISE_MASK: mask value (NLA_NESTED: nft_data_attributes) + * @NFTA_BITWISE_XOR: xor value (NLA_NESTED: nft_data_attributes) ++ * @NFTA_BITWISE_OP: type of operation (NLA_U32: nft_bitwise_ops) ++ * @NFTA_BITWISE_DATA: argument for non-boolean operations ++ * (NLA_NESTED: nft_data_attributes) + * +- * The bitwise expression performs the following operation: ++ * The bitwise expression supports boolean and shift operations. It implements ++ * the boolean operations by performing the following operation: + * + * dreg = (sreg & mask) ^ xor + * +- * which allow to express all bitwise operations: ++ * with these mask and xor values: + * + * mask xor + * NOT: 1 1 +- * OR: 0 x ++ * OR: ~x x + * XOR: 1 x + * AND: x 0 + */ +@@ -505,6 +582,8 @@ enum nft_bitwise_attributes { + NFTA_BITWISE_LEN, + NFTA_BITWISE_MASK, + NFTA_BITWISE_XOR, ++ NFTA_BITWISE_OP, ++ NFTA_BITWISE_DATA, + __NFTA_BITWISE_MAX + }; + #define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1) +@@ -631,10 +710,12 @@ enum nft_lookup_attributes { + enum nft_dynset_ops { + NFT_DYNSET_OP_ADD, + NFT_DYNSET_OP_UPDATE, ++ NFT_DYNSET_OP_DELETE, + }; + + enum nft_dynset_flags { + NFT_DYNSET_F_INV = (1 << 0), ++ NFT_DYNSET_F_EXPR = (1 << 1), + }; + + /** +@@ -648,6 +729,7 @@ enum nft_dynset_flags { + * @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64) + * @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes) + * @NFTA_DYNSET_FLAGS: flags (NLA_U32) ++ * @NFTA_DYNSET_EXPRESSIONS: list of expressions (NLA_NESTED: nft_list_attributes) + */ + enum nft_dynset_attributes { + NFTA_DYNSET_UNSPEC, +@@ -660,6 +742,7 @@ enum nft_dynset_attributes { + NFTA_DYNSET_EXPR, + NFTA_DYNSET_PAD, + NFTA_DYNSET_FLAGS, ++ NFTA_DYNSET_EXPRESSIONS, + __NFTA_DYNSET_MAX, + }; + #define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1) +@@ -682,10 +765,12 @@ enum nft_payload_bases { + * + * @NFT_PAYLOAD_CSUM_NONE: no checksumming + * @NFT_PAYLOAD_CSUM_INET: internet checksum (RFC 791) ++ * @NFT_PAYLOAD_CSUM_SCTP: CRC-32c, for use in SCTP header (RFC 3309) + */ + enum nft_payload_csum_types { + NFT_PAYLOAD_CSUM_NONE, + NFT_PAYLOAD_CSUM_INET, ++ NFT_PAYLOAD_CSUM_SCTP, + }; + + enum nft_payload_csum_flags { +@@ -727,10 +812,14 @@ enum nft_exthdr_flags { + * + * @NFT_EXTHDR_OP_IPV6: match against ipv6 extension headers + * @NFT_EXTHDR_OP_TCP: match against tcp options ++ * @NFT_EXTHDR_OP_IPV4: match against ipv4 options ++ * @NFT_EXTHDR_OP_SCTP: match against sctp chunks + */ + enum nft_exthdr_op { + NFT_EXTHDR_OP_IPV6, + NFT_EXTHDR_OP_TCPOPT, ++ NFT_EXTHDR_OP_IPV4, ++ NFT_EXTHDR_OP_SCTP, + __NFT_EXTHDR_OP_MAX + }; + #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1) +@@ -788,6 +877,15 @@ enum nft_exthdr_attributes { + * @NFT_META_CGROUP: socket control group (skb->sk->sk_classid) + * @NFT_META_PRANDOM: a 32bit pseudo-random number + * @NFT_META_SECPATH: boolean, secpath_exists (!!skb->sp) ++ * @NFT_META_IIFKIND: packet input interface kind name (dev->rtnl_link_ops->kind) ++ * @NFT_META_OIFKIND: packet output interface kind name (dev->rtnl_link_ops->kind) ++ * @NFT_META_BRI_IIFPVID: packet input bridge port pvid ++ * @NFT_META_BRI_IIFVPROTO: packet input bridge vlan proto ++ * @NFT_META_TIME_NS: time since epoch (in nanoseconds) ++ * @NFT_META_TIME_DAY: day of week (from 0 = Sunday to 6 = Saturday) ++ * @NFT_META_TIME_HOUR: hour of day (in seconds) ++ * @NFT_META_SDIF: slave device interface index ++ * @NFT_META_SDIFNAME: slave device interface name + */ + enum nft_meta_keys { + NFT_META_LEN, +@@ -816,6 +914,15 @@ enum nft_meta_keys { + NFT_META_CGROUP, + NFT_META_PRANDOM, + NFT_META_SECPATH, ++ NFT_META_IIFKIND, ++ NFT_META_OIFKIND, ++ NFT_META_BRI_IIFPVID, ++ NFT_META_BRI_IIFVPROTO, ++ NFT_META_TIME_NS, ++ NFT_META_TIME_DAY, ++ NFT_META_TIME_HOUR, ++ NFT_META_SDIF, ++ NFT_META_SDIFNAME, + }; + + /** +@@ -825,13 +932,17 @@ enum nft_meta_keys { + * @NFT_RT_NEXTHOP4: routing nexthop for IPv4 + * @NFT_RT_NEXTHOP6: routing nexthop for IPv6 + * @NFT_RT_TCPMSS: fetch current path tcp mss ++ * @NFT_RT_XFRM: boolean, skb->dst->xfrm != NULL + */ + enum nft_rt_keys { + NFT_RT_CLASSID, + NFT_RT_NEXTHOP4, + NFT_RT_NEXTHOP6, + NFT_RT_TCPMSS, ++ NFT_RT_XFRM, ++ __NFT_RT_MAX + }; ++#define NFT_RT_MAX (__NFT_RT_MAX - 1) + + /** + * enum nft_hash_types - nf_tables hash expression types +@@ -854,6 +965,8 @@ enum nft_hash_types { + * @NFTA_HASH_SEED: seed value (NLA_U32) + * @NFTA_HASH_OFFSET: add this offset value to hash result (NLA_U32) + * @NFTA_HASH_TYPE: hash operation (NLA_U32: nft_hash_types) ++ * @NFTA_HASH_SET_NAME: name of the map to lookup (NLA_STRING) ++ * @NFTA_HASH_SET_ID: id of the map (NLA_U32) + */ + enum nft_hash_attributes { + NFTA_HASH_UNSPEC, +@@ -864,6 +977,8 @@ enum nft_hash_attributes { + NFTA_HASH_SEED, + NFTA_HASH_OFFSET, + NFTA_HASH_TYPE, ++ NFTA_HASH_SET_NAME, /* deprecated */ ++ NFTA_HASH_SET_ID, /* deprecated */ + __NFTA_HASH_MAX, + }; + #define NFTA_HASH_MAX (__NFTA_HASH_MAX - 1) +@@ -898,6 +1013,39 @@ enum nft_rt_attributes { + }; + #define NFTA_RT_MAX (__NFTA_RT_MAX - 1) + ++/** ++ * enum nft_socket_attributes - nf_tables socket expression netlink attributes ++ * ++ * @NFTA_SOCKET_KEY: socket key to match ++ * @NFTA_SOCKET_DREG: destination register ++ * @NFTA_SOCKET_LEVEL: cgroups2 ancestor level (only for cgroupsv2) ++ */ ++enum nft_socket_attributes { ++ NFTA_SOCKET_UNSPEC, ++ NFTA_SOCKET_KEY, ++ NFTA_SOCKET_DREG, ++ NFTA_SOCKET_LEVEL, ++ __NFTA_SOCKET_MAX ++}; ++#define NFTA_SOCKET_MAX (__NFTA_SOCKET_MAX - 1) ++ ++/* ++ * enum nft_socket_keys - nf_tables socket expression keys ++ * ++ * @NFT_SOCKET_TRANSPARENT: Value of the IP(V6)_TRANSPARENT socket option ++ * @NFT_SOCKET_MARK: Value of the socket mark ++ * @NFT_SOCKET_WILDCARD: Whether the socket is zero-bound (e.g. 0.0.0.0 or ::0) ++ * @NFT_SOCKET_CGROUPV2: Match on cgroups version 2 ++ */ ++enum nft_socket_keys { ++ NFT_SOCKET_TRANSPARENT, ++ NFT_SOCKET_MARK, ++ NFT_SOCKET_WILDCARD, ++ NFT_SOCKET_CGROUPV2, ++ __NFT_SOCKET_MAX ++}; ++#define NFT_SOCKET_MAX (__NFT_SOCKET_MAX - 1) ++ + /** + * enum nft_ct_keys - nf_tables ct expression keys + * +@@ -909,8 +1057,8 @@ enum nft_rt_attributes { + * @NFT_CT_EXPIRATION: relative conntrack expiration time in ms + * @NFT_CT_HELPER: connection tracking helper assigned to conntrack + * @NFT_CT_L3PROTOCOL: conntrack layer 3 protocol +- * @NFT_CT_SRC: conntrack layer 3 protocol source (IPv4/IPv6 address) +- * @NFT_CT_DST: conntrack layer 3 protocol destination (IPv4/IPv6 address) ++ * @NFT_CT_SRC: conntrack layer 3 protocol source (IPv4/IPv6 address, deprecated) ++ * @NFT_CT_DST: conntrack layer 3 protocol destination (IPv4/IPv6 address, deprecated) + * @NFT_CT_PROTOCOL: conntrack layer 4 protocol + * @NFT_CT_PROTO_SRC: conntrack layer 4 protocol source + * @NFT_CT_PROTO_DST: conntrack layer 4 protocol destination +@@ -920,6 +1068,11 @@ enum nft_rt_attributes { + * @NFT_CT_AVGPKT: conntrack average bytes per packet + * @NFT_CT_ZONE: conntrack zone + * @NFT_CT_EVENTMASK: ctnetlink events to be generated for this conntrack ++ * @NFT_CT_SRC_IP: conntrack layer 3 protocol source (IPv4 address) ++ * @NFT_CT_DST_IP: conntrack layer 3 protocol destination (IPv4 address) ++ * @NFT_CT_SRC_IP6: conntrack layer 3 protocol source (IPv6 address) ++ * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address) ++ * @NFT_CT_ID: conntrack id + */ + enum nft_ct_keys { + NFT_CT_STATE, +@@ -941,7 +1094,14 @@ enum nft_ct_keys { + NFT_CT_AVGPKT, + NFT_CT_ZONE, + NFT_CT_EVENTMASK, ++ NFT_CT_SRC_IP, ++ NFT_CT_DST_IP, ++ NFT_CT_SRC_IP6, ++ NFT_CT_DST_IP6, ++ NFT_CT_ID, ++ __NFT_CT_MAX + }; ++#define NFT_CT_MAX (__NFT_CT_MAX - 1) + + /** + * enum nft_ct_attributes - nf_tables ct expression netlink attributes +@@ -1002,6 +1162,24 @@ enum nft_limit_attributes { + }; + #define NFTA_LIMIT_MAX (__NFTA_LIMIT_MAX - 1) + ++enum nft_connlimit_flags { ++ NFT_CONNLIMIT_F_INV = (1 << 0), ++}; ++ ++/** ++ * enum nft_connlimit_attributes - nf_tables connlimit expression netlink attributes ++ * ++ * @NFTA_CONNLIMIT_COUNT: number of connections (NLA_U32) ++ * @NFTA_CONNLIMIT_FLAGS: flags (NLA_U32: enum nft_connlimit_flags) ++ */ ++enum nft_connlimit_attributes { ++ NFTA_CONNLIMIT_UNSPEC, ++ NFTA_CONNLIMIT_COUNT, ++ NFTA_CONNLIMIT_FLAGS, ++ __NFTA_CONNLIMIT_MAX ++}; ++#define NFTA_CONNLIMIT_MAX (__NFTA_CONNLIMIT_MAX - 1) ++ + /** + * enum nft_counter_attributes - nf_tables counter expression netlink attributes + * +@@ -1017,6 +1195,21 @@ enum nft_counter_attributes { + }; + #define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1) + ++/** ++ * enum nft_last_attributes - nf_tables last expression netlink attributes ++ * ++ * @NFTA_LAST_SET: last update has been set, zero means never updated (NLA_U32) ++ * @NFTA_LAST_MSECS: milliseconds since last update (NLA_U64) ++ */ ++enum nft_last_attributes { ++ NFTA_LAST_UNSPEC, ++ NFTA_LAST_SET, ++ NFTA_LAST_MSECS, ++ NFTA_LAST_PAD, ++ __NFTA_LAST_MAX ++}; ++#define NFTA_LAST_MAX (__NFTA_LAST_MAX - 1) ++ + /** + * enum nft_log_attributes - nf_tables log expression netlink attributes + * +@@ -1039,6 +1232,33 @@ enum nft_log_attributes { + }; + #define NFTA_LOG_MAX (__NFTA_LOG_MAX - 1) + ++/** ++ * enum nft_log_level - nf_tables log levels ++ * ++ * @NFT_LOGLEVEL_EMERG: system is unusable ++ * @NFT_LOGLEVEL_ALERT: action must be taken immediately ++ * @NFT_LOGLEVEL_CRIT: critical conditions ++ * @NFT_LOGLEVEL_ERR: error conditions ++ * @NFT_LOGLEVEL_WARNING: warning conditions ++ * @NFT_LOGLEVEL_NOTICE: normal but significant condition ++ * @NFT_LOGLEVEL_INFO: informational ++ * @NFT_LOGLEVEL_DEBUG: debug-level messages ++ * @NFT_LOGLEVEL_AUDIT: enabling audit logging ++ */ ++enum nft_log_level { ++ NFT_LOGLEVEL_EMERG, ++ NFT_LOGLEVEL_ALERT, ++ NFT_LOGLEVEL_CRIT, ++ NFT_LOGLEVEL_ERR, ++ NFT_LOGLEVEL_WARNING, ++ NFT_LOGLEVEL_NOTICE, ++ NFT_LOGLEVEL_INFO, ++ NFT_LOGLEVEL_DEBUG, ++ NFT_LOGLEVEL_AUDIT, ++ __NFT_LOGLEVEL_MAX ++}; ++#define NFT_LOGLEVEL_MAX (__NFT_LOGLEVEL_MAX - 1) ++ + /** + * enum nft_queue_attributes - nf_tables queue expression netlink attributes + * +@@ -1083,6 +1303,21 @@ enum nft_quota_attributes { + }; + #define NFTA_QUOTA_MAX (__NFTA_QUOTA_MAX - 1) + ++/** ++ * enum nft_secmark_attributes - nf_tables secmark object netlink attributes ++ * ++ * @NFTA_SECMARK_CTX: security context (NLA_STRING) ++ */ ++enum nft_secmark_attributes { ++ NFTA_SECMARK_UNSPEC, ++ NFTA_SECMARK_CTX, ++ __NFTA_SECMARK_MAX, ++}; ++#define NFTA_SECMARK_MAX (__NFTA_SECMARK_MAX - 1) ++ ++/* Max security context length */ ++#define NFT_SECMARK_CTX_MAXLEN 256 ++ + /** + * enum nft_reject_types - nf_tables reject expression reject types + * +@@ -1164,6 +1399,22 @@ enum nft_nat_attributes { + }; + #define NFTA_NAT_MAX (__NFTA_NAT_MAX - 1) + ++/** ++ * enum nft_tproxy_attributes - nf_tables tproxy expression netlink attributes ++ * ++ * NFTA_TPROXY_FAMILY: Target address family (NLA_U32: nft_registers) ++ * NFTA_TPROXY_REG_ADDR: Target address register (NLA_U32: nft_registers) ++ * NFTA_TPROXY_REG_PORT: Target port register (NLA_U32: nft_registers) ++ */ ++enum nft_tproxy_attributes { ++ NFTA_TPROXY_UNSPEC, ++ NFTA_TPROXY_FAMILY, ++ NFTA_TPROXY_REG_ADDR, ++ NFTA_TPROXY_REG_PORT, ++ __NFTA_TPROXY_MAX ++}; ++#define NFTA_TPROXY_MAX (__NFTA_TPROXY_MAX - 1) ++ + /** + * enum nft_masq_attributes - nf_tables masquerade expression attributes + * +@@ -1214,10 +1465,14 @@ enum nft_dup_attributes { + * enum nft_fwd_attributes - nf_tables fwd expression netlink attributes + * + * @NFTA_FWD_SREG_DEV: source register of output interface (NLA_U32: nft_register) ++ * @NFTA_FWD_SREG_ADDR: source register of destination address (NLA_U32: nft_register) ++ * @NFTA_FWD_NFPROTO: layer 3 family of source register address (NLA_U32: enum nfproto) + */ + enum nft_fwd_attributes { + NFTA_FWD_UNSPEC, + NFTA_FWD_SREG_DEV, ++ NFTA_FWD_SREG_ADDR, ++ NFTA_FWD_NFPROTO, + __NFTA_FWD_MAX + }; + #define NFTA_FWD_MAX (__NFTA_FWD_MAX - 1) +@@ -1302,12 +1557,38 @@ enum nft_ct_helper_attributes { + }; + #define NFTA_CT_HELPER_MAX (__NFTA_CT_HELPER_MAX - 1) + ++enum nft_ct_timeout_timeout_attributes { ++ NFTA_CT_TIMEOUT_UNSPEC, ++ NFTA_CT_TIMEOUT_L3PROTO, ++ NFTA_CT_TIMEOUT_L4PROTO, ++ NFTA_CT_TIMEOUT_DATA, ++ __NFTA_CT_TIMEOUT_MAX, ++}; ++#define NFTA_CT_TIMEOUT_MAX (__NFTA_CT_TIMEOUT_MAX - 1) ++ ++enum nft_ct_expectation_attributes { ++ NFTA_CT_EXPECT_UNSPEC, ++ NFTA_CT_EXPECT_L3PROTO, ++ NFTA_CT_EXPECT_L4PROTO, ++ NFTA_CT_EXPECT_DPORT, ++ NFTA_CT_EXPECT_TIMEOUT, ++ NFTA_CT_EXPECT_SIZE, ++ __NFTA_CT_EXPECT_MAX, ++}; ++#define NFTA_CT_EXPECT_MAX (__NFTA_CT_EXPECT_MAX - 1) ++ + #define NFT_OBJECT_UNSPEC 0 + #define NFT_OBJECT_COUNTER 1 + #define NFT_OBJECT_QUOTA 2 + #define NFT_OBJECT_CT_HELPER 3 + #define NFT_OBJECT_LIMIT 4 +-#define __NFT_OBJECT_MAX 5 ++#define NFT_OBJECT_CONNLIMIT 5 ++#define NFT_OBJECT_TUNNEL 6 ++#define NFT_OBJECT_CT_TIMEOUT 7 ++#define NFT_OBJECT_SECMARK 8 ++#define NFT_OBJECT_CT_EXPECT 9 ++#define NFT_OBJECT_SYNPROXY 10 ++#define __NFT_OBJECT_MAX 11 + #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) + + /** +@@ -1319,6 +1600,7 @@ enum nft_ct_helper_attributes { + * @NFTA_OBJ_DATA: stateful object data (NLA_NESTED) + * @NFTA_OBJ_USE: number of references to this expression (NLA_U32) + * @NFTA_OBJ_HANDLE: object handle (NLA_U64) ++ * @NFTA_OBJ_USERDATA: user data (NLA_BINARY) + */ + enum nft_object_attributes { + NFTA_OBJ_UNSPEC, +@@ -1329,10 +1611,24 @@ enum nft_object_attributes { + NFTA_OBJ_USE, + NFTA_OBJ_HANDLE, + NFTA_OBJ_PAD, ++ NFTA_OBJ_USERDATA, + __NFTA_OBJ_MAX + }; + #define NFTA_OBJ_MAX (__NFTA_OBJ_MAX - 1) + ++/** ++ * enum nft_flowtable_flags - nf_tables flowtable flags ++ * ++ * @NFT_FLOWTABLE_HW_OFFLOAD: flowtable hardware offload is enabled ++ * @NFT_FLOWTABLE_COUNTER: enable flow counters ++ */ ++enum nft_flowtable_flags { ++ NFT_FLOWTABLE_HW_OFFLOAD = 0x1, ++ NFT_FLOWTABLE_COUNTER = 0x2, ++ NFT_FLOWTABLE_MASK = (NFT_FLOWTABLE_HW_OFFLOAD | ++ NFT_FLOWTABLE_COUNTER) ++}; ++ + /** + * enum nft_flowtable_attributes - nf_tables flow table netlink attributes + * +@@ -1341,6 +1637,7 @@ enum nft_object_attributes { + * @NFTA_FLOWTABLE_HOOK: netfilter hook configuration(NLA_U32) + * @NFTA_FLOWTABLE_USE: number of references to this flow table (NLA_U32) + * @NFTA_FLOWTABLE_HANDLE: object handle (NLA_U64) ++ * @NFTA_FLOWTABLE_FLAGS: flags (NLA_U32) + */ + enum nft_flowtable_attributes { + NFTA_FLOWTABLE_UNSPEC, +@@ -1350,6 +1647,7 @@ enum nft_flowtable_attributes { + NFTA_FLOWTABLE_USE, + NFTA_FLOWTABLE_HANDLE, + NFTA_FLOWTABLE_PAD, ++ NFTA_FLOWTABLE_FLAGS, + __NFTA_FLOWTABLE_MAX + }; + #define NFTA_FLOWTABLE_MAX (__NFTA_FLOWTABLE_MAX - 1) +@@ -1370,6 +1668,42 @@ enum nft_flowtable_hook_attributes { + }; + #define NFTA_FLOWTABLE_HOOK_MAX (__NFTA_FLOWTABLE_HOOK_MAX - 1) + ++/** ++ * enum nft_osf_attributes - nftables osf expression netlink attributes ++ * ++ * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers) ++ * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8) ++ * @NFTA_OSF_FLAGS: flags (NLA_U32) ++ */ ++enum nft_osf_attributes { ++ NFTA_OSF_UNSPEC, ++ NFTA_OSF_DREG, ++ NFTA_OSF_TTL, ++ NFTA_OSF_FLAGS, ++ __NFTA_OSF_MAX, ++}; ++#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1) ++ ++enum nft_osf_flags { ++ NFT_OSF_F_VERSION = (1 << 0), ++}; ++ ++/** ++ * enum nft_synproxy_attributes - nf_tables synproxy expression netlink attributes ++ * ++ * @NFTA_SYNPROXY_MSS: mss value sent to the backend (NLA_U16) ++ * @NFTA_SYNPROXY_WSCALE: wscale value sent to the backend (NLA_U8) ++ * @NFTA_SYNPROXY_FLAGS: flags (NLA_U32) ++ */ ++enum nft_synproxy_attributes { ++ NFTA_SYNPROXY_UNSPEC, ++ NFTA_SYNPROXY_MSS, ++ NFTA_SYNPROXY_WSCALE, ++ NFTA_SYNPROXY_FLAGS, ++ __NFTA_SYNPROXY_MAX, ++}; ++#define NFTA_SYNPROXY_MAX (__NFTA_SYNPROXY_MAX - 1) ++ + /** + * enum nft_device_attributes - nf_tables device netlink attributes + * +@@ -1382,6 +1716,35 @@ enum nft_devices_attributes { + }; + #define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1) + ++/* ++ * enum nft_xfrm_attributes - nf_tables xfrm expr netlink attributes ++ * ++ * @NFTA_XFRM_DREG: destination register (NLA_U32) ++ * @NFTA_XFRM_KEY: enum nft_xfrm_keys (NLA_U32) ++ * @NFTA_XFRM_DIR: direction (NLA_U8) ++ * @NFTA_XFRM_SPNUM: index in secpath array (NLA_U32) ++ */ ++enum nft_xfrm_attributes { ++ NFTA_XFRM_UNSPEC, ++ NFTA_XFRM_DREG, ++ NFTA_XFRM_KEY, ++ NFTA_XFRM_DIR, ++ NFTA_XFRM_SPNUM, ++ __NFTA_XFRM_MAX ++}; ++#define NFTA_XFRM_MAX (__NFTA_XFRM_MAX - 1) ++ ++enum nft_xfrm_keys { ++ NFT_XFRM_KEY_UNSPEC, ++ NFT_XFRM_KEY_DADDR_IP4, ++ NFT_XFRM_KEY_DADDR_IP6, ++ NFT_XFRM_KEY_SADDR_IP4, ++ NFT_XFRM_KEY_SADDR_IP6, ++ NFT_XFRM_KEY_REQID, ++ NFT_XFRM_KEY_SPI, ++ __NFT_XFRM_KEY_MAX, ++}; ++#define NFT_XFRM_KEY_MAX (__NFT_XFRM_KEY_MAX - 1) + + /** + * enum nft_trace_attributes - nf_tables trace netlink attributes +@@ -1442,6 +1805,8 @@ enum nft_trace_types { + * @NFTA_NG_MODULUS: maximum counter value (NLA_U32) + * @NFTA_NG_TYPE: operation type (NLA_U32) + * @NFTA_NG_OFFSET: offset to be added to the counter (NLA_U32) ++ * @NFTA_NG_SET_NAME: name of the map to lookup (NLA_STRING) ++ * @NFTA_NG_SET_ID: id of the map (NLA_U32) + */ + enum nft_ng_attributes { + NFTA_NG_UNSPEC, +@@ -1449,6 +1814,8 @@ enum nft_ng_attributes { + NFTA_NG_MODULUS, + NFTA_NG_TYPE, + NFTA_NG_OFFSET, ++ NFTA_NG_SET_NAME, /* deprecated */ ++ NFTA_NG_SET_ID, /* deprecated */ + __NFTA_NG_MAX + }; + #define NFTA_NG_MAX (__NFTA_NG_MAX - 1) +@@ -1460,4 +1827,104 @@ enum nft_ng_types { + }; + #define NFT_NG_MAX (__NFT_NG_MAX - 1) + ++enum nft_tunnel_key_ip_attributes { ++ NFTA_TUNNEL_KEY_IP_UNSPEC, ++ NFTA_TUNNEL_KEY_IP_SRC, ++ NFTA_TUNNEL_KEY_IP_DST, ++ __NFTA_TUNNEL_KEY_IP_MAX ++}; ++#define NFTA_TUNNEL_KEY_IP_MAX (__NFTA_TUNNEL_KEY_IP_MAX - 1) ++ ++enum nft_tunnel_ip6_attributes { ++ NFTA_TUNNEL_KEY_IP6_UNSPEC, ++ NFTA_TUNNEL_KEY_IP6_SRC, ++ NFTA_TUNNEL_KEY_IP6_DST, ++ NFTA_TUNNEL_KEY_IP6_FLOWLABEL, ++ __NFTA_TUNNEL_KEY_IP6_MAX ++}; ++#define NFTA_TUNNEL_KEY_IP6_MAX (__NFTA_TUNNEL_KEY_IP6_MAX - 1) ++ ++enum nft_tunnel_opts_attributes { ++ NFTA_TUNNEL_KEY_OPTS_UNSPEC, ++ NFTA_TUNNEL_KEY_OPTS_VXLAN, ++ NFTA_TUNNEL_KEY_OPTS_ERSPAN, ++ NFTA_TUNNEL_KEY_OPTS_GENEVE, ++ __NFTA_TUNNEL_KEY_OPTS_MAX ++}; ++#define NFTA_TUNNEL_KEY_OPTS_MAX (__NFTA_TUNNEL_KEY_OPTS_MAX - 1) ++ ++enum nft_tunnel_opts_vxlan_attributes { ++ NFTA_TUNNEL_KEY_VXLAN_UNSPEC, ++ NFTA_TUNNEL_KEY_VXLAN_GBP, ++ __NFTA_TUNNEL_KEY_VXLAN_MAX ++}; ++#define NFTA_TUNNEL_KEY_VXLAN_MAX (__NFTA_TUNNEL_KEY_VXLAN_MAX - 1) ++ ++enum nft_tunnel_opts_erspan_attributes { ++ NFTA_TUNNEL_KEY_ERSPAN_UNSPEC, ++ NFTA_TUNNEL_KEY_ERSPAN_VERSION, ++ NFTA_TUNNEL_KEY_ERSPAN_V1_INDEX, ++ NFTA_TUNNEL_KEY_ERSPAN_V2_HWID, ++ NFTA_TUNNEL_KEY_ERSPAN_V2_DIR, ++ __NFTA_TUNNEL_KEY_ERSPAN_MAX ++}; ++#define NFTA_TUNNEL_KEY_ERSPAN_MAX (__NFTA_TUNNEL_KEY_ERSPAN_MAX - 1) ++ ++enum nft_tunnel_opts_geneve_attributes { ++ NFTA_TUNNEL_KEY_GENEVE_UNSPEC, ++ NFTA_TUNNEL_KEY_GENEVE_CLASS, ++ NFTA_TUNNEL_KEY_GENEVE_TYPE, ++ NFTA_TUNNEL_KEY_GENEVE_DATA, ++ __NFTA_TUNNEL_KEY_GENEVE_MAX ++}; ++#define NFTA_TUNNEL_KEY_GENEVE_MAX (__NFTA_TUNNEL_KEY_GENEVE_MAX - 1) ++ ++enum nft_tunnel_flags { ++ NFT_TUNNEL_F_ZERO_CSUM_TX = (1 << 0), ++ NFT_TUNNEL_F_DONT_FRAGMENT = (1 << 1), ++ NFT_TUNNEL_F_SEQ_NUMBER = (1 << 2), ++}; ++#define NFT_TUNNEL_F_MASK (NFT_TUNNEL_F_ZERO_CSUM_TX | \ ++ NFT_TUNNEL_F_DONT_FRAGMENT | \ ++ NFT_TUNNEL_F_SEQ_NUMBER) ++ ++enum nft_tunnel_key_attributes { ++ NFTA_TUNNEL_KEY_UNSPEC, ++ NFTA_TUNNEL_KEY_ID, ++ NFTA_TUNNEL_KEY_IP, ++ NFTA_TUNNEL_KEY_IP6, ++ NFTA_TUNNEL_KEY_FLAGS, ++ NFTA_TUNNEL_KEY_TOS, ++ NFTA_TUNNEL_KEY_TTL, ++ NFTA_TUNNEL_KEY_SPORT, ++ NFTA_TUNNEL_KEY_DPORT, ++ NFTA_TUNNEL_KEY_OPTS, ++ __NFTA_TUNNEL_KEY_MAX ++}; ++#define NFTA_TUNNEL_KEY_MAX (__NFTA_TUNNEL_KEY_MAX - 1) ++ ++enum nft_tunnel_keys { ++ NFT_TUNNEL_PATH, ++ NFT_TUNNEL_ID, ++ __NFT_TUNNEL_MAX ++}; ++#define NFT_TUNNEL_MAX (__NFT_TUNNEL_MAX - 1) ++ ++enum nft_tunnel_mode { ++ NFT_TUNNEL_MODE_NONE, ++ NFT_TUNNEL_MODE_RX, ++ NFT_TUNNEL_MODE_TX, ++ __NFT_TUNNEL_MODE_MAX ++}; ++#define NFT_TUNNEL_MODE_MAX (__NFT_TUNNEL_MODE_MAX - 1) ++ ++enum nft_tunnel_attributes { ++ NFTA_TUNNEL_UNSPEC, ++ NFTA_TUNNEL_KEY, ++ NFTA_TUNNEL_DREG, ++ NFTA_TUNNEL_MODE, ++ __NFTA_TUNNEL_MAX ++}; ++#define NFTA_TUNNEL_MAX (__NFTA_TUNNEL_MAX - 1) ++ + #endif /* _LINUX_NF_TABLES_H */ +diff --git a/iptables/nft.c b/iptables/nft.c +index c130369f78348..0ec7679d25289 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -1086,7 +1086,7 @@ static int __add_nft_among(struct nft_handle *h, const char *table, + type = type << CONCAT_TYPE_BITS | NFT_DATATYPE_IPADDR; + len += sizeof(struct in_addr) + NETLINK_ALIGN - 1; + len &= ~(NETLINK_ALIGN - 1); +- flags = NFT_SET_INTERVAL; ++ flags = NFT_SET_INTERVAL | NFT_SET_CONCAT; + } + + s = add_anon_set(h, table, flags, type, len, cnt); +-- +2.40.0 + diff --git a/SOURCES/0081-nft-shared-Introduce-__get_cmp_data.patch b/SOURCES/0081-nft-shared-Introduce-__get_cmp_data.patch new file mode 100644 index 0000000..1cb11d2 --- /dev/null +++ b/SOURCES/0081-nft-shared-Introduce-__get_cmp_data.patch @@ -0,0 +1,67 @@ +From 116427bbf1365e2d284e7410a125205a983c0b1b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 27 Sep 2022 23:15:37 +0200 +Subject: [PATCH] nft-shared: Introduce __get_cmp_data() + +This is an inner function to get_cmp_data() returning the op value as-is +for caller examination. + +Signed-off-by: Phil Sutter +(cherry picked from commit 8dc22798bf813ce92aaac58a6fe8749fe3fc18dc) + +Conflicts: + iptables/nft-shared.h +-> Context change due to missing commit aa92ec96078d0 + ("nft: pass struct nft_xt_ctx to parse_meta()"). +--- + iptables/nft-shared.c | 17 ++++++++++------- + iptables/nft-shared.h | 1 + + 2 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 2b934ffc17756..cb1c2d61f52c1 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -373,17 +373,20 @@ static void nft_parse_match(struct nft_xt_ctx *ctx, struct nftnl_expr *e) + ctx->h->ops->parse_match(match, ctx->cs); + } + +-void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv) ++void __get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, uint8_t *op) + { + uint32_t len; +- uint8_t op; + + memcpy(data, nftnl_expr_get(e, NFTNL_EXPR_CMP_DATA, &len), dlen); +- op = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP); +- if (op == NFT_CMP_NEQ) +- *inv = true; +- else +- *inv = false; ++ *op = nftnl_expr_get_u32(e, NFTNL_EXPR_CMP_OP); ++} ++ ++void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv) ++{ ++ uint8_t op; ++ ++ __get_cmp_data(e, data, dlen, &op); ++ *inv = (op == NFT_CMP_NEQ); + } + + static void nft_meta_set_to_target(struct nft_xt_ctx *ctx) +diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h +index 2c5f2cfc012d5..3531631bd8acd 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -139,6 +139,7 @@ bool is_same_interfaces(const char *a_iniface, const char *a_outiface, + int parse_meta(struct nftnl_expr *e, uint8_t key, char *iniface, + unsigned char *iniface_mask, char *outiface, + unsigned char *outiface_mask, uint8_t *invflags); ++void __get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, uint8_t *op); + void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv); + void nft_rule_to_iptables_command_state(struct nft_handle *h, + const struct nftnl_rule *r, +-- +2.40.0 + diff --git a/SOURCES/0082-ebtables-Support-p-Length.patch b/SOURCES/0082-ebtables-Support-p-Length.patch new file mode 100644 index 0000000..55b2a9a --- /dev/null +++ b/SOURCES/0082-ebtables-Support-p-Length.patch @@ -0,0 +1,228 @@ +From 07007c27ceebffcb6e3223768fa876c907b0d55d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 27 Sep 2022 23:19:34 +0200 +Subject: [PATCH] ebtables: Support '-p Length' + +To match on Ethernet frames using the etherproto field as length value, +ebtables accepts the special protocol name "LENGTH". Implement this in +ebtables-nft using a native match for 'ether type < 0x0600'. + +Since extension 802_3 matches are valid only with such Ethernet frames, +add a local add_match() wrapper which complains if the extension is used +without '-p Length' parameter. Legacy ebtables does this within the +extension's final_check callback, but it's not possible here due for lack of +fw->bitmask field access. + +While being at it, add xlate support, adjust tests and make ebtables-nft +print the case-insensitive argument with capital 'L' like legacy +ebtables does. + +Signed-off-by: Phil Sutter +(cherry picked from commit aa0b8b03f7c7e741ccd96360bd64d90ea8c3c3aa) + +Conflicts: + iptables/nft-bridge.c +-> Adjusted to missing commit 7e38890c6b4fb + ("nft: prepare for dynamic register allocation"). +-> Context change due to missing commits 0c0cd4340ed88 + ("nft: Don't pass command state opaque to family ops callbacks") and + b5881e7f22d42 ("nft: Change whitespace printing in save_rule callback"). +--- + extensions/generic.txlate | 6 +++ + extensions/libebt_802_3.t | 6 ++- + iptables/nft-bridge.c | 47 +++++++++++++++---- + .../ebtables/0002-ebtables-save-restore_0 | 12 ++--- + 4 files changed, 53 insertions(+), 18 deletions(-) + +diff --git a/extensions/generic.txlate b/extensions/generic.txlate +index 9ae9a5b54c1b9..6779d6f86dec8 100644 +--- a/extensions/generic.txlate ++++ b/extensions/generic.txlate +@@ -67,6 +67,12 @@ nft add rule bridge filter FORWARD iifname != "iname" meta ibrname "ilogname" oi + ebtables-translate -I INPUT -p ip -d 1:2:3:4:5:6/ff:ff:ff:ff:00:00 + nft insert rule bridge filter INPUT ether type 0x800 ether daddr 01:02:03:04:00:00 and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 counter + ++ebtables-translate -I INPUT -p Length ++nft insert rule bridge filter INPUT ether type < 0x0600 counter ++ ++ebtables-translate -I INPUT -p ! Length ++nft insert rule bridge filter INPUT ether type >= 0x0600 counter ++ + # asterisk is not special in iptables and it is even a valid interface name + iptables-translate -A FORWARD -i '*' -o 'eth*foo' + nft add rule ip filter FORWARD iifname "\*" oifname "eth\*foo" counter +diff --git a/extensions/libebt_802_3.t b/extensions/libebt_802_3.t +index ddfb2f0a72baf..a138f35d2c756 100644 +--- a/extensions/libebt_802_3.t ++++ b/extensions/libebt_802_3.t +@@ -1,3 +1,5 @@ + :INPUT,FORWARD,OUTPUT +---802_3-sap ! 0x0a -j CONTINUE;=;OK +---802_3-type 0x000a -j RETURN;=;OK ++--802_3-sap ! 0x0a -j CONTINUE;=;FAIL ++--802_3-type 0x000a -j RETURN;=;FAIL ++-p Length --802_3-sap ! 0x0a -j CONTINUE;=;OK ++-p Length --802_3-type 0x000a -j RETURN;=;OK +diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c +index 9cc6f87b28fe0..fbed1616253a6 100644 +--- a/iptables/nft-bridge.c ++++ b/iptables/nft-bridge.c +@@ -129,6 +129,18 @@ static int _add_action(struct nftnl_rule *r, struct iptables_command_state *cs) + return add_action(r, cs, false); + } + ++static int ++nft_bridge_add_match(struct nft_handle *h, const struct ebt_entry *fw, ++ struct nftnl_rule *r, struct xt_entry_match *m) ++{ ++ if (!strcmp(m->u.user.name, "802_3") && ++ !(fw->bitmask & EBT_802_3)) ++ xtables_error(PARAMETER_PROBLEM, ++ "For 802.3 DSAP/SSAP filtering the protocol must be LENGTH"); ++ ++ return add_match(h, r, m); ++} ++ + static int nft_bridge_add(struct nft_handle *h, + struct nftnl_rule *r, void *data) + { +@@ -172,17 +184,25 @@ static int nft_bridge_add(struct nft_handle *h, + } + + if ((fw->bitmask & EBT_NOPROTO) == 0) { ++ uint16_t ethproto = fw->ethproto; ++ + op = nft_invflags2cmp(fw->invflags, EBT_IPROTO); + add_payload(r, offsetof(struct ethhdr, h_proto), 2, + NFT_PAYLOAD_LL_HEADER); +- add_cmp_u16(r, fw->ethproto, op); ++ ++ if (fw->bitmask & EBT_802_3) { ++ op = (op == NFT_CMP_EQ ? NFT_CMP_LT : NFT_CMP_GTE); ++ ethproto = htons(0x0600); ++ } ++ ++ add_cmp_u16(r, ethproto, op); + } + + add_compat(r, fw->ethproto, fw->invflags & EBT_IPROTO); + + for (iter = cs->match_list; iter; iter = iter->next) { + if (iter->ismatch) { +- if (add_match(h, r, iter->u.match->m)) ++ if (nft_bridge_add_match(h, fw, r, iter->u.match->m)) + break; + } else { + if (add_target(r, iter->u.watcher->t)) +@@ -239,6 +259,7 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, + struct ebt_entry *fw = &cs->eb; + unsigned char addr[ETH_ALEN]; + unsigned short int ethproto; ++ uint8_t op; + bool inv; + int i; + +@@ -275,8 +296,14 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx, + fw->bitmask |= EBT_ISOURCE; + break; + case offsetof(struct ethhdr, h_proto): +- get_cmp_data(e, ðproto, sizeof(ethproto), &inv); +- fw->ethproto = ethproto; ++ __get_cmp_data(e, ðproto, sizeof(ethproto), &op); ++ if (ethproto == htons(0x0600)) { ++ fw->bitmask |= EBT_802_3; ++ inv = (op == NFT_CMP_GTE); ++ } else { ++ fw->ethproto = ethproto; ++ inv = (op == NFT_CMP_NEQ); ++ } + if (inv) + fw->invflags |= EBT_IPROTO; + fw->bitmask &= ~EBT_NOPROTO; +@@ -620,7 +647,7 @@ static void print_protocol(uint16_t ethproto, bool invert, unsigned int bitmask) + printf("! "); + + if (bitmask & EBT_802_3) { +- printf("length "); ++ printf("Length "); + return; + } + +@@ -635,7 +662,7 @@ static void nft_bridge_save_rule(const void *data, unsigned int format) + { + const struct iptables_command_state *cs = data; + +- if (cs->eb.ethproto) ++ if (!(cs->eb.bitmask & EBT_NOPROTO)) + print_protocol(cs->eb.ethproto, cs->eb.invflags & EBT_IPROTO, + cs->eb.bitmask); + if (cs->eb.bitmask & EBT_ISOURCE) +@@ -866,7 +893,10 @@ static int nft_bridge_xlate(const void *data, struct xt_xlate *xl) + xlate_ifname(xl, "meta obrname", cs->eb.logical_out, + cs->eb.invflags & EBT_ILOGICALOUT); + +- if ((cs->eb.bitmask & EBT_NOPROTO) == 0) { ++ if (cs->eb.bitmask & EBT_802_3) { ++ xt_xlate_add(xl, "ether type %s 0x0600 ", ++ cs->eb.invflags & EBT_IPROTO ? ">=" : "<"); ++ } else if ((cs->eb.bitmask & EBT_NOPROTO) == 0) { + const char *implicit = NULL; + + switch (ntohs(cs->eb.ethproto)) { +@@ -889,9 +919,6 @@ static int nft_bridge_xlate(const void *data, struct xt_xlate *xl) + ntohs(cs->eb.ethproto)); + } + +- if (cs->eb.bitmask & EBT_802_3) +- return 0; +- + if (cs->eb.bitmask & EBT_ISOURCE) + nft_bridge_xlate_mac(xl, "saddr", cs->eb.invflags & EBT_ISOURCE, + cs->eb.sourcemac, cs->eb.sourcemsk); +diff --git a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 +index b84f63a7c3672..a4fc31548e323 100755 +--- a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 ++++ b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 +@@ -13,8 +13,8 @@ $XT_MULTI ebtables -A INPUT -p IPv4 -i lo -j ACCEPT + $XT_MULTI ebtables -P FORWARD DROP + $XT_MULTI ebtables -A OUTPUT -s ff:ff:ff:ff:ff:ff/ff:ff:ff:ff:ff:ff -j DROP + $XT_MULTI ebtables -N foo +-$XT_MULTI ebtables -A foo --802_3-sap 0x23 -j ACCEPT +-$XT_MULTI ebtables -A foo --802_3-sap 0xaa --802_3-type 0x1337 -j ACCEPT ++$XT_MULTI ebtables -A foo -p length --802_3-sap 0x23 -j ACCEPT ++$XT_MULTI ebtables -A foo -p length --802_3-sap 0xaa --802_3-type 0x1337 -j ACCEPT + #$XT_MULTI ebtables -A foo --among-dst fe:ed:ba:be:00:01,fe:ed:ba:be:00:02,fe:ed:ba:be:00:03 -j ACCEPT + $XT_MULTI ebtables -A foo -p ARP --arp-gratuitous -j ACCEPT + $XT_MULTI ebtables -A foo -p ARP --arp-opcode Request -j ACCEPT +@@ -44,7 +44,7 @@ $XT_MULTI ebtables -A foo --pkttype-type multicast -j ACCEPT + $XT_MULTI ebtables -A foo --stp-type config -j ACCEPT + #$XT_MULTI ebtables -A foo --vlan-id 42 -j ACCEPT + +-$XT_MULTI ebtables -A foo --802_3-sap 0x23 --limit 100 -j ACCEPT ++$XT_MULTI ebtables -A foo -p length --802_3-sap 0x23 --limit 100 -j ACCEPT + $XT_MULTI ebtables -A foo --pkttype-type multicast --log + $XT_MULTI ebtables -A foo --pkttype-type multicast --limit 100 -j ACCEPT + +@@ -75,8 +75,8 @@ DUMP='*filter + -A INPUT -p IPv4 -i lo -j ACCEPT + -A FORWARD -j foo + -A OUTPUT -s Broadcast -j DROP +--A foo --802_3-sap 0x23 -j ACCEPT +--A foo --802_3-sap 0xaa --802_3-type 0x1337 -j ACCEPT ++-A foo -p Length --802_3-sap 0x23 -j ACCEPT ++-A foo -p Length --802_3-sap 0xaa --802_3-type 0x1337 -j ACCEPT + -A foo -p ARP --arp-gratuitous -j ACCEPT + -A foo -p ARP --arp-op Request -j ACCEPT + -A foo -p ARP --arp-ip-src 10.0.0.1 -j ACCEPT +@@ -96,7 +96,7 @@ DUMP='*filter + -A foo --nflog-group 1 -j CONTINUE + -A foo --pkttype-type multicast -j ACCEPT + -A foo --stp-type config -j ACCEPT +--A foo --802_3-sap 0x23 --limit 100/sec --limit-burst 5 -j ACCEPT ++-A foo -p Length --802_3-sap 0x23 --limit 100/sec --limit-burst 5 -j ACCEPT + -A foo --pkttype-type multicast --log-level notice --log-prefix "" -j CONTINUE + -A foo --pkttype-type multicast --limit 100/sec --limit-burst 5 -j ACCEPT + *nat +-- +2.40.0 + diff --git a/SOURCES/0083-extensions-among-Remove-pointless-fall-through.patch b/SOURCES/0083-extensions-among-Remove-pointless-fall-through.patch new file mode 100644 index 0000000..b591a9b --- /dev/null +++ b/SOURCES/0083-extensions-among-Remove-pointless-fall-through.patch @@ -0,0 +1,36 @@ +From bf73dcb492c75cc03aeb945b749a49a529090ae3 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 29 Sep 2022 19:11:55 +0200 +Subject: [PATCH] extensions: among: Remove pointless fall through + +This seems to be a leftover from an earlier version of the switch(). +This fall through is never effective as the next case's code will never +apply. So just break instead. + +Fixes: 26753888720d8 ("nft: bridge: Rudimental among extension support") +Signed-off-by: Phil Sutter +(cherry picked from commit eafe731a50058ed59305ee4ab1ea2d63d6c4e86e) +--- + extensions/libebt_among.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c +index 7eb898f984bba..c607a775539d3 100644 +--- a/extensions/libebt_among.c ++++ b/extensions/libebt_among.c +@@ -152,10 +152,9 @@ static int bramong_parse(int c, char **argv, int invert, + xtables_error(PARAMETER_PROBLEM, + "File should only contain one line"); + optarg[flen-1] = '\0'; +- /* fall through */ ++ break; + case AMONG_DST: +- if (c == AMONG_DST) +- dst = true; ++ dst = true; + /* fall through */ + case AMONG_SRC: + break; +-- +2.40.0 + diff --git a/SOURCES/0084-extensions-among-Fix-for-use-with-ebtables-restore.patch b/SOURCES/0084-extensions-among-Fix-for-use-with-ebtables-restore.patch new file mode 100644 index 0000000..aa10447 --- /dev/null +++ b/SOURCES/0084-extensions-among-Fix-for-use-with-ebtables-restore.patch @@ -0,0 +1,57 @@ +From 6a7b38bdb0253cfac68893ff7704f1f9cbfe891a Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 30 Sep 2022 17:51:55 +0200 +Subject: [PATCH] extensions: among: Fix for use with ebtables-restore + +When restoring multiple rules which use among match, new size may be +smaller than the old one which caused invalid writes by the memcpy() +call. Expect this and realloc the match only if it needs to grow. Also +use realloc instead of freeing and allocating from scratch. + +Fixes: 26753888720d8 ("nft: bridge: Rudimental among extension support") +Signed-off-by: Phil Sutter +(cherry picked from commit fca04aa7a53252464c289997e71de10189971da6) +--- + extensions/libebt_among.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c +index c607a775539d3..1eab201984408 100644 +--- a/extensions/libebt_among.c ++++ b/extensions/libebt_among.c +@@ -119,7 +119,6 @@ static int bramong_parse(int c, char **argv, int invert, + struct xt_entry_match **match) + { + struct nft_among_data *data = (struct nft_among_data *)(*match)->data; +- struct xt_entry_match *new_match; + bool have_ip, dst = false; + size_t new_size, cnt; + struct stat stats; +@@ -170,18 +169,17 @@ static int bramong_parse(int c, char **argv, int invert, + new_size *= sizeof(struct nft_among_pair); + new_size += XT_ALIGN(sizeof(struct xt_entry_match)) + + sizeof(struct nft_among_data); +- new_match = xtables_calloc(1, new_size); +- memcpy(new_match, *match, (*match)->u.match_size); +- new_match->u.match_size = new_size; + +- data = (struct nft_among_data *)new_match->data; ++ if (new_size > (*match)->u.match_size) { ++ *match = xtables_realloc(*match, new_size); ++ (*match)->u.match_size = new_size; ++ data = (struct nft_among_data *)(*match)->data; ++ } ++ + have_ip = nft_among_pairs_have_ip(optarg); + poff = nft_among_prepare_data(data, dst, cnt, invert, have_ip); + parse_nft_among_pairs(data->pairs + poff, optarg, cnt, have_ip); + +- free(*match); +- *match = new_match; +- + if (c == AMONG_DST_F || c == AMONG_SRC_F) { + munmap(argv, flen); + close(fd); +-- +2.40.0 + diff --git a/SOURCES/0085-extensions-libebt_stp-Eliminate-duplicate-space-in-o.patch b/SOURCES/0085-extensions-libebt_stp-Eliminate-duplicate-space-in-o.patch new file mode 100644 index 0000000..6e15bd3 --- /dev/null +++ b/SOURCES/0085-extensions-libebt_stp-Eliminate-duplicate-space-in-o.patch @@ -0,0 +1,34 @@ +From 67ce94bf558361cf45a72957d0d563dc2742a0c2 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 1 Oct 2022 00:15:35 +0200 +Subject: [PATCH] extensions: libebt_stp: Eliminate duplicate space in output + +No need for print_range() to print a trailing whitespace, caller does +this already. + +Fixes: fd8d7d7e5d911 ("ebtables-nft: add stp match") +Signed-off-by: Phil Sutter +(cherry picked from commit 262dff31a998ef8e2507bbfd9349d761769888da) +--- + extensions/libebt_stp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extensions/libebt_stp.c b/extensions/libebt_stp.c +index 06cf93b8d8449..9270bf822a711 100644 +--- a/extensions/libebt_stp.c ++++ b/extensions/libebt_stp.c +@@ -145,9 +145,9 @@ static int parse_range(const char *portstring, void *lower, void *upper, + static void print_range(unsigned int l, unsigned int u) + { + if (l == u) +- printf("%u ", l); ++ printf("%u", l); + else +- printf("%u:%u ", l, u); ++ printf("%u:%u", l, u); + } + + static int brstp_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask) +-- +2.40.0 + diff --git a/SOURCES/0086-extensions-libip6t_dst-Fix-output-for-empty-options.patch b/SOURCES/0086-extensions-libip6t_dst-Fix-output-for-empty-options.patch new file mode 100644 index 0000000..d4dfa81 --- /dev/null +++ b/SOURCES/0086-extensions-libip6t_dst-Fix-output-for-empty-options.patch @@ -0,0 +1,41 @@ +From bea48d4a3323ce41973674e2edd64b990f8a849e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 1 Oct 2022 00:17:50 +0200 +Subject: [PATCH] extensions: libip6t_dst: Fix output for empty options + +If no --dst-opts were given, print_options() would print just a +whitespace. + +Fixes: 73866357e4a7a ("iptables: do not print trailing whitespaces") +Signed-off-by: Phil Sutter +(cherry picked from commit 11e06cbb3a87739a3d958ba4c2f08fea7b100a68) +--- + extensions/libip6t_dst.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/extensions/libip6t_dst.c b/extensions/libip6t_dst.c +index fe7e3403468ce..ba8cd66b13182 100644 +--- a/extensions/libip6t_dst.c ++++ b/extensions/libip6t_dst.c +@@ -127,15 +127,15 @@ static void + print_options(unsigned int optsnr, uint16_t *optsp) + { + unsigned int i; ++ char sep = ' '; + +- printf(" "); + for(i = 0; i < optsnr; i++) { +- printf("%d", (optsp[i] & 0xFF00) >> 8); ++ printf("%c%d", sep, (optsp[i] & 0xFF00) >> 8); + + if ((optsp[i] & 0x00FF) != 0x00FF) + printf(":%d", (optsp[i] & 0x00FF)); + +- printf("%c", (i != optsnr - 1) ? ',' : ' '); ++ sep = ','; + } + } + +-- +2.40.0 + diff --git a/SOURCES/0087-extensions-TCPOPTSTRIP-Do-not-print-empty-options.patch b/SOURCES/0087-extensions-TCPOPTSTRIP-Do-not-print-empty-options.patch new file mode 100644 index 0000000..5a86109 --- /dev/null +++ b/SOURCES/0087-extensions-TCPOPTSTRIP-Do-not-print-empty-options.patch @@ -0,0 +1,55 @@ +From 6e857353e3ce7231fc852c6187df0c6dd81767ba Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 1 Oct 2022 00:36:50 +0200 +Subject: [PATCH] extensions: TCPOPTSTRIP: Do not print empty options + +No point in printing anything if none of the bits are set. + +Fixes: aef4c1e727563 ("libxt_TCPOPTSTRIP") +Signed-off-by: Phil Sutter +(cherry picked from commit dba32a76aacf84181a9bd3ba1e301e59ab49d370) +--- + extensions/libxt_TCPOPTSTRIP.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/extensions/libxt_TCPOPTSTRIP.c b/extensions/libxt_TCPOPTSTRIP.c +index 6ea3489224602..ff873f98b3aaa 100644 +--- a/extensions/libxt_TCPOPTSTRIP.c ++++ b/extensions/libxt_TCPOPTSTRIP.c +@@ -142,6 +142,13 @@ tcpoptstrip_print_list(const struct xt_tcpoptstrip_target_info *info, + } + } + ++static bool tcpoptstrip_empty(const struct xt_tcpoptstrip_target_info *info) ++{ ++ static const struct xt_tcpoptstrip_target_info empty = {}; ++ ++ return memcmp(info, &empty, sizeof(empty)) == 0; ++} ++ + static void + tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target, + int numeric) +@@ -149,6 +156,9 @@ tcpoptstrip_tg_print(const void *ip, const struct xt_entry_target *target, + const struct xt_tcpoptstrip_target_info *info = + (const void *)target->data; + ++ if (tcpoptstrip_empty(info)) ++ return; ++ + printf(" TCPOPTSTRIP options "); + tcpoptstrip_print_list(info, numeric); + } +@@ -159,6 +169,9 @@ tcpoptstrip_tg_save(const void *ip, const struct xt_entry_target *target) + const struct xt_tcpoptstrip_target_info *info = + (const void *)target->data; + ++ if (tcpoptstrip_empty(info)) ++ return; ++ + printf(" --strip-options "); + tcpoptstrip_print_list(info, true); + } +-- +2.40.0 + diff --git a/SOURCES/0088-tests-IDLETIMER.t-Fix-syntax-support-for-restore-inp.patch b/SOURCES/0088-tests-IDLETIMER.t-Fix-syntax-support-for-restore-inp.patch new file mode 100644 index 0000000..afd6e5d --- /dev/null +++ b/SOURCES/0088-tests-IDLETIMER.t-Fix-syntax-support-for-restore-inp.patch @@ -0,0 +1,29 @@ +From f180adb86f7004c959cea29eee855a1bc489dcc9 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 30 Sep 2022 18:06:10 +0200 +Subject: [PATCH] tests: IDLETIMER.t: Fix syntax, support for restore input + +Expected output was wrong in the last OK test, probably defeating rule +search check. Also use a different label, otherwise the kernel will +reject the second idletimer with same label but different type if both +rules are added at once. + +Fixes: 85b9ec8615428 ("extensions: IDLETIMER: Add alarm timer option") +(cherry picked from commit de043bbf2b78cad83a639e27c75263aa478e8cc4) +--- + extensions/libxt_IDLETIMER.t | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libxt_IDLETIMER.t b/extensions/libxt_IDLETIMER.t +index e8f306d2462c7..3345d5bef9e38 100644 +--- a/extensions/libxt_IDLETIMER.t ++++ b/extensions/libxt_IDLETIMER.t +@@ -2,4 +2,4 @@ + -j IDLETIMER --timeout;;FAIL + -j IDLETIMER --timeout 42;;FAIL + -j IDLETIMER --timeout 42 --label foo;=;OK +--j IDLETIMER --timeout 42 --label foo --alarm;;OK ++-j IDLETIMER --timeout 42 --label bar --alarm;=;OK +-- +2.40.0 + diff --git a/SOURCES/0089-tests-libebt_stp.t-Drop-duplicate-whitespace.patch b/SOURCES/0089-tests-libebt_stp.t-Drop-duplicate-whitespace.patch new file mode 100644 index 0000000..9b185e9 --- /dev/null +++ b/SOURCES/0089-tests-libebt_stp.t-Drop-duplicate-whitespace.patch @@ -0,0 +1,29 @@ +From 8b8249ce6128e0b9f909535e63629c10920af4ec Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 5 Oct 2022 20:29:36 +0200 +Subject: [PATCH] tests: libebt_stp.t: Drop duplicate whitespace + +Code was fixed but the testcase adjustment slipped through. + +Fixes: 262dff31a998e ("extensions: libebt_stp: Eliminate duplicate space in output") +(cherry picked from commit dafb31980c4469fd28964b9703d3c77433cc7d21) +--- + extensions/libebt_stp.t | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libebt_stp.t b/extensions/libebt_stp.t +index 0c6b77b91454b..17d6c1c0978e3 100644 +--- a/extensions/libebt_stp.t ++++ b/extensions/libebt_stp.t +@@ -1,7 +1,7 @@ + :INPUT,FORWARD,OUTPUT + --stp-type 1;=;OK + --stp-flags 0x1;--stp-flags topology-change -j CONTINUE;OK +---stp-root-prio 1 -j ACCEPT;=;OK ++--stp-root-prio 1 -j ACCEPT;=;OK + --stp-root-addr 0d:ea:d0:0b:ee:f0;=;OK + --stp-root-cost 1;=;OK + --stp-sender-prio 1;=;OK +-- +2.40.0 + diff --git a/SOURCES/0090-tests-shell-Fix-expected-output-for-ip6tables-dst-ma.patch b/SOURCES/0090-tests-shell-Fix-expected-output-for-ip6tables-dst-ma.patch new file mode 100644 index 0000000..6676f78 --- /dev/null +++ b/SOURCES/0090-tests-shell-Fix-expected-output-for-ip6tables-dst-ma.patch @@ -0,0 +1,45 @@ +From 3bf8687623a0a7b15ce9621f0da6f3361d5753df Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 6 Oct 2022 02:08:10 +0200 +Subject: [PATCH] tests: shell: Fix expected output for ip6tables dst match + +Forgot to update the shell testsuites when fixing for duplicate +whitespace in output. + +Fixes: 11e06cbb3a877 ("extensions: libip6t_dst: Fix output for empty options") +Signed-off-by: Phil Sutter +(cherry picked from commit d89cc773618ddbdedd1ae967a8e686adbaf501f6) + +Conflicts: + iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 +-> Adjusted to missing commit 68e09d49ef26c + ("tests: shell: Fix testcases for changed ip6tables opts output"). +--- + .../tests/shell/testcases/ip6tables/0002-verbose-output_0 | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 b/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 +index 7624cbab655ad..65f755b627bb0 100755 +--- a/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 ++++ b/iptables/tests/shell/testcases/ip6tables/0002-verbose-output_0 +@@ -12,7 +12,7 @@ VOUT2='ACCEPT all opt in eth2 out eth3 feed:babe::4 -> feed:babe::5' + RULE3='-p icmpv6 -m icmp6 --icmpv6-type no-route' + VOUT3=' ipv6-icmp opt in * out * ::/0 -> ::/0 ipv6-icmptype 1 code 0' + RULE4='-m dst --dst-len 42 -m rt --rt-type 23' +-VOUT4=' all opt in * out * ::/0 -> ::/0 dst length:42 rt type:23' ++VOUT4=' all opt in * out * ::/0 -> ::/0 dst length:42 rt type:23' + RULE5='-m frag --fragid 1337 -j LOG' + VOUT5='LOG all opt in * out * ::/0 -> ::/0 frag id:1337 LOG flags 0 level 4' + +@@ -36,7 +36,7 @@ Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) + 0 0 ACCEPT all eth2 eth3 feed:babe::1 feed:babe::2 + 0 0 ACCEPT all eth2 eth3 feed:babe::4 feed:babe::5 + 0 0 ipv6-icmp * * ::/0 ::/0 ipv6-icmptype 1 code 0 +- 0 0 all * * ::/0 ::/0 dst length:42 rt type:23 ++ 0 0 all * * ::/0 ::/0 dst length:42 rt type:23 + 0 0 LOG all * * ::/0 ::/0 frag id:1337 LOG flags 0 level 4 + + Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) +-- +2.40.0 + diff --git a/SOURCES/0091-libiptc-Fix-for-segfault-when-renaming-a-chain.patch b/SOURCES/0091-libiptc-Fix-for-segfault-when-renaming-a-chain.patch new file mode 100644 index 0000000..72d9629 --- /dev/null +++ b/SOURCES/0091-libiptc-Fix-for-segfault-when-renaming-a-chain.patch @@ -0,0 +1,67 @@ +From a6c758229e79375efcbf4b30a68cd8c24b48e88f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 7 Oct 2022 18:29:07 +0200 +Subject: [PATCH] libiptc: Fix for segfault when renaming a chain + +This is an odd bug: If the number of chains is right and one renames the +last one in the list, libiptc dereferences a NULL pointer. Add fix and +test case for it. + +Fixes: 64ff47cde38e4 ("libiptc: fix chain rename bug in libiptc") +Reported-by: Julien Castets +Signed-off-by: Phil Sutter +(cherry picked from commit 97bf4e68fc0794adba3243fd96f40f4568e7216f) +--- + .../testcases/chain/0006rename-segfault_0 | 19 +++++++++++++++++++ + libiptc/libiptc.c | 9 +++++++++ + 2 files changed, 28 insertions(+) + create mode 100755 iptables/tests/shell/testcases/chain/0006rename-segfault_0 + +diff --git a/iptables/tests/shell/testcases/chain/0006rename-segfault_0 b/iptables/tests/shell/testcases/chain/0006rename-segfault_0 +new file mode 100755 +index 0000000000000..c10a8006b56b4 +--- /dev/null ++++ b/iptables/tests/shell/testcases/chain/0006rename-segfault_0 +@@ -0,0 +1,19 @@ ++#!/bin/bash ++# ++# Cover for a bug in libiptc: ++# - the chain 'node-98-tmp' is the last in the list sorted by name ++# - there are 81 chains in total, so three chain index buckets ++# - the last index bucket contains only the 'node-98-tmp' chain ++# => rename temporarily removes it from the bucket, leaving a NULL bucket ++# behind which is dereferenced later when inserting the chain again with new ++# name again ++ ++( ++ echo "*filter" ++ for chain in node-1 node-10 node-101 node-102 node-104 node-107 node-11 node-12 node-13 node-14 node-15 node-16 node-17 node-18 node-19 node-2 node-20 node-21 node-22 node-23 node-25 node-26 node-27 node-28 node-29 node-3 node-30 node-31 node-32 node-33 node-34 node-36 node-37 node-39 node-4 node-40 node-41 node-42 node-43 node-44 node-45 node-46 node-47 node-48 node-49 node-5 node-50 node-51 node-53 node-54 node-55 node-56 node-57 node-58 node-59 node-6 node-60 node-61 node-62 node-63 node-64 node-65 node-66 node-68 node-69 node-7 node-70 node-71 node-74 node-75 node-76 node-8 node-80 node-81 node-86 node-89 node-9 node-92 node-93 node-95 node-98-tmp; do ++ echo ":$chain - [0:0]" ++ done ++ echo "COMMIT" ++) | $XT_MULTI iptables-restore ++$XT_MULTI iptables -E node-98-tmp node-98 ++exit $? +diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c +index 5888201525213..56bb75e5c3bef 100644 +--- a/libiptc/libiptc.c ++++ b/libiptc/libiptc.c +@@ -606,6 +606,15 @@ static int iptcc_chain_index_delete_chain(struct chain_head *c, struct xtc_handl + + if (index_ptr == &c->list) { /* Chain used as index ptr */ + ++ /* If this is the last chain in the list, its index bucket just ++ * became empty. Adjust the size to avoid a NULL-pointer deref ++ * later. ++ */ ++ if (next == &h->chains) { ++ h->chain_index_sz--; ++ return 0; ++ } ++ + /* See if its possible to avoid a rebuild, by shifting + * to next pointer. Its possible if the next pointer + * is located in the same index bucket. +-- +2.40.0 + diff --git a/SOURCES/0092-extensions-libebt_mark-Fix-xlate-test-case.patch b/SOURCES/0092-extensions-libebt_mark-Fix-xlate-test-case.patch new file mode 100644 index 0000000..e8a87ba --- /dev/null +++ b/SOURCES/0092-extensions-libebt_mark-Fix-xlate-test-case.patch @@ -0,0 +1,57 @@ +From 6f275ecd5b0654a865d8230c1955baeeed4dae5d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 11 Mar 2022 18:28:49 +0100 +Subject: [PATCH] extensions: libebt_mark: Fix xlate test case + +The false suffix effectively disabled this test file, but it also has +problems: Apart from brmark_xlate() printing 'meta mark' instead of just +'mark', target is printed in the wrong position (like with any other +target-possessing extension. + +Fixes: e67c08880961f ("ebtables-translate: add initial test cases") +Signed-off-by: Phil Sutter +(cherry picked from commit bc5f9d05dbf7d0a6c5256c63c492273c93ad3434) +--- + extensions/libebt_mark.txlate | 11 +++++++++++ + extensions/libebt_mark.xlate | 11 ----------- + 2 files changed, 11 insertions(+), 11 deletions(-) + create mode 100644 extensions/libebt_mark.txlate + delete mode 100644 extensions/libebt_mark.xlate + +diff --git a/extensions/libebt_mark.txlate b/extensions/libebt_mark.txlate +new file mode 100644 +index 0000000000000..7529302d9a444 +--- /dev/null ++++ b/extensions/libebt_mark.txlate +@@ -0,0 +1,11 @@ ++ebtables-translate -A INPUT --mark-set 42 ++nft add rule bridge filter INPUT meta mark set 0x2a accept counter ++ ++ebtables-translate -A INPUT --mark-or 42 --mark-target RETURN ++nft add rule bridge filter INPUT meta mark set meta mark or 0x2a return counter ++ ++ebtables-translate -A INPUT --mark-and 42 --mark-target ACCEPT ++nft add rule bridge filter INPUT meta mark set meta mark and 0x2a accept counter ++ ++ebtables-translate -A INPUT --mark-xor 42 --mark-target DROP ++nft add rule bridge filter INPUT meta mark set meta mark xor 0x2a drop counter +diff --git a/extensions/libebt_mark.xlate b/extensions/libebt_mark.xlate +deleted file mode 100644 +index e0982a1e8ebd7..0000000000000 +--- a/extensions/libebt_mark.xlate ++++ /dev/null +@@ -1,11 +0,0 @@ +-ebtables-translate -A INPUT --mark-set 42 +-nft add rule bridge filter INPUT mark set 0x2a counter +- +-ebtables-translate -A INPUT --mark-or 42 --mark-target RETURN +-nft add rule bridge filter INPUT mark set mark or 0x2a counter return +- +-ebtables-translate -A INPUT --mark-and 42 --mark-target ACCEPT +-nft add rule bridge filter INPUT mark set mark and 0x2a counter accept +- +-ebtables-translate -A INPUT --mark-xor 42 --mark-target DROP +-nft add rule bridge filter INPUT mark set mark xor 0x2a counter drop +-- +2.40.0 + diff --git a/SOURCES/0093-extensions-libebt_redirect-Fix-xlate-return-code.patch b/SOURCES/0093-extensions-libebt_redirect-Fix-xlate-return-code.patch new file mode 100644 index 0000000..0bb86ce --- /dev/null +++ b/SOURCES/0093-extensions-libebt_redirect-Fix-xlate-return-code.patch @@ -0,0 +1,30 @@ +From fd19d22db18ac084f45d739416df1f81a4e31c82 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 16 Nov 2022 13:03:05 +0100 +Subject: [PATCH] extensions: libebt_redirect: Fix xlate return code + +The callback is supposed to return 1 on success, not 0. + +Fixes: 24ce7465056ae ("ebtables-compat: add redirect match extension") +Signed-off-by: Phil Sutter +(cherry picked from commit 8543b6f2f4a3a15a5ece7dd1b320b477ce36a8d5) +--- + extensions/libebt_redirect.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libebt_redirect.c b/extensions/libebt_redirect.c +index 6e653997ee99e..4d4c7a02cea89 100644 +--- a/extensions/libebt_redirect.c ++++ b/extensions/libebt_redirect.c +@@ -86,7 +86,7 @@ static int brredir_xlate(struct xt_xlate *xl, + xt_xlate_add(xl, "meta set pkttype host"); + if (red->target != EBT_ACCEPT) + xt_xlate_add(xl, " %s ", brredir_verdict(red->target)); +- return 0; ++ return 1; + } + + static struct xtables_target brredirect_target = { +-- +2.40.0 + diff --git a/SOURCES/0094-extensions-libipt_ttl-Sanitize-xlate-callback.patch b/SOURCES/0094-extensions-libipt_ttl-Sanitize-xlate-callback.patch new file mode 100644 index 0000000..e8ddd78 --- /dev/null +++ b/SOURCES/0094-extensions-libipt_ttl-Sanitize-xlate-callback.patch @@ -0,0 +1,39 @@ +From 64788807be19d744bb9c57943e74fe6775a8c05f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 16 Nov 2022 13:09:16 +0100 +Subject: [PATCH] extensions: libipt_ttl: Sanitize xlate callback + +Catch unexpected values in info->mode, also fix indenting. + +Fixes: 1b320a1a1dc1f ("extensions: libipt_ttl: Add translation to nft") +Signed-off-by: Phil Sutter +(cherry picked from commit 800bed28b2b7bbd931166c7426640ae619f03342) +--- + extensions/libipt_ttl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extensions/libipt_ttl.c b/extensions/libipt_ttl.c +index 6bdd219618091..86ba554ef92a8 100644 +--- a/extensions/libipt_ttl.c ++++ b/extensions/libipt_ttl.c +@@ -106,7 +106,7 @@ static int ttl_xlate(struct xt_xlate *xl, + const struct ipt_ttl_info *info = + (struct ipt_ttl_info *) params->match->data; + +- switch (info->mode) { ++ switch (info->mode) { + case IPT_TTL_EQ: + xt_xlate_add(xl, "ip ttl"); + break; +@@ -121,7 +121,7 @@ static int ttl_xlate(struct xt_xlate *xl, + break; + default: + /* Should not happen. */ +- break; ++ return 0; + } + + xt_xlate_add(xl, " %u", info->ttl); +-- +2.40.0 + diff --git a/SOURCES/0095-extensions-CONNMARK-Fix-xlate-callback.patch b/SOURCES/0095-extensions-CONNMARK-Fix-xlate-callback.patch new file mode 100644 index 0000000..6916c05 --- /dev/null +++ b/SOURCES/0095-extensions-CONNMARK-Fix-xlate-callback.patch @@ -0,0 +1,88 @@ +From f6763e2336fb4eed696fc715375e3ea5a6855b20 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 17 Nov 2022 15:30:11 +0100 +Subject: [PATCH] extensions: CONNMARK: Fix xlate callback + +Bail out if nfmask != ctmask with XT_CONNMARK_SAVE and +XT_CONNMARK_RESTORE. Looks like this needs a similar implementation to +the one for XT_CONNMARK_SET. + +Fix shift mark translation: xt_connmark_shift_ops does not contain +useful strings for nftables. Also add needed braces around the term +being shifted. + +Fixes: db7b4e0de960c ("extensions: libxt_CONNMARK: Support bit-shifting for --restore,set and save-mark") +Signed-off-by: Phil Sutter +(cherry picked from commit e6747f6b1098b2bc7dfd482f287b3f90b351f164) +--- + extensions/libxt_CONNMARK.c | 15 ++++++++++----- + extensions/libxt_CONNMARK.txlate | 3 +++ + 2 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c +index 21e1091386294..a6568c99b6c4d 100644 +--- a/extensions/libxt_CONNMARK.c ++++ b/extensions/libxt_CONNMARK.c +@@ -595,11 +595,11 @@ static int connmark_tg_xlate_v2(struct xt_xlate *xl, + { + const struct xt_connmark_tginfo2 *info = + (const void *)params->target->data; +- const char *shift_op = xt_connmark_shift_ops[info->shift_dir]; ++ const char *braces = info->shift_bits ? "( " : ""; + + switch (info->mode) { + case XT_CONNMARK_SET: +- xt_xlate_add(xl, "ct mark set "); ++ xt_xlate_add(xl, "ct mark set %s", braces); + if (info->ctmask == 0xFFFFFFFFU) + xt_xlate_add(xl, "0x%x ", info->ctmark); + else if (info->ctmark == 0) +@@ -615,26 +615,31 @@ static int connmark_tg_xlate_v2(struct xt_xlate *xl, + info->ctmark, ~info->ctmask); + break; + case XT_CONNMARK_SAVE: +- xt_xlate_add(xl, "ct mark set mark"); ++ xt_xlate_add(xl, "ct mark set %smark", braces); + if (!(info->nfmask == UINT32_MAX && + info->ctmask == UINT32_MAX)) { + if (info->nfmask == info->ctmask) + xt_xlate_add(xl, " and 0x%x", info->nfmask); ++ else ++ return 0; + } + break; + case XT_CONNMARK_RESTORE: +- xt_xlate_add(xl, "meta mark set ct mark"); ++ xt_xlate_add(xl, "meta mark set %sct mark", braces); + if (!(info->nfmask == UINT32_MAX && + info->ctmask == UINT32_MAX)) { + if (info->nfmask == info->ctmask) + xt_xlate_add(xl, " and 0x%x", info->nfmask); ++ else ++ return 0; + } + break; + } + + if (info->mode <= XT_CONNMARK_RESTORE && + info->shift_bits != 0) { +- xt_xlate_add(xl, " %s %u", shift_op, info->shift_bits); ++ xt_xlate_add(xl, " ) %s %u", ++ info->shift_dir ? ">>" : "<<", info->shift_bits); + } + + return 1; +diff --git a/extensions/libxt_CONNMARK.txlate b/extensions/libxt_CONNMARK.txlate +index ce40ae5ea65e0..99627c2b05d45 100644 +--- a/extensions/libxt_CONNMARK.txlate ++++ b/extensions/libxt_CONNMARK.txlate +@@ -18,3 +18,6 @@ nft add rule ip mangle PREROUTING counter ct mark set mark + + iptables-translate -t mangle -A PREROUTING -j CONNMARK --restore-mark + nft add rule ip mangle PREROUTING counter meta mark set ct mark ++ ++iptables-translate -t mangle -A PREROUTING -j CONNMARK --set-mark 0x23/0x42 --right-shift-mark 5 ++nft add rule ip mangle PREROUTING counter ct mark set ( ct mark xor 0x23 and 0xffffff9c ) >> 5 +-- +2.40.0 + diff --git a/SOURCES/0096-extensions-MARK-Sanitize-MARK_xlate.patch b/SOURCES/0096-extensions-MARK-Sanitize-MARK_xlate.patch new file mode 100644 index 0000000..645e8ad --- /dev/null +++ b/SOURCES/0096-extensions-MARK-Sanitize-MARK_xlate.patch @@ -0,0 +1,31 @@ +From ce7198e207384f91d510b50e64305de3e05c2c61 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 17 Nov 2022 16:01:11 +0100 +Subject: [PATCH] extensions: MARK: Sanitize MARK_xlate() + +Since markinfo->mode might contain unexpected values, add a default case +returning zero. + +Fixes: afefc7a134ca0 ("extensions: libxt_MARK: Add translation for revision 1 to nft") +Signed-off-by: Phil Sutter +(cherry picked from commit c4fc6440a6f39606e38744bfc827852bb68829f4) +--- + extensions/libxt_MARK.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/extensions/libxt_MARK.c b/extensions/libxt_MARK.c +index 1536563d0f4c7..100f6a38996ac 100644 +--- a/extensions/libxt_MARK.c ++++ b/extensions/libxt_MARK.c +@@ -366,6 +366,8 @@ static int MARK_xlate(struct xt_xlate *xl, + case XT_MARK_OR: + xt_xlate_add(xl, "mark or 0x%x ", (uint32_t)markinfo->mark); + break; ++ default: ++ return 0; + } + + return 1; +-- +2.40.0 + diff --git a/SOURCES/0097-extensions-TCPMSS-Use-xlate-callback-for-IPv6-too.patch b/SOURCES/0097-extensions-TCPMSS-Use-xlate-callback-for-IPv6-too.patch new file mode 100644 index 0000000..b68e2d1 --- /dev/null +++ b/SOURCES/0097-extensions-TCPMSS-Use-xlate-callback-for-IPv6-too.patch @@ -0,0 +1,29 @@ +From 6069123a02f5ff736e8d06adc5d5f3f11173febf Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 17 Nov 2022 16:06:46 +0100 +Subject: [PATCH] extensions: TCPMSS: Use xlate callback for IPv6, too + +Data structures are identical and the translation is layer3-agnostic. + +Fixes: bebce197adb42 ("iptables: iptables-compat translation for TCPMSS") +Signed-off-by: Phil Sutter +(cherry picked from commit e05d9af176cb2a62c1bd24fa1d82b12a8ad00221) +--- + extensions/libxt_TCPMSS.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/extensions/libxt_TCPMSS.c b/extensions/libxt_TCPMSS.c +index 0d9b200ebc72f..251a5532a838b 100644 +--- a/extensions/libxt_TCPMSS.c ++++ b/extensions/libxt_TCPMSS.c +@@ -131,6 +131,7 @@ static struct xtables_target tcpmss_tg_reg[] = { + .x6_parse = TCPMSS_parse, + .x6_fcheck = TCPMSS_check, + .x6_options = TCPMSS6_opts, ++ .xlate = TCPMSS_xlate, + }, + }; + +-- +2.40.0 + diff --git a/SOURCES/0098-extensions-TOS-Fix-v1-xlate-callback.patch b/SOURCES/0098-extensions-TOS-Fix-v1-xlate-callback.patch new file mode 100644 index 0000000..0b35525 --- /dev/null +++ b/SOURCES/0098-extensions-TOS-Fix-v1-xlate-callback.patch @@ -0,0 +1,95 @@ +From 383c33a62877379b44ec58032cc707a43b662481 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 17 Nov 2022 16:10:14 +0100 +Subject: [PATCH] extensions: TOS: Fix v1 xlate callback + +Translation entirely ignored tos_mask field. + +Fixes: b669e18489709 ("extensions: libxt_TOS: Add translation to nft") +Signed-off-by: Phil Sutter +(cherry picked from commit 161fb8ad126d8f330c8f59a4a1b5885d26477664) +--- + extensions/libxt_TOS.c | 33 +++++++++++++++++++++++---------- + extensions/libxt_TOS.txlate | 9 ++++++--- + 2 files changed, 29 insertions(+), 13 deletions(-) + +diff --git a/extensions/libxt_TOS.c b/extensions/libxt_TOS.c +index b66fa329f4150..4fc849bd2468b 100644 +--- a/extensions/libxt_TOS.c ++++ b/extensions/libxt_TOS.c +@@ -183,28 +183,41 @@ static void tos_tg_save(const void *ip, const struct xt_entry_target *target) + printf(" --set-tos 0x%02x/0x%02x", info->tos_value, info->tos_mask); + } + ++static int __tos_xlate(struct xt_xlate *xl, const char *ip, ++ uint8_t tos, uint8_t tosmask) ++{ ++ xt_xlate_add(xl, "%s dscp set ", ip); ++ if ((tosmask & 0x3f) == 0x3f) ++ xt_xlate_add(xl, "0x%02x", tos >> 2); ++ else if (!tos) ++ xt_xlate_add(xl, "%s dscp and 0x%02x", ++ ip, (uint8_t)~tosmask >> 2); ++ else if (tos == tosmask) ++ xt_xlate_add(xl, "%s dscp or 0x%02x", ip, tos >> 2); ++ else if (!tosmask) ++ xt_xlate_add(xl, "%s dscp xor 0x%02x", ip, tos >> 2); ++ else ++ xt_xlate_add(xl, "%s dscp and 0x%02x xor 0x%02x", ++ ip, (uint8_t)~tosmask >> 2, tos >> 2); ++ return 1; ++} ++ + static int tos_xlate(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) + { + const struct ipt_tos_target_info *info = + (struct ipt_tos_target_info *) params->target->data; +- uint8_t dscp = info->tos >> 2; +- +- xt_xlate_add(xl, "ip dscp set 0x%02x", dscp); + +- return 1; ++ return __tos_xlate(xl, "ip", info->tos, UINT8_MAX); + } + + static int tos_xlate6(struct xt_xlate *xl, + const struct xt_xlate_tg_params *params) + { +- const struct ipt_tos_target_info *info = +- (struct ipt_tos_target_info *) params->target->data; +- uint8_t dscp = info->tos >> 2; ++ const struct xt_tos_target_info *info = ++ (struct xt_tos_target_info *)params->target->data; + +- xt_xlate_add(xl, "ip6 dscp set 0x%02x", dscp); +- +- return 1; ++ return __tos_xlate(xl, "ip6", info->tos_value, info->tos_mask); + } + + static struct xtables_target tos_tg_reg[] = { +diff --git a/extensions/libxt_TOS.txlate b/extensions/libxt_TOS.txlate +index 0952310edc4ac..9c12674299359 100644 +--- a/extensions/libxt_TOS.txlate ++++ b/extensions/libxt_TOS.txlate +@@ -14,10 +14,13 @@ ip6tables-translate -A INPUT -j TOS --set-tos Normal-Service + nft add rule ip6 filter INPUT counter ip6 dscp set 0x00 + + ip6tables-translate -A INPUT -j TOS --and-tos 0x12 +-nft add rule ip6 filter INPUT counter ip6 dscp set 0x00 ++nft add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp and 0x04 + + ip6tables-translate -A INPUT -j TOS --or-tos 0x12 +-nft add rule ip6 filter INPUT counter ip6 dscp set 0x04 ++nft add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp or 0x04 + + ip6tables-translate -A INPUT -j TOS --xor-tos 0x12 +-nft add rule ip6 filter INPUT counter ip6 dscp set 0x04 ++nft add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp xor 0x04 ++ ++ip6tables-translate -A INPUT -j TOS --set-tos 0x12/0x34 ++nft add rule ip6 filter INPUT counter ip6 dscp set ip6 dscp and 0x32 xor 0x04 +-- +2.40.0 + diff --git a/SOURCES/0099-extensions-ecn-Sanitize-xlate-callback.patch b/SOURCES/0099-extensions-ecn-Sanitize-xlate-callback.patch new file mode 100644 index 0000000..f66a33b --- /dev/null +++ b/SOURCES/0099-extensions-ecn-Sanitize-xlate-callback.patch @@ -0,0 +1,30 @@ +From ae3975e65d0f524d4d44c61407078bd11b10493e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 17 Nov 2022 16:37:02 +0100 +Subject: [PATCH] extensions: ecn: Sanitize xlate callback + +Catch unexpected values in einfo->ip_ect. + +Fixes: ca42442093d3d ("iptables: extensions: libxt_ecn: Add translation to nft") +Signed-off-by: Phil Sutter +(cherry picked from commit 424ef98918d31377a305cdf1626e1c1f69ab6df1) +--- + extensions/libxt_ecn.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/extensions/libxt_ecn.c b/extensions/libxt_ecn.c +index ad3c7a0307a0d..83a4acfab7da7 100644 +--- a/extensions/libxt_ecn.c ++++ b/extensions/libxt_ecn.c +@@ -156,6 +156,8 @@ static int ecn_xlate(struct xt_xlate *xl, + case 3: + xt_xlate_add(xl, "ce"); + break; ++ default: ++ return 0; + } + } + return 1; +-- +2.40.0 + diff --git a/SOURCES/0100-extensions-libebt_mark-Fix-mark-target-xlate.patch b/SOURCES/0100-extensions-libebt_mark-Fix-mark-target-xlate.patch new file mode 100644 index 0000000..c0247c8 --- /dev/null +++ b/SOURCES/0100-extensions-libebt_mark-Fix-mark-target-xlate.patch @@ -0,0 +1,31 @@ +From 5d3cf36df7d10011493f9d170be9077b734c52ad Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 23 Nov 2022 03:35:34 +0100 +Subject: [PATCH] extensions: libebt_mark: Fix mark target xlate + +Target value is constructed setting all non-target bits to one instead +of zero. + +Fixes: 03ecffe6c2cc0 ("ebtables-compat: add initial translations") +Signed-off-by: Phil Sutter +(cherry picked from commit c6d7a1dd72a21e7f8f117eedb61bff5b94ef5f0c) +--- + extensions/libebt_mark.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libebt_mark.c b/extensions/libebt_mark.c +index 423c5c9133d0d..40e49618e0215 100644 +--- a/extensions/libebt_mark.c ++++ b/extensions/libebt_mark.c +@@ -201,7 +201,7 @@ static int brmark_xlate(struct xt_xlate *xl, + return 0; + } + +- tmp = info->target & EBT_VERDICT_BITS; ++ tmp = info->target | ~EBT_VERDICT_BITS; + xt_xlate_add(xl, "0x%lx %s ", info->mark, brmark_verdict(tmp)); + return 1; + } +-- +2.40.0 + diff --git a/SOURCES/0101-extensions-libxt_conntrack-Drop-extra-whitespace-in-.patch b/SOURCES/0101-extensions-libxt_conntrack-Drop-extra-whitespace-in-.patch new file mode 100644 index 0000000..0c44c09 --- /dev/null +++ b/SOURCES/0101-extensions-libxt_conntrack-Drop-extra-whitespace-in-.patch @@ -0,0 +1,57 @@ +From 082a131316f145e29f77a1761294d343b8df320b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 25 Nov 2022 04:35:35 +0100 +Subject: [PATCH] extensions: libxt_conntrack: Drop extra whitespace in xlate + +No point in having this. Interestingly, other test cases even made up +for it. + +Fixes: 0afd957f6bc03 ("extensions: libxt_state: add translation to nft") +Signed-off-by: Phil Sutter +(cherry picked from commit 116848ea1e5d8d02fd766356a642bd81574e2723) + +Conflicts: + extensions/libxt_hashlimit.txlate +-> Adjusted to missing commit 023dd2c515be6 + ("libxtables: xt_xlate_add() to take care of spacing"). +--- + extensions/libxt_SYNPROXY.txlate | 2 +- + extensions/libxt_conntrack.c | 1 - + extensions/libxt_hashlimit.txlate | 4 ++-- + 3 files changed, 3 insertions(+), 4 deletions(-) + +diff --git a/extensions/libxt_SYNPROXY.txlate b/extensions/libxt_SYNPROXY.txlate +index b3de2b2a8c9dc..a2a3b6c522fe7 100644 +--- a/extensions/libxt_SYNPROXY.txlate ++++ b/extensions/libxt_SYNPROXY.txlate +@@ -1,2 +1,2 @@ + iptables-translate -t mangle -A INPUT -i iifname -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460 +-nft add rule ip mangle INPUT iifname "iifname" tcp dport 80 ct state invalid,untracked counter synproxy sack-perm timestamp wscale 7 mss 1460 ++nft add rule ip mangle INPUT iifname "iifname" tcp dport 80 ct state invalid,untracked counter synproxy sack-perm timestamp wscale 7 mss 1460 +diff --git a/extensions/libxt_conntrack.c b/extensions/libxt_conntrack.c +index 6ab5c99133d3c..6dfd942dcd5ab 100644 +--- a/extensions/libxt_conntrack.c ++++ b/extensions/libxt_conntrack.c +@@ -1196,7 +1196,6 @@ static int state_xlate(struct xt_xlate *xl, + xt_xlate_add(xl, "ct state "); + state_xlate_print(xl, sinfo->state_mask, + sinfo->invert_flags & XT_CONNTRACK_STATE); +- xt_xlate_add(xl, " "); + return 1; + } + +diff --git a/extensions/libxt_hashlimit.txlate b/extensions/libxt_hashlimit.txlate +index 6c8d07f113d26..2fb6969befb4b 100644 +--- a/extensions/libxt_hashlimit.txlate ++++ b/extensions/libxt_hashlimit.txlate +@@ -1,5 +1,5 @@ + iptables-translate -A OUTPUT -m tcp -p tcp --dport 443 -m hashlimit --hashlimit-above 20kb/s --hashlimit-burst 1mb --hashlimit-mode dstip --hashlimit-name https --hashlimit-dstmask 24 -m state --state NEW -j DROP +-nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr and 255.255.255.0 timeout 60s limit rate over 20 kbytes/second burst 1 mbytes} ct state new counter drop ++nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr and 255.255.255.0 timeout 60s limit rate over 20 kbytes/second burst 1 mbytes} ct state new counter drop + + iptables-translate -A OUTPUT -m tcp -p tcp --dport 443 -m hashlimit --hashlimit-upto 300 --hashlimit-burst 15 --hashlimit-mode srcip,dstip --hashlimit-name https --hashlimit-htable-expire 300000 -m state --state NEW -j DROP +-nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr . ip saddr timeout 300s limit rate 300/second burst 15 packets} ct state new counter drop ++nft add rule ip filter OUTPUT tcp dport 443 meter https { ip daddr . ip saddr timeout 300s limit rate 300/second burst 15 packets} ct state new counter drop +-- +2.40.0 + diff --git a/SOURCES/0102-iptables-restore-Free-handle-with-test-also.patch b/SOURCES/0102-iptables-restore-Free-handle-with-test-also.patch new file mode 100644 index 0000000..ee4f2d5 --- /dev/null +++ b/SOURCES/0102-iptables-restore-Free-handle-with-test-also.patch @@ -0,0 +1,47 @@ +From a1d05d4c6ac02bed334c55f611bff08decff89e6 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 25 Nov 2022 19:24:38 +0100 +Subject: [PATCH] iptables-restore: Free handle with --test also + +When running 'iptables-restore -t', valgrind reports: + +1,496 (160 direct, 1,336 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4 + at 0x48417E5: malloc (vg_replace_malloc.c:381) + by 0x4857A46: alloc_handle (libiptc.c:1279) + by 0x4857A46: iptc_init (libiptc.c:1342) + by 0x1167CE: create_handle (iptables-restore.c:72) + by 0x1167CE: ip46tables_restore_main (iptables-restore.c:229) + by 0x116DAE: iptables_restore_main (iptables-restore.c:388) + by 0x49A2349: (below main) (in /lib64/libc.so.6) + +Free the handle pointer before parsing the next table. + +Fixes: 1c9015b2cb483 ("libiptc: remove indirections") +Signed-off-by: Phil Sutter +(cherry picked from commit 18880dbde615449d00a3e38f3713a19d4566258e) +--- + iptables/iptables-restore.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c +index a34d95015c93c..3b821467db355 100644 +--- a/iptables/iptables-restore.c ++++ b/iptables/iptables-restore.c +@@ -187,12 +187,12 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb, + if (!testing) { + DEBUGP("Calling commit\n"); + ret = cb->ops->commit(handle); +- cb->ops->free(handle); +- handle = NULL; + } else { + DEBUGP("Not calling commit, testing\n"); + ret = 1; + } ++ cb->ops->free(handle); ++ handle = NULL; + + /* Done with the current table, release the lock. */ + if (lock >= 0) { +-- +2.40.0 + diff --git a/SOURCES/0103-iptables-xml-Free-allocated-chain-strings.patch b/SOURCES/0103-iptables-xml-Free-allocated-chain-strings.patch new file mode 100644 index 0000000..712a6ae --- /dev/null +++ b/SOURCES/0103-iptables-xml-Free-allocated-chain-strings.patch @@ -0,0 +1,42 @@ +From 0abbd8f611f379d14cac3dc3d84a2255ef78ee45 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 25 Nov 2022 19:30:09 +0100 +Subject: [PATCH] iptables-xml: Free allocated chain strings + +Freeing only if 'created' is non-zero is wrong - the data was still +allocated. In fact, the field is supposed to prevent only the call to +openChain(). + +Fixes: 8d3eccb19a9c6 ("Add iptables-xml tool (Amin Azez )") +Signed-off-by: Phil Sutter +(cherry picked from commit 73da7fb74c1089391dac0aca70e13e5f5999ace7) +--- + iptables/iptables-xml.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c +index 98d03dda98d2b..815d24e13b300 100644 +--- a/iptables/iptables-xml.c ++++ b/iptables/iptables-xml.c +@@ -225,13 +225,13 @@ finishChains(void) + { + int c; + +- for (c = 0; c < nextChain; c++) +- if (!chains[c].created) { ++ for (c = 0; c < nextChain; c++) { ++ if (!chains[c].created) + openChain(chains[c].chain, chains[c].policy, + &(chains[c].count), '/'); +- free(chains[c].chain); +- free(chains[c].policy); +- } ++ free(chains[c].chain); ++ free(chains[c].policy); ++ } + nextChain = 0; + } + +-- +2.40.0 + diff --git a/SOURCES/0104-nft-Plug-memleak-in-nft_rule_zero_counters.patch b/SOURCES/0104-nft-Plug-memleak-in-nft_rule_zero_counters.patch new file mode 100644 index 0000000..b1cbedf --- /dev/null +++ b/SOURCES/0104-nft-Plug-memleak-in-nft_rule_zero_counters.patch @@ -0,0 +1,51 @@ +From bf06d5a6df59cb5e87fe5e909431da5697a965e3 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 25 Nov 2022 21:21:22 +0100 +Subject: [PATCH] nft: Plug memleak in nft_rule_zero_counters() + +When zeroing a specific rule, valgrind reports: + +40 bytes in 1 blocks are definitely lost in loss record 1 of 1 + at 0x484659F: calloc (vg_replace_malloc.c:1328) + by 0x48DE128: xtables_calloc (xtables.c:434) + by 0x11C7C6: nft_parse_immediate (nft-shared.c:1071) + by 0x11C7C6: nft_rule_to_iptables_command_state (nft-shared.c:1236) + by 0x119AF5: nft_rule_zero_counters (nft.c:2877) + by 0x11A3CA: nft_prepare (nft.c:3445) + by 0x11A7A8: nft_commit (nft.c:3479) + by 0x114258: xtables_main.isra.0 (xtables-standalone.c:94) + by 0x1142D9: xtables_ip6_main (xtables-standalone.c:118) + by 0x49F2349: (below main) (in /lib64/libc.so.6) + +Have to free the matches/target in populated iptables_command_state object +again. While being at it, call the proper family_ops callbacks since this is +family-agnostic code. + +Fixes: a69cc575295ee ("xtables: allow to reset the counters of an existing rule") +Signed-off-by: Phil Sutter +(cherry picked from commit aa0c54030300441e9fd66c7016d0090f6736d449) +--- + iptables/nft.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 0ec7679d25289..b70e9237a04ab 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -2614,10 +2614,11 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, + goto error; + } + +- nft_rule_to_iptables_command_state(h, r, &cs); +- ++ h->ops->rule_to_cs(h, r, &cs); + cs.counters.pcnt = cs.counters.bcnt = 0; + new_rule = nft_rule_new(h, chain, table, &cs); ++ h->ops->clear_cs(&cs); ++ + if (!new_rule) + return 1; + +-- +2.40.0 + diff --git a/SOURCES/0105-xtables-Introduce-xtables_clear_iptables_command_sta.patch b/SOURCES/0105-xtables-Introduce-xtables_clear_iptables_command_sta.patch new file mode 100644 index 0000000..7d726a4 --- /dev/null +++ b/SOURCES/0105-xtables-Introduce-xtables_clear_iptables_command_sta.patch @@ -0,0 +1,219 @@ +From 4d1c89af40811d5527ab5c2b629245076d970542 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 25 Nov 2022 21:42:20 +0100 +Subject: [PATCH] xtables: Introduce xtables_clear_iptables_command_state() + +This is nft_clear_iptables_command_state() but in a location reachable +by legacy iptables, too. + +Changes callers in non-family-specific code to use clear_cs callback +instead of directly calling it - ebtables still has a custom variant. + +Signed-off-by: Phil Sutter +(cherry picked from commit 365647ef056828bc3cb56efef12114951fcb730d) + +Conflicts: + iptables/nft-arp.c + iptables/nft-shared.c + iptables/nft-shared.h + iptables/xshared.c +-> Context change due to missing commits cfdda18044d81 + ("nft-shared: Introduce init_cs family ops callback") and + 62c3c93d4b0f5 ("xshared: Move do_parse to shared space"). +-> Adjust to missing commit 0af80a91b0a98 + ("nft: Merge xtables-arp-standalone.c into xtables-standalone.c"). + +(cherry picked from commit 42792a2949749794487519575119ee1083975a76) +--- + iptables/nft-arp.c | 4 ++-- + iptables/nft-ipv4.c | 4 ++-- + iptables/nft-ipv6.c | 4 ++-- + iptables/nft-shared.c | 14 -------------- + iptables/nft-shared.h | 1 - + iptables/xshared.c | 17 +++++++++++++++++ + iptables/xshared.h | 2 ++ + iptables/xtables-arp.c | 2 +- + iptables/xtables-translate.c | 2 +- + iptables/xtables.c | 2 +- + 10 files changed, 28 insertions(+), 24 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index d55e06572b283..b90f53990fd4f 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -501,7 +501,7 @@ nft_arp_print_rule(struct nft_handle *h, struct nftnl_rule *r, + if (!(format & FMT_NONEWLINE)) + fputc('\n', stdout); + +- nft_clear_iptables_command_state(&cs); ++ xtables_clear_iptables_command_state(&cs); + } + + static bool nft_arp_is_same(const void *data_a, +@@ -550,6 +550,6 @@ struct nft_family_ops nft_family_ops_arp = { + .save_chain = nft_arp_save_chain, + .post_parse = NULL, + .rule_to_cs = nft_rule_to_iptables_command_state, +- .clear_cs = nft_clear_iptables_command_state, ++ .clear_cs = xtables_clear_iptables_command_state, + .parse_target = nft_ipv46_parse_target, + }; +diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c +index 76c76b67100ca..a70e9ece248fe 100644 +--- a/iptables/nft-ipv4.c ++++ b/iptables/nft-ipv4.c +@@ -286,7 +286,7 @@ static void nft_ipv4_print_rule(struct nft_handle *h, struct nftnl_rule *r, + if (!(format & FMT_NONEWLINE)) + fputc('\n', stdout); + +- nft_clear_iptables_command_state(&cs); ++ xtables_clear_iptables_command_state(&cs); + } + + static void save_ipv4_addr(char letter, const struct in_addr *addr, +@@ -476,6 +476,6 @@ struct nft_family_ops nft_family_ops_ipv4 = { + .post_parse = nft_ipv4_post_parse, + .parse_target = nft_ipv46_parse_target, + .rule_to_cs = nft_rule_to_iptables_command_state, +- .clear_cs = nft_clear_iptables_command_state, ++ .clear_cs = xtables_clear_iptables_command_state, + .xlate = nft_ipv4_xlate, + }; +diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c +index fac0f16cfe815..1f73bbcb8771f 100644 +--- a/iptables/nft-ipv6.c ++++ b/iptables/nft-ipv6.c +@@ -215,7 +215,7 @@ static void nft_ipv6_print_rule(struct nft_handle *h, struct nftnl_rule *r, + if (!(format & FMT_NONEWLINE)) + fputc('\n', stdout); + +- nft_clear_iptables_command_state(&cs); ++ xtables_clear_iptables_command_state(&cs); + } + + static void save_ipv6_addr(char letter, const struct in6_addr *addr, +@@ -418,6 +418,6 @@ struct nft_family_ops nft_family_ops_ipv6 = { + .post_parse = nft_ipv6_post_parse, + .parse_target = nft_ipv46_parse_target, + .rule_to_cs = nft_rule_to_iptables_command_state, +- .clear_cs = nft_clear_iptables_command_state, ++ .clear_cs = xtables_clear_iptables_command_state, + .xlate = nft_ipv6_xlate, + }; +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index cb1c2d61f52c1..075ad620250dc 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -685,20 +685,6 @@ void nft_rule_to_iptables_command_state(struct nft_handle *h, + cs->jumpto = ""; + } + +-void nft_clear_iptables_command_state(struct iptables_command_state *cs) +-{ +- xtables_rule_matches_free(&cs->matches); +- if (cs->target) { +- free(cs->target->t); +- cs->target->t = NULL; +- +- if (cs->target == cs->target->next) { +- free(cs->target); +- cs->target = NULL; +- } +- } +-} +- + void print_header(unsigned int format, const char *chain, const char *pol, + const struct xt_counters *counters, bool basechain, + uint32_t refs, uint32_t entries) +diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h +index 3531631bd8acd..e3c1b202b8638 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -144,7 +144,6 @@ void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv); + void nft_rule_to_iptables_command_state(struct nft_handle *h, + const struct nftnl_rule *r, + struct iptables_command_state *cs); +-void nft_clear_iptables_command_state(struct iptables_command_state *cs); + void print_header(unsigned int format, const char *chain, const char *pol, + const struct xt_counters *counters, bool basechain, + uint32_t refs, uint32_t entries); +diff --git a/iptables/xshared.c b/iptables/xshared.c +index b052b849b2069..8de4fe4945279 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -872,3 +872,20 @@ void assert_valid_chain_name(const char *chainname) + xtables_error(PARAMETER_PROBLEM, + "Invalid chain name `%s'", chainname); + } ++ ++void xtables_clear_iptables_command_state(struct iptables_command_state *cs) ++{ ++ xtables_rule_matches_free(&cs->matches); ++ if (cs->target) { ++ free(cs->target->t); ++ cs->target->t = NULL; ++ ++ free(cs->target->udata); ++ cs->target->udata = NULL; ++ ++ if (cs->target == cs->target->next) { ++ free(cs->target); ++ cs->target = NULL; ++ } ++ } ++} +diff --git a/iptables/xshared.h b/iptables/xshared.h +index c512f20afd33a..e8fd82894f48e 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -139,6 +139,8 @@ struct iptables_command_state { + bool restore; + }; + ++void xtables_clear_iptables_command_state(struct iptables_command_state *cs); ++ + typedef int (*mainfunc_t)(int, char **); + + struct subcommand { +diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c +index 0695504892b74..617b4ae41857f 100644 +--- a/iptables/xtables-arp.c ++++ b/iptables/xtables-arp.c +@@ -1007,7 +1007,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, + free(daddrs); + free(dmasks); + +- nft_clear_iptables_command_state(&cs); ++ xtables_clear_iptables_command_state(&cs); + xtables_free_opts(1); + + /* if (verbose > 1) +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index 575fb320dc408..aeae33c38512a 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -319,7 +319,7 @@ static int do_command_xlate(struct nft_handle *h, int argc, char *argv[], + exit(1); + } + +- nft_clear_iptables_command_state(&cs); ++ h->ops->clear_cs(&cs); + + if (h->family == AF_INET) { + free(args.s.addr.v4); +diff --git a/iptables/xtables.c b/iptables/xtables.c +index 3c7b3fc45b6f6..250dacffdf49d 100644 +--- a/iptables/xtables.c ++++ b/iptables/xtables.c +@@ -1051,7 +1051,7 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, + + *table = p.table; + +- nft_clear_iptables_command_state(&cs); ++ h->ops->clear_cs(&cs); + + if (h->family == AF_INET) { + free(args.s.addr.v4); +-- +2.40.0 + diff --git a/SOURCES/0106-iptables-Properly-clear-iptables_command_state-objec.patch b/SOURCES/0106-iptables-Properly-clear-iptables_command_state-objec.patch new file mode 100644 index 0000000..ae9b25d --- /dev/null +++ b/SOURCES/0106-iptables-Properly-clear-iptables_command_state-objec.patch @@ -0,0 +1,75 @@ +From d5391d8f96dffaaaf665233f0c2349455e2fc848 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 25 Nov 2022 21:44:39 +0100 +Subject: [PATCH] iptables: Properly clear iptables_command_state object + +When adding a rule with a target which defines a udata_size, valgrind +prints: + +8 bytes in 1 blocks are definitely lost in loss record 1 of 1 + at 0x484659F: calloc (vg_replace_malloc.c:1328) + by 0x486B128: xtables_calloc (xtables.c:434) + by 0x1128B4: xs_init_target (xshared.c:238) + by 0x113CD3: command_jump (xshared.c:877) + by 0x114969: do_parse (xshared.c:1644) + by 0x10EEB9: do_command4 (iptables.c:691) + by 0x10E45B: iptables_main (iptables-standalone.c:59) + by 0x49A2349: (below main) (in /lib64/libc.so.6) + +It is not sufficient to free cs.target->t, so call +xtables_clear_iptables_command_state() which takes care of all the +details. + +Fixes: 2dba676b68ef8 ("extensions: support for per-extension instance "global" variable space") +Signed-off-by: Phil Sutter +(cherry picked from commit 8bee0db39f7553589c2cec58cc92ed2eafd2eb57) +--- + iptables/ip6tables.c | 3 +-- + iptables/iptables.c | 3 +-- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c +index 897f30d5ef4b0..a0b7d4302a976 100644 +--- a/iptables/ip6tables.c ++++ b/iptables/ip6tables.c +@@ -1559,7 +1559,6 @@ int do_command6(int argc, char *argv[], char **table, + xtables_find_target(cs.jumpto, XTF_LOAD_MUST_SUCCEED); + } else { + e = generate_entry(&cs.fw6, cs.matches, cs.target->t); +- free(cs.target->t); + } + } + +@@ -1658,7 +1657,7 @@ int do_command6(int argc, char *argv[], char **table, + if (verbose > 1) + dump_entries6(*handle); + +- xtables_rule_matches_free(&cs.matches); ++ xtables_clear_iptables_command_state(&cs); + + if (e != NULL) { + free(e); +diff --git a/iptables/iptables.c b/iptables/iptables.c +index 9964d14ed8195..b519fb59cc071 100644 +--- a/iptables/iptables.c ++++ b/iptables/iptables.c +@@ -1552,7 +1552,6 @@ int do_command4(int argc, char *argv[], char **table, + xtables_find_target(cs.jumpto, XTF_LOAD_MUST_SUCCEED); + } else { + e = generate_entry(&cs.fw, cs.matches, cs.target->t); +- free(cs.target->t); + } + } + +@@ -1651,7 +1650,7 @@ int do_command4(int argc, char *argv[], char **table, + if (verbose > 1) + dump_entries(*handle); + +- xtables_rule_matches_free(&cs.matches); ++ xtables_clear_iptables_command_state(&cs); + + if (e != NULL) { + free(e); +-- +2.40.0 + diff --git a/SOURCES/0107-libiptc-Eliminate-garbage-access.patch b/SOURCES/0107-libiptc-Eliminate-garbage-access.patch new file mode 100644 index 0000000..25c5a16 --- /dev/null +++ b/SOURCES/0107-libiptc-Eliminate-garbage-access.patch @@ -0,0 +1,47 @@ +From f946cee2f81140677b89d3da334f1b3b709d1109 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 30 Nov 2022 20:03:30 +0100 +Subject: [PATCH] libiptc: Eliminate garbage access + +When adding a rule, valgrind prints: + +Syscall param socketcall.setsockopt(optval) points to uninitialised byte(s) + at 0x4A8165A: setsockopt (in /lib64/libc.so.6) + by 0x4857A48: iptc_commit (libiptc.c:2676) + by 0x10E4BB: iptables_main (iptables-standalone.c:61) + by 0x49A3349: (below main) (in /lib64/libc.so.6) + Address 0x4b63788 is 40 bytes inside a block of size 1,448 alloc'd + at 0x484659F: calloc (vg_replace_malloc.c:1328) + by 0x4857654: iptc_commit (libiptc.c:2564) + by 0x10E4BB: iptables_main (iptables-standalone.c:61) + by 0x49A3349: (below main) (in /lib64/libc.so.6) + +This is because repl->counters is not initialized upon allocation. Since +the field is an array, make use of calloc() which implicitly does the +initialization. + +Fixes: e37c0dc100c51 ("Revert the recent addition of memset()'s to TC_COMMIT. One of them is bogus and the other one needs more investigation to why valgrind is complaining.") +Signed-off-by: Phil Sutter +(cherry picked from commit 39a2aa8cbfc99f4a75dfc0786a80ced90952ab29) +--- + libiptc/libiptc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c +index 56bb75e5c3bef..157fbc4b72ebc 100644 +--- a/libiptc/libiptc.c ++++ b/libiptc/libiptc.c +@@ -2554,8 +2554,8 @@ TC_COMMIT(struct xtc_handle *handle) + + sizeof(STRUCT_COUNTERS) * new_number; + + /* These are the old counters we will get from kernel */ +- repl->counters = malloc(sizeof(STRUCT_COUNTERS) +- * handle->info.num_entries); ++ repl->counters = calloc(handle->info.num_entries, ++ sizeof(STRUCT_COUNTERS)); + if (!repl->counters) { + errno = ENOMEM; + goto out_free_repl; +-- +2.40.0 + diff --git a/SOURCES/0108-ebtables-Fix-MAC-address-match-translation.patch b/SOURCES/0108-ebtables-Fix-MAC-address-match-translation.patch new file mode 100644 index 0000000..0c12ed8 --- /dev/null +++ b/SOURCES/0108-ebtables-Fix-MAC-address-match-translation.patch @@ -0,0 +1,63 @@ +From 37e59c5df0e7cdd9f7e4673248abd92cc02d569c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 1 Dec 2022 13:03:49 +0100 +Subject: [PATCH] ebtables: Fix MAC address match translation + +If a mask was present, ebtables-translate would emit illegal syntax. + +Fixes: 5e2b473a64bc7 ("xtables-compat: extend generic tests for masks and wildcards") +Signed-off-by: Phil Sutter +(cherry picked from commit 39589b3edb7c0ea3e64777c7f4cdbf45be55ce53) + +Conflicts: + extensions/generic.txlate +-> Adjusted to missing commit 09d63e818ae0d + ("extensions: change expected output for new format") +-> Adjust to missing commit 023dd2c515be6 + ("libxtables: xt_xlate_add() to take care of spacing"). +--- + extensions/generic.txlate | 2 +- + iptables/nft-bridge.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/extensions/generic.txlate b/extensions/generic.txlate +index 6779d6f86dec8..44b84e3b23515 100644 +--- a/extensions/generic.txlate ++++ b/extensions/generic.txlate +@@ -65,7 +65,7 @@ ebtables-translate -A FORWARD ! -i iname --logical-in ilogname -o out+ --logical + nft add rule bridge filter FORWARD iifname != "iname" meta ibrname "ilogname" oifname "out*" meta obrname "lout*" ether daddr 01:02:03:04:de:af counter + + ebtables-translate -I INPUT -p ip -d 1:2:3:4:5:6/ff:ff:ff:ff:00:00 +-nft insert rule bridge filter INPUT ether type 0x800 ether daddr 01:02:03:04:00:00 and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 counter ++nft insert rule bridge filter INPUT ether type 0x800 ether daddr and ff:ff:ff:ff:00:00 == 01:02:03:04:00:00 counter + + ebtables-translate -I INPUT -p Length + nft insert rule bridge filter INPUT ether type < 0x0600 counter +diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c +index fbed1616253a6..48bcda61cfb9c 100644 +--- a/iptables/nft-bridge.c ++++ b/iptables/nft-bridge.c +@@ -863,17 +863,17 @@ static void nft_bridge_xlate_mac(struct xt_xlate *xl, const char *type, bool inv + + xt_xlate_add(xl, "ether %s %s", type, invert ? "!= " : ""); + +- xlate_mac(xl, mac); +- + if (memcmp(mask, one_msk, ETH_ALEN)) { + int i; +- xt_xlate_add(xl, " and "); ++ xt_xlate_add(xl, "and "); + + xlate_mac(xl, mask); + + xt_xlate_add(xl, " == %02x", mac[0] & mask[0]); + for (i=1; i < ETH_ALEN; i++) + xt_xlate_add(xl, ":%02x", mac[i] & mask[i]); ++ } else { ++ xlate_mac(xl, mac); + } + + xt_xlate_add(xl, " "); +-- +2.40.0 + diff --git a/SOURCES/0109-nft-Fix-for-comparing-ifname-matches-against-nft-gen.patch b/SOURCES/0109-nft-Fix-for-comparing-ifname-matches-against-nft-gen.patch new file mode 100644 index 0000000..6736899 --- /dev/null +++ b/SOURCES/0109-nft-Fix-for-comparing-ifname-matches-against-nft-gen.patch @@ -0,0 +1,33 @@ +From 169d4dd39aeeb9108810e95b6eb176b50701ff7e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 1 Dec 2022 13:09:48 +0100 +Subject: [PATCH] nft: Fix for comparing ifname matches against nft-generated + ones + +Since nft adds the interface name as fixed-size string of 16 bytes, +filling a mask based on the length value will not match the mask nft +set. + +Fixes: 652b98e793711 ("xtables-compat: fix wildcard detection") +Signed-off-by: Phil Sutter +(cherry picked from commit f200aca7ff7b6a0edbe9024f0543b3f58111c50e) +--- + iptables/nft-shared.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 075ad620250dc..14b04b24085a0 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -243,7 +243,7 @@ static void parse_ifname(const char *name, unsigned int len, char *dst, unsigned + memcpy(dst, name, len); + if (name[len - 1] == '\0') { + if (mask) +- memset(mask, 0xff, len); ++ memset(mask, 0xff, strlen(name) + 1); + return; + } + +-- +2.40.0 + diff --git a/SOURCES/0110-nft-Fix-match-generator-for-i.patch b/SOURCES/0110-nft-Fix-match-generator-for-i.patch new file mode 100644 index 0000000..d86455d --- /dev/null +++ b/SOURCES/0110-nft-Fix-match-generator-for-i.patch @@ -0,0 +1,52 @@ +From 7eb8f16deca37f85b2988204368051a4556b6228 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 1 Dec 2022 15:08:01 +0100 +Subject: [PATCH] nft: Fix match generator for '! -i +' + +It's actually nonsense since it will never match, but iptables accepts +it and the resulting nftables rule must behave identically. Reuse the +solution implemented into xtables-translate (by commit e179e87a1179e) +and turn the above match into 'iifname INVAL/D'. + +The commit this fixes merely ignored the fact that "any interface" match +might be inverted. + +Fixes: 0a8635183edd0 ("xtables-compat: ignore '+' interface name") +Signed-off-by: Phil Sutter +(cherry picked from commit 5baa4279264bb4ab93c6e80b4887f2bd29691446) + +Conflicts: + iptables/nft-shared.c +-> Adjusted to missing commit 7e38890c6b4fb + ("nft: prepare for dynamic register allocation"). +--- + iptables/nft-shared.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 14b04b24085a0..8e005ed3b5818 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -143,6 +143,9 @@ void add_iniface(struct nftnl_rule *r, char *iface, uint32_t op) + if (iface[iface_len - 1] == '+') { + if (iface_len > 1) + add_cmp_ptr(r, op, iface, iface_len - 1); ++ else if (op != NFT_CMP_EQ) ++ add_cmp_ptr(r, NFT_CMP_EQ, "INVAL/D", ++ strlen("INVAL/D") + 1); + } else + add_cmp_ptr(r, op, iface, iface_len + 1); + } +@@ -157,6 +160,9 @@ void add_outiface(struct nftnl_rule *r, char *iface, uint32_t op) + if (iface[iface_len - 1] == '+') { + if (iface_len > 1) + add_cmp_ptr(r, op, iface, iface_len - 1); ++ else if (op != NFT_CMP_EQ) ++ add_cmp_ptr(r, NFT_CMP_EQ, "INVAL/D", ++ strlen("INVAL/D") + 1); + } else + add_cmp_ptr(r, op, iface, iface_len + 1); + } +-- +2.40.0 + diff --git a/SOURCES/0111-xtables-translate-Fix-for-interfaces-with-asterisk-m.patch b/SOURCES/0111-xtables-translate-Fix-for-interfaces-with-asterisk-m.patch new file mode 100644 index 0000000..a80d175 --- /dev/null +++ b/SOURCES/0111-xtables-translate-Fix-for-interfaces-with-asterisk-m.patch @@ -0,0 +1,74 @@ +From 0d08235024c951cf0f563562cbeaee82d8c7321c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 1 Dec 2022 15:16:43 +0100 +Subject: [PATCH] xtables-translate: Fix for interfaces with asterisk + mid-string + +For nft, asterisk is special at end of the interface name only. Escaping +it mid-string makes the escape char part of the interface name, so avoid +this. + +In the test case, also drop the ticks around interface names in +*-translate command - since there's no shell involved which would eat +them, they become part of the interface name. + +Fixes: e179e87a1179e ("xtables-translate: Fix for interface name corner-cases") +Signed-off-by: Phil Sutter +(cherry picked from commit ba1c0fe89eb56f8bf25f9165f2e5dc366ea0118c) + +Conflicts: + extensions/generic.txlate +-> Adjusted to missing commit 09d63e818ae0d + ("extensions: change expected output for new format"). +--- + extensions/generic.txlate | 14 +++++++------- + iptables/xtables-translate.c | 4 +++- + 2 files changed, 10 insertions(+), 8 deletions(-) + +diff --git a/extensions/generic.txlate b/extensions/generic.txlate +index 44b84e3b23515..0316c1dd3cc2b 100644 +--- a/extensions/generic.txlate ++++ b/extensions/generic.txlate +@@ -74,17 +74,17 @@ ebtables-translate -I INPUT -p ! Length + nft insert rule bridge filter INPUT ether type >= 0x0600 counter + + # asterisk is not special in iptables and it is even a valid interface name +-iptables-translate -A FORWARD -i '*' -o 'eth*foo' +-nft add rule ip filter FORWARD iifname "\*" oifname "eth\*foo" counter ++iptables-translate -A FORWARD -i * -o eth*foo ++nft add rule ip filter FORWARD iifname "\*" oifname "eth*foo" counter + +-# escape all asterisks but translate only the first plus character +-iptables-translate -A FORWARD -i 'eth*foo*+' -o 'eth++' +-nft add rule ip filter FORWARD iifname "eth\*foo\**" oifname "eth+*" counter ++# escape only suffix asterisk and translate only the last plus character ++iptables-translate -A FORWARD -i eth*foo*+ -o eth++ ++nft add rule ip filter FORWARD iifname "eth*foo**" oifname "eth+*" counter + + # skip for always matching interface names +-iptables-translate -A FORWARD -i '+' ++iptables-translate -A FORWARD -i + + nft add rule ip filter FORWARD counter + + # match against invalid interface name to simulate never matching rule +-iptables-translate -A FORWARD ! -i '+' ++iptables-translate -A FORWARD ! -i + + nft add rule ip filter FORWARD iifname "INVAL/D" counter +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index aeae33c38512a..5f5e314dc33d0 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -41,7 +41,9 @@ void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname, + for (i = 0, j = 0; i < ifaclen + 1; i++, j++) { + switch (ifname[i]) { + case '*': +- iface[j++] = '\\'; ++ /* asterisk is non-special mid-string */ ++ if (i == ifaclen - 1) ++ iface[j++] = '\\'; + /* fall through */ + default: + iface[j] = ifname[i]; +-- +2.40.0 + diff --git a/SOURCES/0112-Drop-libiptc-linux_stddef.h.patch b/SOURCES/0112-Drop-libiptc-linux_stddef.h.patch new file mode 100644 index 0000000..22ec05f --- /dev/null +++ b/SOURCES/0112-Drop-libiptc-linux_stddef.h.patch @@ -0,0 +1,63 @@ +From f22984ed9aec54dad7fa5c1953f8d088ec56c002 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 3 Dec 2022 22:45:59 +0100 +Subject: [PATCH] Drop libiptc/linux_stddef.h + +This header was never included anywhere. + +Fixes: aae69bed01982 ("complete libiptc rewrite. Time to load 10k rules goes down from 2.20 minutes to 1.255 seconds (!). Might still contain bugs, use with caution.") +Signed-off-by: Phil Sutter +(cherry picked from commit 53153775b08f830b940d04efbc7b38bc40aaa4b3) +--- + libiptc/linux_stddef.h | 39 --------------------------------------- + 1 file changed, 39 deletions(-) + delete mode 100644 libiptc/linux_stddef.h + +diff --git a/libiptc/linux_stddef.h b/libiptc/linux_stddef.h +deleted file mode 100644 +index 56416f104ecfc..0000000000000 +--- a/libiptc/linux_stddef.h ++++ /dev/null +@@ -1,39 +0,0 @@ +-#ifndef _LINUX_STDDEF_H +-#define _LINUX_STDDEF_H +- +-#undef NULL +-#if defined(__cplusplus) +-#define NULL 0 +-#else +-#define NULL ((void *)0) +-#endif +- +-#undef offsetof +-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +- +- +-/** +- * container_of - cast a member of a structure out to the containing structure +- * +- * @ptr: the pointer to the member. +- * @type: the type of the container struct this is embedded in. +- * @member: the name of the member within the struct. +- * +- */ +-#define container_of(ptr, type, member) ({ \ +- const typeof( ((type *)0)->member ) *__mptr = (ptr); \ +- (type *)( (char *)__mptr - offsetof(type,member) );}) +- +-/* +- * Check at compile time that something is of a particular type. +- * Always evaluates to 1 so you may use it easily in comparisons. +- */ +-#define typecheck(type,x) \ +-({ type __dummy; \ +- typeof(x) __dummy2; \ +- (void)(&__dummy == &__dummy2); \ +- 1; \ +-}) +- +- +-#endif +-- +2.40.0 + diff --git a/SOURCES/0113-include-Makefile-xtables-version.h-is-generated.patch b/SOURCES/0113-include-Makefile-xtables-version.h-is-generated.patch new file mode 100644 index 0000000..411ad1b --- /dev/null +++ b/SOURCES/0113-include-Makefile-xtables-version.h-is-generated.patch @@ -0,0 +1,41 @@ +From 8e9fbe24942ce70909e7f8d672972af949155e8e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 7 Dec 2022 17:23:12 +0100 +Subject: [PATCH] include/Makefile: xtables-version.h is generated + +List it in nodist_include_HEADERS so it is installed but not +distributed - configure generates it from xtables-version.h.in. + +While being at it, list xtables.h in plain include_HEADERS. It doesn't +sit in a sub-dir, so the nobase prefix does not make a difference. + +Fixes: df60a301bf24c ("build: separate AC variable replacements from xtables.h") +Signed-off-by: Phil Sutter +(cherry picked from commit 19f03b7a2a21f22a53b6b0d2f542062986e2f807) +--- + include/Makefile.am | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/Makefile.am b/include/Makefile.am +index e69512092253a..36e0f347aa6be 100644 +--- a/include/Makefile.am ++++ b/include/Makefile.am +@@ -1,12 +1,12 @@ + # -*- Makefile -*- + +-include_HEADERS = +-nobase_include_HEADERS = xtables.h xtables-version.h ++include_HEADERS = xtables.h ++nodist_include_HEADERS = xtables-version.h + + if ENABLE_LIBIPQ + include_HEADERS += libipq/libipq.h + endif + +-nobase_include_HEADERS += \ ++nobase_include_HEADERS = \ + libiptc/ipt_kernel_headers.h libiptc/libiptc.h \ + libiptc/libip6tc.h libiptc/libxtc.h libiptc/xtcshared.h +-- +2.40.0 + diff --git a/SOURCES/0114-arptables-Check-the-mandatory-ar_pln-match.patch b/SOURCES/0114-arptables-Check-the-mandatory-ar_pln-match.patch new file mode 100644 index 0000000..4a69ac9 --- /dev/null +++ b/SOURCES/0114-arptables-Check-the-mandatory-ar_pln-match.patch @@ -0,0 +1,44 @@ +From 918e196100fae784b836c04f0a4b07230be9a4ac Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 15 Dec 2022 16:06:11 +0100 +Subject: [PATCH] arptables: Check the mandatory ar_pln match + +This match is added by nft_arp_add() to every rule with same value, so +when parsing just check it is as expected and otherwise ignore it. This +allows to treat matches on all other offsets/lengths as error. + +Fixes: 84909d171585d ("xtables: bootstrap ARP compatibility layer for nftables") +Signed-off-by: Phil Sutter +(cherry picked from commit f2c5e52863ea48838e9b9246ed94419053673b88) +--- + iptables/nft-arp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index b90f53990fd4f..398face687fbf 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -219,7 +219,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + struct arpt_entry *fw = &cs->arp; + struct in_addr addr; + uint16_t ar_hrd, ar_pro, ar_op; +- uint8_t ar_hln; ++ uint8_t ar_hln, ar_pln; + bool inv; + + switch (ctx->payload.offset) { +@@ -251,6 +251,11 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + if (inv) + fw->arp.invflags |= IPT_INV_ARPOP; + break; ++ case offsetof(struct arphdr, ar_pln): ++ get_cmp_data(e, &ar_pln, sizeof(ar_pln), &inv); ++ if (ar_pln != 4 || inv) ++ ctx->errmsg = "unexpected ARP protocol length match"; ++ break; + default: + if (ctx->payload.offset == sizeof(struct arphdr)) { + if (nft_arp_parse_devaddr(ctx, e, &fw->arp.src_devaddr)) +-- +2.40.0 + diff --git a/SOURCES/0115-gitignore-Ignore-utils-nfsynproxy.patch b/SOURCES/0115-gitignore-Ignore-utils-nfsynproxy.patch new file mode 100644 index 0000000..bd68923 --- /dev/null +++ b/SOURCES/0115-gitignore-Ignore-utils-nfsynproxy.patch @@ -0,0 +1,24 @@ +From 441541709e8e994c487d91cf8a7761232dc1bd5e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 22 Dec 2022 17:23:49 +0100 +Subject: [PATCH] gitignore: Ignore utils/nfsynproxy + +Fixes: 9e6928f037823 ("utils: add nfsynproxy tool") +Signed-off-by: Phil Sutter +(cherry picked from commit 567f6ba105302f57ccb6789dbcfc9e1e2657809a) +--- + utils/.gitignore | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/utils/.gitignore b/utils/.gitignore +index 6300812b1701b..e508bb3270c4f 100644 +--- a/utils/.gitignore ++++ b/utils/.gitignore +@@ -2,3 +2,4 @@ + /nfnl_osf.8 + /nfbpf_compile + /nfbpf_compile.8 ++/nfsynproxy +-- +2.40.0 + diff --git a/SOURCES/0116-etc-Drop-xtables.conf.patch b/SOURCES/0116-etc-Drop-xtables.conf.patch new file mode 100644 index 0000000..e29e96a --- /dev/null +++ b/SOURCES/0116-etc-Drop-xtables.conf.patch @@ -0,0 +1,118 @@ +From 3795aaa59056509193150ccd1357dd2230eff6fe Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 17 Jan 2023 16:38:43 +0100 +Subject: [PATCH] etc: Drop xtables.conf + +The file is not used since the commit this one fixes. Also it wasn't +installed until recently, when commit 3822a992bc277 ("Makefile: Fix for +'make distcheck'") added it in the wrong spot in an attempt to reduce +differences between tarballs generated by 'make tarball' and 'make +dist'. + +While being at it, drop stale xtables_config_main() prototype from +xtables-multi.h. + +Fixes: 06fd5e46d46f7 ("xtables: Drop support for /etc/xtables.conf") +Signed-off-by: Phil Sutter +(cherry picked from commit ca8fb6c21b298b3d96db2bfbf9c74d393bdd4728) +--- + etc/xtables.conf | 74 ---------------------------------------- + iptables/xtables-multi.h | 1 - + 2 files changed, 75 deletions(-) + delete mode 100644 etc/xtables.conf + +diff --git a/etc/xtables.conf b/etc/xtables.conf +deleted file mode 100644 +index 3c54ced043d82..0000000000000 +--- a/etc/xtables.conf ++++ /dev/null +@@ -1,74 +0,0 @@ +-family ipv4 { +- table raw { +- chain PREROUTING hook NF_INET_PRE_ROUTING prio -300 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio -300 +- } +- +- table mangle { +- chain PREROUTING hook NF_INET_PRE_ROUTING prio -150 +- chain INPUT hook NF_INET_LOCAL_IN prio -150 +- chain FORWARD hook NF_INET_FORWARD prio -150 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio -150 +- chain POSTROUTING hook NF_INET_POST_ROUTING prio -150 +- } +- +- table filter { +- chain INPUT hook NF_INET_LOCAL_IN prio 0 +- chain FORWARD hook NF_INET_FORWARD prio 0 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio 0 +- } +- +- table nat { +- chain PREROUTING hook NF_INET_PRE_ROUTING prio -100 +- chain INPUT hook NF_INET_LOCAL_IN prio 100 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio -100 +- chain POSTROUTING hook NF_INET_POST_ROUTING prio 100 +- } +- +- table security { +- chain INPUT hook NF_INET_LOCAL_IN prio 50 +- chain FORWARD hook NF_INET_FORWARD prio 50 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio 50 +- } +-} +- +-family ipv6 { +- table raw { +- chain PREROUTING hook NF_INET_PRE_ROUTING prio -300 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio -300 +- } +- +- table mangle { +- chain PREROUTING hook NF_INET_PRE_ROUTING prio -150 +- chain INPUT hook NF_INET_LOCAL_IN prio -150 +- chain FORWARD hook NF_INET_FORWARD prio -150 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio -150 +- chain POSTROUTING hook NF_INET_POST_ROUTING prio -150 +- } +- +- table filter { +- chain INPUT hook NF_INET_LOCAL_IN prio 0 +- chain FORWARD hook NF_INET_FORWARD prio 0 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio 0 +- } +- +- table nat { +- chain PREROUTING hook NF_INET_PRE_ROUTING prio -100 +- chain INPUT hook NF_INET_LOCAL_IN prio 100 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio -100 +- chain POSTROUTING hook NF_INET_POST_ROUTING prio 100 +- } +- +- table security { +- chain INPUT hook NF_INET_LOCAL_IN prio 50 +- chain FORWARD hook NF_INET_FORWARD prio 50 +- chain OUTPUT hook NF_INET_LOCAL_OUT prio 50 +- } +-} +- +-family arp { +- table filter { +- chain INPUT hook NF_ARP_IN prio 0 +- chain OUTPUT hook NF_ARP_OUT prio 0 +- } +-} +diff --git a/iptables/xtables-multi.h b/iptables/xtables-multi.h +index 0fedb430e1a28..fe14efc48cb13 100644 +--- a/iptables/xtables-multi.h ++++ b/iptables/xtables-multi.h +@@ -20,7 +20,6 @@ extern int xtables_arp_save_main(int, char **); + extern int xtables_eb_main(int, char **); + extern int xtables_eb_restore_main(int, char **); + extern int xtables_eb_save_main(int, char **); +-extern int xtables_config_main(int, char **); + extern int xtables_monitor_main(int, char **); + #endif + +-- +2.40.0 + diff --git a/SOURCES/0117-Proper-fix-for-unknown-argument-error-message.patch b/SOURCES/0117-Proper-fix-for-unknown-argument-error-message.patch new file mode 100644 index 0000000..4dc2073 --- /dev/null +++ b/SOURCES/0117-Proper-fix-for-unknown-argument-error-message.patch @@ -0,0 +1,163 @@ +From 72a17e09b38f9f8496d8e8f1a615b3759cfc905c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 25 Jan 2023 01:51:43 +0100 +Subject: [PATCH] Proper fix for "unknown argument" error message + +While commit 1b8210f848631 kind of fixed the corner-case of invalid +short-options packed with others, it broke error reporting for +long-options. Revert it and deploy a proper solution: + +When passing an invalid short-option, e.g. 'iptables -vaL', getopt_long +sets the variable 'optopt' to the invalid character's value. Use it for +reporting instead of optind if set. + +To distinguish between invalid options and missing option arguments, +ebtables-translate optstring needs adjustment. + +Fixes: 1b8210f848631 ("ebtables: Fix error message for invalid parameters") +Signed-off-by: Phil Sutter +(cherry picked from commit d6eb6a9fd3878ce4fa01f8d4127f1735988bd07b) + +Conflicts: + iptables/xtables-eb.c +-> Adjust to missing commits 65b150ae382a8 + ("xshared: Store optstring in xtables_globals") and fd64a5871b671 + ("libxtables: Drop xtables_globals 'optstring' field"). +--- + .../testcases/iptables/0009-unknown-arg_0 | 31 +++++++++++++++++++ + iptables/xshared.c | 9 ++++-- + iptables/xtables-eb-translate.c | 8 ++--- + iptables/xtables-eb.c | 19 +++++++----- + 4 files changed, 51 insertions(+), 16 deletions(-) + create mode 100755 iptables/tests/shell/testcases/iptables/0009-unknown-arg_0 + +diff --git a/iptables/tests/shell/testcases/iptables/0009-unknown-arg_0 b/iptables/tests/shell/testcases/iptables/0009-unknown-arg_0 +new file mode 100755 +index 0000000000000..ac6e743966196 +--- /dev/null ++++ b/iptables/tests/shell/testcases/iptables/0009-unknown-arg_0 +@@ -0,0 +1,31 @@ ++#!/bin/bash ++ ++rc=0 ++ ++check() { ++ local cmd="$1" ++ local msg="$2" ++ ++ $XT_MULTI $cmd 2>&1 | grep -q "$msg" || { ++ echo "cmd: $XT_MULTI $1" ++ echo "exp: $msg" ++ echo "res: $($XT_MULTI $cmd 2>&1)" ++ rc=1 ++ } ++} ++ ++cmds="iptables ip6tables" ++[[ $XT_MULTI == *xtables-nft-multi ]] && { ++ cmds+=" ebtables" ++ cmds+=" iptables-translate" ++ cmds+=" ip6tables-translate" ++ cmds+=" ebtables-translate" ++} ++ ++for cmd in $cmds; do ++ check "${cmd} --foo" 'unknown option "--foo"' ++ check "${cmd} -A" 'option "-A" requires an argument' ++ check "${cmd} -aL" 'unknown option "-a"' ++done ++ ++exit $rc +diff --git a/iptables/xshared.c b/iptables/xshared.c +index 8de4fe4945279..0bd56604d14b6 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -177,9 +177,12 @@ int command_default(struct iptables_command_state *cs, + if (cs->c == ':') + xtables_error(PARAMETER_PROBLEM, "option \"%s\" " + "requires an argument", cs->argv[optind-1]); +- if (cs->c == '?') +- xtables_error(PARAMETER_PROBLEM, "unknown option " +- "\"%s\"", cs->argv[optind-1]); ++ if (cs->c == '?') { ++ char optoptstr[3] = {'-', optopt, '\0'}; ++ ++ xtables_error(PARAMETER_PROBLEM, "unknown option \"%s\"", ++ optopt ? optoptstr : cs->argv[optind - 1]); ++ } + xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg); + } + +diff --git a/iptables/xtables-eb-translate.c b/iptables/xtables-eb-translate.c +index 96b2730fa97ed..efdddb20edfca 100644 +--- a/iptables/xtables-eb-translate.c ++++ b/iptables/xtables-eb-translate.c +@@ -218,7 +218,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char + printf("nft "); + /* Getopt saves the day */ + while ((c = getopt_long(argc, argv, +- "-A:D:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) { ++ "-:A:D:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) { + cs.c = c; + cs.invert = ebt_invert; + switch (c) { +@@ -505,11 +505,7 @@ static int do_commandeb_xlate(struct nft_handle *h, int argc, char *argv[], char + continue; + default: + ebt_check_inverse2(optarg, argc, argv); +- +- if (ebt_command_default(&cs)) +- xtables_error(PARAMETER_PROBLEM, +- "Unknown argument: '%s'", +- argv[optind - 1]); ++ ebt_command_default(&cs); + + if (command != 'A' && command != 'I' && + command != 'D') +diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c +index d07adad2d73c3..b7f9b3d9c511f 100644 +--- a/iptables/xtables-eb.c ++++ b/iptables/xtables-eb.c +@@ -714,7 +714,16 @@ int ebt_command_default(struct iptables_command_state *cs) + return 0; + } + } +- return 1; ++ if (cs->c == ':') ++ xtables_error(PARAMETER_PROBLEM, "option \"%s\" " ++ "requires an argument", cs->argv[optind - 1]); ++ if (cs->c == '?') { ++ char optoptstr[3] = {'-', optopt, '\0'}; ++ ++ xtables_error(PARAMETER_PROBLEM, "unknown option \"%s\"", ++ optopt ? optoptstr : cs->argv[optind - 1]); ++ } ++ xtables_error(PARAMETER_PROBLEM, "Unknown arg \"%s\"", optarg); + } + + int nft_init_eb(struct nft_handle *h, const char *pname) +@@ -792,7 +801,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, + + /* Getopt saves the day */ + while ((c = getopt_long(argc, argv, +- "-A:D:C:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) { ++ "-:A:D:C:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) { + cs.c = c; + cs.invert = ebt_invert; + switch (c) { +@@ -1143,11 +1152,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, + continue; + default: + ebt_check_inverse2(optarg, argc, argv); +- +- if (ebt_command_default(&cs)) +- xtables_error(PARAMETER_PROBLEM, +- "Unknown argument: '%s'", +- argv[optind]); ++ ebt_command_default(&cs); + + if (command != 'A' && command != 'I' && + command != 'D' && command != 'C') +-- +2.40.0 + diff --git a/SOURCES/0118-ebtables-Refuse-unselected-targets-options.patch b/SOURCES/0118-ebtables-Refuse-unselected-targets-options.patch new file mode 100644 index 0000000..02aa647 --- /dev/null +++ b/SOURCES/0118-ebtables-Refuse-unselected-targets-options.patch @@ -0,0 +1,239 @@ +From 715c128634fc2ff0c7702db8f79783226a0c2fac Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 25 Jan 2023 02:01:56 +0100 +Subject: [PATCH] ebtables: Refuse unselected targets' options + +Unlike legacy, ebtables-nft would allow e.g.: + +| -t nat -A PREROUTING --to-dst fe:ed:00:00:ba:be + +While the result is correct, it may mislead users into believing +multiple targets are possible per rule. Better follow legacy's behaviour +and reject target options unless they have been "enabled" by a previous +'-j' option. + +To achieve this, one needs to distinguish targets from watchers also +attached to 'xtables_targets' and otherwise behaving like regular +matches. Introduce XTABLES_EXT_WATCHER to mark the two. + +The above works already, but error messages are misleading when using +the now unsupported syntax since target options have been merged +already. Solve this by not pre-loading the targets at all, code will +just fall back to loading ad '-j' parsing time as iptables does. + +Note how this also fixes for 'counter' statement being in wrong position +of ebtables-translate output. + +Fixes: fe97f60e5d2a9 ("ebtables-compat: add watchers support") +Signed-off-by: Phil Sutter +(cherry picked from commit 27d37863a486352511dac385bde8f3d20526be5b) + +Conflicts: + extensions/libebt_dnat.txlate + extensions/libebt_mark.txlate + extensions/libebt_snat.txlate +-> Adjusted to missing commit 09d63e818ae0d + ("extensions: change expected output for new format"). +--- + extensions/libebt_dnat.txlate | 12 ++++---- + extensions/libebt_log.c | 1 + + extensions/libebt_mark.txlate | 16 +++++----- + extensions/libebt_nflog.c | 1 + + extensions/libebt_snat.txlate | 8 ++--- + include/xtables.h | 1 + + .../ebtables/0002-ebtables-save-restore_0 | 4 +-- + iptables/xtables-eb.c | 29 +++++++------------ + 8 files changed, 33 insertions(+), 39 deletions(-) + +diff --git a/extensions/libebt_dnat.txlate b/extensions/libebt_dnat.txlate +index 2652dd55b2644..d99396a513b8d 100644 +--- a/extensions/libebt_dnat.txlate ++++ b/extensions/libebt_dnat.txlate +@@ -1,8 +1,8 @@ +-ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff +-nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter ++ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff ++nft add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff accept + +-ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT +-nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff accept counter ++ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target ACCEPT ++nft add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff accept + +-ebtables-translate -t nat -A PREROUTING -i someport --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE +-nft add rule bridge nat PREROUTING iifname "someport" ether daddr set de:ad:0:be:ee:ff continue counter ++ebtables-translate -t nat -A PREROUTING -i someport -j dnat --to-dst de:ad:00:be:ee:ff --dnat-target CONTINUE ++nft add rule bridge nat PREROUTING iifname "someport" counter ether daddr set de:ad:0:be:ee:ff continue +diff --git a/extensions/libebt_log.c b/extensions/libebt_log.c +index 8858cf0e22c00..9f95bf77d9288 100644 +--- a/extensions/libebt_log.c ++++ b/extensions/libebt_log.c +@@ -198,6 +198,7 @@ static int brlog_xlate(struct xt_xlate *xl, + static struct xtables_target brlog_target = { + .name = "log", + .revision = 0, ++ .ext_flags = XTABLES_EXT_WATCHER, + .version = XTABLES_VERSION, + .family = NFPROTO_BRIDGE, + .size = XT_ALIGN(sizeof(struct ebt_log_info)), +diff --git a/extensions/libebt_mark.txlate b/extensions/libebt_mark.txlate +index 7529302d9a444..9695139655055 100644 +--- a/extensions/libebt_mark.txlate ++++ b/extensions/libebt_mark.txlate +@@ -1,11 +1,11 @@ +-ebtables-translate -A INPUT --mark-set 42 +-nft add rule bridge filter INPUT meta mark set 0x2a accept counter ++ebtables-translate -A INPUT -j mark --mark-set 42 ++nft add rule bridge filter INPUT counter meta mark set 0x2a accept + +-ebtables-translate -A INPUT --mark-or 42 --mark-target RETURN +-nft add rule bridge filter INPUT meta mark set meta mark or 0x2a return counter ++ebtables-translate -A INPUT -j mark --mark-or 42 --mark-target RETURN ++nft add rule bridge filter INPUT counter meta mark set meta mark or 0x2a return + +-ebtables-translate -A INPUT --mark-and 42 --mark-target ACCEPT +-nft add rule bridge filter INPUT meta mark set meta mark and 0x2a accept counter ++ebtables-translate -A INPUT -j mark --mark-and 42 --mark-target ACCEPT ++nft add rule bridge filter INPUT counter meta mark set meta mark and 0x2a accept + +-ebtables-translate -A INPUT --mark-xor 42 --mark-target DROP +-nft add rule bridge filter INPUT meta mark set meta mark xor 0x2a drop counter ++ebtables-translate -A INPUT -j mark --mark-xor 42 --mark-target DROP ++nft add rule bridge filter INPUT counter meta mark set meta mark xor 0x2a drop +diff --git a/extensions/libebt_nflog.c b/extensions/libebt_nflog.c +index 9801f358c81b1..23c9eed51d8e9 100644 +--- a/extensions/libebt_nflog.c ++++ b/extensions/libebt_nflog.c +@@ -150,6 +150,7 @@ static int brnflog_xlate(struct xt_xlate *xl, + static struct xtables_target brnflog_watcher = { + .name = "nflog", + .revision = 0, ++ .ext_flags = XTABLES_EXT_WATCHER, + .version = XTABLES_VERSION, + .family = NFPROTO_BRIDGE, + .size = XT_ALIGN(sizeof(struct ebt_nflog_info)), +diff --git a/extensions/libebt_snat.txlate b/extensions/libebt_snat.txlate +index 0d84602466c23..6b2250647daf3 100644 +--- a/extensions/libebt_snat.txlate ++++ b/extensions/libebt_snat.txlate +@@ -1,5 +1,5 @@ +-ebtables-translate -t nat -A POSTROUTING -s 0:0:0:0:0:0 -o someport+ --to-source de:ad:00:be:ee:ff +-nft add rule bridge nat POSTROUTING oifname "someport*" ether saddr 00:00:00:00:00:00 ether saddr set de:ad:0:be:ee:ff accept counter ++ebtables-translate -t nat -A POSTROUTING -s 0:0:0:0:0:0 -o someport+ -j snat --to-source de:ad:00:be:ee:ff ++nft add rule bridge nat POSTROUTING oifname "someport*" ether saddr 00:00:00:00:00:00 counter ether saddr set de:ad:0:be:ee:ff accept + +-ebtables-translate -t nat -A POSTROUTING -o someport --to-src de:ad:00:be:ee:ff --snat-target CONTINUE +-nft add rule bridge nat POSTROUTING oifname "someport" ether saddr set de:ad:0:be:ee:ff continue counter ++ebtables-translate -t nat -A POSTROUTING -o someport -j snat --to-src de:ad:00:be:ee:ff --snat-target CONTINUE ++nft add rule bridge nat POSTROUTING oifname "someport" counter ether saddr set de:ad:0:be:ee:ff continue +diff --git a/include/xtables.h b/include/xtables.h +index 3c0d0f78e8d1a..58ad4270bcaaa 100644 +--- a/include/xtables.h ++++ b/include/xtables.h +@@ -203,6 +203,7 @@ struct xtables_lmap { + + enum xtables_ext_flags { + XTABLES_EXT_ALIAS = 1 << 0, ++ XTABLES_EXT_WATCHER = 1 << 1, + }; + + struct xt_xlate; +diff --git a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 +index a4fc31548e323..05ac5bda66ff8 100755 +--- a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 ++++ b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 +@@ -38,7 +38,7 @@ $XT_MULTI ebtables -A foo -p IPv6 --ip6-proto tcp -j ACCEPT + + $XT_MULTI ebtables -A foo --limit 100 --limit-burst 42 -j ACCEPT + $XT_MULTI ebtables -A foo --log +-$XT_MULTI ebtables -A foo --mark-set 0x23 --mark-target ACCEPT ++$XT_MULTI ebtables -A foo -j mark --mark-set 0x23 --mark-target ACCEPT + $XT_MULTI ebtables -A foo --nflog + $XT_MULTI ebtables -A foo --pkttype-type multicast -j ACCEPT + $XT_MULTI ebtables -A foo --stp-type config -j ACCEPT +@@ -53,7 +53,7 @@ $XT_MULTI ebtables -A FORWARD -j foo + $XT_MULTI ebtables -N bar + $XT_MULTI ebtables -P bar RETURN + +-$XT_MULTI ebtables -t nat -A PREROUTING --redirect-target ACCEPT ++$XT_MULTI ebtables -t nat -A PREROUTING -j redirect --redirect-target ACCEPT + #$XT_MULTI ebtables -t nat -A PREROUTING --to-src fe:ed:ba:be:00:01 + + $XT_MULTI ebtables -t nat -A OUTPUT -j ACCEPT +diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c +index b7f9b3d9c511f..a3d659fb35e27 100644 +--- a/iptables/xtables-eb.c ++++ b/iptables/xtables-eb.c +@@ -536,14 +536,14 @@ static void ebt_load_match(const char *name) + xtables_error(OTHER_PROBLEM, "Can't alloc memory"); + } + +-static void __ebt_load_watcher(const char *name, const char *typename) ++static void ebt_load_watcher(const char *name) + { + struct xtables_target *watcher; + size_t size; + + watcher = xtables_find_target(name, XTF_TRY_LOAD); + if (!watcher) { +- fprintf(stderr, "Unable to load %s %s\n", name, typename); ++ fprintf(stderr, "Unable to load %s watcher\n", name); + return; + } + +@@ -564,16 +564,6 @@ static void __ebt_load_watcher(const char *name, const char *typename) + xtables_error(OTHER_PROBLEM, "Can't alloc memory"); + } + +-static void ebt_load_watcher(const char *name) +-{ +- return __ebt_load_watcher(name, "watcher"); +-} +- +-static void ebt_load_target(const char *name) +-{ +- return __ebt_load_watcher(name, "target"); +-} +- + void ebt_load_match_extensions(void) + { + opts = ebt_original_options; +@@ -590,13 +580,6 @@ void ebt_load_match_extensions(void) + + ebt_load_watcher("log"); + ebt_load_watcher("nflog"); +- +- ebt_load_target("mark"); +- ebt_load_target("dnat"); +- ebt_load_target("snat"); +- ebt_load_target("arpreply"); +- ebt_load_target("redirect"); +- ebt_load_target("standard"); + } + + void ebt_add_match(struct xtables_match *m, +@@ -707,6 +690,9 @@ int ebt_command_default(struct iptables_command_state *cs) + + /* Is it a watcher option? */ + for (t = xtables_targets; t; t = t->next) { ++ if (!(t->ext_flags & XTABLES_EXT_WATCHER)) ++ continue; ++ + if (t->parse && + t->parse(cs->c - t->option_offset, cs->argv, + ebt_invert, &t->tflags, NULL, &t->t)) { +@@ -799,6 +785,11 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, + optind = 0; + opterr = false; + ++ for (t = xtables_targets; t; t = t->next) { ++ t->tflags = 0; ++ t->used = 0; ++ } ++ + /* Getopt saves the day */ + while ((c = getopt_long(argc, argv, + "-:A:D:C:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", opts, NULL)) != -1) { +-- +2.40.0 + diff --git a/SOURCES/0119-extensions-libebt_redirect-Fix-target-translation.patch b/SOURCES/0119-extensions-libebt_redirect-Fix-target-translation.patch new file mode 100644 index 0000000..57ff7f9 --- /dev/null +++ b/SOURCES/0119-extensions-libebt_redirect-Fix-target-translation.patch @@ -0,0 +1,53 @@ +From 514ebcf9229744a18f58b431f6eb004b00e5abaf Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 31 Jan 2023 22:28:24 +0100 +Subject: [PATCH] extensions: libebt_redirect: Fix target translation + +While EBT_ACCEPT is the default verdict for ebtables targets, omitting +it from translation implicitly converts it into 'continue'. Omit the +non-default EBT_CONTINUE instead. + +Fixes: 24ce7465056ae ("ebtables-compat: add redirect match extension") +Signed-off-by: Phil Sutter +(cherry picked from commit bb6b243c481f90f7dc4a0bd89187ee2bb823f1f6) + +Conflicts: + extensions/libebt_redirect.txlate +-> Adjusted to missing commit 83604e7f7327b + ("xlate: get rid of escape_quotes"). +--- + extensions/libebt_redirect.c | 2 +- + extensions/libebt_redirect.txlate | 8 ++++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + create mode 100644 extensions/libebt_redirect.txlate + +diff --git a/extensions/libebt_redirect.c b/extensions/libebt_redirect.c +index 4d4c7a02cea89..389f3ccb53f60 100644 +--- a/extensions/libebt_redirect.c ++++ b/extensions/libebt_redirect.c +@@ -84,7 +84,7 @@ static int brredir_xlate(struct xt_xlate *xl, + const struct ebt_redirect_info *red = (const void*)params->target->data; + + xt_xlate_add(xl, "meta set pkttype host"); +- if (red->target != EBT_ACCEPT) ++ if (red->target != EBT_CONTINUE) + xt_xlate_add(xl, " %s ", brredir_verdict(red->target)); + return 1; + } +diff --git a/extensions/libebt_redirect.txlate b/extensions/libebt_redirect.txlate +new file mode 100644 +index 0000000000000..e750d438a790d +--- /dev/null ++++ b/extensions/libebt_redirect.txlate +@@ -0,0 +1,8 @@ ++ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect ++nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta set pkttype host accept ++ ++ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target RETURN ++nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta set pkttype host return ++ ++ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target CONTINUE ++nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta set pkttype host +-- +2.40.0 + diff --git a/SOURCES/0120-extensions-libebt_redirect-Fix-for-wrong-syntax-in-t.patch b/SOURCES/0120-extensions-libebt_redirect-Fix-for-wrong-syntax-in-t.patch new file mode 100644 index 0000000..fd06a2d --- /dev/null +++ b/SOURCES/0120-extensions-libebt_redirect-Fix-for-wrong-syntax-in-t.patch @@ -0,0 +1,53 @@ +From 96678b34102c5af97dcd4fde35472a77b47e71b4 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 31 Jan 2023 23:32:50 +0100 +Subject: [PATCH] extensions: libebt_redirect: Fix for wrong syntax in + translation + +Meta key comes before 'set' in meta statement. + +Fixes: 24ce7465056ae ("ebtables-compat: add redirect match extension") +Signed-off-by: Phil Sutter +(cherry picked from commit 6d1263002c2a9fc6dfa59c764dee767a084d428d) + +Conflicts: + extensions/libebt_redirect.txlate +-> Adjust to missing commit 83604e7f7327b + ("xlate: get rid of escape_quotes"). +--- + extensions/libebt_redirect.c | 2 +- + extensions/libebt_redirect.txlate | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/extensions/libebt_redirect.c b/extensions/libebt_redirect.c +index 389f3ccb53f60..7821935e137aa 100644 +--- a/extensions/libebt_redirect.c ++++ b/extensions/libebt_redirect.c +@@ -83,7 +83,7 @@ static int brredir_xlate(struct xt_xlate *xl, + { + const struct ebt_redirect_info *red = (const void*)params->target->data; + +- xt_xlate_add(xl, "meta set pkttype host"); ++ xt_xlate_add(xl, "meta pkttype set host"); + if (red->target != EBT_CONTINUE) + xt_xlate_add(xl, " %s ", brredir_verdict(red->target)); + return 1; +diff --git a/extensions/libebt_redirect.txlate b/extensions/libebt_redirect.txlate +index e750d438a790d..921e303f47037 100644 +--- a/extensions/libebt_redirect.txlate ++++ b/extensions/libebt_redirect.txlate +@@ -1,8 +1,8 @@ + ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect +-nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta set pkttype host accept ++nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host accept + + ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target RETURN +-nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta set pkttype host return ++nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host return + + ebtables-translate -t nat -A PREROUTING -d de:ad:00:00:be:ef -j redirect --redirect-target CONTINUE +-nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta set pkttype host ++nft add rule bridge nat PREROUTING ether daddr de:ad:00:00:be:ef counter meta pkttype set host +-- +2.40.0 + diff --git a/SOURCES/0121-extensions-libebt_ip-Do-not-use-ip-dscp-for-translat.patch b/SOURCES/0121-extensions-libebt_ip-Do-not-use-ip-dscp-for-translat.patch new file mode 100644 index 0000000..50c03cb --- /dev/null +++ b/SOURCES/0121-extensions-libebt_ip-Do-not-use-ip-dscp-for-translat.patch @@ -0,0 +1,55 @@ +From bcf59827f2a6ab966c3719f1c02fdd67f3780f82 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 3 Feb 2023 18:58:36 +0100 +Subject: [PATCH] extensions: libebt_ip: Do not use 'ip dscp' for translation + +Converting from TOS field match to DSCP one is irreversible, so replay +testing is not possible. Use a raw payload expression to produce +something that translates 1:1 back into an 'ip' match. + +Fixes: 03ecffe6c2cc0 ("ebtables-compat: add initial translations") +Signed-off-by: Phil Sutter +(cherry picked from commit 744c56bda974caaa274318d2825b3e43b55bf145) + +Conflicts: + extensions/libebt_ip.txlate +-> Adjust to missing commit 09d63e818ae0d + ("extensions: change expected output for new format"). +--- + extensions/libebt_ip.c | 4 ++-- + extensions/libebt_ip.txlate | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c +index acb9bfcdbbd9f..7b6fa4a2139d4 100644 +--- a/extensions/libebt_ip.c ++++ b/extensions/libebt_ip.c +@@ -677,10 +677,10 @@ static int brip_xlate(struct xt_xlate *xl, + brip_xlate_nh(xl, info, EBT_IP_DEST); + + if (info->bitmask & EBT_IP_TOS) { +- xt_xlate_add(xl, "ip dscp "); ++ xt_xlate_add(xl, "@nh,8,8 "); + if (info->invflags & EBT_IP_TOS) + xt_xlate_add(xl, "!= "); +- xt_xlate_add(xl, "0x%02x ", info->tos & 0x3f); /* remove ECN bits */ ++ xt_xlate_add(xl, "0x%02x ", info->tos); + } + if (info->bitmask & EBT_IP_PROTO) { + struct protoent *pe; +diff --git a/extensions/libebt_ip.txlate b/extensions/libebt_ip.txlate +index b5882c342b047..5c766e1b743ea 100644 +--- a/extensions/libebt_ip.txlate ++++ b/extensions/libebt_ip.txlate +@@ -5,7 +5,7 @@ ebtables-translate -I FORWARD -p ip --ip-dst 10.0.0.1 + nft insert rule bridge filter FORWARD ip daddr 10.0.0.1 counter + + ebtables-translate -I OUTPUT 3 -p ip -o eth0 --ip-tos 0xff +-nft insert rule bridge filter OUTPUT oifname "eth0" ip dscp 0x3f counter ++nft insert rule bridge filter OUTPUT oifname "eth0" @nh,8,8 0xff counter + + ebtables-translate -A FORWARD -p ip --ip-proto tcp --ip-dport 22 + nft add rule bridge filter FORWARD tcp dport 22 counter +-- +2.40.0 + diff --git a/SOURCES/0122-extensions-libebt_ip-Translation-has-to-match-on-eth.patch b/SOURCES/0122-extensions-libebt_ip-Translation-has-to-match-on-eth.patch new file mode 100644 index 0000000..e396ce2 --- /dev/null +++ b/SOURCES/0122-extensions-libebt_ip-Translation-has-to-match-on-eth.patch @@ -0,0 +1,90 @@ +From 3b42685aeedbb81f7dc6af0e1eb35200236449d2 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 3 Feb 2023 17:37:40 +0100 +Subject: [PATCH] extensions: libebt_ip: Translation has to match on ether type + +On one hand, nft refuses th expression in bridge family if layer3 +protocol has not been assured by a previous match. On the other, ebt_ip +kernel module will only match on IPv4 packets, so there might be a +functional change in the translation versus the original. + +Instead of just always emitting an 'ether type' match, decide whether +it's actually needed - explicit "ip " payload matches (or +icmp ones) cause implicit creation of a match on IPv4 by nft. + +Fixes: 03ecffe6c2cc0 ("ebtables-compat: add initial translations") +Signed-off-by: Phil Sutter +(cherry picked from commit b860e658200af8fdeced2896a1a6c2f0f0692b70) + +Conflicts: + extensions/libebt_ip.txlate +-> Adjusted to missing commit 09d63e818ae0d + ("extensions: change expected output for new format"). +--- + extensions/libebt_ip.c | 21 +++++++++++++++++++++ + extensions/libebt_ip.txlate | 6 +++--- + 2 files changed, 24 insertions(+), 3 deletions(-) + +diff --git a/extensions/libebt_ip.c b/extensions/libebt_ip.c +index 7b6fa4a2139d4..81500828fe74c 100644 +--- a/extensions/libebt_ip.c ++++ b/extensions/libebt_ip.c +@@ -667,6 +667,24 @@ static void brip_xlate_nh(struct xt_xlate *xl, + xtables_ipmask_to_numeric(maskp)); + } + ++static bool may_skip_ether_type_dep(uint8_t flags) ++{ ++ /* these convert to "ip (s|d)addr" matches */ ++ if (flags & (EBT_IP_SOURCE | EBT_IP_DEST)) ++ return true; ++ ++ /* icmp match triggers implicit ether type dependency in nft */ ++ if (flags & EBT_IP_ICMP) ++ return true; ++ ++ /* allow if "ip protocol" match is created by brip_xlate() */ ++ if (flags & EBT_IP_PROTO && ++ !(flags & (EBT_IP_SPORT | EBT_IP_DPORT | EBT_IP_ICMP))) ++ return true; ++ ++ return false; ++} ++ + static int brip_xlate(struct xt_xlate *xl, + const struct xt_xlate_mt_params *params) + { +@@ -676,6 +694,9 @@ static int brip_xlate(struct xt_xlate *xl, + brip_xlate_nh(xl, info, EBT_IP_SOURCE); + brip_xlate_nh(xl, info, EBT_IP_DEST); + ++ if (!may_skip_ether_type_dep(info->bitmask)) ++ xt_xlate_add(xl, "ether type ip "); ++ + if (info->bitmask & EBT_IP_TOS) { + xt_xlate_add(xl, "@nh,8,8 "); + if (info->invflags & EBT_IP_TOS) +diff --git a/extensions/libebt_ip.txlate b/extensions/libebt_ip.txlate +index 5c766e1b743ea..cc42d2dbacf65 100644 +--- a/extensions/libebt_ip.txlate ++++ b/extensions/libebt_ip.txlate +@@ -5,13 +5,13 @@ ebtables-translate -I FORWARD -p ip --ip-dst 10.0.0.1 + nft insert rule bridge filter FORWARD ip daddr 10.0.0.1 counter + + ebtables-translate -I OUTPUT 3 -p ip -o eth0 --ip-tos 0xff +-nft insert rule bridge filter OUTPUT oifname "eth0" @nh,8,8 0xff counter ++nft insert rule bridge filter OUTPUT oifname "eth0" ether type ip @nh,8,8 0xff counter + + ebtables-translate -A FORWARD -p ip --ip-proto tcp --ip-dport 22 +-nft add rule bridge filter FORWARD tcp dport 22 counter ++nft add rule bridge filter FORWARD ether type ip tcp dport 22 counter + + ebtables-translate -A FORWARD -p ip --ip-proto udp --ip-sport 1024:65535 +-nft add rule bridge filter FORWARD udp sport 1024-65535 counter ++nft add rule bridge filter FORWARD ether type ip udp sport 1024-65535 counter + + ebtables-translate -A FORWARD -p ip --ip-proto 253 + nft add rule bridge filter FORWARD ip protocol 253 counter +-- +2.40.0 + diff --git a/SOURCES/0123-nft-restore-Fix-for-deletion-of-new-referenced-rule.patch b/SOURCES/0123-nft-restore-Fix-for-deletion-of-new-referenced-rule.patch new file mode 100644 index 0000000..94f2eb5 --- /dev/null +++ b/SOURCES/0123-nft-restore-Fix-for-deletion-of-new-referenced-rule.patch @@ -0,0 +1,67 @@ +From 4ef8d59919d8693b8aaeff5d470e6d9eb254ebca Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 28 Feb 2023 18:09:25 +0100 +Subject: [PATCH] nft-restore: Fix for deletion of new, referenced rule + +Combining multiple corner-cases here: + +* Insert a rule before another new one which is not the first. Triggers + NFTNL_RULE_ID assignment of the latter. + +* Delete the referenced new rule in the same batch again. Causes + overwriting of the previously assigned RULE_ID. + +Consequently, iptables-nft-restore fails during *insert*, because the +reference is dangling. + +Reported-by: Eric Garver +Fixes: 760b35b46e4cc ("nft: Fix for add and delete of same rule in single batch") +Signed-off-by: Phil Sutter +Tested-by: Eric Garver +(cherry picked from commit 5fd85822bd12a02f1a921243f605fc6238d705b4) +--- + iptables/nft.c | 3 ++- + .../ipt-restore/0003-restore-ordering_0 | 16 ++++++++++++++++ + 2 files changed, 18 insertions(+), 1 deletion(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index b70e9237a04ab..9a56b1fbffcbc 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -2104,7 +2104,8 @@ static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r) + + nftnl_rule_list_del(r); + +- if (!nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE)) ++ if (!nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE) && ++ !nftnl_rule_get_u32(r, NFTNL_RULE_ID)) + nftnl_rule_set_u32(r, NFTNL_RULE_ID, ++h->rule_id); + + obj = batch_rule_add(h, NFT_COMPAT_RULE_DELETE, r); +diff --git a/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 b/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 +index 3f1d229e915ff..5482b7ea17298 100755 +--- a/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 ++++ b/iptables/tests/shell/testcases/ipt-restore/0003-restore-ordering_0 +@@ -123,3 +123,19 @@ EXPECT='-A FORWARD -m comment --comment "rule 1" -j ACCEPT + -A FORWARD -m comment --comment "rule 3" -j ACCEPT' + + diff -u -Z <(echo -e "$EXPECT") <(ipt_show) ++ ++# test adding, referencing and deleting the same rule in a batch ++ ++$XT_MULTI iptables-restore < +Date: Wed, 29 Mar 2023 16:22:16 +0200 +Subject: [PATCH] nft-shared: Drop unused include + +Code does not refer to struct xt_comment_info anymore. + +Fixes: 3bb497c61d743 ("xtables: Fix for deleting rules with comment") +Signed-off-by: Phil Sutter +(cherry picked from commit 465470184950d9035dcd1101c1f413f8a2051427) + +Conflicts: + iptables/nft-shared.c +-> Context change due to missing commit 62ad29e9b778f + ("extensions: libxt_NFLOG: don't truncate log prefix on print/save"). +--- + iptables/nft-shared.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index 8e005ed3b5818..ed093c07d7617 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -20,7 +20,6 @@ + + #include + +-#include + #include + + #include +-- +2.40.0 + diff --git a/SOURCES/0125-arptables-Fix-parsing-of-inverted-arp-operation-matc.patch b/SOURCES/0125-arptables-Fix-parsing-of-inverted-arp-operation-matc.patch new file mode 100644 index 0000000..a97feda --- /dev/null +++ b/SOURCES/0125-arptables-Fix-parsing-of-inverted-arp-operation-matc.patch @@ -0,0 +1,31 @@ +From 4f87be23b73378c42f7d555c527666d83650de46 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 28 Apr 2023 14:33:43 +0200 +Subject: [PATCH] arptables: Fix parsing of inverted 'arp operation' match + +The wrong bit was set in 'invflags', probably due to copy'n'paste from +the previous case. + +Fixes: 84909d171585d ("xtables: bootstrap ARP compatibility layer for nftables") +Signed-off-by: Phil Sutter +(cherry picked from commit 092e4b022152addc94524e2ba0cb608dac1a3a08) +--- + iptables/nft-arp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index 398face687fbf..ab1108dd69685 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -249,7 +249,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + fw->arp.arhln = ar_hln; + fw->arp.arhln_mask = 0xff; + if (inv) +- fw->arp.invflags |= IPT_INV_ARPOP; ++ fw->arp.invflags |= IPT_INV_ARPHLN; + break; + case offsetof(struct arphdr, ar_pln): + get_cmp_data(e, &ar_pln, sizeof(ar_pln), &inv); +-- +2.40.0 + diff --git a/SOURCES/0126-arptables-Don-t-omit-standard-matches-if-inverted.patch b/SOURCES/0126-arptables-Don-t-omit-standard-matches-if-inverted.patch new file mode 100644 index 0000000..9591d2e --- /dev/null +++ b/SOURCES/0126-arptables-Don-t-omit-standard-matches-if-inverted.patch @@ -0,0 +1,42 @@ +From 9e746a513d5e26f724f992f742f549f7e82f0148 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 28 Apr 2023 14:37:47 +0200 +Subject: [PATCH] arptables: Don't omit standard matches if inverted + +Inverted --h-len and --h-type matches were omitted from output by +accident if they matched on their standard value. + +Fixes: 84331e3ed3f8e ("arptables-nft: Don't print default h-len/h-type values") +Signed-off-by: Phil Sutter +(cherry picked from commit 79f93b0943fa0e46ba29bb476362634509eb594e) +--- + iptables/nft-arp.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index ab1108dd69685..f1cf46476ec83 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -416,7 +416,8 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + + after_devdst: + +- if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6) { ++ if (fw->arp.arhln_mask != 255 || fw->arp.arhln != 6 || ++ fw->arp.invflags & IPT_INV_ARPHLN) { + printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHLN + ? "! " : ""); + printf("--h-length %d", fw->arp.arhln); +@@ -440,7 +441,8 @@ static void nft_arp_print_rule_details(const struct iptables_command_state *cs, + sep = " "; + } + +- if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1)) { ++ if (fw->arp.arhrd_mask != 65535 || fw->arp.arhrd != htons(1) || ++ fw->arp.invflags & IPT_INV_ARPHRD) { + uint16_t tmp = ntohs(fw->arp.arhrd); + + printf("%s%s", sep, fw->arp.invflags & IPT_INV_ARPHRD +-- +2.40.0 + diff --git a/SOURCES/0127-Revert-arptables-Check-the-mandatory-ar_pln-match.patch b/SOURCES/0127-Revert-arptables-Check-the-mandatory-ar_pln-match.patch new file mode 100644 index 0000000..7f0227e --- /dev/null +++ b/SOURCES/0127-Revert-arptables-Check-the-mandatory-ar_pln-match.patch @@ -0,0 +1,44 @@ +From ffbc5cf87e89345ad5c4aac0ae41d3cca7502db9 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 9 May 2023 16:33:12 +0200 +Subject: [PATCH] Revert "arptables: Check the mandatory ar_pln match" + +This reverts commit 8d33fdea9f7883f403a9d3ef5b5d13887b7a5303. + +Due to the missing parser error checking and reporting added by commit +f315af1cf8871 ("nft: track each register individually"), the added check +is ineffective. + +(cherry picked from commit eb7dd6487edb14c20b60efd485e45eb014fcf41a) +--- + iptables/nft-arp.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index f1cf46476ec83..fa1676e7fd878 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -219,7 +219,7 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + struct arpt_entry *fw = &cs->arp; + struct in_addr addr; + uint16_t ar_hrd, ar_pro, ar_op; +- uint8_t ar_hln, ar_pln; ++ uint8_t ar_hln; + bool inv; + + switch (ctx->payload.offset) { +@@ -251,11 +251,6 @@ static void nft_arp_parse_payload(struct nft_xt_ctx *ctx, + if (inv) + fw->arp.invflags |= IPT_INV_ARPHLN; + break; +- case offsetof(struct arphdr, ar_pln): +- get_cmp_data(e, &ar_pln, sizeof(ar_pln), &inv); +- if (ar_pln != 4 || inv) +- ctx->errmsg = "unexpected ARP protocol length match"; +- break; + default: + if (ctx->payload.offset == sizeof(struct arphdr)) { + if (nft_arp_parse_devaddr(ctx, e, &fw->arp.src_devaddr)) +-- +2.40.0 + diff --git a/SOURCES/0128-extensions-SECMARK-Use-a-better-context-in-test-case.patch b/SOURCES/0128-extensions-SECMARK-Use-a-better-context-in-test-case.patch new file mode 100644 index 0000000..89394e3 --- /dev/null +++ b/SOURCES/0128-extensions-SECMARK-Use-a-better-context-in-test-case.patch @@ -0,0 +1,28 @@ +From f24ad92bea508ba2e037a4d2e57770371554e47f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 16 Jul 2021 21:51:49 +0200 +Subject: [PATCH] extensions: SECMARK: Use a better context in test case + +RHEL SELinux policies don't allow setting +system_u:object_r:firewalld_exec_t:s0 context. Use one instead which has +'packet_type' attribute (identified via +'seinfo -xt | grep packet_type'). + +(cherry picked from commit 0f730df43caa68e03380111b40e357141ccce709) +--- + extensions/libxt_SECMARK.t | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libxt_SECMARK.t b/extensions/libxt_SECMARK.t +index 39d4c09348bf4..295e7a7244902 100644 +--- a/extensions/libxt_SECMARK.t ++++ b/extensions/libxt_SECMARK.t +@@ -1,4 +1,4 @@ + :INPUT,FORWARD,OUTPUT + *security +--j SECMARK --selctx system_u:object_r:firewalld_exec_t:s0;=;OK ++-j SECMARK --selctx system_u:object_r:ssh_server_packet_t:s0;=;OK + -j SECMARK;;FAIL +-- +2.40.0 + diff --git a/SOURCES/0129-tests-xlate-test-Print-errors-to-stderr.patch b/SOURCES/0129-tests-xlate-test-Print-errors-to-stderr.patch new file mode 100644 index 0000000..60a3785 --- /dev/null +++ b/SOURCES/0129-tests-xlate-test-Print-errors-to-stderr.patch @@ -0,0 +1,39 @@ +From 80c0fef76c5b3f78b1261f8c15b10d58382a5c3f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 12 Aug 2021 15:12:30 +0200 +Subject: [PATCH] tests: xlate-test: Print errors to stderr + +Return code is always zero, so grepping for output on stderr is a +simple way to detect testsuite failures. + +Signed-off-by: Phil Sutter +(cherry picked from commit 5166c4451fb837e7d5dbb54a7d7cbf2f0c2469cc) +--- + xlate-test.py | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xlate-test.py b/xlate-test.py +index 4c014f9bd269a..50e9893e956aa 100755 +--- a/xlate-test.py ++++ b/xlate-test.py +@@ -65,7 +65,7 @@ xtables_nft_multi = 'xtables-nft-multi' + if (passed == tests) and not args.test: + print(name + ": " + green("OK")) + if not test_passed: +- print("\n".join(result)) ++ print("\n".join(result), file=sys.stderr) + if args.test: + print("1 test file, %d tests, %d tests passed, %d tests failed, %d errors" % (tests, passed, failed, errors)) + else: +@@ -101,7 +101,7 @@ xtables_nft_multi = 'xtables-nft-multi' + with open(args.test, "r") as payload: + run_test(args.test, payload) + except IOError: +- print(red("Error: ") + "test file does not exist") ++ print(red("Error: ") + "test file does not exist", file=sys.stderr) + else: + load_test_files() + +-- +2.40.0 + diff --git a/SOURCES/0130-iptables-test-Make-netns-spawning-more-robust.patch b/SOURCES/0130-iptables-test-Make-netns-spawning-more-robust.patch new file mode 100644 index 0000000..3989580 --- /dev/null +++ b/SOURCES/0130-iptables-test-Make-netns-spawning-more-robust.patch @@ -0,0 +1,72 @@ +From 8d25120581dfdac4585b471d0d0ed36ecf75c817 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 11 Aug 2021 14:46:22 +0200 +Subject: [PATCH] iptables-test: Make netns spawning more robust + +On systems without unshare Python module, try to call unshare binary +with oneself as parameters. + +Signed-off-by: Phil Sutter +(cherry picked from commit 7ae14dc1a938fc158aaa1761b4fba57c5f1ab7a0) +--- + iptables-test.py | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/iptables-test.py b/iptables-test.py +index 6b6eb611a7290..ffe5b1f7da972 100755 +--- a/iptables-test.py ++++ b/iptables-test.py +@@ -304,6 +304,31 @@ log_file = None + + print('\n'.join(missing)) + ++def spawn_netns(): ++ # prefer unshare module ++ try: ++ import unshare ++ unshare.unshare(unshare.CLONE_NEWNET) ++ return True ++ except: ++ pass ++ ++ # sledgehammer style: ++ # - call ourselves prefixed by 'unshare -n' if found ++ # - pass extra --no-netns parameter to avoid another recursion ++ try: ++ import shutil ++ ++ unshare = shutil.which("unshare") ++ if unshare is None: ++ return False ++ ++ sys.argv.append("--no-netns") ++ os.execv(unshare, [unshare, "-n", sys.executable] + sys.argv) ++ except: ++ pass ++ ++ return False + + # + # main +@@ -323,6 +348,8 @@ log_file = None + help='Test iptables-over-nftables') + parser.add_argument('-N', '--netns', action='store_true', + help='Test netnamespace path') ++ parser.add_argument('--no-netns', action='store_true', ++ help='Do not run testsuite in own network namespace') + args = parser.parse_args() + + # +@@ -341,6 +368,9 @@ log_file = None + print("You need to be root to run this, sorry") + return + ++ if not args.netns and not args.no_netns and not spawn_netns(): ++ print("Cannot run in own namespace, connectivity might break") ++ + if not args.host: + os.putenv("XTABLES_LIBDIR", os.path.abspath(EXTENSIONS_PATH)) + os.putenv("PATH", "%s/iptables:%s" % (os.path.abspath(os.path.curdir), +-- +2.40.0 + diff --git a/SOURCES/0131-tests-iptables-test-Print-errors-to-stderr.patch b/SOURCES/0131-tests-iptables-test-Print-errors-to-stderr.patch new file mode 100644 index 0000000..4665596 --- /dev/null +++ b/SOURCES/0131-tests-iptables-test-Print-errors-to-stderr.patch @@ -0,0 +1,54 @@ +From 814f6498d2487e57840ec93e5a206e39731044d8 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 12 Aug 2021 19:14:13 +0200 +Subject: [PATCH] tests: iptables-test: Print errors to stderr + +No big deal, just pass the extra parameter to the four error print +calls. + +Signed-off-by: Phil Sutter +(cherry picked from commit a8da71864d467c4371dc24cd763fa2c1dfb6cfbb) +--- + iptables-test.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/iptables-test.py b/iptables-test.py +index ffe5b1f7da972..06b9937bbf0e5 100755 +--- a/iptables-test.py ++++ b/iptables-test.py +@@ -47,7 +47,7 @@ log_file = None + Prints an error with nice colors, indicating file and line number. + ''' + print(filename + ": " + Colors.RED + "ERROR" + +- Colors.ENDC + ": line %d (%s)" % (lineno, reason)) ++ Colors.ENDC + ": line %d (%s)" % (lineno, reason), file=sys.stderr) + + + def delete_rule(iptables, rule, filename, lineno): +@@ -365,11 +365,12 @@ log_file = None + EXECUTEABLE = "xtables-nft-multi" + + if os.getuid() != 0: +- print("You need to be root to run this, sorry") ++ print("You need to be root to run this, sorry", file=sys.stderr) + return + + if not args.netns and not args.no_netns and not spawn_netns(): +- print("Cannot run in own namespace, connectivity might break") ++ print("Cannot run in own namespace, connectivity might break", ++ file=sys.stderr) + + if not args.host: + os.putenv("XTABLES_LIBDIR", os.path.abspath(EXTENSIONS_PATH)) +@@ -385,7 +386,7 @@ log_file = None + try: + log_file = open(LOGFILE, 'w') + except IOError: +- print("Couldn't open log file %s" % LOGFILE) ++ print("Couldn't open log file %s" % LOGFILE, file=sys.stderr) + return + + if args.filename: +-- +2.40.0 + diff --git a/SOURCES/0132-tests-xlate-test-Exit-non-zero-on-error.patch b/SOURCES/0132-tests-xlate-test-Exit-non-zero-on-error.patch new file mode 100644 index 0000000..01ece03 --- /dev/null +++ b/SOURCES/0132-tests-xlate-test-Exit-non-zero-on-error.patch @@ -0,0 +1,91 @@ +From d5b7963f7ae493ba797bb23188f3db5ed27b7a74 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 6 Sep 2021 13:07:43 +0200 +Subject: [PATCH] tests: xlate-test: Exit non-zero on error + +If a test fails, return a non-zero exit code. To do so, propagate the +pass/fail statistics up to main() for evaluation. While being at it, +move the statistics printing into there as well and get rid of that +redundant assignment to 'test_passed'. + +Signed-off-by: Phil Sutter +(cherry picked from commit c057939d80cc6219a137784c195e14ee1bc62a58) +--- + xlate-test.py | 26 ++++++++++++++++---------- + 1 file changed, 16 insertions(+), 10 deletions(-) + +diff --git a/xlate-test.py b/xlate-test.py +index 50e9893e956aa..7299dc747295f 100755 +--- a/xlate-test.py ++++ b/xlate-test.py +@@ -54,7 +54,6 @@ xtables_nft_multi = 'xtables-nft-multi' + result.append(magenta("src: ") + line.rstrip(" \n")) + result.append(magenta("exp: ") + expected) + result.append(magenta("res: ") + translation + "\n") +- test_passed = False + else: + passed += 1 + else: +@@ -66,10 +65,7 @@ xtables_nft_multi = 'xtables-nft-multi' + print(name + ": " + green("OK")) + if not test_passed: + print("\n".join(result), file=sys.stderr) +- if args.test: +- print("1 test file, %d tests, %d tests passed, %d tests failed, %d errors" % (tests, passed, failed, errors)) +- else: +- return tests, passed, failed, errors ++ return tests, passed, failed, errors + + + def load_test_files(): +@@ -83,10 +79,9 @@ xtables_nft_multi = 'xtables-nft-multi' + total_passed += passed + total_failed += failed + total_error += errors ++ return (test_files, total_tests, total_passed, total_failed, total_error) + + +- print("%d test files, %d tests, %d tests passed, %d tests failed, %d errors" % (test_files, total_tests, total_passed, total_failed, total_error)) +- + def main(): + global xtables_nft_multi + if not args.host: +@@ -94,16 +89,27 @@ xtables_nft_multi = 'xtables-nft-multi' + xtables_nft_multi = os.path.abspath(os.path.curdir) \ + + '/iptables/' + xtables_nft_multi + ++ files = tests = passed = failed = errors = 0 + if args.test: + if not args.test.endswith(".txlate"): + args.test += ".txlate" + try: + with open(args.test, "r") as payload: +- run_test(args.test, payload) ++ files = 1 ++ tests, passed, failed, errors = run_test(args.test, payload) + except IOError: + print(red("Error: ") + "test file does not exist", file=sys.stderr) ++ return -1 ++ else: ++ files, tests, passed, failed, errors = load_test_files() ++ ++ if files > 1: ++ file_word = "files" + else: +- load_test_files() ++ file_word = "file" ++ print("%d test %s, %d tests, %d tests passed, %d tests failed, %d errors" ++ % (files, file_word, tests, passed, failed, errors)) ++ return passed - tests + + + parser = argparse.ArgumentParser() +@@ -111,4 +117,4 @@ parser.add_argument('-H', '--host', action='store_true', + help='Run tests against installed binaries') + parser.add_argument("test", nargs="?", help="run only the specified test file") + args = parser.parse_args() +-main() ++sys.exit(main()) +-- +2.40.0 + diff --git a/SOURCES/0133-tests-iptables-test-Exit-non-zero-on-error.patch b/SOURCES/0133-tests-iptables-test-Exit-non-zero-on-error.patch new file mode 100644 index 0000000..bd679c9 --- /dev/null +++ b/SOURCES/0133-tests-iptables-test-Exit-non-zero-on-error.patch @@ -0,0 +1,30 @@ +From ccbf512feab4e8fc4bb4e2c0ee7747f2624edc3e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 6 Sep 2021 13:49:34 +0200 +Subject: [PATCH] tests: iptables-test: Exit non-zero on error + +If any test fails, return a non-zero exit code. + +Signed-off-by: Phil Sutter +(cherry picked from commit 7559af835d8f58375f797f895e1a5410027127d9) +--- + iptables-test.py | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/iptables-test.py b/iptables-test.py +index 06b9937bbf0e5..0d21f975305db 100755 +--- a/iptables-test.py ++++ b/iptables-test.py +@@ -405,7 +405,8 @@ log_file = None + test_files += 1 + + print("%d test files, %d unit tests, %d passed" % (test_files, tests, passed)) ++ return passed - tests + + + if __name__ == '__main__': +- main() ++ sys.exit(main()) +-- +2.40.0 + diff --git a/SOURCES/0134-tests-shell-Return-non-zero-on-error.patch b/SOURCES/0134-tests-shell-Return-non-zero-on-error.patch new file mode 100644 index 0000000..6460a07 --- /dev/null +++ b/SOURCES/0134-tests-shell-Return-non-zero-on-error.patch @@ -0,0 +1,26 @@ +From b8b02934ad125df53b34af7840be34d5500e1114 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 6 Sep 2021 17:28:30 +0200 +Subject: [PATCH] tests: shell: Return non-zero on error + +If any test fails, return a non-zero exit code. + +Signed-off-by: Phil Sutter +(cherry picked from commit 481626bb4e9c51477ec99dde0727e3af69d2380f) +--- + iptables/tests/shell/run-tests.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/tests/shell/run-tests.sh b/iptables/tests/shell/run-tests.sh +index 2125e2cb119bb..fbb17bedc5478 100755 +--- a/iptables/tests/shell/run-tests.sh ++++ b/iptables/tests/shell/run-tests.sh +@@ -176,4 +176,4 @@ failed=$((legacy_fail+failed)) + + msg_info "combined results: [OK] $ok [FAILED] $failed [TOTAL] $((ok+failed))" + +-exit 0 ++exit -$failed +-- +2.40.0 + diff --git a/SOURCES/0135-iptables-test.py-print-with-color-escapes-only-when-.patch b/SOURCES/0135-iptables-test.py-print-with-color-escapes-only-when-.patch new file mode 100644 index 0000000..0c333ba --- /dev/null +++ b/SOURCES/0135-iptables-test.py-print-with-color-escapes-only-when-.patch @@ -0,0 +1,70 @@ +From aace6f5ac84d738f6b5f0ed1d56b3713b0435cc4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20N=C4=9Bmec?= +Date: Thu, 2 Sep 2021 13:33:07 +0200 +Subject: [PATCH] iptables-test.py: print with color escapes only when stdout + isatty +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When the output doesn't go to a terminal (typical case: log files), +the escape sequences are just noise. + +Signed-off-by: Štěpán Němec +Signed-off-by: Phil Sutter +(cherry picked from commit b714d45dc4c2423d4df4cbf7ccf238ec441675ef) +--- + iptables-test.py | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/iptables-test.py b/iptables-test.py +index 0d21f975305db..fb9503b6fffb4 100755 +--- a/iptables-test.py ++++ b/iptables-test.py +@@ -32,22 +32,25 @@ EXTENSIONS_PATH = "extensions" + LOGFILE="/tmp/iptables-test.log" + log_file = None + ++STDOUT_IS_TTY = sys.stdout.isatty() + +-class Colors: +- HEADER = '\033[95m' +- BLUE = '\033[94m' +- GREEN = '\033[92m' +- YELLOW = '\033[93m' +- RED = '\033[91m' +- ENDC = '\033[0m' ++def maybe_colored(color, text): ++ terminal_sequences = { ++ 'green': '\033[92m', ++ 'red': '\033[91m', ++ } ++ ++ return ( ++ terminal_sequences[color] + text + '\033[0m' if STDOUT_IS_TTY else text ++ ) + + + def print_error(reason, filename=None, lineno=None): + ''' + Prints an error with nice colors, indicating file and line number. + ''' +- print(filename + ": " + Colors.RED + "ERROR" + +- Colors.ENDC + ": line %d (%s)" % (lineno, reason), file=sys.stderr) ++ print(filename + ": " + maybe_colored('red', "ERROR") + ++ ": line %d (%s)" % (lineno, reason), file=sys.stderr) + + + def delete_rule(iptables, rule, filename, lineno): +@@ -282,7 +285,7 @@ log_file = None + if netns: + execute_cmd("ip netns del ____iptables-container-test", filename, 0) + if total_test_passed: +- print(filename + ": " + Colors.GREEN + "OK" + Colors.ENDC) ++ print(filename + ": " + maybe_colored('green', "OK")) + + f.close() + return tests, passed +-- +2.40.0 + diff --git a/SOURCES/0136-tests-iptables-test-Fix-conditional-colors-on-stderr.patch b/SOURCES/0136-tests-iptables-test-Fix-conditional-colors-on-stderr.patch new file mode 100644 index 0000000..0e08ade --- /dev/null +++ b/SOURCES/0136-tests-iptables-test-Fix-conditional-colors-on-stderr.patch @@ -0,0 +1,64 @@ +From 50470c652e32b3bc2025d45e4d39b47c0aba8e23 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 15 Sep 2021 17:47:15 +0200 +Subject: [PATCH] tests: iptables-test: Fix conditional colors on stderr +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Štěpán's patch to make colored output depend on whether output is a TTY +clashed with my change to print errors to stderr instead of stdout. + +Fix this by telling maybe_colored() if it should print colors or not as +only caller knows where output is sent to. + +Signed-off-by: Phil Sutter +(cherry picked from commit 2ed6dc7557b8c4a70bfd81684a72737312d7bd4b) +--- + iptables-test.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/iptables-test.py b/iptables-test.py +index fb9503b6fffb4..d54ed428ddefb 100755 +--- a/iptables-test.py ++++ b/iptables-test.py +@@ -33,15 +33,16 @@ LOGFILE="/tmp/iptables-test.log" + log_file = None + + STDOUT_IS_TTY = sys.stdout.isatty() ++STDERR_IS_TTY = sys.stderr.isatty() + +-def maybe_colored(color, text): ++def maybe_colored(color, text, isatty): + terminal_sequences = { + 'green': '\033[92m', + 'red': '\033[91m', + } + + return ( +- terminal_sequences[color] + text + '\033[0m' if STDOUT_IS_TTY else text ++ terminal_sequences[color] + text + '\033[0m' if isatty else text + ) + + +@@ -49,7 +50,7 @@ STDOUT_IS_TTY = sys.stdout.isatty() + ''' + Prints an error with nice colors, indicating file and line number. + ''' +- print(filename + ": " + maybe_colored('red', "ERROR") + ++ print(filename + ": " + maybe_colored('red', "ERROR", STDERR_IS_TTY) + + ": line %d (%s)" % (lineno, reason), file=sys.stderr) + + +@@ -285,7 +286,7 @@ STDOUT_IS_TTY = sys.stdout.isatty() + if netns: + execute_cmd("ip netns del ____iptables-container-test", filename, 0) + if total_test_passed: +- print(filename + ": " + maybe_colored('green', "OK")) ++ print(filename + ": " + maybe_colored('green', "OK", STDOUT_IS_TTY)) + + f.close() + return tests, passed +-- +2.40.0 + diff --git a/SOURCES/0137-tests-shell-update-format-of-registers-in-bitwise-pa.patch b/SOURCES/0137-tests-shell-update-format-of-registers-in-bitwise-pa.patch new file mode 100644 index 0000000..aec50b1 --- /dev/null +++ b/SOURCES/0137-tests-shell-update-format-of-registers-in-bitwise-pa.patch @@ -0,0 +1,67 @@ +From 71f3a4741df9db345679f32f5829ce3c4b83031d Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Mon, 16 Nov 2020 10:37:41 +0100 +Subject: [PATCH] tests: shell: update format of registers in bitwise payloads. + +libnftnl has been changed to bring the format of registers in bitwise +dumps in line with those in other types of expression. Update the +expected output of Python test-cases. + +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit 83ee6e179829461572be6583ce6e83f68e636eb6) +--- + .../shell/testcases/nft-only/0009-needless-bitwise_0 | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +index c5c6e706a1029..41d765e537312 100755 +--- a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 ++++ b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +@@ -64,7 +64,7 @@ ip filter OUTPUT 5 4 + + ip filter OUTPUT 6 5 + [ payload load 4b @ network header + 16 => reg 1 ] +- [ bitwise reg 1 = (reg=1 & 0xfcffffff ) ^ 0x00000000 ] ++ [ bitwise reg 1 = ( reg 1 & 0xfcffffff ) ^ 0x00000000 ] + [ cmp eq reg 1 0x0002010a ] + [ counter pkts 0 bytes 0 ] + +@@ -98,7 +98,7 @@ ip6 filter OUTPUT 5 4 + + ip6 filter OUTPUT 6 5 + [ payload load 16b @ network header + 24 => reg 1 ] +- [ bitwise reg 1 = (reg=1 & 0xffffffff 0xffffffff 0xffffffff 0xf0ffffff ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ] ++ [ bitwise reg 1 = ( reg 1 & 0xffffffff 0xffffffff 0xffffffff 0xf0ffffff ) ^ 0x00000000 0x00000000 0x00000000 0x00000000 ] + [ cmp eq reg 1 0xffc0edfe 0x020100ee 0x06050403 0x00090807 ] + [ counter pkts 0 bytes 0 ] + +@@ -175,7 +175,7 @@ arp filter OUTPUT 5 4 + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 4b @ network header + 24 => reg 1 ] +- [ bitwise reg 1 = (reg=1 & 0xfcffffff ) ^ 0x00000000 ] ++ [ bitwise reg 1 = ( reg 1 & 0xfcffffff ) ^ 0x00000000 ] + [ cmp eq reg 1 0x0002010a ] + [ counter pkts 0 bytes 0 ] + +@@ -240,7 +240,7 @@ arp filter OUTPUT 11 10 + [ payload load 1b @ network header + 5 => reg 1 ] + [ cmp eq reg 1 0x00000004 ] + [ payload load 6b @ network header + 18 => reg 1 ] +- [ bitwise reg 1 = (reg=1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] ++ [ bitwise reg 1 = ( reg 1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] + [ cmp eq reg 1 0xc000edfe 0x0000e0ff ] + [ counter pkts 0 bytes 0 ] + +@@ -306,7 +306,7 @@ bridge filter OUTPUT 4 + + bridge filter OUTPUT 5 4 + [ payload load 6b @ link header + 0 => reg 1 ] +- [ bitwise reg 1 = (reg=1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] ++ [ bitwise reg 1 = ( reg 1 & 0xffffffff 0x0000f0ff ) ^ 0x00000000 0x00000000 ] + [ cmp eq reg 1 0xc000edfe 0x0000e0ff ] + [ counter pkts 0 bytes 0 ] + +-- +2.40.0 + diff --git a/SOURCES/0138-tests-shell-Fix-nft-only-0009-needless-bitwise_0.patch b/SOURCES/0138-tests-shell-Fix-nft-only-0009-needless-bitwise_0.patch new file mode 100644 index 0000000..ca0423d --- /dev/null +++ b/SOURCES/0138-tests-shell-Fix-nft-only-0009-needless-bitwise_0.patch @@ -0,0 +1,36 @@ +From f31607eafcbf8b4aca4f51bbd6dac33817a1498d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 15 Jan 2021 21:58:48 +0100 +Subject: [PATCH] tests/shell: Fix nft-only/0009-needless-bitwise_0 + +For whatever reason, stored expected output contains false handles. To +overcome this, filter the rule data lines from both expected and stored +output before comparing. + +Fixes: 81a2e12851283 ("tests/shell: Add test for bitwise avoidance fixes") +Signed-off-by: Phil Sutter +(cherry picked from commit 0f7ea0390b33654c9a91015966f518b98356e786) +--- + .../shell/testcases/nft-only/0009-needless-bitwise_0 | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +index 41d765e537312..41588a10863ec 100755 +--- a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 ++++ b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +@@ -336,4 +336,11 @@ bridge filter OUTPUT 10 9 + [ counter pkts 0 bytes 0 ] + " + +-diff -u -Z <(echo "$EXPECT") <(nft --debug=netlink list ruleset | awk '/^table/{exit} {print}') ++# print nothing but: ++# - lines with bytecode (starting with ' [') ++# - empty lines (so printed diff is not a complete mess) ++filter() { ++ awk '/^( \[|$)/{print}' ++} ++ ++diff -u -Z <(filter <<< "$EXPECT") <(nft --debug=netlink list ruleset | filter) +-- +2.40.0 + diff --git a/SOURCES/0139-tests-shell-Sanitize-nft-only-0009-needless-bitwise_.patch b/SOURCES/0139-tests-shell-Sanitize-nft-only-0009-needless-bitwise_.patch new file mode 100644 index 0000000..0b6ac32 --- /dev/null +++ b/SOURCES/0139-tests-shell-Sanitize-nft-only-0009-needless-bitwise_.patch @@ -0,0 +1,34 @@ +From e34d23b5a95801b93550a451b0da0b28221acfd5 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 19 Jul 2023 14:58:11 +0200 +Subject: [PATCH] tests: shell: Sanitize nft-only/0009-needless-bitwise_0 + +Some versions of awk (gawk-4.2.1-4.el8 in particular) also print the +non-debug ruleset listing's empty lines, causing the diff to fail. Catch +this by exiting upon seeing the first table heading. For the sake of +comparing bytecode, the actual ruleset listing is not interesting, +anyway. + +Fixes: 0f7ea0390b336 ("tests/shell: Fix nft-only/0009-needless-bitwise_0") +Signed-off-by: Phil Sutter +(cherry picked from commit 2746726e03d9017d4c940a247590f8d5c5d5a73e) +--- + iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +index 41588a10863ec..34802cc26aad4 100755 +--- a/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 ++++ b/iptables/tests/shell/testcases/nft-only/0009-needless-bitwise_0 +@@ -340,7 +340,7 @@ bridge filter OUTPUT 10 9 + # - lines with bytecode (starting with ' [') + # - empty lines (so printed diff is not a complete mess) + filter() { +- awk '/^( \[|$)/{print}' ++ awk '/^table /{exit} /^( \[|$)/{print}' + } + + diff -u -Z <(filter <<< "$EXPECT") <(nft --debug=netlink list ruleset | filter) +-- +2.40.0 + diff --git a/SOURCES/0140-iptables-Fix-setting-of-ipv6-counters.patch b/SOURCES/0140-iptables-Fix-setting-of-ipv6-counters.patch new file mode 100644 index 0000000..52e16f9 --- /dev/null +++ b/SOURCES/0140-iptables-Fix-setting-of-ipv6-counters.patch @@ -0,0 +1,107 @@ +From 87cf690d64630c1c32986480036c594795224ee7 Mon Sep 17 00:00:00 2001 +From: Jacek Tomasiak +Date: Mon, 19 Jun 2023 12:44:54 +0200 +Subject: [PATCH] iptables: Fix setting of ipv6 counters + +When setting counters using ip6tables-nft -c X Y the X and Y values were +not stored. + +This is a fix based on 9baf3bf0e77dab6ca4b167554ec0e57b65d0af01 but +applied to the nft variant of ipv6 not the legacy. + +Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1647 +Fixes: 0391677c1a0b2 ("xtables: add IPv6 support") +Signed-off-by: Jacek Tomasiak +Signed-off-by: Jacek Tomasiak +Signed-off-by: Phil Sutter +(cherry picked from commit ed839159edf8bda8e9196f1056c4038c22d78bfd) + +Conflicts: + iptables/xshared.c +-> Applied to iptables/nft-ipv6.c due to missing commit e4f5185d8f29a + ("nft: Move proto_parse and post_parse callbacks to xshared") +--- + iptables/nft-ipv6.c | 3 +++ + iptables/tests/shell/testcases/ip6tables/0003-list-rules_0 | 6 +++--- + iptables/tests/shell/testcases/iptables/0003-list-rules_0 | 6 +++--- + 3 files changed, 9 insertions(+), 6 deletions(-) + +diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c +index 1f73bbcb8771f..69d9bc41314fc 100644 +--- a/iptables/nft-ipv6.c ++++ b/iptables/nft-ipv6.c +@@ -298,6 +298,9 @@ static void nft_ipv6_post_parse(int command, struct iptables_command_state *cs, + if (args->goto_set) + cs->fw6.ipv6.flags |= IP6T_F_GOTO; + ++ /* nft-variants use cs->counters, legacy uses cs->fw6.counters */ ++ cs->counters.pcnt = args->pcnt_cnt; ++ cs->counters.bcnt = args->bcnt_cnt; + cs->fw6.counters.pcnt = args->pcnt_cnt; + cs->fw6.counters.bcnt = args->bcnt_cnt; + +diff --git a/iptables/tests/shell/testcases/ip6tables/0003-list-rules_0 b/iptables/tests/shell/testcases/ip6tables/0003-list-rules_0 +index c98bdd6e501aa..09e39927ef390 100755 +--- a/iptables/tests/shell/testcases/ip6tables/0003-list-rules_0 ++++ b/iptables/tests/shell/testcases/ip6tables/0003-list-rules_0 +@@ -3,7 +3,7 @@ + set -e + + $XT_MULTI ip6tables -N foo +-$XT_MULTI ip6tables -A FORWARD -i eth23 -o eth42 -j ACCEPT ++$XT_MULTI ip6tables -A FORWARD -i eth23 -o eth42 -j ACCEPT -c 23 42 + $XT_MULTI ip6tables -A FORWARD -i eth42 -o eth23 -g foo + $XT_MULTI ip6tables -t nat -A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT + +@@ -20,7 +20,7 @@ EXPECT='-P INPUT ACCEPT -c 0 0 + -P FORWARD ACCEPT -c 0 0 + -P OUTPUT ACCEPT -c 0 0 + -N foo +--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT ++-A FORWARD -i eth23 -o eth42 -c 23 42 -j ACCEPT + -A FORWARD -i eth42 -o eth23 -c 0 0 -g foo' + + diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -S) +@@ -32,7 +32,7 @@ EXPECT='-P FORWARD ACCEPT + diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -S FORWARD) + + EXPECT='-P FORWARD ACCEPT -c 0 0 +--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT ++-A FORWARD -i eth23 -o eth42 -c 23 42 -j ACCEPT + -A FORWARD -i eth42 -o eth23 -c 0 0 -g foo' + + diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI ip6tables -v -S FORWARD) +diff --git a/iptables/tests/shell/testcases/iptables/0003-list-rules_0 b/iptables/tests/shell/testcases/iptables/0003-list-rules_0 +index d335d44257a49..d07bd151be76b 100755 +--- a/iptables/tests/shell/testcases/iptables/0003-list-rules_0 ++++ b/iptables/tests/shell/testcases/iptables/0003-list-rules_0 +@@ -3,7 +3,7 @@ + set -e + + $XT_MULTI iptables -N foo +-$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j ACCEPT ++$XT_MULTI iptables -A FORWARD -i eth23 -o eth42 -j ACCEPT -c 23 42 + $XT_MULTI iptables -A FORWARD -i eth42 -o eth23 -g foo + $XT_MULTI iptables -t nat -A OUTPUT -o eth123 -m mark --mark 0x42 -j ACCEPT + +@@ -20,7 +20,7 @@ EXPECT='-P INPUT ACCEPT -c 0 0 + -P FORWARD ACCEPT -c 0 0 + -P OUTPUT ACCEPT -c 0 0 + -N foo +--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT ++-A FORWARD -i eth23 -o eth42 -c 23 42 -j ACCEPT + -A FORWARD -i eth42 -o eth23 -c 0 0 -g foo' + + diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S) +@@ -32,7 +32,7 @@ EXPECT='-P FORWARD ACCEPT + diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -S FORWARD) + + EXPECT='-P FORWARD ACCEPT -c 0 0 +--A FORWARD -i eth23 -o eth42 -c 0 0 -j ACCEPT ++-A FORWARD -i eth23 -o eth42 -c 23 42 -j ACCEPT + -A FORWARD -i eth42 -o eth23 -c 0 0 -g foo' + + diff -u -Z <(echo -e "$EXPECT") <($XT_MULTI iptables -v -S FORWARD) +-- +2.40.0 + diff --git a/SOURCES/0141-iptables-Fix-handling-of-non-existent-chains.patch b/SOURCES/0141-iptables-Fix-handling-of-non-existent-chains.patch new file mode 100644 index 0000000..ff1840c --- /dev/null +++ b/SOURCES/0141-iptables-Fix-handling-of-non-existent-chains.patch @@ -0,0 +1,53 @@ +From 66f7b6b160c53d142ebf5a0b4464ead198f2d7a7 Mon Sep 17 00:00:00 2001 +From: Jacek Tomasiak +Date: Mon, 19 Jun 2023 13:46:36 +0200 +Subject: [PATCH] iptables: Fix handling of non-existent chains + +Since 694612adf87 the "compatibility" check considers non-existent +chains as "incompatible". This broke some scripts which used calls +like `iptables -L CHAIN404` to test for chain existence and expect +"No chain/target/match by that name." in the output. + +This patch changes the logic of `nft_is_table_compatible()` to +report non-existent chains as "compatible" which restores the old +behavior. + +Fixes: 694612adf87 ("nft: Fix selective chain compatibility checks") +Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1648 +Signed-off-by: Jacek Tomasiak +Signed-off-by: Jacek Tomasiak +Signed-off-by: Phil Sutter +(cherry picked from commit 82ccfb488eeac5507471099b9b4e6d136cc06e3b) +--- + iptables/nft.c | 2 +- + iptables/tests/shell/testcases/iptables/0004-return-codes_0 | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 9a56b1fbffcbc..7349904896228 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -3594,7 +3594,7 @@ bool nft_is_table_compatible(struct nft_handle *h, + if (chain) { + struct nftnl_chain *c = nft_chain_find(h, table, chain); + +- return c && !nft_is_chain_compatible(c, h); ++ return !c || !nft_is_chain_compatible(c, h); + } + + clist = nft_chain_list_get(h, table, chain); +diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 +index dcd9dfd3c0806..10e8c1f284080 100755 +--- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 ++++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 +@@ -58,6 +58,7 @@ cmd 1 "$ENOENT" -Z bar + cmd 0 -E foo bar + cmd 1 "$EEXIST_F" -E foo bar + cmd 1 "$ENOENT" -E foo bar2 ++cmd 1 "$ENOENT" -L foo + cmd 0 -N foo2 + cmd 1 "$EEXIST_F" -E foo2 bar + +-- +2.40.0 + diff --git a/SOURCES/0142-nft-bridge-pass-context-structure-to-ops-add-to-impr.patch b/SOURCES/0142-nft-bridge-pass-context-structure-to-ops-add-to-impr.patch new file mode 100644 index 0000000..0118964 --- /dev/null +++ b/SOURCES/0142-nft-bridge-pass-context-structure-to-ops-add-to-impr.patch @@ -0,0 +1,339 @@ +From 83ad886f653aa21e8c12903272ce8e7a863f56b3 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Tue, 11 Jul 2023 22:06:44 +0200 +Subject: [PATCH] nft-bridge: pass context structure to ops->add() to improve + anonymous set support + +Add context structure to improve bridge among support which creates an +anonymous set. This context structure specifies the command and it +allows to optionally store a anonymous set. + +Use this context to generate native bytecode only if this is an +add/insert/replace command. + +This fixes a dangling anonymous set that is created on rule removal. + +Fixes: 26753888720d ("nft: bridge: Rudimental among extension support") +Reported-and-tested-by: Igor Raits +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit 4e95200ded923f0eb5579c33b91176193c59dbe0) + +Conflicts: + iptables/nft-arp.c + iptables/nft-bridge.c + iptables/nft-ipv4.c + iptables/nft-ipv6.c + iptables/nft-shared.h + iptables/nft.c + iptables/nft.h +-> Manually applied, too many conflicts. +--- + iptables/nft-arp.c | 3 ++- + iptables/nft-bridge.c | 9 +++++---- + iptables/nft-cmd.c | 6 +++++- + iptables/nft-ipv4.c | 5 +++-- + iptables/nft-ipv6.c | 5 +++-- + iptables/nft-shared.h | 4 +++- + iptables/nft.c | 42 +++++++++++++++++++++++++++++------------- + iptables/nft.h | 9 ++++++--- + 8 files changed, 56 insertions(+), 27 deletions(-) + +diff --git a/iptables/nft-arp.c b/iptables/nft-arp.c +index fa1676e7fd878..2b6bda617e32c 100644 +--- a/iptables/nft-arp.c ++++ b/iptables/nft-arp.c +@@ -54,7 +54,8 @@ static bool need_devaddr(struct arpt_devaddr_info *info) + return false; + } + +-static int nft_arp_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ++static int nft_arp_add(struct nft_handle *h, struct nft_rule_ctx *ctx, ++ struct nftnl_rule *r, void *data) + { + struct iptables_command_state *cs = data; + struct arpt_entry *fw = &cs->arp; +diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c +index 48bcda61cfb9c..11422a187097c 100644 +--- a/iptables/nft-bridge.c ++++ b/iptables/nft-bridge.c +@@ -131,17 +131,18 @@ static int _add_action(struct nftnl_rule *r, struct iptables_command_state *cs) + + static int + nft_bridge_add_match(struct nft_handle *h, const struct ebt_entry *fw, +- struct nftnl_rule *r, struct xt_entry_match *m) ++ struct nft_rule_ctx *ctx, struct nftnl_rule *r, ++ struct xt_entry_match *m) + { + if (!strcmp(m->u.user.name, "802_3") && + !(fw->bitmask & EBT_802_3)) + xtables_error(PARAMETER_PROBLEM, + "For 802.3 DSAP/SSAP filtering the protocol must be LENGTH"); + +- return add_match(h, r, m); ++ return add_match(h, ctx, r, m); + } + +-static int nft_bridge_add(struct nft_handle *h, ++static int nft_bridge_add(struct nft_handle *h, struct nft_rule_ctx *ctx, + struct nftnl_rule *r, void *data) + { + struct iptables_command_state *cs = data; +@@ -202,7 +203,7 @@ static int nft_bridge_add(struct nft_handle *h, + + for (iter = cs->match_list; iter; iter = iter->next) { + if (iter->ismatch) { +- if (nft_bridge_add_match(h, fw, r, iter->u.match->m)) ++ if (nft_bridge_add_match(h, fw, ctx, r, iter->u.match->m)) + break; + } else { + if (add_target(r, iter->u.watcher->t)) +diff --git a/iptables/nft-cmd.c b/iptables/nft-cmd.c +index fd038503d87e1..9d1c082ef62d0 100644 +--- a/iptables/nft-cmd.c ++++ b/iptables/nft-cmd.c +@@ -13,12 +13,16 @@ + #include + #include "nft.h" + #include "nft-cmd.h" ++#include + + struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command, + const char *table, const char *chain, + struct iptables_command_state *state, + int rulenum, bool verbose) + { ++ struct nft_rule_ctx ctx = { ++ .command = command, ++ }; + struct nftnl_rule *rule; + struct nft_cmd *cmd; + +@@ -34,7 +38,7 @@ struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command, + cmd->verbose = verbose; + + if (state) { +- rule = nft_rule_new(h, chain, table, state); ++ rule = nft_rule_new(h, &ctx, chain, table, state); + if (!rule) { + nft_cmd_free(cmd); + return NULL; +diff --git a/iptables/nft-ipv4.c b/iptables/nft-ipv4.c +index a70e9ece248fe..e06d086bbf82a 100644 +--- a/iptables/nft-ipv4.c ++++ b/iptables/nft-ipv4.c +@@ -26,7 +26,8 @@ + #include "nft.h" + #include "nft-shared.h" + +-static int nft_ipv4_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ++static int nft_ipv4_add(struct nft_handle *h, struct nft_rule_ctx *ctx, ++ struct nftnl_rule *r, void *data) + { + struct iptables_command_state *cs = data; + struct xtables_rule_match *matchp; +@@ -79,7 +80,7 @@ static int nft_ipv4_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + add_compat(r, cs->fw.ip.proto, cs->fw.ip.invflags & XT_INV_PROTO); + + for (matchp = cs->matches; matchp; matchp = matchp->next) { +- ret = add_match(h, r, matchp->match->m); ++ ret = add_match(h, ctx, r, matchp->match->m); + if (ret < 0) + return ret; + } +diff --git a/iptables/nft-ipv6.c b/iptables/nft-ipv6.c +index 69d9bc41314fc..7c8e8b82cf521 100644 +--- a/iptables/nft-ipv6.c ++++ b/iptables/nft-ipv6.c +@@ -25,7 +25,8 @@ + #include "nft.h" + #include "nft-shared.h" + +-static int nft_ipv6_add(struct nft_handle *h, struct nftnl_rule *r, void *data) ++static int nft_ipv6_add(struct nft_handle *h, struct nft_rule_ctx *ctx, ++ struct nftnl_rule *r, void *data) + { + struct iptables_command_state *cs = data; + struct xtables_rule_match *matchp; +@@ -68,7 +69,7 @@ static int nft_ipv6_add(struct nft_handle *h, struct nftnl_rule *r, void *data) + add_compat(r, cs->fw6.ipv6.proto, cs->fw6.ipv6.invflags & XT_INV_PROTO); + + for (matchp = cs->matches; matchp; matchp = matchp->next) { +- ret = add_match(h, r, matchp->match->m); ++ ret = add_match(h, ctx, r, matchp->match->m); + if (ret < 0) + return ret; + } +diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h +index e3c1b202b8638..c29ad12e9151a 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -35,6 +35,7 @@ + | FMT_NUMERIC | FMT_NOTABLE) + #define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab)) + ++struct nft_rule_ctx; + struct xtables_args; + struct nft_handle; + struct xt_xlate; +@@ -74,7 +75,8 @@ struct nft_xt_ctx { + }; + + struct nft_family_ops { +- int (*add)(struct nft_handle *h, struct nftnl_rule *r, void *data); ++ int (*add)(struct nft_handle *h, struct nft_rule_ctx *ctx, ++ struct nftnl_rule *r, void *data); + bool (*is_same)(const void *data_a, + const void *data_b); + void (*print_payload)(struct nftnl_expr *e, +diff --git a/iptables/nft.c b/iptables/nft.c +index 7349904896228..936204a432621 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -1064,7 +1064,8 @@ gen_lookup(uint32_t sreg, const char *set_name, uint32_t set_id, uint32_t flags) + #define NFT_DATATYPE_ETHERADDR 9 + + static int __add_nft_among(struct nft_handle *h, const char *table, +- struct nftnl_rule *r, struct nft_among_pair *pairs, ++ struct nft_rule_ctx *ctx, struct nftnl_rule *r, ++ struct nft_among_pair *pairs, + int cnt, bool dst, bool inv, bool ip) + { + uint32_t set_id, type = NFT_DATATYPE_ETHERADDR, len = ETH_ALEN; +@@ -1142,7 +1143,7 @@ static int __add_nft_among(struct nft_handle *h, const char *table, + return 0; + } + +-static int add_nft_among(struct nft_handle *h, ++static int add_nft_among(struct nft_handle *h, struct nft_rule_ctx *ctx, + struct nftnl_rule *r, struct xt_entry_match *m) + { + struct nft_among_data *data = (struct nft_among_data *)m->data; +@@ -1157,25 +1158,33 @@ static int add_nft_among(struct nft_handle *h, + } + + if (data->src.cnt) +- __add_nft_among(h, table, r, data->pairs, data->src.cnt, ++ __add_nft_among(h, table, ctx, r, data->pairs, data->src.cnt, + false, data->src.inv, data->src.ip); + if (data->dst.cnt) +- __add_nft_among(h, table, r, data->pairs + data->src.cnt, ++ __add_nft_among(h, table, ctx, r, data->pairs + data->src.cnt, + data->dst.cnt, true, data->dst.inv, + data->dst.ip); + return 0; + } + +-int add_match(struct nft_handle *h, ++int add_match(struct nft_handle *h, struct nft_rule_ctx *ctx, + struct nftnl_rule *r, struct xt_entry_match *m) + { + struct nftnl_expr *expr; + int ret; + +- if (!strcmp(m->u.user.name, "limit")) +- return add_nft_limit(r, m); +- else if (!strcmp(m->u.user.name, "among")) +- return add_nft_among(h, r, m); ++ switch (ctx->command) { ++ case NFT_COMPAT_RULE_APPEND: ++ case NFT_COMPAT_RULE_INSERT: ++ case NFT_COMPAT_RULE_REPLACE: ++ if (!strcmp(m->u.user.name, "limit")) ++ return add_nft_limit(r, m); ++ else if (!strcmp(m->u.user.name, "among")) ++ return add_nft_among(h, ctx, r, m); ++ break; ++ default: ++ break; ++ } + + expr = nftnl_expr_alloc("match"); + if (expr == NULL) +@@ -1378,7 +1387,8 @@ void add_compat(struct nftnl_rule *r, uint32_t proto, bool inv) + } + + struct nftnl_rule * +-nft_rule_new(struct nft_handle *h, const char *chain, const char *table, ++nft_rule_new(struct nft_handle *h, struct nft_rule_ctx *ctx, ++ const char *chain, const char *table, + void *data) + { + struct nftnl_rule *r; +@@ -1391,7 +1401,7 @@ nft_rule_new(struct nft_handle *h, const char *chain, const char *table, + nftnl_rule_set_str(r, NFTNL_RULE_TABLE, table); + nftnl_rule_set_str(r, NFTNL_RULE_CHAIN, chain); + +- if (h->ops->add(h, r, data) < 0) ++ if (h->ops->add(h, ctx, r, data) < 0) + goto err; + + return r; +@@ -2599,6 +2609,9 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, + { + struct iptables_command_state cs = {}; + struct nftnl_rule *r, *new_rule; ++ struct nft_rule_ctx ctx = { ++ .command = NFT_COMPAT_RULE_APPEND, ++ }; + struct nftnl_chain *c; + int ret = 0; + +@@ -2617,7 +2630,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, + + h->ops->rule_to_cs(h, r, &cs); + cs.counters.pcnt = cs.counters.bcnt = 0; +- new_rule = nft_rule_new(h, chain, table, &cs); ++ new_rule = nft_rule_new(h, &ctx, chain, table, &cs); + h->ops->clear_cs(&cs); + + if (!new_rule) +@@ -2981,6 +2994,9 @@ static int ebt_add_policy_rule(struct nftnl_chain *c, void *data) + .eb.bitmask = EBT_NOPROTO, + }; + struct nftnl_udata_buf *udata; ++ struct nft_rule_ctx ctx = { ++ .command = NFT_COMPAT_RULE_APPEND, ++ }; + struct nft_handle *h = data; + struct nftnl_rule *r; + const char *pname; +@@ -3008,7 +3024,7 @@ static int ebt_add_policy_rule(struct nftnl_chain *c, void *data) + + command_jump(&cs, pname); + +- r = nft_rule_new(h, nftnl_chain_get_str(c, NFTNL_CHAIN_NAME), ++ r = nft_rule_new(h, &ctx, nftnl_chain_get_str(c, NFTNL_CHAIN_NAME), + nftnl_chain_get_str(c, NFTNL_CHAIN_TABLE), &cs); + ebt_cs_clean(&cs); + +diff --git a/iptables/nft.h b/iptables/nft.h +index bd783231156b7..7baceaa44f698 100644 +--- a/iptables/nft.h ++++ b/iptables/nft.h +@@ -165,9 +165,11 @@ struct nftnl_set *nft_set_batch_lookup_byid(struct nft_handle *h, + /* + * Operations with rule-set. + */ +-struct nftnl_rule; ++struct nft_rule_ctx { ++ int command; ++}; + +-struct nftnl_rule *nft_rule_new(struct nft_handle *h, const char *chain, const char *table, void *data); ++struct nftnl_rule *nft_rule_new(struct nft_handle *h, struct nft_rule_ctx *rule, const char *chain, const char *table, void *data); + int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose); + int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, int rulenum, bool verbose); + int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, bool verbose); +@@ -185,7 +187,8 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain, const char * + */ + int add_counters(struct nftnl_rule *r, uint64_t packets, uint64_t bytes); + int add_verdict(struct nftnl_rule *r, int verdict); +-int add_match(struct nft_handle *h, struct nftnl_rule *r, struct xt_entry_match *m); ++int add_match(struct nft_handle *h, struct nft_rule_ctx *ctx, ++ struct nftnl_rule *r, struct xt_entry_match *m); + int add_target(struct nftnl_rule *r, struct xt_entry_target *t); + int add_jumpto(struct nftnl_rule *r, const char *name, int verdict); + int add_action(struct nftnl_rule *r, struct iptables_command_state *cs, bool goto_set); +-- +2.40.0 + diff --git a/SOURCES/0143-nft-Special-casing-for-among-match-in-compare_matche.patch b/SOURCES/0143-nft-Special-casing-for-among-match-in-compare_matche.patch new file mode 100644 index 0000000..7f5f353 --- /dev/null +++ b/SOURCES/0143-nft-Special-casing-for-among-match-in-compare_matche.patch @@ -0,0 +1,46 @@ +From 1dcbf8ed6849543fcaffb8af0d50e08e27232ce2 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 21 Jul 2023 13:14:36 +0200 +Subject: [PATCH] nft: Special casing for among match in compare_matches() + +When other extensions may have "garbage" appended to their data which +should not be considered for match comparison, among match is the +opposite in that it extends its data beyond the value in 'size' field. +Add special casing to cover for this, avoiding false-positive rule +comparison. + +Fixes: 26753888720d8 ("nft: bridge: Rudimental among extension support") +Signed-off-by: Phil Sutter +(cherry picked from commit 10583537004f7ecd4aa11f6c12b7ba73fb77fc11) +--- + iptables/nft-shared.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c +index ed093c07d7617..0b5745f7e82f4 100644 +--- a/iptables/nft-shared.c ++++ b/iptables/nft-shared.c +@@ -911,6 +911,7 @@ bool compare_matches(struct xtables_rule_match *mt1, + for (mp1 = mt1, mp2 = mt2; mp1 && mp2; mp1 = mp1->next, mp2 = mp2->next) { + struct xt_entry_match *m1 = mp1->match->m; + struct xt_entry_match *m2 = mp2->match->m; ++ size_t cmplen = mp1->match->userspacesize; + + if (strcmp(m1->u.user.name, m2->u.user.name) != 0) { + DEBUGP("mismatching match name\n"); +@@ -922,8 +923,10 @@ bool compare_matches(struct xtables_rule_match *mt1, + return false; + } + +- if (memcmp(m1->data, m2->data, +- mp1->match->userspacesize) != 0) { ++ if (!strcmp(m1->u.user.name, "among")) ++ cmplen = m1->u.match_size - sizeof(*m1); ++ ++ if (memcmp(m1->data, m2->data, cmplen) != 0) { + DEBUGP("mismatch match data\n"); + return false; + } +-- +2.40.0 + diff --git a/SOURCES/0144-nft-Do-not-pass-nft_rule_ctx-to-add_nft_among.patch b/SOURCES/0144-nft-Do-not-pass-nft_rule_ctx-to-add_nft_among.patch new file mode 100644 index 0000000..8ca59c4 --- /dev/null +++ b/SOURCES/0144-nft-Do-not-pass-nft_rule_ctx-to-add_nft_among.patch @@ -0,0 +1,67 @@ +From 4cde53b041a39a0fe9a1c2701b00216f34510f7b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 15 Jul 2023 01:35:39 +0200 +Subject: [PATCH] nft: Do not pass nft_rule_ctx to add_nft_among() + +It is not used, must be a left-over from an earlier version of the fixed +commit. + +Fixes: 4e95200ded923 ("nft-bridge: pass context structure to ops->add() to improve anonymous set support") +Signed-off-by: Phil Sutter +(cherry picked from commit bd71c11a95ab2b44794843fd8a3698039a7db211) + +Conflicts: + iptables/nft.c +-> Context conflict due to missing other native expression conversions. +--- + iptables/nft.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 936204a432621..c3b819f1934a8 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -1064,8 +1064,7 @@ gen_lookup(uint32_t sreg, const char *set_name, uint32_t set_id, uint32_t flags) + #define NFT_DATATYPE_ETHERADDR 9 + + static int __add_nft_among(struct nft_handle *h, const char *table, +- struct nft_rule_ctx *ctx, struct nftnl_rule *r, +- struct nft_among_pair *pairs, ++ struct nftnl_rule *r, struct nft_among_pair *pairs, + int cnt, bool dst, bool inv, bool ip) + { + uint32_t set_id, type = NFT_DATATYPE_ETHERADDR, len = ETH_ALEN; +@@ -1143,7 +1142,7 @@ static int __add_nft_among(struct nft_handle *h, const char *table, + return 0; + } + +-static int add_nft_among(struct nft_handle *h, struct nft_rule_ctx *ctx, ++static int add_nft_among(struct nft_handle *h, + struct nftnl_rule *r, struct xt_entry_match *m) + { + struct nft_among_data *data = (struct nft_among_data *)m->data; +@@ -1158,10 +1157,10 @@ static int add_nft_among(struct nft_handle *h, struct nft_rule_ctx *ctx, + } + + if (data->src.cnt) +- __add_nft_among(h, table, ctx, r, data->pairs, data->src.cnt, ++ __add_nft_among(h, table, r, data->pairs, data->src.cnt, + false, data->src.inv, data->src.ip); + if (data->dst.cnt) +- __add_nft_among(h, table, ctx, r, data->pairs + data->src.cnt, ++ __add_nft_among(h, table, r, data->pairs + data->src.cnt, + data->dst.cnt, true, data->dst.inv, + data->dst.ip); + return 0; +@@ -1180,7 +1179,7 @@ int add_match(struct nft_handle *h, struct nft_rule_ctx *ctx, + if (!strcmp(m->u.user.name, "limit")) + return add_nft_limit(r, m); + else if (!strcmp(m->u.user.name, "among")) +- return add_nft_among(h, ctx, r, m); ++ return add_nft_among(h, r, m); + break; + default: + break; +-- +2.40.0 + diff --git a/SOURCES/0145-iptables-nft-fix-basechain-policy-configuration.patch b/SOURCES/0145-iptables-nft-fix-basechain-policy-configuration.patch new file mode 100644 index 0000000..4650ca5 --- /dev/null +++ b/SOURCES/0145-iptables-nft-fix-basechain-policy-configuration.patch @@ -0,0 +1,82 @@ +From c5533b1a742253bf5c5ad3ae766ef3348f65f923 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Fri, 2 Oct 2020 13:44:36 +0200 +Subject: [PATCH 145/145] 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 +(cherry picked from commit 0bd7a8eaf3582159490ab355b1217a4e42ed021f) +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 6 +++- + .../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 + +diff --git a/iptables/nft.c b/iptables/nft.c +index c3b819f1934a8..6096647bc472d 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -685,7 +685,9 @@ nft_chain_builtin_alloc(const struct builtin_table *table, + 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; +@@ -927,6 +929,8 @@ int nft_chain_set(struct nft_handle *h, const char *table, + 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; + +diff --git a/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 b/iptables/tests/shell/testcases/nft-only/0008-basechain-policy_0 +new file mode 100755 +index 0000000000000..a81e9badc43a5 +--- /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: Thu, 13 Jul 2023 18:32:02 +0200 +Subject: [PATCH] iptables-restore: Drop dead code + +Handle initialization is guarded by 'in_table' boolean, so there can't +be a handle already (because the branch which unsets 'in_table' also +frees the handle). + +Signed-off-by: Phil Sutter +(cherry picked from commit 4d9453233538200e9663c6bd0c2df09e1671b5f4) +--- + iptables/iptables-restore.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c +index 3b821467db355..6dfafe0c18072 100644 +--- a/iptables/iptables-restore.c ++++ b/iptables/iptables-restore.c +@@ -225,8 +225,6 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb, + } + continue; + } +- if (handle) +- cb->ops->free(handle); + + handle = create_handle(cb, table); + if (noflush == 0) { +-- +2.41.0 + diff --git a/SOURCES/0147-iptables-apply-Eliminate-shellcheck-warnings.patch b/SOURCES/0147-iptables-apply-Eliminate-shellcheck-warnings.patch new file mode 100644 index 0000000..a97159d --- /dev/null +++ b/SOURCES/0147-iptables-apply-Eliminate-shellcheck-warnings.patch @@ -0,0 +1,82 @@ +From ff0c0dc23fec33e339974e419c664d3bef39edc9 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 1 Aug 2023 16:56:42 +0200 +Subject: [PATCH] iptables-apply: Eliminate shellcheck warnings + +Actual warnings were only about use of '-a' in bracket expressions +(replace by '&&' pipeline) and the immediate evaluation of the variable +in trap command. + +The remaining changes silence info-level messages: missing quoting +around variables, pointless '$' in arithmetic expressions, backticks +instead of $(...), missing '-r' parameter when calling read and an +awkward negated '-z' check. + +Signed-off-by: Phil Sutter +(cherry picked from commit 9f98550d58a49fc95d529ebdc0173579d957b425) +--- + iptables/iptables-apply | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/iptables/iptables-apply b/iptables/iptables-apply +index 3a7df5e3cbc1f..c603fb2113ef3 100755 +--- a/iptables/iptables-apply ++++ b/iptables/iptables-apply +@@ -141,9 +141,9 @@ for opt in $OPTS; do + ;; + (*) + case "${OPT_STATE:-}" in +- (SET_TIMEOUT) eval TIMEOUT=$opt;; ++ (SET_TIMEOUT) eval TIMEOUT="$opt";; + (SET_SAVEFILE) +- eval SAVEFILE=$opt ++ eval SAVEFILE="$opt" + [ -z "$SAVEFILE" ] && SAVEFILE="$DEF_SAVEFILE" + ;; + esac +@@ -163,13 +163,13 @@ done + + # Validate parameters + if [ "$TIMEOUT" -ge 0 ] 2>/dev/null; then +- TIMEOUT=$(($TIMEOUT)) ++ TIMEOUT=$((TIMEOUT)) + else + echo "Error: timeout must be a positive number" >&2 + exit 1 + fi + +-if [ -n "$SAVEFILE" -a -e "$SAVEFILE" -a ! -w "$SAVEFILE" ]; then ++if [ -n "$SAVEFILE" ] && [ -e "$SAVEFILE" ] && [ ! -w "$SAVEFILE" ]; then + echo "Error: savefile not writable: $SAVEFILE" >&2 + exit 8 + fi +@@ -205,8 +205,8 @@ esac + ### Begin work + + # Store old iptables rules to temporary file +-TMPFILE=`mktemp /tmp/$PROGNAME-XXXXXXXX` +-trap "rm -f $TMPFILE" EXIT HUP INT QUIT ILL TRAP ABRT BUS \ ++TMPFILE=$(mktemp "/tmp/$PROGNAME-XXXXXXXX") ++trap 'rm -f $TMPFILE' EXIT HUP INT QUIT ILL TRAP ABRT BUS \ + FPE USR1 SEGV USR2 PIPE ALRM TERM + + if ! "$SAVE" >"$TMPFILE"; then +@@ -257,13 +257,13 @@ esac + # Prompt user for confirmation + echo -n "Can you establish NEW connections to the machine? (y/N) " + +-read -n1 -t "$TIMEOUT" ret 2>&1 || : ++read -r -n1 -t "$TIMEOUT" ret 2>&1 || : + case "${ret:-}" in + (y*|Y*) + # Success + echo + +- if [ ! -z "$SAVEFILE" ]; then ++ if [ -n "$SAVEFILE" ]; then + # Write successfully applied rules to the savefile + echo "Writing successfully applied rules to '$SAVEFILE'..." + if ! "$SAVE" >"$SAVEFILE"; then +-- +2.41.0 + diff --git a/SOURCES/0148-ebtables-Exit-gracefully-on-invalid-table-names.patch b/SOURCES/0148-ebtables-Exit-gracefully-on-invalid-table-names.patch new file mode 100644 index 0000000..118da17 --- /dev/null +++ b/SOURCES/0148-ebtables-Exit-gracefully-on-invalid-table-names.patch @@ -0,0 +1,51 @@ +From f4f3fd1fa83a56c051fa72ee619ef23942e65504 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 28 Jan 2021 01:09:56 +0100 +Subject: [PATCH] ebtables: Exit gracefully on invalid table names + +Users are able to cause program abort by passing a table name that +doesn't exist: + +| # ebtables-nft -t dummy -P INPUT ACCEPT +| ebtables: nft-cache.c:455: fetch_chain_cache: Assertion `t' failed. +| Aborted + +Avoid this by checking table existence just like iptables-nft does upon +parsing '-t' optarg. Since the list of tables is known and fixed, +checking the given name's length is pointless. So just drop that check +in return. + +With this patch in place, output looks much better: + +| # ebtables-nft -t dummy -P INPUT ACCEPT +| ebtables v1.8.7 (nf_tables): table 'dummy' does not exist +| Perhaps iptables or your kernel needs to be upgraded. + +Signed-off-by: Phil Sutter +(cherry picked from commit 30c1d443896311e69762d6b51b63908ec602574f) +--- + iptables/xtables-eb.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c +index a3d659fb35e27..6e47feec5132f 100644 +--- a/iptables/xtables-eb.c ++++ b/iptables/xtables-eb.c +@@ -957,10 +957,10 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table, + xtables_error(PARAMETER_PROBLEM, + "The -t option (seen in line %u) cannot be used in %s.\n", + line, xt_params->program_name); +- if (strlen(optarg) > EBT_TABLE_MAXNAMELEN - 1) +- xtables_error(PARAMETER_PROBLEM, +- "Table name length cannot exceed %d characters", +- EBT_TABLE_MAXNAMELEN - 1); ++ if (!nft_table_builtin_find(h, optarg)) ++ xtables_error(VERSION_PROBLEM, ++ "table '%s' does not exist", ++ optarg); + *table = optarg; + table_set = true; + break; +-- +2.41.0 + diff --git a/SOURCES/arptables-helper b/SOURCES/arptables-helper new file mode 100644 index 0000000..4039e7d --- /dev/null +++ b/SOURCES/arptables-helper @@ -0,0 +1,89 @@ +#!/bin/bash +# config: /etc/sysconfig/arptables + +# Source 'em up +. /etc/init.d/functions + +ARPTABLES_CONFIG=/etc/sysconfig/arptables + +flush_delete_chains() { + echo -n $"Flushing all chains: " + if arptables -F; then + success + else + failure + fi + echo + + echo -n $"Removing user defined chains: " + if arptables -X; then + success + else + failure + fi + echo +} + +start() { + if [ ! -x /usr/sbin/arptables ]; then + exit 4 + fi + + # don't do squat if we don't have the config file + if [ -f $ARPTABLES_CONFIG ]; then + # If we don't clear these first, we might be adding to + # pre-existing rules. + flush_delete_chains + + arptables -Z + + echo -n $"Applying arptables firewall rules: " + /usr/sbin/arptables-restore < $ARPTABLES_CONFIG && \ + success || \ + failure + echo + touch /var/lock/subsys/arptables + else + failure + echo + echo $"Configuration file /etc/sysconfig/arptables missing" + exit 6 + fi +} + +stop() { + flush_delete_chains + echo -n $"Resetting built-in chains to the default ACCEPT policy:" + arptables -P INPUT ACCEPT && \ + arptables -P OUTPUT ACCEPT && \ + success || \ + failure + echo + rm -f /var/lock/subsys/arptables +} + +case "$1" in +start) + start + ;; + +stop) + stop + ;; + +restart|reload) + # "restart" is really just "start" as this isn't a daemon, + # and "start" clears any pre-defined rules anyway. + # This is really only here to make those who expect it happy + start + ;; + +condrestart|try-restart|force-reload) + [ -e /var/lock/subsys/arptables ] && start + ;; + +*) + exit 2 +esac + +exit 0 diff --git a/SOURCES/arptables.service b/SOURCES/arptables.service new file mode 100644 index 0000000..df6c7d6 --- /dev/null +++ b/SOURCES/arptables.service @@ -0,0 +1,12 @@ +[Unit] +Description=Automates a packet filtering firewall with arptables +After=network.target + +[Service] +Type=oneshot +ExecStart=/usr/libexec/arptables-helper start +ExecStop=/usr/libexec/arptables-helper stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/ebtables-config b/SOURCES/ebtables-config new file mode 100644 index 0000000..69d9289 --- /dev/null +++ b/SOURCES/ebtables-config @@ -0,0 +1,11 @@ +# Save current firewall rules on stop. +# Value: yes|no, default: no +# Saves all firewall rules if firewall gets stopped +# (e.g. on system shutdown). +EBTABLES_SAVE_ON_STOP="no" + +# Save (and restore) rule counters. +# Value: yes|no, default: no +# Save rule counters when saving a kernel table to a file. If the +# rule counters were saved, they will be restored when restoring the table. +EBTABLES_SAVE_COUNTER="no" diff --git a/SOURCES/ebtables.service b/SOURCES/ebtables.service new file mode 100644 index 0000000..e0b0162 --- /dev/null +++ b/SOURCES/ebtables.service @@ -0,0 +1,11 @@ +[Unit] +Description=Ethernet Bridge Filtering tables + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/libexec/ebtables start +ExecStop=/usr/libexec/ebtables stop + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/ebtables.systemd b/SOURCES/ebtables.systemd new file mode 100644 index 0000000..c31ddc0 --- /dev/null +++ b/SOURCES/ebtables.systemd @@ -0,0 +1,71 @@ +#!/bin/bash + +RETVAL=0 +EBTCONF=/etc/sysconfig/ebtables + +initialize() { + # Initialize $TYPE tables + echo -n $" $TYPE tables: " + if [ -r /etc/sysconfig/ebtables.$TYPE ]; then + /sbin/ebtables -t $TYPE --atomic-file /etc/sysconfig/ebtables.$TYPE --atomic-commit > /dev/null || RETVAL=1 + else + echo -n "not configured" + fi + if [ $RETVAL -eq 0 ]; then + echo -n $"[ OK ]" + echo -ne "\r" + else + echo -n $"[FAILED]" + echo -ne "\r" + fi +} + +case $1 in + start) + if [[ -r $EBTCONF ]]; then + ebtables-restore <$EBTCONF + RETVAL=$? + else + echo -n "not configured" + fi + if [ $RETVAL -eq 0 ]; then + echo -n $"[ OK ]" + echo -ne "\r" + else + echo -n $"[FAILED]" + echo -ne "\r" + fi + ;; + stop) + [[ $EBTABLES_SAVE_ON_STOP == "yes" ]] && $0 save + /sbin/ebtables --init-table + RETVAL=$? + + if [ $RETVAL -eq 0 ]; then + echo -n $"[ OK ]" + echo -ne "\r" + else + echo -n $"[FAILED]" + echo -ne "\r" + fi + ;; + save) + echo -n $"Saving Ethernet bridge filtering (ebtables): " + ebtables-save >$EBTCONF + RETVAL=$? + + if [ $RETVAL -eq 0 ]; then + echo -n $"[ OK ]" + echo -ne "\r" + else + echo -n $"[FAILED]" + echo -ne "\r" + fi + ;; + *) + echo "usage: ${0##*/} {start|stop|save}" >&2 + exit 1 + ;; +esac + +# vim:set ts=2 sw=2 ft=sh et: diff --git a/SOURCES/iptables-config b/SOURCES/iptables-config new file mode 100644 index 0000000..3d7e176 --- /dev/null +++ b/SOURCES/iptables-config @@ -0,0 +1,59 @@ +# Load additional iptables modules (nat helpers) +# Default: -none- +# Space separated list of nat helpers (e.g. 'ip_nat_ftp ip_nat_irc'), which +# are loaded after the firewall rules are applied. Options for the helpers are +# stored in /etc/modprobe.conf. +IPTABLES_MODULES="" + +# Save current firewall rules on stop. +# Value: yes|no, default: no +# Saves all firewall rules to /etc/sysconfig/iptables if firewall gets stopped +# (e.g. on system shutdown). +IPTABLES_SAVE_ON_STOP="no" + +# Save current firewall rules on restart. +# Value: yes|no, default: no +# Saves all firewall rules to /etc/sysconfig/iptables if firewall gets +# restarted. +IPTABLES_SAVE_ON_RESTART="no" + +# Save (and restore) rule and chain counter. +# Value: yes|no, default: no +# Save counters for rules and chains to /etc/sysconfig/iptables if +# 'service iptables save' is called or on stop or restart if SAVE_ON_STOP or +# SAVE_ON_RESTART is enabled. +IPTABLES_SAVE_COUNTER="no" + +# Numeric status output +# Value: yes|no, default: yes +# Print IP addresses and port numbers in numeric format in the status output. +IPTABLES_STATUS_NUMERIC="yes" + +# Verbose status output +# Value: yes|no, default: yes +# Print info about the number of packets and bytes plus the "input-" and +# "outputdevice" in the status output. +IPTABLES_STATUS_VERBOSE="no" + +# Status output with numbered lines +# Value: yes|no, default: yes +# Print a counter/number for every rule in the status output. +IPTABLES_STATUS_LINENUMBERS="yes" + +# Reload sysctl settings on start and restart +# Default: -none- +# Space separated list of sysctl items which are to be reloaded on start. +# List items will be matched by fgrep. +#IPTABLES_SYSCTL_LOAD_LIST=".nf_conntrack .bridge-nf" + +# Set wait option for iptables-restore calls in seconds +# Default: 600 +# Set to 0 to deactivate the wait. +#IPTABLES_RESTORE_WAIT=600 + +# Set wait interval option for iptables-restore calls in microseconds +# Default: 1000000 +# Set to 100000 to try to get the lock every 100000 microseconds, 10 times a +# second. +# Only usable with IPTABLES_RESTORE_WAIT > 0 +#IPTABLES_RESTORE_WAIT_INTERVAL=1000000 diff --git a/SOURCES/iptables-test.stderr.expect b/SOURCES/iptables-test.stderr.expect new file mode 100644 index 0000000..5a09a93 --- /dev/null +++ b/SOURCES/iptables-test.stderr.expect @@ -0,0 +1,39 @@ +extensions/libip6t_srh.t: ERROR: line 2 (cannot load: ip6tables -A INPUT -m srh --srh-next-hdr 17) +extensions/libip6t_srh.t: ERROR: line 3 (cannot load: ip6tables -A INPUT -m srh --srh-hdr-len-eq 8) +extensions/libip6t_srh.t: ERROR: line 4 (cannot load: ip6tables -A INPUT -m srh --srh-hdr-len-gt 8) +extensions/libip6t_srh.t: ERROR: line 5 (cannot load: ip6tables -A INPUT -m srh --srh-hdr-len-lt 8) +extensions/libip6t_srh.t: ERROR: line 6 (cannot load: ip6tables -A INPUT -m srh --srh-segs-left-eq 1) +extensions/libip6t_srh.t: ERROR: line 7 (cannot load: ip6tables -A INPUT -m srh --srh-segs-left-gt 1) +extensions/libip6t_srh.t: ERROR: line 8 (cannot load: ip6tables -A INPUT -m srh --srh-segs-left-lt 1) +extensions/libip6t_srh.t: ERROR: line 9 (cannot load: ip6tables -A INPUT -m srh --srh-last-entry-eq 4) +extensions/libip6t_srh.t: ERROR: line 10 (cannot load: ip6tables -A INPUT -m srh --srh-last-entry-gt 4) +extensions/libip6t_srh.t: ERROR: line 11 (cannot load: ip6tables -A INPUT -m srh --srh-last-entry-lt 4) +extensions/libip6t_srh.t: ERROR: line 12 (cannot load: ip6tables -A INPUT -m srh --srh-tag 0) +extensions/libip6t_srh.t: ERROR: line 13 (cannot load: ip6tables -A INPUT -m srh ! --srh-next-hdr 17) +extensions/libip6t_srh.t: ERROR: line 14 (cannot load: ip6tables -A INPUT -m srh ! --srh-hdr-len-eq 8) +extensions/libip6t_srh.t: ERROR: line 15 (cannot load: ip6tables -A INPUT -m srh ! --srh-hdr-len-gt 8) +extensions/libip6t_srh.t: ERROR: line 16 (cannot load: ip6tables -A INPUT -m srh ! --srh-hdr-len-lt 8) +extensions/libip6t_srh.t: ERROR: line 17 (cannot load: ip6tables -A INPUT -m srh ! --srh-segs-left-eq 1) +extensions/libip6t_srh.t: ERROR: line 18 (cannot load: ip6tables -A INPUT -m srh ! --srh-segs-left-gt 1) +extensions/libip6t_srh.t: ERROR: line 19 (cannot load: ip6tables -A INPUT -m srh ! --srh-segs-left-lt 1) +extensions/libip6t_srh.t: ERROR: line 20 (cannot load: ip6tables -A INPUT -m srh ! --srh-last-entry-eq 4) +extensions/libip6t_srh.t: ERROR: line 21 (cannot load: ip6tables -A INPUT -m srh ! --srh-last-entry-gt 4) +extensions/libip6t_srh.t: ERROR: line 22 (cannot load: ip6tables -A INPUT -m srh ! --srh-last-entry-lt 4) +extensions/libip6t_srh.t: ERROR: line 23 (cannot load: ip6tables -A INPUT -m srh ! --srh-tag 0) +extensions/libip6t_srh.t: ERROR: line 24 (cannot load: ip6tables -A INPUT -m srh --srh-next-hdr 17 --srh-segs-left-eq 1 --srh-last-entry-eq 4 --srh-tag 0) +extensions/libip6t_srh.t: ERROR: line 25 (cannot load: ip6tables -A INPUT -m srh ! --srh-next-hdr 17 ! --srh-segs-left-eq 0 --srh-tag 0) +extensions/libip6t_srh.t: ERROR: line 26 (cannot load: ip6tables -A INPUT -m srh --srh-psid a::/64 --srh-nsid b::/128 --srh-lsid c::/0) +extensions/libip6t_srh.t: ERROR: line 27 (cannot load: ip6tables -A INPUT -m srh ! --srh-psid a::/64 ! --srh-nsid b::/128 ! --srh-lsid c::/0) +extensions/libip6t_srh.t: ERROR: line 28 (cannot load: ip6tables -A INPUT -m srh) +extensions/libipt_CLUSTERIP.t: ERROR: line 3 (cannot load: iptables -A INPUT -d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 1 --hash-init 1) +extensions/libipt_CLUSTERIP.t: ERROR: line 4 (cannot load: iptables -A INPUT -d 10.31.3.236/32 -i lo -j CLUSTERIP --new --hashmode sourceip --clustermac 01:AA:7B:47:F7:D7 --total-nodes 2 --local-node 2 --hash-init 1) +extensions/libxt_IDLETIMER.t: ERROR: line 5 (cannot load: iptables -A INPUT -j IDLETIMER --timeout 42 --label bar --alarm) +extensions/libxt_LED.t: ERROR: line 3 (cannot load: iptables -A INPUT -j LED --led-trigger-id "foo") +extensions/libxt_LED.t: ERROR: line 4 (cannot load: iptables -A INPUT -j LED --led-trigger-id "foo" --led-delay 42 --led-always-blink) +extensions/libxt_TCPMSS.t: ERROR: line 4 (should fail: iptables -A FORWARD -t mangle -p tcp -j TCPMSS --set-mss 42) +extensions/libxt_ipcomp.t: ERROR: line 2 (cannot load: iptables -A INPUT -p ipcomp -m ipcomp --ipcompspi 18 -j DROP) +extensions/libxt_ipcomp.t: ERROR: line 3 (cannot load: iptables -A INPUT -p ipcomp -m ipcomp ! --ipcompspi 18 -j ACCEPT) +extensions/libxt_time.t: ERROR: line 2 (cannot load: iptables -A INPUT -m time --timestart 01:02:03 --timestop 04:05:06 --monthdays 1,2,3,4,5 --weekdays Mon,Fri,Sun --datestart 2001-02-03T04:05:06 --datestop 2012-09-08T09:06:05 --kerneltz) +extensions/libxt_time.t: ERROR: line 3 (cannot load: iptables -A INPUT -m time --timestart 01:02:03 --timestop 04:05:06 --monthdays 1,2,3,4,5 --weekdays Mon,Fri,Sun --datestart 2001-02-03T04:05:06 --datestop 2012-09-08T09:06:05) +extensions/libxt_time.t: ERROR: line 4 (cannot load: iptables -A INPUT -m time --timestart 02:00:00 --timestop 03:00:00 --datestart 1970-01-01T02:00:00 --datestop 1970-01-01T03:00:00) +extensions/libxt_u32.t: ERROR: line 2 (cannot load: iptables -A INPUT -m u32 --u32 "0x0=0x0&&0x0=0x1") diff --git a/SOURCES/iptables.init b/SOURCES/iptables.init new file mode 100755 index 0000000..52fa91a --- /dev/null +++ b/SOURCES/iptables.init @@ -0,0 +1,374 @@ +#!/bin/bash +# +# iptables Start iptables firewall +# +# chkconfig: 2345 08 92 +# description: Starts, stops and saves iptables firewall +# +# config: /etc/sysconfig/iptables +# config: /etc/sysconfig/iptables-config +# +### BEGIN INIT INFO +# Provides: iptables +# Required-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: start and stop iptables firewall +# Description: Start, stop and save iptables firewall +### END INIT INFO + +# Source function library. +. /etc/init.d/functions + +IPTABLES=iptables +IPTABLES_DATA=/etc/sysconfig/$IPTABLES +IPTABLES_FALLBACK_DATA=${IPTABLES_DATA}.fallback +IPTABLES_CONFIG=/etc/sysconfig/${IPTABLES}-config +IPV=${IPTABLES%tables} # ip for ipv4 | ip6 for ipv6 +[ "$IPV" = "ip" ] && _IPV="ipv4" || _IPV="ipv6" +VAR_SUBSYS_IPTABLES=/var/lock/subsys/$IPTABLES + +# only usable for root +if [ $EUID != 0 ]; then + echo -n $"${IPTABLES}: Only usable by root."; warning; echo + exit 4 +fi + +if [ ! -x /sbin/$IPTABLES ]; then + echo -n $"${IPTABLES}: /sbin/$IPTABLES does not exist."; warning; echo + exit 5 +fi + +# Default firewall configuration: +IPTABLES_MODULES="" +IPTABLES_SAVE_ON_STOP="no" +IPTABLES_SAVE_ON_RESTART="no" +IPTABLES_SAVE_COUNTER="no" +IPTABLES_STATUS_NUMERIC="yes" +IPTABLES_STATUS_VERBOSE="no" +IPTABLES_STATUS_LINENUMBERS="yes" +IPTABLES_SYSCTL_LOAD_LIST="" +IPTABLES_RESTORE_WAIT=600 +IPTABLES_RESTORE_WAIT_INTERVAL=1000000 + +# Load firewall configuration. +[ -f "$IPTABLES_CONFIG" ] && . "$IPTABLES_CONFIG" + +# explicitly omit security table from this list as +# it should be reserved for SELinux use +NF_TABLES="raw mangle filter nat" + + +flush_n_delete() { + # Flush firewall rules and delete chains. + echo -n $"${IPTABLES}: Flushing firewall rules: " + ret=0 + # For all tables + for i in $NF_TABLES; do + # Flush firewall rules. + $IPTABLES -t $i -F; + let ret+=$?; + + # Delete firewall chains. + $IPTABLES -t $i -X; + let ret+=$?; + + # Set counter to zero. + $IPTABLES -t $i -Z; + let ret+=$?; + done + + [ $ret -eq 0 ] && success || failure + echo + return $ret +} + +set_policy() { + # Set policy for configured tables. + policy=$1 + echo -n $"${IPTABLES}: Setting chains to policy $policy: " + ret=0 + for i in $NF_TABLES; do + echo -n "$i " + case "$i" in + raw) + $IPTABLES -t raw -P PREROUTING $policy \ + && $IPTABLES -t raw -P OUTPUT $policy \ + || let ret+=1 + ;; + filter) + $IPTABLES -t filter -P INPUT $policy \ + && $IPTABLES -t filter -P OUTPUT $policy \ + && $IPTABLES -t filter -P FORWARD $policy \ + || let ret+=1 + ;; + nat) + $IPTABLES -t nat -P PREROUTING $policy \ + && $IPTABLES -t nat -P POSTROUTING $policy \ + && $IPTABLES -t nat -P OUTPUT $policy \ + || let ret+=1 + ;; + mangle) + $IPTABLES -t mangle -P PREROUTING $policy \ + && $IPTABLES -t mangle -P POSTROUTING $policy \ + && $IPTABLES -t mangle -P INPUT $policy \ + && $IPTABLES -t mangle -P OUTPUT $policy \ + && $IPTABLES -t mangle -P FORWARD $policy \ + || let ret+=1 + ;; + *) + let ret+=1 + ;; + esac + done + + [ $ret -eq 0 ] && success || failure + echo + return $ret +} + +load_sysctl() { + # load matched sysctl values + if [ -n "$IPTABLES_SYSCTL_LOAD_LIST" ]; then + echo -n $"Loading sysctl settings: " + ret=0 + for item in $IPTABLES_SYSCTL_LOAD_LIST; do + fgrep -hs $item /etc/sysctl.d/*.conf | sysctl -p - >/dev/null + let ret+=$?; + done + [ $ret -eq 0 ] && success || failure + echo + fi + return $ret +} + +start() { + # Do not start if there is no config file. + if [ ! -f "$IPTABLES_DATA" ]; then + echo -n $"${IPTABLES}: No config file."; warning; echo + return 6 + fi + + # check if ipv6 module load is deactivated + if [ "${_IPV}" = "ipv6" ] \ + && grep -qIsE "^install[[:space:]]+${_IPV}[[:space:]]+/bin/(true|false)" /etc/modprobe.conf /etc/modprobe.d/* ; then + echo $"${IPTABLES}: ${_IPV} is disabled." + return 150 + fi + + echo -n $"${IPTABLES}: Applying firewall rules: " + + OPT= + [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c" + if [ $IPTABLES_RESTORE_WAIT -ne 0 ]; then + OPT="${OPT} --wait ${IPTABLES_RESTORE_WAIT}" + if [ $IPTABLES_RESTORE_WAIT_INTERVAL -lt 1000000 ]; then + OPT="${OPT} --wait-interval ${IPTABLES_RESTORE_WAIT_INTERVAL}" + fi + fi + + $IPTABLES-restore $OPT $IPTABLES_DATA + if [ $? -eq 0 ]; then + success; echo + else + failure; echo; + if [ -f "$IPTABLES_FALLBACK_DATA" ]; then + echo -n $"${IPTABLES}: Applying firewall fallback rules: " + $IPTABLES-restore $OPT $IPTABLES_FALLBACK_DATA + if [ $? -eq 0 ]; then + success; echo + else + failure; echo; return 1 + fi + else + return 1 + fi + fi + + # Load additional modules (helpers) + if [ -n "$IPTABLES_MODULES" ]; then + echo -n $"${IPTABLES}: Loading additional modules: " + ret=0 + for mod in $IPTABLES_MODULES; do + echo -n "$mod " + modprobe $mod > /dev/null 2>&1 + let ret+=$?; + done + [ $ret -eq 0 ] && success || failure + echo + fi + + # Load sysctl settings + load_sysctl + + touch $VAR_SUBSYS_IPTABLES + return $ret +} + +stop() { + # Set default chain policy to ACCEPT, in order to not break shutdown + # on systems where the default policy is DROP and root device is + # network-based (i.e.: iSCSI, NFS) + set_policy ACCEPT + # And then, flush the rules and delete chains + flush_n_delete + + rm -f $VAR_SUBSYS_IPTABLES + return $ret +} + +save() { + echo -n $"${IPTABLES}: Saving firewall rules to $IPTABLES_DATA: " + + OPT= + [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c" + + ret=0 + TMP_FILE=$(/bin/mktemp -q $IPTABLES_DATA.XXXXXX) \ + && chmod 600 "$TMP_FILE" \ + && $IPTABLES-save $OPT > $TMP_FILE 2>/dev/null \ + && size=$(stat -c '%s' $TMP_FILE) && [ $size -gt 0 ] \ + || ret=1 + if [ $ret -eq 0 ]; then + if [ -e $IPTABLES_DATA ]; then + cp -f $IPTABLES_DATA $IPTABLES_DATA.save \ + && chmod 600 $IPTABLES_DATA.save \ + && restorecon $IPTABLES_DATA.save \ + || ret=1 + fi + if [ $ret -eq 0 ]; then + mv -f $TMP_FILE $IPTABLES_DATA \ + && chmod 600 $IPTABLES_DATA \ + && restorecon $IPTABLES_DATA \ + || ret=1 + fi + fi + rm -f $TMP_FILE + [ $ret -eq 0 ] && success || failure + echo + return $ret +} + +status() { + if [ ! -f "$VAR_SUBSYS_IPTABLES" ]; then + echo $"${IPTABLES}: Firewall is not running." + return 3 + fi + + NUM= + [ "x$IPTABLES_STATUS_NUMERIC" = "xyes" ] && NUM="-n" + VERBOSE= + [ "x$IPTABLES_STATUS_VERBOSE" = "xyes" ] && VERBOSE="--verbose" + COUNT= + [ "x$IPTABLES_STATUS_LINENUMBERS" = "xyes" ] && COUNT="--line-numbers" + + for table in $NF_TABLES; do + echo $"Table: $table" + $IPTABLES -t $table --list $NUM $VERBOSE $COUNT && echo + done + + return 0 +} + +reload() { + # Do not reload if there is no config file. + if [ ! -f "$IPTABLES_DATA" ]; then + echo -n $"${IPTABLES}: No config file."; warning; echo + return 6 + fi + + # check if ipv6 module load is deactivated + if [ "${_IPV}" = "ipv6" ] \ + && grep -qIsE "^install[[:space:]]+${_IPV}[[:space:]]+/bin/(true|false)" /etc/modprobe.conf /etc/modprobe.d/* ; then + echo $"${IPTABLES}: ${_IPV} is disabled." + return 150 + fi + + echo -n $"${IPTABLES}: Trying to reload firewall rules: " + + OPT= + [ "x$IPTABLES_SAVE_COUNTER" = "xyes" ] && OPT="-c" + if [ $IPTABLES_RESTORE_WAIT -ne 0 ]; then + OPT="${OPT} --wait ${IPTABLES_RESTORE_WAIT}" + if [ $IPTABLES_RESTORE_WAIT_INTERVAL -lt 1000000 ]; then + OPT="${OPT} --wait-interval ${IPTABLES_RESTORE_WAIT_INTERVAL}" + fi + fi + + $IPTABLES-restore $OPT $IPTABLES_DATA + if [ $? -eq 0 ]; then + success; echo + else + failure; echo; echo "Firewall rules are not changed."; return 1 + fi + + # Load additional modules (helpers) + if [ -n "$IPTABLES_MODULES" ]; then + echo -n $"${IPTABLES}: Loading additional modules: " + ret=0 + for mod in $IPTABLES_MODULES; do + echo -n "$mod " + modprobe $mod > /dev/null 2>&1 + let ret+=$?; + done + [ $ret -eq 0 ] && success || failure + echo + fi + + # Load sysctl settings + load_sysctl + + return $ret +} + +restart() { + [ "x$IPTABLES_SAVE_ON_RESTART" = "xyes" ] && save + stop + start +} + + +case "$1" in + start) + [ -f "$VAR_SUBSYS_IPTABLES" ] && exit 0 + start + RETVAL=$? + ;; + stop) + [ "x$IPTABLES_SAVE_ON_STOP" = "xyes" ] && save + stop + RETVAL=$? + ;; + restart|force-reload) + restart + RETVAL=$? + ;; + reload) + [ -e "$VAR_SUBSYS_IPTABLES" ] && reload + RETVAL=$? + ;; + condrestart|try-restart) + [ ! -e "$VAR_SUBSYS_IPTABLES" ] && exit 0 + restart + RETVAL=$? + ;; + status) + status + RETVAL=$? + ;; + panic) + set_policy DROP + RETVAL=$? + ;; + save) + save + RETVAL=$? + ;; + *) + echo $"Usage: ${IPTABLES} {start|stop|reload|restart|condrestart|status|panic|save}" + RETVAL=2 + ;; +esac + +exit $RETVAL diff --git a/SOURCES/iptables.service b/SOURCES/iptables.service new file mode 100644 index 0000000..39f95f9 --- /dev/null +++ b/SOURCES/iptables.service @@ -0,0 +1,19 @@ +[Unit] +Description=IPv4 firewall with iptables +AssertPathExists=/etc/sysconfig/iptables +Before=network-pre.target +Wants=network-pre.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/libexec/iptables/iptables.init start +ExecReload=/usr/libexec/iptables/iptables.init reload +ExecStop=/usr/libexec/iptables/iptables.init stop +Environment=BOOTUP=serial +Environment=CONSOLETYPE=serial +StandardOutput=syslog +StandardError=syslog + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/sysconfig_ip6tables b/SOURCES/sysconfig_ip6tables new file mode 100644 index 0000000..34b8b87 --- /dev/null +++ b/SOURCES/sysconfig_ip6tables @@ -0,0 +1,15 @@ +# sample configuration for ip6tables service +# you can edit this manually or use system-config-firewall +# please do not ask us to add additional ports/services to this default configuration +*filter +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p ipv6-icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT +-A INPUT -d fe80::/64 -p udp -m udp --dport 546 -m state --state NEW -j ACCEPT +-A INPUT -j REJECT --reject-with icmp6-adm-prohibited +-A FORWARD -j REJECT --reject-with icmp6-adm-prohibited +COMMIT diff --git a/SOURCES/sysconfig_iptables b/SOURCES/sysconfig_iptables new file mode 100644 index 0000000..5183250 --- /dev/null +++ b/SOURCES/sysconfig_iptables @@ -0,0 +1,14 @@ +# sample configuration for iptables service +# you can edit this manually or use system-config-firewall +# please do not ask us to add additional ports/services to this default configuration +*filter +:INPUT ACCEPT [0:0] +:FORWARD ACCEPT [0:0] +:OUTPUT ACCEPT [0:0] +-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT +-A INPUT -p icmp -j ACCEPT +-A INPUT -i lo -j ACCEPT +-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT +-A INPUT -j REJECT --reject-with icmp-host-prohibited +-A FORWARD -j REJECT --reject-with icmp-host-prohibited +COMMIT diff --git a/SPECS/iptables.spec b/SPECS/iptables.spec new file mode 100644 index 0000000..01f2ae5 --- /dev/null +++ b/SPECS/iptables.spec @@ -0,0 +1,1874 @@ +# install init scripts to /usr/libexec with systemd +%global script_path %{_libexecdir}/iptables + +# service legacy actions (RHBZ#748134) +%global legacy_actions %{_libexecdir}/initscripts/legacy-actions + +%global iptc_so_ver 2 + +Name: iptables +Summary: Tools for managing Linux kernel packet filtering capabilities +URL: http://www.netfilter.org/projects/iptables +Version: 1.8.5 +Release: 11%{?dist} +Source: %{url}/files/%{name}-%{version}.tar.bz2 +Source1: iptables.init +Source2: iptables-config +Source3: iptables.service +Source4: sysconfig_iptables +Source5: sysconfig_ip6tables +Source6: arptables.service +Source7: arptables-helper +Source8: ebtables.systemd +Source9: ebtables.service +Source10: ebtables-config +Source11: iptables-test.stderr.expect + +Patch001: 0001-build-resolve-iptables-apply-not-getting-installed.patch +Patch002: 0002-xtables-translate-don-t-fail-if-help-was-requested.patch +Patch003: 0003-xtables-translate-Use-proper-clear_cs-function.patch +Patch004: 0004-libxtables-compiler-warning-fixes-for-NO_SHARED_LIBS.patch +Patch005: 0005-extensions-libxt_conntrack-provide-translation-for-D.patch +Patch006: 0006-nft-Drop-pointless-nft_xt_builtin_init-call.patch +Patch007: 0007-nft-Fix-command-name-in-ip6tables-error-message.patch +Patch008: 0008-tests-shell-Merge-and-extend-return-codes-test.patch +Patch009: 0009-xtables-monitor-Fix-ip6tables-rule-printing.patch +Patch010: 0010-nft-cache-Check-consistency-with-NFT_CL_FAKE-too.patch +Patch011: 0011-nft-Fix-for-broken-address-mask-match-detection.patch +Patch012: 0012-extensions-libipt_icmp-Fix-translation-of-type-any.patch +Patch013: 0013-libxtables-Make-sure-extensions-register-in-revision.patch +Patch014: 0014-libxtables-Simplify-pending-extension-registration.patch +Patch015: 0015-libxtables-Register-multiple-extensions-in-ascending.patch +Patch016: 0016-nft-Make-batch_add_chain-return-the-added-batch-obje.patch +Patch017: 0017-nft-Fix-error-reporting-for-refreshed-transactions.patch +Patch018: 0018-nft-Fix-for-concurrent-noflush-restore-calls.patch +Patch019: 0019-tests-shell-Improve-concurrent-noflush-restore-test-.patch +Patch020: 0020-nft-Optimize-class-based-IP-prefix-matches.patch +Patch021: 0021-ebtables-Optimize-masked-MAC-address-matches.patch +Patch022: 0022-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch +Patch023: 0023-ebtables-Fix-for-broken-chain-renaming.patch +Patch024: 0024-xtables-arp-Don-t-use-ARPT_INV_.patch +Patch025: 0025-xshared-Merge-some-command-option-related-code.patch +Patch026: 0026-tests-shell-Test-for-fixed-extension-registration.patch +Patch027: 0027-extensions-dccp-Fix-for-DCCP-type-INVALID.patch +Patch028: 0028-xtables-monitor-fix-rule-printing.patch +Patch029: 0029-xtables-monitor-fix-packet-family-protocol.patch +Patch030: 0030-xtables-monitor-print-packet-first.patch +Patch031: 0031-xtables-monitor.patch +Patch032: 0032-nft-Fix-selective-chain-compatibility-checks.patch +Patch033: 0033-iptables-nft-fix-Z-option.patch +Patch034: 0034-nft-Fix-bitwise-expression-avoidance-detection.patch +Patch035: 0035-xtables-translate-Fix-translation-of-odd-netmasks.patch +Patch036: 0036-extensions-libxt_conntrack-use-bitops-for-state-nega.patch +Patch037: 0037-Eliminate-inet_aton-and-inet_ntoa.patch +Patch038: 0038-nft-arp-Make-use-of-ipv4_addr_to_string.patch +Patch039: 0039-extensions-SECMARK-Implement-revision-1.patch +Patch040: 0040-Use-proto_to_name-from-xshared-in-more-places.patch +Patch041: 0041-extensions-sctp-Fix-nftables-translation.patch +Patch042: 0042-extensions-sctp-Translate-chunk-types-option.patch +Patch043: 0043-libxtables-Drop-leftover-variable-in-xtables_numeric.patch +Patch044: 0044-extensions-libebt_ip6-Drop-unused-variables.patch +Patch045: 0045-libxtables-Fix-memleak-in-xtopt_parse_hostmask.patch +Patch046: 0046-nft-Avoid-memleak-in-error-path-of-nft_cmd_new.patch +Patch047: 0047-iptables-apply-Drop-unused-variable.patch +Patch048: 0048-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch +Patch049: 0049-ebtables-Dump-atomic-waste.patch +Patch050: 0050-nft-Fix-for-non-verbose-check-command.patch +Patch051: 0051-extensions-hashlimit-Fix-tests-with-HZ-100.patch +Patch052: 0052-nft-Use-xtables_malloc-in-mnl_err_list_node_add.patch +Patch053: 0053-extensions-hashlimit-Fix-tests-with-HZ-1000.patch +Patch054: 0054-xshared-Merge-and-share-parse_chain.patch +Patch055: 0055-nft-shared-Drop-unused-function-print_proto.patch +Patch056: 0056-xshared-Make-load_proto-static.patch +Patch057: 0057-extensions-libxt_NFLOG-fix-nflog-prefix-Python-test-.patch +Patch058: 0058-extensions-libxt_NFLOG-remove-extra-space-when-savin.patch +Patch059: 0059-xshared-Fix-response-to-unprivileged-users.patch +Patch060: 0060-libxtables-Register-only-the-highest-revision-extens.patch +Patch061: 0061-Improve-error-messages-for-unsupported-extensions.patch +Patch062: 0062-nft-Simplify-immediate-parsing.patch +Patch063: 0063-nft-Speed-up-immediate-parsing.patch +Patch064: 0064-xshared-Prefer-xtables_chain_protos-lookup-over-getp.patch +Patch065: 0065-libxtables-Fix-for-warning-in-xtables_ipmask_to_nume.patch +Patch066: 0066-nft-Reject-standard-targets-as-chain-names-when-rest.patch +Patch067: 0067-libxtables-Implement-notargets-hash-table.patch +Patch068: 0068-libxtables-Boost-rule-target-checks-by-announcing-ch.patch +Patch069: 0069-nft-shared-update-context-register-for-bitwise-expre.patch +Patch070: 0070-extensions-MARK-Drop-extra-newline-at-end-of-help.patch +Patch071: 0071-extensions-LOG-Document-log-macdecode-in-man-page.patch +Patch072: 0072-nft-Fix-EPERM-handling-for-extensions-without-rev-0.patch +Patch073: 0073-tests-shell-Check-overhead-in-iptables-save-and-rest.patch +Patch074: 0074-iptables-legacy-Drop-redundant-include-of-xtables-mu.patch +Patch075: 0075-tests-shell-Add-some-more-rules-to-0002-verbose-outp.patch +Patch076: 0076-extensions-string-Do-not-print-default-to-value.patch +Patch077: 0077-xtables-monitor-add-missing-spaces-in-printed-str.patch +Patch078: 0078-libxtables-Fix-unsupported-extension-warning-corner-.patch +Patch079: 0079-extensions-libxt_conntrack-remove-always-false-condi.patch +Patch080: 0080-nft-un-break-among-match-with-concatenation.patch +Patch081: 0081-nft-shared-Introduce-__get_cmp_data.patch +Patch082: 0082-ebtables-Support-p-Length.patch +Patch083: 0083-extensions-among-Remove-pointless-fall-through.patch +Patch084: 0084-extensions-among-Fix-for-use-with-ebtables-restore.patch +Patch085: 0085-extensions-libebt_stp-Eliminate-duplicate-space-in-o.patch +Patch086: 0086-extensions-libip6t_dst-Fix-output-for-empty-options.patch +Patch087: 0087-extensions-TCPOPTSTRIP-Do-not-print-empty-options.patch +Patch088: 0088-tests-IDLETIMER.t-Fix-syntax-support-for-restore-inp.patch +Patch089: 0089-tests-libebt_stp.t-Drop-duplicate-whitespace.patch +Patch090: 0090-tests-shell-Fix-expected-output-for-ip6tables-dst-ma.patch +Patch091: 0091-libiptc-Fix-for-segfault-when-renaming-a-chain.patch +Patch092: 0092-extensions-libebt_mark-Fix-xlate-test-case.patch +Patch093: 0093-extensions-libebt_redirect-Fix-xlate-return-code.patch +Patch094: 0094-extensions-libipt_ttl-Sanitize-xlate-callback.patch +Patch095: 0095-extensions-CONNMARK-Fix-xlate-callback.patch +Patch096: 0096-extensions-MARK-Sanitize-MARK_xlate.patch +Patch097: 0097-extensions-TCPMSS-Use-xlate-callback-for-IPv6-too.patch +Patch098: 0098-extensions-TOS-Fix-v1-xlate-callback.patch +Patch099: 0099-extensions-ecn-Sanitize-xlate-callback.patch +Patch100: 0100-extensions-libebt_mark-Fix-mark-target-xlate.patch +Patch101: 0101-extensions-libxt_conntrack-Drop-extra-whitespace-in-.patch +Patch102: 0102-iptables-restore-Free-handle-with-test-also.patch +Patch103: 0103-iptables-xml-Free-allocated-chain-strings.patch +Patch104: 0104-nft-Plug-memleak-in-nft_rule_zero_counters.patch +Patch105: 0105-xtables-Introduce-xtables_clear_iptables_command_sta.patch +Patch106: 0106-iptables-Properly-clear-iptables_command_state-objec.patch +Patch107: 0107-libiptc-Eliminate-garbage-access.patch +Patch108: 0108-ebtables-Fix-MAC-address-match-translation.patch +Patch109: 0109-nft-Fix-for-comparing-ifname-matches-against-nft-gen.patch +Patch110: 0110-nft-Fix-match-generator-for-i.patch +Patch111: 0111-xtables-translate-Fix-for-interfaces-with-asterisk-m.patch +Patch112: 0112-Drop-libiptc-linux_stddef.h.patch +Patch113: 0113-include-Makefile-xtables-version.h-is-generated.patch +Patch114: 0114-arptables-Check-the-mandatory-ar_pln-match.patch +Patch115: 0115-gitignore-Ignore-utils-nfsynproxy.patch +Patch116: 0116-etc-Drop-xtables.conf.patch +Patch117: 0117-Proper-fix-for-unknown-argument-error-message.patch +Patch118: 0118-ebtables-Refuse-unselected-targets-options.patch +Patch119: 0119-extensions-libebt_redirect-Fix-target-translation.patch +Patch120: 0120-extensions-libebt_redirect-Fix-for-wrong-syntax-in-t.patch +Patch121: 0121-extensions-libebt_ip-Do-not-use-ip-dscp-for-translat.patch +Patch122: 0122-extensions-libebt_ip-Translation-has-to-match-on-eth.patch +Patch123: 0123-nft-restore-Fix-for-deletion-of-new-referenced-rule.patch +Patch124: 0124-nft-shared-Drop-unused-include.patch +Patch125: 0125-arptables-Fix-parsing-of-inverted-arp-operation-matc.patch +Patch126: 0126-arptables-Don-t-omit-standard-matches-if-inverted.patch +Patch127: 0127-Revert-arptables-Check-the-mandatory-ar_pln-match.patch +Patch128: 0128-extensions-SECMARK-Use-a-better-context-in-test-case.patch +Patch129: 0129-tests-xlate-test-Print-errors-to-stderr.patch +Patch130: 0130-iptables-test-Make-netns-spawning-more-robust.patch +Patch131: 0131-tests-iptables-test-Print-errors-to-stderr.patch +Patch132: 0132-tests-xlate-test-Exit-non-zero-on-error.patch +Patch133: 0133-tests-iptables-test-Exit-non-zero-on-error.patch +Patch134: 0134-tests-shell-Return-non-zero-on-error.patch +Patch135: 0135-iptables-test.py-print-with-color-escapes-only-when-.patch +Patch136: 0136-tests-iptables-test-Fix-conditional-colors-on-stderr.patch +Patch137: 0137-tests-shell-update-format-of-registers-in-bitwise-pa.patch +Patch138: 0138-tests-shell-Fix-nft-only-0009-needless-bitwise_0.patch +Patch139: 0139-tests-shell-Sanitize-nft-only-0009-needless-bitwise_.patch +Patch140: 0140-iptables-Fix-setting-of-ipv6-counters.patch +Patch141: 0141-iptables-Fix-handling-of-non-existent-chains.patch +Patch142: 0142-nft-bridge-pass-context-structure-to-ops-add-to-impr.patch +Patch143: 0143-nft-Special-casing-for-among-match-in-compare_matche.patch +Patch144: 0144-nft-Do-not-pass-nft_rule_ctx-to-add_nft_among.patch +Patch145: 0145-iptables-nft-fix-basechain-policy-configuration.patch +Patch146: 0146-iptables-restore-Drop-dead-code.patch +Patch147: 0147-iptables-apply-Eliminate-shellcheck-warnings.patch +Patch148: 0148-ebtables-Exit-gracefully-on-invalid-table-names.patch + +# pf.os: ISC license +# iptables-apply: Artistic Licence 2.0 +License: GPLv2 and Artistic 2.0 and ISC + +# libnetfilter_conntrack is needed for xt_connlabel +BuildRequires: pkgconfig(libnetfilter_conntrack) +# libnfnetlink-devel is requires for nfnl_osf +BuildRequires: pkgconfig(libnfnetlink) +BuildRequires: libselinux-devel +BuildRequires: kernel-headers +BuildRequires: systemd +# libmnl, libnftnl, bison, flex for nftables +BuildRequires: bison +BuildRequires: flex +BuildRequires: gcc +BuildRequires: pkgconfig(libmnl) >= 1.0 +BuildRequires: pkgconfig(libnftnl) >= 1.1.6 +# libpcap-devel for nfbpf_compile +BuildRequires: libpcap-devel +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +%if 0%{?fedora} > 24 +Conflicts: setup < 2.10.4-1 +%endif + +%description +The iptables utility controls the network packet filtering code in the +Linux kernel. If you need to set up firewalls and/or IP masquerading, +you should either install nftables or this package. + +Note: This package contains the nftables-based variants of iptables and +ip6tables, which are drop-in replacements of the legacy tools. + +%package libs +Summary: iptables libraries +Group: System Environment/Base + +%description libs +iptables libraries. + +Please remember that libip*tc libraries do neither have a stable API nor a real so version. + +For more information about this, please have a look at + + http://www.netfilter.org/documentation/FAQ/netfilter-faq-4.html#ss4.5 + + +%package devel +Summary: Development package for iptables +Group: System Environment/Base +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: iptables-libs = %{version}-%{release} +Requires: pkgconfig + +%description devel +iptables development headers and libraries. + +The iptc libraries are marked as not public by upstream. The interface is not +stable and may change with every new version. It is therefore unsupported. + +%package services +Summary: iptables and ip6tables services for iptables +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +# obsolete old main package +Obsoletes: %{name} < 1.4.16.1 +# obsolete ipv6 sub package +Obsoletes: %{name}-ipv6 < 1.4.11.1 + +%description services +iptables services for IPv4 and IPv6 + +This package provides the services iptables and ip6tables that have been split +out of the base package since they are not active by default anymore. + +%package utils +Summary: iptables and ip6tables services for iptables +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} + +%description utils +Utils for iptables. + +Currently only provides nfnl_osf with the pf.os database. + +%package arptables +Summary: User space tool to set up tables of ARP rules in kernel +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Obsoletes: arptables +Provides: arptables + +%description arptables +The arptables tool is used to set up and maintain +the tables of ARP rules in the Linux kernel. These rules inspect +the ARP frames which they see. arptables is analogous to the iptables +user space tool, but is less complicated. + +Note: This package contains the nftables-based variant of arptables, a drop-in +replacement of the legacy tool. + +%package ebtables +Summary: Ethernet Bridge frame table administration tool +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Obsoletes: ebtables +Provides: ebtables + +%description ebtables +Ethernet bridge tables is a firewalling tool to transparently filter network +traffic passing a bridge. The filtering possibilities are limited to link +layer filtering and some basic filtering on higher network layers. + +This tool is the userspace control for the bridge and ebtables kernel +components (built by default in RHEL kernels). + +The ebtables tool can be used together with the other Linux filtering tools, +like iptables. There are no known incompatibility issues. + +Note: This package contains the nftables-based variant of ebtables, a drop-in +replacement of the legacy tool. + +%prep +%autosetup -p1 +cp %{SOURCE11} . + +%build +./autogen.sh +CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing " \ +%configure --enable-devel --enable-bpf-compiler --with-kernel=/usr --with-kbuild=/usr --with-ksource=/usr + +# do not use rpath +sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool +sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool + +rm -f include/linux/types.h + +make %{?_smp_mflags} V=1 + +%install +make install DESTDIR=%{buildroot} +# remove la file(s) +rm -f %{buildroot}/%{_libdir}/*.la + +# install ip*tables.h header files +install -m 644 include/ip*tables.h %{buildroot}%{_includedir}/ +install -d -m 755 %{buildroot}%{_includedir}/iptables +install -m 644 include/iptables/internal.h %{buildroot}%{_includedir}/iptables/ + +# install ipulog header file +install -d -m 755 %{buildroot}%{_includedir}/libipulog/ +install -m 644 include/libipulog/*.h %{buildroot}%{_includedir}/libipulog/ + +# install init scripts and configuration files +install -d -m 755 %{buildroot}%{script_path} +install -c -m 755 %{SOURCE1} %{buildroot}%{script_path}/iptables.init +sed -e 's;iptables;ip6tables;g' -e 's;IPTABLES;IP6TABLES;g' < %{SOURCE1} > ip6tables.init +install -c -m 755 ip6tables.init %{buildroot}%{script_path}/ip6tables.init +install -d -m 755 %{buildroot}%{_sysconfdir}/sysconfig +install -c -m 600 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/iptables-config +sed -e 's;iptables;ip6tables;g' -e 's;IPTABLES;IP6TABLES;g' < %{SOURCE2} > ip6tables-config +install -c -m 600 ip6tables-config %{buildroot}%{_sysconfdir}/sysconfig/ip6tables-config +install -c -m 600 %{SOURCE4} %{buildroot}%{_sysconfdir}/sysconfig/iptables +install -c -m 600 %{SOURCE5} %{buildroot}%{_sysconfdir}/sysconfig/ip6tables + +# install systemd service files +install -d -m 755 %{buildroot}/%{_unitdir} +install -c -m 644 %{SOURCE3} %{buildroot}/%{_unitdir} +sed -e 's;iptables;ip6tables;g' -e 's;IPv4;IPv6;g' -e 's;/usr/libexec/ip6tables;/usr/libexec/iptables;g' < %{SOURCE3} > ip6tables.service +install -c -m 644 ip6tables.service %{buildroot}/%{_unitdir} + +# install legacy actions for service command +install -d %{buildroot}/%{legacy_actions}/iptables +install -d %{buildroot}/%{legacy_actions}/ip6tables + +cat << EOF > %{buildroot}/%{legacy_actions}/iptables/save +#!/bin/bash +exec %{script_path}/iptables.init save +EOF +chmod 755 %{buildroot}/%{legacy_actions}/iptables/save +sed -e 's;iptables.init;ip6tables.init;g' -e 's;IPTABLES;IP6TABLES;g' < %{buildroot}/%{legacy_actions}/iptables/save > ip6tabes.save-legacy +install -c -m 755 ip6tabes.save-legacy %{buildroot}/%{legacy_actions}/ip6tables/save + +cat << EOF > %{buildroot}/%{legacy_actions}/iptables/panic +#!/bin/bash +exec %{script_path}/iptables.init panic +EOF +chmod 755 %{buildroot}/%{legacy_actions}/iptables/panic +sed -e 's;iptables.init;ip6tables.init;g' -e 's;IPTABLES;IP6TABLES;g' < %{buildroot}/%{legacy_actions}/iptables/panic > ip6tabes.panic-legacy +install -c -m 755 ip6tabes.panic-legacy %{buildroot}/%{legacy_actions}/ip6tables/panic + +# install iptables-apply with man page +install -m 755 iptables/iptables-apply %{buildroot}%{_sbindir}/ +install -m 644 iptables/iptables-apply.8 %{buildroot}%{_mandir}/man8/ + +%if 0%{?fedora} > 24 +# Remove /etc/ethertypes (now part of setup) +rm -f %{buildroot}%{_sysconfdir}/ethertypes +%endif + +# drop all legacy tools +rm -f %{buildroot}%{_sbindir}/*legacy* +rm -f %{buildroot}%{_bindir}/iptables-xml +rm -f %{buildroot}%{_mandir}/man1/iptables-xml* +rm -f %{buildroot}%{_mandir}/man8/xtables-legacy* + +# rename nft versions to standard name +pfx=%{buildroot}%{_sbindir}/iptables +for pfx in %{buildroot}%{_sbindir}/{iptables,ip6tables,arptables,ebtables}; do + mv $pfx-nft $pfx + mv $pfx-nft-restore $pfx-restore + mv $pfx-nft-save $pfx-save +done + +# extra sources for arptables +install -p -D -m 644 %{SOURCE6} %{buildroot}%{_unitdir}/arptables.service +mkdir -p %{buildroot}%{_libexecdir}/ +install -p -D -m 755 %{SOURCE7} %{buildroot}%{_libexecdir}/ +mkdir -p %{buildroot}%{_sysconfdir}/sysconfig +echo '# Configure prior to use' > %{buildroot}%{_sysconfdir}/sysconfig/arptables +for sfx in "" "-restore" "-save"; do + echo '.so man8/arptables-nft${sfx}.8' > \ + %{buildroot}%{_mandir}/man8/arptables${sfx}.8 +done + +# extra sources for ebtables +install -p %{SOURCE9} %{buildroot}%{_unitdir}/ +install -m0755 %{SOURCE8} %{buildroot}%{_libexecdir}/ebtables +install -m0600 %{SOURCE10} %{buildroot}%{_sysconfdir}/sysconfig/ebtables-config +touch %{buildroot}%{_sysconfdir}/sysconfig/ebtables +echo '.so man8/ebtables-nft.8' > %{buildroot}%{_mandir}/man8/ebtables.8 + +%if 0%{?rhel} +%pre +for p in %{_sysconfdir}/alternatives/{iptables,ip6tables}.*; do + if [ -h "$p" ]; then + ipt=$(readlink "$p") + echo "Removing alternatives for ${p##*/} with path $ipt" + %{_sbindir}/alternatives --remove "${p##*/}" "$ipt" + fi +done +%endif + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%post services +%systemd_post iptables.service ip6tables.service + +%preun services +%systemd_preun iptables.service ip6tables.service + +%postun services +/sbin/ldconfig +%systemd_postun iptables.service ip6tables.service + +%post arptables +%systemd_post arptables.service + +%preun arptables +%systemd_preun arptables.service + +%postun arptables +%systemd_postun arptables.service + +%post ebtables +%systemd_post ebtables.service + +%preun ebtables +%systemd_preun ebtables.service + +%postun ebtables +%systemd_postun_with_restart ebtables.service + +%files +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc INCOMPATIBILITIES +%config(noreplace) %{_sysconfdir}/sysconfig/iptables-config +%config(noreplace) %{_sysconfdir}/sysconfig/ip6tables-config +%if 0%{?fedora} <= 24 +%{_sysconfdir}/ethertypes +%endif +%{_sbindir}/iptables +%{_sbindir}/iptables-apply +%{_sbindir}/iptables-restore +%{_sbindir}/iptables-restore-translate +%{_sbindir}/iptables-save +%{_sbindir}/iptables-translate +%{_sbindir}/ip6tables +%{_sbindir}/ip6tables-apply +%{_sbindir}/ip6tables-restore +%{_sbindir}/ip6tables-restore-translate +%{_sbindir}/ip6tables-save +%{_sbindir}/ip6tables-translate +%{_sbindir}/xtables-monitor +%{_sbindir}/xtables-nft-multi +%doc %{_mandir}/man8/iptables* +%doc %{_mandir}/man8/ip6tables* +%doc %{_mandir}/man8/xtables-* +%dir %{_libdir}/xtables +%{_libdir}/xtables/libarpt* +%{_libdir}/xtables/libebt* +%{_libdir}/xtables/libipt* +%{_libdir}/xtables/libip6t* +%{_libdir}/xtables/libxt* + +%files libs +%{_libdir}/libip*tc.so.%{iptc_so_ver}* +%{_libdir}/libxtables.so.12* + +%files devel +%dir %{_includedir}/iptables +%{_includedir}/iptables/*.h +%{_includedir}/*.h +%dir %{_includedir}/libiptc +%{_includedir}/libiptc/*.h +%dir %{_includedir}/libipulog +%{_includedir}/libipulog/*.h +%{_libdir}/libip*tc.so +%{_libdir}/libxtables.so +%{_libdir}/pkgconfig/libiptc.pc +%{_libdir}/pkgconfig/libip4tc.pc +%{_libdir}/pkgconfig/libip6tc.pc +%{_libdir}/pkgconfig/xtables.pc + +%files services +%dir %{script_path} +%{script_path}/iptables.init +%{script_path}/ip6tables.init +%config(noreplace) %{_sysconfdir}/sysconfig/iptables +%config(noreplace) %{_sysconfdir}/sysconfig/ip6tables +%{_unitdir}/iptables.service +%{_unitdir}/ip6tables.service +%dir %{legacy_actions}/iptables +%{legacy_actions}/iptables/save +%{legacy_actions}/iptables/panic +%dir %{legacy_actions}/ip6tables +%{legacy_actions}/ip6tables/save +%{legacy_actions}/ip6tables/panic + +%files utils +%{_sbindir}/nfnl_osf +%{_sbindir}/nfbpf_compile +%dir %{_datadir}/xtables +%{_datadir}/xtables/pf.os +%doc %{_mandir}/man8/nfnl_osf* +%doc %{_mandir}/man8/nfbpf_compile* + +%files arptables +%{_sbindir}/arptables* +%{_libexecdir}/arptables-helper +%{_unitdir}/arptables.service +%config(noreplace) %{_sysconfdir}/sysconfig/arptables +%doc %{_mandir}/man8/arptables*.8* + +%files ebtables +%{_sbindir}/ebtables* +%{_libexecdir}/ebtables +%{_unitdir}/ebtables.service +%config(noreplace) %{_sysconfdir}/sysconfig/ebtables-config +%ghost %{_sysconfdir}/sysconfig/ebtables +%doc %{_mandir}/man8/ebtables*.8* + +%changelog +* Fri Mar 29 2024 MSVSphere Packaging Team - 1.8.5-11 +- Rebuilt for MSVSphere 8.10 beta + +* Thu Nov 16 2023 Phil Sutter - 1.8.5-11 +- iptables-restore: Drop dead code +- iptables-apply: Eliminate shellcheck warnings +- ebtables: Exit gracefully on invalid table names + +* Fri Sep 08 2023 Phil Sutter - 1.8.5-10 +- Bump NVR to fix for wrong build tag + +* Wed Sep 06 2023 Phil Sutter - 1.8.5-9 +- iptables-nft: fix basechain policy configuration + +* Fri Jul 28 2023 Phil Sutter - 1.8.5-8 +- Update fixes from upstream once more + +* Wed Jul 19 2023 Phil Sutter - 1.8.5-7 +- Fix shell test-case for older gawk version + +* Tue Jul 18 2023 Phil Sutter - 1.8.5-6 +- Fix shell testcase for rebased libnftnl package + +* Tue Jul 18 2023 Phil Sutter - 1.8.5-5 +- Missed to copy expected results file to destination. + +* Sat Jul 15 2023 Phil Sutter - 1.8.5-4 +- Bump release for CI. + +* Tue Jul 04 2023 Phil Sutter - 1.8.5-3 +- Add expected test results +- Prepare testsuites for expected results + +* Wed Jun 28 2023 Phil Sutter - 1.8.5-2 +- libnftnl package was rebased, depending on 1.1.6 is fine + +* Wed May 10 2023 Phil Sutter - 1.8.5-1 +- Rebase to version 1.8.5 plus upstream-indicated fixes +- Fix for duplicate files in RPM due to imprecise globbing +- Drop bootstrap code again + +* Wed Nov 23 2022 Phil Sutter - 1.8.4-24 +- ebtables: Support '-p Length' +- nft-shared: Introduce __get_cmp_data() + +* Fri Jul 01 2022 Phil Sutter - 1.8.4-23 +- libxtables: Fix unsupported extension warning corner case +- tests: shell: Check overhead in iptables-save and -restore +- nft: Fix EPERM handling for extensions without rev 0 +- Improve error messages for unsupported extensions +- xshared: Fix response to unprivileged users +- libxtables: Register only the highest revision extension +- Use proto_to_name() from xshared in more places +- libxtables: Boost rule target checks by announcing chain names +- libxtables: Implement notargets hash table +- nft: Reject standard targets as chain names when restoring +- xshared: Merge and share parse_chain() +- xshared: Prefer xtables_chain_protos lookup over getprotoent +- nft: Speed up immediate parsing +- nft: Simplify immediate parsing + +* Mon Nov 29 2021 Phil Sutter - 1.8.4-22 +- extensions: hashlimit: Fix tests with HZ=1000 + +* Thu Oct 07 2021 Phil Sutter - 1.8.4-21 +- extensions: hashlimit: Fix tests with HZ=100 +- ebtables: Dump atomic waste +- doc: ebtables-nft.8: Adjust for missing atomic-options + +* Wed Aug 04 2021 Phil Sutter - 1.8.4-20 +- extensions: SECMARK: Use a better context in test case +- extensions: sctp: Translate --chunk-types option +- extensions: sctp: Fix nftables translation +- extensions: SECMARK: Implement revision 1 +- nft: cache: Retry if kernel returns EINTR + +* Fri Jun 18 2021 Phil Sutter - 1.8.4-19 +- Fix for rpminspect results + +* Mon May 24 2021 Phil Sutter - 1.8.4-18 +- xtables-translate: Fix translation of odd netmasks +- nft: Fix bitwise expression avoidance detection +- xtables-monitor: 'LL=0x304' is not very convenient, print LOOPBACK instead. +- xtables-monitor: print packet first +- xtables-monitor: fix packet family protocol +- xtables-monitor: fix rule printing +- xtables-monitor: Fix ip6tables rule printing + +* Thu Dec 10 2020 Phil Sutter - 1.8.4-17 +- extensions: dccp: Fix for DCCP type 'INVALID' +- tests: shell: Merge and extend return codes test +- nft: Fix command name in ip6tables error message +- extensions: libxt_CT: add translation for NOTRACK +- extensions: libipt_icmp: Fix translation of type 'any' +- tests/shell: Test for fixed extension registration +- libxtables: Register multiple extensions in ascending order +- libxtables: Simplify pending extension registration +- libxtables: Make sure extensions register in revision order + +* Wed Oct 28 2020 Phil Sutter - 1.8.4-16 +- tests/shell: Add test for bitwise avoidance fixes +- ebtables: Optimize masked MAC address matches +- nft: Optimize class-based IP prefix matches +- nft: Fix for broken address mask match detection +- nft: cache: Make nft_rebuild_cache() respect fake cache +- tests: shell: Improve concurrent noflush restore test a bit +- nft: Fix for concurrent noflush restore calls +- nft: Fix error reporting for refreshed transactions +- nft: Make batch_add_chain() return the added batch object + +* Sat Aug 15 2020 Phil Sutter - 1.8.4-15 +- Ignore sysctl files not suffixed '.conf' + +* Wed Jun 24 2020 Phil Sutter - 1.8.4-14 +- nft: Fix for '-F' in iptables dumps +- tests: shell: Test -F in dump files + +* Fri May 29 2020 Phil Sutter - 1.8.4-13 +- Fix for endless loop in iptables-restore --test + +* Tue May 26 2020 Phil Sutter - 1.8.4-12 +- Unbreak nfnl_osf tool + +* Tue May 19 2020 Phil Sutter - 1.8.4-11 +- Complete ebtables-nft among match support +- Replace RHEL-only xtables-monitor fix with upstream solution +- xtables: Align effect of -4/-6 options with legacy +- xtables: Drop -4 and -6 support from xtables-{save,restore} +- Review systemd unit files + +* Tue Mar 17 2020 Phil Sutter - 1.8.4-10 +- Fix for iptables-restore segfault under pressure +- Fix for iptables-save segfault under pressure + +* Mon Feb 24 2020 Phil Sutter - 1.8.4-9 +- iptables-test.py: Fix --host mode +- xtables-monitor: Fix segfault when tracing + +* Sat Feb 15 2020 Phil Sutter - 1.8.4-8 +- xtables-translate: Fix for iface++ +- tests: shell: Fix skip checks with --host mode +- xtables-restore: fix for --noflush and empty lines + +* Wed Feb 12 2020 Phil Sutter - 1.8.4-7 +- xtables-translate: Fix for interface name corner-cases + +* Mon Dec 09 2019 Phil Sutter - 1.8.4-6 +- Add missing patch in last release, uAPI covscan fix + +* Mon Dec 09 2019 Phil Sutter - 1.8.4-5 +- Fix covscan-indicated problems + +* Wed Dec 04 2019 Phil Sutter - 1.8.4-4 +- Fix for broken xtables-restore --noflush + +* Tue Dec 03 2019 Phil Sutter - 1.8.4-3 +- Reduce globbing in library file names to expose future SONAME changes +- Add bootstrapping for libip*tc SONAME bump + +* Mon Dec 02 2019 Phil Sutter - 1.8.4-2 +- Use upstream-provided man pages for ebtables and arptables + +* Mon Dec 02 2019 Phil Sutter - 1.8.4-1 +- Rebase onto upstream release 1.8.4 + +* Thu Aug 08 2019 Phil Sutter - 1.8.2-16 +- nft: Set socket receive buffer + +* Wed Jul 31 2019 Phil Sutter - 1.8.2-15 +- doc: Install ip{6,}tables-restore-translate.8 man pages + +* Tue Jul 02 2019 Phil Sutter - 1.8.2-14 +- arptables: Print space before comma and counters +- extensions: Fix ipvs vproto parsing +- extensions: Fix ipvs vproto option printing +- extensions: Add testcase for libxt_ipvs + +* Mon Jul 01 2019 Phil Sutter - 1.8.2-13 +- doc: Install ip{6,}tables-translate.8 manpages +- nft: Eliminate dead code in __nft_rule_list + +* Wed Jun 12 2019 Phil Sutter - 1.8.2-12 +- Add iptables-test.py testsuite to sources +- extensions: libip6t_mh: fix bogus translation error +- extensions: AUDIT: Document ineffective --type option +- xtables-restore: Fix program names in help texts +- xtables-save: Point at existing man page in help text +- utils: Add a manpage for nfbpf_compile +- Mark man pages in base package as documentation files + +* Thu May 23 2019 Phil Sutter - 1.8.2-11 +- Enable verbose output when building + +* Thu May 09 2019 Phil Sutter - 1.8.2-10 +- arptables-nft: fix decoding of hlen on bigendian platforms +- xtables-save: Fix table not found error message +- xtables: Catch errors when zeroing rule rounters +- extensions: TRACE: Point at xtables-monitor in documentation +- extensions: libipt_realm: Document allowed realm values + +* Fri Feb 08 2019 Phil Sutter - 1.8.2-9 +- ebtables-nft: Support user-defined chain policies + +* Thu Feb 07 2019 Phil Sutter - 1.8.2-8 +- arptables.8: Document --set-counters option + +* Thu Feb 07 2019 Phil Sutter - 1.8.2-7 +- arptables: Support --set-counters option + +* Fri Feb 01 2019 Phil Sutter - 1.8.2-6 +- Improve performance with large rulesets +- Fix for changes in arptables output +- Fix for inserting rules at wrong position +- Fix segfault when comparing rules with standard target +- Fix ebtables output for negated values +- Document missing arptables FORWARD chain + +* Tue Dec 18 2018 Phil Sutter - 1.8.2-5 +- Drop change to test snippet not included in tarball from Patch4 + +* Tue Dec 18 2018 Phil Sutter - 1.8.2-4 +- Fix iptables init script for nftables-backend +- Drop references to unsupported broute table from ebtables man page +- xtables: Don't use native nftables comments + +* Thu Dec 06 2018 Phil Sutter - 1.8.2-3 +- Drop change to test snippet not included in tarball from Patch3 + +* Thu Dec 06 2018 Phil Sutter - 1.8.2-2 +- Point out that nftables-variants are installed in package description +- Fix for deleting arptables rules by referencing them + +* Thu Dec 06 2018 Phil Sutter - 1.8.2-1 +- Rebase onto upstream version 1.8.2 + +* Thu Oct 25 2018 Phil Sutter - 1.8.1-2 +- Add upstream fixes to 1.8.1 release + +* Thu Oct 25 2018 Phil Sutter - 1.8.1-1 +- Rebase onto upstream version 1.8.1 + +* Thu Sep 27 2018 Phil Sutter - 1.8.0-11 +- Fix for covscan warnings in init scripts + +* Wed Sep 26 2018 Phil Sutter - 1.8.0-10 +- Fix short name of Artistic Licence + +* Wed Sep 26 2018 Phil Sutter - 1.8.0-9 +- Add further fixes for issues identified by covscan +- Fix for bogus "is incompatible" warnings +- Fix layout in License tag +- Replace "Fedora" with "RHEL" in description +- Make devel sub-package depend on libs sub-package + +* Mon Sep 17 2018 Phil Sutter - 1.8.0-8 +- Fix issues identified by covscan +- xtables-restore: Fix flushing referenced custom chains +- xtables: Accept --wait in iptables-nft-restore + +* Mon Sep 03 2018 Phil Sutter - 1.8.0-7 +- xtables: Align return codes with legacy iptables +- xtables: Drop use of IP6T_F_PROTO + +* Wed Aug 29 2018 Phil Sutter - 1.8.0-6 +- xtables: Fix for deleting rules with comment + +* Fri Aug 24 2018 Phil Sutter - 1.8.0-5 +- xtables: Use meta l4proto for -p match +- ebtables: Fix for listing of non-existent chains +- xtables: Fix for no output in iptables-nft -S + +* Sat Aug 18 2018 Phil Sutter - 1.8.0-4 +- xtables: Fix for segfault in iptables-nft +- ebtables: Fix entries count in chain listing +- Use %%autosetup macro in %%prep + +* Fri Aug 17 2018 Phil Sutter - 1.8.0-3 +- xtables: Make 'iptables -S nonexisting' return non-zero + +* Fri Aug 10 2018 Phil Sutter - 1.8.0-2 +- Rebase onto upstream master commit 514de4801b731db4712 +- Add arptables and ebtables sub-packages + +* Wed Jul 11 2018 Phil Sutter - 1.8.0-1 +- New upstream version 1.8.0 +- Drop compat sub-package +- Use nft tool versions, drop legacy ones + +* Thu Mar 01 2018 Phil Sutter - 1.6.2-2 +- Kill module unloading support +- Support /etc/sysctl.d +- Don't restart services after package update +- Add support for --wait options to restore commands + +* Wed Feb 21 2018 Michael Cronenworth - 1.6.2-1 +- New upstream version 1.6.2 + http://www.netfilter.org/projects/iptables/files/changes-iptables-1.6.2.txt + +* Wed Feb 07 2018 Fedora Release Engineering - 1.6.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sun Oct 22 2017 Kevin Fenzi - 1.6.1-5 +- Rebuild for new libnftnl + +* Wed Aug 02 2017 Fedora Release Engineering - 1.6.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 1.6.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 1.6.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Feb 02 2017 Thomas Woerner - 1.6.1-1 +- New upstream version 1.6.1 with enhanced translation to nft support and + several fixes (RHBZ#1417323) + http://netfilter.org/projects/iptables/files/changes-iptables-1.6.1.txt +- Enable parallel build again + +* Thu Feb 02 2017 Petr Šabata - 1.6.0-4 +- Disabling parallel build to avoid build issues with xtables +- See http://patchwork.alpinelinux.org/patch/1787/ for reference +- This should be fixed in 1.6.1; parallel build can be restored after the + update + +* Mon Dec 19 2016 Thomas Woerner - 1.6.0-3 +- Dropped bad provides for iptables in services sub package (RHBZ#1327786) + +* Fri Jul 22 2016 Thomas Woerner - 1.6.0-2 +- /etc/ethertypes has been moved into the setup package for F-25+. + (RHBZ#1329256) + +* Wed Apr 13 2016 Thomas Woerner - 1.6.0-1 +- New upstream version 1.6.0 with nft-compat support and lots of fixes (RHBZ#1292990) + Upstream changelog: + http://netfilter.org/projects/iptables/files/changes-iptables-1.6.0.txt +- New libs sub package containing libxtables and unstable libip*tc libraries (RHBZ#1323161) +- Using scripts form RHEL-7 (RHBZ#1240366) +- New compat sub package for nftables compatibility +- Install iptables-apply (RHBZ#912047) +- Fixed module uninstall (RHBZ#1324101) +- Incorporated changes by Petr Pisar +- Enabled bpf compiler (RHBZ#1170227) Thanks to Yanko Kaneti for the patch + +* Thu Feb 04 2016 Fedora Release Engineering - 1.4.21-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 1.4.21-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Mon Dec 01 2014 Jiri Popelka - 1.4.21-14 +- add dhcpv6-client to /etc/sysconfig/ip6tables (RHBZ#1169036) + +* Mon Nov 03 2014 Jiri Popelka - 1.4.21-13 +- iptables.init: use /run/lock/subsys/ instead of /var/lock/subsys/ (RHBZ#1159573) + +* Mon Sep 29 2014 Jiri Popelka - 1.4.21-12 +- ip[6]tables.init: change shebang from /bin/sh to /bin/bash (RHBZ#1147272) + +* Sat Aug 16 2014 Fedora Release Engineering - 1.4.21-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jul 12 2014 Tom Callaway - 1.4.21-10 +- fix license handling + +* Sat Jun 07 2014 Fedora Release Engineering - 1.4.21-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed Mar 12 2014 Jiri Popelka - 1.4.21-8 +- add missing reload and panic actions +- BuildRequires: pkgconfig(x) instead of x-devel +- no need to specify file mode bits twice (in %%install and %%files) + +* Sun Jan 19 2014 Ville Skyttä - 1.4.21-7 +- Don't order services after syslog.target. + +* Wed Jan 15 2014 Thomas Woerner 1.4.21-6 +- Enable connlabel support again, needs libnetfilter_conntrack + +* Wed Jan 15 2014 Thomas Woerner 1.4.21-6 +- fixed update from RHEL-6 to RHEL-7 (RHBZ#1043901) + +* Tue Jan 14 2014 Jiri Popelka - 1.4.21-5 +- chmod /etc/sysconfig/ip[6]tables 755 -> 600 + +* Fri Jan 10 2014 Jiri Popelka - 1.4.21-4 +- drop virtual provide for xtables.so.9 +- add default /etc/sysconfig/ip[6]tables (RHBZ#1034494) + +* Thu Jan 09 2014 Jiri Popelka - 1.4.21-3 +- no need to support the pre-systemd things +- use systemd macros (#850166) +- remove scriptlets for migrating to a systemd unit from a SysV initscripts +- ./configure -> %%configure +- spec clean up +- fix self-obsoletion + +* Thu Jan 9 2014 Thomas Woerner 1.4.21-2 +- fixed system hang at shutdown if root device is network based (RHBZ#1007934) + Thanks to Rodrigo A B Freire for the patch + +* Thu Jan 9 2014 Thomas Woerner 1.4.21-1 +- no connlabel.conf upstream anymore +- new version 1.4.21 + - doc: clarify DEBUG usage macro + - iptables: use autoconf to process .in man pages + - extensions: libipt_ULOG: man page should mention NFLOG as replacement + - extensions: libxt_connlabel: use libnetfilter_conntrack + - Introduce a new revision for the set match with the counters support + - libxt_CT: Add the "NOTRACK" alias + - libip6t_mh: Correct command to list named mh types in manpage + - extensions: libxt_DNAT, libxt_REDIRECT, libxt_NETMAP, libxt_SNAT, libxt_MASQUERADE, libxt_LOG: rename IPv4 manpage and tell about IPv6 support + - extensions: libxt_LED: fix parsing of delay + - ip{6}tables-restore: fix breakage due to new locking approach + - libxt_recent: restore minimum value for --seconds + - iptables-xml: fix parameter parsing (similar to 2165f38) + - extensions: add copyright statements + - xtables: improve get_modprobe handling + - ip[6]tables: Add locking to prevent concurrent instances + - iptables: Fix connlabel.conf install location + - ip6tables: don't print out /128 + - libip6t_LOG: target output is different to libipt_LOG + - build: additional include path required after UAPI changes + - iptables: iptables-xml: Fix various parsing bugs + - libxt_recent: restore reap functionality to recent module + - build: fail in configure on missing dependency with --enable-bpf-compiler + - extensions: libxt_NFQUEUE: add --queue-cpu-fanout parameter + - extensions: libxt_set, libxt_SET: check the set family too + - ip6tables: Use consistent exit code for EAGAIN + - iptables: libxt_hashlimit.man: correct address + - iptables: libxt_conntrack.man extraneous commas + - iptables: libip(6)t_REJECT.man default icmp types + - iptables: iptables-xm1.1 correct man section + - iptables: libxt_recent.{c,man} dead URL + - iptables: libxt_string.man add examples + - extensions: libxt_LOG: use generic syslog reference in manpage + - iptables: extensions/GNUMakefile.in use CPPFLAGS + - iptables: correctly reference generated file + - ip[6]tables: fix incorrect alignment in commands_v_options + - build: add software version to manpage first line at configure stage + - extensions: libxt_cluster: add note on arptables-jf + - utils: nfsynproxy: fix error while compiling the BPF filter + - extensions: add SYNPROXY extension + - utils: add nfsynproxy tool + - iptables: state match incompatibilty across versions + - libxtables: xtables_ipmask_to_numeric incorrect with non-CIDR masks + - iptables: improve chain name validation + - iptables: spurious error in load_extension + - xtables: trivial spelling fix + +* Sun Dec 22 2013 Ville Skyttä - 1.4.19.1-2 +- Drop INSTALL from docs, escape macros in %%changelog. + +* Wed Jul 31 2013 Thomas Woerner 1.4.19.1-1 +- new version 1.4.19.1 + - libxt_NFQUEUE: fix bypass option documentation + - extensions: add connlabel match + - extensions: add connlabel match + - ip[6]tables: show --protocol instead of --proto in usage + - libxt_recent: Fix missing space in manpage for --mask option + - extensions: libxt_multiport: Update manpage to list valid protocols + - utils: nfnl_osf: use the right nfnetlink lib + - libip6t_NETMAP: Use xtables_ip6mask_to_cidr and get rid of libip6tc dependency + - Revert "build: resolve link failure for ip6t_NETMAP" + - libxt_osf: fix missing --ttl and --log in save output + - libxt_osf: fix bad location for location in --genre + - libip6t_SNPT: add manpage + - libip6t_DNPT: add manpage + - utils: updates .gitignore to include nfbpf_compile + - extensions: libxt_bpf: clarify --bytecode argument + - libxtables: fix parsing of dotted network mask format + - build: bump version to 1.4.19 + - libxt_conntrack: fix state match alias state parsing + - extensions: add libxt_bpf extension + - utils: nfbpf_compile + - doc: mention SNAT in INPUT chain since kernel 2.6.36 +- fixed changelog date weekdays where needed + +* Mon Mar 4 2013 Thomas Woerner 1.4.18-1 +- new version 1.4.18 + - lots of documentation changes + - Introduce match/target aliases + - Add the "state" alias to the "conntrack" match + - iptables: remove unused leftover definitions + - libxtables: add xtables_rule_matches_free + - libxtables: add xtables_print_num + - extensions: libip6t_DNPT: fix wording in DNPT target + - extension: libip6t_DNAT: allow port DNAT without address + - extensions: libip6t_DNAT: set IPv6 DNAT --to-destination + - extensions: S/DNPT: add missing save function +- changes of 1.4.17: + - libxt_time: add support to ignore day transition + - Convert the NAT targets to use the kernel supplied nf_nat.h header + - extensions: add IPv6 MASQUERADE extension + - extensions: add IPv6 SNAT extension + - extensions: add IPv6 DNAT target + - extensions: add IPv6 REDIRECT extension + - extensions: add IPv6 NETMAP extension + - extensions: add NPT extension + - extensions: libxt_statistic: Fix save output + +* Thu Feb 14 2013 Fedora Release Engineering - 1.4.16.2-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Jan 16 2013 Ville Skyttä - 1.4.16.2-6 +- Own unowned -services libexec dirs (#894464, Michael Scherer). +- Fix -services unit file permissions (#732936, Michal Schmidt). + +* Thu Nov 8 2012 Thomas Woerner 1.4.16.2-5 +- fixed path of ip6tables.init in ip6tables.service + +* Fri Nov 2 2012 Thomas Woerner 1.4.16.2-4 +- fixed missing services for update of pre F-18 installations (rhbz#867960) + - provide and obsolete old main package in services sub package + - provide and obsolete old ipv6 sub package (pre F-17) in services sub package + +* Sun Oct 14 2012 Dan Horák 1.4.16.2-3 +- fix the compat provides for all 64-bit arches + +* Fri Oct 12 2012 Thomas Woerner 1.4.16.2-2 +- new sub package services providing the systemd services (RHBZ#862922) +- new sub package utils: provides nfnl_osf and the pf.os database +- using %%{_libexecdir}/iptables as script path for the original init scripts +- added service iptables save funcitonality using the new way provided by + initscripts 9.37.1 (RHBZ#748134) +- added virtual provide for libxtables.so.7 + +* Mon Oct 8 2012 Thomas Woerner 1.4.16.2-1 +- new version 1.4.16.2 + - build: support for automake-1.12 + - build: separate AC variable replacements from xtables.h + - build: have `make clean` remove dep files too + - doc: grammatical updates to libxt_SET + - doc: clean up interpunction in state list for xt_conntrack + - doc: deduplicate extension descriptions into a new manpage + - doc: trim "state" manpage and reference conntrack instead + - doc: have NOTRACK manpage point to CT instead + - doc: mention iptables-apply in the SEE ALSO sections + - extensions: libxt_addrtype: fix type in help message + - include: add missing linux/netfilter_ipv4/ip_queue.h + - iptables: fix wrong error messages + - iptables: support for match aliases + - iptables: support for target aliases + - iptables-restore: warn about -t in rule lines + - ip[6]tables-restore: cleanup to reduce one level of indentation + - libip6t_frag: match any frag id by default + - libxtables: consolidate preference logic + - libxt_devgroup: consolidate devgroup specification parsing + - libxt_devgroup: guard against negative numbers + - libxt_LED: guard against negative numbers + - libxt_NOTRACK: replace as an alias to CT --notrack + - libxt_state: replace as an alias to xt_conntrack + - libxt_tcp: print space before, not after "flags:" + - libxt_u32: do bounds checking for @'s operands + - libxt_*limit: avoid division by zero + - Merge branch 'master' of git://git.inai.de/iptables + - Merge remote-tracking branch 'nf/stable' + - New set match revision with --return-nomatch flag support +- dropped fixrestore patch, upstream + +* Wed Aug 1 2012 Thomas Woerner 1.4.15-1 +- new version 1.4.15 + - extensions: add HMARK target + - iptables-restore: fix parameter parsing (shows up with gcc-4.7) + - iptables-restore: move code to add_param_to_argv, cleanup (fix gcc-4.7) + - libxtables: add xtables_ip[6]mask_to_cidr + - libxt_devgroup: add man page snippet + - libxt_hashlimit: add support for byte-based operation + - libxt_recent: add --mask netmask + - libxt_recent: remove unused variable + - libxt_HMARK: correct a number of errors introduced by Pablo's rework + - libxt_HMARK: fix ct case example + - libxt_HMARK: fix output of iptables -L + - Revert "iptables-restore: move code to add_param_to_argv, cleanup (fix gcc-4.7)" + +* Wed Jul 18 2012 Thomas Woerner 1.4.14-3 +- added fixrestore patch submitted to upstream by fryasu (nfbz#774) + (RHBZ#825796) + +* Wed Jul 18 2012 Thomas Woerner 1.4.14-2 +- disabled libipq, removed upstream, not provided by kernel anymore + +* Wed Jul 18 2012 Thomas Woerner 1.4.14-1 +- new version 1.4.14 + - extensions: add IPv6 capable ECN match extension + - extensions: add nfacct match + - extensions: add rpfilter module + - extensions: libxt_rateest: output all options in save hook + - iptables: missing free() in function cache_add_entry() + - iptables: missing free() in function delete_entry() + - libiptc: fix retry path in TC_INIT + - libiptc: Returns the position the entry was inserted + - libipt_ULOG: fix --ulog-cprange + - libxt_CT: add --timeout option + - ip(6)tables-restore: make sure argv is NULL terminated + - Revert "libiptc: Returns the position the entry was inserted" + - src: mark newly opened fds as FD_CLOEXEC (close on exec) + - tests: add rateest match rules +- dropped patch5 (cloexec), merged upstream + +* Mon Apr 23 2012 Thomas Woerner 1.4.12.2-5 +- reenable iptables default services + +* Wed Feb 29 2012 Harald Hoyer 1.4.12.2-4 +- install everything in /usr + https://fedoraproject.org/wiki/Features/UsrMove + +* Thu Feb 16 2012 Thomas Woerner 1.4.12.2-3 +- fixed auto enable check for Fedora > 16 and added rhel > 6 check + +* Wed Feb 15 2012 Thomas Woerner 1.4.12.2-2 +- disabled autostart and auto enable for iptables.service and ip6tables.service + for Fedora > 16 + +* Mon Jan 16 2012 Thomas Woerner 1.4.12.2-1 +- new version 1.4.12.2 with new pkgconfig/libip4tc.pc and pkgconfig/libip6tc.pc + - build: make check stage not fail when building statically + - build: restore build order of modules + - build: scan for unreferenced symbols + - build: sort file list before build + - doc: clarification on the meaning of -p 0 + - doc: document iptables-restore's -T option + - doc: fix undesired newline in ip6tables-restore(8) + - ip6tables-restore: implement missing -T option + - iptables: move kernel version find routing into libxtables + - libiptc: provide separate pkgconfig files + - libipt_SAME: set PROTO_RANDOM on all ranges + - libxtables: Fix file descriptor leak in xtables_lmap_init on error + - libxt_connbytes: fix handling of --connbytes FROM + - libxt_CONNSECMARK: fix spacing in output + - libxt_conntrack: improve error message on parsing violation + - libxt_NFQUEUE: fix --queue-bypass ipt-save output + - libxt_RATEEST: link with -lm + - libxt_statistic: link with -lm + - Merge branch 'stable' + - Merge branch 'stable' of git://dev.medozas.de/iptables + - nfnl_osf: add missing libnfnetlink_CFLAGS to compile process + - xtoptions: fill in fallback value for nvals + - xtoptions: simplify xtables_parse_interface + +* Fri Jan 13 2012 Fedora Release Engineering - 1.4.12.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Dec 12 2011 Thomas Woerner 1.4.12.1-1 +- new version 1.4.12.1 with new pkgconfig/libipq.pc + - build: abort autogen on subcommand failure + - build: strengthen check for overlong lladdr components + - build: workaround broken linux-headers on RHEL-5 + - doc: clarify libxt_connlimit defaults + - doc: fix typo in libxt_TRACE + - extensions: use multi-target registration + - libip6t_dst: restore setting IP6T_OPTS_LEN flag + - libip6t_frag: restore inversion support + - libip6t_hbh: restore setting IP6T_OPTS_LEN flag + - libipq: add pkgconfig file + - libipt_ttl: document that negation is available + - libxt_conntrack: fix --ctproto 0 output + - libxt_conntrack: remove one misleading comment + - libxt_dccp: fix deprecated intrapositional ordering of ! + - libxt_dccp: fix random output of ! on --dccp-option + - libxt_dccp: provide man pages options in short help too + - libxt_dccp: restore missing XTOPT_INVERT tags for options + - libxt_dccp: spell out option name on save + - libxt_dscp: restore inversion support + - libxt_hashlimit: default htable-expire must be in milliseconds + - libxt_hashlimit: observe new default gc-expire time when saving + - libxt_hashlimit: remove inversion from hashlimit rev 0 + - libxt_owner: restore inversion support + - libxt_physdev: restore inversion support + - libxt_policy: remove superfluous inversion + - libxt_set: put differing variable names in directly + - libxt_set: update man page about kernel support on the feature + - libxt_string: define _GNU_SOURCE for strnlen + - libxt_string: escape the escaping char too + - libxt_string: fix space around arguments + - libxt_string: replace hex codes by char equivalents + - libxt_string: simplify hex output routine + - libxt_tcp: always print the mask parts + - libxt_TCPMSS: restore build with IPv6-less libcs + - libxt_TOS: update linux kernel version list for backported fix + - libxt_u32: fix missing allowance for inversion + - src: remove unused IPTABLES_MULTI define + - tests: add negation tests for libxt_statistic + - xtoptions: flag use of XTOPT_POINTER without XTOPT_PUT +- removed include/linux/types.h before build to be able to compile + +* Tue Jul 26 2011 Thomas Woerner 1.4.12-2 +- dropped temporary provide again + +* Tue Jul 26 2011 Thomas Woerner 1.4.12-1.1 +- added temporary provides for libxtables.so.6 to be able to rebuild iproute, + which is part of the standard build environment + +* Mon Jul 25 2011 Thomas Woerner 1.4.12-1 +- new version 1.4.12 with support of all new features of kernel 3.0 + - build: attempt to fix building under Linux 2.4 + - build: bump soversion for recent data structure change + - build: install modules in arch-dependent location + - doc: fix group range in libxt_NFLOG's man + - doc: fix version string in ip6tables.8 + - doc: include matches/targets in manpage again + - doc: mention multiple verbosity flags + - doc: the -m option cannot be inverted + - extensions: support for per-extension instance global variable space + - iptables-apply: select default rule file depending on call name + - iptables: consolidate target/match init call + - iptables: Coverity: DEADCODE + - iptables: Coverity: NEGATIVE_RETURNS + - iptables: Coverity: RESOURCE_LEAK + - iptables: Coverity: REVERSE_INULL + - iptables: Coverity: VARARGS + - iptables: restore negation for -f + - libip6t_HL: fix option names from ttl -> hl + - libipt_LOG: fix ignoring all but last flags + - libxtables: ignore whitespace in the multiaddress argument parser + - libxtables: properly reject empty hostnames + - libxtables: set clone's initial data to NULL + - libxt_conntrack: move more data into the xt_option_entry + - libxt_conntrack: restore network-byte order for v1,v2 + - libxt_hashlimit: use a more obvious expiry value by default + - libxt_rateest: abolish global variables + - libxt_RATEEST: abolish global variables + - libxt_RATEEST: fix userspacesize field + - libxt_RATEEST: use guided option parser + - libxt_state: fix regression about inversion of main option + - option: remove last traces of intrapositional negation +- complete changelog: + http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.12.txt + +* Thu Jul 21 2011 Thomas Woerner 1.4.11.1-4 +- merged ipv6 sub package into main package +- renamed init scripts to /usr/libexec/ip*tables.init + +* Fri Jul 15 2011 Thomas Woerner 1.4.11.1-3 +- added support for native systemd file (rhbz#694738) + - new iptables.service file + - additional requires + - moved sysv init scripts to /usr/libexec + - added new post, preun and postun scripts and triggers + +* Tue Jul 12 2011 Thomas Woerner 1.4.11.1-2 +- dropped temporary provide again +- enabled smp build + +* Tue Jul 12 2011 Thomas Woerner 1.4.11.1-1.1 +- added temporary provides for libxtables.so.5 to be able to rebuild iproute, + which is part of the standard build environment + +* Mon Jul 11 2011 Thomas Woerner 1.4.11.1-1 +- new version 1.4.11.1, bug and doc fix release for 1.4.11 + +* Tue Jun 7 2011 Thomas Woerner 1.4.11-1 +- new version 1.4.11 with all new features of 2.6.37-39 (not usable) + - lots of changes and bugfixes for base and extensions + - complete changelog: + http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.11.txt + +* Wed Feb 09 2011 Fedora Release Engineering - 1.4.10-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jan 10 2011 Thomas Woerner 1.4.10-1 +- new version 1.4.10 with all new features of 2.6.36 + - all: consistent syntax use in struct option + - build: fix static linking + - doc: let man(1) autoalign the text in xt_cpu + - doc: remove extra empty line from xt_cpu + - doc: minimal spelling updates to xt_cpu + - doc: consistent use of markup + - extensions: libxt_quota: don't ignore the quota value on deletion + - extensions: REDIRECT: add random help + - extensions: add xt_cpu match + - extensions: add idletimer xt target extension + - extensions: libxt_IDLETIMER: use xtables_param_act when checking options + - extensions: libxt_CHECKSUM extension + - extensions: libipt_LOG/libip6t_LOG: support macdecode option + - extensions: fix compilation of the new CHECKSUM target + - extensions: libxt_ipvs: user-space lib for netfilter matcher xt_ipvs + - iptables-xml: resolve compiler warnings + - iptables: limit chain name length to be consistent with targets + - libiptc: add Libs.private to pkgconfig files + - libiptc: build with -Wl,--no-as-needed + - xtables: remove unnecessary cast +- dropped xt_CHECKSUM, added upstream + +* Tue Oct 12 2010 Thomas Woerner 1.4.9-2 +- added xt_CHECKSUM patch from Michael S. Tsirkin (rhbz#612587) + +* Wed Aug 4 2010 Thomas Woerner 1.4.9-1 +- new version 1.4.9 with all new features of 2.6.35 + - doc: xt_hashlimit: fix a typo + - doc: xt_LED: nroff formatting requirements + - doc: xt_string: correct copy-and-pasting in manpage + - extensions: add the LED target + - extensions: libxt_quota.c: Support option negation + - extensions: libxt_rateest: fix bps options for iptables-save + - extensions: libxt_rateest: fix typo in the man page + - extensions: REDIRECT: add random help + - includes: sync header files from Linux 2.6.35-rc1 + - libxt_conntrack: do print netmask + - libxt_hashlimit: always print burst value + - libxt_set: new revision added + - utils: add missing include flags to Makefile + - xtables: another try at chain name length checking + - xtables: remove xtables_set_revision function + - xt_quota: also document negation + - xt_sctp: Trace DATA chunk that supports SACK-IMMEDIATELY extension + - xt_sctp: support FORWARD_TSN chunk type + +* Fri Jul 2 2010 Thomas Woerner 1.4.8-1 +- new version 1.4.8 all new features of 2.6.34 (rhbz#) + - extensions: REDIRECT: fix --to-ports parser + - iptables: add noreturn attribute to exit_tryhelp() + - extensions: MASQUERADE: fix --to-ports parser + - libxt_comment: avoid use of IPv4-specific examples + - libxt_CT: add a manpage + - iptables: correctly check for too-long chain/target/match names + - doc: libxt_MARK: no longer restricted to mangle table + - doc: remove claim that TCPMSS is limited to mangle + - libxt_recent: add a missing space in output + - doc: add manpage for libxt_osf + - libxt_osf: import nfnl_osf program + - extensions: add support for xt_TEE + - CT: fix --ctevents parsing + - extensions: add CT extension + - libxt_CT: print conntrack zone in ->print/->save + - xtables: fix compilation when debugging is enabled + - libxt_conntrack: document --ctstate UNTRACKED + - iprange: fix xt_iprange v0 parsing + +* Wed Mar 24 2010 Thomas Woerner 1.4.7-2 +- added default values for IPTABLES_STATUS_VERBOSE and + IPTABLES_STATUS_LINENUMBERS in init script +- added missing lsb keywords Required-Start and Required-Stop to init script + +* Fri Mar 5 2010 Thomas Woerner 1.4.7-1 +- new version 1.4.7 with support for all new features of 2.6.33 (rhbz#570767) + - libip4tc: Add static qualifier to dump_entry() + - libipq: build as shared library + - recent: reorder cases in code (cosmetic cleanup) + - several man page and documentation fixes + - policy: fix error message showing wrong option + - includes: header updates + - Lift restrictions on interface names +- fixed license and moved iptables-xml into base package according to review + +* Wed Jan 27 2010 Thomas Woerner 1.4.6-2 +- moved libip*tc and libxtables libs to /lib[64], added symlinks for .so libs + to /usr/lib[64] for compatibility (rhbz#558796) + +* Wed Jan 13 2010 Thomas Woerner 1.4.6-1 +- new version 1.4.6 with support for all new features of 2.6.32 + - several man page fixes + - Support for nommu arches + - realm: remove static initializations + - libiptc: remove unused functions + - libiptc: avoid strict-aliasing warnings + - iprange: do accept non-ranges for xt_iprange v1 + - iprange: warn on reverse range + - iprange: roll address parsing into a loop + - iprange: do accept non-ranges for xt_iprange v1 (log) + - iprange: warn on reverse range (log) + - libiptc: fix wrong maptype of base chain counters on restore + - iptables: fix undersized deletion mask creation + - style: reduce indent in xtables_check_inverse + - libxtables: hand argv to xtables_check_inverse + - iptables/extensions: make bundled options work again + - CONNMARK: print mark rules with mask 0xffffffff as set instead of xset + - iptables: take masks into consideration for replace command + - doc: explain experienced --hitcount limit + - doc: name resolution clarification + - iptables: expose option to zero packet/byte counters for a specific rule + - build: restore --disable-ipv6 functionality on system w/o v6 headers + - MARK: print mark rules with mask 0xffffffff as --set-mark instead of --set-xmark + - DNAT: fix incorrect check during parsing + - extensions: add osf extension + - conntrack: fix --expires parsing + +* Thu Dec 17 2009 Thomas Woerner 1.4.5-2 +- dropped nf_ext_init remains from cloexec patch + +* Thu Sep 17 2009 Thomas Woerner 1.4.5-1 +- new version 1.4.5 with support for all new features of 2.6.31 + - libxt_NFQUEUE: add new v1 version with queue-balance option + - xt_conntrack: revision 2 for enlarged state_mask member + - libxt_helper: fix invalid passed option to check_inverse + - libiptc: split v4 and v6 + - extensions: collapse registration structures + - iptables: allow for parse-less extensions + - iptables: allow for help-less extensions + - extensions: remove empty help and parse functions + - xtables: add multi-registration functions + - extensions: collapse data variables to use multi-reg calls + - xtables: warn of missing version identifier in extensions + - multi binary: allow subcommand via argv[1] + - iptables: accept multiple IP address specifications for -s, -d + - several build fixes + - several man page fixes +- fixed two leaked file descriptors on sockets (rhbz#521397) + +* Mon Aug 24 2009 Thomas Woerner 1.4.4-1 +- new version 1.4.4 with support for all new features of 2.6.30 + - several man page fixes + - iptables: replace open-coded sizeof by ARRAY_SIZE + - libip6t_policy: remove redundant functions + - policy: use direct xt_policy_info instead of ipt/ip6t + - policy: merge ipv6 and ipv4 variant + - extensions: add `cluster' match support + - extensions: add const qualifiers in print/save functions + - extensions: use NFPROTO_UNSPEC for .family field + - extensions: remove redundant casts + - iptables: close open file descriptors + - fix segfault if incorrect protocol name is used + - replace open-coded sizeof by ARRAY_SIZE + - do not include v4-only modules in ip6tables manpage + - use direct xt_policy_info instead of ipt/ip6t + - xtables: fix segfault if incorrect protocol name is used + - libxt_connlimit: initialize v6_mask + - SNAT/DNAT: add support for persistent multi-range NAT mappings + +* Fri Jul 24 2009 Fedora Release Engineering - 1.4.3.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Apr 15 2009 Thomas Woerner 1.4.3.2-1 +- new version 1.4.3.2 +- also install iptables/internal.h, needed for iptables.h and ip6tables.h + +* Mon Mar 30 2009 Thomas Woerner 1.4.3.1-1 +- new version 1.4.3.1 + - libiptc is now shared + - supports all new features of the 2.6.29 kernel +- dropped typo_latter patch + +* Thu Mar 5 2009 Thomas Woerner 1.4.2-3 +- still more review fixes (rhbz#225906) + - consistent macro usage + - use sed instead of perl for rpath removal + - use standard RPM CFLAGS, but also -fno-strict-aliasing (needed for libiptc*) + +* Wed Feb 25 2009 Fedora Release Engineering - 1.4.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Feb 20 2009 Thomas Woerner 1.4.2-1 +- new version 1.4.2 +- removed TOS value mask patch (upstream) +- more review fixes (rhbz#225906) +- install all header files (rhbz#462207) +- dropped nf_ext_init (rhbz#472548) + +* Tue Jul 22 2008 Thomas Woerner 1.4.1.1-2 +- fixed TOS value mask problem (rhbz#456244) (upstream patch) +- two more cloexec fixes + +* Tue Jul 1 2008 Thomas Woerner 1.4.1.1-1 +- upstream bug fix release 1.4.1.1 +- dropped extra patch for 1.4.1 - not needed anymore + +* Tue Jun 10 2008 Thomas Woerner 1.4.1-1 +- new version 1.4.1 with new build environment +- additional ipv6 network mask patch from Jan Engelhardt +- spec file cleanup +- removed old patches + +* Fri Jun 6 2008 Tom "spot" Callaway 1.4.0-5 +- use normal kernel headers, not linux/compiler.h +- change BuildRequires: kernel-devel to kernel-headers +- We need to do this to be able to build for both sparcv9 and sparc64 + (there is no kernel-devel.sparcv9) + +* Thu Mar 20 2008 Thomas Woerner 1.4.0-4 +- use O_CLOEXEC for all opened files in all applications (rhbz#438189) + +* Mon Mar 3 2008 Thomas Woerner 1.4.0-3 +- use the kernel headers from the build tree for iptables for now to be able to + compile this package, but this makes the package more kernel dependant +- use s6_addr32 instead of in6_u.u6_addr32 + +* Wed Feb 20 2008 Fedora Release Engineering - 1.4.0-2 +- Autorebuild for GCC 4.3 + +* Mon Feb 11 2008 Thomas Woerner 1.4.0-1 +- new version 1.4.0 +- fixed condrestart (rhbz#428148) +- report the module in rmmod_r if there is an error +- use nf_ext_init instead of my_init for extension constructors + +* Mon Nov 5 2007 Thomas Woerner 1.3.8-6 +- fixed leaked file descriptor before fork/exec (rhbz#312191) +- blacklisting is not working, use "install X /bin/(true|false)" test instead +- return private exit code 150 for disabled ipv6 support +- use script name for output messages + +* Tue Oct 16 2007 Thomas Woerner 1.3.8-5 +- fixed error code for stopping a already stopped firewall (rhbz#321751) +- moved blacklist test into start + +* Wed Sep 26 2007 Thomas Woerner 1.3.8-4.1 +- do not start ip6tables if ipv6 is blacklisted (rhbz#236888) +- use simpler fix for (rhbz#295611) + Thanks to Linus Torvalds for the patch. + +* Mon Sep 24 2007 Thomas Woerner 1.3.8-4 +- fixed IPv6 reject type (rhbz#295181) +- fixed init script: start, stop and status +- support netfilter compiled into kernel in init script (rhbz#295611) +- dropped inversion for limit modules from man pages (rhbz#220780) +- fixed typo in ip6tables man page (rhbz#236185) + +* Wed Sep 19 2007 Thomas Woerner 1.3.8-3 +- do not depend on local_fs in lsb header - this delayes start after network +- fixed exit code for initscript usage + +* Mon Sep 17 2007 Thomas Woerner 1.3.8-2.1 +- do not use lock file for condrestart test + +* Thu Aug 23 2007 Thomas Woerner 1.3.8-2 +- fixed initscript for LSB conformance (rhbz#246953, rhbz#242459) +- provide iptc interface again, but unsupported (rhbz#216733) +- compile all extension, which are supported by the kernel-headers package +- review fixes (rhbz#225906) + +* Tue Jul 31 2007 Thomas Woerner +- reverted ipv6 fix, because it disables the ipv6 at all (rhbz#236888) + +* Fri Jul 13 2007 Steve Conklin - 1.3.8-1 +- New version 1.3.8 + +* Mon Apr 23 2007 Jeremy Katz - 1.3.7-2 +- fix error when ipv6 support isn't loaded in the kernel (#236888) + +* Wed Jan 10 2007 Thomas Woerner 1.3.7-1.1 +- fixed installation of secmark modules + +* Tue Jan 9 2007 Thomas Woerner 1.3.7-1 +- new verison 1.3.7 +- iptc is not a public interface and therefore not installed anymore +- dropped upstream secmark patch + +* Tue Sep 19 2006 Thomas Woerner 1.3.5-2 +- added secmark iptables patches (#201573) + +* Wed Jul 12 2006 Jesse Keating - 1.3.5-1.2.1 +- rebuild + +* Fri Feb 10 2006 Jesse Keating - 1.3.5-1.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 1.3.5-1.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Feb 2 2006 Thomas Woerner 1.3.5-1 +- new version 1.3.5 +- fixed init script to set policy for raw tables, too (#179094) + +* Tue Jan 24 2006 Thomas Woerner 1.3.4-3 +- added important iptables header files to devel package + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Fri Nov 25 2005 Thomas Woerner 1.3.4-2 +- fix for plugin problem: link with "gcc -shared" instead of "ld -shared" and + replace "_init" with "__attribute((constructor)) my_init" + +* Fri Nov 25 2005 Thomas Woerner 1.3.4-1.1 +- rebuild due to unresolved symbols in shared libraries + +* Fri Nov 18 2005 Thomas Woerner 1.3.4-1 +- new version 1.3.4 +- dropped free_opts patch (upstream fixed) +- made libipq PIC (#158623) +- additional configuration options for iptables startup script (#172929) + Thanks to Jan Gruenwald for the patch +- spec file cleanup (dropped linux_header define and usage) + +* Mon Jul 18 2005 Thomas Woerner 1.3.2-1 +- new version 1.3.2 with additional patch for the misplaced free_opts call + from Marcus Sundberg + +* Wed May 11 2005 Thomas Woerner 1.3.1-1 +- new version 1.3.1 + +* Fri Mar 18 2005 Thomas Woerner 1.3.0-2 +- Remove unnecessary explicit kernel dep (#146142) +- Fixed out of bounds accesses (#131848): Thanks to Steve Grubb + for the patch +- Adapted iptables-config to reference to modprobe.conf (#150143) +- Remove misleading message (#140154): Thanks to Ulrich Drepper + for the patch + +* Mon Feb 21 2005 Thomas Woerner 1.3.0-1 +- new version 1.3.0 + +* Thu Nov 11 2004 Thomas Woerner 1.2.11-3.2 +- fixed autoload problem in iptables and ip6tables (CAN-2004-0986) + +* Fri Sep 17 2004 Thomas Woerner 1.2.11-3.1 +- changed default behaviour for IPTABLES_STATUS_NUMERIC to "yes" (#129731) +- modified config file to match this change and un-commented variables with + default values + +* Thu Sep 16 2004 Thomas Woerner 1.2.11-3 +- applied second part of cleanup patch from (#131848): thanks to Steve Grubb + for the patch + +* Wed Aug 25 2004 Thomas Woerner 1.2.11-2 +- fixed free bug in iptables (#128322) + +* Tue Jun 22 2004 Thomas Woerner 1.2.11-1 +- new version 1.2.11 + +* Thu Jun 17 2004 Thomas Woerner 1.2.10-1 +- new version 1.2.10 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Thu Feb 26 2004 Thomas Woerner 1.2.9-2.3 +- fixed iptables-restore -c fault if there are no counters (#116421) + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Sun Jan 25 2004 Dan Walsh 1.2.9-1.2 +- Close File descriptors to prevent SELinux error message + +* Wed Jan 7 2004 Thomas Woerner 1.2.9-1.1 +- rebuild + +* Wed Dec 17 2003 Thomas Woerner 1.2.9-1 +- vew version 1.2.9 +- new config options in ipXtables-config: + IPTABLES_MODULES_UNLOAD +- more documentation in ipXtables-config +- fix for netlink security issue in libipq (devel package) +- print fix for libipt_icmp (#109546) + +* Thu Oct 23 2003 Thomas Woerner 1.2.8-13 +- marked all messages in iptables init script for translation (#107462) +- enabled devel package (#105884, #106101) +- bumped build for fedora for libipt_recent.so (#106002) + +* Tue Sep 23 2003 Thomas Woerner 1.2.8-12.1 +- fixed lost udp port range in ip6tables-save (#104484) +- fixed non numeric multiport port output in ipXtables-savs + +* Mon Sep 22 2003 Florian La Roche 1.2.8-11 +- do not link against -lnsl + +* Wed Sep 17 2003 Thomas Woerner 1.2.8-10 +- made variables in rmmod_r local + +* Tue Jul 22 2003 Thomas Woerner 1.2.8-9 +- fixed permission for init script + +* Sat Jul 19 2003 Thomas Woerner 1.2.8-8 +- fixed save when iptables file is missing and iptables-config permissions + +* Tue Jul 8 2003 Thomas Woerner 1.2.8-7 +- fixes for ip6tables: module unloading, setting policy only for existing + tables + +* Thu Jul 3 2003 Thomas Woerner 1.2.8-6 +- IPTABLES_SAVE_COUNTER defaults to no, now +- install config file in /etc/sysconfig +- exchange unload of ip_tables and ip_conntrack +- fixed start function + +* Wed Jul 2 2003 Thomas Woerner 1.2.8-5 +- new config option IPTABLES_SAVE_ON_RESTART +- init script: new status, save and restart +- fixes #44905, #65389, #80785, #82860, #91040, #91560 and #91374 + +* Mon Jun 30 2003 Thomas Woerner 1.2.8-4 +- new config option IPTABLES_STATUS_NUMERIC +- cleared IPTABLES_MODULES in iptables-config + +* Mon Jun 30 2003 Thomas Woerner 1.2.8-3 +- new init scripts + +* Sat Jun 28 2003 Florian La Roche +- remove check for very old kernel versions in init scripts +- sync up both init scripts and remove some further ugly things +- add some docu into rpm + +* Thu Jun 26 2003 Thomas Woerner 1.2.8-2 +- rebuild + +* Mon Jun 16 2003 Thomas Woerner 1.2.8-1 +- update to 1.2.8 + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Mon Jan 13 2003 Bill Nottingham 1.2.7a-1 +- update to 1.2.7a +- add a plethora of bugfixes courtesy Michael Schwendt + +* Fri Dec 13 2002 Elliot Lee 1.2.6a-3 +- Fix multilib + +* Wed Aug 07 2002 Karsten Hopp +- fixed iptables and ip6tables initscript output, based on #70511 +- check return status of all iptables calls, not just the last one + in a 'for' loop. + +* Mon Jul 29 2002 Bernhard Rosenkraenzer 1.2.6a-1 +- 1.2.6a (bugfix release, #69747) + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Thu May 23 2002 Tim Powers +- automated rebuild + +* Mon Mar 4 2002 Bernhard Rosenkraenzer 1.2.5-3 +- Add some fixes from CVS, fixing bug #60465 + +* Tue Feb 12 2002 Bernhard Rosenkraenzer 1.2.5-2 +- Merge ip6tables improvements from Ian Prowell + #59402 +- Update URL (#59354) +- Use /sbin/chkconfig rather than chkconfig in %%postun script + +* Fri Jan 11 2002 Bernhard Rosenkraenzer 1.2.5-1 +- 1.2.5 + +* Wed Jan 09 2002 Tim Powers +- automated rebuild + +* Mon Nov 5 2001 Bernhard Rosenkraenzer 1.2.4-2 +- Fix %%preun script + +* Tue Oct 30 2001 Bernhard Rosenkraenzer 1.2.4-1 +- Update to 1.2.4 (various fixes, including security fixes; among others: + #42990, #50500, #53325, #54280) +- Fix init script (#31133) + +* Mon Sep 3 2001 Bernhard Rosenkraenzer 1.2.3-1 +- 1.2.3 (5 security fixes, some other fixes) +- Fix updating (#53032) + +* Mon Aug 27 2001 Bernhard Rosenkraenzer 1.2.2-4 +- Fix #50990 +- Add some fixes from current CVS; should fix #52620 + +* Mon Jul 16 2001 Bernhard Rosenkraenzer 1.2.2-3 +- Add some fixes from the current CVS tree; fixes #49154 and some IPv6 + issues + +* Tue Jun 26 2001 Bernhard Rosenkraenzer 1.2.2-2 +- Fix iptables-save reject-with (#45632), Patch from Michael Schwendt + + +* Tue May 8 2001 Bernhard Rosenkraenzer 1.2.2-1 +- 1.2.2 + +* Wed Mar 21 2001 Bernhard Rosenkraenzer +- 1.2.1a, fixes #28412, #31136, #31460, #31133 + +* Thu Mar 1 2001 Bernhard Rosenkraenzer +- Yet another initscript fix (#30173) +- Fix the fixes; they fixed some issues but broke more important + stuff :/ (#30176) + +* Tue Feb 27 2001 Bernhard Rosenkraenzer +- Fix up initscript (#27962) +- Add fixes from CVS to iptables-{restore,save}, fixing #28412 + +* Fri Feb 09 2001 Karsten Hopp +- create /etc/sysconfig/iptables mode 600 (same problem as #24245) + +* Mon Feb 05 2001 Karsten Hopp +- fix bugzilla #25986 (initscript not marked as config file) +- fix bugzilla #25962 (iptables-restore) +- mv chkconfig --del from postun to preun + +* Thu Feb 1 2001 Trond Eivind Glomsrød +- Fix check for ipchains + +* Mon Jan 29 2001 Bernhard Rosenkraenzer +- Some fixes to init scripts + +* Wed Jan 24 2001 Bernhard Rosenkraenzer +- Add some fixes from CVS, fixes among other things Bug #24732 + +* Wed Jan 17 2001 Bernhard Rosenkraenzer +- Add missing man pages, fix up init script (Bug #17676) + +* Mon Jan 15 2001 Bill Nottingham +- add init script + +* Mon Jan 15 2001 Bernhard Rosenkraenzer +- 1.2 +- fix up ipv6 split +- add init script +- Move the plugins from /usr/lib/iptables to /lib/iptables. + This needs to work before /usr is mounted... +- Use -O1 on alpha (compiler bug) + +* Sat Jan 6 2001 Bernhard Rosenkraenzer +- 1.1.2 +- Add IPv6 support (in separate package) + +* Thu Aug 17 2000 Bill Nottingham +- build everywhere + +* Tue Jul 25 2000 Bernhard Rosenkraenzer +- 1.1.1 + +* Thu Jul 13 2000 Prospector +- automatic rebuild + +* Tue Jun 27 2000 Preston Brown +- move iptables to /sbin. +- excludearch alpha for now, not building there because of compiler bug(?) + +* Fri Jun 9 2000 Bill Nottingham +- don't obsolete ipchains either +- update to 1.1.0 + +* Sun Jun 4 2000 Bill Nottingham +- remove explicit kernel requirement + +* Tue May 2 2000 Bernhard Rosenkränzer +- initial package