import nftables-0.9.3-14.el8

This commit is contained in:
CentOS Sources 2020-07-28 02:42:51 -04:00 committed by Stepan Oksanichenko
parent ff918a70b1
commit ee8ec96d0a
29 changed files with 3115 additions and 17 deletions

View File

@ -0,0 +1,244 @@
From 5fac849eac7ecfde4ca6f9c9c406ace030f358f2 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <pablo@netfilter.org>
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 <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,50 @@
From 0c808b1ee29d4a0974f4cc5c0586138730361a41 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <pablo@netfilter.org>
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 <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,68 @@
From 13bd961c3ba83e4189dcffdcf570c5a4391fd5f9 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,80 @@
From 2e7cb6c2d46d9b8b91ff4b5d6797b7544c23ba44 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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 <statement.h>
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

View File

@ -0,0 +1,51 @@
From ca4d1604b18abf7189ecfd5e06cb74abc3694076 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <fw@strlen.de>
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 <fw@strlen.de>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,573 @@
From 8537751e48dfacee11d48ad3f050bdacc930284c Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,85 @@
From a44bd9f4b6cf77cb75c5f596908100270893e8d5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,51 @@
From cc70f19e588a0a33ed86c4a059b56a8f5b0c7a82 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,75 @@
From 6ecccc872b9cbed921af10e32d1a628eb6a74c01 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,42 @@
From 55c537734f476d04c18f67083642b96bbead6219 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,39 @@
From 04d0d2e685063d422ce73b67eb01d4803100d379 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
---
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

View File

@ -0,0 +1,68 @@
From 0eb301a3f50fb70cb78d955692f3feea1ad8095e Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
---
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

View File

@ -0,0 +1,64 @@
From 67f168ebfbeb26a8d7e4f1b9284cc32f13ceff9b Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,40 @@
From 18e1b545cbd2d055b16ec3bf5f481d8032dc5dbe Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
---
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

View File

@ -0,0 +1,76 @@
From 74575c409bad2940470f31946c97430043c3195e Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
---
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

View File

@ -0,0 +1,43 @@
From d58192a8d2810271d5c6525dc66ba1e1ec3fd2b7 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
---
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

View File

@ -0,0 +1,39 @@
From 34ba60c0c2b6057e8b56a77e47899bbeccd88bfd Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <phil@nwl.cc>
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 <phil@nwl.cc>
---
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

View File

@ -0,0 +1,162 @@
From 160d84fb761c54a5f757aff907fc197d259196bd Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <fw@strlen.de>
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 <fw@strlen.de>
---
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

View File

@ -0,0 +1,84 @@
From e872d169c189f363ebbdc39105510c1809b58276 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <sbrivio@redhat.com>
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 <sbrivio@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,181 @@
From c8a5da2f527c85ab7c392cd293ff37d02a3f93a7 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <sbrivio@redhat.com>
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 <sbrivio@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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

View File

@ -0,0 +1,577 @@
From 7b1f98e90a32865faca9a97f4348f20c753cd2f3 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
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 <sbrivio@redhat.com>
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 <sbrivio@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
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 <statement.h>
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

View File

@ -0,0 +1,119 @@
From 68392da523f43b9ae09f824fa68b04b20c9c88f5 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 20 May 2020 11:12:37 +0200
Subject: [PATCH] parser_json: Support ranges in concat expressions
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1805798
Upstream Status: nftables commit 9475ca305a993
commit 9475ca305a993751b05cf26ef8e785a00de98b94
Author: Phil Sutter <phil@nwl.cc>
Date: Fri Mar 6 16:15:48 2020 +0100
parser_json: Support ranges in concat expressions
Duplicate commit 8ac2f3b2fca38's changes to bison parser into JSON
parser by introducing a new context flag signalling we're parsing
concatenated expressions.
Fixes: 8ac2f3b2fca38 ("src: Add support for concatenated set ranges")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Eric Garver <eric@garver.life>
---
src/parser_json.c | 51 +++++++++++++++++++++++++++++----------------------
1 file changed, 29 insertions(+), 22 deletions(-)
diff --git a/src/parser_json.c b/src/parser_json.c
index 031930e..c48faa8 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -40,6 +40,7 @@
#define CTX_F_MANGLE (1 << 5)
#define CTX_F_SES (1 << 6) /* set_elem_expr_stmt */
#define CTX_F_MAP (1 << 7) /* LHS of map_expr */
+#define CTX_F_CONCAT (1 << 8) /* inside concat_expr */
struct json_ctx {
struct input_descriptor indesc;
@@ -99,6 +100,7 @@ static struct expr *json_parse_primary_expr(struct json_ctx *ctx, json_t *root);
static struct expr *json_parse_set_rhs_expr(struct json_ctx *ctx, json_t *root);
static struct expr *json_parse_set_elem_expr_stmt(struct json_ctx *ctx, json_t *root);
static struct expr *json_parse_map_lhs_expr(struct json_ctx *ctx, json_t *root);
+static struct expr *json_parse_concat_elem_expr(struct json_ctx *ctx, json_t *root);
static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root);
/* parsing helpers */
@@ -1058,7 +1060,7 @@ static struct expr *json_parse_concat_expr(struct json_ctx *ctx,
}
json_array_foreach(root, index, value) {
- tmp = json_parse_primary_expr(ctx, value);
+ tmp = json_parse_concat_elem_expr(ctx, value);
if (!tmp) {
json_error(ctx, "Parsing expr at index %zd failed.", index);
expr_free(expr);
@@ -1354,28 +1356,28 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root)
{ "set", json_parse_set_expr, CTX_F_RHS | CTX_F_STMT }, /* allow this as stmt expr because that allows set references */
{ "map", json_parse_map_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS },
/* below three are multiton_rhs_expr */
- { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_STMT },
- { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_STMT },
- { "payload", json_parse_payload_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP },
- { "exthdr", json_parse_exthdr_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "tcp option", json_parse_tcp_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES },
- { "ip option", json_parse_ip_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES },
- { "meta", json_parse_meta_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP },
- { "osf", json_parse_osf_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_MAP },
- { "ipsec", json_parse_xfrm_expr, CTX_F_PRIMARY | CTX_F_MAP },
- { "socket", json_parse_socket_expr, CTX_F_PRIMARY },
- { "rt", json_parse_rt_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "ct", json_parse_ct_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP },
- { "numgen", json_parse_numgen_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
+ { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_CONCAT },
+ { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_CONCAT },
+ { "payload", json_parse_payload_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "exthdr", json_parse_exthdr_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "tcp option", json_parse_tcp_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT },
+ { "ip option", json_parse_ip_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT },
+ { "meta", json_parse_meta_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "osf", json_parse_osf_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_MAP | CTX_F_CONCAT },
+ { "ipsec", json_parse_xfrm_expr, CTX_F_PRIMARY | CTX_F_MAP | CTX_F_CONCAT },
+ { "socket", json_parse_socket_expr, CTX_F_PRIMARY | CTX_F_CONCAT },
+ { "rt", json_parse_rt_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "ct", json_parse_ct_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "numgen", json_parse_numgen_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
/* below two are hash expr */
- { "jhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "symhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "fib", json_parse_fib_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "|", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "^", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "&", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { ">>", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
- { "<<", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP },
+ { "jhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "symhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "fib", json_parse_fib_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "|", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "^", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "&", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { ">>", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
+ { "<<", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT },
{ "accept", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS },
{ "drop", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS },
{ "continue", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS },
@@ -1500,6 +1502,11 @@ static struct expr *json_parse_map_lhs_expr(struct json_ctx *ctx, json_t *root)
return json_parse_flagged_expr(ctx, CTX_F_MAP, root);
}
+static struct expr *json_parse_concat_elem_expr(struct json_ctx *ctx, json_t *root)
+{
+ return json_parse_flagged_expr(ctx, CTX_F_CONCAT, root);
+}
+
static struct expr *json_parse_dtype_expr(struct json_ctx *ctx, json_t *root)
{
if (json_is_string(root)) {
--
1.8.3.1

View File

@ -0,0 +1,51 @@
From f7a31d5c3277b29f104fd8ff48df24c8bc790f19 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 24 Jun 2020 18:46:39 +0200
Subject: [PATCH] doc: Document notrack statement
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1841292
Upstream Status: nftables commit f16fbe76f62dc
commit f16fbe76f62dcb9f7395d1837ad2d056463ba55f
Author: Phil Sutter <phil@nwl.cc>
Date: Mon Jun 22 15:07:40 2020 +0200
doc: Document notrack statement
Merely a stub, but better to mention it explicitly instead of having it
appear in synproxy examples and letting users guess as to what it does.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
---
doc/statements.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/doc/statements.txt b/doc/statements.txt
index 3b82436..749533a 100644
--- a/doc/statements.txt
+++ b/doc/statements.txt
@@ -262,6 +262,20 @@ table inet raw {
ct event set new,related,destroy
--------------------------------------
+NOTRACK STATEMENT
+~~~~~~~~~~~~~~~~~
+The notrack statement allows to disable connection tracking for certain
+packets.
+
+[verse]
+*notrack*
+
+Note that for this statement to be effective, it has to be applied to packets
+before a conntrack lookup happens. Therefore, it needs to sit in a chain with
+either prerouting or output hook and a hook priority of -300 or less.
+
+See SYNPROXY STATEMENT for an example usage.
+
META STATEMENT
~~~~~~~~~~~~~~
A meta statement sets the value of a meta expression. The existing meta fields
--
1.8.3.1

View File

@ -0,0 +1,53 @@
From 58d8baa70172bb9862276ac5f542248c88d3faf4 Mon Sep 17 00:00:00 2001
From: Phil Sutter <psutter@redhat.com>
Date: Wed, 24 Jun 2020 18:48:14 +0200
Subject: [PATCH] JSON: Improve performance of json_events_cb()
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1835300
Upstream Status: nftables commit c96c7da272e33
commit c96c7da272e33a34770c4de4e3e50f7ed264672e
Author: Phil Sutter <phil@nwl.cc>
Date: Wed May 13 16:29:51 2020 +0200
JSON: Improve performance of json_events_cb()
The function tries to insert handles into JSON input for echo option.
Yet there may be nothing to do if the given netlink message doesn't
contain a handle, e.g. if it is an 'add element' command. Calling
seqnum_to_json() is pointless overhead in that case, and if input is
large this overhead is significant. Better wait with that call until
after checking if the message is relevant at all.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Eric Garver <eric@garver.life>
---
src/parser_json.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/parser_json.c b/src/parser_json.c
index c48faa8..ce8e566 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -3845,12 +3845,15 @@ static uint64_t handle_from_nlmsg(const struct nlmsghdr *nlh)
}
int json_events_cb(const struct nlmsghdr *nlh, struct netlink_mon_handler *monh)
{
- json_t *tmp, *json = seqnum_to_json(nlh->nlmsg_seq);
uint64_t handle = handle_from_nlmsg(nlh);
+ json_t *tmp, *json;
void *iter;
- /* might be anonymous set, ignore message */
- if (!json || !handle)
+ if (!handle)
+ return MNL_CB_OK;
+
+ json = seqnum_to_json(nlh->nlmsg_seq);
+ if (!json)
return MNL_CB_OK;
tmp = json_object_get(json, "add");
--
1.8.3.1

64
SOURCES/main.nft Normal file
View File

@ -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"

30
SOURCES/nat.nft Normal file
View File

@ -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
}
}

View File

@ -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'.

16
SOURCES/router.nft Normal file
View File

@ -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
}
}

View File

@ -1,5 +1,5 @@
%define rpmversion 0.9.3
%define specrelease 4%{?dist}
%define specrelease 14%{?dist}
Name: nftables
Version: %{rpmversion}
@ -13,6 +13,34 @@ URL: http://netfilter.org/projects/nftables/
Source0: http://ftp.netfilter.org/pub/nftables/nftables-%{version}.tar.bz2
Source1: nftables.service
Source2: nftables.conf
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
Patch22: 0022-parser_json-Support-ranges-in-concat-expressions.patch
Patch23: 0023-doc-Document-notrack-statement.patch
Patch24: 0024-JSON-Improve-performance-of-json_events_cb.patch
BuildRequires: autogen
BuildRequires: autoconf
@ -24,14 +52,14 @@ BuildRequires: bison
BuildRequires: libmnl-devel
BuildRequires: gmp-devel
BuildRequires: readline-devel
BuildRequires: pkgconfig(libnftnl) >= 1.1.5-1
BuildRequires: pkgconfig(libnftnl) >= 1.1.5-3
BuildRequires: systemd
BuildRequires: asciidoc
BuildRequires: iptables-devel
BuildRequires: jansson-devel
BuildRequires: python3-devel
Requires: libnftnl >= 1.1.5-1
Requires: libnftnl >= 1.1.5-3
%description
Netfilter Tables userspace utilities.
@ -77,6 +105,10 @@ cp -a %{SOURCE1} $RPM_BUILD_ROOT/%{_unitdir}/
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig
cp -a %{SOURCE2} $RPM_BUILD_ROOT/%{_sysconfdir}/sysconfig/
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 {} \; \)
@ -125,6 +157,53 @@ touch -r %{SOURCE2} $RPM_BUILD_ROOT/%{python3_sitelib}/nftables/nftables.py
%{python3_sitelib}/nftables/
%changelog
* Wed Jun 24 2020 Phil Sutter <psutter@redhat.com> [0.9.3-14.el8]
- JSON: Improve performance of json_events_cb() (Phil Sutter) [1835300]
- doc: Document notrack statement (Phil Sutter) [1841292]
* Wed May 27 2020 Phil Sutter <psutter@redhat.com> [0.9.3-13.el8]
- parser_json: Support ranges in concat expressions (Phil Sutter) [1805798]
* Thu Mar 26 2020 Phil Sutter <psutter@redhat.com> [0.9.3-12.el8]
- Restore default config to be empty (Phil Sutter) [1694723]
* Mon Feb 17 2020 Phil Sutter <psutter@redhat.com> [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 <psutter@redhat.com> [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 <psutter@redhat.com> [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 <psutter@redhat.com> [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 <psutter@redhat.com> [0.9.3-7.el8]
- monitor: Fix output for ranges in anonymous sets (Phil Sutter) [1774742]
* Fri Jan 10 2020 Phil Sutter <psutter@redhat.com> [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 <psutter@redhat.com> [0.9.3-5.el8]
- Install an improved sample config (Phil Sutter) [1694723]
* Wed Dec 04 2019 Phil Sutter <psutter@redhat.com> [0.9.3-4.el8]
- Explicitly depend on newer libnftl version (Phil Sutter) [1643192]