summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/payload.h2
-rw-r--r--src/netlink_delinearize.c4
-rw-r--r--src/payload.c31
3 files changed, 31 insertions, 6 deletions
diff --git a/include/payload.h b/include/payload.h
index 8bc3fb9a..af6fa478 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -47,6 +47,8 @@ extern void payload_dependency_store(struct payload_dep_ctx *ctx,
enum proto_bases base);
extern bool payload_dependency_exists(const struct payload_dep_ctx *ctx,
enum proto_bases base);
+extern struct expr *payload_dependency_get(struct payload_dep_ctx *ctx,
+ enum proto_bases base);
extern void payload_dependency_release(struct payload_dep_ctx *ctx);
extern void payload_dependency_kill(struct payload_dep_ctx *ctx,
struct expr *expr, unsigned int family);
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 87316429..068d305b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2067,9 +2067,9 @@ static bool meta_may_dependency_kill(struct payload_dep_ctx *ctx,
const struct expr *expr)
{
uint8_t l4proto, nfproto = NFPROTO_UNSPEC;
- struct expr *dep = ctx->pdep->expr;
+ struct expr *dep = payload_dependency_get(ctx, PROTO_BASE_NETWORK_HDR);
- if (ctx->pbase != PROTO_BASE_NETWORK_HDR)
+ if (!dep)
return true;
if (__meta_dependency_may_kill(dep, &nfproto))
diff --git a/src/payload.c b/src/payload.c
index 576eb149..accbe0ab 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -631,6 +631,27 @@ bool payload_dependency_exists(const struct payload_dep_ctx *ctx,
(ctx->pbase == base || (base == PROTO_BASE_TRANSPORT_HDR && ctx->pbase == base + 1));
}
+/**
+ * payload_dependency_get - return a payload dependency if available
+ * @ctx: payload dependency context
+ * @base: payload protocol base
+ *
+ * If we have seen a protocol key payload expression for this base, we return
+ * it.
+ */
+struct expr *payload_dependency_get(struct payload_dep_ctx *ctx,
+ enum proto_bases base)
+{
+ if (ctx->pbase == base)
+ return ctx->pdep->expr;
+
+ if (base == PROTO_BASE_TRANSPORT_HDR &&
+ ctx->pbase == PROTO_BASE_INNER_HDR)
+ return ctx->pdep->expr;
+
+ return NULL;
+}
+
void payload_dependency_release(struct payload_dep_ctx *ctx)
{
list_del(&ctx->pdep->list);
@@ -661,7 +682,7 @@ static uint8_t icmp_dep_to_type(enum icmp_hdr_field_type t)
static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct expr *expr)
{
- const struct expr *dep = ctx->pdep->expr;
+ const struct expr *dep = payload_dependency_get(ctx, expr->payload.base);
uint8_t icmp_type;
icmp_type = expr->payload.tmpl->icmp_dep;
@@ -678,9 +699,11 @@ static bool payload_may_dependency_kill_icmp(struct payload_dep_ctx *ctx, struct
static bool payload_may_dependency_kill_ll(struct payload_dep_ctx *ctx, struct expr *expr)
{
- const struct expr *dep = ctx->pdep->expr;
+ const struct expr *dep = payload_dependency_get(ctx, expr->payload.base);
- /* Never remove a 'vlan type 0x...' expression, they are never added implicitly */
+ /* Never remove a 'vlan type 0x...' expression, they are never added
+ * implicitly
+ */
if (dep->left->payload.desc == &proto_vlan)
return false;
@@ -697,7 +720,7 @@ static bool payload_may_dependency_kill_ll(struct payload_dep_ctx *ctx, struct e
static bool payload_may_dependency_kill(struct payload_dep_ctx *ctx,
unsigned int family, struct expr *expr)
{
- struct expr *dep = ctx->pdep->expr;
+ struct expr *dep = payload_dependency_get(ctx, expr->payload.base);
/* Protocol key payload expression at network base such as 'ip6 nexthdr'
* need to be left in place since it implicitly restricts matching to