diff options
Diffstat (limited to 'include')
34 files changed, 384 insertions, 132 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..8ca4a9a7 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), @@ -55,6 +57,7 @@ struct nft_cache_filter { const char *chain; const char *set; const char *ft; + uint64_t rule_handle; } list; struct { @@ -63,12 +66,13 @@ struct nft_cache_filter { }; 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 +98,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); @@ -118,6 +124,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,7 +143,13 @@ struct nft_cache { uint32_t flags; }; +struct netlink_ctx; + void nft_chain_cache_update(struct netlink_ctx *ctx, struct table *table, const char *chain); +int rule_cache_dump(struct netlink_ctx *ctx, const struct handle *h, + const struct nft_cache_filter *filter, + bool dump, bool reset); + #endif /* _NFT_CACHE_H_ */ 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..92a4152b 100644 --- a/include/cmd.h +++ b/include/cmd.h @@ -1,7 +1,13 @@ #ifndef _NFT_CMD_H_ #define _NFT_CMD_H_ +void cmd_add_loc(struct cmd *cmd, uint16_t offset, const struct location *loc); void nft_cmd_error(struct netlink_ctx *ctx, struct cmd *cmd, struct mnl_err *err); +void nft_cmd_expand(struct cmd *cmd); +void nft_cmd_post_expand(struct cmd *cmd); +bool nft_cmd_collapse(struct list_head *cmds); +void nft_cmd_uncollapse(struct list_head *cmds); + #endif diff --git a/include/ct.h b/include/ct.h index efb2d418..0a705fd0 100644 --- a/include/ct.h +++ b/include/ct.h @@ -39,5 +39,7 @@ 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; #endif /* NFTABLES_CT_H */ diff --git a/include/datatype.h b/include/datatype.h index 73f38f66..d4b4737c 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) @@ -167,6 +166,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 +174,15 @@ 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); struct parse_ctx { struct symbol_tables *tbl; + const struct input_ctx *input; }; extern struct error_record *symbol_parse(struct parse_ctx *ctx, @@ -250,6 +252,9 @@ 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; @@ -278,6 +283,11 @@ extern const struct datatype priority_type; extern const struct datatype policy_type; extern const struct datatype cgroupv2_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; + void inet_service_type_print(const struct expr *expr, struct output_ctx *octx); extern const struct datatype *concat_type_alloc(uint32_t type); @@ -299,7 +309,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 3f06a38a..01b45b7c 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 * @@ -121,7 +124,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; @@ -186,7 +193,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 @@ -316,6 +323,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; @@ -334,6 +342,7 @@ struct expr { /* EXPR_META */ enum nft_meta_keys key; enum proto_bases base; + const struct proto_desc *inner_desc; } meta; struct { /* SOCKET */ @@ -521,5 +530,6 @@ struct expr *flagcmp_expr_alloc(const struct location *loc, enum ops op, 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..084daba5 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, 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/intervals.h b/include/intervals.h index 964804b1..ef0fb53e 100644 --- a/include/intervals.h +++ b/include/intervals.h @@ -1,7 +1,6 @@ #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, diff --git a/include/json.h b/include/json.h index b0d78eb8..39be8928 100644 --- a/include/json.h +++ b/include/json.h @@ -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); @@ -176,6 +179,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 +189,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 +199,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 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 466fd3f4..c62e6ac5 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, }; @@ -760,6 +778,7 @@ enum nft_payload_bases { NFT_PAYLOAD_NETWORK_HEADER, NFT_PAYLOAD_TRANSPORT_HEADER, NFT_PAYLOAD_INNER_HEADER, + NFT_PAYLOAD_TUN_HEADER, }; /** @@ -779,6 +798,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 * @@ -816,12 +861,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) @@ -888,6 +935,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, @@ -926,6 +974,7 @@ enum nft_meta_keys { NFT_META_TIME_HOUR, NFT_META_SDIF, NFT_META_SDIFNAME, + NFT_META_BRI_BROUTE, __NFT_META_IIFTYPE, }; 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_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/meta.h b/include/meta.h index 1478902e..af2d772b 100644 --- a/include/meta.h +++ b/include/meta.h @@ -45,4 +45,6 @@ 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); + #endif /* NFTABLES_META_H */ diff --git a/include/mnl.h b/include/mnl.h index 8e0a7e3f..cd5a2053 100644 --- a/include/mnl.h +++ b/include/mnl.h @@ -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); @@ -66,9 +68,11 @@ int mnl_nft_setelem_add(struct netlink_ctx *ctx, struct cmd *cmd, int mnl_nft_setelem_del(struct netlink_ctx *ctx, struct cmd *cmd, const struct handle *h, 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, diff --git a/include/netlink.h b/include/netlink.h index 63d07edf..27a62462 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); @@ -92,7 +101,7 @@ 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,10 +166,11 @@ 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); + struct set *set, struct expr *init, bool reset); extern int netlink_delinearize_setelem(struct nftnl_set_elem *nlse, struct set *set, struct nft_cache *cache); @@ -176,6 +186,9 @@ extern int netlink_list_flowtables(struct netlink_ctx *ctx, extern struct flowtable *netlink_delinearize_flowtable(struct netlink_ctx *ctx, struct nftnl_flowtable *nlo); +extern int netlink_reset_rules(struct netlink_ctx *ctx, const struct cmd *cmd, + bool dump); + extern void netlink_dump_chain(const struct nftnl_chain *nlc, struct netlink_ctx *ctx); extern void netlink_dump_rule(const struct nftnl_rule *nlr, @@ -246,4 +259,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..4b7c3359 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,6 +22,20 @@ 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; union { @@ -119,6 +132,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; @@ -210,7 +224,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,8 +235,7 @@ 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); 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..f79a22f3 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, diff --git a/include/payload.h b/include/payload.h index 37869928..08e45f7f 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); @@ -67,4 +69,6 @@ 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); + #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..5b3e12b5 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, @@ -330,6 +331,7 @@ 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 * @desc.size: count of set elements * @desc.field_len: length of single concatenated fields, bytes * @desc.field_count: count of concatenated fields @@ -354,6 +356,7 @@ struct set { bool root; bool automerge; bool key_typeof_valid; + bool errors; const char *comment; struct { uint32_t size; @@ -410,6 +413,11 @@ 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; @@ -518,7 +526,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; @@ -562,6 +570,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 +588,7 @@ enum cmd_ops { CMD_EXPORT, CMD_MONITOR, CMD_DESCRIBE, + CMD_DESTROY, }; /** @@ -619,6 +629,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 +652,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, @@ -731,16 +744,11 @@ 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> @@ -754,10 +762,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 counter * @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 +778,11 @@ struct eval_ctx { struct rule *rule; struct set *set; struct stmt *stmt; + uint32_t stmt_len; + uint32_t 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 +798,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..662f99dd 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; @@ -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, }; /** @@ -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,6 +416,7 @@ 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); 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 */ |