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;
}
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;
struct expr *payload)
{
enum proto_bases base = payload->payload.base;
- const struct proto_desc *next;
struct stmt *nstmt = NULL;
int link, err;
}
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;
}
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:
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;
}
{
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)
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 = {