diff --git a/.gitignore b/.gitignore index 546e9c6..cdf126b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/nftables-0.9.0.tar.bz2 +SOURCES/nftables-0.9.3.tar.bz2 diff --git a/.nftables.metadata b/.nftables.metadata index 09a6972..9c4c1a3 100644 --- a/.nftables.metadata +++ b/.nftables.metadata @@ -1 +1 @@ -a3463fc6589c08631ec3f306f6db7f0905249542 SOURCES/nftables-0.9.0.tar.bz2 +20156858169fde135a0b4c22c4cd9437afcbb733 SOURCES/nftables-0.9.3.tar.bz2 diff --git a/SOURCES/0001-evaluate-reject-Allow-icmpx-in-inet-bridge-families.patch b/SOURCES/0001-evaluate-reject-Allow-icmpx-in-inet-bridge-families.patch deleted file mode 100644 index 4aafcba..0000000 --- a/SOURCES/0001-evaluate-reject-Allow-icmpx-in-inet-bridge-families.patch +++ /dev/null @@ -1,227 +0,0 @@ -From f47941faed177fd3943c7eaf9408e9e6481595f6 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 13 Aug 2018 18:58:57 +0200 -Subject: [PATCH] evaluate: reject: Allow icmpx in inet/bridge families - -Commit 3e6ab2b335142 added restraints on reject types for bridge and -inet families but aparently those were too strict: If a rule in e.g. -inet family contained a match which introduced a protocol dependency, -icmpx type rejects were disallowed for no obvious reason. - -Allow icmpx type rejects in inet family regardless of protocol -dependency since we either have IPv4 or IPv6 traffic in there and for -both icmpx is fine. - -Merge restraints in bridge family with those for TCP reset since it -already does what is needed, namely checking that ether proto is either -IPv4 or IPv6. - -Fixes: 3e6ab2b335142 ("evaluate: reject: check in bridge and inet the network context in reject") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 8d2c3c72935443228b5e0492c8d3e2e2048c0c5a) -Signed-off-by: Phil Sutter ---- - src/evaluate.c | 7 +---- - tests/py/bridge/reject.t | 5 ++++ - tests/py/bridge/reject.t.json | 44 +++++++++++++++++++++++++++++ - tests/py/bridge/reject.t.payload | 12 ++++++++ - tests/py/inet/reject.t | 3 ++ - tests/py/inet/reject.t.json | 42 +++++++++++++++++++++++++++ - tests/py/inet/reject.t.payload.inet | 12 ++++++++ - 7 files changed, 119 insertions(+), 6 deletions(-) - -diff --git a/src/evaluate.c b/src/evaluate.c -index c4ee3cc94a3db..d18af34341b0d 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -2130,9 +2130,7 @@ static int stmt_evaluate_reject_inet_family(struct eval_ctx *ctx, - case NFT_REJECT_TCP_RST: - break; - case NFT_REJECT_ICMPX_UNREACH: -- return stmt_binary_error(ctx, stmt->reject.expr, -- &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], -- "conflicting network protocol specified"); -+ break; - case NFT_REJECT_ICMP_UNREACH: - base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; - protocol = proto_find_num(base, desc); -@@ -2183,9 +2181,6 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx, - - switch (stmt->reject.type) { - case NFT_REJECT_ICMPX_UNREACH: -- return stmt_binary_error(ctx, stmt->reject.expr, -- &ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR], -- "conflicting network protocol specified"); - case NFT_REJECT_TCP_RST: - base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; - protocol = proto_find_num(base, desc); -diff --git a/tests/py/bridge/reject.t b/tests/py/bridge/reject.t -index 67deac8d3b5e4..13d65b115c3cb 100644 ---- a/tests/py/bridge/reject.t -+++ b/tests/py/bridge/reject.t -@@ -37,3 +37,8 @@ ether type arp reject;fail - ether type vlan reject with tcp reset;fail - ether type arp reject with tcp reset;fail - ip protocol udp reject with tcp reset;fail -+ -+ether type ip reject with icmpx type admin-prohibited;ok -+ether type ip6 reject with icmpx type admin-prohibited;ok -+ether type vlan reject with icmpx type admin-prohibited;fail -+ether type arp reject with icmpx type admin-prohibited;fail -diff --git a/tests/py/bridge/reject.t.json b/tests/py/bridge/reject.t.json -index aa716f8070666..c0bed56e6ce41 100644 ---- a/tests/py/bridge/reject.t.json -+++ b/tests/py/bridge/reject.t.json -@@ -219,3 +219,47 @@ - } - ] - -+# ether type ip reject with icmpx type admin-prohibited -+[ -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "protocol": "ether" -+ } -+ }, -+ "op": "==", -+ "right": "ip" -+ } -+ }, -+ { -+ "reject": { -+ "expr": "admin-prohibited", -+ "type": "icmpx" -+ } -+ } -+] -+ -+# ether type ip6 reject with icmpx type admin-prohibited -+[ -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "protocol": "ether" -+ } -+ }, -+ "op": "==", -+ "right": "ip6" -+ } -+ }, -+ { -+ "reject": { -+ "expr": "admin-prohibited", -+ "type": "icmpx" -+ } -+ } -+] -+ -diff --git a/tests/py/bridge/reject.t.payload b/tests/py/bridge/reject.t.payload -index b984f6f8de4d6..888179df9c977 100644 ---- a/tests/py/bridge/reject.t.payload -+++ b/tests/py/bridge/reject.t.payload -@@ -106,3 +106,15 @@ bridge test-bridge input - bridge test-bridge input - [ reject type 2 code 1 ] - -+# ether type ip reject with icmpx type admin-prohibited -+bridge test-bridge input -+ [ payload load 2b @ link header + 12 => reg 1 ] -+ [ cmp eq reg 1 0x00000008 ] -+ [ reject type 2 code 3 ] -+ -+# ether type ip6 reject with icmpx type admin-prohibited -+bridge test-bridge input -+ [ payload load 2b @ link header + 12 => reg 1 ] -+ [ cmp eq reg 1 0x0000dd86 ] -+ [ reject type 2 code 3 ] -+ -diff --git a/tests/py/inet/reject.t b/tests/py/inet/reject.t -index 7679407e6f8d4..a88c5a4afae51 100644 ---- a/tests/py/inet/reject.t -+++ b/tests/py/inet/reject.t -@@ -34,3 +34,6 @@ meta nfproto ipv6 reject with icmp type host-unreachable;fail - meta nfproto ipv4 ip protocol icmp reject with icmpv6 type no-route;fail - meta nfproto ipv6 ip protocol icmp reject with icmp type host-unreachable;fail - meta l4proto udp reject with tcp reset;fail -+ -+meta nfproto ipv4 reject with icmpx type admin-prohibited;ok -+meta nfproto ipv6 reject with icmpx type admin-prohibited;ok -diff --git a/tests/py/inet/reject.t.json b/tests/py/inet/reject.t.json -index 0939f4450509b..46d4857a57c99 100644 ---- a/tests/py/inet/reject.t.json -+++ b/tests/py/inet/reject.t.json -@@ -238,3 +238,45 @@ - } - ] - -+# meta nfproto ipv4 reject with icmpx type admin-prohibited -+[ -+ { -+ "match": { -+ "left": { -+ "meta": { -+ "key": "nfproto" -+ } -+ }, -+ "op": "==", -+ "right": "ipv4" -+ } -+ }, -+ { -+ "reject": { -+ "expr": "admin-prohibited", -+ "type": "icmpx" -+ } -+ } -+] -+ -+# meta nfproto ipv6 reject with icmpx type admin-prohibited -+[ -+ { -+ "match": { -+ "left": { -+ "meta": { -+ "key": "nfproto" -+ } -+ }, -+ "op": "==", -+ "right": "ipv6" -+ } -+ }, -+ { -+ "reject": { -+ "expr": "admin-prohibited", -+ "type": "icmpx" -+ } -+ } -+] -+ -diff --git a/tests/py/inet/reject.t.payload.inet b/tests/py/inet/reject.t.payload.inet -index 7a6468e81f9e7..ee1aae02f1e1d 100644 ---- a/tests/py/inet/reject.t.payload.inet -+++ b/tests/py/inet/reject.t.payload.inet -@@ -220,3 +220,15 @@ inet test-inet input - [ cmp eq reg 1 0x0000000a ] - [ reject type 0 code 0 ] - -+# meta nfproto ipv4 reject with icmpx type admin-prohibited -+inet test-inet input -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x00000002 ] -+ [ reject type 2 code 3 ] -+ -+# meta nfproto ipv6 reject with icmpx type admin-prohibited -+inet test-inet input -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x0000000a ] -+ [ reject type 2 code 3 ] -+ --- -2.21.0 - diff --git a/SOURCES/0001-main-enforce-options-before-commands.patch b/SOURCES/0001-main-enforce-options-before-commands.patch new file mode 100644 index 0000000..45b750c --- /dev/null +++ b/SOURCES/0001-main-enforce-options-before-commands.patch @@ -0,0 +1,244 @@ +From 5fac849eac7ecfde4ca6f9c9c406ace030f358f2 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 10 Jan 2020 19:54:16 +0100 +Subject: [PATCH] main: enforce options before commands + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1778883 +Upstream Status: nftables commit fb9cea50e8b37 + +commit fb9cea50e8b370b6931e7b53b1a881d3b95b1c91 +Author: Pablo Neira Ayuso +Date: Fri Dec 13 11:32:46 2019 +0100 + + main: enforce options before commands + + This patch turns on POSIXLY_CORRECT on the getopt parser to enforce + options before commands. Users get a hint in such a case: + + # nft list ruleset -a + Error: syntax error, options must be specified before commands + nft list ruleset -a + ^ ~~ + + This patch recovers 9fc71bc6b602 ("main: Fix for misleading error with + negative chain priority"). + + Tests have been updated. + + Signed-off-by: Pablo Neira Ayuso +--- + src/main.c | 46 +++++++++++++++++++++- + tests/shell/testcases/cache/0001_cache_handling_0 | 2 +- + tests/shell/testcases/chains/0016delete_handle_0 | 4 +- + .../shell/testcases/chains/0039negative_priority_0 | 8 ++++ + .../shell/testcases/flowtable/0010delete_handle_0 | 2 +- + .../shell/testcases/maps/0008interval_map_delete_0 | 2 +- + tests/shell/testcases/optionals/comments_0 | 2 +- + tests/shell/testcases/optionals/comments_handles_0 | 2 +- + .../testcases/optionals/delete_object_handles_0 | 4 +- + tests/shell/testcases/optionals/handles_0 | 2 +- + tests/shell/testcases/sets/0028delete_handle_0 | 2 +- + 11 files changed, 64 insertions(+), 12 deletions(-) + create mode 100755 tests/shell/testcases/chains/0039negative_priority_0 + +diff --git a/src/main.c b/src/main.c +index fde8b15..74199f9 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -46,7 +46,7 @@ enum opt_vals { + OPT_TERSE = 't', + OPT_INVALID = '?', + }; +-#define OPTSTRING "hvcf:iI:jvnsNaeSupypTt" ++#define OPTSTRING "+hvcf:iI:jvnsNaeSupypTt" + + static const struct option options[] = { + { +@@ -202,6 +202,47 @@ static const struct { + }, + }; + ++static void nft_options_error(int argc, char * const argv[], int pos) ++{ ++ int i; ++ ++ fprintf(stderr, "Error: syntax error, options must be specified before commands\n"); ++ for (i = 0; i < argc; i++) ++ fprintf(stderr, "%s ", argv[i]); ++ printf("\n%4c%*s\n", '^', pos - 2, "~~"); ++} ++ ++static bool nft_options_check(int argc, char * const argv[]) ++{ ++ bool skip = false, nonoption = false; ++ int pos = 0, i; ++ ++ for (i = 1; i < argc; i++) { ++ pos += strlen(argv[i - 1]) + 1; ++ if (argv[i][0] == '{') { ++ break; ++ } else if (skip) { ++ skip = false; ++ continue; ++ } else if (argv[i][0] == '-') { ++ if (nonoption) { ++ nft_options_error(argc, argv, pos); ++ return false; ++ } else if (argv[i][1] == 'I' || ++ argv[i][1] == 'f' || ++ !strcmp(argv[i], "--includepath") || ++ !strcmp(argv[i], "--file")) { ++ skip = true; ++ continue; ++ } ++ } else if (argv[i][0] != '-') { ++ nonoption = true; ++ } ++ } ++ ++ return true; ++} ++ + int main(int argc, char * const *argv) + { + char *buf = NULL, *filename = NULL; +@@ -211,6 +252,9 @@ int main(int argc, char * const *argv) + unsigned int len; + int i, val, rc; + ++ if (!nft_options_check(argc, argv)) ++ exit(EXIT_FAILURE); ++ + nft = nft_ctx_new(NFT_CTX_DEFAULT); + + while (1) { +diff --git a/tests/shell/testcases/cache/0001_cache_handling_0 b/tests/shell/testcases/cache/0001_cache_handling_0 +index 431aada..0a68440 100755 +--- a/tests/shell/testcases/cache/0001_cache_handling_0 ++++ b/tests/shell/testcases/cache/0001_cache_handling_0 +@@ -20,7 +20,7 @@ TMP=$(mktemp) + echo "$RULESET" >> "$TMP" + $NFT "flush ruleset;include \"$TMP\"" + rm -f "$TMP" +-rule_handle=$($NFT list ruleset -a | awk '/saddr/{print $NF}') ++rule_handle=$($NFT -a list ruleset | awk '/saddr/{print $NF}') + $NFT delete rule inet test test handle $rule_handle + $NFT delete set inet test test + $NFT -f - <<< "$RULESET" +diff --git a/tests/shell/testcases/chains/0016delete_handle_0 b/tests/shell/testcases/chains/0016delete_handle_0 +index 4633d77..8fd1ad8 100755 +--- a/tests/shell/testcases/chains/0016delete_handle_0 ++++ b/tests/shell/testcases/chains/0016delete_handle_0 +@@ -10,8 +10,8 @@ $NFT add chain ip6 test-ip6 x + $NFT add chain ip6 test-ip6 y + $NFT add chain ip6 test-ip6 z + +-chain_y_handle=$($NFT list ruleset -a | awk -v n=1 '/chain y/ && !--n {print $NF; exit}'); +-chain_z_handle=$($NFT list ruleset -a | awk -v n=2 '/chain z/ && !--n {print $NF; exit}'); ++chain_y_handle=$($NFT -a list ruleset | awk -v n=1 '/chain y/ && !--n {print $NF; exit}'); ++chain_z_handle=$($NFT -a list ruleset | awk -v n=2 '/chain z/ && !--n {print $NF; exit}'); + + $NFT delete chain test-ip handle $chain_y_handle + $NFT delete chain ip6 test-ip6 handle $chain_z_handle +diff --git a/tests/shell/testcases/chains/0039negative_priority_0 b/tests/shell/testcases/chains/0039negative_priority_0 +new file mode 100755 +index 0000000..ba17b8c +--- /dev/null ++++ b/tests/shell/testcases/chains/0039negative_priority_0 +@@ -0,0 +1,8 @@ ++#!/bin/bash ++ ++# Test parsing of negative priority values ++ ++set -e ++ ++$NFT add table t ++$NFT add chain t c { type filter hook input priority -30\; } +diff --git a/tests/shell/testcases/flowtable/0010delete_handle_0 b/tests/shell/testcases/flowtable/0010delete_handle_0 +index 303967d..985d4a3 100755 +--- a/tests/shell/testcases/flowtable/0010delete_handle_0 ++++ b/tests/shell/testcases/flowtable/0010delete_handle_0 +@@ -7,7 +7,7 @@ set -e + $NFT add table inet t + $NFT add flowtable inet t f { hook ingress priority filter\; devices = { lo }\; } + +-FH=$($NFT list ruleset -a | awk '/flowtable f/ { print $NF }') ++FH=$($NFT -a list ruleset | awk '/flowtable f/ { print $NF }') + + $NFT delete flowtable inet t handle $FH + +diff --git a/tests/shell/testcases/maps/0008interval_map_delete_0 b/tests/shell/testcases/maps/0008interval_map_delete_0 +index a43fd28..7da6eb3 100755 +--- a/tests/shell/testcases/maps/0008interval_map_delete_0 ++++ b/tests/shell/testcases/maps/0008interval_map_delete_0 +@@ -24,7 +24,7 @@ $NFT delete element filter m { 127.0.0.3 } + $NFT add element filter m { 127.0.0.3 : 0x3 } + $NFT add element filter m { 127.0.0.2 : 0x2 } + +-GET=$($NFT list ruleset -s) ++GET=$($NFT -s list ruleset) + if [ "$EXPECTED" != "$GET" ] ; then + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") +diff --git a/tests/shell/testcases/optionals/comments_0 b/tests/shell/testcases/optionals/comments_0 +index 29b8506..ab85936 100755 +--- a/tests/shell/testcases/optionals/comments_0 ++++ b/tests/shell/testcases/optionals/comments_0 +@@ -5,4 +5,4 @@ + $NFT add table test + $NFT add chain test test + $NFT add rule test test tcp dport 22 counter accept comment test_comment +-$NFT list table test -a | grep 'accept comment \"test_comment\"' >/dev/null ++$NFT -a list table test | grep 'accept comment \"test_comment\"' >/dev/null +diff --git a/tests/shell/testcases/optionals/comments_handles_0 b/tests/shell/testcases/optionals/comments_handles_0 +index 30539bf..a01df1d 100755 +--- a/tests/shell/testcases/optionals/comments_handles_0 ++++ b/tests/shell/testcases/optionals/comments_handles_0 +@@ -6,5 +6,5 @@ $NFT add table test + $NFT add chain test test + $NFT add rule test test tcp dport 22 counter accept comment test_comment + set -e +-$NFT list table test -a | grep 'accept comment \"test_comment\" # handle '[[:digit:]]$ >/dev/null ++$NFT -a list table test | grep 'accept comment \"test_comment\" # handle '[[:digit:]]$ >/dev/null + $NFT list table test | grep 'accept comment \"test_comment\"' | grep -v '# handle '[[:digit:]]$ >/dev/null +diff --git a/tests/shell/testcases/optionals/delete_object_handles_0 b/tests/shell/testcases/optionals/delete_object_handles_0 +index d5d9654..a2ae422 100755 +--- a/tests/shell/testcases/optionals/delete_object_handles_0 ++++ b/tests/shell/testcases/optionals/delete_object_handles_0 +@@ -10,8 +10,8 @@ $NFT add quota ip6 test-ip6 http-quota over 25 mbytes + $NFT add counter ip6 test-ip6 http-traffic + $NFT add quota ip6 test-ip6 ssh-quota 10 mbytes + +-counter_handle=$($NFT list ruleset -a | awk '/https-traffic/{print $NF}') +-quota_handle=$($NFT list ruleset -a | awk '/ssh-quota/{print $NF}') ++counter_handle=$($NFT -a list ruleset | awk '/https-traffic/{print $NF}') ++quota_handle=$($NFT -a list ruleset | awk '/ssh-quota/{print $NF}') + $NFT delete counter test-ip handle $counter_handle + $NFT delete quota ip6 test-ip6 handle $quota_handle + +diff --git a/tests/shell/testcases/optionals/handles_0 b/tests/shell/testcases/optionals/handles_0 +index 7c6a437..80f3c5b 100755 +--- a/tests/shell/testcases/optionals/handles_0 ++++ b/tests/shell/testcases/optionals/handles_0 +@@ -5,4 +5,4 @@ + $NFT add table test + $NFT add chain test test + $NFT add rule test test tcp dport 22 counter accept +-$NFT list table test -a | grep 'accept # handle '[[:digit:]]$ >/dev/null ++$NFT -a list table test | grep 'accept # handle '[[:digit:]]$ >/dev/null +diff --git a/tests/shell/testcases/sets/0028delete_handle_0 b/tests/shell/testcases/sets/0028delete_handle_0 +index 4e8b322..5ad17c2 100755 +--- a/tests/shell/testcases/sets/0028delete_handle_0 ++++ b/tests/shell/testcases/sets/0028delete_handle_0 +@@ -7,7 +7,7 @@ $NFT add set test-ip y { type inet_service \; timeout 3h45s \;} + $NFT add set test-ip z { type ipv4_addr\; flags constant , interval\;} + $NFT add set test-ip c {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;} + +-set_handle=$($NFT list ruleset -a | awk '/set c/{print $NF}') ++set_handle=$($NFT -a list ruleset | awk '/set c/{print $NF}') + $NFT delete set test-ip handle $set_handle + + EXPECTED="table ip test-ip { +-- +1.8.3.1 + diff --git a/SOURCES/0002-main-restore-debug.patch b/SOURCES/0002-main-restore-debug.patch new file mode 100644 index 0000000..442f24b --- /dev/null +++ b/SOURCES/0002-main-restore-debug.patch @@ -0,0 +1,50 @@ +From 0c808b1ee29d4a0974f4cc5c0586138730361a41 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 10 Jan 2020 19:54:16 +0100 +Subject: [PATCH] main: restore --debug + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1778883 +Upstream Status: nftables commit ea5af85371bd1 + +commit ea5af85371bd18658ea2ffa0a6c9c48e2c64684b +Author: Pablo Neira Ayuso +Date: Thu Jan 9 18:16:18 2020 +0100 + + main: restore --debug + + Broken since options are mandatory before commands. + + Fixes: fb9cea50e8b3 ("main: enforce options before commands") + Signed-off-by: Pablo Neira Ayuso +--- + src/main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 74199f9..6ab1b89 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -46,7 +46,7 @@ enum opt_vals { + OPT_TERSE = 't', + OPT_INVALID = '?', + }; +-#define OPTSTRING "+hvcf:iI:jvnsNaeSupypTt" ++#define OPTSTRING "+hvd:cf:iI:jvnsNaeSupypTt" + + static const struct option options[] = { + { +@@ -228,8 +228,10 @@ static bool nft_options_check(int argc, char * const argv[]) + if (nonoption) { + nft_options_error(argc, argv, pos); + return false; +- } else if (argv[i][1] == 'I' || ++ } else if (argv[i][1] == 'd' || ++ argv[i][1] == 'I' || + argv[i][1] == 'f' || ++ !strcmp(argv[i], "--debug") || + !strcmp(argv[i], "--includepath") || + !strcmp(argv[i], "--file")) { + skip = true; +-- +1.8.3.1 + diff --git a/SOURCES/0002-monitor-Drop-fake-XML-support.patch b/SOURCES/0002-monitor-Drop-fake-XML-support.patch deleted file mode 100644 index 08e6467..0000000 --- a/SOURCES/0002-monitor-Drop-fake-XML-support.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 7a2546c151233aceb7cb8628b234e2a7d2d7620f Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 11 Oct 2018 17:48:57 +0200 -Subject: [PATCH] monitor: Drop fake XML support - -Since libnftnl doesn't support XML formatting, pretending to do so in -nft monitor is pointless. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 2194a76ed46a2f097c5ca5955e44544418866cc2) -Signed-off-by: Phil Sutter ---- - src/monitor.c | 6 ------ - 1 file changed, 6 deletions(-) - -diff --git a/src/monitor.c b/src/monitor.c -index 4310c3b8dc434..d75410888e3d0 100644 ---- a/src/monitor.c -+++ b/src/monitor.c -@@ -203,7 +203,6 @@ static int netlink_events_table_cb(const struct nlmsghdr *nlh, int type, - nftnl_table_get_u64(nlt, NFTNL_TABLE_HANDLE)); - nft_mon_print(monh, "\n"); - break; -- case NFTNL_OUTPUT_XML: - case NFTNL_OUTPUT_JSON: - nftnl_table_fprintf(monh->ctx->octx->output_fp, nlt, - monh->format, netlink_msg2nftnl_of(type)); -@@ -245,7 +244,6 @@ static int netlink_events_chain_cb(const struct nlmsghdr *nlh, int type, - break; - } - break; -- case NFTNL_OUTPUT_XML: - case NFTNL_OUTPUT_JSON: - nftnl_chain_fprintf(monh->ctx->octx->output_fp, nlc, - monh->format, netlink_msg2nftnl_of(type)); -@@ -292,7 +290,6 @@ static int netlink_events_set_cb(const struct nlmsghdr *nlh, int type, - break; - } - break; -- case NFTNL_OUTPUT_XML: - case NFTNL_OUTPUT_JSON: - nftnl_set_fprintf(monh->ctx->octx->output_fp, nls, - monh->format, netlink_msg2nftnl_of(type)); -@@ -441,7 +438,6 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type, - - set_free(dummyset); - break; -- case NFTNL_OUTPUT_XML: - case NFTNL_OUTPUT_JSON: - nftnl_set_fprintf(monh->ctx->octx->output_fp, nls, - monh->format, netlink_msg2nftnl_of(type)); -@@ -486,7 +482,6 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, - break; - } - break; -- case NFTNL_OUTPUT_XML: - case NFTNL_OUTPUT_JSON: - nftnl_obj_fprintf(monh->ctx->octx->output_fp, nlo, - monh->format, netlink_msg2nftnl_of(type)); -@@ -542,7 +537,6 @@ static int netlink_events_rule_cb(const struct nlmsghdr *nlh, int type, - break; - } - break; -- case NFTNL_OUTPUT_XML: - case NFTNL_OUTPUT_JSON: - nftnl_rule_fprintf(monh->ctx->octx->output_fp, nlr, - monh->format, netlink_msg2nftnl_of(type)); --- -2.21.0 - diff --git a/SOURCES/0003-monitor-Do-not-decompose-non-anonymous-sets.patch b/SOURCES/0003-monitor-Do-not-decompose-non-anonymous-sets.patch new file mode 100644 index 0000000..5f1d629 --- /dev/null +++ b/SOURCES/0003-monitor-Do-not-decompose-non-anonymous-sets.patch @@ -0,0 +1,68 @@ +From 13bd961c3ba83e4189dcffdcf570c5a4391fd5f9 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 10 Jan 2020 19:58:29 +0100 +Subject: [PATCH] monitor: Do not decompose non-anonymous sets + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1774742 +Upstream Status: nftables commit 5d57fa3e99bb9 + +commit 5d57fa3e99bb9f2044e236d4ddb7d874cfefe1dd +Author: Phil Sutter +Date: Thu Jan 9 13:34:20 2020 +0100 + + monitor: Do not decompose non-anonymous sets + + They have been decomposed already, trying to do that again causes a + segfault. This is a similar fix as in commit 8ecb885589591 ("src: + restore --echo with anonymous sets"). + + Signed-off-by: Phil Sutter + Acked-by: Pablo Neira Ayuso +--- + src/monitor.c | 2 +- + tests/monitor/testcases/set-interval.t | 20 ++++++++++++++++++++ + 2 files changed, 21 insertions(+), 1 deletion(-) + create mode 100644 tests/monitor/testcases/set-interval.t + +diff --git a/src/monitor.c b/src/monitor.c +index ea0393c..0da9858 100644 +--- a/src/monitor.c ++++ b/src/monitor.c +@@ -500,7 +500,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, + + static void rule_map_decompose_cb(struct set *s, void *data) + { +- if (s->flags & NFT_SET_INTERVAL) ++ if (s->flags & (NFT_SET_INTERVAL & NFT_SET_ANONYMOUS)) + interval_map_decompose(s->init); + } + +diff --git a/tests/monitor/testcases/set-interval.t b/tests/monitor/testcases/set-interval.t +new file mode 100644 +index 0000000..59930c5 +--- /dev/null ++++ b/tests/monitor/testcases/set-interval.t +@@ -0,0 +1,20 @@ ++# setup first ++I add table ip t ++I add chain ip t c ++O - ++J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} ++J {"add": {"chain": {"family": "ip", "table": "t", "name": "c", "handle": 0}}} ++ ++# add set with elements, monitor output expectedly differs ++I add set ip t s { type inet_service; flags interval; elements = { 20, 30-40 }; } ++O add set ip t s { type inet_service; flags interval; } ++O add element ip t s { 20 } ++O add element ip t s { 30-40 } ++J {"add": {"set": {"family": "ip", "name": "s", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}} ++J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [20]}}}} ++J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [{"range": [30, 40]}]}}}} ++ ++# this would crash nft ++I add rule ip t c tcp dport @s ++O - ++J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": "@s"}}]}}} +-- +1.8.3.1 + diff --git a/SOURCES/0003-monitor-Drop-update-table-and-update-chain-cases.patch b/SOURCES/0003-monitor-Drop-update-table-and-update-chain-cases.patch deleted file mode 100644 index 8c23bb4..0000000 --- a/SOURCES/0003-monitor-Drop-update-table-and-update-chain-cases.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 12169cc4179429a88fcc4ffab3e52adb0daf95fc Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 11 Oct 2018 17:48:58 +0200 -Subject: [PATCH] monitor: Drop 'update table' and 'update chain' cases - -There seems to be no situation where this comes to play. Also, since -there is no 'nft update table/chain' command, this is inconsistent with -input. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 62cea2e4ca9d6bc781ced6518810144a8d697275) -Signed-off-by: Phil Sutter ---- - src/monitor.c | 10 ++-------- - 1 file changed, 2 insertions(+), 8 deletions(-) - -diff --git a/src/monitor.c b/src/monitor.c -index d75410888e3d0..3e70b89f0b2ab 100644 ---- a/src/monitor.c -+++ b/src/monitor.c -@@ -186,10 +186,7 @@ static int netlink_events_table_cb(const struct nlmsghdr *nlh, int type, - switch (monh->format) { - case NFTNL_OUTPUT_DEFAULT: - if (type == NFT_MSG_NEWTABLE) { -- if (nlh->nlmsg_flags & NLM_F_EXCL) -- nft_mon_print(monh, "update table "); -- else -- nft_mon_print(monh, "add table "); -+ nft_mon_print(monh, "add table "); - } else { - nft_mon_print(monh, "delete table "); - } -@@ -227,10 +224,7 @@ static int netlink_events_chain_cb(const struct nlmsghdr *nlh, int type, - case NFTNL_OUTPUT_DEFAULT: - switch (type) { - case NFT_MSG_NEWCHAIN: -- if (nlh->nlmsg_flags & NLM_F_EXCL) -- nft_mon_print(monh, "update "); -- else -- nft_mon_print(monh, "add "); -+ nft_mon_print(monh, "add "); - - c = netlink_delinearize_chain(monh->ctx, nlc); - chain_print_plain(c, monh->ctx->octx); --- -2.21.0 - diff --git a/SOURCES/0004-monitor-Fix-output-for-ranges-in-anonymous-sets.patch b/SOURCES/0004-monitor-Fix-output-for-ranges-in-anonymous-sets.patch new file mode 100644 index 0000000..42209e3 --- /dev/null +++ b/SOURCES/0004-monitor-Fix-output-for-ranges-in-anonymous-sets.patch @@ -0,0 +1,80 @@ +From 2e7cb6c2d46d9b8b91ff4b5d6797b7544c23ba44 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 13 Jan 2020 16:58:57 +0100 +Subject: [PATCH] monitor: Fix output for ranges in anonymous sets + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1774742 +Upstream Status: nftables commit ddbacd70d061e + +commit ddbacd70d061eb1b6808f501969809bfb5d03001 +Author: Phil Sutter +Date: Mon Jan 13 14:53:24 2020 +0100 + + monitor: Fix output for ranges in anonymous sets + + Previous fix for named interval sets was simply wrong: Instead of + limiting decomposing to anonymous interval sets, it effectively disabled + it entirely. + + Since code needs to check for both interval and anonymous bits + separately, introduce set_is_interval() helper to keep the code + readable. + + Also extend test case to assert ranges in anonymous sets are correctly + printed by echo or monitor modes. Without this fix, range boundaries are + printed as individual set elements. + + Fixes: 5d57fa3e99bb9 ("monitor: Do not decompose non-anonymous sets") + Signed-off-by: Phil Sutter + Reviewed-by: Pablo Neira Ayuso +--- + include/rule.h | 5 +++++ + src/monitor.c | 2 +- + tests/monitor/testcases/set-interval.t | 5 +++++ + 3 files changed, 11 insertions(+), 1 deletion(-) + +diff --git a/include/rule.h b/include/rule.h +index 0b2eba3..47eb29f 100644 +--- a/include/rule.h ++++ b/include/rule.h +@@ -363,6 +363,11 @@ static inline bool set_is_meter(uint32_t set_flags) + return set_is_anonymous(set_flags) && (set_flags & NFT_SET_EVAL); + } + ++static inline bool set_is_interval(uint32_t set_flags) ++{ ++ return set_flags & NFT_SET_INTERVAL; ++} ++ + #include + + struct counter { +diff --git a/src/monitor.c b/src/monitor.c +index 0da9858..fb803cf 100644 +--- a/src/monitor.c ++++ b/src/monitor.c +@@ -500,7 +500,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, + + static void rule_map_decompose_cb(struct set *s, void *data) + { +- if (s->flags & (NFT_SET_INTERVAL & NFT_SET_ANONYMOUS)) ++ if (set_is_interval(s->flags) && set_is_anonymous(s->flags)) + interval_map_decompose(s->init); + } + +diff --git a/tests/monitor/testcases/set-interval.t b/tests/monitor/testcases/set-interval.t +index 59930c5..1fbcfe2 100644 +--- a/tests/monitor/testcases/set-interval.t ++++ b/tests/monitor/testcases/set-interval.t +@@ -18,3 +18,8 @@ J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set" + I add rule ip t c tcp dport @s + O - + J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": "@s"}}]}}} ++ ++# test anonymous interval sets as well ++I add rule ip t c tcp dport { 20, 30-40 } ++O - ++J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": {"set": [20, {"range": [30, 40]}]}}}]}}} +-- +1.8.3.1 + diff --git a/SOURCES/0004-monitor-Fix-printing-of-ct-objects.patch b/SOURCES/0004-monitor-Fix-printing-of-ct-objects.patch deleted file mode 100644 index ca630d7..0000000 --- a/SOURCES/0004-monitor-Fix-printing-of-ct-objects.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 892ec2ca97263ccfffb52f2943c2ab2ac34f476d Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 11 Oct 2018 17:48:59 +0200 -Subject: [PATCH] monitor: Fix printing of ct objects - -Monitor output is supposed to be single lined without tabs, but ct -object were printed with newlines and tabs hard-coded. Fixing this -wasn't too hard given that there is 'stmt_separator' to also include -semi-colons where required if newline was removed. - -A more obvious mistake was position of object type in monitor output: -Like with other object types, it has to occur between command and table -spec. As a positive side-effect, this aligns ct objects better with -others (see obj_type_name_array for instance). - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 90ed4fb3855f0d9d881b812c75e338e5e93081ba) - -Conflicts: - src/rule.c - tests/shell/testcases/listing/0013objects_0 - tests/shell/testcases/nft-f/0017ct_timeout_obj_0 - tests/shell/testcases/nft-f/dumps/0017ct_timeout_obj_0.nft --> missing ct timeout support - -Signed-off-by: Phil Sutter ---- - src/json.c | 1 - - src/rule.c | 26 ++++++++++++++++---------- - tests/monitor/testcases/object.t | 27 +++++++++++++++++++++++++++ - 3 files changed, 43 insertions(+), 11 deletions(-) - create mode 100644 tests/monitor/testcases/object.t - -diff --git a/src/json.c b/src/json.c -index b6e6ca9c6c383..af157212c081e 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -264,7 +264,6 @@ static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) - json_decref(tmp); - break; - case NFT_OBJECT_CT_HELPER: -- type = "ct helper"; - tmp = json_pack("{s:s, s:o, s:s}", - "type", obj->ct_helper.name, "protocol", - proto_name_json(obj->ct_helper.l4proto), -diff --git a/src/rule.c b/src/rule.c -index 56b956a4f8fec..eb06302d4f223 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -1432,8 +1432,8 @@ static void obj_print_data(const struct obj *obj, - nft_print(octx, "packets 0 bytes 0"); - break; - } -- nft_print(octx, "packets %" PRIu64 " bytes %" PRIu64 "", -- obj->counter.packets, obj->counter.bytes); -+ nft_print(octx, "packets %" PRIu64 " bytes %" PRIu64 "%s", -+ obj->counter.packets, obj->counter.bytes, opts->nl); - break; - case NFT_OBJECT_QUOTA: { - const char *data_unit; -@@ -1452,18 +1452,22 @@ static void obj_print_data(const struct obj *obj, - nft_print(octx, " used %" PRIu64 " %s", - bytes, data_unit); - } -+ nft_print(octx, "%s", opts->nl); - } - break; - case NFT_OBJECT_CT_HELPER: -- nft_print(octx, "ct helper %s {", obj->handle.obj.name); -+ nft_print(octx, " %s {", obj->handle.obj.name); - if (octx->handle > 0) - nft_print(octx, " # handle %" PRIu64, obj->handle.handle.id); - nft_print(octx, "%s", opts->nl); -- nft_print(octx, "\t\ttype \"%s\" protocol ", -- obj->ct_helper.name); -+ nft_print(octx, "%s%stype \"%s\" protocol ", -+ opts->tab, opts->tab, obj->ct_helper.name); - print_proto_name_proto(obj->ct_helper.l4proto, octx); -- nft_print(octx, "\t\tl3proto %s", -- family2str(obj->ct_helper.l3proto)); -+ nft_print(octx, "%s", opts->stmt_separator); -+ nft_print(octx, "%s%sl3proto %s%s", -+ opts->tab, opts->tab, -+ family2str(obj->ct_helper.l3proto), -+ opts->stmt_separator); - break; - case NFT_OBJECT_LIMIT: { - bool inv = obj->limit.flags & NFT_LIMIT_F_INV; -@@ -1498,10 +1502,11 @@ static void obj_print_data(const struct obj *obj, - } - break; - } -+ nft_print(octx, "%s", opts->nl); - } - break; - default: -- nft_print(octx, "unknown {%s", opts->nl); -+ nft_print(octx, " unknown {%s", opts->nl); - break; - } - } -@@ -1509,7 +1514,7 @@ static void obj_print_data(const struct obj *obj, - static const char * const obj_type_name_array[] = { - [NFT_OBJECT_COUNTER] = "counter", - [NFT_OBJECT_QUOTA] = "quota", -- [NFT_OBJECT_CT_HELPER] = "", -+ [NFT_OBJECT_CT_HELPER] = "ct helper", - [NFT_OBJECT_LIMIT] = "limit", - }; - -@@ -1548,7 +1553,7 @@ static void obj_print_declaration(const struct obj *obj, - - obj_print_data(obj, opts, octx); - -- nft_print(octx, "%s%s}%s", opts->nl, opts->tab, opts->nl); -+ nft_print(octx, "%s}%s", opts->tab, opts->nl); - } - - void obj_print(const struct obj *obj, struct output_ctx *octx) -@@ -1569,6 +1574,7 @@ void obj_print_plain(const struct obj *obj, struct output_ctx *octx) - .nl = " ", - .table = obj->handle.table.name, - .family = family2str(obj->handle.family), -+ .stmt_separator = "; ", - }; - - obj_print_declaration(obj, &opts, octx); -diff --git a/tests/monitor/testcases/object.t b/tests/monitor/testcases/object.t -new file mode 100644 -index 0000000000000..7b88409775796 ---- /dev/null -+++ b/tests/monitor/testcases/object.t -@@ -0,0 +1,27 @@ -+# first the setup -+I add table ip t -+O - -+ -+I add counter ip t c -+O add counter ip t c { packets 0 bytes 0 } -+ -+I delete counter ip t c -+O - -+ -+I add quota ip t q 25 mbytes -+O add quota ip t q { 25 mbytes } -+ -+I delete quota ip t q -+O - -+ -+I add limit ip t l rate 1/second -+O add limit ip t l { rate 1/second } -+ -+I delete limit ip t l -+O - -+ -+I add ct helper ip t cth { type "sip" protocol tcp; l3proto ip; } -+O - -+ -+I delete ct helper ip t cth -+O - --- -2.21.0 - diff --git a/SOURCES/0005-monitor-Use-libnftables-JSON-output.patch b/SOURCES/0005-monitor-Use-libnftables-JSON-output.patch deleted file mode 100644 index 2523ce9..0000000 --- a/SOURCES/0005-monitor-Use-libnftables-JSON-output.patch +++ /dev/null @@ -1,652 +0,0 @@ -From 53693c43d94dddf1ae1a0e69bfa953fba2c098e0 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 11 Oct 2018 17:49:00 +0200 -Subject: [PATCH] monitor: Use libnftables JSON output - -This switches 'nft monitor' JSON output from using libnftnl's to -libnftables' implementation. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 9e88aae28e9f44d010f3ecf7577357f4c0e7d622) -Signed-off-by: Phil Sutter ---- - include/json.h | 51 +++++++++ - src/json.c | 57 ++++++++++ - src/monitor.c | 281 +++++++++++++++++++++++++------------------------ - src/rule.c | 2 - - 4 files changed, 251 insertions(+), 140 deletions(-) - -diff --git a/include/json.h b/include/json.h -index ae3938142aeac..af0f72f13dd60 100644 ---- a/include/json.h -+++ b/include/json.h -@@ -9,9 +9,11 @@ struct expr; - struct netlink_ctx; - struct rule; - struct set; -+struct obj; - struct stmt; - struct symbol_table; - struct table; -+struct netlink_mon_handler; - - #ifdef HAVE_LIBJANSSON - -@@ -81,6 +83,19 @@ int nft_parse_json_buffer(struct nft_ctx *nft, char *buf, size_t buflen, - int nft_parse_json_filename(struct nft_ctx *nft, const char *filename, - struct list_head *msgs, struct list_head *cmds); - -+void monitor_print_table_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct table *t); -+void monitor_print_chain_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct chain *c); -+void monitor_print_set_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct set *s); -+void monitor_print_element_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct set *s); -+void monitor_print_obj_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct obj *o); -+void monitor_print_rule_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct rule *r); -+ - #else /* ! HAVE_LIBJANSSON */ - - typedef void json_t; -@@ -176,6 +191,42 @@ nft_parse_json_filename(struct nft_ctx *nft, const char *filename, - return -EINVAL; - } - -+static inline void monitor_print_table_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct table *t) -+{ -+ /* empty */ -+} -+ -+static inline void monitor_print_chain_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct chain *c) -+{ -+ /* empty */ -+} -+ -+static inline void monitor_print_set_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct set *s) -+{ -+ /* empty */ -+} -+ -+static inline void monitor_print_element_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct set *s) -+{ -+ /* empty */ -+} -+ -+static inline void monitor_print_obj_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct obj *o) -+{ -+ /* empty */ -+} -+ -+static inline void monitor_print_rule_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct rule *r) -+{ -+ /* empty */ -+} -+ - #endif /* HAVE_LIBJANSSON */ - - #endif /* NFTABLES_JSON_H */ -diff --git a/src/json.c b/src/json.c -index af157212c081e..7d89754bd666d 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -147,6 +147,19 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set) - return json_pack("{s:o}", type, root); - } - -+/* XXX: Merge with set_print_json()? */ -+static json_t *element_print_json(struct output_ctx *octx, -+ const struct set *set) -+{ -+ json_t *root = expr_print_json(set->init, octx); -+ -+ return json_pack("{s: {s:s, s:s, s:s, s:o}}", "element", -+ "family", family2str(set->handle.family), -+ "table", set->handle.table.name, -+ "name", set->handle.set.name, -+ "elem", root); -+} -+ - static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx) - { - char buf[1024]; -@@ -1554,3 +1567,47 @@ int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd) - json_decref(root); - return 0; - } -+ -+static void monitor_print_json(struct netlink_mon_handler *monh, -+ const char *cmd, json_t *obj) -+{ -+ obj = json_pack("{s:o}", cmd, obj); -+ json_dumpf(obj, monh->ctx->octx->output_fp, 0); -+ json_decref(obj); -+} -+ -+void monitor_print_table_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct table *t) -+{ -+ monitor_print_json(monh, cmd, table_print_json(monh->ctx->octx, t)); -+} -+ -+void monitor_print_chain_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct chain *c) -+{ -+ monitor_print_json(monh, cmd, chain_print_json(monh->ctx->octx, c)); -+} -+ -+void monitor_print_set_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct set *s) -+{ -+ monitor_print_json(monh, cmd, set_print_json(monh->ctx->octx, s)); -+} -+ -+void monitor_print_element_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct set *s) -+{ -+ monitor_print_json(monh, cmd, element_print_json(monh->ctx->octx, s)); -+} -+ -+void monitor_print_obj_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct obj *o) -+{ -+ monitor_print_json(monh, cmd, obj_print_json(monh->ctx->octx, o)); -+} -+ -+void monitor_print_rule_json(struct netlink_mon_handler *monh, -+ const char *cmd, struct rule *r) -+{ -+ monitor_print_json(monh, cmd, rule_print_json(monh->ctx->octx, r)); -+} -diff --git a/src/monitor.c b/src/monitor.c -index 3e70b89f0b2ab..213c40d119b4c 100644 ---- a/src/monitor.c -+++ b/src/monitor.c -@@ -38,6 +38,7 @@ - #include - #include - #include -+#include - - #define nft_mon_print(monh, ...) nft_print(monh->ctx->octx, __VA_ARGS__) - -@@ -127,18 +128,39 @@ static uint32_t netlink_msg2nftnl_of(uint32_t msg) - case NFT_MSG_NEWSET: - case NFT_MSG_NEWSETELEM: - case NFT_MSG_NEWRULE: -+ case NFT_MSG_NEWOBJ: -+ case NFT_MSG_NEWFLOWTABLE: - return NFTNL_OF_EVENT_NEW; - case NFT_MSG_DELTABLE: - case NFT_MSG_DELCHAIN: - case NFT_MSG_DELSET: - case NFT_MSG_DELSETELEM: - case NFT_MSG_DELRULE: -+ case NFT_MSG_DELOBJ: -+ case NFT_MSG_DELFLOWTABLE: - return NFTNL_OF_EVENT_DEL; - } - - return 0; - } - -+static const char *nftnl_of2cmd(uint32_t of) -+{ -+ switch (of) { -+ case NFTNL_OF_EVENT_NEW: -+ return "add"; -+ case NFTNL_OF_EVENT_DEL: -+ return "delete"; -+ default: -+ return "???"; -+ } -+} -+ -+static const char *netlink_msg2cmd(uint32_t msg) -+{ -+ return nftnl_of2cmd(netlink_msg2nftnl_of(msg)); -+} -+ - static void nlr_for_each_set(struct nftnl_rule *nlr, - void (*cb)(struct set *s, void *data), - void *data, struct nft_cache *cache) -@@ -179,34 +201,29 @@ static int netlink_events_table_cb(const struct nlmsghdr *nlh, int type, - struct netlink_mon_handler *monh) - { - struct nftnl_table *nlt; -- uint32_t family; -+ struct table *t; -+ const char *cmd; - - nlt = netlink_table_alloc(nlh); -+ t = netlink_delinearize_table(monh->ctx, nlt); -+ cmd = netlink_msg2cmd(type); - - switch (monh->format) { - case NFTNL_OUTPUT_DEFAULT: -- if (type == NFT_MSG_NEWTABLE) { -- nft_mon_print(monh, "add table "); -- } else { -- nft_mon_print(monh, "delete table "); -- } -+ nft_mon_print(monh, "%s table ", cmd); - -- family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY); -- -- nft_mon_print(monh, "%s %s", family2str(family), -- nftnl_table_get_str(nlt, NFTNL_TABLE_NAME)); -+ nft_mon_print(monh, "%s %s", family2str(t->handle.family), -+ t->handle.table.name); - if (monh->ctx->octx->handle > 0) - nft_mon_print(monh, " # handle %" PRIu64 "", -- nftnl_table_get_u64(nlt, NFTNL_TABLE_HANDLE)); -- nft_mon_print(monh, "\n"); -+ t->handle.handle.id); - break; - case NFTNL_OUTPUT_JSON: -- nftnl_table_fprintf(monh->ctx->octx->output_fp, nlt, -- monh->format, netlink_msg2nftnl_of(type)); -- nft_mon_print(monh, "\n"); -+ monitor_print_table_json(monh, cmd, t); - break; - } -- -+ nft_mon_print(monh, "\n"); -+ table_free(t); - nftnl_table_free(nlt); - return MNL_CB_OK; - } -@@ -216,35 +233,34 @@ static int netlink_events_chain_cb(const struct nlmsghdr *nlh, int type, - { - struct nftnl_chain *nlc; - struct chain *c; -- uint32_t family; -+ const char *cmd; - - nlc = netlink_chain_alloc(nlh); -+ c = netlink_delinearize_chain(monh->ctx, nlc); -+ cmd = netlink_msg2cmd(type); - - switch (monh->format) { - case NFTNL_OUTPUT_DEFAULT: -+ nft_mon_print(monh, "%s ", cmd); -+ - switch (type) { - case NFT_MSG_NEWCHAIN: -- nft_mon_print(monh, "add "); -- -- c = netlink_delinearize_chain(monh->ctx, nlc); - chain_print_plain(c, monh->ctx->octx); -- chain_free(c); - break; - case NFT_MSG_DELCHAIN: -- family = nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY); -- nft_mon_print(monh, "delete chain %s %s %s\n", family2str(family), -- nftnl_chain_get_str(nlc, NFTNL_CHAIN_TABLE), -- nftnl_chain_get_str(nlc, NFTNL_CHAIN_NAME)); -+ nft_mon_print(monh, "chain %s %s %s", -+ family2str(c->handle.family), -+ c->handle.table.name, -+ c->handle.chain.name); - break; - } - break; - case NFTNL_OUTPUT_JSON: -- nftnl_chain_fprintf(monh->ctx->octx->output_fp, nlc, -- monh->format, netlink_msg2nftnl_of(type)); -- nft_mon_print(monh, "\n"); -+ monitor_print_chain_json(monh, cmd, c); - break; - } -- -+ nft_mon_print(monh, "\n"); -+ chain_free(c); - nftnl_chain_free(nlc); - return MNL_CB_OK; - } -@@ -253,43 +269,44 @@ static int netlink_events_set_cb(const struct nlmsghdr *nlh, int type, - struct netlink_mon_handler *monh) - { - struct nftnl_set *nls; -+ const char *family, *cmd; - struct set *set; -- uint32_t family, flags; -+ uint32_t flags; - - nls = netlink_set_alloc(nlh); - flags = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS); - if (flags & NFT_SET_ANONYMOUS) - goto out; - -+ set = netlink_delinearize_set(monh->ctx, nls); -+ if (set == NULL) { -+ nftnl_set_free(nls); -+ return MNL_CB_ERROR; -+ } -+ family = family2str(set->handle.family); -+ cmd = netlink_msg2cmd(type); -+ - switch (monh->format) { - case NFTNL_OUTPUT_DEFAULT: -+ nft_mon_print(monh, "%s ", cmd); -+ - switch (type) { - case NFT_MSG_NEWSET: -- nft_mon_print(monh, "add "); -- set = netlink_delinearize_set(monh->ctx, nls); -- if (set == NULL) { -- nftnl_set_free(nls); -- return MNL_CB_ERROR; -- } - set_print_plain(set, monh->ctx->octx); -- set_free(set); -- nft_mon_print(monh, "\n"); - break; - case NFT_MSG_DELSET: -- family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY); -- nft_mon_print(monh, "delete set %s %s %s\n", -- family2str(family), -- nftnl_set_get_str(nls, NFTNL_SET_TABLE), -- nftnl_set_get_str(nls, NFTNL_SET_NAME)); -+ nft_mon_print(monh, "set %s %s %s", family, -+ set->handle.table.name, -+ set->handle.set.name); - break; - } - break; - case NFTNL_OUTPUT_JSON: -- nftnl_set_fprintf(monh->ctx->octx->output_fp, nls, -- monh->format, netlink_msg2nftnl_of(type)); -- nft_mon_print(monh, "\n"); -+ monitor_print_set_json(monh, cmd, set); - break; - } -+ nft_mon_print(monh, "\n"); -+ set_free(set); - out: - nftnl_set_free(nls); - return MNL_CB_OK; -@@ -360,13 +377,14 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type, - struct nftnl_set *nls; - struct set *dummyset; - struct set *set; -- const char *setname, *table; -+ const char *setname, *table, *cmd; - uint32_t family; - - nls = netlink_setelem_alloc(nlh); - table = nftnl_set_get_str(nls, NFTNL_SET_TABLE); - setname = nftnl_set_get_str(nls, NFTNL_SET_NAME); - family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY); -+ cmd = netlink_msg2cmd(type); - - set = set_lookup_global(family, table, setname, monh->cache); - if (set == NULL) { -@@ -374,70 +392,63 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type, - goto out; - } - -- switch (monh->format) { -- case NFTNL_OUTPUT_DEFAULT: -- if (set->flags & NFT_SET_ANONYMOUS) -- goto out; -- -- /* we want to 'delinearize' the set_elem, but don't -- * modify the original cached set. This path is only -- * used by named sets, so use a dummy set. -- */ -- dummyset = set_alloc(monh->loc); -- dummyset->key = expr_clone(set->key); -- dummyset->datatype = set->datatype; -- dummyset->flags = set->flags; -- dummyset->init = set_expr_alloc(monh->loc, set); -+ if (set->flags & NFT_SET_ANONYMOUS) -+ goto out; - -- nlsei = nftnl_set_elems_iter_create(nls); -- if (nlsei == NULL) -- memory_allocation_error(); -+ /* we want to 'delinearize' the set_elem, but don't -+ * modify the original cached set. This path is only -+ * used by named sets, so use a dummy set. -+ */ -+ dummyset = set_alloc(monh->loc); -+ dummyset->key = expr_clone(set->key); -+ dummyset->datatype = set->datatype; -+ dummyset->flags = set->flags; -+ dummyset->init = set_expr_alloc(monh->loc, set); - -- nlse = nftnl_set_elems_iter_next(nlsei); -- while (nlse != NULL) { -- if (netlink_event_ignore_range_event(nlse)) { -- set_free(dummyset); -- nftnl_set_elems_iter_destroy(nlsei); -- goto out; -- } -- if (netlink_delinearize_setelem(nlse, dummyset, -- monh->cache) < 0) { -- set_free(dummyset); -- nftnl_set_elems_iter_destroy(nlsei); -- goto out; -- } -- nlse = nftnl_set_elems_iter_next(nlsei); -- } -- nftnl_set_elems_iter_destroy(nlsei); -+ nlsei = nftnl_set_elems_iter_create(nls); -+ if (nlsei == NULL) -+ memory_allocation_error(); - -- if (netlink_event_range_cache(set, dummyset)) { -+ nlse = nftnl_set_elems_iter_next(nlsei); -+ while (nlse != NULL) { -+ if (netlink_event_ignore_range_event(nlse)) { - set_free(dummyset); -+ nftnl_set_elems_iter_destroy(nlsei); - goto out; - } -- -- switch (type) { -- case NFT_MSG_NEWSETELEM: -- nft_mon_print(monh, "add "); -- break; -- case NFT_MSG_DELSETELEM: -- nft_mon_print(monh, "delete "); -- break; -- default: -+ if (netlink_delinearize_setelem(nlse, dummyset, -+ monh->cache) < 0) { - set_free(dummyset); -+ nftnl_set_elems_iter_destroy(nlsei); - goto out; - } -- nft_mon_print(monh, "element %s %s %s ", family2str(family), table, setname); -- expr_print(dummyset->init, monh->ctx->octx); -- nft_mon_print(monh, "\n"); -+ nlse = nftnl_set_elems_iter_next(nlsei); -+ } -+ nftnl_set_elems_iter_destroy(nlsei); - -+ if (netlink_event_range_cache(set, dummyset)) { - set_free(dummyset); -+ goto out; -+ } -+ -+ switch (monh->format) { -+ case NFTNL_OUTPUT_DEFAULT: -+ nft_mon_print(monh, "%s element %s %s %s ", -+ cmd, family2str(family), table, setname); -+ expr_print(dummyset->init, monh->ctx->octx); - break; - case NFTNL_OUTPUT_JSON: -- nftnl_set_fprintf(monh->ctx->octx->output_fp, nls, -- monh->format, netlink_msg2nftnl_of(type)); -- nft_mon_print(monh, "\n"); -+ dummyset->handle.family = family; -+ dummyset->handle.set.name = setname; -+ dummyset->handle.table.name = table; -+ monitor_print_element_json(monh, cmd, dummyset); -+ /* prevent set_free() from trying to free those */ -+ dummyset->handle.set.name = NULL; -+ dummyset->handle.table.name = NULL; - break; - } -+ nft_mon_print(monh, "\n"); -+ set_free(dummyset); - out: - nftnl_set_free(nls); - return MNL_CB_OK; -@@ -446,43 +457,43 @@ out: - static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, - struct netlink_mon_handler *monh) - { -+ const char *family, *cmd; - struct nftnl_obj *nlo; -- uint32_t family; - struct obj *obj; - - nlo = netlink_obj_alloc(nlh); - -+ obj = netlink_delinearize_obj(monh->ctx, nlo); -+ if (obj == NULL) { -+ nftnl_obj_free(nlo); -+ return MNL_CB_ERROR; -+ } -+ family = family2str(obj->handle.family); -+ cmd = netlink_msg2cmd(type); -+ - switch (monh->format) { - case NFTNL_OUTPUT_DEFAULT: -+ nft_mon_print(monh, "%s ", cmd); -+ - switch (type) { - case NFT_MSG_NEWOBJ: -- nft_mon_print(monh, "add "); -- obj = netlink_delinearize_obj(monh->ctx, nlo); -- if (obj == NULL) { -- nftnl_obj_free(nlo); -- return MNL_CB_ERROR; -- } - obj_print_plain(obj, monh->ctx->octx); -- obj_free(obj); -- nft_mon_print(monh, "\n"); - break; - case NFT_MSG_DELOBJ: -- family = nftnl_obj_get_u32(nlo, NFTNL_OBJ_FAMILY); -- nft_mon_print(monh, "delete %s %s %s %s\n", -- obj_type_name(nftnl_obj_get_u32(nlo, NFTNL_OBJ_TYPE)), -- family2str(family), -- nftnl_obj_get_str(nlo, NFTNL_OBJ_TABLE), -- nftnl_obj_get_str(nlo, NFTNL_OBJ_NAME)); -+ nft_mon_print(monh, "%s %s %s %s", -+ obj_type_name(obj->type), -+ family, -+ obj->handle.table.name, -+ obj->handle.obj.name); - break; - } - break; - case NFTNL_OUTPUT_JSON: -- nftnl_obj_fprintf(monh->ctx->octx->output_fp, nlo, -- monh->format, netlink_msg2nftnl_of(type)); -- nft_mon_print(monh, "\n"); -+ monitor_print_obj_json(monh, cmd, obj); - break; - } -- -+ nft_mon_print(monh, "\n"); -+ obj_free(obj); - nftnl_obj_free(nlo); - return MNL_CB_OK; - } -@@ -496,48 +507,42 @@ static void rule_map_decompose_cb(struct set *s, void *data) - static int netlink_events_rule_cb(const struct nlmsghdr *nlh, int type, - struct netlink_mon_handler *monh) - { -+ const char *family, *cmd; - struct nftnl_rule *nlr; -- const char *family; -- const char *table; -- const char *chain; - struct rule *r; -- uint64_t handle; -- uint32_t fam; - - nlr = netlink_rule_alloc(nlh); -+ r = netlink_delinearize_rule(monh->ctx, nlr); -+ nlr_for_each_set(nlr, rule_map_decompose_cb, NULL, monh->cache); -+ cmd = netlink_msg2cmd(type); -+ - switch (monh->format) { - case NFTNL_OUTPUT_DEFAULT: -- fam = nftnl_rule_get_u32(nlr, NFTNL_RULE_FAMILY); -- family = family2str(fam); -- table = nftnl_rule_get_str(nlr, NFTNL_RULE_TABLE); -- chain = nftnl_rule_get_str(nlr, NFTNL_RULE_CHAIN); -- handle = nftnl_rule_get_u64(nlr, NFTNL_RULE_HANDLE); -+ family = family2str(r->handle.family); -+ -+ nft_mon_print(monh, "%s rule %s %s %s ", -+ cmd, -+ family, -+ r->handle.table.name, -+ r->handle.chain.name); - - switch (type) { - case NFT_MSG_NEWRULE: -- r = netlink_delinearize_rule(monh->ctx, nlr); -- nlr_for_each_set(nlr, rule_map_decompose_cb, NULL, -- monh->cache); -- -- nft_mon_print(monh, "add rule %s %s %s ", family, table, chain); - rule_print(r, monh->ctx->octx); -- nft_mon_print(monh, "\n"); - -- rule_free(r); - break; - case NFT_MSG_DELRULE: -- nft_mon_print(monh, "delete rule %s %s %s handle %u\n", -- family, table, chain, (unsigned int)handle); -+ nft_mon_print(monh, "handle %" PRIu64, -+ r->handle.handle.id); - break; - } - break; - case NFTNL_OUTPUT_JSON: -- nftnl_rule_fprintf(monh->ctx->octx->output_fp, nlr, -- monh->format, netlink_msg2nftnl_of(type)); -- nft_mon_print(monh, "\n"); -+ monitor_print_rule_json(monh, cmd, r); - break; - } -- -+ nft_mon_print(monh, "\n"); -+ rule_free(r); - nftnl_rule_free(nlr); - return MNL_CB_OK; - } -diff --git a/src/rule.c b/src/rule.c -index eb06302d4f223..3065cc5474bbf 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -812,8 +812,6 @@ void chain_print_plain(const struct chain *chain, struct output_ctx *octx) - } - if (octx->handle > 0) - nft_print(octx, " # handle %" PRIu64, chain->handle.handle.id); -- -- nft_print(octx, "\n"); - } - - struct table *table_alloc(void) --- -2.21.0 - diff --git a/SOURCES/0005-xfrm-spi-is-big-endian.patch b/SOURCES/0005-xfrm-spi-is-big-endian.patch new file mode 100644 index 0000000..8dd30e8 --- /dev/null +++ b/SOURCES/0005-xfrm-spi-is-big-endian.patch @@ -0,0 +1,51 @@ +From ca4d1604b18abf7189ecfd5e06cb74abc3694076 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 16 Jan 2020 18:40:52 +0100 +Subject: [PATCH] xfrm: spi is big-endian + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1790963 +Upstream Status: nftables commit 488356b895024 + +commit 488356b895024d0944b20feb1f930558726e0877 +Author: Florian Westphal +Date: Tue Jan 14 13:37:28 2020 +0100 + + xfrm: spi is big-endian + + the kernel stores spi in a __be32, so fix up the byteorder annotation. + + Signed-off-by: Florian Westphal + Acked-by: Pablo Neira Ayuso +--- + src/xfrm.c | 2 +- + tests/py/inet/ipsec.t.payload | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/xfrm.c b/src/xfrm.c +index 4dd53c3..336e8c9 100644 +--- a/src/xfrm.c ++++ b/src/xfrm.c +@@ -39,7 +39,7 @@ const struct xfrm_template xfrm_templates[] = { + [NFT_XFRM_KEY_DADDR_IP6] = XFRM_TEMPLATE_BE("daddr", &ip6addr_type, 16 * BITS_PER_BYTE), + [NFT_XFRM_KEY_SADDR_IP6] = XFRM_TEMPLATE_BE("saddr", &ip6addr_type, 16 * BITS_PER_BYTE), + [NFT_XFRM_KEY_REQID] = XFRM_TEMPLATE_HE("reqid", &integer_type, 4 * BITS_PER_BYTE), +- [NFT_XFRM_KEY_SPI] = XFRM_TEMPLATE_HE("spi", &integer_type, 4 * BITS_PER_BYTE), ++ [NFT_XFRM_KEY_SPI] = XFRM_TEMPLATE_BE("spi", &integer_type, 4 * BITS_PER_BYTE), + }; + + static void xfrm_expr_print(const struct expr *expr, struct output_ctx *octx) +diff --git a/tests/py/inet/ipsec.t.payload b/tests/py/inet/ipsec.t.payload +index 6049c66..c46a226 100644 +--- a/tests/py/inet/ipsec.t.payload ++++ b/tests/py/inet/ipsec.t.payload +@@ -16,7 +16,6 @@ ip ipsec-ip4 ipsec-input + # ipsec out spi 1-561 + inet ipsec-inet ipsec-post + [ xfrm load out 0 spi => reg 1 ] +- [ byteorder reg 1 = hton(reg 1, 4, 4) ] + [ cmp gte reg 1 0x01000000 ] + [ cmp lte reg 1 0x31020000 ] + +-- +1.8.3.1 + diff --git a/SOURCES/0006-tests-monitor-Test-JSON-output-as-well.patch b/SOURCES/0006-tests-monitor-Test-JSON-output-as-well.patch deleted file mode 100644 index b2ca0ca..0000000 --- a/SOURCES/0006-tests-monitor-Test-JSON-output-as-well.patch +++ /dev/null @@ -1,368 +0,0 @@ -From 24b0395e8d26ed9f7eb1716249a8e07f9f84571d Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 11 Oct 2018 17:49:01 +0200 -Subject: [PATCH] tests: monitor: Test JSON output as well - -Enhance monitor test suite to test check JSON output as well. Note that -for now there is no support for --echo output testing with JSON. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 16694bdd4c01ae001b60fbc18d45200fffc84de5) - -Conflicts: - tests/monitor/testcases/object.t --> Missing ct timeout support - -Signed-off-by: Phil Sutter ---- - tests/monitor/README | 27 +++++++++++----- - tests/monitor/run-tests.sh | 45 ++++++++++++++++++++++++-- - tests/monitor/testcases/object.t | 11 +++++++ - tests/monitor/testcases/set-maps.t | 4 +++ - tests/monitor/testcases/set-mixed.t | 7 ++++ - tests/monitor/testcases/set-multiple.t | 5 +++ - tests/monitor/testcases/set-simple.t | 19 +++++++++++ - tests/monitor/testcases/simple.t | 8 +++++ - 8 files changed, 115 insertions(+), 11 deletions(-) - -diff --git a/tests/monitor/README b/tests/monitor/README -index 9c5e37f5c75c9..39096a7fae078 100644 ---- a/tests/monitor/README -+++ b/tests/monitor/README -@@ -15,13 +15,14 @@ to be established manually, i.e. in order to test monitor output when adding a - chain, the table containing it has to be created first. In between each - testcase, rule set is flushed completely. - --Input and output lines are prefixed by 'I' and 'O', respectively. The prefix has --to be separated from the rest of the line by whitespace. Consecutive input lines --are passed to 'nft' together, hence lead to a single transaction. -+Input lines are prefixed by 'I'. Multiple consecutive input lines are passed to -+'nft' together, hence lead to a single transaction. - --Since in most cases output should be equal to input, there is a shortcut: If a --line consists of 'O -' only, the test script uses all previous input lines as --expected output directly. -+There are two types of output lines: Those for standard syntax, prefixed by 'O' -+and those for JSON output, prefixed by 'J'. For standard syntax output lines, -+there is a shortcut: If a line consists of 'O -' only, the test script uses all -+previous input lines as expected output directly. Of course this is not -+available for JSON output lines. - - Empty lines and those starting with '#' are ignored. - -@@ -29,8 +30,8 @@ Test Script Semantics - --------------------- - - The script iterates over all test case files, reading them line by line. It --assumes that sections of 'I' lines alternate with sections of 'O' lines. After --stripping the prefix, each line is appended to a temporary file. There are -+assumes that sections of 'I' lines alternate with sections of 'O'/'J' lines. -+After stripping the prefix, each line is appended to a temporary file. There are - separate files for input and output lines. - - If a set of input and output lines is complete (i.e. upon encountering either a -@@ -46,3 +47,13 @@ Note: Running 'nft monitor' in background is prone to race conditions. Hence - an artificial delay is introduced before calling 'nft -f' to allow for 'nft - monitor' to complete initialization and another one before comparing the output - to allow for 'nft monitor' to process the netlink events. -+ -+By default, only standard syntax is being tested for, i.e. 'J'-prefixed lines -+are simply ignored. If JSON testing was requested (by passing '-j' flag to the -+test script), 'O'-prefixed lines in turn are ignored. -+ -+There is one caveat with regards to JSON output: Since it always contains handle -+properties (if the given object possesses such) which is supposed to be -+arbitrary, there is a filter script which normalizes all handle values in -+monitor output to zero before comparison. Therefore expected output must have -+all handle properties present but with a value of zero. -diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh -index 1adabda193949..f4089887b69aa 100755 ---- a/tests/monitor/run-tests.sh -+++ b/tests/monitor/run-tests.sh -@@ -3,6 +3,7 @@ - cd $(dirname $0) - nft=../../src/nft - debug=false -+test_json=false - - mydiff() { - diff -w -I '^# ' "$@" -@@ -47,9 +48,16 @@ echo_output_append() { - } - [[ "$*" =~ ^add|replace|insert ]] && echo "$*" >>$output_file - } -+json_output_filter() { # (filename) -+ # unify handle values -+ sed -i -e 's/\("handle":\) [0-9][0-9]*/\1 0/g' "$1" -+} - monitor_run_test() { - monitor_output=$(mktemp -p $testdir) -- $nft -nn monitor >$monitor_output & -+ monitor_args="" -+ $test_json && monitor_args="vm json" -+ -+ $nft -nn monitor $monitor_args >$monitor_output & - monitor_pid=$! - - sleep 0.5 -@@ -67,6 +75,7 @@ monitor_run_test() { - sleep 0.5 - kill $monitor_pid - wait >/dev/null 2>&1 -+ $test_json && json_output_filter $monitor_output - if ! mydiff -q $monitor_output $output_file >/dev/null 2>&1; then - echo "monitor output differs!" - mydiff -u $output_file $monitor_output -@@ -99,7 +108,33 @@ echo_run_test() { - touch $output_file - } - --for variant in monitor echo; do -+while [ -n "$1" ]; do -+ case "$1" in -+ -d|--debug) -+ debug=true -+ shift -+ ;; -+ -j|--json) -+ test_json=true -+ shift -+ ;; -+ *) -+ echo "unknown option '$1'" -+ ;& -+ -h|--help) -+ echo "Usage: $(basename $0) [-j|--json] [-d|--debug]" -+ exit 1 -+ ;; -+ esac -+done -+ -+if $test_json; then -+ variants="monitor" -+else -+ variants="monitor echo" -+fi -+ -+for variant in $variants; do - run_test=${variant}_run_test - output_append=${variant}_output_append - -@@ -124,7 +159,11 @@ for variant in monitor echo; do - ;; - O) - input_complete=true -- $output_append "$line" -+ $test_json || $output_append "$line" -+ ;; -+ J) -+ input_complete=true -+ $test_json && $output_append "$line" - ;; - '#'|'') - # ignore comments and empty lines -diff --git a/tests/monitor/testcases/object.t b/tests/monitor/testcases/object.t -index 7b88409775796..e9a6d56ac546c 100644 ---- a/tests/monitor/testcases/object.t -+++ b/tests/monitor/testcases/object.t -@@ -1,27 +1,38 @@ - # first the setup - I add table ip t - O - -+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} - - I add counter ip t c - O add counter ip t c { packets 0 bytes 0 } -+J {"add": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0, "packets": 0, "bytes": 0}}} - - I delete counter ip t c - O - -+J {"delete": {"counter": {"family": "ip", "name": "c", "table": "t", "handle": 0, "packets": 0, "bytes": 0}}} - -+# FIXME: input/output shouldn't be asynchronous here - I add quota ip t q 25 mbytes - O add quota ip t q { 25 mbytes } -+J {"add": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0, "bytes": 26214400, "used": 0, "inv": false}}} - - I delete quota ip t q - O - -+J {"delete": {"quota": {"family": "ip", "name": "q", "table": "t", "handle": 0, "bytes": 26214400, "used": 0, "inv": false}}} - -+# FIXME: input/output shouldn't be asynchronous here - I add limit ip t l rate 1/second - O add limit ip t l { rate 1/second } -+J {"add": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0, "rate": 1, "per": "second", "burst": 5}}} - - I delete limit ip t l - O - -+J {"delete": {"limit": {"family": "ip", "name": "l", "table": "t", "handle": 0, "rate": 1, "per": "second", "burst": 5}}} - - I add ct helper ip t cth { type "sip" protocol tcp; l3proto ip; } - O - -+J {"add": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle": 0, "type": "sip", "protocol": "tcp", "l3proto": "ip"}}} - - I delete ct helper ip t cth - O - -+J {"delete": {"ct helper": {"family": "ip", "name": "cth", "table": "t", "handle": 0, "type": "sip", "protocol": "tcp", "l3proto": "ip"}}} -diff --git a/tests/monitor/testcases/set-maps.t b/tests/monitor/testcases/set-maps.t -index 3d86720ec8136..acda480d86dbb 100644 ---- a/tests/monitor/testcases/set-maps.t -+++ b/tests/monitor/testcases/set-maps.t -@@ -2,9 +2,13 @@ - I add table ip t - I add map ip t portip { type inet_service: ipv4_addr; flags interval; } - O - -+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} -+J {"add": {"map": {"family": "ip", "name": "portip", "table": "t", "type": "inet_service", "handle": 0, "map": "ipv4_addr", "flags": ["interval"]}}} - - I add element ip t portip { 80-100: 10.0.0.1 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portip", "elem": {"set": [[{"range": [80, 100]}, "10.0.0.1"]]}}}} - - I add element ip t portip { 1024-65535: 10.0.0.1 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portip", "elem": {"set": [[{"range": [1024, 65535]}, "10.0.0.1"]]}}}} -diff --git a/tests/monitor/testcases/set-mixed.t b/tests/monitor/testcases/set-mixed.t -index 9c1c5323f2e4e..08c20116de92f 100644 ---- a/tests/monitor/testcases/set-mixed.t -+++ b/tests/monitor/testcases/set-mixed.t -@@ -3,13 +3,20 @@ I add table ip t - I add set ip t portrange { type inet_service; flags interval; } - I add set ip t ports { type inet_service; } - O - -+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} -+J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}} -+J {"add": {"set": {"family": "ip", "name": "ports", "table": "t", "type": "inet_service", "handle": 0}}} - - # make sure concurrent adds work - I add element ip t portrange { 1024-65535 } - I add element ip t ports { 10 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} -+J {"add": {"element": {"family": "ip", "table": "t", "name": "ports", "elem": {"set": [10]}}}} - - # delete items again - I delete element ip t portrange { 1024-65535 } - I delete element ip t ports { 10 } - O - -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "ports", "elem": {"set": [10]}}}} -diff --git a/tests/monitor/testcases/set-multiple.t b/tests/monitor/testcases/set-multiple.t -index ad91fac047fe8..bd7a6246a46b4 100644 ---- a/tests/monitor/testcases/set-multiple.t -+++ b/tests/monitor/testcases/set-multiple.t -@@ -3,8 +3,13 @@ I add table ip t - I add set ip t portrange { type inet_service; flags interval; } - I add set ip t portrange2 { type inet_service; flags interval; } - O - -+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} -+J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}} -+J {"add": {"set": {"family": "ip", "name": "portrange2", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}} - - # make sure concurrent adds work - I add element ip t portrange { 1024-65535 } - I add element ip t portrange2 { 10-20 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange2", "elem": {"set": [{"range": [10, 20]}]}}}} -diff --git a/tests/monitor/testcases/set-simple.t b/tests/monitor/testcases/set-simple.t -index ebff7cbda0c8b..8ca4f32463fd7 100644 ---- a/tests/monitor/testcases/set-simple.t -+++ b/tests/monitor/testcases/set-simple.t -@@ -2,15 +2,21 @@ - I add table ip t - I add set ip t portrange { type inet_service; flags interval; } - O - -+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} -+J {"add": {"set": {"family": "ip", "name": "portrange", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}} - - # adding some ranges - I add element ip t portrange { 1-10 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1, 10]}]}}}} - I add element ip t portrange { 1024-65535 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} - I add element ip t portrange { 20-30, 40-50 } - O add element ip t portrange { 20-30 } - O add element ip t portrange { 40-50 } -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [20, 30]}]}}}} -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [40, 50]}]}}}} - - # test flushing -> elements are removed in reverse - I flush set ip t portrange -@@ -18,25 +24,38 @@ O delete element ip t portrange { 1024-65535 } - O delete element ip t portrange { 40-50 } - O delete element ip t portrange { 20-30 } - O delete element ip t portrange { 1-10 } -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [40, 50]}]}}}} -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [20, 30]}]}}}} -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1, 10]}]}}}} - - # make sure lower scope boundary works - I add element ip t portrange { 0-10 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [0, 10]}]}}}} - - # make sure half open before other element works - I add element ip t portrange { 1024-65535 } - I add element ip t portrange { 100-200 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [100, 200]}]}}}} - - # make sure deletion of elements works - I delete element ip t portrange { 0-10 } - O - -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [0, 10]}]}}}} - I delete element ip t portrange { 100-200 } - I delete element ip t portrange { 1024-65535 } - O - -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [100, 200]}]}}}} -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} - - # make sure mixed add/delete works - I add element ip t portrange { 10-20 } - I add element ip t portrange { 1024-65535 } - I delete element ip t portrange { 10-20 } - O - -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [10, 20]}]}}}} -+J {"add": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [1024, 65535]}]}}}} -+J {"delete": {"element": {"family": "ip", "table": "t", "name": "portrange", "elem": {"set": [{"range": [10, 20]}]}}}} -diff --git a/tests/monitor/testcases/simple.t b/tests/monitor/testcases/simple.t -index e4dc073e14b65..78d8f8b04bd36 100644 ---- a/tests/monitor/testcases/simple.t -+++ b/tests/monitor/testcases/simple.t -@@ -2,19 +2,27 @@ - I add table ip t - I add chain ip t c - O - -+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} -+J {"add": {"chain": {"family": "ip", "table": "t", "name": "c", "handle": 0}}} - - I add rule ip t c accept - O - -+J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"accept": null}]}}} - - I add rule ip t c tcp dport { 22, 80, 443 } accept - O - -+J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": {"set": [22, 80, 443]}}}, {"accept": null}]}}} - - I insert rule ip t c counter accept - O add rule ip t c counter packets 0 bytes 0 accept -+J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"counter": {"packets": 0, "bytes": 0}}, {"accept": null}]}}} - - I replace rule ip t c handle 2 accept comment "foo bar" - O delete rule ip t c handle 2 - O add rule ip t c accept comment "foo bar" -+J {"delete": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"accept": null}]}}} -+J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "comment": "foo bar", "expr": [{"accept": null}]}}} - - I add counter ip t cnt - O add counter ip t cnt { packets 0 bytes 0 } -+J {"add": {"counter": {"family": "ip", "name": "cnt", "table": "t", "handle": 0, "packets": 0, "bytes": 0}}} --- -2.21.0 - diff --git a/SOURCES/0006-tests-shell-Search-diff-tool-once-and-for-all.patch b/SOURCES/0006-tests-shell-Search-diff-tool-once-and-for-all.patch new file mode 100644 index 0000000..e6adbfc --- /dev/null +++ b/SOURCES/0006-tests-shell-Search-diff-tool-once-and-for-all.patch @@ -0,0 +1,573 @@ +From 8537751e48dfacee11d48ad3f050bdacc930284c Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 17 Jan 2020 12:50:23 +0100 +Subject: [PATCH] tests: shell: Search diff tool once and for all + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1790793 +Upstream Status: nftables commit 68310ba0f9c20 + +commit 68310ba0f9c2066f7463d66a1a1938b66fb8a4c4 +Author: Phil Sutter +Date: Tue Jan 14 16:50:35 2020 +0100 + + tests: shell: Search diff tool once and for all + + Instead of calling 'which diff' over and over again, just detect the + tool's presence in run-tests.sh and pass $DIFF to each testcase just + like with nft binary. + + Fall back to using 'true' command to avoid the need for any conditional + calling in test cases. + + While being at it, unify potential diff calls so that a string + comparison in shell happens irrespective of diff presence. + + Signed-off-by: Phil Sutter + Acked-by: Pablo Neira Ayuso +--- + tests/shell/run-tests.sh | 7 ++++++- + tests/shell/testcases/flowtable/0010delete_handle_0 | 3 +-- + tests/shell/testcases/listing/0003table_0 | 6 ++---- + tests/shell/testcases/listing/0004table_0 | 3 +-- + tests/shell/testcases/listing/0005ruleset_ip_0 | 3 +-- + tests/shell/testcases/listing/0006ruleset_ip6_0 | 3 +-- + tests/shell/testcases/listing/0007ruleset_inet_0 | 3 +-- + tests/shell/testcases/listing/0008ruleset_arp_0 | 3 +-- + tests/shell/testcases/listing/0009ruleset_bridge_0 | 3 +-- + tests/shell/testcases/listing/0010sets_0 | 3 +-- + tests/shell/testcases/listing/0011sets_0 | 3 +-- + tests/shell/testcases/listing/0012sets_0 | 3 +-- + tests/shell/testcases/listing/0013objects_0 | 3 +-- + tests/shell/testcases/listing/0014objects_0 | 6 ++---- + tests/shell/testcases/listing/0015dynamic_0 | 3 +-- + tests/shell/testcases/listing/0017objects_0 | 3 +-- + tests/shell/testcases/listing/0018data_0 | 3 +-- + tests/shell/testcases/listing/0019set_0 | 3 +-- + tests/shell/testcases/listing/0020flowtable_0 | 3 +-- + tests/shell/testcases/maps/0003map_add_many_elements_0 | 3 +-- + tests/shell/testcases/maps/0004interval_map_create_once_0 | 3 +-- + tests/shell/testcases/maps/0008interval_map_delete_0 | 3 +-- + tests/shell/testcases/netns/0001nft-f_0 | 3 +-- + tests/shell/testcases/netns/0002loosecommands_0 | 3 +-- + tests/shell/testcases/netns/0003many_0 | 3 +-- + tests/shell/testcases/nft-f/0016redefines_1 | 3 +-- + tests/shell/testcases/optionals/delete_object_handles_0 | 3 +-- + tests/shell/testcases/optionals/update_object_handles_0 | 3 +-- + .../shell/testcases/rule_management/0001addinsertposition_0 | 12 ++++-------- + tests/shell/testcases/sets/0028delete_handle_0 | 3 +-- + tests/shell/testcases/sets/0036add_set_element_expiration_0 | 5 ++++- + tests/shell/testcases/transactions/0003table_0 | 4 +--- + tests/shell/testcases/transactions/0040set_0 | 3 +-- + 33 files changed, 46 insertions(+), 75 deletions(-) + +diff --git a/tests/shell/run-tests.sh b/tests/shell/run-tests.sh +index 632ccce..29a2c39 100755 +--- a/tests/shell/run-tests.sh ++++ b/tests/shell/run-tests.sh +@@ -43,6 +43,11 @@ if [ ! -x "$MODPROBE" ] ; then + msg_error "no modprobe binary found" + fi + ++DIFF="$(which diff)" ++if [ ! -x "$DIFF" ] ; then ++ DIFF=true ++fi ++ + if [ "$1" == "-v" ] ; then + VERBOSE=y + shift +@@ -96,7 +101,7 @@ do + kernel_cleanup + + msg_info "[EXECUTING] $testfile" +- test_output=$(NFT=$NFT ${testfile} 2>&1) ++ test_output=$(NFT=$NFT DIFF=$DIFF ${testfile} 2>&1) + rc_got=$? + echo -en "\033[1A\033[K" # clean the [EXECUTING] foobar line + +diff --git a/tests/shell/testcases/flowtable/0010delete_handle_0 b/tests/shell/testcases/flowtable/0010delete_handle_0 +index 985d4a3..8dd8d9f 100755 +--- a/tests/shell/testcases/flowtable/0010delete_handle_0 ++++ b/tests/shell/testcases/flowtable/0010delete_handle_0 +@@ -16,7 +16,6 @@ EXPECTED="table inet t { + + GET="$($NFT list ruleset)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0003table_0 b/tests/shell/testcases/listing/0003table_0 +index 1b288e4..5060be0 100755 +--- a/tests/shell/testcases/listing/0003table_0 ++++ b/tests/shell/testcases/listing/0003table_0 +@@ -11,15 +11,13 @@ $NFT add table test + + GET="$($NFT list table test)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + + # also this way + GET="$($NFT list table ip test)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0004table_0 b/tests/shell/testcases/listing/0004table_0 +index 2c7c995..1d69119 100755 +--- a/tests/shell/testcases/listing/0004table_0 ++++ b/tests/shell/testcases/listing/0004table_0 +@@ -12,8 +12,7 @@ $NFT add table test2 + + GET="$($NFT list table test)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + +diff --git a/tests/shell/testcases/listing/0005ruleset_ip_0 b/tests/shell/testcases/listing/0005ruleset_ip_0 +index c326680..39c0328 100755 +--- a/tests/shell/testcases/listing/0005ruleset_ip_0 ++++ b/tests/shell/testcases/listing/0005ruleset_ip_0 +@@ -15,7 +15,6 @@ $NFT add table bridge test + + GET="$($NFT list ruleset ip)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0006ruleset_ip6_0 b/tests/shell/testcases/listing/0006ruleset_ip6_0 +index 093d5a5..1b67f50 100755 +--- a/tests/shell/testcases/listing/0006ruleset_ip6_0 ++++ b/tests/shell/testcases/listing/0006ruleset_ip6_0 +@@ -15,7 +15,6 @@ $NFT add table bridge test + + GET="$($NFT list ruleset ip6)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0007ruleset_inet_0 b/tests/shell/testcases/listing/0007ruleset_inet_0 +index b24cc4c..257c7a9 100755 +--- a/tests/shell/testcases/listing/0007ruleset_inet_0 ++++ b/tests/shell/testcases/listing/0007ruleset_inet_0 +@@ -15,7 +15,6 @@ $NFT add table bridge test + + GET="$($NFT list ruleset inet)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0008ruleset_arp_0 b/tests/shell/testcases/listing/0008ruleset_arp_0 +index fff0fee..be42c47 100755 +--- a/tests/shell/testcases/listing/0008ruleset_arp_0 ++++ b/tests/shell/testcases/listing/0008ruleset_arp_0 +@@ -15,7 +15,6 @@ $NFT add table bridge test + + GET="$($NFT list ruleset arp)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0009ruleset_bridge_0 b/tests/shell/testcases/listing/0009ruleset_bridge_0 +index 247ed47..c6a99f5 100755 +--- a/tests/shell/testcases/listing/0009ruleset_bridge_0 ++++ b/tests/shell/testcases/listing/0009ruleset_bridge_0 +@@ -15,7 +15,6 @@ $NFT add table bridge test + + GET="$($NFT list ruleset bridge)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0010sets_0 b/tests/shell/testcases/listing/0010sets_0 +index 855cceb..0f5f2bd 100755 +--- a/tests/shell/testcases/listing/0010sets_0 ++++ b/tests/shell/testcases/listing/0010sets_0 +@@ -57,7 +57,6 @@ $NFT add set inet filter set2 { type icmpv6_type \; } + + GET="$($NFT list sets)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0011sets_0 b/tests/shell/testcases/listing/0011sets_0 +index aac9eac..b6f12b5 100755 +--- a/tests/shell/testcases/listing/0011sets_0 ++++ b/tests/shell/testcases/listing/0011sets_0 +@@ -38,7 +38,6 @@ $NFT add rule inet filter test tcp dport {80, 443} + GET="$($NFT list sets)" + + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0012sets_0 b/tests/shell/testcases/listing/0012sets_0 +index da16d94..6e4c959 100755 +--- a/tests/shell/testcases/listing/0012sets_0 ++++ b/tests/shell/testcases/listing/0012sets_0 +@@ -33,7 +33,6 @@ $NFT add set inet filter set2 { type icmpv6_type \; } + + GET="$($NFT list sets inet)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0013objects_0 b/tests/shell/testcases/listing/0013objects_0 +index f691579..4d39143 100755 +--- a/tests/shell/testcases/listing/0013objects_0 ++++ b/tests/shell/testcases/listing/0013objects_0 +@@ -42,7 +42,6 @@ $NFT add table test-ip + + GET="$($NFT list table test)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0014objects_0 b/tests/shell/testcases/listing/0014objects_0 +index 20f6840..31d94f8 100755 +--- a/tests/shell/testcases/listing/0014objects_0 ++++ b/tests/shell/testcases/listing/0014objects_0 +@@ -17,15 +17,13 @@ $NFT add table test-ip + + GET="$($NFT list quotas)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + + GET="$($NFT list quota test https-quota)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + +diff --git a/tests/shell/testcases/listing/0015dynamic_0 b/tests/shell/testcases/listing/0015dynamic_0 +index 4ff74e3..65fbe62 100755 +--- a/tests/shell/testcases/listing/0015dynamic_0 ++++ b/tests/shell/testcases/listing/0015dynamic_0 +@@ -16,8 +16,7 @@ $NFT -f - <<< "$EXPECTED" + + GET="$($NFT list set ip filter test_set)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + +diff --git a/tests/shell/testcases/listing/0017objects_0 b/tests/shell/testcases/listing/0017objects_0 +index 8a586e8..c4e72db 100755 +--- a/tests/shell/testcases/listing/0017objects_0 ++++ b/tests/shell/testcases/listing/0017objects_0 +@@ -13,7 +13,6 @@ $NFT flush map inet filter countermap + + GET="$($NFT list map inet filter countermap)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0018data_0 b/tests/shell/testcases/listing/0018data_0 +index 544b6bf..4af253d 100755 +--- a/tests/shell/testcases/listing/0018data_0 ++++ b/tests/shell/testcases/listing/0018data_0 +@@ -13,7 +13,6 @@ $NFT flush map inet filter ipmap + + GET="$($NFT list map inet filter ipmap)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0019set_0 b/tests/shell/testcases/listing/0019set_0 +index 54a8a06..6e8cb4d 100755 +--- a/tests/shell/testcases/listing/0019set_0 ++++ b/tests/shell/testcases/listing/0019set_0 +@@ -13,7 +13,6 @@ $NFT flush set inet filter ipset + + GET="$($NFT list set inet filter ipset)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/listing/0020flowtable_0 b/tests/shell/testcases/listing/0020flowtable_0 +index 6f630f1..2f0a98d 100755 +--- a/tests/shell/testcases/listing/0020flowtable_0 ++++ b/tests/shell/testcases/listing/0020flowtable_0 +@@ -15,7 +15,6 @@ $NFT -f - <<< "$EXPECTED" + + GET="$($NFT list flowtable inet filter f)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/maps/0003map_add_many_elements_0 b/tests/shell/testcases/maps/0003map_add_many_elements_0 +index 047f949..2b254c5 100755 +--- a/tests/shell/testcases/maps/0003map_add_many_elements_0 ++++ b/tests/shell/testcases/maps/0003map_add_many_elements_0 +@@ -61,8 +61,7 @@ EXPECTED="table ip x { + }" + GET=$($NFT list ruleset) + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + +diff --git a/tests/shell/testcases/maps/0004interval_map_create_once_0 b/tests/shell/testcases/maps/0004interval_map_create_once_0 +index 58b399c..3de0c9d 100755 +--- a/tests/shell/testcases/maps/0004interval_map_create_once_0 ++++ b/tests/shell/testcases/maps/0004interval_map_create_once_0 +@@ -60,8 +60,7 @@ EXPECTED="table ip x { + }" + GET=$($NFT list ruleset) + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + +diff --git a/tests/shell/testcases/maps/0008interval_map_delete_0 b/tests/shell/testcases/maps/0008interval_map_delete_0 +index 7da6eb3..39ea312 100755 +--- a/tests/shell/testcases/maps/0008interval_map_delete_0 ++++ b/tests/shell/testcases/maps/0008interval_map_delete_0 +@@ -26,7 +26,6 @@ $NFT add element filter m { 127.0.0.2 : 0x2 } + + GET=$($NFT -s list ruleset) + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/netns/0001nft-f_0 b/tests/shell/testcases/netns/0001nft-f_0 +index 8194226..a591f2c 100755 +--- a/tests/shell/testcases/netns/0001nft-f_0 ++++ b/tests/shell/testcases/netns/0001nft-f_0 +@@ -93,8 +93,7 @@ fi + KERNEL_RULESET="$($IP netns exec $NETNS_NAME $NFT list ruleset)" + $IP netns del $NETNS_NAME + if [ "$RULESET" != "$KERNEL_RULESET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") ++ $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + exit 1 + fi + exit 0 +diff --git a/tests/shell/testcases/netns/0002loosecommands_0 b/tests/shell/testcases/netns/0002loosecommands_0 +index 465c2e8..231f1fb 100755 +--- a/tests/shell/testcases/netns/0002loosecommands_0 ++++ b/tests/shell/testcases/netns/0002loosecommands_0 +@@ -56,7 +56,6 @@ RULESET="table ip t { + KERNEL_RULESET="$($IP netns exec $NETNS_NAME $NFT list ruleset)" + $IP netns del $NETNS_NAME + if [ "$RULESET" != "$KERNEL_RULESET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") ++ $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + exit 1 + fi +diff --git a/tests/shell/testcases/netns/0003many_0 b/tests/shell/testcases/netns/0003many_0 +index a5fcb5d..afe9117 100755 +--- a/tests/shell/testcases/netns/0003many_0 ++++ b/tests/shell/testcases/netns/0003many_0 +@@ -97,8 +97,7 @@ function test_netns() + KERNEL_RULESET="$($IP netns exec $NETNS_NAME $NFT list ruleset)" + if [ "$RULESET" != "$KERNEL_RULESET" ] ; then + echo "E: ruleset in netns $NETNS_NAME differs from the loaded" >&2 +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") ++ $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + $IP netns del $NETNS_NAME + exit 1 + fi +diff --git a/tests/shell/testcases/nft-f/0016redefines_1 b/tests/shell/testcases/nft-f/0016redefines_1 +index 4c26b37..1f59f6b 100755 +--- a/tests/shell/testcases/nft-f/0016redefines_1 ++++ b/tests/shell/testcases/nft-f/0016redefines_1 +@@ -26,8 +26,7 @@ $NFT -f - <<< "$RULESET" + GET="$($NFT list ruleset)" + + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + +diff --git a/tests/shell/testcases/optionals/delete_object_handles_0 b/tests/shell/testcases/optionals/delete_object_handles_0 +index a2ae422..9b65e67 100755 +--- a/tests/shell/testcases/optionals/delete_object_handles_0 ++++ b/tests/shell/testcases/optionals/delete_object_handles_0 +@@ -37,7 +37,6 @@ table ip6 test-ip6 { + GET="$($NFT list ruleset)" + + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/optionals/update_object_handles_0 b/tests/shell/testcases/optionals/update_object_handles_0 +index 17c0c86..8b12b8c 100755 +--- a/tests/shell/testcases/optionals/update_object_handles_0 ++++ b/tests/shell/testcases/optionals/update_object_handles_0 +@@ -19,7 +19,6 @@ EXPECTED="table ip test-ip { + + GET="$($NFT list ruleset)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/rule_management/0001addinsertposition_0 b/tests/shell/testcases/rule_management/0001addinsertposition_0 +index bb3fda5..237e9e3 100755 +--- a/tests/shell/testcases/rule_management/0001addinsertposition_0 ++++ b/tests/shell/testcases/rule_management/0001addinsertposition_0 +@@ -30,8 +30,7 @@ for arg in "position 2" "handle 2" "index 0"; do + + GET="$($NFT list ruleset)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + done +@@ -42,8 +41,7 @@ for arg in "position 3" "handle 3" "index 1"; do + + GET="$($NFT list ruleset)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + done +@@ -62,8 +60,7 @@ for arg in "position 3" "handle 3" "index 1"; do + + GET="$($NFT list ruleset)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + done +@@ -82,8 +79,7 @@ for arg in "position 2" "handle 2" "index 0"; do + + GET="$($NFT list ruleset)" + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi + done +diff --git a/tests/shell/testcases/sets/0028delete_handle_0 b/tests/shell/testcases/sets/0028delete_handle_0 +index 5ad17c2..c6d1253 100755 +--- a/tests/shell/testcases/sets/0028delete_handle_0 ++++ b/tests/shell/testcases/sets/0028delete_handle_0 +@@ -29,7 +29,6 @@ EXPECTED="table ip test-ip { + GET="$($NFT list ruleset)" + + if [ "$EXPECTED" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + exit 1 + fi +diff --git a/tests/shell/testcases/sets/0036add_set_element_expiration_0 b/tests/shell/testcases/sets/0036add_set_element_expiration_0 +index 8dfed6c..51ed0f2 100755 +--- a/tests/shell/testcases/sets/0036add_set_element_expiration_0 ++++ b/tests/shell/testcases/sets/0036add_set_element_expiration_0 +@@ -8,6 +8,9 @@ add element ip x y { 1.1.1.1 timeout 30s expires 15s }" + + test_output=$($NFT -e -f - <<< "$RULESET" 2>&1) + +-diff -u <(echo "$test_output") <(echo "$RULESET") ++if [ "$test_output" != "$RULESET" ] ; then ++ $DIFF -u <(echo "$test_output") <(echo "$RULESET") ++ exit 1 ++fi + + $NFT "add chain ip x c; add rule ip x c ip saddr @y" +diff --git a/tests/shell/testcases/transactions/0003table_0 b/tests/shell/testcases/transactions/0003table_0 +index 6861eab..91186de 100755 +--- a/tests/shell/testcases/transactions/0003table_0 ++++ b/tests/shell/testcases/transactions/0003table_0 +@@ -14,7 +14,6 @@ fi + + KERNEL_RULESET="$($NFT list ruleset)" + if [ "" != "$KERNEL_RULESET" ] ; then +- DIFF="$(which diff)" + echo "Got a ruleset, but expected empty: " + echo "$KERNEL_RULESET" + exit 1 +@@ -42,7 +41,6 @@ $NFT -f - <<< "$RULESETFAIL" && exit 2 + + KERNEL_RULESET="$($NFT list ruleset)" + if [ "$RULESET" != "$KERNEL_RULESET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") ++ $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + exit 1 + fi +diff --git a/tests/shell/testcases/transactions/0040set_0 b/tests/shell/testcases/transactions/0040set_0 +index a404abc..468816b 100755 +--- a/tests/shell/testcases/transactions/0040set_0 ++++ b/tests/shell/testcases/transactions/0040set_0 +@@ -29,8 +29,7 @@ fi + GET="$($NFT list ruleset)" + + if [ "$RULESET" != "$GET" ] ; then +- DIFF="$(which diff)" +- [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$GET") ++ $DIFF -u <(echo "$RULESET") <(echo "$GET") + exit 1 + fi + +-- +1.8.3.1 + diff --git a/SOURCES/0007-cache-Fix-for-doubled-output-after-reset-command.patch b/SOURCES/0007-cache-Fix-for-doubled-output-after-reset-command.patch new file mode 100644 index 0000000..b1aba78 --- /dev/null +++ b/SOURCES/0007-cache-Fix-for-doubled-output-after-reset-command.patch @@ -0,0 +1,85 @@ +From a44bd9f4b6cf77cb75c5f596908100270893e8d5 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 17 Jan 2020 12:50:23 +0100 +Subject: [PATCH] cache: Fix for doubled output after reset command + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1790793 +Upstream Status: nftables commit 7def18395d118 + +commit 7def18395d118e22a009de7e2e8de7f77906580b +Author: Phil Sutter +Date: Tue Jan 14 17:25:35 2020 +0100 + + cache: Fix for doubled output after reset command + + Reset command causes a dump of the objects to reset and adds those to + cache. Yet it ignored if the object in question was already there and up + to now CMD_RESET was flagged as NFT_CACHE_FULL. + + Tackle this from two angles: First, reduce cache requirements of reset + command to the necessary bits which is table cache. This alone would + suffice if there wasn't interactive mode (and other libnftables users): + A cache containing the objects to reset might be in place already, so + add dumped objects to cache only if they don't exist already. + + Signed-off-by: Phil Sutter + Acked-by: Pablo Neira Ayuso +--- + src/cache.c | 4 +++- + src/rule.c | 3 ++- + tests/shell/testcases/sets/0024named_objects_0 | 12 +++++++++++- + 3 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/src/cache.c b/src/cache.c +index 0c28a28..05f0d68 100644 +--- a/src/cache.c ++++ b/src/cache.c +@@ -138,8 +138,10 @@ unsigned int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds) + case CMD_GET: + flags = evaluate_cache_get(cmd, flags); + break; +- case CMD_LIST: + case CMD_RESET: ++ flags |= NFT_CACHE_TABLE; ++ break; ++ case CMD_LIST: + case CMD_EXPORT: + case CMD_MONITOR: + flags |= NFT_CACHE_FULL; +diff --git a/src/rule.c b/src/rule.c +index d985d3a..3ca1805 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -2554,7 +2554,8 @@ static int do_command_reset(struct netlink_ctx *ctx, struct cmd *cmd) + ret = netlink_reset_objs(ctx, cmd, type, dump); + list_for_each_entry_safe(obj, next, &ctx->list, list) { + table = table_lookup(&obj->handle, &ctx->nft->cache); +- list_move(&obj->list, &table->objs); ++ if (!obj_lookup(table, obj->handle.obj.name, obj->type)) ++ list_move(&obj->list, &table->objs); + } + if (ret < 0) + return ret; +diff --git a/tests/shell/testcases/sets/0024named_objects_0 b/tests/shell/testcases/sets/0024named_objects_0 +index 3bd16f2..21200c3 100755 +--- a/tests/shell/testcases/sets/0024named_objects_0 ++++ b/tests/shell/testcases/sets/0024named_objects_0 +@@ -35,4 +35,14 @@ table inet x { + set -e + $NFT -f - <<< "$RULESET" + +-$NFT reset counter inet x user321 ++EXPECTED="table inet x { ++ counter user321 { ++ packets 12 bytes 1433 ++ } ++}" ++ ++GET="$($NFT reset counter inet x user321)" ++if [ "$EXPECTED" != "$GET" ] ; then ++ $DIFF -u <(echo "$EXPECTED") <(echo "$GET") ++ exit 1 ++fi +-- +1.8.3.1 + diff --git a/SOURCES/0007-segtree-bogus-range-via-get-set-element-on-existing-.patch b/SOURCES/0007-segtree-bogus-range-via-get-set-element-on-existing-.patch deleted file mode 100644 index 2b0e0e9..0000000 --- a/SOURCES/0007-segtree-bogus-range-via-get-set-element-on-existing-.patch +++ /dev/null @@ -1,148 +0,0 @@ -From 0a9ad3152c4e4678c94502441f5b002fef4fbff2 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 1 Oct 2018 14:51:24 +0200 -Subject: [PATCH] segtree: bogus range via get set element on existing elements - - table ip x { - set y { - type inet_service - flags interval - elements = { 10, 20-30, 40, 50-60 } - } - } - - # nft get element x y { 20-40 } - table ip x { - set y { - type inet_service - flags interval - elements = { 20-40 } - } - } - -20 and 40 exist in the tree, but they are part of different ranges. -This patch adds a new get_set_decompose() function to validate that the -left and the right side of the range. - -Reported-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 95629758a5ec36313d839f8545fef0dc220408d8) -Signed-off-by: Phil Sutter ---- - include/expression.h | 2 +- - src/netlink.c | 5 +++-- - src/segtree.c | 48 ++++++++++++++++++++++++++++++++++++++++++-- - 3 files changed, 50 insertions(+), 5 deletions(-) - -diff --git a/include/expression.h b/include/expression.h -index 2bb51e531ecbe..885e9c43bb77f 100644 ---- a/include/expression.h -+++ b/include/expression.h -@@ -442,7 +442,7 @@ extern void interval_map_decompose(struct expr *set); - extern struct expr *get_set_intervals(const struct set *set, - const struct expr *init); - struct table; --extern void get_set_decompose(struct table *table, struct set *set); -+extern int get_set_decompose(struct table *table, struct set *set); - - extern struct expr *mapping_expr_alloc(const struct location *loc, - struct expr *from, struct expr *to); -diff --git a/src/netlink.c b/src/netlink.c -index 864947b4d2f07..ca5e9b4a0f8a6 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -1353,8 +1353,9 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, - nftnl_set_free(nls_out); - ctx->set = NULL; - -- if (set->flags & NFT_SET_INTERVAL) -- get_set_decompose(table, set); -+ if (set->flags & NFT_SET_INTERVAL && -+ get_set_decompose(table, set) < 0) -+ return -1; - - return 0; - } -diff --git a/src/segtree.c b/src/segtree.c -index 8a8aa71e8a6e2..288b01f420a48 100644 ---- a/src/segtree.c -+++ b/src/segtree.c -@@ -641,6 +641,42 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init) - return new_init; - } - -+static struct expr *get_set_interval_find(const struct table *table, -+ const char *set_name, -+ struct expr *left, -+ struct expr *right) -+{ -+ struct expr *range = NULL; -+ struct set *set; -+ mpz_t low, high; -+ struct expr *i; -+ -+ set = set_lookup(table, set_name); -+ mpz_init2(low, set->key->len); -+ mpz_init2(high, set->key->len); -+ -+ list_for_each_entry(i, &set->init->expressions, list) { -+ switch (i->key->ops->type) { -+ case EXPR_RANGE: -+ range_expr_value_low(low, i); -+ range_expr_value_high(high, i); -+ if (mpz_cmp(left->key->value, low) >= 0 && -+ mpz_cmp(right->key->value, high) <= 0) -+ range = range_expr_alloc(&internal_location, -+ expr_clone(left->key), -+ expr_clone(right->key)); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ mpz_clear(low); -+ mpz_clear(high); -+ -+ return range; -+} -+ - static struct expr *get_set_interval_end(const struct table *table, - const char *set_name, - struct expr *left) -@@ -675,7 +711,7 @@ static struct expr *get_set_interval_end(const struct table *table, - return left; - } - --void get_set_decompose(struct table *table, struct set *set) -+int get_set_decompose(struct table *table, struct set *set) - { - struct expr *i, *next, *new; - struct expr *left = NULL; -@@ -688,7 +724,13 @@ void get_set_decompose(struct table *table, struct set *set) - list_del(&left->list); - list_del(&i->list); - mpz_sub_ui(i->key->value, i->key->value, 1); -- new = range_expr_alloc(&internal_location, left, i); -+ new = get_set_interval_find(table, set->handle.set.name, -+ left, i); -+ if (!new) { -+ errno = ENOENT; -+ return -1; -+ } -+ - compound_expr_add(new_init, new); - left = NULL; - } else { -@@ -707,6 +749,8 @@ void get_set_decompose(struct table *table, struct set *set) - } - - set->init = new_init; -+ -+ return 0; - } - - static bool range_is_prefix(const mpz_t range) --- -2.21.0 - diff --git a/SOURCES/0008-netlink-Fix-leak-in-unterminated-string-deserializer.patch b/SOURCES/0008-netlink-Fix-leak-in-unterminated-string-deserializer.patch new file mode 100644 index 0000000..b15c611 --- /dev/null +++ b/SOURCES/0008-netlink-Fix-leak-in-unterminated-string-deserializer.patch @@ -0,0 +1,51 @@ +From cc70f19e588a0a33ed86c4a059b56a8f5b0c7a82 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 27 Jan 2020 16:11:41 +0100 +Subject: [PATCH] netlink: Fix leak in unterminated string deserializer + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1793030 +Upstream Status: nftables commit c3f6be3f2dced + +commit c3f6be3f2dcedf6d79751c0b975315ebc3184364 +Author: Phil Sutter +Date: Mon Jan 20 13:52:10 2020 +0100 + + netlink: Fix leak in unterminated string deserializer + + Allocated 'mask' expression is not freed before returning to caller, + although it is used temporarily only. + + Fixes: b851ba4731d9f ("src: add interface wildcard matching") + Signed-off-by: Phil Sutter + Acked-by: Pablo Neira Ayuso +--- + src/netlink_delinearize.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c +index 154353b..06a0312 100644 +--- a/src/netlink_delinearize.c ++++ b/src/netlink_delinearize.c +@@ -2030,7 +2030,7 @@ static bool __expr_postprocess_string(struct expr **exprp) + + static struct expr *expr_postprocess_string(struct expr *expr) + { +- struct expr *mask; ++ struct expr *mask, *out; + + assert(expr_basetype(expr)->type == TYPE_STRING); + if (__expr_postprocess_string(&expr)) +@@ -2040,7 +2040,9 @@ static struct expr *expr_postprocess_string(struct expr *expr) + BYTEORDER_HOST_ENDIAN, + expr->len + BITS_PER_BYTE, NULL); + mpz_init_bitmask(mask->value, expr->len); +- return string_wildcard_expr_alloc(&expr->location, mask, expr); ++ out = string_wildcard_expr_alloc(&expr->location, mask, expr); ++ expr_free(mask); ++ return out; + } + + static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) +-- +1.8.3.1 + diff --git a/SOURCES/0008-segtree-disantangle-get_set_interval_end.patch b/SOURCES/0008-segtree-disantangle-get_set_interval_end.patch deleted file mode 100644 index 5b84089..0000000 --- a/SOURCES/0008-segtree-disantangle-get_set_interval_end.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 40edcc35cbfca22d4cb471464eacc12cf7c5c28a Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 3 Oct 2018 12:09:09 +0200 -Subject: [PATCH] segtree: disantangle get_set_interval_end() - -This function overrides the left pointer. Instead update this function -to return the range that we found to enclose the left element. Note that -we may not find a closing right element - therefore, it is a standalone -element - in that case this function returns NULL. - -Reported-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 33eb4594a1c764776a46b48bc1a7d726b561359d) -Signed-off-by: Phil Sutter ---- - src/segtree.c | 37 ++++++++++++++++++++++--------------- - 1 file changed, 22 insertions(+), 15 deletions(-) - -diff --git a/src/segtree.c b/src/segtree.c -index 288b01f420a48..0d53c83fd837e 100644 ---- a/src/segtree.c -+++ b/src/segtree.c -@@ -681,9 +681,9 @@ static struct expr *get_set_interval_end(const struct table *table, - const char *set_name, - struct expr *left) - { -+ struct expr *i, *range = NULL; - struct set *set; - mpz_t low, high; -- struct expr *i; - - set = set_lookup(table, set_name); - mpz_init2(low, set->key->len); -@@ -694,9 +694,9 @@ static struct expr *get_set_interval_end(const struct table *table, - case EXPR_RANGE: - range_expr_value_low(low, i); - if (mpz_cmp(low, left->key->value) == 0) { -- left = range_expr_alloc(&internal_location, -- expr_clone(left->key), -- expr_clone(i->key->right)); -+ range = range_expr_alloc(&internal_location, -+ expr_clone(left->key), -+ expr_clone(i->key->right)); - break; - } - break; -@@ -708,12 +708,12 @@ static struct expr *get_set_interval_end(const struct table *table, - mpz_clear(low); - mpz_clear(high); - -- return left; -+ return range; - } - - int get_set_decompose(struct table *table, struct set *set) - { -- struct expr *i, *next, *new; -+ struct expr *i, *next, *range; - struct expr *left = NULL; - struct expr *new_init; - -@@ -724,28 +724,35 @@ int get_set_decompose(struct table *table, struct set *set) - list_del(&left->list); - list_del(&i->list); - mpz_sub_ui(i->key->value, i->key->value, 1); -- new = get_set_interval_find(table, set->handle.set.name, -+ range = get_set_interval_find(table, set->handle.set.name, - left, i); -- if (!new) { -+ if (!range) { - errno = ENOENT; - return -1; - } - -- compound_expr_add(new_init, new); -+ compound_expr_add(new_init, range); - left = NULL; - } else { - if (left) { -- left = get_set_interval_end(table, -- set->handle.set.name, -- left); -- compound_expr_add(new_init, left); -+ range = get_set_interval_end(table, -+ set->handle.set.name, -+ left); -+ if (range) -+ compound_expr_add(new_init, range); -+ else -+ compound_expr_add(new_init, -+ expr_clone(left)); - } - left = i; - } - } - if (left) { -- left = get_set_interval_end(table, set->handle.set.name, left); -- compound_expr_add(new_init, left); -+ range = get_set_interval_end(table, set->handle.set.name, left); -+ if (range) -+ compound_expr_add(new_init, left); -+ else -+ compound_expr_add(new_init, expr_clone(left)); - } - - set->init = new_init; --- -2.21.0 - diff --git a/SOURCES/0009-netlink-Fix-leaks-in-netlink_parse_cmp.patch b/SOURCES/0009-netlink-Fix-leaks-in-netlink_parse_cmp.patch new file mode 100644 index 0000000..46e878c --- /dev/null +++ b/SOURCES/0009-netlink-Fix-leaks-in-netlink_parse_cmp.patch @@ -0,0 +1,75 @@ +From 6ecccc872b9cbed921af10e32d1a628eb6a74c01 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 27 Jan 2020 16:11:41 +0100 +Subject: [PATCH] netlink: Fix leaks in netlink_parse_cmp() + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1793030 +Upstream Status: nftables commit e957bd9f10d5e + +commit e957bd9f10d5e36671a0b0398e2037fc6201275b +Author: Phil Sutter +Date: Mon Jan 20 14:48:26 2020 +0100 + + netlink: Fix leaks in netlink_parse_cmp() + + This fixes several problems at once: + + * Err path would leak expr 'right' in two places and 'left' in one. + * Concat case would leak 'right' by overwriting the pointer. Introduce a + temporary variable to hold the new pointer. + + Fixes: 6377380bc265f ("netlink_delinearize: handle relational and lookup concat expressions") + Signed-off-by: Phil Sutter + Acked-by: Pablo Neira Ayuso +--- + src/netlink_delinearize.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c +index 06a0312..88dbd5a 100644 +--- a/src/netlink_delinearize.c ++++ b/src/netlink_delinearize.c +@@ -274,7 +274,7 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx, + { + struct nft_data_delinearize nld; + enum nft_registers sreg; +- struct expr *expr, *left, *right; ++ struct expr *expr, *left, *right, *tmp; + enum ops op; + + sreg = netlink_parse_register(nle, NFTNL_EXPR_CMP_SREG); +@@ -291,19 +291,26 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx, + + if (left->len > right->len && + expr_basetype(left) != &string_type) { +- return netlink_error(ctx, loc, "Relational expression size mismatch"); ++ netlink_error(ctx, loc, "Relational expression size mismatch"); ++ goto err_free; + } else if (left->len > 0 && left->len < right->len) { + expr_free(left); + left = netlink_parse_concat_expr(ctx, loc, sreg, right->len); + if (left == NULL) +- return; +- right = netlink_parse_concat_data(ctx, loc, sreg, right->len, right); +- if (right == NULL) +- return; ++ goto err_free; ++ tmp = netlink_parse_concat_data(ctx, loc, sreg, right->len, right); ++ if (tmp == NULL) ++ goto err_free; ++ expr_free(right); ++ right = tmp; + } + + expr = relational_expr_alloc(loc, op, left, right); + ctx->stmt = expr_stmt_alloc(loc, expr); ++ return; ++err_free: ++ expr_free(left); ++ expr_free(right); + } + + static void netlink_parse_lookup(struct netlink_parse_ctx *ctx, +-- +1.8.3.1 + diff --git a/SOURCES/0009-segtree-memleak-in-get_set_decompose.patch b/SOURCES/0009-segtree-memleak-in-get_set_decompose.patch deleted file mode 100644 index 0a2eac0..0000000 --- a/SOURCES/0009-segtree-memleak-in-get_set_decompose.patch +++ /dev/null @@ -1,38 +0,0 @@ -From b18f069971e8e5c161e87ad1742b677ee4185bad Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 3 Oct 2018 12:16:40 +0200 -Subject: [PATCH] segtree: memleak in get_set_decompose() - -Release set content on error. Moreover, release input set content in -case we finally manage to decompose it. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit e08c8bbfeda80f3807ce3784558ce1fb6f0d2bc8) -Signed-off-by: Phil Sutter ---- - src/segtree.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/segtree.c b/src/segtree.c -index 0d53c83fd837e..dc2554b72acf3 100644 ---- a/src/segtree.c -+++ b/src/segtree.c -@@ -727,6 +727,7 @@ int get_set_decompose(struct table *table, struct set *set) - range = get_set_interval_find(table, set->handle.set.name, - left, i); - if (!range) { -+ expr_free(new_init); - errno = ENOENT; - return -1; - } -@@ -755,6 +756,7 @@ int get_set_decompose(struct table *table, struct set *set) - compound_expr_add(new_init, expr_clone(left)); - } - -+ expr_free(set->init); - set->init = new_init; - - return 0; --- -2.21.0 - diff --git a/SOURCES/0010-netlink-Avoid-potential-NULL-pointer-deref-in-netlin.patch b/SOURCES/0010-netlink-Avoid-potential-NULL-pointer-deref-in-netlin.patch new file mode 100644 index 0000000..b48f1e6 --- /dev/null +++ b/SOURCES/0010-netlink-Avoid-potential-NULL-pointer-deref-in-netlin.patch @@ -0,0 +1,42 @@ +From 55c537734f476d04c18f67083642b96bbead6219 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 27 Jan 2020 16:11:41 +0100 +Subject: [PATCH] netlink: Avoid potential NULL-pointer deref in + netlink_gen_payload_stmt() + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1793030 +Upstream Status: nftables commit c9ddf0bff363f + +commit c9ddf0bff363fc9101b563b592db600bdf4d65c5 +Author: Phil Sutter +Date: Mon Jan 20 16:32:40 2020 +0100 + + netlink: Avoid potential NULL-pointer deref in netlink_gen_payload_stmt() + + With payload_needs_l4csum_update_pseudohdr() unconditionally + dereferencing passed 'desc' parameter and a previous check for it to be + non-NULL, make sure to call the function only if input is sane. + + Fixes: 68de70f2b3fc6 ("netlink_linearize: fix IPv6 layer 4 checksum mangling") + Signed-off-by: Phil Sutter + Acked-by: Pablo Neira Ayuso +--- + src/netlink_linearize.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c +index 498326d..cb1b7fe 100644 +--- a/src/netlink_linearize.c ++++ b/src/netlink_linearize.c +@@ -941,7 +941,7 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx, + nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_OFFSET, + csum_off / BITS_PER_BYTE); + } +- if (expr->payload.base == PROTO_BASE_NETWORK_HDR && ++ if (expr->payload.base == PROTO_BASE_NETWORK_HDR && desc && + payload_needs_l4csum_update_pseudohdr(expr, desc)) + nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_FLAGS, + NFT_PAYLOAD_L4CSUM_PSEUDOHDR); +-- +1.8.3.1 + diff --git a/SOURCES/0010-segtree-stop-iteration-on-existing-elements-in-case-.patch b/SOURCES/0010-segtree-stop-iteration-on-existing-elements-in-case-.patch deleted file mode 100644 index 5ba7493..0000000 --- a/SOURCES/0010-segtree-stop-iteration-on-existing-elements-in-case-.patch +++ /dev/null @@ -1,60 +0,0 @@ -From d1145542184ec34ce19f383ea3d361d3287651ee Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 3 Oct 2018 16:19:47 +0200 -Subject: [PATCH] segtree: stop iteration on existing elements in case range is - found - -No need to keep iterating once the range object has been allocated. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit a493147e60d350aca4197975281bf2ffe4cd1009) -Signed-off-by: Phil Sutter ---- - src/segtree.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/src/segtree.c b/src/segtree.c -index dc2554b72acf3..dc457d6bc1b7d 100644 ---- a/src/segtree.c -+++ b/src/segtree.c -@@ -661,16 +661,18 @@ static struct expr *get_set_interval_find(const struct table *table, - range_expr_value_low(low, i); - range_expr_value_high(high, i); - if (mpz_cmp(left->key->value, low) >= 0 && -- mpz_cmp(right->key->value, high) <= 0) -+ mpz_cmp(right->key->value, high) <= 0) { - range = range_expr_alloc(&internal_location, - expr_clone(left->key), - expr_clone(right->key)); -+ goto out; -+ } - break; - default: - break; - } - } -- -+out: - mpz_clear(low); - mpz_clear(high); - -@@ -697,14 +699,14 @@ static struct expr *get_set_interval_end(const struct table *table, - range = range_expr_alloc(&internal_location, - expr_clone(left->key), - expr_clone(i->key->right)); -- break; -+ goto out; - } - break; - default: - break; - } - } -- -+out: - mpz_clear(low); - mpz_clear(high); - --- -2.21.0 - diff --git a/SOURCES/0011-segtree-incorrect-handling-of-last-element-in-get_se.patch b/SOURCES/0011-segtree-incorrect-handling-of-last-element-in-get_se.patch deleted file mode 100644 index f64907a..0000000 --- a/SOURCES/0011-segtree-incorrect-handling-of-last-element-in-get_se.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0a80f39e125ba9bb41386607e0db04b271c0bcea Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 10 Oct 2018 15:41:04 +0200 -Subject: [PATCH] segtree: incorrect handling of last element in - get_set_decompose() - -Add range to the list of matching elements. - -Fixes: 95629758a5ec ("segtree: bogus range via get set element on existing elements") -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 98b047f231215817d87a49dfffbe7b4c0dc29b57) -Signed-off-by: Phil Sutter ---- - src/segtree.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/segtree.c b/src/segtree.c -index dc457d6bc1b7d..4ee09884cbde6 100644 ---- a/src/segtree.c -+++ b/src/segtree.c -@@ -753,7 +753,7 @@ int get_set_decompose(struct table *table, struct set *set) - if (left) { - range = get_set_interval_end(table, set->handle.set.name, left); - if (range) -- compound_expr_add(new_init, left); -+ compound_expr_add(new_init, range); - else - compound_expr_add(new_init, expr_clone(left)); - } --- -2.21.0 - diff --git a/SOURCES/0011-tests-json_echo-Fix-for-Python3.patch b/SOURCES/0011-tests-json_echo-Fix-for-Python3.patch new file mode 100644 index 0000000..f907886 --- /dev/null +++ b/SOURCES/0011-tests-json_echo-Fix-for-Python3.patch @@ -0,0 +1,39 @@ +From 04d0d2e685063d422ce73b67eb01d4803100d379 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 22:35:27 +0100 +Subject: [PATCH] tests: json_echo: Fix for Python3 + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1754047 +Upstream Status: nftables commit 582f142b1578b + +commit 582f142b1578b6036707242bfe874bcefc002ac2 +Author: Phil Sutter +Date: Thu Feb 6 01:21:30 2020 +0100 + + tests: json_echo: Fix for Python3 + + The keys() method returns an object which does not support indexing, so + convert it to a list prior to doing so. + + Fixes: a35e3a0cdc63a ("tests: json_echo: convert to py3") + Signed-off-by: Phil Sutter +--- + tests/json_echo/run-test.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tests/json_echo/run-test.py b/tests/json_echo/run-test.py +index a636d5f..fa7d69a 100755 +--- a/tests/json_echo/run-test.py ++++ b/tests/json_echo/run-test.py +@@ -119,7 +119,7 @@ def get_handle(output, search): + else: + data = item + +- k = search.keys()[0] ++ k = list(search.keys())[0] + + if not k in data: + continue +-- +1.8.3.1 + diff --git a/SOURCES/0012-segtree-set-proper-error-cause-on-existing-elements.patch b/SOURCES/0012-segtree-set-proper-error-cause-on-existing-elements.patch deleted file mode 100644 index d7d852d..0000000 --- a/SOURCES/0012-segtree-set-proper-error-cause-on-existing-elements.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 4c211953b1e6290653fa3bb151b85be29d02288f Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 10 Oct 2018 19:19:18 +0200 -Subject: [PATCH] segtree: set proper error cause on existing elements - -Adding new elements result in a confusing "Success" error message. - - # nft add element x y { 0-3 } - [...] - Error: Could not process rule: Success - add element x y { 0-3 } - ^^^^^^^^^^^^^^^^^^^^^^^^ - -after this patch, this reports: - - Error: Could not process rule: File exists - add element x y { 0-3 } - ^^^^^^^^^^^^^^^^^^^^^^^^ - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 8ef0efb97006081e7f6054a950cb3614dd57729f) -Signed-off-by: Phil Sutter ---- - src/segtree.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/segtree.c b/src/segtree.c -index 4ee09884cbde6..5685618b3724a 100644 ---- a/src/segtree.c -+++ b/src/segtree.c -@@ -270,6 +270,7 @@ static int ei_insert(struct list_head *msgs, struct seg_tree *tree, - - return 0; - err: -+ errno = EEXIST; - return expr_binary_error(msgs, lei->expr, new->expr, - "conflicting intervals specified"); - } -@@ -371,6 +372,7 @@ static int set_overlap(struct list_head *msgs, const struct set *set, - - expr_error(msgs, new_intervals[i]->expr, - "interval overlaps with an existing one"); -+ errno = EEXIST; - ret = -1; - goto out; - } --- -2.21.0 - diff --git a/SOURCES/0012-tests-json_echo-Support-testing-host-binaries.patch b/SOURCES/0012-tests-json_echo-Support-testing-host-binaries.patch new file mode 100644 index 0000000..c2958df --- /dev/null +++ b/SOURCES/0012-tests-json_echo-Support-testing-host-binaries.patch @@ -0,0 +1,68 @@ +From 0eb301a3f50fb70cb78d955692f3feea1ad8095e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 22:35:27 +0100 +Subject: [PATCH] tests: json_echo: Support testing host binaries + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1754047 +Upstream Status: nftables commit 106b1f2b93f82 + +commit 106b1f2b93f82784c18dd5e312bbf88e6c02a5b8 +Author: Phil Sutter +Date: Fri Jan 10 11:19:42 2020 +0100 + + tests: json_echo: Support testing host binaries + + Support -H/--host option to use host's libnftables.so.1. Alternatively + users may specify a custom library path via -l/--library option. + + Signed-off-by: Phil Sutter +--- + tests/json_echo/run-test.py | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/tests/json_echo/run-test.py b/tests/json_echo/run-test.py +index fa7d69a..36a377a 100755 +--- a/tests/json_echo/run-test.py ++++ b/tests/json_echo/run-test.py +@@ -4,6 +4,7 @@ from __future__ import print_function + import sys + import os + import json ++import argparse + + TESTS_PATH = os.path.dirname(os.path.abspath(__file__)) + sys.path.insert(0, os.path.join(TESTS_PATH, '../../py/')) +@@ -13,12 +14,26 @@ from nftables import Nftables + # Change working directory to repository root + os.chdir(TESTS_PATH + "/../..") + +-if not os.path.exists('src/.libs/libnftables.so'): +- print("The nftables library does not exist. " +- "You need to build the project.") ++parser = argparse.ArgumentParser(description='Run JSON echo tests') ++parser.add_argument('-H', '--host', action='store_true', ++ help='Run tests against installed libnftables.so.1') ++parser.add_argument('-l', '--library', default=None, ++ help='Path to libntables.so, overrides --host') ++args = parser.parse_args() ++ ++check_lib_path = True ++if args.library is None: ++ if args.host: ++ args.library = 'libnftables.so.1' ++ check_lib_path = False ++ else: ++ args.library = 'src/.libs/libnftables.so.1' ++ ++if check_lib_path and not os.path.exists(args.library): ++ print("Library not found at '%s'." % args.library) + sys.exit(1) + +-nftables = Nftables(sofile = 'src/.libs/libnftables.so') ++nftables = Nftables(sofile = args.library) + nftables.set_echo_output(True) + + # various commands to work with +-- +1.8.3.1 + diff --git a/SOURCES/0013-rule-fix-memleak-in-do_get_setelems.patch b/SOURCES/0013-rule-fix-memleak-in-do_get_setelems.patch deleted file mode 100644 index f203c0a..0000000 --- a/SOURCES/0013-rule-fix-memleak-in-do_get_setelems.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 1c305050b37bef63a255570c27f0eead0cb4b582 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 3 Oct 2018 16:05:32 +0200 -Subject: [PATCH] rule: fix memleak in do_get_setelems() - -Release set and elements in case of error. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 406d17db7e02f78d258edb38ac8571112ef8c767) -Signed-off-by: Phil Sutter ---- - src/rule.c | 8 +++----- - 1 file changed, 3 insertions(+), 5 deletions(-) - -diff --git a/src/rule.c b/src/rule.c -index 3065cc5474bbf..a157ac91683cc 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -1911,17 +1911,15 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, - /* Fetch from kernel the elements that have been requested .*/ - err = netlink_get_setelem(ctx, &cmd->handle, &cmd->location, - table, new_set, init); -- if (err < 0) -- return err; -- -- __do_list_set(ctx, cmd, table, new_set); -+ if (err >= 0) -+ __do_list_set(ctx, cmd, table, new_set); - - if (set->flags & NFT_SET_INTERVAL) - expr_free(init); - - set_free(new_set); - -- return 0; -+ return err; - } - - static int do_command_get(struct netlink_ctx *ctx, struct cmd *cmd) --- -2.21.0 - diff --git a/SOURCES/0013-tests-monitor-Support-running-individual-test-cases.patch b/SOURCES/0013-tests-monitor-Support-running-individual-test-cases.patch new file mode 100644 index 0000000..26c9079 --- /dev/null +++ b/SOURCES/0013-tests-monitor-Support-running-individual-test-cases.patch @@ -0,0 +1,64 @@ +From 67f168ebfbeb26a8d7e4f1b9284cc32f13ceff9b Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 22:35:27 +0100 +Subject: [PATCH] tests: monitor: Support running individual test cases + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1754047 +Upstream Status: nftables commit eb5034108cdc6 + +commit eb5034108cdc60341b2d61599077db935b6bbc4f +Author: Phil Sutter +Date: Fri Jan 10 11:15:45 2020 +0100 + + tests: monitor: Support running individual test cases + + Recognize testcase paths on command line and limit testing on those + only. + + Signed-off-by: Phil Sutter + Acked-by: Pablo Neira Ayuso +--- + tests/monitor/run-tests.sh | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh +index 0478cf6..efacdaa 100755 +--- a/tests/monitor/run-tests.sh ++++ b/tests/monitor/run-tests.sh +@@ -108,6 +108,7 @@ echo_run_test() { + touch $output_file + } + ++testcases="" + while [ -n "$1" ]; do + case "$1" in + -d|--debug) +@@ -118,11 +119,15 @@ while [ -n "$1" ]; do + test_json=true + shift + ;; ++ testcases/*.t) ++ testcases+=" $1" ++ shift ++ ;; + *) + echo "unknown option '$1'" + ;& + -h|--help) +- echo "Usage: $(basename $0) [-j|--json] [-d|--debug]" ++ echo "Usage: $(basename $0) [-j|--json] [-d|--debug] [testcase ...]" + exit 1 + ;; + esac +@@ -138,7 +143,7 @@ for variant in $variants; do + run_test=${variant}_run_test + output_append=${variant}_output_append + +- for testcase in testcases/*.t; do ++ for testcase in ${testcases:-testcases/*.t}; do + echo "$variant: running tests from file $(basename $testcase)" + # files are like this: + # +-- +1.8.3.1 + diff --git a/SOURCES/0014-Fix-memleak-in-netlink_parse_fwd-error-path.patch b/SOURCES/0014-Fix-memleak-in-netlink_parse_fwd-error-path.patch deleted file mode 100644 index 56190df..0000000 --- a/SOURCES/0014-Fix-memleak-in-netlink_parse_fwd-error-path.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 3578231d0a44c4a7617c046d3ef8b3cb1299c05e Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 12 Oct 2018 12:54:09 +0200 -Subject: [PATCH] Fix memleak in netlink_parse_fwd() error path - -Make sure allocated 'stmt' is freed before returning to caller. - -Fixes: 30d45266bf38b ("expr: extend fwd statement to support address and family") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 30541cb66e2de38eea04ab28cb14f298cce9d99f) -Signed-off-by: Phil Sutter ---- - src/netlink_delinearize.c | 13 ++++++++----- - 1 file changed, 8 insertions(+), 5 deletions(-) - -diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c -index 31d62420d41c8..ae84512c56f3a 100644 ---- a/src/netlink_delinearize.c -+++ b/src/netlink_delinearize.c -@@ -1152,9 +1152,11 @@ static void netlink_parse_fwd(struct netlink_parse_ctx *ctx, - reg2 = netlink_parse_register(nle, NFTNL_EXPR_FWD_SREG_ADDR); - if (reg2) { - addr = netlink_get_register(ctx, loc, reg2); -- if (addr == NULL) -- return netlink_error(ctx, loc, -- "fwd statement has no output expression"); -+ if (addr == NULL) { -+ netlink_error(ctx, loc, -+ "fwd statement has no output expression"); -+ goto out_err; -+ } - - switch (stmt->fwd.family) { - case AF_INET: -@@ -1166,8 +1168,9 @@ static void netlink_parse_fwd(struct netlink_parse_ctx *ctx, - BYTEORDER_BIG_ENDIAN); - break; - default: -- return netlink_error(ctx, loc, -- "fwd statement has no family"); -+ netlink_error(ctx, loc, -+ "fwd statement has no family"); -+ goto out_err; - } - stmt->fwd.addr = addr; - } --- -2.21.0 - diff --git a/SOURCES/0014-tests-monitor-Support-testing-host-s-nft-binary.patch b/SOURCES/0014-tests-monitor-Support-testing-host-s-nft-binary.patch new file mode 100644 index 0000000..502b623 --- /dev/null +++ b/SOURCES/0014-tests-monitor-Support-testing-host-s-nft-binary.patch @@ -0,0 +1,40 @@ +From 18e1b545cbd2d055b16ec3bf5f481d8032dc5dbe Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 22:35:27 +0100 +Subject: [PATCH] tests: monitor: Support testing host's nft binary + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1754047 +Upstream Status: nftables commit 15ede6857c8c5 + +commit 15ede6857c8c578ec6211c8b68424183ba1baf1a +Author: Phil Sutter +Date: Wed Feb 5 19:48:53 2020 +0100 + + tests: monitor: Support testing host's nft binary + + Add support for -H/--host flag to use 'nft' tool from $PATH instead of + the local one. + + Signed-off-by: Phil Sutter +--- + tests/monitor/run-tests.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh +index efacdaa..ffb833a 100755 +--- a/tests/monitor/run-tests.sh ++++ b/tests/monitor/run-tests.sh +@@ -119,6 +119,10 @@ while [ -n "$1" ]; do + test_json=true + shift + ;; ++ -H|--host) ++ nft=nft ++ shift ++ ;; + testcases/*.t) + testcases+=" $1" + shift +-- +1.8.3.1 + diff --git a/SOURCES/0015-libnftables-Fix-memleak-in-nft_parse_bison_filename.patch b/SOURCES/0015-libnftables-Fix-memleak-in-nft_parse_bison_filename.patch deleted file mode 100644 index 581bf53..0000000 --- a/SOURCES/0015-libnftables-Fix-memleak-in-nft_parse_bison_filename.patch +++ /dev/null @@ -1,43 +0,0 @@ -From eb770d79146941ce975c7b7caa9372b380978f98 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 12 Oct 2018 13:22:55 +0200 -Subject: [PATCH] libnftables: Fix memleak in nft_parse_bison_filename() - -Allocated scanner object leaks when returning to caller. For some odd -reason, this was missed by the commit referenced below. - -Fixes: bd82e03e15df8 ("libnftables: Move scanner object into struct nft_ctx") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit a56fe55dbd3232e70514610a1c2df1d6b15b931f) -Signed-off-by: Phil Sutter ---- - src/libnftables.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/src/libnftables.c b/src/libnftables.c -index 5bc7ba0d210ab..91af169ca7190 100644 ---- a/src/libnftables.c -+++ b/src/libnftables.c -@@ -418,15 +418,14 @@ static int nft_parse_bison_filename(struct nft_ctx *nft, const char *filename, - struct list_head *msgs, struct list_head *cmds) - { - struct cmd *cmd; -- void *scanner; - int ret; - - parser_init(nft, nft->state, msgs, cmds); -- scanner = scanner_init(nft->state); -- if (scanner_read_file(scanner, filename, &internal_location) < 0) -+ nft->scanner = scanner_init(nft->state); -+ if (scanner_read_file(nft->scanner, filename, &internal_location) < 0) - return -1; - -- ret = nft_parse(nft, scanner, nft->state); -+ ret = nft_parse(nft, nft->scanner, nft->state); - if (ret != 0 || nft->state->nerrs > 0) - return -1; - --- -2.21.0 - diff --git a/SOURCES/0015-tests-py-Support-testing-host-binaries.patch b/SOURCES/0015-tests-py-Support-testing-host-binaries.patch new file mode 100644 index 0000000..007fc9b --- /dev/null +++ b/SOURCES/0015-tests-py-Support-testing-host-binaries.patch @@ -0,0 +1,76 @@ +From 74575c409bad2940470f31946c97430043c3195e Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 22:35:27 +0100 +Subject: [PATCH] tests: py: Support testing host binaries + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1754047 +Upstream Status: nftables commit 5f2746205e50c + +commit 5f2746205e50c77295d0f84f8178ee3a1ce15407 +Author: Phil Sutter +Date: Thu Feb 6 01:36:01 2020 +0100 + + tests: py: Support testing host binaries + + Support -H/--host option to use host's libnftables.so.1. Alternatively + users may specify a custom library path via -l/--library option. + + Signed-off-by: Phil Sutter +--- + tests/py/nft-test.py | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py +index 6edca3c..01ee6c9 100755 +--- a/tests/py/nft-test.py ++++ b/tests/py/nft-test.py +@@ -1357,10 +1357,16 @@ def main(): + dest='force_all_family', + help='keep testing all families on error') + ++ parser.add_argument('-H', '--host', action='store_true', ++ help='run tests against installed libnftables.so.1') ++ + parser.add_argument('-j', '--enable-json', action='store_true', + dest='enable_json', + help='test JSON functionality as well') + ++ parser.add_argument('-l', '--library', default=None, ++ help='path to libntables.so.1, overrides --host') ++ + parser.add_argument('-s', '--schema', action='store_true', + dest='enable_schema', + help='verify json input/output against schema') +@@ -1388,9 +1394,17 @@ def main(): + # Change working directory to repository root + os.chdir(TESTS_PATH + "/../..") + +- if not os.path.exists('src/.libs/libnftables.so'): +- print("The nftables library does not exist. " +- "You need to build the project.") ++ check_lib_path = True ++ if args.library is None: ++ if args.host: ++ args.library = 'libnftables.so.1' ++ check_lib_path = False ++ else: ++ args.library = 'src/.libs/libnftables.so.1' ++ ++ if check_lib_path and not os.path.exists(args.library): ++ print("The nftables library at '%s' does not exist. " ++ "You need to build the project." % args.library) + return + + if args.enable_schema and not args.enable_json: +@@ -1398,7 +1412,7 @@ def main(): + return + + global nftables +- nftables = Nftables(sofile = 'src/.libs/libnftables.so') ++ nftables = Nftables(sofile = args.library) + + test_files = files_ok = run_total = 0 + tests = passed = warnings = errors = 0 +-- +1.8.3.1 + diff --git a/SOURCES/0016-doc-nft.8-Mention-wildcard-interface-matching.patch b/SOURCES/0016-doc-nft.8-Mention-wildcard-interface-matching.patch new file mode 100644 index 0000000..f534eec --- /dev/null +++ b/SOURCES/0016-doc-nft.8-Mention-wildcard-interface-matching.patch @@ -0,0 +1,43 @@ +From d58192a8d2810271d5c6525dc66ba1e1ec3fd2b7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 22:39:44 +0100 +Subject: [PATCH] doc: nft.8: Mention wildcard interface matching + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1763652 +Upstream Status: nftables commit 03d45ad330a25 + +commit 03d45ad330a25323610648bb05f550e0fb9d65b2 +Author: Phil Sutter +Date: Thu Feb 6 12:24:51 2020 +0100 + + doc: nft.8: Mention wildcard interface matching + + Special meaning of asterisk in interface names wasn't described + anywhere. + + Signed-off-by: Phil Sutter +--- + doc/primary-expression.txt | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt +index 5473d59..a5cab9d 100644 +--- a/doc/primary-expression.txt ++++ b/doc/primary-expression.txt +@@ -36,6 +36,13 @@ add such a rule, it will stop matching if the interface gets renamed and it + will match again in case interface gets deleted and later a new interface + with the same name is created. + ++Like with iptables, wildcard matching on interface name prefixes is available for ++*iifname* and *oifname* matches by appending an asterisk (*) character. Note ++however that unlike iptables, nftables does not accept interface names ++consisting of the wildcard character only - users are supposed to just skip ++those always matching expressions. In order to match on literal asterisk ++character, one may escape it using backslash (\). ++ + .Meta expression types + [options="header"] + |================== +-- +1.8.3.1 + diff --git a/SOURCES/0016-src-pass-struct-nft_ctx-through-struct-eval_ctx.patch b/SOURCES/0016-src-pass-struct-nft_ctx-through-struct-eval_ctx.patch deleted file mode 100644 index 9b95b2b..0000000 --- a/SOURCES/0016-src-pass-struct-nft_ctx-through-struct-eval_ctx.patch +++ /dev/null @@ -1,441 +0,0 @@ -From 09a890d3653a87e3752a3ebfc3f5de597a679cc5 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 22 Oct 2018 12:38:35 +0200 -Subject: [PATCH] src: pass struct nft_ctx through struct eval_ctx - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 00f777bfc414af1e1384a213adc91ae4ecf6cbdf) - -Conflicts: - src/evaluate.c --> Missing osf support - -Signed-off-by: Phil Sutter ---- - include/rule.h | 5 +- - src/evaluate.c | 128 ++++++++++++++++++++++----------------------- - src/parser_bison.y | 5 +- - 3 files changed, 66 insertions(+), 72 deletions(-) - -diff --git a/include/rule.h b/include/rule.h -index 909ff36db80c1..b1d15c8725813 100644 ---- a/include/rule.h -+++ b/include/rule.h -@@ -556,16 +556,13 @@ extern void cmd_free(struct cmd *cmd); - * @pctx: payload context - */ - struct eval_ctx { -- struct mnl_socket *nf_sock; -+ struct nft_ctx *nft; - struct list_head *msgs; - struct cmd *cmd; - struct table *table; - struct rule *rule; - struct set *set; - struct stmt *stmt; -- struct nft_cache *cache; -- struct output_ctx *octx; -- unsigned int debug_mask; - struct expr_ctx ectx; - struct proto_ctx pctx; - }; -diff --git a/src/evaluate.c b/src/evaluate.c -index d18af34341b0d..5e9c6328fc692 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -156,7 +156,7 @@ static struct table *table_lookup_global(struct eval_ctx *ctx) - if (ctx->table != NULL) - return ctx->table; - -- table = table_lookup(&ctx->cmd->handle, ctx->cache); -+ table = table_lookup(&ctx->cmd->handle, &ctx->nft->cache); - if (table == NULL) - return NULL; - -@@ -184,8 +184,8 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr) - } - break; - case SYMBOL_SET: -- ret = cache_update(ctx->nf_sock, ctx->cache, ctx->cmd->op, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, ctx->cmd->op, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -1731,13 +1731,13 @@ static int expr_evaluate_variable(struct eval_ctx *ctx, struct expr **exprp) - - static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr) - { -- if (ctx->debug_mask & NFT_DEBUG_EVALUATION) { -+ if (ctx->nft->debug_mask & NFT_DEBUG_EVALUATION) { - struct error_record *erec; - erec = erec_create(EREC_INFORMATIONAL, &(*expr)->location, - "Evaluate %s", (*expr)->ops->name); -- erec_print(ctx->octx, erec, ctx->debug_mask); -- expr_print(*expr, ctx->octx); -- nft_print(ctx->octx, "\n\n"); -+ erec_print(&ctx->nft->output, erec, ctx->nft->debug_mask); -+ expr_print(*expr, &ctx->nft->output); -+ nft_print(&ctx->nft->output, "\n\n"); - erec_destroy(erec); - } - -@@ -2717,13 +2717,13 @@ static int stmt_evaluate_objref(struct eval_ctx *ctx, struct stmt *stmt) - - int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) - { -- if (ctx->debug_mask & NFT_DEBUG_EVALUATION) { -+ if (ctx->nft->debug_mask & NFT_DEBUG_EVALUATION) { - struct error_record *erec; - erec = erec_create(EREC_INFORMATIONAL, &stmt->location, - "Evaluate %s", stmt->ops->name); -- erec_print(ctx->octx, erec, ctx->debug_mask); -- stmt_print(stmt, ctx->octx); -- nft_print(ctx->octx, "\n\n"); -+ erec_print(&ctx->nft->output, erec, ctx->nft->debug_mask); -+ stmt_print(stmt, &ctx->nft->output); -+ nft_print(&ctx->nft->output, "\n\n"); - erec_destroy(erec); - } - -@@ -2895,12 +2895,12 @@ static int rule_translate_index(struct eval_ctx *ctx, struct rule *rule) - int ret; - - /* update cache with CMD_LIST so that rules are fetched, too */ -- ret = cache_update(ctx->nf_sock, ctx->cache, CMD_LIST, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, CMD_LIST, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -- table = table_lookup(&rule->handle, ctx->cache); -+ table = table_lookup(&rule->handle, &ctx->nft->cache); - if (!table) - return cmd_error(ctx, &rule->handle.table.location, - "Could not process rule: %s", -@@ -2931,7 +2931,7 @@ static int rule_evaluate(struct eval_ctx *ctx, struct rule *rule) - struct stmt *stmt, *tstmt = NULL; - struct error_record *erec; - -- proto_ctx_init(&ctx->pctx, rule->handle.family, ctx->debug_mask); -+ proto_ctx_init(&ctx->pctx, rule->handle.family, ctx->nft->debug_mask); - memset(&ctx->ectx, 0, sizeof(ctx->ectx)); - - ctx->rule = rule; -@@ -3047,13 +3047,13 @@ static int table_evaluate(struct eval_ctx *ctx, struct table *table) - struct chain *chain; - struct set *set; - -- if (table_lookup(&ctx->cmd->handle, ctx->cache) == NULL) { -+ if (table_lookup(&ctx->cmd->handle, &ctx->nft->cache) == NULL) { - if (table == NULL) { - table = table_alloc(); - handle_merge(&table->handle, &ctx->cmd->handle); -- table_add_hash(table, ctx->cache); -+ table_add_hash(table, &ctx->nft->cache); - } else { -- table_add_hash(table_get(table), ctx->cache); -+ table_add_hash(table_get(table), &ctx->nft->cache); - } - } - -@@ -3088,15 +3088,15 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_SETELEM: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - - return setelem_evaluate(ctx, &cmd->expr); - case CMD_OBJ_SET: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -3106,8 +3106,8 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) - handle_merge(&cmd->rule->handle, &cmd->handle); - return rule_evaluate(ctx, cmd->rule); - case CMD_OBJ_CHAIN: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -3115,8 +3115,8 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) - case CMD_OBJ_TABLE: - return table_evaluate(ctx, cmd->table); - case CMD_OBJ_FLOWTABLE: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -3138,8 +3138,8 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_SETELEM: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -3165,14 +3165,14 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd) - struct set *set; - int ret; - -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - - switch (cmd->obj) { - case CMD_OBJ_SETELEM: -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", -@@ -3197,7 +3197,7 @@ static int cmd_evaluate_list_obj(struct eval_ctx *ctx, const struct cmd *cmd, - if (obj_type == NFT_OBJECT_UNSPEC) - obj_type = NFT_OBJECT_COUNTER; - -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", -@@ -3215,8 +3215,8 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) - struct set *set; - int ret; - -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -3225,14 +3225,14 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) - if (cmd->handle.table.name == NULL) - return 0; - -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); - return 0; - case CMD_OBJ_SET: -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", -@@ -3244,7 +3244,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) - strerror(ENOENT)); - return 0; - case CMD_OBJ_METER: -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", -@@ -3256,7 +3256,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) - strerror(ENOENT)); - return 0; - case CMD_OBJ_MAP: -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", -@@ -3268,7 +3268,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) - strerror(ENOENT)); - return 0; - case CMD_OBJ_CHAIN: -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", -@@ -3294,7 +3294,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) - case CMD_OBJ_FLOWTABLES: - if (cmd->handle.table.name == NULL) - return 0; -- if (table_lookup(&cmd->handle, ctx->cache) == NULL) -+ if (table_lookup(&cmd->handle, &ctx->nft->cache) == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); -@@ -3313,8 +3313,8 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd) - { - int ret; - -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -3325,7 +3325,7 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd) - case CMD_OBJ_QUOTAS: - if (cmd->handle.table.name == NULL) - return 0; -- if (table_lookup(&cmd->handle, ctx->cache) == NULL) -+ if (table_lookup(&cmd->handle, &ctx->nft->cache) == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", - strerror(ENOENT)); -@@ -3343,8 +3343,8 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_RULESET: -- cache_flush(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ cache_flush(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - break; - case CMD_OBJ_TABLE: - /* Flushing a table does not empty the sets in the table nor remove -@@ -3354,12 +3354,12 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - /* Chains don't hold sets */ - break; - case CMD_OBJ_SET: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &cmd->handle.table.location, - "Could not process rule: %s", -@@ -3371,12 +3371,12 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - strerror(ENOENT)); - return 0; - case CMD_OBJ_MAP: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", -@@ -3388,12 +3388,12 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - strerror(ENOENT)); - return 0; - case CMD_OBJ_METER: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", -@@ -3417,12 +3417,12 @@ static int cmd_evaluate_rename(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_CHAIN: -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -+ ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -- table = table_lookup(&ctx->cmd->handle, ctx->cache); -+ table = table_lookup(&ctx->cmd->handle, &ctx->nft->cache); - if (table == NULL) - return cmd_error(ctx, &ctx->cmd->handle.table.location, - "Could not process rule: %s", -@@ -3517,8 +3517,8 @@ static int cmd_evaluate_monitor(struct eval_ctx *ctx, struct cmd *cmd) - uint32_t event; - int ret; - -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - if (ret < 0) - return ret; - -@@ -3543,8 +3543,8 @@ static int cmd_evaluate_export(struct eval_ctx *ctx, struct cmd *cmd) - return cmd_error(ctx, &cmd->location, - "this output type is not supported"); - -- return cache_update(ctx->nf_sock, ctx->cache, cmd->op, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ return cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -+ ctx->nft->debug_mask, &ctx->nft->output); - } - - static int cmd_evaluate_import(struct eval_ctx *ctx, struct cmd *cmd) -@@ -3582,13 +3582,13 @@ static const char *cmd_op_to_name(enum cmd_ops op) - - int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd) - { -- if (ctx->debug_mask & NFT_DEBUG_EVALUATION) { -+ if (ctx->nft->debug_mask & NFT_DEBUG_EVALUATION) { - struct error_record *erec; - - erec = erec_create(EREC_INFORMATIONAL, &cmd->location, - "Evaluate %s", cmd_op_to_name(cmd->op)); -- erec_print(ctx->octx, erec, ctx->debug_mask); -- nft_print(ctx->octx, "\n\n"); -+ erec_print(&ctx->nft->output, erec, ctx->nft->debug_mask); -+ nft_print(&ctx->nft->output, "\n\n"); - erec_destroy(erec); - } - -diff --git a/src/parser_bison.y b/src/parser_bison.y -index 33915ed8702a6..d75cd50fa29b9 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -44,11 +44,8 @@ void parser_init(struct nft_ctx *nft, struct parser_state *state, - state->msgs = msgs; - state->cmds = cmds; - state->scopes[0] = scope_init(&state->top_scope, NULL); -- state->ectx.cache = &nft->cache; -+ state->ectx.nft = nft; - state->ectx.msgs = msgs; -- state->ectx.nf_sock = nft->nf_sock; -- state->ectx.debug_mask = nft->debug_mask; -- state->ectx.octx = &nft->output; - } - - static void yyerror(struct location *loc, struct nft_ctx *nft, void *scanner, --- -2.21.0 - diff --git a/SOURCES/0017-scanner-Extend-asteriskstring-definition.patch b/SOURCES/0017-scanner-Extend-asteriskstring-definition.patch new file mode 100644 index 0000000..09717b0 --- /dev/null +++ b/SOURCES/0017-scanner-Extend-asteriskstring-definition.patch @@ -0,0 +1,39 @@ +From 34ba60c0c2b6057e8b56a77e47899bbeccd88bfd Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Wed, 12 Feb 2020 22:39:44 +0100 +Subject: [PATCH] scanner: Extend asteriskstring definition + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1763652 +Upstream Status: nftables commit 556c5a94b8067 + +commit 556c5a94b8067f33ef0a42836753dae0736b7524 +Author: Phil Sutter +Date: Thu Feb 6 12:31:56 2020 +0100 + + scanner: Extend asteriskstring definition + + Accept escaped asterisks also mid-string and as only character. + Especially the latter will help when translating from iptables where + asterisk has no special meaning. + + Signed-off-by: Phil Sutter +--- + src/scanner.l | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/scanner.l b/src/scanner.l +index d32adf4..7daf5c1 100644 +--- a/src/scanner.l ++++ b/src/scanner.l +@@ -120,7 +120,7 @@ numberstring ({decstring}|{hexstring}) + letter [a-zA-Z] + string ({letter}|[_.])({letter}|{digit}|[/\-_\.])* + quotedstring \"[^"]*\" +-asteriskstring ({string}\*|{string}\\\*) ++asteriskstring ({string}\*|{string}\\\*|\\\*|{string}\\\*{string}) + comment #.*$ + slash \/ + +-- +1.8.3.1 + diff --git a/SOURCES/0017-src-trace-fix-policy-printing.patch b/SOURCES/0017-src-trace-fix-policy-printing.patch deleted file mode 100644 index 9455910..0000000 --- a/SOURCES/0017-src-trace-fix-policy-printing.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 244a83f9e0809177f07fb7b7474f84a126cf827f Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 20 Jun 2018 23:06:04 +0200 -Subject: [PATCH] src: trace: fix policy printing - -policy type is erronously handled via verdict, this is wrong. -It is a different event type and needs to be handled as such. - -before: -trace id 42b54e71 inet filter input packet: iif "lo" ip saddr 127.0.0.1 .. -trace id 42b54e71 inet filter input rule ip protocol icmp nftrace set 1 (verdict continue) -trace id 42b54e71 inet filter input verdict continue -trace id 42b54e71 inet filter input - -after: -trace id 9f40c5c7 inet filter input packet: iif "lo" ip saddr 127.0.0.1 .. -trace id 9f40c5c7 inet filter input rule ip protocol icmp nftrace set 1 (verdict continue) -trace id 9f40c5c7 inet filter input verdict continue -trace id 9f40c5c7 inet filter input policy drop - -Reported-by: vtol@gmx.net -Signed-off-by: Florian Westphal -(cherry picked from commit 78ba4ffdeacc9b31f7396d72c98907e861024653) -Signed-off-by: Phil Sutter ---- - src/netlink.c | 31 ++++++++++++++++++++++++++++++- - 1 file changed, 30 insertions(+), 1 deletion(-) - -diff --git a/src/netlink.c b/src/netlink.c -index ca5e9b4a0f8a6..4fd3f2dfefced 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -1705,7 +1705,22 @@ static void trace_print_verdict(const struct nftnl_trace *nlt, - chain = xstrdup(nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET)); - expr = verdict_expr_alloc(&netlink_location, verdict, chain); - -- printf("verdict "); -+ nft_print(octx, "verdict "); -+ expr_print(expr, octx); -+ expr_free(expr); -+} -+ -+static void trace_print_policy(const struct nftnl_trace *nlt, -+ struct output_ctx *octx) -+{ -+ unsigned int policy; -+ struct expr *expr; -+ -+ policy = nftnl_trace_get_u32(nlt, NFTNL_TRACE_POLICY); -+ -+ expr = verdict_expr_alloc(&netlink_location, policy, NULL); -+ -+ nft_print(octx, "policy "); - expr_print(expr, octx); - expr_free(expr); - } -@@ -1921,6 +1936,20 @@ int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type, - trace_print_rule(nlt, monh->ctx->octx, monh->cache); - break; - case NFT_TRACETYPE_POLICY: -+ trace_print_hdr(nlt, monh->ctx->octx); -+ -+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_POLICY)) { -+ trace_print_policy(nlt, monh->ctx->octx); -+ nft_mon_print(monh, " "); -+ } -+ -+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_MARK)) -+ trace_print_expr(nlt, NFTNL_TRACE_MARK, -+ meta_expr_alloc(&netlink_location, -+ NFT_META_MARK), -+ monh->ctx->octx); -+ nft_mon_print(monh, "\n"); -+ break; - case NFT_TRACETYPE_RETURN: - trace_print_hdr(nlt, monh->ctx->octx); - --- -2.21.0 - diff --git a/SOURCES/0018-parser-add-a-helper-for-concat-expression-handling.patch b/SOURCES/0018-parser-add-a-helper-for-concat-expression-handling.patch new file mode 100644 index 0000000..5a93472 --- /dev/null +++ b/SOURCES/0018-parser-add-a-helper-for-concat-expression-handling.patch @@ -0,0 +1,162 @@ +From 160d84fb761c54a5f757aff907fc197d259196bd Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 17 Feb 2020 15:26:42 +0100 +Subject: [PATCH] parser: add a helper for concat expression handling + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795224 +Upstream Status: nftables commit 10f114806ccd9 + +commit 10f114806ccd9d64f9d72eaa813babb04d719688 +Author: Florian Westphal +Date: Wed Dec 11 14:31:44 2019 +0100 + + parser: add a helper for concat expression handling + + Cull the repeated copy&paste snippets and add/use a helper for this. + + Signed-off-by: Florian Westphal +--- + src/parser_bison.y | 99 ++++++++++++++++++++++++------------------------------ + 1 file changed, 43 insertions(+), 56 deletions(-) + +diff --git a/src/parser_bison.y b/src/parser_bison.y +index 707f467..0fd9b94 100644 +--- a/src/parser_bison.y ++++ b/src/parser_bison.y +@@ -102,6 +102,25 @@ static void location_update(struct location *loc, struct location *rhs, int n) + } + } + ++static struct expr *handle_concat_expr(const struct location *loc, ++ struct expr *expr, ++ struct expr *expr_l, struct expr *expr_r, ++ struct location loc_rhs[3]) ++{ ++ if (expr->etype != EXPR_CONCAT) { ++ expr = concat_expr_alloc(loc); ++ compound_expr_add(expr, expr_l); ++ } else { ++ location_update(&expr_r->location, loc_rhs, 2); ++ ++ expr = expr_l; ++ expr->location = *loc; ++ } ++ ++ compound_expr_add(expr, expr_r); ++ return expr; ++} ++ + #define YYLLOC_DEFAULT(Current, Rhs, N) location_update(&Current, Rhs, N) + + #define symbol_value(loc, str) \ +@@ -1878,20 +1897,12 @@ data_type_atom_expr : type_identifier + data_type_expr : data_type_atom_expr + | data_type_expr DOT data_type_atom_expr + { +- if ($1->etype != EXPR_CONCAT) { +- $$ = concat_expr_alloc(&@$); +- compound_expr_add($$, $1); +- } else { +- struct location rhs[] = { +- [1] = @2, +- [2] = @3, +- }; +- location_update(&$3->location, rhs, 2); +- +- $$ = $1; +- $$->location = @$; +- } +- compound_expr_add($$, $3); ++ struct location rhs[] = { ++ [1] = @2, ++ [2] = @3, ++ }; ++ ++ $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + } + ; + +@@ -2992,20 +3003,12 @@ basic_stmt_expr : inclusive_or_stmt_expr + concat_stmt_expr : basic_stmt_expr + | concat_stmt_expr DOT primary_stmt_expr + { +- if ($$->etype != EXPR_CONCAT) { +- $$ = concat_expr_alloc(&@$); +- compound_expr_add($$, $1); +- } else { +- struct location rhs[] = { +- [1] = @2, +- [2] = @3, +- }; +- location_update(&$3->location, rhs, 2); +- +- $$ = $1; +- $$->location = @$; +- } +- compound_expr_add($$, $3); ++ struct location rhs[] = { ++ [1] = @2, ++ [2] = @3, ++ }; ++ ++ $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + } + ; + +@@ -3525,20 +3528,12 @@ basic_expr : inclusive_or_expr + concat_expr : basic_expr + | concat_expr DOT basic_expr + { +- if ($$->etype != EXPR_CONCAT) { +- $$ = concat_expr_alloc(&@$); +- compound_expr_add($$, $1); +- } else { +- struct location rhs[] = { +- [1] = @2, +- [2] = @3, +- }; +- location_update(&$3->location, rhs, 2); +- +- $$ = $1; +- $$->location = @$; +- } +- compound_expr_add($$, $3); ++ struct location rhs[] = { ++ [1] = @2, ++ [2] = @3, ++ }; ++ ++ $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + } + ; + +@@ -3946,20 +3941,12 @@ basic_rhs_expr : inclusive_or_rhs_expr + concat_rhs_expr : basic_rhs_expr + | concat_rhs_expr DOT basic_rhs_expr + { +- if ($$->etype != EXPR_CONCAT) { +- $$ = concat_expr_alloc(&@$); +- compound_expr_add($$, $1); +- } else { +- struct location rhs[] = { +- [1] = @2, +- [2] = @3, +- }; +- location_update(&$3->location, rhs, 2); +- +- $$ = $1; +- $$->location = @$; +- } +- compound_expr_add($$, $3); ++ struct location rhs[] = { ++ [1] = @2, ++ [2] = @3, ++ }; ++ ++ $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + } + ; + +-- +1.8.3.1 + diff --git a/SOURCES/0018-rule-list-only-the-table-containing-object.patch b/SOURCES/0018-rule-list-only-the-table-containing-object.patch deleted file mode 100644 index ba17c37..0000000 --- a/SOURCES/0018-rule-list-only-the-table-containing-object.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 48169840569b45e7695b125935bf30967f30b10c Mon Sep 17 00:00:00 2001 -From: Harsha Sharma -Date: Sun, 8 Jul 2018 12:41:03 +0200 -Subject: [PATCH] rule: list only the table containing object - -For e.g. - - % nft list ct helper ip raw cthelp1 - table ip filter { - } - table ip raw { - ct helper cthelp1 { - type "ftp" protocol tcp - l3proto ip - } - } - -With this patch, print only table raw. - -Signed-off-by: Harsha Sharma -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 88456a7ef011728a98c950447630f0a128dcad13) -Signed-off-by: Phil Sutter ---- - src/rule.c | 12 +++++------- - 1 file changed, 5 insertions(+), 7 deletions(-) - -diff --git a/src/rule.c b/src/rule.c -index a157ac91683cc..3b5468d00e79c 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -1593,15 +1593,13 @@ static int do_list_obj(struct netlink_ctx *ctx, struct cmd *cmd, uint32_t type) - cmd->handle.family != table->handle.family) - continue; - -- nft_print(ctx->octx, "table %s %s {\n", -- family2str(table->handle.family), -- table->handle.table.name); -- - if (cmd->handle.table.name != NULL && -- strcmp(cmd->handle.table.name, table->handle.table.name)) { -- nft_print(ctx->octx, "}\n"); -+ !strcmp(cmd->handle.table.name, table->handle.table.name)) { -+ nft_print(ctx->octx, "table %s %s {\n", -+ family2str(table->handle.family), -+ cmd->handle.table.name); -+ } else - continue; -- } - - list_for_each_entry(obj, &table->objs, list) { - if (obj->type != type || --- -2.21.0 - diff --git a/SOURCES/0019-include-resync-nf_tables.h-cache-copy.patch b/SOURCES/0019-include-resync-nf_tables.h-cache-copy.patch new file mode 100644 index 0000000..bd55b39 --- /dev/null +++ b/SOURCES/0019-include-resync-nf_tables.h-cache-copy.patch @@ -0,0 +1,84 @@ +From e872d169c189f363ebbdc39105510c1809b58276 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 13 Feb 2020 17:48:18 +0100 +Subject: [PATCH] include: resync nf_tables.h cache copy + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795224 +Upstream Status: nftables commit 9b94127950f98 + +commit 9b94127950f9848bc5a1505ae65ca3045ff68a16 +Author: Stefano Brivio +Date: Thu Jan 30 01:16:55 2020 +0100 + + include: resync nf_tables.h cache copy + + Get this header in sync with nf-next as of merge commit + b3a608222336 (5.6-rc1-ish). + + Signed-off-by: Stefano Brivio + Signed-off-by: Pablo Neira Ayuso +--- + include/linux/netfilter/nf_tables.h | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h +index ed8881a..1a99df3 100644 +--- a/include/linux/netfilter/nf_tables.h ++++ b/include/linux/netfilter/nf_tables.h +@@ -48,6 +48,7 @@ enum nft_registers { + + #define NFT_REG_SIZE 16 + #define NFT_REG32_SIZE 4 ++#define NFT_REG32_COUNT (NFT_REG32_15 - NFT_REG32_00 + 1) + + /** + * enum nft_verdicts - nf_tables internal verdicts +@@ -299,15 +300,29 @@ enum nft_set_policies { + * enum nft_set_desc_attributes - set element description + * + * @NFTA_SET_DESC_SIZE: number of elements in set (NLA_U32) ++ * @NFTA_SET_DESC_CONCAT: description of field concatenation (NLA_NESTED) + */ + enum nft_set_desc_attributes { + NFTA_SET_DESC_UNSPEC, + NFTA_SET_DESC_SIZE, ++ NFTA_SET_DESC_CONCAT, + __NFTA_SET_DESC_MAX + }; + #define NFTA_SET_DESC_MAX (__NFTA_SET_DESC_MAX - 1) + + /** ++ * enum nft_set_field_attributes - attributes of concatenated fields ++ * ++ * @NFTA_SET_FIELD_LEN: length of single field, in bits (NLA_U32) ++ */ ++enum nft_set_field_attributes { ++ NFTA_SET_FIELD_UNSPEC, ++ NFTA_SET_FIELD_LEN, ++ __NFTA_SET_FIELD_MAX ++}; ++#define NFTA_SET_FIELD_MAX (__NFTA_SET_FIELD_MAX - 1) ++ ++/** + * enum nft_set_attributes - nf_tables set netlink attributes + * + * @NFTA_SET_TABLE: table name (NLA_STRING) +@@ -368,6 +383,7 @@ enum nft_set_elem_flags { + * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY) + * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes) + * @NFTA_SET_ELEM_OBJREF: stateful object reference (NLA_STRING) ++ * @NFTA_SET_ELEM_KEY_END: closing key value (NLA_NESTED: nft_data) + */ + enum nft_set_elem_attributes { + NFTA_SET_ELEM_UNSPEC, +@@ -380,6 +396,7 @@ enum nft_set_elem_attributes { + NFTA_SET_ELEM_EXPR, + NFTA_SET_ELEM_PAD, + NFTA_SET_ELEM_OBJREF, ++ NFTA_SET_ELEM_KEY_END, + __NFTA_SET_ELEM_MAX + }; + #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1) +-- +1.8.3.1 + diff --git a/SOURCES/0019-src-pass-struct-nft_ctx-through-struct-netlink_ctx.patch b/SOURCES/0019-src-pass-struct-nft_ctx-through-struct-netlink_ctx.patch deleted file mode 100644 index 9f2cac8..0000000 --- a/SOURCES/0019-src-pass-struct-nft_ctx-through-struct-netlink_ctx.patch +++ /dev/null @@ -1,1139 +0,0 @@ -From da71df5d7e2602279cfe713be01bd402c699cd4e Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 22 Oct 2018 21:18:19 +0200 -Subject: [PATCH] src: pass struct nft_ctx through struct netlink_ctx - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 2dc07bcd7eaa56369dff01b596acf010308007d3) - -Conflicts: - src/evaluate.c - src/mnl.c - src/nfnl_osf.c - src/rule.c --> Missing osf support --> Missing cleanups - -Signed-off-by: Phil Sutter ---- - include/netlink.h | 9 +-- - include/rule.h | 10 ++- - src/evaluate.c | 51 +++++---------- - src/libnftables.c | 8 +-- - src/mnl.c | 22 +++---- - src/monitor.c | 52 ++++++++-------- - src/netlink.c | 47 +++++++------- - src/netlink_delinearize.c | 4 +- - src/rule.c | 128 ++++++++++++++++++-------------------- - 9 files changed, 147 insertions(+), 184 deletions(-) - -diff --git a/include/netlink.h b/include/netlink.h -index d153e2be03ac5..31465ff16822e 100644 ---- a/include/netlink.h -+++ b/include/netlink.h -@@ -35,26 +35,21 @@ extern const struct location netlink_location; - /** - * struct netlink_ctx - * -+ * @nft: nftables context - * @msgs: message queue - * @list: list of parsed rules/chains/tables - * @set: current set - * @data: pointer to pass data to callback - * @seqnum: sequence number -- * @octx: output context -- * @debug_mask: display debugging information -- * @cache: cache context - */ - struct netlink_ctx { -- struct mnl_socket *nf_sock; -+ struct nft_ctx *nft; - struct list_head *msgs; - struct list_head list; - struct set *set; - const void *data; - uint32_t seqnum; - struct nftnl_batch *batch; -- unsigned int debug_mask; -- struct output_ctx *octx; -- struct nft_cache *cache; - }; - - extern struct nftnl_table *alloc_nftnl_table(const struct handle *h); -diff --git a/include/rule.h b/include/rule.h -index b1d15c8725813..12c2984a14362 100644 ---- a/include/rule.h -+++ b/include/rule.h -@@ -574,12 +574,10 @@ extern struct error_record *rule_postprocess(struct rule *rule); - struct netlink_ctx; - extern int do_command(struct netlink_ctx *ctx, struct cmd *cmd); - --extern int cache_update(struct mnl_socket *nf_sock, struct nft_cache *cache, -- enum cmd_ops cmd, struct list_head *msgs, unsigned int debug_flag, -- struct output_ctx *octx); --extern void cache_flush(struct mnl_socket *nf_sock, struct nft_cache *cache, -- enum cmd_ops cmd, struct list_head *msgs, -- unsigned int debug_mask, struct output_ctx *octx); -+extern int cache_update(struct nft_ctx *ctx, enum cmd_ops cmd, -+ struct list_head *msgs); -+extern void cache_flush(struct nft_ctx *ctx, enum cmd_ops cmd, -+ struct list_head *msgs); - extern void cache_release(struct nft_cache *cache); - - enum udata_type { -diff --git a/src/evaluate.c b/src/evaluate.c -index 5e9c6328fc692..809920748c0a9 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -184,8 +184,7 @@ static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr) - } - break; - case SYMBOL_SET: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, ctx->cmd->op, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, ctx->cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -2895,8 +2894,7 @@ static int rule_translate_index(struct eval_ctx *ctx, struct rule *rule) - int ret; - - /* update cache with CMD_LIST so that rules are fetched, too */ -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, CMD_LIST, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, CMD_LIST, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3088,15 +3086,13 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_SETELEM: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - - return setelem_evaluate(ctx, &cmd->expr); - case CMD_OBJ_SET: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3106,8 +3102,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) - handle_merge(&cmd->rule->handle, &cmd->handle); - return rule_evaluate(ctx, cmd->rule); - case CMD_OBJ_CHAIN: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3115,8 +3110,7 @@ static int cmd_evaluate_add(struct eval_ctx *ctx, struct cmd *cmd) - case CMD_OBJ_TABLE: - return table_evaluate(ctx, cmd->table); - case CMD_OBJ_FLOWTABLE: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3138,8 +3132,7 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_SETELEM: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3165,8 +3158,7 @@ static int cmd_evaluate_get(struct eval_ctx *ctx, struct cmd *cmd) - struct set *set; - int ret; - -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3215,8 +3207,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd) - struct set *set; - int ret; - -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3313,8 +3304,7 @@ static int cmd_evaluate_reset(struct eval_ctx *ctx, struct cmd *cmd) - { - int ret; - -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3343,8 +3333,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_RULESET: -- cache_flush(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ cache_flush(ctx->nft, cmd->op, ctx->msgs); - break; - case CMD_OBJ_TABLE: - /* Flushing a table does not empty the sets in the table nor remove -@@ -3354,8 +3343,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - /* Chains don't hold sets */ - break; - case CMD_OBJ_SET: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3371,8 +3359,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - strerror(ENOENT)); - return 0; - case CMD_OBJ_MAP: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3388,8 +3375,7 @@ static int cmd_evaluate_flush(struct eval_ctx *ctx, struct cmd *cmd) - strerror(ENOENT)); - return 0; - case CMD_OBJ_METER: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3417,8 +3403,7 @@ static int cmd_evaluate_rename(struct eval_ctx *ctx, struct cmd *cmd) - - switch (cmd->obj) { - case CMD_OBJ_CHAIN: -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, -- ctx->msgs, ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3517,8 +3502,7 @@ static int cmd_evaluate_monitor(struct eval_ctx *ctx, struct cmd *cmd) - uint32_t event; - int ret; - -- ret = cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ ret = cache_update(ctx->nft, cmd->op, ctx->msgs); - if (ret < 0) - return ret; - -@@ -3543,8 +3527,7 @@ static int cmd_evaluate_export(struct eval_ctx *ctx, struct cmd *cmd) - return cmd_error(ctx, &cmd->location, - "this output type is not supported"); - -- return cache_update(ctx->nft->nf_sock, &ctx->nft->cache, cmd->op, ctx->msgs, -- ctx->nft->debug_mask, &ctx->nft->output); -+ return cache_update(ctx->nft, cmd->op, ctx->msgs); - } - - static int cmd_evaluate_import(struct eval_ctx *ctx, struct cmd *cmd) -diff --git a/src/libnftables.c b/src/libnftables.c -index 91af169ca7190..848c9cba65657 100644 ---- a/src/libnftables.c -+++ b/src/libnftables.c -@@ -40,10 +40,7 @@ static int nft_netlink(struct nft_ctx *nft, - ctx.msgs = msgs; - ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum); - ctx.batch = batch; -- ctx.octx = &nft->output; -- ctx.nf_sock = nf_sock; -- ctx.cache = &nft->cache; -- ctx.debug_mask = nft->debug_mask; -+ ctx.nft = nft; - init_list_head(&ctx.list); - ret = do_command(&ctx, cmd); - if (ret < 0) { -@@ -480,8 +477,7 @@ int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename) - LIST_HEAD(cmds); - int rc; - -- rc = cache_update(nft->nf_sock, &nft->cache, CMD_INVALID, &msgs, -- nft->debug_mask, &nft->output); -+ rc = cache_update(nft, CMD_INVALID, &msgs); - if (rc < 0) - return -1; - -diff --git a/src/mnl.c b/src/mnl.c -index 42eacab74e4e0..fd89ee7f28aaf 100644 ---- a/src/mnl.c -+++ b/src/mnl.c -@@ -51,13 +51,13 @@ nft_mnl_recv(struct netlink_ctx *ctx, uint32_t portid, - char buf[NFT_NLMSG_MAXSIZE]; - int ret; - -- ret = mnl_socket_recvfrom(ctx->nf_sock, buf, sizeof(buf)); -+ ret = mnl_socket_recvfrom(ctx->nft->nf_sock, buf, sizeof(buf)); - while (ret > 0) { - ret = mnl_cb_run(buf, ret, ctx->seqnum, portid, cb, cb_data); - if (ret <= 0) - goto out; - -- ret = mnl_socket_recvfrom(ctx->nf_sock, buf, sizeof(buf)); -+ ret = mnl_socket_recvfrom(ctx->nft->nf_sock, buf, sizeof(buf)); - } - out: - if (ret < 0 && errno == EAGAIN) -@@ -70,13 +70,13 @@ static int - nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len, - int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data) - { -- uint32_t portid = mnl_socket_get_portid(ctx->nf_sock); -+ uint32_t portid = mnl_socket_get_portid(ctx->nft->nf_sock); - -- if (ctx->debug_mask & NFT_DEBUG_MNL) -- mnl_nlmsg_fprintf(ctx->octx->output_fp, data, len, -+ if (ctx->nft->debug_mask & NFT_DEBUG_MNL) -+ mnl_nlmsg_fprintf(ctx->nft->output.output_fp, data, len, - sizeof(struct nfgenmsg)); - -- if (mnl_socket_sendto(ctx->nf_sock, data, len) < 0) -+ if (mnl_socket_sendto(ctx->nft->nf_sock, data, len) < 0) - return -1; - - return nft_mnl_recv(ctx, portid, cb, cb_data); -@@ -225,23 +225,23 @@ static ssize_t mnl_nft_socket_sendmsg(const struct netlink_ctx *ctx) - }; - uint32_t i; - -- mnl_set_sndbuffer(ctx->nf_sock, ctx->batch); -+ mnl_set_sndbuffer(ctx->nft->nf_sock, ctx->batch); - nftnl_batch_iovec(ctx->batch, iov, iov_len); - - for (i = 0; i < iov_len; i++) { -- if (ctx->debug_mask & NFT_DEBUG_MNL) { -- mnl_nlmsg_fprintf(ctx->octx->output_fp, -+ if (ctx->nft->debug_mask & NFT_DEBUG_MNL) { -+ mnl_nlmsg_fprintf(ctx->nft->output.output_fp, - iov[i].iov_base, iov[i].iov_len, - sizeof(struct nfgenmsg)); - } - } - -- return sendmsg(mnl_socket_get_fd(ctx->nf_sock), &msg, 0); -+ return sendmsg(mnl_socket_get_fd(ctx->nft->nf_sock), &msg, 0); - } - - int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list) - { -- struct mnl_socket *nl = ctx->nf_sock; -+ struct mnl_socket *nl = ctx->nft->nf_sock; - int ret, fd = mnl_socket_get_fd(nl), portid = mnl_socket_get_portid(nl); - char rcv_buf[MNL_SOCKET_BUFFER_SIZE]; - fd_set readfds; -diff --git a/src/monitor.c b/src/monitor.c -index 213c40d119b4c..14ccbc5fe04ca 100644 ---- a/src/monitor.c -+++ b/src/monitor.c -@@ -40,7 +40,7 @@ - #include - #include - --#define nft_mon_print(monh, ...) nft_print(monh->ctx->octx, __VA_ARGS__) -+#define nft_mon_print(monh, ...) nft_print(&monh->ctx->nft->output, __VA_ARGS__) - - static struct nftnl_table *netlink_table_alloc(const struct nlmsghdr *nlh) - { -@@ -214,7 +214,7 @@ static int netlink_events_table_cb(const struct nlmsghdr *nlh, int type, - - nft_mon_print(monh, "%s %s", family2str(t->handle.family), - t->handle.table.name); -- if (monh->ctx->octx->handle > 0) -+ if (monh->ctx->nft->output.handle > 0) - nft_mon_print(monh, " # handle %" PRIu64 "", - t->handle.handle.id); - break; -@@ -245,7 +245,7 @@ static int netlink_events_chain_cb(const struct nlmsghdr *nlh, int type, - - switch (type) { - case NFT_MSG_NEWCHAIN: -- chain_print_plain(c, monh->ctx->octx); -+ chain_print_plain(c, &monh->ctx->nft->output); - break; - case NFT_MSG_DELCHAIN: - nft_mon_print(monh, "chain %s %s %s", -@@ -292,7 +292,7 @@ static int netlink_events_set_cb(const struct nlmsghdr *nlh, int type, - - switch (type) { - case NFT_MSG_NEWSET: -- set_print_plain(set, monh->ctx->octx); -+ set_print_plain(set, &monh->ctx->nft->output); - break; - case NFT_MSG_DELSET: - nft_mon_print(monh, "set %s %s %s", family, -@@ -386,7 +386,7 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type, - family = nftnl_set_get_u32(nls, NFTNL_SET_FAMILY); - cmd = netlink_msg2cmd(type); - -- set = set_lookup_global(family, table, setname, monh->cache); -+ set = set_lookup_global(family, table, setname, &monh->ctx->nft->cache); - if (set == NULL) { - fprintf(stderr, "W: Received event for an unknown set."); - goto out; -@@ -417,7 +417,7 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type, - goto out; - } - if (netlink_delinearize_setelem(nlse, dummyset, -- monh->cache) < 0) { -+ &monh->ctx->nft->cache) < 0) { - set_free(dummyset); - nftnl_set_elems_iter_destroy(nlsei); - goto out; -@@ -435,7 +435,7 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type, - case NFTNL_OUTPUT_DEFAULT: - nft_mon_print(monh, "%s element %s %s %s ", - cmd, family2str(family), table, setname); -- expr_print(dummyset->init, monh->ctx->octx); -+ expr_print(dummyset->init, &monh->ctx->nft->output); - break; - case NFTNL_OUTPUT_JSON: - dummyset->handle.family = family; -@@ -477,7 +477,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, - - switch (type) { - case NFT_MSG_NEWOBJ: -- obj_print_plain(obj, monh->ctx->octx); -+ obj_print_plain(obj, &monh->ctx->nft->output); - break; - case NFT_MSG_DELOBJ: - nft_mon_print(monh, "%s %s %s %s", -@@ -513,7 +513,8 @@ static int netlink_events_rule_cb(const struct nlmsghdr *nlh, int type, - - nlr = netlink_rule_alloc(nlh); - r = netlink_delinearize_rule(monh->ctx, nlr); -- nlr_for_each_set(nlr, rule_map_decompose_cb, NULL, monh->cache); -+ nlr_for_each_set(nlr, rule_map_decompose_cb, NULL, -+ &monh->ctx->nft->cache); - cmd = netlink_msg2cmd(type); - - switch (monh->format) { -@@ -528,7 +529,7 @@ static int netlink_events_rule_cb(const struct nlmsghdr *nlh, int type, - - switch (type) { - case NFT_MSG_NEWRULE: -- rule_print(r, monh->ctx->octx); -+ rule_print(r, &monh->ctx->nft->output); - - break; - case NFT_MSG_DELRULE: -@@ -557,7 +558,7 @@ static void netlink_events_cache_addtable(struct netlink_mon_handler *monh, - t = netlink_delinearize_table(monh->ctx, nlt); - nftnl_table_free(nlt); - -- table_add_hash(t, monh->cache); -+ table_add_hash(t, &monh->ctx->nft->cache); - } - - static void netlink_events_cache_deltable(struct netlink_mon_handler *monh, -@@ -571,7 +572,7 @@ static void netlink_events_cache_deltable(struct netlink_mon_handler *monh, - h.family = nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY); - h.table.name = nftnl_table_get_str(nlt, NFTNL_TABLE_NAME); - -- t = table_lookup(&h, monh->cache); -+ t = table_lookup(&h, &monh->ctx->nft->cache); - if (t == NULL) - goto out; - -@@ -601,7 +602,7 @@ static void netlink_events_cache_addset(struct netlink_mon_handler *monh, - goto out; - s->init = set_expr_alloc(monh->loc, s); - -- t = table_lookup(&s->handle, monh->cache); -+ t = table_lookup(&s->handle, &monh->ctx->nft->cache); - if (t == NULL) { - fprintf(stderr, "W: Unable to cache set: table not found.\n"); - set_free(s); -@@ -628,7 +629,7 @@ static void netlink_events_cache_addsetelem(struct netlink_mon_handler *monh, - table = nftnl_set_get_str(nls, NFTNL_SET_TABLE); - setname = nftnl_set_get_str(nls, NFTNL_SET_NAME); - -- set = set_lookup_global(family, table, setname, monh->cache); -+ set = set_lookup_global(family, table, setname, &monh->ctx->nft->cache); - if (set == NULL) { - fprintf(stderr, - "W: Unable to cache set_elem. Set not found.\n"); -@@ -641,7 +642,8 @@ static void netlink_events_cache_addsetelem(struct netlink_mon_handler *monh, - - nlse = nftnl_set_elems_iter_next(nlsei); - while (nlse != NULL) { -- if (netlink_delinearize_setelem(nlse, set, monh->cache) < 0) { -+ if (netlink_delinearize_setelem(nlse, set, -+ &monh->ctx->nft->cache) < 0) { - fprintf(stderr, - "W: Unable to cache set_elem. " - "Delinearize failed.\n"); -@@ -668,7 +670,7 @@ static void netlink_events_cache_delsets(struct netlink_mon_handler *monh, - struct nftnl_rule *nlr = netlink_rule_alloc(nlh); - - nlr_for_each_set(nlr, netlink_events_cache_delset_cb, NULL, -- monh->cache); -+ &monh->ctx->nft->cache); - nftnl_rule_free(nlr); - } - -@@ -691,7 +693,7 @@ static void netlink_events_cache_addobj(struct netlink_mon_handler *monh, - if (obj == NULL) - goto out; - -- t = table_lookup(&obj->handle, monh->cache); -+ t = table_lookup(&obj->handle, &monh->ctx->nft->cache); - if (t == NULL) { - fprintf(stderr, "W: Unable to cache object: table not found.\n"); - obj_free(obj); -@@ -721,7 +723,7 @@ static void netlink_events_cache_delobj(struct netlink_mon_handler *monh, - type = nftnl_obj_get_u32(nlo, NFTNL_OBJ_TYPE); - h.handle.id = nftnl_obj_get_u64(nlo, NFTNL_OBJ_HANDLE); - -- t = table_lookup(&h, monh->cache); -+ t = table_lookup(&h, &monh->ctx->nft->cache); - if (t == NULL) { - fprintf(stderr, "W: Unable to cache object: table not found.\n"); - goto out; -@@ -835,7 +837,7 @@ static int netlink_events_newgen_cb(const struct nlmsghdr *nlh, int type, - nft_mon_print(monh, "# new generation %d", genid); - if (pid >= 0) { - nft_mon_print(monh, " by process %d", pid); -- if (!monh->ctx->octx->numeric) -+ if (!monh->ctx->nft->output.numeric) - nft_mon_print(monh, " (%s)", name); - } - nft_mon_print(monh, "\n"); -@@ -850,7 +852,7 @@ static int netlink_events_cb(const struct nlmsghdr *nlh, void *data) - uint16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type); - struct netlink_mon_handler *monh = (struct netlink_mon_handler *)data; - -- netlink_events_debug(type, monh->debug_mask); -+ netlink_events_debug(type, monh->ctx->nft->debug_mask); - netlink_events_cache_update(monh, nlh, type); - - if (!(monh->monitor_flags & (1 << type))) -@@ -901,11 +903,9 @@ int netlink_echo_callback(const struct nlmsghdr *nlh, void *data) - .loc = &netlink_location, - .monitor_flags = 0xffffffff, - .cache_needed = true, -- .cache = ctx->cache, -- .debug_mask = ctx->debug_mask, - }; - -- if (!echo_monh.ctx->octx->echo) -+ if (!echo_monh.ctx->nft->output.echo) - return MNL_CB_OK; - - return netlink_events_cb(nlh, &echo_monh); -@@ -929,7 +929,7 @@ int netlink_monitor(struct netlink_mon_handler *monhandler, - return -1; - } - -- return mnl_nft_event_listener(nf_sock, monhandler->debug_mask, -- monhandler->ctx->octx, netlink_events_cb, -- monhandler); -+ return mnl_nft_event_listener(nf_sock, monhandler->ctx->nft->debug_mask, -+ &monhandler->ctx->nft->output, -+ netlink_events_cb, monhandler); - } -diff --git a/src/netlink.c b/src/netlink.c -index 4fd3f2dfefced..e16eb504fdef8 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -42,7 +42,7 @@ - #include - #include - --#define nft_mon_print(monh, ...) nft_print(monh->ctx->octx, __VA_ARGS__) -+#define nft_mon_print(monh, ...) nft_print(&monh->ctx->nft->output, __VA_ARGS__) - - const struct input_descriptor indesc_netlink = { - .name = "netlink", -@@ -475,10 +475,8 @@ int netlink_replace_rule_batch(struct netlink_ctx *ctx, const struct cmd *cmd) - struct nftnl_rule *nlr; - int err, flags = 0; - -- if (ctx->octx->echo) { -- err = cache_update(ctx->nf_sock, ctx->cache, -- CMD_INVALID, ctx->msgs, -- ctx->debug_mask, ctx->octx); -+ if (ctx->nft->output.echo) { -+ err = cache_update(ctx->nft, CMD_INVALID, ctx->msgs); - if (err < 0) - return err; - -@@ -507,9 +505,9 @@ int netlink_del_rule_batch(struct netlink_ctx *ctx, const struct cmd *cmd) - - void netlink_dump_rule(const struct nftnl_rule *nlr, struct netlink_ctx *ctx) - { -- FILE *fp = ctx->octx->output_fp; -+ FILE *fp = ctx->nft->output.output_fp; - -- if (!(ctx->debug_mask & NFT_DEBUG_NETLINK) || !fp) -+ if (!(ctx->nft->debug_mask & NFT_DEBUG_NETLINK) || !fp) - return; - - nftnl_rule_fprintf(fp, nlr, 0, 0); -@@ -575,9 +573,9 @@ static int netlink_flush_rules(struct netlink_ctx *ctx, const struct cmd *cmd) - - void netlink_dump_chain(const struct nftnl_chain *nlc, struct netlink_ctx *ctx) - { -- FILE *fp = ctx->octx->output_fp; -+ FILE *fp = ctx->nft->output.output_fp; - -- if (!(ctx->debug_mask & NFT_DEBUG_NETLINK) || !fp) -+ if (!(ctx->nft->debug_mask & NFT_DEBUG_NETLINK) || !fp) - return; - - nftnl_chain_fprintf(fp, nlc, 0, 0); -@@ -837,9 +835,9 @@ static const struct datatype *dtype_map_from_kernel(enum nft_data_types type) - - void netlink_dump_set(const struct nftnl_set *nls, struct netlink_ctx *ctx) - { -- FILE *fp = ctx->octx->output_fp; -+ FILE *fp = ctx->nft->output.output_fp; - -- if (!(ctx->debug_mask & NFT_DEBUG_NETLINK) || !fp) -+ if (!(ctx->nft->debug_mask & NFT_DEBUG_NETLINK) || !fp) - return; - - nftnl_set_fprintf(fp, nls, 0, 0); -@@ -1291,7 +1289,7 @@ out: - static int list_setelem_cb(struct nftnl_set_elem *nlse, void *arg) - { - struct netlink_ctx *ctx = arg; -- return netlink_delinearize_setelem(nlse, ctx->set, ctx->cache); -+ return netlink_delinearize_setelem(nlse, ctx->set, &ctx->nft->cache); - } - - int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, -@@ -1362,9 +1360,9 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, - - void netlink_dump_obj(struct nftnl_obj *nln, struct netlink_ctx *ctx) - { -- FILE *fp = ctx->octx->output_fp; -+ FILE *fp = ctx->nft->output.output_fp; - -- if (!(ctx->debug_mask & NFT_DEBUG_NETLINK) || !fp) -+ if (!(ctx->nft->debug_mask & NFT_DEBUG_NETLINK) || !fp) - return; - - nftnl_obj_fprintf(fp, nln, 0, 0); -@@ -1476,9 +1474,9 @@ static struct nftnl_flowtable *alloc_nftnl_flowtable(const struct handle *h, - static void netlink_dump_flowtable(struct nftnl_flowtable *flo, - struct netlink_ctx *ctx) - { -- FILE *fp = ctx->octx->output_fp; -+ FILE *fp = ctx->nft->output.output_fp; - -- if (!(ctx->debug_mask & NFT_DEBUG_NETLINK) || !fp) -+ if (!(ctx->nft->debug_mask & NFT_DEBUG_NETLINK) || !fp) - return; - - nftnl_flowtable_fprintf(fp, flo, 0, 0); -@@ -1930,16 +1928,17 @@ int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type, - case NFT_TRACETYPE_RULE: - if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) || - nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER)) -- trace_print_packet(nlt, monh->ctx->octx); -+ trace_print_packet(nlt, &monh->ctx->nft->output); - - if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) -- trace_print_rule(nlt, monh->ctx->octx, monh->cache); -+ trace_print_rule(nlt, &monh->ctx->nft->output, -+ &monh->ctx->nft->cache); - break; - case NFT_TRACETYPE_POLICY: -- trace_print_hdr(nlt, monh->ctx->octx); -+ trace_print_hdr(nlt, &monh->ctx->nft->output); - - if (nftnl_trace_is_set(nlt, NFTNL_TRACE_POLICY)) { -- trace_print_policy(nlt, monh->ctx->octx); -+ trace_print_policy(nlt, &monh->ctx->nft->output); - nft_mon_print(monh, " "); - } - -@@ -1947,14 +1946,14 @@ int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type, - trace_print_expr(nlt, NFTNL_TRACE_MARK, - meta_expr_alloc(&netlink_location, - NFT_META_MARK), -- monh->ctx->octx); -+ &monh->ctx->nft->output); - nft_mon_print(monh, "\n"); - break; - case NFT_TRACETYPE_RETURN: -- trace_print_hdr(nlt, monh->ctx->octx); -+ trace_print_hdr(nlt, &monh->ctx->nft->output); - - if (nftnl_trace_is_set(nlt, NFTNL_TRACE_VERDICT)) { -- trace_print_verdict(nlt, monh->ctx->octx); -+ trace_print_verdict(nlt, &monh->ctx->nft->output); - nft_mon_print(monh, " "); - } - -@@ -1962,7 +1961,7 @@ int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type, - trace_print_expr(nlt, NFTNL_TRACE_MARK, - meta_expr_alloc(&netlink_location, - NFT_META_MARK), -- monh->ctx->octx); -+ &monh->ctx->nft->output); - nft_mon_print(monh, "\n"); - break; - } -diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c -index ae84512c56f3a..bf990e9e979d5 100644 ---- a/src/netlink_delinearize.c -+++ b/src/netlink_delinearize.c -@@ -2508,7 +2508,7 @@ struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx, - - memset(&_ctx, 0, sizeof(_ctx)); - _ctx.msgs = ctx->msgs; -- _ctx.debug_mask = ctx->debug_mask; -+ _ctx.debug_mask = ctx->nft->debug_mask; - - memset(&h, 0, sizeof(h)); - h.family = nftnl_rule_get_u32(nlr, NFTNL_RULE_FAMILY); -@@ -2520,7 +2520,7 @@ struct rule *netlink_delinearize_rule(struct netlink_ctx *ctx, - h.position.id = nftnl_rule_get_u64(nlr, NFTNL_RULE_POSITION); - - pctx->rule = rule_alloc(&netlink_location, &h); -- pctx->table = table_lookup(&h, ctx->cache); -+ pctx->table = table_lookup(&h, &ctx->nft->cache); - assert(pctx->table != NULL); - - if (nftnl_rule_is_set(nlr, NFTNL_RULE_USERDATA)) { -diff --git a/src/rule.c b/src/rule.c -index 3b5468d00e79c..6acfa3ac1695c 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -86,7 +86,7 @@ static int cache_init_objects(struct netlink_ctx *ctx, enum cmd_ops cmd) - struct set *set; - int ret; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - ret = netlink_list_sets(ctx, &table->handle); - list_splice_tail_init(&ctx->list, &table->sets); - -@@ -141,7 +141,7 @@ static int cache_init(struct netlink_ctx *ctx, enum cmd_ops cmd) - }; - int ret; - -- ret = cache_init_tables(ctx, &handle, ctx->cache); -+ ret = cache_init_tables(ctx, &handle, &ctx->nft->cache); - if (ret < 0) - return ret; - ret = cache_init_objects(ctx, cmd); -@@ -151,20 +151,18 @@ static int cache_init(struct netlink_ctx *ctx, enum cmd_ops cmd) - return 0; - } - --int cache_update(struct mnl_socket *nf_sock, struct nft_cache *cache, -- enum cmd_ops cmd, struct list_head *msgs, unsigned int debug_mask, -- struct output_ctx *octx) -+int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) - { - uint16_t genid; - int ret; - struct netlink_ctx ctx = { - .list = LIST_HEAD_INIT(ctx.list), -- .nf_sock = nf_sock, -- .cache = cache, -+ .nft = nft, - .msgs = msgs, -- .debug_mask = debug_mask, -- .octx = octx, -+ .nft = nft, - }; -+ struct mnl_socket *nf_sock = nft->nf_sock; -+ struct nft_cache *cache = &nft->cache; - - replay: - ctx.seqnum = cache->seqnum++; -@@ -197,18 +195,14 @@ static void __cache_flush(struct list_head *table_list) - } - } - --void cache_flush(struct mnl_socket *nf_sock, struct nft_cache *cache, -- enum cmd_ops cmd, struct list_head *msgs, -- unsigned int debug_mask, struct output_ctx *octx) -+void cache_flush(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) - { - struct netlink_ctx ctx = { - .list = LIST_HEAD_INIT(ctx.list), -- .nf_sock = nf_sock, -- .cache = cache, -+ .nft = nft, - .msgs = msgs, -- .debug_mask = debug_mask, -- .octx = octx, - }; -+ struct nft_cache *cache = &nft->cache; - - __cache_flush(&cache->list); - cache->genid = netlink_genid_get(&ctx); -@@ -1121,12 +1115,12 @@ static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd, - struct table *table; - struct set *set; - -- table = table_lookup(h, ctx->cache); -+ table = table_lookup(h, &ctx->nft->cache); - set = set_lookup(table, h->set.name); - - if (set->flags & NFT_SET_INTERVAL && - set_to_intervals(ctx->msgs, set, init, true, -- ctx->debug_mask, set->automerge) < 0) -+ ctx->nft->debug_mask, set->automerge) < 0) - return -1; - - return __do_add_setelems(ctx, h, set, init, flags); -@@ -1140,7 +1134,7 @@ static int do_add_set(struct netlink_ctx *ctx, const struct cmd *cmd, - if (set->init != NULL) { - if (set->flags & NFT_SET_INTERVAL && - set_to_intervals(ctx->msgs, set, set->init, true, -- ctx->debug_mask, set->automerge) < 0) -+ ctx->nft->debug_mask, set->automerge) < 0) - return -1; - } - if (netlink_add_set_batch(ctx, cmd, flags) < 0) -@@ -1156,11 +1150,10 @@ static int do_command_add(struct netlink_ctx *ctx, struct cmd *cmd, bool excl) - { - uint32_t flags = excl ? NLM_F_EXCL : 0; - -- if (ctx->octx->echo) { -+ if (ctx->nft->output.echo) { - int ret; - -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->obj, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft, cmd->obj, ctx->msgs); - if (ret < 0) - return ret; - -@@ -1206,11 +1199,10 @@ static int do_command_insert(struct netlink_ctx *ctx, struct cmd *cmd) - { - uint32_t flags = 0; - -- if (ctx->octx->echo) { -+ if (ctx->nft->output.echo) { - int ret; - -- ret = cache_update(ctx->nf_sock, ctx->cache, cmd->obj, -- ctx->msgs, ctx->debug_mask, ctx->octx); -+ ret = cache_update(ctx->nft, cmd->obj, ctx->msgs); - if (ret < 0) - return ret; - -@@ -1233,12 +1225,12 @@ static int do_delete_setelems(struct netlink_ctx *ctx, struct cmd *cmd) - struct table *table; - struct set *set; - -- table = table_lookup(h, ctx->cache); -+ table = table_lookup(h, &ctx->nft->cache); - set = set_lookup(table, h->set.name); - - if (set->flags & NFT_SET_INTERVAL && - set_to_intervals(ctx->msgs, set, expr, false, -- ctx->debug_mask, set->automerge) < 0) -+ ctx->nft->debug_mask, set->automerge) < 0) - return -1; - - if (netlink_delete_setelems_batch(ctx, cmd) < 0) -@@ -1278,7 +1270,7 @@ static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd) - static int do_command_export(struct netlink_ctx *ctx, struct cmd *cmd) - { - struct nftnl_ruleset *rs; -- FILE *fp = ctx->octx->output_fp; -+ FILE *fp = ctx->nft->output.output_fp; - - do { - rs = netlink_dump_ruleset(ctx, &cmd->handle, &cmd->location); -@@ -1288,7 +1280,7 @@ static int do_command_export(struct netlink_ctx *ctx, struct cmd *cmd) - - nftnl_ruleset_fprintf(fp, rs, cmd->markup->format, NFTNL_OF_EVENT_NEW); - -- nft_print(ctx->octx, "\n"); -+ nft_print(&ctx->nft->output, "\n"); - - nftnl_ruleset_free(rs); - return 0; -@@ -1319,7 +1311,7 @@ static int do_command_import(struct netlink_ctx *ctx, struct cmd *cmd) - static int do_list_table(struct netlink_ctx *ctx, struct cmd *cmd, - struct table *table) - { -- table_print(table, ctx->octx); -+ table_print(table, &ctx->nft->output); - return 0; - } - -@@ -1333,12 +1325,12 @@ static int do_list_sets(struct netlink_ctx *ctx, struct cmd *cmd) - struct table *table; - struct set *set; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; - -- nft_print(ctx->octx, "table %s %s {\n", -+ nft_print(&ctx->nft->output, "table %s %s {\n", - family2str(table->handle.family), - table->handle.table.name); - -@@ -1353,11 +1345,11 @@ static int do_list_sets(struct netlink_ctx *ctx, struct cmd *cmd) - if (cmd->obj == CMD_OBJ_MAPS && - !(set->flags & NFT_SET_MAP)) - continue; -- set_print_declaration(set, &opts, ctx->octx); -- nft_print(ctx->octx, "%s}%s", opts.tab, opts.nl); -+ set_print_declaration(set, &opts, &ctx->nft->output); -+ nft_print(&ctx->nft->output, "%s}%s", opts.tab, opts.nl); - } - -- nft_print(ctx->octx, "}\n"); -+ nft_print(&ctx->nft->output, "}\n"); - } - return 0; - } -@@ -1588,14 +1580,14 @@ static int do_list_obj(struct netlink_ctx *ctx, struct cmd *cmd, uint32_t type) - struct table *table; - struct obj *obj; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; - - if (cmd->handle.table.name != NULL && - !strcmp(cmd->handle.table.name, table->handle.table.name)) { -- nft_print(ctx->octx, "table %s %s {\n", -+ nft_print(&ctx->nft->output, "table %s %s {\n", - family2str(table->handle.family), - cmd->handle.table.name); - } else -@@ -1607,10 +1599,10 @@ static int do_list_obj(struct netlink_ctx *ctx, struct cmd *cmd, uint32_t type) - strcmp(cmd->handle.obj.name, obj->handle.obj.name))) - continue; - -- obj_print_declaration(obj, &opts, ctx->octx); -+ obj_print_declaration(obj, &opts, &ctx->nft->output); - } - -- nft_print(ctx->octx, "}\n"); -+ nft_print(&ctx->nft->output, "}\n"); - } - return 0; - } -@@ -1705,21 +1697,21 @@ static int do_list_flowtables(struct netlink_ctx *ctx, struct cmd *cmd) - struct flowtable *flowtable; - struct table *table; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; - -- nft_print(ctx->octx, "table %s %s {\n", -+ nft_print(&ctx->nft->output, "table %s %s {\n", - family2str(table->handle.family), - table->handle.table.name); - - list_for_each_entry(flowtable, &table->flowtables, list) { -- flowtable_print_declaration(flowtable, &opts, ctx->octx); -- nft_print(ctx->octx, "%s}%s", opts.tab, opts.nl); -+ flowtable_print_declaration(flowtable, &opts, &ctx->nft->output); -+ nft_print(&ctx->nft->output, "%s}%s", opts.tab, opts.nl); - } - -- nft_print(ctx->octx, "}\n"); -+ nft_print(&ctx->nft->output, "}\n"); - } - return 0; - } -@@ -1729,7 +1721,7 @@ static int do_list_ruleset(struct netlink_ctx *ctx, struct cmd *cmd) - unsigned int family = cmd->handle.family; - struct table *table; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (family != NFPROTO_UNSPEC && - table->handle.family != family) - continue; -@@ -1750,12 +1742,12 @@ static int do_list_tables(struct netlink_ctx *ctx, struct cmd *cmd) - { - struct table *table; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; - -- nft_print(ctx->octx, "table %s %s\n", -+ nft_print(&ctx->nft->output, "table %s %s\n", - family2str(table->handle.family), - table->handle.table.name); - } -@@ -1776,17 +1768,17 @@ static int do_list_chain(struct netlink_ctx *ctx, struct cmd *cmd, - { - struct chain *chain; - -- table_print_declaration(table, ctx->octx); -+ table_print_declaration(table, &ctx->nft->output); - - list_for_each_entry(chain, &table->chains, list) { - if (chain->handle.family != cmd->handle.family || - strcmp(cmd->handle.chain.name, chain->handle.chain.name) != 0) - continue; - -- chain_print(chain, ctx->octx); -+ chain_print(chain, &ctx->nft->output); - } - -- nft_print(ctx->octx, "}\n"); -+ nft_print(&ctx->nft->output, "}\n"); - - return 0; - } -@@ -1796,18 +1788,18 @@ static int do_list_chains(struct netlink_ctx *ctx, struct cmd *cmd) - struct table *table; - struct chain *chain; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; - -- table_print_declaration(table, ctx->octx); -+ table_print_declaration(table, &ctx->nft->output); - - list_for_each_entry(chain, &table->chains, list) { -- chain_print_declaration(chain, ctx->octx); -- nft_print(ctx->octx, "\t}\n"); -+ chain_print_declaration(chain, &ctx->nft->output); -+ nft_print(&ctx->nft->output, "\t}\n"); - } -- nft_print(ctx->octx, "}\n"); -+ nft_print(&ctx->nft->output, "}\n"); - } - - return 0; -@@ -1816,9 +1808,9 @@ static int do_list_chains(struct netlink_ctx *ctx, struct cmd *cmd) - static void __do_list_set(struct netlink_ctx *ctx, struct cmd *cmd, - struct table *table, struct set *set) - { -- table_print_declaration(table, ctx->octx); -- set_print(set, ctx->octx); -- nft_print(ctx->octx, "}\n"); -+ table_print_declaration(table, &ctx->nft->output); -+ set_print(set, &ctx->nft->output); -+ nft_print(&ctx->nft->output, "}\n"); - } - - static int do_list_set(struct netlink_ctx *ctx, struct cmd *cmd, -@@ -1839,11 +1831,11 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd) - { - struct table *table = NULL; - -- if (ctx->octx->json) -+ if (ctx->nft->output.json) - return do_command_list_json(ctx, cmd); - - if (cmd->handle.table.name != NULL) -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - - switch (cmd->obj) { - case CMD_OBJ_TABLE: -@@ -1925,7 +1917,7 @@ static int do_command_get(struct netlink_ctx *ctx, struct cmd *cmd) - struct table *table = NULL; - - if (cmd->handle.table.name != NULL) -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - - switch (cmd->obj) { - case CMD_OBJ_SETELEM: -@@ -1964,7 +1956,7 @@ static int do_command_reset(struct netlink_ctx *ctx, struct cmd *cmd) - - ret = netlink_reset_objs(ctx, cmd, type, dump); - list_for_each_entry_safe(obj, next, &ctx->list, list) { -- table = table_lookup(&obj->handle, ctx->cache); -+ table = table_lookup(&obj->handle, &ctx->nft->cache); - list_move(&obj->list, &table->objs); - } - if (ret < 0) -@@ -1994,7 +1986,7 @@ static int do_command_flush(struct netlink_ctx *ctx, struct cmd *cmd) - - static int do_command_rename(struct netlink_ctx *ctx, struct cmd *cmd) - { -- struct table *table = table_lookup(&cmd->handle, ctx->cache); -+ struct table *table = table_lookup(&cmd->handle, &ctx->nft->cache); - struct chain *chain; - - switch (cmd->obj) { -@@ -2034,8 +2026,8 @@ static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd) - .format = cmd->monitor->format, - .ctx = ctx, - .loc = &cmd->location, -- .cache = ctx->cache, -- .debug_mask = ctx->debug_mask, -+ .cache = &ctx->nft->cache, -+ .debug_mask = ctx->nft->debug_mask, - }; - - monhandler.cache_needed = need_cache(cmd); -@@ -2044,7 +2036,7 @@ static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd) - struct chain *chain; - int ret; - -- list_for_each_entry(t, &ctx->cache->list, list) { -+ list_for_each_entry(t, &ctx->nft->cache.list, list) { - list_for_each_entry(s, &t->sets, list) - s->init = set_expr_alloc(&cmd->location, s); - -@@ -2070,7 +2062,7 @@ static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd) - } - } - -- return netlink_monitor(&monhandler, ctx->nf_sock); -+ return netlink_monitor(&monhandler, ctx->nft->nf_sock); - } - - static int do_command_describe(struct netlink_ctx *ctx, struct cmd *cmd, -@@ -2129,7 +2121,7 @@ int do_command(struct netlink_ctx *ctx, struct cmd *cmd) - case CMD_MONITOR: - return do_command_monitor(ctx, cmd); - case CMD_DESCRIBE: -- return do_command_describe(ctx, cmd, ctx->octx); -+ return do_command_describe(ctx, cmd, &ctx->nft->output); - default: - BUG("invalid command object type %u\n", cmd->obj); - } --- -2.21.0 - diff --git a/SOURCES/0020-netlink-reset-mnl_socket-field-in-struct-nft_ctx-on-.patch b/SOURCES/0020-netlink-reset-mnl_socket-field-in-struct-nft_ctx-on-.patch deleted file mode 100644 index 688c3c8..0000000 --- a/SOURCES/0020-netlink-reset-mnl_socket-field-in-struct-nft_ctx-on-.patch +++ /dev/null @@ -1,75 +0,0 @@ -From c8b6092b4fec23b823695c0c9b10325f9c33150c Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 22 Oct 2018 21:20:44 +0200 -Subject: [PATCH] netlink: reset mnl_socket field in struct nft_ctx on EINTR - -Otherwise we keep using the old netlink socket if we hit EINTR. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit d7ef1e206bd9b36607dddcf337fada11d743b61f) - -Conflicts: - include/netlink.h --> Missing upstream commit 0562beb6544d3 ("src: get rid of netlink_genid_get()") - -Signed-off-by: Phil Sutter ---- - include/netlink.h | 2 +- - src/netlink.c | 4 ++-- - src/rule.c | 3 +-- - 3 files changed, 4 insertions(+), 5 deletions(-) - -diff --git a/include/netlink.h b/include/netlink.h -index 31465ff16822e..894bf6fc98487 100644 ---- a/include/netlink.h -+++ b/include/netlink.h -@@ -191,7 +191,7 @@ extern void netlink_dump_obj(struct nftnl_obj *nlo, struct netlink_ctx *ctx); - extern int netlink_batch_send(struct netlink_ctx *ctx, struct list_head *err_list); - - extern uint16_t netlink_genid_get(struct netlink_ctx *ctx); --extern void netlink_restart(struct mnl_socket *nf_sock); -+extern struct mnl_socket *netlink_restart(struct mnl_socket *nf_sock); - #define netlink_abi_error() \ - __netlink_abi_error(__FILE__, __LINE__, strerror(errno)); - extern void __noreturn __netlink_abi_error(const char *file, int line, const char *reason); -diff --git a/src/netlink.c b/src/netlink.c -index e16eb504fdef8..c178be3c9ee26 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -73,10 +73,10 @@ void netlink_close_sock(struct mnl_socket *nf_sock) - mnl_socket_close(nf_sock); - } - --void netlink_restart(struct mnl_socket *nf_sock) -+struct mnl_socket *netlink_restart(struct mnl_socket *nf_sock) - { - netlink_close_sock(nf_sock); -- nf_sock = netlink_open_sock(); -+ return netlink_open_sock(); - } - - uint16_t netlink_genid_get(struct netlink_ctx *ctx) -diff --git a/src/rule.c b/src/rule.c -index 6acfa3ac1695c..47b0d30cbed18 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -161,7 +161,6 @@ int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) - .msgs = msgs, - .nft = nft, - }; -- struct mnl_socket *nf_sock = nft->nf_sock; - struct nft_cache *cache = &nft->cache; - - replay: -@@ -176,7 +175,7 @@ replay: - if (ret < 0) { - cache_release(cache); - if (errno == EINTR) { -- netlink_restart(nf_sock); -+ nft->nf_sock = netlink_restart(nft->nf_sock); - goto replay; - } - return -1; --- -2.21.0 - diff --git a/SOURCES/0020-src-Add-support-for-NFTNL_SET_DESC_CONCAT.patch b/SOURCES/0020-src-Add-support-for-NFTNL_SET_DESC_CONCAT.patch new file mode 100644 index 0000000..663f661 --- /dev/null +++ b/SOURCES/0020-src-Add-support-for-NFTNL_SET_DESC_CONCAT.patch @@ -0,0 +1,181 @@ +From c8a5da2f527c85ab7c392cd293ff37d02a3f93a7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 13 Feb 2020 17:48:18 +0100 +Subject: [PATCH] src: Add support for NFTNL_SET_DESC_CONCAT + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795224 +Upstream Status: nftables commit 6156ba34018dd +Conflicts: Context change in src/mnl.c due to missing commit + 6e48df5329eab ("src: add "typeof" build/parse/print support") + +commit 6156ba34018dddd59cb6737cfd5a69a0cbc5eaa4 +Author: Stefano Brivio +Date: Thu Jan 30 01:16:56 2020 +0100 + + src: Add support for NFTNL_SET_DESC_CONCAT + + To support arbitrary range concatenations, the kernel needs to know + how long each field in the concatenation is. The new libnftnl + NFTNL_SET_DESC_CONCAT set attribute describes this as an array of + lengths, in bytes, of concatenated fields. + + While evaluating concatenated expressions, export the datatype size + into the new field_len array, and hand the data over via libnftnl. + + Similarly, when data is passed back from libnftnl, parse it into + the set description. + + When set data is cloned, we now need to copy the additional fields + in set_clone(), too. + + This change depends on the libnftnl patch with title: + set: Add support for NFTA_SET_DESC_CONCAT attributes + + v4: No changes + v3: Rework to use set description data instead of a stand-alone + attribute + v2: No changes + + Signed-off-by: Stefano Brivio + Signed-off-by: Pablo Neira Ayuso +--- + include/expression.h | 2 ++ + include/rule.h | 6 +++++- + src/evaluate.c | 14 +++++++++++--- + src/mnl.c | 7 +++++++ + src/netlink.c | 11 +++++++++++ + src/rule.c | 2 +- + 6 files changed, 37 insertions(+), 5 deletions(-) + +diff --git a/include/expression.h b/include/expression.h +index 717b675..ee726aa 100644 +--- a/include/expression.h ++++ b/include/expression.h +@@ -256,6 +256,8 @@ struct expr { + struct list_head expressions; + unsigned int size; + uint32_t set_flags; ++ uint8_t field_len[NFT_REG32_COUNT]; ++ uint8_t field_count; + }; + struct { + /* EXPR_SET_REF */ +diff --git a/include/rule.h b/include/rule.h +index 47eb29f..c03b0b8 100644 +--- a/include/rule.h ++++ b/include/rule.h +@@ -290,7 +290,9 @@ extern struct rule *rule_lookup_by_index(const struct chain *chain, + * @rg_cache: cached range element (left) + * @policy: set mechanism policy + * @automerge: merge adjacents and overlapping elements, if possible +- * @desc: set mechanism desc ++ * @desc.size: count of set elements ++ * @desc.field_len: length of single concatenated fields, bytes ++ * @desc.field_count: count of concatenated fields + */ + struct set { + struct list_head list; +@@ -310,6 +312,8 @@ struct set { + bool automerge; + struct { + uint32_t size; ++ uint8_t field_len[NFT_REG32_COUNT]; ++ uint8_t field_count; + } desc; + }; + +diff --git a/src/evaluate.c b/src/evaluate.c +index a865902..58f458d 100644 +--- a/src/evaluate.c ++++ b/src/evaluate.c +@@ -1216,6 +1216,8 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr, + struct expr *i, *next; + + list_for_each_entry_safe(i, next, &(*expr)->expressions, list) { ++ unsigned dsize_bytes; ++ + if (expr_is_constant(*expr) && dtype && off == 0) + return expr_binary_error(ctx->msgs, i, *expr, + "unexpected concat component, " +@@ -1240,6 +1242,9 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr, + i->dtype->name); + + ntype = concat_subtype_add(ntype, i->dtype->type); ++ ++ dsize_bytes = div_round_up(i->dtype->size, BITS_PER_BYTE); ++ (*expr)->field_len[(*expr)->field_count++] = dsize_bytes; + } + + (*expr)->flags |= flags; +@@ -3321,9 +3326,12 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) + "specified in %s definition", + set->key->dtype->name, type); + } +- if (set->flags & NFT_SET_INTERVAL && +- set->key->etype == EXPR_CONCAT) +- return set_error(ctx, set, "concatenated types not supported in interval sets"); ++ ++ if (set->flags & NFT_SET_INTERVAL && set->key->etype == EXPR_CONCAT) { ++ memcpy(&set->desc.field_len, &set->key->field_len, ++ sizeof(set->desc.field_len)); ++ set->desc.field_count = set->key->field_count; ++ } + + if (set_is_datamap(set->flags)) { + if (set->datatype == NULL) +diff --git a/src/mnl.c b/src/mnl.c +index aa5b0b4..221ee05 100644 +--- a/src/mnl.c ++++ b/src/mnl.c +@@ -881,6 +881,13 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd, + set->automerge)) + memory_allocation_error(); + ++ if (set->desc.field_len[0]) { ++ nftnl_set_set_data(nls, NFTNL_SET_DESC_CONCAT, ++ set->desc.field_len, ++ set->desc.field_count * ++ sizeof(set->desc.field_len[0])); ++ } ++ + nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf), + nftnl_udata_buf_len(udbuf)); + nftnl_udata_buf_free(udbuf); +diff --git a/src/netlink.c b/src/netlink.c +index 486e124..83d863c 100644 +--- a/src/netlink.c ++++ b/src/netlink.c +@@ -672,6 +672,17 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx, + if (nftnl_set_is_set(nls, NFTNL_SET_DESC_SIZE)) + set->desc.size = nftnl_set_get_u32(nls, NFTNL_SET_DESC_SIZE); + ++ if (nftnl_set_is_set(nls, NFTNL_SET_DESC_CONCAT)) { ++ uint32_t len = NFT_REG32_COUNT; ++ const uint8_t *data; ++ ++ data = nftnl_set_get_data(nls, NFTNL_SET_DESC_CONCAT, &len); ++ if (data) { ++ memcpy(set->desc.field_len, data, len); ++ set->desc.field_count = len; ++ } ++ } ++ + return set; + } + +diff --git a/src/rule.c b/src/rule.c +index 3ca1805..4669577 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -337,7 +337,7 @@ struct set *set_clone(const struct set *set) + new_set->objtype = set->objtype; + new_set->policy = set->policy; + new_set->automerge = set->automerge; +- new_set->desc.size = set->desc.size; ++ new_set->desc = set->desc; + + return new_set; + } +-- +1.8.3.1 + diff --git a/SOURCES/0021-src-Add-support-for-concatenated-set-ranges.patch b/SOURCES/0021-src-Add-support-for-concatenated-set-ranges.patch new file mode 100644 index 0000000..00f8f9e --- /dev/null +++ b/SOURCES/0021-src-Add-support-for-concatenated-set-ranges.patch @@ -0,0 +1,577 @@ +From 7b1f98e90a32865faca9a97f4348f20c753cd2f3 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Fri, 14 Feb 2020 14:51:33 +0100 +Subject: [PATCH] src: Add support for concatenated set ranges + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1795224 +Upstream Status: nftables commit 8ac2f3b2fca38 + +commit 8ac2f3b2fca38b6533043b0678730c10ba4dc5ef +Author: Stefano Brivio +Date: Thu Jan 30 01:16:57 2020 +0100 + + src: Add support for concatenated set ranges + + After exporting field lengths via NFTNL_SET_DESC_CONCAT attributes, + we now need to adjust parsing of user input and generation of + netlink key data to complete support for concatenation of set + ranges. + + Instead of using separate elements for start and end of a range, + denoting the end element by the NFT_SET_ELEM_INTERVAL_END flag, + as it's currently done for ranges without concatenation, we'll use + the new attribute NFTNL_SET_ELEM_KEY_END as suggested by Pablo. It + behaves in the same way as NFTNL_SET_ELEM_KEY, but it indicates + that the included key represents the upper bound of a range. + + For example, "packets with an IPv4 address between 192.0.2.0 and + 192.0.2.42, with destination port between 22 and 25", needs to be + expressed as a single element with two keys: + + NFTA_SET_ELEM_KEY: 192.0.2.0 . 22 + NFTA_SET_ELEM_KEY_END: 192.0.2.42 . 25 + + To achieve this, we need to: + + - adjust the lexer rules to allow multiton expressions as elements + of a concatenation. As wildcards are not allowed (semantics would + be ambiguous), exclude wildcards expressions from the set of + possible multiton expressions, and allow them directly where + needed. Concatenations now admit prefixes and ranges + + - generate, for each element in a range concatenation, a second key + attribute, that includes the upper bound for the range + + - also expand prefixes and non-ranged values in the concatenation + to ranges: given a set with interval and concatenation support, + the kernel has no way to tell which elements are ranged, so they + all need to be. For example, 192.0.2.0 . 192.0.2.9 : 1024 is + sent as: + + NFTA_SET_ELEM_KEY: 192.0.2.0 . 1024 + NFTA_SET_ELEM_KEY_END: 192.0.2.9 . 1024 + + - aggregate ranges when elements received by the kernel represent + concatenated ranges, see concat_range_aggregate() + + - perform a few minor adjustments where interval expressions + are already handled: we have intervals in these sets, but + the set specification isn't just an interval, so we can't + just aggregate and deaggregate interval ranges linearly + + v4: No changes + v3: + - rework to use a separate key for closing element of range instead of + a separate element with EXPR_F_INTERVAL_END set (Pablo Neira Ayuso) + v2: + - reworked netlink_gen_concat_data(), moved loop body to a new function, + netlink_gen_concat_data_expr() (Phil Sutter) + - dropped repeated pattern in bison file, replaced by a new helper, + compound_expr_alloc_or_add() (Phil Sutter) + - added set_is_nonconcat_range() helper (Phil Sutter) + - in expr_evaluate_set(), we need to set NFT_SET_SUBKEY also on empty + sets where the set in the context already has the flag + - dropped additional 'end' parameter from netlink_gen_data(), + temporarily set EXPR_F_INTERVAL_END on expressions and use that from + netlink_gen_concat_data() to figure out we need to add the 'end' + element (Phil Sutter) + - replace range_mask_len() by a simplified version, as we don't need + to actually store the composing masks of a range (Phil Sutter) + + Signed-off-by: Stefano Brivio + Signed-off-by: Pablo Neira Ayuso +--- + include/expression.h | 1 + + include/rule.h | 5 +++ + src/evaluate.c | 5 +++ + src/netlink.c | 109 +++++++++++++++++++++++++++++++++++------------ + src/parser_bison.y | 17 ++++++-- + src/rule.c | 13 +++--- + src/segtree.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 7 files changed, 229 insertions(+), 38 deletions(-) + +diff --git a/include/expression.h b/include/expression.h +index ee726aa..2e41aa0 100644 +--- a/include/expression.h ++++ b/include/expression.h +@@ -460,6 +460,7 @@ extern int set_to_intervals(struct list_head *msgs, struct set *set, + struct expr *init, bool add, + unsigned int debug_mask, bool merge, + struct output_ctx *octx); ++extern void concat_range_aggregate(struct expr *set); + extern void interval_map_decompose(struct expr *set); + + extern struct expr *get_set_intervals(const struct set *set, +diff --git a/include/rule.h b/include/rule.h +index c03b0b8..626973e 100644 +--- a/include/rule.h ++++ b/include/rule.h +@@ -372,6 +372,11 @@ static inline bool set_is_interval(uint32_t set_flags) + return set_flags & NFT_SET_INTERVAL; + } + ++static inline bool set_is_non_concat_range(struct set *s) ++{ ++ return (s->flags & NFT_SET_INTERVAL) && s->desc.field_count <= 1; ++} ++ + #include + + struct counter { +diff --git a/src/evaluate.c b/src/evaluate.c +index 58f458d..0c84816 100644 +--- a/src/evaluate.c ++++ b/src/evaluate.c +@@ -136,6 +136,11 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr, + + if ((*expr)->byteorder == byteorder) + return 0; ++ ++ /* Conversion for EXPR_CONCAT is handled for single composing ranges */ ++ if ((*expr)->etype == EXPR_CONCAT) ++ return 0; ++ + if (expr_basetype(*expr)->type != TYPE_INTEGER) + return expr_error(ctx->msgs, *expr, + "Byteorder mismatch: expected %s, got %s", +diff --git a/src/netlink.c b/src/netlink.c +index 83d863c..e0ba903 100644 +--- a/src/netlink.c ++++ b/src/netlink.c +@@ -98,10 +98,11 @@ struct nftnl_expr *alloc_nft_expr(const char *name) + static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set, + const struct expr *expr) + { +- const struct expr *elem, *key, *data; ++ const struct expr *elem, *data; + struct nftnl_set_elem *nlse; + struct nft_data_linearize nld; + struct nftnl_udata_buf *udbuf = NULL; ++ struct expr *key; + + nlse = nftnl_set_elem_alloc(); + if (nlse == NULL) +@@ -119,6 +120,16 @@ static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set, + + netlink_gen_data(key, &nld); + nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, &nld.value, nld.len); ++ ++ if (set->set_flags & NFT_SET_INTERVAL && expr->key->field_count > 1) { ++ key->flags |= EXPR_F_INTERVAL_END; ++ netlink_gen_data(key, &nld); ++ key->flags &= ~EXPR_F_INTERVAL_END; ++ ++ nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY_END, &nld.value, ++ nld.len); ++ } ++ + if (elem->timeout) + nftnl_set_elem_set_u64(nlse, NFTNL_SET_ELEM_TIMEOUT, + elem->timeout); +@@ -186,28 +197,58 @@ void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder, + data->len = len; + } + ++static int netlink_export_pad(unsigned char *data, const mpz_t v, ++ const struct expr *i) ++{ ++ mpz_export_data(data, v, i->byteorder, ++ div_round_up(i->len, BITS_PER_BYTE)); ++ ++ return netlink_padded_len(i->len) / BITS_PER_BYTE; ++} ++ ++static int netlink_gen_concat_data_expr(int end, const struct expr *i, ++ unsigned char *data) ++{ ++ switch (i->etype) { ++ case EXPR_RANGE: ++ i = end ? i->right : i->left; ++ break; ++ case EXPR_PREFIX: ++ if (end) { ++ int count; ++ mpz_t v; ++ ++ mpz_init_bitmask(v, i->len - i->prefix_len); ++ mpz_add(v, i->prefix->value, v); ++ count = netlink_export_pad(data, v, i); ++ mpz_clear(v); ++ return count; ++ } ++ return netlink_export_pad(data, i->prefix->value, i); ++ case EXPR_VALUE: ++ break; ++ default: ++ BUG("invalid expression type '%s' in set", expr_ops(i)->name); ++ } ++ ++ return netlink_export_pad(data, i->value, i); ++} ++ + static void netlink_gen_concat_data(const struct expr *expr, + struct nft_data_linearize *nld) + { ++ unsigned int len = expr->len / BITS_PER_BYTE, offset = 0; ++ int end = expr->flags & EXPR_F_INTERVAL_END; ++ unsigned char data[len]; + const struct expr *i; +- unsigned int len, offset; +- +- len = expr->len / BITS_PER_BYTE; +- if (1) { +- unsigned char data[len]; +- +- memset(data, 0, sizeof(data)); +- offset = 0; +- list_for_each_entry(i, &expr->expressions, list) { +- assert(i->etype == EXPR_VALUE); +- mpz_export_data(data + offset, i->value, i->byteorder, +- div_round_up(i->len, BITS_PER_BYTE)); +- offset += netlink_padded_len(i->len) / BITS_PER_BYTE; +- } + +- memcpy(nld->value, data, len); +- nld->len = len; +- } ++ memset(data, 0, len); ++ ++ list_for_each_entry(i, &expr->expressions, list) ++ offset += netlink_gen_concat_data_expr(end, i, data + offset); ++ ++ memcpy(nld->value, data, len); ++ nld->len = len; + } + + static void netlink_gen_constant_data(const struct expr *expr, +@@ -812,6 +853,7 @@ int netlink_delinearize_setelem(struct nftnl_set_elem *nlse, + if (nftnl_set_elem_is_set(nlse, NFTNL_SET_ELEM_FLAGS)) + flags = nftnl_set_elem_get_u32(nlse, NFTNL_SET_ELEM_FLAGS); + ++key_end: + key = netlink_alloc_value(&netlink_location, &nld); + datatype_set(key, set->key->dtype); + key->byteorder = set->key->byteorder; +@@ -880,6 +922,15 @@ int netlink_delinearize_setelem(struct nftnl_set_elem *nlse, + } + out: + compound_expr_add(set->init, expr); ++ ++ if (!(flags & NFT_SET_ELEM_INTERVAL_END) && ++ nftnl_set_elem_is_set(nlse, NFTNL_SET_ELEM_KEY_END)) { ++ flags |= NFT_SET_ELEM_INTERVAL_END; ++ nld.value = nftnl_set_elem_get(nlse, NFTNL_SET_ELEM_KEY_END, ++ &nld.len); ++ goto key_end; ++ } ++ + return 0; + } + +@@ -918,15 +969,16 @@ int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, + set->init = set_expr_alloc(&internal_location, set); + nftnl_set_elem_foreach(nls, list_setelem_cb, ctx); + +- if (!(set->flags & NFT_SET_INTERVAL)) ++ if (set->flags & NFT_SET_INTERVAL && set->desc.field_count > 1) ++ concat_range_aggregate(set->init); ++ else if (set->flags & NFT_SET_INTERVAL) ++ interval_map_decompose(set->init); ++ else + list_expr_sort(&ctx->set->init->expressions); + + nftnl_set_free(nls); + ctx->set = NULL; + +- if (set->flags & NFT_SET_INTERVAL) +- interval_map_decompose(set->init); +- + return 0; + } + +@@ -935,6 +987,7 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, + struct set *set, struct expr *init) + { + struct nftnl_set *nls, *nls_out = NULL; ++ int err = 0; + + nls = nftnl_set_alloc(); + if (nls == NULL) +@@ -958,18 +1011,18 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, + set->init = set_expr_alloc(loc, set); + nftnl_set_elem_foreach(nls_out, list_setelem_cb, ctx); + +- if (!(set->flags & NFT_SET_INTERVAL)) ++ if (set->flags & NFT_SET_INTERVAL && set->desc.field_count > 1) ++ concat_range_aggregate(set->init); ++ else if (set->flags & NFT_SET_INTERVAL) ++ err = get_set_decompose(table, set); ++ else + list_expr_sort(&ctx->set->init->expressions); + + nftnl_set_free(nls); + nftnl_set_free(nls_out); + ctx->set = NULL; + +- if (set->flags & NFT_SET_INTERVAL && +- get_set_decompose(table, set) < 0) +- return -1; +- +- return 0; ++ return err; + } + + void netlink_dump_obj(struct nftnl_obj *nln, struct netlink_ctx *ctx) +diff --git a/src/parser_bison.y b/src/parser_bison.y +index 0fd9b94..ea83f52 100644 +--- a/src/parser_bison.y ++++ b/src/parser_bison.y +@@ -3551,7 +3551,6 @@ range_rhs_expr : basic_rhs_expr DASH basic_rhs_expr + + multiton_rhs_expr : prefix_rhs_expr + | range_rhs_expr +- | wildcard_expr + ; + + map_expr : concat_expr MAP rhs_expr +@@ -3645,7 +3644,7 @@ set_elem_option : TIMEOUT time_spec + ; + + set_lhs_expr : concat_rhs_expr +- | multiton_rhs_expr ++ | wildcard_expr + ; + + set_rhs_expr : concat_rhs_expr +@@ -3898,7 +3897,7 @@ list_rhs_expr : basic_rhs_expr COMMA basic_rhs_expr + ; + + rhs_expr : concat_rhs_expr { $$ = $1; } +- | multiton_rhs_expr { $$ = $1; } ++ | wildcard_expr { $$ = $1; } + | set_expr { $$ = $1; } + | set_ref_symbol_expr { $$ = $1; } + ; +@@ -3939,7 +3938,17 @@ basic_rhs_expr : inclusive_or_rhs_expr + ; + + concat_rhs_expr : basic_rhs_expr +- | concat_rhs_expr DOT basic_rhs_expr ++ | multiton_rhs_expr ++ | concat_rhs_expr DOT multiton_rhs_expr ++ { ++ struct location rhs[] = { ++ [1] = @2, ++ [2] = @3, ++ }; ++ ++ $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); ++ } ++ | concat_rhs_expr DOT basic_rhs_expr + { + struct location rhs[] = { + [1] = @2, +diff --git a/src/rule.c b/src/rule.c +index 4669577..e18237b 100644 +--- a/src/rule.c ++++ b/src/rule.c +@@ -1512,7 +1512,8 @@ static int __do_add_setelems(struct netlink_ctx *ctx, struct set *set, + return -1; + + if (set->init != NULL && +- set->flags & NFT_SET_INTERVAL) { ++ set->flags & NFT_SET_INTERVAL && ++ set->desc.field_count <= 1) { + interval_map_decompose(expr); + list_splice_tail_init(&expr->expressions, &set->init->expressions); + set->init->size += expr->size; +@@ -1533,7 +1534,7 @@ static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd, + table = table_lookup(h, &ctx->nft->cache); + set = set_lookup(table, h->set.name); + +- if (set->flags & NFT_SET_INTERVAL && ++ if (set_is_non_concat_range(set) && + set_to_intervals(ctx->msgs, set, init, true, + ctx->nft->debug_mask, set->automerge, + &ctx->nft->output) < 0) +@@ -1548,7 +1549,7 @@ static int do_add_set(struct netlink_ctx *ctx, const struct cmd *cmd, + struct set *set = cmd->set; + + if (set->init != NULL) { +- if (set->flags & NFT_SET_INTERVAL && ++ if (set_is_non_concat_range(set) && + set_to_intervals(ctx->msgs, set, set->init, true, + ctx->nft->debug_mask, set->automerge, + &ctx->nft->output) < 0) +@@ -1634,7 +1635,7 @@ static int do_delete_setelems(struct netlink_ctx *ctx, struct cmd *cmd) + table = table_lookup(h, &ctx->nft->cache); + set = set_lookup(table, h->set.name); + +- if (set->flags & NFT_SET_INTERVAL && ++ if (set_is_non_concat_range(set) && + set_to_intervals(ctx->msgs, set, expr, false, + ctx->nft->debug_mask, set->automerge, + &ctx->nft->output) < 0) +@@ -2488,7 +2489,7 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, + set = set_lookup(table, cmd->handle.set.name); + + /* Create a list of elements based of what we got from command line. */ +- if (set->flags & NFT_SET_INTERVAL) ++ if (set_is_non_concat_range(set)) + init = get_set_intervals(set, cmd->expr); + else + init = cmd->expr; +@@ -2501,7 +2502,7 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, + if (err >= 0) + __do_list_set(ctx, cmd, table, new_set); + +- if (set->flags & NFT_SET_INTERVAL) ++ if (set_is_non_concat_range(set)) + expr_free(init); + + set_free(new_set); +diff --git a/src/segtree.c b/src/segtree.c +index 7217dbc..e859f84 100644 +--- a/src/segtree.c ++++ b/src/segtree.c +@@ -652,6 +652,11 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init) + set_elem_add(set, new_init, i->key->value, + i->flags, i->byteorder); + break; ++ case EXPR_CONCAT: ++ compound_expr_add(new_init, expr_clone(i)); ++ i->flags |= EXPR_F_INTERVAL_END; ++ compound_expr_add(new_init, expr_clone(i)); ++ break; + default: + range_expr_value_low(low, i); + set_elem_add(set, new_init, low, 0, i->byteorder); +@@ -823,6 +828,9 @@ static int expr_value_cmp(const void *p1, const void *p2) + struct expr *e2 = *(void * const *)p2; + int ret; + ++ if (expr_value(e1)->etype == EXPR_CONCAT) ++ return -1; ++ + ret = mpz_cmp(expr_value(e1)->value, expr_value(e2)->value); + if (ret == 0) { + if (e1->flags & EXPR_F_INTERVAL_END) +@@ -834,6 +842,115 @@ static int expr_value_cmp(const void *p1, const void *p2) + return ret; + } + ++/* Given start and end elements of a range, check if it can be represented as ++ * a single netmask, and if so, how long, by returning zero or a positive value. ++ */ ++static int range_mask_len(const mpz_t start, const mpz_t end, unsigned int len) ++{ ++ mpz_t tmp_start, tmp_end; ++ int ret; ++ ++ mpz_init_set_ui(tmp_start, mpz_get_ui(start)); ++ mpz_init_set_ui(tmp_end, mpz_get_ui(end)); ++ ++ while (mpz_cmp(tmp_start, tmp_end) <= 0 && ++ !mpz_tstbit(tmp_start, 0) && mpz_tstbit(tmp_end, 0) && ++ len--) { ++ mpz_fdiv_q_2exp(tmp_start, tmp_start, 1); ++ mpz_fdiv_q_2exp(tmp_end, tmp_end, 1); ++ } ++ ++ ret = !mpz_cmp(tmp_start, tmp_end) ? (int)len : -1; ++ ++ mpz_clear(tmp_start); ++ mpz_clear(tmp_end); ++ ++ return ret; ++} ++ ++/* Given a set with two elements (start and end), transform them into a ++ * concatenation of ranges. That is, from a list of start expressions and a list ++ * of end expressions, form a list of start - end expressions. ++ */ ++void concat_range_aggregate(struct expr *set) ++{ ++ struct expr *i, *start = NULL, *end, *r1, *r2, *next, *r1_next, *tmp; ++ struct list_head *r2_next; ++ int prefix_len, free_r1; ++ mpz_t range, p; ++ ++ list_for_each_entry_safe(i, next, &set->expressions, list) { ++ if (!start) { ++ start = i; ++ continue; ++ } ++ end = i; ++ ++ /* Walk over r1 (start expression) and r2 (end) in parallel, ++ * form ranges between corresponding r1 and r2 expressions, ++ * store them by replacing r2 expressions, and free r1 ++ * expressions. ++ */ ++ r2 = list_first_entry(&expr_value(end)->expressions, ++ struct expr, list); ++ list_for_each_entry_safe(r1, r1_next, ++ &expr_value(start)->expressions, ++ list) { ++ mpz_init(range); ++ mpz_init(p); ++ ++ r2_next = r2->list.next; ++ free_r1 = 0; ++ ++ if (!mpz_cmp(r1->value, r2->value)) { ++ free_r1 = 1; ++ goto next; ++ } ++ ++ mpz_sub(range, r2->value, r1->value); ++ mpz_sub_ui(range, range, 1); ++ mpz_and(p, r1->value, range); ++ ++ /* Check if we are forced, or if it's anyway preferable, ++ * to express the range as two points instead of a ++ * netmask. ++ */ ++ prefix_len = range_mask_len(r1->value, r2->value, ++ r1->len); ++ if (prefix_len < 0 || ++ !(r1->dtype->flags & DTYPE_F_PREFIX)) { ++ tmp = range_expr_alloc(&r1->location, r1, ++ r2); ++ ++ list_replace(&r2->list, &tmp->list); ++ r2_next = tmp->list.next; ++ } else { ++ tmp = prefix_expr_alloc(&r1->location, r1, ++ prefix_len); ++ tmp->len = r2->len; ++ ++ list_replace(&r2->list, &tmp->list); ++ r2_next = tmp->list.next; ++ expr_free(r2); ++ } ++ ++next: ++ mpz_clear(p); ++ mpz_clear(range); ++ ++ r2 = list_entry(r2_next, typeof(*r2), list); ++ compound_expr_remove(start, r1); ++ ++ if (free_r1) ++ expr_free(r1); ++ } ++ ++ compound_expr_remove(set, start); ++ expr_free(start); ++ start = NULL; ++ } ++} ++ + void interval_map_decompose(struct expr *set) + { + struct expr **elements, **ranges; +-- +1.8.3.1 + diff --git a/SOURCES/0021-src-remove-opts-field-from-struct-xt_stmt.patch b/SOURCES/0021-src-remove-opts-field-from-struct-xt_stmt.patch deleted file mode 100644 index 774c912..0000000 --- a/SOURCES/0021-src-remove-opts-field-from-struct-xt_stmt.patch +++ /dev/null @@ -1,71 +0,0 @@ -From ed4ceb7da31534de89df66d241d449c644fd3ec2 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Tue, 16 Oct 2018 20:56:57 +0200 -Subject: [PATCH] src: remove opts field from struct xt_stmt - -This is never used, ie. always NULL. - -Reported-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -Acked-by: Phil Sutter -(cherry picked from commit b274c169014e71715f9333ee028c5a9304881919) -Signed-off-by: Phil Sutter ---- - include/statement.h | 1 - - src/statement.c | 1 - - src/xt.c | 8 ++------ - 3 files changed, 2 insertions(+), 8 deletions(-) - -diff --git a/include/statement.h b/include/statement.h -index 5a907aa4dee48..0ddbffd24772b 100644 ---- a/include/statement.h -+++ b/include/statement.h -@@ -225,7 +225,6 @@ struct xt_stmt { - struct xtables_match *match; - struct xtables_target *target; - }; -- const char *opts; - void *entry; - }; - -diff --git a/src/statement.c b/src/statement.c -index 58e86f215d5ac..e9c9d648b0092 100644 ---- a/src/statement.c -+++ b/src/statement.c -@@ -767,7 +767,6 @@ static void xt_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - static void xt_stmt_destroy(struct stmt *stmt) - { - xfree(stmt->xt.name); -- xfree(stmt->xt.opts); - xt_stmt_release(stmt); - } - -diff --git a/src/xt.c b/src/xt.c -index 95d0c5f24c07e..74763d58cafd7 100644 ---- a/src/xt.c -+++ b/src/xt.c -@@ -32,9 +32,7 @@ void xt_stmt_xlate(const struct stmt *stmt) - - switch (stmt->xt.type) { - case NFT_XT_MATCH: -- if (stmt->xt.match == NULL && stmt->xt.opts) { -- printf("%s", stmt->xt.opts); -- } else if (stmt->xt.match->xlate) { -+ if (stmt->xt.match->xlate) { - struct xt_xlate_mt_params params = { - .ip = stmt->xt.entry, - .match = stmt->xt.match->m, -@@ -51,9 +49,7 @@ void xt_stmt_xlate(const struct stmt *stmt) - break; - case NFT_XT_WATCHER: - case NFT_XT_TARGET: -- if (stmt->xt.target == NULL && stmt->xt.opts) { -- printf("%s", stmt->xt.opts); -- } else if (stmt->xt.target->xlate) { -+ if (stmt->xt.target->xlate) { - struct xt_xlate_tg_params params = { - .ip = stmt->xt.entry, - .target = stmt->xt.target->t, --- -2.21.0 - diff --git a/SOURCES/0022-JSON-Support-latest-enhancements-of-fwd-statement.patch b/SOURCES/0022-JSON-Support-latest-enhancements-of-fwd-statement.patch deleted file mode 100644 index e2cec35..0000000 --- a/SOURCES/0022-JSON-Support-latest-enhancements-of-fwd-statement.patch +++ /dev/null @@ -1,240 +0,0 @@ -From 48d688ddb20d4594ee946014a661d30c82c9247d Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 8 Jun 2018 17:27:18 +0200 -Subject: [PATCH] JSON: Support latest enhancements of fwd statement - -JSON equivalent of fwd statement was too primitive to support the added -address and family parameters, so make its value an object and accept -the device expression as value of a "dev" property in there. Then add -optional "addr" and "family" properties to it. - -While being at it, add a testcase to make sure the extended syntax works -right. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit f63b54623fcd1ab7d2f51928571c164409f00175) -Signed-off-by: Phil Sutter ---- - src/json.c | 13 ++++++++-- - src/parser_json.c | 40 ++++++++++++++++++++++++++++-- - tests/py/any/fwd.t | 1 + - tests/py/any/fwd.t.json | 45 ++++++++++++++++++++++------------ - tests/py/any/fwd.t.json.output | 30 ++++++++++++----------- - tests/py/any/fwd.t.payload | 6 +++++ - 6 files changed, 102 insertions(+), 33 deletions(-) - -diff --git a/src/json.c b/src/json.c -index 7d89754bd666d..eeba90e266f75 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -1008,9 +1008,18 @@ json_t *limit_stmt_json(const struct stmt *stmt, struct output_ctx *octx) - - json_t *fwd_stmt_json(const struct stmt *stmt, struct output_ctx *octx) - { -- json_t *root; -+ json_t *root, *tmp; -+ -+ root = json_pack("{s:o}", "dev", expr_print_json(stmt->fwd.dev, octx)); -+ -+ if (stmt->fwd.addr) { -+ tmp = json_string(family2str(stmt->fwd.family)); -+ json_object_set_new(root, "family", tmp); -+ -+ tmp = expr_print_json(stmt->fwd.addr, octx); -+ json_object_set_new(root, "addr", tmp); -+ } - -- root = expr_print_json(stmt->fwd.dev, octx); - return json_pack("{s:o}", "fwd", root); - } - -diff --git a/src/parser_json.c b/src/parser_json.c -index 6e14fb7278fb0..af57b3025a104 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -1561,11 +1561,47 @@ static struct stmt *json_parse_limit_stmt(struct json_ctx *ctx, - static struct stmt *json_parse_fwd_stmt(struct json_ctx *ctx, - const char *key, json_t *value) - { -- struct stmt *stmt = fwd_stmt_alloc(int_loc); -+ json_t *jaddr, *jdev; -+ const char *family; -+ struct stmt *stmt; -+ int familyval; -+ -+ if (json_unpack_err(ctx, value, "{s:o}", "dev", &jdev)) -+ return NULL; - -- stmt->fwd.dev = json_parse_expr(ctx, value); -+ stmt = fwd_stmt_alloc(int_loc); -+ -+ stmt->fwd.dev = json_parse_stmt_expr(ctx, jdev); -+ if (!stmt->fwd.dev) { -+ json_error(ctx, "Invalid fwd dev value."); -+ goto out_err; -+ } -+ -+ if (json_unpack(value, "{s:s, s:o}", -+ "family", &family, "addr", &jaddr)) -+ return stmt; -+ -+ familyval = parse_family(family); -+ switch (familyval) { -+ case NFPROTO_IPV4: -+ case NFPROTO_IPV6: -+ stmt->fwd.family = familyval; -+ break; -+ default: -+ json_error(ctx, "Invalid fwd family value '%s'.", family); -+ goto out_err; -+ } -+ -+ stmt->fwd.addr = json_parse_stmt_expr(ctx, jaddr); -+ if (!stmt->fwd.addr) { -+ json_error(ctx, "Invalid fwd addr value."); -+ goto out_err; -+ } - - return stmt; -+out_err: -+ stmt_free(stmt); -+ return NULL; - } - - static struct stmt *json_parse_notrack_stmt(struct json_ctx *ctx, -diff --git a/tests/py/any/fwd.t b/tests/py/any/fwd.t -index d9b4514ee29a1..986a16d9e2c8c 100644 ---- a/tests/py/any/fwd.t -+++ b/tests/py/any/fwd.t -@@ -5,3 +5,4 @@ - fwd to "lo";ok - fwd to mark map { 0x00000001 : "lo", 0x00000002 : "lo"};ok - -+fwd ip to 192.168.2.200 device "lo";ok -diff --git a/tests/py/any/fwd.t.json b/tests/py/any/fwd.t.json -index 644d6d48c2a19..e58a8ad25829b 100644 ---- a/tests/py/any/fwd.t.json -+++ b/tests/py/any/fwd.t.json -@@ -1,7 +1,9 @@ - # fwd to "lo" - [ - { -- "fwd": "lo" -+ "fwd": { -+ "dev": "lo" -+ } - } - ] - -@@ -9,24 +11,37 @@ - [ - { - "fwd": { -- "map": { -- "left": { -- "meta": "mark" -- }, -- "right": { -- "set": [ -- [ -- "0x00000001", -- "lo" -- ], -- [ -- "0x00000002", -- "lo" -+ "dev": { -+ "map": { -+ "left": { -+ "meta": "mark" -+ }, -+ "right": { -+ "set": [ -+ [ -+ "0x00000001", -+ "lo" -+ ], -+ [ -+ "0x00000002", -+ "lo" -+ ] - ] -- ] -+ } - } - } - } - } - ] - -+# fwd ip to 192.168.2.200 device "lo" -+[ -+ { -+ "fwd": { -+ "addr": "192.168.2.200", -+ "dev": "lo", -+ "family": "ip" -+ } -+ } -+] -+ -diff --git a/tests/py/any/fwd.t.json.output b/tests/py/any/fwd.t.json.output -index 5a943567adb0c..e4bad620b22d4 100644 ---- a/tests/py/any/fwd.t.json.output -+++ b/tests/py/any/fwd.t.json.output -@@ -2,21 +2,23 @@ - [ - { - "fwd": { -- "map": { -- "left": { -- "meta": "mark" -- }, -- "right": { -- "set": [ -- [ -- 1, -- "lo" -- ], -- [ -- 2, -- "lo" -+ "dev": { -+ "map": { -+ "left": { -+ "meta": "mark" -+ }, -+ "right": { -+ "set": [ -+ [ -+ 1, -+ "lo" -+ ], -+ [ -+ 2, -+ "lo" -+ ] - ] -- ] -+ } - } - } - } -diff --git a/tests/py/any/fwd.t.payload b/tests/py/any/fwd.t.payload -index 696b55efe8207..966c08b0959c3 100644 ---- a/tests/py/any/fwd.t.payload -+++ b/tests/py/any/fwd.t.payload -@@ -12,3 +12,9 @@ netdev test-netdev ingress - [ lookup reg 1 set __map%d dreg 1 ] - [ fwd sreg_dev 1 ] - -+# fwd ip to 192.168.2.200 device "lo" -+netdev test-netdev ingress -+ [ immediate reg 1 0x00000001 ] -+ [ immediate reg 2 0xc802a8c0 ] -+ [ fwd sreg_dev 1 sreg_addr 2 nfproto 2 ] -+ --- -2.21.0 - diff --git a/SOURCES/0023-parser_json-Fix-for-ineffective-family-value-checks.patch b/SOURCES/0023-parser_json-Fix-for-ineffective-family-value-checks.patch deleted file mode 100644 index 68225c7..0000000 --- a/SOURCES/0023-parser_json-Fix-for-ineffective-family-value-checks.patch +++ /dev/null @@ -1,310 +0,0 @@ -From c40b8c22beef6011d79c60742bc4043d681198c1 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 12 Oct 2018 17:23:24 +0200 -Subject: [PATCH] parser_json: Fix for ineffective family value checks - -Since handle->family is unsigned, checking for value < 0 never yields -true. Overcome this by changing parse_family() to return an error code -and write the parsed family value into a pointer passed as parameter. - -The above change required a bit more cleanup to avoid passing pointers -to signed variables to the function. Also leverage json_parse_family() a -bit more to reduce code side. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit c7a5401943df8b6b96f6b5eedd9a1e0013e01d86) - -Conflicts: - src/parser_json.c --> Missing ct timeout support --> missing tproxy support in JSON --> Missing ipsec expression - -Signed-off-by: Phil Sutter ---- - src/parser_json.c | 130 ++++++++++++++++++++++------------------------ - 1 file changed, 62 insertions(+), 68 deletions(-) - -diff --git a/src/parser_json.c b/src/parser_json.c -index af57b3025a104..30de17f8a1e26 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -173,7 +173,7 @@ static int json_unpack_stmt(struct json_ctx *ctx, json_t *root, - return 1; - } - --static int parse_family(const char *name) -+static int parse_family(const char *name, uint32_t *family) - { - unsigned int i; - struct { -@@ -188,13 +188,37 @@ static int parse_family(const char *name) - { "netdev", NFPROTO_NETDEV } - }; - -+ assert(family); -+ - for (i = 0; i < array_size(family_tbl); i++) { -- if (!strcmp(name, family_tbl[i].name)) -- return family_tbl[i].val; -+ if (strcmp(name, family_tbl[i].name)) -+ continue; -+ -+ *family = family_tbl[i].val; -+ return 0; - } - return -1; - } - -+static int json_parse_family(struct json_ctx *ctx, json_t *root) -+{ -+ const char *family; -+ -+ if (!json_unpack(root, "{s:s}", "family", &family)) { -+ uint32_t familyval; -+ -+ if (parse_family(family, &familyval) || -+ (familyval != NFPROTO_IPV6 && -+ familyval != NFPROTO_IPV4)) { -+ json_error(ctx, "Invalid family '%s'.", family); -+ return -1; -+ } -+ return familyval; -+ } -+ -+ return NFPROTO_UNSPEC; -+} -+ - static bool is_keyword(const char *keyword) - { - const char *keywords[] = { -@@ -594,19 +618,15 @@ static struct expr *json_parse_rt_expr(struct json_ctx *ctx, - { "nexthop", NFT_RT_NEXTHOP4 }, - { "mtu", NFT_RT_TCPMSS }, - }; -- unsigned int i, familyval = NFPROTO_UNSPEC; -- const char *key, *family = NULL; -+ const char *key; -+ unsigned int i; -+ int familyval; - - if (json_unpack_err(ctx, root, "{s:s}", "key", &key)) - return NULL; -- if (!json_unpack(root, "{s:s}", "family", &family)) { -- familyval = parse_family(family); -- if (familyval != NFPROTO_IPV4 && -- familyval != NFPROTO_IPV6) { -- json_error(ctx, "Invalid RT family '%s'.", family); -- return NULL; -- } -- } -+ familyval = json_parse_family(ctx, root); -+ if (familyval < 0) -+ return NULL; - - for (i = 0; i < array_size(rt_key_tbl); i++) { - int val = rt_key_tbl[i].val; -@@ -653,9 +673,9 @@ static bool ct_key_is_dir(enum nft_ct_keys key) - static struct expr *json_parse_ct_expr(struct json_ctx *ctx, - const char *type, json_t *root) - { -- const char *key, *dir, *family; -+ const char *key, *dir; - unsigned int i; -- int dirval = -1, familyval = NFPROTO_UNSPEC, keyval = -1; -+ int dirval = -1, familyval, keyval = -1; - - if (json_unpack_err(ctx, root, "{s:s}", "key", &key)) - return NULL; -@@ -672,14 +692,9 @@ static struct expr *json_parse_ct_expr(struct json_ctx *ctx, - return NULL; - } - -- if (!json_unpack(root, "{s:s}", "family", &family)) { -- familyval = parse_family(family); -- if (familyval != NFPROTO_IPV4 && -- familyval != NFPROTO_IPV6) { -- json_error(ctx, "Invalid CT family '%s'.", family); -- return NULL; -- } -- } -+ familyval = json_parse_family(ctx, root); -+ if (familyval < 0) -+ return NULL; - - if (!json_unpack(root, "{s:s}", "dir", &dir)) { - if (!strcmp(dir, "original")) { -@@ -1562,7 +1577,6 @@ static struct stmt *json_parse_fwd_stmt(struct json_ctx *ctx, - const char *key, json_t *value) - { - json_t *jaddr, *jdev; -- const char *family; - struct stmt *stmt; - int familyval; - -@@ -1577,21 +1591,15 @@ static struct stmt *json_parse_fwd_stmt(struct json_ctx *ctx, - goto out_err; - } - -- if (json_unpack(value, "{s:s, s:o}", -- "family", &family, "addr", &jaddr)) -- return stmt; -- -- familyval = parse_family(family); -- switch (familyval) { -- case NFPROTO_IPV4: -- case NFPROTO_IPV6: -- stmt->fwd.family = familyval; -- break; -- default: -- json_error(ctx, "Invalid fwd family value '%s'.", family); -+ familyval = json_parse_family(ctx, value); -+ if (familyval < 0) - goto out_err; -- } - -+ if (familyval == NFPROTO_UNSPEC || -+ json_unpack(value, "{s:o}", "addr", &jaddr)) -+ return stmt; -+ -+ stmt->fwd.family = familyval; - stmt->fwd.addr = json_parse_stmt_expr(ctx, jaddr); - if (!stmt->fwd.addr) { - json_error(ctx, "Invalid fwd addr value."); -@@ -2137,8 +2145,7 @@ static struct cmd *json_parse_cmd_add_table(struct json_ctx *ctx, json_t *root, - json_error(ctx, "Either name or handle required to delete a table."); - return NULL; - } -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2178,8 +2185,7 @@ static struct cmd *json_parse_cmd_add_chain(struct json_ctx *ctx, json_t *root, - json_error(ctx, "Either name or handle required to delete a chain."); - return NULL; - } -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2240,8 +2246,7 @@ static struct cmd *json_parse_cmd_add_rule(struct json_ctx *ctx, json_t *root, - json_unpack_err(ctx, root, "{s:I}", "handle", &h.handle.id)) - return NULL; - -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2347,8 +2352,7 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root, - return NULL; - } - -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2459,8 +2463,7 @@ static struct cmd *json_parse_cmd_add_element(struct json_ctx *ctx, - "elem", &tmp)) - return NULL; - -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2523,8 +2526,7 @@ static struct cmd *json_parse_cmd_add_flowtable(struct json_ctx *ctx, - "name", &h.flowtable)) - return NULL; - -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2568,6 +2570,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, - enum cmd_obj cmd_obj) - { - const char *family, *tmp, *rate_unit = "packets", *burst_unit = "bytes"; -+ uint32_t l3proto = NFPROTO_IPV4; - struct handle h = { 0 }; - struct obj *obj; - int inv = 0; -@@ -2588,8 +2591,7 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, - return NULL; - } - -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2647,18 +2649,13 @@ static struct cmd *json_parse_cmd_add_object(struct json_ctx *ctx, - return NULL; - } - } -- if (!json_unpack(root, "{s:s}", "l3proto", &tmp)) { -- int family = parse_family(tmp); -- -- if (family < 0) { -- json_error(ctx, "Invalid ct helper l3proto '%s'.", tmp); -- obj_free(obj); -- return NULL; -- } -- obj->ct_helper.l3proto = family; -- } else { -- obj->ct_helper.l3proto = NFPROTO_IPV4; -+ if (!json_unpack(root, "{s:s}", "l3proto", &tmp) && -+ parse_family(tmp, &l3proto)) { -+ json_error(ctx, "Invalid ct helper l3proto '%s'.", tmp); -+ obj_free(obj); -+ return NULL; - } -+ obj->ct_helper.l3proto = l3proto; - break; - case CMD_OBJ_LIMIT: - obj->type = NFT_OBJECT_LIMIT; -@@ -2770,8 +2767,7 @@ static struct cmd *json_parse_cmd_replace(struct json_ctx *ctx, - h.handle.id = 0; - } - -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } -@@ -2825,8 +2821,7 @@ static struct cmd *json_parse_cmd_list_multiple(struct json_ctx *ctx, - const char *tmp; - - if (!json_unpack(root, "{s:s}", "family", &tmp)) { -- h.family = parse_family(tmp); -- if (h.family < 0) { -+ if (parse_family(tmp, &h.family)) { - json_error(ctx, "Unknown family '%s'.", tmp); - return NULL; - } -@@ -2981,8 +2976,7 @@ static struct cmd *json_parse_cmd_rename(struct json_ctx *ctx, - "name", &h.chain.name, - "newname", &newname)) - return NULL; -- h.family = parse_family(family); -- if (h.family < 0) { -+ if (parse_family(family, &h.family)) { - json_error(ctx, "Unknown family '%s'.", family); - return NULL; - } --- -2.21.0 - diff --git a/SOURCES/0024-json-Fix-memleak-in-dup_stmt_json.patch b/SOURCES/0024-json-Fix-memleak-in-dup_stmt_json.patch deleted file mode 100644 index aa20e45..0000000 --- a/SOURCES/0024-json-Fix-memleak-in-dup_stmt_json.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5b386b65d61c0f2831ef31a3674225dc21f9e1ff Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 12 Oct 2018 17:50:15 +0200 -Subject: [PATCH] json: Fix memleak in dup_stmt_json() - -The variable 'root' is always assigned to after initialization, so there -is no point in initializing it upon declaration. - -Fixes: e70354f53e9f6 ("libnftables: Implement JSON output support") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 27d8946db90b79762a36e66647bb8d8fc4c17ce9) -Signed-off-by: Phil Sutter ---- - src/json.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/json.c b/src/json.c -index eeba90e266f75..66b02a934a24b 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -1030,7 +1030,7 @@ json_t *notrack_stmt_json(const struct stmt *stmt, struct output_ctx *octx) - - json_t *dup_stmt_json(const struct stmt *stmt, struct output_ctx *octx) - { -- json_t *root = json_object(); -+ json_t *root; - - if (stmt->dup.to) { - root = json_pack("{s:o}", "addr", expr_print_json(stmt->dup.to, octx)); --- -2.21.0 - diff --git a/SOURCES/0025-json-Fix-for-recent-changes-to-context-structs.patch b/SOURCES/0025-json-Fix-for-recent-changes-to-context-structs.patch deleted file mode 100644 index 5f405e2..0000000 --- a/SOURCES/0025-json-Fix-for-recent-changes-to-context-structs.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 5eff789ea5d32ad000805c727584ec0d4ee7a392 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 24 Oct 2018 12:35:04 +0200 -Subject: [PATCH] json: Fix for recent changes to context structs - -Commits introducing nft_ctx pointer to netlink and eval contexts did not -update JSON code accordingly. - -Fixes: 00f777bfc414a ("src: pass struct nft_ctx through struct eval_ctx") -Fixes: 2dc07bcd7eaa5 ("src: pass struct nft_ctx through struct netlink_ctx") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 841d5f5a3deacfe7b4245df0890849d8e4ad5817) - -Conflicts: --> Missing ct timeout support - -Signed-off-by: Phil Sutter ---- - src/json.c | 69 ++++++++++++++++++++++++----------------------- - src/parser_json.c | 5 +--- - 2 files changed, 37 insertions(+), 37 deletions(-) - -diff --git a/src/json.c b/src/json.c -index 66b02a934a24b..98581a3c2a3e4 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -211,8 +211,7 @@ static json_t *rule_print_json(struct output_ctx *octx, - return json_pack("{s:o}", "rule", root); - } - --static json_t *chain_print_json(const struct output_ctx *octx, -- const struct chain *chain) -+static json_t *chain_print_json(const struct chain *chain) - { - json_t *root, *tmp; - -@@ -247,7 +246,7 @@ static json_t *proto_name_json(uint8_t proto) - return json_integer(proto); - } - --static json_t *obj_print_json(struct output_ctx *octx, const struct obj *obj) -+static json_t *obj_print_json(const struct obj *obj) - { - const char *rate_unit = NULL, *burst_unit = NULL; - const char *type = obj_type_name(obj->type); -@@ -371,8 +370,7 @@ static json_t *table_flags_json(const struct table *table) - return root; - } - --static json_t *table_print_json(const struct output_ctx *octx, -- const struct table *table) -+static json_t *table_print_json(const struct table *table) - { - json_t *root, *tmp; - -@@ -1295,17 +1293,17 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx, - struct obj *obj; - struct set *set; - -- tmp = table_print_json(ctx->octx, table); -+ tmp = table_print_json(table); - json_array_append_new(root, tmp); - - list_for_each_entry(obj, &table->objs, list) { -- tmp = obj_print_json(ctx->octx, obj); -+ tmp = obj_print_json(obj); - json_array_append_new(root, tmp); - } - list_for_each_entry(set, &table->sets, list) { - if (set->flags & NFT_SET_ANONYMOUS) - continue; -- tmp = set_print_json(ctx->octx, set); -+ tmp = set_print_json(&ctx->nft->output, set); - json_array_append_new(root, tmp); - } - list_for_each_entry(flowtable, &table->flowtables, list) { -@@ -1313,11 +1311,11 @@ static json_t *table_print_json_full(struct netlink_ctx *ctx, - json_array_append_new(root, tmp); - } - list_for_each_entry(chain, &table->chains, list) { -- tmp = chain_print_json(ctx->octx, chain); -+ tmp = chain_print_json(chain); - json_array_append_new(root, tmp); - - list_for_each_entry(rule, &chain->rules, list) { -- tmp = rule_print_json(ctx->octx, rule); -+ tmp = rule_print_json(&ctx->nft->output, rule); - json_array_append_new(root, tmp); - } - } -@@ -1331,7 +1329,7 @@ static json_t *do_list_ruleset_json(struct netlink_ctx *ctx, struct cmd *cmd) - json_t *root = json_array(); - struct table *table; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (family != NFPROTO_UNSPEC && - table->handle.family != family) - continue; -@@ -1348,12 +1346,12 @@ static json_t *do_list_tables_json(struct netlink_ctx *ctx, struct cmd *cmd) - json_t *root = json_array(); - struct table *table; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (family != NFPROTO_UNSPEC && - table->handle.family != family) - continue; - -- json_array_append_new(root, table_print_json(ctx->octx, table)); -+ json_array_append_new(root, table_print_json(table)); - } - - return root; -@@ -1377,10 +1375,10 @@ static json_t *do_list_chain_json(struct netlink_ctx *ctx, - strcmp(cmd->handle.chain.name, chain->handle.chain.name)) - continue; - -- json_array_append_new(root, chain_print_json(ctx->octx, chain)); -+ json_array_append_new(root, chain_print_json(chain)); - - list_for_each_entry(rule, &chain->rules, list) { -- json_t *tmp = rule_print_json(ctx->octx, rule); -+ json_t *tmp = rule_print_json(&ctx->nft->output, rule); - - json_array_append_new(root, tmp); - } -@@ -1395,13 +1393,13 @@ static json_t *do_list_chains_json(struct netlink_ctx *ctx, struct cmd *cmd) - struct table *table; - struct chain *chain; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; - - list_for_each_entry(chain, &table->chains, list) { -- json_t *tmp = chain_print_json(ctx->octx, chain); -+ json_t *tmp = chain_print_json(chain); - - json_array_append_new(root, tmp); - } -@@ -1418,17 +1416,17 @@ static json_t *do_list_set_json(struct netlink_ctx *ctx, - if (set == NULL) - return json_null(); - -- return json_pack("[o]", set_print_json(ctx->octx, set)); -+ return json_pack("[o]", set_print_json(&ctx->nft->output, set)); - } - - static json_t *do_list_sets_json(struct netlink_ctx *ctx, struct cmd *cmd) - { -- struct output_ctx *octx = ctx->octx; -+ struct output_ctx *octx = &ctx->nft->output; - json_t *root = json_array(); - struct table *table; - struct set *set; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; -@@ -1458,7 +1456,7 @@ static json_t *do_list_obj_json(struct netlink_ctx *ctx, - struct table *table; - struct obj *obj; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; -@@ -1473,8 +1471,7 @@ static json_t *do_list_obj_json(struct netlink_ctx *ctx, - strcmp(cmd->handle.obj.name, obj->handle.obj.name))) - continue; - -- json_array_append_new(root, -- obj_print_json(ctx->octx, obj)); -+ json_array_append_new(root, obj_print_json(obj)); - } - } - -@@ -1487,7 +1484,7 @@ static json_t *do_list_flowtables_json(struct netlink_ctx *ctx, struct cmd *cmd) - struct flowtable *flowtable; - struct table *table; - -- list_for_each_entry(table, &ctx->cache->list, list) { -+ list_for_each_entry(table, &ctx->nft->cache.list, list) { - if (cmd->handle.family != NFPROTO_UNSPEC && - cmd->handle.family != table->handle.family) - continue; -@@ -1507,7 +1504,7 @@ int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd) - json_t *root; - - if (cmd->handle.table.name) -- table = table_lookup(&cmd->handle, ctx->cache); -+ table = table_lookup(&cmd->handle, &ctx->nft->cache); - - switch (cmd->obj) { - case CMD_OBJ_TABLE: -@@ -1572,7 +1569,7 @@ int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd) - root = json_null(); - } - root = json_pack("{s:o}", "nftables", root); -- json_dumpf(root, ctx->octx->output_fp, 0); -+ json_dumpf(root, ctx->nft->output.output_fp, 0); - json_decref(root); - return 0; - } -@@ -1581,42 +1578,48 @@ static void monitor_print_json(struct netlink_mon_handler *monh, - const char *cmd, json_t *obj) - { - obj = json_pack("{s:o}", cmd, obj); -- json_dumpf(obj, monh->ctx->octx->output_fp, 0); -+ json_dumpf(obj, monh->ctx->nft->output.output_fp, 0); - json_decref(obj); - } - - void monitor_print_table_json(struct netlink_mon_handler *monh, - const char *cmd, struct table *t) - { -- monitor_print_json(monh, cmd, table_print_json(monh->ctx->octx, t)); -+ monitor_print_json(monh, cmd, table_print_json(t)); - } - - void monitor_print_chain_json(struct netlink_mon_handler *monh, - const char *cmd, struct chain *c) - { -- monitor_print_json(monh, cmd, chain_print_json(monh->ctx->octx, c)); -+ monitor_print_json(monh, cmd, chain_print_json(c)); - } - - void monitor_print_set_json(struct netlink_mon_handler *monh, - const char *cmd, struct set *s) - { -- monitor_print_json(monh, cmd, set_print_json(monh->ctx->octx, s)); -+ struct output_ctx *octx = &monh->ctx->nft->output; -+ -+ monitor_print_json(monh, cmd, set_print_json(octx, s)); - } - - void monitor_print_element_json(struct netlink_mon_handler *monh, - const char *cmd, struct set *s) - { -- monitor_print_json(monh, cmd, element_print_json(monh->ctx->octx, s)); -+ struct output_ctx *octx = &monh->ctx->nft->output; -+ -+ monitor_print_json(monh, cmd, element_print_json(octx, s)); - } - - void monitor_print_obj_json(struct netlink_mon_handler *monh, - const char *cmd, struct obj *o) - { -- monitor_print_json(monh, cmd, obj_print_json(monh->ctx->octx, o)); -+ monitor_print_json(monh, cmd, obj_print_json(o)); - } - - void monitor_print_rule_json(struct netlink_mon_handler *monh, - const char *cmd, struct rule *r) - { -- monitor_print_json(monh, cmd, rule_print_json(monh->ctx->octx, r)); -+ struct output_ctx *octx = &monh->ctx->nft->output; -+ -+ monitor_print_json(monh, cmd, rule_print_json(octx, r)); - } -diff --git a/src/parser_json.c b/src/parser_json.c -index 30de17f8a1e26..817415c15fb89 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -3025,11 +3025,8 @@ static struct cmd *json_parse_cmd(struct json_ctx *ctx, json_t *root) - static int __json_parse(struct json_ctx *ctx, json_t *root) - { - struct eval_ctx ectx = { -- .nf_sock = ctx->nft->nf_sock, -+ .nft = ctx->nft, - .msgs = ctx->msgs, -- .cache = &ctx->nft->cache, -- .octx = &ctx->nft->output, -- .debug_mask = ctx->nft->debug_mask, - }; - json_t *tmp, *value; - size_t index; --- -2.21.0 - diff --git a/SOURCES/0026-parser_bison-Fix-for-ECN-keyword-in-LHS-of-relationa.patch b/SOURCES/0026-parser_bison-Fix-for-ECN-keyword-in-LHS-of-relationa.patch deleted file mode 100644 index 3b502b4..0000000 --- a/SOURCES/0026-parser_bison-Fix-for-ECN-keyword-in-LHS-of-relationa.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 64b101f4a124f39b494dc5906159a8890568d1f9 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 24 Aug 2018 13:26:57 +0200 -Subject: [PATCH] parser_bison: Fix for ECN keyword in LHS of relational - -Of all possible TCP flags, 'ecn' is special since it is recognized by -lex as a keyword (there is a a field in IPv4 and IPv6 headers with the -same name). Therefore it is listed in keyword_expr, but that was -sufficient for RHS only. The following statement reproduces the issue: - -| tcp flags & (syn | ecn) == (syn | ecn) - -The solution is to limit binop expressions to accept an RHS expression -on RHS ("real" LHS expressions don't make much sense there anyway), -which then allows keyword_expr to occur there. In order to maintain the -recursive behaviour if braces are present, allow primary_rhs_expr to -consist of a basic_rhs_expr enclosed in braces. This in turn requires -for braced RHS part in relational_expr to be dropped, otherwise bison -complains about shift/reduce conflict. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 14a9968a56f8b35138bab172aa7ce796f5d98e03) -Signed-off-by: Phil Sutter ---- - src/parser_bison.y | 15 ++++++--------- - tests/py/inet/tcp.t | 1 + - tests/py/inet/tcp.t.json | 23 +++++++++++++++++++++++ - tests/py/inet/tcp.t.json.output | 16 ++++++++++++++++ - tests/py/inet/tcp.t.payload | 8 ++++++++ - 5 files changed, 54 insertions(+), 9 deletions(-) - -diff --git a/src/parser_bison.y b/src/parser_bison.y -index d75cd50fa29b9..a6b6fc1745a72 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -2948,32 +2948,32 @@ fib_tuple : fib_flag DOT fib_tuple - ; - - shift_expr : primary_expr -- | shift_expr LSHIFT primary_expr -+ | shift_expr LSHIFT primary_rhs_expr - { - $$ = binop_expr_alloc(&@$, OP_LSHIFT, $1, $3); - } -- | shift_expr RSHIFT primary_expr -+ | shift_expr RSHIFT primary_rhs_expr - { - $$ = binop_expr_alloc(&@$, OP_RSHIFT, $1, $3); - } - ; - - and_expr : shift_expr -- | and_expr AMPERSAND shift_expr -+ | and_expr AMPERSAND shift_rhs_expr - { - $$ = binop_expr_alloc(&@$, OP_AND, $1, $3); - } - ; - - exclusive_or_expr : and_expr -- | exclusive_or_expr CARET and_expr -+ | exclusive_or_expr CARET and_rhs_expr - { - $$ = binop_expr_alloc(&@$, OP_XOR, $1, $3); - } - ; - - inclusive_or_expr : exclusive_or_expr -- | inclusive_or_expr '|' exclusive_or_expr -+ | inclusive_or_expr '|' exclusive_or_rhs_expr - { - $$ = binop_expr_alloc(&@$, OP_OR, $1, $3); - } -@@ -3252,10 +3252,6 @@ relational_expr : expr /* implicit */ rhs_expr - { - $$ = relational_expr_alloc(&@2, $2, $1, $3); - } -- | expr relational_op '(' rhs_expr ')' -- { -- $$ = relational_expr_alloc(&@2, $2, $1, $4); -- } - ; - - list_rhs_expr : basic_rhs_expr COMMA basic_rhs_expr -@@ -3439,6 +3435,7 @@ primary_rhs_expr : symbol_expr { $$ = $1; } - BYTEORDER_HOST_ENDIAN, - sizeof(data) * BITS_PER_BYTE, &data); - } -+ | '(' basic_rhs_expr ')' { $$ = $2; } - ; - - relational_op : EQ { $$ = OP_EQ; } -diff --git a/tests/py/inet/tcp.t b/tests/py/inet/tcp.t -index d66ba8438a32f..f96e3634f41ed 100644 ---- a/tests/py/inet/tcp.t -+++ b/tests/py/inet/tcp.t -@@ -78,6 +78,7 @@ tcp flags cwr;ok - tcp flags != cwr;ok - tcp flags == syn;ok - tcp flags & (syn|fin) == (syn|fin);ok;tcp flags & (fin | syn) == fin | syn -+tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr;ok;tcp flags == 0xff - - tcp window 22222;ok - tcp window 22;ok -diff --git a/tests/py/inet/tcp.t.json b/tests/py/inet/tcp.t.json -index f5df72aa252a6..9ae51018e93ee 100644 ---- a/tests/py/inet/tcp.t.json -+++ b/tests/py/inet/tcp.t.json -@@ -1068,6 +1068,29 @@ - } - ] - -+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr -+[ -+ { -+ "match": { -+ "left": { -+ "&": [ -+ { -+ "payload": { -+ "field": "flags", -+ "protocol": "tcp" -+ } -+ }, -+ { -+ "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ] -+ } -+ ] -+ }, -+ "op": "==", -+ "right": { "|": [ "fin", { "|": [ "syn", { "|": [ "rst", { "|": [ "psh", { "|": [ "ack", { "|": [ "urg", { "|": [ "ecn", "cwr" ] } ] } ] } ] } ] } ] } ] } -+ } -+ } -+] -+ - # tcp window 22222 - [ - { -diff --git a/tests/py/inet/tcp.t.json.output b/tests/py/inet/tcp.t.json.output -index d099d6febb122..ff58756cf596d 100644 ---- a/tests/py/inet/tcp.t.json.output -+++ b/tests/py/inet/tcp.t.json.output -@@ -132,3 +132,19 @@ - } - ] - -+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr -+[ -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "flags", -+ "protocol": "tcp" -+ } -+ }, -+ "op": "==", -+ "right": 255 -+ } -+ } -+] -+ -diff --git a/tests/py/inet/tcp.t.payload b/tests/py/inet/tcp.t.payload -index 09538aed746c9..2390a24ead15c 100644 ---- a/tests/py/inet/tcp.t.payload -+++ b/tests/py/inet/tcp.t.payload -@@ -436,6 +436,14 @@ inet test-inet input - [ bitwise reg 1 = (reg=1 & 0x00000003 ) ^ 0x00000000 ] - [ cmp eq reg 1 0x00000003 ] - -+# tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr -+inet test-inet input -+ [ meta load l4proto => reg 1 ] -+ [ cmp eq reg 1 0x00000006 ] -+ [ payload load 1b @ transport header + 13 => reg 1 ] -+ [ bitwise reg 1 = (reg=1 & 0x000000ff ) ^ 0x00000000 ] -+ [ cmp eq reg 1 0x000000ff ] -+ - # tcp window 22222 - inet test-inet input - [ meta load l4proto => reg 1 ] --- -2.21.0 - diff --git a/SOURCES/0027-nft.8-Update-meta-pkt_type-value-description.patch b/SOURCES/0027-nft.8-Update-meta-pkt_type-value-description.patch deleted file mode 100644 index 8aaabdc..0000000 --- a/SOURCES/0027-nft.8-Update-meta-pkt_type-value-description.patch +++ /dev/null @@ -1,47 +0,0 @@ -From c2d82484a75c99e079754e75ccc510e91290bb72 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 14 Sep 2018 11:00:14 +0200 -Subject: [PATCH] nft.8: Update meta pkt_type value description - -Commit 8a7f6de536408 ("meta: fix pkttype name and add 'other' symbol") -deprecated pkt_type value 'unicast' (for it being misleading) and -introduced 'host' and 'other' but it did not update documentation -accordingly. Fix this by replacing 'unicast' with 'host' in -documentation and adding 'other'. - -While being at it, make sure these literal values are recognized as -such: Put them in all lower-case (as required by the parser) and in bold -font (to stand out a bit more). - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit d75e9184bb51a1311ac950b13384f329836d597e) - -Conflicts: - doc/primary-expression.txt --> Patch manually applied to doc/nft.xml, patches converting man page - source to asciidoc are missing entirely. - -Signed-off-by: Phil Sutter ---- - doc/nft.xml | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/doc/nft.xml b/doc/nft.xml -index 3a5571b0da57a..0df42810c5e68 100644 ---- a/doc/nft.xml -+++ b/doc/nft.xml -@@ -2991,8 +2991,8 @@ filter output icmpv6 type { echo-request, echo-reply } - - pkt_type - -- Packet type: Unicast (addressed to local host), -- Broadcast (to all), Multicast (to group). -+ Packet type: host (addressed to local host), -+ broadcast (to all), multicast (to group), other (addressed to another host). - - - --- -2.21.0 - diff --git a/SOURCES/0028-json-Work-around-segfault-when-encountering-xt-stmt.patch b/SOURCES/0028-json-Work-around-segfault-when-encountering-xt-stmt.patch deleted file mode 100644 index a8d5c1f..0000000 --- a/SOURCES/0028-json-Work-around-segfault-when-encountering-xt-stmt.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 48c743edbd41470149a5ac58c350b47cb80fb9eb Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 24 Oct 2018 21:14:37 +0200 -Subject: [PATCH] json: Work around segfault when encountering xt stmt - -When trying to convert an xt stmt into JSON, print() callback was -called. Though the code in src/xt.c does not respect output_fp, -therefore buffer wasn't filled as expected making libjansson to puke: - -| # nft -j list ruleset -| warning: stmt ops xt have no json callback -| nft: json.c:169: stmt_print_json: Assertion `__out' failed. -| Aborted (core dumped) - -Avoid this by detecting xt stmt ops and returning a stub. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit b849b0dfd9f3aecff5617bc60d5852ef36c3d494) - -Conflicts: - doc/libnftables-json.adoc --> Patches adding this man page are missing entirely. - -Signed-off-by: Phil Sutter ---- - src/json.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/json.c b/src/json.c -index 98581a3c2a3e4..f74afd5a7292e 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -165,6 +165,12 @@ static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx) - char buf[1024]; - FILE *fp; - -+ /* XXX: Can't be supported at this point: -+ * xt_stmt_xlate() ignores output_fp. -+ */ -+ if (stmt->ops->type == STMT_XT) -+ return json_pack("{s:n}", "xt"); -+ - if (stmt->ops->json) - return stmt->ops->json(stmt, octx); - --- -2.21.0 - diff --git a/SOURCES/0029-nft.8-Document-log-level-audit.patch b/SOURCES/0029-nft.8-Document-log-level-audit.patch deleted file mode 100644 index 0562634..0000000 --- a/SOURCES/0029-nft.8-Document-log-level-audit.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 109aab644873fcc732c08aea25288b7be1525ed0 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Sat, 27 Oct 2018 12:15:50 +0200 -Subject: [PATCH] nft.8: Document log level audit - -Since this pseudo log level fundamentally changes behaviour of log -statement, dedicate this mode a separate paragraph. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso - -Conflicts: - doc/statements.txt --> Patch manually applied to doc/nft.xml from asciidoc source. - -Signed-off-by: Phil Sutter ---- - doc/nft.xml | 15 ++++++++++++++- - 1 file changed, 14 insertions(+), 1 deletion(-) - -diff --git a/doc/nft.xml b/doc/nft.xml -index 0df42810c5e68..22d57ac630037 100644 ---- a/doc/nft.xml -+++ b/doc/nft.xml -@@ -4700,9 +4700,22 @@ tcp flags syn tcp option maxseg size set rt mtu - snaplen - size - -+ -+ log -+ level audit -+ -+ -+ -+ The log statement enables logging of matching packets. When this statement is used from a rule, the Linux kernel will print some information on all matching packets, such as header fields, via the kernel log (where it can be read with dmesg(1) or read in the syslog). -+ -+ -+ In the second form of invocation (if 'nflog_group' is specified), the Linux kernel will pass the packet to nfnetlink_log which will multicast the packet through a netlink socket to the specified multicast group. One or more userspace processes may subscribe to the group to receive the packets, see libnetfilter_queue documentation for details. -+ -+ -+ In the third form of invocation (if level audit is specified), the Linux kernel writes a message into the audit buffer suitably formatted for reading with auditd. Therefore no further formatting options (such as prefix or flags) are allowed in this mode. - - -- The log statement enables logging of matching packets. When this statement is used from a rule, the Linux kernel will print some information on all matching packets, such as header fields, via the kernel log (where it can be read with dmesg(1) or read in the syslog). If the group number is specified, the Linux kernel will pass the packet to nfnetlink_log which will multicast the packet through a netlink socket to the specified multicast group. One or more userspace processes may subscribe to the group to receive the packets, see libnetfilter_queue documentation for details. This is a non-terminating statement, so the rule evaluation continues after the packet is logged. -+ This is a non-terminating statement, so the rule evaluation continues after the packet is logged. - - - --- -2.21.0 - diff --git a/SOURCES/0030-nft.8-Clarify-index-option-of-add-rule-command.patch b/SOURCES/0030-nft.8-Clarify-index-option-of-add-rule-command.patch deleted file mode 100644 index e01dc5b..0000000 --- a/SOURCES/0030-nft.8-Clarify-index-option-of-add-rule-command.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 8d5b7e557b65cd547b55567ac3dfbb2ea3f65418 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 12 Nov 2018 15:02:52 +0100 -Subject: [PATCH] nft.8: Clarify 'index' option of add rule command - -Documentation for add rule command might trick readers into believing -the optional 'index' argument does not need to be that of an existing -rule. This false assumption is fueled by the fact that iptables allows -to insert with last rule number + 1 to actually append to a chain. -Change the relevant sentence to clarify that. - -While being at it, drop the deprecated 'position' option from -documentation - since this will likely go away at some point, don't -encourage users to use it although they should notice that they -shoudn't. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit f4e40e395af2b73cd72c5454e41fb879da8c5f61) - -Conflicts: - doc/nft.txt --> Patch applied manually to doc/nft.xml from asciidoc source. - -Signed-off-by: Phil Sutter ---- - doc/nft.xml | 11 +++-------- - 1 file changed, 3 insertions(+), 8 deletions(-) - -diff --git a/doc/nft.xml b/doc/nft.xml -index 22d57ac630037..512724ed8f9a7 100644 ---- a/doc/nft.xml -+++ b/doc/nft.xml -@@ -877,10 +877,7 @@ add table inet mytable - chain - - -- -- handle -- position -- -+ handle - handle - - -@@ -917,8 +914,8 @@ add table inet mytable - - - The add and insert commands support an optional -- location specifier, which is either a handle of an existing -- rule or an index (starting at zero). Internally, -+ location specifier, which is either a handle or the -+ index (starting at zero) of an existing rule. Internally, - rule locations are always identified by handle and the - translation from index happens in userspace. This has two - potential implications in case a concurrent ruleset change happens after the translation -@@ -935,8 +932,6 @@ add table inet mytable - Add a new rule described by the list of statements. The rule is appended to the - given chain unless a handle is specified, in which case the - rule is appended to the rule given by the handle. -- The alternative name position is deprecated and should not be -- used anymore. - - - --- -2.21.0 - diff --git a/SOURCES/0031-src-Reject-export-vm-json-command.patch b/SOURCES/0031-src-Reject-export-vm-json-command.patch deleted file mode 100644 index 4347d85..0000000 --- a/SOURCES/0031-src-Reject-export-vm-json-command.patch +++ /dev/null @@ -1,152 +0,0 @@ -From b5fd560fa6b1aa1e112273d9f04281b58eb06dae Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 17 Dec 2018 16:29:56 +0100 -Subject: [PATCH] src: Reject 'export vm json' command - -Since libnftnl recently dropped JSON output support, this form of JSON -export is not available anymore. Point at 'nft -j list ruleset' command -for a replacement in error message. - -Since 'export' command is not useable anymore, remove it from -documentation. Instead point out that 'list ruleset' command serves well -for dumping and later restoring. - -To not cause pointless inconvenience for users wishing to store their -ruleset in JSON format, make JSON parser fallback to CMD_ADD if no -recognized command property was found. This allows to feed the output of -'nft -j list ruleset' into 'nft -f' without any modification. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 8d51f169e0e832a41d2ed278be903c08bd4fa473) - -Conflicts: --> Documentation changes applied manually due to missing conversion to - asciidoc. --> Dropped references to libnftables-json man page from documentation. - (This file has not been backported and doing so is non-trivial due to - asciidoc conversion.) --> Include libnftnl/common.h in src/evaluate.c to make symbol - NFTNL_OUTPUT_JSON known. - -Signed-off-by: Phil Sutter ---- - doc/nft.xml | 34 +++++++++++++--------------------- - src/evaluate.c | 5 +++++ - src/parser_json.c | 4 ++-- - 3 files changed, 20 insertions(+), 23 deletions(-) - -diff --git a/doc/nft.xml b/doc/nft.xml -index 512724ed8f9a7..1a97d7a169776 100644 ---- a/doc/nft.xml -+++ b/doc/nft.xml -@@ -46,7 +46,7 @@ vi:ts=4 sw=4 - - nft - -- -+ - - -I - directory -@@ -155,6 +155,14 @@ vi:ts=4 sw=4 - - - -+ -+ -+ -+ -+ Format output in JSON. -+ -+ -+ - - - -@@ -480,11 +488,6 @@ filter input iif $int_ifs accept - ruleset - family - -- -- export -- ruleset -- format -- - - - -@@ -514,17 +517,6 @@ filter input iif $int_ifs accept - - - -- -- -- -- -- Print the ruleset in machine readable format. The -- mandatory format parameter -- may be either xml or -- json. -- -- -- - - - -@@ -534,10 +526,10 @@ filter input iif $int_ifs accept - - - -- Note that contrary to what one might assume, the output generated -- by export is not parseable by -- nft -f. Instead, the output of -- list command serves well for that purpose. -+ By design, list ruleset command output may be -+ used as input to nft -f. -+ Effectively, this is the nft-equivalent of iptables-save and -+ iptables-restore. - - - -diff --git a/src/evaluate.c b/src/evaluate.c -index 809920748c0a9..4656c7566db39 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -31,6 +31,8 @@ - #include - #include - -+#include -+ - static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr); - - static const char * const byteorder_names[] = { -@@ -3526,6 +3528,9 @@ static int cmd_evaluate_export(struct eval_ctx *ctx, struct cmd *cmd) - if (cmd->markup->format == __NFT_OUTPUT_NOTSUPP) - return cmd_error(ctx, &cmd->location, - "this output type is not supported"); -+ else if (cmd->markup->format == NFTNL_OUTPUT_JSON) -+ return cmd_error(ctx, &cmd->location, -+ "JSON export is no longer supported, use 'nft -j list ruleset' instead"); - - return cache_update(ctx->nft, cmd->op, ctx->msgs); - } -diff --git a/src/parser_json.c b/src/parser_json.c -index 817415c15fb89..1e3688b2dc1cd 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -3018,8 +3018,8 @@ static struct cmd *json_parse_cmd(struct json_ctx *ctx, json_t *root) - - return parse_cb_table[i].cb(ctx, tmp, parse_cb_table[i].op); - } -- json_error(ctx, "Unknown command object."); -- return NULL; -+ /* to accept 'list ruleset' output 1:1, try add command */ -+ return json_parse_cmd_add(ctx, root, CMD_ADD); - } - - static int __json_parse(struct json_ctx *ctx, json_t *root) --- -2.21.0 - diff --git a/SOURCES/0032-datatype-add-stolen-verdict.patch b/SOURCES/0032-datatype-add-stolen-verdict.patch deleted file mode 100644 index 56e8553..0000000 --- a/SOURCES/0032-datatype-add-stolen-verdict.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 14c526641e1fdec01f345c8d9f22fff809e59790 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 12 Jun 2018 18:39:13 +0200 -Subject: [PATCH] datatype: add stolen verdict - -using fwd statement causes crash when using nft trace: - - trace id ddbbaae2 netdev vpn ingress_out packet: iif "enp2s0" ether saddr 78:54:00:29:bb:aa ether daddr 52:54:00:01:53:9f ip saddr 85.14.236.41 ip daddr 17.25.63.98 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 49036 ip length 84 icmp type echo-reply icmp code 0 icmp id 16947 icmp sequence 4 - trace id ddbbaae2 netdev vpn ingress_out rule ip saddr 85.14.236.41 nftrace set 1 (verdict continue) - trace id ddbbaae2 netdev vpn ingress_out rule ip saddr 85.14.236.41 ether saddr set aa:bb:00:18:cc:dd ether daddr set 00:00:5e:00:00:11 fwd to "enp1s0" - BUG: invalid verdict value 2 - nft: datatype.c:282: verdict_type_print: Assertion `0' failed. - -ADd stolen verdict (2) and remove the BUG statement. - -Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1261 -Signed-off-by: Florian Westphal -(cherry picked from commit bbbed9f3175c5260332ae7e6800b3a6791418fd2) -Signed-off-by: Phil Sutter ---- - src/datatype.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/datatype.c b/src/datatype.c -index c77d228e95a1e..209044539bb84 100644 ---- a/src/datatype.c -+++ b/src/datatype.c -@@ -280,8 +280,12 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) - case NF_QUEUE: - nft_print(octx, "queue"); - break; -+ case NF_STOLEN: -+ nft_print(octx, "stolen"); -+ break; - default: -- BUG("invalid verdict value %u\n", expr->verdict); -+ nft_print(octx, "unknown verdict value %u", expr->verdict); -+ break; - } - } - } --- -2.21.0 - diff --git a/SOURCES/0033-libnftables-Fix-exit_cookie.patch b/SOURCES/0033-libnftables-Fix-exit_cookie.patch deleted file mode 100644 index f4347b4..0000000 --- a/SOURCES/0033-libnftables-Fix-exit_cookie.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 742f52eeb2bf587abb89dbd81ea0f6f58a9d7309 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 13 Jun 2018 19:18:24 +0200 -Subject: [PATCH] libnftables: Fix exit_cookie() - -The output and error buffer feature depends on cookie->orig_fp to -indicate the current status of buffering: If it is set, a prior call to -init_cookie() is assumed. Though exit_cookie() missed to reset that -pointer to NULL. causing weird behaviour in applications if they do: - -| nft = nft_ctx_new(0); -| nft_ctx_buffer_output(nft); -| nft_ctx_unbuffer_output(nft); -| nft_ctx_buffer_output(nft); - -While being at it, apply the same fix to error path in init_cookie() as -well. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 5ca7ad252366865225d5c59d297e71215b68f027) -Signed-off-by: Phil Sutter ---- - src/libnftables.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/libnftables.c b/src/libnftables.c -index 848c9cba65657..640693df93755 100644 ---- a/src/libnftables.c -+++ b/src/libnftables.c -@@ -195,6 +195,7 @@ static int init_cookie(struct cookie *cookie) - cookie->fp = fopencookie(cookie, "w", cookie_fops); - if (!cookie->fp) { - cookie->fp = cookie->orig_fp; -+ cookie->orig_fp = NULL; - return 1; - } - -@@ -208,6 +209,7 @@ static int exit_cookie(struct cookie *cookie) - - fclose(cookie->fp); - cookie->fp = cookie->orig_fp; -+ cookie->orig_fp = NULL; - free(cookie->buf); - cookie->buf = NULL; - cookie->buflen = 0; --- -2.21.0 - diff --git a/SOURCES/0034-scanner-Do-not-convert-tabs-into-spaces.patch b/SOURCES/0034-scanner-Do-not-convert-tabs-into-spaces.patch deleted file mode 100644 index b21c130..0000000 --- a/SOURCES/0034-scanner-Do-not-convert-tabs-into-spaces.patch +++ /dev/null @@ -1,59 +0,0 @@ -From b652c8a14c3cda433cd8d3ebe8290ee7907e4815 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 18 Jun 2018 10:23:22 +0200 -Subject: [PATCH] scanner: Do not convert tabs into spaces - -Commit 2f86dd5a43baf ("erec: Review erec_print()") changed erec_print() -function to expect tabs in input by replacing the whitespace character -in the marker line at the same offset with a tab character so that the -marker aligns with the offending part of input. - -The need for that came from JSON input not having its tabs converted to -spaces, which erec_print() didn't expect. - -Above change though has a shortcoming: When reading standard syntax -input from a file, Flex code converts tabs into spaces. Location -information is taken from this converted input, but when printing an -error message, the offending input line is read from the input file -directly (which still contains tabs). - -The solution is to simply drop said tab conversion from scanner.l. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 7f8d28105c8caeae7af5bccbe4a6d79f1f73e205) -Signed-off-by: Phil Sutter ---- - src/scanner.l | 16 +--------------- - 1 file changed, 1 insertion(+), 15 deletions(-) - -diff --git a/src/scanner.l b/src/scanner.l -index 416bd27af1427..3551fbf80df6e 100644 ---- a/src/scanner.l -+++ b/src/scanner.l -@@ -613,21 +613,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) - return NEWLINE; - } - --{tab} { -- /* -- * Compensate difference between visible length -- * and real length. -- */ -- struct parser_state *state = yyget_extra(yyscanner); -- unsigned int diff; -- -- diff = TABSIZE - strlen("\t"); -- diff -= (state->indesc->column - -- strlen("\t") - 1) % TABSIZE; -- -- update_pos(state, yylloc, diff); -- } -- -+{tab}+ - {space}+ - {comment} - --- -2.21.0 - diff --git a/SOURCES/0035-netlink_delinearize-Refactor-meta_may_dependency_kil.patch b/SOURCES/0035-netlink_delinearize-Refactor-meta_may_dependency_kil.patch deleted file mode 100644 index 43869fc..0000000 --- a/SOURCES/0035-netlink_delinearize-Refactor-meta_may_dependency_kil.patch +++ /dev/null @@ -1,384 +0,0 @@ -From 0709a45a89405ad4c564b3a8071fffb79da58612 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 21 Jun 2018 14:01:13 +0200 -Subject: [PATCH] netlink_delinearize: Refactor meta_may_dependency_kill() - -The original intent was to fix a bug: The following rule in inet table: - -| meta nfproto ipv4 icmpv6 type echo-reply - -Was added correctly but when printing the meta match was falsely -removed. The fix is to deny dependency killing if RHS family of nfproto -match doesn't match RHS family of l4proto match. Adding this to the -already large conditional led to even more unreadable code, therefore -this patch tries to clean that up (and also removes the partial code -duplication. - -Signed-off-by: Phil Sutter -Signed-off-by: Florian Westphal -(cherry picked from commit 056aaa3e6dc65aced5e552233ac3e7f89fb81f86) -Signed-off-by: Phil Sutter ---- - src/netlink_delinearize.c | 83 +++++++++++----------- - tests/py/inet/icmp.t | 18 +++++ - tests/py/inet/icmp.t.json | 114 +++++++++++++++++++++++++++++++ - tests/py/inet/icmp.t.json.output | 30 ++++++++ - tests/py/inet/icmp.t.payload | 54 +++++++++++++++ - 5 files changed, 259 insertions(+), 40 deletions(-) - create mode 100644 tests/py/inet/icmp.t - create mode 100644 tests/py/inet/icmp.t.json - create mode 100644 tests/py/inet/icmp.t.json.output - create mode 100644 tests/py/inet/icmp.t.payload - -diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c -index bf990e9e979d5..0f4f62f34256c 100644 ---- a/src/netlink_delinearize.c -+++ b/src/netlink_delinearize.c -@@ -1525,61 +1525,64 @@ static bool meta_may_dependency_kill(struct payload_dep_ctx *ctx, - const struct expr *expr) - { - struct expr *dep = ctx->pdep->expr; -+ uint16_t l3proto; -+ uint8_t l4proto; - - if (ctx->pbase != PROTO_BASE_NETWORK_HDR) - return true; - - switch (family) { - case NFPROTO_INET: -- switch (dep->left->ops->type) { -- case EXPR_META: -- if (dep->left->meta.key == NFT_META_NFPROTO && -- (mpz_get_uint16(dep->right->value) == NFPROTO_IPV4 || -- mpz_get_uint16(dep->right->value) == NFPROTO_IPV6) && -- expr->left->meta.key == NFT_META_L4PROTO && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMP && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMPV6) -- return false; -- break; -- case EXPR_PAYLOAD: -- if (dep->left->payload.base == PROTO_BASE_LL_HDR && -- (mpz_get_uint16(dep->right->value) == ETH_P_IP || -- mpz_get_uint16(dep->right->value) == ETH_P_IPV6) && -- expr->left->meta.key == NFT_META_L4PROTO && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMP && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMPV6) -- return false; -- break; -- default: -- break; -- } -- break; - case NFPROTO_NETDEV: - case NFPROTO_BRIDGE: -- switch (dep->left->ops->type) { -- case EXPR_META: -- if (dep->left->meta.key == NFT_META_PROTOCOL && -- (mpz_get_uint16(dep->right->value) == ETH_P_IP || -- mpz_get_uint16(dep->right->value) == ETH_P_IPV6) && -- expr->left->meta.key == NFT_META_L4PROTO && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMP && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMPV6) -- return false; -+ break; -+ default: -+ return true; -+ } -+ -+ if (expr->left->meta.key != NFT_META_L4PROTO) -+ return true; -+ -+ l3proto = mpz_get_uint16(dep->right->value); -+ -+ switch (dep->left->ops->type) { -+ case EXPR_META: -+ if (dep->left->meta.key != NFT_META_NFPROTO) -+ return true; -+ break; -+ case EXPR_PAYLOAD: -+ if (dep->left->payload.base != PROTO_BASE_LL_HDR) -+ return true; -+ -+ switch(l3proto) { -+ case ETH_P_IP: -+ l3proto = NFPROTO_IPV4; - break; -- case EXPR_PAYLOAD: -- if (dep->left->payload.base == PROTO_BASE_LL_HDR && -- (mpz_get_uint16(dep->right->value) == ETH_P_IP || -- mpz_get_uint16(dep->right->value) == ETH_P_IPV6) && -- expr->left->meta.key == NFT_META_L4PROTO && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMP && -- mpz_get_uint8(expr->right->value) != IPPROTO_ICMPV6) -- return false; -+ case ETH_P_IPV6: -+ l3proto = NFPROTO_IPV6; - break; - default: - break; - } - break; -+ default: -+ break; -+ } -+ -+ l4proto = mpz_get_uint8(expr->right->value); -+ -+ switch (l4proto) { -+ case IPPROTO_ICMP: -+ case IPPROTO_ICMPV6: -+ break; -+ default: -+ return false; - } -+ -+ if ((l3proto == NFPROTO_IPV4 && l4proto == IPPROTO_ICMPV6) || -+ (l3proto == NFPROTO_IPV6 && l4proto == IPPROTO_ICMP)) -+ return false; -+ - return true; - } - -diff --git a/tests/py/inet/icmp.t b/tests/py/inet/icmp.t -new file mode 100644 -index 0000000000000..9014f846729c7 ---- /dev/null -+++ b/tests/py/inet/icmp.t -@@ -0,0 +1,18 @@ -+:output;type filter hook output priority 0 -+ -+*inet;test-inet;output -+ -+# without nfproto specified, these should add an implicit dependency on -+# the likely l3 proto (i.e., IPv6 for icmpv6 and IPv4 for icmp) -+ -+icmp type echo-request;ok -+icmpv6 type echo-request;ok -+ -+# make sure only those nfproto matches are dropped if -+# the next statement would add it as a dependency anyway -+ -+meta nfproto ipv4 icmp type echo-request;ok;icmp type echo-request -+meta nfproto ipv4 icmpv6 type echo-request;ok -+ -+meta nfproto ipv6 icmp type echo-request;ok -+meta nfproto ipv6 icmpv6 type echo-request;ok;icmpv6 type echo-request -diff --git a/tests/py/inet/icmp.t.json b/tests/py/inet/icmp.t.json -new file mode 100644 -index 0000000000000..c4517605a7186 ---- /dev/null -+++ b/tests/py/inet/icmp.t.json -@@ -0,0 +1,114 @@ -+# icmp type echo-request -+[ -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmp" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -+# icmpv6 type echo-request -+[ -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmpv6" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -+# meta nfproto ipv4 icmp type echo-request -+[ -+ { -+ "match": { -+ "left": { "meta": "nfproto" }, -+ "right": "ipv4" -+ } -+ }, -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmp" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -+# meta nfproto ipv4 icmpv6 type echo-request -+[ -+ { -+ "match": { -+ "left": { "meta": "nfproto" }, -+ "right": "ipv4" -+ } -+ }, -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmpv6" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -+# meta nfproto ipv6 icmp type echo-request -+[ -+ { -+ "match": { -+ "left": { "meta": "nfproto" }, -+ "right": "ipv6" -+ } -+ }, -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmp" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -+# meta nfproto ipv6 icmpv6 type echo-request -+[ -+ { -+ "match": { -+ "left": { "meta": "nfproto" }, -+ "right": "ipv6" -+ } -+ }, -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmpv6" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -diff --git a/tests/py/inet/icmp.t.json.output b/tests/py/inet/icmp.t.json.output -new file mode 100644 -index 0000000000000..2282900d58e98 ---- /dev/null -+++ b/tests/py/inet/icmp.t.json.output -@@ -0,0 +1,30 @@ -+# meta nfproto ipv4 icmp type echo-request -+[ -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmp" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -+# meta nfproto ipv6 icmpv6 type echo-request -+[ -+ { -+ "match": { -+ "left": { -+ "payload": { -+ "field": "type", -+ "name": "icmpv6" -+ } -+ }, -+ "right": "echo-request" -+ } -+ } -+] -+ -diff --git a/tests/py/inet/icmp.t.payload b/tests/py/inet/icmp.t.payload -new file mode 100644 -index 0000000000000..f98cfc39abed4 ---- /dev/null -+++ b/tests/py/inet/icmp.t.payload -@@ -0,0 +1,54 @@ -+# icmp type echo-request -+inet test-inet output -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x00000002 ] -+ [ meta load l4proto => reg 1 ] -+ [ cmp eq reg 1 0x00000001 ] -+ [ payload load 1b @ transport header + 0 => reg 1 ] -+ [ cmp eq reg 1 0x00000008 ] -+ -+# icmpv6 type echo-request -+inet test-inet output -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x0000000a ] -+ [ meta load l4proto => reg 1 ] -+ [ cmp eq reg 1 0x0000003a ] -+ [ payload load 1b @ transport header + 0 => reg 1 ] -+ [ cmp eq reg 1 0x00000080 ] -+ -+# meta nfproto ipv4 icmp type echo-request -+inet test-inet output -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x00000002 ] -+ [ meta load l4proto => reg 1 ] -+ [ cmp eq reg 1 0x00000001 ] -+ [ payload load 1b @ transport header + 0 => reg 1 ] -+ [ cmp eq reg 1 0x00000008 ] -+ -+# meta nfproto ipv4 icmpv6 type echo-request -+inet test-inet output -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x00000002 ] -+ [ meta load l4proto => reg 1 ] -+ [ cmp eq reg 1 0x0000003a ] -+ [ payload load 1b @ transport header + 0 => reg 1 ] -+ [ cmp eq reg 1 0x00000080 ] -+ -+# meta nfproto ipv6 icmp type echo-request -+inet test-inet output -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x0000000a ] -+ [ meta load l4proto => reg 1 ] -+ [ cmp eq reg 1 0x00000001 ] -+ [ payload load 1b @ transport header + 0 => reg 1 ] -+ [ cmp eq reg 1 0x00000008 ] -+ -+# meta nfproto ipv6 icmpv6 type echo-request -+inet test-inet output -+ [ meta load nfproto => reg 1 ] -+ [ cmp eq reg 1 0x0000000a ] -+ [ meta load l4proto => reg 1 ] -+ [ cmp eq reg 1 0x0000003a ] -+ [ payload load 1b @ transport header + 0 => reg 1 ] -+ [ cmp eq reg 1 0x00000080 ] -+ --- -2.21.0 - diff --git a/SOURCES/0036-evaluate-skip-evaluation-of-datatype-concatenations.patch b/SOURCES/0036-evaluate-skip-evaluation-of-datatype-concatenations.patch deleted file mode 100644 index bc4527e..0000000 --- a/SOURCES/0036-evaluate-skip-evaluation-of-datatype-concatenations.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 1c690d0992d3ef1dbb872b1cd65c10161628e9fd Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Fri, 6 Jul 2018 20:07:54 +0200 -Subject: [PATCH] evaluate: skip evaluation of datatype concatenations - -These are not really expressions, so there is not value in place. The -expr_evaluate_concat() is called from set_evaluate() to calculate the -total length of the tuple. - -Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1265 -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 6b00b9537e181eaf630ecaf0d4e56905eb29d87c) -Signed-off-by: Phil Sutter ---- - src/evaluate.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/src/evaluate.c b/src/evaluate.c -index 4656c7566db39..6ab4a3309ad77 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -1090,7 +1090,8 @@ static int list_member_evaluate(struct eval_ctx *ctx, struct expr **expr) - return err; - } - --static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) -+static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr, -+ bool eval) - { - const struct datatype *dtype = ctx->ectx.dtype, *tmp; - uint32_t type = dtype ? dtype->type : 0, ntype = 0; -@@ -1111,7 +1112,7 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) - tmp = concat_subtype_lookup(type, --off); - expr_set_context(&ctx->ectx, tmp, tmp->size); - -- if (list_member_evaluate(ctx, &i) < 0) -+ if (eval && list_member_evaluate(ctx, &i) < 0) - return -1; - flags &= i->flags; - -@@ -1776,7 +1777,7 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr) - case EXPR_BINOP: - return expr_evaluate_binop(ctx, expr); - case EXPR_CONCAT: -- return expr_evaluate_concat(ctx, expr); -+ return expr_evaluate_concat(ctx, expr, true); - case EXPR_LIST: - return expr_evaluate_list(ctx, expr); - case EXPR_SET: -@@ -2820,7 +2821,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) - - if (set->key->len == 0) { - if (set->key->ops->type == EXPR_CONCAT && -- expr_evaluate_concat(ctx, &set->key) < 0) -+ expr_evaluate_concat(ctx, &set->key, false) < 0) - return -1; - - if (set->key->len == 0) --- -2.21.0 - diff --git a/SOURCES/0037-tests-shell-add-tests-for-listing-objects.patch b/SOURCES/0037-tests-shell-add-tests-for-listing-objects.patch deleted file mode 100644 index 68601dd..0000000 --- a/SOURCES/0037-tests-shell-add-tests-for-listing-objects.patch +++ /dev/null @@ -1,96 +0,0 @@ -From c4bc472abe9f92ca2fcb9696e8e84083dcc29269 Mon Sep 17 00:00:00 2001 -From: Harsha Sharma -Date: Tue, 10 Jul 2018 22:00:21 +0200 -Subject: [PATCH] tests: shell: add tests for listing objects - -Add tests for listing specific object for a given table name and all -objects of a table. - -Signed-off-by: Harsha Sharma -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit bf91cfd9a619484fa3fde325ac092d69738ecf47) - -Conflicts: --> adjust expected output in 0013objects_0 to old code base. - -Signed-off-by: Phil Sutter ---- - tests/shell/testcases/listing/0013objects_0 | 34 +++++++++++++++++++++ - tests/shell/testcases/listing/0014objects_0 | 24 +++++++++++++++ - 2 files changed, 58 insertions(+) - create mode 100755 tests/shell/testcases/listing/0013objects_0 - create mode 100755 tests/shell/testcases/listing/0014objects_0 - -diff --git a/tests/shell/testcases/listing/0013objects_0 b/tests/shell/testcases/listing/0013objects_0 -new file mode 100755 -index 0000000000000..c237e932a4483 ---- /dev/null -+++ b/tests/shell/testcases/listing/0013objects_0 -@@ -0,0 +1,34 @@ -+#!/bin/bash -+ -+# list table with all objects and chains -+ -+EXPECTED="table ip test { -+ quota https-quota { -+ 25 mbytes -+ } -+ -+ ct helper cthelp { -+ type \"sip\" protocol tcp -+ -+ l3proto ip -+ } -+ -+ chain input { -+ } -+}" -+ -+set -e -+ -+$NFT add table test -+$NFT add chain test input -+$NFT add quota test https-quota 25 mbytes -+$NFT add ct helper test cthelp { type \"sip\" protocol tcp \; } -+$NFT add table test-ip -+ -+GET="$($NFT list table test)" -+if [ "$EXPECTED" != "$GET" ] ; then -+ DIFF="$(which diff)" -+ [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") -+ exit 1 -+fi -+ -diff --git a/tests/shell/testcases/listing/0014objects_0 b/tests/shell/testcases/listing/0014objects_0 -new file mode 100755 -index 0000000000000..dcfe2e6f80947 ---- /dev/null -+++ b/tests/shell/testcases/listing/0014objects_0 -@@ -0,0 +1,24 @@ -+#!/bin/bash -+ -+# list only the object asked for with table -+ -+EXPECTED="table ip test { -+ quota https-quota { -+ 25 mbytes -+ } -+}" -+ -+set -e -+ -+$NFT add table test -+$NFT add quota test https-quota 25 mbytes -+$NFT add ct helper test cthelp { type \"sip\" protocol tcp \; } -+$NFT add table test-ip -+ -+GET="$($NFT list quota test https-quota)" -+if [ "$EXPECTED" != "$GET" ] ; then -+ DIFF="$(which diff)" -+ [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") -+ exit 1 -+fi -+ --- -2.21.0 - diff --git a/SOURCES/0038-rule-fix-object-listing-when-no-table-is-given.patch b/SOURCES/0038-rule-fix-object-listing-when-no-table-is-given.patch deleted file mode 100644 index 92facd9..0000000 --- a/SOURCES/0038-rule-fix-object-listing-when-no-table-is-given.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 3e28756a6f0730abac937d9fb10b7ee9c3569a15 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 2 Jan 2019 17:10:36 +0100 -Subject: [PATCH] rule: fix object listing when no table is given - -'nft list quotas' would not print anything at all anymore. - -Fixes: 88456a7ef01172 ("rule: list only the table containing object") -Signed-off-by: Florian Westphal -(cherry picked from commit dafac7d528de0890b82f943fc818ccb7a82fca7d) -Signed-off-by: Phil Sutter ---- - src/rule.c | 13 ++++++++----- - tests/shell/testcases/listing/0014objects_0 | 7 +++++++ - 2 files changed, 15 insertions(+), 5 deletions(-) - -diff --git a/src/rule.c b/src/rule.c -index 47b0d30cbed18..c3a2e7cc464bb 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -1585,13 +1585,16 @@ static int do_list_obj(struct netlink_ctx *ctx, struct cmd *cmd, uint32_t type) - continue; - - if (cmd->handle.table.name != NULL && -- !strcmp(cmd->handle.table.name, table->handle.table.name)) { -- nft_print(&ctx->nft->output, "table %s %s {\n", -- family2str(table->handle.family), -- cmd->handle.table.name); -- } else -+ strcmp(cmd->handle.table.name, table->handle.table.name)) - continue; - -+ if (list_empty(&table->objs)) -+ continue; -+ -+ nft_print(&ctx->nft->output, "table %s %s {\n", -+ family2str(table->handle.family), -+ table->handle.table.name); -+ - list_for_each_entry(obj, &table->objs, list) { - if (obj->type != type || - (cmd->handle.obj.name != NULL && -diff --git a/tests/shell/testcases/listing/0014objects_0 b/tests/shell/testcases/listing/0014objects_0 -index dcfe2e6f80947..20f68406e58fa 100755 ---- a/tests/shell/testcases/listing/0014objects_0 -+++ b/tests/shell/testcases/listing/0014objects_0 -@@ -15,6 +15,13 @@ $NFT add quota test https-quota 25 mbytes - $NFT add ct helper test cthelp { type \"sip\" protocol tcp \; } - $NFT add table test-ip - -+GET="$($NFT list quotas)" -+if [ "$EXPECTED" != "$GET" ] ; then -+ DIFF="$(which diff)" -+ [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") -+ exit 1 -+fi -+ - GET="$($NFT list quota test https-quota)" - if [ "$EXPECTED" != "$GET" ] ; then - DIFF="$(which diff)" --- -2.21.0 - diff --git a/SOURCES/0039-proto-fix-icmp-icmpv6-code-datatype.patch b/SOURCES/0039-proto-fix-icmp-icmpv6-code-datatype.patch deleted file mode 100644 index 4f03b5a..0000000 --- a/SOURCES/0039-proto-fix-icmp-icmpv6-code-datatype.patch +++ /dev/null @@ -1,122 +0,0 @@ -From f314ae8d3cc29d473ff5ce67ad4aa3776283e3d6 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 4 Sep 2018 13:53:59 +0200 -Subject: [PATCH] proto: fix icmp/icmpv6 code datatype - -Andrew A. Sabitov says: - I'd like to use a set (concatenation) of icmpv6 type and icmpv6 code - and check incoming icmpv6 traffic against it: - - add set inet fw in_icmpv6_types { type icmpv6_type . icmpv6_code; } - add element inet fw in_icmpv6_types { 1 . 0 } # no route to destination - add element inet fw in_icmpv6_types { 1 . 1 } # communication with destination administratively prohibited - # ... - - add rule inet fw in_icmpv6 icmpv6 type . icmpv6 code @in_icmpv6_types \ - limit rate 15/minute accept - -yields: -Error: can not use variable sized data types (integer) in concat expressions - icmpv6 type . icmpv6 code @in_icmpv6_types - ~~~~~~~~~~~~~~^^^^^^^^^^^ - -Change 'code' type to the icmp/icmpv6 code type. -Needs minor change to test suite as nft will now display -human-readable names instead of numeric codes. - -Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1276 -Signed-off-by: Florian Westphal -(cherry picked from commit 0f44d4f62753535d39d95d83778348bee4e88053) -Signed-off-by: Phil Sutter ---- - src/proto.c | 4 ++-- - tests/py/ip/icmp.t | 4 ++-- - tests/py/ip/icmp.t.payload.ip | 2 +- - tests/py/ip6/icmpv6.t | 6 +++--- - tests/py/ip6/icmpv6.t.payload.ip6 | 2 +- - 5 files changed, 9 insertions(+), 9 deletions(-) - -diff --git a/src/proto.c b/src/proto.c -index ed011efab2229..d178bf39ea907 100644 ---- a/src/proto.c -+++ b/src/proto.c -@@ -347,7 +347,7 @@ const struct proto_desc proto_icmp = { - .checksum_key = ICMPHDR_CHECKSUM, - .templates = { - [ICMPHDR_TYPE] = ICMPHDR_TYPE("type", &icmp_type_type, type), -- [ICMPHDR_CODE] = ICMPHDR_FIELD("code", code), -+ [ICMPHDR_CODE] = ICMPHDR_TYPE("code", &icmp_code_type, code), - [ICMPHDR_CHECKSUM] = ICMPHDR_FIELD("checksum", checksum), - [ICMPHDR_ID] = ICMPHDR_FIELD("id", un.echo.id), - [ICMPHDR_SEQ] = ICMPHDR_FIELD("sequence", un.echo.sequence), -@@ -686,7 +686,7 @@ const struct proto_desc proto_icmp6 = { - .checksum_key = ICMP6HDR_CHECKSUM, - .templates = { - [ICMP6HDR_TYPE] = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type), -- [ICMP6HDR_CODE] = ICMP6HDR_FIELD("code", icmp6_code), -+ [ICMP6HDR_CODE] = ICMP6HDR_TYPE("code", &icmpv6_code_type, icmp6_code), - [ICMP6HDR_CHECKSUM] = ICMP6HDR_FIELD("checksum", icmp6_cksum), - [ICMP6HDR_PPTR] = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr), - [ICMP6HDR_MTU] = ICMP6HDR_FIELD("mtu", icmp6_mtu), -diff --git a/tests/py/ip/icmp.t b/tests/py/ip/icmp.t -index 5a7ce7e08bac0..6c05fb9d0fbca 100644 ---- a/tests/py/ip/icmp.t -+++ b/tests/py/ip/icmp.t -@@ -28,8 +28,8 @@ icmp code 33-55;ok - icmp code != 33-55;ok - icmp code { 33-55};ok - icmp code != { 33-55};ok --icmp code { 2, 4, 54, 33, 56};ok --icmp code != { 2, 4, 54, 33, 56};ok -+icmp code { 2, 4, 54, 33, 56};ok;icmp code { prot-unreachable, 4, 33, 54, 56} -+icmp code != { prot-unreachable, 4, 33, 54, 56};ok - - icmp checksum 12343 accept;ok - icmp checksum != 12343 accept;ok -diff --git a/tests/py/ip/icmp.t.payload.ip b/tests/py/ip/icmp.t.payload.ip -index f959cf338295c..27f222072d5dc 100644 ---- a/tests/py/ip/icmp.t.payload.ip -+++ b/tests/py/ip/icmp.t.payload.ip -@@ -184,7 +184,7 @@ ip test-ip4 input - [ payload load 1b @ transport header + 1 => reg 1 ] - [ lookup reg 1 set __set%d ] - --# icmp code != { 2, 4, 54, 33, 56} -+# icmp code != { prot-unreachable, 4, 33, 54, 56} - __set%d test-ip4 3 - __set%d test-ip4 0 - element 00000002 : 0 [end] element 00000004 : 0 [end] element 00000036 : 0 [end] element 00000021 : 0 [end] element 00000038 : 0 [end] -diff --git a/tests/py/ip6/icmpv6.t b/tests/py/ip6/icmpv6.t -index a898fe30c24c7..8d794115d51e9 100644 ---- a/tests/py/ip6/icmpv6.t -+++ b/tests/py/ip6/icmpv6.t -@@ -28,10 +28,10 @@ icmpv6 type {router-renumbering, mld-listener-done, time-exceeded, nd-router-sol - icmpv6 type {mld-listener-query, time-exceeded, nd-router-advert} accept;ok - icmpv6 type != {mld-listener-query, time-exceeded, nd-router-advert} accept;ok - --icmpv6 code 4;ok -+icmpv6 code 4;ok;icmpv6 code port-unreachable - icmpv6 code 3-66;ok --icmpv6 code {5, 6, 7} accept;ok --icmpv6 code != {5, 6, 7} accept;ok -+icmpv6 code {5, 6, 7} accept;ok;icmpv6 code {policy-fail, reject-route, 7} accept -+icmpv6 code != {policy-fail, reject-route, 7} accept;ok - icmpv6 code { 3-66};ok - icmpv6 code != { 3-66};ok - -diff --git a/tests/py/ip6/icmpv6.t.payload.ip6 b/tests/py/ip6/icmpv6.t.payload.ip6 -index 7a630f9f8b097..51d71f4149b56 100644 ---- a/tests/py/ip6/icmpv6.t.payload.ip6 -+++ b/tests/py/ip6/icmpv6.t.payload.ip6 -@@ -220,7 +220,7 @@ ip6 test-ip6 input - [ lookup reg 1 set __set%d ] - [ immediate reg 0 accept ] - --# icmpv6 code != {5, 6, 7} accept -+# icmpv6 code != {policy-fail, reject-route, 7} accept - __set%d test-ip6 3 - __set%d test-ip6 0 - element 00000005 : 0 [end] element 00000006 : 0 [end] element 00000007 : 0 [end] --- -2.21.0 - diff --git a/SOURCES/0040-evaluate-throw-distinct-error-if-map-exists-but-cont.patch b/SOURCES/0040-evaluate-throw-distinct-error-if-map-exists-but-cont.patch deleted file mode 100644 index 32d28b4..0000000 --- a/SOURCES/0040-evaluate-throw-distinct-error-if-map-exists-but-cont.patch +++ /dev/null @@ -1,55 +0,0 @@ -From f50e0290b648f00fb76655b23d48d0729500c76a Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Thu, 20 Sep 2018 17:21:45 +0200 -Subject: [PATCH] evaluate: throw distinct error if map exists but contains no - objects -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -nft would throw misleading error in case map exists but doesn't contain -expected objects. - -nft add rule filter in ct helper set tcp dport map @foo -Error: Expression is not a map -add rule filter in ct helper set tcp dport map @foo - ^^^^ -nft list table filter -table ip filter { - map foo { - type inet_service : ifname - } -... - -clarify this. - -Reported-by: Christian Göttsche -Signed-off-by: Florian Westphal -(cherry picked from commit 5b35fb3132b1fa4348266139661ffa21a5a5ae0d) -Signed-off-by: Phil Sutter ---- - src/evaluate.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/evaluate.c b/src/evaluate.c -index 6ab4a3309ad77..88fa44dd34ef5 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -2671,10 +2671,12 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt) - case EXPR_SYMBOL: - if (expr_evaluate(ctx, &map->mappings) < 0) - return -1; -- if (map->mappings->ops->type != EXPR_SET_REF || -- !(map->mappings->set->flags & NFT_SET_OBJECT)) -+ if (map->mappings->ops->type != EXPR_SET_REF) - return expr_error(ctx->msgs, map->mappings, - "Expression is not a map"); -+ if (!(map->mappings->set->flags & NFT_SET_OBJECT)) -+ return expr_error(ctx->msgs, map->mappings, -+ "Expression is not a map with objects"); - break; - default: - BUG("invalid mapping expression %s\n", --- -2.21.0 - diff --git a/SOURCES/0041-parser-bail-out-on-incorrect-burst-unit.patch b/SOURCES/0041-parser-bail-out-on-incorrect-burst-unit.patch deleted file mode 100644 index 69d44ac..0000000 --- a/SOURCES/0041-parser-bail-out-on-incorrect-burst-unit.patch +++ /dev/null @@ -1,106 +0,0 @@ -From bd7a8291c1e00c3625dd348dbb7246b4a7aa357d Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 3 Dec 2018 17:06:21 +0100 -Subject: [PATCH] parser: bail out on incorrect burst unit - -Burst can be either bytes or packets, depending on the rate limit unit. - - # nft add rule x y iif eth0 limit rate 512 kbytes/second burst 5 packets - Error: syntax error, unexpected packets, expecting string or bytes - add rule x y iif eth0 limit rate 512 kbytes/second burst 5 packets - ^^^^^^^ - -Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1306 -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 1018eae77176cffd39bad0e499010923642c2cba) -Signed-off-by: Phil Sutter ---- - src/parser_bison.y | 15 +++++++++------ - tests/py/any/limit.t | 2 ++ - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/src/parser_bison.y b/src/parser_bison.y -index a6b6fc1745a72..aabf16316ff8b 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -562,7 +562,7 @@ int nft_lex(void *, void *, void *); - %type level_type log_flags log_flags_tcp log_flag_tcp - %type limit_stmt quota_stmt connlimit_stmt - %destructor { stmt_free($$); } limit_stmt quota_stmt connlimit_stmt --%type limit_burst limit_mode time_unit quota_mode -+%type limit_burst_pkts limit_burst_bytes limit_mode time_unit quota_mode - %type reject_stmt reject_stmt_alloc - %destructor { stmt_free($$); } reject_stmt reject_stmt_alloc - %type nat_stmt nat_stmt_alloc masq_stmt masq_stmt_alloc redir_stmt redir_stmt_alloc -@@ -2298,7 +2298,7 @@ log_flag_tcp : SEQUENCE - } - ; - --limit_stmt : LIMIT RATE limit_mode NUM SLASH time_unit limit_burst -+limit_stmt : LIMIT RATE limit_mode NUM SLASH time_unit limit_burst_pkts - { - $$ = limit_stmt_alloc(&@$); - $$->limit.rate = $4; -@@ -2307,7 +2307,7 @@ limit_stmt : LIMIT RATE limit_mode NUM SLASH time_unit limit_burst - $$->limit.type = NFT_LIMIT_PKTS; - $$->limit.flags = $3; - } -- | LIMIT RATE limit_mode NUM STRING limit_burst -+ | LIMIT RATE limit_mode NUM STRING limit_burst_bytes - { - struct error_record *erec; - uint64_t rate, unit; -@@ -2388,8 +2388,11 @@ limit_mode : OVER { $$ = NFT_LIMIT_F_INV; } - | /* empty */ { $$ = 0; } - ; - --limit_burst : /* empty */ { $$ = 0; } -+limit_burst_pkts : /* empty */ { $$ = 0; } - | BURST NUM PACKETS { $$ = $2; } -+ ; -+ -+limit_burst_bytes : /* empty */ { $$ = 0; } - | BURST NUM BYTES { $$ = $2; } - | BURST NUM STRING - { -@@ -3199,7 +3202,7 @@ ct_obj_alloc : - } - ; - --limit_config : RATE limit_mode NUM SLASH time_unit limit_burst -+limit_config : RATE limit_mode NUM SLASH time_unit limit_burst_pkts - { - struct limit *limit; - limit = xzalloc(sizeof(*limit)); -@@ -3210,7 +3213,7 @@ limit_config : RATE limit_mode NUM SLASH time_unit limit_burst - limit->flags = $2; - $$ = limit; - } -- | RATE limit_mode NUM STRING limit_burst -+ | RATE limit_mode NUM STRING limit_burst_bytes - { - struct limit *limit; - struct error_record *erec; -diff --git a/tests/py/any/limit.t b/tests/py/any/limit.t -index 8180bea3ddae6..ef7f93133297f 100644 ---- a/tests/py/any/limit.t -+++ b/tests/py/any/limit.t -@@ -14,6 +14,7 @@ limit rate 400/hour;ok - limit rate 40/day;ok - limit rate 400/week;ok - limit rate 1023/second burst 10 packets;ok -+limit rate 1023/second burst 10 bytes;fail - - limit rate 1 kbytes/second;ok - limit rate 2 kbytes/second;ok -@@ -21,6 +22,7 @@ limit rate 1025 kbytes/second;ok - limit rate 1023 mbytes/second;ok - limit rate 10230 mbytes/second;ok - limit rate 1023000 mbytes/second;ok -+limit rate 512 kbytes/second burst 5 packets;fail - - limit rate 1025 bytes/second burst 512 bytes;ok - limit rate 1025 kbytes/second burst 1023 kbytes;ok --- -2.21.0 - diff --git a/SOURCES/0042-src-fix-netdev-family-device-name-parsing.patch b/SOURCES/0042-src-fix-netdev-family-device-name-parsing.patch deleted file mode 100644 index 6af5875..0000000 --- a/SOURCES/0042-src-fix-netdev-family-device-name-parsing.patch +++ /dev/null @@ -1,53 +0,0 @@ -From b4a5b3b3b0a46d9155d0e07e5ab226cf5697cd13 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 9 Jan 2019 23:26:05 +0100 -Subject: [PATCH] src: fix netdev family device name parsing - -Should use accept/use quotes, else you can't use this with a device name -that is shared with a key word, e.g. 'device vm'. - -Signed-off-by: Florian Westphal -Acked-by: Pablo Neira Ayuso -(cherry picked from commit b338244abc7f018d79a95657fff88eadee7e9f6b) - -Conflicts: - src/rule.c - tests/shell/testcases/chains/dumps/0021prio_0.nft --> Context change due to missing commit c8a0e8c90e2d1 - ("src: Set/print standard chain prios with textual names") - -Signed-off-by: Phil Sutter ---- - src/parser_bison.y | 2 +- - src/rule.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/parser_bison.y b/src/parser_bison.y -index aabf16316ff8b..f86a754deea8e 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -1793,7 +1793,7 @@ prio_spec : NUM { $$ = $1; } - | DASH NUM { $$ = -$2; } - ; - --dev_spec : DEVICE STRING { $$ = $2; } -+dev_spec : DEVICE string { $$ = $2; } - | /* empty */ { $$ = NULL; } - ; - -diff --git a/src/rule.c b/src/rule.c -index c3a2e7cc464bb..0b494e4326be6 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -773,7 +773,7 @@ static void chain_print_declaration(const struct chain *chain, - nft_print(octx, "\t\ttype %s hook %s", chain->type, - hooknum2str(chain->handle.family, chain->hooknum)); - if (chain->dev != NULL) -- nft_print(octx, " device %s", chain->dev); -+ nft_print(octx, " device \"%s\"", chain->dev); - nft_print(octx, " priority %d; policy %s;\n", - chain->priority, chain_policy2str(chain->policy)); - } --- -2.21.0 - diff --git a/SOURCES/0043-libnftables-Print-errors-before-freeing-commands.patch b/SOURCES/0043-libnftables-Print-errors-before-freeing-commands.patch deleted file mode 100644 index ab7f593..0000000 --- a/SOURCES/0043-libnftables-Print-errors-before-freeing-commands.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 25d8f60537cd6a700b15941032a2b93066938af3 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 26 Feb 2019 22:13:38 +0100 -Subject: [PATCH] libnftables: Print errors before freeing commands - -Commands may contain data printed by an error record, so make sure -cmd_free() is not called before erec_print_list() has returned. - -Fixes: 778de37d82e7b ("libnftables: Keep cmds list outside of parser_state") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit a0da4c5bbf0d741fb815a977c945afe1b9a0739f) -Signed-off-by: Phil Sutter ---- - src/libnftables.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/libnftables.c b/src/libnftables.c -index 640693df93755..5ca8236d8ba03 100644 ---- a/src/libnftables.c -+++ b/src/libnftables.c -@@ -457,11 +457,11 @@ int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen) - if (nft_netlink(nft, &cmds, &msgs, nft->nf_sock) != 0) - rc = -1; - err: -+ erec_print_list(&nft->output, &msgs, nft->debug_mask); - list_for_each_entry_safe(cmd, next, &cmds, list) { - list_del(&cmd->list); - cmd_free(cmd); - } -- erec_print_list(&nft->output, &msgs, nft->debug_mask); - iface_cache_release(); - if (nft->scanner) { - scanner_destroy(nft->scanner); -@@ -497,11 +497,11 @@ int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename) - if (nft_netlink(nft, &cmds, &msgs, nft->nf_sock) != 0) - rc = -1; - err: -+ erec_print_list(&nft->output, &msgs, nft->debug_mask); - list_for_each_entry_safe(cmd, next, &cmds, list) { - list_del(&cmd->list); - cmd_free(cmd); - } -- erec_print_list(&nft->output, &msgs, nft->debug_mask); - iface_cache_release(); - if (nft->scanner) { - scanner_destroy(nft->scanner); --- -2.21.0 - diff --git a/SOURCES/0044-segtree-fix-crash-when-debug-mode-is-active.patch b/SOURCES/0044-segtree-fix-crash-when-debug-mode-is-active.patch deleted file mode 100644 index e40cda4..0000000 --- a/SOURCES/0044-segtree-fix-crash-when-debug-mode-is-active.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 9c9034a8cb88de406c64553d27f6471f99b9e06a Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Mon, 4 Mar 2019 01:06:05 +0100 -Subject: [PATCH] segtree: fix crash when debug mode is active -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We must set output_fp to sensible filep, else crash. - -Reported-by: Václav Zindulka -Signed-off-by: Florian Westphal -(cherry picked from commit afd1ad6f68680c0f0a4afad7c67ddc8652948732) -Signed-off-by: Phil Sutter ---- - src/segtree.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/segtree.c b/src/segtree.c -index 5685618b3724a..5a5a728912db7 100644 ---- a/src/segtree.c -+++ b/src/segtree.c -@@ -9,6 +9,7 @@ - */ - - #include -+#include - #include - #include - -@@ -67,8 +68,6 @@ struct elementary_interval { - struct expr *expr; - }; - --static struct output_ctx debug_octx = {}; -- - static void seg_tree_init(struct seg_tree *tree, const struct set *set, - struct expr *init, unsigned int debug_mask) - { -@@ -570,6 +569,7 @@ int set_to_intervals(struct list_head *errs, struct set *set, - bool merge) - { - struct elementary_interval *ei, *next; -+ struct output_ctx debug_octx; - struct seg_tree tree; - LIST_HEAD(list); - -@@ -590,6 +590,9 @@ int set_to_intervals(struct list_head *errs, struct set *set, - } - - if (segtree_debug(tree.debug_mask)) { -+ memset(&debug_octx, 0, sizeof(debug_octx)); -+ debug_octx.output_fp = stderr; -+ debug_octx.error_fp = stderr; - expr_print(init, &debug_octx); - pr_gmp_debug("\n"); - } --- -2.21.0 - diff --git a/SOURCES/0045-parser_bison-no-need-for-statement-separator-for-ct-.patch b/SOURCES/0045-parser_bison-no-need-for-statement-separator-for-ct-.patch deleted file mode 100644 index db0621f..0000000 --- a/SOURCES/0045-parser_bison-no-need-for-statement-separator-for-ct-.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 156f738087525eeb35e1225d8fb1e23da71dc58b Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Thu, 14 Mar 2019 11:04:37 +0100 -Subject: [PATCH] parser_bison: no need for statement separator for ct object - commands - -Otherwise, this forces user to place a double semi-colon to skip a -parser error in a multi-line commands: - - # nft add "ct helper ip filter test { type \"ftp\" protocol tcp; };add rule filter test ct helper set \"ftp\"" - Error: syntax error, unexpected add, expecting end of file or newline or semicolon - add ct helper ip filter test { type "ftp" protocol tcp; };add rule filter test ct helper set "ftp" - ^^^ - -Reported-by: Laura Garcia -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit d3cace26609253a8e3f20aeb8693f37d63897a7e) - -Conflicts: - src/parser_bison.y --> Some chunks dropped for missing commit c7c94802679cd - ("src: add ct timeout support") - -Signed-off-by: Phil Sutter ---- - src/parser_bison.y | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/parser_bison.y b/src/parser_bison.y -index f86a754deea8e..99d60822790dc 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -941,7 +941,7 @@ add_cmd : TABLE table_spec - { - $$ = cmd_alloc(CMD_ADD, CMD_OBJ_QUOTA, &$2, &@$, $3); - } -- | CT HELPER obj_spec ct_obj_alloc '{' ct_helper_block '}' stmt_separator -+ | CT HELPER obj_spec ct_obj_alloc '{' ct_helper_block '}' - { - - $$ = cmd_alloc_obj_ct(CMD_ADD, NFT_OBJECT_CT_HELPER, &$3, &@$, $4); -@@ -1023,7 +1023,7 @@ create_cmd : TABLE table_spec - { - $$ = cmd_alloc(CMD_CREATE, CMD_OBJ_QUOTA, &$2, &@$, $3); - } -- | CT HELPER obj_spec ct_obj_alloc '{' ct_helper_block '}' stmt_separator -+ | CT HELPER obj_spec ct_obj_alloc '{' ct_helper_block '}' - { - $$ = cmd_alloc_obj_ct(CMD_CREATE, NFT_OBJECT_CT_HELPER, &$3, &@$, $4); - } --- -2.21.0 - diff --git a/SOURCES/0046-ct-use-nft_print-instead-of-printf.patch b/SOURCES/0046-ct-use-nft_print-instead-of-printf.patch deleted file mode 100644 index cd17e21..0000000 --- a/SOURCES/0046-ct-use-nft_print-instead-of-printf.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 5d255c91b90a3480d084c50c6c61bb3dcd380ab7 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Fri, 5 Apr 2019 15:36:48 +0200 -Subject: [PATCH] ct: use nft_print() instead of printf() - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit e07be57df3f5191d23b05c4fb06a94f3961beb13) - -Conflicts: --> Change applied manually due to missing commit 4795a994e2810 - ("src: use 'flow add' syntax") - -Signed-off-by: Phil Sutter ---- - src/ct.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/ct.c b/src/ct.c -index 1d50382bab8b1..f019f5af3e182 100644 ---- a/src/ct.c -+++ b/src/ct.c -@@ -481,7 +481,7 @@ struct stmt *notrack_stmt_alloc(const struct location *loc) - static void flow_offload_stmt_print(const struct stmt *stmt, - struct output_ctx *octx) - { -- printf("flow offload @%s", stmt->flow.table_name); -+ nft_print(octx, "flow offload @%s", stmt->flow.table_name); - } - - static const struct stmt_ops flow_offload_stmt_ops = { --- -2.21.0 - diff --git a/SOURCES/0047-parser_bison-type_identifier-string-memleak.patch b/SOURCES/0047-parser_bison-type_identifier-string-memleak.patch deleted file mode 100644 index 51687b4..0000000 --- a/SOURCES/0047-parser_bison-type_identifier-string-memleak.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 539029b8aee913dd391da66ecd0ac9ff2adb12ff Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Fri, 5 Apr 2019 14:09:56 +0200 -Subject: [PATCH] parser_bison: type_identifier string memleak - -==6297== 24 bytes in 3 blocks are definitely lost in loss record 2 of 13 -==6297== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) -==6297== by 0x56193B9: strdup (strdup.c:42) -==6297== by 0x4E758BD: xstrdup (utils.c:75) -==6297== by 0x4E7F9D3: nft_parse (parser_bison.y:1895) -==6297== by 0x4E7AAE1: nft_parse_bison_filename (libnftables.c:370) -==6297== by 0x4E7AAE1: nft_run_cmd_from_filename (libnftables.c:438) -==6297== by 0x109A33: main (main.c:310) - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 4d97f0a4eebd25d1639cd7c7ac2452445205a819) -Signed-off-by: Phil Sutter ---- - src/parser_bison.y | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/parser_bison.y b/src/parser_bison.y -index 99d60822790dc..1dc83953ea858 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -1681,11 +1681,11 @@ data_type_atom_expr : type_identifier - if (dtype == NULL) { - erec_queue(error(&@1, "unknown datatype %s", $1), - state->msgs); -- xfree($1); - YYERROR; - } - $$ = constant_expr_alloc(&@1, dtype, dtype->byteorder, - dtype->size, NULL); -+ xfree($1); - } - ; - --- -2.21.0 - diff --git a/SOURCES/0048-src-missing-destroy-function-in-statement-definition.patch b/SOURCES/0048-src-missing-destroy-function-in-statement-definition.patch deleted file mode 100644 index 7b7ea9f..0000000 --- a/SOURCES/0048-src-missing-destroy-function-in-statement-definition.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 61e3dab3169af7add5fa131bb7414adf586d2997 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Fri, 5 Apr 2019 15:35:36 +0200 -Subject: [PATCH] src: missing destroy function in statement definitions - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 4ac11b890fe870d1c066783bccc235e1922dd431) - -Conflicts: --> Dropped changes to set_stmt_destroy() and map_stmt_destroy() due to - missing commit a55ca1a24b7b2 ("src: integrate stateful expressions - into sets and maps") - -Signed-off-by: Phil Sutter ---- - src/ct.c | 12 ++++++++++++ - src/exthdr.c | 7 +++++++ - src/meta.c | 6 ++++++ - src/payload.c | 7 +++++++ - src/statement.c | 19 +++++++++++++++++++ - src/xt.c | 1 + - 6 files changed, 52 insertions(+) - -diff --git a/src/ct.c b/src/ct.c -index f019f5af3e182..c2ca51494af60 100644 ---- a/src/ct.c -+++ b/src/ct.c -@@ -440,11 +440,17 @@ static void ct_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - expr_print(stmt->ct.expr, octx); - } - -+static void ct_stmt_destroy(struct stmt *stmt) -+{ -+ expr_free(stmt->ct.expr); -+} -+ - static const struct stmt_ops ct_stmt_ops = { - .type = STMT_CT, - .name = "ct", - .print = ct_stmt_print, - .json = ct_stmt_json, -+ .destroy = ct_stmt_destroy, - }; - - struct stmt *ct_stmt_alloc(const struct location *loc, enum nft_ct_keys key, -@@ -484,10 +490,16 @@ static void flow_offload_stmt_print(const struct stmt *stmt, - nft_print(octx, "flow offload @%s", stmt->flow.table_name); - } - -+static void flow_offload_stmt_destroy(struct stmt *stmt) -+{ -+ xfree(stmt->flow.table_name); -+} -+ - static const struct stmt_ops flow_offload_stmt_ops = { - .type = STMT_FLOW_OFFLOAD, - .name = "flow_offload", - .print = flow_offload_stmt_print, -+ .destroy = flow_offload_stmt_destroy, - }; - - struct stmt *flow_offload_stmt_alloc(const struct location *loc, -diff --git a/src/exthdr.c b/src/exthdr.c -index cb0a58e8526a5..8602016f66477 100644 ---- a/src/exthdr.c -+++ b/src/exthdr.c -@@ -104,11 +104,18 @@ static void exthdr_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - expr_print(stmt->exthdr.val, octx); - } - -+static void exthdr_stmt_destroy(struct stmt *stmt) -+{ -+ expr_free(stmt->exthdr.expr); -+ expr_free(stmt->exthdr.val); -+} -+ - static const struct stmt_ops exthdr_stmt_ops = { - .type = STMT_EXTHDR, - .name = "exthdr", - .print = exthdr_stmt_print, - .json = exthdr_stmt_json, -+ .destroy = exthdr_stmt_destroy, - }; - - struct stmt *exthdr_stmt_alloc(const struct location *loc, -diff --git a/src/meta.c b/src/meta.c -index ff0cb122d7dfa..c1021febdefd4 100644 ---- a/src/meta.c -+++ b/src/meta.c -@@ -604,11 +604,17 @@ static void meta_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - expr_print(stmt->meta.expr, octx); - } - -+static void meta_stmt_destroy(struct stmt *stmt) -+{ -+ expr_free(stmt->meta.expr); -+} -+ - static const struct stmt_ops meta_stmt_ops = { - .type = STMT_META, - .name = "meta", - .print = meta_stmt_print, - .json = meta_stmt_json, -+ .destroy = meta_stmt_destroy, - }; - - struct stmt *meta_stmt_alloc(const struct location *loc, enum nft_meta_keys key, -diff --git a/src/payload.c b/src/payload.c -index 6517686cbfba5..42b055360848d 100644 ---- a/src/payload.c -+++ b/src/payload.c -@@ -189,11 +189,18 @@ static void payload_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - expr_print(stmt->payload.val, octx); - } - -+static void payload_stmt_destroy(struct stmt *stmt) -+{ -+ expr_free(stmt->payload.expr); -+ expr_free(stmt->payload.val); -+} -+ - static const struct stmt_ops payload_stmt_ops = { - .type = STMT_PAYLOAD, - .name = "payload", - .print = payload_stmt_print, - .json = payload_stmt_json, -+ .destroy = payload_stmt_destroy, - }; - - struct stmt *payload_stmt_alloc(const struct location *loc, -diff --git a/src/statement.c b/src/statement.c -index e9c9d648b0092..1b889e77cca20 100644 ---- a/src/statement.c -+++ b/src/statement.c -@@ -134,6 +134,7 @@ static void meter_stmt_destroy(struct stmt *stmt) - expr_free(stmt->meter.key); - expr_free(stmt->meter.set); - stmt_free(stmt->meter.stmt); -+ xfree(stmt->meter.name); - } - - static const struct stmt_ops meter_stmt_ops = { -@@ -226,11 +227,17 @@ static void objref_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - expr_print(stmt->objref.expr, octx); - } - -+static void objref_stmt_destroy(struct stmt *stmt) -+{ -+ expr_free(stmt->objref.expr); -+} -+ - static const struct stmt_ops objref_stmt_ops = { - .type = STMT_OBJREF, - .name = "objref", - .print = objref_stmt_print, - .json = objref_stmt_json, -+ .destroy = objref_stmt_destroy, - }; - - struct stmt *objref_stmt_alloc(const struct location *loc) -@@ -435,11 +442,17 @@ static void queue_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - - } - -+static void queue_stmt_destroy(struct stmt *stmt) -+{ -+ expr_free(stmt->queue.queue); -+} -+ - static const struct stmt_ops queue_stmt_ops = { - .type = STMT_QUEUE, - .name = "queue", - .print = queue_stmt_print, - .json = queue_stmt_json, -+ .destroy = queue_stmt_destroy, - }; - - struct stmt *queue_stmt_alloc(const struct location *loc) -@@ -511,11 +524,17 @@ static void reject_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - } - } - -+static void reject_stmt_destroy(struct stmt *stmt) -+{ -+ expr_free(stmt->reject.expr); -+} -+ - static const struct stmt_ops reject_stmt_ops = { - .type = STMT_REJECT, - .name = "reject", - .print = reject_stmt_print, - .json = reject_stmt_json, -+ .destroy = reject_stmt_destroy, - }; - - struct stmt *reject_stmt_alloc(const struct location *loc) -diff --git a/src/xt.c b/src/xt.c -index 74763d58cafd7..298a94d51e8a0 100644 ---- a/src/xt.c -+++ b/src/xt.c -@@ -92,6 +92,7 @@ void xt_stmt_release(const struct stmt *stmt) - break; - } - xfree(stmt->xt.entry); -+ xfree(stmt->xt.name); - } - - static void *xt_entry_alloc(struct xt_stmt *xt, uint32_t af) --- -2.21.0 - diff --git a/SOURCES/0049-tests-shell-validate-too-deep-jumpstack-from-basecha.patch b/SOURCES/0049-tests-shell-validate-too-deep-jumpstack-from-basecha.patch deleted file mode 100644 index 67a76b3..0000000 --- a/SOURCES/0049-tests-shell-validate-too-deep-jumpstack-from-basecha.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 62e3a8f9d4246bc491d0b4aa11b250ed8ad06ecc Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 8 Aug 2018 21:52:50 +0200 -Subject: [PATCH] tests: shell: validate too deep jumpstack from basechain - -If there is no basechain, the validation is never exercised. - -Too deep nested chains are fine as long as they are not connected to a -basechain. - -Update test to add a basechain so we exercise validation. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 760a8bab07ade570e589bc8da36935776d225d95) -Signed-off-by: Phil Sutter ---- - tests/shell/testcases/chains/0002jumps_1 | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/tests/shell/testcases/chains/0002jumps_1 b/tests/shell/testcases/chains/0002jumps_1 -index 0cc89288670ed..4d163b05fe1b9 100755 ---- a/tests/shell/testcases/chains/0002jumps_1 -+++ b/tests/shell/testcases/chains/0002jumps_1 -@@ -6,7 +6,9 @@ MAX_JUMPS=16 - - $NFT add table t - --for i in $(seq 1 $MAX_JUMPS) -+$NFT add chain t c1 { type filter hook input priority 0\; } -+ -+for i in $(seq 2 $MAX_JUMPS) - do - $NFT add chain t c${i} - done --- -2.21.0 - diff --git a/SOURCES/0050-netlink-remove-markup-json-parsing-code.patch b/SOURCES/0050-netlink-remove-markup-json-parsing-code.patch deleted file mode 100644 index fdeb584..0000000 --- a/SOURCES/0050-netlink-remove-markup-json-parsing-code.patch +++ /dev/null @@ -1,367 +0,0 @@ -From fbccf77429c4f1fccd48a201369402e33bea91c6 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Wed, 26 Sep 2018 16:23:19 +0200 -Subject: [PATCH] netlink: remove markup json parsing code - -We have better json support these days, remove libnftnl json support. - -While at it, remove test file for this too. - -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 276c452e47c5e22b3af06a051aa2908521aeba66) -Signed-off-by: Phil Sutter ---- - src/netlink.c | 276 +----------------- - tests/shell/testcases/import/vm_json_import_0 | 53 ---- - 2 files changed, 2 insertions(+), 327 deletions(-) - delete mode 100755 tests/shell/testcases/import/vm_json_import_0 - -diff --git a/src/netlink.c b/src/netlink.c -index c178be3c9ee26..0509a06b3d2b3 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -1970,280 +1970,8 @@ int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type, - return MNL_CB_OK; - } - --static int netlink_markup_setelems(const struct nftnl_parse_ctx *ctx) --{ -- const struct ruleset_parse *rp; -- struct nftnl_set *set; -- uint32_t cmd; -- int ret = -1; -- -- set = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_SET); -- rp = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_DATA); -- -- cmd = nftnl_ruleset_ctx_get_u32(ctx, NFTNL_RULESET_CTX_CMD); -- switch (cmd) { -- case NFTNL_CMD_ADD: -- ret = mnl_nft_setelem_batch_add(set, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_DELETE: -- ret = mnl_nft_setelem_batch_del(set, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- default: -- errno = EOPNOTSUPP; -- break; -- } -- -- return ret; --} -- --static int netlink_markup_set(const struct nftnl_parse_ctx *ctx) --{ -- const struct ruleset_parse *rp; -- struct nftnl_set *set; -- uint32_t cmd; -- int ret = -1; -- -- set = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_SET); -- rp = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_DATA); -- -- cmd = nftnl_ruleset_ctx_get_u32(ctx, NFTNL_RULESET_CTX_CMD); -- switch (cmd) { -- case NFTNL_CMD_ADD: -- ret = mnl_nft_set_batch_add(set, rp->nl_ctx->batch, NLM_F_EXCL, -- rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_DELETE: -- ret = mnl_nft_set_batch_del(set, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- default: -- errno = EOPNOTSUPP; -- break; -- } -- -- if (ret < 0) -- return ret; -- -- return netlink_markup_setelems(ctx); --} -- --static int netlink_markup_build_rule(const struct nftnl_parse_ctx *ctx, -- uint32_t cmd, struct nftnl_rule *rule) --{ -- const struct ruleset_parse *rp; -- uint32_t nl_flags; -- int ret = -1; -- -- rp = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_DATA); -- -- switch (cmd) { -- case NFTNL_CMD_ADD: -- nl_flags = NLM_F_APPEND | NLM_F_CREATE; -- nftnl_rule_unset(rule, NFTNL_RULE_HANDLE); -- ret = mnl_nft_rule_batch_add(rule, rp->nl_ctx->batch, nl_flags, -- rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_DELETE: -- ret = mnl_nft_rule_batch_del(rule, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_REPLACE: -- nl_flags = NLM_F_REPLACE; -- ret = mnl_nft_rule_batch_add(rule, rp->nl_ctx->batch, nl_flags, -- rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_INSERT: -- nl_flags = NLM_F_CREATE; -- nftnl_rule_unset(rule, NFTNL_RULE_HANDLE); -- ret = mnl_nft_rule_batch_add(rule, rp->nl_ctx->batch, nl_flags, -- rp->nl_ctx->seqnum); -- break; -- default: -- errno = EOPNOTSUPP; -- break; -- } -- -- return ret; -- --} -- --static int netlink_markup_rule(const struct nftnl_parse_ctx *ctx) --{ -- struct nftnl_rule *rule; -- uint32_t cmd; -- -- cmd = nftnl_ruleset_ctx_get_u32(ctx, NFTNL_RULESET_CTX_CMD); -- rule = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_RULE); -- -- return netlink_markup_build_rule(ctx, cmd, rule); --} -- --static int netlink_markup_build_flush(const struct nftnl_parse_ctx *ctx) --{ -- struct nftnl_rule *rule; -- struct nftnl_table *table; -- struct nftnl_chain *chain; -- const char *table_get_name, *table_get_family; -- const char *chain_get_table, *chain_get_name, *chain_get_family; -- uint32_t type; -- int ret = -1; -- -- rule = nftnl_rule_alloc(); -- if (rule == NULL) -- return -1; -- -- type = nftnl_ruleset_ctx_get_u32(ctx, NFTNL_RULESET_CTX_TYPE); -- switch (type) { -- case NFTNL_RULESET_TABLE: -- table = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_TABLE); -- table_get_name = nftnl_table_get(table, NFTNL_TABLE_NAME); -- table_get_family = nftnl_table_get(table, NFTNL_TABLE_FAMILY); -- -- nftnl_rule_set(rule, NFTNL_RULE_TABLE, table_get_name); -- nftnl_rule_set(rule, NFTNL_RULE_FAMILY, table_get_family); -- break; -- case NFTNL_RULESET_CHAIN: -- chain = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_CHAIN); -- chain_get_table = nftnl_chain_get(chain, NFTNL_CHAIN_TABLE); -- chain_get_name = nftnl_chain_get(chain, NFTNL_CHAIN_NAME); -- chain_get_family = nftnl_chain_get(chain, NFTNL_TABLE_FAMILY); -- -- nftnl_rule_set(rule, NFTNL_RULE_TABLE, chain_get_table); -- nftnl_rule_set(rule, NFTNL_RULE_CHAIN, chain_get_name); -- nftnl_rule_set(rule, NFTNL_RULE_FAMILY, chain_get_family); -- break; -- default: -- errno = EOPNOTSUPP; -- goto err; -- } -- -- ret = netlink_markup_build_rule(ctx, NFTNL_CMD_DELETE, rule); --err: -- nftnl_rule_free(rule); -- return ret; --} -- --static int netlink_markup_chain(const struct nftnl_parse_ctx *ctx) --{ -- const struct ruleset_parse *rp; -- struct nftnl_chain *chain; -- uint32_t cmd; -- int ret = -1; -- -- chain = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_CHAIN); -- rp = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_DATA); -- -- nftnl_chain_unset(chain, NFTNL_CHAIN_HANDLE); -- -- cmd = nftnl_ruleset_ctx_get_u32(ctx, NFTNL_RULESET_CTX_CMD); -- switch (cmd) { -- case NFTNL_CMD_ADD: -- ret = mnl_nft_chain_batch_add(chain, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_DELETE: -- ret = mnl_nft_chain_batch_del(chain, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_FLUSH: -- ret = netlink_markup_build_flush(ctx); -- break; -- default: -- errno = EOPNOTSUPP; -- break; -- } -- -- return ret; --} -- -- --static int netlink_markup_build_table(const struct nftnl_parse_ctx *ctx, -- uint32_t cmd, struct nftnl_table *table) --{ -- struct ruleset_parse *rp; -- int ret = -1; -- -- rp = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_DATA); -- -- switch (cmd) { -- case NFTNL_CMD_ADD: -- ret = mnl_nft_table_batch_add(table, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_DELETE: -- ret = mnl_nft_table_batch_del(table, rp->nl_ctx->batch, -- 0, rp->nl_ctx->seqnum); -- break; -- case NFTNL_CMD_FLUSH: -- ret = netlink_markup_build_flush(ctx); -- break; -- default: -- errno = EOPNOTSUPP; -- break; -- } -- -- return ret; --} -- --static int netlink_markup_table(const struct nftnl_parse_ctx *ctx) --{ -- struct nftnl_table *table; -- uint32_t cmd; -- -- cmd = nftnl_ruleset_ctx_get_u32(ctx, NFTNL_RULESET_CTX_CMD); -- table = nftnl_ruleset_ctx_get(ctx, NFTNL_RULESET_CTX_TABLE); -- -- return netlink_markup_build_table(ctx, cmd, table); --} -- --static int netlink_markup_flush(const struct nftnl_parse_ctx *ctx) --{ -- struct nftnl_table *table; -- int ret; -- -- table = nftnl_table_alloc(); -- if (table == NULL) -- return -1; -- -- ret = netlink_markup_build_table(ctx, NFTNL_CMD_DELETE, table); -- nftnl_table_free(table); -- -- return ret; --} -- - int netlink_markup_parse_cb(const struct nftnl_parse_ctx *ctx) - { -- uint32_t type; -- int ret = -1; -- -- type = nftnl_ruleset_ctx_get_u32(ctx, NFTNL_RULESET_CTX_TYPE); -- switch (type) { -- case NFTNL_RULESET_TABLE: -- ret = netlink_markup_table(ctx); -- break; -- case NFTNL_RULESET_CHAIN: -- ret = netlink_markup_chain(ctx); -- break; -- case NFTNL_RULESET_RULE: -- ret = netlink_markup_rule(ctx); -- break; -- case NFTNL_RULESET_SET: -- ret = netlink_markup_set(ctx); -- break; -- case NFTNL_RULESET_SET_ELEMS: -- ret = netlink_markup_setelems(ctx); -- break; -- case NFTNL_RULESET_RULESET: -- ret = netlink_markup_flush(ctx); -- break; -- default: -- errno = EOPNOTSUPP; -- break; -- } -- -- nftnl_ruleset_ctx_free(ctx); -- -- return ret; -+ errno = EOPNOTSUPP; -+ return -1; - } -diff --git a/tests/shell/testcases/import/vm_json_import_0 b/tests/shell/testcases/import/vm_json_import_0 -deleted file mode 100755 -index 546ccf7ab490f..0000000000000 ---- a/tests/shell/testcases/import/vm_json_import_0 -+++ /dev/null -@@ -1,53 +0,0 @@ --#!/bin/bash -- --RULESET="table ip mangle { -- set blackhole { -- type ipv4_addr -- elements = { 192.168.1.4, 192.168.1.5 } -- } -- -- chain prerouting { -- type filter hook prerouting priority 0; policy accept; -- tcp dport { ssh, http } accept -- ip saddr @blackhole drop -- icmp type echo-request accept -- iifname \"lo\" accept -- icmp type echo-request counter packets 0 bytes 0 -- ct state established,related accept -- tcp flags != syn counter packets 7 bytes 841 -- ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter packets 0 bytes 0 -- } --} --table arp x { -- chain y { -- arp htype 22 -- arp ptype ip -- arp operation != rrequest -- arp operation { request, reply, rrequest, rreply, inrequest, inreply, nak } -- arp hlen 33-45 -- } --} --table bridge x { -- chain y { -- type filter hook input priority 0; policy accept; -- vlan id 4094 -- vlan id 4094 vlan cfi 0 -- vlan id 1 ip saddr 10.0.0.0/23 udp dport domain -- } --} --table ip6 x { -- chain y { -- type nat hook postrouting priority 0; policy accept; -- icmpv6 id 33-45 -- ip6 daddr fe00::1-fe00::200 udp dport domain counter packets 0 bytes 0 -- meta l4proto tcp masquerade to :1024 -- iifname \"wlan0\" ct state established,new tcp dport vmap { ssh : drop, 222 : drop } masquerade -- tcp dport ssh ip6 daddr 1::2 ether saddr 00:0f:54:0c:11:04 accept -- ip6 daddr fe00::1-fe00::200 udp dport domain counter packets 0 bytes 0 masquerade -- } --}" -- --$NFT -f - <<< "$RULESET" --RULESET_JSON=$($NFT export vm json) --$NFT flush ruleset --$NFT import vm json <<< "$RULESET_JSON" --- -2.21.0 - diff --git a/SOURCES/0051-rule-limit-don-t-print-default-burst-value.patch b/SOURCES/0051-rule-limit-don-t-print-default-burst-value.patch deleted file mode 100644 index 4a51b2e..0000000 --- a/SOURCES/0051-rule-limit-don-t-print-default-burst-value.patch +++ /dev/null @@ -1,36 +0,0 @@ -From a06d879ceba6b1ae7b541c223701435a4d1394e1 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 4 Jul 2018 15:10:12 +0200 -Subject: [PATCH] rule: limit: don't print default burst value - -limit http-traffic { rate 1/second } gets printed as -limit http-traffic { rate 1/second burst 5 packets } - -caused tests/shell/run-tests.sh tests/shell/testcases/sets/0026named_limit_0 - -to return 'DUMP FAIL'. - -Signed-off-by: Florian Westphal -Acked-by: Pablo Neira Ayuso -(cherry picked from commit 1dc9be8445265498a2db534ae254260b6e7dd75b) -Signed-off-by: Phil Sutter ---- - src/rule.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/rule.c b/src/rule.c -index 0b494e4326be6..850b00cfc9874 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -1472,7 +1472,7 @@ static void obj_print_data(const struct obj *obj, - nft_print(octx, "rate %s%" PRIu64 "/%s", - inv ? "over " : "", obj->limit.rate, - get_unit(obj->limit.unit)); -- if (obj->limit.burst > 0) -+ if (obj->limit.burst > 0 && obj->limit.burst != 5) - nft_print(octx, " burst %u packets", - obj->limit.burst); - break; --- -2.21.0 - diff --git a/SOURCES/0052-JSON-Review-verdict-statement-and-expression.patch b/SOURCES/0052-JSON-Review-verdict-statement-and-expression.patch deleted file mode 100644 index b0dce22..0000000 --- a/SOURCES/0052-JSON-Review-verdict-statement-and-expression.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 9eb22ba5e195c97ca7a1e2baac7fec68b3f3b310 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Wed, 29 Aug 2018 16:23:23 +0200 -Subject: [PATCH] JSON: Review verdict statement and expression - -Change jump and goto verdicts to become extensible by dedicating an -object for the target parameter. - -While being at it, drop break and queue verdict expressions since they -don't seem to exist, no idea where I got those from in the first place. -For queue, there is a dedicated expression at least. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 8125785d5c5d35ec275e508166091d5472748bc1) - -Conflicts: - doc/libnftables-json.adoc --> Dropped changes to non-existent libnftables JSON API documentation. - -Signed-off-by: Phil Sutter ---- - src/json.c | 5 ++++- - src/parser_json.c | 10 ++++------ - tests/py/nft-test.py | 4 +++- - 3 files changed, 11 insertions(+), 8 deletions(-) - -diff --git a/src/json.c b/src/json.c -index f74afd5a7292e..fad2a83624062 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -651,7 +651,10 @@ json_t *verdict_expr_json(const struct expr *expr, struct output_ctx *octx) - BUG("Unknown verdict %d.", expr->verdict); - return NULL; - } -- return json_pack("{s:o}", name, chain ? json_string(chain) : json_null()); -+ if (chain) -+ return json_pack("{s:{s:s}}", name, "target", chain); -+ else -+ return json_pack("{s:n}", name); - } - - json_t *rt_expr_json(const struct expr *expr, struct output_ctx *octx) -diff --git a/src/parser_json.c b/src/parser_json.c -index 1e3688b2dc1cd..e3f20ae51c764 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -1008,27 +1008,25 @@ static struct expr *json_parse_verdict_expr(struct json_ctx *ctx, - bool chain; - } verdict_tbl[] = { - { NFT_CONTINUE, "continue", false }, -- { NFT_BREAK, "break", false }, - { NFT_JUMP, "jump", true }, - { NFT_GOTO, "goto", true }, - { NFT_RETURN, "return", false }, - { NF_ACCEPT, "accept", false }, - { NF_DROP, "drop", false }, -- { NF_QUEUE, "queue", false }, - }; - const char *chain = NULL; - unsigned int i; - -- json_unpack(root, "s", &chain); -+ json_unpack(root, "{s:s}", "target", &chain); - - for (i = 0; i < array_size(verdict_tbl); i++) { - if (strcmp(type, verdict_tbl[i].name)) - continue; - -- if (verdict_tbl[i].chain && !chain) { -- json_error(ctx, "Verdict %s needs chain argument.", type); -+ if (verdict_tbl[i].chain && -+ json_unpack_err(ctx, root, "{s:s}", "target", &chain)) - return NULL; -- } -+ - return verdict_expr_alloc(int_loc, - verdict_tbl[i].verdict, chain); - } -diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py -index c02294ac54562..08569fbe0de44 100755 ---- a/tests/py/nft-test.py -+++ b/tests/py/nft-test.py -@@ -277,7 +277,9 @@ def chain_create(chain, table, filename): - print_error(reason, filename, chain.lineno) - return -1 - -- cmd = "add chain %s %s { %s; }" % (table, chain, chain.config) -+ cmd = "add chain %s %s" % (table, chain) -+ if chain.config: -+ cmd += " { %s; }" % chain.config - - ret = execute_cmd(cmd, filename, chain.lineno) - if ret != 0: --- -2.21.0 - diff --git a/SOURCES/0053-parser_json-Duplicate-chain-name-when-parsing-jump-v.patch b/SOURCES/0053-parser_json-Duplicate-chain-name-when-parsing-jump-v.patch deleted file mode 100644 index 362a141..0000000 --- a/SOURCES/0053-parser_json-Duplicate-chain-name-when-parsing-jump-v.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 5a6bcfe9e3d323e9503383601234fde3f3cf4a0b Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Tue, 26 Feb 2019 22:13:39 +0100 -Subject: [PATCH] parser_json: Duplicate chain name when parsing jump verdict - -Since verdict expression frees the chain name, pass a newly allocated -string to it. Otherwise double free happens because json_decref() frees -the string property value as well. - -Fixes: d1057a5feb5fd ("JSON: Simplify verdict statement parsing") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit dc6a6e83b47fc7078a061350cd2b111cb2adec14) -Signed-off-by: Phil Sutter ---- - src/parser_json.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/parser_json.c b/src/parser_json.c -index e3f20ae51c764..688fac1bddde2 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -1028,7 +1028,8 @@ static struct expr *json_parse_verdict_expr(struct json_ctx *ctx, - return NULL; - - return verdict_expr_alloc(int_loc, -- verdict_tbl[i].verdict, chain); -+ verdict_tbl[i].verdict, -+ chain ? xstrdup(chain) : NULL); - } - json_error(ctx, "Unknown verdict '%s'.", type); - return NULL; --- -2.21.0 - diff --git a/SOURCES/0054-src-Introduce-chain_expr-in-jump-and-goto-statements.patch b/SOURCES/0054-src-Introduce-chain_expr-in-jump-and-goto-statements.patch deleted file mode 100644 index 7a3fded..0000000 --- a/SOURCES/0054-src-Introduce-chain_expr-in-jump-and-goto-statements.patch +++ /dev/null @@ -1,324 +0,0 @@ -From b5852ee30b4ee854c81bf93c1c7b4ec5b0dd7e3f Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -Date: Fri, 24 May 2019 15:06:47 +0200 -Subject: [PATCH] src: Introduce chain_expr in jump and goto statements - -Introduce expressions as a chain in jump and goto statements. -This is going to be used to support variables as a chain in the -following patches. - -Signed-off-by: Fernando Fernandez Mancera -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit f1e8a129ee428419a0d5a45a2f410e8e4008d109) - -Conflicts: --> Adjust for missing commit 72931553828af - ("src: expr: add expression etype") - -Signed-off-by: Phil Sutter ---- - include/expression.h | 4 ++-- - src/datatype.c | 22 ++++++++++++++++++++-- - src/evaluate.c | 4 ++++ - src/expression.c | 12 ++++++------ - src/json.c | 6 +++--- - src/netlink.c | 26 +++++++++++++++++++++----- - src/parser_bison.y | 17 +++++++++++++---- - src/parser_json.c | 9 +++++++-- - 8 files changed, 76 insertions(+), 24 deletions(-) - -diff --git a/include/expression.h b/include/expression.h -index 885e9c43bb77f..5f814fdb065fe 100644 ---- a/include/expression.h -+++ b/include/expression.h -@@ -233,7 +233,7 @@ struct expr { - struct { - /* EXPR_VERDICT */ - int verdict; -- const char *chain; -+ struct expr *chain; - }; - struct { - /* EXPR_VALUE */ -@@ -385,7 +385,7 @@ extern void relational_expr_pctx_update(struct proto_ctx *ctx, - const struct expr *expr); - - extern struct expr *verdict_expr_alloc(const struct location *loc, -- int verdict, const char *chain); -+ int verdict, struct expr *chain); - - extern struct expr *symbol_expr_alloc(const struct location *loc, - enum symbol_types type, struct scope *scope, -diff --git a/src/datatype.c b/src/datatype.c -index 209044539bb84..f7defa37ff196 100644 ---- a/src/datatype.c -+++ b/src/datatype.c -@@ -253,6 +253,8 @@ const struct datatype invalid_type = { - - static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) - { -+ char chain[NFT_CHAIN_MAXNAMELEN]; -+ - switch (expr->verdict) { - case NFT_CONTINUE: - nft_print(octx, "continue"); -@@ -261,10 +263,26 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) - nft_print(octx, "break"); - break; - case NFT_JUMP: -- nft_print(octx, "jump %s", expr->chain); -+ if (expr->chain->ops->type == EXPR_VALUE) { -+ mpz_export_data(chain, expr->chain->value, -+ BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN); -+ nft_print(octx, "jump %s", chain); -+ } else { -+ nft_print(octx, "jump "); -+ expr_print(expr->chain, octx); -+ } - break; - case NFT_GOTO: -- nft_print(octx, "goto %s", expr->chain); -+ if (expr->chain->ops->type == EXPR_VALUE) { -+ mpz_export_data(chain, expr->chain->value, -+ BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN); -+ nft_print(octx, "goto %s", chain); -+ } else { -+ nft_print(octx, "goto "); -+ expr_print(expr->chain, octx); -+ } - break; - case NFT_RETURN: - nft_print(octx, "return"); -diff --git a/src/evaluate.c b/src/evaluate.c -index 88fa44dd34ef5..5f0f3b36fd99f 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -1847,6 +1847,10 @@ static int stmt_evaluate_verdict(struct eval_ctx *ctx, struct stmt *stmt) - case EXPR_VERDICT: - if (stmt->expr->verdict != NFT_CONTINUE) - stmt->flags |= STMT_F_TERMINAL; -+ if (stmt->expr->chain != NULL) { -+ if (expr_evaluate(ctx, &stmt->expr->chain) < 0) -+ return -1; -+ } - break; - case EXPR_MAP: - break; -diff --git a/src/expression.c b/src/expression.c -index bea0f4c8d9bc1..411047cb9341d 100644 ---- a/src/expression.c -+++ b/src/expression.c -@@ -174,22 +174,22 @@ static bool verdict_expr_cmp(const struct expr *e1, const struct expr *e2) - - if ((e1->verdict == NFT_JUMP || - e1->verdict == NFT_GOTO) && -- strcmp(e1->chain, e2->chain)) -- return false; -+ expr_cmp(e1->chain, e2->chain)) -+ return true; - -- return true; -+ return false; - } - - static void verdict_expr_clone(struct expr *new, const struct expr *expr) - { - new->verdict = expr->verdict; - if (expr->chain != NULL) -- new->chain = xstrdup(expr->chain); -+ mpz_init_set(new->chain->value, expr->chain->value); - } - - static void verdict_expr_destroy(struct expr *expr) - { -- xfree(expr->chain); -+ expr_free(expr->chain); - } - - static const struct expr_ops verdict_expr_ops = { -@@ -203,7 +203,7 @@ static const struct expr_ops verdict_expr_ops = { - }; - - struct expr *verdict_expr_alloc(const struct location *loc, -- int verdict, const char *chain) -+ int verdict, struct expr *chain) - { - struct expr *expr; - -diff --git a/src/json.c b/src/json.c -index fad2a83624062..6ecebc477146f 100644 ---- a/src/json.c -+++ b/src/json.c -@@ -636,14 +636,14 @@ json_t *verdict_expr_json(const struct expr *expr, struct output_ctx *octx) - { NF_QUEUE, "queue", false }, - }; - const char *name = NULL; -- const char *chain = NULL; -+ json_t *chain = NULL; - unsigned int i; - - for (i = 0; i < array_size(verdict_tbl); i++) { - if (expr->verdict == verdict_tbl[i].verdict) { - name = verdict_tbl[i].name; - if (verdict_tbl[i].chain && expr->chain) -- chain = expr->chain; -+ chain = expr_print_json(expr->chain, octx); - break; - } - } -@@ -652,7 +652,7 @@ json_t *verdict_expr_json(const struct expr *expr, struct output_ctx *octx) - return NULL; - } - if (chain) -- return json_pack("{s:{s:s}}", name, "target", chain); -+ return json_pack("{s:{s:o}}", name, "target", chain); - else - return json_pack("{s:n}", name); - } -diff --git a/src/netlink.c b/src/netlink.c -index 0509a06b3d2b3..fcd05b73f4c0e 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -391,12 +391,17 @@ static void netlink_gen_constant_data(const struct expr *expr, - static void netlink_gen_verdict(const struct expr *expr, - struct nft_data_linearize *data) - { -+ char chain[NFT_CHAIN_MAXNAMELEN]; -+ - data->verdict = expr->verdict; - - switch (expr->verdict) { - case NFT_JUMP: - case NFT_GOTO: -- snprintf(data->chain, NFT_CHAIN_MAXNAMELEN, "%s", expr->chain); -+ mpz_export_data(chain, expr->chain->value, -+ BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN); -+ snprintf(data->chain, NFT_CHAIN_MAXNAMELEN, "%s", chain); - data->chain[NFT_CHAIN_MAXNAMELEN-1] = '\0'; - break; - } -@@ -426,12 +431,15 @@ struct expr *netlink_alloc_value(const struct location *loc, - static struct expr *netlink_alloc_verdict(const struct location *loc, - const struct nft_data_delinearize *nld) - { -- char *chain; -+ struct expr *chain; - - switch (nld->verdict) { - case NFT_JUMP: - case NFT_GOTO: -- chain = xstrdup(nld->chain); -+ chain = constant_expr_alloc(loc, &string_type, -+ BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN * -+ BITS_PER_BYTE, nld->chain); - break; - default: - chain = NULL; -@@ -1694,14 +1702,22 @@ static void trace_print_expr(const struct nftnl_trace *nlt, unsigned int attr, - static void trace_print_verdict(const struct nftnl_trace *nlt, - struct output_ctx *octx) - { -+ struct expr *chain_expr = NULL; - const char *chain = NULL; - unsigned int verdict; - struct expr *expr; - - verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT); -- if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) -+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET)) { - chain = xstrdup(nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET)); -- expr = verdict_expr_alloc(&netlink_location, verdict, chain); -+ chain_expr = constant_expr_alloc(&netlink_location, -+ &string_type, -+ BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN -+ * BITS_PER_BYTE, -+ chain); -+ } -+ expr = verdict_expr_alloc(&netlink_location, verdict, chain_expr); - - nft_print(octx, "verdict "); - expr_print(expr, octx); -diff --git a/src/parser_bison.y b/src/parser_bison.y -index 1dc83953ea858..08dce52cebd1e 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -583,8 +583,8 @@ int nft_lex(void *, void *, void *); - %type meter_stmt meter_stmt_alloc flow_stmt_legacy_alloc - %destructor { stmt_free($$); } meter_stmt meter_stmt_alloc flow_stmt_legacy_alloc - --%type symbol_expr verdict_expr integer_expr variable_expr --%destructor { expr_free($$); } symbol_expr verdict_expr integer_expr variable_expr -+%type symbol_expr verdict_expr integer_expr variable_expr chain_expr -+%destructor { expr_free($$); } symbol_expr verdict_expr integer_expr variable_expr chain_expr - %type primary_expr shift_expr and_expr - %destructor { expr_free($$); } primary_expr shift_expr and_expr - %type exclusive_or_expr inclusive_or_expr -@@ -3461,11 +3461,11 @@ verdict_expr : ACCEPT - { - $$ = verdict_expr_alloc(&@$, NFT_CONTINUE, NULL); - } -- | JUMP identifier -+ | JUMP chain_expr - { - $$ = verdict_expr_alloc(&@$, NFT_JUMP, $2); - } -- | GOTO identifier -+ | GOTO chain_expr - { - $$ = verdict_expr_alloc(&@$, NFT_GOTO, $2); - } -@@ -3475,6 +3475,15 @@ verdict_expr : ACCEPT - } - ; - -+chain_expr : identifier -+ { -+ $$ = constant_expr_alloc(&@$, &string_type, -+ BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN * -+ BITS_PER_BYTE, $1); -+ } -+ ; -+ - meta_expr : META meta_key - { - $$ = meta_expr_alloc(&@$, $2); -diff --git a/src/parser_json.c b/src/parser_json.c -index 688fac1bddde2..b62c4125a0144 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -1014,10 +1014,16 @@ static struct expr *json_parse_verdict_expr(struct json_ctx *ctx, - { NF_ACCEPT, "accept", false }, - { NF_DROP, "drop", false }, - }; -+ struct expr *chain_expr = NULL; - const char *chain = NULL; - unsigned int i; - - json_unpack(root, "{s:s}", "target", &chain); -+ if (!chain) -+ chain_expr = constant_expr_alloc(int_loc, &string_type, -+ BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN * -+ BITS_PER_BYTE, chain); - - for (i = 0; i < array_size(verdict_tbl); i++) { - if (strcmp(type, verdict_tbl[i].name)) -@@ -1028,8 +1034,7 @@ static struct expr *json_parse_verdict_expr(struct json_ctx *ctx, - return NULL; - - return verdict_expr_alloc(int_loc, -- verdict_tbl[i].verdict, -- chain ? xstrdup(chain) : NULL); -+ verdict_tbl[i].verdict, chain_expr); - } - json_error(ctx, "Unknown verdict '%s'.", type); - return NULL; --- -2.21.0 - diff --git a/SOURCES/0055-src-Allow-goto-and-jump-to-a-variable.patch b/SOURCES/0055-src-Allow-goto-and-jump-to-a-variable.patch deleted file mode 100644 index 7928c06..0000000 --- a/SOURCES/0055-src-Allow-goto-and-jump-to-a-variable.patch +++ /dev/null @@ -1,204 +0,0 @@ -From 0100e69baee2e3a7e4bf5f0fb5c824d5c3e81286 Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -Date: Fri, 24 May 2019 15:06:50 +0200 -Subject: [PATCH] src: Allow goto and jump to a variable - -This patch introduces the use of nft input files variables in 'jump' and 'goto' -statements, e.g. - -define dest = ber - -add table ip foo -add chain ip foo bar {type filter hook input priority 0;} -add chain ip foo ber -add rule ip foo ber counter -add rule ip foo bar jump $dest - -table ip foo { - chain bar { - type filter hook input priority filter; policy accept; - jump ber - } - - chain ber { - counter packets 71 bytes 6664 - } -} - -Signed-off-by: Fernando Fernandez Mancera -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit c64457cff9673fbb41f613a67e158b4d62235c09) - -Conflicts: --> Adjust for missing commits 72931553828af - ("src: expr: add expression etype") and 68e76238749fb - ("src: expr: add and use expr_name helper"). - -Signed-off-by: Phil Sutter ---- - src/datatype.c | 11 ++++++++++ - src/evaluate.c | 7 +++++++ - src/parser_bison.y | 3 ++- - .../shell/testcases/nft-f/0018jump_variable_0 | 19 ++++++++++++++++++ - .../shell/testcases/nft-f/0019jump_variable_1 | 20 +++++++++++++++++++ - .../shell/testcases/nft-f/0020jump_variable_1 | 20 +++++++++++++++++++ - .../nft-f/dumps/0018jump_variable_0.nft | 8 ++++++++ - 7 files changed, 87 insertions(+), 1 deletion(-) - create mode 100755 tests/shell/testcases/nft-f/0018jump_variable_0 - create mode 100755 tests/shell/testcases/nft-f/0019jump_variable_1 - create mode 100755 tests/shell/testcases/nft-f/0020jump_variable_1 - create mode 100644 tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft - -diff --git a/src/datatype.c b/src/datatype.c -index f7defa37ff196..5791a6a41599e 100644 ---- a/src/datatype.c -+++ b/src/datatype.c -@@ -308,11 +308,22 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) - } - } - -+static struct error_record *verdict_type_parse(const struct expr *sym, -+ struct expr **res) -+{ -+ *res = constant_expr_alloc(&sym->location, &string_type, -+ BYTEORDER_HOST_ENDIAN, -+ (strlen(sym->identifier) + 1) * BITS_PER_BYTE, -+ sym->identifier); -+ return NULL; -+} -+ - const struct datatype verdict_type = { - .type = TYPE_VERDICT, - .name = "verdict", - .desc = "netfilter verdict", - .print = verdict_type_print, -+ .parse = verdict_type_parse, - }; - - static const struct symbol_table nfproto_tbl = { -diff --git a/src/evaluate.c b/src/evaluate.c -index 5f0f3b36fd99f..8e15e71d8a33b 100644 ---- a/src/evaluate.c -+++ b/src/evaluate.c -@@ -1850,6 +1850,13 @@ static int stmt_evaluate_verdict(struct eval_ctx *ctx, struct stmt *stmt) - if (stmt->expr->chain != NULL) { - if (expr_evaluate(ctx, &stmt->expr->chain) < 0) - return -1; -+ if ((stmt->expr->chain->ops->type != EXPR_SYMBOL && -+ stmt->expr->chain->ops->type != EXPR_VALUE) || -+ stmt->expr->chain->symtype != SYMBOL_VALUE) { -+ return stmt_error(ctx, stmt, -+ "invalid verdict chain expression %s\n", -+ stmt->expr->chain->ops->name); -+ } - } - break; - case EXPR_MAP: -diff --git a/src/parser_bison.y b/src/parser_bison.y -index 08dce52cebd1e..2e8ebde34eee6 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -3475,7 +3475,8 @@ verdict_expr : ACCEPT - } - ; - --chain_expr : identifier -+chain_expr : variable_expr -+ | identifier - { - $$ = constant_expr_alloc(&@$, &string_type, - BYTEORDER_HOST_ENDIAN, -diff --git a/tests/shell/testcases/nft-f/0018jump_variable_0 b/tests/shell/testcases/nft-f/0018jump_variable_0 -new file mode 100755 -index 0000000000000..003a1bdf701f1 ---- /dev/null -+++ b/tests/shell/testcases/nft-f/0018jump_variable_0 -@@ -0,0 +1,19 @@ -+#!/bin/bash -+ -+# Tests use of variables in jump statements -+ -+set -e -+ -+RULESET=" -+define dest = ber -+ -+table ip foo { -+ chain bar { -+ jump \$dest -+ } -+ -+ chain ber { -+ } -+}" -+ -+$NFT -f - <<< "$RULESET" -diff --git a/tests/shell/testcases/nft-f/0019jump_variable_1 b/tests/shell/testcases/nft-f/0019jump_variable_1 -new file mode 100755 -index 0000000000000..bda861c91df31 ---- /dev/null -+++ b/tests/shell/testcases/nft-f/0019jump_variable_1 -@@ -0,0 +1,20 @@ -+#!/bin/bash -+ -+# Tests use of variables in jump statements -+ -+set -e -+ -+RULESET=" -+define dest = { 1024 } -+ -+table ip foo { -+ chain bar { -+ jump \$dest -+ } -+ -+ chain ber { -+ } -+}" -+ -+$NFT -f - <<< "$RULESET" && exit 1 -+exit 0 -diff --git a/tests/shell/testcases/nft-f/0020jump_variable_1 b/tests/shell/testcases/nft-f/0020jump_variable_1 -new file mode 100755 -index 0000000000000..f753058f24f64 ---- /dev/null -+++ b/tests/shell/testcases/nft-f/0020jump_variable_1 -@@ -0,0 +1,20 @@ -+#!/bin/bash -+ -+# Tests use of variables in jump statements -+ -+set -e -+ -+RULESET=" -+define dest = * -+ -+table ip foo { -+ chain bar { -+ jump \$dest -+ } -+ -+ chain ber { -+ } -+}" -+ -+$NFT -f - <<< "$RULESET" && exit 1 -+exit 0 -diff --git a/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft b/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft -new file mode 100644 -index 0000000000000..0ddaf07f0ea3b ---- /dev/null -+++ b/tests/shell/testcases/nft-f/dumps/0018jump_variable_0.nft -@@ -0,0 +1,8 @@ -+table ip foo { -+ chain bar { -+ jump ber -+ } -+ -+ chain ber { -+ } -+} --- -2.21.0 - diff --git a/SOURCES/0056-parser_json-Fix-and-simplify-verdict-expression-pars.patch b/SOURCES/0056-parser_json-Fix-and-simplify-verdict-expression-pars.patch deleted file mode 100644 index c12a61e..0000000 --- a/SOURCES/0056-parser_json-Fix-and-simplify-verdict-expression-pars.patch +++ /dev/null @@ -1,82 +0,0 @@ -From cc4fa3ebfd8bbb18e17711f8ec122043340a1680 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 27 May 2019 13:37:00 +0200 -Subject: [PATCH] parser_json: Fix and simplify verdict expression parsing - -Parsing of the "target" property was flawed in two ways: - -* The value was extracted twice. Drop the first unconditional one. -* Expression allocation required since commit f1e8a129ee428 was broken, - The expression was allocated only if the property was not present. - -Fixes: f1e8a129ee428 ("src: Introduce chain_expr in jump and goto statements") -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit c34ad1653ff98db5d1ddceab663401055ac7ae4c) -Signed-off-by: Phil Sutter ---- - src/parser_json.c | 25 +++++++++++++------------ - 1 file changed, 13 insertions(+), 12 deletions(-) - -diff --git a/src/parser_json.c b/src/parser_json.c -index b62c4125a0144..7e4da4838e40b 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -999,13 +999,22 @@ static struct expr *json_parse_range_expr(struct json_ctx *ctx, - return range_expr_alloc(int_loc, expr_low, expr_high); - } - -+static struct expr *json_alloc_chain_expr(const char *chain) -+{ -+ if (!chain) -+ return NULL; -+ -+ return constant_expr_alloc(int_loc, &string_type, BYTEORDER_HOST_ENDIAN, -+ NFT_CHAIN_MAXNAMELEN * BITS_PER_BYTE, chain); -+} -+ - static struct expr *json_parse_verdict_expr(struct json_ctx *ctx, - const char *type, json_t *root) - { - const struct { - int verdict; - const char *name; -- bool chain; -+ bool need_chain; - } verdict_tbl[] = { - { NFT_CONTINUE, "continue", false }, - { NFT_JUMP, "jump", true }, -@@ -1014,27 +1023,19 @@ static struct expr *json_parse_verdict_expr(struct json_ctx *ctx, - { NF_ACCEPT, "accept", false }, - { NF_DROP, "drop", false }, - }; -- struct expr *chain_expr = NULL; - const char *chain = NULL; - unsigned int i; - -- json_unpack(root, "{s:s}", "target", &chain); -- if (!chain) -- chain_expr = constant_expr_alloc(int_loc, &string_type, -- BYTEORDER_HOST_ENDIAN, -- NFT_CHAIN_MAXNAMELEN * -- BITS_PER_BYTE, chain); -- - for (i = 0; i < array_size(verdict_tbl); i++) { - if (strcmp(type, verdict_tbl[i].name)) - continue; - -- if (verdict_tbl[i].chain && -+ if (verdict_tbl[i].need_chain && - json_unpack_err(ctx, root, "{s:s}", "target", &chain)) - return NULL; - -- return verdict_expr_alloc(int_loc, -- verdict_tbl[i].verdict, chain_expr); -+ return verdict_expr_alloc(int_loc, verdict_tbl[i].verdict, -+ json_alloc_chain_expr(chain)); - } - json_error(ctx, "Unknown verdict '%s'.", type); - return NULL; --- -2.21.0 - diff --git a/SOURCES/0057-src-invalid-read-when-importing-chain-name.patch b/SOURCES/0057-src-invalid-read-when-importing-chain-name.patch deleted file mode 100644 index ab5df69..0000000 --- a/SOURCES/0057-src-invalid-read-when-importing-chain-name.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 2b491f62a6a2d34f747ccf083eb016a8d0dcdba9 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 10 Jun 2019 13:12:20 +0200 -Subject: [PATCH] src: invalid read when importing chain name - -Use strlen(), otherwise mpz_import_data() reads too much beyond the real -chain string. Valgrind reports the following error: - -==2759== Invalid read of size 1 -==2759== at 0x67D68D6: __gmpz_import (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2) -==2759== by 0x4E79467: mpz_import_data (gmputil.c:133) -==2759== by 0x4E60A12: constant_expr_alloc (expression.c:375) -==2759== by 0x4E8ED65: nft_parse (parser_bison.y:3825) -==2759== by 0x4E7E850: nft_parse_bison_buffer (libnftables.c:357) -==2759== by 0x4E7E850: nft_run_cmd_from_buffer (libnftables.c:424) -==2759== by 0x1095D4: main (in /tmp/a.out) -==2759== Address 0x6ee1b4a is 0 bytes after a block of size 10 alloc'd -==2759== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) -==2759== by 0x59FD3B9: strdup (strdup.c:42) -==2759== by 0x4E7963D: xstrdup (utils.c:75) -==2759== by 0x4E9C233: nft_lex (scanner.l:626) -==2759== by 0x4E8E382: nft_parse (parser_bison.c:5297) -==2759== by 0x4E7E850: nft_parse_bison_buffer (libnftables.c:357) -==2759== by 0x4E7E850: nft_run_cmd_from_buffer (libnftables.c:424) - -Fixes: f1e8a129ee42 ("src: Introduce chain_expr in jump and goto statements") -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 142350f154c78a1aeccebc6115440162986dc906) -Signed-off-by: Phil Sutter ---- - src/netlink.c | 4 ++-- - src/parser_bison.y | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/netlink.c b/src/netlink.c -index fcd05b73f4c0e..fc310fd293d64 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -438,8 +438,8 @@ static struct expr *netlink_alloc_verdict(const struct location *loc, - case NFT_GOTO: - chain = constant_expr_alloc(loc, &string_type, - BYTEORDER_HOST_ENDIAN, -- NFT_CHAIN_MAXNAMELEN * -- BITS_PER_BYTE, nld->chain); -+ strlen(nld->chain) * BITS_PER_BYTE, -+ nld->chain); - break; - default: - chain = NULL; -diff --git a/src/parser_bison.y b/src/parser_bison.y -index 2e8ebde34eee6..4bd1ae1e39855 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -3480,8 +3480,8 @@ chain_expr : variable_expr - { - $$ = constant_expr_alloc(&@$, &string_type, - BYTEORDER_HOST_ENDIAN, -- NFT_CHAIN_MAXNAMELEN * -- BITS_PER_BYTE, $1); -+ strlen($1) * BITS_PER_BYTE, -+ $1); - } - ; - --- -2.21.0 - diff --git a/SOURCES/0058-expression-use-expr_clone-from-verdict_expr_clone.patch b/SOURCES/0058-expression-use-expr_clone-from-verdict_expr_clone.patch deleted file mode 100644 index a8ffd48..0000000 --- a/SOURCES/0058-expression-use-expr_clone-from-verdict_expr_clone.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b9422bf04c66ac4c6fd5fec1f539e8ff270f83f1 Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 10 Jun 2019 13:51:20 +0200 -Subject: [PATCH] expression: use expr_clone() from verdict_expr_clone() - -Chains are now expressions, do not assume a constant value is used. - -==26302== Process terminating with default action of signal 11 (SIGSEGV) -==26302== Access not within mapped region at address 0x50 -==26302== at 0x67D7EE7: __gmpz_init_set (in /usr/lib/x86_64-linux-gnu/libgmp.so.10.3.2) -==26302== by 0x4E61224: expr_clone (expression.c:65) -==26302== by 0x4E7898B: interval_map_decompose (segtree.c:943) -==26302== by 0x4E6DDA0: netlink_list_setelems (netlink.c:882) -==26302== by 0x4E5A806: cache_init_objects (rule.c:166) -==26302== by 0x4E5A806: cache_init (rule.c:216) -==26302== by 0x4E5A806: cache_update (rule.c:266) -==26302== by 0x4E7E0EE: nft_evaluate (libnftables.c:388) -==26302== by 0x4E7E8AB: nft_run_cmd_from_buffer (libnftables.c:428) - -Fixes: f1e8a129ee42 ("src: Introduce chain_expr in jump and goto statements") -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit aaf0167f2615372c1baaff327d1fb89d4297a52a) -Signed-off-by: Phil Sutter ---- - src/expression.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/expression.c b/src/expression.c -index 411047cb9341d..a339c6f30bce5 100644 ---- a/src/expression.c -+++ b/src/expression.c -@@ -184,7 +184,7 @@ static void verdict_expr_clone(struct expr *new, const struct expr *expr) - { - new->verdict = expr->verdict; - if (expr->chain != NULL) -- mpz_init_set(new->chain->value, expr->chain->value); -+ new->chain = expr_clone(expr->chain); - } - - static void verdict_expr_destroy(struct expr *expr) --- -2.21.0 - diff --git a/SOURCES/0059-parser_bison-free-chain-name-after-creating-constant.patch b/SOURCES/0059-parser_bison-free-chain-name-after-creating-constant.patch deleted file mode 100644 index f01ea16..0000000 --- a/SOURCES/0059-parser_bison-free-chain-name-after-creating-constant.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 8bd95db6d02b8ed268f2bfb7ec62b4d0cfbf82ad Mon Sep 17 00:00:00 2001 -From: Pablo Neira Ayuso -Date: Mon, 10 Jun 2019 19:23:40 +0200 -Subject: [PATCH] parser_bison: free chain name after creating constant - expression - -==2330== 2 bytes in 1 blocks are definitely lost in loss record 1 of 1 -==2330== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) -==2330== by 0x583D3B9: strdup (strdup.c:42) -==2330== by 0x4E7966D: xstrdup (utils.c:75) -==2330== by 0x4E9C283: nft_lex (scanner.l:626) -==2330== by 0x4E8E3C2: nft_parse (parser_bison.c:5297) -==2330== by 0x4E7EAB2: nft_parse_bison_filename (libnftables.c:374) -==2330== by 0x4E7EAB2: nft_run_cmd_from_filename (libnftables.c:475) -==2330== by 0x109A53: main (main.c:310) - -Fixes: f1e8a129ee42 ("src: Introduce chain_expr in jump and goto statements") -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 29d0b6b0526ed9b661db9f1c8dbd2abbff11483a) -Signed-off-by: Phil Sutter ---- - src/parser_bison.y | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/parser_bison.y b/src/parser_bison.y -index 4bd1ae1e39855..cea5d7660ba4c 100644 ---- a/src/parser_bison.y -+++ b/src/parser_bison.y -@@ -3482,6 +3482,7 @@ chain_expr : variable_expr - BYTEORDER_HOST_ENDIAN, - strlen($1) * BITS_PER_BYTE, - $1); -+ xfree($1); - } - ; - --- -2.21.0 - diff --git a/SOURCES/0060-doc-update-nft-list-plural-form-parameters.patch b/SOURCES/0060-doc-update-nft-list-plural-form-parameters.patch deleted file mode 100644 index 363ef4e..0000000 --- a/SOURCES/0060-doc-update-nft-list-plural-form-parameters.patch +++ /dev/null @@ -1,84 +0,0 @@ -From dafcd4c03c7d05ba8613c9fffb78aefaf87b31b7 Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -Date: Fri, 5 Apr 2019 17:36:55 +0200 -Subject: [PATCH] doc: update nft list plural form parameters - -Signed-off-by: Fernando Fernandez Mancera -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 067ac215e93f6cb912c3f99ca9e6689397bfba2f) - -Conflicts: - doc/nft.txt --> Changes applied manually to doc/nft.xml - -Signed-off-by: Phil Sutter ---- - doc/nft.xml | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/doc/nft.xml b/doc/nft.xml -index 1a97d7a169776..ea3973e1b8f1a 100644 ---- a/doc/nft.xml -+++ b/doc/nft.xml -@@ -560,6 +560,10 @@ filter input iif $int_ifs accept - family - table - -+ -+ list -+ tables -+ - - delete - table -@@ -705,6 +709,10 @@ add table inet mytable - table - chain - -+ -+ list -+ chains -+ - - delete - chain -@@ -1036,6 +1044,10 @@ table inet filter { - table - set - -+ -+ list -+ sets -+ - - delete - set -@@ -1187,6 +1199,10 @@ table inet filter { - policy policy ; - } - -+ -+ list -+ maps -+ - - - delete -@@ -1418,6 +1434,14 @@ table inet filter { - table - handle handle - -+ -+ list -+ counters -+ -+ -+ list -+ quotas -+ - - - Stateful objects are attached to tables and are identified by an unique name. They group stateful information from rules, to reference them in rules the keywords "type name" are used e.g. "counter name". --- -2.21.0 - diff --git a/SOURCES/0061-doc-Add-minimal-description-of-v-map-statements.patch b/SOURCES/0061-doc-Add-minimal-description-of-v-map-statements.patch deleted file mode 100644 index c34cd0e..0000000 --- a/SOURCES/0061-doc-Add-minimal-description-of-v-map-statements.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 1ac8084be4f5a66f078fb346c7dee618ce2d217e Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 4 Apr 2019 13:02:55 +0200 -Subject: [PATCH] doc: Add minimal description of (v)map statements - -Although quite useful, these were missing in man page. Content loosely -based on wiki documentation. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 3b29acc8f29944c5cf34259f2e2b5b40b4d0ccdd) - -Conflicts: --> Changes applied manually, upstream merged to asciidoc. - -Signed-off-by: Phil Sutter ---- - doc/nft.xml | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 66 insertions(+) - -diff --git a/doc/nft.xml b/doc/nft.xml -index ea3973e1b8f1a..9acff09e30619 100644 ---- a/doc/nft.xml -+++ b/doc/nft.xml -@@ -5535,6 +5535,72 @@ dup to ip daddr map { 192.168.7.1 : "eth0", 192.168.7.2 : "eth1" } - - - -+ -+ -+ Map statement -+ -+ The map statement is used to lookup data based on some specific input key. -+ -+ -+ -+ expression -+ map { -+ key -+ : -+ value -+ -+ , -+ key -+ : -+ value -+ -+ } -+ -+ -+ -+ using the map statement -+ -+# select DNAT target based on TCP dport: -+# connections to port 80 are redirected to 192.168.1.100, -+# connections to port 8888 are redirected to 192.168.1.101 -+nft add rule ip nat prerouting dnat tcp dport map { 80 : 192.168.1.100, 8888 : 192.168.1.101 } -+ -+# source address based SNAT: -+# packets from net 192.168.1.0/24 will appear as originating from 10.0.0.1, -+# packets from net 192.168.2.0/24 will appear as originating from 10.0.0.2 -+nft add rule ip nat postrouting snat to ip saddr map { 192.168.1.0/24 : 10.0.0.1, 192.168.2.0/24 : 10.0.0.2 } -+ -+ -+ -+ -+ Vmap statement -+ -+ The verdict map (vmap) statement works analogous to the map statement, but contains verdicts as values. -+ -+ -+ -+ expression -+ vmap { -+ key -+ : -+ value -+ -+ , -+ key -+ : -+ value -+ -+ } -+ -+ -+ -+ using the vmap statement -+ -+# jump to different chains depending on layer 4 protocol type: -+nft add rule ip filter input ip protocol vmap { tcp : jump tcp-chain, udp : jump udp-chain , icmp : jump icmp-chain } -+ -+ -+ - - - --- -2.21.0 - diff --git a/SOURCES/0062-xt-pass-octx-to-translate-function.patch b/SOURCES/0062-xt-pass-octx-to-translate-function.patch deleted file mode 100644 index 95088bb..0000000 --- a/SOURCES/0062-xt-pass-octx-to-translate-function.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 68c1ca177513a94f41ea974de9a48259e8ca5866 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 6 Nov 2018 16:06:26 +0100 -Subject: [PATCH] xt: pass octx to translate function - -We can't use it when no translation is available as libxtables will -use plain printf(), but when translation is available we can. - -Signed-off-by: Florian Westphal -(cherry picked from commit c15c2869168d71d07aca0221e1b37f0c5da54547) -Signed-off-by: Phil Sutter ---- - include/xt.h | 5 +++-- - src/statement.c | 2 +- - src/xt.c | 6 +++--- - 3 files changed, 7 insertions(+), 6 deletions(-) - -diff --git a/include/xt.h b/include/xt.h -index 753511e635080..549eb9fe41531 100644 ---- a/include/xt.h -+++ b/include/xt.h -@@ -6,9 +6,10 @@ struct netlink_parse_ctx; - struct nftnl_expr; - struct rule_pp_ctx; - struct rule; -+struct output_ctx; - - #ifdef HAVE_LIBXTABLES --void xt_stmt_xlate(const struct stmt *stmt); -+void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx); - void xt_stmt_release(const struct stmt *stmt); - - void netlink_parse_target(struct netlink_parse_ctx *ctx, -@@ -20,7 +21,7 @@ void netlink_parse_match(struct netlink_parse_ctx *ctx, - void stmt_xt_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt, - struct rule *rule); - #else --static inline void xt_stmt_xlate(const struct stmt *stmt) {} -+static inline void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx) {} - static inline void xt_stmt_release(const struct stmt *stmt) {} - - #include -diff --git a/src/statement.c b/src/statement.c -index 1b889e77cca20..29b73f9fba4ae 100644 ---- a/src/statement.c -+++ b/src/statement.c -@@ -780,7 +780,7 @@ struct stmt *fwd_stmt_alloc(const struct location *loc) - - static void xt_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - { -- xt_stmt_xlate(stmt); -+ xt_stmt_xlate(stmt, octx); - } - - static void xt_stmt_destroy(struct stmt *stmt) -diff --git a/src/xt.c b/src/xt.c -index 298a94d51e8a0..9b7d4c29194aa 100644 ---- a/src/xt.c -+++ b/src/xt.c -@@ -26,7 +26,7 @@ - #include - #include - --void xt_stmt_xlate(const struct stmt *stmt) -+void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx) - { - struct xt_xlate *xl = xt_xlate_alloc(10240); - -@@ -40,7 +40,7 @@ void xt_stmt_xlate(const struct stmt *stmt) - }; - - stmt->xt.match->xlate(xl, ¶ms); -- printf("%s", xt_xlate_get(xl)); -+ nft_print(octx, "%s", xt_xlate_get(xl)); - } else if (stmt->xt.match->print) { - printf("#"); - stmt->xt.match->print(&stmt->xt.entry, -@@ -57,7 +57,7 @@ void xt_stmt_xlate(const struct stmt *stmt) - }; - - stmt->xt.target->xlate(xl, ¶ms); -- printf("%s", xt_xlate_get(xl)); -+ nft_print(octx, "%s", xt_xlate_get(xl)); - } else if (stmt->xt.target->print) { - printf("#"); - stmt->xt.target->print(NULL, stmt->xt.target->t, 0); --- -2.21.0 - diff --git a/SOURCES/0063-xt-always-build-with-a-minimal-support-for-xt-match-.patch b/SOURCES/0063-xt-always-build-with-a-minimal-support-for-xt-match-.patch deleted file mode 100644 index c226edd..0000000 --- a/SOURCES/0063-xt-always-build-with-a-minimal-support-for-xt-match-.patch +++ /dev/null @@ -1,163 +0,0 @@ -From 4a4acdac14e0ec770589534aa4a5ea469a76e2a5 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 6 Nov 2018 16:06:27 +0100 -Subject: [PATCH] xt: always build with a minimal support for xt match/target - decode - -When building without libxtables, nft would just silently omit any presence -of nft_compat in the output. - -This adds ifdef-ry to at least print name of target/match involved when -libxtables isn't available for decoding. - -Signed-off-by: Florian Westphal -(cherry picked from commit b3c8de9c5aecde38eec964f31120df82b9704c8c) -Signed-off-by: Phil Sutter ---- - include/xt.h | 13 +------------ - src/Makefile.am | 2 +- - src/xt.c | 22 ++++++++++++++++++++++ - 3 files changed, 24 insertions(+), 13 deletions(-) - -diff --git a/include/xt.h b/include/xt.h -index 549eb9fe41531..ab59bb3d45a41 100644 ---- a/include/xt.h -+++ b/include/xt.h -@@ -8,7 +8,6 @@ struct rule_pp_ctx; - struct rule; - struct output_ctx; - --#ifdef HAVE_LIBXTABLES - void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx); - void xt_stmt_release(const struct stmt *stmt); - -@@ -18,20 +17,10 @@ void netlink_parse_target(struct netlink_parse_ctx *ctx, - void netlink_parse_match(struct netlink_parse_ctx *ctx, - const struct location *loc, - const struct nftnl_expr *nle); -+#ifdef HAVE_LIBXTABLES - void stmt_xt_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt, - struct rule *rule); - #else --static inline void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx) {} --static inline void xt_stmt_release(const struct stmt *stmt) {} -- --#include -- --static inline void netlink_parse_target(struct netlink_parse_ctx *ctx, -- const struct location *loc, -- const struct nftnl_expr *nle) {} --static inline void netlink_parse_match(struct netlink_parse_ctx *ctx, -- const struct location *loc, -- const struct nftnl_expr *nle) {} - static inline void stmt_xt_postprocess(struct rule_pp_ctx *rctx, - struct stmt *stmt, struct rule *rule) {} - -diff --git a/src/Makefile.am b/src/Makefile.am -index a4ad8cb31236b..495511803b686 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -78,8 +78,8 @@ libminigmp_la_CFLAGS = ${AM_CFLAGS} -Wno-sign-compare - libnftables_la_LIBADD += libminigmp.la - endif - --if BUILD_XTABLES - libnftables_la_SOURCES += xt.c -+if BUILD_XTABLES - libnftables_la_LIBADD += ${XTABLES_LIBS} - endif - -diff --git a/src/xt.c b/src/xt.c -index 9b7d4c29194aa..c35c84edca0e6 100644 ---- a/src/xt.c -+++ b/src/xt.c -@@ -28,6 +28,7 @@ - - void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx) - { -+#ifdef HAVE_LIBXTABLES - struct xt_xlate *xl = xt_xlate_alloc(10240); - - switch (stmt->xt.type) { -@@ -68,6 +69,9 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx) - } - - xt_xlate_free(xl); -+#else -+ nft_print(octx, "# xt_%s", stmt->xt.name); -+#endif - } - - void xt_stmt_release(const struct stmt *stmt) -@@ -95,6 +99,7 @@ void xt_stmt_release(const struct stmt *stmt) - xfree(stmt->xt.name); - } - -+#ifdef HAVE_LIBXTABLES - static void *xt_entry_alloc(struct xt_stmt *xt, uint32_t af) - { - union nft_entry { -@@ -180,6 +185,7 @@ static struct xtables_match *xt_match_clone(struct xtables_match *m) - memcpy(clone, m, sizeof(struct xtables_match)); - return clone; - } -+#endif - - /* - * Delinearization -@@ -191,6 +197,7 @@ void netlink_parse_match(struct netlink_parse_ctx *ctx, - { - struct stmt *stmt; - const char *name; -+#ifdef HAVE_LIBXTABLES - struct xtables_match *mt; - const char *mtinfo; - struct xt_entry_match *m; -@@ -218,7 +225,13 @@ void netlink_parse_match(struct netlink_parse_ctx *ctx, - stmt->xt.type = NFT_XT_MATCH; - stmt->xt.match = xt_match_clone(mt); - stmt->xt.match->m = m; -+#else -+ name = nftnl_expr_get_str(nle, NFTNL_EXPR_MT_NAME); - -+ stmt = xt_stmt_alloc(loc); -+ stmt->xt.name = strdup(name); -+ stmt->xt.type = NFT_XT_MATCH; -+#endif - list_add_tail(&stmt->list, &ctx->rule->stmts); - } - -@@ -228,6 +241,7 @@ void netlink_parse_target(struct netlink_parse_ctx *ctx, - { - struct stmt *stmt; - const char *name; -+#ifdef HAVE_LIBXTABLES - struct xtables_target *tg; - const void *tginfo; - struct xt_entry_target *t; -@@ -256,10 +270,17 @@ void netlink_parse_target(struct netlink_parse_ctx *ctx, - stmt->xt.type = NFT_XT_TARGET; - stmt->xt.target = xt_target_clone(tg); - stmt->xt.target->t = t; -+#else -+ name = nftnl_expr_get_str(nle, NFTNL_EXPR_TG_NAME); - -+ stmt = xt_stmt_alloc(loc); -+ stmt->xt.name = strdup(name); -+ stmt->xt.type = NFT_XT_TARGET; -+#endif - list_add_tail(&stmt->list, &ctx->rule->stmts); - } - -+#ifdef HAVE_LIBXTABLES - static bool is_watcher(uint32_t family, struct stmt *stmt) - { - if (family != NFPROTO_BRIDGE || -@@ -371,3 +392,4 @@ void xt_init(void) - /* Default to IPv4, but this changes in runtime */ - xtables_init_all(&xt_nft_globals, NFPROTO_IPV4); - } -+#endif --- -2.21.0 - diff --git a/SOURCES/0064-src-fix-double-free-on-xt-stmt-destruction.patch b/SOURCES/0064-src-fix-double-free-on-xt-stmt-destruction.patch deleted file mode 100644 index c21de02..0000000 --- a/SOURCES/0064-src-fix-double-free-on-xt-stmt-destruction.patch +++ /dev/null @@ -1,68 +0,0 @@ -From b8d39d718360e1b46be846dbedd94a6b099a9e31 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Tue, 23 Apr 2019 13:18:05 +0200 -Subject: [PATCH] src: fix double free on xt stmt destruction - -'nft monitor' dies with: -*** Error in `/sbin/nft': double free or corruption (fasttop): 0x000055f8ba57b750 *** - -... when the iptables-nft test suite is running in parallel, because -xfree(stmt->xt.name) gets called twice. - -Fixes: 4ac11b890fe870 ("src: missing destroy function in statement definitions") -Signed-off-by: Florian Westphal -Acked-by: Pablo Neira Ayuso -(cherry picked from commit 99afd62d48f4c510bdb4076eb9d811c001ad1cac) -Signed-off-by: Phil Sutter ---- - include/xt.h | 2 +- - src/statement.c | 6 ------ - src/xt.c | 2 +- - 3 files changed, 2 insertions(+), 8 deletions(-) - -diff --git a/include/xt.h b/include/xt.h -index ab59bb3d45a41..9fc515084d597 100644 ---- a/include/xt.h -+++ b/include/xt.h -@@ -9,7 +9,7 @@ struct rule; - struct output_ctx; - - void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx); --void xt_stmt_release(const struct stmt *stmt); -+void xt_stmt_destroy(struct stmt *stmt); - - void netlink_parse_target(struct netlink_parse_ctx *ctx, - const struct location *loc, -diff --git a/src/statement.c b/src/statement.c -index 29b73f9fba4ae..c261540b92ebd 100644 ---- a/src/statement.c -+++ b/src/statement.c -@@ -783,12 +783,6 @@ static void xt_stmt_print(const struct stmt *stmt, struct output_ctx *octx) - xt_stmt_xlate(stmt, octx); - } - --static void xt_stmt_destroy(struct stmt *stmt) --{ -- xfree(stmt->xt.name); -- xt_stmt_release(stmt); --} -- - static const struct stmt_ops xt_stmt_ops = { - .type = STMT_XT, - .name = "xt", -diff --git a/src/xt.c b/src/xt.c -index c35c84edca0e6..ef371720fbcfa 100644 ---- a/src/xt.c -+++ b/src/xt.c -@@ -74,7 +74,7 @@ void xt_stmt_xlate(const struct stmt *stmt, struct output_ctx *octx) - #endif - } - --void xt_stmt_release(const struct stmt *stmt) -+void xt_stmt_destroy(struct stmt *stmt) - { - switch (stmt->xt.type) { - case NFT_XT_MATCH: --- -2.21.0 - diff --git a/SOURCES/0065-tests-shell-Add-testcase-for-cache-update-problems.patch b/SOURCES/0065-tests-shell-Add-testcase-for-cache-update-problems.patch deleted file mode 100644 index b4bfab1..0000000 --- a/SOURCES/0065-tests-shell-Add-testcase-for-cache-update-problems.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 802c96c0b2061dbab20694184bebbeba5eda4a03 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Fri, 26 Oct 2018 11:42:05 +0200 -Subject: [PATCH] tests/shell: Add testcase for cache update problems - -The first test in there shows how the current cache update strategy -causes trouble. The second test shows that proposed "locking" of cache -when local entries are added is flawed, too. - -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit 21d678639b28b99c301262c163128fdf67397ca6) -Signed-off-by: Phil Sutter ---- - .../shell/testcases/cache/0003_cache_update_0 | 29 +++++++++++++++++++ - 1 file changed, 29 insertions(+) - create mode 100755 tests/shell/testcases/cache/0003_cache_update_0 - -diff --git a/tests/shell/testcases/cache/0003_cache_update_0 b/tests/shell/testcases/cache/0003_cache_update_0 -new file mode 100755 -index 0000000000000..deb45db2c43be ---- /dev/null -+++ b/tests/shell/testcases/cache/0003_cache_update_0 -@@ -0,0 +1,29 @@ -+#!/bin/bash -+ -+set -e -+ -+# Expose how naive cache update logic (i.e., drop cache and repopulate from -+# kernel ruleset) may mess things up. The following input does: -+# -+# list ruleset -> populate the cache, cache->genid is non-zero -+# add table ip t -> make kernel's genid increment (cache->genid remains -+# unchanged) -+# add table ip t2; -> first command of batch, new table t2 is added to the cache -+# add chain ip t2 c -> second command of batch, triggers cache_update() which -+# removes table t2 from it -+ -+$NFT -i >/dev/null < cache would be locked without previous update -+# add chain ip t c -> table t is not found due to no cache update happening -+ -+$NFT -i >/dev/null < -Date: Wed, 22 May 2019 21:44:04 +0200 -Subject: [PATCH] src: update cache if cmd is more specific - -If we've done a partial fetch of the cache and the genid is the same the -cache update will be skipped without fetching the needed items. This -change flushes the cache if the new request is more specific than the -current cache - forcing a cache update which includes the needed items. - -Introduces a simple scoring system which reflects how -cache_init_objects() looks at the current command to decide if it is -finished already or not. Then use that in cache_needs_more(): If current -command's score is higher than old command's, cache needs an update. - -Fixes: 816d8c7659c1 ("Support 'add/insert rule index '") -Signed-off-by: Eric Garver -Signed-off-by: Phil Sutter -Signed-off-by: Pablo Neira Ayuso -(cherry picked from commit eeda228c2d1719f5b6276b40ad14a5b3c3e88536) - -Conflicts: - src/rule.c --> Context change due to missing commit 0562beb6544d3 - ("src: get rid of netlink_genid_get()"). - -Signed-off-by: Phil Sutter ---- - include/nftables.h | 1 + - src/rule.c | 20 +++++++++++++++++++ - .../shell/testcases/cache/0003_cache_update_0 | 14 +++++++++++++ - 3 files changed, 35 insertions(+) - -diff --git a/include/nftables.h b/include/nftables.h -index 5e209b417d5a5..e9425d1fc8fb3 100644 ---- a/include/nftables.h -+++ b/include/nftables.h -@@ -36,6 +36,7 @@ struct nft_cache { - uint16_t genid; - struct list_head list; - uint32_t seqnum; -+ uint32_t cmd; - }; - - struct mnl_socket; -diff --git a/src/rule.c b/src/rule.c -index 850b00cfc9874..a03abe1bf0c47 100644 ---- a/src/rule.c -+++ b/src/rule.c -@@ -151,6 +151,23 @@ static int cache_init(struct netlink_ctx *ctx, enum cmd_ops cmd) - return 0; - } - -+/* Return a "score" of how complete local cache will be if -+ * cache_init_objects() ran for given cmd. Higher value -+ * means more complete. */ -+static int cache_completeness(enum cmd_ops cmd) -+{ -+ if (cmd == CMD_LIST) -+ return 3; -+ if (cmd != CMD_RESET) -+ return 2; -+ return 1; -+} -+ -+static bool cache_needs_more(enum cmd_ops old_cmd, enum cmd_ops cmd) -+{ -+ return cache_completeness(old_cmd) < cache_completeness(cmd); -+} -+ - int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) - { - uint16_t genid; -@@ -166,6 +183,8 @@ int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) - replay: - ctx.seqnum = cache->seqnum++; - genid = netlink_genid_get(&ctx); -+ if (cache->genid && cache_needs_more(cache->cmd, cmd)) -+ cache_release(cache); - if (genid && genid == cache->genid) - return 0; - if (cache->genid) -@@ -181,6 +200,7 @@ replay: - return -1; - } - cache->genid = genid; -+ cache->cmd = cmd; - return 0; - } - -diff --git a/tests/shell/testcases/cache/0003_cache_update_0 b/tests/shell/testcases/cache/0003_cache_update_0 -index deb45db2c43be..fa9b5df380a41 100755 ---- a/tests/shell/testcases/cache/0003_cache_update_0 -+++ b/tests/shell/testcases/cache/0003_cache_update_0 -@@ -27,3 +27,17 @@ EOF - $NFT -i >/dev/null < rule to reference in next step -+# add rule ip t4 c index 0 drop -> index 0 is not found due to rule cache not -+# being updated -+$NFT -i >/dev/null </dev/null < -Date: Tue, 13 Aug 2019 22:12:44 +0200 -Subject: [PATCH] src: fix jumps on bigendian arches - -table bla { - chain foo { } - chain bar { jump foo } - } -} - -Fails to restore on big-endian platforms: -jump.nft:5:2-9: Error: Could not process rule: No such file or directory - jump foo - -nft passes a 0-length name to the kernel. - -This is because when we export the value (the string), we provide -the size of the destination buffer. - -In earlier versions, the parser allocated the name with the same -fixed size and all was fine. - -After the fix, the export places the name in the wrong location -in the destination buffer. - -This makes tests/shell/testcases/chains/0001jumps_0 work on s390x. - -v2: convert one error check to a BUG(), it should not happen unless - kernel abi is broken. - -Fixes: 142350f154c78 ("src: invalid read when importing chain name") -Signed-off-by: Florian Westphal -Acked-by: Pablo Neira Ayuso -(cherry picked from commit fb6d826afb1fa346bdf61c43cd6f7551caee27ba) - -Conflicts: - src/datatype.c --> Context change due to missing commit 72931553828af - ("src: expr: add expression etype") - -Signed-off-by: Phil Sutter ---- - src/datatype.c | 27 ++++++++++++++++++--------- - src/netlink.c | 16 +++++++++++++--- - 2 files changed, 31 insertions(+), 12 deletions(-) - -diff --git a/src/datatype.c b/src/datatype.c -index 5791a6a41599e..7bea6062de9c4 100644 ---- a/src/datatype.c -+++ b/src/datatype.c -@@ -251,10 +251,25 @@ const struct datatype invalid_type = { - .print = invalid_type_print, - }; - --static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) -+static void verdict_jump_chain_print(const char *what, const struct expr *e, -+ struct output_ctx *octx) - { - char chain[NFT_CHAIN_MAXNAMELEN]; -+ unsigned int len; -+ -+ memset(chain, 0, sizeof(chain)); -+ -+ len = e->len / BITS_PER_BYTE; -+ if (len >= sizeof(chain)) -+ BUG("verdict expression length %u is too large (%lu bits max)", -+ e->len, (unsigned long)sizeof(chain) * BITS_PER_BYTE); - -+ mpz_export_data(chain, e->value, BYTEORDER_HOST_ENDIAN, len); -+ nft_print(octx, "%s %s", what, chain); -+} -+ -+static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) -+{ - switch (expr->verdict) { - case NFT_CONTINUE: - nft_print(octx, "continue"); -@@ -264,10 +279,7 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) - break; - case NFT_JUMP: - if (expr->chain->ops->type == EXPR_VALUE) { -- mpz_export_data(chain, expr->chain->value, -- BYTEORDER_HOST_ENDIAN, -- NFT_CHAIN_MAXNAMELEN); -- nft_print(octx, "jump %s", chain); -+ verdict_jump_chain_print("jump", expr->chain, octx); - } else { - nft_print(octx, "jump "); - expr_print(expr->chain, octx); -@@ -275,10 +287,7 @@ static void verdict_type_print(const struct expr *expr, struct output_ctx *octx) - break; - case NFT_GOTO: - if (expr->chain->ops->type == EXPR_VALUE) { -- mpz_export_data(chain, expr->chain->value, -- BYTEORDER_HOST_ENDIAN, -- NFT_CHAIN_MAXNAMELEN); -- nft_print(octx, "goto %s", chain); -+ verdict_jump_chain_print("goto", expr->chain, octx); - } else { - nft_print(octx, "goto "); - expr_print(expr->chain, octx); -diff --git a/src/netlink.c b/src/netlink.c -index fc310fd293d64..4ad527a02e871 100644 ---- a/src/netlink.c -+++ b/src/netlink.c -@@ -392,17 +392,27 @@ static void netlink_gen_verdict(const struct expr *expr, - struct nft_data_linearize *data) - { - char chain[NFT_CHAIN_MAXNAMELEN]; -+ unsigned int len; - - data->verdict = expr->verdict; - - switch (expr->verdict) { - case NFT_JUMP: - case NFT_GOTO: -+ len = expr->chain->len / BITS_PER_BYTE; -+ -+ if (!len) -+ BUG("chain length is 0"); -+ -+ if (len > sizeof(chain)) -+ BUG("chain is too large (%u, %u max)", -+ len, (unsigned int)sizeof(chain)); -+ -+ memset(chain, 0, sizeof(chain)); -+ - mpz_export_data(chain, expr->chain->value, -- BYTEORDER_HOST_ENDIAN, -- NFT_CHAIN_MAXNAMELEN); -+ BYTEORDER_HOST_ENDIAN, len); - snprintf(data->chain, NFT_CHAIN_MAXNAMELEN, "%s", chain); -- data->chain[NFT_CHAIN_MAXNAMELEN-1] = '\0'; - break; - } - } --- -2.22.0 - diff --git a/SOURCES/0068-src-json-fix-constant-parsing-on-bigendian.patch b/SOURCES/0068-src-json-fix-constant-parsing-on-bigendian.patch deleted file mode 100644 index 45cb829..0000000 --- a/SOURCES/0068-src-json-fix-constant-parsing-on-bigendian.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 582df543fab12f6c9032ddf6c789a4e0a7242358 Mon Sep 17 00:00:00 2001 -From: Florian Westphal -Date: Wed, 14 Aug 2019 13:45:19 +0200 -Subject: [PATCH] src: json: fix constant parsing on bigendian - -json restore is broken on big-endian because we errounously -passed uint8_t with 64 bit size indicator. - -On bigendian, this causes all values to get shifted by 56 bit, -this will then cause the eval step to bail because all values -are outside of the 8bit 0-255 protocol range. - -Signed-off-by: Florian Westphal -Acked-by: Pablo Neira Ayuso -(cherry picked from commit 452e7653334bd2808441fe40235307f1f3dd23c4) -Signed-off-by: Phil Sutter ---- - src/parser_json.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/parser_json.c b/src/parser_json.c -index 7e4da4838e40b..231f377c4f2da 100644 ---- a/src/parser_json.c -+++ b/src/parser_json.c -@@ -295,7 +295,7 @@ static struct expr *json_parse_constant(struct json_ctx *ctx, const char *name) - return constant_expr_alloc(int_loc, - constant_tbl[i].dtype, - BYTEORDER_HOST_ENDIAN, -- 8 * BITS_PER_BYTE, -+ BITS_PER_BYTE, - &constant_tbl[i].data); - } - json_error(ctx, "Unknown constant '%s'.", name); --- -2.22.0 - diff --git a/SOURCES/0069-monitor-Do-not-decompose-non-anonymous-sets.patch b/SOURCES/0069-monitor-Do-not-decompose-non-anonymous-sets.patch deleted file mode 100644 index 0204a92..0000000 --- a/SOURCES/0069-monitor-Do-not-decompose-non-anonymous-sets.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 7859b19a1e8307b5bee6ca71261dd0bc06fda6f2 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Thu, 9 Jan 2020 13:34:20 +0100 -Subject: [PATCH] monitor: Do not decompose non-anonymous sets - -They have been decomposed already, trying to do that again causes a -segfault. This is a similar fix as in commit 8ecb885589591 ("src: -restore --echo with anonymous sets"). - -Signed-off-by: Phil Sutter -Acked-by: Pablo Neira Ayuso -(cherry picked from commit 5d57fa3e99bb9f2044e236d4ddb7d874cfefe1dd) -Signed-off-by: Phil Sutter ---- - src/monitor.c | 2 +- - tests/monitor/testcases/set-interval.t | 20 ++++++++++++++++++++ - 2 files changed, 21 insertions(+), 1 deletion(-) - create mode 100644 tests/monitor/testcases/set-interval.t - -diff --git a/src/monitor.c b/src/monitor.c -index 14ccbc5fe04ca..ba8e11888a215 100644 ---- a/src/monitor.c -+++ b/src/monitor.c -@@ -500,7 +500,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, - - static void rule_map_decompose_cb(struct set *s, void *data) - { -- if (s->flags & NFT_SET_INTERVAL) -+ if (s->flags & (NFT_SET_INTERVAL & NFT_SET_ANONYMOUS)) - interval_map_decompose(s->init); - } - -diff --git a/tests/monitor/testcases/set-interval.t b/tests/monitor/testcases/set-interval.t -new file mode 100644 -index 0000000000000..59930c58243d8 ---- /dev/null -+++ b/tests/monitor/testcases/set-interval.t -@@ -0,0 +1,20 @@ -+# setup first -+I add table ip t -+I add chain ip t c -+O - -+J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} -+J {"add": {"chain": {"family": "ip", "table": "t", "name": "c", "handle": 0}}} -+ -+# add set with elements, monitor output expectedly differs -+I add set ip t s { type inet_service; flags interval; elements = { 20, 30-40 }; } -+O add set ip t s { type inet_service; flags interval; } -+O add element ip t s { 20 } -+O add element ip t s { 30-40 } -+J {"add": {"set": {"family": "ip", "name": "s", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}} -+J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [20]}}}} -+J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [{"range": [30, 40]}]}}}} -+ -+# this would crash nft -+I add rule ip t c tcp dport @s -+O - -+J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": "@s"}}]}}} --- -2.24.1 - diff --git a/SOURCES/0070-monitor-Fix-output-for-ranges-in-anonymous-sets.patch b/SOURCES/0070-monitor-Fix-output-for-ranges-in-anonymous-sets.patch deleted file mode 100644 index a0a5510..0000000 --- a/SOURCES/0070-monitor-Fix-output-for-ranges-in-anonymous-sets.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 299aeba9aa84ae0556a0bba18b7adace89069a91 Mon Sep 17 00:00:00 2001 -From: Phil Sutter -Date: Mon, 13 Jan 2020 14:53:24 +0100 -Subject: [PATCH] monitor: Fix output for ranges in anonymous sets - -Previous fix for named interval sets was simply wrong: Instead of -limiting decomposing to anonymous interval sets, it effectively disabled -it entirely. - -Since code needs to check for both interval and anonymous bits -separately, introduce set_is_interval() helper to keep the code -readable. - -Also extend test case to assert ranges in anonymous sets are correctly -printed by echo or monitor modes. Without this fix, range boundaries are -printed as individual set elements. - -Fixes: 5d57fa3e99bb9 ("monitor: Do not decompose non-anonymous sets") -Signed-off-by: Phil Sutter -Reviewed-by: Pablo Neira Ayuso -(cherry picked from commit ddbacd70d061eb1b6808f501969809bfb5d03001) - -Conflicts: - include/rule.h -- Context change due to missing other set_is_*() helpers. -- Manually added set_is_anonymous() helper since code fix uses it. -- Manually added missing include statement to make NFT_SET_* flags - known. - -Signed-off-by: Phil Sutter ---- - include/rule.h | 11 +++++++++++ - src/monitor.c | 2 +- - tests/monitor/testcases/set-interval.t | 5 +++++ - 3 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/include/rule.h b/include/rule.h -index 12c2984a14362..c2d1d5212649f 100644 ---- a/include/rule.h -+++ b/include/rule.h -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - /** - * struct handle_spec - handle ID -@@ -289,6 +290,16 @@ extern const char *set_policy2str(uint32_t policy); - extern void set_print(const struct set *set, struct output_ctx *octx); - extern void set_print_plain(const struct set *s, struct output_ctx *octx); - -+static inline bool set_is_anonymous(uint32_t set_flags) -+{ -+ return set_flags & NFT_SET_ANONYMOUS; -+} -+ -+static inline bool set_is_interval(uint32_t set_flags) -+{ -+ return set_flags & NFT_SET_INTERVAL; -+} -+ - #include - - struct counter { -diff --git a/src/monitor.c b/src/monitor.c -index ba8e11888a215..9bb3424d76be2 100644 ---- a/src/monitor.c -+++ b/src/monitor.c -@@ -500,7 +500,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, - - static void rule_map_decompose_cb(struct set *s, void *data) - { -- if (s->flags & (NFT_SET_INTERVAL & NFT_SET_ANONYMOUS)) -+ if (set_is_interval(s->flags) && set_is_anonymous(s->flags)) - interval_map_decompose(s->init); - } - -diff --git a/tests/monitor/testcases/set-interval.t b/tests/monitor/testcases/set-interval.t -index 59930c58243d8..1fbcfe222a2b0 100644 ---- a/tests/monitor/testcases/set-interval.t -+++ b/tests/monitor/testcases/set-interval.t -@@ -18,3 +18,8 @@ J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set" - I add rule ip t c tcp dport @s - O - - J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": "@s"}}]}}} -+ -+# test anonymous interval sets as well -+I add rule ip t c tcp dport { 20, 30-40 } -+O - -+J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": {"set": [20, {"range": [30, 40]}]}}}]}}} --- -2.24.1 - diff --git a/SOURCES/main.nft b/SOURCES/main.nft new file mode 100644 index 0000000..6460d10 --- /dev/null +++ b/SOURCES/main.nft @@ -0,0 +1,64 @@ +# Sample configuration for nftables service. +# Load this by calling 'nft -f /etc/nftables/main.nft'. + +# Note about base chain priorities: +# The priority values used in these sample configs are +# offset by 20 in order to avoid ambiguity when firewalld +# is also running which uses an offset of 10. This means +# that packets will traverse firewalld first and if not +# dropped/rejected there will hit the chains defined here. +# Chains created by iptables, ebtables and arptables tools +# do not use an offset, so those chains are traversed first +# in any case. + +# drop any existing nftables ruleset +flush ruleset + +# a common table for both IPv4 and IPv6 +table inet nftables_svc { + + # protocols to allow + set allowed_protocols { + type inet_proto + elements = { icmp, icmpv6 } + } + + # interfaces to accept any traffic on + set allowed_interfaces { + type ifname + elements = { "lo" } + } + + # services to allow + set allowed_tcp_dports { + type inet_service + elements = { ssh, 9090 } + } + + # this chain gathers all accept conditions + chain allow { + ct state established,related accept + + meta l4proto @allowed_protocols accept + iifname @allowed_interfaces accept + tcp dport @allowed_tcp_dports accept + } + + # base-chain for traffic to this host + chain INPUT { + type filter hook input priority filter + 20 + policy accept + + jump allow + reject with icmpx type port-unreachable + } +} + +# By default, any forwarding traffic is allowed. +# Uncomment the following line to filter it based +# on the same criteria as input traffic. +#include "/etc/nftables/router.nft" + +# Uncomment the following line to enable masquerading of +# forwarded traffic. May be used with or without router.nft. +#include "/etc/nftables/nat.nft" diff --git a/SOURCES/nat.nft b/SOURCES/nat.nft new file mode 100644 index 0000000..7079893 --- /dev/null +++ b/SOURCES/nat.nft @@ -0,0 +1,30 @@ +# Sample configuration snippet for nftables service. +# Meant to be included by main.nft, not for direct use. + +# dedicated table for IPv4 +table ip nftables_svc { + + # interfaces to masquerade traffic from + set masq_interfaces { + type ifname + elements = { "virbr0" } + } + + # networks to masquerade traffic from + # 'interval' flag is required to support subnets + set masq_ips { + type ipv4_addr + flags interval + elements = { 192.168.122.0/24 } + } + + # base-chain to manipulate conntrack in postrouting, + # will see packets for new or related traffic only + chain POSTROUTING { + type nat hook postrouting priority srcnat + 20 + policy accept + + iifname @masq_interfaces oifname != @masq_interfaces masquerade + ip saddr @masq_ips masquerade + } +} diff --git a/SOURCES/nftables.conf b/SOURCES/nftables.conf index 5f602ac..c3d9649 100644 --- a/SOURCES/nftables.conf +++ b/SOURCES/nftables.conf @@ -1,14 +1,8 @@ -# -# This this will contain your nftables rules and -# is read by the systemd service when restarting -# -# These provide an iptables like set of filters -# (uncomment to include) -# include "/etc/nftables/bridge-filter.nft" -# include "/etc/nftables/inet-filter.nft" -# include "/etc/nftables/ipv4-filter.nft" -# include "/etc/nftables/ipv4-mangle.nft" -# include "/etc/nftables/ipv4-nat.nft" -# include "/etc/nftables/ipv6-filter.nft" -# include "/etc/nftables/ipv6-mangle.nft" -# include "/etc/nftables/ipv6-nat.nft" +# Uncomment the include statement here to load the default config sample +# in /etc/nftables for nftables service. + +#include "/etc/nftables/main.nft" + +# To customize, either edit the samples in /etc/nftables, append further +# commands to the end of this file or overwrite it after first service +# start by calling: 'nft list ruleset >/etc/sysconfig/nftables.conf'. diff --git a/SOURCES/router.nft b/SOURCES/router.nft new file mode 100644 index 0000000..6300a55 --- /dev/null +++ b/SOURCES/router.nft @@ -0,0 +1,16 @@ +# Sample configuration snippet for nftables service. +# Meant to be included by main.nft, not for direct use. + +# a common table for both IPv4 and IPv6 +table inet nftables_svc { + + # base-chain for traffic forwarded by this host + # re-uses 'allow' chain from main.nft + chain FORWARD { + type filter hook forward priority filter + 20 + policy accept + + jump allow + reject with icmpx type host-unreachable + } +} diff --git a/SPECS/nftables.spec b/SPECS/nftables.spec index b6c5d3f..81d1b36 100644 --- a/SPECS/nftables.spec +++ b/SPECS/nftables.spec @@ -1,6 +1,9 @@ +%define rpmversion 0.9.3 +%define specrelease 12%{?dist} + Name: nftables -Version: 0.9.0 -Release: 14%{?dist}.1 +Version: %{rpmversion} +Release: %{specrelease}%{?buildid} # Upstream released a 0.100 version, then 0.4. Need Epoch to get back on track. Epoch: 1 Summary: Netfilter Tables userspace utillites @@ -10,77 +13,31 @@ URL: http://netfilter.org/projects/nftables/ Source0: http://ftp.netfilter.org/pub/nftables/nftables-%{version}.tar.bz2 Source1: nftables.service Source2: nftables.conf - -Patch1: 0001-evaluate-reject-Allow-icmpx-in-inet-bridge-families.patch -Patch2: 0002-monitor-Drop-fake-XML-support.patch -Patch3: 0003-monitor-Drop-update-table-and-update-chain-cases.patch -Patch4: 0004-monitor-Fix-printing-of-ct-objects.patch -Patch5: 0005-monitor-Use-libnftables-JSON-output.patch -Patch6: 0006-tests-monitor-Test-JSON-output-as-well.patch -Patch7: 0007-segtree-bogus-range-via-get-set-element-on-existing-.patch -Patch8: 0008-segtree-disantangle-get_set_interval_end.patch -Patch9: 0009-segtree-memleak-in-get_set_decompose.patch -Patch10: 0010-segtree-stop-iteration-on-existing-elements-in-case-.patch -Patch11: 0011-segtree-incorrect-handling-of-last-element-in-get_se.patch -Patch12: 0012-segtree-set-proper-error-cause-on-existing-elements.patch -Patch13: 0013-rule-fix-memleak-in-do_get_setelems.patch -Patch14: 0014-Fix-memleak-in-netlink_parse_fwd-error-path.patch -Patch15: 0015-libnftables-Fix-memleak-in-nft_parse_bison_filename.patch -Patch16: 0016-src-pass-struct-nft_ctx-through-struct-eval_ctx.patch -Patch17: 0017-src-trace-fix-policy-printing.patch -Patch18: 0018-rule-list-only-the-table-containing-object.patch -Patch19: 0019-src-pass-struct-nft_ctx-through-struct-netlink_ctx.patch -Patch20: 0020-netlink-reset-mnl_socket-field-in-struct-nft_ctx-on-.patch -Patch21: 0021-src-remove-opts-field-from-struct-xt_stmt.patch -Patch22: 0022-JSON-Support-latest-enhancements-of-fwd-statement.patch -Patch23: 0023-parser_json-Fix-for-ineffective-family-value-checks.patch -Patch24: 0024-json-Fix-memleak-in-dup_stmt_json.patch -Patch25: 0025-json-Fix-for-recent-changes-to-context-structs.patch -Patch26: 0026-parser_bison-Fix-for-ECN-keyword-in-LHS-of-relationa.patch -Patch27: 0027-nft.8-Update-meta-pkt_type-value-description.patch -Patch28: 0028-json-Work-around-segfault-when-encountering-xt-stmt.patch -Patch29: 0029-nft.8-Document-log-level-audit.patch -Patch30: 0030-nft.8-Clarify-index-option-of-add-rule-command.patch -Patch31: 0031-src-Reject-export-vm-json-command.patch -Patch32: 0032-datatype-add-stolen-verdict.patch -Patch33: 0033-libnftables-Fix-exit_cookie.patch -Patch34: 0034-scanner-Do-not-convert-tabs-into-spaces.patch -Patch35: 0035-netlink_delinearize-Refactor-meta_may_dependency_kil.patch -Patch36: 0036-evaluate-skip-evaluation-of-datatype-concatenations.patch -Patch37: 0037-tests-shell-add-tests-for-listing-objects.patch -Patch38: 0038-rule-fix-object-listing-when-no-table-is-given.patch -Patch39: 0039-proto-fix-icmp-icmpv6-code-datatype.patch -Patch40: 0040-evaluate-throw-distinct-error-if-map-exists-but-cont.patch -Patch41: 0041-parser-bail-out-on-incorrect-burst-unit.patch -Patch42: 0042-src-fix-netdev-family-device-name-parsing.patch -Patch43: 0043-libnftables-Print-errors-before-freeing-commands.patch -Patch44: 0044-segtree-fix-crash-when-debug-mode-is-active.patch -Patch45: 0045-parser_bison-no-need-for-statement-separator-for-ct-.patch -Patch46: 0046-ct-use-nft_print-instead-of-printf.patch -Patch47: 0047-parser_bison-type_identifier-string-memleak.patch -Patch48: 0048-src-missing-destroy-function-in-statement-definition.patch -Patch49: 0049-tests-shell-validate-too-deep-jumpstack-from-basecha.patch -Patch50: 0050-netlink-remove-markup-json-parsing-code.patch -Patch51: 0051-rule-limit-don-t-print-default-burst-value.patch -Patch52: 0052-JSON-Review-verdict-statement-and-expression.patch -Patch53: 0053-parser_json-Duplicate-chain-name-when-parsing-jump-v.patch -Patch54: 0054-src-Introduce-chain_expr-in-jump-and-goto-statements.patch -Patch55: 0055-src-Allow-goto-and-jump-to-a-variable.patch -Patch56: 0056-parser_json-Fix-and-simplify-verdict-expression-pars.patch -Patch57: 0057-src-invalid-read-when-importing-chain-name.patch -Patch58: 0058-expression-use-expr_clone-from-verdict_expr_clone.patch -Patch59: 0059-parser_bison-free-chain-name-after-creating-constant.patch -Patch60: 0060-doc-update-nft-list-plural-form-parameters.patch -Patch61: 0061-doc-Add-minimal-description-of-v-map-statements.patch -Patch62: 0062-xt-pass-octx-to-translate-function.patch -Patch63: 0063-xt-always-build-with-a-minimal-support-for-xt-match-.patch -Patch64: 0064-src-fix-double-free-on-xt-stmt-destruction.patch -Patch65: 0065-tests-shell-Add-testcase-for-cache-update-problems.patch -Patch66: 0066-src-update-cache-if-cmd-is-more-specific.patch -Patch67: 0067-src-fix-jumps-on-bigendian-arches.patch -Patch68: 0068-src-json-fix-constant-parsing-on-bigendian.patch -Patch69: 0069-monitor-Do-not-decompose-non-anonymous-sets.patch -Patch70: 0070-monitor-Fix-output-for-ranges-in-anonymous-sets.patch +Source3: main.nft +Source4: router.nft +Source5: nat.nft + +Patch1: 0001-main-enforce-options-before-commands.patch +Patch2: 0002-main-restore-debug.patch +Patch3: 0003-monitor-Do-not-decompose-non-anonymous-sets.patch +Patch4: 0004-monitor-Fix-output-for-ranges-in-anonymous-sets.patch +Patch5: 0005-xfrm-spi-is-big-endian.patch +Patch6: 0006-tests-shell-Search-diff-tool-once-and-for-all.patch +Patch7: 0007-cache-Fix-for-doubled-output-after-reset-command.patch +Patch8: 0008-netlink-Fix-leak-in-unterminated-string-deserializer.patch +Patch9: 0009-netlink-Fix-leaks-in-netlink_parse_cmp.patch +Patch10: 0010-netlink-Avoid-potential-NULL-pointer-deref-in-netlin.patch +Patch11: 0011-tests-json_echo-Fix-for-Python3.patch +Patch12: 0012-tests-json_echo-Support-testing-host-binaries.patch +Patch13: 0013-tests-monitor-Support-running-individual-test-cases.patch +Patch14: 0014-tests-monitor-Support-testing-host-s-nft-binary.patch +Patch15: 0015-tests-py-Support-testing-host-binaries.patch +Patch16: 0016-doc-nft.8-Mention-wildcard-interface-matching.patch +Patch17: 0017-scanner-Extend-asteriskstring-definition.patch +Patch18: 0018-parser-add-a-helper-for-concat-expression-handling.patch +Patch19: 0019-include-resync-nf_tables.h-cache-copy.patch +Patch20: 0020-src-Add-support-for-NFTNL_SET_DESC_CONCAT.patch +Patch21: 0021-src-Add-support-for-concatenated-set-ranges.patch BuildRequires: autogen BuildRequires: autoconf @@ -92,11 +49,14 @@ BuildRequires: bison BuildRequires: libmnl-devel BuildRequires: gmp-devel BuildRequires: readline-devel -BuildRequires: libnftnl-devel -BuildRequires: docbook2X +BuildRequires: pkgconfig(libnftnl) >= 1.1.5-3 BuildRequires: systemd -BuildRequires: jansson-devel +BuildRequires: asciidoc BuildRequires: iptables-devel +BuildRequires: jansson-devel +BuildRequires: python3-devel + +Requires: libnftnl >= 1.1.5-3 %description Netfilter Tables userspace utilities. @@ -110,13 +70,21 @@ Requires: pkgconfig %description devel Development tools and static libraries and header files for the libnftables library. +%package -n python3-nftables +Summary: Python module providing an interface to libnftables +Requires: %{name} = %{epoch}:%{version}-%{release} + +%description -n python3-nftables +The nftables python module provides an interface to libnftables via ctypes. + %prep %autosetup -p1 %build autoreconf -fi rm -Rf autom4te*.cache config.h.in~ -%configure --disable-silent-rules --with-json --with-xtables +%configure --disable-silent-rules --with-json --with-xtables \ + --enable-python --with-python-bin=%{__python3} make %{?_smp_mflags} %install @@ -133,11 +101,21 @@ cp -a %{SOURCE1} $RPM_BUILD_ROOT/%{_unitdir}/ mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig cp -a %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/ -chmod 600 $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/nftables.conf -cp files/examples/netdev-ingress.nft $RPM_BUILD_ROOT/%{_sysconfdir}/nftables -chmod 750 $RPM_BUILD_ROOT/%{_sysconfdir}/nftables -chmod 600 $RPM_BUILD_ROOT/%{_sysconfdir}/nftables/*.nft +rm $RPM_BUILD_ROOT/%{_sysconfdir}/nftables/*.nft +cp %{SOURCE3} %{SOURCE4} %{SOURCE5} \ + $RPM_BUILD_ROOT/%{_sysconfdir}/nftables/ + +find $RPM_BUILD_ROOT/%{_sysconfdir} \ + \( -type d -exec chmod 0700 {} \; \) , \ + \( -type f -exec chmod 0600 {} \; \) + +# make nftables.py use the real library file name +# to avoid nftables-devel package dependency +sofile=$(readlink $RPM_BUILD_ROOT/%{_libdir}/libnftables.so) +sed -i -e 's/\(sofile=\)".*"/\1"'$sofile'"/' \ + $RPM_BUILD_ROOT/%{python3_sitelib}/nftables/nftables.py +touch -r %{SOURCE2} $RPM_BUILD_ROOT/%{python3_sitelib}/nftables/nftables.py %post %systemd_post nftables.service @@ -160,18 +138,107 @@ chmod 600 $RPM_BUILD_ROOT/%{_sysconfdir}/nftables/*.nft %config(noreplace) %{_sysconfdir}/sysconfig/nftables.conf %{_sbindir}/nft %{_libdir}/libnftables.so.* +%{_mandir}/man5/libnftables-json.5* %{_mandir}/man8/nft* %{_unitdir}/nftables.service +%{_docdir}/nftables/examples/*.nft %files devel %{_libdir}/libnftables.so %{_libdir}/pkgconfig/libnftables.pc %{_includedir}/nftables/libnftables.h +%{_mandir}/man3/libnftables.3* + +%files -n python3-nftables +%{python3_sitelib}/nftables-*.egg-info +%{python3_sitelib}/nftables/ %changelog -* Wed Feb 12 2020 Phil Sutter - 1:0.9.0-14.1 -- monitor: Fix output for ranges in anonymous sets -- monitor: Do not decompose non-anonymous sets +* Thu Mar 26 2020 Phil Sutter [0.9.3-12.el8] +- Restore default config to be empty (Phil Sutter) [1694723] + +* Mon Feb 17 2020 Phil Sutter [0.9.3-11.el8] +- Package requires libnftnl-1.1.5-3 (Phil Sutter) [1795224] +- src: Add support for concatenated set ranges (Phil Sutter) [1795224] +- src: Add support for NFTNL_SET_DESC_CONCAT (Phil Sutter) [1795224] +- include: resync nf_tables.h cache copy (Phil Sutter) [1795224] +- parser: add a helper for concat expression handling (Phil Sutter) [1795224] + +* Wed Feb 12 2020 Phil Sutter [0.9.3-10.el8] +- scanner: Extend asteriskstring definition (Phil Sutter) [1763652] +- doc: nft.8: Mention wildcard interface matching (Phil Sutter) [1763652] +- tests: py: Support testing host binaries (Phil Sutter) [1754047] +- tests: monitor: Support testing host's nft binary (Phil Sutter) [1754047] +- tests: monitor: Support running individual test cases (Phil Sutter) [1754047] +- tests: json_echo: Support testing host binaries (Phil Sutter) [1754047] +- tests: json_echo: Fix for Python3 (Phil Sutter) [1754047] + +* Mon Jan 27 2020 Phil Sutter [0.9.3-9.el8] +- netlink: Avoid potential NULL-pointer deref in netlink_gen_payload_stmt() (Phil Sutter) [1793030] +- netlink: Fix leaks in netlink_parse_cmp() (Phil Sutter) [1793030] +- netlink: Fix leak in unterminated string deserializer (Phil Sutter) [1793030] + +* Fri Jan 17 2020 Phil Sutter [0.9.3-8.el8] +- cache: Fix for doubled output after reset command (Phil Sutter) [1790793] +- tests: shell: Search diff tool once and for all (Phil Sutter) [1790793] +- xfrm: spi is big-endian (Phil Sutter) [1790963] + +* Mon Jan 13 2020 Phil Sutter [0.9.3-7.el8] +- monitor: Fix output for ranges in anonymous sets (Phil Sutter) [1774742] + +* Fri Jan 10 2020 Phil Sutter [0.9.3-6.el8] +- monitor: Do not decompose non-anonymous sets (Phil Sutter) [1774742] +- main: restore --debug (Phil Sutter) [1778883] +- main: enforce options before commands (Phil Sutter) [1778883] + +* Fri Jan 10 2020 Phil Sutter [0.9.3-5.el8] +- Install an improved sample config (Phil Sutter) [1694723] + +* Wed Dec 04 2019 Phil Sutter [0.9.3-4.el8] +- Explicitly depend on newer libnftl version (Phil Sutter) [1643192] + +* Tue Dec 03 2019 Phil Sutter [0.9.3-3.el8] +- Fix permissions of osf-related configs (Phil Sutter) [1776462] + +* Tue Dec 03 2019 Phil Sutter [0.9.3-2.el8] +- Add example scripts to nftables package (Phil Sutter) [1643192] + +* Mon Dec 02 2019 Phil Sutter [0.9.3-1.el8] +- Rebase onto upstream release 0.9.3 (Phil Sutter) [1643192] + +* Mon Oct 21 2019 Phil Sutter [0.9.2-4.el8] +- tproxy: Add missing error checking when parsing from netlink (Phil Sutter) [1643192] +- parser_json: Fix checking of parse_policy() return code (Phil Sutter) [1643192] + +* Fri Oct 18 2019 Phil Sutter [0.9.2-3.el8] +- spec: Avoid multilib problems due to updated nftables.py (Phil Sutter) [1643192] + +* Fri Oct 18 2019 Phil Sutter [0.9.2-2.el8] +- rule: Fix for single line ct timeout printing (Phil Sutter) [1643192] +- tests/monitor: Fix for changed ct timeout format (Phil Sutter) [1643192] +- monitor: Add missing newline to error message (Phil Sutter) [1643192] +- src: restore --echo with anonymous sets (Phil Sutter) [1643192] + +* Tue Oct 15 2019 Phil Sutter [0.9.2-1.el8] +- src: obj: fix memleak in handle_free() (Phil Sutter) [1643192] +- libnftables: memleak when list of commands is empty (Phil Sutter) [1643192] +- mnl: do not cache sender buffer size (Phil Sutter) [1643192] +- src: meter: avoid double-space in list ruleset output (Phil Sutter) [1643192] +- src: parser_json: fix crash while restoring secmark object (Phil Sutter) [1643192] +- nftables: don't crash in 'list ruleset' if policy is not set (Phil Sutter) [1643192] +- json: tests: fix typo in ct expectation json test (Phil Sutter) [1643192] +- parser_bison: Fix 'exists' keyword on Big Endian (Phil Sutter) [1643192] +- json: fix type mismatch on "ct expect" json exporting (Phil Sutter) [1643192] +- libnftables: use-after-free in exit path (Phil Sutter) [1643192] +- netlink_delinearize: fix wrong conversion to "list" in ct mark (Phil Sutter) [1643192] +- mnl: fix --echo buffer size again (Phil Sutter) [1643192] +- parser_json: fix crash on insert rule to bad references (Phil Sutter) [1643192] +- evaluate: flag fwd and queue statements as terminal (Phil Sutter) [1643192] +- tests: shell: check that rule add with index works with echo (Phil Sutter) [1643192] +- cache: fix --echo with index/position (Phil Sutter) [1643192] +- src: secmark: fix brace indentation and missing quotes in selctx output (Phil Sutter) [1643192] +- Add python3-nftables sub-package (Phil Sutter) [1643192] +- Rebase onto upstream version 0.9.2 (Phil Sutter) [1643192] * Mon Aug 12 2019 Phil Sutter - 1:0.9.0-14 - src: fix jumps on bigendian arches