payload_expr_parse_udata() restores the pseudo transport header (th) proto desc from set userdata, but not payload.is_raw. The bison and json parsers both set is_raw for raw th expressions, which makes evaluation skip the transport protocol conflict check. Without it, re-evaluating a map declared with 'typeof ... th dport ...' from a later transaction fails with a bogus conflicting transport layer protocols specified: tcp vs. th Set is_raw when the restored desc is proto_th, just like the parsers do. Signed-off-by: Adrian Moisey --- src/payload.c | 3 ++ .../testcases/maps/typeof_maps_restore_0 | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 tests/shell/testcases/maps/typeof_maps_restore_0 diff --git a/src/payload.c b/src/payload.c index 162367eb..4f1834a0 100644 --- a/src/payload.c +++ b/src/payload.c @@ -239,6 +239,9 @@ static struct expr *payload_expr_parse_udata(const struct nftnl_udata *attr) expr = payload_expr_alloc(&internal_location, desc, type); + if (desc == &proto_th) + expr->payload.is_raw = true; + if (len) expr->len = len; diff --git a/tests/shell/testcases/maps/typeof_maps_restore_0 b/tests/shell/testcases/maps/typeof_maps_restore_0 new file mode 100755 index 00000000..417e1c3c --- /dev/null +++ b/tests/shell/testcases/maps/typeof_maps_restore_0 @@ -0,0 +1,28 @@ +#!/bin/bash + +# 'th dport' in a typeof map is restored from set userdata. A later +# transaction re-evaluating it must not fail with a bogus +# "conflicting transport layer protocols specified: tcp vs. th". + +set -e + +$NFT -f - <