diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7550cb0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/iptables-1.8.2.tar.bz2 +/iptables-1.8.4.tar.bz2 diff --git a/0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch b/0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch new file mode 100644 index 0000000..ef6490b --- /dev/null +++ b/0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch @@ -0,0 +1,35 @@ +From a69b9119bde58b372acb1c3914ee90f2ed48afb8 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 17 Sep 2018 11:39:50 +0200 +Subject: [PATCH] iptables-apply: Use mktemp instead of tempfile + +Signed-off-by: Phil Sutter +--- + iptables/iptables-apply | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/iptables/iptables-apply b/iptables/iptables-apply +index 819ca4a459c42..a685b6bbcd7dc 100755 +--- a/iptables/iptables-apply ++++ b/iptables/iptables-apply +@@ -111,7 +111,7 @@ if [[ ! -r "$FILE" ]]; then + exit 2 + fi + +-COMMANDS=(tempfile "$SAVE" "$RESTORE") ++COMMANDS=(mktemp "$SAVE" "$RESTORE") + + for cmd in "${COMMANDS[@]}"; do + if ! command -v $cmd >/dev/null; then +@@ -122,7 +122,7 @@ done + + umask 0700 + +-TMPFILE=$(tempfile -p iptap) ++TMPFILE=$(mktemp) + trap "rm -f $TMPFILE" EXIT HUP INT QUIT ILL TRAP ABRT BUS \ + FPE USR1 SEGV USR2 PIPE ALRM TERM + +-- +2.24.0 + diff --git a/0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch b/0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch new file mode 100644 index 0000000..4910448 --- /dev/null +++ b/0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch @@ -0,0 +1,59 @@ +From 25af0fd3a7edd9a9aa5ed7ed63188456ee6389ef Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 4 Dec 2019 09:56:06 +0100 +Subject: [PATCH] xtables-restore: Fix parser feed from line buffer + +When called with --noflush, xtables-restore would trip over chain lines: +Parser uses strtok() to separate chain name, policy and counters which +inserts nul-chars into the source string. Therefore strlen() can't be +used anymore to find end of line. Fix this by caching line length before +calling xtables_restore_parse_line(). + +Fixes: 09cb517949e69 ("xtables-restore: Improve performance of --noflush operation") +Signed-off-by: Phil Sutter +Acked-by: Pablo Neira Ayuso +(cherry picked from commit a103fbfadf4c17b8b12caa57eef72deaaa71a18c) +Signed-off-by: Phil Sutter +--- + .../testcases/ipt-restore/0010-noflush-new-chain_0 | 10 ++++++++++ + iptables/xtables-restore.c | 4 +++- + 2 files changed, 13 insertions(+), 1 deletion(-) + create mode 100755 iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 + +diff --git a/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 +new file mode 100755 +index 0000000000000..739e684a21183 +--- /dev/null ++++ b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 +@@ -0,0 +1,10 @@ ++#!/bin/sh -e ++ ++# assert input feed from buffer doesn't trip over ++# added nul-chars from parsing chain line. ++ ++$XT_MULTI iptables-restore --noflush <error.lineno = ++line; + DEBUGP("%s: buffered line %d: '%s'\n", __func__, line, ptr); + xtables_restore_parse_line(h, p, &state, ptr); +- ptr += strlen(ptr) + 1; ++ ptr += len + 1; + } + if (*buffer) { + h->error.lineno = ++line; +-- +2.24.0 + diff --git a/0003-extensions-format-security-fixes-in-libip-6-t_icmp.patch b/0003-extensions-format-security-fixes-in-libip-6-t_icmp.patch new file mode 100644 index 0000000..cfefe78 --- /dev/null +++ b/0003-extensions-format-security-fixes-in-libip-6-t_icmp.patch @@ -0,0 +1,61 @@ +From 7e63dd95957a264d15eefdda3ea9449a6c72eb86 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Adam=20Go=C5=82=C4=99biowski?= +Date: Wed, 14 Nov 2018 07:35:28 +0100 +Subject: [PATCH] extensions: format-security fixes in libip[6]t_icmp +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 61d6c3834de3 ("xtables: add 'printf' attribute to xlate_add") +introduced support for gcc feature to check format string against passed +argument. This commit adds missing bits to extenstions's libipt_icmp.c +and libip6t_icmp6.c that were causing build to fail. + +Fixes: 61d6c3834de3 ("xtables: add 'printf' attribute to xlate_add") +Signed-off-by: Adam Gołębiowski +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit 907e429d7548157016cd51aba4adc5d0c7d9f816) +Signed-off-by: Phil Sutter +--- + extensions/libip6t_icmp6.c | 4 ++-- + extensions/libipt_icmp.c | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/extensions/libip6t_icmp6.c b/extensions/libip6t_icmp6.c +index 45a71875722c4..cc7bfaeb72fd7 100644 +--- a/extensions/libip6t_icmp6.c ++++ b/extensions/libip6t_icmp6.c +@@ -230,7 +230,7 @@ static unsigned int type_xlate_print(struct xt_xlate *xl, unsigned int icmptype, + type_name = icmp6_type_xlate(icmptype); + + if (type_name) { +- xt_xlate_add(xl, type_name); ++ xt_xlate_add(xl, "%s", type_name); + } else { + for (i = 0; i < ARRAY_SIZE(icmpv6_codes); ++i) + if (icmpv6_codes[i].type == icmptype && +@@ -239,7 +239,7 @@ static unsigned int type_xlate_print(struct xt_xlate *xl, unsigned int icmptype, + break; + + if (i != ARRAY_SIZE(icmpv6_codes)) +- xt_xlate_add(xl, icmpv6_codes[i].name); ++ xt_xlate_add(xl, "%s", icmpv6_codes[i].name); + else + return 0; + } +diff --git a/extensions/libipt_icmp.c b/extensions/libipt_icmp.c +index 5418997668d4c..e76257c54708c 100644 +--- a/extensions/libipt_icmp.c ++++ b/extensions/libipt_icmp.c +@@ -236,7 +236,7 @@ static unsigned int type_xlate_print(struct xt_xlate *xl, unsigned int icmptype, + if (icmp_codes[i].type == icmptype && + icmp_codes[i].code_min == code_min && + icmp_codes[i].code_max == code_max) { +- xt_xlate_add(xl, icmp_codes[i].name); ++ xt_xlate_add(xl, "%s", icmp_codes[i].name); + return 1; + } + } +-- +2.21.0 + diff --git a/0003-xtables-restore-Avoid-access-of-uninitialized-data.patch b/0003-xtables-restore-Avoid-access-of-uninitialized-data.patch new file mode 100644 index 0000000..0af13d3 --- /dev/null +++ b/0003-xtables-restore-Avoid-access-of-uninitialized-data.patch @@ -0,0 +1,31 @@ +From 5ee8338b9f1b5c02efca1a33185cf648cdf1aa20 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 11:40:26 +0100 +Subject: [PATCH] xtables-restore: Avoid access of uninitialized data + +When flushing, 'buffer' is not written to prior to checking its first +byte's value. Therefore it needs to be initialized upon declaration. + +Fixes: 09cb517949e69 ("xtables-restore: Improve performance of --noflush operation") +(cherry picked from commit 48be21bf39f9af35d53af0e211cbd50dcfd12d08) +Signed-off-by: Phil Sutter +--- + iptables/xtables-restore.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c +index dd907e0b8ddd5..63cc15cee9621 100644 +--- a/iptables/xtables-restore.c ++++ b/iptables/xtables-restore.c +@@ -281,7 +281,7 @@ void xtables_restore_parse(struct nft_handle *h, + const struct nft_xt_restore_parse *p) + { + struct nft_xt_restore_state state = {}; +- char preload_buffer[PREBUFSIZ] = {}, buffer[10240], *ptr; ++ char preload_buffer[PREBUFSIZ] = {}, buffer[10240] = {}, *ptr; + + if (!h->noflush) { + nft_fake_cache(h); +-- +2.24.0 + diff --git a/0004-extensions-time-Avoid-undefined-shift.patch b/0004-extensions-time-Avoid-undefined-shift.patch new file mode 100644 index 0000000..ad67a3d --- /dev/null +++ b/0004-extensions-time-Avoid-undefined-shift.patch @@ -0,0 +1,31 @@ +From bda4f46d1a474e5cc13712a0302adcf723e3cc5c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 13:15:01 +0100 +Subject: [PATCH] extensions: time: Avoid undefined shift + +Value 1 is signed by default and left-shifting by 31 is undefined for +those. Fix this by marking the value as unsigned. + +Fixes: ad326ef9f734a ("Add the libxt_time iptables match") +(cherry picked from commit 98b221002960040bf3505811c06025b6b9b6984b) +Signed-off-by: Phil Sutter +--- + extensions/libxt_time.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c +index 5a8cc5de13031..d001f5b7f448f 100644 +--- a/extensions/libxt_time.c ++++ b/extensions/libxt_time.c +@@ -330,7 +330,7 @@ static void time_print_monthdays(uint32_t mask, bool human_readable) + + printf(" "); + for (i = 1; i <= 31; ++i) +- if (mask & (1 << i)) { ++ if (mask & (1u << i)) { + if (nbdays++ > 0) + printf(","); + printf("%u", i); +-- +2.24.0 + diff --git a/0005-extensions-cluster-Avoid-undefined-shift.patch b/0005-extensions-cluster-Avoid-undefined-shift.patch new file mode 100644 index 0000000..576db90 --- /dev/null +++ b/0005-extensions-cluster-Avoid-undefined-shift.patch @@ -0,0 +1,31 @@ +From 45aacdc1bbb3a889d9820c1fb587dc8df3cae763 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 13:36:31 +0100 +Subject: [PATCH] extensions: cluster: Avoid undefined shift + +Value 1 is signed by default and left-shifting by 31 is undefined for +those. Fix this by marking the value as unsigned. + +Fixes: 64a0e09894e52 ("extensions: libxt_cluster: Add translation to nft") +(cherry picked from commit 28c16371cdad16707674450b59919e3d97185694) +Signed-off-by: Phil Sutter +--- + extensions/libxt_cluster.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/libxt_cluster.c b/extensions/libxt_cluster.c +index c9c35ee22e3df..d164bf6960166 100644 +--- a/extensions/libxt_cluster.c ++++ b/extensions/libxt_cluster.c +@@ -156,7 +156,7 @@ static int cluster_xlate(struct xt_xlate *xl, + xt_xlate_add(xl, "%s %u seed 0x%08x ", jhash_st, + info->total_nodes, info->hash_seed); + for (node = 0; node < 32; node++) { +- if (info->node_mask & (1 << node)) { ++ if (info->node_mask & (1u << node)) { + if (needs_set == 0) { + xt_xlate_add(xl, "{ "); + needs_set = 1; +-- +2.24.0 + diff --git a/0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch b/0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch new file mode 100644 index 0000000..6b03afa --- /dev/null +++ b/0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch @@ -0,0 +1,32 @@ +From d3641eaed9ad19b74f3bababb3db53af0004488b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 13:57:18 +0100 +Subject: [PATCH] libxtables: Avoid buffer overrun in + xtables_compatible_revision() + +The function is exported and accepts arbitrary strings as input. Calling +strcpy() without length checks is not OK. + +(cherry picked from commit f7d3dbb82e7ed94ccbf10cf70a3c7b3f3aaef1a1) +Signed-off-by: Phil Sutter +--- + libxtables/xtables.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 895f6988eaf57..777c2b08e9896 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -856,7 +856,8 @@ int xtables_compatible_revision(const char *name, uint8_t revision, int opt) + + xtables_load_ko(xtables_modprobe_program, true); + +- strcpy(rev.name, name); ++ strncpy(rev.name, name, XT_EXTENSION_MAXNAMELEN - 1); ++ rev.name[XT_EXTENSION_MAXNAMELEN - 1] = '\0'; + rev.revision = revision; + + max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); +-- +2.24.0 + diff --git a/0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch b/0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch new file mode 100644 index 0000000..5ef2d9e --- /dev/null +++ b/0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch @@ -0,0 +1,40 @@ +From 5fe54ca701a38e283faf840903e9ed20eba8a6f4 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 16:01:29 +0100 +Subject: [PATCH] xtables-translate: Guard strcpy() call in xlate_ifname() + +The function potentially fed overlong strings to strcpy(). Given that +everything needed to avoid this is there, reorder code a bit to prevent +those inputs, too. + +Fixes: 0ddd663e9c167 ("iptables-translate: add in/out ifname wildcard match translation to nft") +(cherry picked from commit 2861bdbbf062071487a49103513d129ce40e2652) +Signed-off-by: Phil Sutter +--- + iptables/xtables-translate.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index a42c60a3b64c6..77a186b905d73 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -32,14 +32,13 @@ + void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname, + bool invert) + { ++ int ifaclen = strlen(ifname); + char iface[IFNAMSIZ]; +- int ifaclen; + +- if (ifname[0] == '\0') ++ if (ifaclen < 1 || ifaclen >= IFNAMSIZ) + return; + + strcpy(iface, ifname); +- ifaclen = strlen(iface); + if (iface[ifaclen - 1] == '+') + iface[ifaclen - 1] = '*'; + +-- +2.24.0 + diff --git a/0008-extensions-among-Check-call-to-fstat.patch b/0008-extensions-among-Check-call-to-fstat.patch new file mode 100644 index 0000000..8d6bd90 --- /dev/null +++ b/0008-extensions-among-Check-call-to-fstat.patch @@ -0,0 +1,41 @@ +From 3a4d59e5cb35cf2395cfd8004dd16d45dd889e11 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 5 Dec 2019 16:35:51 +0100 +Subject: [PATCH] extensions: among: Check call to fstat() + +If this fails, a bogus length value may be passed to mmap(). + +Fixes: 26753888720d8 ("nft: bridge: Rudimental among extension support") +(cherry picked from commit 25b38bcbf2fdc019f438805c7d1ecd877af9c968) +Signed-off-by: Phil Sutter +--- + extensions/libebt_among.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c +index 2e87db3bc06fa..715d559f432c2 100644 +--- a/extensions/libebt_among.c ++++ b/extensions/libebt_among.c +@@ -6,6 +6,7 @@ + * August, 2003 + */ + ++#include + #include + #include + #include +@@ -137,7 +138,10 @@ static int bramong_parse(int c, char **argv, int invert, + if ((fd = open(optarg, O_RDONLY)) == -1) + xtables_error(PARAMETER_PROBLEM, + "Couldn't open file '%s'", optarg); +- fstat(fd, &stats); ++ if (fstat(fd, &stats) < 0) ++ xtables_error(PARAMETER_PROBLEM, ++ "fstat(%s) failed: '%s'", ++ optarg, strerror(errno)); + flen = stats.st_size; + /* use mmap because the file will probably be big */ + optarg = mmap(0, flen, PROT_READ | PROT_WRITE, +-- +2.24.0 + diff --git a/0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch b/0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch new file mode 100644 index 0000000..1842162 --- /dev/null +++ b/0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch @@ -0,0 +1,43 @@ +From fe1ac5eaa8ae482c9112aed6b89f9f2e529f4516 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 10 Dec 2019 12:27:13 +0100 +Subject: [PATCH] uapi: netfilter: Avoid undefined left-shift in xt_sctp.h + +This is a backport of kernel commit 164166558aace ("netfilter: uapi: +Avoid undefined left-shift in xt_sctp.h"). + +Signed-off-by: Phil Sutter +--- + include/linux/netfilter/xt_sctp.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/linux/netfilter/xt_sctp.h b/include/linux/netfilter/xt_sctp.h +index a501e6196905d..5b28525a2482a 100644 +--- a/include/linux/netfilter/xt_sctp.h ++++ b/include/linux/netfilter/xt_sctp.h +@@ -40,19 +40,19 @@ struct xt_sctp_info { + #define SCTP_CHUNKMAP_SET(chunkmap, type) \ + do { \ + (chunkmap)[type / bytes(__u32)] |= \ +- 1 << (type % bytes(__u32)); \ ++ 1u << (type % bytes(__u32)); \ + } while (0) + + #define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \ + do { \ + (chunkmap)[type / bytes(__u32)] &= \ +- ~(1 << (type % bytes(__u32))); \ ++ ~(1u << (type % bytes(__u32))); \ + } while (0) + + #define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \ + ({ \ + ((chunkmap)[type / bytes (__u32)] & \ +- (1 << (type % bytes (__u32)))) ? 1: 0; \ ++ (1u << (type % bytes (__u32)))) ? 1: 0; \ + }) + + #define SCTP_CHUNKMAP_RESET(chunkmap) \ +-- +2.24.0 + diff --git a/0010-xtables-translate-Fix-for-interface-name-corner-case.patch b/0010-xtables-translate-Fix-for-interface-name-corner-case.patch new file mode 100644 index 0000000..a1bc86c --- /dev/null +++ b/0010-xtables-translate-Fix-for-interface-name-corner-case.patch @@ -0,0 +1,98 @@ +From da36213a48f6114ab998a5fb37bae61d2a02d5f6 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 6 Feb 2020 15:08:41 +0100 +Subject: [PATCH] xtables-translate: Fix for interface name corner-cases + +There are two special situations xlate_ifname() didn't cover for: + +* Interface name containing '*': This went unchanged, creating a command + nft wouldn't accept. Instead translate into '\*' which doesn't change + semantics. + +* Interface name being '+': Can't translate into nft wildcard character + as nft doesn't accept asterisk-only interface names. Instead decide + what to do based on 'invert' value: Skip match creation if false, + match against an invalid interface name if true. + +Also add a test to make sure future changes to this behaviour are +noticed. + +Signed-off-by: Phil Sutter +(cherry picked from commit e179e87a1179e272a9bdabb0220b17d61d099ee3) +Signed-off-by: Phil Sutter +--- + extensions/generic.txlate | 12 ++++++++++++ + iptables/xtables-translate.c | 33 ++++++++++++++++++++++++++++----- + 2 files changed, 40 insertions(+), 5 deletions(-) + +diff --git a/extensions/generic.txlate b/extensions/generic.txlate +index b38fbd1fe113b..c92d082abea78 100644 +--- a/extensions/generic.txlate ++++ b/extensions/generic.txlate +@@ -18,3 +18,15 @@ 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 ++ ++# 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 ++ ++# skip for always matching interface names ++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 '+' ++nft add rule ip filter FORWARD iifname "INVAL/D" counter +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index 77a186b905d73..c4e177c0d63ba 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -32,15 +32,38 @@ + void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname, + bool invert) + { +- int ifaclen = strlen(ifname); +- char iface[IFNAMSIZ]; ++ int ifaclen = strlen(ifname), i, j; ++ char iface[IFNAMSIZ * 2]; + + if (ifaclen < 1 || ifaclen >= IFNAMSIZ) + return; + +- strcpy(iface, ifname); +- if (iface[ifaclen - 1] == '+') +- iface[ifaclen - 1] = '*'; ++ for (i = 0, j = 0; i < ifaclen + 1; i++, j++) { ++ switch (ifname[i]) { ++ case '+': ++ iface[j] = '*'; ++ break; ++ case '*': ++ iface[j++] = '\\'; ++ /* fall through */ ++ default: ++ iface[j] = ifname[i]; ++ break; ++ } ++ } ++ ++ if (ifaclen == 1 && ifname[0] == '+') { ++ /* Nftables does not support wildcard only string. Workaround ++ * is easy, given that this will match always or never ++ * depending on 'invert' value. To match always, simply don't ++ * generate an expression. To match never, use an invalid ++ * interface name (kernel doesn't accept '/' in names) to match ++ * against. */ ++ if (!invert) ++ return; ++ strcpy(iface, "INVAL/D"); ++ invert = false; ++ } + + xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface); + } +-- +2.24.1 + diff --git a/0011-xtables-translate-Fix-for-iface.patch b/0011-xtables-translate-Fix-for-iface.patch new file mode 100644 index 0000000..5971ec1 --- /dev/null +++ b/0011-xtables-translate-Fix-for-iface.patch @@ -0,0 +1,60 @@ +From 1e1fda9ac0a809c64fd13b4fb759becac824809e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 13 Feb 2020 14:01:50 +0100 +Subject: [PATCH] xtables-translate: Fix for iface++ + +In legacy iptables, only the last plus sign remains special, any +previous ones are taken literally. Therefore xtables-translate must not +replace all of them with asterisk but just the last one. + +Fixes: e179e87a1179e ("xtables-translate: Fix for interface name corner-cases") +Signed-off-by: Phil Sutter +(cherry picked from commit 94488d4eb912f5af4c88d148b39b38eb8a3c1f0b) +Signed-off-by: Phil Sutter +--- + extensions/generic.txlate | 4 ++++ + iptables/xtables-translate.c | 6 +++--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/extensions/generic.txlate b/extensions/generic.txlate +index c92d082abea78..0e256c3727559 100644 +--- a/extensions/generic.txlate ++++ b/extensions/generic.txlate +@@ -23,6 +23,10 @@ nft insert rule bridge filter INPUT ether type 0x800 ether daddr 01:02:03:04:00: + 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 ++ + # skip for always matching interface names + iptables-translate -A FORWARD -i '+' + nft add rule ip filter FORWARD counter +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index c4e177c0d63ba..0f95855b41aa4 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -40,9 +40,6 @@ 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] = '*'; +- break; + case '*': + iface[j++] = '\\'; + /* fall through */ +@@ -65,6 +62,9 @@ void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname, + invert = false; + } + ++ if (iface[j - 2] == '+') ++ iface[j - 2] = '*'; ++ + xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface); + } + +-- +2.24.1 + diff --git a/0012-tests-shell-Fix-skip-checks-with-host-mode.patch b/0012-tests-shell-Fix-skip-checks-with-host-mode.patch new file mode 100644 index 0000000..4501a92 --- /dev/null +++ b/0012-tests-shell-Fix-skip-checks-with-host-mode.patch @@ -0,0 +1,366 @@ +From bbd2dd9ee6db7d11ab5b2b10a63b3dfd8b8acc9d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 21:26:06 +0100 +Subject: [PATCH] tests: shell: Fix skip checks with --host mode + +When testing host binaries, XT_MULTI variable contains just the program +name without path component which most skip checks didn't expect. Fix +them, and while being at it also reduce indenting level in two scripts +by moving the skip check up front with an early exit call. + +Fixes: 416898e335322 ("tests/shell: Support testing host binaries") +Signed-off-by: Phil Sutter +(cherry picked from commit 2b2b7948c1960ba4680677664ff58477be869de6) +Signed-off-by: Phil Sutter +--- + .../arptables/0001-arptables-save-restore_0 | 2 +- + .../0002-arptables-restore-defaults_0 | 2 +- + .../arptables/0003-arptables-verbose-output_0 | 2 +- + .../testcases/ebtables/0001-ebtables-basic_0 | 135 +++++++++--------- + .../ebtables/0002-ebtables-save-restore_0 | 2 +- + .../ebtables/0003-ebtables-restore-defaults_0 | 2 +- + .../testcases/ebtables/0004-save-counters_0 | 2 +- + .../testcases/ebtables/0005-ifnamechecks_0 | 2 +- + .../firewalld-restore/0001-firewalld_0 | 2 +- + .../testcases/ipt-restore/0004-restore-race_0 | 2 +- + .../shell/testcases/nft-only/0001compat_0 | 15 +- + .../shell/testcases/nft-only/0002invflags_0 | 2 +- + .../nft-only/0003delete-with-comment_0 | 2 +- + 13 files changed, 88 insertions(+), 84 deletions(-) + +diff --git a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 +index bf04dc0a3e15a..e64e9142ee98b 100755 +--- a/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 ++++ b/iptables/tests/shell/testcases/arptables/0001-arptables-save-restore_0 +@@ -4,7 +4,7 @@ set -e + #set -x + + # there is no legacy backend to test +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + # fill arptables manually + +diff --git a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 +index 38d387f327ebb..afd0fcb460d85 100755 +--- a/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 ++++ b/iptables/tests/shell/testcases/arptables/0002-arptables-restore-defaults_0 +@@ -3,7 +3,7 @@ + set -e + + # there is no legacy backend to test +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + # arptables-restore reuses preloaded targets and matches, make sure defaults + # apply to consecutive rules using the same target/match as a previous one +diff --git a/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 b/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 +index 10c5ec33ada2c..952cfa7898371 100755 +--- a/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 ++++ b/iptables/tests/shell/testcases/arptables/0003-arptables-verbose-output_0 +@@ -4,7 +4,7 @@ set -e + set -x + + # there is no legacy backend to test +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + $XT_MULTI arptables -N foo + +diff --git a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 +index c7f24a383f698..0c1eb4ca66f52 100755 +--- a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 ++++ b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 +@@ -1,86 +1,89 @@ + #!/bin/sh + ++case "$XT_MULTI" in ++*xtables-nft-multi) ++ ;; ++*) ++ echo "skip $XT_MULTI" ++ exit 0 ++ ;; ++esac ++ + get_entries_count() { # (chain) + $XT_MULTI ebtables -L $1 | sed -n 's/.*entries: \([0-9]*\).*/\1/p' + } + + set -x +-case "$XT_MULTI" in +-*/xtables-nft-multi) +- for t in filter nat;do +- $XT_MULTI ebtables -t $t -L || exit 1 +- $XT_MULTI ebtables -t $t -X || exit 1 +- $XT_MULTI ebtables -t $t -F || exit 1 +- done +- +- for t in broute foobar ;do +- $XT_MULTI ebtables -t $t -L && +- $XT_MULTI ebtables -t $t -X && +- $XT_MULTI ebtables -t $t -F +- if [ $? -eq 0 ]; then +- echo "Expect nonzero return for unsupported table" +- exit 1 +- fi +- done + ++for t in filter nat;do ++ $XT_MULTI ebtables -t $t -L || exit 1 ++ $XT_MULTI ebtables -t $t -X || exit 1 ++ $XT_MULTI ebtables -t $t -F || exit 1 ++done + +- $XT_MULTI ebtables -t filter -N FOO || exit 1 +- $XT_MULTI ebtables -t filter -N FOO ++for t in broute foobar ;do ++ $XT_MULTI ebtables -t $t -L && ++ $XT_MULTI ebtables -t $t -X && ++ $XT_MULTI ebtables -t $t -F + if [ $? -eq 0 ]; then +- echo "Duplicate chain FOO" +- $XT_MULTI ebtables -t filter -L ++ echo "Expect nonzero return for unsupported table" + exit 1 + fi ++done + +- entries=$(get_entries_count FOO) +- if [ $entries -ne 0 ]; then +- echo "Unexpected entries count in empty unreferenced chain (expected 0, have $entries)" +- $XT_MULTI ebtables -L +- exit 1 +- fi + +- $XT_MULTI ebtables -A FORWARD -j FOO +- entries=$(get_entries_count FORWARD) +- if [ $entries -ne 1 ]; then +- echo "Unexpected entries count in FORWARD chain (expected 1, have $entries)" +- $XT_MULTI ebtables -L +- exit 1 +- fi ++$XT_MULTI ebtables -t filter -N FOO || exit 1 ++$XT_MULTI ebtables -t filter -N FOO ++if [ $? -eq 0 ]; then ++ echo "Duplicate chain FOO" ++ $XT_MULTI ebtables -t filter -L ++ exit 1 ++fi + +- entries=$(get_entries_count FOO) +- if [ $entries -ne 0 ]; then +- echo "Unexpected entries count in empty referenced chain (expected 0, have $entries)" +- $XT_MULTI ebtables -L +- exit 1 +- fi ++entries=$(get_entries_count FOO) ++if [ $entries -ne 0 ]; then ++ echo "Unexpected entries count in empty unreferenced chain (expected 0, have $entries)" ++ $XT_MULTI ebtables -L ++ exit 1 ++fi + +- $XT_MULTI ebtables -A FOO -j ACCEPT +- entries=$(get_entries_count FOO) +- if [ $entries -ne 1 ]; then +- echo "Unexpected entries count in non-empty referenced chain (expected 1, have $entries)" +- $XT_MULTI ebtables -L +- exit 1 +- fi ++$XT_MULTI ebtables -A FORWARD -j FOO ++entries=$(get_entries_count FORWARD) ++if [ $entries -ne 1 ]; then ++ echo "Unexpected entries count in FORWARD chain (expected 1, have $entries)" ++ $XT_MULTI ebtables -L ++ exit 1 ++fi + +- $XT_MULTI ebtables -t filter -N BAR || exit 1 +- $XT_MULTI ebtables -t filter -N BAZ || exit 1 ++entries=$(get_entries_count FOO) ++if [ $entries -ne 0 ]; then ++ echo "Unexpected entries count in empty referenced chain (expected 0, have $entries)" ++ $XT_MULTI ebtables -L ++ exit 1 ++fi + +- $XT_MULTI ebtables -t filter -L | grep -q FOO || exit 1 +- $XT_MULTI ebtables -t filter -L | grep -q BAR || exit 1 +- $XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1 ++$XT_MULTI ebtables -A FOO -j ACCEPT ++entries=$(get_entries_count FOO) ++if [ $entries -ne 1 ]; then ++ echo "Unexpected entries count in non-empty referenced chain (expected 1, have $entries)" ++ $XT_MULTI ebtables -L ++ exit 1 ++fi + +- $XT_MULTI ebtables -t filter -L BAZ || exit 1 +- $XT_MULTI ebtables -t filter -X BAZ || exit 1 +- $XT_MULTI ebtables -t filter -L BAZ | grep -q BAZ +- if [ $? -eq 0 ]; then +- echo "Deleted chain -L BAZ ok, expected failure" +- $XT_MULTI ebtables -t filter -L +- exit 1 +- fi ++$XT_MULTI ebtables -t filter -N BAR || exit 1 ++$XT_MULTI ebtables -t filter -N BAZ || exit 1 + +- $XT_MULTI ebtables -t $t -F || exit 0 +- ;; +-*) +- echo "skip $XT_MULTI" +- ;; +-esac ++$XT_MULTI ebtables -t filter -L | grep -q FOO || exit 1 ++$XT_MULTI ebtables -t filter -L | grep -q BAR || exit 1 ++$XT_MULTI ebtables -t filter -L | grep -q BAZ || exit 1 ++ ++$XT_MULTI ebtables -t filter -L BAZ || exit 1 ++$XT_MULTI ebtables -t filter -X BAZ || exit 1 ++$XT_MULTI ebtables -t filter -L BAZ | grep -q BAZ ++if [ $? -eq 0 ]; then ++ echo "Deleted chain -L BAZ ok, expected failure" ++ $XT_MULTI ebtables -t filter -L ++ exit 1 ++fi ++ ++$XT_MULTI ebtables -t $t -F || exit 0 +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 e18d46551509d..b84f63a7c3672 100755 +--- a/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 ++++ b/iptables/tests/shell/testcases/ebtables/0002-ebtables-save-restore_0 +@@ -4,7 +4,7 @@ set -e + #set -x + + # there is no legacy backend to test +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + # fill ebtables manually + +diff --git a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 b/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 +index 62d224134456b..63891c1bb731a 100755 +--- a/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 ++++ b/iptables/tests/shell/testcases/ebtables/0003-ebtables-restore-defaults_0 +@@ -3,7 +3,7 @@ + set -e + + # there is no legacy backend to test +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + # ebtables-restore reuses preloaded targets and matches, make sure defaults + # apply to consecutive rules using the same target/match as a previous one +diff --git a/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 b/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 +index 46966f433139a..d52db900604ef 100755 +--- a/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 ++++ b/iptables/tests/shell/testcases/ebtables/0004-save-counters_0 +@@ -3,7 +3,7 @@ + set -e + + # there is no legacy backend to test +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + $XT_MULTI ebtables --init-table + $XT_MULTI ebtables -A FORWARD -i nodev123 -o nodev432 -j ACCEPT +diff --git a/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 b/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 +index 2163d364b318b..0b3acfd7613db 100755 +--- a/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 ++++ b/iptables/tests/shell/testcases/ebtables/0005-ifnamechecks_0 +@@ -3,7 +3,7 @@ + set -e + + # there is no legacy backend to test +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + EXPECT='*filter + :INPUT ACCEPT +diff --git a/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 b/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 +index 8bf0c2c6c194e..0174b03f4ebc7 100755 +--- a/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 ++++ b/iptables/tests/shell/testcases/firewalld-restore/0001-firewalld_0 +@@ -231,7 +231,7 @@ for table in nat mangle raw filter;do + done + + case "$XT_MULTI" in +-*/xtables-nft-multi) ++*xtables-nft-multi) + # nft-multi displays chain names in different order, work around this for now + tmpfile2=$(mktemp) + sort "$tmpfile" > "$tmpfile2" +diff --git a/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 b/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 +index 96a5e66d0ab81..9fc50615b8926 100755 +--- a/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 ++++ b/iptables/tests/shell/testcases/ipt-restore/0004-restore-race_0 +@@ -86,7 +86,7 @@ if [ $LINES1 -ne $LINES2 ]; then + fi + + case "$XT_MULTI" in +-*/xtables-nft-multi) ++*xtables-nft-multi) + attempts=$((RANDOM%10)) + attempts=$((attempts+1)) + ;; +diff --git a/iptables/tests/shell/testcases/nft-only/0001compat_0 b/iptables/tests/shell/testcases/nft-only/0001compat_0 +index 4319ea5a6a797..a617c52f53695 100755 +--- a/iptables/tests/shell/testcases/nft-only/0001compat_0 ++++ b/iptables/tests/shell/testcases/nft-only/0001compat_0 +@@ -5,17 +5,18 @@ + # xtables: avoid bogus 'is incompatible' warning + + case "$XT_MULTI" in +-*/xtables-nft-multi) +- nft -v >/dev/null || exit 0 +- nft 'add table ip nft-test; add chain ip nft-test foobar { type filter hook forward priority 42; }' || exit 1 +- nft 'add table ip6 nft-test; add chain ip6 nft-test foobar { type filter hook forward priority 42; }' || exit 1 +- +- $XT_MULTI iptables -L -t filter || exit 1 +- $XT_MULTI ip6tables -L -t filter || exit 1 ++*xtables-nft-multi) + ;; + *) + echo skip $XT_MULTI ++ exit 0 + ;; + esac + ++nft -v >/dev/null || exit 0 ++nft 'add table ip nft-test; add chain ip nft-test foobar { type filter hook forward priority 42; }' || exit 1 ++nft 'add table ip6 nft-test; add chain ip6 nft-test foobar { type filter hook forward priority 42; }' || exit 1 ++ ++$XT_MULTI iptables -L -t filter || exit 1 ++$XT_MULTI ip6tables -L -t filter || exit 1 + exit 0 +diff --git a/iptables/tests/shell/testcases/nft-only/0002invflags_0 b/iptables/tests/shell/testcases/nft-only/0002invflags_0 +index 406b6081a98a4..fe33874dde7f2 100755 +--- a/iptables/tests/shell/testcases/nft-only/0002invflags_0 ++++ b/iptables/tests/shell/testcases/nft-only/0002invflags_0 +@@ -2,7 +2,7 @@ + + set -e + +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + $XT_MULTI iptables -A INPUT -p tcp --dport 53 ! -s 192.168.0.1 -j ACCEPT + $XT_MULTI ip6tables -A INPUT -p tcp --dport 53 ! -s feed:babe::1 -j ACCEPT +diff --git a/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 b/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 +index 67af9fd897410..ccb009e469076 100755 +--- a/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 ++++ b/iptables/tests/shell/testcases/nft-only/0003delete-with-comment_0 +@@ -2,7 +2,7 @@ + + set -e + +-[[ $XT_MULTI == */xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } ++[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; } + + comment1="foo bar" + comment2="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +-- +2.24.1 + diff --git a/0013-xtables-restore-fix-for-noflush-and-empty-lines.patch b/0013-xtables-restore-fix-for-noflush-and-empty-lines.patch new file mode 100644 index 0000000..cb49b21 --- /dev/null +++ b/0013-xtables-restore-fix-for-noflush-and-empty-lines.patch @@ -0,0 +1,78 @@ +From 5ea18ea8c0c99f2c71a5eaf32f4fbf6339ce8cc7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 11 Feb 2020 16:52:59 +0100 +Subject: [PATCH] xtables-restore: fix for --noflush and empty lines + +Lookahead buffer used for cache requirements estimate in restore +--noflush separates individual lines with nul-chars. Two consecutive +nul-chars are interpreted as end of buffer and remaining buffer content +is skipped. + +Sadly, reading an empty line (i.e., one containing a newline character +only) caused double nul-chars to appear in buffer as well, leading to +premature stop when reading cached lines from buffer. + +To fix that, make use of xtables_restore_parse_line() skipping empty +lines without calling strtok() and just leave the newline character in +place. A more intuitive approach, namely skipping empty lines while +buffering, is deliberately not chosen as that would cause wrong values +in 'line' variable. + +Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1400 +Fixes: 09cb517949e69 ("xtables-restore: Improve performance of --noflush operation") +Signed-off-by: Phil Sutter +Acked-by: Arturo Borrero Gonzalez +(cherry picked from commit 8e76391096f12212985c401ee83a67990aa27a29) +Signed-off-by: Phil Sutter +--- + .../ipt-restore/0011-noflush-empty-line_0 | 16 ++++++++++++++++ + iptables/xtables-restore.c | 8 +++++--- + 2 files changed, 21 insertions(+), 3 deletions(-) + create mode 100755 iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 + +diff --git a/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 b/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 +new file mode 100755 +index 0000000000000..bea1a690bb624 +--- /dev/null ++++ b/iptables/tests/shell/testcases/ipt-restore/0011-noflush-empty-line_0 +@@ -0,0 +1,16 @@ ++#!/bin/bash -e ++ ++# make sure empty lines won't break --noflush ++ ++cat <in)) { + size_t blen = strlen(buffer); + +- /* drop trailing newline; xtables_restore_parse_line() ++ /* Drop trailing newline; xtables_restore_parse_line() + * uses strtok() which replaces them by nul-characters, + * causing unpredictable string delimiting in +- * preload_buffer */ +- if (buffer[blen - 1] == '\n') ++ * preload_buffer. ++ * Unless this is an empty line which would fold into a ++ * spurious EoB indicator (double nul-char). */ ++ if (buffer[blen - 1] == '\n' && blen > 1) + buffer[blen - 1] = '\0'; + else + blen++; +-- +2.24.1 + diff --git a/0014-iptables-test.py-Fix-host-mode.patch b/0014-iptables-test.py-Fix-host-mode.patch new file mode 100644 index 0000000..0387700 --- /dev/null +++ b/0014-iptables-test.py-Fix-host-mode.patch @@ -0,0 +1,43 @@ +From 40e7bc3055f9bc34ccb6327f1f32c2fc524fb693 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 18 Feb 2020 16:43:16 +0100 +Subject: [PATCH] iptables-test.py: Fix --host mode + +In some cases, the script still called repo binaries. Avoid this when in +--host mode to allow testing without the need to compile sources in +beforehand. + +Fixes: 1b5d762c1865e ("iptables-test: Support testing host binaries") +Signed-off-by: Phil Sutter +(cherry picked from commit ba2af278e8836977a8cfb35c54dac60ca9b40000) +Signed-off-by: Phil Sutter +--- + iptables-test.py | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/iptables-test.py b/iptables-test.py +index fdb4e6a3644e4..e986d7a318218 100755 +--- a/iptables-test.py ++++ b/iptables-test.py +@@ -119,8 +119,7 @@ def run_test(iptables, rule, rule_save, res, filename, lineno, netns): + elif splitted[0] == EBTABLES: + command = EBTABLES_SAVE + +- path = os.path.abspath(os.path.curdir) + "/iptables/" + EXECUTEABLE +- command = path + " " + command ++ command = EXECUTEABLE + " " + command + + if netns: + command = "ip netns exec ____iptables-container-test " + command +@@ -165,7 +164,7 @@ def execute_cmd(cmd, filename, lineno): + ''' + global log_file + if cmd.startswith('iptables ') or cmd.startswith('ip6tables ') or cmd.startswith('ebtables ') or cmd.startswith('arptables '): +- cmd = os.path.abspath(os.path.curdir) + "/iptables/" + EXECUTEABLE + " " + cmd ++ cmd = EXECUTEABLE + " " + cmd + + print("command: {}".format(cmd), file=log_file) + ret = subprocess.call(cmd, shell=True, universal_newlines=True, +-- +2.25.1 + diff --git a/0015-xtables-Review-nft_init.patch b/0015-xtables-Review-nft_init.patch new file mode 100644 index 0000000..2246b84 --- /dev/null +++ b/0015-xtables-Review-nft_init.patch @@ -0,0 +1,274 @@ +From 51f895d54af6e163e0290520e124e9413438ccf4 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 21 Feb 2020 14:55:52 +0100 +Subject: [PATCH] xtables: Review nft_init() + +Move common code into nft_init(), such as: + +* initial zeroing nft_handle fields +* family ops lookup and assignment to 'ops' field +* setting of 'family' field + +This requires minor adjustments in xtables_restore_main() so extra field +initialization doesn't happen before nft_init() call. + +As a side-effect, this fixes segfaulting xtables-monitor binary when +printing rules for trace event as in that code-path 'ops' field wasn't +initialized. + +Signed-off-by: Phil Sutter +(cherry picked from commit d0446ab11182f6ca2adc486a124895f09a220c6e) +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 9 ++++++++- + iptables/nft.h | 2 +- + iptables/xtables-arp.c | 9 +-------- + iptables/xtables-eb.c | 9 +-------- + iptables/xtables-monitor.c | 2 +- + iptables/xtables-restore.c | 14 +++++++------- + iptables/xtables-save.c | 9 ++------- + iptables/xtables-standalone.c | 6 ++---- + iptables/xtables-translate.c | 2 +- + iptables/xtables.c | 4 ---- + 10 files changed, 24 insertions(+), 42 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 3f2a62ae12c07..0287add3fb21f 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -789,8 +789,10 @@ int nft_restart(struct nft_handle *h) + return 0; + } + +-int nft_init(struct nft_handle *h, const struct builtin_table *t) ++int nft_init(struct nft_handle *h, int family, const struct builtin_table *t) + { ++ memset(h, 0, sizeof(*h)); ++ + h->nl = mnl_socket_open(NETLINK_NETFILTER); + if (h->nl == NULL) + return -1; +@@ -800,9 +802,14 @@ int nft_init(struct nft_handle *h, const struct builtin_table *t) + return -1; + } + ++ h->ops = nft_family_ops_lookup(family); ++ if (!h->ops) ++ xtables_error(PARAMETER_PROBLEM, "Unknown family"); ++ + h->portid = mnl_socket_get_portid(h->nl); + h->tables = t; + h->cache = &h->__cache[0]; ++ h->family = family; + + INIT_LIST_HEAD(&h->obj_list); + INIT_LIST_HEAD(&h->err_list); +diff --git a/iptables/nft.h b/iptables/nft.h +index 51b5660314c0c..5cf260a6d2cd3 100644 +--- a/iptables/nft.h ++++ b/iptables/nft.h +@@ -80,7 +80,7 @@ extern const struct builtin_table xtables_bridge[NFT_TABLE_MAX]; + int mnl_talk(struct nft_handle *h, struct nlmsghdr *nlh, + int (*cb)(const struct nlmsghdr *nlh, void *data), + void *data); +-int nft_init(struct nft_handle *h, const struct builtin_table *t); ++int nft_init(struct nft_handle *h, int family, const struct builtin_table *t); + void nft_fini(struct nft_handle *h); + int nft_restart(struct nft_handle *h); + +diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c +index 9cfad76263d32..c8196f08baa59 100644 +--- a/iptables/xtables-arp.c ++++ b/iptables/xtables-arp.c +@@ -500,17 +500,10 @@ int nft_init_arp(struct nft_handle *h, const char *pname) + init_extensionsa(); + #endif + +- memset(h, 0, sizeof(*h)); +- h->family = NFPROTO_ARP; +- +- if (nft_init(h, xtables_arp) < 0) ++ if (nft_init(h, NFPROTO_ARP, xtables_arp) < 0) + xtables_error(OTHER_PROBLEM, + "Could not initialize nftables layer."); + +- h->ops = nft_family_ops_lookup(h->family); +- if (h->ops == NULL) +- xtables_error(PARAMETER_PROBLEM, "Unknown family"); +- + return 0; + } + +diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c +index 15b971da3d425..c006bc95ac681 100644 +--- a/iptables/xtables-eb.c ++++ b/iptables/xtables-eb.c +@@ -739,16 +739,9 @@ int nft_init_eb(struct nft_handle *h, const char *pname) + init_extensionsb(); + #endif + +- memset(h, 0, sizeof(*h)); +- +- h->family = NFPROTO_BRIDGE; +- +- if (nft_init(h, xtables_bridge) < 0) ++ if (nft_init(h, NFPROTO_BRIDGE, xtables_bridge) < 0) + xtables_error(OTHER_PROBLEM, + "Could not initialize nftables layer."); +- h->ops = nft_family_ops_lookup(h->family); +- if (!h->ops) +- xtables_error(PARAMETER_PROBLEM, "Unknown family"); + + /* manually registering ebt matches, given the original ebtables parser + * don't use '-m matchname' and the match can't be loaded dynamically when +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index a5245d1422af9..c2b31dbaa0795 100644 +--- a/iptables/xtables-monitor.c ++++ b/iptables/xtables-monitor.c +@@ -615,7 +615,7 @@ int xtables_monitor_main(int argc, char *argv[]) + init_extensions4(); + #endif + +- if (nft_init(&h, xtables_ipv4)) { ++ if (nft_init(&h, AF_INET, xtables_ipv4)) { + fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", + xtables_globals.program_name, + xtables_globals.program_version, +diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c +index fb2ac8b5c12a3..11834c0ea98c5 100644 +--- a/iptables/xtables-restore.c ++++ b/iptables/xtables-restore.c +@@ -360,15 +360,13 @@ static int + xtables_restore_main(int family, const char *progname, int argc, char *argv[]) + { + const struct builtin_table *tables; +- struct nft_handle h = { +- .family = family, +- .restore = true, +- }; +- int c; + struct nft_xt_restore_parse p = { + .commit = true, + .cb = &restore_cb, + }; ++ bool noflush = false; ++ struct nft_handle h; ++ int c; + + line = 0; + +@@ -402,7 +400,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) + print_usage(prog_name, PACKAGE_VERSION); + exit(0); + case 'n': +- h.noflush = 1; ++ noflush = true; + break; + case 'M': + xtables_modprobe_program = optarg; +@@ -464,13 +462,15 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) + return 1; + } + +- if (nft_init(&h, tables) < 0) { ++ if (nft_init(&h, family, tables) < 0) { + fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", + xtables_globals.program_name, + xtables_globals.program_version, + strerror(errno)); + exit(EXIT_FAILURE); + } ++ h.noflush = noflush; ++ h.restore = true; + + xtables_restore_parse(&h, &p); + +diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c +index 3a52f8c3d8209..228282deaed07 100644 +--- a/iptables/xtables-save.c ++++ b/iptables/xtables-save.c +@@ -139,10 +139,8 @@ xtables_save_main(int family, int argc, char *argv[], + struct do_output_data d = { + .format = FMT_NOCOUNTS, + }; ++ struct nft_handle h; + bool dump = false; +- struct nft_handle h = { +- .family = family, +- }; + FILE *file = NULL; + int ret, c; + +@@ -242,16 +240,13 @@ xtables_save_main(int family, int argc, char *argv[], + return 1; + } + +- if (nft_init(&h, tables) < 0) { ++ if (nft_init(&h, family, tables) < 0) { + fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", + xtables_globals.program_name, + xtables_globals.program_version, + strerror(errno)); + exit(EXIT_FAILURE); + } +- h.ops = nft_family_ops_lookup(h.family); +- if (!h.ops) +- xtables_error(PARAMETER_PROBLEM, "Unknown family"); + + ret = do_output(&h, tablename, &d); + nft_fini(&h); +diff --git a/iptables/xtables-standalone.c b/iptables/xtables-standalone.c +index 1a28c5480629f..022d5dd44abbf 100644 +--- a/iptables/xtables-standalone.c ++++ b/iptables/xtables-standalone.c +@@ -44,9 +44,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) + { + int ret; + char *table = "filter"; +- struct nft_handle h = { +- .family = family, +- }; ++ struct nft_handle h; + + xtables_globals.program_name = progname; + ret = xtables_init_all(&xtables_globals, family); +@@ -61,7 +59,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) + init_extensions4(); + #endif + +- if (nft_init(&h, xtables_ipv4) < 0) { ++ if (nft_init(&h, family, xtables_ipv4) < 0) { + fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", + xtables_globals.program_name, + xtables_globals.program_version, +diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c +index 0f95855b41aa4..76ad7eb69eca9 100644 +--- a/iptables/xtables-translate.c ++++ b/iptables/xtables-translate.c +@@ -480,7 +480,7 @@ static int xtables_xlate_main_common(struct nft_handle *h, + return 1; + } + +- if (nft_init(h, tables) < 0) { ++ if (nft_init(h, family, tables) < 0) { + fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", + xtables_globals.program_name, + xtables_globals.program_version, +diff --git a/iptables/xtables.c b/iptables/xtables.c +index 8f9dc628d0029..4b24d15c46295 100644 +--- a/iptables/xtables.c ++++ b/iptables/xtables.c +@@ -571,10 +571,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], + demand-load a protocol. */ + opterr = 0; + +- h->ops = nft_family_ops_lookup(h->family); +- if (h->ops == NULL) +- xtables_error(PARAMETER_PROBLEM, "Unknown family"); +- + opts = xt_params->orig_opts; + while ((cs->c = getopt_long(argc, argv, + "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46", +-- +2.26.2 + diff --git a/0016-nft-cache-Fix-nft_release_cache-under-stress.patch b/0016-nft-cache-Fix-nft_release_cache-under-stress.patch new file mode 100644 index 0000000..ff06e05 --- /dev/null +++ b/0016-nft-cache-Fix-nft_release_cache-under-stress.patch @@ -0,0 +1,49 @@ +From 66b9f92ef41de90fc2b0359247c36bc6d128233d Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 28 Feb 2020 20:32:13 +0100 +Subject: [PATCH] nft: cache: Fix nft_release_cache() under stress + +iptables-nft-restore calls nft_action(h, NFT_COMPAT_COMMIT) for each +COMMIT line in input. When restoring a dump containing multiple large +tables, chances are nft_rebuild_cache() has to run multiple times. + +If the above happens, consecutive table contents are added to __cache[1] +which nft_rebuild_cache() then frees, so next commit attempt accesses +invalid memory. + +Fix this by making nft_release_cache() (called after each successful +commit) return things into pre-rebuild state again, but keeping the +fresh cache copy. + +Fixes: f6ad231d698c7 ("nft: keep original cache in case of ERESTART") +Signed-off-by: Phil Sutter +(cherry picked from commit c550c81fd373e5753103d20f7902171f0fa79807) +Signed-off-by: Phil Sutter +--- + iptables/nft-cache.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c +index 7345a27e2894b..6f21f2283e0fb 100644 +--- a/iptables/nft-cache.c ++++ b/iptables/nft-cache.c +@@ -647,8 +647,14 @@ void nft_rebuild_cache(struct nft_handle *h) + + void nft_release_cache(struct nft_handle *h) + { +- if (h->cache_index) +- flush_cache(h, &h->__cache[0], NULL); ++ if (!h->cache_index) ++ return; ++ ++ flush_cache(h, &h->__cache[0], NULL); ++ memcpy(&h->__cache[0], &h->__cache[1], sizeof(h->__cache[0])); ++ memset(&h->__cache[1], 0, sizeof(h->__cache[1])); ++ h->cache_index = 0; ++ h->cache = &h->__cache[0]; + } + + struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h) +-- +2.25.1 + diff --git a/0017-nft-cache-Fix-iptables-save-segfault-under-stress.patch b/0017-nft-cache-Fix-iptables-save-segfault-under-stress.patch new file mode 100644 index 0000000..accd32f --- /dev/null +++ b/0017-nft-cache-Fix-iptables-save-segfault-under-stress.patch @@ -0,0 +1,84 @@ +From 38c94a9f5ea03deffe0a34056a0f83a4af4641bb Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 13 Mar 2020 13:02:12 +0100 +Subject: [PATCH] nft: cache: Fix iptables-save segfault under stress + +If kernel ruleset is constantly changing, code called by +nft_is_table_compatible() may crash: For each item in table's chain +list, nft_is_chain_compatible() is called. This in turn calls +nft_build_cache() to fetch chain's rules. Though if kernel genid has changed +meanwhile, cache is flushed and rebuilt from scratch, thereby freeing +table's chain list - the foreach loop in nft_is_table_compatible() then +operates on freed memory. + +A simple reproducer (may need a few calls): + +| RULESET='*filter +| :INPUT ACCEPT [10517:1483527] +| :FORWARD ACCEPT [0:0] +| :OUTPUT ACCEPT [1714:105671] +| COMMIT +| ' +| +| for ((i = 0; i < 100; i++)); do +| iptables-nft-restore <<< "$RULESET" & +| done & +| iptables-nft-save + +To fix the problem, basically revert commit ab1cd3b510fa5 ("nft: ensure +cache consistency") so that __nft_build_cache() no longer flushes the +cache. Instead just record kernel's genid when fetching for the first +time. If kernel rule set changes until the changes are committed, the +commit simply fails and local cache is being rebuilt. + +Signed-off-by: Phil Sutter +(cherry picked from commit 200bc399651499f502ac0de45f4d4aa4c9d37ab6) +Signed-off-by: Phil Sutter +--- + iptables/nft-cache.c | 16 ++-------------- + 1 file changed, 2 insertions(+), 14 deletions(-) + +diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c +index 6f21f2283e0fb..07265b7795e4f 100644 +--- a/iptables/nft-cache.c ++++ b/iptables/nft-cache.c +@@ -452,15 +452,11 @@ __nft_build_cache(struct nft_handle *h, enum nft_cache_level level, + const struct builtin_table *t, const char *set, + const char *chain) + { +- uint32_t genid_start, genid_stop; +- + if (level <= h->cache_level) + return; +-retry: +- mnl_genid_get(h, &genid_start); + +- if (h->cache_level && genid_start != h->nft_genid) +- flush_chain_cache(h, NULL); ++ if (!h->nft_genid) ++ mnl_genid_get(h, &h->nft_genid); + + switch (h->cache_level) { + case NFT_CL_NONE: +@@ -487,18 +483,10 @@ retry: + break; + } + +- mnl_genid_get(h, &genid_stop); +- if (genid_start != genid_stop) { +- flush_chain_cache(h, NULL); +- goto retry; +- } +- + if (!t && !chain) + h->cache_level = level; + else if (h->cache_level < NFT_CL_TABLES) + h->cache_level = NFT_CL_TABLES; +- +- h->nft_genid = genid_start; + } + + void nft_build_cache(struct nft_handle *h, struct nftnl_chain *c) +-- +2.25.1 + diff --git a/0018-ebtables-among-Support-mixed-MAC-and-MAC-IP-entries.patch b/0018-ebtables-among-Support-mixed-MAC-and-MAC-IP-entries.patch new file mode 100644 index 0000000..73d9987 --- /dev/null +++ b/0018-ebtables-among-Support-mixed-MAC-and-MAC-IP-entries.patch @@ -0,0 +1,127 @@ +From 654b2e2512630df07e3ea57f8d54e851e75b33f1 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 13 Feb 2020 17:49:53 +0100 +Subject: [PATCH] ebtables: among: Support mixed MAC and MAC/IP entries + +Powered by Stefano's support for concatenated ranges, a full among match +replacement can be implemented. The trick is to add MAC-only elements as +a concatenation of MAC and zero-length prefix, i.e. a range from +0.0.0.0 till 255.255.255.255. + +Although not quite needed, detection of pure MAC-only matches is left in +place. For those, no implicit 'meta protocol' match is added (which is +required otherwise at least to keep nft output correct) and no concat +type is used for the set. + +Signed-off-by: Phil Sutter +(cherry picked from commit c33bae9c6c7a49c8af16df846e6112fc4727e643) +Signed-off-by: Phil Sutter +--- + extensions/libebt_among.c | 6 +----- + extensions/libebt_among.t | 2 +- + iptables/ebtables-nft.8 | 4 ---- + iptables/nft.c | 20 +++++++++++++++++++- + 4 files changed, 21 insertions(+), 11 deletions(-) + +diff --git a/extensions/libebt_among.c b/extensions/libebt_among.c +index 715d559f432c2..2b9a1b6566684 100644 +--- a/extensions/libebt_among.c ++++ b/extensions/libebt_among.c +@@ -63,10 +63,6 @@ parse_nft_among_pair(char *buf, struct nft_among_pair *pair, bool have_ip) + char *sep = index(buf, '='); + struct ether_addr *ether; + +- if (have_ip ^ !!sep) +- xtables_error(PARAMETER_PROBLEM, +- "among: Mixed MAC and MAC=IP not allowed."); +- + if (sep) { + *sep = '\0'; + +@@ -205,7 +201,7 @@ static void __bramong_print(struct nft_among_pair *pairs, + isep = ","; + + printf("%s", ether_ntoa(&pairs[i].ether)); +- if (have_ip) ++ if (pairs[i].in.s_addr != INADDR_ANY) + printf("=%s", inet_ntoa(pairs[i].in)); + } + printf(" "); +diff --git a/extensions/libebt_among.t b/extensions/libebt_among.t +index 56b299161ff31..a02206f391cde 100644 +--- a/extensions/libebt_among.t ++++ b/extensions/libebt_among.t +@@ -13,4 +13,4 @@ + --among-src;=;FAIL + --among-src 00:11=10.0.0.1;=;FAIL + --among-src de:ad:0:be:ee:ff=10.256.0.1;=;FAIL +---among-src de:ad:0:be:ee:ff,c0:ff:ee:0:ba:be=192.168.1.1;=;FAIL ++--among-src c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff;=;OK +diff --git a/iptables/ebtables-nft.8 b/iptables/ebtables-nft.8 +index a91f0c1aacb0f..1fa5ad9388cc0 100644 +--- a/iptables/ebtables-nft.8 ++++ b/iptables/ebtables-nft.8 +@@ -551,10 +551,6 @@ Same as + .BR "--among-src-file " "[!] \fIfile\fP" + Same as + .BR --among-src " but the list is read in from the specified file." +-.PP +-Note that in this implementation of ebtables, among lists uses must be +-internally homogeneous regarding whether IP addresses are present or not. Mixed +-use of MAC addresses and MAC/IP address pairs is not supported yet. + .SS arp + Specify (R)ARP fields. The protocol must be specified as + .IR ARP " or " RARP . +diff --git a/iptables/nft.c b/iptables/nft.c +index 0287add3fb21f..4930b6de534d8 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -1029,19 +1029,28 @@ static int __add_nft_among(struct nft_handle *h, const char *table, + }; + struct nftnl_expr *e; + struct nftnl_set *s; ++ uint32_t flags = 0; + int idx = 0; + + if (ip) { + type = type << CONCAT_TYPE_BITS | NFT_DATATYPE_IPADDR; + len += sizeof(struct in_addr) + NETLINK_ALIGN - 1; + len &= ~(NETLINK_ALIGN - 1); ++ flags = NFT_SET_INTERVAL; + } + +- s = add_anon_set(h, table, 0, type, len, cnt); ++ s = add_anon_set(h, table, flags, type, len, cnt); + if (!s) + return -ENOMEM; + set_id = nftnl_set_get_u32(s, NFTNL_SET_ID); + ++ if (ip) { ++ uint8_t field_len[2] = { ETH_ALEN, sizeof(struct in_addr) }; ++ ++ nftnl_set_set_data(s, NFTNL_SET_DESC_CONCAT, ++ field_len, sizeof(field_len)); ++ } ++ + for (idx = 0; idx < cnt; idx++) { + struct nftnl_set_elem *elem = nftnl_set_elem_alloc(); + +@@ -1049,6 +1058,15 @@ static int __add_nft_among(struct nft_handle *h, const char *table, + return -ENOMEM; + nftnl_set_elem_set(elem, NFTNL_SET_ELEM_KEY, + &pairs[idx], len); ++ if (ip) { ++ struct in_addr tmp = pairs[idx].in; ++ ++ if (tmp.s_addr == INADDR_ANY) ++ pairs[idx].in.s_addr = INADDR_BROADCAST; ++ nftnl_set_elem_set(elem, NFTNL_SET_ELEM_KEY_END, ++ &pairs[idx], len); ++ pairs[idx].in = tmp; ++ } + nftnl_set_elem_add(s, elem); + } + +-- +2.26.2 + diff --git a/0019-xtables-Align-effect-of-4-6-options-with-legacy.patch b/0019-xtables-Align-effect-of-4-6-options-with-legacy.patch new file mode 100644 index 0000000..fb77d66 --- /dev/null +++ b/0019-xtables-Align-effect-of-4-6-options-with-legacy.patch @@ -0,0 +1,157 @@ +From aa221d3a7ffc8e3245d9031173b306431ddfaf9f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 21 Feb 2020 13:18:32 +0100 +Subject: [PATCH] xtables: Align effect of -4/-6 options with legacy + +Legacy iptables doesn't accept -4 or -6 if they don't match the +symlink's native family. The only exception to that is iptables-restore +which simply ignores the lines introduced by non-matching options, which +is useful to create combined dump files for feeding into both +iptables-restore and ip6tables-restore. + +Signed-off-by: Phil Sutter +(cherry picked from commit 1639b8ba5105542c73e0e1c35e70f245dab89d81) +Signed-off-by: Phil Sutter +--- + .../shell/testcases/iptables/0006-46-args_0 | 88 +++++++++++++++++++ + iptables/xtables.c | 21 ++--- + 2 files changed, 96 insertions(+), 13 deletions(-) + create mode 100755 iptables/tests/shell/testcases/iptables/0006-46-args_0 + +diff --git a/iptables/tests/shell/testcases/iptables/0006-46-args_0 b/iptables/tests/shell/testcases/iptables/0006-46-args_0 +new file mode 100755 +index 0000000000000..17a0a01829df5 +--- /dev/null ++++ b/iptables/tests/shell/testcases/iptables/0006-46-args_0 +@@ -0,0 +1,88 @@ ++#!/bin/bash ++ ++RC=0 ++ ++$XT_MULTI iptables -6 -A FORWARD -j ACCEPT ++rc=$? ++if [[ $rc -ne 2 ]]; then ++ echo "'iptables -6' returned $rc instead of 2" ++ RC=1 ++fi ++ ++$XT_MULTI ip6tables -4 -A FORWARD -j ACCEPT ++rc=$? ++if [[ $rc -ne 2 ]]; then ++ echo "'ip6tables -4' returned $rc instead of 2" ++ RC=1 ++fi ++ ++RULESET='*filter ++-4 -A FORWARD -d 10.0.0.1 -j ACCEPT ++-6 -A FORWARD -d fec0:10::1 -j ACCEPT ++COMMIT ++' ++EXPECT4='-P FORWARD ACCEPT ++-A FORWARD -d 10.0.0.1/32 -j ACCEPT' ++EXPECT6='-P FORWARD ACCEPT ++-A FORWARD -d fec0:10::1/128 -j ACCEPT' ++EXPECT_EMPTY='-P FORWARD ACCEPT' ++ ++echo "$RULESET" | $XT_MULTI iptables-restore || { ++ echo "iptables-restore failed!" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || { ++ echo "unexpected iptables ruleset" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || { ++ echo "unexpected non-empty ip6tables ruleset" ++ RC=1 ++} ++ ++$XT_MULTI iptables -F FORWARD ++ ++echo "$RULESET" | $XT_MULTI ip6tables-restore || { ++ echo "ip6tables-restore failed!" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || { ++ echo "unexpected ip6tables ruleset" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || { ++ echo "unexpected non-empty iptables ruleset" ++ RC=1 ++} ++ ++$XT_MULTI ip6tables -F FORWARD ++ ++$XT_MULTI iptables -4 -A FORWARD -d 10.0.0.1 -j ACCEPT || { ++ echo "iptables failed!" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || { ++ echo "unexpected iptables ruleset" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || { ++ echo "unexpected non-empty ip6tables ruleset" ++ RC=1 ++} ++ ++$XT_MULTI iptables -F FORWARD ++ ++$XT_MULTI ip6tables -6 -A FORWARD -d fec0:10::1 -j ACCEPT || { ++ echo "ip6tables failed!" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || { ++ echo "unexpected ip6tables ruleset" ++ RC=1 ++} ++diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || { ++ echo "unexpected non-empty iptables ruleset" ++ RC=1 ++} ++ ++exit $RC +diff --git a/iptables/xtables.c b/iptables/xtables.c +index 4b24d15c46295..8c2d21d42b7d2 100644 +--- a/iptables/xtables.c ++++ b/iptables/xtables.c +@@ -913,27 +913,22 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], + break; + + case '4': ++ if (args->family == AF_INET) ++ break; ++ + if (p->restore && args->family == AF_INET6) + return; + +- if (args->family != AF_INET) +- exit_tryhelp(2); +- +- h->ops = nft_family_ops_lookup(args->family); +- break; ++ exit_tryhelp(2); + + case '6': ++ if (args->family == AF_INET6) ++ break; ++ + if (p->restore && args->family == AF_INET) + return; + +- args->family = AF_INET6; +- xtables_set_nfproto(AF_INET6); +- +- h->ops = nft_family_ops_lookup(args->family); +- if (h->ops == NULL) +- xtables_error(PARAMETER_PROBLEM, +- "Unknown family"); +- break; ++ exit_tryhelp(2); + + case 1: /* non option */ + if (optarg[0] == '!' && optarg[1] == '\0') { +-- +2.26.2 + diff --git a/0020-xtables-Drop-4-and-6-support-from-xtables-save-resto.patch b/0020-xtables-Drop-4-and-6-support-from-xtables-save-resto.patch new file mode 100644 index 0000000..ccd6b5d --- /dev/null +++ b/0020-xtables-Drop-4-and-6-support-from-xtables-save-resto.patch @@ -0,0 +1,81 @@ +From ea9d40744307d7c49808d8fabfc904d525081055 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 21 Feb 2020 13:29:05 +0100 +Subject: [PATCH] xtables: Drop -4 and -6 support from xtables-{save,restore} + +Legacy tools don't support those options, either. + +Signed-off-by: Phil Sutter +(cherry picked from commit 0f40a8bc49d3f7b815336199931a82f919f37c4e) +Signed-off-by: Phil Sutter +--- + iptables/xtables-restore.c | 9 +-------- + iptables/xtables-save.c | 11 +---------- + 2 files changed, 2 insertions(+), 18 deletions(-) + +diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c +index 11834c0ea98c5..c472ac9bf651b 100644 +--- a/iptables/xtables-restore.c ++++ b/iptables/xtables-restore.c +@@ -379,7 +379,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) + exit(1); + } + +- while ((c = getopt_long(argc, argv, "bcvVthnM:T:46wW", options, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, "bcvVthnM:T:wW", options, NULL)) != -1) { + switch (c) { + case 'b': + fprintf(stderr, "-b/--binary option is not implemented\n"); +@@ -408,13 +408,6 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) + case 'T': + p.tablename = optarg; + break; +- case '4': +- h.family = AF_INET; +- break; +- case '6': +- h.family = AF_INET6; +- xtables_set_nfproto(AF_INET6); +- break; + case 'w': /* fallthrough. Ignored by xt-restore */ + case 'W': + if (!optarg && xs_has_arg(argc, argv)) +diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c +index 228282deaed07..28f7490275ce5 100644 +--- a/iptables/xtables-save.c ++++ b/iptables/xtables-save.c +@@ -32,7 +32,7 @@ + #define prog_name xtables_globals.program_name + #define prog_vers xtables_globals.program_version + +-static const char *ipt_save_optstring = "bcdt:M:f:46V"; ++static const char *ipt_save_optstring = "bcdt:M:f:V"; + static const struct option ipt_save_options[] = { + {.name = "counters", .has_arg = false, .val = 'c'}, + {.name = "version", .has_arg = false, .val = 'V'}, +@@ -40,8 +40,6 @@ static const struct option ipt_save_options[] = { + {.name = "table", .has_arg = true, .val = 't'}, + {.name = "modprobe", .has_arg = true, .val = 'M'}, + {.name = "file", .has_arg = true, .val = 'f'}, +- {.name = "ipv4", .has_arg = false, .val = '4'}, +- {.name = "ipv6", .has_arg = false, .val = '6'}, + {NULL}, + }; + +@@ -187,13 +185,6 @@ xtables_save_main(int family, int argc, char *argv[], + case 'd': + dump = true; + break; +- case '4': +- h.family = AF_INET; +- break; +- case '6': +- h.family = AF_INET6; +- xtables_set_nfproto(AF_INET6); +- break; + case 'V': + printf("%s v%s (nf_tables)\n", prog_name, prog_vers); + exit(0); +-- +2.26.2 + diff --git a/0021-nfnl_osf-Fix-broken-conversion-to-nfnl_query.patch b/0021-nfnl_osf-Fix-broken-conversion-to-nfnl_query.patch new file mode 100644 index 0000000..0ca025c --- /dev/null +++ b/0021-nfnl_osf-Fix-broken-conversion-to-nfnl_query.patch @@ -0,0 +1,42 @@ +From b29b3a215b9cbec20ea633e6a861accfc48b59bb Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 9 May 2020 13:36:49 +0200 +Subject: [PATCH] nfnl_osf: Fix broken conversion to nfnl_query() + +Due to missing NLM_F_ACK flag in request, nfnetlink code in kernel +didn't create an own ACK message but left it upon subsystem to ACK or +not. Since nfnetlink_osf doesn't ACK by itself, nfnl_query() got stuck +waiting for a reply. + +Whoever did the conversion from deprecated nfnl_talk() obviously didn't +even test basic functionality of the tool. + +Fixes: 52aa15098ebd6 ("nfnl_osf: Replace deprecated nfnl_talk() by nfnl_query()") +Signed-off-by: Phil Sutter +(cherry picked from commit c8332553caf48132403895bae750b3cd09a2efd8) +Signed-off-by: Phil Sutter +--- + utils/nfnl_osf.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/utils/nfnl_osf.c b/utils/nfnl_osf.c +index 15d531975e11d..922d90ac135b7 100644 +--- a/utils/nfnl_osf.c ++++ b/utils/nfnl_osf.c +@@ -378,9 +378,11 @@ static int osf_load_line(char *buffer, int len, int del) + memset(buf, 0, sizeof(buf)); + + if (del) +- nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_REMOVE, NLM_F_REQUEST); ++ nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_REMOVE, ++ NLM_F_ACK | NLM_F_REQUEST); + else +- nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_ADD, NLM_F_REQUEST | NLM_F_CREATE); ++ nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_ADD, ++ NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE); + + nfnl_addattr_l(nmh, sizeof(buf), OSF_ATTR_FINGER, &f, sizeof(struct xt_osf_user_finger)); + +-- +2.26.2 + diff --git a/0022-nfnl_osf-Improve-error-handling.patch b/0022-nfnl_osf-Improve-error-handling.patch new file mode 100644 index 0000000..df9cfd3 --- /dev/null +++ b/0022-nfnl_osf-Improve-error-handling.patch @@ -0,0 +1,80 @@ +From acc1fb93b3674f81c9d1daa0e4e855410d2568b0 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 9 May 2020 13:42:56 +0200 +Subject: [PATCH] nfnl_osf: Improve error handling + +For some error cases, no log message was created - hence apart from the +return code there was no indication of failing execution. + +If a line load fails, don't abort but continue with the remaining +file contents. The current pf.os file in this repository serves as +proof-of-concept: + +Lines 700 and 701: Duplicates of lines 698 and 699 because 'W*' and 'W0' +parse into the same data. + +Line 704: Duplicate of line 702 because apart from 'W*' and 'W0', only +the first three fields on right-hand side are sent to the kernel. + +When loading, these dups are ignored (they would bounce if NLM_F_EXCL +was given). Upon deletion, they cause ENOENT response from kernel. In +order to align duplicate-tolerance in both modes, just ignore that +ENOENT. + +Signed-off-by: Phil Sutter +(cherry picked from commit 3e09bd1888575cfec136574d2b0e810ba33f1cfb) +Signed-off-by: Phil Sutter +--- + utils/nfnl_osf.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/utils/nfnl_osf.c b/utils/nfnl_osf.c +index 922d90ac135b7..8008e83d8af4b 100644 +--- a/utils/nfnl_osf.c ++++ b/utils/nfnl_osf.c +@@ -392,7 +392,7 @@ static int osf_load_line(char *buffer, int len, int del) + static int osf_load_entries(char *path, int del) + { + FILE *inf; +- int err = 0; ++ int err = 0, lineno = 0; + char buf[1024]; + + inf = fopen(path, "r"); +@@ -402,7 +402,9 @@ static int osf_load_entries(char *path, int del) + } + + while(fgets(buf, sizeof(buf), inf)) { +- int len; ++ int len, rc; ++ ++ lineno++; + + if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') + continue; +@@ -414,9 +416,11 @@ static int osf_load_entries(char *path, int del) + + buf[len] = '\0'; + +- err = osf_load_line(buf, len, del); +- if (err) +- break; ++ rc = osf_load_line(buf, len, del); ++ if (rc && (!del || errno != ENOENT)) { ++ ulog_err("Failed to load line %d", lineno); ++ err = rc; ++ } + + memset(buf, 0, sizeof(buf)); + } +@@ -448,6 +452,7 @@ int main(int argc, char *argv[]) + + if (!fingerprints) { + err = -ENOENT; ++ ulog("Missing fingerprints file argument.\n"); + goto err_out_exit; + } + +-- +2.26.2 + diff --git a/0023-nft-cache-Reset-genid-when-rebuilding-cache.patch b/0023-nft-cache-Reset-genid-when-rebuilding-cache.patch new file mode 100644 index 0000000..67f69ea --- /dev/null +++ b/0023-nft-cache-Reset-genid-when-rebuilding-cache.patch @@ -0,0 +1,37 @@ +From 3b98024d952d265d50078c5b7ad04c9c65373733 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 29 May 2020 19:33:22 +0200 +Subject: [PATCH] nft: cache: Reset genid when rebuilding cache + +This is required in order to avoid a cache rebuild loop if +iptables-nft-restore is called with '--test' parameter and a dump +containing more than a single table. + +If non-zero, __nft_build_cache() never updates genid and therefore the +incorrect genid (caused by increment in nft_action()) is never +corrected. + +This is a RHEL-only fix, upstream rewrote the whole cache logic which +implicitly resolved this problem. + +Fixes: 200bc39965149 ("nft: cache: Fix iptables-save segfault under stress") +Signed-off-by: Phil Sutter +--- + iptables/nft-cache.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c +index 07265b7795e4f..bc6e7f7eaebfb 100644 +--- a/iptables/nft-cache.c ++++ b/iptables/nft-cache.c +@@ -629,6 +629,7 @@ void nft_rebuild_cache(struct nft_handle *h) + if (h->cache_level) + __nft_flush_cache(h); + ++ h->nft_genid = 0; + h->cache_level = NFT_CL_NONE; + __nft_build_cache(h, level, NULL, NULL, NULL); + } +-- +2.26.2 + diff --git a/0024-nft-Fix-for-F-in-iptables-dumps.patch b/0024-nft-Fix-for-F-in-iptables-dumps.patch new file mode 100644 index 0000000..cf2c571 --- /dev/null +++ b/0024-nft-Fix-for-F-in-iptables-dumps.patch @@ -0,0 +1,81 @@ +From 8ae56bbaa4119bdcf1d6abc8b78f21490657983c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 24 Apr 2020 11:32:08 +0200 +Subject: [PATCH] nft: Fix for '-F' in iptables dumps + +When restoring a dump which contains an explicit flush command, +previously added rules are removed from cache and the following commit +will try to create netlink messages based on freed memory. + +Fix this by weeding any rule-based commands from obj_list if they +address the same chain. + +Signed-off-by: Phil Sutter +(cherry picked from commit 5bd3ab5c778033877d44a0c619ef6f98f34516af) +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 4930b6de534d8..e95e99f1d8d71 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -411,6 +411,38 @@ batch_rule_add(struct nft_handle *h, enum obj_update_type type, + return batch_add(h, type, r); + } + ++static void batch_obj_del(struct nft_handle *h, struct obj_update *o); ++ ++static void batch_chain_flush(struct nft_handle *h, ++ const char *table, const char *chain) ++{ ++ struct obj_update *obj, *tmp; ++ ++ list_for_each_entry_safe(obj, tmp, &h->obj_list, head) { ++ struct nftnl_rule *r = obj->ptr; ++ ++ switch (obj->type) { ++ case NFT_COMPAT_RULE_APPEND: ++ case NFT_COMPAT_RULE_INSERT: ++ case NFT_COMPAT_RULE_REPLACE: ++ case NFT_COMPAT_RULE_DELETE: ++ break; ++ default: ++ continue; ++ } ++ ++ if (table && ++ strcmp(table, nftnl_rule_get_str(r, NFTNL_RULE_TABLE))) ++ continue; ++ ++ if (chain && ++ strcmp(chain, nftnl_rule_get_str(r, NFTNL_RULE_CHAIN))) ++ continue; ++ ++ batch_obj_del(h, obj); ++ } ++} ++ + const struct builtin_table xtables_ipv4[NFT_TABLE_MAX] = { + [NFT_TABLE_RAW] = { + .name = "raw", +@@ -1671,6 +1703,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, + } + + if (chain || !verbose) { ++ batch_chain_flush(h, table, chain); + __nft_rule_flush(h, table, chain, verbose, false); + flush_rule_cache(h, table, c); + return 1; +@@ -1686,6 +1719,7 @@ int nft_rule_flush(struct nft_handle *h, const char *chain, const char *table, + while (c != NULL) { + chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME); + ++ batch_chain_flush(h, table, chain); + __nft_rule_flush(h, table, chain, verbose, false); + flush_rule_cache(h, table, c); + c = nftnl_chain_list_iter_next(iter); +-- +2.27.0 + diff --git a/0025-tests-shell-Test-F-in-dump-files.patch b/0025-tests-shell-Test-F-in-dump-files.patch new file mode 100644 index 0000000..628a565 --- /dev/null +++ b/0025-tests-shell-Test-F-in-dump-files.patch @@ -0,0 +1,37 @@ +From dd98af599516806e2eb3e1186d0ad52ce7c6b4b5 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Tue, 21 Apr 2020 14:10:53 +0200 +Subject: [PATCH] tests: shell: Test -F in dump files + +While not really useful, iptables-nft-restore shouldn't segfault either. +This tests the problem described in nfbz#1407. + +Signed-off-by: Phil Sutter +(cherry picked from commit f2ace0cdf25a5911ac84015829d65d6050a5e82d) +Signed-off-by: Phil Sutter +--- + .../tests/shell/testcases/ipt-restore/0012-dash-F_0 | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + create mode 100755 iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 + +diff --git a/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 b/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 +new file mode 100755 +index 0000000000000..fd82afa1bc8ce +--- /dev/null ++++ b/iptables/tests/shell/testcases/ipt-restore/0012-dash-F_0 +@@ -0,0 +1,12 @@ ++#!/bin/bash -e ++ ++# make sure -F lines don't cause segfaults ++ ++RULESET='*nat ++-F PREROUTING ++-A PREROUTING -j ACCEPT ++-F PREROUTING ++COMMIT' ++ ++echo -e "$RULESET" | $XT_MULTI iptables-restore ++echo -e "$RULESET" | $XT_MULTI iptables-restore -n +-- +2.27.0 + diff --git a/0026-nft-Make-batch_add_chain-return-the-added-batch-obje.patch b/0026-nft-Make-batch_add_chain-return-the-added-batch-obje.patch new file mode 100644 index 0000000..4e077ad --- /dev/null +++ b/0026-nft-Make-batch_add_chain-return-the-added-batch-obje.patch @@ -0,0 +1,167 @@ +From d1b516014e4883f30ee2faf264dd89a6d7940e2c 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) + +Conflicts: + iptables/nft.c +-> Upstream changed good/bad return codes of nft_chain_restore() + function. + +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 35 +++++++++++++++++------------------ + 1 file changed, 17 insertions(+), 18 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index e95e99f1d8d71..0efd18d57320f 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -398,10 +398,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 * +@@ -910,7 +911,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; + +@@ -924,10 +924,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) +@@ -1734,7 +1735,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; + +@@ -1754,14 +1754,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) +@@ -1769,7 +1770,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) { +@@ -1794,13 +1794,14 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table + if (!created) + return 0; + +- ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c); ++ if (!batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c)) ++ return -1; + + list = nft_chain_list_get(h, table, chain); + if (list) + nftnl_chain_list_add(c, list); + +- return ret; ++ return 0; + } + + /* From linux/netlink.h */ +@@ -1818,7 +1819,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)) +@@ -1834,8 +1834,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); +@@ -1910,7 +1909,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; + +@@ -1941,10 +1939,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) +@@ -3217,7 +3216,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.28.0 + diff --git a/0027-nft-Fix-error-reporting-for-refreshed-transactions.patch b/0027-nft-Fix-error-reporting-for-refreshed-transactions.patch new file mode 100644 index 0000000..c0a8f40 --- /dev/null +++ b/0027-nft-Fix-error-reporting-for-refreshed-transactions.patch @@ -0,0 +1,42 @@ +From 2dff9a669400644ec1e66d394b03d743eec2cd55 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) +Signed-off-by: Phil Sutter +--- + iptables/nft.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/iptables/nft.c b/iptables/nft.c +index 0efd18d57320f..d661ac2cafda6 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -2767,9 +2767,10 @@ retry: + 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.28.0 + diff --git a/0028-nft-Fix-for-concurrent-noflush-restore-calls.patch b/0028-nft-Fix-for-concurrent-noflush-restore-calls.patch new file mode 100644 index 0000000..98a7ebb --- /dev/null +++ b/0028-nft-Fix-for-concurrent-noflush-restore-calls.patch @@ -0,0 +1,242 @@ +From 575a1e5589f813af7e838c045863b510b4740353 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) + +Conflicts: + iptables/nft.c +-> Upstream changed good/bad return codes of nft_chain_restore() + function. + +Signed-off-by: Phil Sutter +--- + 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 d661ac2cafda6..dc5490c085364 100644 +--- a/iptables/nft.c ++++ b/iptables/nft.c +@@ -283,7 +283,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; +@@ -1650,7 +1649,7 @@ int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format) + + 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; +@@ -1672,7 +1671,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, +@@ -1768,17 +1767,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 -1; +@@ -1786,20 +1780,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 0; ++ __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 -1; + +- list = nft_chain_list_get(h, table, chain); +- if (list) +- nftnl_chain_list_add(c, list); ++ obj->skip = !created; + + return 0; + } +@@ -2693,11 +2693,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); +@@ -2723,14 +2718,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: +@@ -2742,7 +2745,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: + break; + } +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.28.0 + diff --git a/0029-tests-shell-Improve-concurrent-noflush-restore-test-.patch b/0029-tests-shell-Improve-concurrent-noflush-restore-test-.patch new file mode 100644 index 0000000..6d5d040 --- /dev/null +++ b/0029-tests-shell-Improve-concurrent-noflush-restore-test-.patch @@ -0,0 +1,55 @@ +From 674cce10a34e90f2791a3d58789793eef29e8f8b 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) +Signed-off-by: Phil Sutter +--- + .../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.28.0 + diff --git a/0030-nft-cache-Make-nft_rebuild_cache-respect-fake-cache.patch b/0030-nft-cache-Make-nft_rebuild_cache-respect-fake-cache.patch new file mode 100644 index 0000000..e802197 --- /dev/null +++ b/0030-nft-cache-Make-nft_rebuild_cache-respect-fake-cache.patch @@ -0,0 +1,80 @@ +From 2c183a2457d8640aaee3a98fc8fea70bf64d46f2 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Sat, 29 Feb 2020 02:08:26 +0100 +Subject: [PATCH] nft: cache: Make nft_rebuild_cache() respect fake cache + +If transaction needed a refresh in nft_action(), restore with flush +would fetch a full cache instead of merely refreshing table list +contained in "fake" cache. + +To fix this, nft_rebuild_cache() must distinguish between fake cache and +full rule cache. Therefore introduce NFT_CL_FAKE to be distinguished +from NFT_CL_RULES. + +Signed-off-by: Phil Sutter +(cherry picked from commit 40ad7793d1884f28767cf58c96e9d76ae0a18db1) + +RHEL-only fix: Make nft_rebuild_cache() check 'level' instead of +'h->cache_level' as the latter may be reset by __nft_flush_cache(). + +Signed-off-by: Phil Sutter +--- + iptables/nft-cache.c | 13 +++++++++---- + iptables/nft.h | 3 ++- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c +index bc6e7f7eaebfb..9623b463f0dd5 100644 +--- a/iptables/nft-cache.c ++++ b/iptables/nft-cache.c +@@ -480,6 +480,7 @@ __nft_build_cache(struct nft_handle *h, enum nft_cache_level level, + break; + /* fall through */ + case NFT_CL_RULES: ++ case NFT_CL_FAKE: + break; + } + +@@ -516,7 +517,7 @@ void nft_fake_cache(struct nft_handle *h) + + h->cache->table[type].chains = nftnl_chain_list_alloc(); + } +- h->cache_level = NFT_CL_RULES; ++ h->cache_level = NFT_CL_FAKE; + mnl_genid_get(h, &h->nft_genid); + } + +@@ -629,9 +630,13 @@ void nft_rebuild_cache(struct nft_handle *h) + if (h->cache_level) + __nft_flush_cache(h); + +- h->nft_genid = 0; +- h->cache_level = NFT_CL_NONE; +- __nft_build_cache(h, level, NULL, NULL, NULL); ++ if (level == NFT_CL_FAKE) { ++ nft_fake_cache(h); ++ } else { ++ h->nft_genid = 0; ++ h->cache_level = NFT_CL_NONE; ++ __nft_build_cache(h, level, NULL, NULL, NULL); ++ } + } + + void nft_release_cache(struct nft_handle *h) +diff --git a/iptables/nft.h b/iptables/nft.h +index 5cf260a6d2cd3..2094b01455194 100644 +--- a/iptables/nft.h ++++ b/iptables/nft.h +@@ -32,7 +32,8 @@ enum nft_cache_level { + NFT_CL_TABLES, + NFT_CL_CHAINS, + NFT_CL_SETS, +- NFT_CL_RULES ++ NFT_CL_RULES, ++ NFT_CL_FAKE /* must be last entry */ + }; + + struct nft_cache { +-- +2.28.0 + diff --git a/0031-nft-Fix-for-broken-address-mask-match-detection.patch b/0031-nft-Fix-for-broken-address-mask-match-detection.patch new file mode 100644 index 0000000..3f69e13 --- /dev/null +++ b/0031-nft-Fix-for-broken-address-mask-match-detection.patch @@ -0,0 +1,60 @@ +From 74a62264d4615ae7f76454e7ca406c46a62c7999 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) +Signed-off-by: Phil Sutter +--- + 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 78e422781723f..f60f5df97fb86 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.28.0 + diff --git a/0032-nft-Optimize-class-based-IP-prefix-matches.patch b/0032-nft-Optimize-class-based-IP-prefix-matches.patch new file mode 100644 index 0000000..80f79a2 --- /dev/null +++ b/0032-nft-Optimize-class-based-IP-prefix-matches.patch @@ -0,0 +1,150 @@ +From 87a2128fcfd4c5b0847a8c611652ade8c54d8185 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) +Signed-off-by: Phil Sutter +--- + 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 d4a86610ec217..ac400e484a4fa 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 70634f8fad84d..c84af2df90da7 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 d01491bfdb689..cfced245a781c 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 f60f5df97fb86..b1237049d0a34 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 bee99a7dd0c93..c7f1e366b75ee 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -252,4 +252,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.28.0 + diff --git a/0033-ebtables-Optimize-masked-MAC-address-matches.patch b/0033-ebtables-Optimize-masked-MAC-address-matches.patch new file mode 100644 index 0000000..f70a4fa --- /dev/null +++ b/0033-ebtables-Optimize-masked-MAC-address-matches.patch @@ -0,0 +1,218 @@ +From 03a484b63c5a61678555bcaca68fa36dc81468c1 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) +Signed-off-by: Phil Sutter +--- + 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 ac400e484a4fa..776b55949472b 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 3f85cbbf5e4cf..2aa15e2d1e69d 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 c84af2df90da7..5bd0710781533 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 cfced245a781c..6ece631d85f59 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 b1237049d0a34..2aae0a3a49dfe 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 c7f1e366b75ee..520a296fb530c 100644 +--- a/iptables/nft-shared.h ++++ b/iptables/nft-shared.h +@@ -8,6 +8,7 @@ + #include + + #include ++#include + + #include "xshared.h" + +@@ -124,7 +125,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.28.0 + diff --git a/0034-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch b/0034-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch new file mode 100644 index 0000000..281a9d4 --- /dev/null +++ b/0034-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch @@ -0,0 +1,366 @@ +From 6aef90100bebe2b00d4edffe59fb9c43643816de 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) +Signed-off-by: Phil Sutter +--- + .../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.28.0 + diff --git a/0035-libxtables-Make-sure-extensions-register-in-revision.patch b/0035-libxtables-Make-sure-extensions-register-in-revision.patch new file mode 100644 index 0000000..9ab85d2 --- /dev/null +++ b/0035-libxtables-Make-sure-extensions-register-in-revision.patch @@ -0,0 +1,128 @@ +From e6eede725bbd395fb8b385aec4d0a32ce99e842c 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) +Signed-off-by: Phil Sutter +--- + libxtables/xtables.c | 71 +++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 64 insertions(+), 7 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 777c2b08e9896..13139d7f8ad62 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -902,8 +902,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); +@@ -955,10 +961,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 + } + + /** +@@ -1097,6 +1127,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); +@@ -1152,9 +1185,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.28.0 + diff --git a/0036-libxtables-Simplify-pending-extension-registration.patch b/0036-libxtables-Simplify-pending-extension-registration.patch new file mode 100644 index 0000000..9b527a5 --- /dev/null +++ b/0036-libxtables-Simplify-pending-extension-registration.patch @@ -0,0 +1,241 @@ +From 1a842fb1cfb3b36f3081aee37c5fdd4a897d77d5 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) +Signed-off-by: Phil Sutter +--- + libxtables/xtables.c | 128 +++++++++++-------------------------------- + 1 file changed, 33 insertions(+), 95 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 13139d7f8ad62..409128333e0e6 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); + + void xtables_init(void) + { +@@ -616,6 +618,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"; +@@ -637,8 +640,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); +@@ -732,6 +739,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; + +@@ -748,8 +756,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); +@@ -1052,64 +1064,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; +@@ -1214,11 +1189,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. */ +@@ -1227,54 +1202,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.28.0 + diff --git a/0037-libxtables-Register-multiple-extensions-in-ascending.patch b/0037-libxtables-Register-multiple-extensions-in-ascending.patch new file mode 100644 index 0000000..1146305 --- /dev/null +++ b/0037-libxtables-Register-multiple-extensions-in-ascending.patch @@ -0,0 +1,52 @@ +From cfcafd3638cdc06a8b4a1d267e58b5ad1e35922c 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) +Signed-off-by: Phil Sutter +--- + libxtables/xtables.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/libxtables/xtables.c b/libxtables/xtables.c +index 409128333e0e6..28ffffedd8147 100644 +--- a/libxtables/xtables.c ++++ b/libxtables/xtables.c +@@ -1095,9 +1095,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) +@@ -1223,9 +1224,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.28.0 + diff --git a/0038-tests-shell-Test-for-fixed-extension-registration.patch b/0038-tests-shell-Test-for-fixed-extension-registration.patch new file mode 100644 index 0000000..7a5cca6 --- /dev/null +++ b/0038-tests-shell-Test-for-fixed-extension-registration.patch @@ -0,0 +1,53 @@ +From f5185f4efad409fc7ec4ae05267b642ee4103a6c 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) +Signed-off-by: Phil Sutter +--- + .../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.28.0 + diff --git a/0039-extensions-libipt_icmp-Fix-translation-of-type-any.patch b/0039-extensions-libipt_icmp-Fix-translation-of-type-any.patch new file mode 100644 index 0000000..c1c430d --- /dev/null +++ b/0039-extensions-libipt_icmp-Fix-translation-of-type-any.patch @@ -0,0 +1,52 @@ +From 6adcdca2aaf8cba6ee452c88f41ad8695bebdcfc 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) +Signed-off-by: Phil Sutter +--- + 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.28.0 + diff --git a/0040-extensions-libxt_CT-add-translation-for-NOTRACK.patch b/0040-extensions-libxt_CT-add-translation-for-NOTRACK.patch new file mode 100644 index 0000000..ca1316b --- /dev/null +++ b/0040-extensions-libxt_CT-add-translation-for-NOTRACK.patch @@ -0,0 +1,66 @@ +From 1695f552d3947299e54978bcd5bc1cdc3a5c14f7 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Wed, 15 Apr 2020 18:16:41 +0200 +Subject: [PATCH] extensions: libxt_CT: add translation for NOTRACK + +Signed-off-by: Pablo Neira Ayuso +(cherry picked from commit f3d4a3ddbcfca15a00dd9758f481420038f6de10) +Signed-off-by: Phil Sutter +--- + extensions/libxt_CT.c | 16 ++++++++++++++++ + extensions/libxt_NOTRACK.txlate | 2 ++ + 2 files changed, 18 insertions(+) + create mode 100644 extensions/libxt_NOTRACK.txlate + +diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c +index 371b21766c56c..fbbbe2660e9fc 100644 +--- a/extensions/libxt_CT.c ++++ b/extensions/libxt_CT.c +@@ -348,6 +348,20 @@ static void notrack_ct2_tg_init(struct xt_entry_target *target) + info->flags = XT_CT_NOTRACK | XT_CT_NOTRACK_ALIAS; + } + ++static int xlate_ct1_tg(struct xt_xlate *xl, ++ const struct xt_xlate_tg_params *params) ++{ ++ struct xt_ct_target_info_v1 *info = ++ (struct xt_ct_target_info_v1 *)params->target->data; ++ ++ if (info->flags & XT_CT_NOTRACK) ++ xt_xlate_add(xl, "notrack"); ++ else ++ return 0; ++ ++ return 1; ++} ++ + static struct xtables_target ct_target_reg[] = { + { + .family = NFPROTO_UNSPEC, +@@ -387,6 +401,7 @@ static struct xtables_target ct_target_reg[] = { + .alias = ct_print_name_alias, + .x6_parse = ct_parse_v1, + .x6_options = ct_opts_v1, ++ .xlate = xlate_ct1_tg, + }, + { + .family = NFPROTO_UNSPEC, +@@ -418,6 +433,7 @@ static struct xtables_target ct_target_reg[] = { + .size = XT_ALIGN(sizeof(struct xt_ct_target_info_v1)), + .userspacesize = offsetof(struct xt_ct_target_info_v1, ct), + .init = notrack_ct2_tg_init, ++ .xlate = xlate_ct1_tg, + }, + { + .family = NFPROTO_UNSPEC, +diff --git a/extensions/libxt_NOTRACK.txlate b/extensions/libxt_NOTRACK.txlate +new file mode 100644 +index 0000000000000..9d35619d3dbdd +--- /dev/null ++++ b/extensions/libxt_NOTRACK.txlate +@@ -0,0 +1,2 @@ ++iptables-translate -A PREROUTING -t raw -j NOTRACK ++nft add rule ip raw PREROUTING counter notrack +-- +2.28.0 + diff --git a/0041-nft-Fix-command-name-in-ip6tables-error-message.patch b/0041-nft-Fix-command-name-in-ip6tables-error-message.patch new file mode 100644 index 0000000..3a57697 --- /dev/null +++ b/0041-nft-Fix-command-name-in-ip6tables-error-message.patch @@ -0,0 +1,45 @@ +From 6d8a390bd13bac294ff9de225a49fe9e4de2d6e5 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) +Signed-off-by: Phil Sutter +--- + 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 022d5dd44abbf..b5b7ccaf4e660 100644 +--- a/iptables/xtables-standalone.c ++++ b/iptables/xtables-standalone.c +@@ -74,14 +74,10 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) + nft_fini(&h); + + 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.28.0 + diff --git a/0042-tests-shell-Merge-and-extend-return-codes-test.patch b/0042-tests-shell-Merge-and-extend-return-codes-test.patch new file mode 100644 index 0000000..93ce99a --- /dev/null +++ b/0042-tests-shell-Merge-and-extend-return-codes-test.patch @@ -0,0 +1,206 @@ +From c5f07a7d718f812f916686926567adbac6c1b125 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) + +Conflicts: + iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 + iptables/tests/shell/testcases/iptables/0004-return-codes_0 +-> Missing upstream commit a7f1e208cdf9c ("nft: split parsing from + netlink commands") which added a few tests to both files. + +Signed-off-by: Phil Sutter +--- + .../testcases/ip6tables/0004-return-codes_0 | 38 ------- + .../testcases/iptables/0004-return-codes_0 | 104 ++++++++++-------- + 2 files changed, 58 insertions(+), 84 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 f023b7915498e..0000000000000 +--- a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 ++++ /dev/null +@@ -1,38 +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 +- +-# 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 ce02e0bcb128b..67f1698945753 100755 +--- a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 ++++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 +@@ -13,69 +13,81 @@ 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 0 -E foo bar ++cmd 1 "$EEXIST_F" -E foo bar + + # test rule adding +-cmd 0 iptables -A INPUT -j ACCEPT +-cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT ++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.28.0 + diff --git a/0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch b/0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch new file mode 100644 index 0000000..bf463a2 --- /dev/null +++ b/0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch @@ -0,0 +1,177 @@ +From 98794894774a39927bc975921fc9e40f00db937b 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) +Signed-off-by: Phil Sutter +--- + 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.28.0 + diff --git a/0044-xtables-monitor-Fix-ip6tables-rule-printing.patch b/0044-xtables-monitor-Fix-ip6tables-rule-printing.patch new file mode 100644 index 0000000..c0f14d7 --- /dev/null +++ b/0044-xtables-monitor-Fix-ip6tables-rule-printing.patch @@ -0,0 +1,38 @@ +From 538acaef0d8424bd61047e6f1b81e3bc8bd421ec 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) +Signed-off-by: Phil Sutter +--- + iptables/xtables-monitor.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index c2b31dbaa0795..92962a2a95f48 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.31.1 + diff --git a/0045-xtables-monitor-fix-rule-printing.patch b/0045-xtables-monitor-fix-rule-printing.patch new file mode 100644 index 0000000..c878ec2 --- /dev/null +++ b/0045-xtables-monitor-fix-rule-printing.patch @@ -0,0 +1,86 @@ +From 0b886ea23e8473e692bdf20ecf4985f44408a132 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) +Signed-off-by: Phil Sutter +--- + 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 92962a2a95f48..43b9064c3d30e 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.31.1 + diff --git a/0046-xtables-monitor-fix-packet-family-protocol.patch b/0046-xtables-monitor-fix-packet-family-protocol.patch new file mode 100644 index 0000000..67acb11 --- /dev/null +++ b/0046-xtables-monitor-fix-packet-family-protocol.patch @@ -0,0 +1,39 @@ +From d272e1225bf9b31ec0397bd86b39a54da49d5468 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) +Signed-off-by: Phil Sutter +--- + 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 43b9064c3d30e..9fa1ca166a61e 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.31.1 + diff --git a/0047-xtables-monitor-print-packet-first.patch b/0047-xtables-monitor-print-packet-first.patch new file mode 100644 index 0000000..30ffb03 --- /dev/null +++ b/0047-xtables-monitor-print-packet-first.patch @@ -0,0 +1,102 @@ +From 07f51d26e405b4a328813f35bc27015eb9324330 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) +Signed-off-by: Phil Sutter +--- + 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 9fa1ca166a61e..23e828988bb8b 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.31.1 + diff --git a/0048-xtables-monitor.patch b/0048-xtables-monitor.patch new file mode 100644 index 0000000..128393b --- /dev/null +++ b/0048-xtables-monitor.patch @@ -0,0 +1,31 @@ +From d64511250cf43ae11e18964cc0dccf9c2d6c3973 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) +Signed-off-by: Phil Sutter +--- + iptables/xtables-monitor.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c +index 23e828988bb8b..88033a59526d2 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.31.1 + diff --git a/0049-nft-Fix-bitwise-expression-avoidance-detection.patch b/0049-nft-Fix-bitwise-expression-avoidance-detection.patch new file mode 100644 index 0000000..32ee3e9 --- /dev/null +++ b/0049-nft-Fix-bitwise-expression-avoidance-detection.patch @@ -0,0 +1,74 @@ +From f2d177c3a7a6a7154aabfab6047c510e0cee428e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +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) +Signed-off-by: Phil Sutter +--- + 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 2aae0a3a49dfe..7f757d38ecaec 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) +Signed-off-by: Phil Sutter +--- + 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 5bd0710781533..af5db31532540 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 6ece631d85f59..a5481b3f77ac5 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.31.1 + diff --git a/0051-Eliminate-inet_aton-and-inet_ntoa.patch b/0051-Eliminate-inet_aton-and-inet_ntoa.patch new file mode 100644 index 0000000..668cbce --- /dev/null +++ b/0051-Eliminate-inet_aton-and-inet_ntoa.patch @@ -0,0 +1,120 @@ +From 97b85789657bab340fd7aaaf6d41b8f698f9a5b1 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 af5db31532540..d8c48ce8817b6 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.31.1 + diff --git a/0052-xtables-arp-Don-t-use-ARPT_INV_.patch b/0052-xtables-arp-Don-t-use-ARPT_INV_.patch new file mode 100644 index 0000000..a24c2f8 --- /dev/null +++ b/0052-xtables-arp-Don-t-use-ARPT_INV_.patch @@ -0,0 +1,374 @@ +From a5d52efe21e0f0ba6447b48e1646bb7046cb09eb 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 776b55949472b..ec8147dd58c0d 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 @@ after_devsrc: + 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 @@ after_devsrc: + 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 @@ after_devdst: + 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 @@ after_devdst: + 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 @@ after_devdst: + 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 c8196f08baa59..3f96cb22c3ec0 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, + }; + + /***********************************************/ +@@ -903,7 +903,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.31.1 + diff --git a/0053-nft-arp-Make-use-of-ipv4_addr_to_string.patch b/0053-nft-arp-Make-use-of-ipv4_addr_to_string.patch new file mode 100644 index 0000000..0b98179 --- /dev/null +++ b/0053-nft-arp-Make-use-of-ipv4_addr_to_string.patch @@ -0,0 +1,181 @@ +From 201fd565a1ce44b4af11ce9f245b2fa77c026fed 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 ec8147dd58c0d..7c61c31a13c40 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 16c58914e59a5..e3c8072b5ca96 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -546,9 +546,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 490b19ade5106..e4015c00e2a35 100644 +--- a/iptables/xshared.h ++++ b/iptables/xshared.h +@@ -200,6 +200,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.31.1 + diff --git a/0054-extensions-SECMARK-Implement-revision-1.patch b/0054-extensions-SECMARK-Implement-revision-1.patch new file mode 100644 index 0000000..b271812 --- /dev/null +++ b/0054-extensions-SECMARK-Implement-revision-1.patch @@ -0,0 +1,177 @@ +From 3bd3af273ccfa550ed50ad19d4bcd04a29b88f5b 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.31.1 + diff --git a/0055-extensions-sctp-Fix-nftables-translation.patch b/0055-extensions-sctp-Fix-nftables-translation.patch new file mode 100644 index 0000000..5253354 --- /dev/null +++ b/0055-extensions-sctp-Fix-nftables-translation.patch @@ -0,0 +1,80 @@ +From b675a15b70215deab520ef1a8e52edad9129328e 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.31.1 + diff --git a/0056-extensions-sctp-Translate-chunk-types-option.patch b/0056-extensions-sctp-Translate-chunk-types-option.patch new file mode 100644 index 0000000..9a23f2c --- /dev/null +++ b/0056-extensions-sctp-Translate-chunk-types-option.patch @@ -0,0 +1,159 @@ +From 48f38c4224f31d19176df83539501292fcc6092b 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.31.1 + diff --git a/0057-extensions-SECMARK-Use-a-better-context-in-test-case.patch b/0057-extensions-SECMARK-Use-a-better-context-in-test-case.patch new file mode 100644 index 0000000..6498fa6 --- /dev/null +++ b/0057-extensions-SECMARK-Use-a-better-context-in-test-case.patch @@ -0,0 +1,26 @@ +From 2a45c01c4d3892871b3d3d6b67d10cb62abc561e 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'). +--- + 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.31.1 + diff --git a/0058-nft-cache-Retry-if-kernel-returns-EINTR.patch b/0058-nft-cache-Retry-if-kernel-returns-EINTR.patch new file mode 100644 index 0000000..09af587 --- /dev/null +++ b/0058-nft-cache-Retry-if-kernel-returns-EINTR.patch @@ -0,0 +1,77 @@ +From 681cb811e4cb8c5f22fd0fae60a3533289657705 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 4 Aug 2021 17:14:05 +0200 +Subject: [PATCH] nft: cache: Retry if kernel returns EINTR + +In case of parallel ruleset updates, recvfrom() calls may return EINTR. +Due to the fact that cache fetches may get triggered while iterating +over cache elements, __nft_build_cache must not restart based on +comparing before and after generation ID like upstream does. Instead, +just retry the recvfrom() calls until they either succeed or return a +different error than EINTR. +--- + iptables/nft-cache.c | 18 ++++++++++++++---- + 1 file changed, 14 insertions(+), 4 deletions(-) + +diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c +index 9623b463f0dd5..699dc66a95cd1 100644 +--- a/iptables/nft-cache.c ++++ b/iptables/nft-cache.c +@@ -98,9 +98,12 @@ static int fetch_table_cache(struct nft_handle *h) + nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family, + NLM_F_DUMP, h->seq); + ++retry: + ret = mnl_talk(h, nlh, nftnl_table_list_cb, list); +- if (ret < 0 && errno == EINTR) ++ if (ret < 0 && errno == EINTR) { + assert(nft_restart(h) >= 0); ++ goto retry; ++ } + + h->cache->tables = list; + +@@ -275,10 +278,11 @@ static int fetch_set_cache(struct nft_handle *h, + NLM_F_DUMP, h->seq); + } + ++retry: + ret = mnl_talk(h, nlh, nftnl_set_list_cb, &d); + if (ret < 0 && errno == EINTR) { + assert(nft_restart(h) >= 0); +- return ret; ++ goto retry; + } + + if (t && set) { +@@ -355,9 +359,12 @@ static int fetch_chain_cache(struct nft_handle *h, + h->seq); + } + ++retry: + ret = mnl_talk(h, nlh, nftnl_chain_list_cb, &d); +- if (ret < 0 && errno == EINTR) ++ if (ret < 0 && errno == EINTR) { + assert(nft_restart(h) >= 0); ++ goto retry; ++ } + + return ret; + } +@@ -404,9 +411,12 @@ static int nft_rule_list_update(struct nftnl_chain *c, void *data) + NLM_F_DUMP, h->seq); + nftnl_rule_nlmsg_build_payload(nlh, rule); + ++retry: + ret = mnl_talk(h, nlh, nftnl_rule_list_cb, c); +- if (ret < 0 && errno == EINTR) ++ if (ret < 0 && errno == EINTR) { + assert(nft_restart(h) >= 0); ++ goto retry; ++ } + + nftnl_rule_free(rule); + +-- +2.32.0 + diff --git a/0059-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch b/0059-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch new file mode 100644 index 0000000..51e3fd2 --- /dev/null +++ b/0059-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch @@ -0,0 +1,130 @@ +From 947e9c06a863c47e91a46d2cce90c677a90e4d09 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.33.0 + diff --git a/0060-ebtables-Dump-atomic-waste.patch b/0060-ebtables-Dump-atomic-waste.patch new file mode 100644 index 0000000..4fd9fb7 --- /dev/null +++ b/0060-ebtables-Dump-atomic-waste.patch @@ -0,0 +1,102 @@ +From c1eaf1738533eeec3dc1bdc2285dbf28c68d5042 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 c006bc95ac681..b836616ed0259 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" +@@ -1116,54 +1108,9 @@ print_zero: + "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_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.33.0 + diff --git a/0061-extensions-hashlimit-Fix-tests-with-HZ-100.patch b/0061-extensions-hashlimit-Fix-tests-with-HZ-100.patch new file mode 100644 index 0000000..b52c8b0 --- /dev/null +++ b/0061-extensions-hashlimit-Fix-tests-with-HZ-100.patch @@ -0,0 +1,41 @@ +From ec4a91ac53e4dba210daa9bb3af9e09532c86b06 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.33.0 + diff --git a/0062-extensions-hashlimit-Fix-tests-with-HZ-1000.patch b/0062-extensions-hashlimit-Fix-tests-with-HZ-1000.patch new file mode 100644 index 0000000..81b2c3a --- /dev/null +++ b/0062-extensions-hashlimit-Fix-tests-with-HZ-1000.patch @@ -0,0 +1,47 @@ +From 41660ba1faea8b7ebd71e94c70ef175a75ab91cc 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.33.0 + diff --git a/EMPTY b/EMPTY deleted file mode 100644 index 0519ecb..0000000 --- a/EMPTY +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/arptables-helper b/arptables-helper new file mode 100644 index 0000000..4039e7d --- /dev/null +++ b/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/arptables.service b/arptables.service new file mode 100644 index 0000000..df6c7d6 --- /dev/null +++ b/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/ebtables-config b/ebtables-config new file mode 100644 index 0000000..69d9289 --- /dev/null +++ b/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/ebtables.service b/ebtables.service new file mode 100644 index 0000000..e0b0162 --- /dev/null +++ b/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/ebtables.systemd b/ebtables.systemd new file mode 100644 index 0000000..c31ddc0 --- /dev/null +++ b/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/iptables-config b/iptables-config new file mode 100644 index 0000000..3d7e176 --- /dev/null +++ b/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/iptables.init b/iptables.init new file mode 100755 index 0000000..52fa91a --- /dev/null +++ b/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/iptables.service b/iptables.service new file mode 100644 index 0000000..39f95f9 --- /dev/null +++ b/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/iptables.spec b/iptables.spec new file mode 100644 index 0000000..85be0bd --- /dev/null +++ b/iptables.spec @@ -0,0 +1,1773 @@ +# 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 + +# boostrap mode to assist in libip{4,6}tc SONAME bump +%global bootstrap 1 + +%if 0%{?bootstrap} +%global version_old 1.8.2 +%global iptc_so_ver_old 0 +%endif +%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.4 +Release: 22%{?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 +%if 0%{?bootstrap} +Source11: %{url}/files/%{name}-%{version_old}.tar.bz2 +Source12: 0003-extensions-format-security-fixes-in-libip-6-t_icmp.patch +%endif + +Patch01: 0001-iptables-apply-Use-mktemp-instead-of-tempfile.patch +Patch02: 0002-xtables-restore-Fix-parser-feed-from-line-buffer.patch +Patch03: 0003-xtables-restore-Avoid-access-of-uninitialized-data.patch +Patch04: 0004-extensions-time-Avoid-undefined-shift.patch +Patch05: 0005-extensions-cluster-Avoid-undefined-shift.patch +Patch06: 0006-libxtables-Avoid-buffer-overrun-in-xtables_compatibl.patch +Patch07: 0007-xtables-translate-Guard-strcpy-call-in-xlate_ifname.patch +Patch08: 0008-extensions-among-Check-call-to-fstat.patch +Patch09: 0009-uapi-netfilter-Avoid-undefined-left-shift-in-xt_sctp.patch +Patch10: 0010-xtables-translate-Fix-for-interface-name-corner-case.patch +Patch11: 0011-xtables-translate-Fix-for-iface.patch +Patch12: 0012-tests-shell-Fix-skip-checks-with-host-mode.patch +Patch13: 0013-xtables-restore-fix-for-noflush-and-empty-lines.patch +Patch14: 0014-iptables-test.py-Fix-host-mode.patch +Patch15: 0015-xtables-Review-nft_init.patch +Patch16: 0016-nft-cache-Fix-nft_release_cache-under-stress.patch +Patch17: 0017-nft-cache-Fix-iptables-save-segfault-under-stress.patch +Patch18: 0018-ebtables-among-Support-mixed-MAC-and-MAC-IP-entries.patch +Patch19: 0019-xtables-Align-effect-of-4-6-options-with-legacy.patch +Patch20: 0020-xtables-Drop-4-and-6-support-from-xtables-save-resto.patch +Patch21: 0021-nfnl_osf-Fix-broken-conversion-to-nfnl_query.patch +Patch22: 0022-nfnl_osf-Improve-error-handling.patch +Patch23: 0023-nft-cache-Reset-genid-when-rebuilding-cache.patch +Patch24: 0024-nft-Fix-for-F-in-iptables-dumps.patch +Patch25: 0025-tests-shell-Test-F-in-dump-files.patch +Patch26: 0026-nft-Make-batch_add_chain-return-the-added-batch-obje.patch +Patch27: 0027-nft-Fix-error-reporting-for-refreshed-transactions.patch +Patch28: 0028-nft-Fix-for-concurrent-noflush-restore-calls.patch +Patch29: 0029-tests-shell-Improve-concurrent-noflush-restore-test-.patch +Patch30: 0030-nft-cache-Make-nft_rebuild_cache-respect-fake-cache.patch +Patch31: 0031-nft-Fix-for-broken-address-mask-match-detection.patch +Patch32: 0032-nft-Optimize-class-based-IP-prefix-matches.patch +Patch33: 0033-ebtables-Optimize-masked-MAC-address-matches.patch +Patch34: 0034-tests-shell-Add-test-for-bitwise-avoidance-fixes.patch +Patch35: 0035-libxtables-Make-sure-extensions-register-in-revision.patch +Patch36: 0036-libxtables-Simplify-pending-extension-registration.patch +Patch37: 0037-libxtables-Register-multiple-extensions-in-ascending.patch +Patch38: 0038-tests-shell-Test-for-fixed-extension-registration.patch +Patch39: 0039-extensions-libipt_icmp-Fix-translation-of-type-any.patch +Patch40: 0040-extensions-libxt_CT-add-translation-for-NOTRACK.patch +Patch41: 0041-nft-Fix-command-name-in-ip6tables-error-message.patch +Patch42: 0042-tests-shell-Merge-and-extend-return-codes-test.patch +Patch43: 0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch +Patch44: 0044-xtables-monitor-Fix-ip6tables-rule-printing.patch +Patch45: 0045-xtables-monitor-fix-rule-printing.patch +Patch46: 0046-xtables-monitor-fix-packet-family-protocol.patch +Patch47: 0047-xtables-monitor-print-packet-first.patch +Patch48: 0048-xtables-monitor.patch +Patch49: 0049-nft-Fix-bitwise-expression-avoidance-detection.patch +Patch50: 0050-xtables-translate-Fix-translation-of-odd-netmasks.patch +Patch51: 0051-Eliminate-inet_aton-and-inet_ntoa.patch +Patch52: 0052-xtables-arp-Don-t-use-ARPT_INV_.patch +Patch53: 0053-nft-arp-Make-use-of-ipv4_addr_to_string.patch +Patch54: 0054-extensions-SECMARK-Implement-revision-1.patch +Patch55: 0055-extensions-sctp-Fix-nftables-translation.patch +Patch56: 0056-extensions-sctp-Translate-chunk-types-option.patch +Patch57: 0057-extensions-SECMARK-Use-a-better-context-in-test-case.patch +Patch58: 0058-nft-cache-Retry-if-kernel-returns-EINTR.patch +Patch59: 0059-doc-ebtables-nft.8-Adjust-for-missing-atomic-options.patch +Patch60: 0060-ebtables-Dump-atomic-waste.patch +Patch61: 0061-extensions-hashlimit-Fix-tests-with-HZ-100.patch +Patch62: 0062-extensions-hashlimit-Fix-tests-with-HZ-1000.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.5-1 +# 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 + +%if 0%{?bootstrap} +%{__mkdir} -p bootstrap_ver +pushd bootstrap_ver +%{__tar} --strip-components=1 -xf %{SOURCE11} +%{__patch} -p1 <%{SOURCE12} +popd +%endif + +%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 + +%if 0%{?bootstrap} +pushd bootstrap_ver +./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 +popd +%endif + +%install +%if 0%{?bootstrap} +%make_install -C bootstrap_ver +find %{buildroot} -xtype f -not \ + -name 'libip*tc.so.%{iptc_so_ver_old}*' -delete -print +find %{buildroot} -type l -not \ + -name 'libip*tc.so.%{iptc_so_ver_old}*' -delete -print +%endif + +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-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-monitor* +%doc %{_mandir}/man8/xtables-nft* +%doc %{_mandir}/man8/*tables-translate* +%doc %{_mandir}/man8/*tables-restore-translate* +%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}* +%if 0%{?bootstrap} +%{_libdir}/libip*tc.so.%{iptc_so_ver_old}* +%endif +%{_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 +* 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 diff --git a/sources b/sources new file mode 100644 index 0000000..acd77de --- /dev/null +++ b/sources @@ -0,0 +1,2 @@ +SHA512 (iptables-1.8.2.tar.bz2) = 8cf0f515764e1dc6e03284581d682d1949b33e8f25fea29c27ae856f1089fe8ca7b1814524b85f4378fd1fc7c7c7d002f06557b257ae2bbc945f8555bad0dc76 +SHA512 (iptables-1.8.4.tar.bz2) = a7faaab58608ffaa51e26e8056551c0e91a49187439d30fcf5cce2800274cc3c0515db6cfba0f4c85613fb80779cf96089b8915db0e89161e9980a6384faebdb diff --git a/sysconfig_ip6tables b/sysconfig_ip6tables new file mode 100644 index 0000000..34b8b87 --- /dev/null +++ b/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/sysconfig_iptables b/sysconfig_iptables new file mode 100644 index 0000000..5183250 --- /dev/null +++ b/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