summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/evaluate.c44
-rw-r--r--src/netlink_delinearize.c7
-rw-r--r--src/payload.c8
-rw-r--r--src/proto.c10
4 files changed, 26 insertions, 43 deletions
diff --git a/src/evaluate.c b/src/evaluate.c
index 346e34fc..a65e145d 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -358,12 +358,6 @@ conflict_resolution_gen_dependency(struct eval_ctx *ctx, int protocol,
return expr_error(ctx->msgs, expr,
"dependency statement is invalid");
- ctx->pctx.protocol[base].desc = expr->payload.desc;
- assert(ctx->pctx.protocol[base].offset == 0);
-
- assert(desc->length);
- ctx->pctx.protocol[base].offset += desc->length;
-
*res = stmt;
return 0;
}
@@ -430,17 +424,6 @@ 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;
@@ -451,7 +434,6 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx,
struct expr *payload)
{
enum proto_bases base = payload->payload.base;
- const struct proto_desc *next;
struct stmt *nstmt = NULL;
int link, err;
@@ -465,27 +447,17 @@ 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) {
- proto_ctx_debunk(ctx, desc, next, payload, base);
- return 0;
- }
-
/* This payload and the existing context don't match, conflict. */
- if (next != NULL)
+ if (ctx->pctx.protocol[base + 1].desc != NULL)
return 1;
link = proto_find_num(desc, payload->payload.desc);
- if (link < 0 || conflict_resolution_gen_dependency(ctx, link, payload, &nstmt) < 0)
+ if (link < 0 ||
+ conflict_resolution_gen_dependency(ctx, link, payload, &nstmt) < 0)
return 1;
payload->payload.offset += ctx->pctx.protocol[base].offset;
list_add_tail(&nstmt->list, &ctx->stmt->list);
- ctx->pctx.protocol[base + 1].desc = NULL;
return 0;
}
@@ -1622,7 +1594,7 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx,
default:
return stmt_binary_error(ctx, stmt,
&ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR],
- "cannot reject this ether type");
+ "cannot reject this network family");
}
break;
case NFT_REJECT_ICMP_UNREACH:
@@ -1644,7 +1616,7 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx,
default:
return stmt_binary_error(ctx, stmt,
&ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR],
- "cannot reject this ether type");
+ "cannot reject this network family");
}
break;
}
@@ -1657,6 +1629,12 @@ static int stmt_evaluate_reject_bridge(struct eval_ctx *ctx, struct stmt *stmt,
{
const struct proto_desc *desc;
+ desc = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc;
+ if (desc != &proto_eth)
+ return stmt_binary_error(ctx,
+ &ctx->pctx.protocol[PROTO_BASE_LL_HDR],
+ stmt, "unsupported link layer protocol");
+
desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc;
if (desc != NULL &&
stmt_evaluate_reject_bridge_family(ctx, stmt, desc) < 0)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index ca1c6e60..ee4cf12b 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1077,13 +1077,10 @@ static void payload_dependency_save(struct rule_pp_ctx *ctx, unsigned int base,
stacked_header = next && next->base == base;
}
- if (stacked_header) {
- ctx->pctx.protocol[base].desc = next;
- ctx->pctx.protocol[base].offset += desc->length;
+ if (stacked_header)
payload_dependency_store(ctx, nstmt, base - 1);
- } else {
+ else
payload_dependency_store(ctx, nstmt, base);
- }
}
static void payload_match_expand(struct rule_pp_ctx *ctx,
diff --git a/src/payload.c b/src/payload.c
index f6c0a975..45a2ba21 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -85,8 +85,12 @@ static void payload_expr_pctx_update(struct proto_ctx *ctx,
base = ctx->protocol[left->payload.base].desc;
desc = proto_find_upper(base, proto);
- assert(left->payload.base + 1 <= PROTO_BASE_MAX);
- proto_ctx_update(ctx, left->payload.base + 1, &expr->location, desc);
+ assert(desc->base <= PROTO_BASE_MAX);
+ if (desc->base == base->base) {
+ assert(base->length > 0);
+ ctx->protocol[base->base].offset += base->length;
+ }
+ proto_ctx_update(ctx, desc->base, &expr->location, desc);
}
static const struct expr_ops payload_expr_ops = {
diff --git a/src/proto.c b/src/proto.c
index b54a4c14..329d9919 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -148,11 +148,15 @@ static void proto_ctx_debug(const struct proto_ctx *ctx, enum proto_bases base)
pr_debug("update %s protocol context:\n", proto_base_names[base]);
for (i = PROTO_BASE_LL_HDR; i <= PROTO_BASE_MAX; i++) {
- pr_debug(" %-20s: %s%s\n",
+ pr_debug(" %-20s: %s",
proto_base_names[i],
ctx->protocol[i].desc ? ctx->protocol[i].desc->name :
- "none",
- i == base ? " <-" : "");
+ "none");
+ if (ctx->protocol[i].offset)
+ pr_debug(" (offset: %u)", ctx->protocol[i].offset);
+ if (i == base)
+ pr_debug(" <-");
+ pr_debug("\n");
}
pr_debug("\n");
#endif