diff options
author | Patrick McHardy <kaber@trash.net> | 2009-03-20 16:12:18 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2009-03-20 16:12:18 +0100 |
commit | 1bd3b87687328e1e097ca69cf18f2f14abfa9782 (patch) | |
tree | 5da11e82f3b32151afec78f7d216a25a39d0c429 | |
parent | b076d6c6376a77fa84aa813bf267628820bcc883 (diff) |
expr: add support for cloning expressions
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/expression.h | 3 | ||||
-rw-r--r-- | src/ct.c | 6 | ||||
-rw-r--r-- | src/expression.c | 93 | ||||
-rw-r--r-- | src/exthdr.c | 7 | ||||
-rw-r--r-- | src/meta.c | 6 | ||||
-rw-r--r-- | src/payload.c | 10 |
6 files changed, 125 insertions, 0 deletions
diff --git a/include/expression.h b/include/expression.h index d4222060..b0084c07 100644 --- a/include/expression.h +++ b/include/expression.h @@ -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); @@ -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) diff --git a/src/expression.c b/src/expression.c index 4b3e1e04..dba5331d 100644 --- a/src/expression.c +++ b/src/expression.c @@ -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, }; diff --git a/src/exthdr.c b/src/exthdr.c index 2defc7cb..718979a5 100644 --- a/src/exthdr.c +++ b/src/exthdr.c @@ -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 = @@ -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) diff --git a/src/payload.c b/src/payload.c index b7fbcb36..f76586e3 100644 --- a/src/payload.c +++ b/src/payload.c @@ -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, |