diff options
Diffstat (limited to 'src/expression.c')
-rw-r--r-- | src/expression.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/src/expression.c b/src/expression.c index 7390089c..c0cb7f22 100644 --- a/src/expression.c +++ b/src/expression.c @@ -8,11 +8,10 @@ * Development of this code funded by Astaro AG (http://www.astaro.com/) */ +#include <nft.h> + #include <stddef.h> -#include <stdlib.h> #include <stdio.h> -#include <stdint.h> -#include <string.h> #include <limits.h> #include <expression.h> @@ -29,6 +28,7 @@ extern const struct expr_ops ct_expr_ops; extern const struct expr_ops fib_expr_ops; extern const struct expr_ops hash_expr_ops; +extern const struct expr_ops inner_expr_ops; extern const struct expr_ops meta_expr_ops; extern const struct expr_ops numgen_expr_ops; extern const struct expr_ops osf_expr_ops; @@ -94,7 +94,7 @@ void expr_free(struct expr *expr) */ if (expr->etype != EXPR_INVALID) expr_destroy(expr); - xfree(expr); + free(expr); } void expr_print(const struct expr *expr, struct output_ctx *octx) @@ -140,8 +140,10 @@ void expr_describe(const struct expr *expr, struct output_ctx *octx) nft_print(octx, "%s expression, datatype %s (%s)", expr_name(expr), dtype->name, dtype->desc); - if (dtype == &invalid_type) + if (dtype == &invalid_type) { + nft_print(octx, "\n"); return; + } } if (dtype->basetype != NULL) { @@ -181,15 +183,6 @@ void expr_describe(const struct expr *expr, struct output_ctx *octx) } } -void expr_to_string(const struct expr *expr, char *string) -{ - int len = expr->len / BITS_PER_BYTE; - - assert(expr->dtype == &string_type); - - mpz_export_data(string, expr->value, BYTEORDER_HOST_ENDIAN, len); -} - void expr_set_type(struct expr *expr, const struct datatype *dtype, enum byteorder byteorder) { @@ -314,7 +307,7 @@ static void symbol_expr_clone(struct expr *new, const struct expr *expr) static void symbol_expr_destroy(struct expr *expr) { - xfree(expr->identifier); + free_const(expr->identifier); } static const struct expr_ops symbol_expr_ops = { @@ -994,7 +987,7 @@ static struct expr *concat_expr_parse_udata(const struct nftnl_udata *attr) goto err_free; etype = nftnl_udata_get_u32(nest_ud[NFTNL_UDATA_SET_KEY_CONCAT_SUB_TYPE]); - ops = expr_ops_by_type(etype); + ops = expr_ops_by_type_u32(etype); if (!ops || !ops->parse_udata) goto err_free; @@ -1012,7 +1005,7 @@ static struct expr *concat_expr_parse_udata(const struct nftnl_udata *attr) if (!dtype) goto err_free; - concat_expr->dtype = datatype_get(dtype); + __datatype_set(concat_expr, dtype); concat_expr->len = len; return concat_expr; @@ -1321,9 +1314,14 @@ static void set_elem_expr_print(const struct expr *expr, } if (expr->timeout) { nft_print(octx, " timeout "); - time_print(expr->timeout, octx); + if (expr->timeout == NFT_NEVER_TIMEOUT) + nft_print(octx, "never"); + else + time_print(expr->timeout, octx); } - if (!nft_output_stateless(octx) && expr->expiration) { + if (!nft_output_stateless(octx) && + expr->timeout != NFT_NEVER_TIMEOUT && + expr->expiration) { nft_print(octx, " expires "); time_print(expr->expiration, octx); } @@ -1335,15 +1333,14 @@ static void set_elem_expr_destroy(struct expr *expr) { struct stmt *stmt, *next; - xfree(expr->comment); + free_const(expr->comment); expr_free(expr->key); list_for_each_entry_safe(stmt, next, &expr->stmt_list, list) stmt_free(stmt); } -static void set_elem_expr_clone(struct expr *new, const struct expr *expr) +static void __set_elem_expr_clone(struct expr *new, const struct expr *expr) { - new->key = expr_clone(expr->key); new->expiration = expr->expiration; new->timeout = expr->timeout; if (expr->comment) @@ -1351,6 +1348,12 @@ static void set_elem_expr_clone(struct expr *new, const struct expr *expr) init_list_head(&new->stmt_list); } +static void set_elem_expr_clone(struct expr *new, const struct expr *expr) +{ + new->key = expr_clone(expr->key); + __set_elem_expr_clone(new, expr); +} + static const struct expr_ops set_elem_expr_ops = { .type = EXPR_SET_ELEM, .name = "set element", @@ -1378,11 +1381,17 @@ static void set_elem_catchall_expr_print(const struct expr *expr, nft_print(octx, "*"); } +static void set_elem_catchall_expr_clone(struct expr *new, const struct expr *expr) +{ + __set_elem_expr_clone(new, expr); +} + static const struct expr_ops set_elem_catchall_expr_ops = { .type = EXPR_SET_ELEM_CATCHALL, .name = "catch-all set element", .print = set_elem_catchall_expr_print, .json = set_elem_catchall_expr_json, + .clone = set_elem_catchall_expr_clone, }; struct expr *set_elem_catchall_expr_alloc(const struct location *loc) @@ -1497,9 +1506,7 @@ void range_expr_value_high(mpz_t rop, const struct expr *expr) static const struct expr_ops *__expr_ops_by_type(enum expr_types etype) { switch (etype) { - case EXPR_INVALID: - BUG("Invalid expression ops requested"); - break; + case EXPR_INVALID: break; case EXPR_VERDICT: return &verdict_expr_ops; case EXPR_SYMBOL: return &symbol_expr_ops; case EXPR_VARIABLE: return &variable_expr_ops; @@ -1531,20 +1538,23 @@ static const struct expr_ops *__expr_ops_by_type(enum expr_types etype) case EXPR_FLAGCMP: return &flagcmp_expr_ops; } - BUG("Unknown expression type %d\n", etype); + return NULL; } const struct expr_ops *expr_ops(const struct expr *e) { - return __expr_ops_by_type(e->etype); + const struct expr_ops *ops; + + ops = __expr_ops_by_type(e->etype); + if (!ops) + BUG("Unknown expression type %d\n", e->etype); + + return ops; } -const struct expr_ops *expr_ops_by_type(uint32_t value) +const struct expr_ops *expr_ops_by_type_u32(uint32_t value) { - /* value might come from unreliable source, such as "udata" - * annotation of set keys. Avoid BUG() assertion. - */ - if (value == EXPR_INVALID || value > EXPR_MAX) + if (value > EXPR_MAX) return NULL; return __expr_ops_by_type(value); |