]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
expr: add support for cloning expressions
authorPatrick McHardy <kaber@trash.net>
Fri, 20 Mar 2009 15:12:18 +0000 (16:12 +0100)
committerPatrick McHardy <kaber@trash.net>
Fri, 20 Mar 2009 15:12:18 +0000 (16:12 +0100)
Signed-off-by: Patrick McHardy <kaber@trash.net>
include/expression.h
src/ct.c
src/expression.c
src/exthdr.c
src/meta.c
src/payload.c

index d422206033dea29e6a4f22cbfaa0ac695a270ad4..b0084c07f080d8839888fe41a1fb78fd87be23af 100644 (file)
@@ -106,6 +106,7 @@ static inline void expr_set_context(struct expr_ctx *ctx,
  *
  * @type:      expression type
  * @name:      expression name for diagnostics
+ * @clone:     function to clone type specific data
  * @destroy:   destructor, must release inner expressions
  * @set_type:  function to promote type and byteorder of inner types
  * @print:     function to print the expression
@@ -113,6 +114,7 @@ static inline void expr_set_context(struct expr_ctx *ctx,
 struct expr_ops {
        enum expr_types         type;
        const char              *name;
+       void                    (*clone)(struct expr *new, const struct expr *expr);
        void                    (*destroy)(struct expr *expr);
        void                    (*set_type)(const struct expr *expr,
                                            const struct datatype *dtype,
@@ -238,6 +240,7 @@ extern struct expr *expr_alloc(const struct location *loc,
                               const struct expr_ops *ops,
                               const struct datatype *dtype,
                               enum byteorder byteorder, unsigned int len);
+extern struct expr *expr_clone(const struct expr *expr);
 extern struct expr *expr_get(struct expr *expr);
 extern void expr_free(struct expr *expr);
 extern void expr_print(const struct expr *expr);
index 008953949f36dde32092a6b8909e2403f1324420..43dd9878bbd40deca4f7fbd2122fa61ab805b774 100644 (file)
--- a/src/ct.c
+++ b/src/ct.c
@@ -131,10 +131,16 @@ static void ct_expr_print(const struct expr *expr)
        printf("ct %s", ct_templates[expr->ct.key].token);
 }
 
+static void ct_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->ct.key = expr->ct.key;
+}
+
 static const struct expr_ops ct_expr_ops = {
        .type           = EXPR_CT,
        .name           = "ct",
        .print          = ct_expr_print,
+       .clone          = ct_expr_clone,
 };
 
 struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key)
index 4b3e1e0475d23824cf04fbef1988b8063f321dd0..dba5331d4f67e08182419083fdf80d276d38379e 100644 (file)
@@ -39,6 +39,18 @@ struct expr *expr_alloc(const struct location *loc, const struct expr_ops *ops,
        return expr;
 }
 
+struct expr *expr_clone(const struct expr *expr)
+{
+       struct expr *new;
+
+       new = expr_alloc(&expr->location, expr->ops, expr->dtype,
+                        expr->byteorder, expr->len);
+       new->flags = expr->flags;
+       new->op    = expr->op;
+       expr->ops->clone(new, expr);
+       return new;
+}
+
 struct expr *expr_get(struct expr *expr)
 {
        expr->refcnt++;
@@ -134,6 +146,13 @@ static void verdict_expr_print(const struct expr *expr)
        datatype_print(expr);
 }
 
+static void verdict_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->verdict = expr->verdict;
+       if (expr->chain != NULL)
+               new->chain = xstrdup(expr->chain);
+}
+
 static void verdict_expr_destroy(struct expr *expr)
 {
         xfree(expr->chain);
@@ -143,6 +162,7 @@ static const struct expr_ops verdict_expr_ops = {
        .type           = EXPR_VERDICT,
        .name           = "verdict",
        .print          = verdict_expr_print,
+       .clone          = verdict_expr_clone,
        .destroy        = verdict_expr_destroy,
 };
 
@@ -165,6 +185,13 @@ static void symbol_expr_print(const struct expr *expr)
        printf("%s%s", expr->scope != NULL ? "$" : "", expr->identifier);
 }
 
+static void symbol_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->sym_type   = expr->sym_type;
+       new->scope      = expr->scope;
+       new->identifier = xstrdup(expr->identifier);
+}
+
 static void symbol_expr_destroy(struct expr *expr)
 {
        xfree(expr->identifier);
@@ -174,6 +201,7 @@ static const struct expr_ops symbol_expr_ops = {
        .type           = EXPR_SYMBOL,
        .name           = "symbol",
        .print          = symbol_expr_print,
+       .clone          = symbol_expr_clone,
        .destroy        = symbol_expr_destroy,
 };
 
@@ -193,6 +221,11 @@ static void constant_expr_print(const struct expr *expr)
        datatype_print(expr);
 }
 
+static void constant_expr_clone(struct expr *new, const struct expr *expr)
+{
+       mpz_init_set(new->value, expr->value);
+}
+
 static void constant_expr_destroy(struct expr *expr)
 {
        mpz_clear(expr->value);
@@ -202,6 +235,7 @@ static const struct expr_ops constant_expr_ops = {
        .type           = EXPR_VALUE,
        .name           = "value",
        .print          = constant_expr_print,
+       .clone          = constant_expr_clone,
        .destroy        = constant_expr_destroy,
 };
 
@@ -275,11 +309,24 @@ static void prefix_expr_set_type(const struct expr *expr,
        expr_set_type(expr->expr, type, byteorder);
 }
 
+static void prefix_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->expr       = expr_clone(expr->expr);
+       new->prefix_len = expr->prefix_len;
+}
+
+static void prefix_expr_destroy(struct expr *expr)
+{
+       expr_free(expr->expr);
+}
+
 static const struct expr_ops prefix_expr_ops = {
        .type           = EXPR_PREFIX,
        .name           = "prefix",
        .print          = prefix_expr_print,
        .set_type       = prefix_expr_set_type,
+       .clone          = prefix_expr_clone,
+       .destroy        = prefix_expr_destroy,
 };
 
 struct expr *prefix_expr_alloc(const struct location *loc,
@@ -321,6 +368,11 @@ static void unary_expr_print(const struct expr *expr)
        printf(")");
 }
 
+static void unary_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->arg = expr_clone(expr->expr);
+}
+
 static void unary_expr_destroy(struct expr *expr)
 {
        expr_free(expr->arg);
@@ -330,6 +382,7 @@ static const struct expr_ops unary_expr_ops = {
        .type           = EXPR_UNARY,
        .name           = "unary",
        .print          = unary_expr_print,
+       .clone          = unary_expr_clone,
        .destroy        = unary_expr_destroy,
 };
 
@@ -355,6 +408,12 @@ static void binop_expr_print(const struct expr *expr)
        expr_print(expr->right);
 }
 
+static void binop_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->left  = expr_clone(expr->left);
+       new->right = expr_clone(expr->right);
+}
+
 static void binop_expr_destroy(struct expr *expr)
 {
        expr_free(expr->left);
@@ -365,6 +424,7 @@ static const struct expr_ops binop_expr_ops = {
        .type           = EXPR_BINOP,
        .name           = "binop",
        .print          = binop_expr_print,
+       .clone          = binop_expr_clone,
        .destroy        = binop_expr_destroy,
 };
 
@@ -408,6 +468,12 @@ static void range_expr_print(const struct expr *expr)
        expr_print(expr->right);
 }
 
+static void range_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->left  = expr_clone(expr->left);
+       new->right = expr_clone(expr->right);
+}
+
 static void range_expr_destroy(struct expr *expr)
 {
        expr_free(expr->left);
@@ -426,6 +492,7 @@ static const struct expr_ops range_expr_ops = {
        .type           = EXPR_RANGE,
        .name           = "range",
        .print          = range_expr_print,
+       .clone          = range_expr_clone,
        .destroy        = range_expr_destroy,
        .set_type       = range_expr_set_type,
 };
@@ -452,6 +519,15 @@ static struct expr *compound_expr_alloc(const struct location *loc,
        return expr;
 }
 
+static void compound_expr_clone(struct expr *new, const struct expr *expr)
+{
+       struct expr *i;
+
+       init_list_head(&new->expressions);
+       list_for_each_entry(i, &expr->expressions, list)
+               compound_expr_add(new, expr_clone(i));
+}
+
 static void compound_expr_destroy(struct expr *expr)
 {
        struct expr *i, *next;
@@ -493,6 +569,7 @@ static const struct expr_ops concat_expr_ops = {
        .type           = EXPR_CONCAT,
        .name           = "concat",
        .print          = concat_expr_print,
+       .clone          = compound_expr_clone,
        .destroy        = compound_expr_destroy,
 };
 
@@ -510,6 +587,7 @@ static const struct expr_ops list_expr_ops = {
        .type           = EXPR_LIST,
        .name           = "list",
        .print          = list_expr_print,
+       .clone          = compound_expr_clone,
        .destroy        = compound_expr_destroy,
 };
 
@@ -540,6 +618,7 @@ static const struct expr_ops set_expr_ops = {
        .name           = "set",
        .print          = set_expr_print,
        .set_type       = set_expr_set_type,
+       .clone          = compound_expr_clone,
        .destroy        = compound_expr_destroy,
 };
 
@@ -562,6 +641,12 @@ static void mapping_expr_set_type(const struct expr *expr,
        expr_set_type(expr->left, dtype, byteorder);
 }
 
+static void mapping_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->left  = expr_clone(expr->left);
+       new->right = expr_clone(expr->right);
+}
+
 static void mapping_expr_destroy(struct expr *expr)
 {
        expr_free(expr->left);
@@ -573,6 +658,7 @@ static const struct expr_ops mapping_expr_ops = {
        .name           = "mapping",
        .print          = mapping_expr_print,
        .set_type       = mapping_expr_set_type,
+       .clone          = mapping_expr_clone,
        .destroy        = mapping_expr_destroy,
 };
 
@@ -595,6 +681,12 @@ static void map_expr_print(const struct expr *expr)
        expr_print(expr->mappings);
 }
 
+static void map_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->expr     = expr_clone(expr->expr);
+       new->mappings = expr_clone(expr->mappings);
+}
+
 static void map_expr_destroy(struct expr *expr)
 {
        expr_free(expr->expr);
@@ -605,6 +697,7 @@ static const struct expr_ops map_expr_ops = {
        .type           = EXPR_MAP,
        .name           = "map",
        .print          = map_expr_print,
+       .clone          = map_expr_clone,
        .destroy        = map_expr_destroy,
 };
 
index 2defc7cb27c2e338f6cbcaa5078701b05908665a..718979a5ff05ce6d645e450657e6cb0c8a78d100 100644 (file)
@@ -27,10 +27,17 @@ static void exthdr_expr_print(const struct expr *expr)
        printf("%s %s", expr->exthdr.desc->name, expr->exthdr.tmpl->token);
 }
 
+static void exthdr_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->exthdr.desc = expr->exthdr.desc;
+       new->exthdr.tmpl = expr->exthdr.tmpl;
+}
+
 static const struct expr_ops exthdr_expr_ops = {
        .type           = EXPR_EXTHDR,
        .name           = "exthdr",
        .print          = exthdr_expr_print,
+       .clone          = exthdr_expr_clone,
 };
 
 static const struct payload_template exthdr_unknown_template =
index cb9e495c623d5241b8690951d4c589c13477247e..5998d09c1a31672cbf772fd93ee7298c22a561c3 100644 (file)
@@ -305,10 +305,16 @@ static void meta_expr_print(const struct expr *expr)
        printf("meta %s", meta_templates[expr->meta.key].token);
 }
 
+static void meta_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->meta.key = expr->meta.key;
+}
+
 static const struct expr_ops meta_expr_ops = {
        .type           = EXPR_META,
        .name           = "meta",
        .print          = meta_expr_print,
+       .clone          = meta_expr_clone,
 };
 
 struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
index b7fbcb366d58f2594d95fc98a0d9e157ea62f3dd..f76586e3f4c8c8edea298d458c9485d0b57ff9bc 100644 (file)
@@ -63,10 +63,20 @@ static void payload_expr_print(const struct expr *expr)
                       expr->payload.offset, expr->len);
 }
 
+static void payload_expr_clone(struct expr *new, const struct expr *expr)
+{
+       new->payload.desc   = expr->payload.desc;
+       new->payload.tmpl   = expr->payload.tmpl;
+       new->payload.base   = expr->payload.base;
+       new->payload.offset = expr->payload.offset;
+       new->payload.flags  = expr->payload.flags;
+}
+
 static const struct expr_ops payload_expr_ops = {
        .type           = EXPR_PAYLOAD,
        .name           = "payload",
        .print          = payload_expr_print,
+       .clone          = payload_expr_clone,
 };
 
 struct expr *payload_expr_alloc(const struct location *loc,