]> git.karo-electronics.de Git - karo-tx-linux.git/blob - include/net/netfilter/nf_tables.h
Merge remote-tracking branch 'net-next/master'
[karo-tx-linux.git] / include / net / netfilter / nf_tables.h
1 #ifndef _NET_NF_TABLES_H
2 #define _NET_NF_TABLES_H
3
4 #include <linux/list.h>
5 #include <linux/netfilter.h>
6 #include <linux/netfilter/x_tables.h>
7 #include <linux/netfilter/nf_tables.h>
8 #include <net/netlink.h>
9
10 #define NFT_JUMP_STACK_SIZE     16
11
12 struct nft_pktinfo {
13         struct sk_buff                  *skb;
14         const struct net_device         *in;
15         const struct net_device         *out;
16         u8                              hooknum;
17         u8                              nhoff;
18         u8                              thoff;
19         /* for x_tables compatibility */
20         struct xt_action_param          xt;
21 };
22
23 static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
24                                    const struct nf_hook_ops *ops,
25                                    struct sk_buff *skb,
26                                    const struct net_device *in,
27                                    const struct net_device *out)
28 {
29         pkt->skb = skb;
30         pkt->in = pkt->xt.in = in;
31         pkt->out = pkt->xt.out = out;
32         pkt->hooknum = pkt->xt.hooknum = ops->hooknum;
33         pkt->xt.family = ops->pf;
34 }
35
36 struct nft_data {
37         union {
38                 u32                             data[4];
39                 struct {
40                         u32                     verdict;
41                         struct nft_chain        *chain;
42                 };
43         };
44 } __attribute__((aligned(__alignof__(u64))));
45
46 static inline int nft_data_cmp(const struct nft_data *d1,
47                                const struct nft_data *d2,
48                                unsigned int len)
49 {
50         return memcmp(d1->data, d2->data, len);
51 }
52
53 static inline void nft_data_copy(struct nft_data *dst,
54                                  const struct nft_data *src)
55 {
56         BUILD_BUG_ON(__alignof__(*dst) != __alignof__(u64));
57         *(u64 *)&dst->data[0] = *(u64 *)&src->data[0];
58         *(u64 *)&dst->data[2] = *(u64 *)&src->data[2];
59 }
60
61 static inline void nft_data_debug(const struct nft_data *data)
62 {
63         pr_debug("data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n",
64                  data->data[0], data->data[1],
65                  data->data[2], data->data[3]);
66 }
67
68 /**
69  *      struct nft_ctx - nf_tables rule/set context
70  *
71  *      @net: net namespace
72  *      @skb: netlink skb
73  *      @nlh: netlink message header
74  *      @afi: address family info
75  *      @table: the table the chain is contained in
76  *      @chain: the chain the rule is contained in
77  *      @nla: netlink attributes
78  */
79 struct nft_ctx {
80         struct net                      *net;
81         const struct sk_buff            *skb;
82         const struct nlmsghdr           *nlh;
83         const struct nft_af_info        *afi;
84         const struct nft_table          *table;
85         const struct nft_chain          *chain;
86         const struct nlattr * const     *nla;
87 };
88
89 struct nft_data_desc {
90         enum nft_data_types             type;
91         unsigned int                    len;
92 };
93
94 int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
95                   struct nft_data_desc *desc, const struct nlattr *nla);
96 void nft_data_uninit(const struct nft_data *data, enum nft_data_types type);
97 int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
98                   enum nft_data_types type, unsigned int len);
99
100 static inline enum nft_data_types nft_dreg_to_type(enum nft_registers reg)
101 {
102         return reg == NFT_REG_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE;
103 }
104
105 static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
106 {
107         return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
108 }
109
110 int nft_validate_input_register(enum nft_registers reg);
111 int nft_validate_output_register(enum nft_registers reg);
112 int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
113                            const struct nft_data *data,
114                            enum nft_data_types type);
115
116 /**
117  *      struct nft_set_elem - generic representation of set elements
118  *
119  *      @cookie: implementation specific element cookie
120  *      @key: element key
121  *      @data: element data (maps only)
122  *      @flags: element flags (end of interval)
123  *
124  *      The cookie can be used to store a handle to the element for subsequent
125  *      removal.
126  */
127 struct nft_set_elem {
128         void                    *cookie;
129         struct nft_data         key;
130         struct nft_data         data;
131         u32                     flags;
132 };
133
134 struct nft_set;
135 struct nft_set_iter {
136         unsigned int    count;
137         unsigned int    skip;
138         int             err;
139         int             (*fn)(const struct nft_ctx *ctx,
140                               const struct nft_set *set,
141                               const struct nft_set_iter *iter,
142                               const struct nft_set_elem *elem);
143 };
144
145 /**
146  *      struct nft_set_ops - nf_tables set operations
147  *
148  *      @lookup: look up an element within the set
149  *      @insert: insert new element into set
150  *      @remove: remove element from set
151  *      @walk: iterate over all set elemeennts
152  *      @privsize: function to return size of set private data
153  *      @init: initialize private data of new set instance
154  *      @destroy: destroy private data of set instance
155  *      @list: nf_tables_set_ops list node
156  *      @owner: module reference
157  *      @features: features supported by the implementation
158  */
159 struct nft_set_ops {
160         bool                            (*lookup)(const struct nft_set *set,
161                                                   const struct nft_data *key,
162                                                   struct nft_data *data);
163         int                             (*get)(const struct nft_set *set,
164                                                struct nft_set_elem *elem);
165         int                             (*insert)(const struct nft_set *set,
166                                                   const struct nft_set_elem *elem);
167         void                            (*remove)(const struct nft_set *set,
168                                                   const struct nft_set_elem *elem);
169         void                            (*walk)(const struct nft_ctx *ctx,
170                                                 const struct nft_set *set,
171                                                 struct nft_set_iter *iter);
172
173         unsigned int                    (*privsize)(const struct nlattr * const nla[]);
174         int                             (*init)(const struct nft_set *set,
175                                                 const struct nlattr * const nla[]);
176         void                            (*destroy)(const struct nft_set *set);
177
178         struct list_head                list;
179         struct module                   *owner;
180         u32                             features;
181 };
182
183 int nft_register_set(struct nft_set_ops *ops);
184 void nft_unregister_set(struct nft_set_ops *ops);
185
186 /**
187  *      struct nft_set - nf_tables set instance
188  *
189  *      @list: table set list node
190  *      @bindings: list of set bindings
191  *      @name: name of the set
192  *      @ktype: key type (numeric type defined by userspace, not used in the kernel)
193  *      @dtype: data type (verdict or numeric type defined by userspace)
194  *      @ops: set ops
195  *      @flags: set flags
196  *      @klen: key length
197  *      @dlen: data length
198  *      @data: private set data
199  */
200 struct nft_set {
201         struct list_head                list;
202         struct list_head                bindings;
203         char                            name[IFNAMSIZ];
204         u32                             ktype;
205         u32                             dtype;
206         /* runtime data below here */
207         const struct nft_set_ops        *ops ____cacheline_aligned;
208         u16                             flags;
209         u8                              klen;
210         u8                              dlen;
211         unsigned char                   data[]
212                 __attribute__((aligned(__alignof__(u64))));
213 };
214
215 static inline void *nft_set_priv(const struct nft_set *set)
216 {
217         return (void *)set->data;
218 }
219
220 struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
221                                      const struct nlattr *nla);
222
223 /**
224  *      struct nft_set_binding - nf_tables set binding
225  *
226  *      @list: set bindings list node
227  *      @chain: chain containing the rule bound to the set
228  *
229  *      A set binding contains all information necessary for validation
230  *      of new elements added to a bound set.
231  */
232 struct nft_set_binding {
233         struct list_head                list;
234         const struct nft_chain          *chain;
235 };
236
237 int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
238                        struct nft_set_binding *binding);
239 void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
240                           struct nft_set_binding *binding);
241
242
243 /**
244  *      struct nft_expr_type - nf_tables expression type
245  *
246  *      @select_ops: function to select nft_expr_ops
247  *      @ops: default ops, used when no select_ops functions is present
248  *      @list: used internally
249  *      @name: Identifier
250  *      @owner: module reference
251  *      @policy: netlink attribute policy
252  *      @maxattr: highest netlink attribute number
253  */
254 struct nft_expr_type {
255         const struct nft_expr_ops       *(*select_ops)(const struct nft_ctx *,
256                                                        const struct nlattr * const tb[]);
257         const struct nft_expr_ops       *ops;
258         struct list_head                list;
259         const char                      *name;
260         struct module                   *owner;
261         const struct nla_policy         *policy;
262         unsigned int                    maxattr;
263 };
264
265 /**
266  *      struct nft_expr_ops - nf_tables expression operations
267  *
268  *      @eval: Expression evaluation function
269  *      @size: full expression size, including private data size
270  *      @init: initialization function
271  *      @destroy: destruction function
272  *      @dump: function to dump parameters
273  *      @type: expression type
274  *      @validate: validate expression, called during loop detection
275  *      @data: extra data to attach to this expression operation
276  */
277 struct nft_expr;
278 struct nft_expr_ops {
279         void                            (*eval)(const struct nft_expr *expr,
280                                                 struct nft_data data[NFT_REG_MAX + 1],
281                                                 const struct nft_pktinfo *pkt);
282         unsigned int                    size;
283
284         int                             (*init)(const struct nft_ctx *ctx,
285                                                 const struct nft_expr *expr,
286                                                 const struct nlattr * const tb[]);
287         void                            (*destroy)(const struct nft_expr *expr);
288         int                             (*dump)(struct sk_buff *skb,
289                                                 const struct nft_expr *expr);
290         int                             (*validate)(const struct nft_ctx *ctx,
291                                                     const struct nft_expr *expr,
292                                                     const struct nft_data **data);
293         const struct nft_expr_type      *type;
294         void                            *data;
295 };
296
297 #define NFT_EXPR_MAXATTR                16
298 #define NFT_EXPR_SIZE(size)             (sizeof(struct nft_expr) + \
299                                          ALIGN(size, __alignof__(struct nft_expr)))
300
301 /**
302  *      struct nft_expr - nf_tables expression
303  *
304  *      @ops: expression ops
305  *      @data: expression private data
306  */
307 struct nft_expr {
308         const struct nft_expr_ops       *ops;
309         unsigned char                   data[];
310 };
311
312 static inline void *nft_expr_priv(const struct nft_expr *expr)
313 {
314         return (void *)expr->data;
315 }
316
317 /**
318  *      struct nft_rule - nf_tables rule
319  *
320  *      @list: used internally
321  *      @rcu_head: used internally for rcu
322  *      @handle: rule handle
323  *      @genmask: generation mask
324  *      @dlen: length of expression data
325  *      @data: expression data
326  */
327 struct nft_rule {
328         struct list_head                list;
329         struct rcu_head                 rcu_head;
330         u64                             handle:46,
331                                         genmask:2,
332                                         dlen:16;
333         unsigned char                   data[]
334                 __attribute__((aligned(__alignof__(struct nft_expr))));
335 };
336
337 /**
338  *      struct nft_rule_trans - nf_tables rule update in transaction
339  *
340  *      @list: used internally
341  *      @rule: rule that needs to be updated
342  *      @chain: chain that this rule belongs to
343  *      @table: table for which this chain applies
344  *      @nlh: netlink header of the message that contain this update
345  *      @family: family expressesed as AF_*
346  */
347 struct nft_rule_trans {
348         struct list_head                list;
349         struct nft_rule                 *rule;
350         const struct nft_chain          *chain;
351         const struct nft_table          *table;
352         const struct nlmsghdr           *nlh;
353         u8                              family;
354 };
355
356 static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
357 {
358         return (struct nft_expr *)&rule->data[0];
359 }
360
361 static inline struct nft_expr *nft_expr_next(const struct nft_expr *expr)
362 {
363         return ((void *)expr) + expr->ops->size;
364 }
365
366 static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
367 {
368         return (struct nft_expr *)&rule->data[rule->dlen];
369 }
370
371 /*
372  * The last pointer isn't really necessary, but the compiler isn't able to
373  * determine that the result of nft_expr_last() is always the same since it
374  * can't assume that the dlen value wasn't changed within calls in the loop.
375  */
376 #define nft_rule_for_each_expr(expr, last, rule) \
377         for ((expr) = nft_expr_first(rule), (last) = nft_expr_last(rule); \
378              (expr) != (last); \
379              (expr) = nft_expr_next(expr))
380
381 enum nft_chain_flags {
382         NFT_BASE_CHAIN                  = 0x1,
383 };
384
385 /**
386  *      struct nft_chain - nf_tables chain
387  *
388  *      @rules: list of rules in the chain
389  *      @list: used internally
390  *      @rcu_head: used internally
391  *      @net: net namespace that this chain belongs to
392  *      @table: table that this chain belongs to
393  *      @handle: chain handle
394  *      @flags: bitmask of enum nft_chain_flags
395  *      @use: number of jump references to this chain
396  *      @level: length of longest path to this chain
397  *      @name: name of the chain
398  */
399 struct nft_chain {
400         struct list_head                rules;
401         struct list_head                list;
402         struct rcu_head                 rcu_head;
403         struct net                      *net;
404         struct nft_table                *table;
405         u64                             handle;
406         u8                              flags;
407         u16                             use;
408         u16                             level;
409         char                            name[NFT_CHAIN_MAXNAMELEN];
410 };
411
412 enum nft_chain_type {
413         NFT_CHAIN_T_DEFAULT = 0,
414         NFT_CHAIN_T_ROUTE,
415         NFT_CHAIN_T_NAT,
416         NFT_CHAIN_T_MAX
417 };
418
419 struct nft_stats {
420         u64 bytes;
421         u64 pkts;
422 };
423
424 /**
425  *      struct nft_base_chain - nf_tables base chain
426  *
427  *      @ops: netfilter hook ops
428  *      @type: chain type
429  *      @policy: default policy
430  *      @stats: per-cpu chain stats
431  *      @chain: the chain
432  */
433 struct nft_base_chain {
434         struct nf_hook_ops              ops;
435         enum nft_chain_type             type;
436         u8                              policy;
437         struct nft_stats __percpu       *stats;
438         struct nft_chain                chain;
439 };
440
441 static inline struct nft_base_chain *nft_base_chain(const struct nft_chain *chain)
442 {
443         return container_of(chain, struct nft_base_chain, chain);
444 }
445
446 unsigned int nft_do_chain_pktinfo(struct nft_pktinfo *pkt,
447                                   const struct nf_hook_ops *ops);
448
449 /**
450  *      struct nft_table - nf_tables table
451  *
452  *      @list: used internally
453  *      @chains: chains in the table
454  *      @sets: sets in the table
455  *      @hgenerator: handle generator state
456  *      @use: number of chain references to this table
457  *      @flags: table flag (see enum nft_table_flags)
458  *      @name: name of the table
459  */
460 struct nft_table {
461         struct list_head                list;
462         struct list_head                chains;
463         struct list_head                sets;
464         u64                             hgenerator;
465         u32                             use;
466         u16                             flags;
467         char                            name[];
468 };
469
470 /**
471  *      struct nft_af_info - nf_tables address family info
472  *
473  *      @list: used internally
474  *      @family: address family
475  *      @nhooks: number of hooks in this family
476  *      @owner: module owner
477  *      @tables: used internally
478  *      @hooks: hookfn overrides for packet validation
479  */
480 struct nft_af_info {
481         struct list_head                list;
482         int                             family;
483         unsigned int                    nhooks;
484         struct module                   *owner;
485         struct list_head                tables;
486         nf_hookfn                       *hooks[NF_MAX_HOOKS];
487 };
488
489 int nft_register_afinfo(struct net *, struct nft_af_info *);
490 void nft_unregister_afinfo(struct nft_af_info *);
491
492 struct nf_chain_type {
493         unsigned int            hook_mask;
494         const char              *name;
495         enum nft_chain_type     type;
496         nf_hookfn               *fn[NF_MAX_HOOKS];
497         struct module           *me;
498         int                     family;
499 };
500
501 int nft_register_chain_type(struct nf_chain_type *);
502 void nft_unregister_chain_type(struct nf_chain_type *);
503
504 int nft_register_expr(struct nft_expr_type *);
505 void nft_unregister_expr(struct nft_expr_type *);
506
507 #define MODULE_ALIAS_NFT_FAMILY(family) \
508         MODULE_ALIAS("nft-afinfo-" __stringify(family))
509
510 #define MODULE_ALIAS_NFT_CHAIN(family, name) \
511         MODULE_ALIAS("nft-chain-" __stringify(family) "-" name)
512
513 #define MODULE_ALIAS_NFT_EXPR(name) \
514         MODULE_ALIAS("nft-expr-" name)
515
516 #define MODULE_ALIAS_NFT_SET() \
517         MODULE_ALIAS("nft-set")
518
519 #endif /* _NET_NF_TABLES_H */