diff options
author | Patrick McHardy <kaber@trash.net> | 2015-06-13 14:48:56 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2015-06-13 14:48:56 +0200 |
commit | 077509fdea3aa009823491be7096749c84795874 (patch) | |
tree | 07287fb0971df4011b33135d25ef8b0c0848e099 | |
parent | 45cabc474e46c74c27b645582d37a55d5d076051 (diff) | |
parent | a93bc1795b272174a10d90961a248f2c620bfa2c (diff) |
Merge remote-tracking branch 'origin/next-4.1'
-rw-r--r-- | include/linux/netfilter/nf_tables.h | 34 | ||||
-rw-r--r-- | include/netlink.h | 15 | ||||
-rw-r--r-- | src/datatype.c | 5 | ||||
-rw-r--r-- | src/evaluate.c | 7 | ||||
-rw-r--r-- | src/netlink.c | 46 | ||||
-rw-r--r-- | src/netlink_delinearize.c | 130 | ||||
-rw-r--r-- | src/netlink_linearize.c | 105 |
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); |