]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
src: add new netdev protocol description
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 25 Dec 2015 18:19:18 +0000 (19:19 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 25 Dec 2015 21:06:17 +0000 (22:06 +0100)
This relies on NFT_META_PROTOCOL instead of ethernet protocol type
header field to prepare support for non-ethernet protocols in the
future.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/proto.h
src/evaluate.c
src/meta.c
src/payload.c
src/proto.c

index d90bccd0199e89ee3609ec18fac18aaa53816ebb..c252a67d6ccdb81f5a58976b48ee7cd7e272d168 100644 (file)
@@ -308,6 +308,8 @@ extern const struct proto_desc proto_arp;
 extern const struct proto_desc proto_vlan;
 extern const struct proto_desc proto_eth;
 
+extern const struct proto_desc proto_netdev;
+
 extern const struct proto_desc proto_unknown;
 extern const struct proto_hdr_template proto_unknown_template;
 
index 7aab6aacc0a4368e59c5638e9e7c98b5f3668eba..6277f14e8fc215b3f3a7d98401c42c378559397d 100644 (file)
@@ -365,7 +365,7 @@ static bool supersede_dep(const struct proto_desc *have,
        if (payload->payload.base != PROTO_BASE_LL_HDR || have->length)
                return false;
 
-       if (have != &proto_inet)
+       if (have != &proto_inet && have != &proto_netdev)
                return false;
 
        return true;
index d31d2922132d665f90f4ed0f3e1ee690ff3d49bd..8cbc97456e31e0d1d1abc85c0ce6be82a9581039 100644 (file)
@@ -470,7 +470,9 @@ static void meta_expr_pctx_update(struct proto_ctx *ctx,
 
        switch (left->meta.key) {
        case NFT_META_IIFTYPE:
-               if (h->base < PROTO_BASE_NETWORK_HDR && ctx->family != NFPROTO_INET)
+               if (h->base < PROTO_BASE_NETWORK_HDR &&
+                   ctx->family != NFPROTO_INET &&
+                   ctx->family != NFPROTO_NETDEV)
                        return;
 
                desc = proto_dev_desc(mpz_get_uint16(right->value));
@@ -494,6 +496,16 @@ static void meta_expr_pctx_update(struct proto_ctx *ctx,
 
                proto_ctx_update(ctx, PROTO_BASE_TRANSPORT_HDR, &expr->location, desc);
                break;
+       case NFT_META_PROTOCOL:
+               if (h->base < PROTO_BASE_NETWORK_HDR && ctx->family != NFPROTO_NETDEV)
+                       return;
+
+               desc = proto_find_upper(h->desc, ntohs(mpz_get_uint16(right->value)));
+               if (desc == NULL)
+                       desc = &proto_unknown;
+
+               proto_ctx_update(ctx, PROTO_BASE_NETWORK_HDR, &expr->location, desc);
+               break;
        default:
                break;
        }
@@ -529,6 +541,10 @@ struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
                expr->flags |= EXPR_F_PROTOCOL;
                expr->meta.base = PROTO_BASE_NETWORK_HDR;
                break;
+       case NFT_META_PROTOCOL:
+               expr->flags |= EXPR_F_PROTOCOL;
+               expr->meta.base = PROTO_BASE_LL_HDR;
+               break;
        default:
                break;
        }
index fe91ee0dcc927d114f54750d139da6659041908a..6a977e8d0f267ace54ecd385ba8718f9530939fe 100644 (file)
@@ -233,7 +233,6 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
                        }
                        break;
                case NFPROTO_BRIDGE:
-               case NFPROTO_NETDEV:
                        switch (expr->payload.base) {
                        case PROTO_BASE_LL_HDR:
                                desc = &proto_eth;
@@ -245,6 +244,18 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
                                break;
                        }
                        break;
+               case NFPROTO_NETDEV:
+                       switch (expr->payload.base) {
+                       case PROTO_BASE_LL_HDR:
+                               desc = &proto_netdev;
+                               break;
+                       case PROTO_BASE_TRANSPORT_HDR:
+                               desc = &proto_inet_service;
+                               break;
+                       default:
+                               break;
+                       }
+                       break;
                }
        }
 
index 68d635f515ebfc81ac14e1e863d624bd447f9beb..3282271fa41d8878c9e7e476f9ccefe353321540 100644 (file)
@@ -123,7 +123,7 @@ const struct proto_desc *proto_dev_desc(uint16_t type)
 
 const struct hook_proto_desc hook_proto_desc[] = {
        [NFPROTO_BRIDGE]        = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR,      &proto_eth),
-       [NFPROTO_NETDEV]        = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR,      &proto_eth),
+       [NFPROTO_NETDEV]        = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR,      &proto_netdev),
        [NFPROTO_INET]          = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR,      &proto_inet),
        [NFPROTO_IPV4]          = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip),
        [NFPROTO_IPV6]          = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip6),
@@ -806,6 +806,23 @@ const struct proto_desc proto_eth = {
        },
 };
 
+/*
+ * Dummy protocol for netdev tables.
+ */
+const struct proto_desc proto_netdev = {
+       .name           = "netdev",
+       .base           = PROTO_BASE_LL_HDR,
+       .protocols      = {
+               PROTO_LINK(__constant_htons(ETH_P_IP),          &proto_ip),
+               PROTO_LINK(__constant_htons(ETH_P_ARP),         &proto_arp),
+               PROTO_LINK(__constant_htons(ETH_P_IPV6),        &proto_ip6),
+               PROTO_LINK(__constant_htons(ETH_P_8021Q),       &proto_vlan),
+       },
+       .templates      = {
+               [0]     = PROTO_META_TEMPLATE("protocol", &ethertype_type, NFT_META_PROTOCOL, 16),
+       },
+};
+
 static void __init proto_init(void)
 {
        datatype_register(&icmp_type_type);