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