summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-01-28 18:09:50 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2016-01-31 23:43:36 +0100
commit0b858391781ba3086fbea2920a6e43927725fd4b (patch)
tree70ac8a2bdc48b37eff7089262d241e8631d3528a /src
parent89cc69c1d6a3ca6c5818690509af1dbec4319f99 (diff)
src: annotate follow up dependency just after killing another
The inet and netdev families generate two implicit dependencies to check for the interface type, so we have to check just after killing an implicit dependency if there is another that we should annotate to kill it as well. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r--src/netlink_delinearize.c45
1 files changed, 27 insertions, 18 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 94fa11fa..7d94f309 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1031,6 +1031,30 @@ static void integer_type_postprocess(struct expr *expr)
}
}
+static void payload_dependency_save(struct rule_pp_ctx *ctx, unsigned int base,
+ struct stmt *nstmt, struct expr *tmp)
+{
+ unsigned int proto = mpz_get_be16(tmp->value);
+ const struct proto_desc *desc, *next;
+ bool stacked_header = false;
+
+ desc = ctx->pctx.protocol[base].desc;
+
+ assert(desc);
+ if (desc) {
+ next = proto_find_upper(desc, proto);
+ stacked_header = next && next->base == base;
+ }
+
+ if (stacked_header) {
+ ctx->pctx.protocol[base].desc = next;
+ ctx->pctx.protocol[base].offset += desc->length;
+ payload_dependency_store(ctx, nstmt, base - 1);
+ } else {
+ payload_dependency_store(ctx, nstmt, base);
+ }
+}
+
static void payload_match_expand(struct rule_pp_ctx *ctx,
struct expr *expr,
struct expr *payload)
@@ -1069,26 +1093,11 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
if (ctx->pbase == PROTO_BASE_INVALID &&
expr->op == OP_EQ &&
left->flags & EXPR_F_PROTOCOL) {
- unsigned int proto = mpz_get_be16(tmp->value);
- const struct proto_desc *desc, *next;
- bool stacked_header = false;
-
- desc = ctx->pctx.protocol[base].desc;
- assert(desc);
- if (desc) {
- next = proto_find_upper(desc, proto);
- stacked_header = next && next->base == base;
- }
-
- if (stacked_header) {
- ctx->pctx.protocol[base].desc = next;
- ctx->pctx.protocol[base].offset += desc->length;
- payload_dependency_store(ctx, nstmt, base - 1);
- } else {
- payload_dependency_store(ctx, nstmt, base);
- }
+ payload_dependency_save(ctx, base, nstmt, tmp);
} else {
payload_dependency_kill(ctx, nexpr->left);
+ if (left->flags & EXPR_F_PROTOCOL)
+ payload_dependency_save(ctx, base, nstmt, tmp);
}
}
list_del(&ctx->stmt->list);