]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add auto-dependencies for ipv6 icmp6
authorFlorian Westphal <fw@strlen.de>
Tue, 8 Dec 2020 16:36:23 +0000 (17:36 +0100)
committerFlorian Westphal <fw@strlen.de>
Wed, 9 Dec 2020 17:33:53 +0000 (18:33 +0100)
Extend the earlier commit to also cover icmpv6.

Signed-off-by: Florian Westphal <fw@strlen.de>
include/proto.h
src/evaluate.c
src/payload.c
src/proto.c

index f383291b5a79b319b69bd0a1f90f4dc8e9b4fb53..b9217588f3e3c0a468230e8ba124541a8a9639aa 100644 (file)
@@ -30,6 +30,10 @@ enum icmp_hdr_field_type {
        PROTO_ICMP_ECHO,        /* echo and reply */
        PROTO_ICMP_MTU,         /* destination unreachable */
        PROTO_ICMP_ADDRESS,     /* redirect */
+       PROTO_ICMP6_MTU,
+       PROTO_ICMP6_PPTR,
+       PROTO_ICMP6_ECHO,
+       PROTO_ICMP6_MGMQ,
 };
 
 /**
index 3eb8e1bfc2c5443b048dd9abe11052b9773051a9..e776cd01805113940a14649fa37019d11883e68e 100644 (file)
@@ -729,7 +729,7 @@ static int __expr_evaluate_payload(struct eval_ctx *ctx, struct expr *expr)
 
                payload->payload.offset += ctx->pctx.protocol[base].offset;
 check_icmp:
-               if (desc != &proto_icmp)
+               if (desc != &proto_icmp && desc != &proto_icmp6)
                        return 0;
 
                tmpl = expr->payload.tmpl;
index 54b08f051dc079b9f58f0c3105b62da0ff85d7aa..7cfa530c06c60b75988263433fe10377b893242c 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/netfilter.h>
 #include <linux/if_ether.h>
 #include <netinet/ip_icmp.h>
+#include <netinet/icmp6.h>
 
 #include <rule.h>
 #include <expression.h>
@@ -677,8 +678,12 @@ static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t)
        case PROTO_ICMP_ANY:
                BUG("Invalid map for simple dependency");
        case PROTO_ICMP_ECHO: return ICMP_ECHO;
+       case PROTO_ICMP6_ECHO: return ICMP6_ECHO_REQUEST;
        case PROTO_ICMP_MTU: return ICMP_DEST_UNREACH;
        case PROTO_ICMP_ADDRESS: return ICMP_REDIRECT;
+       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;
        }
 
        BUG("Missing icmp type mapping");
@@ -1023,6 +1028,34 @@ int payload_gen_icmp_dependency(struct eval_ctx *ctx, const struct expr *expr,
                                                            &icmp_type_type,
                                                            desc, type);
                break;
+       case PROTO_ICMP6_ECHO:
+               if (ctx->pctx.th_dep.icmp.type == ICMP6_ECHO_REQUEST ||
+                   ctx->pctx.th_dep.icmp.type == ICMP6_ECHO_REPLY)
+                       goto done;
+
+               type = ICMP6_ECHO_REQUEST;
+               if (ctx->pctx.th_dep.icmp.type)
+                       goto bad_proto;
+
+               stmt = __payload_gen_icmp_echo_dependency(ctx, expr,
+                                                         ICMP6_ECHO_REQUEST,
+                                                         ICMP6_ECHO_REPLY,
+                                                         &icmp6_type_type,
+                                                         desc);
+               break;
+       case PROTO_ICMP6_MTU:
+       case PROTO_ICMP6_MGMQ:
+       case PROTO_ICMP6_PPTR:
+               type = icmp_dep_to_type(tmpl->icmp_dep);
+               if (ctx->pctx.th_dep.icmp.type == type)
+                       goto done;
+               if (ctx->pctx.th_dep.icmp.type)
+                       goto bad_proto;
+               stmt = __payload_gen_icmp_simple_dependency(ctx, expr,
+                                                           &icmp6_type_type,
+                                                           desc, type);
+               break;
+               break;
        default:
                BUG("Unhandled icmp dependency code");
        }
index d3371ac6597572a1a80a2f75f3d3fc13cc3e2ebd..b75626df2861e47cba1eae8d0379d0bfad5158d7 100644 (file)
@@ -396,16 +396,19 @@ const struct datatype icmp_type_type = {
        .sym_tbl        = &icmp_type_tbl,
 };
 
-#define ICMPHDR_FIELD(__token, __member, __dep)                                        \
+#define ICMP46HDR_FIELD(__token, __struct, __member, __dep)                    \
        {                                                                       \
                .token          = (__token),                                    \
                .dtype          = &integer_type,                                \
                .byteorder      = BYTEORDER_BIG_ENDIAN,                         \
-               .offset         = offsetof(struct icmphdr, __member) * 8,       \
-               .len            = field_sizeof(struct icmphdr, __member) * 8,   \
+               .offset         = offsetof(__struct, __member) * 8,             \
+               .len            = field_sizeof(__struct, __member) * 8,         \
                .icmp_dep       = (__dep),                                      \
        }
 
+#define ICMPHDR_FIELD(__token, __member, __dep) \
+       ICMP46HDR_FIELD(__token, struct icmphdr, __member, __dep)
+
 #define ICMPHDR_TYPE(__name, __type, __member) \
        HDR_TYPE(__name,  __type, struct icmphdr, __member)
 
@@ -822,8 +825,8 @@ const struct datatype icmp6_type_type = {
        .sym_tbl        = &icmp6_type_tbl,
 };
 
-#define ICMP6HDR_FIELD(__name, __member) \
-       HDR_FIELD(__name, struct icmp6_hdr, __member)
+#define ICMP6HDR_FIELD(__token, __member, __dep) \
+       ICMP46HDR_FIELD(__token, struct icmp6_hdr, __member, __dep)
 #define ICMP6HDR_TYPE(__name, __type, __member) \
        HDR_TYPE(__name, __type, struct icmp6_hdr, __member)
 
@@ -831,17 +834,18 @@ const struct proto_desc proto_icmp6 = {
        .name           = "icmpv6",
        .id             = PROTO_DESC_ICMPV6,
        .base           = PROTO_BASE_TRANSPORT_HDR,
+       .protocol_key   = ICMP6HDR_TYPE,
        .checksum_key   = ICMP6HDR_CHECKSUM,
        .checksum_type  = NFT_PAYLOAD_CSUM_INET,
        .templates      = {
                [ICMP6HDR_TYPE]         = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type),
                [ICMP6HDR_CODE]         = ICMP6HDR_TYPE("code", &icmpv6_code_type, icmp6_code),
-               [ICMP6HDR_CHECKSUM]     = ICMP6HDR_FIELD("checksum", icmp6_cksum),
-               [ICMP6HDR_PPTR]         = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr),
-               [ICMP6HDR_MTU]          = ICMP6HDR_FIELD("mtu", icmp6_mtu),
-               [ICMP6HDR_ID]           = ICMP6HDR_FIELD("id", icmp6_id),
-               [ICMP6HDR_SEQ]          = ICMP6HDR_FIELD("sequence", icmp6_seq),
-               [ICMP6HDR_MAXDELAY]     = ICMP6HDR_FIELD("max-delay", icmp6_maxdelay),
+               [ICMP6HDR_CHECKSUM]     = ICMP6HDR_FIELD("checksum", icmp6_cksum, PROTO_ICMP_ANY),
+               [ICMP6HDR_PPTR]         = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr, PROTO_ICMP6_PPTR),
+               [ICMP6HDR_MTU]          = ICMP6HDR_FIELD("mtu", icmp6_mtu, PROTO_ICMP6_MTU),
+               [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),
        },
 };