From 410d16e5ca95565460b55ff6349d376782d731ae Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 09 2020 17:26:34 +0000 Subject: Prepare for a new update Reverting patches so we can apply the latest update and changes can be seen in the spec file and sources. --- diff --git a/extensions/generic.txlate b/extensions/generic.txlate index 0e256c3..b38fbd1 100644 --- a/extensions/generic.txlate +++ b/extensions/generic.txlate @@ -18,19 +18,3 @@ 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 - -# 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 - -# 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/extensions/libebt_among.c b/extensions/libebt_among.c index 2b9a1b6..2e87db3 100644 --- a/extensions/libebt_among.c +++ b/extensions/libebt_among.c @@ -6,7 +6,6 @@ * August, 2003 */ -#include #include #include #include @@ -63,6 +62,10 @@ 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'; @@ -134,10 +137,7 @@ 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); - if (fstat(fd, &stats) < 0) - xtables_error(PARAMETER_PROBLEM, - "fstat(%s) failed: '%s'", - optarg, strerror(errno)); + fstat(fd, &stats); flen = stats.st_size; /* use mmap because the file will probably be big */ optarg = mmap(0, flen, PROT_READ | PROT_WRITE, @@ -201,7 +201,7 @@ static void __bramong_print(struct nft_among_pair *pairs, isep = ","; printf("%s", ether_ntoa(&pairs[i].ether)); - if (pairs[i].in.s_addr != INADDR_ANY) + if (have_ip) printf("=%s", inet_ntoa(pairs[i].in)); } printf(" "); diff --git a/extensions/libebt_among.t b/extensions/libebt_among.t index a02206f..56b2991 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 c0:ff:ee:0:ba:be=192.168.1.1,de:ad:0:be:ee:ff;=;OK +--among-src de:ad:0:be:ee:ff,c0:ff:ee:0:ba:be=192.168.1.1;=;FAIL diff --git a/extensions/libxt_cluster.c b/extensions/libxt_cluster.c index d164bf6..c9c35ee 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 & (1u << node)) { + if (info->node_mask & (1 << node)) { if (needs_set == 0) { xt_xlate_add(xl, "{ "); needs_set = 1; diff --git a/extensions/libxt_time.c b/extensions/libxt_time.c index d001f5b..5a8cc5d 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 & (1u << i)) { + if (mask & (1 << i)) { if (nbdays++ > 0) printf(","); printf("%u", i); diff --git a/include/linux/netfilter/xt_sctp.h b/include/linux/netfilter/xt_sctp.h index 5b28525..a501e61 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)] |= \ - 1u << (type % bytes(__u32)); \ + 1 << (type % bytes(__u32)); \ } while (0) #define SCTP_CHUNKMAP_CLEAR(chunkmap, type) \ do { \ (chunkmap)[type / bytes(__u32)] &= \ - ~(1u << (type % bytes(__u32))); \ + ~(1 << (type % bytes(__u32))); \ } while (0) #define SCTP_CHUNKMAP_IS_SET(chunkmap, type) \ ({ \ ((chunkmap)[type / bytes (__u32)] & \ - (1u << (type % bytes (__u32)))) ? 1: 0; \ + (1 << (type % bytes (__u32)))) ? 1: 0; \ }) #define SCTP_CHUNKMAP_RESET(chunkmap) \ diff --git a/iptables-test.py b/iptables-test.py index e986d7a..fdb4e6a 100755 --- a/iptables-test.py +++ b/iptables-test.py @@ -119,7 +119,8 @@ def run_test(iptables, rule, rule_save, res, filename, lineno, netns): elif splitted[0] == EBTABLES: command = EBTABLES_SAVE - command = EXECUTEABLE + " " + command + path = os.path.abspath(os.path.curdir) + "/iptables/" + EXECUTEABLE + command = path + " " + command if netns: command = "ip netns exec ____iptables-container-test " + command @@ -164,7 +165,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 = EXECUTEABLE + " " + cmd + cmd = os.path.abspath(os.path.curdir) + "/iptables/" + EXECUTEABLE + " " + cmd print("command: {}".format(cmd), file=log_file) ret = subprocess.call(cmd, shell=True, universal_newlines=True, diff --git a/iptables/ebtables-nft.8 b/iptables/ebtables-nft.8 index 1fa5ad9..a91f0c1 100644 --- a/iptables/ebtables-nft.8 +++ b/iptables/ebtables-nft.8 @@ -551,6 +551,10 @@ 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/iptables-apply b/iptables/iptables-apply index a685b6b..819ca4a 100755 --- a/iptables/iptables-apply +++ b/iptables/iptables-apply @@ -111,7 +111,7 @@ if [[ ! -r "$FILE" ]]; then exit 2 fi -COMMANDS=(mktemp "$SAVE" "$RESTORE") +COMMANDS=(tempfile "$SAVE" "$RESTORE") for cmd in "${COMMANDS[@]}"; do if ! command -v $cmd >/dev/null; then @@ -122,7 +122,7 @@ done umask 0700 -TMPFILE=$(mktemp) +TMPFILE=$(tempfile -p iptap) trap "rm -f $TMPFILE" EXIT HUP INT QUIT ILL TRAP ABRT BUS \ FPE USR1 SEGV USR2 PIPE ALRM TERM diff --git a/iptables/nft-cache.c b/iptables/nft-cache.c index bc6e7f7..7345a27 100644 --- a/iptables/nft-cache.c +++ b/iptables/nft-cache.c @@ -452,11 +452,15 @@ __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->nft_genid) - mnl_genid_get(h, &h->nft_genid); + if (h->cache_level && genid_start != h->nft_genid) + flush_chain_cache(h, NULL); switch (h->cache_level) { case NFT_CL_NONE: @@ -483,10 +487,18 @@ __nft_build_cache(struct nft_handle *h, enum nft_cache_level level, 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) @@ -629,21 +641,14 @@ 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); } void nft_release_cache(struct nft_handle *h) { - 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]; + if (h->cache_index) + flush_cache(h, &h->__cache[0], NULL); } struct nftnl_table_list *nftnl_table_list_get(struct nft_handle *h) diff --git a/iptables/nft.c b/iptables/nft.c index e95e99f..3f2a62a 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -411,38 +411,6 @@ 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", @@ -821,10 +789,8 @@ int nft_restart(struct nft_handle *h) return 0; } -int nft_init(struct nft_handle *h, int family, const struct builtin_table *t) +int nft_init(struct nft_handle *h, const struct builtin_table *t) { - memset(h, 0, sizeof(*h)); - h->nl = mnl_socket_open(NETLINK_NETFILTER); if (h->nl == NULL) return -1; @@ -834,14 +800,9 @@ int nft_init(struct nft_handle *h, int family, 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); @@ -1061,28 +1022,19 @@ 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, flags, type, len, cnt); + s = add_anon_set(h, table, 0, 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(); @@ -1090,15 +1042,6 @@ 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); } @@ -1703,7 +1646,6 @@ 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; @@ -1719,7 +1661,6 @@ 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); diff --git a/iptables/nft.h b/iptables/nft.h index 5cf260a..51b5660 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, int family, const struct builtin_table *t); +int nft_init(struct nft_handle *h, const struct builtin_table *t); void nft_fini(struct nft_handle *h); int nft_restart(struct nft_handle *h); 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 e64e914..bf04dc0 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 afd0fcb..38d387f 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 952cfa7..10c5ec3 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 0c1eb4c..c7f24a3 100755 --- a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 +++ b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 @@ -1,89 +1,86 @@ #!/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 -for t in broute foobar ;do - $XT_MULTI ebtables -t $t -L && - $XT_MULTI ebtables -t $t -X && - $XT_MULTI ebtables -t $t -F + $XT_MULTI ebtables -t filter -N FOO || exit 1 + $XT_MULTI ebtables -t filter -N FOO if [ $? -eq 0 ]; then - echo "Expect nonzero return for unsupported table" + echo "Duplicate chain FOO" + $XT_MULTI ebtables -t filter -L exit 1 fi -done - - -$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 unreferenced 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 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 -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 -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 referenced 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 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 -N BAR || exit 1 -$XT_MULTI ebtables -t filter -N BAZ || exit 1 + $XT_MULTI ebtables -t filter -N BAR || exit 1 + $XT_MULTI ebtables -t filter -N BAZ || exit 1 -$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 | 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 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 + $XT_MULTI ebtables -t $t -F || exit 0 + ;; +*) + echo "skip $XT_MULTI" + ;; +esac 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 b84f63a..e18d465 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 63891c1..62d2241 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 d52db90..46966f4 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 0b3acfd..2163d36 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 0174b03..8bf0c2c 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 9fc5061..96a5e66 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/ipt-restore/0010-noflush-new-chain_0 b/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 deleted file mode 100755 index 739e684..0000000 --- a/iptables/tests/shell/testcases/ipt-restore/0010-noflush-new-chain_0 +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -e - -# assert input feed from buffer doesn't trip over -# added nul-chars from parsing chain line. - -$XT_MULTI iptables-restore --noflush </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 ;; *) 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 fe33874..406b608 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 ccb009e..67af9fd 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" diff --git a/iptables/xtables-arp.c b/iptables/xtables-arp.c index c8196f0..9cfad76 100644 --- a/iptables/xtables-arp.c +++ b/iptables/xtables-arp.c @@ -500,10 +500,17 @@ int nft_init_arp(struct nft_handle *h, const char *pname) init_extensionsa(); #endif - if (nft_init(h, NFPROTO_ARP, xtables_arp) < 0) + memset(h, 0, sizeof(*h)); + h->family = NFPROTO_ARP; + + if (nft_init(h, 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 c006bc9..15b971d 100644 --- a/iptables/xtables-eb.c +++ b/iptables/xtables-eb.c @@ -739,9 +739,16 @@ int nft_init_eb(struct nft_handle *h, const char *pname) init_extensionsb(); #endif - if (nft_init(h, NFPROTO_BRIDGE, xtables_bridge) < 0) + memset(h, 0, sizeof(*h)); + + h->family = NFPROTO_BRIDGE; + + if (nft_init(h, 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 c2b31db..a5245d1 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, AF_INET, xtables_ipv4)) { + if (nft_init(&h, 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 c472ac9..2f0fe7d 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); @@ -293,13 +293,11 @@ void xtables_restore_parse(struct nft_handle *h, while (fgets(buffer, sizeof(buffer), p->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. - * Unless this is an empty line which would fold into a - * spurious EoB indicator (double nul-char). */ - if (buffer[blen - 1] == '\n' && blen > 1) + * preload_buffer */ + if (buffer[blen - 1] == '\n') buffer[blen - 1] = '\0'; else blen++; @@ -329,12 +327,10 @@ void xtables_restore_parse(struct nft_handle *h, line = 0; ptr = preload_buffer; while (*ptr) { - size_t len = strlen(ptr); - h->error.lineno = ++line; DEBUGP("%s: buffered line %d: '%s'\n", __func__, line, ptr); xtables_restore_parse_line(h, p, &state, ptr); - ptr += len + 1; + ptr += strlen(ptr) + 1; } if (*buffer) { h->error.lineno = ++line; @@ -360,13 +356,15 @@ 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; @@ -379,7 +377,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) exit(1); } - while ((c = getopt_long(argc, argv, "bcvVthnM:T:wW", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "bcvVthnM:T:46wW", options, NULL)) != -1) { switch (c) { case 'b': fprintf(stderr, "-b/--binary option is not implemented\n"); @@ -400,7 +398,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) print_usage(prog_name, PACKAGE_VERSION); exit(0); case 'n': - noflush = true; + h.noflush = 1; break; case 'M': xtables_modprobe_program = optarg; @@ -408,6 +406,13 @@ 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)) @@ -455,15 +460,13 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) return 1; } - if (nft_init(&h, family, tables) < 0) { + if (nft_init(&h, 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 28f7490..3a52f8c 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:V"; +static const char *ipt_save_optstring = "bcdt:M:f:46V"; static const struct option ipt_save_options[] = { {.name = "counters", .has_arg = false, .val = 'c'}, {.name = "version", .has_arg = false, .val = 'V'}, @@ -40,6 +40,8 @@ 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}, }; @@ -137,8 +139,10 @@ 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; @@ -185,6 +189,13 @@ 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); @@ -231,13 +242,16 @@ xtables_save_main(int family, int argc, char *argv[], return 1; } - if (nft_init(&h, family, tables) < 0) { + if (nft_init(&h, 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 022d5dd..1a28c54 100644 --- a/iptables/xtables-standalone.c +++ b/iptables/xtables-standalone.c @@ -44,7 +44,9 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) { int ret; char *table = "filter"; - struct nft_handle h; + struct nft_handle h = { + .family = family, + }; xtables_globals.program_name = progname; ret = xtables_init_all(&xtables_globals, family); @@ -59,7 +61,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[]) init_extensions4(); #endif - if (nft_init(&h, family, xtables_ipv4) < 0) { + if (nft_init(&h, 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 76ad7eb..a42c60a 100644 --- a/iptables/xtables-translate.c +++ b/iptables/xtables-translate.c @@ -32,38 +32,16 @@ void xlate_ifname(struct xt_xlate *xl, const char *nftmeta, const char *ifname, bool invert) { - int ifaclen = strlen(ifname), i, j; - char iface[IFNAMSIZ * 2]; + char iface[IFNAMSIZ]; + int ifaclen; - if (ifaclen < 1 || ifaclen >= IFNAMSIZ) + if (ifname[0] == '\0') return; - for (i = 0, j = 0; i < ifaclen + 1; i++, j++) { - switch (ifname[i]) { - 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; - } - - if (iface[j - 2] == '+') - iface[j - 2] = '*'; + strcpy(iface, ifname); + ifaclen = strlen(iface); + if (iface[ifaclen - 1] == '+') + iface[ifaclen - 1] = '*'; xt_xlate_add(xl, "%s %s\"%s\" ", nftmeta, invert ? "!= " : "", iface); } @@ -480,7 +458,7 @@ static int xtables_xlate_main_common(struct nft_handle *h, return 1; } - if (nft_init(h, family, tables) < 0) { + if (nft_init(h, 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 8c2d21d..8f9dc62 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -571,6 +571,10 @@ 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", @@ -913,22 +917,27 @@ 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; - exit_tryhelp(2); + if (args->family != AF_INET) + exit_tryhelp(2); - case '6': - if (args->family == AF_INET6) - break; + h->ops = nft_family_ops_lookup(args->family); + break; + case '6': if (p->restore && args->family == AF_INET) return; - exit_tryhelp(2); + 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; case 1: /* non option */ if (optarg[0] == '!' && optarg[1] == '\0') { diff --git a/libxtables/xtables.c b/libxtables/xtables.c index 777c2b0..895f698 100644 --- a/libxtables/xtables.c +++ b/libxtables/xtables.c @@ -856,8 +856,7 @@ int xtables_compatible_revision(const char *name, uint8_t revision, int opt) xtables_load_ko(xtables_modprobe_program, true); - strncpy(rev.name, name, XT_EXTENSION_MAXNAMELEN - 1); - rev.name[XT_EXTENSION_MAXNAMELEN - 1] = '\0'; + strcpy(rev.name, name); rev.revision = revision; max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); diff --git a/utils/nfnl_osf.c b/utils/nfnl_osf.c index 8008e83..15d5319 100644 --- a/utils/nfnl_osf.c +++ b/utils/nfnl_osf.c @@ -378,11 +378,9 @@ 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_ACK | NLM_F_REQUEST); + nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_REMOVE, NLM_F_REQUEST); else - nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_ADD, - NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE); + nfnl_fill_hdr(nfnlssh, nmh, 0, AF_UNSPEC, 0, OSF_MSG_ADD, NLM_F_REQUEST | NLM_F_CREATE); nfnl_addattr_l(nmh, sizeof(buf), OSF_ATTR_FINGER, &f, sizeof(struct xt_osf_user_finger)); @@ -392,7 +390,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, lineno = 0; + int err = 0; char buf[1024]; inf = fopen(path, "r"); @@ -402,9 +400,7 @@ static int osf_load_entries(char *path, int del) } while(fgets(buf, sizeof(buf), inf)) { - int len, rc; - - lineno++; + int len; if (buf[0] == '#' || buf[0] == '\n' || buf[0] == '\r') continue; @@ -416,11 +412,9 @@ static int osf_load_entries(char *path, int del) buf[len] = '\0'; - rc = osf_load_line(buf, len, del); - if (rc && (!del || errno != ENOENT)) { - ulog_err("Failed to load line %d", lineno); - err = rc; - } + err = osf_load_line(buf, len, del); + if (err) + break; memset(buf, 0, sizeof(buf)); } @@ -452,7 +446,6 @@ int main(int argc, char *argv[]) if (!fingerprints) { err = -ENOENT; - ulog("Missing fingerprints file argument.\n"); goto err_out_exit; }