summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/evaluate.c23
-rw-r--r--src/netlink.c25
-rw-r--r--tests/py/inet/meta.t2
-rw-r--r--tests/py/inet/meta.t.payload12
-rwxr-xr-xtests/shell/testcases/maps/0012map_019
-rw-r--r--tests/shell/testcases/maps/dumps/0012map_0.nft13
6 files changed, 87 insertions, 7 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 0bf6a0d1..991de1d7 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -148,8 +148,29 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr,
return 0;
/* Conversion for EXPR_CONCAT is handled for single composing ranges */
- if ((*expr)->etype == EXPR_CONCAT)
+ if ((*expr)->etype == EXPR_CONCAT) {
+ struct expr *i, *next, *unary;
+
+ list_for_each_entry_safe(i, next, &(*expr)->expressions, list) {
+ if (i->byteorder == BYTEORDER_BIG_ENDIAN)
+ continue;
+
+ basetype = expr_basetype(i)->type;
+ if (basetype == TYPE_STRING)
+ continue;
+
+ assert(basetype == TYPE_INTEGER);
+
+ op = byteorder_conversion_op(i, byteorder);
+ unary = unary_expr_alloc(&i->location, op, i);
+ if (expr_evaluate(ctx, &unary) < 0)
+ return -1;
+
+ list_replace(&i->list, &unary->list);
+ }
+
return 0;
+ }
basetype = expr_basetype(*expr)->type;
switch (basetype) {
diff --git a/src/netlink.c b/src/netlink.c
index 799cf9b8..db5e79f2 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -249,9 +249,20 @@ static int netlink_export_pad(unsigned char *data, const mpz_t v,
static int netlink_gen_concat_data_expr(int end, const struct expr *i,
unsigned char *data)
{
+ struct expr *expr;
+
switch (i->etype) {
case EXPR_RANGE:
- i = end ? i->right : i->left;
+ if (end)
+ expr = i->right;
+ else
+ expr = i->left;
+
+ if (expr_basetype(expr)->type == TYPE_INTEGER &&
+ expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ mpz_switch_byteorder(expr->value, expr->len / BITS_PER_BYTE);
+
+ i = expr;
break;
case EXPR_PREFIX:
if (end) {
@@ -1109,7 +1120,7 @@ static struct expr *netlink_parse_interval_elem(const struct set *set,
return range_expr_to_prefix(range);
}
-static struct expr *concat_elem_expr(struct expr *key,
+static struct expr *concat_elem_expr(const struct set *set, struct expr *key,
const struct datatype *dtype,
struct expr *data, int *off)
{
@@ -1133,7 +1144,9 @@ static struct expr *concat_elem_expr(struct expr *key,
expr->byteorder = subtype->byteorder;
}
- if (expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ if (expr_basetype(expr)->type == TYPE_STRING ||
+ (!(set->flags & NFT_SET_INTERVAL) &&
+ expr->byteorder == BYTEORDER_HOST_ENDIAN))
mpz_switch_byteorder(expr->value, expr->len / BITS_PER_BYTE);
if (expr->dtype->basetype != NULL &&
@@ -1157,7 +1170,7 @@ static struct expr *netlink_parse_concat_elem_key(const struct set *set,
concat = concat_expr_alloc(&data->location);
while (off > 0) {
- expr = concat_elem_expr(n, dtype, data, &off);
+ expr = concat_elem_expr(set, n, dtype, data, &off);
compound_expr_add(concat, expr);
if (set->key->etype == EXPR_CONCAT)
n = list_next_entry(n, list);
@@ -1180,7 +1193,7 @@ static struct expr *netlink_parse_concat_elem(const struct set *set,
concat = concat_expr_alloc(&data->location);
while (off > 0) {
- expr = concat_elem_expr(NULL, dtype, data, &off);
+ expr = concat_elem_expr(set, NULL, dtype, data, &off);
list_add_tail(&expr->list, &expressions);
}
@@ -1192,7 +1205,7 @@ static struct expr *netlink_parse_concat_elem(const struct set *set,
while (off > 0) {
left = list_first_entry(&expressions, struct expr, list);
- expr = concat_elem_expr(NULL, dtype, data, &off);
+ expr = concat_elem_expr(set, NULL, dtype, data, &off);
list_del(&left->list);
range = range_expr_alloc(&data->location, left, expr);
diff --git a/tests/py/inet/meta.t b/tests/py/inet/meta.t
index 423cc5f3..0d7d5f25 100644
--- a/tests/py/inet/meta.t
+++ b/tests/py/inet/meta.t
@@ -21,3 +21,5 @@ meta secpath missing;ok;meta ipsec missing
meta ibrname "br0";fail
meta obrname "br0";fail
meta mark set ct mark >> 8;ok
+
+meta mark . tcp dport { 0x0000000a-0x00000014 . 80-90, 0x00100000-0x00100123 . 100-120 };ok
diff --git a/tests/py/inet/meta.t.payload b/tests/py/inet/meta.t.payload
index fd054549..2b4e6c2d 100644
--- a/tests/py/inet/meta.t.payload
+++ b/tests/py/inet/meta.t.payload
@@ -97,3 +97,15 @@ inet test-inet input
[ cmp eq reg 1 0x00000011 ]
[ payload load 2b @ transport header + 2 => reg 1 ]
[ cmp eq reg 1 0x00004300 ]
+
+# meta mark . tcp dport { 0x0000000a-0x00000014 . 80-90, 0x00100000-0x00100123 . 100-120 }
+__set%d test-inet 87 size 1
+__set%d test-inet 0
+ element 0a000000 00005000 - 14000000 00005a00 : 0 [end] element 00001000 00006400 - 23011000 00007800 : 0 [end]
+ip test-inet input
+ [ meta load l4proto => reg 1 ]
+ [ cmp eq reg 1 0x00000006 ]
+ [ meta load mark => reg 1 ]
+ [ byteorder reg 1 = hton(reg 1, 4, 4) ]
+ [ payload load 2b @ transport header + 2 => reg 9 ]
+ [ lookup reg 1 set __set%d ]
diff --git a/tests/shell/testcases/maps/0012map_0 b/tests/shell/testcases/maps/0012map_0
index dd93c482..49e51b75 100755
--- a/tests/shell/testcases/maps/0012map_0
+++ b/tests/shell/testcases/maps/0012map_0
@@ -15,3 +15,22 @@ table ip x {
}"
$NFT -f - <<< "$EXPECTED"
+
+EXPECTED="table ip x {
+ map w {
+ typeof ip saddr . meta mark : verdict
+ flags interval
+ counter
+ elements = {
+ 127.0.0.1-127.0.0.4 . 0x123434-0xb00122 : accept,
+ }
+ }
+
+ chain k {
+ type filter hook input priority filter + 1; policy accept;
+ meta mark set 0x123434
+ ip saddr . meta mark vmap @w
+ }
+}"
+
+$NFT -f - <<< "$EXPECTED"
diff --git a/tests/shell/testcases/maps/dumps/0012map_0.nft b/tests/shell/testcases/maps/dumps/0012map_0.nft
index e734fc1c..895490cf 100644
--- a/tests/shell/testcases/maps/dumps/0012map_0.nft
+++ b/tests/shell/testcases/maps/dumps/0012map_0.nft
@@ -6,7 +6,20 @@ table ip x {
"eth1" : drop }
}
+ map w {
+ typeof ip saddr . meta mark : verdict
+ flags interval
+ counter
+ elements = { 127.0.0.1-127.0.0.4 . 0x00123434-0x00b00122 counter packets 0 bytes 0 : accept }
+ }
+
chain y {
iifname vmap { "lo" : accept, "eth0" : drop, "eth1" : drop }
}
+
+ chain k {
+ type filter hook input priority filter + 1; policy accept;
+ meta mark set 0x00123434
+ ip saddr . meta mark vmap @w
+ }
}