diff options
Diffstat (limited to 'include')
38 files changed, 555 insertions, 266 deletions
diff --git a/include/Makefile.am b/include/Makefile.am deleted file mode 100644 index ff56dfe4..00000000 --- a/include/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -SUBDIRS = linux \ - nftables - -noinst_HEADERS = cli.h \ - cache.h \ - cmd.h \ - datatype.h \ - expression.h \ - fib.h \ - hash.h \ - intervals.h \ - ipopt.h \ - json.h \ - mini-gmp.h \ - gmputil.h \ - iface.h \ - mnl.h \ - nftables.h \ - payload.h \ - tcpopt.h \ - statement.h \ - ct.h \ - erec.h \ - exthdr.h \ - headers.h \ - list.h \ - meta.h \ - misspell.h \ - numgen.h \ - netlink.h \ - osf.h \ - owner.h \ - parser.h \ - proto.h \ - sctp_chunk.h \ - socket.h \ - rule.h \ - rt.h \ - utils.h \ - xfrm.h \ - xt.h diff --git a/include/cache.h b/include/cache.h index 575381ef..c969534f 100644 --- a/include/cache.h +++ b/include/cache.h @@ -1,7 +1,9 @@ #ifndef _NFT_CACHE_H_ #define _NFT_CACHE_H_ -#include <string.h> +#include <list.h> + +struct handle; enum cache_level_bits { NFT_CACHE_TABLE_BIT = (1 << 0), @@ -29,7 +31,6 @@ enum cache_level_flags { NFT_CACHE_SET_BIT | NFT_CACHE_SETELEM_BIT, NFT_CACHE_RULE = NFT_CACHE_TABLE_BIT | - NFT_CACHE_CHAIN_BIT | NFT_CACHE_RULE_BIT, NFT_CACHE_FULL = __NFT_CACHE_MAX_BIT - 1, NFT_CACHE_TERSE = (1 << 27), @@ -53,22 +54,32 @@ struct nft_cache_filter { uint32_t family; const char *table; const char *chain; + const char *obj; const char *set; const char *ft; + int obj_type; + uint64_t rule_handle; } list; struct { struct list_head head; } obj[NFT_CACHE_HSIZE]; + + struct { + bool obj; + bool rule; + bool elem; + } reset; }; struct nft_cache; +struct nft_ctx; enum cmd_ops; int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds, struct list_head *msgs, struct nft_cache_filter *filter, unsigned int *flags); -int nft_cache_update(struct nft_ctx *ctx, enum cmd_ops cmd, +int nft_cache_update(struct nft_ctx *ctx, unsigned int flags, struct list_head *msgs, const struct nft_cache_filter *filter); bool nft_cache_needs_update(struct nft_cache *cache); @@ -94,6 +105,8 @@ void chain_cache_add(struct chain *chain, struct table *table); void chain_cache_del(struct chain *chain); struct chain *chain_cache_find(const struct table *table, const char *name); +struct set; + void set_cache_add(struct set *set, struct table *table); void set_cache_del(struct set *set); struct set *set_cache_find(const struct table *table, const char *name); @@ -110,7 +123,7 @@ struct cache_item { void cache_init(struct cache *cache); void cache_free(struct cache *cache); -void cache_add(struct cache_item *item, struct cache *cache, uint32_t hash); +void cache_add(struct cache_item *item, struct cache *cache, const char *name); void cache_del(struct cache_item *item); void table_cache_add(struct table *table, struct nft_cache *cache); @@ -118,6 +131,8 @@ void table_cache_del(struct table *table); struct table *table_cache_find(const struct cache *cache, const char *name, uint32_t family); +struct obj; + void obj_cache_add(struct obj *obj, struct table *table); void obj_cache_del(struct obj *obj); struct obj *obj_cache_find(const struct table *table, const char *name, @@ -135,6 +150,8 @@ struct nft_cache { uint32_t flags; }; +struct netlink_ctx; + void nft_chain_cache_update(struct netlink_ctx *ctx, struct table *table, const char *chain); diff --git a/include/cli.h b/include/cli.h index 609ed2ed..f0a0d47a 100644 --- a/include/cli.h +++ b/include/cli.h @@ -2,7 +2,6 @@ #define _NFT_CLI_H_ #include <nftables/libnftables.h> -#include <config.h> #if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT) || defined(HAVE_LIBLINENOISE) extern int cli_init(struct nft_ctx *nft); @@ -12,6 +11,6 @@ static inline int cli_init(struct nft_ctx *nft) return -1; } #endif -extern void cli_exit(void); +extern void cli_exit(int rc); #endif diff --git a/include/cmd.h b/include/cmd.h index 27fa6087..cf7e43bf 100644 --- a/include/cmd.h +++ b/include/cmd.h @@ -1,7 +1,14 @@ #ifndef _NFT_CMD_H_ #define _NFT_CMD_H_ +void cmd_add_loc(struct cmd *cmd, const struct nlmsghdr *nlh, const struct location *loc); +struct mnl_err; void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd, struct mnl_err *err); +bool nft_cmd_collapse_elems(enum cmd_ops op, struct list_head *cmds, + struct handle *handle, struct expr *init); + +void nft_cmd_expand(struct cmd *cmd); + #endif diff --git a/include/ct.h b/include/ct.h index efb2d418..bb9193d8 100644 --- a/include/ct.h +++ b/include/ct.h @@ -39,5 +39,11 @@ extern const char *ct_label2str(const struct symbol_table *tbl, extern const struct datatype ct_dir_type; extern const struct datatype ct_state_type; extern const struct datatype ct_status_type; +extern const struct datatype ct_label_type; +extern const struct datatype ct_event_type; + +extern const struct stmt_ops ct_stmt_ops; +extern const struct stmt_ops notrack_stmt_ops; +extern const struct stmt_ops flow_offload_stmt_ops; #endif /* NFTABLES_CT_H */ diff --git a/include/datatype.h b/include/datatype.h index 73f38f66..4fb47f15 100644 --- a/include/datatype.h +++ b/include/datatype.h @@ -1,7 +1,6 @@ #ifndef NFTABLES_DATATYPE_H #define NFTABLES_DATATYPE_H -#include <stdbool.h> #include <json.h> /** @@ -23,7 +22,7 @@ * @TYPE_INET_SERVICE: internet service (integer subtype) * @TYPE_ICMP_TYPE: ICMP type codes (integer subtype) * @TYPE_TCP_FLAG: TCP flag (bitmask subtype) - * @TCPE_DCCP_PKTTYPE: DCCP packet type (integer subtype) + * @TYPE_DCCP_PKTTYPE: DCCP packet type (integer subtype) * @TYPE_MH_TYPE: Mobility Header type (integer subtype) * @TYPE_TIME: relative time * @TYPE_MARK: packet mark (integer subtype) @@ -121,24 +120,12 @@ enum byteorder { struct expr; -/** - * enum datatype_flags - * - * @DTYPE_F_ALLOC: datatype is dynamically allocated - * @DTYPE_F_PREFIX: preferred representation for ranges is a prefix - */ -enum datatype_flags { - DTYPE_F_ALLOC = (1 << 0), - DTYPE_F_PREFIX = (1 << 1), -}; - struct parse_ctx; /** * struct datatype * * @type: numeric identifier * @byteorder: byteorder of type (non-basetypes only) - * @flags: flags * @size: type size (fixed sized non-basetypes only) * @subtypes: number of subtypes (concat type) * @name: type name @@ -148,12 +135,13 @@ struct parse_ctx; * @print: function to print a constant of this type * @parse: function to parse a symbol and return an expression * @sym_tbl: symbol table for this type - * @refcnt: reference counter (only for DTYPE_F_ALLOC) + * @refcnt: reference counter (only for dynamically allocated, see .alloc) */ struct datatype { uint32_t type; - enum byteorder byteorder; - unsigned int flags; + enum byteorder byteorder:8; + uint32_t alloc:1, + is_typeof:1; unsigned int size; unsigned int subtypes; const char *name; @@ -167,6 +155,7 @@ struct datatype { struct error_record *(*parse)(struct parse_ctx *ctx, const struct expr *sym, struct expr **res); + struct error_record *(*err)(const struct expr *sym); void (*describe)(struct output_ctx *octx); const struct symbol_table *sym_tbl; unsigned int refcnt; @@ -174,13 +163,16 @@ struct datatype { extern const struct datatype *datatype_lookup(enum datatypes type); extern const struct datatype *datatype_lookup_byname(const char *name); -extern struct datatype *datatype_get(const struct datatype *dtype); +extern const struct datatype *datatype_get(const struct datatype *dtype); extern void datatype_set(struct expr *expr, const struct datatype *dtype); +extern void __datatype_set(struct expr *expr, const struct datatype *dtype); extern void datatype_free(const struct datatype *dtype); -struct datatype *dtype_clone(const struct datatype *orig_dtype); +struct datatype *datatype_clone(const struct datatype *orig_dtype); +bool datatype_prefix_notation(const struct datatype *dtype); struct parse_ctx { struct symbol_tables *tbl; + const struct input_ctx *input; }; extern struct error_record *symbol_parse(struct parse_ctx *ctx, @@ -250,13 +242,15 @@ extern void symbol_table_print(const struct symbol_table *tbl, extern struct symbol_table *rt_symbol_table_init(const char *filename); extern void rt_symbol_table_free(const struct symbol_table *tbl); +extern void rt_symbol_table_describe(struct output_ctx *octx, const char *name, + const struct symbol_table *tbl, + const struct datatype *type); extern const struct datatype invalid_type; extern const struct datatype verdict_type; extern const struct datatype nfproto_type; extern const struct datatype bitmask_type; extern const struct datatype integer_type; -extern const struct datatype xinteger_type; extern const struct datatype string_type; extern const struct datatype lladdr_type; extern const struct datatype ipaddr_type; @@ -277,6 +271,16 @@ extern const struct datatype boolean_type; extern const struct datatype priority_type; extern const struct datatype policy_type; extern const struct datatype cgroupv2_type; +extern const struct datatype queue_type; + +/* private datatypes for reject statement. */ +extern const struct datatype reject_icmp_code_type; +extern const struct datatype reject_icmpv6_code_type; +extern const struct datatype reject_icmpx_code_type; + +/* TYPE_INTEGER aliases: */ +extern const struct datatype xinteger_type; +extern const struct datatype mptcpopt_subtype; void inet_service_type_print(const struct expr *expr, struct output_ctx *octx); @@ -299,7 +303,7 @@ concat_subtype_lookup(uint32_t type, unsigned int n) } extern const struct datatype * -set_datatype_alloc(const struct datatype *orig_dtype, unsigned int byteorder); +set_datatype_alloc(const struct datatype *orig_dtype, enum byteorder byteorder); extern void time_print(uint64_t msec, struct output_ctx *octx); extern struct error_record *time_parse(const struct location *loc, diff --git a/include/dccpopt.h b/include/dccpopt.h new file mode 100644 index 00000000..3617fc1a --- /dev/null +++ b/include/dccpopt.h @@ -0,0 +1,41 @@ +#ifndef NFTABLES_DCCPOPT_H +#define NFTABLES_DCCPOPT_H + +#include <nftables.h> + +#define DCCPOPT_TYPE_MIN 0 +#define DCCPOPT_TYPE_MAX UINT8_MAX + +enum dccpopt_fields { + DCCPOPT_FIELD_INVALID, + DCCPOPT_FIELD_TYPE, +}; + +enum dccpopt_types { + DCCPOPT_PADDING = 0, + DCCPOPT_MANDATORY = 1, + DCCPOPT_SLOW_RECEIVER = 2, + DCCPOPT_RESERVED_SHORT = 3, + DCCPOPT_CHANGE_L = 32, + DCCPOPT_CONFIRM_L = 33, + DCCPOPT_CHANGE_R = 34, + DCCPOPT_CONFIRM_R = 35, + DCCPOPT_INIT_COOKIE = 36, + DCCPOPT_NDP_COUNT = 37, + DCCPOPT_ACK_VECTOR_NONCE_0 = 38, + DCCPOPT_ACK_VECTOR_NONCE_1 = 39, + DCCPOPT_DATA_DROPPED = 40, + DCCPOPT_TIMESTAMP = 41, + DCCPOPT_TIMESTAMP_ECHO = 42, + DCCPOPT_ELAPSED_TIME = 43, + DCCPOPT_DATA_CHECKSUM = 44, + DCCPOPT_RESERVED_LONG = 45, + DCCPOPT_CCID_SPECIFIC = 128, +}; + +const struct exthdr_desc *dccpopt_find_desc(uint8_t type); +struct expr *dccpopt_expr_alloc(const struct location *loc, uint8_t type); +void dccpopt_init_raw(struct expr *expr, uint8_t type, unsigned int offset, + unsigned int len); + +#endif /* NFTABLES_DCCPOPT_H */ diff --git a/include/expression.h b/include/expression.h index cf7319b6..f42a0c2b 100644 --- a/include/expression.h +++ b/include/expression.h @@ -1,7 +1,6 @@ #ifndef NFTABLES_EXPRESSION_H #define NFTABLES_EXPRESSION_H -#include <stdbool.h> #include <gmputil.h> #include <linux/netfilter/nf_tables.h> @@ -12,6 +11,10 @@ #include <json.h> #include <libnftnl/udata.h> +#define NFT_MAX_EXPR_LEN_BYTES (NFT_REG32_COUNT * sizeof(uint32_t)) +#define NFT_MAX_EXPR_LEN_BITS (NFT_MAX_EXPR_LEN_BYTES * BITS_PER_BYTE) +#define NFT_MAX_EXPR_RECURSION 16 + /** * enum expr_types * @@ -41,6 +44,11 @@ * @EXPR_NUMGEN: number generation expression * @EXPR_HASH: hash expression * @EXPR_RT: routing expression + * @EXPR_FIB forward information base expression + * @EXPR_XFRM XFRM (ipsec) expression + * @EXPR_SET_ELEM_CATCHALL catchall element expression + * @EXPR_RANGE_VALUE constant range expression + * @EXPR_RANGE_SYMBOL unparse symbol range expression */ enum expr_types { EXPR_INVALID, @@ -72,9 +80,11 @@ enum expr_types { EXPR_FIB, EXPR_XFRM, EXPR_SET_ELEM_CATCHALL, - EXPR_FLAGCMP, + EXPR_RANGE_VALUE, + EXPR_RANGE_SYMBOL, + __EXPR_MAX }; -#define EXPR_MAX EXPR_XFRM +#define EXPR_MAX (__EXPR_MAX - 1) enum ops { OP_INVALID, @@ -116,7 +126,11 @@ enum symbol_types { * @maxval: expected maximum value */ struct expr_ctx { + /* expr_ctx does not own the reference to dtype. The caller must ensure + * the valid lifetime. + */ const struct datatype *dtype; + enum byteorder byteorder; unsigned int len; unsigned int maxval; @@ -181,7 +195,7 @@ struct expr_ops { }; const struct expr_ops *expr_ops(const struct expr *e); -const struct expr_ops *expr_ops_by_type(enum expr_types etype); +const struct expr_ops *expr_ops_by_type_u32(uint32_t value); /** * enum expr_flags @@ -203,6 +217,7 @@ enum expr_flags { EXPR_F_INTERVAL = 0x20, EXPR_F_KERNEL = 0x40, EXPR_F_REMOVE = 0x80, + EXPR_F_INTERVAL_OPEN = 0x100, }; #include <payload.h> @@ -243,13 +258,15 @@ struct expr { enum expr_types etype:8; enum ops op:8; unsigned int len; - struct cmd *cmd; union { struct { - /* EXPR_SYMBOL */ + /* EXPR_SYMBOL, EXPR_RANGE_SYMBOL */ const struct scope *scope; - const char *identifier; + union { + const char *identifier; + const char *identifier_range[2]; + }; enum symbol_types symtype; }; struct { @@ -267,6 +284,11 @@ struct expr { mpz_t value; }; struct { + /* EXPR_RANGE_VALUE */ + mpz_t low; + mpz_t high; + } range; + struct { /* EXPR_PREFIX */ struct expr *prefix; unsigned int prefix_len; @@ -290,7 +312,6 @@ struct expr { uint64_t expiration; const char *comment; struct list_head stmt_list; - uint32_t elem_flags; }; struct { /* EXPR_UNARY */ @@ -311,6 +332,7 @@ struct expr { /* EXPR_PAYLOAD */ const struct proto_desc *desc; const struct proto_hdr_template *tmpl; + const struct proto_desc *inner_desc; enum proto_bases base; unsigned int offset; bool is_raw; @@ -329,6 +351,7 @@ struct expr { /* EXPR_META */ enum nft_meta_keys key; enum proto_bases base; + const struct proto_desc *inner_desc; } meta; struct { /* SOCKET */ @@ -377,12 +400,6 @@ struct expr { uint8_t ttl; uint32_t flags; } osf; - struct { - /* EXPR_FLAGCMP */ - struct expr *expr; - struct expr *mask; - struct expr *value; - } flagcmp; }; }; @@ -401,8 +418,6 @@ extern const struct datatype *expr_basetype(const struct expr *expr); extern void expr_set_type(struct expr *expr, const struct datatype *dtype, enum byteorder byteorder); -void expr_to_string(const struct expr *expr, char *string); - struct eval_ctx; extern int expr_binary_error(struct list_head *msgs, const struct expr *e1, const struct expr *e2, @@ -462,6 +477,16 @@ extern struct expr *constant_expr_join(const struct expr *e1, const struct expr *e2); extern struct expr *constant_expr_splice(struct expr *expr, unsigned int len); +extern struct expr *constant_range_expr_alloc(const struct location *loc, + const struct datatype *dtype, + enum byteorder byteorder, + unsigned int len, + mpz_t low, mpz_t high); + +struct expr *symbol_range_expr_alloc(const struct location *loc, + enum symbol_types type, const struct scope *scope, + const char *identifier_low, const char *identifier_high); + extern struct expr *flag_expr_alloc(const struct location *loc, const struct datatype *dtype, enum byteorder byteorder, @@ -486,6 +511,7 @@ extern void list_splice_sorted(struct list_head *list, struct list_head *head); extern struct expr *concat_expr_alloc(const struct location *loc); extern struct expr *list_expr_alloc(const struct location *loc); +struct expr *list_expr_to_binop(struct expr *expr); extern struct expr *set_expr_alloc(const struct location *loc, const struct set *set); @@ -510,11 +536,8 @@ extern struct expr *set_elem_expr_alloc(const struct location *loc, struct expr *set_elem_catchall_expr_alloc(const struct location *loc); -struct expr *flagcmp_expr_alloc(const struct location *loc, enum ops op, - struct expr *expr, struct expr *mask, - struct expr *value); - 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); +void range_expr_swap_values(struct expr *range); #endif /* NFTABLES_EXPRESSION_H */ diff --git a/include/exthdr.h b/include/exthdr.h index 1bc756f9..98494e4d 100644 --- a/include/exthdr.h +++ b/include/exthdr.h @@ -4,6 +4,7 @@ #include <proto.h> #include <tcpopt.h> #include <ipopt.h> +#include <dccpopt.h> enum exthdr_desc_id { EXTHDR_DESC_UNKNOWN = 0, @@ -116,4 +117,6 @@ extern const struct exthdr_desc exthdr_dst; extern const struct exthdr_desc exthdr_mh; extern const struct datatype mh_type_type; +extern const struct stmt_ops exthdr_stmt_ops; + #endif /* NFTABLES_EXTHDR_H */ diff --git a/include/fib.h b/include/fib.h index 67edccfe..07bb2210 100644 --- a/include/fib.h +++ b/include/fib.h @@ -3,7 +3,7 @@ #include <linux/netfilter/nf_tables.h> -extern const char *fib_result_str(enum nft_fib_result result); +extern const char *fib_result_str(const struct expr *expr); extern struct expr *fib_expr_alloc(const struct location *loc, unsigned int flags, unsigned int result); diff --git a/include/gmputil.h b/include/gmputil.h index 0cb85a7d..d1f4dcd2 100644 --- a/include/gmputil.h +++ b/include/gmputil.h @@ -1,8 +1,6 @@ #ifndef NFTABLES_GMPUTIL_H #define NFTABLES_GMPUTIL_H -#include <config.h> - #ifdef HAVE_LIBGMP #include <gmp.h> #else @@ -79,4 +77,6 @@ extern void __mpz_switch_byteorder(mpz_t rop, unsigned int len); __mpz_switch_byteorder(rop, len); \ } +void nft_gmp_free(void *ptr); + #endif /* NFTABLES_GMPUTIL_H */ diff --git a/include/headers.h b/include/headers.h index 759f93bf..13324c72 100644 --- a/include/headers.h +++ b/include/headers.h @@ -1,6 +1,8 @@ #ifndef NFTABLES_HEADERS_H #define NFTABLES_HEADERS_H +#include <netinet/in.h> + #ifndef IPPROTO_UDPLITE # define IPPROTO_UDPLITE 136 #endif diff --git a/include/iface.h b/include/iface.h index f41ee8be..786b1dfc 100644 --- a/include/iface.h +++ b/include/iface.h @@ -2,6 +2,7 @@ #define _NFTABLES_IFACE_H_ #include <net/if.h> +#include <list.h> struct iface { struct list_head list; @@ -15,4 +16,5 @@ char *nft_if_indextoname(unsigned int ifindex, char *name); void iface_cache_update(void); void iface_cache_release(void); +const struct iface *iface_cache_get_next_entry(const struct iface *prev); #endif diff --git a/include/intervals.h b/include/intervals.h index 964804b1..2366c295 100644 --- a/include/intervals.h +++ b/include/intervals.h @@ -1,12 +1,13 @@ #ifndef NFTABLES_INTERVALS_H #define NFTABLES_INTERVALS_H -void set_to_range(struct expr *init); int set_automerge(struct list_head *msgs, struct cmd *cmd, struct set *set, struct expr *init, unsigned int debug_mask); int set_delete(struct list_head *msgs, struct cmd *cmd, struct set *set, struct expr *init, unsigned int debug_mask); int set_overlap(struct list_head *msgs, struct set *set, struct expr *init); int set_to_intervals(const struct set *set, struct expr *init, bool add); +int setelem_to_interval(const struct set *set, struct expr *elem, + struct expr *next_elem, struct list_head *interval_list); #endif diff --git a/include/json.h b/include/json.h index b0d78eb8..b61eeafe 100644 --- a/include/json.h +++ b/include/json.h @@ -11,6 +11,7 @@ struct nlmsghdr; struct rule; struct set; struct obj; +struct flowtable; struct stmt; struct symbol_table; struct table; @@ -28,7 +29,6 @@ struct list_head; json_t *binop_expr_json(const struct expr *expr, struct output_ctx *octx); json_t *relational_expr_json(const struct expr *expr, struct output_ctx *octx); -json_t *flagcmp_expr_json(const struct expr *expr, struct output_ctx *octx); json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx); json_t *meta_expr_json(const struct expr *expr, struct output_ctx *octx); json_t *payload_expr_json(const struct expr *expr, struct output_ctx *octx); @@ -74,6 +74,7 @@ json_t *payload_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *exthdr_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *quota_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *ct_stmt_json(const struct stmt *stmt, struct output_ctx *octx); +json_t *last_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *limit_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *fwd_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *notrack_stmt_json(const struct stmt *stmt, struct output_ctx *octx); @@ -83,6 +84,7 @@ json_t *nat_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *reject_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *counter_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *set_stmt_json(const struct stmt *stmt, struct output_ctx *octx); +json_t *map_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *log_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *objref_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx); @@ -92,6 +94,7 @@ json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx); json_t *optstrip_stmt_json(const struct stmt *stmt, struct output_ctx *octx); +json_t *xt_stmt_json(const struct stmt *stmt, struct output_ctx *octx); int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd); @@ -110,6 +113,8 @@ void monitor_print_element_json(struct netlink_mon_handler *monh, const char *cmd, struct set *s); void monitor_print_obj_json(struct netlink_mon_handler *monh, const char *cmd, struct obj *o); +void monitor_print_flowtable_json(struct netlink_mon_handler *monh, + const char *cmd, struct flowtable *ft); void monitor_print_rule_json(struct netlink_mon_handler *monh, const char *cmd, struct rule *r); @@ -131,7 +136,6 @@ static inline json_t *name##_json(arg1_t arg1, arg2_t arg2) { return NULL; } JSON_PRINT_STUB(name##_stmt, const struct stmt *, struct output_ctx *) EXPR_PRINT_STUB(binop_expr) -EXPR_PRINT_STUB(flagcmp_expr) EXPR_PRINT_STUB(relational_expr) EXPR_PRINT_STUB(range_expr) EXPR_PRINT_STUB(meta_expr) @@ -176,6 +180,7 @@ STMT_PRINT_STUB(payload) STMT_PRINT_STUB(exthdr) STMT_PRINT_STUB(quota) STMT_PRINT_STUB(ct) +STMT_PRINT_STUB(last) STMT_PRINT_STUB(limit) STMT_PRINT_STUB(fwd) STMT_PRINT_STUB(notrack) @@ -185,6 +190,7 @@ STMT_PRINT_STUB(nat) STMT_PRINT_STUB(reject) STMT_PRINT_STUB(counter) STMT_PRINT_STUB(set) +STMT_PRINT_STUB(map) STMT_PRINT_STUB(log) STMT_PRINT_STUB(objref) STMT_PRINT_STUB(meter) @@ -194,6 +200,7 @@ STMT_PRINT_STUB(connlimit) STMT_PRINT_STUB(tproxy) STMT_PRINT_STUB(synproxy) STMT_PRINT_STUB(optstrip) +STMT_PRINT_STUB(xt) #undef STMT_PRINT_STUB #undef EXPR_PRINT_STUB @@ -248,6 +255,13 @@ static inline void monitor_print_obj_json(struct netlink_mon_handler *monh, /* empty */ } +static inline void +monitor_print_flowtable_json(struct netlink_mon_handler *monh, + const char *cmd, struct flowtable *ft) +{ + /* empty */ +} + static inline void monitor_print_rule_json(struct netlink_mon_handler *monh, const char *cmd, struct rule *r) { diff --git a/include/linux/Makefile.am b/include/linux/Makefile.am deleted file mode 100644 index eb9fc4e4..00000000 --- a/include/linux/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -SUBDIRS = netfilter \ - netfilter_arp \ - netfilter_bridge \ - netfilter_ipv4 \ - netfilter_ipv6 - -noinst_HEADERS = netfilter_arp.h \ - netfilter_bridge.h \ - netfilter_decnet.h \ - netfilter.h \ - netfilter_ipv4.h \ - netfilter_ipv6.h diff --git a/include/linux/netfilter/Makefile.am b/include/linux/netfilter/Makefile.am deleted file mode 100644 index 22f66a7e..00000000 --- a/include/linux/netfilter/Makefile.am +++ /dev/null @@ -1,10 +0,0 @@ -noinst_HEADERS = nf_conntrack_common.h \ - nf_conntrack_tuple_common.h \ - nf_log.h \ - nf_nat.h \ - nf_tables.h \ - nf_tables_compat.h \ - nf_synproxy.h \ - nfnetlink_osf.h \ - nfnetlink_hook.h \ - nfnetlink.h diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 75df968d..f57963e8 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -97,6 +97,15 @@ enum nft_verdicts { * @NFT_MSG_NEWFLOWTABLE: add new flow table (enum nft_flowtable_attributes) * @NFT_MSG_GETFLOWTABLE: get flow table (enum nft_flowtable_attributes) * @NFT_MSG_DELFLOWTABLE: delete flow table (enum nft_flowtable_attributes) + * @NFT_MSG_GETRULE_RESET: get rules and reset stateful expressions (enum nft_obj_attributes) + * @NFT_MSG_DESTROYTABLE: destroy a table (enum nft_table_attributes) + * @NFT_MSG_DESTROYCHAIN: destroy a chain (enum nft_chain_attributes) + * @NFT_MSG_DESTROYRULE: destroy a rule (enum nft_rule_attributes) + * @NFT_MSG_DESTROYSET: destroy a set (enum nft_set_attributes) + * @NFT_MSG_DESTROYSETELEM: destroy a set element (enum nft_set_elem_attributes) + * @NFT_MSG_DESTROYOBJ: destroy a stateful object (enum nft_object_attributes) + * @NFT_MSG_DESTROYFLOWTABLE: destroy flow table (enum nft_flowtable_attributes) + * @NFT_MSG_GETSETELEM_RESET: get set elements and reset attached stateful expressio ns (enum nft_set_elem_attributes) */ enum nf_tables_msg_types { NFT_MSG_NEWTABLE, @@ -124,6 +133,15 @@ enum nf_tables_msg_types { NFT_MSG_NEWFLOWTABLE, NFT_MSG_GETFLOWTABLE, NFT_MSG_DELFLOWTABLE, + NFT_MSG_GETRULE_RESET, + NFT_MSG_DESTROYTABLE, + NFT_MSG_DESTROYCHAIN, + NFT_MSG_DESTROYRULE, + NFT_MSG_DESTROYSET, + NFT_MSG_DESTROYSETELEM, + NFT_MSG_DESTROYOBJ, + NFT_MSG_DESTROYFLOWTABLE, + NFT_MSG_GETSETELEM_RESET, NFT_MSG_MAX, }; @@ -164,7 +182,10 @@ enum nft_hook_attributes { */ enum nft_table_flags { NFT_TABLE_F_DORMANT = 0x1, + NFT_TABLE_F_OWNER = 0x2, }; +#define NFT_TABLE_F_MASK (NFT_TABLE_F_DORMANT | \ + NFT_TABLE_F_OWNER) /** * enum nft_table_attributes - nf_tables table netlink attributes @@ -173,6 +194,7 @@ enum nft_table_flags { * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32) * @NFTA_TABLE_USE: number of chains in this table (NLA_U32) * @NFTA_TABLE_USERDATA: user data (NLA_BINARY) + * @NFTA_TABLE_OWNER: owner of this table through netlink portID (NLA_U32) */ enum nft_table_attributes { NFTA_TABLE_UNSPEC, @@ -182,6 +204,7 @@ enum nft_table_attributes { NFTA_TABLE_HANDLE, NFTA_TABLE_PAD, NFTA_TABLE_USERDATA, + NFTA_TABLE_OWNER, __NFTA_TABLE_MAX }; #define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1) @@ -534,16 +557,27 @@ enum nft_immediate_attributes { /** * enum nft_bitwise_ops - nf_tables bitwise operations * - * @NFT_BITWISE_BOOL: mask-and-xor operation used to implement NOT, AND, OR and - * XOR boolean operations + * @NFT_BITWISE_MASK_XOR: mask-and-xor operation used to implement NOT, AND, OR + * and XOR boolean operations * @NFT_BITWISE_LSHIFT: left-shift operation * @NFT_BITWISE_RSHIFT: right-shift operation + * @NFT_BITWISE_AND: and operation + * @NFT_BITWISE_OR: or operation + * @NFT_BITWISE_XOR: xor operation */ enum nft_bitwise_ops { - NFT_BITWISE_BOOL, + NFT_BITWISE_MASK_XOR, NFT_BITWISE_LSHIFT, NFT_BITWISE_RSHIFT, + NFT_BITWISE_AND, + NFT_BITWISE_OR, + NFT_BITWISE_XOR, }; +/* + * Old name for NFT_BITWISE_MASK_XOR, predating the addition of NFT_BITWISE_AND, + * NFT_BITWISE_OR and NFT_BITWISE_XOR. Retained for backwards-compatibility. + */ +#define NFT_BITWISE_BOOL NFT_BITWISE_MASK_XOR /** * enum nft_bitwise_attributes - nf_tables bitwise expression netlink attributes @@ -556,6 +590,7 @@ enum nft_bitwise_ops { * @NFTA_BITWISE_OP: type of operation (NLA_U32: nft_bitwise_ops) * @NFTA_BITWISE_DATA: argument for non-boolean operations * (NLA_NESTED: nft_data_attributes) + * @NFTA_BITWISE_SREG2: second source register (NLA_U32: nft_registers) * * The bitwise expression supports boolean and shift operations. It implements * the boolean operations by performing the following operation: @@ -579,6 +614,7 @@ enum nft_bitwise_attributes { NFTA_BITWISE_XOR, NFTA_BITWISE_OP, NFTA_BITWISE_DATA, + NFTA_BITWISE_SREG2, __NFTA_BITWISE_MAX }; #define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1) @@ -748,11 +784,14 @@ enum nft_dynset_attributes { * @NFT_PAYLOAD_LL_HEADER: link layer header * @NFT_PAYLOAD_NETWORK_HEADER: network header * @NFT_PAYLOAD_TRANSPORT_HEADER: transport header + * @NFT_PAYLOAD_INNER_HEADER: inner header / payload */ enum nft_payload_bases { NFT_PAYLOAD_LL_HEADER, NFT_PAYLOAD_NETWORK_HEADER, NFT_PAYLOAD_TRANSPORT_HEADER, + NFT_PAYLOAD_INNER_HEADER, + NFT_PAYLOAD_TUN_HEADER, }; /** @@ -772,6 +811,32 @@ enum nft_payload_csum_flags { NFT_PAYLOAD_L4CSUM_PSEUDOHDR = (1 << 0), }; +enum nft_inner_type { + NFT_INNER_UNSPEC = 0, + NFT_INNER_VXLAN, + NFT_INNER_GENEVE, +}; + +enum nft_inner_flags { + NFT_INNER_HDRSIZE = (1 << 0), + NFT_INNER_LL = (1 << 1), + NFT_INNER_NH = (1 << 2), + NFT_INNER_TH = (1 << 3), +}; +#define NFT_INNER_MASK (NFT_INNER_HDRSIZE | NFT_INNER_LL | \ + NFT_INNER_NH | NFT_INNER_TH) + +enum nft_inner_attributes { + NFTA_INNER_UNSPEC, + NFTA_INNER_NUM, + NFTA_INNER_TYPE, + NFTA_INNER_FLAGS, + NFTA_INNER_HDRSIZE, + NFTA_INNER_EXPR, + __NFTA_INNER_MAX +}; +#define NFTA_INNER_MAX (__NFTA_INNER_MAX - 1) + /** * enum nft_payload_attributes - nf_tables payload expression netlink attributes * @@ -809,12 +874,14 @@ enum nft_exthdr_flags { * @NFT_EXTHDR_OP_TCP: match against tcp options * @NFT_EXTHDR_OP_IPV4: match against ipv4 options * @NFT_EXTHDR_OP_SCTP: match against sctp chunks + * @NFT_EXTHDR_OP_DCCP: match against dccp options */ enum nft_exthdr_op { NFT_EXTHDR_OP_IPV6, NFT_EXTHDR_OP_TCPOPT, NFT_EXTHDR_OP_IPV4, NFT_EXTHDR_OP_SCTP, + NFT_EXTHDR_OP_DCCP, __NFT_EXTHDR_OP_MAX }; #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1) @@ -881,6 +948,7 @@ enum nft_exthdr_attributes { * @NFT_META_TIME_HOUR: hour of day (in seconds) * @NFT_META_SDIF: slave device interface index * @NFT_META_SDIFNAME: slave device interface name + * @NFT_META_BRI_BROUTE: packet br_netfilter_broute bit */ enum nft_meta_keys { NFT_META_LEN, @@ -891,7 +959,8 @@ enum nft_meta_keys { NFT_META_OIF, NFT_META_IIFNAME, NFT_META_OIFNAME, - NFT_META_IIFTYPE, + NFT_META_IFTYPE, +#define NFT_META_IIFTYPE NFT_META_IFTYPE NFT_META_OIFTYPE, NFT_META_SKUID, NFT_META_SKGID, @@ -918,6 +987,8 @@ enum nft_meta_keys { NFT_META_TIME_HOUR, NFT_META_SDIF, NFT_META_SDIFNAME, + NFT_META_BRI_BROUTE, + __NFT_META_IIFTYPE, }; /** @@ -1013,6 +1084,7 @@ enum nft_rt_attributes { * * @NFTA_SOCKET_KEY: socket key to match * @NFTA_SOCKET_DREG: destination register + * @NFTA_SOCKET_LEVEL: cgroups2 ancestor level (only for cgroupsv2) */ enum nft_socket_attributes { NFTA_SOCKET_UNSPEC, @@ -1029,6 +1101,7 @@ enum nft_socket_attributes { * @NFT_SOCKET_TRANSPARENT: Value of the IP(V6)_TRANSPARENT socket option * @NFT_SOCKET_MARK: Value of the socket mark * @NFT_SOCKET_WILDCARD: Whether the socket is zero-bound (e.g. 0.0.0.0 or ::0) + * @NFT_SOCKET_CGROUPV2: Match on cgroups version 2 */ enum nft_socket_keys { NFT_SOCKET_TRANSPARENT, @@ -1189,6 +1262,21 @@ enum nft_counter_attributes { #define NFTA_COUNTER_MAX (__NFTA_COUNTER_MAX - 1) /** + * enum nft_last_attributes - nf_tables last expression netlink attributes + * + * @NFTA_LAST_SET: last update has been set, zero means never updated (NLA_U32) + * @NFTA_LAST_MSECS: milliseconds since last update (NLA_U64) + */ +enum nft_last_attributes { + NFTA_LAST_UNSPEC, + NFTA_LAST_SET, + NFTA_LAST_MSECS, + NFTA_LAST_PAD, + __NFTA_LAST_MAX +}; +#define NFTA_LAST_MAX (__NFTA_LAST_MAX - 1) + +/** * enum nft_log_attributes - nf_tables log expression netlink attributes * * @NFTA_LOG_GROUP: netlink group to send messages to (NLA_U32) diff --git a/include/linux/netfilter/nfnetlink_hook.h b/include/linux/netfilter/nfnetlink_hook.h index bbcd285b..84a561a7 100644 --- a/include/linux/netfilter/nfnetlink_hook.h +++ b/include/linux/netfilter/nfnetlink_hook.h @@ -32,8 +32,12 @@ enum nfnl_hook_attributes { /** * enum nfnl_hook_chain_info_attributes - chain description * - * NFNLA_HOOK_INFO_DESC: nft chain and table name (enum nft_table_attributes) (NLA_NESTED) - * NFNLA_HOOK_INFO_TYPE: chain type (enum nfnl_hook_chaintype) (NLA_U32) + * @NFNLA_HOOK_INFO_DESC: nft chain and table name (NLA_NESTED) + * @NFNLA_HOOK_INFO_TYPE: chain type (enum nfnl_hook_chaintype) (NLA_U32) + * + * NFNLA_HOOK_INFO_DESC depends on NFNLA_HOOK_INFO_TYPE value: + * NFNL_HOOK_TYPE_NFTABLES: enum nft_table_attributes + * NFNL_HOOK_TYPE_BPF: enum nfnl_hook_bpf_attributes */ enum nfnl_hook_chain_info_attributes { NFNLA_HOOK_INFO_UNSPEC, @@ -55,10 +59,24 @@ enum nfnl_hook_chain_desc_attributes { /** * enum nfnl_hook_chaintype - chain type * - * @NFNL_HOOK_TYPE_NFTABLES nf_tables base chain + * @NFNL_HOOK_TYPE_NFTABLES: nf_tables base chain + * @NFNL_HOOK_TYPE_BPF: bpf program */ enum nfnl_hook_chaintype { NFNL_HOOK_TYPE_NFTABLES = 0x1, + NFNL_HOOK_TYPE_BPF, +}; + +/** + * enum nfnl_hook_bpf_attributes - bpf prog description + * + * @NFNLA_HOOK_BPF_ID: bpf program id (NLA_U32) + */ +enum nfnl_hook_bpf_attributes { + NFNLA_HOOK_BPF_UNSPEC, + NFNLA_HOOK_BPF_ID, + __NFNLA_HOOK_BPF_MAX, }; +#define NFNLA_HOOK_BPF_MAX (__NFNLA_HOOK_BPF_MAX - 1) #endif /* _NFNL_HOOK_H */ diff --git a/include/linux/netfilter_arp/Makefile.am b/include/linux/netfilter_arp/Makefile.am deleted file mode 100644 index 0a16c1ab..00000000 --- a/include/linux/netfilter_arp/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -noinst_HEADERS = arp_tables.h diff --git a/include/linux/netfilter_bridge/Makefile.am b/include/linux/netfilter_bridge/Makefile.am deleted file mode 100644 index d2e8b38b..00000000 --- a/include/linux/netfilter_bridge/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -noinst_HEADERS = ebtables.h diff --git a/include/linux/netfilter_decnet.h b/include/linux/netfilter_decnet.h deleted file mode 100644 index ca70c6cd..00000000 --- a/include/linux/netfilter_decnet.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __LINUX_DECNET_NETFILTER_H -#define __LINUX_DECNET_NETFILTER_H - -/* DECnet-specific defines for netfilter. - * This file (C) Steve Whitehouse 1999 derived from the - * ipv4 netfilter header file which is - * (C)1998 Rusty Russell -- This code is GPL. - */ - -#include <linux/netfilter.h> - -/* only for userspace compatibility */ -/* IP Cache bits. */ -/* Src IP address. */ -#define NFC_DN_SRC 0x0001 -/* Dest IP address. */ -#define NFC_DN_DST 0x0002 -/* Input device. */ -#define NFC_DN_IF_IN 0x0004 -/* Output device. */ -#define NFC_DN_IF_OUT 0x0008 - -/* DECnet Hooks */ -/* After promisc drops, checksum checks. */ -#define NF_DN_PRE_ROUTING 0 -/* If the packet is destined for this box. */ -#define NF_DN_LOCAL_IN 1 -/* If the packet is destined for another interface. */ -#define NF_DN_FORWARD 2 -/* Packets coming from a local process. */ -#define NF_DN_LOCAL_OUT 3 -/* Packets about to hit the wire. */ -#define NF_DN_POST_ROUTING 4 -/* Input Hello Packets */ -#define NF_DN_HELLO 5 -/* Input Routing Packets */ -#define NF_DN_ROUTE 6 -#define NF_DN_NUMHOOKS 7 - -enum nf_dn_hook_priorities { - NF_DN_PRI_FIRST = INT_MIN, - NF_DN_PRI_CONNTRACK = -200, - NF_DN_PRI_MANGLE = -150, - NF_DN_PRI_NAT_DST = -100, - NF_DN_PRI_FILTER = 0, - NF_DN_PRI_NAT_SRC = 100, - NF_DN_PRI_DNRTMSG = 200, - NF_DN_PRI_LAST = INT_MAX, -}; - -struct nf_dn_rtmsg { - int nfdn_ifindex; -}; - -#define NFDN_RTMSG(r) ((unsigned char *)(r) + NLMSG_ALIGN(sizeof(struct nf_dn_rtmsg))) - -/* backwards compatibility for userspace */ -#define DNRMG_L1_GROUP 0x01 -#define DNRMG_L2_GROUP 0x02 - -enum { - DNRNG_NLGRP_NONE, -#define DNRNG_NLGRP_NONE DNRNG_NLGRP_NONE - DNRNG_NLGRP_L1, -#define DNRNG_NLGRP_L1 DNRNG_NLGRP_L1 - DNRNG_NLGRP_L2, -#define DNRNG_NLGRP_L2 DNRNG_NLGRP_L2 - __DNRNG_NLGRP_MAX -}; -#define DNRNG_NLGRP_MAX (__DNRNG_NLGRP_MAX - 1) - -#endif /*__LINUX_DECNET_NETFILTER_H*/ diff --git a/include/linux/netfilter_ipv4/Makefile.am b/include/linux/netfilter_ipv4/Makefile.am deleted file mode 100644 index fec42533..00000000 --- a/include/linux/netfilter_ipv4/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -noinst_HEADERS = ip_tables.h diff --git a/include/linux/netfilter_ipv6/Makefile.am b/include/linux/netfilter_ipv6/Makefile.am deleted file mode 100644 index bec6c3f1..00000000 --- a/include/linux/netfilter_ipv6/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -noinst_HEADERS = ip6_tables.h diff --git a/include/list.h b/include/list.h index 857921e3..4382a670 100644 --- a/include/list.h +++ b/include/list.h @@ -349,6 +349,25 @@ static inline void list_splice_tail_init(struct list_head *list, list_entry((ptr)->next, type, member) /** + * list_prev_entry - get the prev element in list + * @ptr: the type * to cursor + * @member: the name of the list_head within the struct. + */ +#define list_prev_entry(ptr, member) \ + list_entry((ptr)->member.prev, typeof(*(ptr)), member) + +/** + * list_last_entry - get the last element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_head within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +/** * list_next_entry - get the next element in list * @pos: the type * to cursor * @member: the name of the list_head within the struct. diff --git a/include/meta.h b/include/meta.h index 1478902e..84937ba3 100644 --- a/include/meta.h +++ b/include/meta.h @@ -45,4 +45,8 @@ extern const struct datatype date_type; extern const struct datatype hour_type; extern const struct datatype day_type; +bool lhs_is_meta_hour(const struct expr *meta); + +extern const struct stmt_ops meta_stmt_ops; + #endif /* NFTABLES_META_H */ diff --git a/include/mnl.h b/include/mnl.h index 8e0a7e3f..f50ac644 100644 --- a/include/mnl.h +++ b/include/mnl.h @@ -8,7 +8,7 @@ struct mnl_socket *nft_mnl_socket_open(void); -uint32_t mnl_seqnum_alloc(uint32_t *seqnum); +uint32_t mnl_seqnum_inc(uint32_t *seqnum); uint32_t mnl_genid_get(struct netlink_ctx *ctx); struct mnl_err { @@ -34,7 +34,9 @@ int mnl_nft_rule_del(struct netlink_ctx *ctx, struct cmd *cmd); int mnl_nft_rule_replace(struct netlink_ctx *ctx, struct cmd *cmd); struct nftnl_rule_list *mnl_nft_rule_dump(struct netlink_ctx *ctx, int family, - const char *table, const char *chain); + const char *table, const char *chain, + uint64_t rule_handle, + bool dump, bool reset); int mnl_nft_chain_add(struct netlink_ctx *ctx, struct cmd *cmd, unsigned int flags); @@ -64,11 +66,14 @@ int mnl_nft_setelem_add(struct netlink_ctx *ctx, struct cmd *cmd, const struct set *set, const struct expr *expr, unsigned int flags); int mnl_nft_setelem_del(struct netlink_ctx *ctx, struct cmd *cmd, - const struct handle *h, const struct expr *init); + const struct handle *h, const struct set *set, + const struct expr *init); int mnl_nft_setelem_flush(struct netlink_ctx *ctx, const struct cmd *cmd); -int mnl_nft_setelem_get(struct netlink_ctx *ctx, struct nftnl_set *nls); +int mnl_nft_setelem_get(struct netlink_ctx *ctx, struct nftnl_set *nls, + bool reset); struct nftnl_set *mnl_nft_setelem_get_one(struct netlink_ctx *ctx, - struct nftnl_set *nls); + struct nftnl_set *nls, + bool reset); struct nftnl_obj_list *mnl_nft_obj_dump(struct netlink_ctx *ctx, int family, const char *table, @@ -86,7 +91,7 @@ int mnl_nft_flowtable_add(struct netlink_ctx *ctx, struct cmd *cmd, unsigned int flags); int mnl_nft_flowtable_del(struct netlink_ctx *ctx, struct cmd *cmd); -int mnl_nft_dump_nf_hooks(struct netlink_ctx *ctx, int family, int hook, +int mnl_nft_dump_nf_hooks(struct netlink_ctx *ctx, int family, const char *devname); int mnl_nft_event_listener(struct mnl_socket *nf_sock, unsigned int debug_mask, diff --git a/include/netlink.h b/include/netlink.h index 63d07edf..c7da6f9e 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -40,6 +40,8 @@ struct netlink_parse_ctx { struct expr *registers[MAX_REGS + 1]; unsigned int debug_mask; struct netlink_ctx *nlctx; + bool inner; + uint8_t inner_reg; }; @@ -49,11 +51,17 @@ struct netlink_parse_ctx { #define RULE_PP_REMOVE_OP_AND (RULE_PP_IN_CONCATENATION | \ RULE_PP_IN_SET_ELEM) -struct rule_pp_ctx { +struct dl_proto_ctx { struct proto_ctx pctx; struct payload_dep_ctx pdctx; +}; + +struct rule_pp_ctx { + struct dl_proto_ctx _dl[2]; + struct dl_proto_ctx *dl; struct stmt *stmt; unsigned int flags; + struct set *set; }; extern const struct input_descriptor indesc_netlink; @@ -77,6 +85,7 @@ struct netlink_ctx { const void *data; uint32_t seqnum; struct nftnl_batch *batch; + int maybe_emsgsize; }; extern struct nftnl_expr *alloc_nft_expr(const char *name); @@ -88,11 +97,12 @@ extern struct nftnl_table *netlink_table_alloc(const struct nlmsghdr *nlh); extern struct nftnl_chain *netlink_chain_alloc(const struct nlmsghdr *nlh); extern struct nftnl_set *netlink_set_alloc(const struct nlmsghdr *nlh); extern struct nftnl_obj *netlink_obj_alloc(const struct nlmsghdr *nlh); +extern struct nftnl_flowtable *netlink_flowtable_alloc(const struct nlmsghdr *nlh); extern struct nftnl_rule *netlink_rule_alloc(const struct nlmsghdr *nlh); struct nft_data_linearize { uint32_t len; - uint32_t value[4]; + uint32_t value[NFT_REG32_COUNT]; char chain[NFT_CHAIN_MAXNAMELEN]; uint32_t chain_id; int verdict; @@ -157,17 +167,16 @@ extern struct stmt *netlink_parse_set_expr(const struct set *set, const struct nftnl_expr *nle); extern int netlink_list_setelems(struct netlink_ctx *ctx, - const struct handle *h, struct set *set); + const struct handle *h, struct set *set, + bool reset); extern int netlink_get_setelem(struct netlink_ctx *ctx, const struct handle *h, const struct location *loc, struct set *cache_set, - struct set *set, struct expr *init); -extern int netlink_delinearize_setelem(struct nftnl_set_elem *nlse, - struct set *set, - struct nft_cache *cache); + struct set *set, struct expr *init, bool reset); +extern int netlink_delinearize_setelem(struct netlink_ctx *ctx, + struct nftnl_set_elem *nlse, + struct set *set); extern int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h); -extern int netlink_reset_objs(struct netlink_ctx *ctx, const struct cmd *cmd, - uint32_t type, bool dump); extern struct obj *netlink_delinearize_obj(struct netlink_ctx *ctx, struct nftnl_obj *nlo); @@ -246,4 +255,6 @@ struct nft_expr_loc { struct nft_expr_loc *nft_expr_loc_find(const struct nftnl_expr *nle, struct netlink_linearize_ctx *ctx); +struct dl_proto_ctx *dl_proto_ctx(struct rule_pp_ctx *ctx); + #endif /* NFTABLES_NETLINK_H */ diff --git a/include/nft.h b/include/nft.h new file mode 100644 index 00000000..a2d62dbf --- /dev/null +++ b/include/nft.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef NFTABLES_NFT_H +#define NFTABLES_NFT_H + +#include <config.h> + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +/* Just free(), but casts to a (void*). This is for places where + * we have a const pointer that we know we want to free. We could just + * do the (void*) cast, but free_const() makes it clear that this is + * something we frequently need to do and it's intentional. */ +#define free_const(ptr) free((void *)(ptr)) + +#endif /* NFTABLES_NFT_H */ diff --git a/include/nftables.h b/include/nftables.h index d49eb579..c058667c 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -1,7 +1,6 @@ #ifndef NFTABLES_NFTABLES_H #define NFTABLES_NFTABLES_H -#include <stdbool.h> #include <stdarg.h> #include <limits.h> #include <utils.h> @@ -23,8 +22,23 @@ struct symbol_tables { const struct symbol_table *realm; }; +struct input_ctx { + unsigned int flags; +}; + +static inline bool nft_input_no_dns(const struct input_ctx *ictx) +{ + return ictx->flags & NFT_CTX_INPUT_NO_DNS; +} + +static inline bool nft_input_json(const struct input_ctx *ictx) +{ + return ictx->flags & NFT_CTX_INPUT_JSON; +} + struct output_ctx { unsigned int flags; + bool force_newline; union { FILE *output_fp; struct cookie output_cookie; @@ -119,6 +133,7 @@ struct nft_ctx { unsigned int num_vars; unsigned int parser_max_errors; unsigned int debug_mask; + struct input_ctx input; struct output_ctx output; bool check; struct nft_cache cache; @@ -144,11 +159,8 @@ struct location { const struct input_descriptor *indesc; union { struct { - off_t token_offset; - off_t line_offset; - + unsigned int line_offset; unsigned int first_line; - unsigned int last_line; unsigned int first_column; unsigned int last_column; }; @@ -210,7 +222,6 @@ struct input_descriptor { void ct_label_table_init(struct nft_ctx *ctx); void mark_table_init(struct nft_ctx *ctx); -void gmp_init(void); void realm_table_rt_init(struct nft_ctx *ctx); void devgroup_table_init(struct nft_ctx *ctx); void xt_init(void); @@ -222,11 +233,13 @@ void realm_table_rt_exit(struct nft_ctx *ctx); int nft_print(struct output_ctx *octx, const char *fmt, ...) __attribute__((format(printf, 2, 3))); -int nft_gmp_print(struct output_ctx *octx, const char *fmt, ...) - __attribute__((format(printf, 2, 0))); +int nft_gmp_print(struct output_ctx *octx, const char *fmt, ...); int nft_optimize(struct nft_ctx *nft, struct list_head *cmds); #define __NFT_OUTPUT_NOTSUPP UINT_MAX +/* internal marker, not used by the kernel. */ +#define NFT_NEVER_TIMEOUT UINT64_MAX + #endif /* NFTABLES_NFTABLES_H */ diff --git a/include/nftables/Makefile.am b/include/nftables/Makefile.am deleted file mode 100644 index 5cfb0c6c..00000000 --- a/include/nftables/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -pkginclude_HEADERS = libnftables.h diff --git a/include/nftables/libnftables.h b/include/nftables/libnftables.h index 85e08c9b..c1d48d76 100644 --- a/include/nftables/libnftables.h +++ b/include/nftables/libnftables.h @@ -9,7 +9,6 @@ #ifndef LIB_NFTABLES_H #define LIB_NFTABLES_H -#define _GNU_SOURCE #include <stdint.h> #include <stdio.h> #include <stdbool.h> @@ -49,6 +48,14 @@ uint32_t nft_ctx_get_optimize(struct nft_ctx *ctx); void nft_ctx_set_optimize(struct nft_ctx *ctx, uint32_t flags); enum { + NFT_CTX_INPUT_NO_DNS = (1 << 0), + NFT_CTX_INPUT_JSON = (1 << 1), +}; + +unsigned int nft_ctx_input_get_flags(struct nft_ctx *ctx); +unsigned int nft_ctx_input_set_flags(struct nft_ctx *ctx, unsigned int flags); + +enum { NFT_CTX_OUTPUT_REVERSEDNS = (1 << 0), NFT_CTX_OUTPUT_SERVICE = (1 << 1), NFT_CTX_OUTPUT_STATELESS = (1 << 2), diff --git a/include/parser.h b/include/parser.h index 2fb037cb..576e5e43 100644 --- a/include/parser.h +++ b/include/parser.h @@ -22,6 +22,7 @@ struct parser_state { struct scope *scopes[SCOPE_NEST_MAX]; unsigned int scope; + bool scope_err; unsigned int flex_state_pop; unsigned int startcond_type; @@ -36,10 +37,12 @@ enum startcond_type { PARSER_SC_CT, PARSER_SC_COUNTER, PARSER_SC_ETH, + PARSER_SC_GRE, PARSER_SC_ICMP, PARSER_SC_IGMP, PARSER_SC_IP, PARSER_SC_IP6, + PARSER_SC_LAST, PARSER_SC_LIMIT, PARSER_SC_META, PARSER_SC_POLICY, @@ -49,6 +52,8 @@ enum startcond_type { PARSER_SC_TCP, PARSER_SC_TYPE, PARSER_SC_VLAN, + PARSER_SC_XT, + PARSER_SC_CMD_DESTROY, PARSER_SC_CMD_EXPORT, PARSER_SC_CMD_IMPORT, PARSER_SC_CMD_LIST, @@ -107,4 +112,8 @@ extern void scanner_push_buffer(void *scanner, extern void scanner_pop_start_cond(void *scanner, enum startcond_type sc); +const char *str_preprocess(struct parser_state *state, struct location *loc, + struct scope *scope, const char *x, + struct error_record **rec); + #endif /* NFTABLES_PARSER_H */ diff --git a/include/payload.h b/include/payload.h index 37869928..e14fc0f2 100644 --- a/include/payload.h +++ b/include/payload.h @@ -15,6 +15,8 @@ struct eval_ctx; struct stmt; extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr, struct stmt **res); +int payload_gen_inner_dependency(struct eval_ctx *ctx, const struct expr *expr, + struct stmt **res); extern int payload_gen_icmp_dependency(struct eval_ctx *ctx, const struct expr *expr, struct stmt **res); @@ -60,6 +62,9 @@ extern struct expr *payload_expr_join(const struct expr *e1, bool payload_expr_trim(struct expr *expr, struct expr *mask, const struct proto_ctx *ctx, unsigned int *shift); +bool payload_expr_trim_force(struct expr *expr, struct expr *mask, + unsigned int *shift); +bool stmt_payload_expr_trim(struct stmt *stmt, const struct proto_ctx *ctx); extern void payload_expr_expand(struct list_head *list, struct expr *expr, const struct proto_ctx *ctx); extern void payload_expr_complete(struct expr *expr, @@ -67,4 +72,8 @@ extern void payload_expr_complete(struct expr *expr, bool payload_expr_cmp(const struct expr *e1, const struct expr *e2); +const struct proto_desc *find_proto_desc(const struct nftnl_udata *ud); + +extern const struct stmt_ops payload_stmt_ops; + #endif /* NFTABLES_PAYLOAD_H */ diff --git a/include/proto.h b/include/proto.h index 35e760c7..9c98a0b7 100644 --- a/include/proto.h +++ b/include/proto.h @@ -35,6 +35,8 @@ enum icmp_hdr_field_type { PROTO_ICMP6_PPTR, PROTO_ICMP6_ECHO, PROTO_ICMP6_MGMQ, + PROTO_ICMP6_ADDRESS, /* neighbor solicit/advert, redirect and MLD */ + PROTO_ICMP6_REDIRECT, }; /** @@ -96,6 +98,10 @@ enum proto_desc_id { PROTO_DESC_ARP, PROTO_DESC_VLAN, PROTO_DESC_ETHER, + PROTO_DESC_VXLAN, + PROTO_DESC_GENEVE, + PROTO_DESC_GRE, + PROTO_DESC_GRETAP, __PROTO_DESC_MAX }; #define PROTO_DESC_MAX (__PROTO_DESC_MAX - 1) @@ -131,7 +137,11 @@ struct proto_desc { uint32_t filter; } format; unsigned int pseudohdr[PROTO_HDRS_MAX]; - + struct { + uint32_t hdrsize; + uint32_t flags; + enum nft_inner_type type; + } inner; }; #define PROTO_LINK(__num, __desc) { .num = (__num), .desc = (__desc), } @@ -185,6 +195,7 @@ extern const struct proto_desc *proto_dev_desc(uint16_t type); struct proto_ctx { unsigned int debug_mask; uint8_t family; + bool inner; union { struct { uint8_t type; @@ -204,7 +215,7 @@ struct proto_ctx { }; extern void proto_ctx_init(struct proto_ctx *ctx, unsigned int family, - unsigned int debug_mask); + unsigned int debug_mask, bool inner); extern void proto_ctx_update(struct proto_ctx *ctx, enum proto_bases base, const struct location *loc, const struct proto_desc *desc); @@ -216,6 +227,8 @@ extern const struct proto_desc *proto_find_upper(const struct proto_desc *base, unsigned int num); extern int proto_find_num(const struct proto_desc *base, const struct proto_desc *desc); +const struct proto_desc *proto_find_inner(uint32_t type, uint32_t hdrsize, + uint32_t flags); extern const struct proto_desc *proto_find_desc(enum proto_desc_id desc_id); @@ -263,6 +276,7 @@ enum ip_hdr_fields { IPHDR_SADDR, IPHDR_DADDR, }; +#define IPHDR_MAX IPHDR_DADDR enum icmp_hdr_fields { ICMPHDR_INVALID, @@ -293,6 +307,8 @@ enum icmp6_hdr_fields { ICMP6HDR_ID, ICMP6HDR_SEQ, ICMP6HDR_MAXDELAY, + ICMP6HDR_TADDR, + ICMP6HDR_DADDR, }; enum ip6_hdr_fields { @@ -376,6 +392,45 @@ enum th_hdr_fields { THDR_DPORT, }; +struct vxlanhdr { + uint32_t vx_flags; + uint32_t vx_vni; +}; + +enum vxlan_hdr_fields { + VXLANHDR_INVALID, + VXLANHDR_VNI, + VXLANHDR_FLAGS, +}; + +struct gnvhdr { + uint16_t flags; + uint16_t type; + uint32_t vni; +}; +enum geneve_hdr_fields { + GNVHDR_INVALID, + GNVHDR_VNI, + GNVHDR_TYPE, +}; + +struct grehdr { + uint16_t flags; + uint16_t protocol; +}; + +enum gre_hdr_fields { + GREHDR_INVALID, + GREHDR_VERSION, + GREHDR_FLAGS, + GREHDR_PROTOCOL, +}; + +extern const struct proto_desc proto_vxlan; +extern const struct proto_desc proto_geneve; +extern const struct proto_desc proto_gre; +extern const struct proto_desc proto_gretap; + extern const struct proto_desc proto_icmp; extern const struct proto_desc proto_igmp; extern const struct proto_desc proto_ah; @@ -413,4 +468,7 @@ extern const struct datatype icmp6_type_type; extern const struct datatype dscp_type; extern const struct datatype ecn_type; +struct eval_ctx; +struct proto_ctx *eval_proto_ctx(struct eval_ctx *ctx); + #endif /* NFTABLES_PROTO_H */ diff --git a/include/rule.h b/include/rule.h index ad9f9127..470ae107 100644 --- a/include/rule.h +++ b/include/rule.h @@ -1,13 +1,11 @@ #ifndef NFTABLES_RULE_H #define NFTABLES_RULE_H -#include <stdint.h> #include <nftables.h> #include <list.h> #include <netinet/in.h> #include <libnftnl/object.h> /* For NFTNL_CTTIMEOUT_ARRAY_MAX. */ #include <linux/netfilter/nf_tables.h> -#include <string.h> #include <cache.h> /** @@ -132,10 +130,12 @@ struct symbol *symbol_get(const struct scope *scope, const char *identifier); enum table_flags { TABLE_F_DORMANT = (1 << 0), TABLE_F_OWNER = (1 << 1), + TABLE_F_PERSIST = (1 << 2), }; -#define TABLE_FLAGS_MAX 2 +#define TABLE_FLAGS_MAX 3 const char *table_flag_name(uint32_t flag); +unsigned int parse_table_flag(const char *name); /** * struct table - nftables table @@ -169,6 +169,7 @@ struct table { unsigned int refcnt; uint32_t owner; const char *comment; + bool has_xt_stmts; }; extern struct table *table_alloc(void); @@ -260,7 +261,7 @@ struct chain { extern int std_prio_lookup(const char *std_prio_name, int family, int hook); extern const char *chain_type_name_lookup(const char *name); extern const char *chain_hookname_lookup(const char *name); -extern struct chain *chain_alloc(const char *name); +extern struct chain *chain_alloc(void); extern struct chain *chain_get(struct chain *chain); extern void chain_free(struct chain *chain); extern struct chain *chain_lookup_fuzzy(const struct handle *h, @@ -320,6 +321,7 @@ void rule_stmt_insert_at(struct rule *rule, struct stmt *nstmt, * @refcnt: reference count * @flags: bitmask of set flags * @gc_int: garbage collection interval + * @count: count of kernel-allocated elements * @timeout: default timeout value * @key: key expression (data type, length)) * @data: mapping data expression @@ -330,6 +332,8 @@ void rule_stmt_insert_at(struct rule *rule, struct stmt *nstmt, * @policy: set mechanism policy * @automerge: merge adjacents and overlapping elements, if possible * @comment: comment + * @errors: expr evaluation errors seen + * @elem_has_comment: element with comment seen (for printing) * @desc.size: count of set elements * @desc.field_len: length of single concatenated fields, bytes * @desc.field_count: count of concatenated fields @@ -342,6 +346,7 @@ struct set { unsigned int refcnt; uint32_t flags; uint32_t gc_int; + uint32_t count; uint64_t timeout; struct expr *key; struct expr *data; @@ -354,6 +359,8 @@ struct set { bool root; bool automerge; bool key_typeof_valid; + bool errors; + bool elem_has_comment; const char *comment; struct { uint32_t size; @@ -410,12 +417,17 @@ 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_meter_compat(uint32_t set_flags) +{ + return 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) +static inline bool set_is_non_concat_range(const struct set *s) { return (s->flags & NFT_SET_INTERVAL) && s->desc.field_count <= 1; } @@ -518,7 +530,7 @@ struct obj *obj_lookup_fuzzy(const char *obj_name, void obj_print(const struct obj *n, struct output_ctx *octx); void obj_print_plain(const struct obj *obj, struct output_ctx *octx); const char *obj_type_name(uint32_t type); -uint32_t obj_type_to_cmd(uint32_t type); +enum cmd_obj obj_type_to_cmd(uint32_t type); struct flowtable { struct list_head list; @@ -543,6 +555,7 @@ extern struct flowtable *flowtable_lookup_fuzzy(const char *ft_name, const struct table **table); void flowtable_print(const struct flowtable *n, struct output_ctx *octx); +void flowtable_print_plain(const struct flowtable *ft, struct output_ctx *octx); /** * enum cmd_ops - command operations @@ -562,6 +575,7 @@ void flowtable_print(const struct flowtable *n, struct output_ctx *octx); * @CMD_EXPORT: export the ruleset in a given format * @CMD_MONITOR: event listener * @CMD_DESCRIBE: describe an expression + * @CMD_DESTROY: destroy object */ enum cmd_ops { CMD_INVALID, @@ -579,6 +593,7 @@ enum cmd_ops { CMD_EXPORT, CMD_MONITOR, CMD_DESCRIBE, + CMD_DESTROY, }; /** @@ -619,6 +634,7 @@ enum cmd_obj { CMD_OBJ_SETELEMS, CMD_OBJ_SETS, CMD_OBJ_RULE, + CMD_OBJ_RULES, CMD_OBJ_CHAIN, CMD_OBJ_CHAINS, CMD_OBJ_TABLE, @@ -641,9 +657,11 @@ enum cmd_obj { CMD_OBJ_FLOWTABLE, CMD_OBJ_FLOWTABLES, CMD_OBJ_CT_TIMEOUT, + CMD_OBJ_CT_TIMEOUTS, CMD_OBJ_SECMARK, CMD_OBJ_SECMARKS, CMD_OBJ_CT_EXPECT, + CMD_OBJ_CT_EXPECTATIONS, CMD_OBJ_SYNPROXY, CMD_OBJ_SYNPROXYS, CMD_OBJ_HOOKS, @@ -682,7 +700,8 @@ void monitor_free(struct monitor *m); #define NFT_NLATTR_LOC_MAX 32 struct nlerr_loc { - uint16_t offset; + uint32_t seqnum; + uint32_t offset; const struct location *location; }; @@ -704,8 +723,8 @@ struct cmd { enum cmd_ops op; enum cmd_obj obj; struct handle handle; - uint32_t seqnum; - struct list_head collapse_list; + uint32_t seqnum_from; + uint32_t seqnum_to; union { void *data; struct expr *expr; @@ -731,19 +750,19 @@ struct cmd { extern struct cmd *cmd_alloc(enum cmd_ops op, enum cmd_obj obj, const struct handle *h, const struct location *loc, void *data); -extern void nft_cmd_expand(struct cmd *cmd); -extern bool nft_cmd_collapse(struct list_head *cmds); -extern void nft_cmd_uncollapse(struct list_head *cmds); extern struct cmd *cmd_alloc_obj_ct(enum cmd_ops op, int type, const struct handle *h, const struct location *loc, struct obj *obj); extern void cmd_free(struct cmd *cmd); -void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc); - #include <payload.h> #include <expression.h> +struct eval_recursion { + uint16_t binop; + uint16_t list; +}; + /** * struct eval_ctx - evaluation context * @@ -754,10 +773,13 @@ void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc); * @rule: current rule * @set: current set * @stmt: current statement + * @stmt_len: current statement template length + * @recursion: expr evaluation recursion counters * @cache: cache context * @debug_mask: debugging bitmask * @ectx: expression context - * @pctx: payload context + * @_pctx: payload contexts + * @inner_desc: inner header description */ struct eval_ctx { struct nft_ctx *nft; @@ -767,8 +789,11 @@ struct eval_ctx { struct rule *rule; struct set *set; struct stmt *stmt; + uint32_t stmt_len; + struct eval_recursion recursion; struct expr_ctx ectx; - struct proto_ctx pctx; + struct proto_ctx _pctx[2]; + const struct proto_desc *inner_desc; }; extern int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd); @@ -784,7 +809,7 @@ struct timeout_protocol { uint32_t *dflt_timeout; }; -extern struct timeout_protocol timeout_protocol[IPPROTO_MAX]; +extern struct timeout_protocol timeout_protocol[UINT8_MAX + 1]; extern int timeout_str2num(uint16_t l4proto, struct timeout_state *ts); #endif /* NFTABLES_RULE_H */ diff --git a/include/statement.h b/include/statement.h index 2a2d3001..e8724dde 100644 --- a/include/statement.h +++ b/include/statement.h @@ -47,6 +47,13 @@ struct counter_stmt { extern struct stmt *counter_stmt_alloc(const struct location *loc); +struct last_stmt { + uint64_t used; + uint32_t set; +}; + +extern struct stmt *last_stmt_alloc(const struct location *loc); + struct exthdr_stmt { struct expr *expr; struct expr *val; @@ -83,7 +90,7 @@ enum { }; struct log_stmt { - struct expr *prefix; + const char *prefix; unsigned int snaplen; uint16_t group; uint16_t qthreshold; @@ -255,8 +262,8 @@ enum nft_xt_type { NFT_XT_MATCH = 0, NFT_XT_TARGET, NFT_XT_WATCHER, - NFT_XT_MAX }; +#define NFT_XT_MAX (NFT_XT_WATCHER + 1) struct xtables_match; struct xtables_target; @@ -264,12 +271,11 @@ struct xtables_target; struct xt_stmt { const char *name; enum nft_xt_type type; + uint32_t rev; + uint32_t family; + size_t infolen; + void *info; uint32_t proto; - union { - struct xtables_match *match; - struct xtables_target *target; - }; - void *entry; }; extern struct stmt *xt_stmt_alloc(const struct location *loc); @@ -304,6 +310,7 @@ extern struct stmt *xt_stmt_alloc(const struct location *loc); * @STMT_SYNPROXY: synproxy statement * @STMT_CHAIN: chain statement * @STMT_OPTSTRIP: optstrip statement + * @STMT_LAST: last statement */ enum stmt_types { STMT_INVALID, @@ -334,6 +341,7 @@ enum stmt_types { STMT_SYNPROXY, STMT_CHAIN, STMT_OPTSTRIP, + STMT_LAST, }; /** @@ -364,16 +372,16 @@ enum stmt_flags { * struct stmt * * @list: rule list node - * @ops: statement ops * @location: location where the statement was defined * @flags: statement flags + * @type: statement type * @union: type specific data */ struct stmt { struct list_head list; - const struct stmt_ops *ops; struct location location; enum stmt_flags flags; + enum stmt_types type:8; union { struct expr *expr; @@ -383,6 +391,7 @@ struct stmt { struct counter_stmt counter; struct payload_stmt payload; struct meta_stmt meta; + struct last_stmt last; struct log_stmt log; struct limit_stmt limit; struct reject_stmt reject; @@ -407,9 +416,12 @@ struct stmt { extern struct stmt *stmt_alloc(const struct location *loc, const struct stmt_ops *ops); int stmt_evaluate(struct eval_ctx *ctx, struct stmt *stmt); +int stmt_dependency_evaluate(struct eval_ctx *ctx, struct stmt *stmt); extern void stmt_free(struct stmt *stmt); extern void stmt_list_free(struct list_head *list); extern void stmt_print(const struct stmt *stmt, struct output_ctx *octx); +const char *stmt_name(const struct stmt *stmt); +const struct stmt_ops *stmt_ops(const struct stmt *stmt); const char *get_rate(uint64_t byte_rate, uint64_t *rate); const char *get_unit(uint64_t u); diff --git a/include/utils.h b/include/utils.h index ffbe2cbb..e18fabec 100644 --- a/include/utils.h +++ b/include/utils.h @@ -2,8 +2,6 @@ #define NFTABLES_UTILS_H #include <asm/byteorder.h> -#include <stdint.h> -#include <stdbool.h> #include <stdarg.h> #include <stdio.h> #include <unistd.h> @@ -11,7 +9,6 @@ #include <list.h> #include <gmputil.h> -#include "config.h" #ifdef HAVE_VISIBILITY_HIDDEN # define __visible __attribute__((visibility("default"))) # define EXPORT_SYMBOL(x) typeof(x) (x) __visible; @@ -39,7 +36,7 @@ #define __must_check __attribute__((warn_unused_result)) #define __noreturn __attribute__((__noreturn__)) -#define BUG(fmt, arg...) ({ fprintf(stderr, "BUG: " fmt, ##arg); assert(0); }) +#define BUG(fmt, arg...) ({ fprintf(stderr, "BUG: " fmt, ##arg); assert(0); abort(); }) #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) #define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1) @@ -75,15 +72,32 @@ #define max(_x, _y) ({ \ _x > _y ? _x : _y; }) -#define SNPRINTF_BUFFER_SIZE(ret, size, len, offset) \ - if (ret < 0) \ - abort(); \ - offset += ret; \ - assert(ret < len); \ - if (ret > len) \ - ret = len; \ - size += ret; \ - len -= ret; +#define SNPRINTF_BUFFER_SIZE(ret, len, offset) \ + ({ \ + const int _ret = (ret); \ + size_t *const _len = (len); \ + size_t *const _offset = (offset); \ + bool _not_truncated = true; \ + size_t _ret2; \ + \ + assert(_ret >= 0); \ + \ + if ((size_t) _ret >= *_len) { \ + /* Truncated. + * + * We will leave "len" at zero and increment + * "offset" to point one byte after the buffer + * (after the terminating NUL byte). */ \ + _ret2 = *_len; \ + _not_truncated = false; \ + } else \ + _ret2 = (size_t) _ret; \ + \ + *_offset += _ret2; \ + *_len -= _ret2; \ + \ + _not_truncated; \ + }) #define MSEC_PER_SEC 1000L @@ -128,7 +142,6 @@ extern void __memory_allocation_error(const char *filename, uint32_t line) __nor #define memory_allocation_error() \ __memory_allocation_error(__FILE__, __LINE__); -extern void xfree(const void *ptr); extern void *xmalloc(size_t size); extern void *xmalloc_array(size_t nmemb, size_t size); extern void *xrealloc(void *ptr, size_t size); @@ -136,5 +149,6 @@ extern void *xzalloc(size_t size); extern void *xzalloc_array(size_t nmemb, size_t size); extern char *xstrdup(const char *s); extern void xstrunescape(const char *in, char *out); +extern int round_pow_2(unsigned int value); #endif /* NFTABLES_UTILS_H */ |