Blame view

include/net/netfilter/nf_tables.h 29.6 KB
96518518c   Patrick McHardy   netfilter: add nf...
1
2
  #ifndef _NET_NF_TABLES_H
  #define _NET_NF_TABLES_H
0b2d8a7b6   Patrick McHardy   netfilter: nf_tab...
3
  #include <linux/module.h>
96518518c   Patrick McHardy   netfilter: add nf...
4
5
  #include <linux/list.h>
  #include <linux/netfilter.h>
67a8fc27c   Patrick McHardy   netfilter: nf_tab...
6
  #include <linux/netfilter/nfnetlink.h>
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
7
  #include <linux/netfilter/x_tables.h>
96518518c   Patrick McHardy   netfilter: add nf...
8
  #include <linux/netfilter/nf_tables.h>
ce355e209   Eric Dumazet   netfilter: nf_tab...
9
  #include <linux/u64_stats_sync.h>
96518518c   Patrick McHardy   netfilter: add nf...
10
  #include <net/netlink.h>
20a69341f   Patrick McHardy   netfilter: nf_tab...
11
  #define NFT_JUMP_STACK_SIZE	16
96518518c   Patrick McHardy   netfilter: add nf...
12
13
  struct nft_pktinfo {
  	struct sk_buff			*skb;
46448d009   Eric W. Biederman   netfilter: nf_tab...
14
  	struct net			*net;
96518518c   Patrick McHardy   netfilter: add nf...
15
16
  	const struct net_device		*in;
  	const struct net_device		*out;
6aa187f21   Eric W. Biederman   netfilter: nf_tab...
17
18
  	u8				pf;
  	u8				hook;
beac5afa2   Pablo Neira Ayuso   netfilter: nf_tab...
19
  	bool				tprot_set;
4566bf270   Patrick McHardy   netfilter: nft_me...
20
  	u8				tprot;
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
21
22
  	/* for x_tables compatibility */
  	struct xt_action_param		xt;
96518518c   Patrick McHardy   netfilter: add nf...
23
  };
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
24
  static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
25
  				   struct sk_buff *skb,
073bfd568   David S. Miller   netfilter: Pass n...
26
  				   const struct nf_hook_state *state)
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
27
28
  {
  	pkt->skb = skb;
46448d009   Eric W. Biederman   netfilter: nf_tab...
29
  	pkt->net = pkt->xt.net = state->net;
073bfd568   David S. Miller   netfilter: Pass n...
30
31
  	pkt->in = pkt->xt.in = state->in;
  	pkt->out = pkt->xt.out = state->out;
6aa187f21   Eric W. Biederman   netfilter: nf_tab...
32
33
  	pkt->hook = pkt->xt.hooknum = state->hook;
  	pkt->pf = pkt->xt.family = state->pf;
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
34
  }
beac5afa2   Pablo Neira Ayuso   netfilter: nf_tab...
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
  static inline void nft_set_pktinfo_proto_unspec(struct nft_pktinfo *pkt,
  						struct sk_buff *skb)
  {
  	pkt->tprot_set = false;
  	pkt->tprot = 0;
  	pkt->xt.thoff = 0;
  	pkt->xt.fragoff = 0;
  }
  
  static inline void nft_set_pktinfo_unspec(struct nft_pktinfo *pkt,
  					  struct sk_buff *skb,
  					  const struct nf_hook_state *state)
  {
  	nft_set_pktinfo(pkt, skb, state);
  	nft_set_pktinfo_proto_unspec(pkt, skb);
  }
a55e22e92   Patrick McHardy   netfilter: nf_tab...
51
52
53
54
55
56
57
58
59
60
  /**
   * 	struct nft_verdict - nf_tables verdict
   *
   * 	@code: nf_tables/netfilter verdict code
   * 	@chain: destination chain for NFT_JUMP/NFT_GOTO
   */
  struct nft_verdict {
  	u32				code;
  	struct nft_chain		*chain;
  };
96518518c   Patrick McHardy   netfilter: add nf...
61
62
  struct nft_data {
  	union {
1ca2e1702   Patrick McHardy   netfilter: nf_tab...
63
64
  		u32			data[4];
  		struct nft_verdict	verdict;
96518518c   Patrick McHardy   netfilter: add nf...
65
66
  	};
  } __attribute__((aligned(__alignof__(u64))));
a55e22e92   Patrick McHardy   netfilter: nf_tab...
67
68
69
70
71
72
73
74
75
76
  /**
   *	struct nft_regs - nf_tables register set
   *
   *	@data: data registers
   *	@verdict: verdict register
   *
   *	The first four data registers alias to the verdict register.
   */
  struct nft_regs {
  	union {
49499c3e6   Patrick McHardy   netfilter: nf_tab...
77
  		u32			data[20];
a55e22e92   Patrick McHardy   netfilter: nf_tab...
78
79
80
  		struct nft_verdict	verdict;
  	};
  };
49499c3e6   Patrick McHardy   netfilter: nf_tab...
81
82
  static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
  				 unsigned int len)
96518518c   Patrick McHardy   netfilter: add nf...
83
  {
49499c3e6   Patrick McHardy   netfilter: nf_tab...
84
  	memcpy(dst, src, len);
96518518c   Patrick McHardy   netfilter: add nf...
85
86
87
88
89
90
91
92
93
94
95
  }
  
  static inline void nft_data_debug(const struct nft_data *data)
  {
  	pr_debug("data[0]=%x data[1]=%x data[2]=%x data[3]=%x
  ",
  		 data->data[0], data->data[1],
  		 data->data[2], data->data[3]);
  }
  
  /**
20a69341f   Patrick McHardy   netfilter: nf_tab...
96
   *	struct nft_ctx - nf_tables rule/set context
96518518c   Patrick McHardy   netfilter: add nf...
97
   *
99633ab29   Pablo Neira Ayuso   netfilter: nf_tab...
98
   *	@net: net namespace
96518518c   Patrick McHardy   netfilter: add nf...
99
100
101
   * 	@afi: address family info
   * 	@table: the table the chain is contained in
   * 	@chain: the chain the rule is contained in
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
102
   *	@nla: netlink attributes
128ad3322   Pablo Neira Ayuso   netfilter: nf_tab...
103
104
105
   *	@portid: netlink portID of the original message
   *	@seq: netlink sequence number
   *	@report: notify via unicast netlink message
96518518c   Patrick McHardy   netfilter: add nf...
106
107
   */
  struct nft_ctx {
99633ab29   Pablo Neira Ayuso   netfilter: nf_tab...
108
  	struct net			*net;
7c95f6d86   Pablo Neira Ayuso   netfilter: nf_tab...
109
110
111
  	struct nft_af_info		*afi;
  	struct nft_table		*table;
  	struct nft_chain		*chain;
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
112
  	const struct nlattr * const 	*nla;
128ad3322   Pablo Neira Ayuso   netfilter: nf_tab...
113
114
115
  	u32				portid;
  	u32				seq;
  	bool				report;
96518518c   Patrick McHardy   netfilter: add nf...
116
  };
96518518c   Patrick McHardy   netfilter: add nf...
117
118
119
120
  struct nft_data_desc {
  	enum nft_data_types		type;
  	unsigned int			len;
  };
d0a11fc3d   Patrick McHardy   netfilter: nf_tab...
121
122
  int nft_data_init(const struct nft_ctx *ctx,
  		  struct nft_data *data, unsigned int size,
5eccdfaab   Joe Perches   nf_tables*.h: Rem...
123
124
125
126
  		  struct nft_data_desc *desc, const struct nlattr *nla);
  void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
  int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
  		  enum nft_data_types type, unsigned int len);
96518518c   Patrick McHardy   netfilter: add nf...
127
128
129
130
131
  
  static inline enum nft_data_types nft_dreg_to_type(enum nft_registers reg)
  {
  	return reg == NFT_REG_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE;
  }
20a69341f   Patrick McHardy   netfilter: nf_tab...
132
133
  static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
  {
bf798657e   Pablo Neira Ayuso   netfilter: nf_tab...
134
  	return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE;
20a69341f   Patrick McHardy   netfilter: nf_tab...
135
  }
f1d505bb7   John W. Linville   netfilter: nf_tab...
136
  int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);
b1c96ed37   Patrick McHardy   netfilter: nf_tab...
137
138
  unsigned int nft_parse_register(const struct nlattr *attr);
  int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
d07db9884   Patrick McHardy   netfilter: nf_tab...
139
  int nft_validate_register_load(enum nft_registers reg, unsigned int len);
1ec10212f   Patrick McHardy   netfilter: nf_tab...
140
141
142
143
  int nft_validate_register_store(const struct nft_ctx *ctx,
  				enum nft_registers reg,
  				const struct nft_data *data,
  				enum nft_data_types type, unsigned int len);
96518518c   Patrick McHardy   netfilter: add nf...
144

86f1ec323   Patrick McHardy   netfilter: nf_tab...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  /**
   *	struct nft_userdata - user defined data associated with an object
   *
   *	@len: length of the data
   *	@data: content
   *
   *	The presence of user data is indicated in an object specific fashion,
   *	so a length of zero can't occur and the value "len" indicates data
   *	of length len + 1.
   */
  struct nft_userdata {
  	u8			len;
  	unsigned char		data[0];
  };
96518518c   Patrick McHardy   netfilter: add nf...
159
  /**
20a69341f   Patrick McHardy   netfilter: nf_tab...
160
161
   *	struct nft_set_elem - generic representation of set elements
   *
20a69341f   Patrick McHardy   netfilter: nf_tab...
162
   *	@key: element key
fe2811ebe   Patrick McHardy   netfilter: nf_tab...
163
   *	@priv: element private data and extensions
20a69341f   Patrick McHardy   netfilter: nf_tab...
164
165
   */
  struct nft_set_elem {
7d7402642   Patrick McHardy   netfilter: nf_tab...
166
167
168
169
  	union {
  		u32		buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
  		struct nft_data	val;
  	} key;
fe2811ebe   Patrick McHardy   netfilter: nf_tab...
170
  	void			*priv;
20a69341f   Patrick McHardy   netfilter: nf_tab...
171
172
173
174
  };
  
  struct nft_set;
  struct nft_set_iter {
8588ac097   Pablo Neira Ayuso   netfilter: nf_tab...
175
  	u8		genmask;
20a69341f   Patrick McHardy   netfilter: nf_tab...
176
177
178
179
180
181
182
183
184
185
  	unsigned int	count;
  	unsigned int	skip;
  	int		err;
  	int		(*fn)(const struct nft_ctx *ctx,
  			      const struct nft_set *set,
  			      const struct nft_set_iter *iter,
  			      const struct nft_set_elem *elem);
  };
  
  /**
c50b960cc   Patrick McHardy   netfilter: nf_tab...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
   *	struct nft_set_desc - description of set elements
   *
   *	@klen: key length
   *	@dlen: data length
   *	@size: number of set elements
   */
  struct nft_set_desc {
  	unsigned int		klen;
  	unsigned int		dlen;
  	unsigned int		size;
  };
  
  /**
   *	enum nft_set_class - performance class
   *
   *	@NFT_LOOKUP_O_1: constant, O(1)
   *	@NFT_LOOKUP_O_LOG_N: logarithmic, O(log N)
   *	@NFT_LOOKUP_O_N: linear, O(N)
   */
  enum nft_set_class {
  	NFT_SET_CLASS_O_1,
  	NFT_SET_CLASS_O_LOG_N,
  	NFT_SET_CLASS_O_N,
  };
  
  /**
   *	struct nft_set_estimate - estimation of memory and performance
   *				  characteristics
   *
   *	@size: required memory
   *	@class: lookup performance class
   */
  struct nft_set_estimate {
  	unsigned int		size;
  	enum nft_set_class	class;
  };
b2832dd66   Patrick McHardy   netfilter: nf_tab...
222
  struct nft_set_ext;
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
223
  struct nft_expr;
b2832dd66   Patrick McHardy   netfilter: nf_tab...
224

c50b960cc   Patrick McHardy   netfilter: nf_tab...
225
  /**
20a69341f   Patrick McHardy   netfilter: nf_tab...
226
227
228
229
   *	struct nft_set_ops - nf_tables set operations
   *
   *	@lookup: look up an element within the set
   *	@insert: insert new element into set
cc02e457b   Patrick McHardy   netfilter: nf_tab...
230
231
   *	@activate: activate new element in the next generation
   *	@deactivate: deactivate element in the next generation
20a69341f   Patrick McHardy   netfilter: nf_tab...
232
233
234
235
236
237
238
   *	@remove: remove element from set
   *	@walk: iterate over all set elemeennts
   *	@privsize: function to return size of set private data
   *	@init: initialize private data of new set instance
   *	@destroy: destroy private data of set instance
   *	@list: nf_tables_set_ops list node
   *	@owner: module reference
fe2811ebe   Patrick McHardy   netfilter: nf_tab...
239
   *	@elemsize: element private size
20a69341f   Patrick McHardy   netfilter: nf_tab...
240
241
242
   *	@features: features supported by the implementation
   */
  struct nft_set_ops {
42a557691   Pablo Neira Ayuso   netfilter: nf_tab...
243
244
  	bool				(*lookup)(const struct net *net,
  						  const struct nft_set *set,
8cd8937ac   Patrick McHardy   netfilter: nf_tab...
245
  						  const u32 *key,
b2832dd66   Patrick McHardy   netfilter: nf_tab...
246
  						  const struct nft_set_ext **ext);
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
247
  	bool				(*update)(struct nft_set *set,
8cd8937ac   Patrick McHardy   netfilter: nf_tab...
248
  						  const u32 *key,
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
249
250
  						  void *(*new)(struct nft_set *,
  							       const struct nft_expr *,
a55e22e92   Patrick McHardy   netfilter: nf_tab...
251
  							       struct nft_regs *),
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
252
  						  const struct nft_expr *expr,
a55e22e92   Patrick McHardy   netfilter: nf_tab...
253
  						  struct nft_regs *regs,
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
254
  						  const struct nft_set_ext **ext);
42a557691   Pablo Neira Ayuso   netfilter: nf_tab...
255
256
  	int				(*insert)(const struct net *net,
  						  const struct nft_set *set,
c016c7e45   Pablo Neira Ayuso   netfilter: nf_tab...
257
258
  						  const struct nft_set_elem *elem,
  						  struct nft_set_ext **ext);
42a557691   Pablo Neira Ayuso   netfilter: nf_tab...
259
260
  	void				(*activate)(const struct net *net,
  						    const struct nft_set *set,
cc02e457b   Patrick McHardy   netfilter: nf_tab...
261
  						    const struct nft_set_elem *elem);
42a557691   Pablo Neira Ayuso   netfilter: nf_tab...
262
263
  	void *				(*deactivate)(const struct net *net,
  						      const struct nft_set *set,
cc02e457b   Patrick McHardy   netfilter: nf_tab...
264
  						      const struct nft_set_elem *elem);
20a69341f   Patrick McHardy   netfilter: nf_tab...
265
266
267
268
269
270
271
  	void				(*remove)(const struct nft_set *set,
  						  const struct nft_set_elem *elem);
  	void				(*walk)(const struct nft_ctx *ctx,
  						const struct nft_set *set,
  						struct nft_set_iter *iter);
  
  	unsigned int			(*privsize)(const struct nlattr * const nla[]);
c50b960cc   Patrick McHardy   netfilter: nf_tab...
272
273
274
  	bool				(*estimate)(const struct nft_set_desc *desc,
  						    u32 features,
  						    struct nft_set_estimate *est);
20a69341f   Patrick McHardy   netfilter: nf_tab...
275
  	int				(*init)(const struct nft_set *set,
c50b960cc   Patrick McHardy   netfilter: nf_tab...
276
  						const struct nft_set_desc *desc,
20a69341f   Patrick McHardy   netfilter: nf_tab...
277
278
279
280
281
  						const struct nlattr * const nla[]);
  	void				(*destroy)(const struct nft_set *set);
  
  	struct list_head		list;
  	struct module			*owner;
fe2811ebe   Patrick McHardy   netfilter: nf_tab...
282
  	unsigned int			elemsize;
20a69341f   Patrick McHardy   netfilter: nf_tab...
283
284
  	u32				features;
  };
5eccdfaab   Joe Perches   nf_tables*.h: Rem...
285
286
  int nft_register_set(struct nft_set_ops *ops);
  void nft_unregister_set(struct nft_set_ops *ops);
20a69341f   Patrick McHardy   netfilter: nf_tab...
287
288
289
290
291
292
293
294
295
  
  /**
   * 	struct nft_set - nf_tables set instance
   *
   *	@list: table set list node
   *	@bindings: list of set bindings
   * 	@name: name of the set
   * 	@ktype: key type (numeric type defined by userspace, not used in the kernel)
   * 	@dtype: data type (verdict or numeric type defined by userspace)
c50b960cc   Patrick McHardy   netfilter: nf_tab...
296
297
   * 	@size: maximum set size
   * 	@nelems: number of elements
3dd0673ac   Patrick McHardy   netfilter: nf_tab...
298
   * 	@ndeact: number of deactivated elements queued for removal
d3e2a1110   Anders K. Pedersen   netfilter: nf_tab...
299
   *	@timeout: default timeout value in jiffies
761da2935   Patrick McHardy   netfilter: nf_tab...
300
   * 	@gc_int: garbage collection interval in msecs
9363dc4b5   Arturo Borrero   netfilter: nf_tab...
301
   *	@policy: set parameterization (see enum nft_set_policies)
e6d8ecac9   Carlos Falgueras García   netfilter: nf_tab...
302
303
   *	@udlen: user data length
   *	@udata: user data
20a69341f   Patrick McHardy   netfilter: nf_tab...
304
305
   * 	@ops: set ops
   * 	@flags: set flags
37a9cc525   Pablo Neira Ayuso   netfilter: nf_tab...
306
   *	@genmask: generation mask
20a69341f   Patrick McHardy   netfilter: nf_tab...
307
308
309
310
311
312
313
   * 	@klen: key length
   * 	@dlen: data length
   * 	@data: private set data
   */
  struct nft_set {
  	struct list_head		list;
  	struct list_head		bindings;
cb39ad8b8   Pablo Neira Ayuso   netfilter: nf_tab...
314
  	char				name[NFT_SET_MAXNAMELEN];
20a69341f   Patrick McHardy   netfilter: nf_tab...
315
316
  	u32				ktype;
  	u32				dtype;
c50b960cc   Patrick McHardy   netfilter: nf_tab...
317
  	u32				size;
3dd0673ac   Patrick McHardy   netfilter: nf_tab...
318
319
  	atomic_t			nelems;
  	u32				ndeact;
761da2935   Patrick McHardy   netfilter: nf_tab...
320
321
  	u64				timeout;
  	u32				gc_int;
9363dc4b5   Arturo Borrero   netfilter: nf_tab...
322
  	u16				policy;
e6d8ecac9   Carlos Falgueras García   netfilter: nf_tab...
323
324
  	u16				udlen;
  	unsigned char			*udata;
20a69341f   Patrick McHardy   netfilter: nf_tab...
325
326
  	/* runtime data below here */
  	const struct nft_set_ops	*ops ____cacheline_aligned;
37a9cc525   Pablo Neira Ayuso   netfilter: nf_tab...
327
328
  	u16				flags:14,
  					genmask:2;
20a69341f   Patrick McHardy   netfilter: nf_tab...
329
330
331
332
333
334
335
336
337
338
  	u8				klen;
  	u8				dlen;
  	unsigned char			data[]
  		__attribute__((aligned(__alignof__(u64))));
  };
  
  static inline void *nft_set_priv(const struct nft_set *set)
  {
  	return (void *)set->data;
  }
9d0982927   Patrick McHardy   netfilter: nft_ha...
339
340
341
342
  static inline struct nft_set *nft_set_container_of(const void *priv)
  {
  	return (void *)priv - offsetof(struct nft_set, data);
  }
5eccdfaab   Joe Perches   nf_tables*.h: Rem...
343
  struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
37a9cc525   Pablo Neira Ayuso   netfilter: nf_tab...
344
  				     const struct nlattr *nla, u8 genmask);
958bee14d   Pablo Neira Ayuso   netfilter: nf_tab...
345
  struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
37a9cc525   Pablo Neira Ayuso   netfilter: nf_tab...
346
  					  const struct nlattr *nla, u8 genmask);
20a69341f   Patrick McHardy   netfilter: nf_tab...
347

761da2935   Patrick McHardy   netfilter: nf_tab...
348
349
350
351
  static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
  {
  	return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ;
  }
20a69341f   Patrick McHardy   netfilter: nf_tab...
352
353
354
355
356
  /**
   *	struct nft_set_binding - nf_tables set binding
   *
   *	@list: set bindings list node
   *	@chain: chain containing the rule bound to the set
11113e190   Patrick McHardy   netfilter: nf_tab...
357
   *	@flags: set action flags
20a69341f   Patrick McHardy   netfilter: nf_tab...
358
359
360
361
362
363
364
   *
   *	A set binding contains all information necessary for validation
   *	of new elements added to a bound set.
   */
  struct nft_set_binding {
  	struct list_head		list;
  	const struct nft_chain		*chain;
11113e190   Patrick McHardy   netfilter: nf_tab...
365
  	u32				flags;
20a69341f   Patrick McHardy   netfilter: nf_tab...
366
  };
5eccdfaab   Joe Perches   nf_tables*.h: Rem...
367
368
369
370
  int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
  		       struct nft_set_binding *binding);
  void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
  			  struct nft_set_binding *binding);
20a69341f   Patrick McHardy   netfilter: nf_tab...
371

3ac4c07a2   Patrick McHardy   netfilter: nf_tab...
372
373
374
375
376
377
  /**
   *	enum nft_set_extensions - set extension type IDs
   *
   *	@NFT_SET_EXT_KEY: element key
   *	@NFT_SET_EXT_DATA: mapping data
   *	@NFT_SET_EXT_FLAGS: element flags
c3e1b005e   Patrick McHardy   netfilter: nf_tab...
378
379
   *	@NFT_SET_EXT_TIMEOUT: element timeout
   *	@NFT_SET_EXT_EXPIRATION: element expiration time
68e942e88   Patrick McHardy   netfilter: nf_tab...
380
   *	@NFT_SET_EXT_USERDATA: user data associated with the element
f25ad2e90   Patrick McHardy   netfilter: nf_tab...
381
   *	@NFT_SET_EXT_EXPR: expression assiociated with the element
3ac4c07a2   Patrick McHardy   netfilter: nf_tab...
382
383
384
385
386
387
   *	@NFT_SET_EXT_NUM: number of extension types
   */
  enum nft_set_extensions {
  	NFT_SET_EXT_KEY,
  	NFT_SET_EXT_DATA,
  	NFT_SET_EXT_FLAGS,
c3e1b005e   Patrick McHardy   netfilter: nf_tab...
388
389
  	NFT_SET_EXT_TIMEOUT,
  	NFT_SET_EXT_EXPIRATION,
68e942e88   Patrick McHardy   netfilter: nf_tab...
390
  	NFT_SET_EXT_USERDATA,
f25ad2e90   Patrick McHardy   netfilter: nf_tab...
391
  	NFT_SET_EXT_EXPR,
3ac4c07a2   Patrick McHardy   netfilter: nf_tab...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  	NFT_SET_EXT_NUM
  };
  
  /**
   *	struct nft_set_ext_type - set extension type
   *
   * 	@len: fixed part length of the extension
   * 	@align: alignment requirements of the extension
   */
  struct nft_set_ext_type {
  	u8	len;
  	u8	align;
  };
  
  extern const struct nft_set_ext_type nft_set_ext_types[];
  
  /**
   *	struct nft_set_ext_tmpl - set extension template
   *
   *	@len: length of extension area
   *	@offset: offsets of individual extension types
   */
  struct nft_set_ext_tmpl {
  	u16	len;
  	u8	offset[NFT_SET_EXT_NUM];
  };
  
  /**
   *	struct nft_set_ext - set extensions
   *
cc02e457b   Patrick McHardy   netfilter: nf_tab...
422
   *	@genmask: generation mask
3ac4c07a2   Patrick McHardy   netfilter: nf_tab...
423
424
425
426
   *	@offset: offsets of individual extension types
   *	@data: beginning of extension data
   */
  struct nft_set_ext {
cc02e457b   Patrick McHardy   netfilter: nf_tab...
427
  	u8	genmask;
3ac4c07a2   Patrick McHardy   netfilter: nf_tab...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
  	u8	offset[NFT_SET_EXT_NUM];
  	char	data[0];
  };
  
  static inline void nft_set_ext_prepare(struct nft_set_ext_tmpl *tmpl)
  {
  	memset(tmpl, 0, sizeof(*tmpl));
  	tmpl->len = sizeof(struct nft_set_ext);
  }
  
  static inline void nft_set_ext_add_length(struct nft_set_ext_tmpl *tmpl, u8 id,
  					  unsigned int len)
  {
  	tmpl->len	 = ALIGN(tmpl->len, nft_set_ext_types[id].align);
  	BUG_ON(tmpl->len > U8_MAX);
  	tmpl->offset[id] = tmpl->len;
  	tmpl->len	+= nft_set_ext_types[id].len + len;
  }
  
  static inline void nft_set_ext_add(struct nft_set_ext_tmpl *tmpl, u8 id)
  {
  	nft_set_ext_add_length(tmpl, id, 0);
  }
  
  static inline void nft_set_ext_init(struct nft_set_ext *ext,
  				    const struct nft_set_ext_tmpl *tmpl)
  {
  	memcpy(ext->offset, tmpl->offset, sizeof(ext->offset));
  }
  
  static inline bool __nft_set_ext_exists(const struct nft_set_ext *ext, u8 id)
  {
  	return !!ext->offset[id];
  }
  
  static inline bool nft_set_ext_exists(const struct nft_set_ext *ext, u8 id)
  {
  	return ext && __nft_set_ext_exists(ext, id);
  }
  
  static inline void *nft_set_ext(const struct nft_set_ext *ext, u8 id)
  {
  	return (void *)ext + ext->offset[id];
  }
  
  static inline struct nft_data *nft_set_ext_key(const struct nft_set_ext *ext)
  {
  	return nft_set_ext(ext, NFT_SET_EXT_KEY);
  }
  
  static inline struct nft_data *nft_set_ext_data(const struct nft_set_ext *ext)
  {
  	return nft_set_ext(ext, NFT_SET_EXT_DATA);
  }
  
  static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext)
  {
  	return nft_set_ext(ext, NFT_SET_EXT_FLAGS);
  }
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
487

c3e1b005e   Patrick McHardy   netfilter: nf_tab...
488
489
490
491
492
493
494
495
496
  static inline u64 *nft_set_ext_timeout(const struct nft_set_ext *ext)
  {
  	return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
  }
  
  static inline unsigned long *nft_set_ext_expiration(const struct nft_set_ext *ext)
  {
  	return nft_set_ext(ext, NFT_SET_EXT_EXPIRATION);
  }
68e942e88   Patrick McHardy   netfilter: nf_tab...
497
498
499
500
  static inline struct nft_userdata *nft_set_ext_userdata(const struct nft_set_ext *ext)
  {
  	return nft_set_ext(ext, NFT_SET_EXT_USERDATA);
  }
f25ad2e90   Patrick McHardy   netfilter: nf_tab...
501
502
503
504
  static inline struct nft_expr *nft_set_ext_expr(const struct nft_set_ext *ext)
  {
  	return nft_set_ext(ext, NFT_SET_EXT_EXPR);
  }
c3e1b005e   Patrick McHardy   netfilter: nf_tab...
505
506
507
508
509
  static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
  {
  	return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
  	       time_is_before_eq_jiffies(*nft_set_ext_expiration(ext));
  }
fe2811ebe   Patrick McHardy   netfilter: nf_tab...
510
511
512
513
514
  static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
  						   void *elem)
  {
  	return elem + set->ops->elemsize;
  }
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
515
516
  void *nft_set_elem_init(const struct nft_set *set,
  			const struct nft_set_ext_tmpl *tmpl,
49499c3e6   Patrick McHardy   netfilter: nf_tab...
517
  			const u32 *key, const u32 *data,
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
518
  			u64 timeout, gfp_t gfp);
61f9e2924   Liping Zhang   netfilter: nf_tab...
519
520
  void nft_set_elem_destroy(const struct nft_set *set, void *elem,
  			  bool destroy_expr);
61edafbb4   Patrick McHardy   netfilter: nf_tab...
521

20a69341f   Patrick McHardy   netfilter: nf_tab...
522
  /**
cfed7e1b1   Patrick McHardy   netfilter: nf_tab...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
   *	struct nft_set_gc_batch_head - nf_tables set garbage collection batch
   *
   *	@rcu: rcu head
   *	@set: set the elements belong to
   *	@cnt: count of elements
   */
  struct nft_set_gc_batch_head {
  	struct rcu_head			rcu;
  	const struct nft_set		*set;
  	unsigned int			cnt;
  };
  
  #define NFT_SET_GC_BATCH_SIZE	((PAGE_SIZE -				  \
  				  sizeof(struct nft_set_gc_batch_head)) / \
  				 sizeof(void *))
  
  /**
   *	struct nft_set_gc_batch - nf_tables set garbage collection batch
   *
   * 	@head: GC batch head
   * 	@elems: garbage collection elements
   */
  struct nft_set_gc_batch {
  	struct nft_set_gc_batch_head	head;
  	void				*elems[NFT_SET_GC_BATCH_SIZE];
  };
  
  struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
  						gfp_t gfp);
  void nft_set_gc_batch_release(struct rcu_head *rcu);
  
  static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb)
  {
  	if (gcb != NULL)
  		call_rcu(&gcb->head.rcu, nft_set_gc_batch_release);
  }
  
  static inline struct nft_set_gc_batch *
  nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb,
  		       gfp_t gfp)
  {
  	if (gcb != NULL) {
  		if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems))
  			return gcb;
  		nft_set_gc_batch_complete(gcb);
  	}
  	return nft_set_gc_batch_alloc(set, gfp);
  }
  
  static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
  					void *elem)
  {
  	gcb->elems[gcb->head.cnt++] = elem;
  }
  
  /**
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
579
   *	struct nft_expr_type - nf_tables expression type
96518518c   Patrick McHardy   netfilter: add nf...
580
   *
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
581
582
   *	@select_ops: function to select nft_expr_ops
   *	@ops: default ops, used when no select_ops functions is present
96518518c   Patrick McHardy   netfilter: add nf...
583
584
585
586
587
   *	@list: used internally
   *	@name: Identifier
   *	@owner: module reference
   *	@policy: netlink attribute policy
   *	@maxattr: highest netlink attribute number
64d46806b   Patrick McHardy   netfilter: nf_tab...
588
   *	@family: address family for AF-specific types
151d799a6   Patrick McHardy   netfilter: nf_tab...
589
   *	@flags: expression type flags
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
590
591
   */
  struct nft_expr_type {
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
592
593
  	const struct nft_expr_ops	*(*select_ops)(const struct nft_ctx *,
  						       const struct nlattr * const tb[]);
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
594
595
596
597
598
599
  	const struct nft_expr_ops	*ops;
  	struct list_head		list;
  	const char			*name;
  	struct module			*owner;
  	const struct nla_policy		*policy;
  	unsigned int			maxattr;
64d46806b   Patrick McHardy   netfilter: nf_tab...
600
  	u8				family;
151d799a6   Patrick McHardy   netfilter: nf_tab...
601
  	u8				flags;
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
602
  };
151d799a6   Patrick McHardy   netfilter: nf_tab...
603
  #define NFT_EXPR_STATEFUL		0x1
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
604
605
606
607
  /**
   *	struct nft_expr_ops - nf_tables expression operations
   *
   *	@eval: Expression evaluation function
96518518c   Patrick McHardy   netfilter: add nf...
608
   *	@size: full expression size, including private data size
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
609
610
611
612
   *	@init: initialization function
   *	@destroy: destruction function
   *	@dump: function to dump parameters
   *	@type: expression type
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
613
614
   *	@validate: validate expression, called during loop detection
   *	@data: extra data to attach to this expression operation
96518518c   Patrick McHardy   netfilter: add nf...
615
616
617
618
   */
  struct nft_expr;
  struct nft_expr_ops {
  	void				(*eval)(const struct nft_expr *expr,
a55e22e92   Patrick McHardy   netfilter: nf_tab...
619
  						struct nft_regs *regs,
96518518c   Patrick McHardy   netfilter: add nf...
620
  						const struct nft_pktinfo *pkt);
086f33216   Pablo Neira Ayuso   netfilter: nf_tab...
621
622
  	int				(*clone)(struct nft_expr *dst,
  						 const struct nft_expr *src);
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
623
  	unsigned int			size;
96518518c   Patrick McHardy   netfilter: add nf...
624
625
626
  	int				(*init)(const struct nft_ctx *ctx,
  						const struct nft_expr *expr,
  						const struct nlattr * const tb[]);
62472bcef   Patrick McHardy   netfilter: nf_tab...
627
628
  	void				(*destroy)(const struct nft_ctx *ctx,
  						   const struct nft_expr *expr);
96518518c   Patrick McHardy   netfilter: add nf...
629
630
  	int				(*dump)(struct sk_buff *skb,
  						const struct nft_expr *expr);
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
631
632
633
  	int				(*validate)(const struct nft_ctx *ctx,
  						    const struct nft_expr *expr,
  						    const struct nft_data **data);
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
634
  	const struct nft_expr_type	*type;
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
635
  	void				*data;
96518518c   Patrick McHardy   netfilter: add nf...
636
  };
ef1f7df91   Patrick McHardy   netfilter: nf_tab...
637
  #define NFT_EXPR_MAXATTR		16
96518518c   Patrick McHardy   netfilter: add nf...
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
  #define NFT_EXPR_SIZE(size)		(sizeof(struct nft_expr) + \
  					 ALIGN(size, __alignof__(struct nft_expr)))
  
  /**
   *	struct nft_expr - nf_tables expression
   *
   *	@ops: expression ops
   *	@data: expression private data
   */
  struct nft_expr {
  	const struct nft_expr_ops	*ops;
  	unsigned char			data[];
  };
  
  static inline void *nft_expr_priv(const struct nft_expr *expr)
  {
  	return (void *)expr->data;
  }
0b2d8a7b6   Patrick McHardy   netfilter: nf_tab...
656
657
658
659
660
  struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
  			       const struct nlattr *nla);
  void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr);
  int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
  		  const struct nft_expr *expr);
086f33216   Pablo Neira Ayuso   netfilter: nf_tab...
661
  static inline int nft_expr_clone(struct nft_expr *dst, struct nft_expr *src)
0b2d8a7b6   Patrick McHardy   netfilter: nf_tab...
662
  {
086f33216   Pablo Neira Ayuso   netfilter: nf_tab...
663
  	int err;
086f33216   Pablo Neira Ayuso   netfilter: nf_tab...
664
665
666
667
668
669
670
671
  	if (src->ops->clone) {
  		dst->ops = src->ops;
  		err = src->ops->clone(dst, src);
  		if (err < 0)
  			return err;
  	} else {
  		memcpy(dst, src, src->ops->size);
  	}
61f9e2924   Liping Zhang   netfilter: nf_tab...
672
673
  
  	__module_get(src->ops->type->owner);
086f33216   Pablo Neira Ayuso   netfilter: nf_tab...
674
  	return 0;
0b2d8a7b6   Patrick McHardy   netfilter: nf_tab...
675
  }
96518518c   Patrick McHardy   netfilter: add nf...
676
677
678
679
  /**
   *	struct nft_rule - nf_tables rule
   *
   *	@list: used internally
96518518c   Patrick McHardy   netfilter: add nf...
680
   *	@handle: rule handle
0628b123c   Pablo Neira Ayuso   netfilter: nfnetl...
681
   *	@genmask: generation mask
96518518c   Patrick McHardy   netfilter: add nf...
682
   *	@dlen: length of expression data
86f1ec323   Patrick McHardy   netfilter: nf_tab...
683
   *	@udata: user data is appended to the rule
96518518c   Patrick McHardy   netfilter: add nf...
684
685
686
687
   *	@data: expression data
   */
  struct nft_rule {
  	struct list_head		list;
0768b3b3d   Pablo Neira Ayuso   netfilter: nf_tab...
688
  	u64				handle:42,
0628b123c   Pablo Neira Ayuso   netfilter: nfnetl...
689
  					genmask:2,
0768b3b3d   Pablo Neira Ayuso   netfilter: nf_tab...
690
  					dlen:12,
86f1ec323   Patrick McHardy   netfilter: nf_tab...
691
  					udata:1;
96518518c   Patrick McHardy   netfilter: add nf...
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
  	unsigned char			data[]
  		__attribute__((aligned(__alignof__(struct nft_expr))));
  };
  
  static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
  {
  	return (struct nft_expr *)&rule->data[0];
  }
  
  static inline struct nft_expr *nft_expr_next(const struct nft_expr *expr)
  {
  	return ((void *)expr) + expr->ops->size;
  }
  
  static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
  {
  	return (struct nft_expr *)&rule->data[rule->dlen];
  }
86f1ec323   Patrick McHardy   netfilter: nf_tab...
710
  static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
0768b3b3d   Pablo Neira Ayuso   netfilter: nf_tab...
711
712
713
  {
  	return (void *)&rule->data[rule->dlen];
  }
96518518c   Patrick McHardy   netfilter: add nf...
714
715
716
717
718
719
720
721
722
723
724
725
  /*
   * The last pointer isn't really necessary, but the compiler isn't able to
   * determine that the result of nft_expr_last() is always the same since it
   * can't assume that the dlen value wasn't changed within calls in the loop.
   */
  #define nft_rule_for_each_expr(expr, last, rule) \
  	for ((expr) = nft_expr_first(rule), (last) = nft_expr_last(rule); \
  	     (expr) != (last); \
  	     (expr) = nft_expr_next(expr))
  
  enum nft_chain_flags {
  	NFT_BASE_CHAIN			= 0x1,
96518518c   Patrick McHardy   netfilter: add nf...
726
727
728
729
730
731
732
  };
  
  /**
   *	struct nft_chain - nf_tables chain
   *
   *	@rules: list of rules in the chain
   *	@list: used internally
b5bc89bfa   Pablo Neira Ayuso   netfilter: nf_tab...
733
   *	@table: table that this chain belongs to
96518518c   Patrick McHardy   netfilter: add nf...
734
   *	@handle: chain handle
96518518c   Patrick McHardy   netfilter: add nf...
735
736
   *	@use: number of jump references to this chain
   *	@level: length of longest path to this chain
a0a7379e1   Pablo Neira Ayuso   netfilter: nf_tab...
737
   *	@flags: bitmask of enum nft_chain_flags
96518518c   Patrick McHardy   netfilter: add nf...
738
739
740
741
742
   *	@name: name of the chain
   */
  struct nft_chain {
  	struct list_head		rules;
  	struct list_head		list;
b5bc89bfa   Pablo Neira Ayuso   netfilter: nf_tab...
743
  	struct nft_table		*table;
96518518c   Patrick McHardy   netfilter: add nf...
744
  	u64				handle;
a0a7379e1   Pablo Neira Ayuso   netfilter: nf_tab...
745
  	u32				use;
96518518c   Patrick McHardy   netfilter: add nf...
746
  	u16				level;
664b0f8cd   Pablo Neira Ayuso   netfilter: nf_tab...
747
748
  	u8				flags:6,
  					genmask:2;
96518518c   Patrick McHardy   netfilter: add nf...
749
750
  	char				name[NFT_CHAIN_MAXNAMELEN];
  };
9370761c5   Pablo Neira Ayuso   netfilter: nf_tab...
751
752
753
754
755
756
  enum nft_chain_type {
  	NFT_CHAIN_T_DEFAULT = 0,
  	NFT_CHAIN_T_ROUTE,
  	NFT_CHAIN_T_NAT,
  	NFT_CHAIN_T_MAX
  };
1a1e1a121   Patrick McHardy   netfilter: nf_tab...
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
  /**
   * 	struct nf_chain_type - nf_tables chain type info
   *
   * 	@name: name of the type
   * 	@type: numeric identifier
   * 	@family: address family
   * 	@owner: module owner
   * 	@hook_mask: mask of valid hooks
   * 	@hooks: hookfn overrides
   */
  struct nf_chain_type {
  	const char			*name;
  	enum nft_chain_type		type;
  	int				family;
  	struct module			*owner;
  	unsigned int			hook_mask;
  	nf_hookfn			*hooks[NF_MAX_HOOKS];
  };
7210e4e38   Pablo Neira Ayuso   netfilter: nf_tab...
775
776
  int nft_chain_validate_dependency(const struct nft_chain *chain,
  				  enum nft_chain_type type);
75e8d06d4   Pablo Neira Ayuso   netfilter: nf_tab...
777
778
  int nft_chain_validate_hooks(const struct nft_chain *chain,
                               unsigned int hook_flags);
7210e4e38   Pablo Neira Ayuso   netfilter: nf_tab...
779

0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
780
  struct nft_stats {
ce355e209   Eric Dumazet   netfilter: nf_tab...
781
782
783
  	u64			bytes;
  	u64			pkts;
  	struct u64_stats_sync	syncp;
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
784
  };
115a60b17   Patrick McHardy   netfilter: nf_tab...
785
  #define NFT_HOOK_OPS_MAX		2
96518518c   Patrick McHardy   netfilter: add nf...
786
787
788
789
  /**
   *	struct nft_base_chain - nf_tables base chain
   *
   *	@ops: netfilter hook ops
9370761c5   Pablo Neira Ayuso   netfilter: nf_tab...
790
   *	@type: chain type
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
791
792
   *	@policy: default policy
   *	@stats: per-cpu chain stats
96518518c   Patrick McHardy   netfilter: add nf...
793
   *	@chain: the chain
2cbce139f   Pablo Neira Ayuso   netfilter: nf_tab...
794
   *	@dev_name: device name that this base chain is attached to (if any)
96518518c   Patrick McHardy   netfilter: add nf...
795
796
   */
  struct nft_base_chain {
115a60b17   Patrick McHardy   netfilter: nf_tab...
797
  	struct nf_hook_ops		ops[NFT_HOOK_OPS_MAX];
2a37d755b   Patrick McHardy   netfilter: nf_tab...
798
  	const struct nf_chain_type	*type;
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
799
  	u8				policy;
835b80337   Pablo Neira Ayuso   netfilter: nf_tab...
800
  	u8				flags;
0ca743a55   Pablo Neira Ayuso   netfilter: nf_tab...
801
  	struct nft_stats __percpu	*stats;
96518518c   Patrick McHardy   netfilter: add nf...
802
  	struct nft_chain		chain;
2cbce139f   Pablo Neira Ayuso   netfilter: nf_tab...
803
  	char 				dev_name[IFNAMSIZ];
96518518c   Patrick McHardy   netfilter: add nf...
804
805
806
807
808
809
  };
  
  static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chain)
  {
  	return container_of(chain, struct nft_base_chain, chain);
  }
5ebe0b0ee   Pablo Neira Ayuso   netfilter: nf_tab...
810
  int __nft_release_basechain(struct nft_ctx *ctx);
835b80337   Pablo Neira Ayuso   netfilter: nf_tab...
811

06198b34a   Eric W. Biederman   netfilter: Pass p...
812
  unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
96518518c   Patrick McHardy   netfilter: add nf...
813

96518518c   Patrick McHardy   netfilter: add nf...
814
815
816
817
818
819
820
821
822
  /**
   *	struct nft_table - nf_tables table
   *
   *	@list: used internally
   *	@chains: chains in the table
   *	@sets: sets in the table
   *	@hgenerator: handle generator state
   *	@use: number of chain references to this table
   *	@flags: table flag (see enum nft_table_flags)
f2a6d7667   Pablo Neira Ayuso   netfilter: nf_tab...
823
   *	@genmask: generation mask
96518518c   Patrick McHardy   netfilter: add nf...
824
825
826
827
828
829
830
831
   *	@name: name of the table
   */
  struct nft_table {
  	struct list_head		list;
  	struct list_head		chains;
  	struct list_head		sets;
  	u64				hgenerator;
  	u32				use;
f2a6d7667   Pablo Neira Ayuso   netfilter: nf_tab...
832
833
  	u16				flags:14,
  					genmask:2;
1cae565e8   Pablo Neira Ayuso   netfilter: nf_tab...
834
  	char				name[NFT_TABLE_MAXNAMELEN];
ebddf1a8d   Pablo Neira Ayuso   netfilter: nf_tab...
835
836
837
838
  };
  
  enum nft_af_flags {
  	NFT_AF_NEEDS_DEV	= (1 << 0),
96518518c   Patrick McHardy   netfilter: add nf...
839
840
841
842
843
844
845
846
847
848
  };
  
  /**
   *	struct nft_af_info - nf_tables address family info
   *
   *	@list: used internally
   *	@family: address family
   *	@nhooks: number of hooks in this family
   *	@owner: module owner
   *	@tables: used internally
ebddf1a8d   Pablo Neira Ayuso   netfilter: nf_tab...
849
   *	@flags: family flags
115a60b17   Patrick McHardy   netfilter: nf_tab...
850
851
   *	@nops: number of hook ops in this family
   *	@hook_ops_init: initialization function for chain hook ops
96518518c   Patrick McHardy   netfilter: add nf...
852
853
854
855
856
857
858
859
   *	@hooks: hookfn overrides for packet validation
   */
  struct nft_af_info {
  	struct list_head		list;
  	int				family;
  	unsigned int			nhooks;
  	struct module			*owner;
  	struct list_head		tables;
ebddf1a8d   Pablo Neira Ayuso   netfilter: nf_tab...
860
  	u32				flags;
115a60b17   Patrick McHardy   netfilter: nf_tab...
861
862
863
  	unsigned int			nops;
  	void				(*hook_ops_init)(struct nf_hook_ops *,
  							 unsigned int);
96518518c   Patrick McHardy   netfilter: add nf...
864
865
  	nf_hookfn			*hooks[NF_MAX_HOOKS];
  };
5eccdfaab   Joe Perches   nf_tables*.h: Rem...
866
  int nft_register_afinfo(struct net *, struct nft_af_info *);
df05ef874   Pablo Neira Ayuso   netfilter: nf_tab...
867
  void nft_unregister_afinfo(struct net *, struct nft_af_info *);
96518518c   Patrick McHardy   netfilter: add nf...
868

2a37d755b   Patrick McHardy   netfilter: nf_tab...
869
870
  int nft_register_chain_type(const struct nf_chain_type *);
  void nft_unregister_chain_type(const struct nf_chain_type *);
96518518c   Patrick McHardy   netfilter: add nf...
871

5eccdfaab   Joe Perches   nf_tables*.h: Rem...
872
873
  int nft_register_expr(struct nft_expr_type *);
  void nft_unregister_expr(struct nft_expr_type *);
96518518c   Patrick McHardy   netfilter: add nf...
874

33d5a7b14   Florian Westphal   netfilter: nf_tab...
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
  int nft_verdict_dump(struct sk_buff *skb, int type,
  		     const struct nft_verdict *v);
  
  /**
   *	struct nft_traceinfo - nft tracing information and state
   *
   *	@pkt: pktinfo currently processed
   *	@basechain: base chain currently processed
   *	@chain: chain currently processed
   *	@rule:  rule that was evaluated
   *	@verdict: verdict given by rule
   *	@type: event type (enum nft_trace_types)
   *	@packet_dumped: packet headers sent in a previous traceinfo message
   *	@trace: other struct members are initialised
   */
  struct nft_traceinfo {
  	const struct nft_pktinfo	*pkt;
  	const struct nft_base_chain	*basechain;
  	const struct nft_chain		*chain;
  	const struct nft_rule		*rule;
  	const struct nft_verdict	*verdict;
  	enum nft_trace_types		type;
  	bool				packet_dumped;
  	bool				trace;
  };
  
  void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt,
  		    const struct nft_verdict *verdict,
  		    const struct nft_chain *basechain);
  
  void nft_trace_notify(struct nft_traceinfo *info);
67a8fc27c   Patrick McHardy   netfilter: nf_tab...
906
907
  #define nft_dereference(p)					\
  	nfnl_dereference(p, NFNL_SUBSYS_NFTABLES)
96518518c   Patrick McHardy   netfilter: add nf...
908
909
  #define MODULE_ALIAS_NFT_FAMILY(family)	\
  	MODULE_ALIAS("nft-afinfo-" __stringify(family))
9370761c5   Pablo Neira Ayuso   netfilter: nf_tab...
910
911
  #define MODULE_ALIAS_NFT_CHAIN(family, name) \
  	MODULE_ALIAS("nft-chain-" __stringify(family) "-" name)
96518518c   Patrick McHardy   netfilter: add nf...
912

64d46806b   Patrick McHardy   netfilter: nf_tab...
913
914
  #define MODULE_ALIAS_NFT_AF_EXPR(family, name) \
  	MODULE_ALIAS("nft-expr-" __stringify(family) "-" name)
96518518c   Patrick McHardy   netfilter: add nf...
915
916
  #define MODULE_ALIAS_NFT_EXPR(name) \
  	MODULE_ALIAS("nft-expr-" name)
20a69341f   Patrick McHardy   netfilter: nf_tab...
917
918
  #define MODULE_ALIAS_NFT_SET() \
  	MODULE_ALIAS("nft-set")
ea4bd995b   Patrick McHardy   netfilter: nf_tab...
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
  /*
   * The gencursor defines two generations, the currently active and the
   * next one. Objects contain a bitmask of 2 bits specifying the generations
   * they're active in. A set bit means they're inactive in the generation
   * represented by that bit.
   *
   * New objects start out as inactive in the current and active in the
   * next generation. When committing the ruleset the bitmask is cleared,
   * meaning they're active in all generations. When removing an object,
   * it is set inactive in the next generation. After committing the ruleset,
   * the objects are removed.
   */
  static inline unsigned int nft_gencursor_next(const struct net *net)
  {
  	return net->nft.gencursor + 1 == 1 ? 1 : 0;
  }
  
  static inline u8 nft_genmask_next(const struct net *net)
  {
  	return 1 << nft_gencursor_next(net);
  }
  
  static inline u8 nft_genmask_cur(const struct net *net)
  {
  	/* Use ACCESS_ONCE() to prevent refetching the value for atomicity */
  	return 1 << ACCESS_ONCE(net->nft.gencursor);
  }
22fe54d5f   Patrick McHardy   netfilter: nf_tab...
946
  #define NFT_GENMASK_ANY		((1 << 0) | (1 << 1))
cc02e457b   Patrick McHardy   netfilter: nf_tab...
947
  /*
889f7ee7c   Pablo Neira Ayuso   netfilter: nf_tab...
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
   * Generic transaction helpers
   */
  
  /* Check if this object is currently active. */
  #define nft_is_active(__net, __obj)				\
  	(((__obj)->genmask & nft_genmask_cur(__net)) == 0)
  
  /* Check if this object is active in the next generation. */
  #define nft_is_active_next(__net, __obj)			\
  	(((__obj)->genmask & nft_genmask_next(__net)) == 0)
  
  /* This object becomes active in the next generation. */
  #define nft_activate_next(__net, __obj)				\
  	(__obj)->genmask = nft_genmask_cur(__net)
  
  /* This object becomes inactive in the next generation. */
  #define nft_deactivate_next(__net, __obj)			\
          (__obj)->genmask = nft_genmask_next(__net)
  
  /* After committing the ruleset, clear the stale generation bit. */
  #define nft_clear(__net, __obj)					\
  	(__obj)->genmask &= ~nft_genmask_next(__net)
f2a6d7667   Pablo Neira Ayuso   netfilter: nf_tab...
970
971
  #define nft_active_genmask(__obj, __genmask)			\
  	!((__obj)->genmask & __genmask)
889f7ee7c   Pablo Neira Ayuso   netfilter: nf_tab...
972
973
  
  /*
cc02e457b   Patrick McHardy   netfilter: nf_tab...
974
975
976
977
978
979
980
981
   * Set element transaction helpers
   */
  
  static inline bool nft_set_elem_active(const struct nft_set_ext *ext,
  				       u8 genmask)
  {
  	return !(ext->genmask & genmask);
  }
42a557691   Pablo Neira Ayuso   netfilter: nf_tab...
982
983
  static inline void nft_set_elem_change_active(const struct net *net,
  					      const struct nft_set *set,
cc02e457b   Patrick McHardy   netfilter: nf_tab...
984
985
  					      struct nft_set_ext *ext)
  {
42a557691   Pablo Neira Ayuso   netfilter: nf_tab...
986
  	ext->genmask ^= nft_genmask_next(net);
cc02e457b   Patrick McHardy   netfilter: nf_tab...
987
  }
690866582   Patrick McHardy   netfilter: nf_tab...
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
  /*
   * We use a free bit in the genmask field to indicate the element
   * is busy, meaning it is currently being processed either by
   * the netlink API or GC.
   *
   * Even though the genmask is only a single byte wide, this works
   * because the extension structure if fully constant once initialized,
   * so there are no non-atomic write accesses unless it is already
   * marked busy.
   */
  #define NFT_SET_ELEM_BUSY_MASK	(1 << 2)
  
  #if defined(__LITTLE_ENDIAN_BITFIELD)
  #define NFT_SET_ELEM_BUSY_BIT	2
  #elif defined(__BIG_ENDIAN_BITFIELD)
  #define NFT_SET_ELEM_BUSY_BIT	(BITS_PER_LONG - BITS_PER_BYTE + 2)
  #else
  #error
  #endif
  
  static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext)
  {
  	unsigned long *word = (unsigned long *)ext;
  
  	BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
  	return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word);
  }
  
  static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
  {
  	unsigned long *word = (unsigned long *)ext;
  
  	clear_bit(NFT_SET_ELEM_BUSY_BIT, word);
  }
1a1e1a121   Patrick McHardy   netfilter: nf_tab...
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  /**
   *	struct nft_trans - nf_tables object update in transaction
   *
   *	@list: used internally
   *	@msg_type: message type
   *	@ctx: transaction context
   *	@data: internal information related to the transaction
   */
  struct nft_trans {
  	struct list_head		list;
  	int				msg_type;
  	struct nft_ctx			ctx;
  	char				data[0];
  };
  
  struct nft_trans_rule {
  	struct nft_rule			*rule;
  };
  
  #define nft_trans_rule(trans)	\
  	(((struct nft_trans_rule *)trans->data)->rule)
  
  struct nft_trans_set {
  	struct nft_set			*set;
  	u32				set_id;
  };
  
  #define nft_trans_set(trans)	\
  	(((struct nft_trans_set *)trans->data)->set)
  #define nft_trans_set_id(trans)	\
  	(((struct nft_trans_set *)trans->data)->set_id)
  
  struct nft_trans_chain {
  	bool				update;
  	char				name[NFT_CHAIN_MAXNAMELEN];
  	struct nft_stats __percpu	*stats;
  	u8				policy;
  };
  
  #define nft_trans_chain_update(trans)	\
  	(((struct nft_trans_chain *)trans->data)->update)
  #define nft_trans_chain_name(trans)	\
  	(((struct nft_trans_chain *)trans->data)->name)
  #define nft_trans_chain_stats(trans)	\
  	(((struct nft_trans_chain *)trans->data)->stats)
  #define nft_trans_chain_policy(trans)	\
  	(((struct nft_trans_chain *)trans->data)->policy)
  
  struct nft_trans_table {
  	bool				update;
  	bool				enable;
  };
  
  #define nft_trans_table_update(trans)	\
  	(((struct nft_trans_table *)trans->data)->update)
  #define nft_trans_table_enable(trans)	\
  	(((struct nft_trans_table *)trans->data)->enable)
  
  struct nft_trans_elem {
  	struct nft_set			*set;
  	struct nft_set_elem		elem;
  };
  
  #define nft_trans_elem_set(trans)	\
  	(((struct nft_trans_elem *)trans->data)->set)
  #define nft_trans_elem(trans)	\
  	(((struct nft_trans_elem *)trans->data)->elem)
96518518c   Patrick McHardy   netfilter: add nf...
1089
  #endif /* _NET_NF_TABLES_H */