196518518SPatrick McHardy #ifndef _NET_NF_TABLES_H
296518518SPatrick McHardy #define _NET_NF_TABLES_H
396518518SPatrick McHardy 
496518518SPatrick McHardy #include <linux/list.h>
596518518SPatrick McHardy #include <linux/netfilter.h>
667a8fc27SPatrick McHardy #include <linux/netfilter/nfnetlink.h>
70ca743a5SPablo Neira Ayuso #include <linux/netfilter/x_tables.h>
896518518SPatrick McHardy #include <linux/netfilter/nf_tables.h>
9ce355e20SEric Dumazet #include <linux/u64_stats_sync.h>
1096518518SPatrick McHardy #include <net/netlink.h>
1196518518SPatrick McHardy 
1220a69341SPatrick McHardy #define NFT_JUMP_STACK_SIZE	16
1320a69341SPatrick McHardy 
1496518518SPatrick McHardy struct nft_pktinfo {
1596518518SPatrick McHardy 	struct sk_buff			*skb;
1696518518SPatrick McHardy 	const struct net_device		*in;
1796518518SPatrick McHardy 	const struct net_device		*out;
18c9484874SPatrick McHardy 	const struct nf_hook_ops	*ops;
1996518518SPatrick McHardy 	u8				nhoff;
2096518518SPatrick McHardy 	u8				thoff;
214566bf27SPatrick McHardy 	u8				tprot;
220ca743a5SPablo Neira Ayuso 	/* for x_tables compatibility */
230ca743a5SPablo Neira Ayuso 	struct xt_action_param		xt;
2496518518SPatrick McHardy };
2596518518SPatrick McHardy 
260ca743a5SPablo Neira Ayuso static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
270ca743a5SPablo Neira Ayuso 				   const struct nf_hook_ops *ops,
280ca743a5SPablo Neira Ayuso 				   struct sk_buff *skb,
290ca743a5SPablo Neira Ayuso 				   const struct net_device *in,
300ca743a5SPablo Neira Ayuso 				   const struct net_device *out)
310ca743a5SPablo Neira Ayuso {
320ca743a5SPablo Neira Ayuso 	pkt->skb = skb;
330ca743a5SPablo Neira Ayuso 	pkt->in = pkt->xt.in = in;
340ca743a5SPablo Neira Ayuso 	pkt->out = pkt->xt.out = out;
35c9484874SPatrick McHardy 	pkt->ops = ops;
36c9484874SPatrick McHardy 	pkt->xt.hooknum = ops->hooknum;
370ca743a5SPablo Neira Ayuso 	pkt->xt.family = ops->pf;
380ca743a5SPablo Neira Ayuso }
390ca743a5SPablo Neira Ayuso 
4096518518SPatrick McHardy struct nft_data {
4196518518SPatrick McHardy 	union {
4296518518SPatrick McHardy 		u32				data[4];
4396518518SPatrick McHardy 		struct {
4496518518SPatrick McHardy 			u32			verdict;
4596518518SPatrick McHardy 			struct nft_chain	*chain;
4696518518SPatrick McHardy 		};
4796518518SPatrick McHardy 	};
4896518518SPatrick McHardy } __attribute__((aligned(__alignof__(u64))));
4996518518SPatrick McHardy 
5096518518SPatrick McHardy static inline int nft_data_cmp(const struct nft_data *d1,
5196518518SPatrick McHardy 			       const struct nft_data *d2,
5296518518SPatrick McHardy 			       unsigned int len)
5396518518SPatrick McHardy {
5496518518SPatrick McHardy 	return memcmp(d1->data, d2->data, len);
5596518518SPatrick McHardy }
5696518518SPatrick McHardy 
5796518518SPatrick McHardy static inline void nft_data_copy(struct nft_data *dst,
5896518518SPatrick McHardy 				 const struct nft_data *src)
5996518518SPatrick McHardy {
6096518518SPatrick McHardy 	BUILD_BUG_ON(__alignof__(*dst) != __alignof__(u64));
6196518518SPatrick McHardy 	*(u64 *)&dst->data[0] = *(u64 *)&src->data[0];
6296518518SPatrick McHardy 	*(u64 *)&dst->data[2] = *(u64 *)&src->data[2];
6396518518SPatrick McHardy }
6496518518SPatrick McHardy 
6596518518SPatrick McHardy static inline void nft_data_debug(const struct nft_data *data)
6696518518SPatrick McHardy {
6796518518SPatrick McHardy 	pr_debug("data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n",
6896518518SPatrick McHardy 		 data->data[0], data->data[1],
6996518518SPatrick McHardy 		 data->data[2], data->data[3]);
7096518518SPatrick McHardy }
7196518518SPatrick McHardy 
7296518518SPatrick McHardy /**
7320a69341SPatrick McHardy  *	struct nft_ctx - nf_tables rule/set context
7496518518SPatrick McHardy  *
7599633ab2SPablo Neira Ayuso  *	@net: net namespace
7696518518SPatrick McHardy  * 	@afi: address family info
7796518518SPatrick McHardy  * 	@table: the table the chain is contained in
7896518518SPatrick McHardy  * 	@chain: the chain the rule is contained in
790ca743a5SPablo Neira Ayuso  *	@nla: netlink attributes
80128ad332SPablo Neira Ayuso  *	@portid: netlink portID of the original message
81128ad332SPablo Neira Ayuso  *	@seq: netlink sequence number
82128ad332SPablo Neira Ayuso  *	@report: notify via unicast netlink message
8396518518SPatrick McHardy  */
8496518518SPatrick McHardy struct nft_ctx {
8599633ab2SPablo Neira Ayuso 	struct net			*net;
867c95f6d8SPablo Neira Ayuso 	struct nft_af_info		*afi;
877c95f6d8SPablo Neira Ayuso 	struct nft_table		*table;
887c95f6d8SPablo Neira Ayuso 	struct nft_chain		*chain;
890ca743a5SPablo Neira Ayuso 	const struct nlattr * const 	*nla;
90128ad332SPablo Neira Ayuso 	u32				portid;
91128ad332SPablo Neira Ayuso 	u32				seq;
92128ad332SPablo Neira Ayuso 	bool				report;
9396518518SPatrick McHardy };
9496518518SPatrick McHardy 
9596518518SPatrick McHardy struct nft_data_desc {
9696518518SPatrick McHardy 	enum nft_data_types		type;
9796518518SPatrick McHardy 	unsigned int			len;
9896518518SPatrick McHardy };
9996518518SPatrick McHardy 
1005eccdfaaSJoe Perches int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
10196518518SPatrick McHardy 		  struct nft_data_desc *desc, const struct nlattr *nla);
1025eccdfaaSJoe Perches void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
1035eccdfaaSJoe Perches int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
10496518518SPatrick McHardy 		  enum nft_data_types type, unsigned int len);
10596518518SPatrick McHardy 
10696518518SPatrick McHardy static inline enum nft_data_types nft_dreg_to_type(enum nft_registers reg)
10796518518SPatrick McHardy {
10896518518SPatrick McHardy 	return reg == NFT_REG_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE;
10996518518SPatrick McHardy }
11096518518SPatrick McHardy 
11120a69341SPatrick McHardy static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
11220a69341SPatrick McHardy {
11320a69341SPatrick McHardy 	return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
11420a69341SPatrick McHardy }
11520a69341SPatrick McHardy 
1165eccdfaaSJoe Perches int nft_validate_input_register(enum nft_registers reg);
1175eccdfaaSJoe Perches int nft_validate_output_register(enum nft_registers reg);
1185eccdfaaSJoe Perches int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
11996518518SPatrick McHardy 			   const struct nft_data *data,
12096518518SPatrick McHardy 			   enum nft_data_types type);
12196518518SPatrick McHardy 
12296518518SPatrick McHardy /**
12320a69341SPatrick McHardy  *	struct nft_set_elem - generic representation of set elements
12420a69341SPatrick McHardy  *
12520a69341SPatrick McHardy  *	@cookie: implementation specific element cookie
12620a69341SPatrick McHardy  *	@key: element key
12720a69341SPatrick McHardy  *	@data: element data (maps only)
12820a69341SPatrick McHardy  *	@flags: element flags (end of interval)
12920a69341SPatrick McHardy  *
13020a69341SPatrick McHardy  *	The cookie can be used to store a handle to the element for subsequent
13120a69341SPatrick McHardy  *	removal.
13220a69341SPatrick McHardy  */
13320a69341SPatrick McHardy struct nft_set_elem {
13420a69341SPatrick McHardy 	void			*cookie;
13520a69341SPatrick McHardy 	struct nft_data		key;
13620a69341SPatrick McHardy 	struct nft_data		data;
13720a69341SPatrick McHardy 	u32			flags;
13820a69341SPatrick McHardy };
13920a69341SPatrick McHardy 
14020a69341SPatrick McHardy struct nft_set;
14120a69341SPatrick McHardy struct nft_set_iter {
14220a69341SPatrick McHardy 	unsigned int	count;
14320a69341SPatrick McHardy 	unsigned int	skip;
14420a69341SPatrick McHardy 	int		err;
14520a69341SPatrick McHardy 	int		(*fn)(const struct nft_ctx *ctx,
14620a69341SPatrick McHardy 			      const struct nft_set *set,
14720a69341SPatrick McHardy 			      const struct nft_set_iter *iter,
14820a69341SPatrick McHardy 			      const struct nft_set_elem *elem);
14920a69341SPatrick McHardy };
15020a69341SPatrick McHardy 
15120a69341SPatrick McHardy /**
152c50b960cSPatrick McHardy  *	struct nft_set_desc - description of set elements
153c50b960cSPatrick McHardy  *
154c50b960cSPatrick McHardy  *	@klen: key length
155c50b960cSPatrick McHardy  *	@dlen: data length
156c50b960cSPatrick McHardy  *	@size: number of set elements
157c50b960cSPatrick McHardy  */
158c50b960cSPatrick McHardy struct nft_set_desc {
159c50b960cSPatrick McHardy 	unsigned int		klen;
160c50b960cSPatrick McHardy 	unsigned int		dlen;
161c50b960cSPatrick McHardy 	unsigned int		size;
162c50b960cSPatrick McHardy };
163c50b960cSPatrick McHardy 
164c50b960cSPatrick McHardy /**
165c50b960cSPatrick McHardy  *	enum nft_set_class - performance class
166c50b960cSPatrick McHardy  *
167c50b960cSPatrick McHardy  *	@NFT_LOOKUP_O_1: constant, O(1)
168c50b960cSPatrick McHardy  *	@NFT_LOOKUP_O_LOG_N: logarithmic, O(log N)
169c50b960cSPatrick McHardy  *	@NFT_LOOKUP_O_N: linear, O(N)
170c50b960cSPatrick McHardy  */
171c50b960cSPatrick McHardy enum nft_set_class {
172c50b960cSPatrick McHardy 	NFT_SET_CLASS_O_1,
173c50b960cSPatrick McHardy 	NFT_SET_CLASS_O_LOG_N,
174c50b960cSPatrick McHardy 	NFT_SET_CLASS_O_N,
175c50b960cSPatrick McHardy };
176c50b960cSPatrick McHardy 
177c50b960cSPatrick McHardy /**
178c50b960cSPatrick McHardy  *	struct nft_set_estimate - estimation of memory and performance
179c50b960cSPatrick McHardy  *				  characteristics
180c50b960cSPatrick McHardy  *
181c50b960cSPatrick McHardy  *	@size: required memory
182c50b960cSPatrick McHardy  *	@class: lookup performance class
183c50b960cSPatrick McHardy  */
184c50b960cSPatrick McHardy struct nft_set_estimate {
185c50b960cSPatrick McHardy 	unsigned int		size;
186c50b960cSPatrick McHardy 	enum nft_set_class	class;
187c50b960cSPatrick McHardy };
188c50b960cSPatrick McHardy 
189c50b960cSPatrick McHardy /**
19020a69341SPatrick McHardy  *	struct nft_set_ops - nf_tables set operations
19120a69341SPatrick McHardy  *
19220a69341SPatrick McHardy  *	@lookup: look up an element within the set
19320a69341SPatrick McHardy  *	@insert: insert new element into set
19420a69341SPatrick McHardy  *	@remove: remove element from set
19520a69341SPatrick McHardy  *	@walk: iterate over all set elemeennts
19620a69341SPatrick McHardy  *	@privsize: function to return size of set private data
19720a69341SPatrick McHardy  *	@init: initialize private data of new set instance
19820a69341SPatrick McHardy  *	@destroy: destroy private data of set instance
19920a69341SPatrick McHardy  *	@list: nf_tables_set_ops list node
20020a69341SPatrick McHardy  *	@owner: module reference
20120a69341SPatrick McHardy  *	@features: features supported by the implementation
20220a69341SPatrick McHardy  */
20320a69341SPatrick McHardy struct nft_set_ops {
20420a69341SPatrick McHardy 	bool				(*lookup)(const struct nft_set *set,
20520a69341SPatrick McHardy 						  const struct nft_data *key,
20620a69341SPatrick McHardy 						  struct nft_data *data);
20720a69341SPatrick McHardy 	int				(*get)(const struct nft_set *set,
20820a69341SPatrick McHardy 					       struct nft_set_elem *elem);
20920a69341SPatrick McHardy 	int				(*insert)(const struct nft_set *set,
21020a69341SPatrick McHardy 						  const struct nft_set_elem *elem);
21120a69341SPatrick McHardy 	void				(*remove)(const struct nft_set *set,
21220a69341SPatrick McHardy 						  const struct nft_set_elem *elem);
21320a69341SPatrick McHardy 	void				(*walk)(const struct nft_ctx *ctx,
21420a69341SPatrick McHardy 						const struct nft_set *set,
21520a69341SPatrick McHardy 						struct nft_set_iter *iter);
21620a69341SPatrick McHardy 
21720a69341SPatrick McHardy 	unsigned int			(*privsize)(const struct nlattr * const nla[]);
218c50b960cSPatrick McHardy 	bool				(*estimate)(const struct nft_set_desc *desc,
219c50b960cSPatrick McHardy 						    u32 features,
220c50b960cSPatrick McHardy 						    struct nft_set_estimate *est);
22120a69341SPatrick McHardy 	int				(*init)(const struct nft_set *set,
222c50b960cSPatrick McHardy 						const struct nft_set_desc *desc,
22320a69341SPatrick McHardy 						const struct nlattr * const nla[]);
22420a69341SPatrick McHardy 	void				(*destroy)(const struct nft_set *set);
22520a69341SPatrick McHardy 
22620a69341SPatrick McHardy 	struct list_head		list;
22720a69341SPatrick McHardy 	struct module			*owner;
22820a69341SPatrick McHardy 	u32				features;
22920a69341SPatrick McHardy };
23020a69341SPatrick McHardy 
2315eccdfaaSJoe Perches int nft_register_set(struct nft_set_ops *ops);
2325eccdfaaSJoe Perches void nft_unregister_set(struct nft_set_ops *ops);
23320a69341SPatrick McHardy 
23420a69341SPatrick McHardy /**
23520a69341SPatrick McHardy  * 	struct nft_set - nf_tables set instance
23620a69341SPatrick McHardy  *
23720a69341SPatrick McHardy  *	@list: table set list node
23820a69341SPatrick McHardy  *	@bindings: list of set bindings
23920a69341SPatrick McHardy  * 	@name: name of the set
24020a69341SPatrick McHardy  * 	@ktype: key type (numeric type defined by userspace, not used in the kernel)
24120a69341SPatrick McHardy  * 	@dtype: data type (verdict or numeric type defined by userspace)
242c50b960cSPatrick McHardy  * 	@size: maximum set size
243c50b960cSPatrick McHardy  * 	@nelems: number of elements
2449363dc4bSArturo Borrero  *	@policy: set parameterization (see enum nft_set_policies)
24520a69341SPatrick McHardy  * 	@ops: set ops
24620a69341SPatrick McHardy  * 	@flags: set flags
24720a69341SPatrick McHardy  * 	@klen: key length
24820a69341SPatrick McHardy  * 	@dlen: data length
24920a69341SPatrick McHardy  * 	@data: private set data
25020a69341SPatrick McHardy  */
25120a69341SPatrick McHardy struct nft_set {
25220a69341SPatrick McHardy 	struct list_head		list;
25320a69341SPatrick McHardy 	struct list_head		bindings;
25420a69341SPatrick McHardy 	char				name[IFNAMSIZ];
25520a69341SPatrick McHardy 	u32				ktype;
25620a69341SPatrick McHardy 	u32				dtype;
257c50b960cSPatrick McHardy 	u32				size;
258c50b960cSPatrick McHardy 	u32				nelems;
2599363dc4bSArturo Borrero 	u16				policy;
26020a69341SPatrick McHardy 	/* runtime data below here */
26120a69341SPatrick McHardy 	const struct nft_set_ops	*ops ____cacheline_aligned;
26220a69341SPatrick McHardy 	u16				flags;
26320a69341SPatrick McHardy 	u8				klen;
26420a69341SPatrick McHardy 	u8				dlen;
26520a69341SPatrick McHardy 	unsigned char			data[]
26620a69341SPatrick McHardy 		__attribute__((aligned(__alignof__(u64))));
26720a69341SPatrick McHardy };
26820a69341SPatrick McHardy 
26920a69341SPatrick McHardy static inline void *nft_set_priv(const struct nft_set *set)
27020a69341SPatrick McHardy {
27120a69341SPatrick McHardy 	return (void *)set->data;
27220a69341SPatrick McHardy }
27320a69341SPatrick McHardy 
2745eccdfaaSJoe Perches struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
27520a69341SPatrick McHardy 				     const struct nlattr *nla);
276958bee14SPablo Neira Ayuso struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
277958bee14SPablo Neira Ayuso 					  const struct nlattr *nla);
27820a69341SPatrick McHardy 
27920a69341SPatrick McHardy /**
28020a69341SPatrick McHardy  *	struct nft_set_binding - nf_tables set binding
28120a69341SPatrick McHardy  *
28220a69341SPatrick McHardy  *	@list: set bindings list node
28320a69341SPatrick McHardy  *	@chain: chain containing the rule bound to the set
28420a69341SPatrick McHardy  *
28520a69341SPatrick McHardy  *	A set binding contains all information necessary for validation
28620a69341SPatrick McHardy  *	of new elements added to a bound set.
28720a69341SPatrick McHardy  */
28820a69341SPatrick McHardy struct nft_set_binding {
28920a69341SPatrick McHardy 	struct list_head		list;
29020a69341SPatrick McHardy 	const struct nft_chain		*chain;
29120a69341SPatrick McHardy };
29220a69341SPatrick McHardy 
2935eccdfaaSJoe Perches int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
29420a69341SPatrick McHardy 		       struct nft_set_binding *binding);
2955eccdfaaSJoe Perches void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
29620a69341SPatrick McHardy 			  struct nft_set_binding *binding);
29720a69341SPatrick McHardy 
298ef1f7df9SPatrick McHardy 
29920a69341SPatrick McHardy /**
300ef1f7df9SPatrick McHardy  *	struct nft_expr_type - nf_tables expression type
30196518518SPatrick McHardy  *
302ef1f7df9SPatrick McHardy  *	@select_ops: function to select nft_expr_ops
303ef1f7df9SPatrick McHardy  *	@ops: default ops, used when no select_ops functions is present
30496518518SPatrick McHardy  *	@list: used internally
30596518518SPatrick McHardy  *	@name: Identifier
30696518518SPatrick McHardy  *	@owner: module reference
30796518518SPatrick McHardy  *	@policy: netlink attribute policy
30896518518SPatrick McHardy  *	@maxattr: highest netlink attribute number
30964d46806SPatrick McHardy  *	@family: address family for AF-specific types
310ef1f7df9SPatrick McHardy  */
311ef1f7df9SPatrick McHardy struct nft_expr_type {
3120ca743a5SPablo Neira Ayuso 	const struct nft_expr_ops	*(*select_ops)(const struct nft_ctx *,
3130ca743a5SPablo Neira Ayuso 						       const struct nlattr * const tb[]);
314ef1f7df9SPatrick McHardy 	const struct nft_expr_ops	*ops;
315ef1f7df9SPatrick McHardy 	struct list_head		list;
316ef1f7df9SPatrick McHardy 	const char			*name;
317ef1f7df9SPatrick McHardy 	struct module			*owner;
318ef1f7df9SPatrick McHardy 	const struct nla_policy		*policy;
319ef1f7df9SPatrick McHardy 	unsigned int			maxattr;
32064d46806SPatrick McHardy 	u8				family;
321ef1f7df9SPatrick McHardy };
322ef1f7df9SPatrick McHardy 
323ef1f7df9SPatrick McHardy /**
324ef1f7df9SPatrick McHardy  *	struct nft_expr_ops - nf_tables expression operations
325ef1f7df9SPatrick McHardy  *
326ef1f7df9SPatrick McHardy  *	@eval: Expression evaluation function
32796518518SPatrick McHardy  *	@size: full expression size, including private data size
328ef1f7df9SPatrick McHardy  *	@init: initialization function
329ef1f7df9SPatrick McHardy  *	@destroy: destruction function
330ef1f7df9SPatrick McHardy  *	@dump: function to dump parameters
331ef1f7df9SPatrick McHardy  *	@type: expression type
3320ca743a5SPablo Neira Ayuso  *	@validate: validate expression, called during loop detection
3330ca743a5SPablo Neira Ayuso  *	@data: extra data to attach to this expression operation
33496518518SPatrick McHardy  */
33596518518SPatrick McHardy struct nft_expr;
33696518518SPatrick McHardy struct nft_expr_ops {
33796518518SPatrick McHardy 	void				(*eval)(const struct nft_expr *expr,
33896518518SPatrick McHardy 						struct nft_data data[NFT_REG_MAX + 1],
33996518518SPatrick McHardy 						const struct nft_pktinfo *pkt);
340ef1f7df9SPatrick McHardy 	unsigned int			size;
341ef1f7df9SPatrick McHardy 
34296518518SPatrick McHardy 	int				(*init)(const struct nft_ctx *ctx,
34396518518SPatrick McHardy 						const struct nft_expr *expr,
34496518518SPatrick McHardy 						const struct nlattr * const tb[]);
34562472bceSPatrick McHardy 	void				(*destroy)(const struct nft_ctx *ctx,
34662472bceSPatrick McHardy 						   const struct nft_expr *expr);
34796518518SPatrick McHardy 	int				(*dump)(struct sk_buff *skb,
34896518518SPatrick McHardy 						const struct nft_expr *expr);
3490ca743a5SPablo Neira Ayuso 	int				(*validate)(const struct nft_ctx *ctx,
3500ca743a5SPablo Neira Ayuso 						    const struct nft_expr *expr,
3510ca743a5SPablo Neira Ayuso 						    const struct nft_data **data);
352ef1f7df9SPatrick McHardy 	const struct nft_expr_type	*type;
3530ca743a5SPablo Neira Ayuso 	void				*data;
35496518518SPatrick McHardy };
35596518518SPatrick McHardy 
356ef1f7df9SPatrick McHardy #define NFT_EXPR_MAXATTR		16
35796518518SPatrick McHardy #define NFT_EXPR_SIZE(size)		(sizeof(struct nft_expr) + \
35896518518SPatrick McHardy 					 ALIGN(size, __alignof__(struct nft_expr)))
35996518518SPatrick McHardy 
36096518518SPatrick McHardy /**
36196518518SPatrick McHardy  *	struct nft_expr - nf_tables expression
36296518518SPatrick McHardy  *
36396518518SPatrick McHardy  *	@ops: expression ops
36496518518SPatrick McHardy  *	@data: expression private data
36596518518SPatrick McHardy  */
36696518518SPatrick McHardy struct nft_expr {
36796518518SPatrick McHardy 	const struct nft_expr_ops	*ops;
36896518518SPatrick McHardy 	unsigned char			data[];
36996518518SPatrick McHardy };
37096518518SPatrick McHardy 
37196518518SPatrick McHardy static inline void *nft_expr_priv(const struct nft_expr *expr)
37296518518SPatrick McHardy {
37396518518SPatrick McHardy 	return (void *)expr->data;
37496518518SPatrick McHardy }
37596518518SPatrick McHardy 
37696518518SPatrick McHardy /**
37796518518SPatrick McHardy  *	struct nft_rule - nf_tables rule
37896518518SPatrick McHardy  *
37996518518SPatrick McHardy  *	@list: used internally
38096518518SPatrick McHardy  *	@handle: rule handle
3810628b123SPablo Neira Ayuso  *	@genmask: generation mask
38296518518SPatrick McHardy  *	@dlen: length of expression data
3830768b3b3SPablo Neira Ayuso  *	@ulen: length of user data (used for comments)
38496518518SPatrick McHardy  *	@data: expression data
38596518518SPatrick McHardy  */
38696518518SPatrick McHardy struct nft_rule {
38796518518SPatrick McHardy 	struct list_head		list;
3880768b3b3SPablo Neira Ayuso 	u64				handle:42,
3890628b123SPablo Neira Ayuso 					genmask:2,
3900768b3b3SPablo Neira Ayuso 					dlen:12,
3910768b3b3SPablo Neira Ayuso 					ulen:8;
39296518518SPatrick McHardy 	unsigned char			data[]
39396518518SPatrick McHardy 		__attribute__((aligned(__alignof__(struct nft_expr))));
39496518518SPatrick McHardy };
39596518518SPatrick McHardy 
39696518518SPatrick McHardy static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
39796518518SPatrick McHardy {
39896518518SPatrick McHardy 	return (struct nft_expr *)&rule->data[0];
39996518518SPatrick McHardy }
40096518518SPatrick McHardy 
40196518518SPatrick McHardy static inline struct nft_expr *nft_expr_next(const struct nft_expr *expr)
40296518518SPatrick McHardy {
40396518518SPatrick McHardy 	return ((void *)expr) + expr->ops->size;
40496518518SPatrick McHardy }
40596518518SPatrick McHardy 
40696518518SPatrick McHardy static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
40796518518SPatrick McHardy {
40896518518SPatrick McHardy 	return (struct nft_expr *)&rule->data[rule->dlen];
40996518518SPatrick McHardy }
41096518518SPatrick McHardy 
4110768b3b3SPablo Neira Ayuso static inline void *nft_userdata(const struct nft_rule *rule)
4120768b3b3SPablo Neira Ayuso {
4130768b3b3SPablo Neira Ayuso 	return (void *)&rule->data[rule->dlen];
4140768b3b3SPablo Neira Ayuso }
4150768b3b3SPablo Neira Ayuso 
41696518518SPatrick McHardy /*
41796518518SPatrick McHardy  * The last pointer isn't really necessary, but the compiler isn't able to
41896518518SPatrick McHardy  * determine that the result of nft_expr_last() is always the same since it
41996518518SPatrick McHardy  * can't assume that the dlen value wasn't changed within calls in the loop.
42096518518SPatrick McHardy  */
42196518518SPatrick McHardy #define nft_rule_for_each_expr(expr, last, rule) \
42296518518SPatrick McHardy 	for ((expr) = nft_expr_first(rule), (last) = nft_expr_last(rule); \
42396518518SPatrick McHardy 	     (expr) != (last); \
42496518518SPatrick McHardy 	     (expr) = nft_expr_next(expr))
42596518518SPatrick McHardy 
42696518518SPatrick McHardy enum nft_chain_flags {
42796518518SPatrick McHardy 	NFT_BASE_CHAIN			= 0x1,
42891c7b38dSPablo Neira Ayuso 	NFT_CHAIN_INACTIVE		= 0x2,
42996518518SPatrick McHardy };
43096518518SPatrick McHardy 
43196518518SPatrick McHardy /**
43296518518SPatrick McHardy  *	struct nft_chain - nf_tables chain
43396518518SPatrick McHardy  *
43496518518SPatrick McHardy  *	@rules: list of rules in the chain
43596518518SPatrick McHardy  *	@list: used internally
4360628b123SPablo Neira Ayuso  *	@net: net namespace that this chain belongs to
437b5bc89bfSPablo Neira Ayuso  *	@table: table that this chain belongs to
43896518518SPatrick McHardy  *	@handle: chain handle
43996518518SPatrick McHardy  *	@use: number of jump references to this chain
44096518518SPatrick McHardy  *	@level: length of longest path to this chain
441a0a7379eSPablo Neira Ayuso  *	@flags: bitmask of enum nft_chain_flags
44296518518SPatrick McHardy  *	@name: name of the chain
44396518518SPatrick McHardy  */
44496518518SPatrick McHardy struct nft_chain {
44596518518SPatrick McHardy 	struct list_head		rules;
44696518518SPatrick McHardy 	struct list_head		list;
4470628b123SPablo Neira Ayuso 	struct net			*net;
448b5bc89bfSPablo Neira Ayuso 	struct nft_table		*table;
44996518518SPatrick McHardy 	u64				handle;
450a0a7379eSPablo Neira Ayuso 	u32				use;
45196518518SPatrick McHardy 	u16				level;
452a0a7379eSPablo Neira Ayuso 	u8				flags;
45396518518SPatrick McHardy 	char				name[NFT_CHAIN_MAXNAMELEN];
45496518518SPatrick McHardy };
45596518518SPatrick McHardy 
4569370761cSPablo Neira Ayuso enum nft_chain_type {
4579370761cSPablo Neira Ayuso 	NFT_CHAIN_T_DEFAULT = 0,
4589370761cSPablo Neira Ayuso 	NFT_CHAIN_T_ROUTE,
4599370761cSPablo Neira Ayuso 	NFT_CHAIN_T_NAT,
4609370761cSPablo Neira Ayuso 	NFT_CHAIN_T_MAX
4619370761cSPablo Neira Ayuso };
4629370761cSPablo Neira Ayuso 
4631a1e1a12SPatrick McHardy /**
4641a1e1a12SPatrick McHardy  * 	struct nf_chain_type - nf_tables chain type info
4651a1e1a12SPatrick McHardy  *
4661a1e1a12SPatrick McHardy  * 	@name: name of the type
4671a1e1a12SPatrick McHardy  * 	@type: numeric identifier
4681a1e1a12SPatrick McHardy  * 	@family: address family
4691a1e1a12SPatrick McHardy  * 	@owner: module owner
4701a1e1a12SPatrick McHardy  * 	@hook_mask: mask of valid hooks
4711a1e1a12SPatrick McHardy  * 	@hooks: hookfn overrides
4721a1e1a12SPatrick McHardy  */
4731a1e1a12SPatrick McHardy struct nf_chain_type {
4741a1e1a12SPatrick McHardy 	const char			*name;
4751a1e1a12SPatrick McHardy 	enum nft_chain_type		type;
4761a1e1a12SPatrick McHardy 	int				family;
4771a1e1a12SPatrick McHardy 	struct module			*owner;
4781a1e1a12SPatrick McHardy 	unsigned int			hook_mask;
4791a1e1a12SPatrick McHardy 	nf_hookfn			*hooks[NF_MAX_HOOKS];
4801a1e1a12SPatrick McHardy };
4811a1e1a12SPatrick McHardy 
4827210e4e3SPablo Neira Ayuso int nft_chain_validate_dependency(const struct nft_chain *chain,
4837210e4e3SPablo Neira Ayuso 				  enum nft_chain_type type);
48475e8d06dSPablo Neira Ayuso int nft_chain_validate_hooks(const struct nft_chain *chain,
48575e8d06dSPablo Neira Ayuso                              unsigned int hook_flags);
4867210e4e3SPablo Neira Ayuso 
4870ca743a5SPablo Neira Ayuso struct nft_stats {
4880ca743a5SPablo Neira Ayuso 	u64			bytes;
4890ca743a5SPablo Neira Ayuso 	u64			pkts;
490ce355e20SEric Dumazet 	struct u64_stats_sync	syncp;
4910ca743a5SPablo Neira Ayuso };
4920ca743a5SPablo Neira Ayuso 
493115a60b1SPatrick McHardy #define NFT_HOOK_OPS_MAX		2
494115a60b1SPatrick McHardy 
49596518518SPatrick McHardy /**
49696518518SPatrick McHardy  *	struct nft_base_chain - nf_tables base chain
49796518518SPatrick McHardy  *
49896518518SPatrick McHardy  *	@ops: netfilter hook ops
4999370761cSPablo Neira Ayuso  *	@type: chain type
5000ca743a5SPablo Neira Ayuso  *	@policy: default policy
5010ca743a5SPablo Neira Ayuso  *	@stats: per-cpu chain stats
50296518518SPatrick McHardy  *	@chain: the chain
50396518518SPatrick McHardy  */
50496518518SPatrick McHardy struct nft_base_chain {
505115a60b1SPatrick McHardy 	struct nf_hook_ops		ops[NFT_HOOK_OPS_MAX];
5062a37d755SPatrick McHardy 	const struct nf_chain_type	*type;
5070ca743a5SPablo Neira Ayuso 	u8				policy;
5080ca743a5SPablo Neira Ayuso 	struct nft_stats __percpu	*stats;
50996518518SPatrick McHardy 	struct nft_chain		chain;
51096518518SPatrick McHardy };
51196518518SPatrick McHardy 
51296518518SPatrick McHardy static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chain)
51396518518SPatrick McHardy {
51496518518SPatrick McHardy 	return container_of(chain, struct nft_base_chain, chain);
51596518518SPatrick McHardy }
51696518518SPatrick McHardy 
5173876d22dSPatrick McHardy unsigned int nft_do_chain(struct nft_pktinfo *pkt,
5180ca743a5SPablo Neira Ayuso 			  const struct nf_hook_ops *ops);
51996518518SPatrick McHardy 
52096518518SPatrick McHardy /**
52196518518SPatrick McHardy  *	struct nft_table - nf_tables table
52296518518SPatrick McHardy  *
52396518518SPatrick McHardy  *	@list: used internally
52496518518SPatrick McHardy  *	@chains: chains in the table
52596518518SPatrick McHardy  *	@sets: sets in the table
52696518518SPatrick McHardy  *	@hgenerator: handle generator state
52796518518SPatrick McHardy  *	@use: number of chain references to this table
52896518518SPatrick McHardy  *	@flags: table flag (see enum nft_table_flags)
52996518518SPatrick McHardy  *	@name: name of the table
53096518518SPatrick McHardy  */
53196518518SPatrick McHardy struct nft_table {
53296518518SPatrick McHardy 	struct list_head		list;
53396518518SPatrick McHardy 	struct list_head		chains;
53496518518SPatrick McHardy 	struct list_head		sets;
53596518518SPatrick McHardy 	u64				hgenerator;
53696518518SPatrick McHardy 	u32				use;
53796518518SPatrick McHardy 	u16				flags;
53896518518SPatrick McHardy 	char				name[];
53996518518SPatrick McHardy };
54096518518SPatrick McHardy 
54196518518SPatrick McHardy /**
54296518518SPatrick McHardy  *	struct nft_af_info - nf_tables address family info
54396518518SPatrick McHardy  *
54496518518SPatrick McHardy  *	@list: used internally
54596518518SPatrick McHardy  *	@family: address family
54696518518SPatrick McHardy  *	@nhooks: number of hooks in this family
54796518518SPatrick McHardy  *	@owner: module owner
54896518518SPatrick McHardy  *	@tables: used internally
549115a60b1SPatrick McHardy  *	@nops: number of hook ops in this family
550115a60b1SPatrick McHardy  *	@hook_ops_init: initialization function for chain hook ops
55196518518SPatrick McHardy  *	@hooks: hookfn overrides for packet validation
55296518518SPatrick McHardy  */
55396518518SPatrick McHardy struct nft_af_info {
55496518518SPatrick McHardy 	struct list_head		list;
55596518518SPatrick McHardy 	int				family;
55696518518SPatrick McHardy 	unsigned int			nhooks;
55796518518SPatrick McHardy 	struct module			*owner;
55896518518SPatrick McHardy 	struct list_head		tables;
559115a60b1SPatrick McHardy 	unsigned int			nops;
560115a60b1SPatrick McHardy 	void				(*hook_ops_init)(struct nf_hook_ops *,
561115a60b1SPatrick McHardy 							 unsigned int);
56296518518SPatrick McHardy 	nf_hookfn			*hooks[NF_MAX_HOOKS];
56396518518SPatrick McHardy };
56496518518SPatrick McHardy 
5655eccdfaaSJoe Perches int nft_register_afinfo(struct net *, struct nft_af_info *);
5665eccdfaaSJoe Perches void nft_unregister_afinfo(struct nft_af_info *);
56796518518SPatrick McHardy 
5682a37d755SPatrick McHardy int nft_register_chain_type(const struct nf_chain_type *);
5692a37d755SPatrick McHardy void nft_unregister_chain_type(const struct nf_chain_type *);
57096518518SPatrick McHardy 
5715eccdfaaSJoe Perches int nft_register_expr(struct nft_expr_type *);
5725eccdfaaSJoe Perches void nft_unregister_expr(struct nft_expr_type *);
57396518518SPatrick McHardy 
57467a8fc27SPatrick McHardy #define nft_dereference(p)					\
57567a8fc27SPatrick McHardy 	nfnl_dereference(p, NFNL_SUBSYS_NFTABLES)
57667a8fc27SPatrick McHardy 
57796518518SPatrick McHardy #define MODULE_ALIAS_NFT_FAMILY(family)	\
57896518518SPatrick McHardy 	MODULE_ALIAS("nft-afinfo-" __stringify(family))
57996518518SPatrick McHardy 
5809370761cSPablo Neira Ayuso #define MODULE_ALIAS_NFT_CHAIN(family, name) \
5819370761cSPablo Neira Ayuso 	MODULE_ALIAS("nft-chain-" __stringify(family) "-" name)
58296518518SPatrick McHardy 
58364d46806SPatrick McHardy #define MODULE_ALIAS_NFT_AF_EXPR(family, name) \
58464d46806SPatrick McHardy 	MODULE_ALIAS("nft-expr-" __stringify(family) "-" name)
58564d46806SPatrick McHardy 
58696518518SPatrick McHardy #define MODULE_ALIAS_NFT_EXPR(name) \
58796518518SPatrick McHardy 	MODULE_ALIAS("nft-expr-" name)
58896518518SPatrick McHardy 
58920a69341SPatrick McHardy #define MODULE_ALIAS_NFT_SET() \
59020a69341SPatrick McHardy 	MODULE_ALIAS("nft-set")
59120a69341SPatrick McHardy 
5921a1e1a12SPatrick McHardy /**
5931a1e1a12SPatrick McHardy  *	struct nft_trans - nf_tables object update in transaction
5941a1e1a12SPatrick McHardy  *
5951a1e1a12SPatrick McHardy  *	@list: used internally
5961a1e1a12SPatrick McHardy  *	@msg_type: message type
5971a1e1a12SPatrick McHardy  *	@ctx: transaction context
5981a1e1a12SPatrick McHardy  *	@data: internal information related to the transaction
5991a1e1a12SPatrick McHardy  */
6001a1e1a12SPatrick McHardy struct nft_trans {
6011a1e1a12SPatrick McHardy 	struct list_head		list;
6021a1e1a12SPatrick McHardy 	int				msg_type;
6031a1e1a12SPatrick McHardy 	struct nft_ctx			ctx;
6041a1e1a12SPatrick McHardy 	char				data[0];
6051a1e1a12SPatrick McHardy };
6061a1e1a12SPatrick McHardy 
6071a1e1a12SPatrick McHardy struct nft_trans_rule {
6081a1e1a12SPatrick McHardy 	struct nft_rule			*rule;
6091a1e1a12SPatrick McHardy };
6101a1e1a12SPatrick McHardy 
6111a1e1a12SPatrick McHardy #define nft_trans_rule(trans)	\
6121a1e1a12SPatrick McHardy 	(((struct nft_trans_rule *)trans->data)->rule)
6131a1e1a12SPatrick McHardy 
6141a1e1a12SPatrick McHardy struct nft_trans_set {
6151a1e1a12SPatrick McHardy 	struct nft_set			*set;
6161a1e1a12SPatrick McHardy 	u32				set_id;
6171a1e1a12SPatrick McHardy };
6181a1e1a12SPatrick McHardy 
6191a1e1a12SPatrick McHardy #define nft_trans_set(trans)	\
6201a1e1a12SPatrick McHardy 	(((struct nft_trans_set *)trans->data)->set)
6211a1e1a12SPatrick McHardy #define nft_trans_set_id(trans)	\
6221a1e1a12SPatrick McHardy 	(((struct nft_trans_set *)trans->data)->set_id)
6231a1e1a12SPatrick McHardy 
6241a1e1a12SPatrick McHardy struct nft_trans_chain {
6251a1e1a12SPatrick McHardy 	bool				update;
6261a1e1a12SPatrick McHardy 	char				name[NFT_CHAIN_MAXNAMELEN];
6271a1e1a12SPatrick McHardy 	struct nft_stats __percpu	*stats;
6281a1e1a12SPatrick McHardy 	u8				policy;
6291a1e1a12SPatrick McHardy };
6301a1e1a12SPatrick McHardy 
6311a1e1a12SPatrick McHardy #define nft_trans_chain_update(trans)	\
6321a1e1a12SPatrick McHardy 	(((struct nft_trans_chain *)trans->data)->update)
6331a1e1a12SPatrick McHardy #define nft_trans_chain_name(trans)	\
6341a1e1a12SPatrick McHardy 	(((struct nft_trans_chain *)trans->data)->name)
6351a1e1a12SPatrick McHardy #define nft_trans_chain_stats(trans)	\
6361a1e1a12SPatrick McHardy 	(((struct nft_trans_chain *)trans->data)->stats)
6371a1e1a12SPatrick McHardy #define nft_trans_chain_policy(trans)	\
6381a1e1a12SPatrick McHardy 	(((struct nft_trans_chain *)trans->data)->policy)
6391a1e1a12SPatrick McHardy 
6401a1e1a12SPatrick McHardy struct nft_trans_table {
6411a1e1a12SPatrick McHardy 	bool				update;
6421a1e1a12SPatrick McHardy 	bool				enable;
6431a1e1a12SPatrick McHardy };
6441a1e1a12SPatrick McHardy 
6451a1e1a12SPatrick McHardy #define nft_trans_table_update(trans)	\
6461a1e1a12SPatrick McHardy 	(((struct nft_trans_table *)trans->data)->update)
6471a1e1a12SPatrick McHardy #define nft_trans_table_enable(trans)	\
6481a1e1a12SPatrick McHardy 	(((struct nft_trans_table *)trans->data)->enable)
6491a1e1a12SPatrick McHardy 
6501a1e1a12SPatrick McHardy struct nft_trans_elem {
6511a1e1a12SPatrick McHardy 	struct nft_set			*set;
6521a1e1a12SPatrick McHardy 	struct nft_set_elem		elem;
6531a1e1a12SPatrick McHardy };
6541a1e1a12SPatrick McHardy 
6551a1e1a12SPatrick McHardy #define nft_trans_elem_set(trans)	\
6561a1e1a12SPatrick McHardy 	(((struct nft_trans_elem *)trans->data)->set)
6571a1e1a12SPatrick McHardy #define nft_trans_elem(trans)	\
6581a1e1a12SPatrick McHardy 	(((struct nft_trans_elem *)trans->data)->elem)
6591a1e1a12SPatrick McHardy 
66096518518SPatrick McHardy #endif /* _NET_NF_TABLES_H */
661