From 87908ff7a12c969ca21338ab7ed27ed93a9b09c3 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 14:54:19 +0100 Subject: datatype: fix parsing of time type Properly detect time strings in the lexer without quotation marks. Signed-off-by: Patrick McHardy --- src/datatype.c | 4 ---- src/scanner.l | 7 +++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/datatype.c b/src/datatype.c index c93f76a3..0772b507 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -775,8 +775,6 @@ static void time_type_print(const struct expr *expr) minutes = seconds / 60; seconds %= 60; - printf("\""); - if (days > 0) printf("%"PRIu64"d", days); if (hours > 0) @@ -785,8 +783,6 @@ static void time_type_print(const struct expr *expr) printf("%"PRIu64"m", minutes); if (seconds > 0) printf("%"PRIu64"s", seconds); - - printf("\""); } enum { diff --git a/src/scanner.l b/src/scanner.l index 73c4f8b1..27d95bfc 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -117,6 +117,8 @@ quotedstring \"[^"]*\" comment #.*$ slash \/ +timestring ([0-9]+d)?([0-9]+h)?([0-9]+m)?([0-9]+s)? + hex4 ([[:xdigit:]]{1,4}) v680 (({hex4}:){7}{hex4}) v670 ((:)((:{hex4}){7})) @@ -457,6 +459,11 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) return STRING; } +{timestring} { + yylval->string = xstrdup(yytext); + return STRING; + } + {decstring} { errno = 0; yylval->val = strtoull(yytext, NULL, 0); -- cgit v1.2.3 From 262b97bd112cbaed098c7941bd452c7b16a89646 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 14:56:16 +0100 Subject: datatype: less strict time parsing Don't require hours to be in range 0-23 and minutes/seconds in range 0-59. The time_type is used for relative times where it is entirely reasonable to specify 180s instead of 3m. Signed-off-by: Patrick McHardy --- src/datatype.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/datatype.c b/src/datatype.c index 0772b507..1c837152 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -831,10 +831,6 @@ static struct error_record *time_type_parse(const struct expr *sym, } h = str2int(tmp, c, k); k = 0; - if (h > 23) { - return error(&sym->location, - "Hour needs to be 0-23"); - } mask |= HOUR; break; case 'm': @@ -844,10 +840,6 @@ static struct error_record *time_type_parse(const struct expr *sym, } m = str2int(tmp, c, k); k = 0; - if (m > 59) { - return error(&sym->location, - "Minute needs to be 0-59"); - } mask |= MIN; break; case 's': @@ -857,10 +849,6 @@ static struct error_record *time_type_parse(const struct expr *sym, } s = str2int(tmp, c, k); k = 0; - if (s > 59) { - return error(&sym->location, - "second needs to be 0-59"); - } mask |= SECS; break; default: -- cgit v1.2.3 From 0974fa84f162aecf16b4c252dcb438f7149856ab Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 15:59:44 +0100 Subject: datatype: seperate time parsing/printing from time_type Seperate relative time parsing and printing from the time_type to make it usable for set and set element time related parameters. Signed-off-by: Patrick McHardy --- include/datatype.h | 4 ++++ src/datatype.c | 66 +++++++++++++++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/include/datatype.h b/include/datatype.h index 3c3f42f3..2a6a4fca 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -231,4 +231,8 @@ concat_subtype_lookup(uint32_t type, unsigned int n) return datatype_lookup(concat_subtype_id(type, n)); } +extern void time_print(uint64_t seconds); +extern struct error_record *time_parse(const struct location *loc, + const char *c, uint64_t *res); + #endif /* NFTABLES_DATATYPE_H */ diff --git a/src/datatype.c b/src/datatype.c index 1c837152..f93337b1 100644 --- a/src/datatype.c +++ b/src/datatype.c @@ -760,11 +760,9 @@ const struct datatype icmpx_code_type = { .sym_tbl = &icmpx_code_tbl, }; -static void time_type_print(const struct expr *expr) +void time_print(uint64_t seconds) { - uint64_t days, hours, minutes, seconds; - - seconds = mpz_get_uint64(expr->value); + uint64_t days, hours, minutes; days = seconds / 86400; seconds %= 86400; @@ -801,8 +799,8 @@ static uint32_t str2int(char *tmp, const char *c, int k) return atoi(tmp); } -static struct error_record *time_type_parse(const struct expr *sym, - struct expr **res) +struct error_record *time_parse(const struct location *loc, const char *str, + uint64_t *res) { int i, len; unsigned int k = 0; @@ -811,64 +809,82 @@ static struct error_record *time_type_parse(const struct expr *sym, uint64_t d = 0, h = 0, m = 0, s = 0; uint32_t mask = 0; - c = sym->identifier; + c = str; len = strlen(c); for (i = 0; i < len; i++, c++) { switch (*c) { case 'd': - if (mask & DAY) { - return error(&sym->location, + if (mask & DAY) + return error(loc, "Day has been specified twice"); - } + d = str2int(tmp, c, k); k = 0; mask |= DAY; break; case 'h': - if (mask & HOUR) { - return error(&sym->location, + if (mask & HOUR) + return error(loc, "Hour has been specified twice"); - } + h = str2int(tmp, c, k); k = 0; mask |= HOUR; break; case 'm': - if (mask & MIN) { - return error(&sym->location, + if (mask & MIN) + return error(loc, "Minute has been specified twice"); - } + m = str2int(tmp, c, k); k = 0; mask |= MIN; break; case 's': - if (mask & SECS) { - return error(&sym->location, + if (mask & SECS) + return error(loc, "Second has been specified twice"); - } + s = str2int(tmp, c, k); k = 0; mask |= SECS; break; default: if (!isdigit(*c)) - return error(&sym->location, "wrong format"); + return error(loc, "wrong time format"); - if (k++ >= array_size(tmp)) { - return error(&sym->location, - "value too large"); - } + if (k++ >= array_size(tmp)) + return error(loc, "value too large"); break; } } /* default to seconds if no unit was specified */ if (!mask) - s = atoi(sym->identifier); + s = atoi(str); else s = 24*60*60*d+60*60*h+60*m+s; + *res = s; + return NULL; +} + + +static void time_type_print(const struct expr *expr) +{ + time_print(mpz_get_uint64(expr->value)); +} + +static struct error_record *time_type_parse(const struct expr *sym, + struct expr **res) +{ + struct error_record *erec; + uint64_t s; + + erec = time_parse(&sym->location, sym->identifier, &s); + if (erec != NULL) + return erec; + if (s > UINT32_MAX) return error(&sym->location, "value too large"); -- cgit v1.2.3 From 48587aa855a5173b4b1e94290af885000dbd679e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 15:41:32 +0100 Subject: parser: add a time_spec rule Signed-off-by: Patrick McHardy --- src/parser_bison.y | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/parser_bison.y b/src/parser_bison.y index b86381d9..cd4e096a 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -396,6 +396,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type identifier string comment_spec %destructor { xfree($$); } identifier string comment_spec +%type time_spec + %type type_identifier %type data_type @@ -1093,6 +1095,20 @@ string : STRING | QUOTED_STRING ; +time_spec : STRING + { + struct error_record *erec; + uint64_t res; + + erec = time_parse(&@1, $1, &res); + if (erec != NULL) { + erec_queue(erec, state->msgs); + YYERROR; + } + $$ = res; + } + ; + family_spec : /* empty */ { $$ = NFPROTO_IPV4; } | family_spec_explicit ; -- cgit v1.2.3 From 6aa18b5216a34a2cd29ad4a1997c37f705f76247 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Apr 2015 10:41:56 +0100 Subject: parser: fix inconsistencies in set expression rules Set keys are currently defined as a regular expr for pure sets and map_lhs_expr for maps. map_lhs_expr is what can actually be used for a single member, namely a concat_expr or a multiton_expr. The reason why pure sets use expr for the key is to allow recursive set specifications, which doesn't make sense for maps since every element needs a mapping. However, the rule is too wide and also allows map expressions as a key, which obviously doesn't make sense. Rearrange the rules so we have: set_lhs_expr: concat or multiton set_rhs_expr: concat or verdict and special case the recursive set specifications, as they deserve. Besides making it a lot easier to understand what is actually supported, this will be used by the following patch to support timeouts and comments for keys in a uniform way. Signed-off-by: Patrick McHardy --- src/parser_bison.y | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/parser_bison.y b/src/parser_bison.y index cd4e096a..c934533d 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -470,8 +470,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %destructor { expr_free($$); } prefix_expr range_expr wildcard_expr %type list_expr %destructor { expr_free($$); } list_expr -%type concat_expr map_lhs_expr -%destructor { expr_free($$); } concat_expr map_lhs_expr +%type concat_expr +%destructor { expr_free($$); } concat_expr %type map_expr %destructor { expr_free($$); } map_expr @@ -484,6 +484,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type set_expr set_list_expr set_list_member_expr %destructor { expr_free($$); } set_expr set_list_expr set_list_member_expr +%type set_lhs_expr set_rhs_expr +%destructor { expr_free($$); } set_lhs_expr set_rhs_expr %type expr initializer_expr %destructor { expr_free($$); } expr initializer_expr @@ -1297,13 +1299,12 @@ verdict_map_list_expr : verdict_map_list_member_expr | verdict_map_list_expr COMMA opt_newline ; -verdict_map_list_member_expr: opt_newline map_lhs_expr COLON verdict_expr opt_newline +verdict_map_list_member_expr: opt_newline set_lhs_expr COLON verdict_expr opt_newline { $$ = mapping_expr_alloc(&@$, $2, $4); } ; - counter_stmt : counter_stmt_alloc | counter_stmt_alloc counter_args @@ -1718,10 +1719,6 @@ multiton_expr : prefix_expr | wildcard_expr ; -map_lhs_expr : multiton_expr - | concat_expr - ; - map_expr : concat_expr MAP expr { $$ = map_expr_alloc(&@$, $1, $3); @@ -1729,9 +1726,9 @@ map_expr : concat_expr MAP expr ; expr : concat_expr + | multiton_expr | set_expr | map_expr - | multiton_expr ; set_expr : '{' set_list_expr '}' @@ -1754,20 +1751,28 @@ set_list_expr : set_list_member_expr | set_list_expr COMMA opt_newline ; -set_list_member_expr : opt_newline expr opt_newline +set_list_member_expr : opt_newline set_expr opt_newline { $$ = $2; } - | opt_newline map_lhs_expr COLON concat_expr opt_newline + | opt_newline set_lhs_expr opt_newline { - $$ = mapping_expr_alloc(&@$, $2, $4); + $$ = $2; } - | opt_newline map_lhs_expr COLON verdict_expr opt_newline + | opt_newline set_lhs_expr COLON set_rhs_expr opt_newline { $$ = mapping_expr_alloc(&@$, $2, $4); } ; +set_lhs_expr : concat_expr + | multiton_expr + ; + +set_rhs_expr : concat_expr + | verdict_expr + ; + initializer_expr : expr | list_expr ; -- cgit v1.2.3 From 52532335290457cc449564b7e011f73bef3a83e2 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 11 Apr 2015 17:02:13 +0100 Subject: expr: add set_elem_expr as container for set element attributes Add a new expression type "set_elem_expr" that is used as container for the key in order to attach different attributes, such as timeout values, to the key. The expression hierarchy is as follows: Sets: elem | key Maps: mapping / \ elem data | key Signed-off-by: Patrick McHardy --- include/expression.h | 8 +++++++ src/evaluate.c | 15 ++++++++++++++ src/expression.c | 31 +++++++++++++++++++++++++++ src/netlink.c | 53 +++++++++++++++++++++++++++-------------------- src/netlink_delinearize.c | 3 +++ src/netlink_linearize.c | 2 ++ src/parser_bison.y | 19 ++++++++++++----- src/segtree.c | 8 +++++-- 8 files changed, 109 insertions(+), 30 deletions(-) diff --git a/include/expression.h b/include/expression.h index 7477c3e6..d481f288 100644 --- a/include/expression.h +++ b/include/expression.h @@ -27,6 +27,7 @@ * @EXPR_LIST: list of expressions * @EXPR_SET: literal set * @EXPR_SET_REF: set reference + * @EXPR_SET_ELEM: set element * @EXPR_MAPPING: a single mapping (key : value) * @EXPR_MAP: map operation (expr map { EXPR_MAPPING, ... }) * @EXPR_UNARY: byteorder conversion, generated during evaluation @@ -48,6 +49,7 @@ enum expr_types { EXPR_LIST, EXPR_SET, EXPR_SET_REF, + EXPR_SET_ELEM, EXPR_MAPPING, EXPR_MAP, EXPR_UNARY, @@ -229,6 +231,10 @@ struct expr { /* EXPR_SET_REF */ struct set *set; }; + struct { + /* EXPR_SET_ELEM */ + struct expr *key; + }; struct { /* EXPR_UNARY */ struct expr *arg; @@ -363,6 +369,8 @@ extern struct expr *map_expr_alloc(const struct location *loc, extern struct expr *set_ref_expr_alloc(const struct location *loc, struct set *set); +extern struct expr *set_elem_expr_alloc(const struct location *loc, + struct expr *key); extern void range_expr_value_low(mpz_t rop, const struct expr *expr); extern void range_expr_value_high(mpz_t rop, const struct expr *expr); diff --git a/src/evaluate.c b/src/evaluate.c index 7ecb7939..37db107b 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -675,6 +675,19 @@ static int expr_evaluate_list(struct eval_ctx *ctx, struct expr **expr) return 0; } +static int expr_evaluate_set_elem(struct eval_ctx *ctx, struct expr **expr) +{ + struct expr *elem = *expr; + + if (expr_evaluate(ctx, &elem->key) < 0) + return -1; + + elem->dtype = elem->key->dtype; + elem->len = elem->key->len; + elem->flags = elem->key->flags; + return 0; +} + static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) { struct expr *set = *expr, *i, *next; @@ -1100,6 +1113,8 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr) return expr_evaluate_list(ctx, expr); case EXPR_SET: return expr_evaluate_set(ctx, expr); + case EXPR_SET_ELEM: + return expr_evaluate_set_elem(ctx, expr); case EXPR_MAP: return expr_evaluate_map(ctx, expr); case EXPR_MAPPING: diff --git a/src/expression.c b/src/expression.c index 5b848da7..67893968 100644 --- a/src/expression.c +++ b/src/expression.c @@ -886,6 +886,33 @@ struct expr *set_ref_expr_alloc(const struct location *loc, struct set *set) return expr; } +static void set_elem_expr_print(const struct expr *expr) +{ + expr_print(expr->key); +} + +static void set_elem_expr_destroy(struct expr *expr) +{ + expr_free(expr->key); +} + +static const struct expr_ops set_elem_expr_ops = { + .type = EXPR_SET_ELEM, + .name = "set element", + .print = set_elem_expr_print, + .destroy = set_elem_expr_destroy, +}; + +struct expr *set_elem_expr_alloc(const struct location *loc, struct expr *key) +{ + struct expr *expr; + + expr = expr_alloc(loc, &set_elem_expr_ops, key->dtype, + key->byteorder, key->len); + expr->key = key; + return expr; +} + void range_expr_value_low(mpz_t rop, const struct expr *expr) { switch (expr->ops->type) { @@ -897,6 +924,8 @@ void range_expr_value_low(mpz_t rop, const struct expr *expr) return range_expr_value_low(rop, expr->left); case EXPR_MAPPING: return range_expr_value_low(rop, expr->left); + case EXPR_SET_ELEM: + return range_expr_value_low(rop, expr->key); default: BUG("invalid range expression type %s\n", expr->ops->name); } @@ -919,6 +948,8 @@ void range_expr_value_high(mpz_t rop, const struct expr *expr) return range_expr_value_high(rop, expr->right); case EXPR_MAPPING: return range_expr_value_high(rop, expr->left); + case EXPR_SET_ELEM: + return range_expr_value_high(rop, expr->key); default: BUG("invalid range expression type %s\n", expr->ops->name); } diff --git a/src/netlink.c b/src/netlink.c index 343d8bea..0827034e 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -205,6 +205,7 @@ struct nft_set *alloc_nft_set(const struct handle *h) static struct nft_set_elem *alloc_nft_setelem(const struct expr *expr) { + const struct expr *elem, *key, *data; struct nft_set_elem *nlse; struct nft_data_linearize nld; @@ -212,24 +213,28 @@ static struct nft_set_elem *alloc_nft_setelem(const struct expr *expr) if (nlse == NULL) memory_allocation_error(); - if (expr->ops->type == EXPR_VALUE || - expr->flags & EXPR_F_INTERVAL_END) { - netlink_gen_data(expr, &nld); - nft_set_elem_attr_set(nlse, NFT_SET_ELEM_ATTR_KEY, - &nld.value, nld.len); + data = NULL; + if (expr->ops->type == EXPR_MAPPING) { + elem = expr->left; + if (!(expr->flags & EXPR_F_INTERVAL_END)) + data = expr->right; } else { - assert(expr->ops->type == EXPR_MAPPING); - netlink_gen_data(expr->left, &nld); - nft_set_elem_attr_set(nlse, NFT_SET_ELEM_ATTR_KEY, - &nld.value, nld.len); - netlink_gen_data(expr->right, &nld); - switch (expr->right->ops->type) { + elem = expr; + } + key = elem->key; + + netlink_gen_data(key, &nld); + nft_set_elem_attr_set(nlse, NFT_SET_ELEM_ATTR_KEY, &nld.value, nld.len); + + if (data != NULL) { + netlink_gen_data(data, &nld); + switch (data->ops->type) { case EXPR_VERDICT: nft_set_elem_attr_set_u32(nlse, NFT_SET_ELEM_ATTR_VERDICT, - expr->right->verdict); - if (expr->chain != NULL) + data->verdict); + if (data->chain != NULL) nft_set_elem_attr_set(nlse, NFT_SET_ELEM_ATTR_CHAIN, - nld.chain, strlen(nld.chain)); + nld.chain, strlen(nld.chain)); break; case EXPR_VALUE: nft_set_elem_attr_set(nlse, NFT_SET_ELEM_ATTR_DATA, @@ -1368,7 +1373,7 @@ static int netlink_delinearize_setelem(struct nft_set_elem *nlse, struct set *set) { struct nft_data_delinearize nld; - struct expr *expr, *data; + struct expr *expr, *key, *data; uint32_t flags = 0; nld.value = @@ -1376,17 +1381,19 @@ static int netlink_delinearize_setelem(struct nft_set_elem *nlse, if (nft_set_elem_attr_is_set(nlse, NFT_SET_ELEM_ATTR_FLAGS)) flags = nft_set_elem_attr_get_u32(nlse, NFT_SET_ELEM_ATTR_FLAGS); - expr = netlink_alloc_value(&netlink_location, &nld); - expr->dtype = set->keytype; - expr->byteorder = set->keytype->byteorder; + key = netlink_alloc_value(&netlink_location, &nld); + key->dtype = set->keytype; + key->byteorder = set->keytype->byteorder; if (!(set->flags & SET_F_INTERVAL) && - expr->byteorder == BYTEORDER_HOST_ENDIAN) - mpz_switch_byteorder(expr->value, expr->len / BITS_PER_BYTE); + key->byteorder == BYTEORDER_HOST_ENDIAN) + mpz_switch_byteorder(key->value, key->len / BITS_PER_BYTE); + + if (key->dtype->basetype != NULL && + key->dtype->basetype->type == TYPE_BITMASK) + key = bitmask_expr_to_binops(key); - if (expr->dtype->basetype != NULL && - expr->dtype->basetype->type == TYPE_BITMASK) - expr = bitmask_expr_to_binops(expr); + expr = set_elem_expr_alloc(&netlink_location, key); if (flags & NFT_SET_ELEM_INTERVAL_END) { expr->flags |= EXPR_F_INTERVAL_END; diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index ec1a9646..c564a8a5 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -1033,6 +1033,9 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, expr_postprocess(ctx, stmt, &expr->left); expr_postprocess(ctx, stmt, &expr->right); break; + case EXPR_SET_ELEM: + expr_postprocess(ctx, stmt, &expr->key); + break; case EXPR_SET_REF: case EXPR_EXTHDR: case EXPR_META: diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 9bef67b3..d1414c14 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -528,6 +528,8 @@ static void netlink_gen_expr(struct netlink_linearize_ctx *ctx, return netlink_gen_meta(ctx, expr, dreg); case EXPR_CT: return netlink_gen_ct(ctx, expr, dreg); + case EXPR_SET_ELEM: + return netlink_gen_expr(ctx, expr->key, dreg); default: BUG("unknown expression type %s\n", expr->ops->name); } diff --git a/src/parser_bison.y b/src/parser_bison.y index c934533d..9fbc590c 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -484,8 +484,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type set_expr set_list_expr set_list_member_expr %destructor { expr_free($$); } set_expr set_list_expr set_list_member_expr -%type set_lhs_expr set_rhs_expr -%destructor { expr_free($$); } set_lhs_expr set_rhs_expr +%type set_elem_expr set_elem_expr_alloc set_lhs_expr set_rhs_expr +%destructor { expr_free($$); } set_elem_expr set_elem_expr_alloc set_lhs_expr set_rhs_expr %type expr initializer_expr %destructor { expr_free($$); } expr initializer_expr @@ -1299,7 +1299,7 @@ verdict_map_list_expr : verdict_map_list_member_expr | verdict_map_list_expr COMMA opt_newline ; -verdict_map_list_member_expr: opt_newline set_lhs_expr COLON verdict_expr opt_newline +verdict_map_list_member_expr: opt_newline set_elem_expr COLON verdict_expr opt_newline { $$ = mapping_expr_alloc(&@$, $2, $4); } @@ -1755,16 +1755,25 @@ set_list_member_expr : opt_newline set_expr opt_newline { $$ = $2; } - | opt_newline set_lhs_expr opt_newline + | opt_newline set_elem_expr opt_newline { $$ = $2; } - | opt_newline set_lhs_expr COLON set_rhs_expr opt_newline + | opt_newline set_elem_expr COLON set_rhs_expr opt_newline { $$ = mapping_expr_alloc(&@$, $2, $4); } ; +set_elem_expr : set_elem_expr_alloc + ; + +set_elem_expr_alloc : set_lhs_expr + { + $$ = set_elem_expr_alloc(&@1, $1); + } + ; + set_lhs_expr : concat_expr | multiton_expr ; diff --git a/src/segtree.c b/src/segtree.c index 65221e9d..060951c0 100644 --- a/src/segtree.c +++ b/src/segtree.c @@ -419,6 +419,7 @@ static void set_insert_interval(struct expr *set, struct seg_tree *tree, expr = constant_expr_alloc(&internal_location, tree->keytype, tree->byteorder, tree->keylen, NULL); mpz_set(expr->value, ei->left); + expr = set_elem_expr_alloc(&internal_location, expr); if (ei->expr != NULL && ei->expr->ops->type == EXPR_MAPPING) expr = mapping_expr_alloc(&ei->expr->location, expr, @@ -473,9 +474,9 @@ extern void interval_map_decompose(struct expr *set); static struct expr *expr_value(struct expr *expr) { if (expr->ops->type == EXPR_MAPPING) - return expr->left; + return expr->left->key; else - return expr; + return expr->key; } static int expr_value_cmp(const void *p1, const void *p2) @@ -565,6 +566,7 @@ void interval_map_decompose(struct expr *set) mpz_set(tmp->value, range); tmp = range_expr_alloc(&low->location, expr_value(low), tmp); + tmp = set_elem_expr_alloc(&low->location, tmp); if (low->ops->type == EXPR_MAPPING) tmp = mapping_expr_alloc(&tmp->location, tmp, low->right); @@ -576,6 +578,7 @@ void interval_map_decompose(struct expr *set) prefix_len = expr_value(i)->len - mpz_scan0(range, 0); prefix = prefix_expr_alloc(&low->location, expr_value(low), prefix_len); + prefix = set_elem_expr_alloc(&low->location, prefix); if (low->ops->type == EXPR_MAPPING) prefix = mapping_expr_alloc(&low->location, prefix, low->right); @@ -598,6 +601,7 @@ void interval_map_decompose(struct expr *set) mpz_init_bitmask(i->value, i->len); i = range_expr_alloc(&low->location, expr_value(low), i); + i = set_elem_expr_alloc(&low->location, i); if (low->ops->type == EXPR_MAPPING) i = mapping_expr_alloc(&i->location, i, low->right); -- cgit v1.2.3 From 38a077f7af8a2151b565e3cb324901b48afd299e Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Mon, 23 Mar 2015 21:34:57 +0000 Subject: set: add timeout support for sets Timeout support can be enabled in one of two ways: 1. Using a default timeout value: set test { type ipv4_addr; timeout 1h; } 2. Using the timeout flag without a default: set test { type ipv4_addr; flags timeout; } Optionally a garbage collection interval can be specified using gc-interval ; Signed-off-by: Patrick McHardy --- include/linux/netfilter/nf_tables.h | 6 ++++++ include/rule.h | 5 +++++ src/evaluate.c | 4 ++++ src/netlink.c | 10 ++++++++++ src/parser_bison.y | 13 +++++++++++++ src/rule.c | 23 ++++++++++++++++++++++- src/scanner.l | 2 ++ 7 files changed, 62 insertions(+), 1 deletion(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 832bc46d..8671505e 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -207,12 +207,14 @@ enum nft_rule_compat_attributes { * @NFT_SET_CONSTANT: set contents may not change while bound * @NFT_SET_INTERVAL: set contains intervals * @NFT_SET_MAP: set is used as a dictionary + * @NFT_SET_TIMEOUT: set uses timeouts */ enum nft_set_flags { NFT_SET_ANONYMOUS = 0x1, NFT_SET_CONSTANT = 0x2, NFT_SET_INTERVAL = 0x4, NFT_SET_MAP = 0x8, + NFT_SET_TIMEOUT = 0x10, }; /** @@ -251,6 +253,8 @@ enum nft_set_desc_attributes { * @NFTA_SET_POLICY: selection policy (NLA_U32) * @NFTA_SET_DESC: set description (NLA_NESTED) * @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32) + * @NFTA_SET_TIMEOUT: default timeout value (NLA_U64) + * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32) */ enum nft_set_attributes { NFTA_SET_UNSPEC, @@ -264,6 +268,8 @@ enum nft_set_attributes { NFTA_SET_POLICY, NFTA_SET_DESC, NFTA_SET_ID, + NFTA_SET_TIMEOUT, + NFTA_SET_GC_INTERVAL, __NFTA_SET_MAX }; #define NFTA_SET_MAX (__NFTA_SET_MAX - 1) diff --git a/include/rule.h b/include/rule.h index 97959f7b..5d445993 100644 --- a/include/rule.h +++ b/include/rule.h @@ -173,6 +173,7 @@ enum set_flags { SET_F_CONSTANT = 0x2, SET_F_INTERVAL = 0x4, SET_F_MAP = 0x8, + SET_F_TIMEOUT = 0x10, }; /** @@ -183,6 +184,8 @@ enum set_flags { * @location: location the set was defined/declared at * @refcnt: reference count * @flags: bitmask of set flags + * @gc_int: garbage collection interval + * @timeout: default timeout value * @keytype: key data type * @keylen: key length * @datatype: mapping data type @@ -197,6 +200,8 @@ struct set { struct location location; unsigned int refcnt; uint32_t flags; + uint32_t gc_int; + uint64_t timeout; const struct datatype *keytype; unsigned int keylen; const struct datatype *datatype; diff --git a/src/evaluate.c b/src/evaluate.c index 37db107b..04ca08df 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1737,6 +1737,10 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) return -1; } + /* Default timeout value implies timeout support */ + if (set->timeout) + set->flags |= SET_F_TIMEOUT; + if (!(set->flags & SET_F_MAP)) return 0; diff --git a/src/netlink.c b/src/netlink.c index 0827034e..e1d6421f 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1068,6 +1068,11 @@ static struct set *netlink_delinearize_set(struct netlink_ctx *ctx, set->datalen = data_len * BITS_PER_BYTE; } + if (nft_set_attr_is_set(nls, NFT_SET_ATTR_TIMEOUT)) + set->timeout = nft_set_attr_get_u64(nls, NFT_SET_ATTR_TIMEOUT); + if (nft_set_attr_is_set(nls, NFT_SET_ATTR_GC_INTERVAL)) + set->gc_int = nft_set_attr_get_u32(nls, NFT_SET_ATTR_GC_INTERVAL); + if (nft_set_attr_is_set(nls, NFT_SET_ATTR_POLICY)) set->policy = nft_set_attr_get_u32(nls, NFT_SET_ATTR_POLICY); @@ -1131,6 +1136,11 @@ static int netlink_add_set_batch(struct netlink_ctx *ctx, nft_set_attr_set_u32(nls, NFT_SET_ATTR_DATA_LEN, set->datalen / BITS_PER_BYTE); } + if (set->timeout) + nft_set_attr_set_u64(nls, NFT_SET_ATTR_TIMEOUT, set->timeout); + if (set->gc_int) + nft_set_attr_set_u32(nls, NFT_SET_ATTR_GC_INTERVAL, set->gc_int); + set->handle.set_id = ++set_id; nft_set_attr_set_u32(nls, NFT_SET_ATTR_ID, set->handle.set_id); diff --git a/src/parser_bison.y b/src/parser_bison.y index 9fbc590c..80831878 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -201,6 +201,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token CONSTANT "constant" %token INTERVAL "interval" +%token TIMEOUT "timeout" +%token GC_INTERVAL "gc-interval" %token ELEMENTS "elements" %token POLICY "policy" @@ -944,6 +946,16 @@ set_block : /* empty */ { $$ = $-1; } $1->flags = $3; $$ = $1; } + | set_block TIMEOUT time_spec stmt_seperator + { + $1->timeout = $3 * 1000; + $$ = $1; + } + | set_block GC_INTERVAL time_spec stmt_seperator + { + $1->gc_int = $3 * 1000; + $$ = $1; + } | set_block ELEMENTS '=' set_expr { $1->init = $4; @@ -961,6 +973,7 @@ set_flag_list : set_flag_list COMMA set_flag set_flag : CONSTANT { $$ = SET_F_CONSTANT; } | INTERVAL { $$ = SET_F_INTERVAL; } + | TIMEOUT { $$ = SET_F_TIMEOUT; } ; map_block_alloc : /* empty */ diff --git a/src/rule.c b/src/rule.c index 71143807..b2090ddd 100644 --- a/src/rule.c +++ b/src/rule.c @@ -136,6 +136,7 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts) { const char *delim = ""; const char *type; + uint32_t flags; type = set->flags & SET_F_MAP ? "map" : "set"; printf("%s%s", opts->tab, type); @@ -167,7 +168,12 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts) } } - if (set->flags & (SET_F_CONSTANT | SET_F_INTERVAL)) { + flags = set->flags; + /* "timeout" flag is redundant if a default timeout exists */ + if (set->timeout) + flags &= ~SET_F_TIMEOUT; + + if (flags & (SET_F_CONSTANT | SET_F_INTERVAL | SET_F_TIMEOUT)) { printf("%s%sflags ", opts->tab, opts->tab); if (set->flags & SET_F_CONSTANT) { printf("%sconstant", delim); @@ -177,6 +183,21 @@ static void do_set_print(const struct set *set, struct print_fmt_options *opts) printf("%sinterval", delim); delim = ","; } + if (set->flags & SET_F_TIMEOUT) { + printf("%stimeout", delim); + delim = ","; + } + printf("%s", opts->nl); + } + + if (set->timeout) { + printf("%s%stimeout ", opts->tab, opts->tab); + time_print(set->timeout / 1000); + printf("%s", opts->nl); + } + if (set->gc_int) { + printf("%s%sgc-interval ", opts->tab, opts->tab); + time_print(set->gc_int / 1000); printf("%s", opts->nl); } diff --git a/src/scanner.l b/src/scanner.l index 27d95bfc..4231d270 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -271,6 +271,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "constant" { return CONSTANT; } "interval" { return INTERVAL; } +"timeout" { return TIMEOUT; } +"gc-interval" { return GC_INTERVAL; } "elements" { return ELEMENTS; } "policy" { return POLICY; } -- cgit v1.2.3 From 7b5248972d9f2122c7b3683ca205d3165e7a9255 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 19 Mar 2015 13:34:18 +0000 Subject: setelem: add timeout support for set elements Support specifying per element timeout values and displaying the expiration time. If an element should not use the default timeout value of the set, an element specific value can be specified as follows: # nft add element filter test { 192.168.0.1, 192.168.0.2 timeout 10m} For listing of elements that use the default timeout value, just the expiration time is shown, otherwise the element specific timeout value is also displayed: set test { type ipv4_addr timeout 1h elements = { 192.168.0.2 timeout 10m expires 9m59s, 192.168.0.1 expires 59m59s} } Signed-off-by: Patrick McHardy --- include/expression.h | 2 ++ include/linux/netfilter/nf_tables.h | 4 ++++ src/expression.c | 8 ++++++++ src/netlink.c | 7 +++++++ src/parser_bison.y | 14 ++++++++++++++ 5 files changed, 35 insertions(+) diff --git a/include/expression.h b/include/expression.h index d481f288..6f23b6dd 100644 --- a/include/expression.h +++ b/include/expression.h @@ -234,6 +234,8 @@ struct expr { struct { /* EXPR_SET_ELEM */ struct expr *key; + uint64_t timeout; + uint64_t expiration; }; struct { /* EXPR_UNARY */ diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 8671505e..6894ba33 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -289,12 +289,16 @@ enum nft_set_elem_flags { * @NFTA_SET_ELEM_KEY: key value (NLA_NESTED: nft_data) * @NFTA_SET_ELEM_DATA: data value of mapping (NLA_NESTED: nft_data_attributes) * @NFTA_SET_ELEM_FLAGS: bitmask of nft_set_elem_flags (NLA_U32) + * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64) + * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64) */ enum nft_set_elem_attributes { NFTA_SET_ELEM_UNSPEC, NFTA_SET_ELEM_KEY, NFTA_SET_ELEM_DATA, NFTA_SET_ELEM_FLAGS, + NFTA_SET_ELEM_TIMEOUT, + NFTA_SET_ELEM_EXPIRATION, __NFTA_SET_ELEM_MAX }; #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1) diff --git a/src/expression.c b/src/expression.c index 67893968..2037c607 100644 --- a/src/expression.c +++ b/src/expression.c @@ -889,6 +889,14 @@ struct expr *set_ref_expr_alloc(const struct location *loc, struct set *set) static void set_elem_expr_print(const struct expr *expr) { expr_print(expr->key); + if (expr->timeout) { + printf(" timeout "); + time_print(expr->timeout / 1000); + } + if (expr->expiration) { + printf(" expires "); + time_print(expr->expiration / 1000); + } } static void set_elem_expr_destroy(struct expr *expr) diff --git a/src/netlink.c b/src/netlink.c index e1d6421f..7d675d7f 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -225,6 +225,9 @@ static struct nft_set_elem *alloc_nft_setelem(const struct expr *expr) netlink_gen_data(key, &nld); nft_set_elem_attr_set(nlse, NFT_SET_ELEM_ATTR_KEY, &nld.value, nld.len); + if (elem->timeout) + nft_set_elem_attr_set_u64(nlse, NFT_SET_ELEM_ATTR_TIMEOUT, + elem->timeout); if (data != NULL) { netlink_gen_data(data, &nld); @@ -1404,6 +1407,10 @@ static int netlink_delinearize_setelem(struct nft_set_elem *nlse, key = bitmask_expr_to_binops(key); expr = set_elem_expr_alloc(&netlink_location, key); + if (nft_set_elem_attr_is_set(nlse, NFT_SET_ELEM_ATTR_TIMEOUT)) + expr->timeout = nft_set_elem_attr_get_u64(nlse, NFT_SET_ELEM_ATTR_TIMEOUT); + if (nft_set_elem_attr_is_set(nlse, NFT_SET_ELEM_ATTR_EXPIRATION)) + expr->expiration = nft_set_elem_attr_get_u64(nlse, NFT_SET_ELEM_ATTR_EXPIRATION); if (flags & NFT_SET_ELEM_INTERVAL_END) { expr->flags |= EXPR_F_INTERVAL_END; diff --git a/src/parser_bison.y b/src/parser_bison.y index 80831878..736704a5 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -1779,6 +1779,7 @@ set_list_member_expr : opt_newline set_expr opt_newline ; set_elem_expr : set_elem_expr_alloc + | set_elem_expr_alloc set_elem_options ; set_elem_expr_alloc : set_lhs_expr @@ -1787,6 +1788,19 @@ set_elem_expr_alloc : set_lhs_expr } ; +set_elem_options : set_elem_option + { + $$ = $0; + } + | set_elem_options set_elem_option + ; + +set_elem_option : TIMEOUT time_spec + { + $0->timeout = $2 * 1000; + } + ; + set_lhs_expr : concat_expr | multiton_expr ; -- cgit v1.2.3 From 35960e1e19bfe9135e33f13615d7d403d129192b Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 20 Mar 2015 06:30:29 +0000 Subject: setelem: add support for attaching comments to set elements Syntax: # nft add element filter test { 192.168.0.1 comment "some host" } Signed-off-by: Patrick McHardy --- include/expression.h | 1 + include/linux/netfilter/nf_tables.h | 2 ++ src/expression.c | 3 +++ src/netlink.c | 11 +++++++++++ src/parser_bison.y | 4 ++++ 5 files changed, 21 insertions(+) diff --git a/include/expression.h b/include/expression.h index 6f23b6dd..010cb954 100644 --- a/include/expression.h +++ b/include/expression.h @@ -236,6 +236,7 @@ struct expr { struct expr *key; uint64_t timeout; uint64_t expiration; + const char *comment; }; struct { /* EXPR_UNARY */ diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 6894ba33..334b3892 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -291,6 +291,7 @@ enum nft_set_elem_flags { * @NFTA_SET_ELEM_FLAGS: bitmask of nft_set_elem_flags (NLA_U32) * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64) * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64) + * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY) */ enum nft_set_elem_attributes { NFTA_SET_ELEM_UNSPEC, @@ -299,6 +300,7 @@ enum nft_set_elem_attributes { NFTA_SET_ELEM_FLAGS, NFTA_SET_ELEM_TIMEOUT, NFTA_SET_ELEM_EXPIRATION, + NFTA_SET_ELEM_USERDATA, __NFTA_SET_ELEM_MAX }; #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1) diff --git a/src/expression.c b/src/expression.c index 2037c607..3edc5501 100644 --- a/src/expression.c +++ b/src/expression.c @@ -897,10 +897,13 @@ static void set_elem_expr_print(const struct expr *expr) printf(" expires "); time_print(expr->expiration / 1000); } + if (expr->comment) + printf(" comment \"%s\"", expr->comment); } static void set_elem_expr_destroy(struct expr *expr) { + xfree(expr->comment); expr_free(expr->key); } diff --git a/src/netlink.c b/src/netlink.c index 7d675d7f..d31387f8 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -228,6 +228,9 @@ static struct nft_set_elem *alloc_nft_setelem(const struct expr *expr) if (elem->timeout) nft_set_elem_attr_set_u64(nlse, NFT_SET_ELEM_ATTR_TIMEOUT, elem->timeout); + if (elem->comment) + nft_set_elem_attr_set(nlse, NFT_SET_ELEM_ATTR_USERDATA, + elem->comment, strlen(elem->comment) + 1); if (data != NULL) { netlink_gen_data(data, &nld); @@ -1411,6 +1414,14 @@ static int netlink_delinearize_setelem(struct nft_set_elem *nlse, expr->timeout = nft_set_elem_attr_get_u64(nlse, NFT_SET_ELEM_ATTR_TIMEOUT); if (nft_set_elem_attr_is_set(nlse, NFT_SET_ELEM_ATTR_EXPIRATION)) expr->expiration = nft_set_elem_attr_get_u64(nlse, NFT_SET_ELEM_ATTR_EXPIRATION); + if (nft_set_elem_attr_is_set(nlse, NFT_SET_ELEM_ATTR_USERDATA)) { + const void *data; + uint32_t len; + + data = nft_set_elem_attr_get(nlse, NFT_SET_ELEM_ATTR_USERDATA, &len); + expr->comment = xmalloc(len); + memcpy((char *)expr->comment, data, len); + } if (flags & NFT_SET_ELEM_INTERVAL_END) { expr->flags |= EXPR_F_INTERVAL_END; diff --git a/src/parser_bison.y b/src/parser_bison.y index 736704a5..0f2d71a3 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -1799,6 +1799,10 @@ set_elem_option : TIMEOUT time_spec { $0->timeout = $2 * 1000; } + | COMMENT string + { + $0->comment = $2; + } ; set_lhs_expr : concat_expr -- cgit v1.2.3 From a9467e55973b10c2e8fe37525514c961580f8506 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 19 Mar 2015 13:34:18 +0000 Subject: nftables: add set statemet The set statement is used to dynamically add or update elements in a set. Syntax: # nft filter input set add tcp dport @myset # nft filter input set add ip saddr timeout 10s @myset # nft filter input set update ip saddr timeout 10s @myset Signed-off-by: Patrick McHardy --- include/linux/netfilter/nf_tables.h | 27 ++++++++++++++++++++++++++ include/statement.h | 11 +++++++++++ src/evaluate.c | 28 ++++++++++++++++++++++++++- src/netlink_delinearize.c | 38 +++++++++++++++++++++++++++++++++++++ src/netlink_linearize.c | 24 +++++++++++++++++++++++ src/parser_bison.y | 18 ++++++++++++++++++ src/scanner.l | 1 + src/statement.c | 31 ++++++++++++++++++++++++++++++ 8 files changed, 177 insertions(+), 1 deletion(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 334b3892..0e964439 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -516,6 +516,33 @@ enum nft_lookup_attributes { }; #define NFTA_LOOKUP_MAX (__NFTA_LOOKUP_MAX - 1) +enum nft_dynset_ops { + NFT_DYNSET_OP_ADD, + NFT_DYNSET_OP_UPDATE, +}; + +/** + * enum nft_dynset_attributes - dynset expression attributes + * + * @NFTA_DYNSET_SET_NAME: name of set the to add data to (NLA_STRING) + * @NFTA_DYNSET_SET_ID: uniquely identifier of the set in the transaction (NLA_U32) + * @NFTA_DYNSET_OP: operation (NLA_U32) + * @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32) + * @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32) + * @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64) + */ +enum nft_dynset_attributes { + NFTA_DYNSET_UNSPEC, + NFTA_DYNSET_SET_NAME, + NFTA_DYNSET_SET_ID, + NFTA_DYNSET_OP, + NFTA_DYNSET_SREG_KEY, + NFTA_DYNSET_SREG_DATA, + NFTA_DYNSET_TIMEOUT, + __NFTA_DYNSET_MAX, +}; +#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1) + /** * enum nft_payload_bases - nf_tables payload expression offset bases * diff --git a/include/statement.h b/include/statement.h index d1431215..48e61307 100644 --- a/include/statement.h +++ b/include/statement.h @@ -104,6 +104,14 @@ extern struct stmt *ct_stmt_alloc(const struct location *loc, enum nft_ct_keys key, struct expr *expr); +struct set_stmt { + struct expr *set; + struct expr *key; + enum nft_dynset_ops op; +}; + +extern struct stmt *set_stmt_alloc(const struct location *loc); + /** * enum stmt_types - statement types * @@ -120,6 +128,7 @@ extern struct stmt *ct_stmt_alloc(const struct location *loc, * @STMT_REDIR: redirect statement * @STMT_QUEUE: QUEUE statement * @STMT_CT: conntrack statement + * @STMT_SET: set statement */ enum stmt_types { STMT_INVALID, @@ -135,6 +144,7 @@ enum stmt_types { STMT_REDIR, STMT_QUEUE, STMT_CT, + STMT_SET, }; /** @@ -184,6 +194,7 @@ struct stmt { struct redir_stmt redir; struct queue_stmt queue; struct ct_stmt ct; + struct set_stmt set; }; }; diff --git a/src/evaluate.c b/src/evaluate.c index 04ca08df..e260a803 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -614,7 +614,7 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr) struct expr *i, *next; list_for_each_entry_safe(i, next, &(*expr)->expressions, list) { - if (dtype && off == 0) + if (expr_is_constant(*expr) && dtype && off == 0) return expr_binary_error(ctx->msgs, i, *expr, "unexpected concat component, " "expecting %s", @@ -1661,6 +1661,30 @@ static int stmt_evaluate_log(struct eval_ctx *ctx, struct stmt *stmt) return 0; } +static int stmt_evaluate_set(struct eval_ctx *ctx, struct stmt *stmt) +{ + expr_set_context(&ctx->ectx, NULL, 0); + if (expr_evaluate(ctx, &stmt->set.set) < 0) + return -1; + if (stmt->set.set->ops->type != EXPR_SET_REF) + return expr_error(ctx->msgs, stmt->set.set, + "Expression does not refer to a set"); + + if (stmt_evaluate_arg(ctx, stmt, + stmt->set.set->set->keytype, + stmt->set.set->set->keylen, + &stmt->set.key) < 0) + return -1; + if (expr_is_constant(stmt->set.key)) + return expr_error(ctx->msgs, stmt->set.key, + "Key expression can not be constant"); + if (stmt->set.key->comment != NULL) + return expr_error(ctx->msgs, stmt->set.key, + "Key expression comments are not supported"); + + return 0; +} + int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) { #ifdef DEBUG @@ -1695,6 +1719,8 @@ int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt) return stmt_evaluate_redir(ctx, stmt); case STMT_QUEUE: return stmt_evaluate_queue(ctx, stmt); + case STMT_SET: + return stmt_evaluate_set(ctx, stmt); default: BUG("unknown statement type %s\n", stmt->ops->name); } diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index c564a8a5..b041579f 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -694,6 +694,40 @@ static void netlink_parse_queue(struct netlink_parse_ctx *ctx, list_add_tail(&stmt->list, &ctx->rule->stmts); } +static void netlink_parse_dynset(struct netlink_parse_ctx *ctx, + const struct location *loc, + const struct nft_rule_expr *nle) +{ + struct expr *expr; + struct stmt *stmt; + struct set *set; + enum nft_registers sreg; + const char *name; + + name = nft_rule_expr_get_str(nle, NFT_EXPR_DYNSET_SET_NAME); + set = set_lookup(ctx->table, name); + if (set == NULL) + return netlink_error(ctx, loc, + "Unknown set '%s' in dynset statement", + name); + + sreg = netlink_parse_register(nle, NFT_EXPR_DYNSET_SREG_KEY); + expr = netlink_get_register(ctx, loc, sreg); + if (expr == NULL) + return netlink_error(ctx, loc, + "Dynset statement has no key expression"); + + expr = set_elem_expr_alloc(&expr->location, expr); + expr->timeout = nft_rule_expr_get_u64(nle, NFT_EXPR_DYNSET_TIMEOUT); + + stmt = set_stmt_alloc(loc); + stmt->set.set = set_ref_expr_alloc(loc, set); + stmt->set.op = nft_rule_expr_get_u32(nle, NFT_EXPR_DYNSET_OP); + stmt->set.key = expr; + + list_add_tail(&stmt->list, &ctx->rule->stmts); +} + static const struct { const char *name; void (*parse)(struct netlink_parse_ctx *ctx, @@ -717,6 +751,7 @@ static const struct { { .name = "masq", .parse = netlink_parse_masq }, { .name = "redir", .parse = netlink_parse_redir }, { .name = "queue", .parse = netlink_parse_queue }, + { .name = "dynset", .parse = netlink_parse_dynset }, }; static int netlink_parse_expr(struct nft_rule_expr *nle, void *arg) @@ -1140,6 +1175,9 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r case STMT_REJECT: stmt_reject_postprocess(rctx, stmt); break; + case STMT_SET: + expr_postprocess(&rctx, stmt, &stmt->set.key); + break; default: break; } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index d1414c14..09ba2eff 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -800,6 +800,28 @@ static void netlink_gen_ct_stmt(struct netlink_linearize_ctx *ctx, nft_rule_add_expr(ctx->nlr, nle); } +static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx, + const struct stmt *stmt) +{ + struct nft_rule_expr *nle; + enum nft_registers sreg_key; + + sreg_key = get_register(ctx); + netlink_gen_expr(ctx, stmt->set.key, sreg_key); + release_register(ctx); + + nle = alloc_nft_expr("dynset"); + netlink_put_register(nle, NFT_EXPR_DYNSET_SREG_KEY, sreg_key); + nft_rule_expr_set_u64(nle, NFT_EXPR_DYNSET_TIMEOUT, + stmt->set.key->timeout); + nft_rule_expr_set_u32(nle, NFT_EXPR_DYNSET_OP, stmt->set.op); + nft_rule_expr_set_str(nle, NFT_EXPR_DYNSET_SET_NAME, + stmt->set.set->set->handle.set); + nft_rule_expr_set_u32(nle, NFT_EXPR_DYNSET_SET_ID, + stmt->set.set->set->handle.set_id); + nft_rule_add_expr(ctx->nlr, nle); +} + static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx, const struct stmt *stmt) { @@ -828,6 +850,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx, return netlink_gen_queue_stmt(ctx, stmt); case STMT_CT: return netlink_gen_ct_stmt(ctx, stmt); + case STMT_SET: + return netlink_gen_set_stmt(ctx, stmt); default: BUG("unknown statement type %s\n", stmt->ops->name); } diff --git a/src/parser_bison.y b/src/parser_bison.y index 0f2d71a3..eac3fcbe 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -181,6 +181,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token INET "inet" %token ADD "add" +%token UPDATE "update" %token CREATE "create" %token INSERT "insert" %token DELETE "delete" @@ -456,6 +457,9 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type queue_stmt queue_stmt_alloc %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc %type queue_stmt_flags queue_stmt_flag +%type set_stmt +%destructor { stmt_free($$); } set_stmt +%type set_stmt_op %type symbol_expr verdict_expr integer_expr %destructor { expr_free($$); } symbol_expr verdict_expr integer_expr @@ -1267,6 +1271,7 @@ stmt : verdict_stmt | ct_stmt | masq_stmt | redir_stmt + | set_stmt ; verdict_stmt : verdict_expr @@ -1579,6 +1584,19 @@ queue_stmt_flag : BYPASS { $$ = NFT_QUEUE_FLAG_BYPASS; } | FANOUT { $$ = NFT_QUEUE_FLAG_CPU_FANOUT; } ; +set_stmt : SET set_stmt_op set_elem_expr symbol_expr + { + $$ = set_stmt_alloc(&@$); + $$->set.op = $2; + $$->set.key = $3; + $$->set.set = $4; + } + ; + +set_stmt_op : ADD { $$ = NFT_DYNSET_OP_ADD; } + | UPDATE { $$ = NFT_DYNSET_OP_UPDATE; } + ; + match_stmt : relational_expr { $$ = expr_stmt_alloc(&@$, $1); diff --git a/src/scanner.l b/src/scanner.l index 4231d270..985ea2a3 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -257,6 +257,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "inet" { return INET; } "add" { return ADD; } +"update" { return UPDATE; } "create" { return CREATE; } "insert" { return INSERT; } "delete" { return DELETE; } diff --git a/src/statement.c b/src/statement.c index d72c6e9b..9ebc5938 100644 --- a/src/statement.c +++ b/src/statement.c @@ -377,3 +377,34 @@ struct stmt *redir_stmt_alloc(const struct location *loc) { return stmt_alloc(loc, &redir_stmt_ops); } + +static const char * const set_stmt_op_names[] = { + [NFT_DYNSET_OP_ADD] = "add", + [NFT_DYNSET_OP_UPDATE] = "update", +}; + +static void set_stmt_print(const struct stmt *stmt) +{ + printf("set %s ", set_stmt_op_names[stmt->set.op]); + expr_print(stmt->set.key); + printf(" "); + expr_print(stmt->set.set); +} + +static void set_stmt_destroy(struct stmt *stmt) +{ + expr_free(stmt->set.key); + expr_free(stmt->set.set); +} + +static const struct stmt_ops set_stmt_ops = { + .type = STMT_SET, + .name = "set", + .print = set_stmt_print, + .destroy = set_stmt_destroy, +}; + +struct stmt *set_stmt_alloc(const struct location *loc) +{ + return stmt_alloc(loc, &set_stmt_ops); +} -- cgit v1.2.3 From efd5d125dff0dd295a3dfccd3491fc18b4fc164a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 30 May 2015 17:59:18 +0200 Subject: netlink_delinearize: pass ctx pointer to stmt_reject_postprocess() Instead of a copy of the context variable. Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index b041579f..26a8c855 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -1082,18 +1082,18 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, } } -static void stmt_reject_postprocess(struct rule_pp_ctx rctx, struct stmt *stmt) +static void stmt_reject_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt) { const struct proto_desc *desc, *base; int protocol; - switch (rctx.pctx.family) { + switch (rctx->pctx.family) { case NFPROTO_IPV4: - stmt->reject.family = rctx.pctx.family; + stmt->reject.family = rctx->pctx.family; stmt->reject.expr->dtype = &icmp_code_type; break; case NFPROTO_IPV6: - stmt->reject.family = rctx.pctx.family; + stmt->reject.family = rctx->pctx.family; stmt->reject.expr->dtype = &icmpv6_code_type; break; case NFPROTO_INET: @@ -1101,8 +1101,8 @@ static void stmt_reject_postprocess(struct rule_pp_ctx rctx, struct stmt *stmt) stmt->reject.expr->dtype = &icmpx_code_type; break; } - base = rctx.pctx.protocol[PROTO_BASE_LL_HDR].desc; - desc = rctx.pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + base = rctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + desc = rctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; protocol = proto_find_num(base, desc); switch (protocol) { case NFPROTO_IPV4: @@ -1119,8 +1119,8 @@ static void stmt_reject_postprocess(struct rule_pp_ctx rctx, struct stmt *stmt) stmt->reject.expr->dtype = &icmpx_code_type; break; } - base = rctx.pctx.protocol[PROTO_BASE_LL_HDR].desc; - desc = rctx.pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + base = rctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + desc = rctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; protocol = proto_find_num(base, desc); switch (protocol) { case __constant_htons(ETH_P_IP): @@ -1173,7 +1173,7 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r &stmt->redir.proto); break; case STMT_REJECT: - stmt_reject_postprocess(rctx, stmt); + stmt_reject_postprocess(&rctx, stmt); break; case STMT_SET: expr_postprocess(&rctx, stmt, &stmt->set.key); -- cgit v1.2.3 From 3550b3e3ebeb8f2532e8915f7581bbe4bcd7eabd Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 2 Jun 2015 16:45:23 +0200 Subject: netlink_delinearize: keep pointer to current statement from rule_pp_ctx This patch is required by the range postprocess routine that comes in follow up patches. Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 71 ++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 26a8c855..71c32c5f 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -780,6 +780,7 @@ struct rule_pp_ctx { struct proto_ctx pctx; enum proto_bases pbase; struct stmt *pdep; + struct stmt *stmt; }; /* @@ -829,7 +830,7 @@ static void integer_type_postprocess(struct expr *expr) } static void payload_match_postprocess(struct rule_pp_ctx *ctx, - struct stmt *stmt, struct expr *expr) + struct expr *expr) { struct expr *left = expr->left, *right = expr->right, *tmp; struct list_head list = LIST_HEAD_INIT(list); @@ -851,8 +852,8 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx, if (expr->op == OP_EQ) left->ops->pctx_update(&ctx->pctx, nexpr); - nstmt = expr_stmt_alloc(&stmt->location, nexpr); - list_add_tail(&nstmt->list, &stmt->list); + nstmt = expr_stmt_alloc(&ctx->stmt->location, nexpr); + list_add_tail(&nstmt->list, &ctx->stmt->list); /* Remember the first payload protocol expression to * kill it later on if made redundant by a higher layer @@ -865,8 +866,9 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx, else payload_dependency_kill(ctx, nexpr->left); } - list_del(&stmt->list); - stmt_free(stmt); + list_del(&ctx->stmt->list); + stmt_free(ctx->stmt); + ctx->stmt = NULL; break; default: payload_expr_complete(left, &ctx->pctx); @@ -878,7 +880,6 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx, } static void meta_match_postprocess(struct rule_pp_ctx *ctx, - struct stmt *stmt, const struct expr *expr) { struct expr *left = expr->left; @@ -889,7 +890,8 @@ static void meta_match_postprocess(struct rule_pp_ctx *ctx, if (ctx->pbase == PROTO_BASE_INVALID && left->flags & EXPR_F_PROTOCOL) - payload_dependency_store(ctx, stmt, left->meta.base); + payload_dependency_store(ctx, ctx->stmt, + left->meta.base); break; case OP_LOOKUP: expr_set_type(expr->right, expr->left->dtype, @@ -973,8 +975,7 @@ static void relational_binop_postprocess(struct expr *expr) } } -static void expr_postprocess(struct rule_pp_ctx *ctx, - struct stmt *stmt, struct expr **exprp) +static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) { struct expr *expr = *exprp, *i; @@ -982,29 +983,29 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, switch (expr->ops->type) { case EXPR_MAP: - expr_postprocess(ctx, stmt, &expr->map); - expr_postprocess(ctx, stmt, &expr->mappings); + expr_postprocess(ctx, &expr->map); + expr_postprocess(ctx, &expr->mappings); break; case EXPR_MAPPING: - expr_postprocess(ctx, stmt, &expr->left); - expr_postprocess(ctx, stmt, &expr->right); + expr_postprocess(ctx, &expr->left); + expr_postprocess(ctx, &expr->right); break; case EXPR_SET: list_for_each_entry(i, &expr->expressions, list) - expr_postprocess(ctx, stmt, &i); + expr_postprocess(ctx, &i); break; case EXPR_UNARY: - expr_postprocess(ctx, stmt, &expr->arg); + expr_postprocess(ctx, &expr->arg); expr_set_type(expr->arg, expr->arg->dtype, !expr->arg->byteorder); *exprp = expr_get(expr->arg); expr_free(expr); break; case EXPR_BINOP: - expr_postprocess(ctx, stmt, &expr->left); + expr_postprocess(ctx, &expr->left); expr_set_type(expr->right, expr->left->dtype, expr->left->byteorder); - expr_postprocess(ctx, stmt, &expr->right); + expr_postprocess(ctx, &expr->right); expr_set_type(expr, expr->left->dtype, expr->left->byteorder); @@ -1012,19 +1013,19 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, case EXPR_RELATIONAL: switch (expr->left->ops->type) { case EXPR_PAYLOAD: - payload_match_postprocess(ctx, stmt, expr); + payload_match_postprocess(ctx, expr); return; default: - expr_postprocess(ctx, stmt, &expr->left); + expr_postprocess(ctx, &expr->left); break; } expr_set_type(expr->right, expr->left->dtype, expr->left->byteorder); - expr_postprocess(ctx, stmt, &expr->right); + expr_postprocess(ctx, &expr->right); switch (expr->left->ops->type) { case EXPR_META: - meta_match_postprocess(ctx, stmt, expr); + meta_match_postprocess(ctx, expr); break; case EXPR_BINOP: relational_binop_postprocess(expr); @@ -1065,11 +1066,11 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, break; case EXPR_RANGE: - expr_postprocess(ctx, stmt, &expr->left); - expr_postprocess(ctx, stmt, &expr->right); + expr_postprocess(ctx, &expr->left); + expr_postprocess(ctx, &expr->right); break; case EXPR_SET_ELEM: - expr_postprocess(ctx, stmt, &expr->key); + expr_postprocess(ctx, &expr->key); break; case EXPR_SET_REF: case EXPR_EXTHDR: @@ -1082,9 +1083,10 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, } } -static void stmt_reject_postprocess(struct rule_pp_ctx *rctx, struct stmt *stmt) +static void stmt_reject_postprocess(struct rule_pp_ctx *rctx) { const struct proto_desc *desc, *base; + struct stmt *stmt = rctx->stmt; int protocol; switch (rctx->pctx.family) { @@ -1149,34 +1151,35 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r proto_ctx_init(&rctx.pctx, rule->handle.family); list_for_each_entry_safe(stmt, next, &rule->stmts, list) { + rctx.stmt = stmt; + switch (stmt->ops->type) { case STMT_EXPRESSION: - expr_postprocess(&rctx, stmt, &stmt->expr); + expr_postprocess(&rctx, &stmt->expr); break; case STMT_META: if (stmt->meta.expr != NULL) - expr_postprocess(&rctx, stmt, &stmt->meta.expr); + expr_postprocess(&rctx, &stmt->meta.expr); break; case STMT_CT: if (stmt->ct.expr != NULL) - expr_postprocess(&rctx, stmt, &stmt->ct.expr); + expr_postprocess(&rctx, &stmt->ct.expr); break; case STMT_NAT: if (stmt->nat.addr != NULL) - expr_postprocess(&rctx, stmt, &stmt->nat.addr); + expr_postprocess(&rctx, &stmt->nat.addr); if (stmt->nat.proto != NULL) - expr_postprocess(&rctx, stmt, &stmt->nat.proto); + expr_postprocess(&rctx, &stmt->nat.proto); break; case STMT_REDIR: if (stmt->redir.proto != NULL) - expr_postprocess(&rctx, stmt, - &stmt->redir.proto); + expr_postprocess(&rctx, &stmt->redir.proto); break; case STMT_REJECT: - stmt_reject_postprocess(&rctx, stmt); + stmt_reject_postprocess(&rctx); break; case STMT_SET: - expr_postprocess(&rctx, stmt, &stmt->set.key); + expr_postprocess(&rctx, &stmt->set.key); break; default: break; -- cgit v1.2.3 From 9a03828e41695f4694a0b7f711bb01bba3b0a39e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 30 May 2015 21:57:57 +0200 Subject: netlink_delinearize: add payload_match_expand() This function encapsulates the payload expansion logic. This change in required by the follow up patch to consolidate range printing. Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 69 +++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 71c32c5f..7b4d6958 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -829,49 +829,54 @@ static void integer_type_postprocess(struct expr *expr) } } -static void payload_match_postprocess(struct rule_pp_ctx *ctx, - struct expr *expr) +static void payload_match_expand(struct rule_pp_ctx *ctx, struct expr *expr) { struct expr *left = expr->left, *right = expr->right, *tmp; struct list_head list = LIST_HEAD_INIT(list); struct stmt *nstmt; struct expr *nexpr; + payload_expr_expand(&list, left, &ctx->pctx); + list_for_each_entry(left, &list, list) { + tmp = constant_expr_splice(right, left->len); + expr_set_type(tmp, left->dtype, left->byteorder); + if (tmp->byteorder == BYTEORDER_HOST_ENDIAN) + mpz_switch_byteorder(tmp->value, tmp->len / BITS_PER_BYTE); + + nexpr = relational_expr_alloc(&expr->location, expr->op, + left, tmp); + if (expr->op == OP_EQ) + left->ops->pctx_update(&ctx->pctx, nexpr); + + nstmt = expr_stmt_alloc(&ctx->stmt->location, nexpr); + list_add_tail(&nstmt->list, &ctx->stmt->list); + + /* Remember the first payload protocol expression to + * kill it later on if made redundant by a higher layer + * payload expression. + */ + if (ctx->pbase == PROTO_BASE_INVALID && + left->flags & EXPR_F_PROTOCOL) + payload_dependency_store(ctx, nstmt, + left->payload.base); + else + payload_dependency_kill(ctx, nexpr->left); + } + list_del(&ctx->stmt->list); + stmt_free(ctx->stmt); + ctx->stmt = NULL; +} + +static void payload_match_postprocess(struct rule_pp_ctx *ctx, + struct expr *expr) +{ switch (expr->op) { case OP_EQ: case OP_NEQ: - payload_expr_expand(&list, left, &ctx->pctx); - list_for_each_entry(left, &list, list) { - tmp = constant_expr_splice(right, left->len); - expr_set_type(tmp, left->dtype, left->byteorder); - if (tmp->byteorder == BYTEORDER_HOST_ENDIAN) - mpz_switch_byteorder(tmp->value, tmp->len / BITS_PER_BYTE); - - nexpr = relational_expr_alloc(&expr->location, expr->op, - left, tmp); - if (expr->op == OP_EQ) - left->ops->pctx_update(&ctx->pctx, nexpr); - - nstmt = expr_stmt_alloc(&ctx->stmt->location, nexpr); - list_add_tail(&nstmt->list, &ctx->stmt->list); - - /* Remember the first payload protocol expression to - * kill it later on if made redundant by a higher layer - * payload expression. - */ - if (ctx->pbase == PROTO_BASE_INVALID && - left->flags & EXPR_F_PROTOCOL) - payload_dependency_store(ctx, nstmt, - left->payload.base); - else - payload_dependency_kill(ctx, nexpr->left); - } - list_del(&ctx->stmt->list); - stmt_free(ctx->stmt); - ctx->stmt = NULL; + payload_match_expand(ctx, expr); break; default: - payload_expr_complete(left, &ctx->pctx); + payload_expr_complete(expr->left, &ctx->pctx); expr_set_type(expr->right, expr->left->dtype, expr->left->byteorder); payload_dependency_kill(ctx, expr->left); -- cgit v1.2.3 From 09565a4b1ed4863d44c4509a93c50f44efd12771 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 30 May 2015 20:01:43 +0200 Subject: netlink_delinearize: consolidate range printing This patch adds a routine to the postprocess stage to check if the previous expression statement and the current actually represent a range, so we can provide a more compact listing, eg. # nft -nn list table test table ip test { chain test { tcp dport 22 tcp dport 22-23 tcp dport != 22-23 ct mark != 0x00000016-0x00000017 ct mark 0x00000016-0x00000017 mark 0x00000016-0x00000017 mark != 0x00000016-0x00000017 } } To do so, the context state stores a pointer to the current statement. This pointer needs to be invalidated in case the current statement is replaced. Signed-off-by: Pablo Neira Ayuso --- src/netlink_delinearize.c | 82 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 7b4d6958..b1ce9113 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -873,8 +873,11 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx, switch (expr->op) { case OP_EQ: case OP_NEQ: - payload_match_expand(ctx, expr); - break; + if (expr->right->ops->type == EXPR_VALUE) { + payload_match_expand(ctx, expr); + break; + } + /* Fall through */ default: payload_expr_complete(expr->left, &ctx->pctx); expr_set_type(expr->right, expr->left->dtype, @@ -1147,10 +1150,80 @@ static void stmt_reject_postprocess(struct rule_pp_ctx *rctx) } } +static bool expr_may_merge_range(struct expr *expr, struct expr *prev, + enum ops *op) +{ + struct expr *left, *prev_left; + + if (prev->ops->type == EXPR_RELATIONAL && + expr->ops->type == EXPR_RELATIONAL) { + /* ct and meta needs an unary to swap byteorder, in this case + * we have to explore the inner branch in this tree. + */ + if (expr->left->ops->type == EXPR_UNARY) + left = expr->left->arg; + else + left = expr->left; + + if (prev->left->ops->type == EXPR_UNARY) + prev_left = prev->left->arg; + else + prev_left = prev->left; + + if (left->ops->type == prev_left->ops->type) { + if (expr->op == OP_LTE && prev->op == OP_GTE) { + *op = OP_EQ; + return true; + } else if (expr->op == OP_GT && prev->op == OP_LT) { + *op = OP_NEQ; + return true; + } + } + } + + return false; +} + +static void expr_postprocess_range(struct rule_pp_ctx *ctx, struct stmt *prev, + enum ops op) +{ + struct stmt *nstmt, *stmt = ctx->stmt; + struct expr *nexpr, *rel; + + nexpr = range_expr_alloc(&prev->location, expr_clone(prev->expr->right), + expr_clone(stmt->expr->right)); + expr_set_type(nexpr, stmt->expr->right->dtype, + stmt->expr->right->byteorder); + + rel = relational_expr_alloc(&prev->location, op, + expr_clone(stmt->expr->left), nexpr); + + nstmt = expr_stmt_alloc(&stmt->location, rel); + list_add_tail(&nstmt->list, &stmt->list); + + list_del(&prev->list); + stmt_free(prev); + + list_del(&stmt->list); + stmt_free(stmt); + ctx->stmt = nstmt; +} + +static void stmt_expr_postprocess(struct rule_pp_ctx *ctx, struct stmt *prev) +{ + enum ops op; + + if (prev && ctx->stmt->ops->type == prev->ops->type && + expr_may_merge_range(ctx->stmt->expr, prev->expr, &op)) + expr_postprocess_range(ctx, prev, op); + + expr_postprocess(ctx, &ctx->stmt->expr); +} + static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *rule) { struct rule_pp_ctx rctx; - struct stmt *stmt, *next; + struct stmt *stmt, *next, *prev = NULL; memset(&rctx, 0, sizeof(rctx)); proto_ctx_init(&rctx.pctx, rule->handle.family); @@ -1160,7 +1233,7 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r switch (stmt->ops->type) { case STMT_EXPRESSION: - expr_postprocess(&rctx, &stmt->expr); + stmt_expr_postprocess(&rctx, prev); break; case STMT_META: if (stmt->meta.expr != NULL) @@ -1189,6 +1262,7 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r default: break; } + prev = rctx.stmt; } } -- cgit v1.2.3 From bddf8debdaf088e940db7638a816436911837b0d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 30 May 2015 22:07:40 +0200 Subject: tests: regression: reduce code duplication a bit on error reporting Consolidate print_err() and print_warning() into print_msg() to reduce code duplication. Signed-off-by: Pablo Neira Ayuso --- tests/regression/nft-test.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tests/regression/nft-test.py b/tests/regression/nft-test.py index 559ad41f..7823f44c 100755 --- a/tests/regression/nft-test.py +++ b/tests/regression/nft-test.py @@ -44,26 +44,21 @@ class Colors: RED = '' ENDC = '' -def print_error(reason, filename=None, lineno=None): +def print_msg(reason, filename=None, lineno=None, color=None, errstr=None): ''' - Prints an error with nice colors, indicating file and line number. + Prints a message with nice colors, indicating file and line number. ''' if filename and lineno: - print (filename + ": " + Colors.RED + "ERROR:" + + print (filename + ": " + color + "ERROR:" + Colors.ENDC + " line %d: %s" % (lineno + 1, reason)) else: - print (Colors.RED + "ERROR:" + Colors.ENDC + " %s" % (reason)) + print (color + "ERROR:" + Colors.ENDC + " %s" % (reason)) +def print_error(reason, filename=None, lineno=None): + print_msg(reason, filename, lineno, Colors.RED, "ERROR:") def print_warning(reason, filename=None, lineno=None): - ''' - Prints a warning with nice colors, indicating file and line number. - ''' - if filename and lineno: - print (filename + ": " + Colors.YELLOW + "WARNING:" + \ - Colors.ENDC + " line %d: %s" % (lineno + 1, reason)) - else: - print (Colors.YELLOW + "WARNING:" + " %s" % (reason)) + print_msg(reason, filename, lineno, Colors.YELLOW, "WARNING:") def print_differences_warning(filename, lineno, rule1, rule2, cmd): -- cgit v1.2.3 From 99632dd169d7db6c66abc06df017de83feec2d38 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 31 May 2015 18:20:02 +0200 Subject: tests: regression: fix warnings related to range listing Fix lots of warnings, mostly related to the listing of ranges in many of the tests that we have, eg. any/meta.t: WARNING: line: 30: 'nft add rule ip test-ip4 input meta l4proto 33-45': 'meta l4proto 33-45' mismatches 'meta l4proto 33-45' any/meta.t: WARNING: line: 31: 'nft add rule ip test-ip4 input meta l4proto != 33-45': 'meta l4proto != 33-45' mismatches 'meta l4proto != 33-45' any/meta.t: WARNING: line: 99: 'nft add rule ip test-ip4 input meta skuid 3001-3005 accept': 'meta skuid 3001-3005 accept' mismatches 'skuid 3001-3005 accept' any/meta.t: WARNING: line: 100: 'nft add rule ip test-ip4 input meta skuid != 2001-2005 accept': 'meta skuid != 2001-2005 accept' mismatches 'skuid != 2001-2005 accept' any/meta.t: WARNING: line: 111: 'nft add rule ip test-ip4 input meta skgid 2001-2005 accept': 'meta skgid 2001-2005 accept' mismatches 'skgid 2001-2005 accept' any/meta.t: WARNING: line: 112: 'nft add rule ip test-ip4 input meta skgid != 2001-2005 accept': 'meta skgid != 2001-2005 accept' mismatches 'skgid != 2001-2005 accept' any/meta.t: WARNING: line: 156: 'nft add rule ip test-ip4 input meta cpu 1-3': 'meta cpu 1-3' mismatches 'cpu 1-3' any/meta.t: WARNING: line: 158: 'nft add rule ip test-ip4 input meta cpu != 1-2': 'meta cpu != 1-2' mismatches 'cpu != 1-2' any/meta.t: WARNING: line: 187: 'nft add rule ip test-ip4 input meta cgroup 0x100001 - 0x100003': 'meta cgroup 0x100001 - 0x100003' mismatches 'cgroup 1048577-1048579' ... Signed-off-by: Pablo Neira Ayuso --- tests/regression/any/ct.t | 26 +++++++++++------------ tests/regression/any/frag.t | 10 ++++----- tests/regression/any/meta.t | 43 +++++++++++++++++++-------------------- tests/regression/arp/arp.t | 14 ++++++------- tests/regression/inet/ah.t | 16 +++++++-------- tests/regression/inet/comp.t | 8 ++++---- tests/regression/inet/dccp.t | 11 +++++----- tests/regression/inet/esp.t | 8 ++++---- tests/regression/inet/sctp.t | 16 +++++++-------- tests/regression/inet/tcp.t | 30 +++++++++++++-------------- tests/regression/inet/udp.t | 20 +++++++++--------- tests/regression/inet/udplite.t | 18 ++++++++-------- tests/regression/ip/icmp.t | 20 +++++++++--------- tests/regression/ip/ip.t | 38 +++++++++++++++++----------------- tests/regression/ip/masquerade.t | 2 +- tests/regression/ip/nat.t | 14 ++++++------- tests/regression/ip/redirect.t | 2 +- tests/regression/ip6/dst.t | 8 ++++---- tests/regression/ip6/hbh.t | 8 ++++---- tests/regression/ip6/ip6.t | 12 +++++------ tests/regression/ip6/masquerade.t | 2 +- tests/regression/ip6/mh.t | 18 ++++++++-------- tests/regression/ip6/redirect.t | 2 +- tests/regression/ip6/rt.t | 16 +++++++-------- 24 files changed, 180 insertions(+), 182 deletions(-) diff --git a/tests/regression/any/ct.t b/tests/regression/any/ct.t index bb26cb85..6ec05261 100644 --- a/tests/regression/any/ct.t +++ b/tests/regression/any/ct.t @@ -44,10 +44,10 @@ ct mark and 0x3 != 0x1;ok;ct mark & 0x00000003 != 0x00000001 ct mark xor 0x23 == 0x11;ok;ct mark 0x00000032 ct mark xor 0x3 != 0x1;ok;ct mark != 0x00000002 -ct mark 0x32;ok;ct mark 0x00000032 -ct mark != 0x32;ok;ct mark != 0x00000032 -ct mark 0x32-0x45;ok -ct mark != 0x32-0x43;ok +ct mark 0x00000032;ok +ct mark != 0x00000032;ok +ct mark 0x00000032-0x00000045;ok +ct mark != 0x00000032-0x00000045;ok ct mark {0x32, 0x2222, 0x42de3};ok;ct mark { 0x00042de3, 0x00002222, 0x00000032} - ct mark != {0x32, 0x2222, 0x42de3};ok @@ -60,16 +60,14 @@ ct mark set 0x11333 and 0x11;ok;ct mark set 0x00000011 ct mark set 0x12 or 0x11;ok;ct mark set 0x00000013 ct mark set 0x11;ok;ct mark set 0x00000011 -ct expiration 30;ok -ct expiration 22;ok -ct expiration != 233;ok -ct expiration 33-45;ok -# BUG: ct expiration 33-45 and ct expiration != 33-45 -# Broken output: ct expiration >= "33s" ct expiration <= "9709d53m20s" -ct expiration != 33-45;ok -ct expiration {33, 55, 67, 88};ok -- ct expiration != {33, 55, 67, 88};ok -ct expiration {33-55};ok +ct expiration 30;ok;ct expiration 30s +ct expiration 22;ok;ct expiration 22s +ct expiration != 233;ok;ct expiration != 3m53s +ct expiration 33-45;ok;ct expiration 33s-45s +ct expiration != 33-45;ok;ct expiration != 33s-45s +ct expiration {33, 55, 67, 88};ok;ct expiration { 1m7s, 33s, 55s, 1m28s} +- ct expiration != {33, 55, 67, 88};ok;ct expiration { 1m7s, 33s, 55s, 1m28s} +ct expiration {33-55};ok;ct expiration { 33s-55s} # BUG: ct expiration {33-55} # Broken output: ct expiration { "4271d23h25m52s"-"8738d3h11m59s" } - ct expiration != {33-55};ok diff --git a/tests/regression/any/frag.t b/tests/regression/any/frag.t index 92caf1e5..d61a3d4f 100644 --- a/tests/regression/any/frag.t +++ b/tests/regression/any/frag.t @@ -14,9 +14,9 @@ frag nexthdr ah;ok;frag nexthdr 51 frag reserved 22;ok frag reserved != 233;ok -frag reserved 33-45;ok;frag reserved >= 33 frag reserved <= 45 -frag reserved != 33-45;ok;frag reserved < 33 frag reserved > 45 -frag reserved { 33, 55, 67, 88};ok;frag reserved { 88, 33, 67, 55} +frag reserved 33-45;ok +frag reserved != 33-45;ok +frag reserved { 33, 55, 67, 88};ok - frag reserved != { 33, 55, 67, 88};ok frag reserved { 33-55};ok - frag reserved != { 33-55};ok @@ -56,8 +56,8 @@ frag reserved { 33-55};ok frag id 1;ok frag id 22;ok frag id != 33;ok -frag id 33-45;ok;frag id >= 33 frag id <= 45 -frag id != 33-45;ok;frag id < 33 frag id > 45 +frag id 33-45;ok +frag id != 33-45;ok frag id { 33, 55, 67, 88};ok - frag id != { 33, 55, 67, 88};ok frag id { 33-55};ok diff --git a/tests/regression/any/meta.t b/tests/regression/any/meta.t index 7108d177..ca0b4d4a 100644 --- a/tests/regression/any/meta.t +++ b/tests/regression/any/meta.t @@ -27,8 +27,8 @@ meta nfproto {ipv4, ipv6};ok meta l4proto 22;ok meta l4proto != 233;ok -meta l4proto 33-45;ok;meta l4proto >= 33 meta l4proto <= 45 -meta l4proto != 33-45;ok;meta l4proto < 33 meta l4proto > 45 +meta l4proto 33-45;ok +meta l4proto != 33-45;ok meta l4proto { 33, 55, 67, 88};ok;meta l4proto { 33, 55, 67, 88} - meta l4proto != { 33, 55, 67, 88};ok meta l4proto { 33-55};ok @@ -96,9 +96,9 @@ meta skuid != man;ok;skuid != 6 meta skuid lt 3000 accept;ok;skuid < 3000 accept meta skuid gt 3000 accept;ok;skuid > 3000 accept meta skuid eq 3000 accept;ok;skuid 3000 accept -meta skuid 3001-3005 accept;ok -meta skuid != 2001-2005 accept;ok -meta skuid { 2001-2005} accept;ok +meta skuid 3001-3005 accept;ok;skuid 3001-3005 accept +meta skuid != 2001-2005 accept;ok;skuid != 2001-2005 accept +meta skuid { 2001-2005} accept;ok;skuid { 2001-2005} accept - meta skuid != { 2001-2005} accept;ok meta skgid {man, root, backup} accept;ok;skgid { 34, 12, 0} accept @@ -108,10 +108,10 @@ meta skgid != man;ok;skgid != 12 meta skgid lt 3000 accept;ok;skgid < 3000 accept meta skgid gt 3000 accept;ok;skgid > 3000 accept meta skgid eq 3000 accept;ok;skgid 3000 accept -meta skgid 2001-2005 accept;ok -meta skgid != 2001-2005 accept;ok -meta skgid { 2001-2005} accept;ok -- meta skgid != { 2001-2005} accept;ok +meta skgid 2001-2005 accept;ok;skgid 2001-2005 accept +meta skgid != 2001-2005 accept;ok;skgid != 2001-2005 accept +meta skgid { 2001-2005} accept;ok;skgid { 2001-2005} accept +- meta skgid != { 2001-2005} accept;ok;skgid != { 2001-2005} accept # BUG: meta nftrace 2 and meta nftrace 1 # $ sudo nft add rule ip test input meta nftrace 2 @@ -153,11 +153,10 @@ meta pkttype { broadcast, multicast} accept;ok meta cpu 1;ok;cpu 1 meta cpu != 1;ok;cpu != 1 -meta cpu 1-3;ok;cpu >= 1 cpu <= 3 -# BUG: there is not matching of packets with this rule. -meta cpu != 1-2;ok;cpu < 1 cpu > 2 -meta cpu { 2,3};ok;cpu { 2, 3} --meta cpu != { 2,3};ok +meta cpu 1-3;ok;cpu 1-3 +meta cpu != 1-2;ok;cpu != 1-2 +meta cpu { 2,3};ok;cpu { 2,3} +-meta cpu != { 2,3};ok; cpu != { 2,3} meta iifgroup 0;ok;iifgroup default meta iifgroup != 0;ok;iifgroup != default @@ -180,11 +179,11 @@ meta oifgroup {11-33};ok - meta oifgroup != {11,33};ok - meta oifgroup != {11-33};ok -meta cgroup 0x100001;ok;cgroup 1048577 -meta cgroup != 0x100001;ok;cgroup != 1048577 -meta cgroup { 0x100001, 0x100002};ok -# meta cgroup != { 0x100001, 0x100002};ok -meta cgroup 0x100001 - 0x100003;ok -# meta cgroup != 0x100001 - 0x100003;ok -meta cgroup {0x100001 - 0x100003};ok -# meta cgroup != { 0x100001 - 0x100003};ok +meta cgroup 1048577;ok;cgroup 1048577 +meta cgroup != 1048577;ok;cgroup != 1048577 +meta cgroup { 1048577, 1048578 };ok;cgroup { 1048577, 1048578} +# meta cgroup != { 1048577, 1048578};ok;cgroup != { 1048577, 1048578} +meta cgroup 1048577-1048578;ok;cgroup 1048577-1048578 +meta cgroup != 1048577-1048578;ok;cgroup != 1048577-1048578 +meta cgroup {1048577-1048578};ok;cgroup { 1048577-1048578} +# meta cgroup != { 1048577-1048578};ok;cgroup != { 1048577-1048578} diff --git a/tests/regression/arp/arp.t b/tests/regression/arp/arp.t index 797e394b..c4e07d57 100644 --- a/tests/regression/arp/arp.t +++ b/tests/regression/arp/arp.t @@ -6,19 +6,19 @@ arp htype 1;ok arp htype != 1;ok arp htype 22;ok arp htype != 233;ok -arp htype 33-45;ok;arp htype >= 33 arp htype <= 45 -arp htype != 33-45;ok;arp htype < 33 arp htype > 45 +arp htype 33-45;ok +arp htype != 33-45;ok arp htype { 33, 55, 67, 88};ok - arp htype != { 33, 55, 67, 88};ok arp htype { 33-55};ok - arp htype != { 33-55};ok -arp ptype 0x0800;ok +arp ptype 0x0800;ok;arp ptype ip arp hlen 22;ok arp hlen != 233;ok -arp hlen 33-45;ok;arp hlen >= 33 arp hlen <= 45 -arp hlen != 33-45;ok;arp hlen < 33 arp hlen > 45 +arp hlen 33-45;ok +arp hlen != 33-45;ok arp hlen { 33, 55, 67, 88};ok - arp hlen != { 33, 55, 67, 88};ok arp hlen { 33-55};ok @@ -26,8 +26,8 @@ arp hlen { 33-55};ok arp plen 22;ok arp plen != 233;ok -arp plen 33-45;ok;arp plen >= 33 arp plen <= 45 -arp plen != 33-45;ok;arp plen < 33 arp plen > 45 +arp plen 33-45;ok +arp plen != 33-45;ok arp plen { 33, 55, 67, 88};ok - arp plen != { 33, 55, 67, 88};ok arp plen { 33-55};ok diff --git a/tests/regression/inet/ah.t b/tests/regression/inet/ah.t index 6defc35c..666659d3 100644 --- a/tests/regression/inet/ah.t +++ b/tests/regression/inet/ah.t @@ -17,8 +17,8 @@ - ah nexthdr { esp, ah, comp, udp, udplite, tcp, dccp, sctp};ok;ah nexthdr { 6, 132, 50, 17, 136, 33, 51, 108} - ah nexthdr != { esp, ah, comp, udp, udplite, tcp, dccp, sctp};ok -ah hdrlength 11-23;ok;ah hdrlength >= 11 ah hdrlength <= 23 -ah hdrlength != 11-23;ok;ah hdrlength < 11 ah hdrlength > 23 +ah hdrlength 11-23;ok +ah hdrlength != 11-23;ok ah hdrlength { 11-23};ok - ah hdrlength != { 11-23};ok ah hdrlength {11, 23, 44 };ok @@ -26,8 +26,8 @@ ah hdrlength {11, 23, 44 };ok ah reserved 22;ok ah reserved != 233;ok -ah reserved 33-45;ok;ah reserved >= 33 ah reserved <= 45 -ah reserved != 33-45;ok;ah reserved < 33 ah reserved > 45 +ah reserved 33-45;ok +ah reserved != 33-45;ok ah reserved {23, 100};ok - ah reserved != {33, 55, 67, 88};ok ah reserved { 33-55};ok @@ -35,8 +35,8 @@ ah reserved { 33-55};ok ah spi 111;ok ah spi != 111;ok -ah spi 111-222;ok;ah spi >= 111 ah spi <= 222 -ah spi != 111-222;ok;ah spi < 111 ah spi > 222 +ah spi 111-222;ok +ah spi != 111-222;ok ah spi {111, 122};ok - ah spi != {111, 122};ok # BUG: invalid expression type set @@ -54,5 +54,5 @@ ah sequence {23, 25, 33};ok - ah sequence != {23, 25, 33};ok ah sequence { 23-33};ok - ah sequence != { 33-44};ok -ah sequence 23-33;ok;ah sequence >= 23 ah sequence <= 33 -ah sequence != 23-33;ok;ah sequence < 23 ah sequence > 33 +ah sequence 23-33;ok +ah sequence != 23-33;ok diff --git a/tests/regression/inet/comp.t b/tests/regression/inet/comp.t index 32db32b2..afdc63f3 100644 --- a/tests/regression/inet/comp.t +++ b/tests/regression/inet/comp.t @@ -4,9 +4,9 @@ :input;type filter hook input priority 0 -# BUG: Do no list table. +# BUG: nft: payload.c:88: payload_expr_pctx_update: Assertion `left->payload.base + 1 <= (__PROTO_BASE_MAX - 1)' failed. - comp nexthdr esp;ok;comp nexthdr 50 -comp nexthdr != esp;ok +comp nexthdr != esp;ok;comp nexthdr != 50 - comp nexthdr {esp, ah, comp, udp, udplite, tcp, tcp, dccp, sctp};ok # comp flags ## 8-bit field. Reserved for future use. MUST be set to zero. @@ -23,8 +23,8 @@ comp flags { 0x33-0x55};ok comp cpi 22;ok comp cpi != 233;ok -comp cpi 33-45;ok;comp cpi >= 33 comp cpi <= 45 -comp cpi != 33-45;ok;comp cpi < 33 comp cpi > 45 +comp cpi 33-45;ok +comp cpi != 33-45;ok comp cpi {33, 55, 67, 88};ok - comp cpi != {33, 55, 67, 88};ok comp cpi { 33-55};ok diff --git a/tests/regression/inet/dccp.t b/tests/regression/inet/dccp.t index 272c0e2a..e323992e 100644 --- a/tests/regression/inet/dccp.t +++ b/tests/regression/inet/dccp.t @@ -3,15 +3,16 @@ *inet;test-inet :input;type filter hook input priority 0 -dccp sport 21-35;ok;dccp sport >= 21 dccp sport <= 35 -dccp sport != 21-35;ok;dccp sport < 21 dccp sport > 35 -dccp sport {23, 24, 25};ok;dccp sport { 23, 24, 25} +dccp sport 21-35;ok +dccp sport != 21-35;ok +dccp sport {23, 24, 25};ok - dccp sport != { 27, 34};ok # BUG: invalid expression type set # nft: src/evaluate.c:975: expr_evaluate_relational: Assertion '0' failed. -dccp sport { ftp-data - re-mail-ck};ok;dccp sport { 20-50} -dccp sport ftp-data - re-mail-ck;ok;dccp sport >= 20 dccp sport <= 50 +dccp sport { 20-50 };ok +dccp sport ftp-data - re-mail-ck;ok;dccp sport 20-50 +dccp sport 20-50;ok dccp sport { 20-50};ok - dccp sport != {27-34};ok # dccp sport != {27-34};ok diff --git a/tests/regression/inet/esp.t b/tests/regression/inet/esp.t index 1f23aa4e..3a8502d9 100644 --- a/tests/regression/inet/esp.t +++ b/tests/regression/inet/esp.t @@ -5,16 +5,16 @@ esp spi 100;ok esp spi != 100;ok -esp spi 111-222;ok;esp spi >= 111 esp spi <= 222 -esp spi != 111-222;ok;esp spi < 111 esp spi > 222 +esp spi 111-222;ok +esp spi != 111-222;ok esp spi { 100, 102};ok - esp spi != { 100, 102};ok esp spi { 100-102};ok - esp spi {100-102};ok esp sequence 22;ok -esp sequence 22-24;ok;esp sequence >= 22 esp sequence <= 24 -esp sequence != 22-24;ok;esp sequence < 22 esp sequence > 24 +esp sequence 22-24;ok +esp sequence != 22-24;ok esp sequence { 22, 24};ok - esp sequence != { 22, 24};ok # BUG: invalid expression type set diff --git a/tests/regression/inet/sctp.t b/tests/regression/inet/sctp.t index b98b0af4..537a9b17 100644 --- a/tests/regression/inet/sctp.t +++ b/tests/regression/inet/sctp.t @@ -5,8 +5,8 @@ sctp sport 23;ok sctp sport != 23;ok -sctp sport 23-44;ok;sctp sport >= 23 sctp sport <= 44 -sctp sport != 23-44;ok;sctp sport < 23 sctp sport > 44 +sctp sport 23-44;ok +sctp sport != 23-44;ok sctp sport { 23, 24, 25};ok - sctp sport != { 23, 24, 25};ok sctp sport { 23-44};ok @@ -16,8 +16,8 @@ sctp sport { 23-44};ok sctp dport 23;ok sctp dport != 23;ok -sctp dport 23-44;ok;sctp dport >= 23 sctp dport <= 44 -sctp dport != 23-44;ok;sctp dport < 23 sctp dport > 44 +sctp dport 23-44;ok +sctp dport != 23-44;ok sctp dport { 23, 24, 25};ok - sctp dport != { 23, 24, 25};ok sctp dport { 23-44};ok @@ -25,8 +25,8 @@ sctp dport { 23-44};ok sctp checksum 1111;ok sctp checksum != 11;ok -sctp checksum 21-333;ok;sctp checksum >= 21 sctp checksum <= 333 -sctp checksum != 32-111;ok;sctp checksum < 32 sctp checksum > 111 +sctp checksum 21-333;ok +sctp checksum != 32-111;ok sctp checksum { 22, 33, 44};ok - sctp checksum != { 22, 33, 44};ok sctp checksum { 22-44};ok @@ -34,8 +34,8 @@ sctp checksum { 22-44};ok sctp vtag 22;ok sctp vtag != 233;ok -sctp vtag 33-45;ok;sctp vtag >= 33 sctp vtag <= 45 -sctp vtag != 33-45;ok;sctp vtag < 33 sctp vtag > 45 +sctp vtag 33-45;ok +sctp vtag != 33-45;ok sctp vtag {33, 55, 67, 88};ok - sctp vtag != {33, 55, 67, 88};ok sctp vtag { 33-55};ok diff --git a/tests/regression/inet/tcp.t b/tests/regression/inet/tcp.t index f72ec52b..5eb3882c 100644 --- a/tests/regression/inet/tcp.t +++ b/tests/regression/inet/tcp.t @@ -5,8 +5,8 @@ tcp dport 22;ok tcp dport != 233;ok -tcp dport 33-45;ok;tcp dport >= 33 tcp dport <= 45 -tcp dport != 33-45;ok;tcp dport < 33 tcp dport > 45 +tcp dport 33-45;ok +tcp dport != 33-45;ok tcp dport { 33, 55, 67, 88};ok - tcp dport != { 33, 55, 67, 88};ok tcp dport { 33-55};ok @@ -21,8 +21,8 @@ tcp dport { 22, 53, 80, 110 };ok tcp sport 22;ok tcp sport != 233;ok -tcp sport 33-45;ok;tcp sport >= 33 tcp sport <= 45 -tcp sport != 33-45;ok;tcp sport < 33 tcp sport > 45 +tcp sport 33-45;ok +tcp sport != 33-45;ok tcp sport { 33, 55, 67, 88};ok - tcp sport != { 33, 55, 67, 88};ok tcp sport { 33-55};ok @@ -33,13 +33,13 @@ tcp sport 8080 drop;ok tcp sport 1024 tcp dport 22;ok tcp sport 1024 tcp dport 22 tcp sequence 0;ok -tcp sequence 0 tcp sport 1024 tcp dport 22;ok;tcp sport 1024 tcp dport 22 tcp sequence 0 +tcp sequence 0 tcp sport 1024 tcp dport 22;ok tcp sequence 0 tcp sport { 1024, 1022} tcp dport 22;ok tcp sequence 22;ok tcp sequence != 233;ok -tcp sequence 33-45;ok;tcp sequence >= 33 tcp sequence <= 45 -tcp sequence != 33-45;ok;tcp sequence < 33 tcp sequence > 45 +tcp sequence 33-45;ok +tcp sequence != 33-45;ok tcp sequence { 33, 55, 67, 88};ok - tcp sequence != { 33, 55, 67, 88};ok tcp sequence { 33-55};ok @@ -48,8 +48,8 @@ tcp sequence { 33-55};ok tcp ackseq 42949672 drop;ok tcp ackseq 22;ok tcp ackseq != 233;ok -tcp ackseq 33-45;ok;tcp ackseq >= 33 tcp ackseq <= 45 -tcp ackseq != 33-45;ok;tcp ackseq < 33 tcp ackseq > 45 +tcp ackseq 33-45;ok +tcp ackseq != 33-45;ok tcp ackseq { 33, 55, 67, 88};ok - tcp ackseq != { 33, 55, 67, 88};ok tcp ackseq { 33-55};ok @@ -75,8 +75,8 @@ tcp flags != cwr;ok tcp window 22222;ok tcp window 22;ok tcp window != 233;ok -tcp window 33-45;ok;tcp window >= 33 tcp window <= 45 -tcp window != 33-45;ok;tcp window < 33 tcp window > 45 +tcp window 33-45;ok +tcp window != 33-45;ok tcp window { 33, 55, 67, 88};ok - tcp window != { 33, 55, 67, 88};ok tcp window { 33-55};ok @@ -85,8 +85,8 @@ tcp window { 33-55};ok tcp checksum 23456 log drop;ok tcp checksum 22;ok tcp checksum != 233;ok -tcp checksum 33-45;ok;tcp checksum >= 33 tcp checksum <= 45 -tcp checksum != 33-45;ok;tcp checksum < 33 tcp checksum > 45 +tcp checksum 33-45;ok +tcp checksum != 33-45;ok tcp checksum { 33, 55, 67, 88};ok - tcp checksum != { 33, 55, 67, 88};ok tcp checksum { 33-55};ok @@ -95,8 +95,8 @@ tcp checksum { 33-55};ok tcp urgptr 1234 accept;ok tcp urgptr 22;ok tcp urgptr != 233;ok -tcp urgptr 33-45;ok;tcp urgptr >= 33 tcp urgptr <= 45 -tcp urgptr != 33-45;ok;tcp urgptr < 33 tcp urgptr > 45 +tcp urgptr 33-45;ok +tcp urgptr != 33-45;ok tcp urgptr { 33, 55, 67, 88};ok - tcp urgptr != { 33, 55, 67, 88};ok tcp urgptr { 33-55};ok diff --git a/tests/regression/inet/udp.t b/tests/regression/inet/udp.t index 0e8a01f0..58f4002d 100644 --- a/tests/regression/inet/udp.t +++ b/tests/regression/inet/udp.t @@ -5,9 +5,9 @@ udp sport 80 accept;ok udp sport != 60 accept;ok -udp sport 50-70 accept;ok;udp sport >= 50 udp sport <= 70 accept -udp sport != 50-60 accept;ok;udp sport < 50 udp sport > 60 accept -udp sport { 49, 50} drop;ok;udp sport { 49, 50} drop +udp sport 50-70 accept;ok +udp sport != 50-60 accept;ok +udp sport { 49, 50} drop;ok - udp sport != { 50, 60} accept;ok # BUG: invalid expression type set # nft: src/evaluate.c:975: expr_evaluate_relational: Assertion '0' failed. @@ -16,19 +16,19 @@ udp sport { 12-40};ok udp dport 80 accept;ok udp dport != 60 accept;ok -udp dport 70-75 accept;ok;udp dport >= 70 udp dport <= 75 accept -udp dport != 50-60 accept;ok;udp dport < 50 udp dport > 60 accept +udp dport 70-75 accept;ok +udp dport != 50-60 accept;ok udp dport { 49, 50} drop;ok - udp dport != { 50, 60} accept;ok # BUG: invalid expression type set # nft: src/evaluate.c:975: expr_evaluate_relational: Assertion '0' failed. -udp dport { 70-75} accept;ok;udp dport { 70-75} accept +udp dport { 70-75} accept;ok - udp dport != { 50-60} accept;ok udp length 6666;ok udp length != 6666;ok -udp length 50-65 accept;ok;udp length >= 50 udp length <= 65 accept -udp length != 50-65 accept;ok;udp length < 50 udp length > 65 accept +udp length 50-65 accept;ok +udp length != 50-65 accept;ok udp length { 50, 65} accept;ok - udp length != { 50, 65} accept;ok udp length { 35-50};ok @@ -41,8 +41,8 @@ udp checksum 6666 drop;ok udp checksum 22;ok udp checksum != 233;ok -udp checksum 33-45;ok;udp checksum >= 33 udp checksum <= 45 -udp checksum != 33-45;ok;udp checksum < 33 udp checksum > 45 +udp checksum 33-45;ok +udp checksum != 33-45;ok udp checksum { 33, 55, 67, 88};ok - udp checksum != { 33, 55, 67, 88};ok udp checksum { 33-55};ok diff --git a/tests/regression/inet/udplite.t b/tests/regression/inet/udplite.t index 1d5fbb35..9420ab45 100644 --- a/tests/regression/inet/udplite.t +++ b/tests/regression/inet/udplite.t @@ -5,20 +5,20 @@ udplite sport 80 accept;ok udplite sport != 60 accept;ok -udplite sport 50-70 accept;ok;udplite sport >= 50 udplite sport <= 70 accept -udplite sport != 50-60 accept;ok;udplite sport < 50 udplite sport > 60 accept -udplite sport { 49, 50} drop;ok;udplite sport { 49, 50} drop +udplite sport 50-70 accept;ok +udplite sport != 50-60 accept;ok +udplite sport { 49, 50} drop;ok - udplite sport != { 50, 60} accept;ok udplite sport { 12-40};ok - udplite sport != { 13-24};ok udplite dport 80 accept;ok udplite dport != 60 accept;ok -udplite dport 70-75 accept;ok;udplite dport >= 70 udplite dport <= 75 accept -udplite dport != 50-60 accept;ok;udplite dport < 50 udplite dport > 60 accept -udplite dport { 49, 50} drop;ok;udplite dport { 49, 50} drop +udplite dport 70-75 accept;ok +udplite dport != 50-60 accept;ok +udplite dport { 49, 50} drop;ok - udplite dport != { 50, 60} accept;ok -udplite dport { 70-75} accept;ok;udplite dport { 70-75} accept +udplite dport { 70-75} accept;ok - udplite dport != { 50-60} accept;ok - udplite csumcov 6666;ok @@ -34,8 +34,8 @@ udplite checksum 6666 drop;ok - udplite checksum != { 444, 555} accept;ok udplite checksum 22;ok udplite checksum != 233;ok -udplite checksum 33-45;ok;udplite checksum >= 33 udplite checksum <= 45 -udplite checksum != 33-45;ok;udplite checksum < 33 udplite checksum > 45 +udplite checksum 33-45;ok +udplite checksum != 33-45;ok udplite checksum { 33, 55, 67, 88};ok - udplite checksum != { 33, 55, 67, 88};ok udplite checksum { 33-55};ok diff --git a/tests/regression/ip/icmp.t b/tests/regression/ip/icmp.t index cd43a668..9c2aba78 100644 --- a/tests/regression/ip/icmp.t +++ b/tests/regression/ip/icmp.t @@ -24,8 +24,8 @@ icmp type {echo-reply, destination-unreachable, source-quench, redirect, echo-re icmp code 111 accept;ok icmp code != 111 accept;ok -icmp code 33-55;ok;icmp code >= 33 icmp code <= 55 -icmp code != 33-55;ok;icmp code < 33 icmp code > 55 +icmp code 33-55;ok +icmp code != 33-55;ok icmp code { 33-55};ok - icmp code != { 33-55};ok icmp code { 2, 4, 54, 33, 56};ok @@ -36,8 +36,8 @@ icmp code { 2, 4, 54, 33, 56};ok icmp checksum 12343 accept;ok icmp checksum != 12343 accept;ok -icmp checksum 11-343 accept;ok;icmp checksum >= 11 icmp checksum <= 343 accept -icmp checksum != 11-343 accept;ok;icmp checksum < 11 icmp checksum > 343 accept +icmp checksum 11-343 accept;ok +icmp checksum != 11-343 accept;ok icmp checksum { 11-343} accept;ok - icmp checksum != { 11-343} accept;ok icmp checksum { 1111, 222, 343} accept;ok @@ -49,8 +49,8 @@ icmp checksum { 1111, 222, 343} accept;ok icmp id 1245 log;ok icmp id 22;ok icmp id != 233;ok -icmp id 33-45;ok;icmp id >= 33 icmp id <= 45 -icmp id != 33-45;ok;icmp id < 33 icmp id > 45 +icmp id 33-45;ok +icmp id != 33-45;ok icmp id { 33-55};ok - icmp id != { 33-55};ok icmp id { 22, 34, 333};ok @@ -61,8 +61,8 @@ icmp id { 22, 34, 333};ok icmp sequence 22;ok icmp sequence != 233;ok -icmp sequence 33-45;ok;icmp sequence >= 33 icmp sequence <= 45 -icmp sequence != 33-45;ok;icmp sequence < 33 icmp sequence > 45 +icmp sequence 33-45;ok +icmp sequence != 33-45;ok icmp sequence { 33, 55, 67, 88};ok - icmp sequence != { 33, 55, 67, 88};ok icmp sequence { 33-55};ok @@ -83,8 +83,8 @@ icmp mtu { 33-55};ok icmp gateway 22;ok icmp gateway != 233;ok -icmp gateway 33-45;ok;icmp gateway >= 33 icmp gateway <= 45 -icmp gateway != 33-45;ok;icmp gateway < 33 icmp gateway > 45 +icmp gateway 33-45;ok +icmp gateway != 33-45;ok icmp gateway { 33, 55, 67, 88};ok - icmp gateway != { 33, 55, 67, 88};ok icmp gateway { 33-55};ok diff --git a/tests/regression/ip/ip.t b/tests/regression/ip/ip.t index a781de5b..fa864dfd 100644 --- a/tests/regression/ip/ip.t +++ b/tests/regression/ip/ip.t @@ -30,8 +30,8 @@ ip length 232;ok ip length != 233;ok -ip length 333-435;ok;ip length >= 333 ip length <= 435 -ip length != 333-453;ok;ip length < 333 ip length > 453 +ip length 333-435;ok +ip length != 333-453;ok ip length { 333, 553, 673, 838};ok - ip length != { 333, 535, 637, 883};ok ip length { 333-535};ok @@ -39,8 +39,8 @@ ip length { 333-535};ok ip id 22;ok ip id != 233;ok -ip id 33-45;ok;ip id >= 33 ip id <= 45 -ip id != 33-45;ok;ip id < 33 ip id > 45 +ip id 33-45;ok +ip id != 33-45;ok ip id { 33, 55, 67, 88};ok - ip id != { 33, 55, 67, 88};ok ip id { 33-55};ok @@ -48,8 +48,8 @@ ip id { 33-55};ok ip frag-off 222 accept;ok ip frag-off != 233;ok -ip frag-off 33-45;ok;ip frag-off >= 33 ip frag-off <= 45 -ip frag-off != 33-45;ok;ip frag-off < 33 ip frag-off > 45 +ip frag-off 33-45;ok +ip frag-off != 33-45;ok ip frag-off { 33, 55, 67, 88};ok - ip frag-off != { 33, 55, 67, 88};ok ip frag-off { 33-55};ok @@ -57,8 +57,8 @@ ip frag-off { 33-55};ok ip ttl 0 drop;ok ip ttl 233 log;ok -ip ttl 33-55;ok;ip ttl >= 33 ip ttl <= 55 -ip ttl != 45-50;ok;ip ttl < 45 ip ttl > 50 +ip ttl 33-55;ok +ip ttl != 45-50;ok ip ttl {43, 53, 45 };ok - ip ttl != {46, 56, 93 };ok # BUG: ip ttl != {46, 56, 93 };ok @@ -75,8 +75,8 @@ ip protocol { icmp, esp, ah, comp, udp, udplite, tcp, dccp, sctp} accept;ok;ip p ip checksum 13172 drop;ok ip checksum 22;ok ip checksum != 233;ok -ip checksum 33-45;ok;ip checksum >= 33 ip checksum <= 45 -ip checksum != 33-45;ok;ip checksum < 33 ip checksum > 45 +ip checksum 33-45;ok +ip checksum != 33-45;ok ip checksum { 33, 55, 67, 88};ok - ip checksum != { 33, 55, 67, 88};ok ip checksum { 33-55};ok @@ -87,20 +87,20 @@ ip saddr != 192.168.2.0/24;ok ip saddr 192.168.3.1 ip daddr 192.168.3.100;ok ip saddr != 1.1.1.1 log prefix giuseppe;ok;ip saddr != 1.1.1.1 log prefix "giuseppe" ip saddr 1.1.1.1 log prefix example group 1;ok;ip saddr 1.1.1.1 log prefix "example" group 1 -ip daddr 192.168.0.1-192.168.0.250;ok;ip daddr >= 192.168.0.1 ip daddr <= 192.168.0.250 -ip daddr 10.0.0.0-10.255.255.255;ok;ip daddr >= 10.0.0.0 ip daddr <= 10.255.255.255 -ip daddr 172.16.0.0-172.31.255.255;ok;ip daddr >= 172.16.0.0 ip daddr <= 172.31.255.255 -ip daddr 192.168.3.1-192.168.4.250;ok;ip daddr >= 192.168.3.1 ip daddr <= 192.168.4.250 -ip daddr != 192.168.0.1-192.168.0.250;ok;ip daddr < 192.168.0.1 ip daddr > 192.168.0.250 +ip daddr 192.168.0.1-192.168.0.250;ok +ip daddr 10.0.0.0-10.255.255.255;ok +ip daddr 172.16.0.0-172.31.255.255;ok +ip daddr 192.168.3.1-192.168.4.250;ok +ip daddr != 192.168.0.1-192.168.0.250;ok ip daddr { 192.168.0.1-192.168.0.250};ok - ip daddr != { 192.168.0.1-192.168.0.250};ok ip daddr { 192.168.5.1, 192.168.5.2, 192.168.5.3 } accept;ok - ip daddr != { 192.168.5.1, 192.168.5.2, 192.168.5.3 } accept;ok -ip daddr 192.168.1.2-192.168.1.55;ok;ip daddr >= 192.168.1.2 ip daddr <= 192.168.1.55 -ip daddr != 192.168.1.2-192.168.1.55;ok;ip daddr < 192.168.1.2 ip daddr > 192.168.1.55 -ip saddr 192.168.1.3-192.168.33.55;ok;ip saddr >= 192.168.1.3 ip saddr <= 192.168.33.55 -ip saddr != 192.168.1.3-192.168.33.55;ok;ip saddr < 192.168.1.3 ip saddr > 192.168.33.55 +ip daddr 192.168.1.2-192.168.1.55;ok +ip daddr != 192.168.1.2-192.168.1.55;ok +ip saddr 192.168.1.3-192.168.33.55;ok +ip saddr != 192.168.1.3-192.168.33.55;ok ip daddr 192.168.0.1;ok ip daddr 192.168.0.1 drop;ok diff --git a/tests/regression/ip/masquerade.t b/tests/regression/ip/masquerade.t index d0fe02d1..35001f37 100644 --- a/tests/regression/ip/masquerade.t +++ b/tests/regression/ip/masquerade.t @@ -21,5 +21,5 @@ ip saddr 10.1.1.1 masquerade drop;fail # masquerade with sets tcp dport { 1,2,3,4,5,6,7,8,101,202,303,1001,2002,3003} masquerade;ok -ip daddr 10.0.0.0-10.2.3.4 udp dport 53 counter packets 0 bytes 0 masquerade;ok;ip daddr >= 10.0.0.0 ip daddr <= 10.2.3.4 udp dport 53 counter packets 0 bytes 0 masquerade +ip daddr 10.0.0.0-10.2.3.4 udp dport 53 counter packets 0 bytes 0 masquerade;ok iifname eth0 ct state new,established tcp dport vmap {22 : drop, 222 : drop } masquerade;ok diff --git a/tests/regression/ip/nat.t b/tests/regression/ip/nat.t index 5afe823a..26c8cbf7 100644 --- a/tests/regression/ip/nat.t +++ b/tests/regression/ip/nat.t @@ -4,15 +4,15 @@ :output;type nat hook output priority 0 -iifname eth0 tcp dport 80-90 dnat 192.168.3.2;ok;iifname "eth0" tcp dport >= 80 tcp dport <= 90 dnat 192.168.3.2 -iifname eth0 tcp dport != 80-90 dnat 192.168.3.2;ok;iifname "eth0" tcp dport < 80 tcp dport > 90 dnat 192.168.3.2 -iifname eth0 tcp dport {80, 90, 23} dnat 192.168.3.2;ok -- iifname eth0 tcp dport != {80, 90, 23} dnat 192.168.3.2;ok +iifname "eth0" tcp dport 80-90 dnat 192.168.3.2;ok +iifname "eth0" tcp dport != 80-90 dnat 192.168.3.2;ok +iifname "eth0" tcp dport {80, 90, 23} dnat 192.168.3.2;ok +- iifname "eth0" tcp dport != {80, 90, 23} dnat 192.168.3.2;ok -iifname eth0 tcp sport 23-34 snat 192.168.3.2;ok;iifname "eth0" tcp sport >= 23 tcp sport <= 34 snat 192.168.3.2 +iifname eth0 tcp sport 23-34 snat 192.168.3.2;ok -- iifname eth0 tcp dport != {80, 90, 23} dnat 192.168.3.2;ok +- iifname "eth0" tcp dport != {80, 90, 23} dnat 192.168.3.2;ok # BUG: invalid expression type set # nft: src/evaluate.c:975: expr_evaluate_relational: Assertion '0' failed. -iifname eth0 tcp dport != 23-34 dnat 192.168.3.2;ok;iifname "eth0" tcp dport < 23 tcp dport > 34 dnat 192.168.3.2 +iifname "eth0" tcp dport != 23-34 dnat 192.168.3.2;ok diff --git a/tests/regression/ip/redirect.t b/tests/regression/ip/redirect.t index bbf440d1..b7eecb74 100644 --- a/tests/regression/ip/redirect.t +++ b/tests/regression/ip/redirect.t @@ -41,5 +41,5 @@ ip saddr 10.1.1.1 redirect drop;fail # redirect with sets tcp dport { 1, 2, 3, 4, 5, 6, 7, 8, 101, 202, 303, 1001, 2002, 3003} redirect;ok -ip daddr 10.0.0.0-10.2.3.4 udp dport 53 counter packets 0 bytes 0 redirect;ok;ip daddr >= 10.0.0.0 ip daddr <= 10.2.3.4 udp dport 53 counter packets 0 bytes 0 redirect +ip daddr 10.0.0.0-10.2.3.4 udp dport 53 counter packets 0 bytes 0 redirect;ok iifname eth0 ct state new,established tcp dport vmap {22 : drop, 222 : drop } redirect;ok diff --git a/tests/regression/ip6/dst.t b/tests/regression/ip6/dst.t index 1b1bc52a..3207af76 100644 --- a/tests/regression/ip6/dst.t +++ b/tests/regression/ip6/dst.t @@ -4,8 +4,8 @@ dst nexthdr 22;ok dst nexthdr != 233;ok -dst nexthdr 33-45;ok;dst nexthdr >= 33 dst nexthdr <= 45 -dst nexthdr != 33-45;ok;dst nexthdr < 33 dst nexthdr > 45 +dst nexthdr 33-45;ok +dst nexthdr != 33-45;ok dst nexthdr { 33, 55, 67, 88};ok - dst nexthdr != { 33, 55, 67, 88};ok dst nexthdr { 33-55};ok @@ -17,8 +17,8 @@ dst nexthdr != icmp;ok;dst nexthdr != 1 dst hdrlength 22;ok dst hdrlength != 233;ok -dst hdrlength 33-45;ok;dst hdrlength >= 33 dst hdrlength <= 45 -dst hdrlength != 33-45;ok;dst hdrlength < 33 dst hdrlength > 45 +dst hdrlength 33-45;ok +dst hdrlength != 33-45;ok dst hdrlength { 33, 55, 67, 88};ok - dst hdrlength != { 33, 55, 67, 88};ok dst hdrlength { 33-55};ok diff --git a/tests/regression/ip6/hbh.t b/tests/regression/ip6/hbh.t index b274b8b7..4e67c42a 100644 --- a/tests/regression/ip6/hbh.t +++ b/tests/regression/ip6/hbh.t @@ -4,8 +4,8 @@ hbh hdrlength 22;ok hbh hdrlength != 233;ok -hbh hdrlength 33-45;ok;hbh hdrlength >= 33 hbh hdrlength <= 45 -hbh hdrlength != 33-45;ok;hbh hdrlength < 33 hbh hdrlength > 45 +hbh hdrlength 33-45;ok +hbh hdrlength != 33-45;ok hbh hdrlength {33, 55, 67, 88};ok - hbh hdrlength != {33, 55, 67, 88};ok hbh hdrlength { 33-55};ok @@ -15,8 +15,8 @@ hbh nexthdr {esp, ah, comp, udp, udplite, tcp, dccp, sctp, icmpv6};ok;hbh nexthd - hbh nexthdr != {esp, ah, comp, udp, udplite, tcp, dccp, sctp, icmpv6};ok hbh nexthdr 22;ok hbh nexthdr != 233;ok -hbh nexthdr 33-45;ok;hbh nexthdr >= 33 hbh nexthdr <= 45 -hbh nexthdr != 33-45;ok;hbh nexthdr < 33 hbh nexthdr > 45 +hbh nexthdr 33-45;ok +hbh nexthdr != 33-45;ok hbh nexthdr {33, 55, 67, 88};ok - hbh nexthdr != {33, 55, 67, 88};ok hbh nexthdr { 33-55};ok diff --git a/tests/regression/ip6/ip6.t b/tests/regression/ip6/ip6.t index 243c7894..529a0687 100644 --- a/tests/regression/ip6/ip6.t +++ b/tests/regression/ip6/ip6.t @@ -29,8 +29,8 @@ ip6 flowlabel { 33-55};ok ip6 length 22;ok ip6 length != 233;ok -ip6 length 33-45;ok;ip6 length >= 33 ip6 length <= 45 -ip6 length != 33-45;ok;ip6 length < 33 ip6 length > 45 +ip6 length 33-45;ok +ip6 length != 33-45;ok - ip6 length { 33, 55, 67, 88};ok - ip6 length != {33, 55, 67, 88};ok ip6 length { 33-55};ok @@ -43,13 +43,13 @@ ip6 nexthdr esp;ok;ip6 nexthdr 50 ip6 nexthdr != esp;ok;ip6 nexthdr != 50 ip6 nexthdr { 33-44};ok - p6 nexthdr != { 33-44};ok -ip6 nexthdr 33-44;ok;ip6 nexthdr >= 33 ip6 nexthdr <= 44 -ip6 nexthdr != 33-44;ok;ip6 nexthdr < 33 ip6 nexthdr > 44 +ip6 nexthdr 33-44;ok +ip6 nexthdr != 33-44;ok ip6 hoplimit 1 log;ok ip6 hoplimit != 233;ok -ip6 hoplimit 33-45;ok;ip6 hoplimit >= 33 ip6 hoplimit <= 45 -ip6 hoplimit != 33-45;ok;ip6 hoplimit < 33 ip6 hoplimit > 45 +ip6 hoplimit 33-45;ok +ip6 hoplimit != 33-45;ok ip6 hoplimit {33, 55, 67, 88};ok - ip6 hoplimit != {33, 55, 67, 88};ok ip6 hoplimit {33-55};ok diff --git a/tests/regression/ip6/masquerade.t b/tests/regression/ip6/masquerade.t index 817acd4f..4e6c086c 100644 --- a/tests/regression/ip6/masquerade.t +++ b/tests/regression/ip6/masquerade.t @@ -21,5 +21,5 @@ ip6 saddr ::1 masquerade drop;fail # masquerade with sets tcp dport { 1,2,3,4,5,6,7,8,101,202,303,1001,2002,3003} masquerade;ok -ip6 daddr fe00::1-fe00::200 udp dport 53 counter packets 0 bytes 0 masquerade;ok;ip6 daddr >= fe00::1 ip6 daddr <= fe00::200 udp dport 53 counter packets 0 bytes 0 masquerade +ip6 daddr fe00::1-fe00::200 udp dport 53 counter packets 0 bytes 0 masquerade;ok iifname eth0 ct state new,established tcp dport vmap {22 : drop, 222 : drop } masquerade;ok diff --git a/tests/regression/ip6/mh.t b/tests/regression/ip6/mh.t index 4ff58a17..cd652b39 100644 --- a/tests/regression/ip6/mh.t +++ b/tests/regression/ip6/mh.t @@ -10,8 +10,8 @@ mh nexthdr icmp;ok;mh nexthdr 1 mh nexthdr != icmp;ok;mh nexthdr != 1 mh nexthdr 22;ok mh nexthdr != 233;ok -mh nexthdr 33-45;ok;mh nexthdr >= 33 mh nexthdr <= 45 -mh nexthdr != 33-45;ok;mh nexthdr < 33 mh nexthdr > 45 +mh nexthdr 33-45;ok +mh nexthdr != 33-45;ok mh nexthdr { 33, 55, 67, 88 };ok - mh nexthdr != { 33, 55, 67, 88 };ok mh nexthdr { 33-55 };ok @@ -19,9 +19,9 @@ mh nexthdr { 33-55 };ok mh hdrlength 22;ok mh hdrlength != 233;ok -mh hdrlength 33-45;ok;mh hdrlength >= 33 mh hdrlength <= 45 -mh hdrlength != 33-45;ok;mh hdrlength < 33 mh hdrlength > 45 -mh hdrlength { 33, 55, 67, 88 };ok;mh hdrlength { 67, 33, 88, 55} +mh hdrlength 33-45;ok +mh hdrlength != 33-45;ok +mh hdrlength { 33, 55, 67, 88 };ok - mh hdrlength != { 33, 55, 67, 88 };ok mh hdrlength { 33-55 };ok - mh hdrlength != { 33-55 };ok @@ -32,8 +32,8 @@ mh type != home-agent-switch-message;ok mh reserved 22;ok mh reserved != 233;ok -mh reserved 33-45;ok;mh reserved >= 33 mh reserved <= 45 -mh reserved != 33-45;ok;mh reserved < 33 mh reserved > 45 +mh reserved 33-45;ok +mh reserved != 33-45;ok mh reserved { 33, 55, 67, 88};ok - mh reserved != {33, 55, 67, 88};ok mh reserved { 33-55};ok @@ -41,8 +41,8 @@ mh reserved { 33-55};ok mh checksum 22;ok mh checksum != 233;ok -mh checksum 33-45;ok;mh checksum >= 33 mh checksum <= 45 -mh checksum != 33-45;ok;mh checksum < 33 mh checksum > 45 +mh checksum 33-45;ok +mh checksum != 33-45;ok mh checksum { 33, 55, 67, 88};ok - mh checksum != { 33, 55, 67, 88};ok mh checksum { 33-55};ok diff --git a/tests/regression/ip6/redirect.t b/tests/regression/ip6/redirect.t index 730d7339..31ffe8c9 100644 --- a/tests/regression/ip6/redirect.t +++ b/tests/regression/ip6/redirect.t @@ -40,5 +40,5 @@ ip6 saddr ::1 redirect drop;fail # redirect with sets tcp dport { 1, 2, 3, 4, 5, 6, 7, 8, 101, 202, 303, 1001, 2002, 3003} redirect;ok -ip6 daddr fe00::1-fe00::200 udp dport 53 counter packets 0 bytes 0 redirect;ok;ip6 daddr >= fe00::1 ip6 daddr <= fe00::200 udp dport 53 counter packets 0 bytes 0 redirect +ip6 daddr fe00::1-fe00::200 udp dport 53 counter packets 0 bytes 0 redirect;ok iifname eth0 ct state new,established tcp dport vmap {22 : drop, 222 : drop } redirect;ok diff --git a/tests/regression/ip6/rt.t b/tests/regression/ip6/rt.t index 76579ba5..eca47ca8 100644 --- a/tests/regression/ip6/rt.t +++ b/tests/regression/ip6/rt.t @@ -10,8 +10,8 @@ rt nexthdr icmp;ok;rt nexthdr 1 rt nexthdr != icmp;ok;rt nexthdr != 1 rt nexthdr 22;ok rt nexthdr != 233;ok -rt nexthdr 33-45;ok;rt nexthdr >= 33 rt nexthdr <= 45 -rt nexthdr != 33-45;ok;rt nexthdr < 33 rt nexthdr > 45 +rt nexthdr 33-45;ok +rt nexthdr != 33-45;ok rt nexthdr { 33, 55, 67, 88};ok - rt nexthdr != { 33, 55, 67, 88};ok rt nexthdr { 33-55};ok;rt nexthdr { 33-55} @@ -19,8 +19,8 @@ rt nexthdr { 33-55};ok;rt nexthdr { 33-55} rt hdrlength 22;ok rt hdrlength != 233;ok -rt hdrlength 33-45;ok;rt hdrlength >= 33 rt hdrlength <= 45 -rt hdrlength != 33-45;ok;rt hdrlength < 33 rt hdrlength > 45 +rt hdrlength 33-45;ok +rt hdrlength != 33-45;ok rt hdrlength { 33, 55, 67, 88};ok - rt hdrlength != { 33, 55, 67, 88};ok rt hdrlength { 33-55};ok @@ -28,8 +28,8 @@ rt hdrlength { 33-55};ok rt type 22;ok rt type != 233;ok -rt type 33-45;ok;rt type >= 33 rt type <= 45 -rt type != 33-45;ok;rt type < 33 rt type > 45 +rt type 33-45;ok +rt type != 33-45;ok rt type { 33, 55, 67, 88};ok - rt type != { 33, 55, 67, 88};ok rt type { 33-55};ok @@ -37,8 +37,8 @@ rt type { 33-55};ok rt seg-left 22;ok rt seg-left != 233;ok -rt seg-left 33-45;ok;rt seg-left >= 33 rt seg-left <= 45 -rt seg-left != 33-45;ok;rt seg-left < 33 rt seg-left > 45 +rt seg-left 33-45;ok +rt seg-left != 33-45;ok rt seg-left { 33, 55, 67, 88};ok - rt seg-left != { 33, 55, 67, 88};ok rt seg-left { 33-55};ok -- cgit v1.2.3 From 575cc4519aa177c573481f683e07c2789a2f870a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 2 Jun 2015 17:14:59 +0200 Subject: tests: regression: fix NAT tests snat can be only used from prerouting and input, and dnat from output and postrouting. ip/nat.t: ERROR: line 12: nft add rule ip test-ip4 output iifname eth0 tcp sport 23-34 snat 192.168.3.2: This rule should not have failed. Split the test file as they require different chain configuration. Signed-off-by: Pablo Neira Ayuso --- tests/regression/ip/dnat.t | 12 ++++++++++++ tests/regression/ip/nat.t | 18 ------------------ tests/regression/ip/snat.t | 12 ++++++++++++ tests/regression/ip6/dnat.t | 5 +++++ tests/regression/ip6/nat.t | 6 ------ tests/regression/ip6/snat.t | 6 ++++++ 6 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 tests/regression/ip/dnat.t delete mode 100644 tests/regression/ip/nat.t create mode 100644 tests/regression/ip/snat.t create mode 100644 tests/regression/ip6/dnat.t delete mode 100644 tests/regression/ip6/nat.t create mode 100644 tests/regression/ip6/snat.t diff --git a/tests/regression/ip/dnat.t b/tests/regression/ip/dnat.t new file mode 100644 index 00000000..78fc454d --- /dev/null +++ b/tests/regression/ip/dnat.t @@ -0,0 +1,12 @@ +*ip;test-ip4 +:prerouting;type nat hook prerouting priority 0 + +iifname "eth0" tcp dport 80-90 dnat 192.168.3.2;ok +iifname "eth0" tcp dport != 80-90 dnat 192.168.3.2;ok +iifname "eth0" tcp dport {80, 90, 23} dnat 192.168.3.2;ok +- iifname "eth0" tcp dport != {80, 90, 23} dnat 192.168.3.2;ok +- iifname "eth0" tcp dport != {80, 90, 23} dnat 192.168.3.2;ok +# BUG: invalid expression type set +# nft: src/evaluate.c:975: expr_evaluate_relational: Assertion '0' failed. + +iifname "eth0" tcp dport != 23-34 dnat 192.168.3.2;ok diff --git a/tests/regression/ip/nat.t b/tests/regression/ip/nat.t deleted file mode 100644 index 26c8cbf7..00000000 --- a/tests/regression/ip/nat.t +++ /dev/null @@ -1,18 +0,0 @@ -*ip;test-ip4 -# bug: Nat tables is not supported yet in inet table. --*inet;test-inet - -:output;type nat hook output priority 0 - -iifname "eth0" tcp dport 80-90 dnat 192.168.3.2;ok -iifname "eth0" tcp dport != 80-90 dnat 192.168.3.2;ok -iifname "eth0" tcp dport {80, 90, 23} dnat 192.168.3.2;ok -- iifname "eth0" tcp dport != {80, 90, 23} dnat 192.168.3.2;ok - -iifname eth0 tcp sport 23-34 snat 192.168.3.2;ok - -- iifname "eth0" tcp dport != {80, 90, 23} dnat 192.168.3.2;ok -# BUG: invalid expression type set -# nft: src/evaluate.c:975: expr_evaluate_relational: Assertion '0' failed. - -iifname "eth0" tcp dport != 23-34 dnat 192.168.3.2;ok diff --git a/tests/regression/ip/snat.t b/tests/regression/ip/snat.t new file mode 100644 index 00000000..1caf7c76 --- /dev/null +++ b/tests/regression/ip/snat.t @@ -0,0 +1,12 @@ +*ip;test-ip4 +:postrouting;type nat hook postrouting priority 0 + +iifname "eth0" tcp dport 80-90 snat 192.168.3.2;ok +iifname "eth0" tcp dport != 80-90 snat 192.168.3.2;ok +iifname "eth0" tcp dport {80, 90, 23} snat 192.168.3.2;ok +- iifname "eth0" tcp dport != {80, 90, 23} snat 192.168.3.2;ok +- iifname "eth0" tcp dport != {80, 90, 23} snat 192.168.3.2;ok +# BUG: invalid expression type set +# nft: src/evaluate.c:975: expr_evaluate_relational: Assertion '0' failed. + +iifname "eth0" tcp dport != 23-34 snat 192.168.3.2;ok diff --git a/tests/regression/ip6/dnat.t b/tests/regression/ip6/dnat.t new file mode 100644 index 00000000..a2555c72 --- /dev/null +++ b/tests/regression/ip6/dnat.t @@ -0,0 +1,5 @@ +*ip6;test-ip6 +:prerouting;type nat hook prerouting priority 0 + +tcp dport 80-90 dnat 2001:838:35f:1::-2001:838:35f:2:: :80-100;ok +tcp dport 80-90 dnat 2001:838:35f:1::-2001:838:35f:2:: :100;ok diff --git a/tests/regression/ip6/nat.t b/tests/regression/ip6/nat.t deleted file mode 100644 index 2fb4ac81..00000000 --- a/tests/regression/ip6/nat.t +++ /dev/null @@ -1,6 +0,0 @@ -*ip6;test-ip6 -- *inet;test-inet -:input;type nat hook input priority 0 - -tcp dport 80-90 dnat 2001:838:35f:1::-2001:838:35f:2:: :80-100;ok -tcp dport 80-90 dnat 2001:838:35f:1::-2001:838:35f:2:: :100;ok diff --git a/tests/regression/ip6/snat.t b/tests/regression/ip6/snat.t new file mode 100644 index 00000000..73452752 --- /dev/null +++ b/tests/regression/ip6/snat.t @@ -0,0 +1,6 @@ +*ip6;test-ip6 +- *inet;test-inet +:postrouting;type nat hook postrouting priority 0 + +tcp dport 80-90 snat 2001:838:35f:1::-2001:838:35f:2:: :80-100;ok +tcp dport 80-90 snat 2001:838:35f:1::-2001:838:35f:2:: :100;ok -- cgit v1.2.3