diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expression.c | 17 | ||||
-rw-r--r-- | src/netlink.c | 10 |
2 files changed, 22 insertions, 5 deletions
diff --git a/src/expression.c b/src/expression.c index deb649e1..7390089c 100644 --- a/src/expression.c +++ b/src/expression.c @@ -879,17 +879,30 @@ static void concat_expr_print(const struct expr *expr, struct output_ctx *octx) #define NFTNL_UDATA_SET_KEY_CONCAT_SUB_DATA 1 #define NFTNL_UDATA_SET_KEY_CONCAT_SUB_MAX 2 +static struct expr *expr_build_udata_recurse(struct expr *e) +{ + switch (e->etype) { + case EXPR_BINOP: + return e->left; + default: + break; + } + + return e; +} + static int concat_expr_build_udata(struct nftnl_udata_buf *udbuf, const struct expr *concat_expr) { struct nftnl_udata *nest; + struct expr *expr, *tmp; unsigned int i = 0; - struct expr *expr; - list_for_each_entry(expr, &concat_expr->expressions, list) { + list_for_each_entry_safe(expr, tmp, &concat_expr->expressions, list) { struct nftnl_udata *nest_expr; int err; + expr = expr_build_udata_recurse(expr); if (!expr_ops(expr)->build_udata || i >= NFT_REG32_SIZE) return -1; diff --git a/src/netlink.c b/src/netlink.c index 89d864ed..799cf9b8 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1114,17 +1114,21 @@ static struct expr *concat_elem_expr(struct expr *key, struct expr *data, int *off) { const struct datatype *subtype; + unsigned int sub_length; struct expr *expr; if (key) { (*off)--; - expr = constant_expr_splice(data, key->len); + sub_length = round_up(key->len, BITS_PER_BYTE); + + expr = constant_expr_splice(data, sub_length); expr->dtype = datatype_get(key->dtype); expr->byteorder = key->byteorder; expr->len = key->len; } else { subtype = concat_subtype_lookup(dtype->type, --(*off)); - expr = constant_expr_splice(data, subtype->size); + sub_length = round_up(subtype->size, BITS_PER_BYTE); + expr = constant_expr_splice(data, sub_length); expr->dtype = subtype; expr->byteorder = subtype->byteorder; } @@ -1136,7 +1140,7 @@ static struct expr *concat_elem_expr(struct expr *key, expr->dtype->basetype->type == TYPE_BITMASK) expr = bitmask_expr_to_binops(expr); - data->len -= netlink_padding_len(expr->len); + data->len -= netlink_padding_len(sub_length); return expr; } |