diff options
author | Florian Westphal <fw@strlen.de> | 2023-01-23 19:03:28 +0100 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2023-01-26 17:59:22 +0100 |
commit | 4cc6b20d31498d90e90ff574ce8b70276afcee8f (patch) | |
tree | 66cc2c15155ef7b90d29c9e17fa8a1e792e4db84 /tests/shell/testcases/sets | |
parent | 6fca08c6340b0dfed1f1c0f426d86f69446c0732 (diff) |
evaluate: set eval ctx for add/update statements with integer constants
Eric reports that nft asserts when using integer basetype constants with
'typeof' sets. Example:
table netdev t {
set s {
typeof ether saddr . vlan id
flags dynamic,timeout
}
chain c { }
}
loads fine. But adding a rule with add/update statement fails:
nft 'add rule netdev t c set update ether saddr . 0 @s'
nft: netlink_linearize.c:867: netlink_gen_expr: Assertion `dreg < ctx->reg_low' failed.
When the 'ether saddr . 0' concat expression is processed, there is
no set definition available anymore to deduce the required size of the
integer constant.
nft eval step then derives the required length using the data types.
'0' has integer basetype, so the deduced length is 0.
The assertion triggers because serialization step finds that it
needs one more register.
2 are needed to store the ethernet address, another register is
needed for the vlan id.
Update eval step to make the expression context store the set key
information when processing the preceeding set reference, then
let stmt_evaluate_set() preserve the existing context instead of
zeroing it again via stmt_evaluate_arg().
This makes concat expression evaluation compute the total size
needed based on the sets key definition.
Reported-by: Eric Garver <eric@garver.life>
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'tests/shell/testcases/sets')
-rw-r--r-- | tests/shell/testcases/sets/dumps/typeof_sets_concat.nft | 12 | ||||
-rwxr-xr-x | tests/shell/testcases/sets/typeof_sets_concat | 6 |
2 files changed, 18 insertions, 0 deletions
diff --git a/tests/shell/testcases/sets/dumps/typeof_sets_concat.nft b/tests/shell/testcases/sets/dumps/typeof_sets_concat.nft new file mode 100644 index 00000000..dbaf7cdc --- /dev/null +++ b/tests/shell/testcases/sets/dumps/typeof_sets_concat.nft @@ -0,0 +1,12 @@ +table netdev t { + set s { + typeof ether saddr . vlan id + size 2048 + flags dynamic,timeout + } + + chain c { + ether type != 8021q add @s { ether saddr . 0 timeout 5s } counter packets 0 bytes 0 return + ether type != 8021q update @s { ether daddr . 123 timeout 1m } counter packets 0 bytes 0 return + } +} diff --git a/tests/shell/testcases/sets/typeof_sets_concat b/tests/shell/testcases/sets/typeof_sets_concat new file mode 100755 index 00000000..07820b7c --- /dev/null +++ b/tests/shell/testcases/sets/typeof_sets_concat @@ -0,0 +1,6 @@ +#!/bin/bash + +set -e +dumpfile=$(dirname $0)/dumps/$(basename $0).nft + +$NFT -f "$dumpfile" |