All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Anders K. Pedersen | Cohaesio" <akp@cohaesio.com>
To: "netfilter-devel@vger.kernel.org"
	<netfilter-devel@vger.kernel.org>,
	"pablo@netfilter.org" <pablo@netfilter.org>
Subject: [PATCH nftables] netlink_linearize: skip set element expression in set statement key
Date: Wed, 4 Oct 2017 14:27:45 +0000	[thread overview]
Message-ID: <1507127265.20182.2.camel@cohaesio.com> (raw)

From: Anders K. Pedersen <akp@cohaesio.com>

Before this patch the following fails:

# nft add rule ip6 filter x \
	set add ip6 saddr . ip6 daddr @test
nft: netlink_linearize.c:648: netlink_gen_expr: Assertion `dreg < ctx->reg_low' failed.
Aborted

This is was previously fixed for flow statements in fbea4a6f4449
("netlink_linearize: skip set element expression in flow table key"), and
this patch implements the same change for set statements by using the set
element key in netlink_gen_set_stmt().

nft-test.py is updated to support set types with concatenated data types
in order to support testing of this.

Signed-off-by: Anders K. Pedersen <akp@cohaesio.com>
---
Resent because the original submission didn't make it to patchwork.

diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index c070fee..447856d 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -1208,9 +1208,9 @@ static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
 	struct nftnl_expr *nle;
 	enum nft_registers sreg_key;
 
-	sreg_key = get_register(ctx, stmt->set.key);
-	netlink_gen_expr(ctx, stmt->set.key, sreg_key);
-	release_register(ctx, stmt->set.key);
+	sreg_key = get_register(ctx, stmt->set.key->key);
+	netlink_gen_expr(ctx, stmt->set.key->key, sreg_key);
+	release_register(ctx, stmt->set.key->key);
 
 	nle = alloc_nft_expr("dynset");
 	netlink_put_register(nle, NFTNL_EXPR_DYNSET_SREG_KEY, sreg_key);
diff --git a/tests/py/ip/sets.t b/tests/py/ip/sets.t
index 4d14e82..b159ad8 100644
--- a/tests/py/ip/sets.t
+++ b/tests/py/ip/sets.t
@@ -47,6 +47,10 @@ ip saddr != @set33 drop;fail
 ?set4 192.168.1.1;fail
 ?set4 192.168.3.0/24;ok
 
+!set5 type ipv4_addr . ipv4_addr;ok
+ip saddr . ip daddr @set5 drop;ok
+set add ip saddr . ip daddr @set5;ok
+
 # test nested anonymous sets
 ip saddr { { 1.1.1.0, 3.3.3.0 }, 2.2.2.0 };ok;ip saddr { 1.1.1.0, 2.2.2.0, 3.3.3.0 }
 ip saddr { { 1.1.1.0/24, 3.3.3.0/24 }, 2.2.2.0/24 };ok;ip saddr { 1.1.1.0/24, 2.2.2.0/24, 3.3.3.0/24 }
diff --git a/tests/py/ip/sets.t.payload.inet b/tests/py/ip/sets.t.payload.inet
index 35f699c..136db56 100644
--- a/tests/py/ip/sets.t.payload.inet
+++ b/tests/py/ip/sets.t.payload.inet
@@ -30,6 +30,23 @@ inet test-inet input
   [ lookup reg 1 set set2 0x1 ]
   [ immediate reg 0 drop ]
 
+# ip saddr . ip daddr @set5 drop
+inet test-inet input
+  [ 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 set5 ]
+  [ immediate reg 0 drop ]
+
+# set add ip saddr . ip daddr @set5
+inet test-inet input
+  [ 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 ]
+  [ dynset add reg_key 1 set set5 ]
+
 # ip saddr { { 1.1.1.0, 3.3.3.0 }, 2.2.2.0 }
 __set%d t 3
 __set%d t 0
diff --git a/tests/py/ip/sets.t.payload.ip b/tests/py/ip/sets.t.payload.ip
index 891a1ee..a783174 100644
--- a/tests/py/ip/sets.t.payload.ip
+++ b/tests/py/ip/sets.t.payload.ip
@@ -22,6 +22,19 @@ ip test-ip4 input
   [ lookup reg 1 set set2 0x1 ]
   [ immediate reg 0 drop ]
 
+# ip saddr . ip daddr @set5 drop
+ip test-ip4 input
+  [ payload load 4b @ network header + 12 => reg 1 ]
+  [ payload load 4b @ network header + 16 => reg 9 ]
+  [ lookup reg 1 set set5 ]
+  [ immediate reg 0 drop ]
+
+# set add ip saddr . ip daddr @set5
+ip test-ip4 input
+  [ payload load 4b @ network header + 12 => reg 1 ]
+  [ payload load 4b @ network header + 16 => reg 9 ]
+  [ dynset add reg_key 1 set set5 ]
+
 # ip saddr { { 1.1.1.0, 3.3.3.0 }, 2.2.2.0 }
 __set%d test-ip4 3
 __set%d test-ip4 0
diff --git a/tests/py/ip/sets.t.payload.netdev b/tests/py/ip/sets.t.payload.netdev
index ae8b6e7..1689300 100644
--- a/tests/py/ip/sets.t.payload.netdev
+++ b/tests/py/ip/sets.t.payload.netdev
@@ -30,6 +30,23 @@ netdev test-netdev ingress
   [ lookup reg 1 set set2 0x1 ]
   [ immediate reg 0 drop ]
 
+# ip saddr . ip daddr @set5 drop
+netdev test-netdev ingress
+  [ 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 set5 ]
+  [ immediate reg 0 drop ]
+
+# set add ip saddr . ip daddr @set5
+netdev test-netdev ingress
+  [ 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 ]
+  [ dynset add reg_key 1 set set5 ]
+
 # ip saddr { { 1.1.1.0, 3.3.3.0 }, 2.2.2.0 }
 __set%d test-netdev 3
 __set%d test-netdev 0
diff --git a/tests/py/ip6/sets.t b/tests/py/ip6/sets.t
index 3ea2d83..54aa1e4 100644
--- a/tests/py/ip6/sets.t
+++ b/tests/py/ip6/sets.t
@@ -36,3 +36,7 @@ ip6 saddr != @set33 drop;fail
 !set4 type ipv6_addr flags interval;ok
 ?set4 1234:1234:1234:1234::/64 4321:1234:1234:1234::/64;ok
 ?set4 4321:1234:1234:1234:1234:1234::/96;fail
+
+!set5 type ipv6_addr . ipv6_addr;ok
+ip6 saddr . ip6 daddr @set5 drop;ok
+set add ip6 saddr . ip6 daddr @set5;ok
diff --git a/tests/py/ip6/sets.t.payload.inet b/tests/py/ip6/sets.t.payload.inet
index b45f630..cc6f9ef 100644
--- a/tests/py/ip6/sets.t.payload.inet
+++ b/tests/py/ip6/sets.t.payload.inet
@@ -14,3 +14,20 @@ inet test-inet input
   [ lookup reg 1 set set2 0x1 ]
   [ immediate reg 0 drop ]
 
+# ip6 saddr . ip6 daddr @set5 drop
+inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ payload load 16b @ network header + 8 => reg 1 ]
+  [ payload load 16b @ network header + 24 => reg 2 ]
+  [ lookup reg 1 set set5 ]
+  [ immediate reg 0 drop ]
+
+# set add ip6 saddr . ip6 daddr @set5
+inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ payload load 16b @ network header + 8 => reg 1 ]
+  [ payload load 16b @ network header + 24 => reg 2 ]
+  [ dynset add reg_key 1 set set5 ]
+
diff --git a/tests/py/ip6/sets.t.payload.ip6 b/tests/py/ip6/sets.t.payload.ip6
index 0fab365..f55da6e 100644
--- a/tests/py/ip6/sets.t.payload.ip6
+++ b/tests/py/ip6/sets.t.payload.ip6
@@ -10,3 +10,16 @@ ip6 test-ip6 input
   [ lookup reg 1 set set2 0x1 ]
   [ immediate reg 0 drop ]
 
+# ip6 saddr . ip6 daddr @set5 drop
+ip6 test-ip6 input
+  [ payload load 16b @ network header + 8 => reg 1 ]
+  [ payload load 16b @ network header + 24 => reg 2 ]
+  [ lookup reg 1 set set5 ]
+  [ immediate reg 0 drop ]
+
+# set add ip6 saddr . ip6 daddr @set5
+ip6 test-ip6 input
+  [ payload load 16b @ network header + 8 => reg 1 ]
+  [ payload load 16b @ network header + 24 => reg 2 ]
+  [ dynset add reg_key 1 set set5 ]
+
diff --git a/tests/py/ip6/sets.t.payload.netdev b/tests/py/ip6/sets.t.payload.netdev
index 7c4ba3e..16b850c 100644
--- a/tests/py/ip6/sets.t.payload.netdev
+++ b/tests/py/ip6/sets.t.payload.netdev
@@ -14,3 +14,20 @@ netdev test-netdev ingress
   [ lookup reg 1 set set2 0x1 ]
   [ immediate reg 0 drop ]
 
+# ip6 saddr . ip6 daddr @set5 drop
+netdev test-netdev ingress
+  [ meta load protocol => reg 1 ]
+  [ cmp eq reg 1 0x0000dd86 ]
+  [ payload load 16b @ network header + 8 => reg 1 ]
+  [ payload load 16b @ network header + 24 => reg 2 ]
+  [ lookup reg 1 set set5 ]
+  [ immediate reg 0 drop ]
+
+# set add ip6 saddr . ip6 daddr @set5
+netdev test-netdev ingress
+  [ meta load protocol => reg 1 ]
+  [ cmp eq reg 1 0x0000dd86 ]
+  [ payload load 16b @ network header + 8 => reg 1 ]
+  [ payload load 16b @ network header + 24 => reg 2 ]
+  [ dynset add reg_key 1 set set5 ]
+
diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py
index 8d099a1..9ad9771 100755
--- a/tests/py/nft-test.py
+++ b/tests/py/nft-test.py
@@ -866,8 +866,13 @@ def set_process(set_line, filename, lineno):
     set_name = tokens[0]
     set_type = tokens[2]
 
-    if len(tokens) == 5 and tokens[3] == "flags":
-        set_flags = tokens[4]
+    i = 3
+    while len(tokens) > i and tokens[i] == ".":
+        set_type += " . " + tokens[i+1]
+        i += 2
+
+    if len(tokens) == i+2 and tokens[i] == "flags":
+        set_flags = tokens[i+1]
     else:
         set_flags = ""
 

             reply	other threads:[~2017-10-04 14:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-04 14:27 Anders K. Pedersen | Cohaesio [this message]
2017-10-06 12:58 ` [PATCH nftables] netlink_linearize: skip set element expression in set statement key Pablo Neira Ayuso
  -- strict thread matches above, loose matches on Subject: below --
2017-08-26 17:50 Anders K. Pedersen | Cohaesio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1507127265.20182.2.camel@cohaesio.com \
    --to=akp@cohaesio.com \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.