import nftables-0.9.3-17.el8
This commit is contained in:
parent
ee8ec96d0a
commit
264b1152b5
@ -0,0 +1,42 @@
|
||||
From ab62f33df5ef33f6eff8d88d9475a01822a2f625 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Tue, 30 Jun 2020 16:20:22 +0200
|
||||
Subject: [PATCH] segtree: Fix missing expires value in prefixes
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1832235
|
||||
Upstream Status: nftables commit 60ba9c22fecc0
|
||||
|
||||
commit 60ba9c22fecc0ca9bb2a61f6ad39bceed1aee38f
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Tue Apr 28 20:54:03 2020 +0200
|
||||
|
||||
segtree: Fix missing expires value in prefixes
|
||||
|
||||
This probable copy'n'paste bug prevented 'expiration' field from being
|
||||
populated when turning a range into a prefix in
|
||||
interval_map_decompose(). Consequently, interval sets with timeout did
|
||||
print expiry value for ranges (such as 10.0.0.1-10.0.0.5) but not
|
||||
prefixes (10.0.0.0/8, for instance).
|
||||
|
||||
Fixes: bb0e6d8a2851b ("segtree: incorrect handling of comments and timeouts with mapping")
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
---
|
||||
src/segtree.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/segtree.c b/src/segtree.c
|
||||
index e859f84..1ba4363 100644
|
||||
--- a/src/segtree.c
|
||||
+++ b/src/segtree.c
|
||||
@@ -1086,7 +1086,7 @@ void interval_map_decompose(struct expr *set)
|
||||
prefix->comment = xstrdup(low->comment);
|
||||
if (low->timeout)
|
||||
prefix->timeout = low->timeout;
|
||||
- if (low->left->expiration)
|
||||
+ if (low->expiration)
|
||||
prefix->expiration = low->expiration;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 119fbcbd8c37aac314d6ffa6225ab24ee4b0e31e Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Tue, 30 Jun 2020 16:20:23 +0200
|
||||
Subject: [PATCH] segtree: Use expr_clone in get_set_interval_*()
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1832235
|
||||
Upstream Status: nftables commit a2eedcc89d2ed
|
||||
|
||||
commit a2eedcc89d2ed40411c26d53579300c4f1ccb83d
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Thu Apr 30 13:45:40 2020 +0200
|
||||
|
||||
segtree: Use expr_clone in get_set_interval_*()
|
||||
|
||||
Both functions perform interval set lookups with either start and end or
|
||||
only start values as input. Interestingly, in practice they either see
|
||||
values which are not contained or which match an existing range exactly.
|
||||
|
||||
Make use of the above and just return a clone of the matching entry
|
||||
instead of creating a new one based on input data.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
---
|
||||
src/segtree.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/segtree.c b/src/segtree.c
|
||||
index 1ba4363..dc4db6b 100644
|
||||
--- a/src/segtree.c
|
||||
+++ b/src/segtree.c
|
||||
@@ -695,9 +695,7 @@ static struct expr *get_set_interval_find(const struct table *table,
|
||||
range_expr_value_high(high, i);
|
||||
if (mpz_cmp(left->key->value, low) >= 0 &&
|
||||
mpz_cmp(right->key->value, high) <= 0) {
|
||||
- range = range_expr_alloc(&internal_location,
|
||||
- expr_clone(left->key),
|
||||
- expr_clone(right->key));
|
||||
+ range = expr_clone(i->key);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
@@ -729,9 +727,7 @@ static struct expr *get_set_interval_end(const struct table *table,
|
||||
case EXPR_RANGE:
|
||||
range_expr_value_low(low, i);
|
||||
if (mpz_cmp(low, left->key->value) == 0) {
|
||||
- range = range_expr_alloc(&internal_location,
|
||||
- expr_clone(left->key),
|
||||
- expr_clone(i->key->right));
|
||||
+ range = expr_clone(i->key);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,131 @@
|
||||
From 40cdcccf0fc6f4d0d4c2248d4bd9bf3193a922e9 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Tue, 30 Jun 2020 16:20:23 +0200
|
||||
Subject: [PATCH] segtree: Merge get_set_interval_find() and
|
||||
get_set_interval_end()
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1832235
|
||||
Upstream Status: nftables commit f21e73d6700b8
|
||||
|
||||
commit f21e73d6700b873eb1a295f43bbad9caaca577e2
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Thu Apr 30 13:57:35 2020 +0200
|
||||
|
||||
segtree: Merge get_set_interval_find() and get_set_interval_end()
|
||||
|
||||
Both functions were very similar already. Under the assumption that they
|
||||
will always either see a range (or start of) that matches exactly or not
|
||||
at all, reduce complexity and make get_set_interval_find() accept NULL
|
||||
(left or) right values. This way it becomes a full replacement for
|
||||
get_set_interval_end().
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
---
|
||||
src/segtree.c | 63 +++++++++++++++--------------------------------------------
|
||||
1 file changed, 16 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/src/segtree.c b/src/segtree.c
|
||||
index dc4db6b..6e1f696 100644
|
||||
--- a/src/segtree.c
|
||||
+++ b/src/segtree.c
|
||||
@@ -681,63 +681,31 @@ static struct expr *get_set_interval_find(const struct table *table,
|
||||
{
|
||||
struct expr *range = NULL;
|
||||
struct set *set;
|
||||
- mpz_t low, high;
|
||||
struct expr *i;
|
||||
+ mpz_t val;
|
||||
|
||||
set = set_lookup(table, set_name);
|
||||
- mpz_init2(low, set->key->len);
|
||||
- mpz_init2(high, set->key->len);
|
||||
+ mpz_init2(val, set->key->len);
|
||||
|
||||
list_for_each_entry(i, &set->init->expressions, list) {
|
||||
switch (i->key->etype) {
|
||||
case EXPR_RANGE:
|
||||
- range_expr_value_low(low, i);
|
||||
- range_expr_value_high(high, i);
|
||||
- if (mpz_cmp(left->key->value, low) >= 0 &&
|
||||
- mpz_cmp(right->key->value, high) <= 0) {
|
||||
- range = expr_clone(i->key);
|
||||
- goto out;
|
||||
- }
|
||||
- break;
|
||||
- default:
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-out:
|
||||
- mpz_clear(low);
|
||||
- mpz_clear(high);
|
||||
-
|
||||
- return range;
|
||||
-}
|
||||
-
|
||||
-static struct expr *get_set_interval_end(const struct table *table,
|
||||
- const char *set_name,
|
||||
- struct expr *left)
|
||||
-{
|
||||
- struct expr *i, *range = NULL;
|
||||
- struct set *set;
|
||||
- mpz_t low, high;
|
||||
+ range_expr_value_low(val, i);
|
||||
+ if (left && mpz_cmp(left->key->value, val))
|
||||
+ break;
|
||||
|
||||
- set = set_lookup(table, set_name);
|
||||
- mpz_init2(low, set->key->len);
|
||||
- mpz_init2(high, set->key->len);
|
||||
+ range_expr_value_high(val, i);
|
||||
+ if (right && mpz_cmp(right->key->value, val))
|
||||
+ break;
|
||||
|
||||
- list_for_each_entry(i, &set->init->expressions, list) {
|
||||
- switch (i->key->etype) {
|
||||
- case EXPR_RANGE:
|
||||
- range_expr_value_low(low, i);
|
||||
- if (mpz_cmp(low, left->key->value) == 0) {
|
||||
- range = expr_clone(i->key);
|
||||
- goto out;
|
||||
- }
|
||||
- break;
|
||||
+ range = expr_clone(i->key);
|
||||
+ goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
- mpz_clear(low);
|
||||
- mpz_clear(high);
|
||||
+ mpz_clear(val);
|
||||
|
||||
return range;
|
||||
}
|
||||
@@ -767,9 +735,9 @@ int get_set_decompose(struct table *table, struct set *set)
|
||||
left = NULL;
|
||||
} else {
|
||||
if (left) {
|
||||
- range = get_set_interval_end(table,
|
||||
- set->handle.set.name,
|
||||
- left);
|
||||
+ range = get_set_interval_find(table,
|
||||
+ set->handle.set.name,
|
||||
+ left, NULL);
|
||||
if (range)
|
||||
compound_expr_add(new_init, range);
|
||||
else
|
||||
@@ -780,7 +748,8 @@ int get_set_decompose(struct table *table, struct set *set)
|
||||
}
|
||||
}
|
||||
if (left) {
|
||||
- range = get_set_interval_end(table, set->handle.set.name, left);
|
||||
+ range = get_set_interval_find(table, set->handle.set.name,
|
||||
+ left, NULL);
|
||||
if (range)
|
||||
compound_expr_add(new_init, range);
|
||||
else
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,41 @@
|
||||
From 4337d4eafe66b594b56b43261c8742d6b65d5ee8 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Tue, 30 Jun 2020 16:20:23 +0200
|
||||
Subject: [PATCH] tests: 0034get_element_0: do not discard stderr
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1832235
|
||||
Upstream Status: nftables commit ff29e6c09aed9
|
||||
|
||||
commit ff29e6c09aed922a42e0e0551c34dd5d87067512
|
||||
Author: Florian Westphal <fw@strlen.de>
|
||||
Date: Sat Feb 22 00:02:25 2020 +0100
|
||||
|
||||
tests: 0034get_element_0: do not discard stderr
|
||||
|
||||
run_tests.sh alreadty discards stderr by default, but will show it in
|
||||
case the test script is run directly (passed as argument).
|
||||
|
||||
Discarding stderr also in the script prevents one from seeing
|
||||
BUG() assertions and the like.
|
||||
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
---
|
||||
tests/shell/testcases/sets/0034get_element_0 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/shell/testcases/sets/0034get_element_0 b/tests/shell/testcases/sets/0034get_element_0
|
||||
index c7e7298..e23dbda 100755
|
||||
--- a/tests/shell/testcases/sets/0034get_element_0
|
||||
+++ b/tests/shell/testcases/sets/0034get_element_0
|
||||
@@ -3,7 +3,7 @@
|
||||
RC=0
|
||||
|
||||
check() { # (elems, expected)
|
||||
- out=$($NFT get element ip t s "{ $1 }" 2>/dev/null)
|
||||
+ out=$($NFT get element ip t s "{ $1 }")
|
||||
out=$(grep "elements =" <<< "$out")
|
||||
out="${out#* \{ }"
|
||||
out="${out% \}}"
|
||||
--
|
||||
1.8.3.1
|
||||
|
135
SOURCES/0029-segtree-Fix-get-element-command-with-prefixes.patch
Normal file
135
SOURCES/0029-segtree-Fix-get-element-command-with-prefixes.patch
Normal file
@ -0,0 +1,135 @@
|
||||
From 3a2016f539e46183965bada40946e259c33158d9 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Tue, 30 Jun 2020 16:20:23 +0200
|
||||
Subject: [PATCH] segtree: Fix get element command with prefixes
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1832235
|
||||
Upstream Status: nftables commit 506fb113f7ca4
|
||||
|
||||
commit 506fb113f7ca4fbb3d6da09ef6f9dc2b31f54a1f
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Thu Apr 30 14:02:44 2020 +0200
|
||||
|
||||
segtree: Fix get element command with prefixes
|
||||
|
||||
Code wasn't aware of prefix elements in interval sets. With previous
|
||||
changes in place, they merely need to be accepted in
|
||||
get_set_interval_find() - value comparison and expression duplication is
|
||||
identical to ranges.
|
||||
|
||||
Extend sets/0034get_element_0 test to cover prefixes as well. While
|
||||
being at it, also cover concatenated ranges.
|
||||
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
---
|
||||
src/segtree.c | 1 +
|
||||
tests/shell/testcases/sets/0034get_element_0 | 62 ++++++++++++++++++++--------
|
||||
2 files changed, 45 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/segtree.c b/src/segtree.c
|
||||
index 6e1f696..073c6ec 100644
|
||||
--- a/src/segtree.c
|
||||
+++ b/src/segtree.c
|
||||
@@ -689,6 +689,7 @@ static struct expr *get_set_interval_find(const struct table *table,
|
||||
|
||||
list_for_each_entry(i, &set->init->expressions, list) {
|
||||
switch (i->key->etype) {
|
||||
+ case EXPR_PREFIX:
|
||||
case EXPR_RANGE:
|
||||
range_expr_value_low(val, i);
|
||||
if (left && mpz_cmp(left->key->value, val))
|
||||
diff --git a/tests/shell/testcases/sets/0034get_element_0 b/tests/shell/testcases/sets/0034get_element_0
|
||||
index e23dbda..3343529 100755
|
||||
--- a/tests/shell/testcases/sets/0034get_element_0
|
||||
+++ b/tests/shell/testcases/sets/0034get_element_0
|
||||
@@ -2,43 +2,69 @@
|
||||
|
||||
RC=0
|
||||
|
||||
-check() { # (elems, expected)
|
||||
- out=$($NFT get element ip t s "{ $1 }")
|
||||
+check() { # (set, elems, expected)
|
||||
+ out=$($NFT get element ip t $1 "{ $2 }")
|
||||
out=$(grep "elements =" <<< "$out")
|
||||
out="${out#* \{ }"
|
||||
out="${out% \}}"
|
||||
- [[ "$out" == "$2" ]] && return
|
||||
- echo "ERROR: asked for '$1', expecting '$2' but got '$out'"
|
||||
+ [[ "$out" == "$3" ]] && return
|
||||
+ echo "ERROR: asked for '$2' in set $1, expecting '$3' but got '$out'"
|
||||
((RC++))
|
||||
}
|
||||
|
||||
RULESET="add table ip t
|
||||
add set ip t s { type inet_service; flags interval; }
|
||||
add element ip t s { 10, 20-30, 40, 50-60 }
|
||||
+add set ip t ips { type ipv4_addr; flags interval; }
|
||||
+add element ip t ips { 10.0.0.1, 10.0.0.5-10.0.0.8 }
|
||||
+add element ip t ips { 10.0.0.128/25, 10.0.1.0/24, 10.0.2.3-10.0.2.12 }
|
||||
+add set ip t cs { type ipv4_addr . inet_service; flags interval; }
|
||||
+add element ip t cs { 10.0.0.1 . 22, 10.1.0.0/16 . 1-1024 }
|
||||
+add element ip t cs { 10.2.0.1-10.2.0.8 . 1024-65535 }
|
||||
"
|
||||
|
||||
$NFT -f - <<< "$RULESET"
|
||||
|
||||
# simple cases, (non-)existing values and ranges
|
||||
-check 10 10
|
||||
-check 11 ""
|
||||
-check 20-30 20-30
|
||||
-check 15-18 ""
|
||||
+check s 10 10
|
||||
+check s 11 ""
|
||||
+check s 20-30 20-30
|
||||
+check s 15-18 ""
|
||||
|
||||
# multiple single elements, ranges smaller than present
|
||||
-check "10, 40" "10, 40"
|
||||
-check "22-24, 26-28" "20-30, 20-30"
|
||||
-check 21-29 20-30
|
||||
+check s "10, 40" "10, 40"
|
||||
+check s "22-24, 26-28" "20-30, 20-30"
|
||||
+check s 21-29 20-30
|
||||
|
||||
# mixed single elements and ranges
|
||||
-check "10, 20" "10, 20-30"
|
||||
-check "10, 22" "10, 20-30"
|
||||
-check "10, 22-24" "10, 20-30"
|
||||
+check s "10, 20" "10, 20-30"
|
||||
+check s "10, 22" "10, 20-30"
|
||||
+check s "10, 22-24" "10, 20-30"
|
||||
|
||||
# non-existing ranges matching elements
|
||||
-check 10-40 ""
|
||||
-check 10-20 ""
|
||||
-check 10-25 ""
|
||||
-check 25-55 ""
|
||||
+check s 10-40 ""
|
||||
+check s 10-20 ""
|
||||
+check s 10-25 ""
|
||||
+check s 25-55 ""
|
||||
+
|
||||
+# playing with IPs, ranges and prefixes
|
||||
+check ips 10.0.0.1 10.0.0.1
|
||||
+check ips 10.0.0.2 ""
|
||||
+check ips 10.0.1.0/24 10.0.1.0/24
|
||||
+check ips 10.0.1.2/31 10.0.1.0/24
|
||||
+check ips 10.0.1.0 10.0.1.0/24
|
||||
+check ips 10.0.1.3 10.0.1.0/24
|
||||
+check ips 10.0.1.255 10.0.1.0/24
|
||||
+check ips 10.0.2.3-10.0.2.12 10.0.2.3-10.0.2.12
|
||||
+check ips 10.0.2.10 10.0.2.3-10.0.2.12
|
||||
+check ips 10.0.2.12 10.0.2.3-10.0.2.12
|
||||
+
|
||||
+# test concatenated ranges, i.e. Pi, Pa and Po
|
||||
+check cs "10.0.0.1 . 22" "10.0.0.1 . 22"
|
||||
+check cs "10.0.0.1 . 23" ""
|
||||
+check cs "10.0.0.2 . 22" ""
|
||||
+check cs "10.1.0.1 . 42" "10.1.0.0/16 . 1-1024"
|
||||
+check cs "10.1.1.0/24 . 10-20" "10.1.0.0/16 . 1-1024"
|
||||
+check cs "10.2.0.3 . 20000" "10.2.0.1-10.2.0.8 . 1024-65535"
|
||||
|
||||
exit $RC
|
||||
--
|
||||
1.8.3.1
|
||||
|
45
SOURCES/0030-include-Resync-nf_tables.h-cache-copy.patch
Normal file
45
SOURCES/0030-include-Resync-nf_tables.h-cache-copy.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 77a93baa622f8aa33fa6182d72b380d980e39574 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Sat, 8 Aug 2020 00:09:06 +0200
|
||||
Subject: [PATCH] include: Resync nf_tables.h cache copy
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1820684
|
||||
Upstream Status: nftables commit f1e5a0499c077
|
||||
|
||||
commit f1e5a0499c0773f18bc592dd0da0340120daa482
|
||||
Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
Date: Mon Apr 13 21:48:02 2020 +0200
|
||||
|
||||
include: Resync nf_tables.h cache copy
|
||||
|
||||
Get this header in sync with nf.git as of commit ef516e8625dd.
|
||||
|
||||
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
include/linux/netfilter/nf_tables.h | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
|
||||
index 1a99df3..9b54a86 100644
|
||||
--- a/include/linux/netfilter/nf_tables.h
|
||||
+++ b/include/linux/netfilter/nf_tables.h
|
||||
@@ -274,6 +274,7 @@ enum nft_rule_compat_attributes {
|
||||
* @NFT_SET_TIMEOUT: set uses timeouts
|
||||
* @NFT_SET_EVAL: set can be updated from the evaluation path
|
||||
* @NFT_SET_OBJECT: set contains stateful objects
|
||||
+ * @NFT_SET_CONCAT: set contains a concatenation
|
||||
*/
|
||||
enum nft_set_flags {
|
||||
NFT_SET_ANONYMOUS = 0x1,
|
||||
@@ -283,6 +284,7 @@ enum nft_set_flags {
|
||||
NFT_SET_TIMEOUT = 0x10,
|
||||
NFT_SET_EVAL = 0x20,
|
||||
NFT_SET_OBJECT = 0x40,
|
||||
+ NFT_SET_CONCAT = 0x80,
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,72 @@
|
||||
From 5566405cc171c8fa84e0a13ea96b89245a3fb512 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Sat, 8 Aug 2020 00:05:48 +0200
|
||||
Subject: [PATCH] src: Set NFT_SET_CONCAT flag for sets with concatenated
|
||||
ranges
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1820684
|
||||
Upstream Status: nftables commit 09441b5e92cee
|
||||
|
||||
commit 09441b5e92ceea60198a35cd657904fa7a10ee54
|
||||
Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
Date: Mon Apr 13 21:48:03 2020 +0200
|
||||
|
||||
src: Set NFT_SET_CONCAT flag for sets with concatenated ranges
|
||||
|
||||
Pablo reports that nft, after commit 8ac2f3b2fca3 ("src: Add support
|
||||
for concatenated set ranges"), crashes with older kernels (< 5.6)
|
||||
without support for concatenated set ranges: those sets will be sent
|
||||
to the kernel, which adds them without notion of the fact that
|
||||
different concatenated fields are actually included, and nft crashes
|
||||
while trying to list this kind of malformed concatenation.
|
||||
|
||||
Use the NFT_SET_CONCAT flag introduced by kernel commit ef516e8625dd
|
||||
("netfilter: nf_tables: reintroduce the NFT_SET_CONCAT flag") when
|
||||
sets including concatenated ranges are sent to the kernel, so that
|
||||
older kernels (with no knowledge of this flag itself) will refuse set
|
||||
creation.
|
||||
|
||||
Note that, in expr_evaluate_set(), we have to check for the presence
|
||||
of the flag, also on empty sets that might carry it in context data,
|
||||
and actually set it in the actual set flags.
|
||||
|
||||
Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
src/evaluate.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||
index 0c84816..f66251b 100644
|
||||
--- a/src/evaluate.c
|
||||
+++ b/src/evaluate.c
|
||||
@@ -1360,10 +1360,16 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr)
|
||||
set->size += i->size - 1;
|
||||
set->set_flags |= i->set_flags;
|
||||
expr_free(i);
|
||||
- } else if (!expr_is_singleton(i))
|
||||
+ } else if (!expr_is_singleton(i)) {
|
||||
set->set_flags |= NFT_SET_INTERVAL;
|
||||
+ if (i->key->etype == EXPR_CONCAT)
|
||||
+ set->set_flags |= NFT_SET_CONCAT;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ if (ctx->set && (ctx->set->flags & NFT_SET_CONCAT))
|
||||
+ set->set_flags |= NFT_SET_CONCAT;
|
||||
+
|
||||
set->set_flags |= NFT_SET_CONSTANT;
|
||||
|
||||
datatype_set(set, ctx->ectx.dtype);
|
||||
@@ -3336,6 +3342,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
||||
memcpy(&set->desc.field_len, &set->key->field_len,
|
||||
sizeof(set->desc.field_len));
|
||||
set->desc.field_count = set->key->field_count;
|
||||
+ set->flags |= NFT_SET_CONCAT;
|
||||
}
|
||||
|
||||
if (set_is_datamap(set->flags)) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,503 @@
|
||||
From 19da892698f1dce2125a796ad86239711896978f Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Mon, 7 Dec 2020 18:25:20 +0100
|
||||
Subject: [PATCH] src: store expr, not dtype to track data in sets
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1877022
|
||||
Upstream Status: nftables commit 343a51702656a
|
||||
|
||||
commit 343a51702656a6476e37cfb84609a82155c7fc5e
|
||||
Author: Florian Westphal <fw@strlen.de>
|
||||
Date: Tue Jul 16 19:03:55 2019 +0200
|
||||
|
||||
src: store expr, not dtype to track data in sets
|
||||
|
||||
This will be needed once we add support for the 'typeof' keyword to
|
||||
handle maps that could e.g. store 'ct helper' "type" values.
|
||||
|
||||
Instead of:
|
||||
|
||||
set foo {
|
||||
type ipv4_addr . mark;
|
||||
|
||||
this would allow
|
||||
|
||||
set foo {
|
||||
typeof(ip saddr) . typeof(ct mark);
|
||||
|
||||
(exact syntax TBD).
|
||||
|
||||
This would be needed to allow sets that store variable-sized data types
|
||||
(string, integer and the like) that can't be used at at the moment.
|
||||
|
||||
Adding special data types for everything is problematic due to the
|
||||
large amount of different types needed.
|
||||
|
||||
For anonymous sets, e.g. "string" can be used because the needed size can
|
||||
be inferred from the statement, e.g. 'osf name { "Windows", "Linux }',
|
||||
but in case of named sets that won't work because 'type string' lacks the
|
||||
context needed to derive the size information.
|
||||
|
||||
With 'typeof(osf name)' the context is there, but at the moment it won't
|
||||
help because the expression is discarded instantly and only the data
|
||||
type is retained.
|
||||
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
---
|
||||
include/datatype.h | 1 -
|
||||
include/netlink.h | 1 -
|
||||
include/rule.h | 6 ++----
|
||||
src/datatype.c | 5 -----
|
||||
src/evaluate.c | 58 +++++++++++++++++++++++++++++++++++++-----------------
|
||||
src/expression.c | 2 +-
|
||||
src/json.c | 4 ++--
|
||||
src/mnl.c | 6 +++---
|
||||
src/monitor.c | 2 +-
|
||||
src/netlink.c | 32 ++++++++++++++----------------
|
||||
src/parser_bison.y | 3 +--
|
||||
src/parser_json.c | 8 ++++++--
|
||||
src/rule.c | 8 ++++----
|
||||
src/segtree.c | 8 ++++++--
|
||||
14 files changed, 81 insertions(+), 63 deletions(-)
|
||||
|
||||
diff --git a/include/datatype.h b/include/datatype.h
|
||||
index 49b8f60..04b4892 100644
|
||||
--- a/include/datatype.h
|
||||
+++ b/include/datatype.h
|
||||
@@ -293,7 +293,6 @@ concat_subtype_lookup(uint32_t type, unsigned int n)
|
||||
|
||||
extern const struct datatype *
|
||||
set_datatype_alloc(const struct datatype *orig_dtype, unsigned int byteorder);
|
||||
-extern void set_datatype_destroy(const struct datatype *dtype);
|
||||
|
||||
extern void time_print(uint64_t msec, struct output_ctx *octx);
|
||||
extern struct error_record *time_parse(const struct location *loc,
|
||||
diff --git a/include/netlink.h b/include/netlink.h
|
||||
index e694171..88d12ba 100644
|
||||
--- a/include/netlink.h
|
||||
+++ b/include/netlink.h
|
||||
@@ -189,6 +189,5 @@ int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type,
|
||||
struct netlink_mon_handler *monh);
|
||||
|
||||
enum nft_data_types dtype_map_to_kernel(const struct datatype *dtype);
|
||||
-const struct datatype *dtype_map_from_kernel(enum nft_data_types type);
|
||||
|
||||
#endif /* NFTABLES_NETLINK_H */
|
||||
diff --git a/include/rule.h b/include/rule.h
|
||||
index 626973e..3637462 100644
|
||||
--- a/include/rule.h
|
||||
+++ b/include/rule.h
|
||||
@@ -283,8 +283,7 @@ extern struct rule *rule_lookup_by_index(const struct chain *chain,
|
||||
* @gc_int: garbage collection interval
|
||||
* @timeout: default timeout value
|
||||
* @key: key expression (data type, length))
|
||||
- * @datatype: mapping data type
|
||||
- * @datalen: mapping data len
|
||||
+ * @data: mapping data expression
|
||||
* @objtype: mapping object type
|
||||
* @init: initializer
|
||||
* @rg_cache: cached range element (left)
|
||||
@@ -303,8 +302,7 @@ struct set {
|
||||
uint32_t gc_int;
|
||||
uint64_t timeout;
|
||||
struct expr *key;
|
||||
- const struct datatype *datatype;
|
||||
- unsigned int datalen;
|
||||
+ struct expr *data;
|
||||
uint32_t objtype;
|
||||
struct expr *init;
|
||||
struct expr *rg_cache;
|
||||
diff --git a/src/datatype.c b/src/datatype.c
|
||||
index b9e167e..189e1b4 100644
|
||||
--- a/src/datatype.c
|
||||
+++ b/src/datatype.c
|
||||
@@ -1190,11 +1190,6 @@ const struct datatype *set_datatype_alloc(const struct datatype *orig_dtype,
|
||||
return dtype;
|
||||
}
|
||||
|
||||
-void set_datatype_destroy(const struct datatype *dtype)
|
||||
-{
|
||||
- datatype_free(dtype);
|
||||
-}
|
||||
-
|
||||
static struct error_record *time_unit_parse(const struct location *loc,
|
||||
const char *str, uint64_t *unit)
|
||||
{
|
||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||
index f66251b..578dcae 100644
|
||||
--- a/src/evaluate.c
|
||||
+++ b/src/evaluate.c
|
||||
@@ -1383,6 +1383,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
|
||||
{
|
||||
struct expr_ctx ectx = ctx->ectx;
|
||||
struct expr *map = *expr, *mappings;
|
||||
+ const struct datatype *dtype;
|
||||
struct expr *key;
|
||||
|
||||
expr_set_context(&ctx->ectx, NULL, 0);
|
||||
@@ -1405,10 +1406,14 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
|
||||
mappings = implicit_set_declaration(ctx, "__map%d",
|
||||
key,
|
||||
mappings);
|
||||
- mappings->set->datatype =
|
||||
- datatype_get(set_datatype_alloc(ectx.dtype,
|
||||
- ectx.byteorder));
|
||||
- mappings->set->datalen = ectx.len;
|
||||
+
|
||||
+ dtype = set_datatype_alloc(ectx.dtype, ectx.byteorder);
|
||||
+
|
||||
+ mappings->set->data = constant_expr_alloc(&netlink_location,
|
||||
+ dtype, dtype->byteorder,
|
||||
+ ectx.len, NULL);
|
||||
+ if (ectx.len && mappings->set->data->len != ectx.len)
|
||||
+ BUG("%d vs %d\n", mappings->set->data->len, ectx.len);
|
||||
|
||||
map->mappings = mappings;
|
||||
|
||||
@@ -1444,7 +1449,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
|
||||
map->mappings->set->key->dtype->desc,
|
||||
map->map->dtype->desc);
|
||||
|
||||
- datatype_set(map, map->mappings->set->datatype);
|
||||
+ datatype_set(map, map->mappings->set->data->dtype);
|
||||
map->flags |= EXPR_F_CONSTANT;
|
||||
|
||||
/* Data for range lookups needs to be in big endian order */
|
||||
@@ -1474,7 +1479,12 @@ static int expr_evaluate_mapping(struct eval_ctx *ctx, struct expr **expr)
|
||||
"Key must be a constant");
|
||||
mapping->flags |= mapping->left->flags & EXPR_F_SINGLETON;
|
||||
|
||||
- expr_set_context(&ctx->ectx, set->datatype, set->datalen);
|
||||
+ if (set->data) {
|
||||
+ expr_set_context(&ctx->ectx, set->data->dtype, set->data->len);
|
||||
+ } else {
|
||||
+ assert((set->flags & NFT_SET_MAP) == 0);
|
||||
+ }
|
||||
+
|
||||
if (expr_evaluate(ctx, &mapping->right) < 0)
|
||||
return -1;
|
||||
if (!expr_is_constant(mapping->right))
|
||||
@@ -2119,7 +2129,7 @@ static int stmt_evaluate_arg(struct eval_ctx *ctx, struct stmt *stmt,
|
||||
(*expr)->len);
|
||||
else if ((*expr)->dtype->type != TYPE_INTEGER &&
|
||||
!datatype_equal((*expr)->dtype, dtype))
|
||||
- return stmt_binary_error(ctx, *expr, stmt,
|
||||
+ return stmt_binary_error(ctx, *expr, stmt, /* verdict vs invalid? */
|
||||
"datatype mismatch: expected %s, "
|
||||
"expression has type %s",
|
||||
dtype->desc, (*expr)->dtype->desc);
|
||||
@@ -3113,9 +3123,9 @@ static int stmt_evaluate_map(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
"Key expression comments are not supported");
|
||||
|
||||
if (stmt_evaluate_arg(ctx, stmt,
|
||||
- stmt->map.set->set->datatype,
|
||||
- stmt->map.set->set->datalen,
|
||||
- stmt->map.set->set->datatype->byteorder,
|
||||
+ stmt->map.set->set->data->dtype,
|
||||
+ stmt->map.set->set->data->len,
|
||||
+ stmt->map.set->set->data->byteorder,
|
||||
&stmt->map.data->key) < 0)
|
||||
return -1;
|
||||
if (expr_is_constant(stmt->map.data))
|
||||
@@ -3161,8 +3171,12 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
|
||||
mappings = implicit_set_declaration(ctx, "__objmap%d",
|
||||
key, mappings);
|
||||
- mappings->set->datatype = &string_type;
|
||||
- mappings->set->datalen = NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE;
|
||||
+
|
||||
+ mappings->set->data = constant_expr_alloc(&netlink_location,
|
||||
+ &string_type,
|
||||
+ BYTEORDER_HOST_ENDIAN,
|
||||
+ NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE,
|
||||
+ NULL);
|
||||
mappings->set->objtype = stmt->objref.type;
|
||||
|
||||
map->mappings = mappings;
|
||||
@@ -3197,7 +3211,7 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
map->mappings->set->key->dtype->desc,
|
||||
map->map->dtype->desc);
|
||||
|
||||
- datatype_set(map, map->mappings->set->datatype);
|
||||
+ datatype_set(map, map->mappings->set->data->dtype);
|
||||
map->flags |= EXPR_F_CONSTANT;
|
||||
|
||||
/* Data for range lookups needs to be in big endian order */
|
||||
@@ -3346,17 +3360,25 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
||||
}
|
||||
|
||||
if (set_is_datamap(set->flags)) {
|
||||
- if (set->datatype == NULL)
|
||||
+ if (set->data == NULL)
|
||||
return set_error(ctx, set, "map definition does not "
|
||||
"specify mapping data type");
|
||||
|
||||
- set->datalen = set->datatype->size;
|
||||
- if (set->datalen == 0 && set->datatype->type != TYPE_VERDICT)
|
||||
+ if (set->data->len == 0 && set->data->dtype->type != TYPE_VERDICT)
|
||||
return set_error(ctx, set, "unqualified mapping data "
|
||||
"type specified in map definition");
|
||||
} else if (set_is_objmap(set->flags)) {
|
||||
- set->datatype = &string_type;
|
||||
- set->datalen = NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE;
|
||||
+ if (set->data) {
|
||||
+ assert(set->data->etype == EXPR_VALUE);
|
||||
+ assert(set->data->dtype == &string_type);
|
||||
+ }
|
||||
+
|
||||
+ assert(set->data == NULL);
|
||||
+ set->data = constant_expr_alloc(&netlink_location, &string_type,
|
||||
+ BYTEORDER_HOST_ENDIAN,
|
||||
+ NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE,
|
||||
+ NULL);
|
||||
+
|
||||
}
|
||||
|
||||
ctx->set = set;
|
||||
diff --git a/src/expression.c b/src/expression.c
|
||||
index 5070b10..6fa2f1d 100644
|
||||
--- a/src/expression.c
|
||||
+++ b/src/expression.c
|
||||
@@ -1010,7 +1010,7 @@ static void map_expr_print(const struct expr *expr, struct output_ctx *octx)
|
||||
{
|
||||
expr_print(expr->map, octx);
|
||||
if (expr->mappings->etype == EXPR_SET_REF &&
|
||||
- expr->mappings->set->datatype->type == TYPE_VERDICT)
|
||||
+ expr->mappings->set->data->dtype->type == TYPE_VERDICT)
|
||||
nft_print(octx, " vmap ");
|
||||
else
|
||||
nft_print(octx, " map ");
|
||||
diff --git a/src/json.c b/src/json.c
|
||||
index 3498e24..1906e7d 100644
|
||||
--- a/src/json.c
|
||||
+++ b/src/json.c
|
||||
@@ -82,7 +82,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
|
||||
|
||||
if (set_is_datamap(set->flags)) {
|
||||
type = "map";
|
||||
- datatype_ext = set->datatype->name;
|
||||
+ datatype_ext = set->data->dtype->name;
|
||||
} else if (set_is_objmap(set->flags)) {
|
||||
type = "map";
|
||||
datatype_ext = obj_type_name(set->objtype);
|
||||
@@ -645,7 +645,7 @@ json_t *map_expr_json(const struct expr *expr, struct output_ctx *octx)
|
||||
const char *type = "map";
|
||||
|
||||
if (expr->mappings->etype == EXPR_SET_REF &&
|
||||
- expr->mappings->set->datatype->type == TYPE_VERDICT)
|
||||
+ expr->mappings->set->data->dtype->type == TYPE_VERDICT)
|
||||
type = "vmap";
|
||||
|
||||
return json_pack("{s:{s:o, s:o}}", type,
|
||||
diff --git a/src/mnl.c b/src/mnl.c
|
||||
index 221ee05..23341e6 100644
|
||||
--- a/src/mnl.c
|
||||
+++ b/src/mnl.c
|
||||
@@ -839,9 +839,9 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
|
||||
div_round_up(set->key->len, BITS_PER_BYTE));
|
||||
if (set_is_datamap(set->flags)) {
|
||||
nftnl_set_set_u32(nls, NFTNL_SET_DATA_TYPE,
|
||||
- dtype_map_to_kernel(set->datatype));
|
||||
+ dtype_map_to_kernel(set->data->dtype));
|
||||
nftnl_set_set_u32(nls, NFTNL_SET_DATA_LEN,
|
||||
- set->datalen / BITS_PER_BYTE);
|
||||
+ set->data->len / BITS_PER_BYTE);
|
||||
}
|
||||
if (set_is_objmap(set->flags))
|
||||
nftnl_set_set_u32(nls, NFTNL_SET_OBJ_TYPE, set->objtype);
|
||||
@@ -873,7 +873,7 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd,
|
||||
|
||||
if (set_is_datamap(set->flags) &&
|
||||
!nftnl_udata_put_u32(udbuf, NFTNL_UDATA_SET_DATABYTEORDER,
|
||||
- set->datatype->byteorder))
|
||||
+ set->data->byteorder))
|
||||
memory_allocation_error();
|
||||
|
||||
if (set->automerge &&
|
||||
diff --git a/src/monitor.c b/src/monitor.c
|
||||
index fb803cf..7927b6f 100644
|
||||
--- a/src/monitor.c
|
||||
+++ b/src/monitor.c
|
||||
@@ -401,7 +401,7 @@ static int netlink_events_setelem_cb(const struct nlmsghdr *nlh, int type,
|
||||
*/
|
||||
dummyset = set_alloc(monh->loc);
|
||||
dummyset->key = expr_clone(set->key);
|
||||
- dummyset->datatype = set->datatype;
|
||||
+ dummyset->data = set->data;
|
||||
dummyset->flags = set->flags;
|
||||
dummyset->init = set_expr_alloc(monh->loc, set);
|
||||
|
||||
diff --git a/src/netlink.c b/src/netlink.c
|
||||
index e0ba903..64e51e5 100644
|
||||
--- a/src/netlink.c
|
||||
+++ b/src/netlink.c
|
||||
@@ -575,7 +575,7 @@ enum nft_data_types dtype_map_to_kernel(const struct datatype *dtype)
|
||||
}
|
||||
}
|
||||
|
||||
-const struct datatype *dtype_map_from_kernel(enum nft_data_types type)
|
||||
+static const struct datatype *dtype_map_from_kernel(enum nft_data_types type)
|
||||
{
|
||||
switch (type) {
|
||||
case NFT_DATA_VERDICT:
|
||||
@@ -622,10 +622,10 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
|
||||
const struct nftnl_set *nls)
|
||||
{
|
||||
const struct nftnl_udata *ud[NFTNL_UDATA_SET_MAX + 1] = {};
|
||||
- uint32_t flags, key, data, data_len, objtype = 0;
|
||||
enum byteorder keybyteorder = BYTEORDER_INVALID;
|
||||
enum byteorder databyteorder = BYTEORDER_INVALID;
|
||||
- const struct datatype *keytype, *datatype;
|
||||
+ const struct datatype *keytype, *datatype = NULL;
|
||||
+ uint32_t flags, key, objtype = 0;
|
||||
bool automerge = false;
|
||||
const char *udata;
|
||||
struct set *set;
|
||||
@@ -659,6 +659,8 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
|
||||
|
||||
flags = nftnl_set_get_u32(nls, NFTNL_SET_FLAGS);
|
||||
if (set_is_datamap(flags)) {
|
||||
+ uint32_t data;
|
||||
+
|
||||
data = nftnl_set_get_u32(nls, NFTNL_SET_DATA_TYPE);
|
||||
datatype = dtype_map_from_kernel(data);
|
||||
if (datatype == NULL) {
|
||||
@@ -667,8 +669,7 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
|
||||
data);
|
||||
return NULL;
|
||||
}
|
||||
- } else
|
||||
- datatype = NULL;
|
||||
+ }
|
||||
|
||||
if (set_is_objmap(flags)) {
|
||||
objtype = nftnl_set_get_u32(nls, NFTNL_SET_OBJ_TYPE);
|
||||
@@ -691,16 +692,13 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx,
|
||||
|
||||
set->objtype = objtype;
|
||||
|
||||
+ set->data = NULL;
|
||||
if (datatype)
|
||||
- set->datatype = datatype_get(set_datatype_alloc(datatype,
|
||||
- databyteorder));
|
||||
- else
|
||||
- set->datatype = NULL;
|
||||
-
|
||||
- if (nftnl_set_is_set(nls, NFTNL_SET_DATA_LEN)) {
|
||||
- data_len = nftnl_set_get_u32(nls, NFTNL_SET_DATA_LEN);
|
||||
- set->datalen = data_len * BITS_PER_BYTE;
|
||||
- }
|
||||
+ set->data = constant_expr_alloc(&netlink_location,
|
||||
+ set_datatype_alloc(datatype, databyteorder),
|
||||
+ databyteorder,
|
||||
+ nftnl_set_get_u32(nls, NFTNL_SET_DATA_LEN) * BITS_PER_BYTE,
|
||||
+ NULL);
|
||||
|
||||
if (nftnl_set_is_set(nls, NFTNL_SET_TIMEOUT))
|
||||
set->timeout = nftnl_set_get_u64(nls, NFTNL_SET_TIMEOUT);
|
||||
@@ -897,10 +895,10 @@ key_end:
|
||||
goto out;
|
||||
|
||||
data = netlink_alloc_data(&netlink_location, &nld,
|
||||
- set->datatype->type == TYPE_VERDICT ?
|
||||
+ set->data->dtype->type == TYPE_VERDICT ?
|
||||
NFT_REG_VERDICT : NFT_REG_1);
|
||||
- datatype_set(data, set->datatype);
|
||||
- data->byteorder = set->datatype->byteorder;
|
||||
+ datatype_set(data, set->data->dtype);
|
||||
+ data->byteorder = set->data->byteorder;
|
||||
if (data->byteorder == BYTEORDER_HOST_ENDIAN)
|
||||
mpz_switch_byteorder(data->value, data->len / BITS_PER_BYTE);
|
||||
|
||||
diff --git a/src/parser_bison.y b/src/parser_bison.y
|
||||
index ea83f52..4cca31b 100644
|
||||
--- a/src/parser_bison.y
|
||||
+++ b/src/parser_bison.y
|
||||
@@ -1749,9 +1749,8 @@ map_block : /* empty */ { $$ = $<set>-1; }
|
||||
stmt_separator
|
||||
{
|
||||
$1->key = $3;
|
||||
- $1->datatype = $5->dtype;
|
||||
+ $1->data = $5;
|
||||
|
||||
- expr_free($5);
|
||||
$1->flags |= NFT_SET_MAP;
|
||||
$$ = $1;
|
||||
}
|
||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||||
index ce8e566..ddc694f 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -2833,11 +2833,15 @@ static struct cmd *json_parse_cmd_add_set(struct json_ctx *ctx, json_t *root,
|
||||
}
|
||||
|
||||
if (!json_unpack(root, "{s:s}", "map", &dtype_ext)) {
|
||||
+ const struct datatype *dtype;
|
||||
+
|
||||
set->objtype = string_to_nft_object(dtype_ext);
|
||||
if (set->objtype) {
|
||||
set->flags |= NFT_SET_OBJECT;
|
||||
- } else if (datatype_lookup_byname(dtype_ext)) {
|
||||
- set->datatype = datatype_lookup_byname(dtype_ext);
|
||||
+ } else if ((dtype = datatype_lookup_byname(dtype_ext))) {
|
||||
+ set->data = constant_expr_alloc(&netlink_location,
|
||||
+ dtype, dtype->byteorder,
|
||||
+ dtype->size, NULL);
|
||||
set->flags |= NFT_SET_MAP;
|
||||
} else {
|
||||
json_error(ctx, "Invalid map type '%s'.", dtype_ext);
|
||||
diff --git a/src/rule.c b/src/rule.c
|
||||
index e18237b..f7d888b 100644
|
||||
--- a/src/rule.c
|
||||
+++ b/src/rule.c
|
||||
@@ -332,8 +332,8 @@ struct set *set_clone(const struct set *set)
|
||||
new_set->gc_int = set->gc_int;
|
||||
new_set->timeout = set->timeout;
|
||||
new_set->key = expr_clone(set->key);
|
||||
- new_set->datatype = datatype_get(set->datatype);
|
||||
- new_set->datalen = set->datalen;
|
||||
+ if (set->data)
|
||||
+ new_set->data = expr_clone(set->data);
|
||||
new_set->objtype = set->objtype;
|
||||
new_set->policy = set->policy;
|
||||
new_set->automerge = set->automerge;
|
||||
@@ -356,7 +356,7 @@ void set_free(struct set *set)
|
||||
expr_free(set->init);
|
||||
handle_free(&set->handle);
|
||||
expr_free(set->key);
|
||||
- set_datatype_destroy(set->datatype);
|
||||
+ expr_free(set->data);
|
||||
xfree(set);
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ static void set_print_declaration(const struct set *set,
|
||||
nft_print(octx, "%s%stype %s",
|
||||
opts->tab, opts->tab, set->key->dtype->name);
|
||||
if (set_is_datamap(set->flags))
|
||||
- nft_print(octx, " : %s", set->datatype->name);
|
||||
+ nft_print(octx, " : %s", set->data->dtype->name);
|
||||
else if (set_is_objmap(set->flags))
|
||||
nft_print(octx, " : %s", obj_type_name(set->objtype));
|
||||
|
||||
diff --git a/src/segtree.c b/src/segtree.c
|
||||
index 073c6ec..d6e3ce2 100644
|
||||
--- a/src/segtree.c
|
||||
+++ b/src/segtree.c
|
||||
@@ -79,8 +79,12 @@ static void seg_tree_init(struct seg_tree *tree, const struct set *set,
|
||||
tree->root = RB_ROOT;
|
||||
tree->keytype = set->key->dtype;
|
||||
tree->keylen = set->key->len;
|
||||
- tree->datatype = set->datatype;
|
||||
- tree->datalen = set->datalen;
|
||||
+ tree->datatype = NULL;
|
||||
+ tree->datalen = 0;
|
||||
+ if (set->data) {
|
||||
+ tree->datatype = set->data->dtype;
|
||||
+ tree->datalen = set->data->len;
|
||||
+ }
|
||||
tree->byteorder = first->byteorder;
|
||||
tree->debug_mask = debug_mask;
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,120 @@
|
||||
From 785823a1f607a7bcd32d4cb42655422c223fcad5 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Mon, 7 Dec 2020 18:25:20 +0100
|
||||
Subject: [PATCH] evaluate: Perform set evaluation on implicitly declared
|
||||
(anonymous) sets
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1877022
|
||||
Upstream Status: nftables commit 7aa08d45031ec
|
||||
|
||||
commit 7aa08d45031ec7ce5dadb4979471d626367c09cd
|
||||
Author: Stefano Brivio <sbrivio@redhat.com>
|
||||
Date: Wed May 27 22:51:21 2020 +0200
|
||||
|
||||
evaluate: Perform set evaluation on implicitly declared (anonymous) sets
|
||||
|
||||
If a set is implicitly declared, set_evaluate() is not called as a
|
||||
result of cmd_evaluate_add(), because we're adding in fact something
|
||||
else (e.g. a rule). Expression-wise, evaluation still happens as the
|
||||
implicit set expression is eventually found in the tree and handled
|
||||
by expr_evaluate_set(), but context-wise evaluation (set_evaluate())
|
||||
is skipped, and this might be relevant instead.
|
||||
|
||||
This is visible in the reported case of an anonymous set including
|
||||
concatenated ranges:
|
||||
|
||||
# nft add rule t c ip saddr . tcp dport { 192.0.2.1 . 20-30 } accept
|
||||
BUG: invalid range expression type concat
|
||||
nft: expression.c:1160: range_expr_value_low: Assertion `0' failed.
|
||||
Aborted
|
||||
|
||||
because we reach do_add_set() without properly evaluated flags and
|
||||
set description, and eventually end up in expr_to_intervals(), which
|
||||
can't handle that expression.
|
||||
|
||||
Explicitly call set_evaluate() as we add anonymous sets into the
|
||||
context, and instruct the same function to:
|
||||
- skip expression-wise set evaluation if the set is anonymous, as
|
||||
that happens later anyway as part of the general tree evaluation
|
||||
- skip the insertion in the set cache, as it makes no sense to have
|
||||
sets that shouldn't be referenced there
|
||||
|
||||
For object maps, the allocation of the expression for set->data is
|
||||
already handled by set_evaluate(), so we can now drop that from
|
||||
stmt_evaluate_objref_map().
|
||||
|
||||
v2:
|
||||
- skip insertion of set in cache (Pablo Neira Ayuso)
|
||||
- drop double allocation of expression (and leak of the first
|
||||
one) for object maps (Pablo Neira Ayuso)
|
||||
|
||||
Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Reported-by: Phil Sutter <phil@nwl.cc>
|
||||
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
src/evaluate.c | 20 ++++++++++----------
|
||||
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||
index 578dcae..fc45cef 100644
|
||||
--- a/src/evaluate.c
|
||||
+++ b/src/evaluate.c
|
||||
@@ -75,6 +75,7 @@ static void key_fix_dtype_byteorder(struct expr *key)
|
||||
datatype_set(key, set_datatype_alloc(dtype, key->byteorder));
|
||||
}
|
||||
|
||||
+static int set_evaluate(struct eval_ctx *ctx, struct set *set);
|
||||
static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
|
||||
const char *name,
|
||||
struct expr *key,
|
||||
@@ -105,6 +106,8 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
|
||||
list_add_tail(&cmd->list, &ctx->cmd->list);
|
||||
}
|
||||
|
||||
+ set_evaluate(ctx, set);
|
||||
+
|
||||
return set_ref_expr_alloc(&expr->location, set);
|
||||
}
|
||||
|
||||
@@ -3171,12 +3174,6 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
|
||||
mappings = implicit_set_declaration(ctx, "__objmap%d",
|
||||
key, mappings);
|
||||
-
|
||||
- mappings->set->data = constant_expr_alloc(&netlink_location,
|
||||
- &string_type,
|
||||
- BYTEORDER_HOST_ENDIAN,
|
||||
- NFT_OBJ_MAXNAMELEN * BITS_PER_BYTE,
|
||||
- NULL);
|
||||
mappings->set->objtype = stmt->objref.type;
|
||||
|
||||
map->mappings = mappings;
|
||||
@@ -3381,6 +3378,13 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
||||
|
||||
}
|
||||
|
||||
+ /* Default timeout value implies timeout support */
|
||||
+ if (set->timeout)
|
||||
+ set->flags |= NFT_SET_TIMEOUT;
|
||||
+
|
||||
+ if (set_is_anonymous(set->flags))
|
||||
+ return 0;
|
||||
+
|
||||
ctx->set = set;
|
||||
if (set->init != NULL) {
|
||||
expr_set_context(&ctx->ectx, set->key->dtype, set->key->len);
|
||||
@@ -3392,10 +3396,6 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set)
|
||||
if (set_lookup(table, set->handle.set.name) == NULL)
|
||||
set_add_hash(set_get(set), table);
|
||||
|
||||
- /* Default timeout value implies timeout support */
|
||||
- if (set->timeout)
|
||||
- set->flags |= NFT_SET_TIMEOUT;
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,167 @@
|
||||
From 3193f74613b16a42d7784452ebf4d53ccd33b887 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Tue, 12 Jan 2021 10:34:35 +0100
|
||||
Subject: [PATCH] evaluate: missing datatype definition in
|
||||
implicit_set_declaration()
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1877022
|
||||
Upstream Status: nftables commit 54eb1e16cc478
|
||||
|
||||
commit 54eb1e16cc4787906fe8206858f0ea0bfb9c1209
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Sun Jun 7 15:23:21 2020 +0200
|
||||
|
||||
evaluate: missing datatype definition in implicit_set_declaration()
|
||||
|
||||
set->data from implicit_set_declaration(), otherwise, set_evaluation()
|
||||
bails out with:
|
||||
|
||||
# nft -f /etc/nftables/inet-filter.nft
|
||||
/etc/nftables/inet-filter.nft:8:32-54: Error: map definition does not specify
|
||||
mapping data type
|
||||
tcp dport vmap { 22 : jump ssh_input }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
/etc/nftables/inet-filter.nft:13:26-52: Error: map definition does not specify
|
||||
mapping data type
|
||||
iif vmap { "eth0" : jump wan_input }
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Add a test to cover this case.
|
||||
|
||||
Fixes: 7aa08d45031e ("evaluate: Perform set evaluation on implicitly declared (anonymous) sets")
|
||||
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=208093
|
||||
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
src/evaluate.c | 22 ++++++++++++----------
|
||||
tests/shell/testcases/maps/0009vmap_0 | 19 +++++++++++++++++++
|
||||
tests/shell/testcases/maps/dumps/0009vmap_0 | 13 +++++++++++++
|
||||
3 files changed, 44 insertions(+), 10 deletions(-)
|
||||
create mode 100755 tests/shell/testcases/maps/0009vmap_0
|
||||
create mode 100644 tests/shell/testcases/maps/dumps/0009vmap_0
|
||||
|
||||
diff --git a/src/evaluate.c b/src/evaluate.c
|
||||
index fc45cef..a966ed4 100644
|
||||
--- a/src/evaluate.c
|
||||
+++ b/src/evaluate.c
|
||||
@@ -79,6 +79,7 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set);
|
||||
static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
|
||||
const char *name,
|
||||
struct expr *key,
|
||||
+ struct expr *data,
|
||||
struct expr *expr)
|
||||
{
|
||||
struct cmd *cmd;
|
||||
@@ -92,6 +93,7 @@ static struct expr *implicit_set_declaration(struct eval_ctx *ctx,
|
||||
set->flags = NFT_SET_ANONYMOUS | expr->set_flags;
|
||||
set->handle.set.name = xstrdup(name);
|
||||
set->key = key;
|
||||
+ set->data = data;
|
||||
set->init = expr;
|
||||
set->automerge = set->flags & NFT_SET_INTERVAL;
|
||||
|
||||
@@ -1387,7 +1389,7 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
|
||||
struct expr_ctx ectx = ctx->ectx;
|
||||
struct expr *map = *expr, *mappings;
|
||||
const struct datatype *dtype;
|
||||
- struct expr *key;
|
||||
+ struct expr *key, *data;
|
||||
|
||||
expr_set_context(&ctx->ectx, NULL, 0);
|
||||
if (expr_evaluate(ctx, &map->map) < 0)
|
||||
@@ -1406,15 +1408,14 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr)
|
||||
ctx->ectx.byteorder,
|
||||
ctx->ectx.len, NULL);
|
||||
|
||||
+ dtype = set_datatype_alloc(ectx.dtype, ectx.byteorder);
|
||||
+ data = constant_expr_alloc(&netlink_location, dtype,
|
||||
+ dtype->byteorder, ectx.len, NULL);
|
||||
+
|
||||
mappings = implicit_set_declaration(ctx, "__map%d",
|
||||
- key,
|
||||
+ key, data,
|
||||
mappings);
|
||||
|
||||
- dtype = set_datatype_alloc(ectx.dtype, ectx.byteorder);
|
||||
-
|
||||
- mappings->set->data = constant_expr_alloc(&netlink_location,
|
||||
- dtype, dtype->byteorder,
|
||||
- ectx.len, NULL);
|
||||
if (ectx.len && mappings->set->data->len != ectx.len)
|
||||
BUG("%d vs %d\n", mappings->set->data->len, ectx.len);
|
||||
|
||||
@@ -1857,7 +1858,8 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
|
||||
case EXPR_SET:
|
||||
right = rel->right =
|
||||
implicit_set_declaration(ctx, "__set%d",
|
||||
- expr_get(left), right);
|
||||
+ expr_get(left), NULL,
|
||||
+ right);
|
||||
/* fall through */
|
||||
case EXPR_SET_REF:
|
||||
/* Data for range lookups needs to be in big endian order */
|
||||
@@ -2335,7 +2337,7 @@ static int stmt_evaluate_meter(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
set->set_flags |= NFT_SET_TIMEOUT;
|
||||
|
||||
setref = implicit_set_declaration(ctx, stmt->meter.name,
|
||||
- expr_get(key), set);
|
||||
+ expr_get(key), NULL, set);
|
||||
|
||||
setref->set->desc.size = stmt->meter.size;
|
||||
stmt->meter.set = setref;
|
||||
@@ -3173,7 +3175,7 @@ static int stmt_evaluate_objref_map(struct eval_ctx *ctx, struct stmt *stmt)
|
||||
ctx->ectx.len, NULL);
|
||||
|
||||
mappings = implicit_set_declaration(ctx, "__objmap%d",
|
||||
- key, mappings);
|
||||
+ key, NULL, mappings);
|
||||
mappings->set->objtype = stmt->objref.type;
|
||||
|
||||
map->mappings = mappings;
|
||||
diff --git a/tests/shell/testcases/maps/0009vmap_0 b/tests/shell/testcases/maps/0009vmap_0
|
||||
new file mode 100755
|
||||
index 0000000..7627c81
|
||||
--- /dev/null
|
||||
+++ b/tests/shell/testcases/maps/0009vmap_0
|
||||
@@ -0,0 +1,19 @@
|
||||
+#!/bin/bash
|
||||
+
|
||||
+set -e
|
||||
+
|
||||
+EXPECTED="table inet filter {
|
||||
+ chain ssh_input {
|
||||
+ }
|
||||
+
|
||||
+ chain wan_input {
|
||||
+ tcp dport vmap { 22 : jump ssh_input }
|
||||
+ }
|
||||
+
|
||||
+ chain prerouting {
|
||||
+ type filter hook prerouting priority -300; policy accept;
|
||||
+ iif vmap { "lo" : jump wan_input }
|
||||
+ }
|
||||
+}"
|
||||
+
|
||||
+$NFT -f - <<< "$EXPECTED"
|
||||
diff --git a/tests/shell/testcases/maps/dumps/0009vmap_0 b/tests/shell/testcases/maps/dumps/0009vmap_0
|
||||
new file mode 100644
|
||||
index 0000000..540a8af
|
||||
--- /dev/null
|
||||
+++ b/tests/shell/testcases/maps/dumps/0009vmap_0
|
||||
@@ -0,0 +1,13 @@
|
||||
+table inet filter {
|
||||
+ chain ssh_input {
|
||||
+ }
|
||||
+
|
||||
+ chain wan_input {
|
||||
+ tcp dport vmap { 22 : jump ssh_input }
|
||||
+ }
|
||||
+
|
||||
+ chain prerouting {
|
||||
+ type filter hook prerouting priority -300; policy accept;
|
||||
+ iif vmap { "lo" : jump wan_input }
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
1.8.3.1
|
||||
|
88
SOURCES/0035-mergesort-unbreak-listing-with-binops.patch
Normal file
88
SOURCES/0035-mergesort-unbreak-listing-with-binops.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From 9d67918643e7d17c433e82eb6cdb039cb103c50f Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Mon, 7 Dec 2020 18:26:24 +0100
|
||||
Subject: [PATCH] mergesort: unbreak listing with binops
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1891790
|
||||
Upstream Status: nftables commit 3926a3369bb5a
|
||||
|
||||
commit 3926a3369bb5ada5c0706dadcbcf938517822a35
|
||||
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Thu Aug 20 01:05:04 2020 +0200
|
||||
|
||||
mergesort: unbreak listing with binops
|
||||
|
||||
tcp flags == {syn, syn|ack}
|
||||
tcp flags & (fin|syn|rst|psh|ack|urg) == {ack, psh|ack, fin, fin|psh|ack}
|
||||
|
||||
results in:
|
||||
|
||||
BUG: Unknown expression binop
|
||||
nft: mergesort.c:47: expr_msort_cmp: Assertion `0' failed.
|
||||
Aborted (core dumped)
|
||||
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
src/mergesort.c | 2 ++
|
||||
tests/py/inet/tcp.t | 2 ++
|
||||
tests/py/inet/tcp.t.payload | 21 +++++++++++++++++++++
|
||||
3 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/src/mergesort.c b/src/mergesort.c
|
||||
index 649b780..02094b4 100644
|
||||
--- a/src/mergesort.c
|
||||
+++ b/src/mergesort.c
|
||||
@@ -43,6 +43,8 @@ static int expr_msort_cmp(const struct expr *e1, const struct expr *e2)
|
||||
return concat_expr_msort_cmp(e1, e2);
|
||||
case EXPR_MAPPING:
|
||||
return expr_msort_cmp(e1->left, e2->left);
|
||||
+ case EXPR_BINOP:
|
||||
+ return expr_msort_cmp(e1->left, e2->left);
|
||||
default:
|
||||
BUG("Unknown expression %s\n", expr_name(e1));
|
||||
}
|
||||
diff --git a/tests/py/inet/tcp.t b/tests/py/inet/tcp.t
|
||||
index e0a83e2..29f06f5 100644
|
||||
--- a/tests/py/inet/tcp.t
|
||||
+++ b/tests/py/inet/tcp.t
|
||||
@@ -79,6 +79,8 @@ tcp flags != cwr;ok
|
||||
tcp flags == syn;ok
|
||||
tcp flags & (syn|fin) == (syn|fin);ok;tcp flags & (fin | syn) == fin | syn
|
||||
tcp flags & (fin | syn | rst | psh | ack | urg | ecn | cwr) == fin | syn | rst | psh | ack | urg | ecn | cwr;ok;tcp flags == 0xff
|
||||
+tcp flags { syn, syn | ack };ok
|
||||
+tcp flags & (fin | syn | rst | psh | ack | urg) == { fin, ack, psh | ack, fin | psh | ack };ok
|
||||
|
||||
tcp window 22222;ok
|
||||
tcp window 22;ok
|
||||
diff --git a/tests/py/inet/tcp.t.payload b/tests/py/inet/tcp.t.payload
|
||||
index 55f1bc2..076e562 100644
|
||||
--- a/tests/py/inet/tcp.t.payload
|
||||
+++ b/tests/py/inet/tcp.t.payload
|
||||
@@ -680,3 +680,24 @@ inet test-inet input
|
||||
[ bitwise reg 1 = (reg=1 & 0x000000f0 ) ^ 0x00000000 ]
|
||||
[ cmp eq reg 1 0x00000080 ]
|
||||
|
||||
+# tcp flags & (fin | syn | rst | psh | ack | urg) == { fin, ack, psh | ack, fin | psh | ack }
|
||||
+__set%d test-inet 3
|
||||
+__set%d test-inet 0
|
||||
+ element 00000001 : 0 [end] element 00000010 : 0 [end] element 00000018 : 0 [end] element 00000019 : 0 [end]
|
||||
+ip
|
||||
+ [ meta load l4proto => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ transport header + 13 => reg 1 ]
|
||||
+ [ bitwise reg 1 = (reg=1 & 0x0000003f ) ^ 0x00000000 ]
|
||||
+ [ lookup reg 1 set __set%d ]
|
||||
+
|
||||
+# tcp flags { syn, syn | ack }
|
||||
+__set%d test-inet 3
|
||||
+__set%d test-inet 0
|
||||
+ element 00000002 : 0 [end] element 00000012 : 0 [end]
|
||||
+inet
|
||||
+ [ meta load l4proto => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000006 ]
|
||||
+ [ payload load 1b @ transport header + 13 => reg 1 ]
|
||||
+ [ lookup reg 1 set __set%d ]
|
||||
+
|
||||
--
|
||||
1.8.3.1
|
||||
|
134
SOURCES/0036-proto-add-sctp-crc32-checksum-fixup.patch
Normal file
134
SOURCES/0036-proto-add-sctp-crc32-checksum-fixup.patch
Normal file
@ -0,0 +1,134 @@
|
||||
From 876a1202351264f6d3b105258f10bde693870bd4 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Mon, 7 Dec 2020 18:27:16 +0100
|
||||
Subject: [PATCH] proto: add sctp crc32 checksum fixup
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1895804
|
||||
Upstream Status: nftables commit 09a3b2ba0c822
|
||||
|
||||
commit 09a3b2ba0c8228d1c6bf0f030cae97addb397351
|
||||
Author: Florian Westphal <fw@strlen.de>
|
||||
Date: Tue Oct 6 23:16:32 2020 +0200
|
||||
|
||||
proto: add sctp crc32 checksum fixup
|
||||
|
||||
Stateless SCTP header mangling doesn't work reliably.
|
||||
This tells the kernel to update the checksum field using
|
||||
the sctp crc32 algorithm.
|
||||
|
||||
Note that this needs additional kernel support to work.
|
||||
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
---
|
||||
include/linux/netfilter/nf_tables.h | 2 ++
|
||||
include/proto.h | 1 +
|
||||
src/netlink_linearize.c | 2 +-
|
||||
src/proto.c | 8 ++++++++
|
||||
4 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
|
||||
index 9b54a86..1328b8e 100644
|
||||
--- a/include/linux/netfilter/nf_tables.h
|
||||
+++ b/include/linux/netfilter/nf_tables.h
|
||||
@@ -707,10 +707,12 @@ enum nft_payload_bases {
|
||||
*
|
||||
* @NFT_PAYLOAD_CSUM_NONE: no checksumming
|
||||
* @NFT_PAYLOAD_CSUM_INET: internet checksum (RFC 791)
|
||||
+ * @NFT_PAYLOAD_CSUM_SCTP: CRC-32c, for use in SCTP header (RFC 3309)
|
||||
*/
|
||||
enum nft_payload_csum_types {
|
||||
NFT_PAYLOAD_CSUM_NONE,
|
||||
NFT_PAYLOAD_CSUM_INET,
|
||||
+ NFT_PAYLOAD_CSUM_SCTP,
|
||||
};
|
||||
|
||||
enum nft_payload_csum_flags {
|
||||
diff --git a/include/proto.h b/include/proto.h
|
||||
index fab48c1..436cbe3 100644
|
||||
--- a/include/proto.h
|
||||
+++ b/include/proto.h
|
||||
@@ -78,6 +78,7 @@ struct proto_hdr_template {
|
||||
struct proto_desc {
|
||||
const char *name;
|
||||
enum proto_bases base;
|
||||
+ enum nft_payload_csum_types checksum_type;
|
||||
unsigned int checksum_key;
|
||||
unsigned int protocol_key;
|
||||
unsigned int length;
|
||||
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
|
||||
index cb1b7fe..606d97a 100644
|
||||
--- a/src/netlink_linearize.c
|
||||
+++ b/src/netlink_linearize.c
|
||||
@@ -937,7 +937,7 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx,
|
||||
expr->len / BITS_PER_BYTE);
|
||||
if (csum_off) {
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_TYPE,
|
||||
- NFT_PAYLOAD_CSUM_INET);
|
||||
+ desc->checksum_type);
|
||||
nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_OFFSET,
|
||||
csum_off / BITS_PER_BYTE);
|
||||
}
|
||||
diff --git a/src/proto.c b/src/proto.c
|
||||
index 40ce590..8360abf 100644
|
||||
--- a/src/proto.c
|
||||
+++ b/src/proto.c
|
||||
@@ -345,6 +345,7 @@ const struct proto_desc proto_icmp = {
|
||||
.name = "icmp",
|
||||
.base = PROTO_BASE_TRANSPORT_HDR,
|
||||
.checksum_key = ICMPHDR_CHECKSUM,
|
||||
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||||
.templates = {
|
||||
[ICMPHDR_TYPE] = ICMPHDR_TYPE("type", &icmp_type_type, type),
|
||||
[ICMPHDR_CODE] = ICMPHDR_TYPE("code", &icmp_code_type, code),
|
||||
@@ -397,6 +398,7 @@ const struct proto_desc proto_igmp = {
|
||||
.name = "igmp",
|
||||
.base = PROTO_BASE_TRANSPORT_HDR,
|
||||
.checksum_key = IGMPHDR_CHECKSUM,
|
||||
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||||
.templates = {
|
||||
[IGMPHDR_TYPE] = IGMPHDR_TYPE("type", &igmp_type_type, igmp_type),
|
||||
[IGMPHDR_MRT] = IGMPHDR_FIELD("mrt", igmp_code),
|
||||
@@ -417,6 +419,7 @@ const struct proto_desc proto_udp = {
|
||||
.name = "udp",
|
||||
.base = PROTO_BASE_TRANSPORT_HDR,
|
||||
.checksum_key = UDPHDR_CHECKSUM,
|
||||
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||||
.templates = {
|
||||
[UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source),
|
||||
[UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest),
|
||||
@@ -474,6 +477,7 @@ const struct proto_desc proto_tcp = {
|
||||
.name = "tcp",
|
||||
.base = PROTO_BASE_TRANSPORT_HDR,
|
||||
.checksum_key = TCPHDR_CHECKSUM,
|
||||
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||||
.templates = {
|
||||
[TCPHDR_SPORT] = INET_SERVICE("sport", struct tcphdr, source),
|
||||
[TCPHDR_DPORT] = INET_SERVICE("dport", struct tcphdr, dest),
|
||||
@@ -553,6 +557,8 @@ const struct proto_desc proto_dccp = {
|
||||
const struct proto_desc proto_sctp = {
|
||||
.name = "sctp",
|
||||
.base = PROTO_BASE_TRANSPORT_HDR,
|
||||
+ .checksum_key = SCTPHDR_CHECKSUM,
|
||||
+ .checksum_type = NFT_PAYLOAD_CSUM_SCTP,
|
||||
.templates = {
|
||||
[SCTPHDR_SPORT] = INET_SERVICE("sport", struct sctphdr, source),
|
||||
[SCTPHDR_DPORT] = INET_SERVICE("dport", struct sctphdr, dest),
|
||||
@@ -650,6 +656,7 @@ const struct proto_desc proto_ip = {
|
||||
.name = "ip",
|
||||
.base = PROTO_BASE_NETWORK_HDR,
|
||||
.checksum_key = IPHDR_CHECKSUM,
|
||||
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||||
.protocols = {
|
||||
PROTO_LINK(IPPROTO_ICMP, &proto_icmp),
|
||||
PROTO_LINK(IPPROTO_IGMP, &proto_igmp),
|
||||
@@ -746,6 +753,7 @@ const struct proto_desc proto_icmp6 = {
|
||||
.name = "icmpv6",
|
||||
.base = PROTO_BASE_TRANSPORT_HDR,
|
||||
.checksum_key = ICMP6HDR_CHECKSUM,
|
||||
+ .checksum_type = NFT_PAYLOAD_CSUM_INET,
|
||||
.templates = {
|
||||
[ICMP6HDR_TYPE] = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type),
|
||||
[ICMP6HDR_CODE] = ICMP6HDR_TYPE("code", &icmpv6_code_type, icmp6_code),
|
||||
--
|
||||
1.8.3.1
|
||||
|
233
SOURCES/0037-proto-Fix-ARP-header-field-ordering.patch
Normal file
233
SOURCES/0037-proto-Fix-ARP-header-field-ordering.patch
Normal file
@ -0,0 +1,233 @@
|
||||
From 70dc225b23708c6ac96e2895488f3c6dea9e201d Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Mon, 7 Dec 2020 18:28:27 +0100
|
||||
Subject: [PATCH] proto: Fix ARP header field ordering
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1896334
|
||||
Upstream Status: nftables commit f751753f92ea7
|
||||
|
||||
commit f751753f92ea76f582f7d5d1fef8b4d5677ba589
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Tue Nov 10 13:07:49 2020 +0100
|
||||
|
||||
proto: Fix ARP header field ordering
|
||||
|
||||
In ARP header, destination ether address sits between source IP and
|
||||
destination IP addresses. Enum arp_hdr_fields had this wrong, which
|
||||
in turn caused wrong ordering of entries in proto_arp->templates. When
|
||||
expanding a combined payload expression, code assumes that template
|
||||
entries are ordered by header offset, therefore the destination ether
|
||||
address match was printed as raw if an earlier field was matched as
|
||||
well:
|
||||
|
||||
| arp saddr ip 192.168.1.1 arp daddr ether 3e:d1:3f:d6:12:0b
|
||||
|
||||
was printed as:
|
||||
|
||||
| arp saddr ip 192.168.1.1 @nh,144,48 69068440080907
|
||||
|
||||
Note: Although strictly not necessary, reorder fields in
|
||||
proto_arp->templates as well to match their actual ordering, just to
|
||||
avoid confusion.
|
||||
|
||||
Fixes: 4b0f2a712b579 ("src: support for arp sender and target ethernet and IPv4 addresses")
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
---
|
||||
include/proto.h | 2 +-
|
||||
src/proto.c | 2 +-
|
||||
tests/py/arp/arp.t | 3 +++
|
||||
tests/py/arp/arp.t.json | 56 +++++++++++++++++++++++++++++++++++++++
|
||||
tests/py/arp/arp.t.json.output | 28 ++++++++++++++++++++
|
||||
tests/py/arp/arp.t.payload | 10 +++++++
|
||||
tests/py/arp/arp.t.payload.netdev | 14 ++++++++++
|
||||
7 files changed, 113 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/proto.h b/include/proto.h
|
||||
index 436cbe3..5a50059 100644
|
||||
--- a/include/proto.h
|
||||
+++ b/include/proto.h
|
||||
@@ -184,8 +184,8 @@ enum arp_hdr_fields {
|
||||
ARPHDR_PLN,
|
||||
ARPHDR_OP,
|
||||
ARPHDR_SADDR_ETHER,
|
||||
- ARPHDR_DADDR_ETHER,
|
||||
ARPHDR_SADDR_IP,
|
||||
+ ARPHDR_DADDR_ETHER,
|
||||
ARPHDR_DADDR_IP,
|
||||
};
|
||||
|
||||
diff --git a/src/proto.c b/src/proto.c
|
||||
index 8360abf..49c8c92 100644
|
||||
--- a/src/proto.c
|
||||
+++ b/src/proto.c
|
||||
@@ -908,8 +908,8 @@ const struct proto_desc proto_arp = {
|
||||
[ARPHDR_PLN] = ARPHDR_FIELD("plen", plen),
|
||||
[ARPHDR_OP] = ARPHDR_TYPE("operation", &arpop_type, oper),
|
||||
[ARPHDR_SADDR_ETHER] = ARPHDR_TYPE("saddr ether", ðeraddr_type, sha),
|
||||
- [ARPHDR_DADDR_ETHER] = ARPHDR_TYPE("daddr ether", ðeraddr_type, tha),
|
||||
[ARPHDR_SADDR_IP] = ARPHDR_TYPE("saddr ip", &ipaddr_type, spa),
|
||||
+ [ARPHDR_DADDR_ETHER] = ARPHDR_TYPE("daddr ether", ðeraddr_type, tha),
|
||||
[ARPHDR_DADDR_IP] = ARPHDR_TYPE("daddr ip", &ipaddr_type, tpa),
|
||||
},
|
||||
.format = {
|
||||
diff --git a/tests/py/arp/arp.t b/tests/py/arp/arp.t
|
||||
index 2540c0a..109d01d 100644
|
||||
--- a/tests/py/arp/arp.t
|
||||
+++ b/tests/py/arp/arp.t
|
||||
@@ -61,4 +61,7 @@ arp daddr ip 4.3.2.1;ok
|
||||
arp saddr ether aa:bb:cc:aa:bb:cc;ok
|
||||
arp daddr ether aa:bb:cc:aa:bb:cc;ok
|
||||
|
||||
+arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee;ok
|
||||
+arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1;ok;arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
|
||||
+
|
||||
meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566;ok;iifname "invalid" arp htype 1 arp ptype ip arp hlen 6 arp plen 4 arp daddr ip 192.168.143.16 arp daddr ether set 11:22:33:44:55:66
|
||||
diff --git a/tests/py/arp/arp.t.json b/tests/py/arp/arp.t.json
|
||||
index 5f2f6cd..8508c17 100644
|
||||
--- a/tests/py/arp/arp.t.json
|
||||
+++ b/tests/py/arp/arp.t.json
|
||||
@@ -901,6 +901,62 @@
|
||||
}
|
||||
]
|
||||
|
||||
+# arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
|
||||
+[
|
||||
+ {
|
||||
+ "match": {
|
||||
+ "left": {
|
||||
+ "payload": {
|
||||
+ "field": "saddr ip",
|
||||
+ "protocol": "arp"
|
||||
+ }
|
||||
+ },
|
||||
+ "op": "==",
|
||||
+ "right": "192.168.1.1"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "match": {
|
||||
+ "left": {
|
||||
+ "payload": {
|
||||
+ "field": "daddr ether",
|
||||
+ "protocol": "arp"
|
||||
+ }
|
||||
+ },
|
||||
+ "op": "==",
|
||||
+ "right": "fe:ed:00:c0:ff:ee"
|
||||
+ }
|
||||
+ }
|
||||
+]
|
||||
+
|
||||
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
|
||||
+[
|
||||
+ {
|
||||
+ "match": {
|
||||
+ "left": {
|
||||
+ "payload": {
|
||||
+ "field": "daddr ether",
|
||||
+ "protocol": "arp"
|
||||
+ }
|
||||
+ },
|
||||
+ "op": "==",
|
||||
+ "right": "fe:ed:00:c0:ff:ee"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "match": {
|
||||
+ "left": {
|
||||
+ "payload": {
|
||||
+ "field": "saddr ip",
|
||||
+ "protocol": "arp"
|
||||
+ }
|
||||
+ },
|
||||
+ "op": "==",
|
||||
+ "right": "192.168.1.1"
|
||||
+ }
|
||||
+ }
|
||||
+]
|
||||
+
|
||||
# meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566
|
||||
[
|
||||
{
|
||||
diff --git a/tests/py/arp/arp.t.json.output b/tests/py/arp/arp.t.json.output
|
||||
index b8507bf..afa75b2 100644
|
||||
--- a/tests/py/arp/arp.t.json.output
|
||||
+++ b/tests/py/arp/arp.t.json.output
|
||||
@@ -66,6 +66,34 @@
|
||||
}
|
||||
]
|
||||
|
||||
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
|
||||
+[
|
||||
+ {
|
||||
+ "match": {
|
||||
+ "left": {
|
||||
+ "payload": {
|
||||
+ "field": "saddr ip",
|
||||
+ "protocol": "arp"
|
||||
+ }
|
||||
+ },
|
||||
+ "op": "==",
|
||||
+ "right": "192.168.1.1"
|
||||
+ }
|
||||
+ },
|
||||
+ {
|
||||
+ "match": {
|
||||
+ "left": {
|
||||
+ "payload": {
|
||||
+ "field": "daddr ether",
|
||||
+ "protocol": "arp"
|
||||
+ }
|
||||
+ },
|
||||
+ "op": "==",
|
||||
+ "right": "fe:ed:00:c0:ff:ee"
|
||||
+ }
|
||||
+ }
|
||||
+]
|
||||
+
|
||||
# meta iifname "invalid" arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566
|
||||
[
|
||||
{
|
||||
diff --git a/tests/py/arp/arp.t.payload b/tests/py/arp/arp.t.payload
|
||||
index 52c9932..f819853 100644
|
||||
--- a/tests/py/arp/arp.t.payload
|
||||
+++ b/tests/py/arp/arp.t.payload
|
||||
@@ -307,3 +307,13 @@ arp test-arp input
|
||||
[ payload load 6b @ network header + 18 => reg 1 ]
|
||||
[ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
|
||||
|
||||
+# arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
|
||||
+arp
|
||||
+ [ payload load 10b @ network header + 14 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
|
||||
+
|
||||
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
|
||||
+arp
|
||||
+ [ payload load 10b @ network header + 14 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
|
||||
+
|
||||
diff --git a/tests/py/arp/arp.t.payload.netdev b/tests/py/arp/arp.t.payload.netdev
|
||||
index 667691f..f57610c 100644
|
||||
--- a/tests/py/arp/arp.t.payload.netdev
|
||||
+++ b/tests/py/arp/arp.t.payload.netdev
|
||||
@@ -409,3 +409,17 @@ netdev test-netdev ingress
|
||||
[ payload load 6b @ network header + 18 => reg 1 ]
|
||||
[ cmp eq reg 1 0xaaccbbaa 0x0000ccbb ]
|
||||
|
||||
+# arp saddr ip 192.168.1.1 arp daddr ether fe:ed:00:c0:ff:ee
|
||||
+netdev
|
||||
+ [ meta load protocol => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000608 ]
|
||||
+ [ payload load 10b @ network header + 14 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
|
||||
+
|
||||
+# arp daddr ether fe:ed:00:c0:ff:ee arp saddr ip 192.168.1.1
|
||||
+netdev
|
||||
+ [ meta load protocol => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x00000608 ]
|
||||
+ [ payload load 10b @ network header + 14 => reg 1 ]
|
||||
+ [ cmp eq reg 1 0x0101a8c0 0xc000edfe 0x0000eeff ]
|
||||
+
|
||||
--
|
||||
1.8.3.1
|
||||
|
108
SOURCES/0038-json-echo-Speedup-seqnum_to_json.patch
Normal file
108
SOURCES/0038-json-echo-Speedup-seqnum_to_json.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 26c4f15080663a12006abf8539ebf28bb223e6d9 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Mon, 7 Dec 2020 18:29:15 +0100
|
||||
Subject: [PATCH] json: echo: Speedup seqnum_to_json()
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1900565
|
||||
Upstream Status: nftables commit 389a0e1edc89a
|
||||
|
||||
commit 389a0e1edc89a4048a272e569d3349b1d43bc567
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Fri Nov 20 20:01:59 2020 +0100
|
||||
|
||||
json: echo: Speedup seqnum_to_json()
|
||||
|
||||
Derek Dai reports:
|
||||
"If there are a lot of command in JSON node, seqnum_to_json() will slow
|
||||
down application (eg: firewalld) dramatically since it iterate whole
|
||||
command list every time."
|
||||
|
||||
He sent a patch implementing a lookup table, but we can do better: Speed
|
||||
this up by introducing a hash table to store the struct json_cmd_assoc
|
||||
objects in, taking their netlink sequence number as key.
|
||||
|
||||
Quickly tested restoring a ruleset containing about 19k rules:
|
||||
|
||||
| # time ./before/nft -jeaf large_ruleset.json >/dev/null
|
||||
| 4.85user 0.47system 0:05.48elapsed 97%CPU (0avgtext+0avgdata 69732maxresident)k
|
||||
| 0inputs+0outputs (15major+16937minor)pagefaults 0swaps
|
||||
|
||||
| # time ./after/nft -jeaf large_ruleset.json >/dev/null
|
||||
| 0.18user 0.44system 0:00.70elapsed 89%CPU (0avgtext+0avgdata 68484maxresident)k
|
||||
| 0inputs+0outputs (15major+16645minor)pagefaults 0swaps
|
||||
|
||||
Bugzilla: https://bugzilla.netfilter.org/show_bug.cgi?id=1479
|
||||
Reported-by: Derek Dai <daiderek@gmail.com>
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
---
|
||||
src/parser_json.c | 28 ++++++++++++++++++----------
|
||||
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||||
index ddc694f..107dc38 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -3646,42 +3646,50 @@ static int json_verify_metainfo(struct json_ctx *ctx, json_t *root)
|
||||
}
|
||||
|
||||
struct json_cmd_assoc {
|
||||
- struct json_cmd_assoc *next;
|
||||
+ struct hlist_node hnode;
|
||||
const struct cmd *cmd;
|
||||
json_t *json;
|
||||
};
|
||||
|
||||
-static struct json_cmd_assoc *json_cmd_list = NULL;
|
||||
+#define CMD_ASSOC_HSIZE 512
|
||||
+static struct hlist_head json_cmd_assoc_hash[CMD_ASSOC_HSIZE];
|
||||
|
||||
static void json_cmd_assoc_free(void)
|
||||
{
|
||||
struct json_cmd_assoc *cur;
|
||||
+ struct hlist_node *pos, *n;
|
||||
+ int i;
|
||||
|
||||
- while (json_cmd_list) {
|
||||
- cur = json_cmd_list;
|
||||
- json_cmd_list = cur->next;
|
||||
- free(cur);
|
||||
+ for (i = 0; i < CMD_ASSOC_HSIZE; i++) {
|
||||
+ hlist_for_each_entry_safe(cur, pos, n,
|
||||
+ &json_cmd_assoc_hash[i], hnode)
|
||||
+ free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
static void json_cmd_assoc_add(json_t *json, const struct cmd *cmd)
|
||||
{
|
||||
struct json_cmd_assoc *new = xzalloc(sizeof *new);
|
||||
+ int key = cmd->seqnum % CMD_ASSOC_HSIZE;
|
||||
|
||||
- new->next = json_cmd_list;
|
||||
new->json = json;
|
||||
new->cmd = cmd;
|
||||
- json_cmd_list = new;
|
||||
+
|
||||
+ hlist_add_head(&new->hnode, &json_cmd_assoc_hash[key]);
|
||||
}
|
||||
|
||||
static json_t *seqnum_to_json(const uint32_t seqnum)
|
||||
{
|
||||
- const struct json_cmd_assoc *cur;
|
||||
+ int key = seqnum % CMD_ASSOC_HSIZE;
|
||||
+ struct json_cmd_assoc *cur;
|
||||
+ struct hlist_node *n;
|
||||
|
||||
- for (cur = json_cmd_list; cur; cur = cur->next) {
|
||||
+
|
||||
+ hlist_for_each_entry(cur, n, &json_cmd_assoc_hash[key], hnode) {
|
||||
if (cur->cmd->seqnum == seqnum)
|
||||
return cur->json;
|
||||
}
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
116
SOURCES/0039-json-Fix-seqnum_to_json-functionality.patch
Normal file
116
SOURCES/0039-json-Fix-seqnum_to_json-functionality.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From 0dcfa1b0211fa50201d51d0f52869a8e2d93ba76 Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Mon, 7 Dec 2020 18:29:15 +0100
|
||||
Subject: [PATCH] json: Fix seqnum_to_json() functionality
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1900565
|
||||
Upstream Status: nftables commit 299ec575faa6b
|
||||
|
||||
commit 299ec575faa6b070940b483dc517ecd883b9f1a4
|
||||
Author: Phil Sutter <phil@nwl.cc>
|
||||
Date: Wed Dec 2 23:07:11 2020 +0100
|
||||
|
||||
json: Fix seqnum_to_json() functionality
|
||||
|
||||
Introduction of json_cmd_assoc_hash missed that by the time the hash
|
||||
table insert happens, the struct cmd object's 'seqnum' field which is
|
||||
used as key is not initialized yet. This doesn't happen until
|
||||
nft_netlink() prepares the batch object which records the lowest seqnum.
|
||||
Therefore push all json_cmd_assoc objects into a temporary list until
|
||||
the first lookup happens. At this time, all referenced cmd objects have
|
||||
their seqnum set and the list entries can be moved into the hash table
|
||||
for fast lookups.
|
||||
|
||||
To expose such problems in the future, make json_events_cb() emit an
|
||||
error message if the passed message has a handle but no assoc entry is
|
||||
found for its seqnum.
|
||||
|
||||
Fixes: 389a0e1edc89a ("json: echo: Speedup seqnum_to_json()")
|
||||
Cc: Derek Dai <daiderek@gmail.com>
|
||||
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
||||
---
|
||||
src/parser_json.c | 27 +++++++++++++++++++++++----
|
||||
1 file changed, 23 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||||
index 107dc38..785f0e7 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -3646,6 +3646,7 @@ static int json_verify_metainfo(struct json_ctx *ctx, json_t *root)
|
||||
}
|
||||
|
||||
struct json_cmd_assoc {
|
||||
+ struct json_cmd_assoc *next;
|
||||
struct hlist_node hnode;
|
||||
const struct cmd *cmd;
|
||||
json_t *json;
|
||||
@@ -3653,6 +3654,7 @@ struct json_cmd_assoc {
|
||||
|
||||
#define CMD_ASSOC_HSIZE 512
|
||||
static struct hlist_head json_cmd_assoc_hash[CMD_ASSOC_HSIZE];
|
||||
+static struct json_cmd_assoc *json_cmd_assoc_list;
|
||||
|
||||
static void json_cmd_assoc_free(void)
|
||||
{
|
||||
@@ -3660,6 +3662,12 @@ static void json_cmd_assoc_free(void)
|
||||
struct hlist_node *pos, *n;
|
||||
int i;
|
||||
|
||||
+ while (json_cmd_assoc_list) {
|
||||
+ cur = json_cmd_assoc_list->next;
|
||||
+ free(json_cmd_assoc_list);
|
||||
+ json_cmd_assoc_list = cur;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < CMD_ASSOC_HSIZE; i++) {
|
||||
hlist_for_each_entry_safe(cur, pos, n,
|
||||
&json_cmd_assoc_hash[i], hnode)
|
||||
@@ -3670,21 +3678,29 @@ static void json_cmd_assoc_free(void)
|
||||
static void json_cmd_assoc_add(json_t *json, const struct cmd *cmd)
|
||||
{
|
||||
struct json_cmd_assoc *new = xzalloc(sizeof *new);
|
||||
- int key = cmd->seqnum % CMD_ASSOC_HSIZE;
|
||||
|
||||
new->json = json;
|
||||
new->cmd = cmd;
|
||||
+ new->next = json_cmd_assoc_list;
|
||||
|
||||
- hlist_add_head(&new->hnode, &json_cmd_assoc_hash[key]);
|
||||
+ json_cmd_assoc_list = new;
|
||||
}
|
||||
|
||||
static json_t *seqnum_to_json(const uint32_t seqnum)
|
||||
{
|
||||
- int key = seqnum % CMD_ASSOC_HSIZE;
|
||||
struct json_cmd_assoc *cur;
|
||||
struct hlist_node *n;
|
||||
+ int key;
|
||||
|
||||
+ while (json_cmd_assoc_list) {
|
||||
+ cur = json_cmd_assoc_list;
|
||||
+ json_cmd_assoc_list = cur->next;
|
||||
|
||||
+ key = cur->cmd->seqnum % CMD_ASSOC_HSIZE;
|
||||
+ hlist_add_head(&cur->hnode, &json_cmd_assoc_hash[key]);
|
||||
+ }
|
||||
+
|
||||
+ key = seqnum % CMD_ASSOC_HSIZE;
|
||||
hlist_for_each_entry(cur, n, &json_cmd_assoc_hash[key], hnode) {
|
||||
if (cur->cmd->seqnum == seqnum)
|
||||
return cur->json;
|
||||
@@ -3865,8 +3881,11 @@ int json_events_cb(const struct nlmsghdr *nlh, struct netlink_mon_handler *monh)
|
||||
return MNL_CB_OK;
|
||||
|
||||
json = seqnum_to_json(nlh->nlmsg_seq);
|
||||
- if (!json)
|
||||
+ if (!json) {
|
||||
+ json_echo_error(monh, "No JSON command found with seqnum %lu\n",
|
||||
+ nlh->nlmsg_seq);
|
||||
return MNL_CB_OK;
|
||||
+ }
|
||||
|
||||
tmp = json_object_get(json, "add");
|
||||
if (!tmp)
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -0,0 +1,47 @@
|
||||
From b7964157c40066f09411ac52547acb07d1966aee Mon Sep 17 00:00:00 2001
|
||||
From: Phil Sutter <psutter@redhat.com>
|
||||
Date: Tue, 12 Jan 2021 15:49:43 +0100
|
||||
Subject: [PATCH] json: don't leave dangling pointers on hlist
|
||||
|
||||
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1900565
|
||||
Upstream Status: nftables commit 48917d876d51c
|
||||
|
||||
commit 48917d876d51cd6ba5bff07172acef05c9e12474
|
||||
Author: Florian Westphal <fw@strlen.de>
|
||||
Date: Mon Dec 14 16:53:29 2020 +0100
|
||||
|
||||
json: don't leave dangling pointers on hlist
|
||||
|
||||
unshare -n tests/json_echo/run-test.py
|
||||
[..]
|
||||
Adding chain c
|
||||
free(): double free detected in tcache 2
|
||||
Aborted (core dumped)
|
||||
|
||||
The element must be deleted from the hlist prior to freeing it.
|
||||
|
||||
Fixes: 389a0e1edc89a ("json: echo: Speedup seqnum_to_json()")
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
---
|
||||
src/parser_json.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/parser_json.c b/src/parser_json.c
|
||||
index 785f0e7..986f128 100644
|
||||
--- a/src/parser_json.c
|
||||
+++ b/src/parser_json.c
|
||||
@@ -3670,8 +3670,10 @@ static void json_cmd_assoc_free(void)
|
||||
|
||||
for (i = 0; i < CMD_ASSOC_HSIZE; i++) {
|
||||
hlist_for_each_entry_safe(cur, pos, n,
|
||||
- &json_cmd_assoc_hash[i], hnode)
|
||||
+ &json_cmd_assoc_hash[i], hnode) {
|
||||
+ hlist_del(&cur->hnode);
|
||||
free(cur);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
@ -1,5 +1,5 @@
|
||||
%define rpmversion 0.9.3
|
||||
%define specrelease 14%{?dist}
|
||||
%define specrelease 17%{?dist}
|
||||
|
||||
Name: nftables
|
||||
Version: %{rpmversion}
|
||||
@ -41,6 +41,22 @@ 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
|
||||
Patch25: 0025-segtree-Fix-missing-expires-value-in-prefixes.patch
|
||||
Patch26: 0026-segtree-Use-expr_clone-in-get_set_interval_.patch
|
||||
Patch27: 0027-segtree-Merge-get_set_interval_find-and-get_set_inte.patch
|
||||
Patch28: 0028-tests-0034get_element_0-do-not-discard-stderr.patch
|
||||
Patch29: 0029-segtree-Fix-get-element-command-with-prefixes.patch
|
||||
Patch30: 0030-include-Resync-nf_tables.h-cache-copy.patch
|
||||
Patch31: 0031-src-Set-NFT_SET_CONCAT-flag-for-sets-with-concatenat.patch
|
||||
Patch32: 0032-src-store-expr-not-dtype-to-track-data-in-sets.patch
|
||||
Patch33: 0033-evaluate-Perform-set-evaluation-on-implicitly-declar.patch
|
||||
Patch34: 0034-evaluate-missing-datatype-definition-in-implicit_set.patch
|
||||
Patch35: 0035-mergesort-unbreak-listing-with-binops.patch
|
||||
Patch36: 0036-proto-add-sctp-crc32-checksum-fixup.patch
|
||||
Patch37: 0037-proto-Fix-ARP-header-field-ordering.patch
|
||||
Patch38: 0038-json-echo-Speedup-seqnum_to_json.patch
|
||||
Patch39: 0039-json-Fix-seqnum_to_json-functionality.patch
|
||||
Patch40: 0040-json-don-t-leave-dangling-pointers-on-hlist.patch
|
||||
|
||||
BuildRequires: autogen
|
||||
BuildRequires: autoconf
|
||||
@ -157,6 +173,28 @@ touch -r %{SOURCE2} $RPM_BUILD_ROOT/%{python3_sitelib}/nftables/nftables.py
|
||||
%{python3_sitelib}/nftables/
|
||||
|
||||
%changelog
|
||||
* Tue Jan 12 2021 Phil Sutter <psutter@redhat.com> [0.9.3-17.el8]
|
||||
- json: don't leave dangling pointers on hlist (Phil Sutter) [1900565]
|
||||
- json: Fix seqnum_to_json() functionality (Phil Sutter) [1900565]
|
||||
- json: echo: Speedup seqnum_to_json() (Phil Sutter) [1900565]
|
||||
- proto: Fix ARP header field ordering (Phil Sutter) [1896334]
|
||||
- proto: add sctp crc32 checksum fixup (Phil Sutter) [1895804]
|
||||
- mergesort: unbreak listing with binops (Phil Sutter) [1891790]
|
||||
- evaluate: missing datatype definition in implicit_set_declaration() (Phil Sutter) [1877022]
|
||||
- evaluate: Perform set evaluation on implicitly declared (anonymous) sets (Phil Sutter) [1877022]
|
||||
- src: store expr, not dtype to track data in sets (Phil Sutter) [1877022]
|
||||
|
||||
* Sat Aug 08 2020 Phil Sutter <psutter@redhat.com> [0.9.3-16.el8]
|
||||
- src: Set NFT_SET_CONCAT flag for sets with concatenated ranges (Phil Sutter) [1820684]
|
||||
- include: Resync nf_tables.h cache copy (Phil Sutter) [1820684]
|
||||
|
||||
* Tue Jun 30 2020 Phil Sutter <psutter@redhat.com> [0.9.3-15.el8]
|
||||
- segtree: Fix get element command with prefixes (Phil Sutter) [1832235]
|
||||
- tests: 0034get_element_0: do not discard stderr (Phil Sutter) [1832235]
|
||||
- segtree: Merge get_set_interval_find() and get_set_interval_end() (Phil Sutter) [1832235]
|
||||
- segtree: Use expr_clone in get_set_interval_*() (Phil Sutter) [1832235]
|
||||
- segtree: Fix missing expires value in prefixes (Phil Sutter) [1832235]
|
||||
|
||||
* 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]
|
||||
|
Loading…
Reference in New Issue
Block a user