From 25b19818c46d6fea81f3b951223f4ec7fa86ed55 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 13 Dec 2014 07:50:35 +0000 Subject: datatype: change concat_type_alloc() to construct type from id The kernel only stored the id so we need to be able to reconstruct the datatype from the id only. Signed-off-by: Patrick McHardy --- include/datatype.h | 2 +- src/datatype.c | 21 ++++++++++++--------- src/evaluate.c | 11 ++++++----- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index ca6ba9fe..f05f9877 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -212,7 +212,7 @@ extern const struct datatype icmpv6_code_type; extern const struct datatype icmpx_code_type; extern const struct datatype time_type; -extern const struct datatype *concat_type_alloc(const struct expr *expr); +extern const struct datatype *concat_type_alloc(uint32_t type); extern void concat_type_destroy(const struct datatype *dtype); #endif /* NFTABLES_DATATYPE_H */ diff --git a/src/datatype.c b/src/datatype.c index 91e5ed6d..2a9fcdb0 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -924,25 +924,28 @@ static struct datatype *dtype_alloc(void) return dtype; } -const struct datatype *concat_type_alloc(const struct expr *expr) +const struct datatype *concat_type_alloc(uint32_t type) { + const struct datatype *i; struct datatype *dtype; - struct expr *i; char desc[256] = "concatenation of ("; char name[256] = ""; - unsigned int type = 0, size = 0, subtypes = 0; + unsigned int size = 0, subtypes = 0, n; + + n = div_round_up(fls(type), TYPE_BITS); + while ((type >> TYPE_BITS * --n) & TYPE_MASK) { + i = datatype_lookup((type >> TYPE_BITS * n) & TYPE_MASK); + if (i == NULL) + return NULL; - list_for_each_entry(i, &expr->expressions, list) { if (subtypes != 0) { strncat(desc, ", ", sizeof(desc) - strlen(desc) - 1); strncat(name, " . ", sizeof(name) - strlen(name) - 1); } - strncat(desc, i->dtype->desc, sizeof(desc) - strlen(desc) - 1); - strncat(name, i->dtype->name, sizeof(name) - strlen(name) - 1); + strncat(desc, i->desc, sizeof(desc) - strlen(desc) - 1); + strncat(name, i->name, sizeof(name) - strlen(name) - 1); - type <<= TYPE_BITS; - type |= i->dtype->type; - size += i->dtype->size; + size += i->size; subtypes++; } strncat(desc, ")", sizeof(desc) - strlen(desc) - 1); diff --git a/src/evaluate.c b/src/evaluate.c index 9cb2376a..8f0acf72 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -604,11 +604,11 @@ static int list_member_evaluate(struct eval_ctx *ctx, struct expr **expr) static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) { const struct datatype *dtype = ctx->ectx.dtype, *tmp; - unsigned int type = dtype ? dtype->type : 0; + uint32_t type = dtype ? dtype->type : 0, ntype = 0; int off = dtype ? dtype->subtypes : 0; unsigned int flags = EXPR_F_CONSTANT | EXPR_F_SINGLETON; struct expr *i, *next; - unsigned int n, len = 0; + unsigned int n; n = 1; list_for_each_entry_safe(i, next, &(*expr)->expressions, list) { @@ -624,13 +624,14 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) return -1; flags &= i->flags; - len += i->len; + ntype <<= TYPE_BITS; + ntype |= i->dtype->type; n++; } (*expr)->flags |= flags; - (*expr)->dtype = concat_type_alloc(*expr); - (*expr)->len = len; + (*expr)->dtype = concat_type_alloc(ntype); + (*expr)->len = (*expr)->dtype->size; if (off > 0) return expr_error(ctx->msgs, *expr, -- cgit v1.2.3