summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-06-13 14:48:56 +0200
committerPatrick McHardy <kaber@trash.net>2015-06-13 14:48:56 +0200
commit077509fdea3aa009823491be7096749c84795874 (patch)
tree07287fb0971df4011b33135d25ef8b0c0848e099
parent45cabc474e46c74c27b645582d37a55d5d076051 (diff)
parenta93bc1795b272174a10d90961a248f2c620bfa2c (diff)
Merge remote-tracking branch 'origin/next-4.1'
-rw-r--r--include/linux/netfilter/nf_tables.h34
-rw-r--r--include/netlink.h15
-rw-r--r--src/datatype.c5
-rw-r--r--src/evaluate.c7
-rw-r--r--src/netlink.c46
-rw-r--r--src/netlink_delinearize.c130
-rw-r--r--src/netlink_linearize.c105
7 files changed, 288 insertions, 54 deletions
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 0e964439..33056dc2 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -4,16 +4,45 @@
#define NFT_CHAIN_MAXNAMELEN 32
#define NFT_USERDATA_MAXLEN 256
+/**
+ * enum nft_registers - nf_tables registers
+ *
+ * nf_tables used to have five registers: a verdict register and four data
+ * registers of size 16. The data registers have been changed to 16 registers
+ * of size 4. For compatibility reasons, the NFT_REG_[1-4] registers still
+ * map to areas of size 16, the 4 byte registers are addressed using
+ * NFT_REG32_00 - NFT_REG32_15.
+ */
enum nft_registers {
NFT_REG_VERDICT,
NFT_REG_1,
NFT_REG_2,
NFT_REG_3,
NFT_REG_4,
- __NFT_REG_MAX
+ __NFT_REG_MAX,
+
+ NFT_REG32_00 = 8,
+ MFT_REG32_01,
+ NFT_REG32_02,
+ NFT_REG32_03,
+ NFT_REG32_04,
+ NFT_REG32_05,
+ NFT_REG32_06,
+ NFT_REG32_07,
+ NFT_REG32_08,
+ NFT_REG32_09,
+ NFT_REG32_10,
+ NFT_REG32_11,
+ NFT_REG32_12,
+ NFT_REG32_13,
+ NFT_REG32_14,
+ NFT_REG32_15,
};
#define NFT_REG_MAX (__NFT_REG_MAX - 1)
+#define NFT_REG_SIZE 16
+#define NFT_REG32_SIZE 4
+
/**
* enum nft_verdicts - nf_tables internal verdicts
*
@@ -358,6 +387,9 @@ enum nft_data_attributes {
};
#define NFTA_DATA_MAX (__NFTA_DATA_MAX - 1)
+/* Maximum length of a value */
+#define NFT_DATA_VALUE_MAXLEN 64
+
/**
* enum nft_verdict_attributes - nf_tables verdict netlink attributes
*
diff --git a/include/netlink.h b/include/netlink.h
index 9f24ea5e..185c4357 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -53,6 +53,21 @@ struct nft_data_delinearize {
int verdict;
};
+static inline unsigned int netlink_register_space(unsigned int size)
+{
+ return div_round_up(size, NFT_REG32_SIZE * BITS_PER_BYTE);
+}
+
+static inline unsigned int netlink_padded_len(unsigned int size)
+{
+ return netlink_register_space(size) * NFT_REG32_SIZE * BITS_PER_BYTE;
+}
+
+static inline unsigned int netlink_padding_len(unsigned int size)
+{
+ return netlink_padded_len(size) - size;
+}
+
extern void netlink_gen_data(const struct expr *expr,
struct nft_data_linearize *data);
extern void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder,
diff --git a/src/datatype.c b/src/datatype.c
index 82a77537..f42e3dfb 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -23,6 +23,7 @@
#include <expression.h>
#include <gmputil.h>
#include <erec.h>
+#include <netlink.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
@@ -938,7 +939,7 @@ const struct datatype *concat_type_alloc(uint32_t type)
unsigned int size = 0, subtypes = 0, n;
n = div_round_up(fls(type), TYPE_BITS);
- while (concat_subtype_id(type, --n)) {
+ while (n > 0 && concat_subtype_id(type, --n)) {
i = concat_subtype_lookup(type, n);
if (i == NULL)
return NULL;
@@ -950,7 +951,7 @@ const struct datatype *concat_type_alloc(uint32_t type)
strncat(desc, i->desc, sizeof(desc) - strlen(desc) - 1);
strncat(name, i->name, sizeof(name) - strlen(name) - 1);
- size += i->size;
+ size += netlink_padded_len(i->size);
subtypes++;
}
strncat(desc, ")", sizeof(desc) - strlen(desc) - 1);
diff --git a/src/evaluate.c b/src/evaluate.c
index e260a803..d99b38f4 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -620,6 +620,13 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
"expecting %s",
dtype->desc);
+ if (dtype == NULL && i->dtype->size == 0)
+ return expr_binary_error(ctx->msgs, i, *expr,
+ "can not use variable sized "
+ "data types (%s) in concat "
+ "expressions",
+ i->dtype->name);
+
tmp = concat_subtype_lookup(type, --off);
expr_set_context(&ctx->ectx, tmp, tmp->size);
diff --git a/src/netlink.c b/src/netlink.c
index d31387f8..1167c951 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -273,23 +273,21 @@ static void netlink_gen_concat_data(const struct expr *expr,
const struct expr *i;
unsigned int len, offset;
- len = 0;
- list_for_each_entry(i, &expr->expressions, list)
- len += i->len;
-
+ len = expr->len / BITS_PER_BYTE;
if (1) {
- unsigned char data[len / BITS_PER_BYTE];
+ unsigned char data[len];
+ memset(data, 0, sizeof(data));
offset = 0;
list_for_each_entry(i, &expr->expressions, list) {
assert(i->ops->type == EXPR_VALUE);
mpz_export_data(data + offset, i->value, i->byteorder,
i->len / BITS_PER_BYTE);
- offset += i->len / BITS_PER_BYTE;
+ offset += netlink_padded_len(i->len) / BITS_PER_BYTE;
}
- memcpy(nld->value, data, len / BITS_PER_BYTE);
- nld->len = len / BITS_PER_BYTE;
+ memcpy(nld->value, data, len);
+ nld->len = len;
}
}
@@ -1385,6 +1383,36 @@ static int netlink_del_setelems_compat(struct netlink_ctx *ctx,
return err;
}
+static struct expr *netlink_parse_concat_elem(const struct datatype *dtype,
+ struct expr *data)
+{
+ const struct datatype *subtype;
+ struct expr *concat, *expr;
+ int off = dtype->subtypes;
+
+ concat = concat_expr_alloc(&data->location);
+ while (off > 0) {
+ subtype = concat_subtype_lookup(dtype->type, --off);
+
+ expr = constant_expr_splice(data, subtype->size);
+ expr->dtype = subtype;
+ expr->byteorder = subtype->byteorder;
+
+ if (expr->byteorder == BYTEORDER_HOST_ENDIAN)
+ mpz_switch_byteorder(expr->value, expr->len / BITS_PER_BYTE);
+
+ if (expr->dtype->basetype != NULL &&
+ expr->dtype->basetype->type == TYPE_BITMASK)
+ expr = bitmask_expr_to_binops(expr);
+
+ compound_expr_add(concat, expr);
+ data->len -= netlink_padding_len(expr->len);
+ }
+ expr_free(data);
+
+ return concat;
+}
+
static int netlink_delinearize_setelem(struct nft_set_elem *nlse,
struct set *set)
{
@@ -1400,6 +1428,8 @@ static int netlink_delinearize_setelem(struct nft_set_elem *nlse,
key = netlink_alloc_value(&netlink_location, &nld);
key->dtype = set->keytype;
key->byteorder = set->keytype->byteorder;
+ if (set->keytype->subtypes)
+ key = netlink_parse_concat_elem(set->keytype, key);
if (!(set->flags & SET_F_INTERVAL) &&
key->byteorder == BYTEORDER_HOST_ENDIAN)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 2865e8ed..9ee43ba4 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -30,7 +30,7 @@ struct netlink_parse_ctx {
struct list_head *msgs;
struct table *table;
struct rule *rule;
- struct expr *registers[NFT_REG_MAX + 1];
+ struct expr *registers[1 + NFT_REG32_15 - NFT_REG32_00 + 1];
};
static void __fmtstring(3, 4) netlink_error(struct netlink_parse_ctx *ctx,
@@ -49,14 +49,23 @@ static void __fmtstring(3, 4) netlink_error(struct netlink_parse_ctx *ctx,
static unsigned int netlink_parse_register(const struct nft_rule_expr *nle,
unsigned int attr)
{
- return nft_rule_expr_get_u32(nle, attr);
+ unsigned int reg;
+
+ reg = nft_rule_expr_get_u32(nle, attr);
+ /* Translate 128bit registers to corresponding 32bit registers */
+ if (reg >= NFT_REG_1 && reg <= NFT_REG_4)
+ reg = 1 + (reg - NFT_REG_1) * (NFT_REG_SIZE / NFT_REG32_SIZE);
+ else if (reg >= NFT_REG32_00)
+ reg = 1 + reg - NFT_REG32_00;
+
+ return reg;
}
static void netlink_set_register(struct netlink_parse_ctx *ctx,
enum nft_registers reg,
struct expr *expr)
{
- if (reg > NFT_REG_MAX) {
+ if (reg == NFT_REG_VERDICT || reg > 1 + NFT_REG32_15 - NFT_REG32_00) {
netlink_error(ctx, &expr->location,
"Invalid destination register %u", reg);
expr_free(expr);
@@ -75,7 +84,7 @@ static struct expr *netlink_get_register(struct netlink_parse_ctx *ctx,
{
struct expr *expr;
- if (reg == NFT_REG_VERDICT || reg > NFT_REG_MAX) {
+ if (reg == NFT_REG_VERDICT || reg > 1 + NFT_REG32_15 - NFT_REG32_00) {
netlink_error(ctx, loc, "Invalid source register %u", reg);
return NULL;
}
@@ -95,6 +104,63 @@ static void netlink_release_registers(struct netlink_parse_ctx *ctx)
expr_free(ctx->registers[i]);
}
+static struct expr *netlink_parse_concat_expr(struct netlink_parse_ctx *ctx,
+ const struct location *loc,
+ unsigned int reg,
+ unsigned int len)
+{
+ struct expr *concat, *expr;
+
+ concat = concat_expr_alloc(loc);
+ while (len > 0) {
+ expr = netlink_get_register(ctx, loc, reg);
+ if (expr == NULL) {
+ netlink_error(ctx, loc,
+ "Relational expression size mismatch");
+ goto err;
+ }
+ compound_expr_add(concat, expr);
+
+ len -= netlink_padded_len(expr->len);
+ reg += netlink_register_space(expr->len);
+ }
+ return concat;
+
+err:
+ expr_free(concat);
+ return NULL;
+}
+
+static struct expr *netlink_parse_concat_data(struct netlink_parse_ctx *ctx,
+ const struct location *loc,
+ unsigned int reg,
+ unsigned int len,
+ struct expr *data)
+{
+ struct expr *concat, *expr, *i;
+
+ concat = concat_expr_alloc(loc);
+ while (len > 0) {
+ expr = netlink_get_register(ctx, loc, reg);
+ if (expr == NULL) {
+ netlink_error(ctx, loc,
+ "Relational expression size mismatch");
+ goto err;
+ }
+ i = constant_expr_splice(data, expr->len);
+ data->len -= netlink_padding_len(expr->len);
+ compound_expr_add(concat, i);
+
+ len -= netlink_padded_len(expr->len);
+ reg += netlink_register_space(expr->len);
+ }
+ return concat;
+
+err:
+ expr_free(concat);
+ return NULL;
+}
+
static void netlink_parse_immediate(struct netlink_parse_ctx *ctx,
const struct location *loc,
const struct nft_rule_expr *nle)
@@ -166,9 +232,18 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx,
nld.value = nft_rule_expr_get(nle, NFT_EXPR_CMP_DATA, &nld.len);
right = netlink_alloc_value(loc, &nld);
- if (left->len != right->len)
- return netlink_error(ctx, loc,
- "Relational expression size mismatch");
+ if (left->len != right->len) {
+ if (left->len > right->len)
+ return netlink_error(ctx, loc,
+ "Relational expression size "
+ "mismatch");
+ left = netlink_parse_concat_expr(ctx, loc, sreg, right->len);
+ if (left == NULL)
+ return;
+ right = netlink_parse_concat_data(ctx, loc, sreg, right->len, right);
+ if (right == NULL)
+ return;
+ }
expr = relational_expr_alloc(loc, op, left, right);
stmt = expr_stmt_alloc(loc, expr);
@@ -185,12 +260,6 @@ static void netlink_parse_lookup(struct netlink_parse_ctx *ctx,
struct expr *expr, *left, *right;
struct set *set;
- sreg = netlink_parse_register(nle, NFT_EXPR_LOOKUP_SREG);
- left = netlink_get_register(ctx, loc, sreg);
- if (left == NULL)
- return netlink_error(ctx, loc,
- "Lookup expression has no left hand side");
-
name = nft_rule_expr_get_str(nle, NFT_EXPR_LOOKUP_SET);
set = set_lookup(ctx->table, name);
if (set == NULL)
@@ -198,6 +267,18 @@ static void netlink_parse_lookup(struct netlink_parse_ctx *ctx,
"Unknown set '%s' in lookup expression",
name);
+ sreg = netlink_parse_register(nle, NFT_EXPR_LOOKUP_SREG);
+ left = netlink_get_register(ctx, loc, sreg);
+ if (left == NULL)
+ return netlink_error(ctx, loc,
+ "Lookup expression has no left hand side");
+
+ if (left->len < set->keylen) {
+ left = netlink_parse_concat_expr(ctx, loc, sreg, set->keylen);
+ if (left == NULL)
+ return;
+ }
+
right = set_ref_expr_alloc(loc, set);
if (nft_rule_expr_is_set(nle, NFT_EXPR_LOOKUP_DREG)) {
@@ -715,6 +796,12 @@ static void netlink_parse_dynset(struct netlink_parse_ctx *ctx,
return netlink_error(ctx, loc,
"Dynset statement has no key expression");
+ if (expr->len < set->keylen) {
+ expr = netlink_parse_concat_expr(ctx, loc, sreg, set->keylen);
+ if (expr == NULL)
+ return;
+ }
+
expr = set_elem_expr_alloc(&expr->location, expr);
expr->timeout = nft_rule_expr_get_u64(nle, NFT_EXPR_DYNSET_TIMEOUT);
@@ -1004,6 +1091,23 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
list_for_each_entry(i, &expr->expressions, list)
expr_postprocess(ctx, &i);
break;
+ case EXPR_CONCAT: {
+ unsigned int type = expr->dtype->type, ntype = 0;
+ int off = expr->dtype->subtypes;
+ const struct datatype *dtype;
+
+ list_for_each_entry(i, &expr->expressions, list) {
+ if (type) {
+ dtype = concat_subtype_lookup(type, --off);
+ expr_set_type(i, dtype, dtype->byteorder);
+ }
+ expr_postprocess(ctx, stmt, &i);
+
+ ntype = concat_subtype_add(ntype, i->dtype->type);
+ }
+ expr->dtype = concat_type_alloc(ntype);
+ break;
+ }
case EXPR_UNARY:
expr_postprocess(ctx, &expr->arg);
expr_set_type(expr->arg, expr->arg->dtype, !expr->arg->byteorder);
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index fbc6ae12..bf1e56be 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -27,19 +27,60 @@ struct netlink_linearize_ctx {
static void netlink_put_register(struct nft_rule_expr *nle,
uint32_t attr, uint32_t reg)
{
+ /* Convert to 128 bit register numbers if possible for compatibility */
+ if (reg != NFT_REG_VERDICT) {
+ reg -= NFT_REG_1;
+ if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
+ reg = NFT_REG_1 + reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
+ else
+ reg += NFT_REG32_00;
+ }
+
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,
+ unsigned int size)
{
- if (ctx->reg_low > NFT_REG_MAX)
+ unsigned int reg, n;
+
+ n = netlink_register_space(size);
+ if (ctx->reg_low + n > NFT_REG_1 + NFT_REG32_15 - NFT_REG32_00 + 1)
BUG("register reg_low %u invalid\n", ctx->reg_low);
- return ctx->reg_low++;
+
+ reg = ctx->reg_low;
+ ctx->reg_low += n;
+ return reg;
}
-static void release_register(struct netlink_linearize_ctx *ctx)
+static void __release_register(struct netlink_linearize_ctx *ctx,
+ unsigned int size)
{
- ctx->reg_low--;
+ unsigned int n;
+
+ n = netlink_register_space(size);
+ if (ctx->reg_low < NFT_REG_1 + n)
+ BUG("register reg_low %u invalid\n", ctx->reg_low);
+
+ ctx->reg_low -= n;
+}
+
+static enum nft_registers get_register(struct netlink_linearize_ctx *ctx,
+ const struct expr *expr)
+{
+ if (expr && expr->ops->type == EXPR_CONCAT)
+ return __get_register(ctx, expr->len);
+ else
+ return __get_register(ctx, NFT_REG_SIZE * BITS_PER_BYTE);
+}
+
+static void release_register(struct netlink_linearize_ctx *ctx,
+ const struct expr *expr)
+{
+ if (expr && expr->ops->type == EXPR_CONCAT)
+ __release_register(ctx, expr->len);
+ else
+ __release_register(ctx, NFT_REG_SIZE * BITS_PER_BYTE);
}
static void netlink_gen_expr(struct netlink_linearize_ctx *ctx,
@@ -52,8 +93,10 @@ static void netlink_gen_concat(struct netlink_linearize_ctx *ctx,
{
const struct expr *i;
- list_for_each_entry(i, &expr->expressions, list)
+ list_for_each_entry(i, &expr->expressions, list) {
netlink_gen_expr(ctx, i, dreg);
+ dreg += netlink_register_space(i->len);
+ }
}
static void netlink_gen_payload(struct netlink_linearize_ctx *ctx,
@@ -124,7 +167,7 @@ static void netlink_gen_map(struct netlink_linearize_ctx *ctx,
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;
@@ -139,7 +182,7 @@ static void netlink_gen_map(struct netlink_linearize_ctx *ctx,
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);
}
@@ -154,7 +197,7 @@ static void netlink_gen_lookup(struct netlink_linearize_ctx *ctx,
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");
@@ -164,7 +207,7 @@ static void netlink_gen_lookup(struct netlink_linearize_ctx *ctx,
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);
}
@@ -206,7 +249,7 @@ static void netlink_gen_cmp(struct netlink_linearize_ctx *ctx,
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) {
@@ -242,7 +285,7 @@ static void netlink_gen_cmp(struct netlink_linearize_ctx *ctx,
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);
}
@@ -258,7 +301,7 @@ static void netlink_gen_range(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);
nle = alloc_nft_expr("cmp");
@@ -301,7 +344,7 @@ static void netlink_gen_range(struct netlink_linearize_ctx *ctx,
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,
@@ -316,7 +359,7 @@ 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);
@@ -340,7 +383,7 @@ static void netlink_gen_flagcmp(struct netlink_linearize_ctx *ctx,
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,
@@ -507,6 +550,8 @@ static void netlink_gen_expr(struct netlink_linearize_ctx *ctx,
const struct expr *expr,
enum nft_registers dreg)
{
+ assert(dreg < ctx->reg_low);
+
switch (expr->ops->type) {
case EXPR_VERDICT:
case EXPR_VALUE:
@@ -565,9 +610,9 @@ static void netlink_gen_meta_stmt(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);
@@ -647,11 +692,11 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
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);
@@ -669,11 +714,11 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
}
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);
@@ -690,7 +735,7 @@ static void netlink_gen_nat_stmt(struct netlink_linearize_ctx *ctx,
}
while (registers > 0) {
- release_register(ctx);
+ release_register(ctx, NULL);
registers--;
}
@@ -724,11 +769,11 @@ static void netlink_gen_redir_stmt(struct netlink_linearize_ctx *ctx,
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,
@@ -750,7 +795,7 @@ static void netlink_gen_redir_stmt(struct netlink_linearize_ctx *ctx,
}
while (registers > 0) {
- release_register(ctx);
+ release_register(ctx, NULL);
registers--;
}
@@ -791,9 +836,9 @@ static void netlink_gen_ct_stmt(struct netlink_linearize_ctx *ctx,
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);
@@ -807,9 +852,9 @@ static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
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);