diff options
-rw-r--r-- | src/evaluate.c | 23 | ||||
-rw-r--r-- | src/netlink.c | 25 | ||||
-rw-r--r-- | tests/py/inet/meta.t | 2 | ||||
-rw-r--r-- | tests/py/inet/meta.t.payload | 12 | ||||
-rwxr-xr-x | tests/shell/testcases/maps/0012map_0 | 19 | ||||
-rw-r--r-- | tests/shell/testcases/maps/dumps/0012map_0.nft | 13 |
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 + } } |