diff options
-rw-r--r-- | src/evaluate.c | 12 | ||||
-rw-r--r-- | tests/py/ip/snat.t | 6 | ||||
-rw-r--r-- | tests/py/ip/snat.t.payload | 22 |
3 files changed, 37 insertions, 3 deletions
diff --git a/src/evaluate.c b/src/evaluate.c index f3d7ca42..0bc799eb 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -3081,6 +3081,11 @@ static bool nat_evaluate_addr_has_th_expr(const struct expr *map) list_for_each_entry(i, &concat->expressions, list) { enum proto_bases base; + if (i->etype == EXPR_PAYLOAD && + i->payload.base == PROTO_BASE_TRANSPORT_HDR && + i->payload.desc != &proto_th) + return true; + if ((i->flags & EXPR_F_PROTOCOL) == 0) continue; @@ -3160,10 +3165,17 @@ static int stmt_evaluate_addr(struct eval_ctx *ctx, struct stmt *stmt, static int stmt_evaluate_nat_map(struct eval_ctx *ctx, struct stmt *stmt) { + struct proto_ctx *pctx = &ctx->pctx; struct expr *one, *two, *data, *tmp; const struct datatype *dtype; int addr_type, err; + if (pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc == NULL && + !nat_evaluate_addr_has_th_expr(stmt->nat.addr)) + return stmt_binary_error(ctx, stmt->nat.addr, stmt, + "transport protocol mapping is only " + "valid after transport protocol match"); + switch (stmt->nat.family) { case NFPROTO_IPV4: addr_type = TYPE_IPADDR; diff --git a/tests/py/ip/snat.t b/tests/py/ip/snat.t index a8ff8d1a..d4b0d2cb 100644 --- a/tests/py/ip/snat.t +++ b/tests/py/ip/snat.t @@ -11,7 +11,11 @@ iifname "eth0" tcp dport 80-90 snat to 192.168.3.15-192.168.3.240;ok iifname "eth0" tcp dport != 23-34 snat to 192.168.3.2;ok -snat ip to ip saddr map { 10.141.11.4 : 192.168.2.3 . 80 };ok +meta l4proto 17 snat ip to ip saddr map { 10.141.11.4 : 192.168.2.3 . 80 };ok snat ip to ip saddr map { 10.141.11.4 : 192.168.2.2-192.168.2.4 };ok snat ip to ip saddr map { 10.141.12.14 : 192.168.2.0/24 };ok snat ip prefix to ip saddr map { 10.141.11.0/24 : 192.168.2.0/24 };ok + +meta l4proto { 6, 17} snat ip to ip saddr . th dport map { 10.141.11.4 . 20 : 192.168.2.3 . 80};ok +snat ip to ip saddr map { 10.141.11.4 : 192.168.2.3 . 80 };fail +snat ip to ip saddr . th dport map { 10.141.11.4 . 20 : 192.168.2.3 . 80 };fail diff --git a/tests/py/ip/snat.t.payload b/tests/py/ip/snat.t.payload index 64f47896..48ae46b3 100644 --- a/tests/py/ip/snat.t.payload +++ b/tests/py/ip/snat.t.payload @@ -86,11 +86,13 @@ ip [ immediate reg 2 0xf003a8c0 ] [ nat snat ip addr_min reg 1 addr_max reg 2 ] -# snat ip to ip saddr map { 10.141.11.4 : 192.168.2.3 . 80 } +# meta l4proto 17 snat ip to ip saddr map { 10.141.11.4 : 192.168.2.3 . 80 } __map%d test-ip4 b size 1 __map%d test-ip4 0 element 040b8d0a : 0302a8c0 00005000 0 [end] -ip +ip + [ meta load l4proto => reg 1 ] + [ cmp eq reg 1 0x00000011 ] [ payload load 4b @ network header + 12 => reg 1 ] [ lookup reg 1 set __map%d dreg 1 ] [ nat snat ip addr_min reg 1 proto_min reg 9 ] @@ -121,3 +123,19 @@ ip [ payload load 4b @ network header + 12 => reg 1 ] [ lookup reg 1 set __map%d dreg 1 ] [ nat snat ip addr_min reg 1 addr_max reg 9 ] + +# meta l4proto { 6, 17} snat ip to ip saddr . th dport map { 10.141.11.4 . 20 : 192.168.2.3 . 80} +__set%d test-ip4 3 size 2 +__set%d test-ip4 0 + element 00000006 : 0 [end] element 00000011 : 0 [end] +__map%d test-ip4 b size 1 +__map%d test-ip4 0 + element 040b8d0a 00001400 : 0302a8c0 00005000 0 [end] +ip + [ meta load l4proto => reg 1 ] + [ lookup reg 1 set __set%d ] + [ payload load 4b @ network header + 12 => reg 1 ] + [ payload load 2b @ transport header + 2 => reg 9 ] + [ lookup reg 1 set __map%d dreg 1 ] + [ nat snat ip addr_min reg 1 proto_min reg 9 ] + |