]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
icmpv6: Allow matching target address in NS/NA, redirect and MLD
authorNicolas Cavallari <nicolas.cavallari@green-communications.fr>
Wed, 20 Sep 2023 15:03:34 +0000 (17:03 +0200)
committerFlorian Westphal <fw@strlen.de>
Fri, 6 Oct 2023 09:22:20 +0000 (11:22 +0200)
It was currently not possible to match the target address of a neighbor
solicitation or neighbor advertisement against a dynamic set, unlike in
IPv4.

Since they are many ICMPv6 messages with an address at the same offset,
allow filtering on the target address for all icmp types that have one.

While at it, also allow matching the destination address of an ICMPv6
redirect.

Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
Signed-off-by: Florian Westphal <fw@strlen.de>
doc/payload-expression.txt
include/proto.h
src/parser_bison.y
src/payload.c
src/proto.c
src/scanner.l
tests/py/ip6/icmpv6.t
tests/py/ip6/icmpv6.t.json
tests/py/ip6/icmpv6.t.payload.ip6

index 505cc0aa954de37369c32d96964ad2d50e78a5a5..c7c267daee0c8e4d27017f5d74da8a62239de63c 100644 (file)
@@ -269,7 +269,7 @@ ip6 nexthdr ipv6-frag
 ICMPV6 HEADER EXPRESSION
 ~~~~~~~~~~~~~~~~~~~~~~~~
 [verse]
-*icmpv6* {*type* | *code* | *checksum* | *parameter-problem* | *packet-too-big* | *id* | *sequence* | *max-delay*}
+*icmpv6* {*type* | *code* | *checksum* | *parameter-problem* | *packet-too-big* | *id* | *sequence* | *max-delay* | *taddr* | *daddr*}
 
 This expression refers to ICMPv6 header fields. When using it in *inet*,
 *bridge* or *netdev* families, it will cause an implicit dependency on IPv6 to
@@ -304,6 +304,12 @@ integer (16 bit)
 |max-delay|
 maximum response delay of MLD queries|
 integer (16 bit)
+|taddr|
+target address of neighbor solicit/advert, redirect or MLD|
+ipv6_addr
+|daddr|
+destination address of redirect|
+ipv6_addr
 |==============================
 
 TCP HEADER EXPRESSION
index 3a20ff8c4071fb1e884135896726e5796160a14d..9c98a0b7db3fbe6352dd4da0e24401fd56019b76 100644 (file)
@@ -35,6 +35,8 @@ enum icmp_hdr_field_type {
        PROTO_ICMP6_PPTR,
        PROTO_ICMP6_ECHO,
        PROTO_ICMP6_MGMQ,
+       PROTO_ICMP6_ADDRESS,    /* neighbor solicit/advert, redirect and MLD */
+       PROTO_ICMP6_REDIRECT,
 };
 
 /**
@@ -305,6 +307,8 @@ enum icmp6_hdr_fields {
        ICMP6HDR_ID,
        ICMP6HDR_SEQ,
        ICMP6HDR_MAXDELAY,
+       ICMP6HDR_TADDR,
+       ICMP6HDR_DADDR,
 };
 
 enum ip6_hdr_fields {
index bfd53ab3b63a95c00f23a463b0f3aefe9a1ef191..c517dc38b37d6c3884580c86d8b603deeff98fba 100644 (file)
@@ -422,6 +422,7 @@ int nft_lex(void *, void *, void *);
 %token ICMP6                   "icmpv6"
 %token PPTR                    "param-problem"
 %token MAXDELAY                        "max-delay"
+%token TADDR                   "taddr"
 
 %token AH                      "ah"
 %token RESERVED                        "reserved"
@@ -5746,6 +5747,8 @@ icmp6_hdr_field           :       TYPE            close_scope_type        { $$ = ICMP6HDR_TYPE; }
                        |       ID              { $$ = ICMP6HDR_ID; }
                        |       SEQUENCE        { $$ = ICMP6HDR_SEQ; }
                        |       MAXDELAY        { $$ = ICMP6HDR_MAXDELAY; }
+                       |       TADDR           { $$ = ICMP6HDR_TADDR; }
+                       |       DADDR           { $$ = ICMP6HDR_DADDR; }
                        ;
 
 auth_hdr_expr          :       AH      auth_hdr_field  close_scope_ah
index 89bb38eb00999bc75133054d5efd41291f61e2cb..140ca50addf731fc053ed9e829dcd2f30670f0e3 100644 (file)
@@ -793,11 +793,40 @@ static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t)
        case PROTO_ICMP6_MTU: return ICMP6_PACKET_TOO_BIG;
        case PROTO_ICMP6_MGMQ: return MLD_LISTENER_QUERY;
        case PROTO_ICMP6_PPTR: return ICMP6_PARAM_PROB;
+       case PROTO_ICMP6_REDIRECT: return ND_REDIRECT;
+       case PROTO_ICMP6_ADDRESS: return ND_NEIGHBOR_SOLICIT;
        }
 
        BUG("Missing icmp type mapping");
 }
 
+static bool icmp_dep_type_match(enum icmp_hdr_field_type t, uint8_t type)
+{
+       switch (t) {
+       case PROTO_ICMP_ECHO:
+               return type == ICMP_ECHO || type == ICMP_ECHOREPLY;
+       case PROTO_ICMP6_ECHO:
+               return type == ICMP6_ECHO_REQUEST || type == ICMP6_ECHO_REPLY;
+       case PROTO_ICMP6_ADDRESS:
+               return type == ND_NEIGHBOR_SOLICIT ||
+                      type == ND_NEIGHBOR_ADVERT ||
+                      type == ND_REDIRECT ||
+                      type == MLD_LISTENER_QUERY ||
+                      type == MLD_LISTENER_REPORT ||
+                      type == MLD_LISTENER_REDUCTION;
+       case PROTO_ICMP_ADDRESS:
+       case PROTO_ICMP_MTU:
+       case PROTO_ICMP6_MTU:
+       case PROTO_ICMP6_MGMQ:
+       case PROTO_ICMP6_PPTR:
+       case PROTO_ICMP6_REDIRECT:
+               return icmp_dep_to_type(t) == type;
+       case PROTO_ICMP_ANY:
+               return true;
+       }
+       BUG("Missing icmp type mapping");
+}
+
 static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct expr *expr)
 {
        const struct expr *dep = payload_dependency_get(ctx, expr->payload.base);
@@ -810,6 +839,11 @@ static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct
        if (dep->left->payload.desc != expr->payload.desc)
                return false;
 
+       if (expr->payload.tmpl->icmp_dep == PROTO_ICMP_ECHO ||
+           expr->payload.tmpl->icmp_dep == PROTO_ICMP6_ECHO ||
+           expr->payload.tmpl->icmp_dep == PROTO_ICMP6_ADDRESS)
+               return false;
+
        return ctx->icmp_type == icmp_dep_to_type(icmp_dep);
 }
 
@@ -995,7 +1029,8 @@ void payload_expr_complete(struct expr *expr, const struct proto_ctx *ctx)
                        continue;
 
                if (tmpl->icmp_dep && ctx->th_dep.icmp.type &&
-                   ctx->th_dep.icmp.type != icmp_dep_to_type(tmpl->icmp_dep))
+                   !icmp_dep_type_match(tmpl->icmp_dep,
+                                        ctx->th_dep.icmp.type))
                        continue;
 
                expr->dtype        = tmpl->dtype;
@@ -1130,7 +1165,8 @@ void payload_expr_expand(struct list_head *list, struct expr *expr,
                        continue;
 
                if (tmpl->icmp_dep && ctx->th_dep.icmp.type &&
-                    ctx->th_dep.icmp.type != icmp_dep_to_type(tmpl->icmp_dep))
+                   !icmp_dep_type_match(tmpl->icmp_dep,
+                                        ctx->th_dep.icmp.type))
                        continue;
 
                if (tmpl->len <= expr->len) {
@@ -1287,6 +1323,38 @@ __payload_gen_icmp_echo_dependency(struct eval_ctx *ctx, const struct expr *expr
        return expr_stmt_alloc(&dep->location, dep);
 }
 
+static struct stmt *
+__payload_gen_icmp6_addr_dependency(struct eval_ctx *ctx, const struct expr *expr,
+                                   const struct proto_desc *desc)
+{
+       static const uint8_t icmp_addr_types[] = {
+               MLD_LISTENER_QUERY,
+               MLD_LISTENER_REPORT,
+               MLD_LISTENER_REDUCTION,
+               ND_NEIGHBOR_SOLICIT,
+               ND_NEIGHBOR_ADVERT,
+               ND_REDIRECT
+       };
+       struct expr *left, *right, *dep, *set;
+       size_t i;
+
+       left = payload_expr_alloc(&expr->location, desc, desc->protocol_key);
+
+       set = set_expr_alloc(&expr->location, NULL);
+
+       for (i = 0; i < array_size(icmp_addr_types); ++i) {
+               right = constant_expr_alloc(&expr->location, &icmp6_type_type,
+                                           BYTEORDER_BIG_ENDIAN, BITS_PER_BYTE,
+                                           constant_data_ptr(icmp_addr_types[i],
+                                                             BITS_PER_BYTE));
+               right = set_elem_expr_alloc(&expr->location, right);
+               compound_expr_add(set, right);
+       }
+
+       dep = relational_expr_alloc(&expr->location, OP_IMPLICIT, left, set);
+       return expr_stmt_alloc(&dep->location, dep);
+}
+
 int payload_gen_icmp_dependency(struct eval_ctx *ctx, const struct expr *expr,
                                struct stmt **res)
 {
@@ -1345,6 +1413,16 @@ int payload_gen_icmp_dependency(struct eval_ctx *ctx, const struct expr *expr,
                                                          &icmp6_type_type,
                                                          desc);
                break;
+       case PROTO_ICMP6_ADDRESS:
+               if (icmp_dep_type_match(PROTO_ICMP6_ADDRESS,
+                                       pctx->th_dep.icmp.type))
+                       goto done;
+               type = ND_NEIGHBOR_SOLICIT;
+               if (pctx->th_dep.icmp.type)
+                       goto bad_proto;
+               stmt = __payload_gen_icmp6_addr_dependency(ctx, expr, desc);
+               break;
+       case PROTO_ICMP6_REDIRECT:
        case PROTO_ICMP6_MTU:
        case PROTO_ICMP6_MGMQ:
        case PROTO_ICMP6_PPTR:
index dd84f7c16380b1a179a61399acf3a2eea926adf8..553b6a447a7e78538661b85e1dbc3ccec41ca2a8 100644 (file)
@@ -438,10 +438,10 @@ const struct datatype icmp_type_type = {
        .sym_tbl        = &icmp_type_tbl,
 };
 
-#define ICMP46HDR_FIELD(__token, __struct, __member, __dep)                    \
+#define ICMP46HDR_FIELD(__token, __dtype, __struct, __member, __dep)           \
        {                                                                       \
                .token          = (__token),                                    \
-               .dtype          = &integer_type,                                \
+               .dtype          = &__dtype,                                     \
                .byteorder      = BYTEORDER_BIG_ENDIAN,                         \
                .offset         = offsetof(__struct, __member) * 8,             \
                .len            = field_sizeof(__struct, __member) * 8,         \
@@ -449,7 +449,7 @@ const struct datatype icmp_type_type = {
        }
 
 #define ICMPHDR_FIELD(__token, __member, __dep) \
-       ICMP46HDR_FIELD(__token, struct icmphdr, __member, __dep)
+       ICMP46HDR_FIELD(__token, integer_type, struct icmphdr, __member, __dep)
 
 #define ICMPHDR_TYPE(__name, __type, __member) \
        HDR_TYPE(__name,  __type, struct icmphdr, __member)
@@ -913,7 +913,7 @@ const struct datatype icmp6_type_type = {
 };
 
 #define ICMP6HDR_FIELD(__token, __member, __dep) \
-       ICMP46HDR_FIELD(__token, struct icmp6_hdr, __member, __dep)
+       ICMP46HDR_FIELD(__token, integer_type, struct icmp6_hdr, __member, __dep)
 #define ICMP6HDR_TYPE(__name, __type, __member) \
        HDR_TYPE(__name, __type, struct icmp6_hdr, __member)
 
@@ -933,6 +933,12 @@ const struct proto_desc proto_icmp6 = {
                [ICMP6HDR_ID]           = ICMP6HDR_FIELD("id", icmp6_id, PROTO_ICMP6_ECHO),
                [ICMP6HDR_SEQ]          = ICMP6HDR_FIELD("sequence", icmp6_seq, PROTO_ICMP6_ECHO),
                [ICMP6HDR_MAXDELAY]     = ICMP6HDR_FIELD("max-delay", icmp6_maxdelay, PROTO_ICMP6_MGMQ),
+               [ICMP6HDR_TADDR]        = ICMP46HDR_FIELD("taddr", ip6addr_type,
+                                                         struct nd_neighbor_solicit, nd_ns_target,
+                                                         PROTO_ICMP6_ADDRESS),
+               [ICMP6HDR_DADDR]        = ICMP46HDR_FIELD("daddr", ip6addr_type,
+                                                         struct nd_redirect, nd_rd_dst,
+                                                         PROTO_ICMP6_REDIRECT),
        },
 };
 
index 15b272ab1e9e16271a6e9964b5714282eba8420e..88376b7a219935851cb595cf606640b5bdac10c2 100644 (file)
@@ -589,6 +589,8 @@ addrstring  ({macaddr}|{ip4addr}|{ip6addr})
        "param-problem"         { return PPTR; }
        "max-delay"             { return MAXDELAY; }
        "mtu"                   { return MTU; }
+       "taddr"                 { return TADDR; }
+       "daddr"                 { return DADDR; }
 }
 <SCANSTATE_EXPR_AH,SCANSTATE_EXPR_ESP,SCANSTATE_ICMP,SCANSTATE_TCP>{
        "sequence"              { return SEQUENCE; }
index 4de6ee2377ddc2cbdec108b4270965d59379ce18..35dad2be54a4590748b073085d5ac1bf755f5179 100644 (file)
@@ -85,3 +85,15 @@ icmpv6 max-delay {33, 55, 67, 88};ok
 icmpv6 max-delay != {33, 55, 67, 88};ok
 
 icmpv6 type parameter-problem icmpv6 code no-route;ok
+
+icmpv6 type mld-listener-query icmpv6 taddr 2001:db8::133;ok
+icmpv6 type nd-neighbor-solicit icmpv6 taddr 2001:db8::133;ok
+icmpv6 type nd-neighbor-advert icmpv6 taddr 2001:db8::133;ok
+icmpv6 taddr 2001:db8::133;ok;icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133
+
+icmpv6 taddr 2001:db8::133;ok;icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133
+
+icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133;ok
+icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } icmpv6 taddr 2001:db8::133;ok
+icmpv6 daddr 2001:db8::133;ok
+icmpv6 type nd-redirect icmpv6 daddr 2001:db8::133;ok;icmpv6 daddr 2001:db8::133
index 2251be82a39e0dae04aa087441a5622316ce626b..224a8e817c85c53d3fb0cb46d60bd2c4112986e0 100644 (file)
         }
     }
 ]
+
+# icmpv6 type mld-listener-query icmpv6 taddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "type",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "mld-listener-query"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "taddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 type nd-neighbor-solicit icmpv6 taddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "type",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "nd-neighbor-solicit"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "taddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 type nd-neighbor-advert icmpv6 taddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "type",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "nd-neighbor-advert"
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "taddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 taddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "type",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    "mld-listener-query",
+                    "mld-listener-report",
+                    "mld-listener-done",
+                    "nd-neighbor-solicit",
+                    "nd-neighbor-advert",
+                    "nd-redirect"
+                ]
+            }
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "taddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 taddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "type",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    "mld-listener-query",
+                    "mld-listener-report",
+                    "mld-listener-done",
+                    "nd-neighbor-solicit",
+                    "nd-neighbor-advert",
+                    "nd-redirect"
+                ]
+            }
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "taddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "type",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    "mld-listener-query",
+                    "mld-listener-report",
+                    "mld-listener-done",
+                    "nd-neighbor-solicit",
+                    "nd-neighbor-advert",
+                    "nd-redirect"
+                ]
+            }
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "taddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } icmpv6 taddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "type",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": {
+                "set": [
+                    "nd-neighbor-solicit",
+                    "nd-neighbor-advert"
+                ]
+            }
+        }
+    },
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "taddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 daddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "daddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
+
+# icmpv6 type nd-redirect icmpv6 daddr 2001:db8::133
+[
+    {
+        "match": {
+            "left": {
+                "payload": {
+                    "field": "daddr",
+                    "protocol": "icmpv6"
+                }
+            },
+            "op": "==",
+            "right": "2001:db8::133"
+        }
+    }
+]
index 0e96be2d07888c0122f54c1f472e09839f88cd16..fcaf4812244d115b45fe296f86864bca4f71d67e 100644 (file)
@@ -561,3 +561,83 @@ ip6
   [ payload load 2b @ transport header + 0 => reg 1 ]
   [ cmp eq reg 1 0x00000004 ]
 
+# icmpv6 type mld-listener-query icmpv6 taddr 2001:db8::133
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000082 ]
+  [ payload load 16b @ transport header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]
+
+# icmpv6 type nd-neighbor-solicit icmpv6 taddr 2001:db8::133
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000087 ]
+  [ payload load 16b @ transport header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]
+
+# icmpv6 type nd-neighbor-advert icmpv6 taddr 2001:db8::133
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000088 ]
+  [ payload load 16b @ transport header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]
+
+# icmpv6 taddr 2001:db8::133
+__set%d test-ip6 3 size 6
+__set%d test-ip6 0
+       element 00000082  : 0 [end]     element 00000083  : 0 [end]     element 00000084  : 0 [end]     element 00000087  : 0 [end]     element 00000088  : 0 [end]     element 00000089  : 0 [end]
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ lookup reg 1 set __set%d ]
+  [ payload load 16b @ transport header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]
+
+# icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect} icmpv6 taddr 2001:db8::133
+__set%d test-ip6 3 size 6
+__set%d test-ip6 0
+       element 00000082  : 0 [end]     element 00000083  : 0 [end]     element 00000084  : 0 [end]     element 00000087  : 0 [end]     element 00000088  : 0 [end]     element 00000089  : 0 [end]
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ lookup reg 1 set __set%d ]
+  [ payload load 16b @ transport header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]
+
+# icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } icmpv6 taddr 2001:db8::133
+__set%d test-ip6 3 size 2
+__set%d test-ip6 0
+       element 00000087  : 0 [end]     element 00000088  : 0 [end]
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ lookup reg 1 set __set%d ]
+  [ payload load 16b @ transport header + 8 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]
+
+# icmpv6 daddr 2001:db8::133
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000089 ]
+  [ payload load 16b @ transport header + 24 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]
+
+# icmpv6 type nd-redirect icmpv6 daddr 2001:db8::133
+ip6 test-ip6 input
+  [ meta load l4proto => reg 1 ]
+  [ cmp eq reg 1 0x0000003a ]
+  [ payload load 1b @ transport header + 0 => reg 1 ]
+  [ cmp eq reg 1 0x00000089 ]
+  [ payload load 16b @ transport header + 24 => reg 1 ]
+  [ cmp eq reg 1 0xb80d0120 0x00000000 0x00000000 0x33010000 ]