nft_rule_expr_set_u32(nle, attr, reg);
}
-static enum nft_registers get_register(struct netlink_linearize_ctx *ctx)
+static enum nft_registers get_register(struct netlink_linearize_ctx *ctx,
+ const struct expr *expr)
{
if (ctx->reg_low > NFT_REG_MAX)
BUG("register reg_low %u invalid\n", ctx->reg_low);
return ctx->reg_low++;
}
-static void release_register(struct netlink_linearize_ctx *ctx)
+static void release_register(struct netlink_linearize_ctx *ctx,
+ const struct expr *expr)
{
ctx->reg_low--;
}
assert(expr->mappings->ops->type == EXPR_SET_REF);
if (dreg == NFT_REG_VERDICT)
- sreg = get_register(ctx);
+ sreg = get_register(ctx, expr->map);
else
sreg = dreg;
expr->mappings->set->handle.set_id);
if (dreg == NFT_REG_VERDICT)
- release_register(ctx);
+ release_register(ctx, expr->map);
nft_rule_add_expr(ctx->nlr, nle);
}
assert(expr->right->ops->type == EXPR_SET_REF);
assert(dreg == NFT_REG_VERDICT);
- sreg = get_register(ctx);
+ sreg = get_register(ctx, expr->left);
netlink_gen_expr(ctx, expr->left, sreg);
nle = alloc_nft_expr("lookup");
nft_rule_expr_set_u32(nle, NFT_EXPR_LOOKUP_SET_ID,
expr->right->set->handle.set_id);
- release_register(ctx);
+ release_register(ctx, expr->left);
nft_rule_add_expr(ctx->nlr, nle);
}
if (expr->right->ops->type == EXPR_RANGE)
return netlink_gen_range(ctx, expr, dreg);
- sreg = get_register(ctx);
+ sreg = get_register(ctx, expr->left);
netlink_gen_expr(ctx, expr->left, sreg);
switch (expr->right->ops->type) {
netlink_gen_cmp_op(expr->op));
netlink_gen_data(right, &nld);
nft_rule_expr_set(nle, NFT_EXPR_CMP_DATA, nld.value, nld.len);
- release_register(ctx);
+ release_register(ctx, expr->left);
nft_rule_add_expr(ctx->nlr, nle);
}
assert(dreg == NFT_REG_VERDICT);
- sreg = get_register(ctx);
+ sreg = get_register(ctx, expr->left);
netlink_gen_expr(ctx, expr->left, sreg);
nle = alloc_nft_expr("cmp");
nft_rule_expr_set(nle, NFT_EXPR_CMP_DATA, nld.value, nld.len);
nft_rule_add_expr(ctx->nlr, nle);
- release_register(ctx);
+ release_register(ctx, expr->left);
}
static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
assert(dreg == NFT_REG_VERDICT);
- sreg = get_register(ctx);
+ sreg = get_register(ctx, expr->left);
netlink_gen_expr(ctx, expr->left, sreg);
len = div_round_up(expr->left->len, BITS_PER_BYTE);
nft_rule_add_expr(ctx->nlr, nle);
mpz_clear(zero);
- release_register(ctx);
+ release_register(ctx, expr->left);
}
static void netlink_gen_relational(struct netlink_linearize_ctx *ctx,
struct nft_rule_expr *nle;
enum nft_registers sreg;
- sreg = get_register(ctx);
+ sreg = get_register(ctx, stmt->meta.expr);
netlink_gen_expr(ctx, stmt->meta.expr, sreg);
- release_register(ctx);
+ release_register(ctx, stmt->meta.expr);
nle = alloc_nft_expr("meta");
netlink_put_register(nle, NFT_EXPR_META_SREG, sreg);
nft_rule_expr_set_u32(nle, NFT_EXPR_NAT_FLAGS, stmt->nat.flags);
if (stmt->nat.addr) {
- amin_reg = get_register(ctx);
+ amin_reg = get_register(ctx, NULL);
registers++;
if (stmt->nat.addr->ops->type == EXPR_RANGE) {
- amax_reg = get_register(ctx);
+ amax_reg = get_register(ctx, NULL);
registers++;
netlink_gen_expr(ctx, stmt->nat.addr->left, amin_reg);
}
if (stmt->nat.proto) {
- pmin_reg = get_register(ctx);
+ pmin_reg = get_register(ctx, NULL);
registers++;
if (stmt->nat.proto->ops->type == EXPR_RANGE) {
- pmax_reg = get_register(ctx);
+ pmax_reg = get_register(ctx, NULL);
registers++;
netlink_gen_expr(ctx, stmt->nat.proto->left, pmin_reg);
}
while (registers > 0) {
- release_register(ctx);
+ release_register(ctx, NULL);
registers--;
}
stmt->redir.flags);
if (stmt->redir.proto) {
- pmin_reg = get_register(ctx);
+ pmin_reg = get_register(ctx, NULL);
registers++;
if (stmt->redir.proto->ops->type == EXPR_RANGE) {
- pmax_reg = get_register(ctx);
+ pmax_reg = get_register(ctx, NULL);
registers++;
netlink_gen_expr(ctx, stmt->redir.proto->left,
}
while (registers > 0) {
- release_register(ctx);
+ release_register(ctx, NULL);
registers--;
}
struct nft_rule_expr *nle;
enum nft_registers sreg;
- sreg = get_register(ctx);
+ sreg = get_register(ctx, stmt->ct.expr);
netlink_gen_expr(ctx, stmt->ct.expr, sreg);
- release_register(ctx);
+ release_register(ctx, stmt->ct.expr);
nle = alloc_nft_expr("ct");
netlink_put_register(nle, NFT_EXPR_CT_SREG, sreg);
struct nft_rule_expr *nle;
enum nft_registers sreg_key;
- sreg_key = get_register(ctx);
+ sreg_key = get_register(ctx, stmt->set.key);
netlink_gen_expr(ctx, stmt->set.key, sreg_key);
- release_register(ctx);
+ release_register(ctx, stmt->set.key);
nle = alloc_nft_expr("dynset");
netlink_put_register(nle, NFT_EXPR_DYNSET_SREG_KEY, sreg_key);