summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/evaluate.c2
-rw-r--r--src/payload.c15
-rw-r--r--tests/shell/testcases/maps/dumps/typeof_integer_0.nft20
-rwxr-xr-xtests/shell/testcases/maps/typeof_integer_027
4 files changed, 57 insertions, 7 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 61dd4fea..6b3b6366 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -3970,7 +3970,7 @@ static int set_expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
return expr_error(ctx->msgs, i,
"specify either ip or ip6 for address matching");
- if (i->etype == EXPR_PAYLOAD && i->payload.is_raw &&
+ if (i->etype == EXPR_PAYLOAD &&
i->dtype->type == TYPE_INTEGER) {
struct datatype *dtype;
diff --git a/src/payload.c b/src/payload.c
index fd6f7011..66418cdd 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -153,9 +153,9 @@ static int payload_expr_build_udata(struct nftnl_udata_buf *udbuf,
expr->payload.base);
nftnl_udata_put_u32(udbuf, NFTNL_UDATA_SET_KEY_PAYLOAD_OFFSET,
expr->payload.offset);
- nftnl_udata_put_u32(udbuf, NFTNL_UDATA_SET_KEY_PAYLOAD_LEN,
- expr->len);
}
+ if (expr->dtype->type == TYPE_INTEGER)
+ nftnl_udata_put_u32(udbuf, NFTNL_UDATA_SET_KEY_PAYLOAD_LEN, expr->len);
return 0;
}
@@ -191,7 +191,7 @@ static int payload_parse_udata(const struct nftnl_udata *attr, void *data)
static struct expr *payload_expr_parse_udata(const struct nftnl_udata *attr)
{
const struct nftnl_udata *ud[NFTNL_UDATA_SET_KEY_PAYLOAD_MAX + 1] = {};
- unsigned int type, base, offset, len;
+ unsigned int type, base, offset, len = 0;
const struct proto_desc *desc;
bool is_raw = false;
struct expr *expr;
@@ -209,20 +209,23 @@ static struct expr *payload_expr_parse_udata(const struct nftnl_udata *attr)
desc = find_proto_desc(ud[NFTNL_UDATA_SET_KEY_PAYLOAD_DESC]);
if (!desc) {
if (!ud[NFTNL_UDATA_SET_KEY_PAYLOAD_BASE] ||
- !ud[NFTNL_UDATA_SET_KEY_PAYLOAD_OFFSET] ||
- !ud[NFTNL_UDATA_SET_KEY_PAYLOAD_LEN])
+ !ud[NFTNL_UDATA_SET_KEY_PAYLOAD_OFFSET])
return NULL;
base = nftnl_udata_get_u32(ud[NFTNL_UDATA_SET_KEY_PAYLOAD_BASE]);
offset = nftnl_udata_get_u32(ud[NFTNL_UDATA_SET_KEY_PAYLOAD_OFFSET]);
- len = nftnl_udata_get_u32(ud[NFTNL_UDATA_SET_KEY_PAYLOAD_LEN]);
is_raw = true;
}
type = nftnl_udata_get_u32(ud[NFTNL_UDATA_SET_KEY_PAYLOAD_TYPE]);
+ if (ud[NFTNL_UDATA_SET_KEY_PAYLOAD_LEN])
+ len = nftnl_udata_get_u32(ud[NFTNL_UDATA_SET_KEY_PAYLOAD_LEN]);
expr = payload_expr_alloc(&internal_location, desc, type);
+ if (len)
+ expr->len = len;
+
if (is_raw) {
struct datatype *dtype;
diff --git a/tests/shell/testcases/maps/dumps/typeof_integer_0.nft b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
new file mode 100644
index 00000000..33041557
--- /dev/null
+++ b/tests/shell/testcases/maps/dumps/typeof_integer_0.nft
@@ -0,0 +1,20 @@
+table inet t {
+ map m1 {
+ typeof udp length . @ih,32,32 : verdict
+ flags interval
+ elements = { 20-80 . 0x14 : accept,
+ 1-10 . 0xa : drop }
+ }
+
+ map m2 {
+ typeof udp length . @ih,32,32 : verdict
+ elements = { 30 . 0x1e : drop,
+ 20 . 0x24 : accept }
+ }
+
+ chain c {
+ udp length . @ih,32,32 vmap @m1
+ udp length . @ih,32,32 vmap @m2
+ udp length . @th,160,128 vmap { 47-63 . 0xe373135363130333131303735353203 : accept }
+ }
+}
diff --git a/tests/shell/testcases/maps/typeof_integer_0 b/tests/shell/testcases/maps/typeof_integer_0
new file mode 100755
index 00000000..d51510af
--- /dev/null
+++ b/tests/shell/testcases/maps/typeof_integer_0
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+EXPECTED="table inet t {
+ map m1 {
+ typeof udp length . @ih,32,32 : verdict
+ flags interval
+ elements = { 20-80 . 0x14 : accept, 1-10 . 0xa : drop }
+ }
+
+ map m2 {
+ typeof udp length . @ih,32,32 : verdict
+ elements = { 20 . 0x24 : accept, 30 . 0x1e : drop }
+ }
+
+ chain c {
+ udp length . @ih,32,32 vmap @m1
+ udp length . @ih,32,32 vmap @m2
+ udp length . @th,160,128 vmap { 47-63 . 0xe373135363130333131303735353203 : accept }
+ }
+}"
+
+$NFT add element inet t m1 { 90-100 . 40 : drop }
+$NFT delete element inet t m2 { 20 . 20 : accept }
+
+set -e
+$NFT -f - <<< $EXPECTED
+