summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2015-12-25 19:19:18 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2015-12-25 22:06:17 +0100
commit5ae62260db2f55b51daeef59a8c197d020e89252 (patch)
tree09e16a7f62edca93035194e0bd4939ec47c6c256
parent76d672ca7c8518b92f67abb2393fbe228f2e2800 (diff)
src: add new netdev protocol description
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>
-rw-r--r--include/proto.h2
-rw-r--r--src/evaluate.c2
-rw-r--r--src/meta.c18
-rw-r--r--src/payload.c13
-rw-r--r--src/proto.c19
5 files changed, 50 insertions, 4 deletions
diff --git a/include/proto.h b/include/proto.h
index d90bccd0..c252a67d 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -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;
diff --git a/src/evaluate.c b/src/evaluate.c
index 7aab6aac..6277f14e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -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;
diff --git a/src/meta.c b/src/meta.c
index d31d2922..8cbc9745 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -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;
}
diff --git a/src/payload.c b/src/payload.c
index fe91ee0d..6a977e8d 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -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;
}
}
diff --git a/src/proto.c b/src/proto.c
index 68d635f5..3282271f 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -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);