summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-01-28 13:22:34 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2016-01-31 23:43:35 +0100
commit03dc38424bef6d5be472e28e0a26db3cd09960af (patch)
tree458d2d776f7ad651f8bbc80e4a004c7066d43050 /src
parent55b825559d1070c6addc541bb5761f4734c03c62 (diff)
evaluate: wrap protocol context debunk into function
ether type vlan sets the network layer protocol context to vlan. This function debunks the existing link layer protocol context by setting it to vlan. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/evaluate.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index b70ff07c..e53627a5 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -382,6 +382,17 @@ static int meta_iiftype_gen_dependency(struct eval_ctx *ctx,
return 0;
}
+static void proto_ctx_debunk(struct eval_ctx *ctx,
+ const struct proto_desc *desc,
+ const struct proto_desc *next,
+ struct expr *payload, enum proto_bases base)
+{
+ ctx->pctx.protocol[base + 1].desc = NULL;
+ ctx->pctx.protocol[base].desc = next;
+ ctx->pctx.protocol[base].offset += desc->length;
+ payload->payload.offset += desc->length;
+}
+
static bool proto_is_dummy(const struct proto_desc *desc)
{
return desc == &proto_inet || desc == &proto_netdev;
@@ -406,16 +417,18 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx,
assert(base < PROTO_BASE_MAX);
next = ctx->pctx.protocol[base + 1].desc;
+ /* ether type vlan sets vlan as network protocol, debunk ethernet if it
+ * is already there.
+ */
if (payload->payload.desc == next) {
- ctx->pctx.protocol[base + 1].desc = NULL;
- ctx->pctx.protocol[base].desc = next;
- ctx->pctx.protocol[base].offset += desc->length;
- payload->payload.offset += desc->length;
+ proto_ctx_debunk(ctx, desc, next, payload, base);
return 0;
- } else if (next) {
- return 1;
}
+ /* This payload and the existing context don't match, conflict. */
+ if (next != NULL)
+ return 1;
+
link = proto_find_num(desc, payload->payload.desc);
if (link < 0 || conflict_resolution_gen_dependency(ctx, link, payload, &nstmt) < 0)
return 1;