]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
datatype: change concat_type_alloc() to construct type from id
authorPatrick McHardy <kaber@trash.net>
Sat, 13 Dec 2014 07:50:35 +0000 (07:50 +0000)
committerPatrick McHardy <kaber@trash.net>
Tue, 16 Dec 2014 17:20:54 +0000 (18:20 +0100)
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 <kaber@trash.net>
include/datatype.h
src/datatype.c
src/evaluate.c

index ca6ba9fe50ee633d30a03df50fcfce710138f5bb..f05f9877c772fe3c7b104f2160b9517b6a4793e1 100644 (file)
@@ -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 */
index 91e5ed6d4bd3577f9ecca6bde8db02954e41e847..2a9fcdb0f37043defa0aeaa3cf8d80640dab7064 100644 (file)
@@ -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);
index 9cb2376aaed73fd0f63038042cebbcf1c5041166..8f0acf72af2e334eeb77ec9129c1098e174f77b7 100644 (file)
@@ -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,