diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-06-04 20:57:20 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2015-06-04 20:57:20 +0200 |
commit | 7c357801945977a7a7759ead56b4cb320673219b (patch) | |
tree | d90c08dcd9286f37b9cfe24a4eabb5f73fb454de | |
parent | 933fb6b993d9ddd9a96d15edbea393dc56c932e3 (diff) | |
parent | 575cc4519aa177c573481f683e07c2789a2f870a (diff) |
Merge branch 'next-4.1'
45 files changed, 845 insertions, 355 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/include/expression.h b/include/expression.h index 7477c3e6..010cb954 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, @@ -230,6 +232,13 @@ struct expr { struct set *set; }; struct { + /* EXPR_SET_ELEM */ + struct expr *key; + uint64_t timeout; + uint64_t expiration; + const char *comment; + }; + struct { /* EXPR_UNARY */ struct expr *arg; }; @@ -363,6 +372,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/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 832bc46d..0e964439 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) @@ -283,12 +289,18 @@ 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) + * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY) */ 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_USERDATA, __NFTA_SET_ELEM_MAX }; #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1) @@ -504,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/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/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/datatype.c b/src/datatype.c index c93f76a3..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; @@ -775,8 +773,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 +781,6 @@ static void time_type_print(const struct expr *expr) printf("%"PRIu64"m", minutes); if (seconds > 0) printf("%"PRIu64"s", seconds); - - printf("\""); } enum { @@ -805,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; @@ -815,76 +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; - if (h > 23) { - return error(&sym->location, - "Hour needs to be 0-23"); - } 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; - if (m > 59) { - return error(&sym->location, - "Minute needs to be 0-59"); - } 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; - if (s > 59) { - return error(&sym->location, - "second needs to be 0-59"); - } 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"); diff --git a/src/evaluate.c b/src/evaluate.c index 7ecb7939..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", @@ -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: @@ -1646,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 @@ -1680,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); } @@ -1722,6 +1763,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/expression.c b/src/expression.c index 5b848da7..3edc5501 100644 --- a/src/expression.c +++ b/src/expression.c @@ -886,6 +886,44 @@ 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); + if (expr->timeout) { + printf(" timeout "); + time_print(expr->timeout / 1000); + } + if (expr->expiration) { + 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); +} + +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 +935,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 +959,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..d31387f8 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,34 @@ 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 (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); + 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, @@ -1063,6 +1074,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); @@ -1126,6 +1142,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); @@ -1368,7 +1389,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 +1397,31 @@ 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); - - if (expr->dtype->basetype != NULL && - expr->dtype->basetype->type == TYPE_BITMASK) - expr = bitmask_expr_to_binops(expr); + 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); + + 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 (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/netlink_delinearize.c b/src/netlink_delinearize.c index b23d5875..0645ea8b 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -692,6 +692,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, @@ -715,6 +749,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) @@ -743,6 +778,7 @@ struct rule_pp_ctx { struct proto_ctx pctx; enum proto_bases pbase; struct stmt *pdep; + struct stmt *stmt; }; /* @@ -791,48 +827,57 @@ static void integer_type_postprocess(struct expr *expr) } } -static void payload_match_postprocess(struct rule_pp_ctx *ctx, - struct stmt *stmt, 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(&stmt->location, nexpr); - list_add_tail(&nstmt->list, &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); + if (expr->right->ops->type == EXPR_VALUE) { + payload_match_expand(ctx, expr); + break; } - list_del(&stmt->list); - stmt_free(stmt); - break; + /* Fall through */ 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); @@ -841,7 +886,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; @@ -852,7 +896,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, @@ -936,8 +981,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; @@ -945,29 +989,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); @@ -975,19 +1019,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); @@ -1028,8 +1072,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, &expr->key); break; case EXPR_SET_REF: case EXPR_EXTHDR: @@ -1042,18 +1089,19 @@ 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) { + 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: @@ -1061,8 +1109,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: @@ -1079,8 +1127,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): @@ -1100,44 +1148,119 @@ static void stmt_reject_postprocess(struct rule_pp_ctx rctx, struct stmt *stmt) } } +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); 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); + stmt_expr_postprocess(&rctx, prev); 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->set.key); break; default: break; } + prev = rctx.stmt; } } diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 0a0b6864..fbc6ae12 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -529,6 +529,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); } @@ -799,6 +801,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) { @@ -827,6 +851,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 b86381d9..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" @@ -201,6 +202,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" @@ -396,6 +399,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type <string> identifier string comment_spec %destructor { xfree($$); } identifier string comment_spec +%type <val> time_spec + %type <val> type_identifier %type <datatype> data_type @@ -452,6 +457,9 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type <stmt> queue_stmt queue_stmt_alloc %destructor { stmt_free($$); } queue_stmt queue_stmt_alloc %type <val> queue_stmt_flags queue_stmt_flag +%type <stmt> set_stmt +%destructor { stmt_free($$); } set_stmt +%type <val> set_stmt_op %type <expr> symbol_expr verdict_expr integer_expr %destructor { expr_free($$); } symbol_expr verdict_expr integer_expr @@ -468,8 +476,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %destructor { expr_free($$); } prefix_expr range_expr wildcard_expr %type <expr> list_expr %destructor { expr_free($$); } list_expr -%type <expr> concat_expr map_lhs_expr -%destructor { expr_free($$); } concat_expr map_lhs_expr +%type <expr> concat_expr +%destructor { expr_free($$); } concat_expr %type <expr> map_expr %destructor { expr_free($$); } map_expr @@ -482,6 +490,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type <expr> set_expr set_list_expr set_list_member_expr %destructor { expr_free($$); } set_expr set_list_expr set_list_member_expr +%type <expr> 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> expr initializer_expr %destructor { expr_free($$); } expr initializer_expr @@ -940,6 +950,16 @@ set_block : /* empty */ { $$ = $<set>-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; @@ -957,6 +977,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 */ @@ -1093,6 +1114,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 ; @@ -1236,6 +1271,7 @@ stmt : verdict_stmt | ct_stmt | masq_stmt | redir_stmt + | set_stmt ; verdict_stmt : verdict_expr @@ -1281,13 +1317,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_elem_expr COLON verdict_expr opt_newline { $$ = mapping_expr_alloc(&@$, $2, $4); } ; - counter_stmt : counter_stmt_alloc | counter_stmt_alloc counter_args @@ -1549,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); @@ -1702,10 +1750,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); @@ -1713,9 +1757,9 @@ map_expr : concat_expr MAP expr ; expr : concat_expr + | multiton_expr | set_expr | map_expr - | multiton_expr ; set_expr : '{' set_list_expr '}' @@ -1738,20 +1782,55 @@ 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_elem_expr opt_newline { - $$ = mapping_expr_alloc(&@$, $2, $4); + $$ = $2; } - | opt_newline map_lhs_expr COLON verdict_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_elem_options + ; + +set_elem_expr_alloc : set_lhs_expr + { + $$ = set_elem_expr_alloc(&@1, $1); + } + ; + +set_elem_options : set_elem_option + { + $<expr>$ = $<expr>0; + } + | set_elem_options set_elem_option + ; + +set_elem_option : TIMEOUT time_spec + { + $<expr>0->timeout = $2 * 1000; + } + | COMMENT string + { + $<expr>0->comment = $2; + } + ; + +set_lhs_expr : concat_expr + | multiton_expr + ; + +set_rhs_expr : concat_expr + | verdict_expr + ; + initializer_expr : expr | list_expr ; @@ -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 73c4f8b1..985ea2a3 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})) @@ -255,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; } @@ -269,6 +272,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; } @@ -457,6 +462,11 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) return STRING; } +{timestring} { + yylval->string = xstrdup(yytext); + return STRING; + } + {decstring} { errno = 0; yylval->val = strtoull(yytext, NULL, 0); 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); 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); +} 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/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/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 deleted file mode 100644 index 5afe823a..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 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 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 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 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/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/nat.t b/tests/regression/ip6/dnat.t index 2fb4ac81..a2555c72 100644 --- a/tests/regression/ip6/nat.t +++ b/tests/regression/ip6/dnat.t @@ -1,6 +1,5 @@ *ip6;test-ip6 -- *inet;test-inet -:input;type nat hook input priority 0 +: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/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 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 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): |