summaryrefslogtreecommitdiffstats
path: root/src/payload.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2021-04-01 16:08:45 +0200
committerFlorian Westphal <fw@strlen.de>2021-04-03 13:55:51 +0200
commit264cb432a2a53e937e46106a4cd04a1eb2dda2ae (patch)
tree860e5bcd1cf0feccf7d0667735801a7205cb66da /src/payload.c
parent9fb39a67b6f44eaab42f7f6206ffee3d93faf5c5 (diff)
payload: be careful on vlan dependency removal
'vlan ...' implies 8021Q frame. In case the expression tests something else (802.1AD for example) its not an implictly added one, so keep it. Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'src/payload.c')
-rw-r--r--src/payload.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/src/payload.c b/src/payload.c
index a77ca550..cfa95224 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -661,6 +661,24 @@ static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct
return ctx->icmp_type == icmp_type;
}
+static bool payload_may_dependency_kill_ll(struct payload_dep_ctx *ctx, struct expr *expr)
+{
+ const struct expr *dep = ctx->pdep->expr;
+
+ /* Never remove a 'vlan type 0x...' expression, they are never added implicitly */
+ if (dep->left->payload.desc == &proto_vlan)
+ return false;
+
+ /* 'vlan id 2' implies 'ether type 8021Q'. If a different protocol is
+ * tested, this is not a redundant expression.
+ */
+ if (dep->left->payload.desc == &proto_eth &&
+ dep->right->etype == EXPR_VALUE && dep->right->len == 16)
+ return mpz_get_uint16(dep->right->value) == ETH_P_8021Q;
+
+ return true;
+}
+
static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx,
unsigned int family, struct expr *expr)
{
@@ -689,9 +707,14 @@ static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx,
* for stacked protocols if we only have protcol type matches.
*/
if (dep->left->etype == EXPR_PAYLOAD && dep->op == OP_EQ &&
- expr->flags & EXPR_F_PROTOCOL &&
- expr->payload.base == dep->left->payload.base)
- return false;
+ expr->payload.base == dep->left->payload.base) {
+ if (expr->flags & EXPR_F_PROTOCOL)
+ return false;
+
+ if (expr->payload.base == PROTO_BASE_LL_HDR)
+ return payload_may_dependency_kill_ll(ctx, expr);
+ }
+
break;
}