netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nft 00/10] nft: exthdr fixes and improvements
@ 2016-03-01 15:37 Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 01/10] evaluate: enforce ip6 proto with exthdr expression Florian Westphal
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel

This adds following enhancements and fixes for the exthdr
expression.

#1.  Treat exthdr as if user asked for an ip6 protocol header field,
i.e. add ipv6 dependency for bridge/netdev/inet family.

#2.  Add scaling and masking to handle protocol headers that have
non-byte divisible sizes.

Tested briefly with following dummy rules (nf_defrag_ipv6 module not loaded):

frag frag-off 0 counter packets 40 bytes 59840
frag frag-off 131 counter packets 0 bytes 0
frag frag-off 1448 counter packets 0 bytes 0
frag frag-off 181 counter packets 40 bytes 59840
frag frag-off > 0 counter packets 120 bytes 148160

Note that the offsets are *NOT* scaled, i.e. we match the raw values
contained in the packet.  To match offset of 1448 one thus needs to
ask for 181.

This is same behaviour as ip hdrlength, where 5 matches a value of 20 bytes.

 include/expression.h             |    1
 include/exthdr.h                 |    2
 include/payload.h                |    2
 src/evaluate.c                   |   29 +++++++
 src/exthdr.c                     |   33 ++++++++
 src/netlink_delinearize.c        |   36 +++++----
 src/netlink_linearize.c          |   62 +++++++++++----
 src/payload.c                    |   75 ++++++++++++-------
 tests/py/ip6/dst.t.payload.inet  |   30 +++++++
 tests/py/ip6/frag.t              |   63 ++++++++++++++++
 tests/py/ip6/frag.t.payload.inet |  145 +++++++++++++++++++++++++++++++++++++
 tests/py/ip6/frag.t.payload.ip6  |  109 +++++++++++++++++++++++++++
 tests/py/ip6/hbh.t.payload.inet  |   30 +++++++
 tests/py/ip6/mh.t.payload.inet   |   64 ++++++++++++++++
 tests/py/ip6/rt.t.payload.inet   |   58 ++++++++++++++
 tests/py/any/frag.t                |   67 -----------------
 tests/py/any/frag.t.payload        |  109 ---------------------------
 17 files changed, 685 insertions(+), 230 deletions(-)

Note: frag-off match is broken at the moment, I passed a patch
to netdev:

https://patchwork.ozlabs.org/patch/590568/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH nft 01/10] evaluate: enforce ip6 proto with exthdr expression
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 02/10] netlink: split generic part of netlink_gen_payload_mask into helper Florian Westphal
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Don't allow use of exthdr with e.g. ip family.
Move frag.t to ip6 directory and don't use it with ipv4 anymore.

This change causes major test failures for all exthdr users
since they now fail with inet/bridge/netdev families.

Will be resolved in a later patch -- we need to add
an ipv6 dependency for them.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 src/evaluate.c                  |  18 ++++++-
 tests/py/any/frag.t             |  67 ------------------------
 tests/py/any/frag.t.payload     | 109 ----------------------------------------
 tests/py/ip6/frag.t             |  63 +++++++++++++++++++++++
 tests/py/ip6/frag.t.payload.ip6 | 109 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 189 insertions(+), 177 deletions(-)
 delete mode 100644 tests/py/any/frag.t
 delete mode 100644 tests/py/any/frag.t.payload
 create mode 100644 tests/py/ip6/frag.t
 create mode 100644 tests/py/ip6/frag.t.payload.ip6

diff --git a/src/evaluate.c b/src/evaluate.c
index a49cdd9..47a1f8c 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -343,6 +343,21 @@ conflict_resolution_gen_dependency(struct eval_ctx *ctx, int protocol,
 	return 0;
 }
 
+/*
+ * Exthdr expression: check whether dependencies are fulfilled.
+ */
+static int expr_evaluate_exthdr(struct eval_ctx *ctx, struct expr **expr)
+{
+	const struct proto_desc *base;
+
+	base = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc;
+	if (base == &proto_ip6)
+		return expr_evaluate_primary(ctx, expr);
+
+	return expr_error(ctx->msgs, *expr,
+			  "exthdr can only be used with ipv6");
+}
+
 /* dependency supersede.
  *
  * 'inet' is a 'phony' l2 dependeny used by NFPROTO_INET to fulfill network
@@ -1320,8 +1335,9 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
 		return 0;
 	case EXPR_VALUE:
 		return expr_evaluate_value(ctx, expr);
-	case EXPR_VERDICT:
 	case EXPR_EXTHDR:
+		return expr_evaluate_exthdr(ctx, expr);
+	case EXPR_VERDICT:
 	case EXPR_META:
 		return expr_evaluate_primary(ctx, expr);
 	case EXPR_PAYLOAD:
diff --git a/tests/py/any/frag.t b/tests/py/any/frag.t
deleted file mode 100644
index 8b5e34a..0000000
--- a/tests/py/any/frag.t
+++ /dev/null
@@ -1,67 +0,0 @@
-:output;type filter hook output priority 0
-:ingress;type filter hook ingress device lo priority 0
-
-*ip;test-ip4;output
-*ip6;test-ip6;output
-*inet;test-inet;output
-*arp;test-arp;output
-*bridge;test-bridge;output
-*netdev;test-netdev;ingress
-
-frag nexthdr tcp;ok;frag nexthdr 6
-frag nexthdr != icmp;ok;frag nexthdr != 1
-frag nexthdr {esp, ah, comp, udp, udplite, tcp, dccp, sctp};ok;frag nexthdr { 51, 136, 132, 6, 108, 50, 17, 33}
-- frag nexthdr != {esp, ah, comp, udp, udplite, tcp, dccp, sctp};ok
-frag nexthdr esp;ok;frag nexthdr 50
-frag nexthdr ah;ok;frag nexthdr 51
-
-frag reserved 22;ok
-frag reserved != 233;ok
-frag reserved 33-45;ok
-frag reserved != 33-45;ok
-frag reserved { 33, 55, 67, 88};ok
-- frag reserved != { 33, 55, 67, 88};ok
-frag reserved { 33-55};ok
-- frag reserved != { 33-55};ok
-
-# BUG: frag frag-off 22 and frag frag-off { 33-55}
-# This breaks table listing: "netlink: Error: Relational expression size mismatch"
-
-- frag frag-off 22;ok
-- frag frag-off != 233;ok
-- frag frag-off 33-45;ok
-- frag frag-off != 33-45;ok
-- frag frag-off { 33, 55, 67, 88};ok
-- frag frag-off != { 33, 55, 67, 88};ok
-- frag frag-off { 33-55};ok
-- frag frag-off != { 33-55};ok
-
-# BUG  frag reserved2 33 and frag reserved2 1
-# $ sudo nft add rule ip test input frag reserved2 33
-# <cmdline>:1:39-40: Error: Value 33 exceeds valid range 0-3
-# add rule ip test input frag reserved2 33
-#                                      ^^
-# sudo nft add rule ip test input frag reserved2 1
-# <cmdline>:1:1-39: Error: Could not process rule: Invalid argument
-# add rule ip test input frag reserved2 1
-# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-# BUG more-fragments 1 and frag more-fragments 4
-# frag more-fragments 1
-# <cmdline>:1:1-44: Error: Could not process rule: Invalid argument
-# add rule ip test input frag more-fragments 1
-# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-# $ sudo nft add rule ip test input frag more-fragments 4
-# <cmdline>:1:44-44: Error: Value 4 exceeds valid range 0-1
-# add rule ip test input frag more-fragments 4
-#                                           ^
-
-frag id 1;ok
-frag id 22;ok
-frag id != 33;ok
-frag id 33-45;ok
-frag id != 33-45;ok
-frag id { 33, 55, 67, 88};ok
-- frag id != { 33, 55, 67, 88};ok
-frag id { 33-55};ok
-- frag id != { 33-55};ok
diff --git a/tests/py/any/frag.t.payload b/tests/py/any/frag.t.payload
deleted file mode 100644
index a91ab3f..0000000
--- a/tests/py/any/frag.t.payload
+++ /dev/null
@@ -1,109 +0,0 @@
-# frag nexthdr tcp
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 0 => reg 1 ]
-  [ cmp eq reg 1 0x00000006 ]
-
-# frag nexthdr != icmp
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 0 => reg 1 ]
-  [ cmp neq reg 1 0x00000001 ]
-
-# frag nexthdr {esp, ah, comp, udp, udplite, tcp, dccp, sctp}
-set%d test-ip4 3
-set%d test-ip4 0
-	element 00000032  : 0 [end]	element 00000033  : 0 [end]	element 0000006c  : 0 [end]	element 00000011  : 0 [end]	element 00000088  : 0 [end]	element 00000006  : 0 [end]	element 00000021  : 0 [end]	element 00000084  : 0 [end]
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 0 => reg 1 ]
-  [ lookup reg 1 set set%d ]
-
-# frag nexthdr esp
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 0 => reg 1 ]
-  [ cmp eq reg 1 0x00000032 ]
-
-# frag nexthdr ah
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 0 => reg 1 ]
-  [ cmp eq reg 1 0x00000033 ]
-
-# frag reserved 22
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 1 => reg 1 ]
-  [ cmp eq reg 1 0x00000016 ]
-
-# frag reserved != 233
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 1 => reg 1 ]
-  [ cmp neq reg 1 0x000000e9 ]
-
-# frag reserved 33-45
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 1 => reg 1 ]
-  [ cmp gte reg 1 0x00000021 ]
-  [ cmp lte reg 1 0x0000002d ]
-
-# frag reserved != 33-45
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 1 => reg 1 ]
-  [ cmp lt reg 1 0x00000021 ]
-  [ cmp gt reg 1 0x0000002d ]
-
-# frag reserved { 33, 55, 67, 88}
-set%d test-ip4 3
-set%d test-ip4 0
-	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 1 => reg 1 ]
-  [ lookup reg 1 set set%d ]
-
-# frag reserved { 33-55}
-set%d test-ip4 7
-set%d test-ip4 0
-	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
-ip test-ip4 output
-  [ exthdr load 1b @ 44 + 1 => reg 1 ]
-  [ lookup reg 1 set set%d ]
-
-# frag id 1
-ip test-ip4 output
-  [ exthdr load 4b @ 44 + 4 => reg 1 ]
-  [ cmp eq reg 1 0x01000000 ]
-
-# frag id 22
-ip test-ip4 output
-  [ exthdr load 4b @ 44 + 4 => reg 1 ]
-  [ cmp eq reg 1 0x16000000 ]
-
-# frag id != 33
-ip test-ip4 output
-  [ exthdr load 4b @ 44 + 4 => reg 1 ]
-  [ cmp neq reg 1 0x21000000 ]
-
-# frag id 33-45
-ip test-ip4 output
-  [ exthdr load 4b @ 44 + 4 => reg 1 ]
-  [ cmp gte reg 1 0x21000000 ]
-  [ cmp lte reg 1 0x2d000000 ]
-
-# frag id != 33-45
-ip test-ip4 output
-  [ exthdr load 4b @ 44 + 4 => reg 1 ]
-  [ cmp lt reg 1 0x21000000 ]
-  [ cmp gt reg 1 0x2d000000 ]
-
-# frag id { 33, 55, 67, 88}
-set%d test-ip4 3
-set%d test-ip4 0
-	element 21000000  : 0 [end]	element 37000000  : 0 [end]	element 43000000  : 0 [end]	element 58000000  : 0 [end]
-ip test-ip4 output
-  [ exthdr load 4b @ 44 + 4 => reg 1 ]
-  [ lookup reg 1 set set%d ]
-
-# frag id { 33-55}
-set%d test-ip4 7
-set%d test-ip4 0
-	element 00000000  : 1 [end]	element 21000000  : 0 [end]	element 38000000  : 1 [end]
-ip test-ip4 output
-  [ exthdr load 4b @ 44 + 4 => reg 1 ]
-  [ lookup reg 1 set set%d ]
-
diff --git a/tests/py/ip6/frag.t b/tests/py/ip6/frag.t
new file mode 100644
index 0000000..56801ed
--- /dev/null
+++ b/tests/py/ip6/frag.t
@@ -0,0 +1,63 @@
+:output;type filter hook output priority 0
+:ingress;type filter hook ingress device lo priority 0
+
+*ip6;test-ip6;output
+*inet;test-inet;output
+
+frag nexthdr tcp;ok;frag nexthdr 6
+frag nexthdr != icmp;ok;frag nexthdr != 1
+frag nexthdr {esp, ah, comp, udp, udplite, tcp, dccp, sctp};ok;frag nexthdr { 51, 136, 132, 6, 108, 50, 17, 33}
+- frag nexthdr != {esp, ah, comp, udp, udplite, tcp, dccp, sctp};ok
+frag nexthdr esp;ok;frag nexthdr 50
+frag nexthdr ah;ok;frag nexthdr 51
+
+frag reserved 22;ok
+frag reserved != 233;ok
+frag reserved 33-45;ok
+frag reserved != 33-45;ok
+frag reserved { 33, 55, 67, 88};ok
+- frag reserved != { 33, 55, 67, 88};ok
+frag reserved { 33-55};ok
+- frag reserved != { 33-55};ok
+
+# BUG: frag frag-off 22 and frag frag-off { 33-55}
+# This breaks table listing: "netlink: Error: Relational expression size mismatch"
+
+- frag frag-off 22;ok
+- frag frag-off != 233;ok
+- frag frag-off 33-45;ok
+- frag frag-off != 33-45;ok
+- frag frag-off { 33, 55, 67, 88};ok
+- frag frag-off != { 33, 55, 67, 88};ok
+- frag frag-off { 33-55};ok
+- frag frag-off != { 33-55};ok
+
+# BUG  frag reserved2 33 and frag reserved2 1
+# $ sudo nft add rule ip test input frag reserved2 33
+# <cmdline>:1:39-40: Error: Value 33 exceeds valid range 0-3
+# add rule ip test input frag reserved2 33
+#                                      ^^
+# sudo nft add rule ip test input frag reserved2 1
+# <cmdline>:1:1-39: Error: Could not process rule: Invalid argument
+# add rule ip test input frag reserved2 1
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+# BUG more-fragments 1 and frag more-fragments 4
+# frag more-fragments 1
+# <cmdline>:1:1-44: Error: Could not process rule: Invalid argument
+# add rule ip test input frag more-fragments 1
+# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+# $ sudo nft add rule ip test input frag more-fragments 4
+# <cmdline>:1:44-44: Error: Value 4 exceeds valid range 0-1
+# add rule ip test input frag more-fragments 4
+#                                           ^
+
+frag id 1;ok
+frag id 22;ok
+frag id != 33;ok
+frag id 33-45;ok
+frag id != 33-45;ok
+frag id { 33, 55, 67, 88};ok
+- frag id != { 33, 55, 67, 88};ok
+frag id { 33-55};ok
+- frag id != { 33-55};ok
diff --git a/tests/py/ip6/frag.t.payload.ip6 b/tests/py/ip6/frag.t.payload.ip6
new file mode 100644
index 0000000..f2d04b6
--- /dev/null
+++ b/tests/py/ip6/frag.t.payload.ip6
@@ -0,0 +1,109 @@
+# frag nexthdr tcp
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000006 ]
+
+# frag nexthdr != icmp
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp neq reg 1 0x00000001 ]
+
+# frag nexthdr {esp, ah, comp, udp, udplite, tcp, dccp, sctp}
+set%d test-ip6 3
+set%d test-ip6 0
+	element 00000032  : 0 [end]	element 00000033  : 0 [end]	element 0000006c  : 0 [end]	element 00000011  : 0 [end]	element 00000088  : 0 [end]	element 00000006  : 0 [end]	element 00000021  : 0 [end]	element 00000084  : 0 [end]
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag nexthdr esp
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000032 ]
+
+# frag nexthdr ah
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000033 ]
+
+# frag reserved 22
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp eq reg 1 0x00000016 ]
+
+# frag reserved != 233
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp neq reg 1 0x000000e9 ]
+
+# frag reserved 33-45
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp gte reg 1 0x00000021 ]
+  [ cmp lte reg 1 0x0000002d ]
+
+# frag reserved != 33-45
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp lt reg 1 0x00000021 ]
+  [ cmp gt reg 1 0x0000002d ]
+
+# frag reserved { 33, 55, 67, 88}
+set%d test-ip6 3
+set%d test-ip6 0
+	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag reserved { 33-55}
+set%d test-ip6 7
+set%d test-ip6 0
+	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
+ip6 test-ip6 output
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag id 1
+ip6 test-ip6 output
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp eq reg 1 0x01000000 ]
+
+# frag id 22
+ip6 test-ip6 output
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp eq reg 1 0x16000000 ]
+
+# frag id != 33
+ip6 test-ip6 output
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp neq reg 1 0x21000000 ]
+
+# frag id 33-45
+ip6 test-ip6 output
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp gte reg 1 0x21000000 ]
+  [ cmp lte reg 1 0x2d000000 ]
+
+# frag id != 33-45
+ip6 test-ip6 output
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp lt reg 1 0x21000000 ]
+  [ cmp gt reg 1 0x2d000000 ]
+
+# frag id { 33, 55, 67, 88}
+set%d test-ip6 3
+set%d test-ip6 0
+	element 21000000  : 0 [end]	element 37000000  : 0 [end]	element 43000000  : 0 [end]	element 58000000  : 0 [end]
+ip6 test-ip6 output
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag id { 33-55}
+set%d test-ip6 7
+set%d test-ip6 0
+	element 00000000  : 1 [end]	element 21000000  : 0 [end]	element 38000000  : 1 [end]
+ip6 test-ip6 output
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 02/10] netlink: split generic part of netlink_gen_payload_mask into helper
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 01/10] evaluate: enforce ip6 proto with exthdr expression Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 03/10] netlink: add and use netlink_gen_exthdr_mask Florian Westphal
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

netlink_gen_payload_mask assumes expr is a payload expression,
but most of this function would work fine with exthdr too.

So split the gernic part into a helper, followup patch will
add netlink_gen_exthdr_mask.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 src/netlink_linearize.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 86b49c6..7715a28 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -103,12 +103,13 @@ static void netlink_gen_concat(struct netlink_linearize_ctx *ctx,
 	}
 }
 
-static unsigned int payload_shift_calc(const struct expr *expr)
+static unsigned int payload_shift_calc(const struct expr *expr,
+				       unsigned int offset)
 {
-	unsigned int offset, len;
+	unsigned int len;
 	int shift;
 
-	offset = expr->payload.offset % BITS_PER_BYTE;
+	offset %= BITS_PER_BYTE;
 	len = round_up(expr->len, BITS_PER_BYTE);
 	shift = len - (offset + expr->len);
 	assert(shift >= 0);
@@ -116,19 +117,16 @@ static unsigned int payload_shift_calc(const struct expr *expr)
 	return shift;
 }
 
-static void netlink_gen_payload_mask(struct netlink_linearize_ctx *ctx,
-				     const struct expr *expr,
-				     enum nft_registers dreg)
+static void netlink_gen_mask(struct netlink_linearize_ctx *ctx,
+			     const struct expr *expr,
+			     unsigned int shift,
+			     enum nft_registers dreg)
 {
 	struct nft_data_linearize nld, zero = {};
-	unsigned int shift, len, masklen;
+	unsigned int len, masklen;
 	struct nftnl_expr *nle;
 	mpz_t mask;
 
-	shift = payload_shift_calc(expr);
-	if (!shift && expr->payload.offset % BITS_PER_BYTE == 0)
-		return;
-
 	masklen = expr->len + shift;
 	assert(masklen <= NFT_REG_SIZE * BITS_PER_BYTE);
 	mpz_init2(mask, masklen);
@@ -151,6 +149,18 @@ static void netlink_gen_payload_mask(struct netlink_linearize_ctx *ctx,
 	nftnl_rule_add_expr(ctx->nlr, nle);
 }
 
+static void netlink_gen_payload_mask(struct netlink_linearize_ctx *ctx,
+				     const struct expr *expr,
+				     enum nft_registers dreg)
+{
+	unsigned int shift, offset;
+
+	offset = expr->payload.offset % BITS_PER_BYTE;
+	shift = payload_shift_calc(expr, offset);
+	if (shift || offset)
+		netlink_gen_mask(ctx, expr, shift, dreg);
+}
+
 static void netlink_gen_payload(struct netlink_linearize_ctx *ctx,
 				const struct expr *expr,
 				enum nft_registers dreg)
@@ -300,7 +310,8 @@ static void payload_shift_value(const struct expr *left, struct expr *right)
 	    left->ops->type != EXPR_PAYLOAD)
 		return;
 
-	mpz_lshift_ui(right->value, payload_shift_calc(left));
+	mpz_lshift_ui(right->value,
+			payload_shift_calc(left, left->payload.offset));
 }
 
 static struct expr *netlink_gen_prefix(struct netlink_linearize_ctx *ctx,
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 03/10] netlink: add and use netlink_gen_exthdr_mask
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 01/10] evaluate: enforce ip6 proto with exthdr expression Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 02/10] netlink: split generic part of netlink_gen_payload_mask into helper Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 04/10] payload: move payload_gen_dependency generic part to helper Florian Westphal
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

rule ip6 filter input frag frag-off 33

before patch:
 [ exthdr load 1b @ 44 + 2 => reg 1 ]
 [ cmp eq reg 1 0x00002100 ]

We truncated 13bit field to 1 byte.

after patch:
 [ exthdr load 2b @ 44 + 2 => reg 1 ]
 [ bitwise reg 1 = (reg=1 & 0x0000f8ff ) ^ 0x00000000 ]
 [ cmp eq reg 1 0x00000801 ]

- ask for 2 bytes
- mask out the 3 lower bits
- shift the value by 3 so equality test will pass for 33

This causes test failures, will be fixed up in a later patch
(the test suite expects the old, broken input).

It also misses the reverse translation to remove the binop,
find the right template and undo the shift of the value.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 src/netlink_linearize.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 7715a28..7ff3b00 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -181,6 +181,18 @@ static void netlink_gen_payload(struct netlink_linearize_ctx *ctx,
 	netlink_gen_payload_mask(ctx, expr, dreg);
 }
 
+static void netlink_gen_exthdr_mask(struct netlink_linearize_ctx *ctx,
+				    const struct expr *expr,
+				    enum nft_registers dreg)
+{
+	unsigned int shift, offset;
+
+	offset = expr->exthdr.tmpl->offset % BITS_PER_BYTE;
+	shift = payload_shift_calc(expr, offset);
+	if (shift || offset)
+		netlink_gen_mask(ctx, expr, shift, dreg);
+}
+
 static void netlink_gen_exthdr(struct netlink_linearize_ctx *ctx,
 			       const struct expr *expr,
 			       enum nft_registers dreg)
@@ -194,8 +206,10 @@ static void netlink_gen_exthdr(struct netlink_linearize_ctx *ctx,
 	nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_OFFSET,
 			   expr->exthdr.tmpl->offset / BITS_PER_BYTE);
 	nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_LEN,
-			   expr->len / BITS_PER_BYTE);
+			   div_round_up(expr->len, BITS_PER_BYTE));
 	nftnl_rule_add_expr(ctx->nlr, nle);
+
+	netlink_gen_exthdr_mask(ctx, expr, dreg);
 }
 
 static void netlink_gen_meta(struct netlink_linearize_ctx *ctx,
@@ -306,10 +320,17 @@ static void netlink_gen_range(struct netlink_linearize_ctx *ctx,
 
 static void payload_shift_value(const struct expr *left, struct expr *right)
 {
-	if (right->ops->type != EXPR_VALUE ||
-	    left->ops->type != EXPR_PAYLOAD)
+	if (right->ops->type != EXPR_VALUE)
 		return;
 
+	switch (left->ops->type) {
+	case EXPR_PAYLOAD:
+	case EXPR_EXTHDR:
+		break;
+	default:
+		return;
+	}
+
 	mpz_lshift_ui(right->value,
 			payload_shift_calc(left, left->payload.offset));
 }
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 04/10] payload: move payload_gen_dependency generic part to helper
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (2 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 03/10] netlink: add and use netlink_gen_exthdr_mask Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 05/10] exthdr: generate dependencies for inet/bridge/netdev family Florian Westphal
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

We should treat exthdr just as if user asked for e.g. ip6 saddr
and inject the needed dependency statement.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 src/payload.c | 66 ++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 38 insertions(+), 28 deletions(-)

diff --git a/src/payload.c b/src/payload.c
index 6a977e8..8f67b6e 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -162,6 +162,43 @@ struct stmt *payload_stmt_alloc(const struct location *loc,
 	return stmt;
 }
 
+static int payload_add_dependency(struct eval_ctx *ctx,
+				  const struct proto_desc *desc,
+				  const struct proto_desc *upper,
+				  const struct expr *expr,
+				  struct stmt **res)
+{
+	const struct proto_hdr_template *tmpl;
+	struct expr *dep, *left, *right;
+	struct stmt *stmt;
+	int protocol = proto_find_num(desc, upper);
+
+	if (protocol < 0)
+		return expr_error(ctx->msgs, expr,
+				  "conflicting protocols specified: %s vs. %s",
+				  desc->name, upper->name);
+
+	tmpl = &desc->templates[desc->protocol_key];
+	if (tmpl->meta_key)
+		left = meta_expr_alloc(&expr->location, tmpl->meta_key);
+	else
+		left = payload_expr_alloc(&expr->location, desc, desc->protocol_key);
+
+	right = constant_expr_alloc(&expr->location, tmpl->dtype,
+				    tmpl->dtype->byteorder, tmpl->len,
+				    constant_data_ptr(protocol, tmpl->len));
+
+	dep = relational_expr_alloc(&expr->location, OP_EQ, left, right);
+	stmt = expr_stmt_alloc(&dep->location, dep);
+	if (stmt_evaluate(ctx, stmt) < 0) {
+		return expr_error(ctx->msgs, expr,
+					  "dependency statement is invalid");
+	}
+	left->ops->pctx_update(&ctx->pctx, dep);
+	*res = stmt;
+	return 0;
+}
+
 /**
  * payload_gen_dependency - generate match expression on payload dependency
  *
@@ -190,10 +227,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
 {
 	const struct hook_proto_desc *h = &hook_proto_desc[ctx->pctx.family];
 	const struct proto_desc *desc;
-	const struct proto_hdr_template *tmpl;
-	struct expr *dep, *left, *right;
 	struct stmt *stmt;
-	int protocol;
 	uint16_t type;
 
 	if (expr->payload.base < h->base) {
@@ -265,31 +299,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
 				  "no %s protocol specified",
 				  proto_base_names[expr->payload.base - 1]);
 
-	protocol = proto_find_num(desc, expr->payload.desc);
-	if (protocol < 0)
-		return expr_error(ctx->msgs, expr,
-				  "conflicting protocols specified: %s vs. %s",
-				  desc->name, expr->payload.desc->name);
-
-	tmpl = &desc->templates[desc->protocol_key];
-	if (tmpl->meta_key)
-		left = meta_expr_alloc(&expr->location, tmpl->meta_key);
-	else
-		left = payload_expr_alloc(&expr->location, desc, desc->protocol_key);
-
-	right = constant_expr_alloc(&expr->location, tmpl->dtype,
-				    tmpl->dtype->byteorder, tmpl->len,
-				    constant_data_ptr(protocol, tmpl->len));
-
-	dep = relational_expr_alloc(&expr->location, OP_EQ, left, right);
-	stmt = expr_stmt_alloc(&dep->location, dep);
-	if (stmt_evaluate(ctx, stmt) < 0) {
-		return expr_error(ctx->msgs, expr,
-					  "dependency statement is invalid");
-	}
-	left->ops->pctx_update(&ctx->pctx, dep);
-	*res = stmt;
-	return 0;
+	return payload_add_dependency(ctx, desc, expr->payload.desc, expr, res);
 }
 
 /**
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 05/10] exthdr: generate dependencies for inet/bridge/netdev family
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (3 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 04/10] payload: move payload_gen_dependency generic part to helper Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 06/10] tests: add/fix inet+exthdr tests Florian Westphal
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Should treat this as if user would have asked to match ipv6 header field.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/payload.h |  2 ++
 src/evaluate.c    | 17 ++++++++++++++---
 src/payload.c     | 15 +++++++++++++++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/include/payload.h b/include/payload.h
index 9192d6e..a19e690 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -14,6 +14,8 @@ struct eval_ctx;
 struct stmt;
 extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
 				  struct stmt **res);
+extern int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
+				  struct stmt **res);
 
 extern bool payload_is_adjacent(const struct expr *e1, const struct expr *e2);
 extern struct expr *payload_expr_join(const struct expr *e1,
diff --git a/src/evaluate.c b/src/evaluate.c
index 47a1f8c..28e17cb 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -344,18 +344,29 @@ conflict_resolution_gen_dependency(struct eval_ctx *ctx, int protocol,
 }
 
 /*
- * Exthdr expression: check whether dependencies are fulfilled.
+ * Exthdr expression: check whether dependencies are fulfilled, otherwise
+ * generate the necessary relational expression and prepend it to the current
+ * statement.
  */
 static int expr_evaluate_exthdr(struct eval_ctx *ctx, struct expr **expr)
 {
 	const struct proto_desc *base;
+	struct stmt *nstmt;
 
 	base = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc;
 	if (base == &proto_ip6)
 		return expr_evaluate_primary(ctx, expr);
 
-	return expr_error(ctx->msgs, *expr,
-			  "exthdr can only be used with ipv6");
+	if (base)
+		return expr_error(ctx->msgs, *expr,
+				  "cannot use exthdr with %s", base->name);
+
+	if (exthdr_gen_dependency(ctx, *expr, &nstmt) < 0)
+		return -1;
+
+	list_add(&nstmt->list, &ctx->rule->stmts);
+
+	return expr_evaluate_primary(ctx, expr);
 }
 
 /* dependency supersede.
diff --git a/src/payload.c b/src/payload.c
index 8f67b6e..7e38061 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -302,6 +302,21 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
 	return payload_add_dependency(ctx, desc, expr->payload.desc, expr, res);
 }
 
+int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
+			  struct stmt **res)
+{
+	const struct proto_desc *desc;
+
+	desc = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc;
+	if (desc == NULL)
+		return expr_error(ctx->msgs, expr,
+				  "Cannot generate dependency: "
+				  "no %s protocol specified",
+				  proto_base_names[PROTO_BASE_LL_HDR]);
+
+	return payload_add_dependency(ctx, desc, &proto_ip6, expr, res);
+}
+
 /**
  * payload_expr_complete - fill in type information of a raw payload expr
  *
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 06/10] tests: add/fix inet+exthdr tests
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (4 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 05/10] exthdr: generate dependencies for inet/bridge/netdev family Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 07/10] exthdr: remove implicit dependencies Florian Westphal
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

exhdr needs to be treated as if we'd test an ipv6 header field, i.e.
inet, bridge, netdev need to add a dependency on ipv6 protocol.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 tests/py/ip6/dst.t.payload.inet  |  30 ++++++++
 tests/py/ip6/frag.t.payload.inet | 145 +++++++++++++++++++++++++++++++++++++++
 tests/py/ip6/hbh.t.payload.inet  |  30 ++++++++
 tests/py/ip6/mh.t.payload.inet   |  64 +++++++++++++++++
 tests/py/ip6/rt.t.payload.inet   |  58 ++++++++++++++++
 5 files changed, 327 insertions(+)
 create mode 100644 tests/py/ip6/frag.t.payload.inet

diff --git a/tests/py/ip6/dst.t.payload.inet b/tests/py/ip6/dst.t.payload.inet
index 7a219f4..348506d 100644
--- a/tests/py/ip6/dst.t.payload.inet
+++ b/tests/py/ip6/dst.t.payload.inet
@@ -1,21 +1,29 @@
 # dst nexthdr 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # dst nexthdr != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # dst nexthdr 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # dst nexthdr != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -25,6 +33,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -33,6 +43,8 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -41,37 +53,51 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000088  : 0 [end]	element 0000006c  : 0 [end]	element 00000011  : 0 [end]	element 00000033  : 0 [end]	element 00000084  : 0 [end]	element 00000032  : 0 [end]	element 00000021  : 0 [end]	element 00000006  : 0 [end]	element 0000003a  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # dst nexthdr icmp
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # dst nexthdr != icmp
 ip6 test-ip6 input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 0 => reg 1 ]
   [ cmp neq reg 1 0x00000001 ]
 
 # dst hdrlength 22
 ip6 test-ip6 input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 1 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # dst hdrlength != 233
 ip6 test-ip6 input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 1 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # dst hdrlength 33-45
 ip6 test-ip6 input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 1 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # dst hdrlength != 33-45
 ip6 test-ip6 input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 1 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -81,6 +107,8 @@ set%d test-ip6 3
 set%d test-ip6 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 ip6 test-ip6 input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -89,6 +117,8 @@ set%d test-ip6 7
 set%d test-ip6 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 ip6 test-ip6 input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 60 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
diff --git a/tests/py/ip6/frag.t.payload.inet b/tests/py/ip6/frag.t.payload.inet
new file mode 100644
index 0000000..7cedaf3
--- /dev/null
+++ b/tests/py/ip6/frag.t.payload.inet
@@ -0,0 +1,145 @@
+# frag nexthdr tcp
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000006 ]
+
+# frag nexthdr != icmp
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp neq reg 1 0x00000001 ]
+
+# frag nexthdr {esp, ah, comp, udp, udplite, tcp, dccp, sctp}
+set%d test-inet 3
+set%d test-inet 0
+	element 00000032  : 0 [end]	element 00000033  : 0 [end]	element 0000006c  : 0 [end]	element 00000011  : 0 [end]	element 00000088  : 0 [end]	element 00000006  : 0 [end]	element 00000021  : 0 [end]	element 00000084  : 0 [end]
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag nexthdr esp
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000032 ]
+
+# frag nexthdr ah
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000033 ]
+
+# frag reserved 22
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp eq reg 1 0x00000016 ]
+
+# frag reserved != 233
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp neq reg 1 0x000000e9 ]
+
+# frag reserved 33-45
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp gte reg 1 0x00000021 ]
+  [ cmp lte reg 1 0x0000002d ]
+
+# frag reserved != 33-45
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ cmp lt reg 1 0x00000021 ]
+  [ cmp gt reg 1 0x0000002d ]
+
+# frag reserved { 33, 55, 67, 88}
+set%d test-inet 3
+set%d test-inet 0
+	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag reserved { 33-55}
+set%d test-inet 7
+set%d test-inet 0
+	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 1b @ 44 + 1 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag id 1
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp eq reg 1 0x01000000 ]
+
+# frag id 22
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp eq reg 1 0x16000000 ]
+
+# frag id != 33
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp neq reg 1 0x21000000 ]
+
+# frag id 33-45
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp gte reg 1 0x21000000 ]
+  [ cmp lte reg 1 0x2d000000 ]
+
+# frag id != 33-45
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ cmp lt reg 1 0x21000000 ]
+  [ cmp gt reg 1 0x2d000000 ]
+
+# frag id { 33, 55, 67, 88}
+set%d test-inet 3
+set%d test-inet 0
+	element 21000000  : 0 [end]	element 37000000  : 0 [end]	element 43000000  : 0 [end]	element 58000000  : 0 [end]
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
+# frag id { 33-55}
+set%d test-inet 7
+set%d test-inet 0
+	element 00000000  : 1 [end]	element 21000000  : 0 [end]	element 38000000  : 1 [end]
+inet test-inet output
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
+  [ exthdr load 4b @ 44 + 4 => reg 1 ]
+  [ lookup reg 1 set set%d ]
+
diff --git a/tests/py/ip6/hbh.t.payload.inet b/tests/py/ip6/hbh.t.payload.inet
index 2b4c9c7..e9a583f 100644
--- a/tests/py/ip6/hbh.t.payload.inet
+++ b/tests/py/ip6/hbh.t.payload.inet
@@ -1,21 +1,29 @@
 # hbh hdrlength 22
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 1 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # hbh hdrlength != 233
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 1 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # hbh hdrlength 33-45
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 1 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # hbh hdrlength != 33-45
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 1 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -25,6 +33,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -33,6 +43,8 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -41,27 +53,37 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000032  : 0 [end]	element 00000033  : 0 [end]	element 0000006c  : 0 [end]	element 00000011  : 0 [end]	element 00000088  : 0 [end]	element 00000006  : 0 [end]	element 00000021  : 0 [end]	element 00000084  : 0 [end]	element 0000003a  : 0 [end]
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # hbh nexthdr 22
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # hbh nexthdr != 233
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # hbh nexthdr 33-45
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # hbh nexthdr != 33-45
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -71,6 +93,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -79,16 +103,22 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # hbh nexthdr ip
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000000 ]
 
 # hbh nexthdr != ip
 inet test-inet filter-input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 0 + 0 => reg 1 ]
   [ cmp neq reg 1 0x00000000 ]
 
diff --git a/tests/py/ip6/mh.t.payload.inet b/tests/py/ip6/mh.t.payload.inet
index 53a0ce0..8be80e2 100644
--- a/tests/py/ip6/mh.t.payload.inet
+++ b/tests/py/ip6/mh.t.payload.inet
@@ -1,10 +1,14 @@
 # mh nexthdr 1
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # mh nexthdr != 1
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp neq reg 1 0x00000001 ]
 
@@ -13,37 +17,51 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000088  : 0 [end]	element 0000006c  : 0 [end]	element 00000011  : 0 [end]	element 00000033  : 0 [end]	element 00000084  : 0 [end]	element 00000032  : 0 [end]	element 00000021  : 0 [end]	element 00000006  : 0 [end]	element 0000003a  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # mh nexthdr icmp
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # mh nexthdr != icmp
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp neq reg 1 0x00000001 ]
 
 # mh nexthdr 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # mh nexthdr != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # mh nexthdr 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # mh nexthdr != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -53,6 +71,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -61,27 +81,37 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # mh hdrlength 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 1 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # mh hdrlength != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 1 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # mh hdrlength 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 1 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # mh hdrlength != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 1 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -91,6 +121,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -99,6 +131,8 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -107,37 +141,51 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000000  : 0 [end]	element 00000001  : 0 [end]	element 00000002  : 0 [end]	element 00000003  : 0 [end]	element 00000004  : 0 [end]	element 00000005  : 0 [end]	element 00000006  : 0 [end]	element 00000007  : 0 [end]	element 00000008  : 0 [end]	element 00000009  : 0 [end]	element 0000000a  : 0 [end]	element 0000000b  : 0 [end]	element 0000000c  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 2 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # mh type home-agent-switch-message
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 2 => reg 1 ]
   [ cmp eq reg 1 0x0000000c ]
 
 # mh type != home-agent-switch-message
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 2 => reg 1 ]
   [ cmp neq reg 1 0x0000000c ]
 
 # mh reserved 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 3 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # mh reserved != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 3 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # mh reserved 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 3 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # mh reserved != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 3 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -147,6 +195,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 3 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -155,27 +205,37 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 135 + 3 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # mh checksum 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 2b @ 135 + 4 => reg 1 ]
   [ cmp eq reg 1 0x00001600 ]
 
 # mh checksum != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 2b @ 135 + 4 => reg 1 ]
   [ cmp neq reg 1 0x0000e900 ]
 
 # mh checksum 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 2b @ 135 + 4 => reg 1 ]
   [ cmp gte reg 1 0x00002100 ]
   [ cmp lte reg 1 0x00002d00 ]
 
 # mh checksum != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 2b @ 135 + 4 => reg 1 ]
   [ cmp lt reg 1 0x00002100 ]
   [ cmp gt reg 1 0x00002d00 ]
@@ -185,6 +245,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00002100  : 0 [end]	element 00003700  : 0 [end]	element 00004300  : 0 [end]	element 00005800  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 2b @ 135 + 4 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -193,6 +255,8 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00002100  : 0 [end]	element 00003800  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 2b @ 135 + 4 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
diff --git a/tests/py/ip6/rt.t.payload.inet b/tests/py/ip6/rt.t.payload.inet
index 9dc51b9..e7a7123 100644
--- a/tests/py/ip6/rt.t.payload.inet
+++ b/tests/py/ip6/rt.t.payload.inet
@@ -1,10 +1,14 @@
 # rt nexthdr 1
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # rt nexthdr != 1
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp neq reg 1 0x00000001 ]
 
@@ -13,37 +17,51 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000088  : 0 [end]	element 0000006c  : 0 [end]	element 00000011  : 0 [end]	element 00000033  : 0 [end]	element 00000084  : 0 [end]	element 00000032  : 0 [end]	element 00000021  : 0 [end]	element 00000006  : 0 [end]	element 0000003a  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # rt nexthdr icmp
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000001 ]
 
 # rt nexthdr != icmp
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp neq reg 1 0x00000001 ]
 
 # rt nexthdr 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # rt nexthdr != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # rt nexthdr 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # rt nexthdr != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -53,6 +71,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -61,27 +81,37 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 0 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # rt hdrlength 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 1 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # rt hdrlength != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 1 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # rt hdrlength 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 1 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # rt hdrlength != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 1 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -91,6 +121,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -99,27 +131,37 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 1 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # rt type 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 2 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # rt type != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 2 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # rt type 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 2 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # rt type != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 2 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -129,6 +171,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 2 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -137,27 +181,37 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 2 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
 # rt seg-left 22
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 3 => reg 1 ]
   [ cmp eq reg 1 0x00000016 ]
 
 # rt seg-left != 233
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 3 => reg 1 ]
   [ cmp neq reg 1 0x000000e9 ]
 
 # rt seg-left 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 3 => reg 1 ]
   [ cmp gte reg 1 0x00000021 ]
   [ cmp lte reg 1 0x0000002d ]
 
 # rt seg-left != 33-45
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 3 => reg 1 ]
   [ cmp lt reg 1 0x00000021 ]
   [ cmp gt reg 1 0x0000002d ]
@@ -167,6 +221,8 @@ set%d test-inet 3
 set%d test-inet 0
 	element 00000021  : 0 [end]	element 00000037  : 0 [end]	element 00000043  : 0 [end]	element 00000058  : 0 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 3 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
@@ -175,6 +231,8 @@ set%d test-inet 7
 set%d test-inet 0
 	element 00000000  : 1 [end]	element 00000021  : 0 [end]	element 00000038  : 1 [end]
 inet test-inet input
+  [ meta load nfproto => reg 1 ]
+  [ cmp eq reg 1 0x0000000a ]
   [ exthdr load 1b @ 43 + 3 => reg 1 ]
   [ lookup reg 1 set set%d ]
 
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 07/10] exthdr: remove implicit dependencies
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (5 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 06/10] tests: add/fix inet+exthdr tests Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 08/10] exthdr: store offset for later use Florian Westphal
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

exthdr expression requires a dependency on ipv6; we can
thus remove an ipv6 protocol test if its present.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 src/netlink_delinearize.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index ae6abb0..eec7d0f 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -982,10 +982,10 @@ struct rule_pp_ctx {
 /*
  * Kill a redundant payload dependecy that is implied by a higher layer payload expression.
  */
-static void payload_dependency_kill(struct rule_pp_ctx *ctx, struct expr *expr)
+static void __payload_dependency_kill(struct rule_pp_ctx *ctx, enum proto_bases base)
 {
 	if (ctx->pbase != PROTO_BASE_INVALID &&
-	    ctx->pbase == expr->payload.base &&
+	    ctx->pbase == base &&
 	    ctx->pdep != NULL) {
 		list_del(&ctx->pdep->list);
 		stmt_free(ctx->pdep);
@@ -996,6 +996,11 @@ static void payload_dependency_kill(struct rule_pp_ctx *ctx, struct expr *expr)
 	}
 }
 
+static void payload_dependency_kill(struct rule_pp_ctx *ctx, const struct expr *expr)
+{
+	__payload_dependency_kill(ctx, expr->payload.base);
+}
+
 static void payload_dependency_store(struct rule_pp_ctx *ctx,
 				     struct stmt *stmt,
 				     enum proto_bases base)
@@ -1505,8 +1510,10 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 	case EXPR_SET_ELEM:
 		expr_postprocess(ctx, &expr->key);
 		break;
-	case EXPR_SET_REF:
 	case EXPR_EXTHDR:
+		__payload_dependency_kill(ctx, PROTO_BASE_NETWORK_HDR);
+		break;
+	case EXPR_SET_REF:
 	case EXPR_META:
 	case EXPR_VERDICT:
 		break;
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 08/10] exthdr: store offset for later use
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (6 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 07/10] exthdr: remove implicit dependencies Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 09/10] netlink_delinearize: prepare binop_postprocess for exthdr demux Florian Westphal
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

Its possible that we cannot find the template without also
considering an implicit mask.  For this we need to store the offset.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/expression.h | 1 +
 src/exthdr.c         | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/include/expression.h b/include/expression.h
index eacbb2d..72b6f69 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -264,6 +264,7 @@ struct expr {
 			/* EXPR_EXTHDR */
 			const struct exthdr_desc	*desc;
 			const struct proto_hdr_template	*tmpl;
+			unsigned int			offset;
 		} exthdr;
 		struct {
 			/* EXPR_META */
diff --git a/src/exthdr.c b/src/exthdr.c
index 9ed0b6a..512de0a 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -37,6 +37,7 @@ static void exthdr_expr_clone(struct expr *new, const struct expr *expr)
 {
 	new->exthdr.desc = expr->exthdr.desc;
 	new->exthdr.tmpl = expr->exthdr.tmpl;
+	new->exthdr.offset = expr->exthdr.offset;
 }
 
 static const struct expr_ops exthdr_expr_ops = {
@@ -86,6 +87,7 @@ void exthdr_init_raw(struct expr *expr, uint8_t type,
 	assert(expr->ops->type == EXPR_EXTHDR);
 
 	expr->len = len;
+	expr->exthdr.offset = offset;
 	expr->exthdr.desc = exthdr_protocols[type];
 	assert(expr->exthdr.desc != NULL);
 
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 09/10] netlink_delinearize: prepare binop_postprocess for exthdr demux
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (7 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 08/10] exthdr: store offset for later use Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-01 15:37 ` [PATCH nft 10/10] netlink_delinearize: handle extension header templates with odd sizes Florian Westphal
  2016-03-02 12:00 ` [PATCH nft 00/10] nft: exthdr fixes and improvements Pablo Neira Ayuso
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

binop_postprocess takes care of removing masks if we're dealing
with payload expressions that have non-byte divisible sizes
or offsets.

Same can happen when matching some extension header fields, i.e.
this also needs to handle exthdr expression, not just payload.

So rename payload to left and move test for left type to
binop_postprocess.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 src/netlink_delinearize.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index eec7d0f..30c5f62 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1213,12 +1213,12 @@ static struct expr *binop_tree_to_list(struct expr *list, struct expr *expr)
 static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
 {
 	struct expr *binop = expr->left, *value = expr->right;
-
-	struct expr *payload = binop->left;
+	struct expr *left = binop->left;
 	struct expr *mask = binop->right;
 	unsigned int shift;
 
-	if (payload_expr_trim(payload, mask, &ctx->pctx, &shift)) {
+	if ((left->ops->type == EXPR_PAYLOAD &&
+	    payload_expr_trim(left, mask, &ctx->pctx, &shift))) {
 		/* mask is implicit, binop needs to be removed.
 		 *
 		 * Fix all values of the expression according to the mask
@@ -1231,15 +1231,15 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
 		if (value->ops->type == EXPR_VALUE) {
 			assert(value->len >= expr->left->right->len);
 			mpz_rshift_ui(value->value, shift);
-			value->len = payload->len;
+			value->len = left->len;
 		}
 
 		assert(expr->left->ops->type == EXPR_BINOP);
-		assert(binop->left == payload);
-		expr->left = expr_get(payload);
+		assert(binop->left == left);
+		expr->left = expr_get(left);
 		expr_free(binop);
 
-		payload_match_postprocess(ctx, expr, payload);
+		payload_match_postprocess(ctx, expr, left);
 	}
 }
 
@@ -1285,7 +1285,6 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e
 		expr_free(value);
 		expr_free(binop);
 	} else if (binop->op == OP_AND &&
-		   binop->left->ops->type == EXPR_PAYLOAD &&
 		   binop->right->ops->type == EXPR_VALUE) {
 		/*
 		 * This *might* be a payload match testing header fields that
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH nft 10/10] netlink_delinearize: handle extension header templates with odd sizes
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (8 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 09/10] netlink_delinearize: prepare binop_postprocess for exthdr demux Florian Westphal
@ 2016-03-01 15:37 ` Florian Westphal
  2016-03-02 12:00 ` [PATCH nft 00/10] nft: exthdr fixes and improvements Pablo Neira Ayuso
  10 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2016-03-01 15:37 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Florian Westphal

This enables nft to display
	frag frag-off 33

... by considering a mask during binop postprocess in case
the initial template lookup done when the exthdr expression was
created did not yield a match.

In the above example, kernel netlink data specifies 16bits,
but the frag field is only 13bits wide.

We use the implicit binop mask to re-do the template lookup with
corrected offset and size information.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/exthdr.h          |  2 ++
 src/exthdr.c              | 31 +++++++++++++++++++++++++++++++
 src/netlink_delinearize.c | 12 ++++++++----
 3 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/include/exthdr.h b/include/exthdr.h
index 87c4285..d17841b 100644
--- a/include/exthdr.h
+++ b/include/exthdr.h
@@ -23,6 +23,8 @@ extern struct expr *exthdr_expr_alloc(const struct location *loc,
 extern void exthdr_init_raw(struct expr *expr, uint8_t type,
 			    unsigned int offset, unsigned int len);
 
+extern bool exthdr_find_template(struct expr *expr, const struct expr *mask,
+				 unsigned int *shift);
 
 enum hbh_hdr_fields {
 	HBHHDR_INVALID,
diff --git a/src/exthdr.c b/src/exthdr.c
index 512de0a..f392cff 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -102,6 +102,37 @@ void exthdr_init_raw(struct expr *expr, uint8_t type,
 	}
 }
 
+static unsigned int mask_length(const struct expr *mask)
+{
+	unsigned long off = mpz_scan1(mask->value, 0);
+
+	return mpz_scan0(mask->value, off + 1);
+}
+
+bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned int *shift)
+{
+	unsigned int off, mask_offset, mask_len;
+
+	if (expr->exthdr.tmpl != &exthdr_unknown_template)
+		return false;
+
+	mask_offset = mpz_scan1(mask->value, 0);
+	mask_len = mask_length(mask);
+
+	off = expr->exthdr.offset;
+	off += round_up(mask->len, BITS_PER_BYTE) - mask_len;
+
+	exthdr_init_raw(expr, expr->exthdr.desc->type,
+			off, mask_len - mask_offset);
+
+	/* still failed to find a template... Bug. */
+	if (expr->exthdr.tmpl == &exthdr_unknown_template)
+		return false;
+
+	*shift = mask_offset;
+	return true;
+}
+
 #define HDR_TEMPLATE(__name, __dtype, __type, __member)			\
 	PROTO_HDR_TEMPLATE(__name, __dtype,				\
 			   BYTEORDER_BIG_ENDIAN,			\
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 30c5f62..fae6e33 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1218,7 +1218,9 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
 	unsigned int shift;
 
 	if ((left->ops->type == EXPR_PAYLOAD &&
-	    payload_expr_trim(left, mask, &ctx->pctx, &shift))) {
+	    payload_expr_trim(left, mask, &ctx->pctx, &shift)) ||
+	    (left->ops->type == EXPR_EXTHDR &&
+	     exthdr_find_template(left, mask, &shift))) {
 		/* mask is implicit, binop needs to be removed.
 		 *
 		 * Fix all values of the expression according to the mask
@@ -1226,7 +1228,7 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
 		 * sizes and offsets we're interested in.
 		 *
 		 * Finally, convert the expression to 1) by replacing
-		 * the binop with the binop payload expr.
+		 * the binop with the binop payload/exthdr expression.
 		 */
 		if (value->ops->type == EXPR_VALUE) {
 			assert(value->len >= expr->left->right->len);
@@ -1238,8 +1240,10 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
 		assert(binop->left == left);
 		expr->left = expr_get(left);
 		expr_free(binop);
-
-		payload_match_postprocess(ctx, expr, left);
+		if (left->ops->type == EXPR_PAYLOAD)
+			payload_match_postprocess(ctx, expr, left);
+		else if (left->ops->type == EXPR_EXTHDR)
+			expr_set_type(expr->right, left->dtype, left->byteorder);
 	}
 }
 
-- 
2.4.10


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH nft 00/10] nft: exthdr fixes and improvements
  2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
                   ` (9 preceding siblings ...)
  2016-03-01 15:37 ` [PATCH nft 10/10] netlink_delinearize: handle extension header templates with odd sizes Florian Westphal
@ 2016-03-02 12:00 ` Pablo Neira Ayuso
  10 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2016-03-02 12:00 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel

Hi Florian,

On Tue, Mar 01, 2016 at 04:37:40PM +0100, Florian Westphal wrote:
> This adds following enhancements and fixes for the exthdr
> expression.
> 
> #1.  Treat exthdr as if user asked for an ip6 protocol header field,
> i.e. add ipv6 dependency for bridge/netdev/inet family.
> 
> #2.  Add scaling and masking to handle protocol headers that have
> non-byte divisible sizes.
> 
> Tested briefly with following dummy rules (nf_defrag_ipv6 module not loaded):
> 
> frag frag-off 0 counter packets 40 bytes 59840
> frag frag-off 131 counter packets 0 bytes 0
> frag frag-off 1448 counter packets 0 bytes 0
> frag frag-off 181 counter packets 40 bytes 59840
> frag frag-off > 0 counter packets 120 bytes 148160
> 
> Note that the offsets are *NOT* scaled, i.e. we match the raw values
> contained in the packet.  To match offset of 1448 one thus needs to
> ask for 181.
> 
> This is same behaviour as ip hdrlength, where 5 matches a value of 20 bytes.

This looks good to me.

I still think we should move part of this to the evaluation phase so
we catch other corner cases, but we can revisit that later on. Willing
to have a look at this at some point.

Thanks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-03-02 12:00 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-01 15:37 [PATCH nft 00/10] nft: exthdr fixes and improvements Florian Westphal
2016-03-01 15:37 ` [PATCH nft 01/10] evaluate: enforce ip6 proto with exthdr expression Florian Westphal
2016-03-01 15:37 ` [PATCH nft 02/10] netlink: split generic part of netlink_gen_payload_mask into helper Florian Westphal
2016-03-01 15:37 ` [PATCH nft 03/10] netlink: add and use netlink_gen_exthdr_mask Florian Westphal
2016-03-01 15:37 ` [PATCH nft 04/10] payload: move payload_gen_dependency generic part to helper Florian Westphal
2016-03-01 15:37 ` [PATCH nft 05/10] exthdr: generate dependencies for inet/bridge/netdev family Florian Westphal
2016-03-01 15:37 ` [PATCH nft 06/10] tests: add/fix inet+exthdr tests Florian Westphal
2016-03-01 15:37 ` [PATCH nft 07/10] exthdr: remove implicit dependencies Florian Westphal
2016-03-01 15:37 ` [PATCH nft 08/10] exthdr: store offset for later use Florian Westphal
2016-03-01 15:37 ` [PATCH nft 09/10] netlink_delinearize: prepare binop_postprocess for exthdr demux Florian Westphal
2016-03-01 15:37 ` [PATCH nft 10/10] netlink_delinearize: handle extension header templates with odd sizes Florian Westphal
2016-03-02 12:00 ` [PATCH nft 00/10] nft: exthdr fixes and improvements Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).