summaryrefslogtreecommitdiffstats
path: root/src/netlink_delinearize.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2017-05-06 22:36:28 +0200
committerFlorian Westphal <fw@strlen.de>2017-05-08 21:56:05 +0200
commit1b6693788cd6f9d9a69c24d205e93c2e3cf4d7fd (patch)
treef5d6c88b9e22ce2b161c7269840d84b6b7704bf3 /src/netlink_delinearize.c
parentf99ccda252fa2a44d587c771e92896bcda1d7c7e (diff)
netlink_delinearize: don't kill dependencies accross statements
nft currently translates ip protocol tcp meta mark set 1 tcp dport 22 to mark set 0x00000001 tcp dport 22 This is wrong, the latter form is same as mark set 0x00000001 ip protocol tcp tcp dport 22 and thats not correct (original rule sets mark for tcp packets only). We need to clear the dependency stack whenever we see a statement other than stmt_expr, as these will have side effects (counter, payload mangling, logging and the like). Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/netlink_delinearize.c')
-rw-r--r--src/netlink_delinearize.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 4a0b8dcc..a65a97da 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2153,6 +2153,27 @@ static void stmt_payload_postprocess(struct rule_pp_ctx *ctx)
expr_postprocess(ctx, &stmt->payload.val);
}
+/*
+ * We can only remove payload dependencies if they occur without
+ * a statment with side effects in between.
+ *
+ * For instance:
+ * 'ip protocol tcp tcp dport 22 counter' is same as
+ * 'tcp dport 22 counter'.
+ *
+ * 'ip protocol tcp counter tcp dport 22' cannot be written as
+ * 'counter tcp dport 22' (that would be counter ip protocol tcp, but
+ * that counts every packet, not just ip/tcp).
+ */
+static void
+rule_maybe_reset_payload_deps(struct payload_dep_ctx *pdctx, enum stmt_types t)
+{
+ if (t == STMT_EXPRESSION)
+ return;
+
+ payload_dependency_reset(pdctx);
+}
+
static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *rule)
{
struct rule_pp_ctx rctx;
@@ -2162,9 +2183,11 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
proto_ctx_init(&rctx.pctx, rule->handle.family);
list_for_each_entry_safe(stmt, next, &rule->stmts, list) {
+ enum stmt_types type = stmt->ops->type;
+
rctx.stmt = stmt;
- switch (stmt->ops->type) {
+ switch (type) {
case STMT_EXPRESSION:
stmt_expr_postprocess(&rctx);
break;
@@ -2217,7 +2240,10 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
default:
break;
}
+
rctx.pdctx.prev = rctx.stmt;
+
+ rule_maybe_reset_payload_deps(&rctx.pdctx, type);
}
}