netfilter: nf_tables: add netlink set API
[deliverable/linux.git] / include / net / netfilter / nf_tables.h
CommitLineData
96518518
PM
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
20a69341
PM
9#define NFT_JUMP_STACK_SIZE 16
10
96518518
PM
11struct 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
20struct 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
30static 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
37static 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
45static 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/**
20a69341 53 * struct nft_ctx - nf_tables rule/set context
96518518 54 *
20a69341
PM
55 * @skb: netlink skb
56 * @nlh: netlink message header
96518518
PM
57 * @afi: address family info
58 * @table: the table the chain is contained in
59 * @chain: the chain the rule is contained in
60 */
61struct nft_ctx {
20a69341
PM
62 const struct sk_buff *skb;
63 const struct nlmsghdr *nlh;
96518518
PM
64 const struct nft_af_info *afi;
65 const struct nft_table *table;
66 const struct nft_chain *chain;
67};
68
96518518
PM
69struct nft_data_desc {
70 enum nft_data_types type;
71 unsigned int len;
72};
73
74extern int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
75 struct nft_data_desc *desc, const struct nlattr *nla);
76extern void nft_data_uninit(const struct nft_data *data,
77 enum nft_data_types type);
78extern 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
82static 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
20a69341
PM
87static 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
96518518
PM
92extern int nft_validate_input_register(enum nft_registers reg);
93extern int nft_validate_output_register(enum nft_registers reg);
94extern 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
20a69341
PM
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 */
110struct nft_set_elem {
111 void *cookie;
112 struct nft_data key;
113 struct nft_data data;
114 u32 flags;
115};
116
117struct nft_set;
118struct 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 */
142struct 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
166extern int nft_register_set(struct nft_set_ops *ops);
167extern 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 */
183struct 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
198static inline void *nft_set_priv(const struct nft_set *set)
199{
200 return (void *)set->data;
201}
202
203extern 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 */
215struct nft_set_binding {
216 struct list_head list;
217 const struct nft_chain *chain;
218};
219
220extern int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
221 struct nft_set_binding *binding);
222extern void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
223 struct nft_set_binding *binding);
224
96518518
PM
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 */
239struct nft_expr;
240struct 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);
20a69341 250 const struct nft_data * (*get_verdict)(const struct nft_expr *expr);
96518518
PM
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 */
268struct nft_expr {
269 const struct nft_expr_ops *ops;
270 unsigned char data[];
271};
272
273static 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 */
287struct 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
296static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule)
297{
298 return (struct nft_expr *)&rule->data[0];
299}
300
301static inline struct nft_expr *nft_expr_next(const struct nft_expr *expr)
302{
303 return ((void *)expr) + expr->ops->size;
304}
305
306static 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
321enum 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 */
338struct 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 */
355struct nft_base_chain {
356 struct nf_hook_ops ops;
357 struct nft_chain chain;
358};
359
360static 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
365extern 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
371enum 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 */
386struct 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 */
406struct 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
415extern int nft_register_afinfo(struct nft_af_info *);
416extern void nft_unregister_afinfo(struct nft_af_info *);
417
418extern int nft_register_table(struct nft_table *, int family);
419extern void nft_unregister_table(struct nft_table *, int family);
420
421extern int nft_register_expr(struct nft_expr_ops *);
422extern 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
20a69341
PM
433#define MODULE_ALIAS_NFT_SET() \
434 MODULE_ALIAS("nft-set")
435
96518518 436#endif /* _NET_NF_TABLES_H */
This page took 0.042706 seconds and 5 git commands to generate.