summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/Makefile.am41
-rw-r--r--include/cache.h23
-rw-r--r--include/cli.h3
-rw-r--r--include/cmd.h6
-rw-r--r--include/ct.h2
-rw-r--r--include/datatype.h20
-rw-r--r--include/dccpopt.h41
-rw-r--r--include/expression.h23
-rw-r--r--include/exthdr.h1
-rw-r--r--include/gmputil.h4
-rw-r--r--include/headers.h2
-rw-r--r--include/intervals.h1
-rw-r--r--include/json.h6
-rw-r--r--include/linux/Makefile.am12
-rw-r--r--include/linux/netfilter/Makefile.am10
-rw-r--r--include/linux/netfilter/nf_tables.h77
-rw-r--r--include/linux/netfilter/nfnetlink_hook.h24
-rw-r--r--include/linux/netfilter_arp/Makefile.am1
-rw-r--r--include/linux/netfilter_bridge/Makefile.am1
-rw-r--r--include/linux/netfilter_ipv4/Makefile.am1
-rw-r--r--include/linux/netfilter_ipv6/Makefile.am1
-rw-r--r--include/meta.h2
-rw-r--r--include/mnl.h19
-rw-r--r--include/netlink.h31
-rw-r--r--include/nft.h18
-rw-r--r--include/nftables.h20
-rw-r--r--include/nftables/Makefile.am1
-rw-r--r--include/nftables/libnftables.h9
-rw-r--r--include/parser.h9
-rw-r--r--include/payload.h4
-rw-r--r--include/proto.h65
-rw-r--r--include/rule.h52
-rw-r--r--include/statement.h22
-rw-r--r--include/utils.h42
34 files changed, 449 insertions, 145 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 b6c7d48b..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,11 +66,13 @@ struct nft_cache_filter {
};
struct nft_cache;
+struct nft_ctx;
enum cmd_ops;
-unsigned int nft_cache_evaluate(struct nft_ctx *nft, struct list_head *cmds,
- struct nft_cache_filter *filter);
-int nft_cache_update(struct nft_ctx *ctx, enum cmd_ops cmd,
+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, unsigned int flags,
struct list_head *msgs,
const struct nft_cache_filter *filter);
bool nft_cache_needs_update(struct nft_cache *cache);
@@ -93,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);
@@ -117,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,
@@ -134,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 2c3818e8..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
*
@@ -41,6 +44,10 @@
* @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_FLAGCMP flagcmp expression
*/
enum expr_types {
EXPR_INVALID,
@@ -73,8 +80,9 @@ enum expr_types {
EXPR_XFRM,
EXPR_SET_ELEM_CATCHALL,
EXPR_FLAGCMP,
+
+ EXPR_MAX = EXPR_FLAGCMP
};
-#define EXPR_MAX EXPR_XFRM
enum ops {
OP_INVALID,
@@ -116,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;
@@ -181,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
@@ -243,6 +255,7 @@ struct expr {
enum expr_types etype:8;
enum ops op:8;
unsigned int len;
+ struct cmd *cmd;
union {
struct {
@@ -310,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;
@@ -328,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 */
@@ -480,6 +495,7 @@ extern struct expr *compound_expr_alloc(const struct location *loc,
extern void compound_expr_add(struct expr *compound, struct expr *expr);
extern void compound_expr_remove(struct expr *compound, struct expr *expr);
extern void list_expr_sort(struct list_head *head);
+extern void list_splice_sorted(struct list_head *list, struct list_head *head);
extern struct expr *concat_expr_alloc(const struct location *loc);
@@ -514,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 75df968d..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,
};
@@ -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)
@@ -748,11 +771,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 +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
*
@@ -809,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)
@@ -881,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,
@@ -891,7 +946,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 +974,8 @@ enum nft_meta_keys {
NFT_META_TIME_HOUR,
NFT_META_SDIF,
NFT_META_SDIFNAME,
+ NFT_META_BRI_BROUTE,
+ __NFT_META_IIFTYPE,
};
/**
@@ -1013,6 +1071,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 +1088,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 +1249,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_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 4c701d4e..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);
@@ -60,14 +62,17 @@ int mnl_nft_set_del(struct netlink_ctx *ctx, struct cmd *cmd);
struct nftnl_set_list *mnl_nft_set_dump(struct netlink_ctx *ctx, int family,
const char *table, const char *set);
-int mnl_nft_setelem_add(struct netlink_ctx *ctx, const struct set *set,
- const struct expr *expr, unsigned int flags);
-int mnl_nft_setelem_del(struct netlink_ctx *ctx, const struct handle *h,
- const struct expr *init);
+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);
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 e8e0f68a..27a62462 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -40,12 +40,28 @@ struct netlink_parse_ctx {
struct expr *registers[MAX_REGS + 1];
unsigned int debug_mask;
struct netlink_ctx *nlctx;
+ bool inner;
+ uint8_t inner_reg;
};
-struct rule_pp_ctx {
+
+#define RULE_PP_IN_CONCATENATION (1 << 0)
+#define RULE_PP_IN_SET_ELEM (1 << 1)
+
+#define RULE_PP_REMOVE_OP_AND (RULE_PP_IN_CONCATENATION | \
+ RULE_PP_IN_SET_ELEM)
+
+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;
@@ -69,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);
@@ -84,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;
@@ -149,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);
@@ -168,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,
@@ -238,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 f32154cc..f79a22f3 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -22,10 +22,12 @@ struct parser_state {
struct scope *scopes[SCOPE_NEST_MAX];
unsigned int scope;
+ bool scope_err;
unsigned int flex_state_pop;
unsigned int startcond_type;
struct list_head *cmds;
+ unsigned int *startcond_active;
};
enum startcond_type {
@@ -35,11 +37,12 @@ enum startcond_type {
PARSER_SC_CT,
PARSER_SC_COUNTER,
PARSER_SC_ETH,
- PARSER_SC_FLAGS,
+ 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,
@@ -82,6 +87,8 @@ enum startcond_type {
PARSER_SC_STMT_REJECT,
PARSER_SC_STMT_SYNPROXY,
PARSER_SC_STMT_TPROXY,
+
+ __SC_MAX
};
struct mnl_socket;
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 a04240a5..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;
@@ -193,17 +204,18 @@ struct proto_ctx {
struct {
struct location location;
const struct proto_desc *desc;
- unsigned int offset;
struct {
struct location location;
const struct proto_desc *desc;
} protos[PROTO_CTX_NUM_PROTOS];
unsigned int num_protos;
} protocol[PROTO_BASE_MAX + 1];
+ const struct proto_desc *stacked_ll[PROTO_CTX_NUM_PROTOS];
+ uint8_t stacked_ll_count;
};
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);
@@ -215,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);
@@ -262,6 +276,7 @@ enum ip_hdr_fields {
IPHDR_SADDR,
IPHDR_DADDR,
};
+#define IPHDR_MAX IPHDR_DADDR
enum icmp_hdr_fields {
ICMPHDR_INVALID,
@@ -292,6 +307,8 @@ enum icmp6_hdr_fields {
ICMP6HDR_ID,
ICMP6HDR_SEQ,
ICMP6HDR_MAXDELAY,
+ ICMP6HDR_TADDR,
+ ICMP6HDR_DADDR,
};
enum ip6_hdr_fields {
@@ -375,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;
@@ -412,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 e232b97a..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,
@@ -681,6 +694,11 @@ void monitor_free(struct monitor *m);
#define NFT_NLATTR_LOC_MAX 32
+struct nlerr_loc {
+ uint16_t offset;
+ const struct location *location;
+};
+
/**
* struct cmd - command statement
*
@@ -700,6 +718,7 @@ struct cmd {
enum cmd_obj obj;
struct handle handle;
uint32_t seqnum;
+ struct list_head collapse_list;
union {
void *data;
struct expr *expr;
@@ -716,25 +735,20 @@ struct cmd {
struct markup *markup;
struct obj *object;
};
- struct {
- uint16_t offset;
- const struct location *location;
- } attr[NFT_NLATTR_LOC_MAX];
- int num_attrs;
+ struct nlerr_loc *attr;
+ uint32_t attr_array_len;
+ uint32_t num_attrs;
const void *arg;
};
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 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>
@@ -748,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;
@@ -761,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);
@@ -778,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 */