diff --git a/doc/primary-expression.txt b/doc/primary-expression.txt index a5cab9d..5473d59 100644 --- a/doc/primary-expression.txt +++ b/doc/primary-expression.txt @@ -36,13 +36,6 @@ add such a rule, it will stop matching if the interface gets renamed and it will match again in case interface gets deleted and later a new interface with the same name is created. -Like with iptables, wildcard matching on interface name prefixes is available for -*iifname* and *oifname* matches by appending an asterisk (*) character. Note -however that unlike iptables, nftables does not accept interface names -consisting of the wildcard character only - users are supposed to just skip -those always matching expressions. In order to match on literal asterisk -character, one may escape it using backslash (\). - .Meta expression types [options="header"] |================== diff --git a/doc/statements.txt b/doc/statements.txt index 749533a..3b82436 100644 --- a/doc/statements.txt +++ b/doc/statements.txt @@ -262,20 +262,6 @@ table inet raw { ct event set new,related,destroy -------------------------------------- -NOTRACK STATEMENT -~~~~~~~~~~~~~~~~~ -The notrack statement allows to disable connection tracking for certain -packets. - -[verse] -*notrack* - -Note that for this statement to be effective, it has to be applied to packets -before a conntrack lookup happens. Therefore, it needs to sit in a chain with -either prerouting or output hook and a hook priority of -300 or less. - -See SYNPROXY STATEMENT for an example usage. - META STATEMENT ~~~~~~~~~~~~~~ A meta statement sets the value of a meta expression. The existing meta fields diff --git a/include/expression.h b/include/expression.h index 2e41aa0..717b675 100644 --- a/include/expression.h +++ b/include/expression.h @@ -256,8 +256,6 @@ struct expr { struct list_head expressions; unsigned int size; uint32_t set_flags; - uint8_t field_len[NFT_REG32_COUNT]; - uint8_t field_count; }; struct { /* EXPR_SET_REF */ @@ -460,7 +458,6 @@ extern int set_to_intervals(struct list_head *msgs, struct set *set, struct expr *init, bool add, unsigned int debug_mask, bool merge, struct output_ctx *octx); -extern void concat_range_aggregate(struct expr *set); extern void interval_map_decompose(struct expr *set); extern struct expr *get_set_intervals(const struct set *set, diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 9b54a86..ed8881a 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -48,7 +48,6 @@ enum nft_registers { #define NFT_REG_SIZE 16 #define NFT_REG32_SIZE 4 -#define NFT_REG32_COUNT (NFT_REG32_15 - NFT_REG32_00 + 1) /** * enum nft_verdicts - nf_tables internal verdicts @@ -274,7 +273,6 @@ enum nft_rule_compat_attributes { * @NFT_SET_TIMEOUT: set uses timeouts * @NFT_SET_EVAL: set can be updated from the evaluation path * @NFT_SET_OBJECT: set contains stateful objects - * @NFT_SET_CONCAT: set contains a concatenation */ enum nft_set_flags { NFT_SET_ANONYMOUS = 0x1, @@ -284,7 +282,6 @@ enum nft_set_flags { NFT_SET_TIMEOUT = 0x10, NFT_SET_EVAL = 0x20, NFT_SET_OBJECT = 0x40, - NFT_SET_CONCAT = 0x80, }; /** @@ -302,29 +299,15 @@ enum nft_set_policies { * enum nft_set_desc_attributes - set element description * * @NFTA_SET_DESC_SIZE: number of elements in set (NLA_U32) - * @NFTA_SET_DESC_CONCAT: description of field concatenation (NLA_NESTED) */ enum nft_set_desc_attributes { NFTA_SET_DESC_UNSPEC, NFTA_SET_DESC_SIZE, - NFTA_SET_DESC_CONCAT, __NFTA_SET_DESC_MAX }; #define NFTA_SET_DESC_MAX (__NFTA_SET_DESC_MAX - 1) /** - * enum nft_set_field_attributes - attributes of concatenated fields - * - * @NFTA_SET_FIELD_LEN: length of single field, in bits (NLA_U32) - */ -enum nft_set_field_attributes { - NFTA_SET_FIELD_UNSPEC, - NFTA_SET_FIELD_LEN, - __NFTA_SET_FIELD_MAX -}; -#define NFTA_SET_FIELD_MAX (__NFTA_SET_FIELD_MAX - 1) - -/** * enum nft_set_attributes - nf_tables set netlink attributes * * @NFTA_SET_TABLE: table name (NLA_STRING) @@ -385,7 +368,6 @@ enum nft_set_elem_flags { * @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY) * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes) * @NFTA_SET_ELEM_OBJREF: stateful object reference (NLA_STRING) - * @NFTA_SET_ELEM_KEY_END: closing key value (NLA_NESTED: nft_data) */ enum nft_set_elem_attributes { NFTA_SET_ELEM_UNSPEC, @@ -398,7 +380,6 @@ enum nft_set_elem_attributes { NFTA_SET_ELEM_EXPR, NFTA_SET_ELEM_PAD, NFTA_SET_ELEM_OBJREF, - NFTA_SET_ELEM_KEY_END, __NFTA_SET_ELEM_MAX }; #define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1) diff --git a/include/rule.h b/include/rule.h index 626973e..0b2eba3 100644 --- a/include/rule.h +++ b/include/rule.h @@ -290,9 +290,7 @@ extern struct rule *rule_lookup_by_index(const struct chain *chain, * @rg_cache: cached range element (left) * @policy: set mechanism policy * @automerge: merge adjacents and overlapping elements, if possible - * @desc.size: count of set elements - * @desc.field_len: length of single concatenated fields, bytes - * @desc.field_count: count of concatenated fields + * @desc: set mechanism desc */ struct set { struct list_head list; @@ -312,8 +310,6 @@ struct set { bool automerge; struct { uint32_t size; - uint8_t field_len[NFT_REG32_COUNT]; - uint8_t field_count; } desc; }; @@ -367,16 +363,6 @@ static inline bool set_is_meter(uint32_t set_flags) return set_is_anonymous(set_flags) && (set_flags & NFT_SET_EVAL); } -static inline bool set_is_interval(uint32_t set_flags) -{ - return set_flags & NFT_SET_INTERVAL; -} - -static inline bool set_is_non_concat_range(struct set *s) -{ - return (s->flags & NFT_SET_INTERVAL) && s->desc.field_count <= 1; -} - #include struct counter { diff --git a/src/cache.c b/src/cache.c index 05f0d68..0c28a28 100644 --- a/src/cache.c +++ b/src/cache.c @@ -138,10 +138,8 @@ unsigned int cache_evaluate(struct nft_ctx *nft, struct list_head *cmds) case CMD_GET: flags = evaluate_cache_get(cmd, flags); break; - case CMD_RESET: - flags |= NFT_CACHE_TABLE; - break; case CMD_LIST: + case CMD_RESET: case CMD_EXPORT: case CMD_MONITOR: flags |= NFT_CACHE_FULL; diff --git a/src/evaluate.c b/src/evaluate.c index f66251b..a865902 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -136,11 +136,6 @@ static int byteorder_conversion(struct eval_ctx *ctx, struct expr **expr, if ((*expr)->byteorder == byteorder) return 0; - - /* Conversion for EXPR_CONCAT is handled for single composing ranges */ - if ((*expr)->etype == EXPR_CONCAT) - return 0; - if (expr_basetype(*expr)->type != TYPE_INTEGER) return expr_error(ctx->msgs, *expr, "Byteorder mismatch: expected %s, got %s", @@ -1221,8 +1216,6 @@ 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) { - unsigned dsize_bytes; - if (expr_is_constant(*expr) && dtype && off == 0) return expr_binary_error(ctx->msgs, i, *expr, "unexpected concat component, " @@ -1247,9 +1240,6 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr, i->dtype->name); ntype = concat_subtype_add(ntype, i->dtype->type); - - dsize_bytes = div_round_up(i->dtype->size, BITS_PER_BYTE); - (*expr)->field_len[(*expr)->field_count++] = dsize_bytes; } (*expr)->flags |= flags; @@ -1360,16 +1350,10 @@ static int expr_evaluate_set(struct eval_ctx *ctx, struct expr **expr) set->size += i->size - 1; set->set_flags |= i->set_flags; expr_free(i); - } else if (!expr_is_singleton(i)) { + } else if (!expr_is_singleton(i)) set->set_flags |= NFT_SET_INTERVAL; - if (i->key->etype == EXPR_CONCAT) - set->set_flags |= NFT_SET_CONCAT; - } } - if (ctx->set && (ctx->set->flags & NFT_SET_CONCAT)) - set->set_flags |= NFT_SET_CONCAT; - set->set_flags |= NFT_SET_CONSTANT; datatype_set(set, ctx->ectx.dtype); @@ -3337,13 +3321,9 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) "specified in %s definition", set->key->dtype->name, type); } - - if (set->flags & NFT_SET_INTERVAL && set->key->etype == EXPR_CONCAT) { - memcpy(&set->desc.field_len, &set->key->field_len, - sizeof(set->desc.field_len)); - set->desc.field_count = set->key->field_count; - set->flags |= NFT_SET_CONCAT; - } + if (set->flags & NFT_SET_INTERVAL && + set->key->etype == EXPR_CONCAT) + return set_error(ctx, set, "concatenated types not supported in interval sets"); if (set_is_datamap(set->flags)) { if (set->datatype == NULL) diff --git a/src/main.c b/src/main.c index 6ab1b89..fde8b15 100644 --- a/src/main.c +++ b/src/main.c @@ -46,7 +46,7 @@ enum opt_vals { OPT_TERSE = 't', OPT_INVALID = '?', }; -#define OPTSTRING "+hvd:cf:iI:jvnsNaeSupypTt" +#define OPTSTRING "hvcf:iI:jvnsNaeSupypTt" static const struct option options[] = { { @@ -202,49 +202,6 @@ static const struct { }, }; -static void nft_options_error(int argc, char * const argv[], int pos) -{ - int i; - - fprintf(stderr, "Error: syntax error, options must be specified before commands\n"); - for (i = 0; i < argc; i++) - fprintf(stderr, "%s ", argv[i]); - printf("\n%4c%*s\n", '^', pos - 2, "~~"); -} - -static bool nft_options_check(int argc, char * const argv[]) -{ - bool skip = false, nonoption = false; - int pos = 0, i; - - for (i = 1; i < argc; i++) { - pos += strlen(argv[i - 1]) + 1; - if (argv[i][0] == '{') { - break; - } else if (skip) { - skip = false; - continue; - } else if (argv[i][0] == '-') { - if (nonoption) { - nft_options_error(argc, argv, pos); - return false; - } else if (argv[i][1] == 'd' || - argv[i][1] == 'I' || - argv[i][1] == 'f' || - !strcmp(argv[i], "--debug") || - !strcmp(argv[i], "--includepath") || - !strcmp(argv[i], "--file")) { - skip = true; - continue; - } - } else if (argv[i][0] != '-') { - nonoption = true; - } - } - - return true; -} - int main(int argc, char * const *argv) { char *buf = NULL, *filename = NULL; @@ -254,9 +211,6 @@ int main(int argc, char * const *argv) unsigned int len; int i, val, rc; - if (!nft_options_check(argc, argv)) - exit(EXIT_FAILURE); - nft = nft_ctx_new(NFT_CTX_DEFAULT); while (1) { diff --git a/src/mnl.c b/src/mnl.c index 221ee05..aa5b0b4 100644 --- a/src/mnl.c +++ b/src/mnl.c @@ -881,13 +881,6 @@ int mnl_nft_set_add(struct netlink_ctx *ctx, const struct cmd *cmd, set->automerge)) memory_allocation_error(); - if (set->desc.field_len[0]) { - nftnl_set_set_data(nls, NFTNL_SET_DESC_CONCAT, - set->desc.field_len, - set->desc.field_count * - sizeof(set->desc.field_len[0])); - } - nftnl_set_set_data(nls, NFTNL_SET_USERDATA, nftnl_udata_buf_data(udbuf), nftnl_udata_buf_len(udbuf)); nftnl_udata_buf_free(udbuf); diff --git a/src/monitor.c b/src/monitor.c index fb803cf..ea0393c 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -500,7 +500,7 @@ static int netlink_events_obj_cb(const struct nlmsghdr *nlh, int type, static void rule_map_decompose_cb(struct set *s, void *data) { - if (set_is_interval(s->flags) && set_is_anonymous(s->flags)) + if (s->flags & NFT_SET_INTERVAL) interval_map_decompose(s->init); } diff --git a/src/netlink.c b/src/netlink.c index e0ba903..486e124 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -98,11 +98,10 @@ struct nftnl_expr *alloc_nft_expr(const char *name) static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set, const struct expr *expr) { - const struct expr *elem, *data; + const struct expr *elem, *key, *data; struct nftnl_set_elem *nlse; struct nft_data_linearize nld; struct nftnl_udata_buf *udbuf = NULL; - struct expr *key; nlse = nftnl_set_elem_alloc(); if (nlse == NULL) @@ -120,16 +119,6 @@ static struct nftnl_set_elem *alloc_nftnl_setelem(const struct expr *set, netlink_gen_data(key, &nld); nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY, &nld.value, nld.len); - - if (set->set_flags & NFT_SET_INTERVAL && expr->key->field_count > 1) { - key->flags |= EXPR_F_INTERVAL_END; - netlink_gen_data(key, &nld); - key->flags &= ~EXPR_F_INTERVAL_END; - - nftnl_set_elem_set(nlse, NFTNL_SET_ELEM_KEY_END, &nld.value, - nld.len); - } - if (elem->timeout) nftnl_set_elem_set_u64(nlse, NFTNL_SET_ELEM_TIMEOUT, elem->timeout); @@ -197,58 +186,28 @@ void netlink_gen_raw_data(const mpz_t value, enum byteorder byteorder, data->len = len; } -static int netlink_export_pad(unsigned char *data, const mpz_t v, - const struct expr *i) -{ - mpz_export_data(data, v, i->byteorder, - div_round_up(i->len, BITS_PER_BYTE)); - - return netlink_padded_len(i->len) / BITS_PER_BYTE; -} - -static int netlink_gen_concat_data_expr(int end, const struct expr *i, - unsigned char *data) -{ - switch (i->etype) { - case EXPR_RANGE: - i = end ? i->right : i->left; - break; - case EXPR_PREFIX: - if (end) { - int count; - mpz_t v; - - mpz_init_bitmask(v, i->len - i->prefix_len); - mpz_add(v, i->prefix->value, v); - count = netlink_export_pad(data, v, i); - mpz_clear(v); - return count; - } - return netlink_export_pad(data, i->prefix->value, i); - case EXPR_VALUE: - break; - default: - BUG("invalid expression type '%s' in set", expr_ops(i)->name); - } - - return netlink_export_pad(data, i->value, i); -} - static void netlink_gen_concat_data(const struct expr *expr, struct nft_data_linearize *nld) { - unsigned int len = expr->len / BITS_PER_BYTE, offset = 0; - int end = expr->flags & EXPR_F_INTERVAL_END; - unsigned char data[len]; const struct expr *i; + unsigned int len, offset; + + len = expr->len / BITS_PER_BYTE; + if (1) { + unsigned char data[len]; + + memset(data, 0, sizeof(data)); + offset = 0; + list_for_each_entry(i, &expr->expressions, list) { + assert(i->etype == EXPR_VALUE); + mpz_export_data(data + offset, i->value, i->byteorder, + div_round_up(i->len, BITS_PER_BYTE)); + offset += netlink_padded_len(i->len) / BITS_PER_BYTE; + } - memset(data, 0, len); - - list_for_each_entry(i, &expr->expressions, list) - offset += netlink_gen_concat_data_expr(end, i, data + offset); - - memcpy(nld->value, data, len); - nld->len = len; + memcpy(nld->value, data, len); + nld->len = len; + } } static void netlink_gen_constant_data(const struct expr *expr, @@ -713,17 +672,6 @@ struct set *netlink_delinearize_set(struct netlink_ctx *ctx, if (nftnl_set_is_set(nls, NFTNL_SET_DESC_SIZE)) set->desc.size = nftnl_set_get_u32(nls, NFTNL_SET_DESC_SIZE); - if (nftnl_set_is_set(nls, NFTNL_SET_DESC_CONCAT)) { - uint32_t len = NFT_REG32_COUNT; - const uint8_t *data; - - data = nftnl_set_get_data(nls, NFTNL_SET_DESC_CONCAT, &len); - if (data) { - memcpy(set->desc.field_len, data, len); - set->desc.field_count = len; - } - } - return set; } @@ -853,7 +801,6 @@ int netlink_delinearize_setelem(struct nftnl_set_elem *nlse, if (nftnl_set_elem_is_set(nlse, NFTNL_SET_ELEM_FLAGS)) flags = nftnl_set_elem_get_u32(nlse, NFTNL_SET_ELEM_FLAGS); -key_end: key = netlink_alloc_value(&netlink_location, &nld); datatype_set(key, set->key->dtype); key->byteorder = set->key->byteorder; @@ -922,15 +869,6 @@ key_end: } out: compound_expr_add(set->init, expr); - - if (!(flags & NFT_SET_ELEM_INTERVAL_END) && - nftnl_set_elem_is_set(nlse, NFTNL_SET_ELEM_KEY_END)) { - flags |= NFT_SET_ELEM_INTERVAL_END; - nld.value = nftnl_set_elem_get(nlse, NFTNL_SET_ELEM_KEY_END, - &nld.len); - goto key_end; - } - return 0; } @@ -969,16 +907,15 @@ int netlink_list_setelems(struct netlink_ctx *ctx, const struct handle *h, set->init = set_expr_alloc(&internal_location, set); nftnl_set_elem_foreach(nls, list_setelem_cb, ctx); - if (set->flags & NFT_SET_INTERVAL && set->desc.field_count > 1) - concat_range_aggregate(set->init); - else if (set->flags & NFT_SET_INTERVAL) - interval_map_decompose(set->init); - else + if (!(set->flags & NFT_SET_INTERVAL)) list_expr_sort(&ctx->set->init->expressions); nftnl_set_free(nls); ctx->set = NULL; + if (set->flags & NFT_SET_INTERVAL) + interval_map_decompose(set->init); + return 0; } @@ -987,7 +924,6 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, struct set *set, struct expr *init) { struct nftnl_set *nls, *nls_out = NULL; - int err = 0; nls = nftnl_set_alloc(); if (nls == NULL) @@ -1011,18 +947,18 @@ int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, set->init = set_expr_alloc(loc, set); nftnl_set_elem_foreach(nls_out, list_setelem_cb, ctx); - if (set->flags & NFT_SET_INTERVAL && set->desc.field_count > 1) - concat_range_aggregate(set->init); - else if (set->flags & NFT_SET_INTERVAL) - err = get_set_decompose(table, set); - else + if (!(set->flags & NFT_SET_INTERVAL)) list_expr_sort(&ctx->set->init->expressions); nftnl_set_free(nls); nftnl_set_free(nls_out); ctx->set = NULL; - return err; + if (set->flags & NFT_SET_INTERVAL && + get_set_decompose(table, set) < 0) + return -1; + + return 0; } void netlink_dump_obj(struct nftnl_obj *nln, struct netlink_ctx *ctx) diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c index 88dbd5a..154353b 100644 --- a/src/netlink_delinearize.c +++ b/src/netlink_delinearize.c @@ -274,7 +274,7 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx, { struct nft_data_delinearize nld; enum nft_registers sreg; - struct expr *expr, *left, *right, *tmp; + struct expr *expr, *left, *right; enum ops op; sreg = netlink_parse_register(nle, NFTNL_EXPR_CMP_SREG); @@ -291,26 +291,19 @@ static void netlink_parse_cmp(struct netlink_parse_ctx *ctx, if (left->len > right->len && expr_basetype(left) != &string_type) { - netlink_error(ctx, loc, "Relational expression size mismatch"); - goto err_free; + return netlink_error(ctx, loc, "Relational expression size mismatch"); } else if (left->len > 0 && left->len < right->len) { expr_free(left); left = netlink_parse_concat_expr(ctx, loc, sreg, right->len); if (left == NULL) - goto err_free; - tmp = netlink_parse_concat_data(ctx, loc, sreg, right->len, right); - if (tmp == NULL) - goto err_free; - expr_free(right); - right = tmp; + return; + right = netlink_parse_concat_data(ctx, loc, sreg, right->len, right); + if (right == NULL) + return; } expr = relational_expr_alloc(loc, op, left, right); ctx->stmt = expr_stmt_alloc(loc, expr); - return; -err_free: - expr_free(left); - expr_free(right); } static void netlink_parse_lookup(struct netlink_parse_ctx *ctx, @@ -2037,7 +2030,7 @@ static bool __expr_postprocess_string(struct expr **exprp) static struct expr *expr_postprocess_string(struct expr *expr) { - struct expr *mask, *out; + struct expr *mask; assert(expr_basetype(expr)->type == TYPE_STRING); if (__expr_postprocess_string(&expr)) @@ -2047,9 +2040,7 @@ static struct expr *expr_postprocess_string(struct expr *expr) BYTEORDER_HOST_ENDIAN, expr->len + BITS_PER_BYTE, NULL); mpz_init_bitmask(mask->value, expr->len); - out = string_wildcard_expr_alloc(&expr->location, mask, expr); - expr_free(mask); - return out; + return string_wildcard_expr_alloc(&expr->location, mask, expr); } static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp) diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index cb1b7fe..498326d 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -941,7 +941,7 @@ static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx, nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_CSUM_OFFSET, csum_off / BITS_PER_BYTE); } - if (expr->payload.base == PROTO_BASE_NETWORK_HDR && desc && + if (expr->payload.base == PROTO_BASE_NETWORK_HDR && payload_needs_l4csum_update_pseudohdr(expr, desc)) nftnl_expr_set_u32(nle, NFTNL_EXPR_PAYLOAD_FLAGS, NFT_PAYLOAD_L4CSUM_PSEUDOHDR); diff --git a/src/parser_bison.y b/src/parser_bison.y index ea83f52..707f467 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -102,25 +102,6 @@ static void location_update(struct location *loc, struct location *rhs, int n) } } -static struct expr *handle_concat_expr(const struct location *loc, - struct expr *expr, - struct expr *expr_l, struct expr *expr_r, - struct location loc_rhs[3]) -{ - if (expr->etype != EXPR_CONCAT) { - expr = concat_expr_alloc(loc); - compound_expr_add(expr, expr_l); - } else { - location_update(&expr_r->location, loc_rhs, 2); - - expr = expr_l; - expr->location = *loc; - } - - compound_expr_add(expr, expr_r); - return expr; -} - #define YYLLOC_DEFAULT(Current, Rhs, N) location_update(&Current, Rhs, N) #define symbol_value(loc, str) \ @@ -1897,12 +1878,20 @@ data_type_atom_expr : type_identifier data_type_expr : data_type_atom_expr | data_type_expr DOT data_type_atom_expr { - struct location rhs[] = { - [1] = @2, - [2] = @3, - }; - - $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + if ($1->etype != EXPR_CONCAT) { + $$ = concat_expr_alloc(&@$); + compound_expr_add($$, $1); + } else { + struct location rhs[] = { + [1] = @2, + [2] = @3, + }; + location_update(&$3->location, rhs, 2); + + $$ = $1; + $$->location = @$; + } + compound_expr_add($$, $3); } ; @@ -3003,12 +2992,20 @@ basic_stmt_expr : inclusive_or_stmt_expr concat_stmt_expr : basic_stmt_expr | concat_stmt_expr DOT primary_stmt_expr { - struct location rhs[] = { - [1] = @2, - [2] = @3, - }; - - $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + if ($$->etype != EXPR_CONCAT) { + $$ = concat_expr_alloc(&@$); + compound_expr_add($$, $1); + } else { + struct location rhs[] = { + [1] = @2, + [2] = @3, + }; + location_update(&$3->location, rhs, 2); + + $$ = $1; + $$->location = @$; + } + compound_expr_add($$, $3); } ; @@ -3528,12 +3525,20 @@ basic_expr : inclusive_or_expr concat_expr : basic_expr | concat_expr DOT basic_expr { - struct location rhs[] = { - [1] = @2, - [2] = @3, - }; - - $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + if ($$->etype != EXPR_CONCAT) { + $$ = concat_expr_alloc(&@$); + compound_expr_add($$, $1); + } else { + struct location rhs[] = { + [1] = @2, + [2] = @3, + }; + location_update(&$3->location, rhs, 2); + + $$ = $1; + $$->location = @$; + } + compound_expr_add($$, $3); } ; @@ -3551,6 +3556,7 @@ range_rhs_expr : basic_rhs_expr DASH basic_rhs_expr multiton_rhs_expr : prefix_rhs_expr | range_rhs_expr + | wildcard_expr ; map_expr : concat_expr MAP rhs_expr @@ -3644,7 +3650,7 @@ set_elem_option : TIMEOUT time_spec ; set_lhs_expr : concat_rhs_expr - | wildcard_expr + | multiton_rhs_expr ; set_rhs_expr : concat_rhs_expr @@ -3897,7 +3903,7 @@ list_rhs_expr : basic_rhs_expr COMMA basic_rhs_expr ; rhs_expr : concat_rhs_expr { $$ = $1; } - | wildcard_expr { $$ = $1; } + | multiton_rhs_expr { $$ = $1; } | set_expr { $$ = $1; } | set_ref_symbol_expr { $$ = $1; } ; @@ -3938,24 +3944,22 @@ basic_rhs_expr : inclusive_or_rhs_expr ; concat_rhs_expr : basic_rhs_expr - | multiton_rhs_expr - | concat_rhs_expr DOT multiton_rhs_expr + | concat_rhs_expr DOT basic_rhs_expr { - struct location rhs[] = { - [1] = @2, - [2] = @3, - }; - - $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); - } - | concat_rhs_expr DOT basic_rhs_expr - { - struct location rhs[] = { - [1] = @2, - [2] = @3, - }; - - $$ = handle_concat_expr(&@$, $$, $1, $3, rhs); + if ($$->etype != EXPR_CONCAT) { + $$ = concat_expr_alloc(&@$); + compound_expr_add($$, $1); + } else { + struct location rhs[] = { + [1] = @2, + [2] = @3, + }; + location_update(&$3->location, rhs, 2); + + $$ = $1; + $$->location = @$; + } + compound_expr_add($$, $3); } ; diff --git a/src/parser_json.c b/src/parser_json.c index ce8e566..031930e 100644 --- a/src/parser_json.c +++ b/src/parser_json.c @@ -40,7 +40,6 @@ #define CTX_F_MANGLE (1 << 5) #define CTX_F_SES (1 << 6) /* set_elem_expr_stmt */ #define CTX_F_MAP (1 << 7) /* LHS of map_expr */ -#define CTX_F_CONCAT (1 << 8) /* inside concat_expr */ struct json_ctx { struct input_descriptor indesc; @@ -100,7 +99,6 @@ static struct expr *json_parse_primary_expr(struct json_ctx *ctx, json_t *root); static struct expr *json_parse_set_rhs_expr(struct json_ctx *ctx, json_t *root); static struct expr *json_parse_set_elem_expr_stmt(struct json_ctx *ctx, json_t *root); static struct expr *json_parse_map_lhs_expr(struct json_ctx *ctx, json_t *root); -static struct expr *json_parse_concat_elem_expr(struct json_ctx *ctx, json_t *root); static struct stmt *json_parse_stmt(struct json_ctx *ctx, json_t *root); /* parsing helpers */ @@ -1060,7 +1058,7 @@ static struct expr *json_parse_concat_expr(struct json_ctx *ctx, } json_array_foreach(root, index, value) { - tmp = json_parse_concat_elem_expr(ctx, value); + tmp = json_parse_primary_expr(ctx, value); if (!tmp) { json_error(ctx, "Parsing expr at index %zd failed.", index); expr_free(expr); @@ -1356,28 +1354,28 @@ static struct expr *json_parse_expr(struct json_ctx *ctx, json_t *root) { "set", json_parse_set_expr, CTX_F_RHS | CTX_F_STMT }, /* allow this as stmt expr because that allows set references */ { "map", json_parse_map_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS }, /* below three are multiton_rhs_expr */ - { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_CONCAT }, - { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_CONCAT }, - { "payload", json_parse_payload_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "exthdr", json_parse_exthdr_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "tcp option", json_parse_tcp_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT }, - { "ip option", json_parse_ip_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_CONCAT }, - { "meta", json_parse_meta_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "osf", json_parse_osf_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_MAP | CTX_F_CONCAT }, - { "ipsec", json_parse_xfrm_expr, CTX_F_PRIMARY | CTX_F_MAP | CTX_F_CONCAT }, - { "socket", json_parse_socket_expr, CTX_F_PRIMARY | CTX_F_CONCAT }, - { "rt", json_parse_rt_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "ct", json_parse_ct_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "numgen", json_parse_numgen_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, + { "prefix", json_parse_prefix_expr, CTX_F_RHS | CTX_F_STMT }, + { "range", json_parse_range_expr, CTX_F_RHS | CTX_F_STMT }, + { "payload", json_parse_payload_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP }, + { "exthdr", json_parse_exthdr_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "tcp option", json_parse_tcp_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES }, + { "ip option", json_parse_ip_option_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES }, + { "meta", json_parse_meta_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP }, + { "osf", json_parse_osf_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_MAP }, + { "ipsec", json_parse_xfrm_expr, CTX_F_PRIMARY | CTX_F_MAP }, + { "socket", json_parse_socket_expr, CTX_F_PRIMARY }, + { "rt", json_parse_rt_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "ct", json_parse_ct_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_MANGLE | CTX_F_SES | CTX_F_MAP }, + { "numgen", json_parse_numgen_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, /* below two are hash expr */ - { "jhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "symhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "fib", json_parse_fib_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "|", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "^", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "&", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { ">>", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, - { "<<", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP | CTX_F_CONCAT }, + { "jhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "symhash", json_parse_hash_expr, CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "fib", json_parse_fib_expr, CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "|", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "^", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "&", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { ">>", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, + { "<<", json_parse_binop_expr, CTX_F_RHS | CTX_F_STMT | CTX_F_PRIMARY | CTX_F_SET_RHS | CTX_F_SES | CTX_F_MAP }, { "accept", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS }, { "drop", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS }, { "continue", json_parse_verdict_expr, CTX_F_RHS | CTX_F_SET_RHS }, @@ -1502,11 +1500,6 @@ static struct expr *json_parse_map_lhs_expr(struct json_ctx *ctx, json_t *root) return json_parse_flagged_expr(ctx, CTX_F_MAP, root); } -static struct expr *json_parse_concat_elem_expr(struct json_ctx *ctx, json_t *root) -{ - return json_parse_flagged_expr(ctx, CTX_F_CONCAT, root); -} - static struct expr *json_parse_dtype_expr(struct json_ctx *ctx, json_t *root) { if (json_is_string(root)) { @@ -3845,15 +3838,12 @@ static uint64_t handle_from_nlmsg(const struct nlmsghdr *nlh) } int json_events_cb(const struct nlmsghdr *nlh, struct netlink_mon_handler *monh) { + json_t *tmp, *json = seqnum_to_json(nlh->nlmsg_seq); uint64_t handle = handle_from_nlmsg(nlh); - json_t *tmp, *json; void *iter; - if (!handle) - return MNL_CB_OK; - - json = seqnum_to_json(nlh->nlmsg_seq); - if (!json) + /* might be anonymous set, ignore message */ + if (!json || !handle) return MNL_CB_OK; tmp = json_object_get(json, "add"); diff --git a/src/rule.c b/src/rule.c index e18237b..d985d3a 100644 --- a/src/rule.c +++ b/src/rule.c @@ -337,7 +337,7 @@ struct set *set_clone(const struct set *set) new_set->objtype = set->objtype; new_set->policy = set->policy; new_set->automerge = set->automerge; - new_set->desc = set->desc; + new_set->desc.size = set->desc.size; return new_set; } @@ -1512,8 +1512,7 @@ static int __do_add_setelems(struct netlink_ctx *ctx, struct set *set, return -1; if (set->init != NULL && - set->flags & NFT_SET_INTERVAL && - set->desc.field_count <= 1) { + set->flags & NFT_SET_INTERVAL) { interval_map_decompose(expr); list_splice_tail_init(&expr->expressions, &set->init->expressions); set->init->size += expr->size; @@ -1534,7 +1533,7 @@ static int do_add_setelems(struct netlink_ctx *ctx, struct cmd *cmd, table = table_lookup(h, &ctx->nft->cache); set = set_lookup(table, h->set.name); - if (set_is_non_concat_range(set) && + if (set->flags & NFT_SET_INTERVAL && set_to_intervals(ctx->msgs, set, init, true, ctx->nft->debug_mask, set->automerge, &ctx->nft->output) < 0) @@ -1549,7 +1548,7 @@ static int do_add_set(struct netlink_ctx *ctx, const struct cmd *cmd, struct set *set = cmd->set; if (set->init != NULL) { - if (set_is_non_concat_range(set) && + if (set->flags & NFT_SET_INTERVAL && set_to_intervals(ctx->msgs, set, set->init, true, ctx->nft->debug_mask, set->automerge, &ctx->nft->output) < 0) @@ -1635,7 +1634,7 @@ static int do_delete_setelems(struct netlink_ctx *ctx, struct cmd *cmd) table = table_lookup(h, &ctx->nft->cache); set = set_lookup(table, h->set.name); - if (set_is_non_concat_range(set) && + if (set->flags & NFT_SET_INTERVAL && set_to_intervals(ctx->msgs, set, expr, false, ctx->nft->debug_mask, set->automerge, &ctx->nft->output) < 0) @@ -2489,7 +2488,7 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, set = set_lookup(table, cmd->handle.set.name); /* Create a list of elements based of what we got from command line. */ - if (set_is_non_concat_range(set)) + if (set->flags & NFT_SET_INTERVAL) init = get_set_intervals(set, cmd->expr); else init = cmd->expr; @@ -2502,7 +2501,7 @@ static int do_get_setelems(struct netlink_ctx *ctx, struct cmd *cmd, if (err >= 0) __do_list_set(ctx, cmd, table, new_set); - if (set_is_non_concat_range(set)) + if (set->flags & NFT_SET_INTERVAL) expr_free(init); set_free(new_set); @@ -2555,8 +2554,7 @@ static int do_command_reset(struct netlink_ctx *ctx, struct cmd *cmd) ret = netlink_reset_objs(ctx, cmd, type, dump); list_for_each_entry_safe(obj, next, &ctx->list, list) { table = table_lookup(&obj->handle, &ctx->nft->cache); - if (!obj_lookup(table, obj->handle.obj.name, obj->type)) - list_move(&obj->list, &table->objs); + list_move(&obj->list, &table->objs); } if (ret < 0) return ret; diff --git a/src/scanner.l b/src/scanner.l index 7daf5c1..d32adf4 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -120,7 +120,7 @@ numberstring ({decstring}|{hexstring}) letter [a-zA-Z] string ({letter}|[_.])({letter}|{digit}|[/\-_\.])* quotedstring \"[^"]*\" -asteriskstring ({string}\*|{string}\\\*|\\\*|{string}\\\*{string}) +asteriskstring ({string}\*|{string}\\\*) comment #.*$ slash \/ diff --git a/src/segtree.c b/src/segtree.c index 073c6ec..7217dbc 100644 --- a/src/segtree.c +++ b/src/segtree.c @@ -652,11 +652,6 @@ struct expr *get_set_intervals(const struct set *set, const struct expr *init) set_elem_add(set, new_init, i->key->value, i->flags, i->byteorder); break; - case EXPR_CONCAT: - compound_expr_add(new_init, expr_clone(i)); - i->flags |= EXPR_F_INTERVAL_END; - compound_expr_add(new_init, expr_clone(i)); - break; default: range_expr_value_low(low, i); set_elem_add(set, new_init, low, 0, i->byteorder); @@ -681,32 +676,67 @@ static struct expr *get_set_interval_find(const struct table *table, { struct expr *range = NULL; struct set *set; + mpz_t low, high; struct expr *i; - mpz_t val; set = set_lookup(table, set_name); - mpz_init2(val, set->key->len); + mpz_init2(low, set->key->len); + mpz_init2(high, set->key->len); list_for_each_entry(i, &set->init->expressions, list) { switch (i->key->etype) { - case EXPR_PREFIX: case EXPR_RANGE: - range_expr_value_low(val, i); - if (left && mpz_cmp(left->key->value, val)) - break; + range_expr_value_low(low, i); + range_expr_value_high(high, i); + if (mpz_cmp(left->key->value, low) >= 0 && + mpz_cmp(right->key->value, high) <= 0) { + range = range_expr_alloc(&internal_location, + expr_clone(left->key), + expr_clone(right->key)); + goto out; + } + break; + default: + break; + } + } +out: + mpz_clear(low); + mpz_clear(high); - range_expr_value_high(val, i); - if (right && mpz_cmp(right->key->value, val)) - break; + return range; +} + +static struct expr *get_set_interval_end(const struct table *table, + const char *set_name, + struct expr *left) +{ + struct expr *i, *range = NULL; + struct set *set; + mpz_t low, high; - range = expr_clone(i->key); - goto out; + set = set_lookup(table, set_name); + mpz_init2(low, set->key->len); + mpz_init2(high, set->key->len); + + list_for_each_entry(i, &set->init->expressions, list) { + switch (i->key->etype) { + case EXPR_RANGE: + range_expr_value_low(low, i); + if (mpz_cmp(low, left->key->value) == 0) { + range = range_expr_alloc(&internal_location, + expr_clone(left->key), + expr_clone(i->key->right)); + goto out; + } + break; default: break; } } out: - mpz_clear(val); + mpz_clear(low); + mpz_clear(high); return range; } @@ -736,9 +766,9 @@ int get_set_decompose(struct table *table, struct set *set) left = NULL; } else { if (left) { - range = get_set_interval_find(table, - set->handle.set.name, - left, NULL); + range = get_set_interval_end(table, + set->handle.set.name, + left); if (range) compound_expr_add(new_init, range); else @@ -749,8 +779,7 @@ int get_set_decompose(struct table *table, struct set *set) } } if (left) { - range = get_set_interval_find(table, set->handle.set.name, - left, NULL); + range = get_set_interval_end(table, set->handle.set.name, left); if (range) compound_expr_add(new_init, range); else @@ -794,9 +823,6 @@ static int expr_value_cmp(const void *p1, const void *p2) struct expr *e2 = *(void * const *)p2; int ret; - if (expr_value(e1)->etype == EXPR_CONCAT) - return -1; - ret = mpz_cmp(expr_value(e1)->value, expr_value(e2)->value); if (ret == 0) { if (e1->flags & EXPR_F_INTERVAL_END) @@ -808,115 +834,6 @@ static int expr_value_cmp(const void *p1, const void *p2) return ret; } -/* Given start and end elements of a range, check if it can be represented as - * a single netmask, and if so, how long, by returning zero or a positive value. - */ -static int range_mask_len(const mpz_t start, const mpz_t end, unsigned int len) -{ - mpz_t tmp_start, tmp_end; - int ret; - - mpz_init_set_ui(tmp_start, mpz_get_ui(start)); - mpz_init_set_ui(tmp_end, mpz_get_ui(end)); - - while (mpz_cmp(tmp_start, tmp_end) <= 0 && - !mpz_tstbit(tmp_start, 0) && mpz_tstbit(tmp_end, 0) && - len--) { - mpz_fdiv_q_2exp(tmp_start, tmp_start, 1); - mpz_fdiv_q_2exp(tmp_end, tmp_end, 1); - } - - ret = !mpz_cmp(tmp_start, tmp_end) ? (int)len : -1; - - mpz_clear(tmp_start); - mpz_clear(tmp_end); - - return ret; -} - -/* Given a set with two elements (start and end), transform them into a - * concatenation of ranges. That is, from a list of start expressions and a list - * of end expressions, form a list of start - end expressions. - */ -void concat_range_aggregate(struct expr *set) -{ - struct expr *i, *start = NULL, *end, *r1, *r2, *next, *r1_next, *tmp; - struct list_head *r2_next; - int prefix_len, free_r1; - mpz_t range, p; - - list_for_each_entry_safe(i, next, &set->expressions, list) { - if (!start) { - start = i; - continue; - } - end = i; - - /* Walk over r1 (start expression) and r2 (end) in parallel, - * form ranges between corresponding r1 and r2 expressions, - * store them by replacing r2 expressions, and free r1 - * expressions. - */ - r2 = list_first_entry(&expr_value(end)->expressions, - struct expr, list); - list_for_each_entry_safe(r1, r1_next, - &expr_value(start)->expressions, - list) { - mpz_init(range); - mpz_init(p); - - r2_next = r2->list.next; - free_r1 = 0; - - if (!mpz_cmp(r1->value, r2->value)) { - free_r1 = 1; - goto next; - } - - mpz_sub(range, r2->value, r1->value); - mpz_sub_ui(range, range, 1); - mpz_and(p, r1->value, range); - - /* Check if we are forced, or if it's anyway preferable, - * to express the range as two points instead of a - * netmask. - */ - prefix_len = range_mask_len(r1->value, r2->value, - r1->len); - if (prefix_len < 0 || - !(r1->dtype->flags & DTYPE_F_PREFIX)) { - tmp = range_expr_alloc(&r1->location, r1, - r2); - - list_replace(&r2->list, &tmp->list); - r2_next = tmp->list.next; - } else { - tmp = prefix_expr_alloc(&r1->location, r1, - prefix_len); - tmp->len = r2->len; - - list_replace(&r2->list, &tmp->list); - r2_next = tmp->list.next; - expr_free(r2); - } - -next: - mpz_clear(p); - mpz_clear(range); - - r2 = list_entry(r2_next, typeof(*r2), list); - compound_expr_remove(start, r1); - - if (free_r1) - expr_free(r1); - } - - compound_expr_remove(set, start); - expr_free(start); - start = NULL; - } -} - void interval_map_decompose(struct expr *set) { struct expr **elements, **ranges; @@ -1052,7 +969,7 @@ void interval_map_decompose(struct expr *set) prefix->comment = xstrdup(low->comment); if (low->timeout) prefix->timeout = low->timeout; - if (low->expiration) + if (low->left->expiration) prefix->expiration = low->expiration; } diff --git a/src/xfrm.c b/src/xfrm.c index 336e8c9..4dd53c3 100644 --- a/src/xfrm.c +++ b/src/xfrm.c @@ -39,7 +39,7 @@ const struct xfrm_template xfrm_templates[] = { [NFT_XFRM_KEY_DADDR_IP6] = XFRM_TEMPLATE_BE("daddr", &ip6addr_type, 16 * BITS_PER_BYTE), [NFT_XFRM_KEY_SADDR_IP6] = XFRM_TEMPLATE_BE("saddr", &ip6addr_type, 16 * BITS_PER_BYTE), [NFT_XFRM_KEY_REQID] = XFRM_TEMPLATE_HE("reqid", &integer_type, 4 * BITS_PER_BYTE), - [NFT_XFRM_KEY_SPI] = XFRM_TEMPLATE_BE("spi", &integer_type, 4 * BITS_PER_BYTE), + [NFT_XFRM_KEY_SPI] = XFRM_TEMPLATE_HE("spi", &integer_type, 4 * BITS_PER_BYTE), }; static void xfrm_expr_print(const struct expr *expr, struct output_ctx *octx) diff --git a/tests/json_echo/run-test.py b/tests/json_echo/run-test.py index 36a377a..a636d5f 100755 --- a/tests/json_echo/run-test.py +++ b/tests/json_echo/run-test.py @@ -4,7 +4,6 @@ from __future__ import print_function import sys import os import json -import argparse TESTS_PATH = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.join(TESTS_PATH, '../../py/')) @@ -14,26 +13,12 @@ from nftables import Nftables # Change working directory to repository root os.chdir(TESTS_PATH + "/../..") -parser = argparse.ArgumentParser(description='Run JSON echo tests') -parser.add_argument('-H', '--host', action='store_true', - help='Run tests against installed libnftables.so.1') -parser.add_argument('-l', '--library', default=None, - help='Path to libntables.so, overrides --host') -args = parser.parse_args() - -check_lib_path = True -if args.library is None: - if args.host: - args.library = 'libnftables.so.1' - check_lib_path = False - else: - args.library = 'src/.libs/libnftables.so.1' - -if check_lib_path and not os.path.exists(args.library): - print("Library not found at '%s'." % args.library) +if not os.path.exists('src/.libs/libnftables.so'): + print("The nftables library does not exist. " + "You need to build the project.") sys.exit(1) -nftables = Nftables(sofile = args.library) +nftables = Nftables(sofile = 'src/.libs/libnftables.so') nftables.set_echo_output(True) # various commands to work with @@ -134,7 +119,7 @@ def get_handle(output, search): else: data = item - k = list(search.keys())[0] + k = search.keys()[0] if not k in data: continue diff --git a/tests/monitor/run-tests.sh b/tests/monitor/run-tests.sh index ffb833a..0478cf6 100755 --- a/tests/monitor/run-tests.sh +++ b/tests/monitor/run-tests.sh @@ -108,7 +108,6 @@ echo_run_test() { touch $output_file } -testcases="" while [ -n "$1" ]; do case "$1" in -d|--debug) @@ -119,19 +118,11 @@ while [ -n "$1" ]; do test_json=true shift ;; - -H|--host) - nft=nft - shift - ;; - testcases/*.t) - testcases+=" $1" - shift - ;; *) echo "unknown option '$1'" ;& -h|--help) - echo "Usage: $(basename $0) [-j|--json] [-d|--debug] [testcase ...]" + echo "Usage: $(basename $0) [-j|--json] [-d|--debug]" exit 1 ;; esac @@ -147,7 +138,7 @@ for variant in $variants; do run_test=${variant}_run_test output_append=${variant}_output_append - for testcase in ${testcases:-testcases/*.t}; do + for testcase in testcases/*.t; do echo "$variant: running tests from file $(basename $testcase)" # files are like this: # diff --git a/tests/monitor/testcases/set-interval.t b/tests/monitor/testcases/set-interval.t deleted file mode 100644 index 1fbcfe2..0000000 --- a/tests/monitor/testcases/set-interval.t +++ /dev/null @@ -1,25 +0,0 @@ -# setup first -I add table ip t -I add chain ip t c -O - -J {"add": {"table": {"family": "ip", "name": "t", "handle": 0}}} -J {"add": {"chain": {"family": "ip", "table": "t", "name": "c", "handle": 0}}} - -# add set with elements, monitor output expectedly differs -I add set ip t s { type inet_service; flags interval; elements = { 20, 30-40 }; } -O add set ip t s { type inet_service; flags interval; } -O add element ip t s { 20 } -O add element ip t s { 30-40 } -J {"add": {"set": {"family": "ip", "name": "s", "table": "t", "type": "inet_service", "handle": 0, "flags": ["interval"]}}} -J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [20]}}}} -J {"add": {"element": {"family": "ip", "table": "t", "name": "s", "elem": {"set": [{"range": [30, 40]}]}}}} - -# this would crash nft -I add rule ip t c tcp dport @s -O - -J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": "@s"}}]}}} - -# test anonymous interval sets as well -I add rule ip t c tcp dport { 20, 30-40 } -O - -J {"add": {"rule": {"family": "ip", "table": "t", "chain": "c", "handle": 0, "expr": [{"match": {"op": "==", "left": {"payload": {"protocol": "tcp", "field": "dport"}}, "right": {"set": [20, {"range": [30, 40]}]}}}]}}} diff --git a/tests/py/inet/ipsec.t.payload b/tests/py/inet/ipsec.t.payload index c46a226..6049c66 100644 --- a/tests/py/inet/ipsec.t.payload +++ b/tests/py/inet/ipsec.t.payload @@ -16,6 +16,7 @@ ip ipsec-ip4 ipsec-input # ipsec out spi 1-561 inet ipsec-inet ipsec-post [ xfrm load out 0 spi => reg 1 ] + [ byteorder reg 1 = hton(reg 1, 4, 4) ] [ cmp gte reg 1 0x01000000 ] [ cmp lte reg 1 0x31020000 ] diff --git a/tests/py/nft-test.py b/tests/py/nft-test.py index 01ee6c9..6edca3c 100755 --- a/tests/py/nft-test.py +++ b/tests/py/nft-test.py @@ -1357,16 +1357,10 @@ def main(): dest='force_all_family', help='keep testing all families on error') - parser.add_argument('-H', '--host', action='store_true', - help='run tests against installed libnftables.so.1') - parser.add_argument('-j', '--enable-json', action='store_true', dest='enable_json', help='test JSON functionality as well') - parser.add_argument('-l', '--library', default=None, - help='path to libntables.so.1, overrides --host') - parser.add_argument('-s', '--schema', action='store_true', dest='enable_schema', help='verify json input/output against schema') @@ -1394,17 +1388,9 @@ def main(): # Change working directory to repository root os.chdir(TESTS_PATH + "/../..") - check_lib_path = True - if args.library is None: - if args.host: - args.library = 'libnftables.so.1' - check_lib_path = False - else: - args.library = 'src/.libs/libnftables.so.1' - - if check_lib_path and not os.path.exists(args.library): - print("The nftables library at '%s' does not exist. " - "You need to build the project." % args.library) + if not os.path.exists('src/.libs/libnftables.so'): + print("The nftables library does not exist. " + "You need to build the project.") return if args.enable_schema and not args.enable_json: @@ -1412,7 +1398,7 @@ def main(): return global nftables - nftables = Nftables(sofile = args.library) + nftables = Nftables(sofile = 'src/.libs/libnftables.so') test_files = files_ok = run_total = 0 tests = passed = warnings = errors = 0 diff --git a/tests/shell/run-tests.sh b/tests/shell/run-tests.sh index 29a2c39..632ccce 100755 --- a/tests/shell/run-tests.sh +++ b/tests/shell/run-tests.sh @@ -43,11 +43,6 @@ if [ ! -x "$MODPROBE" ] ; then msg_error "no modprobe binary found" fi -DIFF="$(which diff)" -if [ ! -x "$DIFF" ] ; then - DIFF=true -fi - if [ "$1" == "-v" ] ; then VERBOSE=y shift @@ -101,7 +96,7 @@ do kernel_cleanup msg_info "[EXECUTING] $testfile" - test_output=$(NFT=$NFT DIFF=$DIFF ${testfile} 2>&1) + test_output=$(NFT=$NFT ${testfile} 2>&1) rc_got=$? echo -en "\033[1A\033[K" # clean the [EXECUTING] foobar line diff --git a/tests/shell/testcases/cache/0001_cache_handling_0 b/tests/shell/testcases/cache/0001_cache_handling_0 index 0a68440..431aada 100755 --- a/tests/shell/testcases/cache/0001_cache_handling_0 +++ b/tests/shell/testcases/cache/0001_cache_handling_0 @@ -20,7 +20,7 @@ TMP=$(mktemp) echo "$RULESET" >> "$TMP" $NFT "flush ruleset;include \"$TMP\"" rm -f "$TMP" -rule_handle=$($NFT -a list ruleset | awk '/saddr/{print $NF}') +rule_handle=$($NFT list ruleset -a | awk '/saddr/{print $NF}') $NFT delete rule inet test test handle $rule_handle $NFT delete set inet test test $NFT -f - <<< "$RULESET" diff --git a/tests/shell/testcases/chains/0016delete_handle_0 b/tests/shell/testcases/chains/0016delete_handle_0 index 8fd1ad8..4633d77 100755 --- a/tests/shell/testcases/chains/0016delete_handle_0 +++ b/tests/shell/testcases/chains/0016delete_handle_0 @@ -10,8 +10,8 @@ $NFT add chain ip6 test-ip6 x $NFT add chain ip6 test-ip6 y $NFT add chain ip6 test-ip6 z -chain_y_handle=$($NFT -a list ruleset | awk -v n=1 '/chain y/ && !--n {print $NF; exit}'); -chain_z_handle=$($NFT -a list ruleset | awk -v n=2 '/chain z/ && !--n {print $NF; exit}'); +chain_y_handle=$($NFT list ruleset -a | awk -v n=1 '/chain y/ && !--n {print $NF; exit}'); +chain_z_handle=$($NFT list ruleset -a | awk -v n=2 '/chain z/ && !--n {print $NF; exit}'); $NFT delete chain test-ip handle $chain_y_handle $NFT delete chain ip6 test-ip6 handle $chain_z_handle diff --git a/tests/shell/testcases/chains/0039negative_priority_0 b/tests/shell/testcases/chains/0039negative_priority_0 deleted file mode 100755 index ba17b8c..0000000 --- a/tests/shell/testcases/chains/0039negative_priority_0 +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -# Test parsing of negative priority values - -set -e - -$NFT add table t -$NFT add chain t c { type filter hook input priority -30\; } diff --git a/tests/shell/testcases/flowtable/0010delete_handle_0 b/tests/shell/testcases/flowtable/0010delete_handle_0 index 8dd8d9f..303967d 100755 --- a/tests/shell/testcases/flowtable/0010delete_handle_0 +++ b/tests/shell/testcases/flowtable/0010delete_handle_0 @@ -7,7 +7,7 @@ set -e $NFT add table inet t $NFT add flowtable inet t f { hook ingress priority filter\; devices = { lo }\; } -FH=$($NFT -a list ruleset | awk '/flowtable f/ { print $NF }') +FH=$($NFT list ruleset -a | awk '/flowtable f/ { print $NF }') $NFT delete flowtable inet t handle $FH @@ -16,6 +16,7 @@ EXPECTED="table inet t { GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0003table_0 b/tests/shell/testcases/listing/0003table_0 index 5060be0..1b288e4 100755 --- a/tests/shell/testcases/listing/0003table_0 +++ b/tests/shell/testcases/listing/0003table_0 @@ -11,13 +11,15 @@ $NFT add table test GET="$($NFT list table test)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi # also this way GET="$($NFT list table ip test)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0004table_0 b/tests/shell/testcases/listing/0004table_0 index 1d69119..2c7c995 100755 --- a/tests/shell/testcases/listing/0004table_0 +++ b/tests/shell/testcases/listing/0004table_0 @@ -12,7 +12,8 @@ $NFT add table test2 GET="$($NFT list table test)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0005ruleset_ip_0 b/tests/shell/testcases/listing/0005ruleset_ip_0 index 39c0328..c326680 100755 --- a/tests/shell/testcases/listing/0005ruleset_ip_0 +++ b/tests/shell/testcases/listing/0005ruleset_ip_0 @@ -15,6 +15,7 @@ $NFT add table bridge test GET="$($NFT list ruleset ip)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0006ruleset_ip6_0 b/tests/shell/testcases/listing/0006ruleset_ip6_0 index 1b67f50..093d5a5 100755 --- a/tests/shell/testcases/listing/0006ruleset_ip6_0 +++ b/tests/shell/testcases/listing/0006ruleset_ip6_0 @@ -15,6 +15,7 @@ $NFT add table bridge test GET="$($NFT list ruleset ip6)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0007ruleset_inet_0 b/tests/shell/testcases/listing/0007ruleset_inet_0 index 257c7a9..b24cc4c 100755 --- a/tests/shell/testcases/listing/0007ruleset_inet_0 +++ b/tests/shell/testcases/listing/0007ruleset_inet_0 @@ -15,6 +15,7 @@ $NFT add table bridge test GET="$($NFT list ruleset inet)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0008ruleset_arp_0 b/tests/shell/testcases/listing/0008ruleset_arp_0 index be42c47..fff0fee 100755 --- a/tests/shell/testcases/listing/0008ruleset_arp_0 +++ b/tests/shell/testcases/listing/0008ruleset_arp_0 @@ -15,6 +15,7 @@ $NFT add table bridge test GET="$($NFT list ruleset arp)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0009ruleset_bridge_0 b/tests/shell/testcases/listing/0009ruleset_bridge_0 index c6a99f5..247ed47 100755 --- a/tests/shell/testcases/listing/0009ruleset_bridge_0 +++ b/tests/shell/testcases/listing/0009ruleset_bridge_0 @@ -15,6 +15,7 @@ $NFT add table bridge test GET="$($NFT list ruleset bridge)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0010sets_0 b/tests/shell/testcases/listing/0010sets_0 index 0f5f2bd..855cceb 100755 --- a/tests/shell/testcases/listing/0010sets_0 +++ b/tests/shell/testcases/listing/0010sets_0 @@ -57,6 +57,7 @@ $NFT add set inet filter set2 { type icmpv6_type \; } GET="$($NFT list sets)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0011sets_0 b/tests/shell/testcases/listing/0011sets_0 index b6f12b5..aac9eac 100755 --- a/tests/shell/testcases/listing/0011sets_0 +++ b/tests/shell/testcases/listing/0011sets_0 @@ -38,6 +38,7 @@ $NFT add rule inet filter test tcp dport {80, 443} GET="$($NFT list sets)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0012sets_0 b/tests/shell/testcases/listing/0012sets_0 index 6e4c959..da16d94 100755 --- a/tests/shell/testcases/listing/0012sets_0 +++ b/tests/shell/testcases/listing/0012sets_0 @@ -33,6 +33,7 @@ $NFT add set inet filter set2 { type icmpv6_type \; } GET="$($NFT list sets inet)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0013objects_0 b/tests/shell/testcases/listing/0013objects_0 index 4d39143..f691579 100755 --- a/tests/shell/testcases/listing/0013objects_0 +++ b/tests/shell/testcases/listing/0013objects_0 @@ -42,6 +42,7 @@ $NFT add table test-ip GET="$($NFT list table test)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0014objects_0 b/tests/shell/testcases/listing/0014objects_0 index 31d94f8..20f6840 100755 --- a/tests/shell/testcases/listing/0014objects_0 +++ b/tests/shell/testcases/listing/0014objects_0 @@ -17,13 +17,15 @@ $NFT add table test-ip GET="$($NFT list quotas)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi GET="$($NFT list quota test https-quota)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0015dynamic_0 b/tests/shell/testcases/listing/0015dynamic_0 index 65fbe62..4ff74e3 100755 --- a/tests/shell/testcases/listing/0015dynamic_0 +++ b/tests/shell/testcases/listing/0015dynamic_0 @@ -16,7 +16,8 @@ $NFT -f - <<< "$EXPECTED" GET="$($NFT list set ip filter test_set)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0017objects_0 b/tests/shell/testcases/listing/0017objects_0 index c4e72db..8a586e8 100755 --- a/tests/shell/testcases/listing/0017objects_0 +++ b/tests/shell/testcases/listing/0017objects_0 @@ -13,6 +13,7 @@ $NFT flush map inet filter countermap GET="$($NFT list map inet filter countermap)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0018data_0 b/tests/shell/testcases/listing/0018data_0 index 4af253d..544b6bf 100755 --- a/tests/shell/testcases/listing/0018data_0 +++ b/tests/shell/testcases/listing/0018data_0 @@ -13,6 +13,7 @@ $NFT flush map inet filter ipmap GET="$($NFT list map inet filter ipmap)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0019set_0 b/tests/shell/testcases/listing/0019set_0 index 6e8cb4d..54a8a06 100755 --- a/tests/shell/testcases/listing/0019set_0 +++ b/tests/shell/testcases/listing/0019set_0 @@ -13,6 +13,7 @@ $NFT flush set inet filter ipset GET="$($NFT list set inet filter ipset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/listing/0020flowtable_0 b/tests/shell/testcases/listing/0020flowtable_0 index 2f0a98d..6f630f1 100755 --- a/tests/shell/testcases/listing/0020flowtable_0 +++ b/tests/shell/testcases/listing/0020flowtable_0 @@ -15,6 +15,7 @@ $NFT -f - <<< "$EXPECTED" GET="$($NFT list flowtable inet filter f)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/maps/0003map_add_many_elements_0 b/tests/shell/testcases/maps/0003map_add_many_elements_0 index 2b254c5..047f949 100755 --- a/tests/shell/testcases/maps/0003map_add_many_elements_0 +++ b/tests/shell/testcases/maps/0003map_add_many_elements_0 @@ -61,7 +61,8 @@ EXPECTED="table ip x { }" GET=$($NFT list ruleset) if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/maps/0004interval_map_create_once_0 b/tests/shell/testcases/maps/0004interval_map_create_once_0 index 3de0c9d..58b399c 100755 --- a/tests/shell/testcases/maps/0004interval_map_create_once_0 +++ b/tests/shell/testcases/maps/0004interval_map_create_once_0 @@ -60,7 +60,8 @@ EXPECTED="table ip x { }" GET=$($NFT list ruleset) if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/maps/0008interval_map_delete_0 b/tests/shell/testcases/maps/0008interval_map_delete_0 index 39ea312..a43fd28 100755 --- a/tests/shell/testcases/maps/0008interval_map_delete_0 +++ b/tests/shell/testcases/maps/0008interval_map_delete_0 @@ -24,8 +24,9 @@ $NFT delete element filter m { 127.0.0.3 } $NFT add element filter m { 127.0.0.3 : 0x3 } $NFT add element filter m { 127.0.0.2 : 0x2 } -GET=$($NFT -s list ruleset) +GET=$($NFT list ruleset -s) if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/netns/0001nft-f_0 b/tests/shell/testcases/netns/0001nft-f_0 index a591f2c..8194226 100755 --- a/tests/shell/testcases/netns/0001nft-f_0 +++ b/tests/shell/testcases/netns/0001nft-f_0 @@ -93,7 +93,8 @@ fi KERNEL_RULESET="$($IP netns exec $NETNS_NAME $NFT list ruleset)" $IP netns del $NETNS_NAME if [ "$RULESET" != "$KERNEL_RULESET" ] ; then - $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") exit 1 fi exit 0 diff --git a/tests/shell/testcases/netns/0002loosecommands_0 b/tests/shell/testcases/netns/0002loosecommands_0 index 231f1fb..465c2e8 100755 --- a/tests/shell/testcases/netns/0002loosecommands_0 +++ b/tests/shell/testcases/netns/0002loosecommands_0 @@ -56,6 +56,7 @@ RULESET="table ip t { KERNEL_RULESET="$($IP netns exec $NETNS_NAME $NFT list ruleset)" $IP netns del $NETNS_NAME if [ "$RULESET" != "$KERNEL_RULESET" ] ; then - $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") exit 1 fi diff --git a/tests/shell/testcases/netns/0003many_0 b/tests/shell/testcases/netns/0003many_0 index afe9117..a5fcb5d 100755 --- a/tests/shell/testcases/netns/0003many_0 +++ b/tests/shell/testcases/netns/0003many_0 @@ -97,7 +97,8 @@ function test_netns() KERNEL_RULESET="$($IP netns exec $NETNS_NAME $NFT list ruleset)" if [ "$RULESET" != "$KERNEL_RULESET" ] ; then echo "E: ruleset in netns $NETNS_NAME differs from the loaded" >&2 - $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") $IP netns del $NETNS_NAME exit 1 fi diff --git a/tests/shell/testcases/nft-f/0016redefines_1 b/tests/shell/testcases/nft-f/0016redefines_1 index 1f59f6b..4c26b37 100755 --- a/tests/shell/testcases/nft-f/0016redefines_1 +++ b/tests/shell/testcases/nft-f/0016redefines_1 @@ -26,7 +26,8 @@ $NFT -f - <<< "$RULESET" GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/optionals/comments_0 b/tests/shell/testcases/optionals/comments_0 index ab85936..29b8506 100755 --- a/tests/shell/testcases/optionals/comments_0 +++ b/tests/shell/testcases/optionals/comments_0 @@ -5,4 +5,4 @@ $NFT add table test $NFT add chain test test $NFT add rule test test tcp dport 22 counter accept comment test_comment -$NFT -a list table test | grep 'accept comment \"test_comment\"' >/dev/null +$NFT list table test -a | grep 'accept comment \"test_comment\"' >/dev/null diff --git a/tests/shell/testcases/optionals/comments_handles_0 b/tests/shell/testcases/optionals/comments_handles_0 index a01df1d..30539bf 100755 --- a/tests/shell/testcases/optionals/comments_handles_0 +++ b/tests/shell/testcases/optionals/comments_handles_0 @@ -6,5 +6,5 @@ $NFT add table test $NFT add chain test test $NFT add rule test test tcp dport 22 counter accept comment test_comment set -e -$NFT -a list table test | grep 'accept comment \"test_comment\" # handle '[[:digit:]]$ >/dev/null +$NFT list table test -a | grep 'accept comment \"test_comment\" # handle '[[:digit:]]$ >/dev/null $NFT list table test | grep 'accept comment \"test_comment\"' | grep -v '# handle '[[:digit:]]$ >/dev/null diff --git a/tests/shell/testcases/optionals/delete_object_handles_0 b/tests/shell/testcases/optionals/delete_object_handles_0 index 9b65e67..d5d9654 100755 --- a/tests/shell/testcases/optionals/delete_object_handles_0 +++ b/tests/shell/testcases/optionals/delete_object_handles_0 @@ -10,8 +10,8 @@ $NFT add quota ip6 test-ip6 http-quota over 25 mbytes $NFT add counter ip6 test-ip6 http-traffic $NFT add quota ip6 test-ip6 ssh-quota 10 mbytes -counter_handle=$($NFT -a list ruleset | awk '/https-traffic/{print $NF}') -quota_handle=$($NFT -a list ruleset | awk '/ssh-quota/{print $NF}') +counter_handle=$($NFT list ruleset -a | awk '/https-traffic/{print $NF}') +quota_handle=$($NFT list ruleset -a | awk '/ssh-quota/{print $NF}') $NFT delete counter test-ip handle $counter_handle $NFT delete quota ip6 test-ip6 handle $quota_handle @@ -37,6 +37,7 @@ table ip6 test-ip6 { GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/optionals/handles_0 b/tests/shell/testcases/optionals/handles_0 index 80f3c5b..7c6a437 100755 --- a/tests/shell/testcases/optionals/handles_0 +++ b/tests/shell/testcases/optionals/handles_0 @@ -5,4 +5,4 @@ $NFT add table test $NFT add chain test test $NFT add rule test test tcp dport 22 counter accept -$NFT -a list table test | grep 'accept # handle '[[:digit:]]$ >/dev/null +$NFT list table test -a | grep 'accept # handle '[[:digit:]]$ >/dev/null diff --git a/tests/shell/testcases/optionals/update_object_handles_0 b/tests/shell/testcases/optionals/update_object_handles_0 index 8b12b8c..17c0c86 100755 --- a/tests/shell/testcases/optionals/update_object_handles_0 +++ b/tests/shell/testcases/optionals/update_object_handles_0 @@ -19,6 +19,7 @@ EXPECTED="table ip test-ip { GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/rule_management/0001addinsertposition_0 b/tests/shell/testcases/rule_management/0001addinsertposition_0 index 237e9e3..bb3fda5 100755 --- a/tests/shell/testcases/rule_management/0001addinsertposition_0 +++ b/tests/shell/testcases/rule_management/0001addinsertposition_0 @@ -30,7 +30,8 @@ for arg in "position 2" "handle 2" "index 0"; do GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi done @@ -41,7 +42,8 @@ for arg in "position 3" "handle 3" "index 1"; do GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi done @@ -60,7 +62,8 @@ for arg in "position 3" "handle 3" "index 1"; do GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi done @@ -79,7 +82,8 @@ for arg in "position 2" "handle 2" "index 0"; do GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi done diff --git a/tests/shell/testcases/sets/0024named_objects_0 b/tests/shell/testcases/sets/0024named_objects_0 index 21200c3..3bd16f2 100755 --- a/tests/shell/testcases/sets/0024named_objects_0 +++ b/tests/shell/testcases/sets/0024named_objects_0 @@ -35,14 +35,4 @@ table inet x { set -e $NFT -f - <<< "$RULESET" -EXPECTED="table inet x { - counter user321 { - packets 12 bytes 1433 - } -}" - -GET="$($NFT reset counter inet x user321)" -if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") - exit 1 -fi +$NFT reset counter inet x user321 diff --git a/tests/shell/testcases/sets/0028delete_handle_0 b/tests/shell/testcases/sets/0028delete_handle_0 index c6d1253..4e8b322 100755 --- a/tests/shell/testcases/sets/0028delete_handle_0 +++ b/tests/shell/testcases/sets/0028delete_handle_0 @@ -7,7 +7,7 @@ $NFT add set test-ip y { type inet_service \; timeout 3h45s \;} $NFT add set test-ip z { type ipv4_addr\; flags constant , interval\;} $NFT add set test-ip c {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;} -set_handle=$($NFT -a list ruleset | awk '/set c/{print $NF}') +set_handle=$($NFT list ruleset -a | awk '/set c/{print $NF}') $NFT delete set test-ip handle $set_handle EXPECTED="table ip test-ip { @@ -29,6 +29,7 @@ EXPECTED="table ip test-ip { GET="$($NFT list ruleset)" if [ "$EXPECTED" != "$GET" ] ; then - $DIFF -u <(echo "$EXPECTED") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET") exit 1 fi diff --git a/tests/shell/testcases/sets/0034get_element_0 b/tests/shell/testcases/sets/0034get_element_0 index 3343529..c7e7298 100755 --- a/tests/shell/testcases/sets/0034get_element_0 +++ b/tests/shell/testcases/sets/0034get_element_0 @@ -2,69 +2,43 @@ RC=0 -check() { # (set, elems, expected) - out=$($NFT get element ip t $1 "{ $2 }") +check() { # (elems, expected) + out=$($NFT get element ip t s "{ $1 }" 2>/dev/null) out=$(grep "elements =" <<< "$out") out="${out#* \{ }" out="${out% \}}" - [[ "$out" == "$3" ]] && return - echo "ERROR: asked for '$2' in set $1, expecting '$3' but got '$out'" + [[ "$out" == "$2" ]] && return + echo "ERROR: asked for '$1', expecting '$2' but got '$out'" ((RC++)) } RULESET="add table ip t add set ip t s { type inet_service; flags interval; } add element ip t s { 10, 20-30, 40, 50-60 } -add set ip t ips { type ipv4_addr; flags interval; } -add element ip t ips { 10.0.0.1, 10.0.0.5-10.0.0.8 } -add element ip t ips { 10.0.0.128/25, 10.0.1.0/24, 10.0.2.3-10.0.2.12 } -add set ip t cs { type ipv4_addr . inet_service; flags interval; } -add element ip t cs { 10.0.0.1 . 22, 10.1.0.0/16 . 1-1024 } -add element ip t cs { 10.2.0.1-10.2.0.8 . 1024-65535 } " $NFT -f - <<< "$RULESET" # simple cases, (non-)existing values and ranges -check s 10 10 -check s 11 "" -check s 20-30 20-30 -check s 15-18 "" +check 10 10 +check 11 "" +check 20-30 20-30 +check 15-18 "" # multiple single elements, ranges smaller than present -check s "10, 40" "10, 40" -check s "22-24, 26-28" "20-30, 20-30" -check s 21-29 20-30 +check "10, 40" "10, 40" +check "22-24, 26-28" "20-30, 20-30" +check 21-29 20-30 # mixed single elements and ranges -check s "10, 20" "10, 20-30" -check s "10, 22" "10, 20-30" -check s "10, 22-24" "10, 20-30" +check "10, 20" "10, 20-30" +check "10, 22" "10, 20-30" +check "10, 22-24" "10, 20-30" # non-existing ranges matching elements -check s 10-40 "" -check s 10-20 "" -check s 10-25 "" -check s 25-55 "" - -# playing with IPs, ranges and prefixes -check ips 10.0.0.1 10.0.0.1 -check ips 10.0.0.2 "" -check ips 10.0.1.0/24 10.0.1.0/24 -check ips 10.0.1.2/31 10.0.1.0/24 -check ips 10.0.1.0 10.0.1.0/24 -check ips 10.0.1.3 10.0.1.0/24 -check ips 10.0.1.255 10.0.1.0/24 -check ips 10.0.2.3-10.0.2.12 10.0.2.3-10.0.2.12 -check ips 10.0.2.10 10.0.2.3-10.0.2.12 -check ips 10.0.2.12 10.0.2.3-10.0.2.12 - -# test concatenated ranges, i.e. Pi, Pa and Po -check cs "10.0.0.1 . 22" "10.0.0.1 . 22" -check cs "10.0.0.1 . 23" "" -check cs "10.0.0.2 . 22" "" -check cs "10.1.0.1 . 42" "10.1.0.0/16 . 1-1024" -check cs "10.1.1.0/24 . 10-20" "10.1.0.0/16 . 1-1024" -check cs "10.2.0.3 . 20000" "10.2.0.1-10.2.0.8 . 1024-65535" +check 10-40 "" +check 10-20 "" +check 10-25 "" +check 25-55 "" exit $RC diff --git a/tests/shell/testcases/sets/0036add_set_element_expiration_0 b/tests/shell/testcases/sets/0036add_set_element_expiration_0 index 51ed0f2..8dfed6c 100755 --- a/tests/shell/testcases/sets/0036add_set_element_expiration_0 +++ b/tests/shell/testcases/sets/0036add_set_element_expiration_0 @@ -8,9 +8,6 @@ add element ip x y { 1.1.1.1 timeout 30s expires 15s }" test_output=$($NFT -e -f - <<< "$RULESET" 2>&1) -if [ "$test_output" != "$RULESET" ] ; then - $DIFF -u <(echo "$test_output") <(echo "$RULESET") - exit 1 -fi +diff -u <(echo "$test_output") <(echo "$RULESET") $NFT "add chain ip x c; add rule ip x c ip saddr @y" diff --git a/tests/shell/testcases/transactions/0003table_0 b/tests/shell/testcases/transactions/0003table_0 index 91186de..6861eab 100755 --- a/tests/shell/testcases/transactions/0003table_0 +++ b/tests/shell/testcases/transactions/0003table_0 @@ -14,6 +14,7 @@ fi KERNEL_RULESET="$($NFT list ruleset)" if [ "" != "$KERNEL_RULESET" ] ; then + DIFF="$(which diff)" echo "Got a ruleset, but expected empty: " echo "$KERNEL_RULESET" exit 1 @@ -41,6 +42,7 @@ $NFT -f - <<< "$RULESETFAIL" && exit 2 KERNEL_RULESET="$($NFT list ruleset)" if [ "$RULESET" != "$KERNEL_RULESET" ] ; then - $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$KERNEL_RULESET") exit 1 fi diff --git a/tests/shell/testcases/transactions/0040set_0 b/tests/shell/testcases/transactions/0040set_0 index 468816b..a404abc 100755 --- a/tests/shell/testcases/transactions/0040set_0 +++ b/tests/shell/testcases/transactions/0040set_0 @@ -29,7 +29,8 @@ fi GET="$($NFT list ruleset)" if [ "$RULESET" != "$GET" ] ; then - $DIFF -u <(echo "$RULESET") <(echo "$GET") + DIFF="$(which diff)" + [ -x $DIFF ] && $DIFF -u <(echo "$RULESET") <(echo "$GET") exit 1 fi