From 1bd3b87687328e1e097ca69cf18f2f14abfa9782 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 20 Mar 2009 16:12:18 +0100 Subject: expr: add support for cloning expressions Signed-off-by: Patrick McHardy --- src/ct.c | 6 ++++ src/expression.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/exthdr.c | 7 +++++ src/meta.c | 6 ++++ src/payload.c | 10 ++++++ 5 files changed, 122 insertions(+) (limited to 'src') diff --git a/src/ct.c b/src/ct.c index 00895394..43dd9878 100644 --- 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) 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 = diff --git a/src/meta.c b/src/meta.c index cb9e495c..5998d09c 100644 --- a/src/meta.c +++ b/src/meta.c @@ -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, -- cgit v1.2.3