From a5674886b45c9b3489aef8cc7435dd85afa9494a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 16 Jun 2021 13:49:08 +0200 Subject: evaluate: unbreak verdict maps with implicit map with interval concatenations Verdict maps in combination with interval concatenations are broken, e.g. # nft add rule x y tcp dport . ip saddr vmap { 1025-65535 . 192.168.10.2 : accept } Retrieve the concatenation field length and count from the map->map expressions that represents the key of the implicit map. Signed-off-by: Pablo Neira Ayuso --- src/evaluate.c | 8 +++++++ tests/py/ip/ip.t | 1 + tests/py/ip/ip.t.json | 50 +++++++++++++++++++++++++++++++++++++++++ tests/py/ip/ip.t.payload | 8 +++++++ tests/py/ip/ip.t.payload.bridge | 11 +++++++++ tests/py/ip/ip.t.payload.inet | 11 +++++++++ tests/py/ip/ip.t.payload.netdev | 11 +++++++++ 7 files changed, 100 insertions(+) diff --git a/src/evaluate.c b/src/evaluate.c index d220c8e3..77fb2459 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1564,6 +1564,14 @@ static int expr_evaluate_map(struct eval_ctx *ctx, struct expr **expr) ctx->set = NULL; map = *expr; map->mappings->set->flags |= map->mappings->set->init->set_flags; + + if (map->mappings->set->flags & NFT_SET_INTERVAL && + map->map->etype == EXPR_CONCAT) { + memcpy(&map->mappings->set->desc.field_len, &map->map->field_len, + sizeof(map->mappings->set->desc.field_len)); + map->mappings->set->desc.field_count = map->map->field_count; + map->mappings->flags |= NFT_SET_CONCAT; + } break; case EXPR_SYMBOL: if (expr_evaluate(ctx, &map->mappings) < 0) diff --git a/tests/py/ip/ip.t b/tests/py/ip/ip.t index b74d465f..f4a3667c 100644 --- a/tests/py/ip/ip.t +++ b/tests/py/ip/ip.t @@ -125,3 +125,4 @@ iif "lo" ip dscp set af23;ok iif "lo" ip dscp set cs0;ok ip saddr . ip daddr { 192.0.2.1 . 10.0.0.1-10.0.0.2 };ok +ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept };ok diff --git a/tests/py/ip/ip.t.json b/tests/py/ip/ip.t.json index 32312b15..b1085035 100644 --- a/tests/py/ip/ip.t.json +++ b/tests/py/ip/ip.t.json @@ -1635,3 +1635,53 @@ } } ] + +# ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept } +[ + { + "vmap": { + "data": { + "set": [ + [ + { + "concat": [ + { + "range": [ + "192.168.5.1", + "192.168.5.128" + ] + }, + { + "range": [ + "192.168.6.1", + "192.168.6.128" + ] + } + ] + }, + { + "accept": null + } + ] + ] + }, + "key": { + "concat": [ + { + "payload": { + "field": "saddr", + "protocol": "ip" + } + }, + { + "payload": { + "field": "daddr", + "protocol": "ip" + } + } + ] + } + } + } +] + diff --git a/tests/py/ip/ip.t.payload b/tests/py/ip/ip.t.payload index 4bb17752..49d1a0fb 100644 --- a/tests/py/ip/ip.t.payload +++ b/tests/py/ip/ip.t.payload @@ -515,3 +515,11 @@ ip [ payload load 4b @ network header + 16 => reg 9 ] [ lookup reg 1 set __set%d ] +# ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept } +__map%d test-ip4 8f size 1 +__map%d test-ip4 0 + element 0105a8c0 0106a8c0 - 8005a8c0 8006a8c0 : accept 0 [end] +ip + [ payload load 4b @ network header + 12 => reg 1 ] + [ payload load 4b @ network header + 16 => reg 9 ] + [ lookup reg 1 set __map%d dreg 0 ] diff --git a/tests/py/ip/ip.t.payload.bridge b/tests/py/ip/ip.t.payload.bridge index c8c1dbad..dac86543 100644 --- a/tests/py/ip/ip.t.payload.bridge +++ b/tests/py/ip/ip.t.payload.bridge @@ -673,3 +673,14 @@ bridge [ payload load 4b @ network header + 16 => reg 9 ] [ lookup reg 1 set __set%d ] +# ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept } +__map%d test-bridge 8f size 1 +__map%d test-bridge 0 + element 0105a8c0 0106a8c0 - 8005a8c0 8006a8c0 : accept 0 [end] +bridge + [ meta load protocol => reg 1 ] + [ cmp eq reg 1 0x00000008 ] + [ payload load 4b @ network header + 12 => reg 1 ] + [ payload load 4b @ network header + 16 => reg 9 ] + [ lookup reg 1 set __map%d dreg 0 ] + diff --git a/tests/py/ip/ip.t.payload.inet b/tests/py/ip/ip.t.payload.inet index 55304fc9..64371650 100644 --- a/tests/py/ip/ip.t.payload.inet +++ b/tests/py/ip/ip.t.payload.inet @@ -673,3 +673,14 @@ inet [ payload load 4b @ network header + 16 => reg 9 ] [ lookup reg 1 set __set%d ] +# ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept } +__map%d test-inet 8f size 1 +__map%d test-inet 0 + element 0105a8c0 0106a8c0 - 8005a8c0 8006a8c0 : accept 0 [end] +inet + [ meta load nfproto => reg 1 ] + [ cmp eq reg 1 0x00000002 ] + [ payload load 4b @ network header + 12 => reg 1 ] + [ payload load 4b @ network header + 16 => reg 9 ] + [ lookup reg 1 set __map%d dreg 0 ] + diff --git a/tests/py/ip/ip.t.payload.netdev b/tests/py/ip/ip.t.payload.netdev index 712cb375..65f8c96a 100644 --- a/tests/py/ip/ip.t.payload.netdev +++ b/tests/py/ip/ip.t.payload.netdev @@ -673,3 +673,14 @@ netdev [ payload load 4b @ network header + 16 => reg 9 ] [ lookup reg 1 set __set%d ] +# ip saddr . ip daddr vmap { 192.168.5.1-192.168.5.128 . 192.168.6.1-192.168.6.128 : accept } +__map%d test-netdev 8f size 1 +__map%d test-netdev 0 + element 0105a8c0 0106a8c0 - 8005a8c0 8006a8c0 : accept 0 [end] +netdev + [ meta load protocol => reg 1 ] + [ cmp eq reg 1 0x00000008 ] + [ payload load 4b @ network header + 12 => reg 1 ] + [ payload load 4b @ network header + 16 => reg 9 ] + [ lookup reg 1 set __map%d dreg 0 ] + -- cgit v1.2.3