netfilter: nft_synproxy: add synproxy stateful object support
[linux-block.git] / net / netfilter / nf_tables_api.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
96518518 2/*
20a69341 3 * Copyright (c) 2007-2009 Patrick McHardy <kaber@trash.net>
96518518 4 *
96518518
PM
5 * Development of this code funded by Astaro AG (http://www.astaro.com/)
6 */
7
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/list.h>
11#include <linux/skbuff.h>
12#include <linux/netlink.h>
1ff75a3e 13#include <linux/vmalloc.h>
0eb71a9d 14#include <linux/rhashtable.h>
96518518
PM
15#include <linux/netfilter.h>
16#include <linux/netfilter/nfnetlink.h>
17#include <linux/netfilter/nf_tables.h>
3b49e2e9 18#include <net/netfilter/nf_flow_table.h>
96518518
PM
19#include <net/netfilter/nf_tables_core.h>
20#include <net/netfilter/nf_tables.h>
c9626a2c 21#include <net/netfilter/nf_tables_offload.h>
99633ab2 22#include <net/net_namespace.h>
96518518
PM
23#include <net/sock.h>
24
96518518 25static LIST_HEAD(nf_tables_expressions);
e5009240 26static LIST_HEAD(nf_tables_objects);
3b49e2e9 27static LIST_HEAD(nf_tables_flowtables);
0935d558
FW
28static LIST_HEAD(nf_tables_destroy_list);
29static DEFINE_SPINLOCK(nf_tables_destroy_list_lock);
3ecbfd65 30static u64 table_handle;
96518518 31
a654de8f
PNA
32enum {
33 NFT_VALIDATE_SKIP = 0,
34 NFT_VALIDATE_NEED,
35 NFT_VALIDATE_DO,
36};
37
4d44175a
FW
38static struct rhltable nft_objname_ht;
39
1b2470e5
FW
40static u32 nft_chain_hash(const void *data, u32 len, u32 seed);
41static u32 nft_chain_hash_obj(const void *data, u32 len, u32 seed);
42static int nft_chain_hash_cmp(struct rhashtable_compare_arg *, const void *);
43
4d44175a
FW
44static u32 nft_objname_hash(const void *data, u32 len, u32 seed);
45static u32 nft_objname_hash_obj(const void *data, u32 len, u32 seed);
46static int nft_objname_hash_cmp(struct rhashtable_compare_arg *, const void *);
47
1b2470e5
FW
48static const struct rhashtable_params nft_chain_ht_params = {
49 .head_offset = offsetof(struct nft_chain, rhlhead),
50 .key_offset = offsetof(struct nft_chain, name),
51 .hashfn = nft_chain_hash,
52 .obj_hashfn = nft_chain_hash_obj,
53 .obj_cmpfn = nft_chain_hash_cmp,
1b2470e5
FW
54 .automatic_shrinking = true,
55};
56
4d44175a
FW
57static const struct rhashtable_params nft_objname_ht_params = {
58 .head_offset = offsetof(struct nft_object, rhlhead),
59 .key_offset = offsetof(struct nft_object, key),
60 .hashfn = nft_objname_hash,
61 .obj_hashfn = nft_objname_hash_obj,
62 .obj_cmpfn = nft_objname_hash_cmp,
63 .automatic_shrinking = true,
64};
65
a654de8f
PNA
66static void nft_validate_state_update(struct net *net, u8 new_validate_state)
67{
68 switch (net->nft.validate_state) {
69 case NFT_VALIDATE_SKIP:
70 WARN_ON_ONCE(new_validate_state == NFT_VALIDATE_DO);
71 break;
72 case NFT_VALIDATE_NEED:
73 break;
74 case NFT_VALIDATE_DO:
75 if (new_validate_state == NFT_VALIDATE_NEED)
76 return;
77 }
78
79 net->nft.validate_state = new_validate_state;
80}
0935d558
FW
81static void nf_tables_trans_destroy_work(struct work_struct *w);
82static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work);
a654de8f 83
7c95f6d8 84static void nft_ctx_init(struct nft_ctx *ctx,
633c9a84 85 struct net *net,
7c95f6d8
PNA
86 const struct sk_buff *skb,
87 const struct nlmsghdr *nlh,
36596dad 88 u8 family,
7c95f6d8
PNA
89 struct nft_table *table,
90 struct nft_chain *chain,
91 const struct nlattr * const *nla)
92{
633c9a84 93 ctx->net = net;
36596dad 94 ctx->family = family;
26b2f552 95 ctx->level = 0;
128ad332
PNA
96 ctx->table = table;
97 ctx->chain = chain;
98 ctx->nla = nla;
99 ctx->portid = NETLINK_CB(skb).portid;
100 ctx->report = nlmsg_report(nlh);
c9626a2c 101 ctx->flags = nlh->nlmsg_flags;
128ad332 102 ctx->seq = nlh->nlmsg_seq;
7c95f6d8
PNA
103}
104
8411b644
PNA
105static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
106 int msg_type, u32 size, gfp_t gfp)
1081d11b
PNA
107{
108 struct nft_trans *trans;
109
8411b644 110 trans = kzalloc(sizeof(struct nft_trans) + size, gfp);
1081d11b
PNA
111 if (trans == NULL)
112 return NULL;
113
b380e5c7 114 trans->msg_type = msg_type;
1081d11b
PNA
115 trans->ctx = *ctx;
116
117 return trans;
118}
119
8411b644
PNA
120static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx,
121 int msg_type, u32 size)
122{
123 return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL);
124}
125
1081d11b
PNA
126static void nft_trans_destroy(struct nft_trans *trans)
127{
128 list_del(&trans->list);
129 kfree(trans);
130}
131
f6ac8585
PNA
132static void nft_set_trans_bind(const struct nft_ctx *ctx, struct nft_set *set)
133{
134 struct net *net = ctx->net;
135 struct nft_trans *trans;
136
137 if (!nft_set_is_anonymous(set))
138 return;
139
140 list_for_each_entry_reverse(trans, &net->nft.commit_list, list) {
6a0a8d10
PNA
141 switch (trans->msg_type) {
142 case NFT_MSG_NEWSET:
143 if (nft_trans_set(trans) == set)
144 nft_trans_set_bound(trans) = true;
145 break;
146 case NFT_MSG_NEWSETELEM:
147 if (nft_trans_elem_set(trans) == set)
148 nft_trans_elem_set_bound(trans) = true;
f6ac8585
PNA
149 break;
150 }
151 }
152}
153
c974a3a3
PNA
154static int nf_tables_register_hook(struct net *net,
155 const struct nft_table *table,
156 struct nft_chain *chain)
d8ee8f7c 157{
4e25ceb8 158 const struct nft_base_chain *basechain;
a37061a6 159 const struct nf_hook_ops *ops;
ae6153b5 160
d8ee8f7c 161 if (table->flags & NFT_TABLE_F_DORMANT ||
f323d954 162 !nft_is_base_chain(chain))
d8ee8f7c
PNA
163 return 0;
164
4e25ceb8
FW
165 basechain = nft_base_chain(chain);
166 ops = &basechain->ops;
ae6153b5 167
4e25ceb8
FW
168 if (basechain->type->ops_register)
169 return basechain->type->ops_register(net, ops);
170
a37061a6 171 return nf_register_net_hook(net, ops);
d8ee8f7c
PNA
172}
173
c974a3a3
PNA
174static void nf_tables_unregister_hook(struct net *net,
175 const struct nft_table *table,
176 struct nft_chain *chain)
c5598794 177{
4e25ceb8
FW
178 const struct nft_base_chain *basechain;
179 const struct nf_hook_ops *ops;
180
d8ee8f7c 181 if (table->flags & NFT_TABLE_F_DORMANT ||
f323d954 182 !nft_is_base_chain(chain))
d8ee8f7c 183 return;
4e25ceb8
FW
184 basechain = nft_base_chain(chain);
185 ops = &basechain->ops;
d8ee8f7c 186
4e25ceb8
FW
187 if (basechain->type->ops_unregister)
188 return basechain->type->ops_unregister(net, ops);
189
190 nf_unregister_net_hook(net, ops);
c5598794
AB
191}
192
ee01d542
AB
193static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
194{
195 struct nft_trans *trans;
196
197 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
198 if (trans == NULL)
199 return -ENOMEM;
200
201 if (msg_type == NFT_MSG_NEWTABLE)
f2a6d766 202 nft_activate_next(ctx->net, ctx->table);
ee01d542
AB
203
204 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
205 return 0;
206}
207
208static int nft_deltable(struct nft_ctx *ctx)
209{
210 int err;
211
212 err = nft_trans_table_add(ctx, NFT_MSG_DELTABLE);
213 if (err < 0)
214 return err;
215
f2a6d766 216 nft_deactivate_next(ctx->net, ctx->table);
ee01d542
AB
217 return err;
218}
219
66293c46 220static struct nft_trans *nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
ee01d542
AB
221{
222 struct nft_trans *trans;
223
224 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
225 if (trans == NULL)
66293c46 226 return ERR_PTR(-ENOMEM);
ee01d542
AB
227
228 if (msg_type == NFT_MSG_NEWCHAIN)
664b0f8c 229 nft_activate_next(ctx->net, ctx->chain);
ee01d542
AB
230
231 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
66293c46 232 return trans;
ee01d542
AB
233}
234
235static int nft_delchain(struct nft_ctx *ctx)
236{
66293c46 237 struct nft_trans *trans;
ee01d542 238
66293c46
FW
239 trans = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
240 if (IS_ERR(trans))
241 return PTR_ERR(trans);
ee01d542
AB
242
243 ctx->table->use--;
664b0f8c 244 nft_deactivate_next(ctx->net, ctx->chain);
ee01d542 245
66293c46 246 return 0;
ee01d542
AB
247}
248
bb7b40ae
PNA
249static void nft_rule_expr_activate(const struct nft_ctx *ctx,
250 struct nft_rule *rule)
251{
252 struct nft_expr *expr;
253
254 expr = nft_expr_first(rule);
255 while (expr != nft_expr_last(rule) && expr->ops) {
256 if (expr->ops->activate)
257 expr->ops->activate(ctx, expr);
258
259 expr = nft_expr_next(expr);
260 }
261}
262
263static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
f6ac8585
PNA
264 struct nft_rule *rule,
265 enum nft_trans_phase phase)
bb7b40ae
PNA
266{
267 struct nft_expr *expr;
268
269 expr = nft_expr_first(rule);
270 while (expr != nft_expr_last(rule) && expr->ops) {
271 if (expr->ops->deactivate)
f6ac8585 272 expr->ops->deactivate(ctx, expr, phase);
bb7b40ae
PNA
273
274 expr = nft_expr_next(expr);
275 }
276}
277
ee01d542
AB
278static int
279nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
280{
281 /* You cannot delete the same rule twice */
889f7ee7
PNA
282 if (nft_is_active_next(ctx->net, rule)) {
283 nft_deactivate_next(ctx->net, rule);
ee01d542
AB
284 ctx->chain->use--;
285 return 0;
286 }
287 return -ENOENT;
288}
289
290static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
291 struct nft_rule *rule)
292{
293 struct nft_trans *trans;
294
295 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
296 if (trans == NULL)
297 return NULL;
298
1a94e38d
PNA
299 if (msg_type == NFT_MSG_NEWRULE && ctx->nla[NFTA_RULE_ID] != NULL) {
300 nft_trans_rule_id(trans) =
301 ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
302 }
ee01d542
AB
303 nft_trans_rule(trans) = rule;
304 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
305
306 return trans;
307}
308
309static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
310{
311 struct nft_trans *trans;
312 int err;
313
314 trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
315 if (trans == NULL)
316 return -ENOMEM;
317
318 err = nf_tables_delrule_deactivate(ctx, rule);
319 if (err < 0) {
320 nft_trans_destroy(trans);
321 return err;
322 }
f6ac8585 323 nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_PREPARE);
ee01d542
AB
324
325 return 0;
326}
327
328static int nft_delrule_by_chain(struct nft_ctx *ctx)
329{
330 struct nft_rule *rule;
331 int err;
332
333 list_for_each_entry(rule, &ctx->chain->rules, list) {
23b7ca4f
PNA
334 if (!nft_is_active_next(ctx->net, rule))
335 continue;
336
ee01d542
AB
337 err = nft_delrule(ctx, rule);
338 if (err < 0)
339 return err;
340 }
341 return 0;
342}
343
cd5125d8 344static int nft_trans_set_add(const struct nft_ctx *ctx, int msg_type,
ee01d542
AB
345 struct nft_set *set)
346{
347 struct nft_trans *trans;
348
349 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
350 if (trans == NULL)
351 return -ENOMEM;
352
353 if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
354 nft_trans_set_id(trans) =
355 ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
37a9cc52 356 nft_activate_next(ctx->net, set);
ee01d542
AB
357 }
358 nft_trans_set(trans) = set;
359 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
360
361 return 0;
362}
363
cd5125d8 364static int nft_delset(const struct nft_ctx *ctx, struct nft_set *set)
ee01d542
AB
365{
366 int err;
367
368 err = nft_trans_set_add(ctx, NFT_MSG_DELSET, set);
369 if (err < 0)
370 return err;
371
37a9cc52 372 nft_deactivate_next(ctx->net, set);
ee01d542
AB
373 ctx->table->use--;
374
375 return err;
376}
377
e5009240
PNA
378static int nft_trans_obj_add(struct nft_ctx *ctx, int msg_type,
379 struct nft_object *obj)
380{
381 struct nft_trans *trans;
382
383 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_obj));
384 if (trans == NULL)
385 return -ENOMEM;
386
387 if (msg_type == NFT_MSG_NEWOBJ)
388 nft_activate_next(ctx->net, obj);
389
390 nft_trans_obj(trans) = obj;
391 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
392
393 return 0;
394}
395
396static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj)
397{
398 int err;
399
400 err = nft_trans_obj_add(ctx, NFT_MSG_DELOBJ, obj);
401 if (err < 0)
402 return err;
403
404 nft_deactivate_next(ctx->net, obj);
405 ctx->table->use--;
406
407 return err;
408}
409
3b49e2e9
PNA
410static int nft_trans_flowtable_add(struct nft_ctx *ctx, int msg_type,
411 struct nft_flowtable *flowtable)
412{
413 struct nft_trans *trans;
414
415 trans = nft_trans_alloc(ctx, msg_type,
416 sizeof(struct nft_trans_flowtable));
417 if (trans == NULL)
418 return -ENOMEM;
419
420 if (msg_type == NFT_MSG_NEWFLOWTABLE)
421 nft_activate_next(ctx->net, flowtable);
422
423 nft_trans_flowtable(trans) = flowtable;
424 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
425
426 return 0;
427}
428
429static int nft_delflowtable(struct nft_ctx *ctx,
430 struct nft_flowtable *flowtable)
431{
432 int err;
433
434 err = nft_trans_flowtable_add(ctx, NFT_MSG_DELFLOWTABLE, flowtable);
435 if (err < 0)
436 return err;
437
438 nft_deactivate_next(ctx->net, flowtable);
439 ctx->table->use--;
440
441 return err;
442}
443
96518518
PM
444/*
445 * Tables
446 */
447
36596dad 448static struct nft_table *nft_table_lookup(const struct net *net,
f2a6d766 449 const struct nlattr *nla,
36596dad 450 u8 family, u8 genmask)
96518518
PM
451{
452 struct nft_table *table;
453
cac20fcd
PNA
454 if (nla == NULL)
455 return ERR_PTR(-EINVAL);
456
d9adf22a 457 list_for_each_entry_rcu(table, &net->nft.tables, list) {
f2a6d766 458 if (!nla_strcmp(nla, table->name) &&
98319cb9 459 table->family == family &&
f2a6d766 460 nft_active_genmask(table, genmask))
96518518
PM
461 return table;
462 }
cac20fcd
PNA
463
464 return ERR_PTR(-ENOENT);
96518518
PM
465}
466
3ecbfd65
HS
467static struct nft_table *nft_table_lookup_byhandle(const struct net *net,
468 const struct nlattr *nla,
469 u8 genmask)
470{
471 struct nft_table *table;
472
473 list_for_each_entry(table, &net->nft.tables, list) {
474 if (be64_to_cpu(nla_get_be64(nla)) == table->handle &&
475 nft_active_genmask(table, genmask))
476 return table;
477 }
3ecbfd65
HS
478
479 return ERR_PTR(-ENOENT);
480}
481
96518518
PM
482static inline u64 nf_tables_alloc_handle(struct nft_table *table)
483{
484 return ++table->hgenerator;
485}
486
32537e91 487static const struct nft_chain_type *chain_type[NFPROTO_NUMPROTO][NFT_CHAIN_T_MAX];
9370761c 488
32537e91 489static const struct nft_chain_type *
1ea26cca 490__nf_tables_chain_type_lookup(const struct nlattr *nla, u8 family)
9370761c
PNA
491{
492 int i;
493
baae3e62 494 for (i = 0; i < NFT_CHAIN_T_MAX; i++) {
9370761c
PNA
495 if (chain_type[family][i] != NULL &&
496 !nla_strcmp(nla, chain_type[family][i]->name))
baae3e62 497 return chain_type[family][i];
9370761c 498 }
baae3e62 499 return NULL;
9370761c
PNA
500}
501
452238e8
FW
502/*
503 * Loading a module requires dropping mutex that guards the
504 * transaction.
505 * We first need to abort any pending transactions as once
506 * mutex is unlocked a different client could start a new
507 * transaction. It must not see any 'future generation'
508 * changes * as these changes will never happen.
509 */
510#ifdef CONFIG_MODULES
511static int __nf_tables_abort(struct net *net);
512
513static void nft_request_module(struct net *net, const char *fmt, ...)
514{
515 char module_name[MODULE_NAME_LEN];
516 va_list args;
517 int ret;
518
519 __nf_tables_abort(net);
520
521 va_start(args, fmt);
522 ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
523 va_end(args);
524 if (WARN(ret >= MODULE_NAME_LEN, "truncated: '%s' (len %d)", module_name, ret))
525 return;
526
f102d66b 527 mutex_unlock(&net->nft.commit_mutex);
452238e8 528 request_module("%s", module_name);
f102d66b 529 mutex_lock(&net->nft.commit_mutex);
452238e8
FW
530}
531#endif
532
f102d66b
FW
533static void lockdep_nfnl_nft_mutex_not_held(void)
534{
535#ifdef CONFIG_PROVE_LOCKING
536 WARN_ON_ONCE(lockdep_nfnl_is_held(NFNL_SUBSYS_NFTABLES));
537#endif
538}
539
32537e91 540static const struct nft_chain_type *
452238e8
FW
541nf_tables_chain_type_lookup(struct net *net, const struct nlattr *nla,
542 u8 family, bool autoload)
9370761c 543{
32537e91 544 const struct nft_chain_type *type;
9370761c 545
1ea26cca 546 type = __nf_tables_chain_type_lookup(nla, family);
93b0806f
PM
547 if (type != NULL)
548 return type;
f102d66b
FW
549
550 lockdep_nfnl_nft_mutex_not_held();
9370761c 551#ifdef CONFIG_MODULES
93b0806f 552 if (autoload) {
452238e8
FW
553 nft_request_module(net, "nft-chain-%u-%.*s", family,
554 nla_len(nla), (const char *)nla_data(nla));
1ea26cca 555 type = __nf_tables_chain_type_lookup(nla, family);
93b0806f
PM
556 if (type != NULL)
557 return ERR_PTR(-EAGAIN);
9370761c
PNA
558 }
559#endif
93b0806f 560 return ERR_PTR(-ENOENT);
9370761c
PNA
561}
562
96518518 563static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
1cae565e
PNA
564 [NFTA_TABLE_NAME] = { .type = NLA_STRING,
565 .len = NFT_TABLE_MAXNAMELEN - 1 },
9ddf6323 566 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
3ecbfd65 567 [NFTA_TABLE_HANDLE] = { .type = NLA_U64 },
96518518
PM
568};
569
84d7fce6
PNA
570static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
571 u32 portid, u32 seq, int event, u32 flags,
572 int family, const struct nft_table *table)
96518518
PM
573{
574 struct nlmsghdr *nlh;
575 struct nfgenmsg *nfmsg;
576
dedb67c4 577 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
96518518
PM
578 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
579 if (nlh == NULL)
580 goto nla_put_failure;
581
582 nfmsg = nlmsg_data(nlh);
583 nfmsg->nfgen_family = family;
584 nfmsg->version = NFNETLINK_V0;
84d7fce6 585 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518 586
9ddf6323 587 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
d8bcc768 588 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||
3ecbfd65
HS
589 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)) ||
590 nla_put_be64(skb, NFTA_TABLE_HANDLE, cpu_to_be64(table->handle),
591 NFTA_TABLE_PAD))
96518518
PM
592 goto nla_put_failure;
593
053c095a
JB
594 nlmsg_end(skb, nlh);
595 return 0;
96518518
PM
596
597nla_put_failure:
598 nlmsg_trim(skb, nlh);
599 return -1;
600}
601
25e94a99 602static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
96518518
PM
603{
604 struct sk_buff *skb;
96518518
PM
605 int err;
606
128ad332
PNA
607 if (!ctx->report &&
608 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 609 return;
96518518 610
96518518
PM
611 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
612 if (skb == NULL)
613 goto err;
614
84d7fce6 615 err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
36596dad 616 event, 0, ctx->family, ctx->table);
96518518
PM
617 if (err < 0) {
618 kfree_skb(skb);
619 goto err;
620 }
621
25e94a99
PNA
622 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
623 ctx->report, GFP_KERNEL);
624 return;
96518518 625err:
25e94a99 626 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
627}
628
629static int nf_tables_dump_tables(struct sk_buff *skb,
630 struct netlink_callback *cb)
631{
632 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
96518518
PM
633 const struct nft_table *table;
634 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 635 struct net *net = sock_net(skb->sk);
96518518
PM
636 int family = nfmsg->nfgen_family;
637
e688a7f8 638 rcu_read_lock();
38e029f1
PNA
639 cb->seq = net->nft.base_seq;
640
36596dad 641 list_for_each_entry_rcu(table, &net->nft.tables, list) {
98319cb9 642 if (family != NFPROTO_UNSPEC && family != table->family)
96518518
PM
643 continue;
644
36596dad
PNA
645 if (idx < s_idx)
646 goto cont;
647 if (idx > s_idx)
648 memset(&cb->args[1], 0,
649 sizeof(cb->args) - sizeof(cb->args[0]));
650 if (!nft_is_active(net, table))
651 continue;
652 if (nf_tables_fill_table_info(skb, net,
653 NETLINK_CB(cb->skb).portid,
654 cb->nlh->nlmsg_seq,
655 NFT_MSG_NEWTABLE, NLM_F_MULTI,
98319cb9 656 table->family, table) < 0)
36596dad
PNA
657 goto done;
658
659 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518 660cont:
36596dad 661 idx++;
96518518
PM
662 }
663done:
e688a7f8 664 rcu_read_unlock();
96518518
PM
665 cb->args[0] = idx;
666 return skb->len;
667}
668
d9adf22a
FW
669static int nft_netlink_dump_start_rcu(struct sock *nlsk, struct sk_buff *skb,
670 const struct nlmsghdr *nlh,
671 struct netlink_dump_control *c)
672{
673 int err;
674
675 if (!try_module_get(THIS_MODULE))
676 return -EINVAL;
677
678 rcu_read_unlock();
679 err = netlink_dump_start(nlsk, skb, nlh, c);
680 rcu_read_lock();
681 module_put(THIS_MODULE);
682
683 return err;
684}
685
686/* called with rcu_read_lock held */
7b8002a1
PNA
687static int nf_tables_gettable(struct net *net, struct sock *nlsk,
688 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
689 const struct nlattr * const nla[],
690 struct netlink_ext_ack *extack)
96518518
PM
691{
692 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 693 u8 genmask = nft_genmask_cur(net);
96518518
PM
694 const struct nft_table *table;
695 struct sk_buff *skb2;
696 int family = nfmsg->nfgen_family;
697 int err;
698
699 if (nlh->nlmsg_flags & NLM_F_DUMP) {
700 struct netlink_dump_control c = {
701 .dump = nf_tables_dump_tables,
d9adf22a 702 .module = THIS_MODULE,
96518518 703 };
d9adf22a
FW
704
705 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
96518518
PM
706 }
707
cac20fcd 708 table = nft_table_lookup(net, nla[NFTA_TABLE_NAME], family, genmask);
36dd1bcc
PNA
709 if (IS_ERR(table)) {
710 NL_SET_BAD_ATTR(extack, nla[NFTA_TABLE_NAME]);
96518518 711 return PTR_ERR(table);
36dd1bcc 712 }
96518518 713
d9adf22a 714 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
96518518
PM
715 if (!skb2)
716 return -ENOMEM;
717
84d7fce6 718 err = nf_tables_fill_table_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
719 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
720 family, table);
721 if (err < 0)
722 goto err;
723
724 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
725
726err:
727 kfree_skb(skb2);
728 return err;
729}
730
c9c17211 731static void nft_table_disable(struct net *net, struct nft_table *table, u32 cnt)
10435c11
F
732{
733 struct nft_chain *chain;
734 u32 i = 0;
735
736 list_for_each_entry(chain, &table->chains, list) {
737 if (!nft_is_active_next(net, chain))
738 continue;
f323d954 739 if (!nft_is_base_chain(chain))
10435c11
F
740 continue;
741
742 if (cnt && i++ == cnt)
743 break;
744
c974a3a3 745 nf_unregister_net_hook(net, &nft_base_chain(chain)->ops);
10435c11
F
746 }
747}
748
c9c17211 749static int nf_tables_table_enable(struct net *net, struct nft_table *table)
9ddf6323
PNA
750{
751 struct nft_chain *chain;
752 int err, i = 0;
753
754 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
755 if (!nft_is_active_next(net, chain))
756 continue;
f323d954 757 if (!nft_is_base_chain(chain))
d2012975
PNA
758 continue;
759
c974a3a3 760 err = nf_register_net_hook(net, &nft_base_chain(chain)->ops);
9ddf6323
PNA
761 if (err < 0)
762 goto err;
763
764 i++;
765 }
766 return 0;
767err:
10435c11 768 if (i)
c9c17211 769 nft_table_disable(net, table, i);
9ddf6323
PNA
770 return err;
771}
772
c9c17211 773static void nf_tables_table_disable(struct net *net, struct nft_table *table)
9ddf6323 774{
c9c17211 775 nft_table_disable(net, table, 0);
9ddf6323
PNA
776}
777
e1aaca93 778static int nf_tables_updtable(struct nft_ctx *ctx)
9ddf6323 779{
55dd6f93 780 struct nft_trans *trans;
e1aaca93 781 u32 flags;
55dd6f93 782 int ret = 0;
9ddf6323 783
e1aaca93
PNA
784 if (!ctx->nla[NFTA_TABLE_FLAGS])
785 return 0;
9ddf6323 786
e1aaca93
PNA
787 flags = ntohl(nla_get_be32(ctx->nla[NFTA_TABLE_FLAGS]));
788 if (flags & ~NFT_TABLE_F_DORMANT)
789 return -EINVAL;
790
63283dd2
PNA
791 if (flags == ctx->table->flags)
792 return 0;
793
55dd6f93
PNA
794 trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
795 sizeof(struct nft_trans_table));
796 if (trans == NULL)
797 return -ENOMEM;
9ddf6323 798
e1aaca93
PNA
799 if ((flags & NFT_TABLE_F_DORMANT) &&
800 !(ctx->table->flags & NFT_TABLE_F_DORMANT)) {
55dd6f93 801 nft_trans_table_enable(trans) = false;
e1aaca93
PNA
802 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
803 ctx->table->flags & NFT_TABLE_F_DORMANT) {
c9c17211 804 ret = nf_tables_table_enable(ctx->net, ctx->table);
55dd6f93 805 if (ret >= 0) {
e1aaca93 806 ctx->table->flags &= ~NFT_TABLE_F_DORMANT;
55dd6f93 807 nft_trans_table_enable(trans) = true;
9ddf6323 808 }
9ddf6323 809 }
e1aaca93
PNA
810 if (ret < 0)
811 goto err;
9ddf6323 812
55dd6f93
PNA
813 nft_trans_table_update(trans) = true;
814 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
815 return 0;
9ddf6323 816err:
55dd6f93 817 nft_trans_destroy(trans);
9ddf6323
PNA
818 return ret;
819}
820
1b2470e5
FW
821static u32 nft_chain_hash(const void *data, u32 len, u32 seed)
822{
823 const char *name = data;
824
825 return jhash(name, strlen(name), seed);
826}
827
828static u32 nft_chain_hash_obj(const void *data, u32 len, u32 seed)
829{
830 const struct nft_chain *chain = data;
831
832 return nft_chain_hash(chain->name, 0, seed);
833}
834
835static int nft_chain_hash_cmp(struct rhashtable_compare_arg *arg,
836 const void *ptr)
837{
838 const struct nft_chain *chain = ptr;
839 const char *name = arg->key;
840
841 return strcmp(chain->name, name);
842}
843
4d44175a
FW
844static u32 nft_objname_hash(const void *data, u32 len, u32 seed)
845{
846 const struct nft_object_hash_key *k = data;
847
848 seed ^= hash_ptr(k->table, 32);
849
850 return jhash(k->name, strlen(k->name), seed);
851}
852
853static u32 nft_objname_hash_obj(const void *data, u32 len, u32 seed)
854{
855 const struct nft_object *obj = data;
856
857 return nft_objname_hash(&obj->key, 0, seed);
858}
859
860static int nft_objname_hash_cmp(struct rhashtable_compare_arg *arg,
861 const void *ptr)
862{
863 const struct nft_object_hash_key *k = arg->key;
864 const struct nft_object *obj = ptr;
865
866 if (obj->key.table != k->table)
867 return -1;
868
869 return strcmp(obj->key.name, k->name);
870}
871
633c9a84
PNA
872static int nf_tables_newtable(struct net *net, struct sock *nlsk,
873 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
874 const struct nlattr * const nla[],
875 struct netlink_ext_ack *extack)
96518518
PM
876{
877 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 878 u8 genmask = nft_genmask_next(net);
96518518 879 int family = nfmsg->nfgen_family;
36dd1bcc
PNA
880 const struct nlattr *attr;
881 struct nft_table *table;
c5c1f975 882 u32 flags = 0;
e1aaca93 883 struct nft_ctx ctx;
55dd6f93 884 int err;
96518518 885
f102d66b 886 lockdep_assert_held(&net->nft.commit_mutex);
36dd1bcc
PNA
887 attr = nla[NFTA_TABLE_NAME];
888 table = nft_table_lookup(net, attr, family, genmask);
96518518
PM
889 if (IS_ERR(table)) {
890 if (PTR_ERR(table) != -ENOENT)
891 return PTR_ERR(table);
1a28ad74 892 } else {
36dd1bcc
PNA
893 if (nlh->nlmsg_flags & NLM_F_EXCL) {
894 NL_SET_BAD_ATTR(extack, attr);
96518518 895 return -EEXIST;
36dd1bcc 896 }
96518518
PM
897 if (nlh->nlmsg_flags & NLM_F_REPLACE)
898 return -EOPNOTSUPP;
e1aaca93 899
98319cb9 900 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e1aaca93 901 return nf_tables_updtable(&ctx);
96518518
PM
902 }
903
c5c1f975
PM
904 if (nla[NFTA_TABLE_FLAGS]) {
905 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
906 if (flags & ~NFT_TABLE_F_DORMANT)
907 return -EINVAL;
908 }
909
ffdb210e 910 err = -ENOMEM;
1cae565e 911 table = kzalloc(sizeof(*table), GFP_KERNEL);
ffdb210e 912 if (table == NULL)
98319cb9 913 goto err_kzalloc;
96518518 914
36dd1bcc 915 table->name = nla_strdup(attr, GFP_KERNEL);
e46abbcc 916 if (table->name == NULL)
98319cb9 917 goto err_strdup;
e46abbcc 918
1b2470e5
FW
919 err = rhltable_init(&table->chains_ht, &nft_chain_ht_params);
920 if (err)
921 goto err_chain_ht;
922
96518518 923 INIT_LIST_HEAD(&table->chains);
20a69341 924 INIT_LIST_HEAD(&table->sets);
e5009240 925 INIT_LIST_HEAD(&table->objects);
3b49e2e9 926 INIT_LIST_HEAD(&table->flowtables);
98319cb9 927 table->family = family;
c5c1f975 928 table->flags = flags;
3ecbfd65 929 table->handle = ++table_handle;
9ddf6323 930
98319cb9 931 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
55dd6f93 932 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
ffdb210e 933 if (err < 0)
98319cb9 934 goto err_trans;
ffdb210e 935
36596dad 936 list_add_tail_rcu(&table->list, &net->nft.tables);
96518518 937 return 0;
98319cb9 938err_trans:
1b2470e5
FW
939 rhltable_destroy(&table->chains_ht);
940err_chain_ht:
e46abbcc 941 kfree(table->name);
98319cb9 942err_strdup:
ffdb210e 943 kfree(table);
98319cb9 944err_kzalloc:
ffdb210e 945 return err;
96518518
PM
946}
947
b9ac12ef
AB
948static int nft_flush_table(struct nft_ctx *ctx)
949{
3b49e2e9 950 struct nft_flowtable *flowtable, *nft;
b9ac12ef 951 struct nft_chain *chain, *nc;
e5009240 952 struct nft_object *obj, *ne;
b9ac12ef 953 struct nft_set *set, *ns;
3b49e2e9 954 int err;
b9ac12ef 955
a2f18db0 956 list_for_each_entry(chain, &ctx->table->chains, list) {
664b0f8c
PNA
957 if (!nft_is_active_next(ctx->net, chain))
958 continue;
959
b9ac12ef
AB
960 ctx->chain = chain;
961
962 err = nft_delrule_by_chain(ctx);
963 if (err < 0)
964 goto out;
b9ac12ef
AB
965 }
966
967 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
37a9cc52
PNA
968 if (!nft_is_active_next(ctx->net, set))
969 continue;
970
408070d6 971 if (nft_set_is_anonymous(set) &&
b9ac12ef
AB
972 !list_empty(&set->bindings))
973 continue;
974
975 err = nft_delset(ctx, set);
976 if (err < 0)
977 goto out;
978 }
979
3b49e2e9
PNA
980 list_for_each_entry_safe(flowtable, nft, &ctx->table->flowtables, list) {
981 err = nft_delflowtable(ctx, flowtable);
982 if (err < 0)
983 goto out;
984 }
985
e5009240
PNA
986 list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) {
987 err = nft_delobj(ctx, obj);
988 if (err < 0)
989 goto out;
990 }
991
a2f18db0 992 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
664b0f8c
PNA
993 if (!nft_is_active_next(ctx->net, chain))
994 continue;
995
a2f18db0
PNA
996 ctx->chain = chain;
997
998 err = nft_delchain(ctx);
999 if (err < 0)
1000 goto out;
1001 }
1002
b9ac12ef
AB
1003 err = nft_deltable(ctx);
1004out:
1005 return err;
1006}
1007
1008static int nft_flush(struct nft_ctx *ctx, int family)
1009{
b9ac12ef
AB
1010 struct nft_table *table, *nt;
1011 const struct nlattr * const *nla = ctx->nla;
1012 int err = 0;
1013
36596dad 1014 list_for_each_entry_safe(table, nt, &ctx->net->nft.tables, list) {
98319cb9 1015 if (family != AF_UNSPEC && table->family != family)
b9ac12ef
AB
1016 continue;
1017
98319cb9 1018 ctx->family = table->family;
f2a6d766 1019
36596dad
PNA
1020 if (!nft_is_active_next(ctx->net, table))
1021 continue;
b9ac12ef 1022
36596dad
PNA
1023 if (nla[NFTA_TABLE_NAME] &&
1024 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
1025 continue;
b9ac12ef 1026
36596dad
PNA
1027 ctx->table = table;
1028
1029 err = nft_flush_table(ctx);
1030 if (err < 0)
1031 goto out;
b9ac12ef
AB
1032 }
1033out:
1034 return err;
1035}
1036
633c9a84
PNA
1037static int nf_tables_deltable(struct net *net, struct sock *nlsk,
1038 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1039 const struct nlattr * const nla[],
1040 struct netlink_ext_ack *extack)
96518518
PM
1041{
1042 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1043 u8 genmask = nft_genmask_next(net);
ee01d542 1044 int family = nfmsg->nfgen_family;
36dd1bcc
PNA
1045 const struct nlattr *attr;
1046 struct nft_table *table;
55dd6f93 1047 struct nft_ctx ctx;
96518518 1048
36596dad 1049 nft_ctx_init(&ctx, net, skb, nlh, 0, NULL, NULL, nla);
3ecbfd65
HS
1050 if (family == AF_UNSPEC ||
1051 (!nla[NFTA_TABLE_NAME] && !nla[NFTA_TABLE_HANDLE]))
b9ac12ef
AB
1052 return nft_flush(&ctx, family);
1053
36dd1bcc
PNA
1054 if (nla[NFTA_TABLE_HANDLE]) {
1055 attr = nla[NFTA_TABLE_HANDLE];
1056 table = nft_table_lookup_byhandle(net, attr, genmask);
1057 } else {
1058 attr = nla[NFTA_TABLE_NAME];
1059 table = nft_table_lookup(net, attr, family, genmask);
1060 }
3ecbfd65 1061
36dd1bcc
PNA
1062 if (IS_ERR(table)) {
1063 NL_SET_BAD_ATTR(extack, attr);
96518518 1064 return PTR_ERR(table);
36dd1bcc 1065 }
96518518 1066
a8278400
PNA
1067 if (nlh->nlmsg_flags & NLM_F_NONREC &&
1068 table->use > 0)
1069 return -EBUSY;
1070
98319cb9 1071 ctx.family = family;
b9ac12ef 1072 ctx.table = table;
55dd6f93 1073
b9ac12ef 1074 return nft_flush_table(&ctx);
96518518
PM
1075}
1076
55dd6f93
PNA
1077static void nf_tables_table_destroy(struct nft_ctx *ctx)
1078{
fa5950e4
FW
1079 if (WARN_ON(ctx->table->use > 0))
1080 return;
4fefee57 1081
1b2470e5 1082 rhltable_destroy(&ctx->table->chains_ht);
e46abbcc 1083 kfree(ctx->table->name);
55dd6f93 1084 kfree(ctx->table);
55dd6f93
PNA
1085}
1086
cc07eeb0 1087void nft_register_chain_type(const struct nft_chain_type *ctype)
96518518 1088{
d8297d4f 1089 if (WARN_ON(ctype->family >= NFPROTO_NUMPROTO))
cc07eeb0 1090 return;
d8297d4f 1091
96518518 1092 nfnl_lock(NFNL_SUBSYS_NFTABLES);
cc07eeb0
PNA
1093 if (WARN_ON(chain_type[ctype->family][ctype->type] != NULL)) {
1094 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1095 return;
96518518 1096 }
9370761c 1097 chain_type[ctype->family][ctype->type] = ctype;
96518518 1098 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
96518518 1099}
9370761c 1100EXPORT_SYMBOL_GPL(nft_register_chain_type);
96518518 1101
32537e91 1102void nft_unregister_chain_type(const struct nft_chain_type *ctype)
96518518 1103{
96518518 1104 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c 1105 chain_type[ctype->family][ctype->type] = NULL;
96518518
PM
1106 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1107}
9370761c 1108EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
96518518
PM
1109
1110/*
1111 * Chains
1112 */
1113
1114static struct nft_chain *
cac20fcd 1115nft_chain_lookup_byhandle(const struct nft_table *table, u64 handle, u8 genmask)
96518518
PM
1116{
1117 struct nft_chain *chain;
1118
1119 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
1120 if (chain->handle == handle &&
1121 nft_active_genmask(chain, genmask))
96518518
PM
1122 return chain;
1123 }
1124
1125 return ERR_PTR(-ENOENT);
1126}
1127
4d44175a 1128static bool lockdep_commit_lock_is_held(const struct net *net)
f102d66b
FW
1129{
1130#ifdef CONFIG_PROVE_LOCKING
1131 return lockdep_is_held(&net->nft.commit_mutex);
1132#else
1133 return true;
1134#endif
1135}
1136
1137static struct nft_chain *nft_chain_lookup(struct net *net,
1138 struct nft_table *table,
cac20fcd 1139 const struct nlattr *nla, u8 genmask)
96518518 1140{
1b2470e5
FW
1141 char search[NFT_CHAIN_MAXNAMELEN + 1];
1142 struct rhlist_head *tmp, *list;
96518518
PM
1143 struct nft_chain *chain;
1144
1145 if (nla == NULL)
1146 return ERR_PTR(-EINVAL);
1147
1b2470e5 1148 nla_strlcpy(search, nla, sizeof(search));
96518518 1149
1b2470e5 1150 WARN_ON(!rcu_read_lock_held() &&
f102d66b 1151 !lockdep_commit_lock_is_held(net));
1b2470e5
FW
1152
1153 chain = ERR_PTR(-ENOENT);
1154 rcu_read_lock();
1155 list = rhltable_lookup(&table->chains_ht, search, nft_chain_ht_params);
1156 if (!list)
1157 goto out_unlock;
1158
1159 rhl_for_each_entry_rcu(chain, tmp, list, rhlhead) {
1160 if (nft_active_genmask(chain, genmask))
1161 goto out_unlock;
1162 }
1163 chain = ERR_PTR(-ENOENT);
1164out_unlock:
1165 rcu_read_unlock();
1166 return chain;
96518518
PM
1167}
1168
1169static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
b2fbd044
LZ
1170 [NFTA_CHAIN_TABLE] = { .type = NLA_STRING,
1171 .len = NFT_TABLE_MAXNAMELEN - 1 },
96518518
PM
1172 [NFTA_CHAIN_HANDLE] = { .type = NLA_U64 },
1173 [NFTA_CHAIN_NAME] = { .type = NLA_STRING,
1174 .len = NFT_CHAIN_MAXNAMELEN - 1 },
1175 [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED },
0ca743a5 1176 [NFTA_CHAIN_POLICY] = { .type = NLA_U32 },
4c1f7818 1177 [NFTA_CHAIN_TYPE] = { .type = NLA_STRING },
0ca743a5 1178 [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED },
c9626a2c 1179 [NFTA_CHAIN_FLAGS] = { .type = NLA_U32 },
96518518
PM
1180};
1181
1182static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
1183 [NFTA_HOOK_HOOKNUM] = { .type = NLA_U32 },
1184 [NFTA_HOOK_PRIORITY] = { .type = NLA_U32 },
2cbce139
PNA
1185 [NFTA_HOOK_DEV] = { .type = NLA_STRING,
1186 .len = IFNAMSIZ - 1 },
96518518
PM
1187};
1188
0ca743a5
PNA
1189static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
1190{
1191 struct nft_stats *cpu_stats, total;
1192 struct nlattr *nest;
ce355e20
ED
1193 unsigned int seq;
1194 u64 pkts, bytes;
0ca743a5
PNA
1195 int cpu;
1196
edbd82c5
FW
1197 if (!stats)
1198 return 0;
1199
0ca743a5
PNA
1200 memset(&total, 0, sizeof(total));
1201 for_each_possible_cpu(cpu) {
1202 cpu_stats = per_cpu_ptr(stats, cpu);
ce355e20
ED
1203 do {
1204 seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
1205 pkts = cpu_stats->pkts;
1206 bytes = cpu_stats->bytes;
1207 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
1208 total.pkts += pkts;
1209 total.bytes += bytes;
0ca743a5 1210 }
ae0be8de 1211 nest = nla_nest_start_noflag(skb, NFTA_CHAIN_COUNTERS);
0ca743a5
PNA
1212 if (nest == NULL)
1213 goto nla_put_failure;
1214
b46f6ded
ND
1215 if (nla_put_be64(skb, NFTA_COUNTER_PACKETS, cpu_to_be64(total.pkts),
1216 NFTA_COUNTER_PAD) ||
1217 nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
1218 NFTA_COUNTER_PAD))
0ca743a5
PNA
1219 goto nla_put_failure;
1220
1221 nla_nest_end(skb, nest);
1222 return 0;
1223
1224nla_put_failure:
1225 return -ENOSPC;
1226}
1227
84d7fce6
PNA
1228static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
1229 u32 portid, u32 seq, int event, u32 flags,
1230 int family, const struct nft_table *table,
96518518
PM
1231 const struct nft_chain *chain)
1232{
1233 struct nlmsghdr *nlh;
1234 struct nfgenmsg *nfmsg;
1235
dedb67c4 1236 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
96518518
PM
1237 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
1238 if (nlh == NULL)
1239 goto nla_put_failure;
1240
1241 nfmsg = nlmsg_data(nlh);
1242 nfmsg->nfgen_family = family;
1243 nfmsg->version = NFNETLINK_V0;
84d7fce6 1244 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518
PM
1245
1246 if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
1247 goto nla_put_failure;
b46f6ded
ND
1248 if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
1249 NFTA_CHAIN_PAD))
96518518
PM
1250 goto nla_put_failure;
1251 if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
1252 goto nla_put_failure;
1253
f323d954 1254 if (nft_is_base_chain(chain)) {
0ca743a5 1255 const struct nft_base_chain *basechain = nft_base_chain(chain);
c974a3a3 1256 const struct nf_hook_ops *ops = &basechain->ops;
edbd82c5 1257 struct nft_stats __percpu *stats;
0ca743a5
PNA
1258 struct nlattr *nest;
1259
ae0be8de 1260 nest = nla_nest_start_noflag(skb, NFTA_CHAIN_HOOK);
96518518
PM
1261 if (nest == NULL)
1262 goto nla_put_failure;
1263 if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum)))
1264 goto nla_put_failure;
1265 if (nla_put_be32(skb, NFTA_HOOK_PRIORITY, htonl(ops->priority)))
1266 goto nla_put_failure;
2cbce139
PNA
1267 if (basechain->dev_name[0] &&
1268 nla_put_string(skb, NFTA_HOOK_DEV, basechain->dev_name))
1269 goto nla_put_failure;
96518518 1270 nla_nest_end(skb, nest);
9370761c 1271
0ca743a5
PNA
1272 if (nla_put_be32(skb, NFTA_CHAIN_POLICY,
1273 htonl(basechain->policy)))
1274 goto nla_put_failure;
1275
baae3e62
PM
1276 if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name))
1277 goto nla_put_failure;
0ca743a5 1278
edbd82c5
FW
1279 stats = rcu_dereference_check(basechain->stats,
1280 lockdep_commit_lock_is_held(net));
1281 if (nft_dump_stats(skb, stats))
0ca743a5 1282 goto nla_put_failure;
96518518
PM
1283 }
1284
0ca743a5
PNA
1285 if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
1286 goto nla_put_failure;
1287
053c095a
JB
1288 nlmsg_end(skb, nlh);
1289 return 0;
96518518
PM
1290
1291nla_put_failure:
1292 nlmsg_trim(skb, nlh);
1293 return -1;
1294}
1295
25e94a99 1296static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
96518518
PM
1297{
1298 struct sk_buff *skb;
96518518
PM
1299 int err;
1300
128ad332
PNA
1301 if (!ctx->report &&
1302 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 1303 return;
96518518 1304
96518518
PM
1305 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1306 if (skb == NULL)
1307 goto err;
1308
84d7fce6 1309 err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
36596dad 1310 event, 0, ctx->family, ctx->table,
35151d84 1311 ctx->chain);
96518518
PM
1312 if (err < 0) {
1313 kfree_skb(skb);
1314 goto err;
1315 }
1316
25e94a99
PNA
1317 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1318 ctx->report, GFP_KERNEL);
1319 return;
96518518 1320err:
25e94a99 1321 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
1322}
1323
1324static int nf_tables_dump_chains(struct sk_buff *skb,
1325 struct netlink_callback *cb)
1326{
1327 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
96518518
PM
1328 const struct nft_table *table;
1329 const struct nft_chain *chain;
1330 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 1331 struct net *net = sock_net(skb->sk);
96518518
PM
1332 int family = nfmsg->nfgen_family;
1333
e688a7f8 1334 rcu_read_lock();
38e029f1
PNA
1335 cb->seq = net->nft.base_seq;
1336
36596dad 1337 list_for_each_entry_rcu(table, &net->nft.tables, list) {
98319cb9 1338 if (family != NFPROTO_UNSPEC && family != table->family)
96518518
PM
1339 continue;
1340
36596dad
PNA
1341 list_for_each_entry_rcu(chain, &table->chains, list) {
1342 if (idx < s_idx)
1343 goto cont;
1344 if (idx > s_idx)
1345 memset(&cb->args[1], 0,
1346 sizeof(cb->args) - sizeof(cb->args[0]));
1347 if (!nft_is_active(net, chain))
1348 continue;
1349 if (nf_tables_fill_chain_info(skb, net,
1350 NETLINK_CB(cb->skb).portid,
1351 cb->nlh->nlmsg_seq,
1352 NFT_MSG_NEWCHAIN,
1353 NLM_F_MULTI,
98319cb9 1354 table->family, table,
36596dad
PNA
1355 chain) < 0)
1356 goto done;
38e029f1 1357
36596dad 1358 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518 1359cont:
36596dad 1360 idx++;
96518518
PM
1361 }
1362 }
1363done:
e688a7f8 1364 rcu_read_unlock();
96518518
PM
1365 cb->args[0] = idx;
1366 return skb->len;
1367}
1368
d9adf22a 1369/* called with rcu_read_lock held */
7b8002a1
PNA
1370static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1371 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1372 const struct nlattr * const nla[],
1373 struct netlink_ext_ack *extack)
96518518
PM
1374{
1375 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1376 u8 genmask = nft_genmask_cur(net);
96518518 1377 const struct nft_chain *chain;
1b2470e5 1378 struct nft_table *table;
96518518
PM
1379 struct sk_buff *skb2;
1380 int family = nfmsg->nfgen_family;
1381 int err;
1382
1383 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1384 struct netlink_dump_control c = {
1385 .dump = nf_tables_dump_chains,
d9adf22a 1386 .module = THIS_MODULE,
96518518 1387 };
d9adf22a
FW
1388
1389 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
96518518
PM
1390 }
1391
cac20fcd 1392 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask);
36dd1bcc
PNA
1393 if (IS_ERR(table)) {
1394 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_TABLE]);
96518518 1395 return PTR_ERR(table);
36dd1bcc 1396 }
96518518 1397
f102d66b 1398 chain = nft_chain_lookup(net, table, nla[NFTA_CHAIN_NAME], genmask);
36dd1bcc
PNA
1399 if (IS_ERR(chain)) {
1400 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_NAME]);
96518518 1401 return PTR_ERR(chain);
36dd1bcc 1402 }
96518518 1403
d9adf22a 1404 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
96518518
PM
1405 if (!skb2)
1406 return -ENOMEM;
1407
84d7fce6 1408 err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
1409 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
1410 family, table, chain);
1411 if (err < 0)
1412 goto err;
1413
1414 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1415
1416err:
1417 kfree_skb(skb2);
1418 return err;
1419}
1420
0ca743a5
PNA
1421static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
1422 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
1423 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
1424};
1425
ff3cd7b3 1426static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
0ca743a5
PNA
1427{
1428 struct nlattr *tb[NFTA_COUNTER_MAX+1];
1429 struct nft_stats __percpu *newstats;
1430 struct nft_stats *stats;
1431 int err;
1432
8cb08174
JB
1433 err = nla_parse_nested_deprecated(tb, NFTA_COUNTER_MAX, attr,
1434 nft_counter_policy, NULL);
0ca743a5 1435 if (err < 0)
ff3cd7b3 1436 return ERR_PTR(err);
0ca743a5
PNA
1437
1438 if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
ff3cd7b3 1439 return ERR_PTR(-EINVAL);
0ca743a5 1440
ce355e20 1441 newstats = netdev_alloc_pcpu_stats(struct nft_stats);
0ca743a5 1442 if (newstats == NULL)
ff3cd7b3 1443 return ERR_PTR(-ENOMEM);
0ca743a5
PNA
1444
1445 /* Restore old counters on this cpu, no problem. Per-cpu statistics
1446 * are not exposed to userspace.
1447 */
e8781f70 1448 preempt_disable();
0ca743a5
PNA
1449 stats = this_cpu_ptr(newstats);
1450 stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
1451 stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
e8781f70 1452 preempt_enable();
0ca743a5 1453
ff3cd7b3
PNA
1454 return newstats;
1455}
1456
53315ac6 1457static void nft_chain_stats_replace(struct nft_trans *trans)
ff3cd7b3 1458{
53315ac6 1459 struct nft_base_chain *chain = nft_base_chain(trans->ctx.chain);
0befd061 1460
53315ac6 1461 if (!nft_trans_chain_stats(trans))
b88825de
PNA
1462 return;
1463
53315ac6
FW
1464 rcu_swap_protected(chain->stats, nft_trans_chain_stats(trans),
1465 lockdep_commit_lock_is_held(trans->ctx.net));
1466
1467 if (!nft_trans_chain_stats(trans))
bbb8c61f 1468 static_branch_inc(&nft_counters_enabled);
0ca743a5
PNA
1469}
1470
0cbc06b3
FW
1471static void nf_tables_chain_free_chain_rules(struct nft_chain *chain)
1472{
1473 struct nft_rule **g0 = rcu_dereference_raw(chain->rules_gen_0);
1474 struct nft_rule **g1 = rcu_dereference_raw(chain->rules_gen_1);
1475
1476 if (g0 != g1)
1477 kvfree(g1);
1478 kvfree(g0);
1479
1480 /* should be NULL either via abort or via successful commit */
1481 WARN_ON_ONCE(chain->rules_next);
1482 kvfree(chain->rules_next);
1483}
1484
43a605f2 1485static void nf_tables_chain_destroy(struct nft_ctx *ctx)
91c7b38d 1486{
43a605f2
PNA
1487 struct nft_chain *chain = ctx->chain;
1488
fa5950e4
FW
1489 if (WARN_ON(chain->use > 0))
1490 return;
91c7b38d 1491
0cbc06b3
FW
1492 /* no concurrent access possible anymore */
1493 nf_tables_chain_free_chain_rules(chain);
1494
f323d954 1495 if (nft_is_base_chain(chain)) {
2cbce139
PNA
1496 struct nft_base_chain *basechain = nft_base_chain(chain);
1497
1498 module_put(basechain->type->owner);
4c05ec47 1499 if (rcu_access_pointer(basechain->stats)) {
9f08ea84 1500 static_branch_dec(&nft_counters_enabled);
4c05ec47
TY
1501 free_percpu(rcu_dereference_raw(basechain->stats));
1502 }
b7263e07 1503 kfree(chain->name);
2cbce139 1504 kfree(basechain);
91c7b38d 1505 } else {
b7263e07 1506 kfree(chain->name);
91c7b38d
PNA
1507 kfree(chain);
1508 }
1509}
1510
508f8ccd
PNA
1511struct nft_chain_hook {
1512 u32 num;
84ba7dd7 1513 s32 priority;
32537e91 1514 const struct nft_chain_type *type;
508f8ccd
PNA
1515 struct net_device *dev;
1516};
1517
1518static int nft_chain_parse_hook(struct net *net,
1519 const struct nlattr * const nla[],
36596dad 1520 struct nft_chain_hook *hook, u8 family,
445509eb 1521 bool autoload)
508f8ccd
PNA
1522{
1523 struct nlattr *ha[NFTA_HOOK_MAX + 1];
32537e91 1524 const struct nft_chain_type *type;
508f8ccd
PNA
1525 struct net_device *dev;
1526 int err;
1527
f102d66b
FW
1528 lockdep_assert_held(&net->nft.commit_mutex);
1529 lockdep_nfnl_nft_mutex_not_held();
1530
8cb08174
JB
1531 err = nla_parse_nested_deprecated(ha, NFTA_HOOK_MAX,
1532 nla[NFTA_CHAIN_HOOK],
1533 nft_hook_policy, NULL);
508f8ccd
PNA
1534 if (err < 0)
1535 return err;
1536
1537 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
1538 ha[NFTA_HOOK_PRIORITY] == NULL)
1539 return -EINVAL;
1540
1541 hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
508f8ccd
PNA
1542 hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
1543
36596dad 1544 type = chain_type[family][NFT_CHAIN_T_DEFAULT];
508f8ccd 1545 if (nla[NFTA_CHAIN_TYPE]) {
452238e8 1546 type = nf_tables_chain_type_lookup(net, nla[NFTA_CHAIN_TYPE],
445509eb 1547 family, autoload);
508f8ccd
PNA
1548 if (IS_ERR(type))
1549 return PTR_ERR(type);
1550 }
33d1c018 1551 if (hook->num > NF_MAX_HOOKS || !(type->hook_mask & (1 << hook->num)))
508f8ccd 1552 return -EOPNOTSUPP;
84ba7dd7
FW
1553
1554 if (type->type == NFT_CHAIN_T_NAT &&
1555 hook->priority <= NF_IP_PRI_CONNTRACK)
1556 return -EOPNOTSUPP;
1557
508f8ccd
PNA
1558 if (!try_module_get(type->owner))
1559 return -ENOENT;
1560
1561 hook->type = type;
1562
1563 hook->dev = NULL;
36596dad 1564 if (family == NFPROTO_NETDEV) {
508f8ccd
PNA
1565 char ifname[IFNAMSIZ];
1566
1567 if (!ha[NFTA_HOOK_DEV]) {
1568 module_put(type->owner);
1569 return -EOPNOTSUPP;
1570 }
1571
1572 nla_strlcpy(ifname, ha[NFTA_HOOK_DEV], IFNAMSIZ);
90d2723c 1573 dev = __dev_get_by_name(net, ifname);
508f8ccd
PNA
1574 if (!dev) {
1575 module_put(type->owner);
1576 return -ENOENT;
1577 }
1578 hook->dev = dev;
1579 } else if (ha[NFTA_HOOK_DEV]) {
1580 module_put(type->owner);
1581 return -EOPNOTSUPP;
1582 }
1583
1584 return 0;
1585}
1586
1587static void nft_chain_release_hook(struct nft_chain_hook *hook)
1588{
1589 module_put(hook->type->owner);
508f8ccd
PNA
1590}
1591
0cbc06b3
FW
1592struct nft_rules_old {
1593 struct rcu_head h;
1594 struct nft_rule **start;
1595};
1596
1597static struct nft_rule **nf_tables_chain_alloc_rules(const struct nft_chain *chain,
1598 unsigned int alloc)
1599{
1600 if (alloc > INT_MAX)
1601 return NULL;
1602
1603 alloc += 1; /* NULL, ends rules */
1604 if (sizeof(struct nft_rule *) > INT_MAX / alloc)
1605 return NULL;
1606
1607 alloc *= sizeof(struct nft_rule *);
1608 alloc += sizeof(struct nft_rules_old);
1609
1610 return kvmalloc(alloc, GFP_KERNEL);
1611}
1612
4035285f 1613static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
c9626a2c 1614 u8 policy, u32 flags)
4035285f
PNA
1615{
1616 const struct nlattr * const *nla = ctx->nla;
1617 struct nft_table *table = ctx->table;
4035285f
PNA
1618 struct nft_base_chain *basechain;
1619 struct nft_stats __percpu *stats;
1620 struct net *net = ctx->net;
66293c46 1621 struct nft_trans *trans;
4035285f 1622 struct nft_chain *chain;
0cbc06b3 1623 struct nft_rule **rules;
4035285f
PNA
1624 int err;
1625
1626 if (table->use == UINT_MAX)
1627 return -EOVERFLOW;
1628
1629 if (nla[NFTA_CHAIN_HOOK]) {
1630 struct nft_chain_hook hook;
1631 struct nf_hook_ops *ops;
4035285f 1632
445509eb 1633 err = nft_chain_parse_hook(net, nla, &hook, family, true);
4035285f
PNA
1634 if (err < 0)
1635 return err;
1636
1637 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
1638 if (basechain == NULL) {
1639 nft_chain_release_hook(&hook);
1640 return -ENOMEM;
1641 }
1642
1643 if (hook.dev != NULL)
1644 strncpy(basechain->dev_name, hook.dev->name, IFNAMSIZ);
1645
1646 if (nla[NFTA_CHAIN_COUNTERS]) {
1647 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1648 if (IS_ERR(stats)) {
1649 nft_chain_release_hook(&hook);
1650 kfree(basechain);
1651 return PTR_ERR(stats);
1652 }
4c05ec47 1653 rcu_assign_pointer(basechain->stats, stats);
4035285f
PNA
1654 static_branch_inc(&nft_counters_enabled);
1655 }
1656
4035285f
PNA
1657 basechain->type = hook.type;
1658 chain = &basechain->chain;
1659
c974a3a3
PNA
1660 ops = &basechain->ops;
1661 ops->pf = family;
1662 ops->hooknum = hook.num;
1663 ops->priority = hook.priority;
1664 ops->priv = chain;
c2f9eafe 1665 ops->hook = hook.type->hooks[ops->hooknum];
c974a3a3 1666 ops->dev = hook.dev;
c974a3a3 1667
c9626a2c 1668 chain->flags |= NFT_BASE_CHAIN | flags;
66293c46 1669 basechain->policy = NF_ACCEPT;
3bc158f8
PNA
1670 if (chain->flags & NFT_CHAIN_HW_OFFLOAD &&
1671 nft_chain_offload_priority(basechain) < 0)
1672 return -EOPNOTSUPP;
1673
14bfb13f 1674 flow_block_init(&basechain->flow_block);
4035285f
PNA
1675 } else {
1676 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1677 if (chain == NULL)
1678 return -ENOMEM;
1679 }
43a605f2
PNA
1680 ctx->chain = chain;
1681
4035285f
PNA
1682 INIT_LIST_HEAD(&chain->rules);
1683 chain->handle = nf_tables_alloc_handle(table);
1684 chain->table = table;
1685 chain->name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
1686 if (!chain->name) {
1687 err = -ENOMEM;
1688 goto err1;
1689 }
1690
0cbc06b3
FW
1691 rules = nf_tables_chain_alloc_rules(chain, 0);
1692 if (!rules) {
1693 err = -ENOMEM;
1694 goto err1;
1695 }
1696
1697 *rules = NULL;
1698 rcu_assign_pointer(chain->rules_gen_0, rules);
1699 rcu_assign_pointer(chain->rules_gen_1, rules);
1700
c974a3a3 1701 err = nf_tables_register_hook(net, table, chain);
4035285f
PNA
1702 if (err < 0)
1703 goto err1;
1704
1b2470e5
FW
1705 err = rhltable_insert_key(&table->chains_ht, chain->name,
1706 &chain->rhlhead, nft_chain_ht_params);
1707 if (err)
1708 goto err2;
1709
66293c46
FW
1710 trans = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
1711 if (IS_ERR(trans)) {
1712 err = PTR_ERR(trans);
1b2470e5
FW
1713 rhltable_remove(&table->chains_ht, &chain->rhlhead,
1714 nft_chain_ht_params);
4035285f 1715 goto err2;
1b2470e5 1716 }
4035285f 1717
66293c46
FW
1718 nft_trans_chain_policy(trans) = -1;
1719 if (nft_is_base_chain(chain))
1720 nft_trans_chain_policy(trans) = policy;
1721
4035285f
PNA
1722 table->use++;
1723 list_add_tail_rcu(&chain->list, &table->chains);
1724
1725 return 0;
1726err2:
c974a3a3 1727 nf_tables_unregister_hook(net, table, chain);
4035285f 1728err1:
43a605f2 1729 nf_tables_chain_destroy(ctx);
4035285f
PNA
1730
1731 return err;
1732}
1733
c9626a2c
PNA
1734static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
1735 u32 flags)
2c4a488a
PNA
1736{
1737 const struct nlattr * const *nla = ctx->nla;
1738 struct nft_table *table = ctx->table;
1739 struct nft_chain *chain = ctx->chain;
2c4a488a
PNA
1740 struct nft_base_chain *basechain;
1741 struct nft_stats *stats = NULL;
1742 struct nft_chain_hook hook;
2c4a488a
PNA
1743 struct nf_hook_ops *ops;
1744 struct nft_trans *trans;
c974a3a3 1745 int err;
2c4a488a 1746
c9626a2c
PNA
1747 if (chain->flags ^ flags)
1748 return -EOPNOTSUPP;
1749
2c4a488a
PNA
1750 if (nla[NFTA_CHAIN_HOOK]) {
1751 if (!nft_is_base_chain(chain))
1752 return -EBUSY;
1753
36596dad 1754 err = nft_chain_parse_hook(ctx->net, nla, &hook, ctx->family,
445509eb 1755 false);
2c4a488a
PNA
1756 if (err < 0)
1757 return err;
1758
1759 basechain = nft_base_chain(chain);
1760 if (basechain->type != hook.type) {
1761 nft_chain_release_hook(&hook);
1762 return -EBUSY;
1763 }
1764
c974a3a3
PNA
1765 ops = &basechain->ops;
1766 if (ops->hooknum != hook.num ||
1767 ops->priority != hook.priority ||
1768 ops->dev != hook.dev) {
1769 nft_chain_release_hook(&hook);
1770 return -EBUSY;
2c4a488a
PNA
1771 }
1772 nft_chain_release_hook(&hook);
1773 }
1774
1775 if (nla[NFTA_CHAIN_HANDLE] &&
1776 nla[NFTA_CHAIN_NAME]) {
1777 struct nft_chain *chain2;
1778
f102d66b
FW
1779 chain2 = nft_chain_lookup(ctx->net, table,
1780 nla[NFTA_CHAIN_NAME], genmask);
0d18779b
JC
1781 if (!IS_ERR(chain2))
1782 return -EEXIST;
2c4a488a
PNA
1783 }
1784
1785 if (nla[NFTA_CHAIN_COUNTERS]) {
1786 if (!nft_is_base_chain(chain))
1787 return -EOPNOTSUPP;
1788
1789 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1790 if (IS_ERR(stats))
1791 return PTR_ERR(stats);
1792 }
1793
c6cc94df 1794 err = -ENOMEM;
2c4a488a
PNA
1795 trans = nft_trans_alloc(ctx, NFT_MSG_NEWCHAIN,
1796 sizeof(struct nft_trans_chain));
c6cc94df
FW
1797 if (trans == NULL)
1798 goto err;
2c4a488a
PNA
1799
1800 nft_trans_chain_stats(trans) = stats;
1801 nft_trans_chain_update(trans) = true;
1802
1803 if (nla[NFTA_CHAIN_POLICY])
1804 nft_trans_chain_policy(trans) = policy;
1805 else
1806 nft_trans_chain_policy(trans) = -1;
1807
c6cc94df
FW
1808 if (nla[NFTA_CHAIN_HANDLE] &&
1809 nla[NFTA_CHAIN_NAME]) {
1810 struct nft_trans *tmp;
1811 char *name;
1812
1813 err = -ENOMEM;
1814 name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
1815 if (!name)
1816 goto err;
1817
1818 err = -EEXIST;
1819 list_for_each_entry(tmp, &ctx->net->nft.commit_list, list) {
1820 if (tmp->msg_type == NFT_MSG_NEWCHAIN &&
1821 tmp->ctx.table == table &&
1822 nft_trans_chain_update(tmp) &&
1823 nft_trans_chain_name(tmp) &&
1824 strcmp(name, nft_trans_chain_name(tmp)) == 0) {
1825 kfree(name);
1826 goto err;
1827 }
2c4a488a 1828 }
c6cc94df
FW
1829
1830 nft_trans_chain_name(trans) = name;
2c4a488a
PNA
1831 }
1832 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
1833
1834 return 0;
c6cc94df
FW
1835err:
1836 free_percpu(stats);
1837 kfree(trans);
1838 return err;
2c4a488a
PNA
1839}
1840
633c9a84
PNA
1841static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1842 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1843 const struct nlattr * const nla[],
1844 struct netlink_ext_ack *extack)
96518518
PM
1845{
1846 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4035285f
PNA
1847 u8 genmask = nft_genmask_next(net);
1848 int family = nfmsg->nfgen_family;
36dd1bcc 1849 const struct nlattr *attr;
96518518
PM
1850 struct nft_table *table;
1851 struct nft_chain *chain;
57de2a0c 1852 u8 policy = NF_ACCEPT;
4035285f 1853 struct nft_ctx ctx;
96518518 1854 u64 handle = 0;
c9626a2c 1855 u32 flags = 0;
96518518 1856
f102d66b
FW
1857 lockdep_assert_held(&net->nft.commit_mutex);
1858
cac20fcd 1859 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask);
36dd1bcc
PNA
1860 if (IS_ERR(table)) {
1861 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_TABLE]);
96518518 1862 return PTR_ERR(table);
36dd1bcc 1863 }
96518518 1864
96518518 1865 chain = NULL;
36dd1bcc 1866 attr = nla[NFTA_CHAIN_NAME];
96518518
PM
1867
1868 if (nla[NFTA_CHAIN_HANDLE]) {
1869 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
cac20fcd 1870 chain = nft_chain_lookup_byhandle(table, handle, genmask);
36dd1bcc
PNA
1871 if (IS_ERR(chain)) {
1872 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_HANDLE]);
96518518 1873 return PTR_ERR(chain);
36dd1bcc
PNA
1874 }
1875 attr = nla[NFTA_CHAIN_HANDLE];
96518518 1876 } else {
f102d66b 1877 chain = nft_chain_lookup(net, table, attr, genmask);
96518518 1878 if (IS_ERR(chain)) {
36dd1bcc
PNA
1879 if (PTR_ERR(chain) != -ENOENT) {
1880 NL_SET_BAD_ATTR(extack, attr);
96518518 1881 return PTR_ERR(chain);
36dd1bcc 1882 }
96518518
PM
1883 chain = NULL;
1884 }
1885 }
1886
57de2a0c 1887 if (nla[NFTA_CHAIN_POLICY]) {
f323d954 1888 if (chain != NULL &&
36dd1bcc
PNA
1889 !nft_is_base_chain(chain)) {
1890 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_POLICY]);
d6b6cb1d 1891 return -EOPNOTSUPP;
36dd1bcc 1892 }
d6b6cb1d
PNA
1893
1894 if (chain == NULL &&
36dd1bcc
PNA
1895 nla[NFTA_CHAIN_HOOK] == NULL) {
1896 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_POLICY]);
57de2a0c 1897 return -EOPNOTSUPP;
36dd1bcc 1898 }
57de2a0c 1899
8f46df18 1900 policy = ntohl(nla_get_be32(nla[NFTA_CHAIN_POLICY]));
57de2a0c
PM
1901 switch (policy) {
1902 case NF_DROP:
1903 case NF_ACCEPT:
1904 break;
1905 default:
1906 return -EINVAL;
1907 }
1908 }
1909
c9626a2c
PNA
1910 if (nla[NFTA_CHAIN_FLAGS])
1911 flags = ntohl(nla_get_be32(nla[NFTA_CHAIN_FLAGS]));
b717273d
FW
1912 else if (chain)
1913 flags = chain->flags;
c9626a2c 1914
98319cb9 1915 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
4035285f 1916
96518518 1917 if (chain != NULL) {
36dd1bcc
PNA
1918 if (nlh->nlmsg_flags & NLM_F_EXCL) {
1919 NL_SET_BAD_ATTR(extack, attr);
96518518 1920 return -EEXIST;
36dd1bcc 1921 }
96518518
PM
1922 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1923 return -EOPNOTSUPP;
1924
c9626a2c 1925 return nf_tables_updchain(&ctx, genmask, policy, flags);
96518518
PM
1926 }
1927
c9626a2c 1928 return nf_tables_addchain(&ctx, family, genmask, policy, flags);
96518518
PM
1929}
1930
633c9a84
PNA
1931static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1932 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1933 const struct nlattr * const nla[],
1934 struct netlink_ext_ack *extack)
96518518
PM
1935{
1936 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1937 u8 genmask = nft_genmask_next(net);
36dd1bcc
PNA
1938 int family = nfmsg->nfgen_family;
1939 const struct nlattr *attr;
96518518
PM
1940 struct nft_table *table;
1941 struct nft_chain *chain;
9dee1474 1942 struct nft_rule *rule;
91c7b38d 1943 struct nft_ctx ctx;
3ecbfd65 1944 u64 handle;
9dee1474
PNA
1945 u32 use;
1946 int err;
96518518 1947
cac20fcd 1948 table = nft_table_lookup(net, nla[NFTA_CHAIN_TABLE], family, genmask);
36dd1bcc
PNA
1949 if (IS_ERR(table)) {
1950 NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_TABLE]);
96518518 1951 return PTR_ERR(table);
36dd1bcc 1952 }
96518518 1953
3ecbfd65 1954 if (nla[NFTA_CHAIN_HANDLE]) {
36dd1bcc
PNA
1955 attr = nla[NFTA_CHAIN_HANDLE];
1956 handle = be64_to_cpu(nla_get_be64(attr));
cac20fcd 1957 chain = nft_chain_lookup_byhandle(table, handle, genmask);
3ecbfd65 1958 } else {
36dd1bcc 1959 attr = nla[NFTA_CHAIN_NAME];
f102d66b 1960 chain = nft_chain_lookup(net, table, attr, genmask);
3ecbfd65 1961 }
36dd1bcc
PNA
1962 if (IS_ERR(chain)) {
1963 NL_SET_BAD_ATTR(extack, attr);
96518518 1964 return PTR_ERR(chain);
36dd1bcc 1965 }
9dee1474
PNA
1966
1967 if (nlh->nlmsg_flags & NLM_F_NONREC &&
1968 chain->use > 0)
96518518
PM
1969 return -EBUSY;
1970
98319cb9 1971 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
0165d932 1972
9dee1474
PNA
1973 use = chain->use;
1974 list_for_each_entry(rule, &chain->rules, list) {
1975 if (!nft_is_active_next(net, rule))
1976 continue;
1977 use--;
1978
1979 err = nft_delrule(&ctx, rule);
1980 if (err < 0)
1981 return err;
1982 }
1983
1984 /* There are rules and elements that are still holding references to us,
1985 * we cannot do a recursive removal in this case.
1986 */
36dd1bcc
PNA
1987 if (use > 0) {
1988 NL_SET_BAD_ATTR(extack, attr);
9dee1474 1989 return -EBUSY;
36dd1bcc 1990 }
9dee1474 1991
ee01d542 1992 return nft_delchain(&ctx);
96518518
PM
1993}
1994
96518518
PM
1995/*
1996 * Expressions
1997 */
1998
1999/**
ef1f7df9
PM
2000 * nft_register_expr - register nf_tables expr type
2001 * @ops: expr type
96518518 2002 *
ef1f7df9 2003 * Registers the expr type for use with nf_tables. Returns zero on
96518518
PM
2004 * success or a negative errno code otherwise.
2005 */
ef1f7df9 2006int nft_register_expr(struct nft_expr_type *type)
96518518
PM
2007{
2008 nfnl_lock(NFNL_SUBSYS_NFTABLES);
758dbcec 2009 if (type->family == NFPROTO_UNSPEC)
e688a7f8 2010 list_add_tail_rcu(&type->list, &nf_tables_expressions);
758dbcec 2011 else
e688a7f8 2012 list_add_rcu(&type->list, &nf_tables_expressions);
96518518
PM
2013 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2014 return 0;
2015}
2016EXPORT_SYMBOL_GPL(nft_register_expr);
2017
2018/**
ef1f7df9
PM
2019 * nft_unregister_expr - unregister nf_tables expr type
2020 * @ops: expr type
96518518 2021 *
ef1f7df9 2022 * Unregisters the expr typefor use with nf_tables.
96518518 2023 */
ef1f7df9 2024void nft_unregister_expr(struct nft_expr_type *type)
96518518
PM
2025{
2026 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 2027 list_del_rcu(&type->list);
96518518
PM
2028 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2029}
2030EXPORT_SYMBOL_GPL(nft_unregister_expr);
2031
64d46806
PM
2032static const struct nft_expr_type *__nft_expr_type_get(u8 family,
2033 struct nlattr *nla)
96518518 2034{
9cff126f 2035 const struct nft_expr_type *type, *candidate = NULL;
96518518 2036
ef1f7df9 2037 list_for_each_entry(type, &nf_tables_expressions, list) {
9cff126f
PNA
2038 if (!nla_strcmp(nla, type->name)) {
2039 if (!type->family && !candidate)
2040 candidate = type;
2041 else if (type->family == family)
2042 candidate = type;
2043 }
96518518 2044 }
9cff126f 2045 return candidate;
96518518
PM
2046}
2047
b9c04ae7
PNA
2048#ifdef CONFIG_MODULES
2049static int nft_expr_type_request_module(struct net *net, u8 family,
2050 struct nlattr *nla)
2051{
2052 nft_request_module(net, "nft-expr-%u-%.*s", family,
2053 nla_len(nla), (char *)nla_data(nla));
2054 if (__nft_expr_type_get(family, nla))
2055 return -EAGAIN;
2056
2057 return 0;
2058}
2059#endif
2060
452238e8
FW
2061static const struct nft_expr_type *nft_expr_type_get(struct net *net,
2062 u8 family,
64d46806 2063 struct nlattr *nla)
96518518 2064{
ef1f7df9 2065 const struct nft_expr_type *type;
96518518
PM
2066
2067 if (nla == NULL)
2068 return ERR_PTR(-EINVAL);
2069
64d46806 2070 type = __nft_expr_type_get(family, nla);
ef1f7df9
PM
2071 if (type != NULL && try_module_get(type->owner))
2072 return type;
96518518 2073
f102d66b 2074 lockdep_nfnl_nft_mutex_not_held();
96518518 2075#ifdef CONFIG_MODULES
ef1f7df9 2076 if (type == NULL) {
b9c04ae7 2077 if (nft_expr_type_request_module(net, family, nla) == -EAGAIN)
64d46806
PM
2078 return ERR_PTR(-EAGAIN);
2079
452238e8
FW
2080 nft_request_module(net, "nft-expr-%.*s",
2081 nla_len(nla), (char *)nla_data(nla));
64d46806 2082 if (__nft_expr_type_get(family, nla))
96518518
PM
2083 return ERR_PTR(-EAGAIN);
2084 }
2085#endif
2086 return ERR_PTR(-ENOENT);
2087}
2088
2089static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
2090 [NFTA_EXPR_NAME] = { .type = NLA_STRING },
2091 [NFTA_EXPR_DATA] = { .type = NLA_NESTED },
2092};
2093
2094static int nf_tables_fill_expr_info(struct sk_buff *skb,
2095 const struct nft_expr *expr)
2096{
ef1f7df9 2097 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
96518518
PM
2098 goto nla_put_failure;
2099
2100 if (expr->ops->dump) {
ae0be8de
MK
2101 struct nlattr *data = nla_nest_start_noflag(skb,
2102 NFTA_EXPR_DATA);
96518518
PM
2103 if (data == NULL)
2104 goto nla_put_failure;
2105 if (expr->ops->dump(skb, expr) < 0)
2106 goto nla_put_failure;
2107 nla_nest_end(skb, data);
2108 }
2109
2110 return skb->len;
2111
2112nla_put_failure:
2113 return -1;
2114};
2115
0b2d8a7b
PM
2116int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
2117 const struct nft_expr *expr)
2118{
2119 struct nlattr *nest;
2120
ae0be8de 2121 nest = nla_nest_start_noflag(skb, attr);
0b2d8a7b
PM
2122 if (!nest)
2123 goto nla_put_failure;
2124 if (nf_tables_fill_expr_info(skb, expr) < 0)
2125 goto nla_put_failure;
2126 nla_nest_end(skb, nest);
2127 return 0;
2128
2129nla_put_failure:
2130 return -1;
2131}
2132
96518518
PM
2133struct nft_expr_info {
2134 const struct nft_expr_ops *ops;
ef1f7df9 2135 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
96518518
PM
2136};
2137
0ca743a5
PNA
2138static int nf_tables_expr_parse(const struct nft_ctx *ctx,
2139 const struct nlattr *nla,
96518518
PM
2140 struct nft_expr_info *info)
2141{
ef1f7df9 2142 const struct nft_expr_type *type;
96518518 2143 const struct nft_expr_ops *ops;
ef1f7df9 2144 struct nlattr *tb[NFTA_EXPR_MAX + 1];
96518518
PM
2145 int err;
2146
8cb08174
JB
2147 err = nla_parse_nested_deprecated(tb, NFTA_EXPR_MAX, nla,
2148 nft_expr_policy, NULL);
96518518
PM
2149 if (err < 0)
2150 return err;
2151
452238e8 2152 type = nft_expr_type_get(ctx->net, ctx->family, tb[NFTA_EXPR_NAME]);
ef1f7df9
PM
2153 if (IS_ERR(type))
2154 return PTR_ERR(type);
2155
2156 if (tb[NFTA_EXPR_DATA]) {
8cb08174
JB
2157 err = nla_parse_nested_deprecated(info->tb, type->maxattr,
2158 tb[NFTA_EXPR_DATA],
2159 type->policy, NULL);
ef1f7df9
PM
2160 if (err < 0)
2161 goto err1;
2162 } else
2163 memset(info->tb, 0, sizeof(info->tb[0]) * (type->maxattr + 1));
2164
2165 if (type->select_ops != NULL) {
0ca743a5
PNA
2166 ops = type->select_ops(ctx,
2167 (const struct nlattr * const *)info->tb);
ef1f7df9
PM
2168 if (IS_ERR(ops)) {
2169 err = PTR_ERR(ops);
0ef1efd1
PNA
2170#ifdef CONFIG_MODULES
2171 if (err == -EAGAIN)
2172 nft_expr_type_request_module(ctx->net,
2173 ctx->family,
2174 tb[NFTA_EXPR_NAME]);
2175#endif
ef1f7df9
PM
2176 goto err1;
2177 }
2178 } else
2179 ops = type->ops;
2180
96518518
PM
2181 info->ops = ops;
2182 return 0;
ef1f7df9
PM
2183
2184err1:
2185 module_put(type->owner);
2186 return err;
96518518
PM
2187}
2188
2189static int nf_tables_newexpr(const struct nft_ctx *ctx,
ef1f7df9 2190 const struct nft_expr_info *info,
96518518
PM
2191 struct nft_expr *expr)
2192{
2193 const struct nft_expr_ops *ops = info->ops;
2194 int err;
2195
2196 expr->ops = ops;
2197 if (ops->init) {
ef1f7df9 2198 err = ops->init(ctx, expr, (const struct nlattr **)info->tb);
96518518
PM
2199 if (err < 0)
2200 goto err1;
2201 }
2202
96518518 2203 return 0;
96518518
PM
2204err1:
2205 expr->ops = NULL;
2206 return err;
2207}
2208
62472bce
PM
2209static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
2210 struct nft_expr *expr)
96518518 2211{
3f3a390d
PNA
2212 const struct nft_expr_type *type = expr->ops->type;
2213
96518518 2214 if (expr->ops->destroy)
62472bce 2215 expr->ops->destroy(ctx, expr);
3f3a390d 2216 module_put(type->owner);
96518518
PM
2217}
2218
0b2d8a7b
PM
2219struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
2220 const struct nlattr *nla)
2221{
2222 struct nft_expr_info info;
2223 struct nft_expr *expr;
b8e20400 2224 struct module *owner;
0b2d8a7b
PM
2225 int err;
2226
2227 err = nf_tables_expr_parse(ctx, nla, &info);
2228 if (err < 0)
2229 goto err1;
2230
2231 err = -ENOMEM;
2232 expr = kzalloc(info.ops->size, GFP_KERNEL);
2233 if (expr == NULL)
2234 goto err2;
2235
2236 err = nf_tables_newexpr(ctx, &info, expr);
2237 if (err < 0)
6cafaf47 2238 goto err3;
0b2d8a7b
PM
2239
2240 return expr;
6cafaf47
LZ
2241err3:
2242 kfree(expr);
0b2d8a7b 2243err2:
b8e20400
PNA
2244 owner = info.ops->type->owner;
2245 if (info.ops->type->release_ops)
2246 info.ops->type->release_ops(info.ops);
2247
2248 module_put(owner);
0b2d8a7b
PM
2249err1:
2250 return ERR_PTR(err);
2251}
2252
2253void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
2254{
2255 nf_tables_expr_destroy(ctx, expr);
2256 kfree(expr);
2257}
2258
96518518
PM
2259/*
2260 * Rules
2261 */
2262
cac20fcd
PNA
2263static struct nft_rule *__nft_rule_lookup(const struct nft_chain *chain,
2264 u64 handle)
96518518
PM
2265{
2266 struct nft_rule *rule;
2267
2268 // FIXME: this sucks
d9adf22a 2269 list_for_each_entry_rcu(rule, &chain->rules, list) {
96518518
PM
2270 if (handle == rule->handle)
2271 return rule;
2272 }
2273
2274 return ERR_PTR(-ENOENT);
2275}
2276
cac20fcd
PNA
2277static struct nft_rule *nft_rule_lookup(const struct nft_chain *chain,
2278 const struct nlattr *nla)
96518518
PM
2279{
2280 if (nla == NULL)
2281 return ERR_PTR(-EINVAL);
2282
cac20fcd 2283 return __nft_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
96518518
PM
2284}
2285
2286static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
b2fbd044
LZ
2287 [NFTA_RULE_TABLE] = { .type = NLA_STRING,
2288 .len = NFT_TABLE_MAXNAMELEN - 1 },
96518518
PM
2289 [NFTA_RULE_CHAIN] = { .type = NLA_STRING,
2290 .len = NFT_CHAIN_MAXNAMELEN - 1 },
2291 [NFTA_RULE_HANDLE] = { .type = NLA_U64 },
2292 [NFTA_RULE_EXPRESSIONS] = { .type = NLA_NESTED },
0ca743a5 2293 [NFTA_RULE_COMPAT] = { .type = NLA_NESTED },
5e948466 2294 [NFTA_RULE_POSITION] = { .type = NLA_U64 },
0768b3b3
PNA
2295 [NFTA_RULE_USERDATA] = { .type = NLA_BINARY,
2296 .len = NFT_USERDATA_MAXLEN },
467697d2 2297 [NFTA_RULE_ID] = { .type = NLA_U32 },
0604628b 2298 [NFTA_RULE_POSITION_ID] = { .type = NLA_U32 },
96518518
PM
2299};
2300
84d7fce6
PNA
2301static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
2302 u32 portid, u32 seq, int event,
2303 u32 flags, int family,
96518518
PM
2304 const struct nft_table *table,
2305 const struct nft_chain *chain,
2c82c7e7
FW
2306 const struct nft_rule *rule,
2307 const struct nft_rule *prule)
96518518
PM
2308{
2309 struct nlmsghdr *nlh;
2310 struct nfgenmsg *nfmsg;
2311 const struct nft_expr *expr, *next;
2312 struct nlattr *list;
dedb67c4 2313 u16 type = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
96518518 2314
dedb67c4 2315 nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg), flags);
96518518
PM
2316 if (nlh == NULL)
2317 goto nla_put_failure;
2318
2319 nfmsg = nlmsg_data(nlh);
2320 nfmsg->nfgen_family = family;
2321 nfmsg->version = NFNETLINK_V0;
84d7fce6 2322 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518
PM
2323
2324 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
2325 goto nla_put_failure;
2326 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
2327 goto nla_put_failure;
b46f6ded
ND
2328 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle),
2329 NFTA_RULE_PAD))
96518518
PM
2330 goto nla_put_failure;
2331
2c82c7e7 2332 if (event != NFT_MSG_DELRULE && prule) {
5e948466 2333 if (nla_put_be64(skb, NFTA_RULE_POSITION,
b46f6ded
ND
2334 cpu_to_be64(prule->handle),
2335 NFTA_RULE_PAD))
5e948466
EL
2336 goto nla_put_failure;
2337 }
2338
ae0be8de 2339 list = nla_nest_start_noflag(skb, NFTA_RULE_EXPRESSIONS);
96518518
PM
2340 if (list == NULL)
2341 goto nla_put_failure;
2342 nft_rule_for_each_expr(expr, next, rule) {
0b2d8a7b 2343 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
96518518 2344 goto nla_put_failure;
96518518
PM
2345 }
2346 nla_nest_end(skb, list);
2347
86f1ec32
PM
2348 if (rule->udata) {
2349 struct nft_userdata *udata = nft_userdata(rule);
2350 if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
2351 udata->data) < 0)
2352 goto nla_put_failure;
2353 }
0768b3b3 2354
053c095a
JB
2355 nlmsg_end(skb, nlh);
2356 return 0;
96518518
PM
2357
2358nla_put_failure:
2359 nlmsg_trim(skb, nlh);
2360 return -1;
2361}
2362
25e94a99
PNA
2363static void nf_tables_rule_notify(const struct nft_ctx *ctx,
2364 const struct nft_rule *rule, int event)
96518518
PM
2365{
2366 struct sk_buff *skb;
96518518
PM
2367 int err;
2368
128ad332
PNA
2369 if (!ctx->report &&
2370 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 2371 return;
96518518 2372
96518518
PM
2373 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2374 if (skb == NULL)
2375 goto err;
2376
84d7fce6 2377 err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
36596dad 2378 event, 0, ctx->family, ctx->table,
2c82c7e7 2379 ctx->chain, rule, NULL);
96518518
PM
2380 if (err < 0) {
2381 kfree_skb(skb);
2382 goto err;
2383 }
2384
25e94a99
PNA
2385 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
2386 ctx->report, GFP_KERNEL);
2387 return;
96518518 2388err:
25e94a99 2389 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
2390}
2391
6e1f760e 2392struct nft_rule_dump_ctx {
e46abbcc 2393 char *table;
b7263e07 2394 char *chain;
6e1f760e
PNA
2395};
2396
241faece
PS
2397static int __nf_tables_dump_rules(struct sk_buff *skb,
2398 unsigned int *idx,
2399 struct netlink_callback *cb,
2400 const struct nft_table *table,
2401 const struct nft_chain *chain)
2402{
2403 struct net *net = sock_net(skb->sk);
2c82c7e7 2404 const struct nft_rule *rule, *prule;
241faece 2405 unsigned int s_idx = cb->args[0];
241faece 2406
2c82c7e7 2407 prule = NULL;
241faece
PS
2408 list_for_each_entry_rcu(rule, &chain->rules, list) {
2409 if (!nft_is_active(net, rule))
2c82c7e7 2410 goto cont_skip;
241faece
PS
2411 if (*idx < s_idx)
2412 goto cont;
2413 if (*idx > s_idx) {
2414 memset(&cb->args[1], 0,
2415 sizeof(cb->args) - sizeof(cb->args[0]));
2416 }
2417 if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
2418 cb->nlh->nlmsg_seq,
2419 NFT_MSG_NEWRULE,
2420 NLM_F_MULTI | NLM_F_APPEND,
2421 table->family,
2c82c7e7 2422 table, chain, rule, prule) < 0)
310529e6 2423 return 1;
241faece
PS
2424
2425 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
2426cont:
2c82c7e7
FW
2427 prule = rule;
2428cont_skip:
241faece
PS
2429 (*idx)++;
2430 }
310529e6 2431 return 0;
241faece
PS
2432}
2433
96518518
PM
2434static int nf_tables_dump_rules(struct sk_buff *skb,
2435 struct netlink_callback *cb)
2436{
2437 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
6e1f760e 2438 const struct nft_rule_dump_ctx *ctx = cb->data;
241faece 2439 struct nft_table *table;
96518518 2440 const struct nft_chain *chain;
241faece 2441 unsigned int idx = 0;
99633ab2 2442 struct net *net = sock_net(skb->sk);
96518518
PM
2443 int family = nfmsg->nfgen_family;
2444
e688a7f8 2445 rcu_read_lock();
38e029f1
PNA
2446 cb->seq = net->nft.base_seq;
2447
36596dad 2448 list_for_each_entry_rcu(table, &net->nft.tables, list) {
98319cb9 2449 if (family != NFPROTO_UNSPEC && family != table->family)
36596dad
PNA
2450 continue;
2451
2452 if (ctx && ctx->table && strcmp(ctx->table, table->name) != 0)
96518518
PM
2453 continue;
2454
715849ab 2455 if (ctx && ctx->table && ctx->chain) {
241faece 2456 struct rhlist_head *list, *tmp;
6e1f760e 2457
241faece
PS
2458 list = rhltable_lookup(&table->chains_ht, ctx->chain,
2459 nft_chain_ht_params);
2460 if (!list)
2461 goto done;
2462
2463 rhl_for_each_entry_rcu(chain, tmp, list, rhlhead) {
2464 if (!nft_is_active(net, chain))
2465 continue;
2466 __nf_tables_dump_rules(skb, &idx,
2467 cb, table, chain);
2468 break;
96518518 2469 }
241faece 2470 goto done;
96518518 2471 }
241faece
PS
2472
2473 list_for_each_entry_rcu(chain, &table->chains, list) {
2474 if (__nf_tables_dump_rules(skb, &idx, cb, table, chain))
2475 goto done;
2476 }
2477
2478 if (ctx && ctx->table)
2479 break;
96518518
PM
2480 }
2481done:
e688a7f8 2482 rcu_read_unlock();
310529e6
PS
2483
2484 cb->args[0] = idx;
96518518
PM
2485 return skb->len;
2486}
2487
90fd131a
FW
2488static int nf_tables_dump_rules_start(struct netlink_callback *cb)
2489{
2490 const struct nlattr * const *nla = cb->data;
2491 struct nft_rule_dump_ctx *ctx = NULL;
2492
2493 if (nla[NFTA_RULE_TABLE] || nla[NFTA_RULE_CHAIN]) {
2494 ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
2495 if (!ctx)
2496 return -ENOMEM;
2497
2498 if (nla[NFTA_RULE_TABLE]) {
2499 ctx->table = nla_strdup(nla[NFTA_RULE_TABLE],
2500 GFP_ATOMIC);
2501 if (!ctx->table) {
2502 kfree(ctx);
2503 return -ENOMEM;
2504 }
2505 }
2506 if (nla[NFTA_RULE_CHAIN]) {
2507 ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN],
2508 GFP_ATOMIC);
2509 if (!ctx->chain) {
2510 kfree(ctx->table);
2511 kfree(ctx);
2512 return -ENOMEM;
2513 }
2514 }
2515 }
2516
2517 cb->data = ctx;
2518 return 0;
2519}
2520
6e1f760e
PNA
2521static int nf_tables_dump_rules_done(struct netlink_callback *cb)
2522{
e46abbcc
PS
2523 struct nft_rule_dump_ctx *ctx = cb->data;
2524
2525 if (ctx) {
2526 kfree(ctx->table);
b7263e07 2527 kfree(ctx->chain);
e46abbcc
PS
2528 kfree(ctx);
2529 }
6e1f760e
PNA
2530 return 0;
2531}
2532
d9adf22a 2533/* called with rcu_read_lock held */
7b8002a1
PNA
2534static int nf_tables_getrule(struct net *net, struct sock *nlsk,
2535 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2536 const struct nlattr * const nla[],
2537 struct netlink_ext_ack *extack)
96518518
PM
2538{
2539 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2540 u8 genmask = nft_genmask_cur(net);
96518518
PM
2541 const struct nft_chain *chain;
2542 const struct nft_rule *rule;
1b2470e5 2543 struct nft_table *table;
96518518
PM
2544 struct sk_buff *skb2;
2545 int family = nfmsg->nfgen_family;
2546 int err;
2547
2548 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2549 struct netlink_dump_control c = {
90fd131a 2550 .start= nf_tables_dump_rules_start,
96518518 2551 .dump = nf_tables_dump_rules,
6e1f760e 2552 .done = nf_tables_dump_rules_done,
d9adf22a 2553 .module = THIS_MODULE,
90fd131a 2554 .data = (void *)nla,
96518518 2555 };
6e1f760e 2556
d9adf22a 2557 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
96518518
PM
2558 }
2559
cac20fcd 2560 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask);
36dd1bcc
PNA
2561 if (IS_ERR(table)) {
2562 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_TABLE]);
96518518 2563 return PTR_ERR(table);
36dd1bcc 2564 }
96518518 2565
f102d66b 2566 chain = nft_chain_lookup(net, table, nla[NFTA_RULE_CHAIN], genmask);
36dd1bcc
PNA
2567 if (IS_ERR(chain)) {
2568 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
96518518 2569 return PTR_ERR(chain);
36dd1bcc 2570 }
96518518 2571
cac20fcd 2572 rule = nft_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
36dd1bcc
PNA
2573 if (IS_ERR(rule)) {
2574 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
96518518 2575 return PTR_ERR(rule);
36dd1bcc 2576 }
96518518 2577
d9adf22a 2578 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
96518518
PM
2579 if (!skb2)
2580 return -ENOMEM;
2581
84d7fce6 2582 err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
96518518 2583 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
2c82c7e7 2584 family, table, chain, rule, NULL);
96518518
PM
2585 if (err < 0)
2586 goto err;
2587
2588 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2589
2590err:
2591 kfree_skb(skb2);
2592 return err;
2593}
2594
62472bce
PM
2595static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
2596 struct nft_rule *rule)
96518518 2597{
29e38801 2598 struct nft_expr *expr, *next;
96518518
PM
2599
2600 /*
2601 * Careful: some expressions might not be initialized in case this
2602 * is called on error from nf_tables_newrule().
2603 */
2604 expr = nft_expr_first(rule);
3e38df13 2605 while (expr != nft_expr_last(rule) && expr->ops) {
29e38801 2606 next = nft_expr_next(expr);
62472bce 2607 nf_tables_expr_destroy(ctx, expr);
29e38801 2608 expr = next;
96518518
PM
2609 }
2610 kfree(rule);
2611}
2612
bb7b40ae
PNA
2613static void nf_tables_rule_release(const struct nft_ctx *ctx,
2614 struct nft_rule *rule)
2615{
f6ac8585 2616 nft_rule_expr_deactivate(ctx, rule, NFT_TRANS_RELEASE);
bb7b40ae
PNA
2617 nf_tables_rule_destroy(ctx, rule);
2618}
2619
a654de8f
PNA
2620int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain)
2621{
2622 struct nft_expr *expr, *last;
2623 const struct nft_data *data;
2624 struct nft_rule *rule;
2625 int err;
2626
26b2f552
TY
2627 if (ctx->level == NFT_JUMP_STACK_SIZE)
2628 return -EMLINK;
2629
a654de8f
PNA
2630 list_for_each_entry(rule, &chain->rules, list) {
2631 if (!nft_is_active_next(ctx->net, rule))
2632 continue;
2633
2634 nft_rule_for_each_expr(expr, last, rule) {
2635 if (!expr->ops->validate)
2636 continue;
2637
2638 err = expr->ops->validate(ctx, expr, &data);
2639 if (err < 0)
2640 return err;
2641 }
2642 }
2643
2644 return 0;
2645}
2646EXPORT_SYMBOL_GPL(nft_chain_validate);
2647
2648static int nft_table_validate(struct net *net, const struct nft_table *table)
2649{
2650 struct nft_chain *chain;
2651 struct nft_ctx ctx = {
2652 .net = net,
2653 .family = table->family,
2654 };
2655 int err;
2656
2657 list_for_each_entry(chain, &table->chains, list) {
2658 if (!nft_is_base_chain(chain))
2659 continue;
2660
2661 ctx.chain = chain;
2662 err = nft_chain_validate(&ctx, chain);
2663 if (err < 0)
2664 return err;
2665 }
2666
2667 return 0;
2668}
2669
75dd48e2
PS
2670static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
2671 const struct nlattr *nla);
2672
1081d11b
PNA
2673#define NFT_RULE_MAXEXPRS 128
2674
633c9a84
PNA
2675static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2676 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2677 const struct nlattr * const nla[],
2678 struct netlink_ext_ack *extack)
96518518
PM
2679{
2680 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2681 u8 genmask = nft_genmask_next(net);
2a43ecf9 2682 struct nft_expr_info *info = NULL;
98319cb9 2683 int family = nfmsg->nfgen_family;
c9626a2c 2684 struct nft_flow_rule *flow;
96518518
PM
2685 struct nft_table *table;
2686 struct nft_chain *chain;
2687 struct nft_rule *rule, *old_rule = NULL;
86f1ec32 2688 struct nft_userdata *udata;
1081d11b 2689 struct nft_trans *trans = NULL;
96518518
PM
2690 struct nft_expr *expr;
2691 struct nft_ctx ctx;
2692 struct nlattr *tmp;
86f1ec32 2693 unsigned int size, i, n, ulen = 0, usize = 0;
96518518 2694 int err, rem;
5e948466 2695 u64 handle, pos_handle;
96518518 2696
f102d66b
FW
2697 lockdep_assert_held(&net->nft.commit_mutex);
2698
cac20fcd 2699 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask);
36dd1bcc
PNA
2700 if (IS_ERR(table)) {
2701 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_TABLE]);
96518518 2702 return PTR_ERR(table);
36dd1bcc 2703 }
96518518 2704
f102d66b 2705 chain = nft_chain_lookup(net, table, nla[NFTA_RULE_CHAIN], genmask);
36dd1bcc
PNA
2706 if (IS_ERR(chain)) {
2707 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
96518518 2708 return PTR_ERR(chain);
36dd1bcc 2709 }
96518518
PM
2710
2711 if (nla[NFTA_RULE_HANDLE]) {
2712 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
cac20fcd 2713 rule = __nft_rule_lookup(chain, handle);
36dd1bcc
PNA
2714 if (IS_ERR(rule)) {
2715 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
96518518 2716 return PTR_ERR(rule);
36dd1bcc 2717 }
96518518 2718
36dd1bcc
PNA
2719 if (nlh->nlmsg_flags & NLM_F_EXCL) {
2720 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
96518518 2721 return -EEXIST;
36dd1bcc 2722 }
96518518
PM
2723 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2724 old_rule = rule;
2725 else
2726 return -EOPNOTSUPP;
2727 } else {
445509eb
PNA
2728 if (!(nlh->nlmsg_flags & NLM_F_CREATE) ||
2729 nlh->nlmsg_flags & NLM_F_REPLACE)
96518518
PM
2730 return -EINVAL;
2731 handle = nf_tables_alloc_handle(table);
a0a7379e
PNA
2732
2733 if (chain->use == UINT_MAX)
2734 return -EOVERFLOW;
5e948466 2735
447750f2
FW
2736 if (nla[NFTA_RULE_POSITION]) {
2737 pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
2738 old_rule = __nft_rule_lookup(chain, pos_handle);
2739 if (IS_ERR(old_rule)) {
2740 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_POSITION]);
2741 return PTR_ERR(old_rule);
2742 }
75dd48e2
PS
2743 } else if (nla[NFTA_RULE_POSITION_ID]) {
2744 old_rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_POSITION_ID]);
2745 if (IS_ERR(old_rule)) {
2746 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_POSITION_ID]);
2747 return PTR_ERR(old_rule);
2748 }
36dd1bcc 2749 }
5e948466
EL
2750 }
2751
98319cb9 2752 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
0ca743a5 2753
96518518
PM
2754 n = 0;
2755 size = 0;
2756 if (nla[NFTA_RULE_EXPRESSIONS]) {
2a43ecf9
FW
2757 info = kvmalloc_array(NFT_RULE_MAXEXPRS,
2758 sizeof(struct nft_expr_info),
2759 GFP_KERNEL);
2760 if (!info)
2761 return -ENOMEM;
2762
96518518
PM
2763 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
2764 err = -EINVAL;
2765 if (nla_type(tmp) != NFTA_LIST_ELEM)
2766 goto err1;
2767 if (n == NFT_RULE_MAXEXPRS)
2768 goto err1;
0ca743a5 2769 err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
96518518
PM
2770 if (err < 0)
2771 goto err1;
2772 size += info[n].ops->size;
2773 n++;
2774 }
2775 }
9889840f
PM
2776 /* Check for overflow of dlen field */
2777 err = -EFBIG;
2778 if (size >= 1 << 12)
2779 goto err1;
96518518 2780
86f1ec32 2781 if (nla[NFTA_RULE_USERDATA]) {
0768b3b3 2782 ulen = nla_len(nla[NFTA_RULE_USERDATA]);
86f1ec32
PM
2783 if (ulen > 0)
2784 usize = sizeof(struct nft_userdata) + ulen;
2785 }
0768b3b3 2786
96518518 2787 err = -ENOMEM;
86f1ec32 2788 rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
96518518
PM
2789 if (rule == NULL)
2790 goto err1;
2791
889f7ee7 2792 nft_activate_next(net, rule);
0628b123 2793
96518518
PM
2794 rule->handle = handle;
2795 rule->dlen = size;
86f1ec32 2796 rule->udata = ulen ? 1 : 0;
0768b3b3 2797
86f1ec32
PM
2798 if (ulen) {
2799 udata = nft_userdata(rule);
2800 udata->len = ulen - 1;
2801 nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
2802 }
96518518 2803
96518518
PM
2804 expr = nft_expr_first(rule);
2805 for (i = 0; i < n; i++) {
2806 err = nf_tables_newexpr(&ctx, &info[i], expr);
2807 if (err < 0)
2808 goto err2;
a654de8f
PNA
2809
2810 if (info[i].ops->validate)
2811 nft_validate_state_update(net, NFT_VALIDATE_NEED);
2812
ef1f7df9 2813 info[i].ops = NULL;
96518518
PM
2814 expr = nft_expr_next(expr);
2815 }
2816
96518518 2817 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
ca089878 2818 trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
569ccae6
FW
2819 if (trans == NULL) {
2820 err = -ENOMEM;
2821 goto err2;
2822 }
ca089878
TY
2823 err = nft_delrule(&ctx, old_rule);
2824 if (err < 0) {
2825 nft_trans_destroy(trans);
569ccae6
FW
2826 goto err2;
2827 }
2828
2829 list_add_tail_rcu(&rule->list, &old_rule->list);
2830 } else {
c9626a2c
PNA
2831 trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
2832 if (!trans) {
569ccae6
FW
2833 err = -ENOMEM;
2834 goto err2;
2835 }
2836
2837 if (nlh->nlmsg_flags & NLM_F_APPEND) {
2838 if (old_rule)
2839 list_add_rcu(&rule->list, &old_rule->list);
2840 else
2841 list_add_tail_rcu(&rule->list, &chain->rules);
2842 } else {
2843 if (old_rule)
2844 list_add_tail_rcu(&rule->list, &old_rule->list);
2845 else
2846 list_add_rcu(&rule->list, &chain->rules);
2847 }
0628b123 2848 }
2a43ecf9 2849 kvfree(info);
4fefee57 2850 chain->use++;
96518518 2851
a654de8f
PNA
2852 if (net->nft.validate_state == NFT_VALIDATE_DO)
2853 return nft_table_validate(net, table);
2854
c9626a2c
PNA
2855 if (chain->flags & NFT_CHAIN_HW_OFFLOAD) {
2856 flow = nft_flow_rule_create(rule);
2857 if (IS_ERR(flow))
2858 return PTR_ERR(flow);
2859
2860 nft_trans_flow_rule(trans) = flow;
2861 }
2862
a654de8f 2863 return 0;
96518518 2864err2:
bb7b40ae 2865 nf_tables_rule_release(&ctx, rule);
96518518
PM
2866err1:
2867 for (i = 0; i < n; i++) {
b25a31bf 2868 if (info[i].ops) {
ef1f7df9 2869 module_put(info[i].ops->type->owner);
b25a31bf
TY
2870 if (info[i].ops->type->release_ops)
2871 info[i].ops->type->release_ops(info[i].ops);
2872 }
96518518 2873 }
2a43ecf9 2874 kvfree(info);
96518518
PM
2875 return err;
2876}
2877
1a94e38d
PNA
2878static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
2879 const struct nlattr *nla)
2880{
2881 u32 id = ntohl(nla_get_be32(nla));
2882 struct nft_trans *trans;
2883
2884 list_for_each_entry(trans, &net->nft.commit_list, list) {
2885 struct nft_rule *rule = nft_trans_rule(trans);
2886
2887 if (trans->msg_type == NFT_MSG_NEWRULE &&
2888 id == nft_trans_rule_id(trans))
2889 return rule;
2890 }
2891 return ERR_PTR(-ENOENT);
2892}
2893
633c9a84
PNA
2894static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2895 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2896 const struct nlattr * const nla[],
2897 struct netlink_ext_ack *extack)
96518518
PM
2898{
2899 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2900 u8 genmask = nft_genmask_next(net);
7c95f6d8 2901 struct nft_table *table;
cf9dc09d
PNA
2902 struct nft_chain *chain = NULL;
2903 struct nft_rule *rule;
0628b123
PNA
2904 int family = nfmsg->nfgen_family, err = 0;
2905 struct nft_ctx ctx;
96518518 2906
cac20fcd 2907 table = nft_table_lookup(net, nla[NFTA_RULE_TABLE], family, genmask);
36dd1bcc
PNA
2908 if (IS_ERR(table)) {
2909 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_TABLE]);
96518518 2910 return PTR_ERR(table);
36dd1bcc 2911 }
96518518 2912
cf9dc09d 2913 if (nla[NFTA_RULE_CHAIN]) {
f102d66b
FW
2914 chain = nft_chain_lookup(net, table, nla[NFTA_RULE_CHAIN],
2915 genmask);
36dd1bcc
PNA
2916 if (IS_ERR(chain)) {
2917 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_CHAIN]);
cf9dc09d 2918 return PTR_ERR(chain);
36dd1bcc 2919 }
cf9dc09d 2920 }
96518518 2921
98319cb9 2922 nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla);
0628b123 2923
cf9dc09d
PNA
2924 if (chain) {
2925 if (nla[NFTA_RULE_HANDLE]) {
cac20fcd 2926 rule = nft_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
36dd1bcc
PNA
2927 if (IS_ERR(rule)) {
2928 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_HANDLE]);
cf9dc09d 2929 return PTR_ERR(rule);
36dd1bcc 2930 }
96518518 2931
1a94e38d
PNA
2932 err = nft_delrule(&ctx, rule);
2933 } else if (nla[NFTA_RULE_ID]) {
2934 rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
36dd1bcc
PNA
2935 if (IS_ERR(rule)) {
2936 NL_SET_BAD_ATTR(extack, nla[NFTA_RULE_ID]);
1a94e38d 2937 return PTR_ERR(rule);
36dd1bcc 2938 }
1a94e38d 2939
5e266fe7 2940 err = nft_delrule(&ctx, rule);
cf9dc09d 2941 } else {
ce24b721 2942 err = nft_delrule_by_chain(&ctx);
cf9dc09d
PNA
2943 }
2944 } else {
2945 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
2946 if (!nft_is_active_next(net, chain))
2947 continue;
2948
cf9dc09d 2949 ctx.chain = chain;
ce24b721 2950 err = nft_delrule_by_chain(&ctx);
0628b123
PNA
2951 if (err < 0)
2952 break;
2953 }
2954 }
2955
2956 return err;
2957}
2958
20a69341
PM
2959/*
2960 * Sets
2961 */
2962
2b664957 2963static LIST_HEAD(nf_tables_set_types);
20a69341 2964
2b664957 2965int nft_register_set(struct nft_set_type *type)
20a69341
PM
2966{
2967 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2b664957 2968 list_add_tail_rcu(&type->list, &nf_tables_set_types);
20a69341
PM
2969 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2970 return 0;
2971}
2972EXPORT_SYMBOL_GPL(nft_register_set);
2973
2b664957 2974void nft_unregister_set(struct nft_set_type *type)
20a69341
PM
2975{
2976 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2b664957 2977 list_del_rcu(&type->list);
20a69341
PM
2978 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2979}
2980EXPORT_SYMBOL_GPL(nft_unregister_set);
2981
2b664957 2982#define NFT_SET_FEATURES (NFT_SET_INTERVAL | NFT_SET_MAP | \
71cc0873
PS
2983 NFT_SET_TIMEOUT | NFT_SET_OBJECT | \
2984 NFT_SET_EVAL)
2b664957 2985
71cc0873 2986static bool nft_set_ops_candidate(const struct nft_set_type *type, u32 flags)
2b664957 2987{
71cc0873 2988 return (flags & type->features) == (flags & NFT_SET_FEATURES);
2b664957
PNA
2989}
2990
c50b960c
PM
2991/*
2992 * Select a set implementation based on the data characteristics and the
2993 * given policy. The total memory use might not be known if no size is
2994 * given, in that case the amount of memory per element is used.
2995 */
2996static const struct nft_set_ops *
2b664957
PNA
2997nft_select_set_ops(const struct nft_ctx *ctx,
2998 const struct nlattr * const nla[],
c50b960c
PM
2999 const struct nft_set_desc *desc,
3000 enum nft_set_policies policy)
20a69341 3001{
c50b960c
PM
3002 const struct nft_set_ops *ops, *bops;
3003 struct nft_set_estimate est, best;
2b664957
PNA
3004 const struct nft_set_type *type;
3005 u32 flags = 0;
20a69341 3006
f102d66b
FW
3007 lockdep_assert_held(&ctx->net->nft.commit_mutex);
3008 lockdep_nfnl_nft_mutex_not_held();
20a69341 3009#ifdef CONFIG_MODULES
2b664957 3010 if (list_empty(&nf_tables_set_types)) {
452238e8 3011 nft_request_module(ctx->net, "nft-set");
2b664957 3012 if (!list_empty(&nf_tables_set_types))
20a69341
PM
3013 return ERR_PTR(-EAGAIN);
3014 }
3015#endif
2b664957
PNA
3016 if (nla[NFTA_SET_FLAGS] != NULL)
3017 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
20a69341 3018
55af753c
PNA
3019 bops = NULL;
3020 best.size = ~0;
3021 best.lookup = ~0;
0b5a7874 3022 best.space = ~0;
c50b960c 3023
2b664957 3024 list_for_each_entry(type, &nf_tables_set_types, list) {
71cc0873 3025 ops = &type->ops;
2b664957 3026
71cc0873 3027 if (!nft_set_ops_candidate(type, flags))
20a69341 3028 continue;
2b664957 3029 if (!ops->estimate(desc, flags, &est))
c50b960c
PM
3030 continue;
3031
3032 switch (policy) {
3033 case NFT_SET_POL_PERFORMANCE:
55af753c 3034 if (est.lookup < best.lookup)
c50b960c 3035 break;
644e334e
PNA
3036 if (est.lookup == best.lookup &&
3037 est.space < best.space)
3038 break;
c50b960c
PM
3039 continue;
3040 case NFT_SET_POL_MEMORY:
0b5a7874
PNA
3041 if (!desc->size) {
3042 if (est.space < best.space)
3043 break;
3044 if (est.space == best.space &&
3045 est.lookup < best.lookup)
3046 break;
4f2921ca 3047 } else if (est.size < best.size || !bops) {
c50b960c 3048 break;
0b5a7874 3049 }
c50b960c
PM
3050 continue;
3051 default:
3052 break;
3053 }
3054
2b664957 3055 if (!try_module_get(type->owner))
20a69341 3056 continue;
c50b960c 3057 if (bops != NULL)
71cc0873 3058 module_put(to_set_type(bops)->owner);
c50b960c
PM
3059
3060 bops = ops;
3061 best = est;
20a69341
PM
3062 }
3063
c50b960c
PM
3064 if (bops != NULL)
3065 return bops;
3066
20a69341
PM
3067 return ERR_PTR(-EOPNOTSUPP);
3068}
3069
3070static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
b2fbd044
LZ
3071 [NFTA_SET_TABLE] = { .type = NLA_STRING,
3072 .len = NFT_TABLE_MAXNAMELEN - 1 },
a9bdd836 3073 [NFTA_SET_NAME] = { .type = NLA_STRING,
cb39ad8b 3074 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341
PM
3075 [NFTA_SET_FLAGS] = { .type = NLA_U32 },
3076 [NFTA_SET_KEY_TYPE] = { .type = NLA_U32 },
3077 [NFTA_SET_KEY_LEN] = { .type = NLA_U32 },
3078 [NFTA_SET_DATA_TYPE] = { .type = NLA_U32 },
3079 [NFTA_SET_DATA_LEN] = { .type = NLA_U32 },
c50b960c
PM
3080 [NFTA_SET_POLICY] = { .type = NLA_U32 },
3081 [NFTA_SET_DESC] = { .type = NLA_NESTED },
958bee14 3082 [NFTA_SET_ID] = { .type = NLA_U32 },
761da293
PM
3083 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
3084 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
e6d8ecac
CFG
3085 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
3086 .len = NFT_USERDATA_MAXLEN },
8aeff920 3087 [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },
3ecbfd65 3088 [NFTA_SET_HANDLE] = { .type = NLA_U64 },
c50b960c
PM
3089};
3090
3091static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
3092 [NFTA_SET_DESC_SIZE] = { .type = NLA_U32 },
20a69341
PM
3093};
3094
633c9a84 3095static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
3096 const struct sk_buff *skb,
3097 const struct nlmsghdr *nlh,
f2a6d766 3098 const struct nlattr * const nla[],
36dd1bcc 3099 struct netlink_ext_ack *extack,
f2a6d766 3100 u8 genmask)
20a69341
PM
3101{
3102 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
98319cb9 3103 int family = nfmsg->nfgen_family;
7c95f6d8 3104 struct nft_table *table = NULL;
20a69341 3105
20a69341 3106 if (nla[NFTA_SET_TABLE] != NULL) {
cac20fcd
PNA
3107 table = nft_table_lookup(net, nla[NFTA_SET_TABLE], family,
3108 genmask);
36dd1bcc
PNA
3109 if (IS_ERR(table)) {
3110 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_TABLE]);
20a69341 3111 return PTR_ERR(table);
36dd1bcc 3112 }
20a69341
PM
3113 }
3114
98319cb9 3115 nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla);
20a69341
PM
3116 return 0;
3117}
3118
cac20fcd
PNA
3119static struct nft_set *nft_set_lookup(const struct nft_table *table,
3120 const struct nlattr *nla, u8 genmask)
20a69341
PM
3121{
3122 struct nft_set *set;
3123
3124 if (nla == NULL)
3125 return ERR_PTR(-EINVAL);
3126
d9adf22a 3127 list_for_each_entry_rcu(set, &table->sets, list) {
37a9cc52
PNA
3128 if (!nla_strcmp(nla, set->name) &&
3129 nft_active_genmask(set, genmask))
20a69341
PM
3130 return set;
3131 }
3132 return ERR_PTR(-ENOENT);
3133}
3134
cac20fcd
PNA
3135static struct nft_set *nft_set_lookup_byhandle(const struct nft_table *table,
3136 const struct nlattr *nla,
3137 u8 genmask)
3ecbfd65
HS
3138{
3139 struct nft_set *set;
3140
3ecbfd65
HS
3141 list_for_each_entry(set, &table->sets, list) {
3142 if (be64_to_cpu(nla_get_be64(nla)) == set->handle &&
3143 nft_active_genmask(set, genmask))
3144 return set;
3145 }
3146 return ERR_PTR(-ENOENT);
3147}
3148
cac20fcd
PNA
3149static struct nft_set *nft_set_lookup_byid(const struct net *net,
3150 const struct nlattr *nla, u8 genmask)
958bee14
PNA
3151{
3152 struct nft_trans *trans;
3153 u32 id = ntohl(nla_get_be32(nla));
3154
3155 list_for_each_entry(trans, &net->nft.commit_list, list) {
9c7f96fd
AK
3156 if (trans->msg_type == NFT_MSG_NEWSET) {
3157 struct nft_set *set = nft_trans_set(trans);
37a9cc52 3158
9c7f96fd
AK
3159 if (id == nft_trans_set_id(trans) &&
3160 nft_active_genmask(set, genmask))
3161 return set;
3162 }
958bee14
PNA
3163 }
3164 return ERR_PTR(-ENOENT);
3165}
c7a72e3f 3166
10659cba
PNA
3167struct nft_set *nft_set_lookup_global(const struct net *net,
3168 const struct nft_table *table,
3169 const struct nlattr *nla_set_name,
3170 const struct nlattr *nla_set_id,
3171 u8 genmask)
c7a72e3f
PNA
3172{
3173 struct nft_set *set;
3174
cac20fcd 3175 set = nft_set_lookup(table, nla_set_name, genmask);
c7a72e3f
PNA
3176 if (IS_ERR(set)) {
3177 if (!nla_set_id)
3178 return set;
3179
cac20fcd 3180 set = nft_set_lookup_byid(net, nla_set_id, genmask);
c7a72e3f
PNA
3181 }
3182 return set;
3183}
10659cba 3184EXPORT_SYMBOL_GPL(nft_set_lookup_global);
958bee14 3185
20a69341
PM
3186static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
3187 const char *name)
3188{
3189 const struct nft_set *i;
3190 const char *p;
3191 unsigned long *inuse;
60eb1894 3192 unsigned int n = 0, min = 0;
20a69341 3193
38745490 3194 p = strchr(name, '%');
20a69341
PM
3195 if (p != NULL) {
3196 if (p[1] != 'd' || strchr(p + 2, '%'))
3197 return -EINVAL;
3198
3199 inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
3200 if (inuse == NULL)
3201 return -ENOMEM;
60eb1894 3202cont:
20a69341 3203 list_for_each_entry(i, &ctx->table->sets, list) {
14662917
DB
3204 int tmp;
3205
37a9cc52
PNA
3206 if (!nft_is_active_next(ctx->net, set))
3207 continue;
14662917 3208 if (!sscanf(i->name, name, &tmp))
20a69341 3209 continue;
60eb1894 3210 if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
20a69341 3211 continue;
14662917 3212
60eb1894 3213 set_bit(tmp - min, inuse);
20a69341
PM
3214 }
3215
53b70287 3216 n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
60eb1894
PM
3217 if (n >= BITS_PER_BYTE * PAGE_SIZE) {
3218 min += BITS_PER_BYTE * PAGE_SIZE;
3219 memset(inuse, 0, PAGE_SIZE);
3220 goto cont;
3221 }
20a69341
PM
3222 free_page((unsigned long)inuse);
3223 }
3224
38745490
PS
3225 set->name = kasprintf(GFP_KERNEL, name, min + n);
3226 if (!set->name)
3227 return -ENOMEM;
3228
20a69341 3229 list_for_each_entry(i, &ctx->table->sets, list) {
37a9cc52
PNA
3230 if (!nft_is_active_next(ctx->net, i))
3231 continue;
e63aaaa6
AY
3232 if (!strcmp(set->name, i->name)) {
3233 kfree(set->name);
20a69341 3234 return -ENFILE;
e63aaaa6 3235 }
20a69341
PM
3236 }
3237 return 0;
3238}
3239
8e1102d5
FW
3240static int nf_msecs_to_jiffies64(const struct nlattr *nla, u64 *result)
3241{
3242 u64 ms = be64_to_cpu(nla_get_be64(nla));
3243 u64 max = (u64)(~((u64)0));
3244
3245 max = div_u64(max, NSEC_PER_MSEC);
3246 if (ms >= max)
3247 return -ERANGE;
3248
3249 ms *= NSEC_PER_MSEC;
3250 *result = nsecs_to_jiffies64(ms);
3251 return 0;
3252}
3253
d6501de8 3254static __be64 nf_jiffies64_to_msecs(u64 input)
8e1102d5 3255{
3b15d09f 3256 return cpu_to_be64(jiffies64_to_msecs(input));
8e1102d5
FW
3257}
3258
20a69341
PM
3259static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
3260 const struct nft_set *set, u16 event, u16 flags)
3261{
3262 struct nfgenmsg *nfmsg;
3263 struct nlmsghdr *nlh;
c50b960c 3264 struct nlattr *desc;
128ad332
PNA
3265 u32 portid = ctx->portid;
3266 u32 seq = ctx->seq;
20a69341 3267
dedb67c4 3268 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
20a69341
PM
3269 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3270 flags);
3271 if (nlh == NULL)
3272 goto nla_put_failure;
3273
3274 nfmsg = nlmsg_data(nlh);
36596dad 3275 nfmsg->nfgen_family = ctx->family;
20a69341 3276 nfmsg->version = NFNETLINK_V0;
84d7fce6 3277 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
20a69341
PM
3278
3279 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
3280 goto nla_put_failure;
3281 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
3282 goto nla_put_failure;
3ecbfd65
HS
3283 if (nla_put_be64(skb, NFTA_SET_HANDLE, cpu_to_be64(set->handle),
3284 NFTA_SET_PAD))
3285 goto nla_put_failure;
20a69341
PM
3286 if (set->flags != 0)
3287 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
3288 goto nla_put_failure;
3289
3290 if (nla_put_be32(skb, NFTA_SET_KEY_TYPE, htonl(set->ktype)))
3291 goto nla_put_failure;
3292 if (nla_put_be32(skb, NFTA_SET_KEY_LEN, htonl(set->klen)))
3293 goto nla_put_failure;
3294 if (set->flags & NFT_SET_MAP) {
3295 if (nla_put_be32(skb, NFTA_SET_DATA_TYPE, htonl(set->dtype)))
3296 goto nla_put_failure;
3297 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
3298 goto nla_put_failure;
3299 }
8aeff920
PNA
3300 if (set->flags & NFT_SET_OBJECT &&
3301 nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
3302 goto nla_put_failure;
20a69341 3303
761da293 3304 if (set->timeout &&
d3e2a111 3305 nla_put_be64(skb, NFTA_SET_TIMEOUT,
8e1102d5 3306 nf_jiffies64_to_msecs(set->timeout),
b46f6ded 3307 NFTA_SET_PAD))
761da293
PM
3308 goto nla_put_failure;
3309 if (set->gc_int &&
3310 nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
3311 goto nla_put_failure;
3312
9363dc4b
AB
3313 if (set->policy != NFT_SET_POL_PERFORMANCE) {
3314 if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
3315 goto nla_put_failure;
3316 }
3317
e6d8ecac
CFG
3318 if (nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata))
3319 goto nla_put_failure;
3320
ae0be8de 3321 desc = nla_nest_start_noflag(skb, NFTA_SET_DESC);
c50b960c
PM
3322 if (desc == NULL)
3323 goto nla_put_failure;
3324 if (set->size &&
3325 nla_put_be32(skb, NFTA_SET_DESC_SIZE, htonl(set->size)))
3326 goto nla_put_failure;
3327 nla_nest_end(skb, desc);
3328
053c095a
JB
3329 nlmsg_end(skb, nlh);
3330 return 0;
20a69341
PM
3331
3332nla_put_failure:
3333 nlmsg_trim(skb, nlh);
3334 return -1;
3335}
3336
25e94a99
PNA
3337static void nf_tables_set_notify(const struct nft_ctx *ctx,
3338 const struct nft_set *set, int event,
3339 gfp_t gfp_flags)
20a69341
PM
3340{
3341 struct sk_buff *skb;
128ad332 3342 u32 portid = ctx->portid;
20a69341
PM
3343 int err;
3344
128ad332
PNA
3345 if (!ctx->report &&
3346 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 3347 return;
20a69341 3348
31f8441c 3349 skb = nlmsg_new(NLMSG_GOODSIZE, gfp_flags);
20a69341
PM
3350 if (skb == NULL)
3351 goto err;
3352
3353 err = nf_tables_fill_set(skb, ctx, set, event, 0);
3354 if (err < 0) {
3355 kfree_skb(skb);
3356 goto err;
3357 }
3358
25e94a99
PNA
3359 nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, ctx->report,
3360 gfp_flags);
3361 return;
20a69341 3362err:
25e94a99 3363 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
20a69341
PM
3364}
3365
5b96af77 3366static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
c9c8e485
PNA
3367{
3368 const struct nft_set *set;
3369 unsigned int idx, s_idx = cb->args[0];
c9c8e485
PNA
3370 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
3371 struct net *net = sock_net(skb->sk);
5b96af77 3372 struct nft_ctx *ctx = cb->data, ctx_set;
c9c8e485
PNA
3373
3374 if (cb->args[1])
3375 return skb->len;
3376
e688a7f8 3377 rcu_read_lock();
38e029f1
PNA
3378 cb->seq = net->nft.base_seq;
3379
36596dad
PNA
3380 list_for_each_entry_rcu(table, &net->nft.tables, list) {
3381 if (ctx->family != NFPROTO_UNSPEC &&
98319cb9 3382 ctx->family != table->family)
36596dad
PNA
3383 continue;
3384
3385 if (ctx->table && ctx->table != table)
5b96af77
PNA
3386 continue;
3387
36596dad
PNA
3388 if (cur_table) {
3389 if (cur_table != table)
c9c8e485
PNA
3390 continue;
3391
36596dad 3392 cur_table = NULL;
c9c8e485 3393 }
36596dad
PNA
3394 idx = 0;
3395 list_for_each_entry_rcu(set, &table->sets, list) {
3396 if (idx < s_idx)
3397 goto cont;
3398 if (!nft_is_active(net, set))
3399 goto cont;
5b96af77 3400
36596dad
PNA
3401 ctx_set = *ctx;
3402 ctx_set.table = table;
98319cb9 3403 ctx_set.family = table->family;
c9c8e485 3404
36596dad
PNA
3405 if (nf_tables_fill_set(skb, &ctx_set, set,
3406 NFT_MSG_NEWSET,
3407 NLM_F_MULTI) < 0) {
3408 cb->args[0] = idx;
3409 cb->args[2] = (unsigned long) table;
3410 goto done;
c9c8e485 3411 }
36596dad 3412 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
c9c8e485 3413cont:
36596dad 3414 idx++;
c9c8e485 3415 }
36596dad
PNA
3416 if (s_idx)
3417 s_idx = 0;
c9c8e485
PNA
3418 }
3419 cb->args[1] = 1;
3420done:
e688a7f8 3421 rcu_read_unlock();
c9c8e485
PNA
3422 return skb->len;
3423}
3424
90fd131a
FW
3425static int nf_tables_dump_sets_start(struct netlink_callback *cb)
3426{
3427 struct nft_ctx *ctx_dump = NULL;
3428
3429 ctx_dump = kmemdup(cb->data, sizeof(*ctx_dump), GFP_ATOMIC);
3430 if (ctx_dump == NULL)
3431 return -ENOMEM;
3432
3433 cb->data = ctx_dump;
3434 return 0;
3435}
3436
5b96af77 3437static int nf_tables_dump_sets_done(struct netlink_callback *cb)
20a69341 3438{
5b96af77
PNA
3439 kfree(cb->data);
3440 return 0;
20a69341
PM
3441}
3442
d9adf22a 3443/* called with rcu_read_lock held */
7b8002a1
PNA
3444static int nf_tables_getset(struct net *net, struct sock *nlsk,
3445 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3446 const struct nlattr * const nla[],
3447 struct netlink_ext_ack *extack)
20a69341 3448{
f2a6d766 3449 u8 genmask = nft_genmask_cur(net);
20a69341
PM
3450 const struct nft_set *set;
3451 struct nft_ctx ctx;
3452 struct sk_buff *skb2;
c9c8e485 3453 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
20a69341
PM
3454 int err;
3455
01cfa0a4 3456 /* Verify existence before starting dump */
36dd1bcc
PNA
3457 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, extack,
3458 genmask);
20a69341
PM
3459 if (err < 0)
3460 return err;
3461
3462 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3463 struct netlink_dump_control c = {
90fd131a 3464 .start = nf_tables_dump_sets_start,
20a69341 3465 .dump = nf_tables_dump_sets,
5b96af77 3466 .done = nf_tables_dump_sets_done,
90fd131a 3467 .data = &ctx,
d9adf22a 3468 .module = THIS_MODULE,
20a69341 3469 };
5b96af77 3470
d9adf22a 3471 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
20a69341
PM
3472 }
3473
c9c8e485
PNA
3474 /* Only accept unspec with dump */
3475 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
3476 return -EAFNOSUPPORT;
eaa2bcd6
PT
3477 if (!nla[NFTA_SET_TABLE])
3478 return -EINVAL;
c9c8e485 3479
cac20fcd 3480 set = nft_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
3481 if (IS_ERR(set))
3482 return PTR_ERR(set);
3483
d9adf22a 3484 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
20a69341
PM
3485 if (skb2 == NULL)
3486 return -ENOMEM;
3487
3488 err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
3489 if (err < 0)
3490 goto err;
3491
3492 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
3493
3494err:
3495 kfree_skb(skb2);
3496 return err;
3497}
3498
f7e840ee 3499static int nf_tables_set_desc_parse(struct nft_set_desc *desc,
c50b960c
PM
3500 const struct nlattr *nla)
3501{
3502 struct nlattr *da[NFTA_SET_DESC_MAX + 1];
3503 int err;
3504
8cb08174
JB
3505 err = nla_parse_nested_deprecated(da, NFTA_SET_DESC_MAX, nla,
3506 nft_set_desc_policy, NULL);
c50b960c
PM
3507 if (err < 0)
3508 return err;
3509
3510 if (da[NFTA_SET_DESC_SIZE] != NULL)
3511 desc->size = ntohl(nla_get_be32(da[NFTA_SET_DESC_SIZE]));
3512
3513 return 0;
3514}
3515
633c9a84
PNA
3516static int nf_tables_newset(struct net *net, struct sock *nlsk,
3517 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3518 const struct nlattr * const nla[],
3519 struct netlink_ext_ack *extack)
20a69341
PM
3520{
3521 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3522 u8 genmask = nft_genmask_next(net);
98319cb9 3523 int family = nfmsg->nfgen_family;
20a69341 3524 const struct nft_set_ops *ops;
20a69341
PM
3525 struct nft_table *table;
3526 struct nft_set *set;
3527 struct nft_ctx ctx;
38745490 3528 char *name;
4ef360dd 3529 u64 size;
761da293 3530 u64 timeout;
8aeff920 3531 u32 ktype, dtype, flags, policy, gc_int, objtype;
c50b960c 3532 struct nft_set_desc desc;
e6d8ecac
CFG
3533 unsigned char *udata;
3534 u16 udlen;
20a69341
PM
3535 int err;
3536
3537 if (nla[NFTA_SET_TABLE] == NULL ||
3538 nla[NFTA_SET_NAME] == NULL ||
958bee14
PNA
3539 nla[NFTA_SET_KEY_LEN] == NULL ||
3540 nla[NFTA_SET_ID] == NULL)
20a69341
PM
3541 return -EINVAL;
3542
c50b960c
PM
3543 memset(&desc, 0, sizeof(desc));
3544
20a69341
PM
3545 ktype = NFT_DATA_VALUE;
3546 if (nla[NFTA_SET_KEY_TYPE] != NULL) {
3547 ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
3548 if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
3549 return -EINVAL;
3550 }
3551
c50b960c 3552 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
7d740264 3553 if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
3554 return -EINVAL;
3555
3556 flags = 0;
3557 if (nla[NFTA_SET_FLAGS] != NULL) {
3558 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
3559 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
7c6c6e95 3560 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
8aeff920
PNA
3561 NFT_SET_MAP | NFT_SET_EVAL |
3562 NFT_SET_OBJECT))
20a69341 3563 return -EINVAL;
8aeff920
PNA
3564 /* Only one of these operations is supported */
3565 if ((flags & (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT)) ==
3566 (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT))
7c6c6e95 3567 return -EOPNOTSUPP;
20a69341
PM
3568 }
3569
3570 dtype = 0;
20a69341
PM
3571 if (nla[NFTA_SET_DATA_TYPE] != NULL) {
3572 if (!(flags & NFT_SET_MAP))
3573 return -EINVAL;
3574
3575 dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
3576 if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
3577 dtype != NFT_DATA_VERDICT)
3578 return -EINVAL;
3579
3580 if (dtype != NFT_DATA_VERDICT) {
3581 if (nla[NFTA_SET_DATA_LEN] == NULL)
3582 return -EINVAL;
c50b960c 3583 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
7d740264 3584 if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
3585 return -EINVAL;
3586 } else
7d740264 3587 desc.dlen = sizeof(struct nft_verdict);
20a69341
PM
3588 } else if (flags & NFT_SET_MAP)
3589 return -EINVAL;
3590
8aeff920
PNA
3591 if (nla[NFTA_SET_OBJ_TYPE] != NULL) {
3592 if (!(flags & NFT_SET_OBJECT))
3593 return -EINVAL;
3594
3595 objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
3596 if (objtype == NFT_OBJECT_UNSPEC ||
3597 objtype > NFT_OBJECT_MAX)
3598 return -EINVAL;
3599 } else if (flags & NFT_SET_OBJECT)
3600 return -EINVAL;
3601 else
3602 objtype = NFT_OBJECT_UNSPEC;
3603
761da293
PM
3604 timeout = 0;
3605 if (nla[NFTA_SET_TIMEOUT] != NULL) {
3606 if (!(flags & NFT_SET_TIMEOUT))
3607 return -EINVAL;
8e1102d5
FW
3608
3609 err = nf_msecs_to_jiffies64(nla[NFTA_SET_TIMEOUT], &timeout);
3610 if (err)
3611 return err;
761da293
PM
3612 }
3613 gc_int = 0;
3614 if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
3615 if (!(flags & NFT_SET_TIMEOUT))
3616 return -EINVAL;
3617 gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
3618 }
3619
c50b960c
PM
3620 policy = NFT_SET_POL_PERFORMANCE;
3621 if (nla[NFTA_SET_POLICY] != NULL)
3622 policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
3623
3624 if (nla[NFTA_SET_DESC] != NULL) {
f7e840ee 3625 err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
c50b960c
PM
3626 if (err < 0)
3627 return err;
3628 }
3629
cac20fcd 3630 table = nft_table_lookup(net, nla[NFTA_SET_TABLE], family, genmask);
36dd1bcc
PNA
3631 if (IS_ERR(table)) {
3632 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_TABLE]);
20a69341 3633 return PTR_ERR(table);
36dd1bcc 3634 }
20a69341 3635
98319cb9 3636 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
20a69341 3637
cac20fcd 3638 set = nft_set_lookup(table, nla[NFTA_SET_NAME], genmask);
20a69341 3639 if (IS_ERR(set)) {
36dd1bcc
PNA
3640 if (PTR_ERR(set) != -ENOENT) {
3641 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
20a69341 3642 return PTR_ERR(set);
36dd1bcc 3643 }
1a28ad74 3644 } else {
36dd1bcc
PNA
3645 if (nlh->nlmsg_flags & NLM_F_EXCL) {
3646 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_NAME]);
20a69341 3647 return -EEXIST;
36dd1bcc 3648 }
20a69341
PM
3649 if (nlh->nlmsg_flags & NLM_F_REPLACE)
3650 return -EOPNOTSUPP;
36dd1bcc 3651
20a69341
PM
3652 return 0;
3653 }
3654
3655 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
3656 return -ENOENT;
3657
2b664957 3658 ops = nft_select_set_ops(&ctx, nla, &desc, policy);
20a69341
PM
3659 if (IS_ERR(ops))
3660 return PTR_ERR(ops);
3661
e6d8ecac
CFG
3662 udlen = 0;
3663 if (nla[NFTA_SET_USERDATA])
3664 udlen = nla_len(nla[NFTA_SET_USERDATA]);
3665
20a69341
PM
3666 size = 0;
3667 if (ops->privsize != NULL)
347b408d 3668 size = ops->privsize(nla, &desc);
20a69341 3669
1ff75a3e
PNA
3670 set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
3671 if (!set) {
3672 err = -ENOMEM;
20a69341 3673 goto err1;
1ff75a3e 3674 }
20a69341 3675
38745490
PS
3676 name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
3677 if (!name) {
3678 err = -ENOMEM;
3679 goto err2;
3680 }
3681
20a69341 3682 err = nf_tables_set_alloc_name(&ctx, set, name);
38745490 3683 kfree(name);
20a69341
PM
3684 if (err < 0)
3685 goto err2;
3686
e6d8ecac
CFG
3687 udata = NULL;
3688 if (udlen) {
3689 udata = set->data + size;
3690 nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
3691 }
3692
20a69341 3693 INIT_LIST_HEAD(&set->bindings);
3453c927
PNA
3694 set->table = table;
3695 write_pnet(&set->net, net);
20a69341
PM
3696 set->ops = ops;
3697 set->ktype = ktype;
c50b960c 3698 set->klen = desc.klen;
20a69341 3699 set->dtype = dtype;
8aeff920 3700 set->objtype = objtype;
c50b960c 3701 set->dlen = desc.dlen;
20a69341 3702 set->flags = flags;
c50b960c 3703 set->size = desc.size;
9363dc4b 3704 set->policy = policy;
e6d8ecac
CFG
3705 set->udlen = udlen;
3706 set->udata = udata;
761da293
PM
3707 set->timeout = timeout;
3708 set->gc_int = gc_int;
3ecbfd65 3709 set->handle = nf_tables_alloc_handle(table);
20a69341 3710
c50b960c 3711 err = ops->init(set, &desc, nla);
20a69341 3712 if (err < 0)
2f6adf48 3713 goto err3;
20a69341 3714
958bee14 3715 err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
20a69341 3716 if (err < 0)
2f6adf48 3717 goto err4;
20a69341 3718
e688a7f8 3719 list_add_tail_rcu(&set->list, &table->sets);
4fefee57 3720 table->use++;
20a69341
PM
3721 return 0;
3722
2f6adf48 3723err4:
c17c3cdf 3724 ops->destroy(set);
2f6adf48
FW
3725err3:
3726 kfree(set->name);
20a69341 3727err2:
1ff75a3e 3728 kvfree(set);
20a69341 3729err1:
71cc0873 3730 module_put(to_set_type(ops)->owner);
20a69341
PM
3731 return err;
3732}
3733
958bee14 3734static void nft_set_destroy(struct nft_set *set)
20a69341 3735{
273fe3f1
PNA
3736 if (WARN_ON(set->use > 0))
3737 return;
3738
20a69341 3739 set->ops->destroy(set);
71cc0873 3740 module_put(to_set_type(set->ops)->owner);
38745490 3741 kfree(set->name);
1ff75a3e 3742 kvfree(set);
20a69341
PM
3743}
3744
633c9a84
PNA
3745static int nf_tables_delset(struct net *net, struct sock *nlsk,
3746 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3747 const struct nlattr * const nla[],
3748 struct netlink_ext_ack *extack)
20a69341 3749{
c9c8e485 3750 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3751 u8 genmask = nft_genmask_next(net);
36dd1bcc 3752 const struct nlattr *attr;
20a69341
PM
3753 struct nft_set *set;
3754 struct nft_ctx ctx;
3755 int err;
3756
ec2c9935
PM
3757 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
3758 return -EAFNOSUPPORT;
20a69341
PM
3759 if (nla[NFTA_SET_TABLE] == NULL)
3760 return -EINVAL;
3761
36dd1bcc
PNA
3762 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, extack,
3763 genmask);
20a69341
PM
3764 if (err < 0)
3765 return err;
3766
36dd1bcc
PNA
3767 if (nla[NFTA_SET_HANDLE]) {
3768 attr = nla[NFTA_SET_HANDLE];
3769 set = nft_set_lookup_byhandle(ctx.table, attr, genmask);
3770 } else {
3771 attr = nla[NFTA_SET_NAME];
3772 set = nft_set_lookup(ctx.table, attr, genmask);
3773 }
a8278400 3774
36dd1bcc
PNA
3775 if (IS_ERR(set)) {
3776 NL_SET_BAD_ATTR(extack, attr);
3777 return PTR_ERR(set);
3778 }
273fe3f1 3779 if (set->use ||
36dd1bcc
PNA
3780 (nlh->nlmsg_flags & NLM_F_NONREC && atomic_read(&set->nelems) > 0)) {
3781 NL_SET_BAD_ATTR(extack, attr);
20a69341 3782 return -EBUSY;
36dd1bcc 3783 }
20a69341 3784
ee01d542 3785 return nft_delset(&ctx, set);
20a69341
PM
3786}
3787
3788static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
de70185d 3789 struct nft_set *set,
20a69341 3790 const struct nft_set_iter *iter,
de70185d 3791 struct nft_set_elem *elem)
20a69341 3792{
fe2811eb 3793 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3794 enum nft_registers dreg;
3795
3796 dreg = nft_type_to_reg(set->dtype);
1ec10212
PM
3797 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
3798 set->dtype == NFT_DATA_VERDICT ?
3799 NFT_DATA_VERDICT : NFT_DATA_VALUE,
3800 set->dlen);
20a69341
PM
3801}
3802
3803int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
3804 struct nft_set_binding *binding)
3805{
3806 struct nft_set_binding *i;
3807 struct nft_set_iter iter;
3808
273fe3f1
PNA
3809 if (set->use == UINT_MAX)
3810 return -EOVERFLOW;
3811
408070d6 3812 if (!list_empty(&set->bindings) && nft_set_is_anonymous(set))
20a69341
PM
3813 return -EBUSY;
3814
11113e19 3815 if (binding->flags & NFT_SET_MAP) {
20a69341
PM
3816 /* If the set is already bound to the same chain all
3817 * jumps are already validated for that chain.
3818 */
3819 list_for_each_entry(i, &set->bindings, list) {
a4684402 3820 if (i->flags & NFT_SET_MAP &&
11113e19 3821 i->chain == binding->chain)
20a69341
PM
3822 goto bind;
3823 }
3824
8588ac09 3825 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
3826 iter.skip = 0;
3827 iter.count = 0;
3828 iter.err = 0;
3829 iter.fn = nf_tables_bind_check_setelem;
3830
3831 set->ops->walk(ctx, set, &iter);
a02f4248 3832 if (iter.err < 0)
20a69341 3833 return iter.err;
20a69341
PM
3834 }
3835bind:
3836 binding->chain = ctx->chain;
e688a7f8 3837 list_add_tail_rcu(&binding->list, &set->bindings);
f6ac8585 3838 nft_set_trans_bind(ctx, set);
273fe3f1 3839 set->use++;
f6ac8585 3840
20a69341
PM
3841 return 0;
3842}
63aea290 3843EXPORT_SYMBOL_GPL(nf_tables_bind_set);
20a69341 3844
3b0a081d
FW
3845static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
3846 struct nft_set_binding *binding, bool event)
20a69341 3847{
e688a7f8 3848 list_del_rcu(&binding->list);
20a69341 3849
f6ac8585 3850 if (list_empty(&set->bindings) && nft_set_is_anonymous(set)) {
cd5125d8 3851 list_del_rcu(&set->list);
f6ac8585
PNA
3852 if (event)
3853 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET,
3854 GFP_KERNEL);
3855 }
20a69341
PM
3856}
3857
273fe3f1
PNA
3858void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
3859 struct nft_set_binding *binding,
3860 enum nft_trans_phase phase)
3861{
3862 switch (phase) {
3863 case NFT_TRANS_PREPARE:
3864 set->use--;
3865 return;
3866 case NFT_TRANS_ABORT:
3867 case NFT_TRANS_RELEASE:
3868 set->use--;
3869 /* fall through */
3870 default:
3871 nf_tables_unbind_set(ctx, set, binding,
3872 phase == NFT_TRANS_COMMIT);
3873 }
3874}
3875EXPORT_SYMBOL_GPL(nf_tables_deactivate_set);
3876
cd5125d8
FW
3877void nf_tables_destroy_set(const struct nft_ctx *ctx, struct nft_set *set)
3878{
f6ac8585 3879 if (list_empty(&set->bindings) && nft_set_is_anonymous(set))
cd5125d8 3880 nft_set_destroy(set);
cd5125d8
FW
3881}
3882EXPORT_SYMBOL_GPL(nf_tables_destroy_set);
3883
3ac4c07a
PM
3884const struct nft_set_ext_type nft_set_ext_types[] = {
3885 [NFT_SET_EXT_KEY] = {
7d740264 3886 .align = __alignof__(u32),
3ac4c07a
PM
3887 },
3888 [NFT_SET_EXT_DATA] = {
7d740264 3889 .align = __alignof__(u32),
3ac4c07a 3890 },
f25ad2e9
PM
3891 [NFT_SET_EXT_EXPR] = {
3892 .align = __alignof__(struct nft_expr),
3893 },
8aeff920
PNA
3894 [NFT_SET_EXT_OBJREF] = {
3895 .len = sizeof(struct nft_object *),
3896 .align = __alignof__(struct nft_object *),
3897 },
3ac4c07a
PM
3898 [NFT_SET_EXT_FLAGS] = {
3899 .len = sizeof(u8),
3900 .align = __alignof__(u8),
3901 },
c3e1b005
PM
3902 [NFT_SET_EXT_TIMEOUT] = {
3903 .len = sizeof(u64),
3904 .align = __alignof__(u64),
3905 },
3906 [NFT_SET_EXT_EXPIRATION] = {
8e1102d5
FW
3907 .len = sizeof(u64),
3908 .align = __alignof__(u64),
c3e1b005 3909 },
68e942e8
PM
3910 [NFT_SET_EXT_USERDATA] = {
3911 .len = sizeof(struct nft_userdata),
3912 .align = __alignof__(struct nft_userdata),
3913 },
3ac4c07a
PM
3914};
3915EXPORT_SYMBOL_GPL(nft_set_ext_types);
3916
20a69341
PM
3917/*
3918 * Set elements
3919 */
3920
3921static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
3922 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
3923 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
3924 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
c3e1b005 3925 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
79ebb5bb 3926 [NFTA_SET_ELEM_EXPIRATION] = { .type = NLA_U64 },
68e942e8
PM
3927 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY,
3928 .len = NFT_USERDATA_MAXLEN },
467697d2
FW
3929 [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED },
3930 [NFTA_SET_ELEM_OBJREF] = { .type = NLA_STRING },
20a69341
PM
3931};
3932
3933static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
b2fbd044
LZ
3934 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING,
3935 .len = NFT_TABLE_MAXNAMELEN - 1 },
3936 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING,
3937 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341 3938 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
958bee14 3939 [NFTA_SET_ELEM_LIST_SET_ID] = { .type = NLA_U32 },
20a69341
PM
3940};
3941
633c9a84 3942static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
3943 const struct sk_buff *skb,
3944 const struct nlmsghdr *nlh,
f2a6d766 3945 const struct nlattr * const nla[],
36dd1bcc 3946 struct netlink_ext_ack *extack,
f2a6d766 3947 u8 genmask)
20a69341
PM
3948{
3949 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
98319cb9 3950 int family = nfmsg->nfgen_family;
7c95f6d8 3951 struct nft_table *table;
20a69341 3952
cac20fcd
PNA
3953 table = nft_table_lookup(net, nla[NFTA_SET_ELEM_LIST_TABLE], family,
3954 genmask);
36dd1bcc
PNA
3955 if (IS_ERR(table)) {
3956 NL_SET_BAD_ATTR(extack, nla[NFTA_SET_ELEM_LIST_TABLE]);
20a69341 3957 return PTR_ERR(table);
36dd1bcc 3958 }
20a69341 3959
98319cb9 3960 nft_ctx_init(ctx, net, skb, nlh, family, table, NULL, nla);
20a69341
PM
3961 return 0;
3962}
3963
3964static int nf_tables_fill_setelem(struct sk_buff *skb,
3965 const struct nft_set *set,
3966 const struct nft_set_elem *elem)
3967{
fe2811eb 3968 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3969 unsigned char *b = skb_tail_pointer(skb);
3970 struct nlattr *nest;
3971
ae0be8de 3972 nest = nla_nest_start_noflag(skb, NFTA_LIST_ELEM);
20a69341
PM
3973 if (nest == NULL)
3974 goto nla_put_failure;
3975
fe2811eb
PM
3976 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, nft_set_ext_key(ext),
3977 NFT_DATA_VALUE, set->klen) < 0)
20a69341
PM
3978 goto nla_put_failure;
3979
fe2811eb
PM
3980 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3981 nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
20a69341
PM
3982 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
3983 set->dlen) < 0)
3984 goto nla_put_failure;
3985
f25ad2e9
PM
3986 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
3987 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
3988 goto nla_put_failure;
3989
8aeff920
PNA
3990 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3991 nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
d152159b 3992 (*nft_set_ext_obj(ext))->key.name) < 0)
8aeff920
PNA
3993 goto nla_put_failure;
3994
fe2811eb
PM
3995 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
3996 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
3997 htonl(*nft_set_ext_flags(ext))))
3998 goto nla_put_failure;
20a69341 3999
c3e1b005
PM
4000 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
4001 nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
8e1102d5 4002 nf_jiffies64_to_msecs(*nft_set_ext_timeout(ext)),
b46f6ded 4003 NFTA_SET_ELEM_PAD))
c3e1b005
PM
4004 goto nla_put_failure;
4005
4006 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
8e1102d5 4007 u64 expires, now = get_jiffies_64();
c3e1b005
PM
4008
4009 expires = *nft_set_ext_expiration(ext);
8e1102d5 4010 if (time_before64(now, expires))
c3e1b005
PM
4011 expires -= now;
4012 else
4013 expires = 0;
4014
4015 if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
8e1102d5 4016 nf_jiffies64_to_msecs(expires),
b46f6ded 4017 NFTA_SET_ELEM_PAD))
c3e1b005
PM
4018 goto nla_put_failure;
4019 }
4020
68e942e8
PM
4021 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
4022 struct nft_userdata *udata;
4023
4024 udata = nft_set_ext_userdata(ext);
4025 if (nla_put(skb, NFTA_SET_ELEM_USERDATA,
4026 udata->len + 1, udata->data))
4027 goto nla_put_failure;
4028 }
4029
20a69341
PM
4030 nla_nest_end(skb, nest);
4031 return 0;
4032
4033nla_put_failure:
4034 nlmsg_trim(skb, b);
4035 return -EMSGSIZE;
4036}
4037
4038struct nft_set_dump_args {
4039 const struct netlink_callback *cb;
4040 struct nft_set_iter iter;
4041 struct sk_buff *skb;
4042};
4043
4044static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
de70185d 4045 struct nft_set *set,
20a69341 4046 const struct nft_set_iter *iter,
de70185d 4047 struct nft_set_elem *elem)
20a69341
PM
4048{
4049 struct nft_set_dump_args *args;
4050
4051 args = container_of(iter, struct nft_set_dump_args, iter);
4052 return nf_tables_fill_setelem(args->skb, set, elem);
4053}
4054
fa803605
LZ
4055struct nft_set_dump_ctx {
4056 const struct nft_set *set;
4057 struct nft_ctx ctx;
4058};
4059
20a69341
PM
4060static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
4061{
fa803605 4062 struct nft_set_dump_ctx *dump_ctx = cb->data;
633c9a84 4063 struct net *net = sock_net(skb->sk);
fa803605 4064 struct nft_table *table;
de70185d 4065 struct nft_set *set;
20a69341 4066 struct nft_set_dump_args args;
fa803605 4067 bool set_found = false;
20a69341
PM
4068 struct nfgenmsg *nfmsg;
4069 struct nlmsghdr *nlh;
4070 struct nlattr *nest;
4071 u32 portid, seq;
fa803605 4072 int event;
20a69341 4073
fa803605 4074 rcu_read_lock();
36596dad
PNA
4075 list_for_each_entry_rcu(table, &net->nft.tables, list) {
4076 if (dump_ctx->ctx.family != NFPROTO_UNSPEC &&
98319cb9 4077 dump_ctx->ctx.family != table->family)
fa803605 4078 continue;
20a69341 4079
36596dad
PNA
4080 if (table != dump_ctx->ctx.table)
4081 continue;
20a69341 4082
36596dad
PNA
4083 list_for_each_entry_rcu(set, &table->sets, list) {
4084 if (set == dump_ctx->set) {
4085 set_found = true;
4086 break;
fa803605 4087 }
fa803605
LZ
4088 }
4089 break;
4090 }
4091
4092 if (!set_found) {
4093 rcu_read_unlock();
4094 return -ENOENT;
4095 }
20a69341 4096
dedb67c4 4097 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSETELEM);
20a69341
PM
4098 portid = NETLINK_CB(cb->skb).portid;
4099 seq = cb->nlh->nlmsg_seq;
4100
4101 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
4102 NLM_F_MULTI);
4103 if (nlh == NULL)
4104 goto nla_put_failure;
4105
4106 nfmsg = nlmsg_data(nlh);
98319cb9 4107 nfmsg->nfgen_family = table->family;
20a69341 4108 nfmsg->version = NFNETLINK_V0;
fa803605 4109 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
20a69341 4110
fa803605 4111 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, table->name))
20a69341
PM
4112 goto nla_put_failure;
4113 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
4114 goto nla_put_failure;
4115
ae0be8de 4116 nest = nla_nest_start_noflag(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
20a69341
PM
4117 if (nest == NULL)
4118 goto nla_put_failure;
4119
8588ac09
PNA
4120 args.cb = cb;
4121 args.skb = skb;
fa803605 4122 args.iter.genmask = nft_genmask_cur(net);
8588ac09
PNA
4123 args.iter.skip = cb->args[0];
4124 args.iter.count = 0;
4125 args.iter.err = 0;
4126 args.iter.fn = nf_tables_dump_setelem;
fa803605
LZ
4127 set->ops->walk(&dump_ctx->ctx, set, &args.iter);
4128 rcu_read_unlock();
20a69341
PM
4129
4130 nla_nest_end(skb, nest);
4131 nlmsg_end(skb, nlh);
4132
4133 if (args.iter.err && args.iter.err != -EMSGSIZE)
4134 return args.iter.err;
4135 if (args.iter.count == cb->args[0])
4136 return 0;
4137
4138 cb->args[0] = args.iter.count;
4139 return skb->len;
4140
4141nla_put_failure:
fa803605 4142 rcu_read_unlock();
20a69341
PM
4143 return -ENOSPC;
4144}
4145
90fd131a
FW
4146static int nf_tables_dump_set_start(struct netlink_callback *cb)
4147{
4148 struct nft_set_dump_ctx *dump_ctx = cb->data;
4149
4150 cb->data = kmemdup(dump_ctx, sizeof(*dump_ctx), GFP_ATOMIC);
4151
4152 return cb->data ? 0 : -ENOMEM;
4153}
4154
fa803605
LZ
4155static int nf_tables_dump_set_done(struct netlink_callback *cb)
4156{
4157 kfree(cb->data);
4158 return 0;
4159}
4160
d60ce62f
AB
4161static int nf_tables_fill_setelem_info(struct sk_buff *skb,
4162 const struct nft_ctx *ctx, u32 seq,
4163 u32 portid, int event, u16 flags,
4164 const struct nft_set *set,
4165 const struct nft_set_elem *elem)
4166{
4167 struct nfgenmsg *nfmsg;
4168 struct nlmsghdr *nlh;
4169 struct nlattr *nest;
4170 int err;
4171
dedb67c4 4172 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
d60ce62f
AB
4173 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
4174 flags);
4175 if (nlh == NULL)
4176 goto nla_put_failure;
4177
4178 nfmsg = nlmsg_data(nlh);
36596dad 4179 nfmsg->nfgen_family = ctx->family;
d60ce62f 4180 nfmsg->version = NFNETLINK_V0;
84d7fce6 4181 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
d60ce62f
AB
4182
4183 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
4184 goto nla_put_failure;
4185 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
4186 goto nla_put_failure;
4187
ae0be8de 4188 nest = nla_nest_start_noflag(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
d60ce62f
AB
4189 if (nest == NULL)
4190 goto nla_put_failure;
4191
4192 err = nf_tables_fill_setelem(skb, set, elem);
4193 if (err < 0)
4194 goto nla_put_failure;
4195
4196 nla_nest_end(skb, nest);
4197
053c095a
JB
4198 nlmsg_end(skb, nlh);
4199 return 0;
d60ce62f
AB
4200
4201nla_put_failure:
4202 nlmsg_trim(skb, nlh);
4203 return -1;
4204}
4205
ba0e4d99
PNA
4206static int nft_setelem_parse_flags(const struct nft_set *set,
4207 const struct nlattr *attr, u32 *flags)
4208{
4209 if (attr == NULL)
4210 return 0;
4211
4212 *flags = ntohl(nla_get_be32(attr));
4213 if (*flags & ~NFT_SET_ELEM_INTERVAL_END)
4214 return -EINVAL;
4215 if (!(set->flags & NFT_SET_INTERVAL) &&
4216 *flags & NFT_SET_ELEM_INTERVAL_END)
4217 return -EINVAL;
4218
4219 return 0;
4220}
4221
4222static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
4223 const struct nlattr *attr)
4224{
4225 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
ba0e4d99
PNA
4226 struct nft_data_desc desc;
4227 struct nft_set_elem elem;
4228 struct sk_buff *skb;
4229 uint32_t flags = 0;
4230 void *priv;
4231 int err;
4232
8cb08174
JB
4233 err = nla_parse_nested_deprecated(nla, NFTA_SET_ELEM_MAX, attr,
4234 nft_set_elem_policy, NULL);
ba0e4d99
PNA
4235 if (err < 0)
4236 return err;
4237
4238 if (!nla[NFTA_SET_ELEM_KEY])
4239 return -EINVAL;
4240
4241 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
4242 if (err < 0)
4243 return err;
4244
4245 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
4246 nla[NFTA_SET_ELEM_KEY]);
4247 if (err < 0)
4248 return err;
4249
4250 err = -EINVAL;
4251 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
4252 return err;
4253
4254 priv = set->ops->get(ctx->net, set, &elem, flags);
4255 if (IS_ERR(priv))
4256 return PTR_ERR(priv);
4257
4258 elem.priv = priv;
ba0e4d99
PNA
4259
4260 err = -ENOMEM;
d9adf22a 4261 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
ba0e4d99
PNA
4262 if (skb == NULL)
4263 goto err1;
4264
4265 err = nf_tables_fill_setelem_info(skb, ctx, ctx->seq, ctx->portid,
4266 NFT_MSG_NEWSETELEM, 0, set, &elem);
4267 if (err < 0)
4268 goto err2;
4269
4270 err = nfnetlink_unicast(skb, ctx->net, ctx->portid, MSG_DONTWAIT);
4271 /* This avoids a loop in nfnetlink. */
4272 if (err < 0)
4273 goto err1;
4274
4275 return 0;
4276err2:
4277 kfree_skb(skb);
4278err1:
4279 /* this avoids a loop in nfnetlink. */
4280 return err == -EAGAIN ? -ENOBUFS : err;
4281}
4282
d9adf22a 4283/* called with rcu_read_lock held */
ba0e4d99
PNA
4284static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
4285 struct sk_buff *skb, const struct nlmsghdr *nlh,
4286 const struct nlattr * const nla[],
4287 struct netlink_ext_ack *extack)
4288{
4289 u8 genmask = nft_genmask_cur(net);
4290 struct nft_set *set;
4291 struct nlattr *attr;
4292 struct nft_ctx ctx;
4293 int rem, err = 0;
4294
36dd1bcc
PNA
4295 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
4296 genmask);
ba0e4d99
PNA
4297 if (err < 0)
4298 return err;
4299
cac20fcd 4300 set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
ba0e4d99
PNA
4301 if (IS_ERR(set))
4302 return PTR_ERR(set);
4303
4304 if (nlh->nlmsg_flags & NLM_F_DUMP) {
4305 struct netlink_dump_control c = {
90fd131a 4306 .start = nf_tables_dump_set_start,
ba0e4d99
PNA
4307 .dump = nf_tables_dump_set,
4308 .done = nf_tables_dump_set_done,
d9adf22a 4309 .module = THIS_MODULE,
ba0e4d99 4310 };
90fd131a
FW
4311 struct nft_set_dump_ctx dump_ctx = {
4312 .set = set,
4313 .ctx = ctx,
4314 };
ba0e4d99 4315
90fd131a 4316 c.data = &dump_ctx;
d9adf22a 4317 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
ba0e4d99
PNA
4318 }
4319
4320 if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
4321 return -EINVAL;
4322
4323 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
4324 err = nft_get_set_elem(&ctx, set, attr);
4325 if (err < 0)
4326 break;
4327 }
4328
4329 return err;
4330}
4331
25e94a99
PNA
4332static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
4333 const struct nft_set *set,
4334 const struct nft_set_elem *elem,
4335 int event, u16 flags)
d60ce62f 4336{
128ad332
PNA
4337 struct net *net = ctx->net;
4338 u32 portid = ctx->portid;
d60ce62f
AB
4339 struct sk_buff *skb;
4340 int err;
4341
128ad332 4342 if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 4343 return;
d60ce62f 4344
d60ce62f
AB
4345 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
4346 if (skb == NULL)
4347 goto err;
4348
4349 err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
4350 set, elem);
4351 if (err < 0) {
4352 kfree_skb(skb);
4353 goto err;
4354 }
4355
25e94a99
PNA
4356 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
4357 GFP_KERNEL);
4358 return;
d60ce62f 4359err:
25e94a99 4360 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
d60ce62f
AB
4361}
4362
60319eb1
PNA
4363static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
4364 int msg_type,
4365 struct nft_set *set)
4366{
4367 struct nft_trans *trans;
4368
4369 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_elem));
4370 if (trans == NULL)
4371 return NULL;
4372
4373 nft_trans_elem_set(trans) = set;
4374 return trans;
4375}
4376
22fe54d5
PM
4377void *nft_set_elem_init(const struct nft_set *set,
4378 const struct nft_set_ext_tmpl *tmpl,
49499c3e 4379 const u32 *key, const u32 *data,
79ebb5bb 4380 u64 timeout, u64 expiration, gfp_t gfp)
fe2811eb
PM
4381{
4382 struct nft_set_ext *ext;
4383 void *elem;
4384
4385 elem = kzalloc(set->ops->elemsize + tmpl->len, gfp);
4386 if (elem == NULL)
4387 return NULL;
4388
4389 ext = nft_set_elem_ext(set, elem);
4390 nft_set_ext_init(ext, tmpl);
4391
4392 memcpy(nft_set_ext_key(ext), key, set->klen);
4393 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4394 memcpy(nft_set_ext_data(ext), data, set->dlen);
79ebb5bb
LGL
4395 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
4396 *nft_set_ext_expiration(ext) = get_jiffies_64() + expiration;
4397 if (expiration == 0)
4398 *nft_set_ext_expiration(ext) += timeout;
4399 }
c3e1b005
PM
4400 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
4401 *nft_set_ext_timeout(ext) = timeout;
fe2811eb
PM
4402
4403 return elem;
4404}
4405
61f9e292
LZ
4406void nft_set_elem_destroy(const struct nft_set *set, void *elem,
4407 bool destroy_expr)
61edafbb
PM
4408{
4409 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3453c927
PNA
4410 struct nft_ctx ctx = {
4411 .net = read_pnet(&set->net),
4412 .family = set->table->family,
4413 };
61edafbb 4414
59105446 4415 nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
61edafbb 4416 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
59105446 4417 nft_data_release(nft_set_ext_data(ext), set->dtype);
371ebcbb
PNA
4418 if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR)) {
4419 struct nft_expr *expr = nft_set_ext_expr(ext);
4420
4421 if (expr->ops->destroy_clone) {
4422 expr->ops->destroy_clone(&ctx, expr);
4423 module_put(expr->ops->type->owner);
4424 } else {
4425 nf_tables_expr_destroy(&ctx, expr);
4426 }
4427 }
8aeff920
PNA
4428 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4429 (*nft_set_ext_obj(ext))->use--;
61edafbb
PM
4430 kfree(elem);
4431}
4432EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
4433
59105446
PNA
4434/* Only called from commit path, nft_set_elem_deactivate() already deals with
4435 * the refcounting from the preparation phase.
4436 */
3453c927
PNA
4437static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
4438 const struct nft_set *set, void *elem)
59105446
PNA
4439{
4440 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
4441
4442 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
3453c927 4443 nf_tables_expr_destroy(ctx, nft_set_ext_expr(ext));
59105446
PNA
4444 kfree(elem);
4445}
4446
60319eb1 4447static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
c016c7e4 4448 const struct nlattr *attr, u32 nlmsg_flags)
20a69341
PM
4449{
4450 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
8aeff920 4451 u8 genmask = nft_genmask_next(ctx->net);
20a69341 4452 struct nft_data_desc d1, d2;
fe2811eb 4453 struct nft_set_ext_tmpl tmpl;
c016c7e4 4454 struct nft_set_ext *ext, *ext2;
20a69341
PM
4455 struct nft_set_elem elem;
4456 struct nft_set_binding *binding;
8aeff920 4457 struct nft_object *obj = NULL;
68e942e8 4458 struct nft_userdata *udata;
fe2811eb 4459 struct nft_data data;
20a69341 4460 enum nft_registers dreg;
60319eb1 4461 struct nft_trans *trans;
0e9091d6 4462 u32 flags = 0;
c3e1b005 4463 u64 timeout;
79ebb5bb 4464 u64 expiration;
68e942e8 4465 u8 ulen;
20a69341
PM
4466 int err;
4467
8cb08174
JB
4468 err = nla_parse_nested_deprecated(nla, NFTA_SET_ELEM_MAX, attr,
4469 nft_set_elem_policy, NULL);
20a69341
PM
4470 if (err < 0)
4471 return err;
4472
4473 if (nla[NFTA_SET_ELEM_KEY] == NULL)
4474 return -EINVAL;
4475
fe2811eb
PM
4476 nft_set_ext_prepare(&tmpl);
4477
0e9091d6
PNA
4478 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
4479 if (err < 0)
4480 return err;
4481 if (flags != 0)
4482 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
20a69341
PM
4483
4484 if (set->flags & NFT_SET_MAP) {
4485 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
fe2811eb 4486 !(flags & NFT_SET_ELEM_INTERVAL_END))
20a69341 4487 return -EINVAL;
bd7fc645 4488 if (nla[NFTA_SET_ELEM_DATA] != NULL &&
fe2811eb 4489 flags & NFT_SET_ELEM_INTERVAL_END)
bd7fc645 4490 return -EINVAL;
20a69341
PM
4491 } else {
4492 if (nla[NFTA_SET_ELEM_DATA] != NULL)
4493 return -EINVAL;
4494 }
4495
c3e1b005
PM
4496 timeout = 0;
4497 if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
4498 if (!(set->flags & NFT_SET_TIMEOUT))
4499 return -EINVAL;
8e1102d5
FW
4500 err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_TIMEOUT],
4501 &timeout);
4502 if (err)
4503 return err;
c3e1b005
PM
4504 } else if (set->flags & NFT_SET_TIMEOUT) {
4505 timeout = set->timeout;
4506 }
4507
79ebb5bb
LGL
4508 expiration = 0;
4509 if (nla[NFTA_SET_ELEM_EXPIRATION] != NULL) {
4510 if (!(set->flags & NFT_SET_TIMEOUT))
4511 return -EINVAL;
4512 err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_EXPIRATION],
4513 &expiration);
4514 if (err)
4515 return err;
4516 }
4517
7d740264 4518 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
d0a11fc3 4519 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
4520 if (err < 0)
4521 goto err1;
4522 err = -EINVAL;
4523 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
4524 goto err2;
4525
7d740264 4526 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
c3e1b005
PM
4527 if (timeout > 0) {
4528 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
4529 if (timeout != set->timeout)
4530 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
4531 }
fe2811eb 4532
8aeff920
PNA
4533 if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
4534 if (!(set->flags & NFT_SET_OBJECT)) {
4535 err = -EINVAL;
4536 goto err2;
4537 }
4d44175a
FW
4538 obj = nft_obj_lookup(ctx->net, ctx->table,
4539 nla[NFTA_SET_ELEM_OBJREF],
cac20fcd 4540 set->objtype, genmask);
8aeff920
PNA
4541 if (IS_ERR(obj)) {
4542 err = PTR_ERR(obj);
4543 goto err2;
4544 }
4545 nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
4546 }
4547
20a69341 4548 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
d0a11fc3
PM
4549 err = nft_data_init(ctx, &data, sizeof(data), &d2,
4550 nla[NFTA_SET_ELEM_DATA]);
20a69341
PM
4551 if (err < 0)
4552 goto err2;
4553
4554 err = -EINVAL;
4555 if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
4556 goto err3;
4557
4558 dreg = nft_type_to_reg(set->dtype);
4559 list_for_each_entry(binding, &set->bindings, list) {
4560 struct nft_ctx bind_ctx = {
58c78e10 4561 .net = ctx->net,
36596dad 4562 .family = ctx->family,
20a69341 4563 .table = ctx->table,
7c95f6d8 4564 .chain = (struct nft_chain *)binding->chain,
20a69341
PM
4565 };
4566
11113e19
PM
4567 if (!(binding->flags & NFT_SET_MAP))
4568 continue;
4569
1ec10212
PM
4570 err = nft_validate_register_store(&bind_ctx, dreg,
4571 &data,
4572 d2.type, d2.len);
20a69341
PM
4573 if (err < 0)
4574 goto err3;
a654de8f
PNA
4575
4576 if (d2.type == NFT_DATA_VERDICT &&
4577 (data.verdict.code == NFT_GOTO ||
4578 data.verdict.code == NFT_JUMP))
4579 nft_validate_state_update(ctx->net,
4580 NFT_VALIDATE_NEED);
20a69341 4581 }
fe2811eb 4582
7d740264 4583 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
20a69341
PM
4584 }
4585
68e942e8
PM
4586 /* The full maximum length of userdata can exceed the maximum
4587 * offset value (U8_MAX) for following extensions, therefor it
4588 * must be the last extension added.
4589 */
4590 ulen = 0;
4591 if (nla[NFTA_SET_ELEM_USERDATA] != NULL) {
4592 ulen = nla_len(nla[NFTA_SET_ELEM_USERDATA]);
4593 if (ulen > 0)
4594 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_USERDATA,
4595 ulen);
4596 }
4597
fe2811eb 4598 err = -ENOMEM;
7d740264 4599 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
79ebb5bb 4600 timeout, expiration, GFP_KERNEL);
fe2811eb
PM
4601 if (elem.priv == NULL)
4602 goto err3;
4603
4604 ext = nft_set_elem_ext(set, elem.priv);
4605 if (flags)
4606 *nft_set_ext_flags(ext) = flags;
68e942e8
PM
4607 if (ulen > 0) {
4608 udata = nft_set_ext_userdata(ext);
4609 udata->len = ulen - 1;
4610 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
4611 }
8aeff920
PNA
4612 if (obj) {
4613 *nft_set_ext_obj(ext) = obj;
4614 obj->use++;
4615 }
fe2811eb 4616
60319eb1
PNA
4617 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
4618 if (trans == NULL)
fe2811eb 4619 goto err4;
60319eb1 4620
69086658 4621 ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
c016c7e4
PNA
4622 err = set->ops->insert(ctx->net, set, &elem, &ext2);
4623 if (err) {
4624 if (err == -EEXIST) {
9744a6fc
PNA
4625 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
4626 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
4627 nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
f0dfd7a2
CIK
4628 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF)) {
4629 err = -EBUSY;
4630 goto err5;
4631 }
8aeff920
PNA
4632 if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
4633 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
4634 memcmp(nft_set_ext_data(ext),
4635 nft_set_ext_data(ext2), set->dlen) != 0) ||
4636 (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
4637 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
4638 *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
c016c7e4
PNA
4639 err = -EBUSY;
4640 else if (!(nlmsg_flags & NLM_F_EXCL))
4641 err = 0;
4642 }
fe2811eb 4643 goto err5;
c016c7e4 4644 }
20a69341 4645
35d0ac90
PNA
4646 if (set->size &&
4647 !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) {
4648 err = -ENFILE;
4649 goto err6;
4650 }
4651
60319eb1 4652 nft_trans_elem(trans) = elem;
46bbafce 4653 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
20a69341
PM
4654 return 0;
4655
35d0ac90 4656err6:
5cb82a38 4657 set->ops->remove(ctx->net, set, &elem);
fe2811eb 4658err5:
60319eb1 4659 kfree(trans);
fe2811eb 4660err4:
b91d9036
TY
4661 if (obj)
4662 obj->use--;
fe2811eb 4663 kfree(elem.priv);
20a69341
PM
4664err3:
4665 if (nla[NFTA_SET_ELEM_DATA] != NULL)
59105446 4666 nft_data_release(&data, d2.type);
20a69341 4667err2:
59105446 4668 nft_data_release(&elem.key.val, d1.type);
20a69341
PM
4669err1:
4670 return err;
4671}
4672
633c9a84
PNA
4673static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
4674 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4675 const struct nlattr * const nla[],
4676 struct netlink_ext_ack *extack)
20a69341 4677{
f2a6d766 4678 u8 genmask = nft_genmask_next(net);
20a69341
PM
4679 const struct nlattr *attr;
4680 struct nft_set *set;
4681 struct nft_ctx ctx;
a654de8f 4682 int rem, err;
20a69341 4683
7d5570ca
PNA
4684 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
4685 return -EINVAL;
4686
36dd1bcc
PNA
4687 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
4688 genmask);
20a69341
PM
4689 if (err < 0)
4690 return err;
4691
a3073c17
PNA
4692 set = nft_set_lookup_global(net, ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
4693 nla[NFTA_SET_ELEM_LIST_SET_ID], genmask);
4694 if (IS_ERR(set))
4695 return PTR_ERR(set);
958bee14 4696
20a69341
PM
4697 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4698 return -EBUSY;
4699
4700 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
c016c7e4 4701 err = nft_add_set_elem(&ctx, set, attr, nlh->nlmsg_flags);
35d0ac90 4702 if (err < 0)
a654de8f 4703 return err;
20a69341 4704 }
a654de8f
PNA
4705
4706 if (net->nft.validate_state == NFT_VALIDATE_DO)
4707 return nft_table_validate(net, ctx.table);
4708
4709 return 0;
20a69341
PM
4710}
4711
59105446
PNA
4712/**
4713 * nft_data_hold - hold a nft_data item
4714 *
4715 * @data: struct nft_data to release
4716 * @type: type of data
4717 *
4718 * Hold a nft_data item. NFT_DATA_VALUE types can be silently discarded,
4719 * NFT_DATA_VERDICT bumps the reference to chains in case of NFT_JUMP and
4720 * NFT_GOTO verdicts. This function must be called on active data objects
4721 * from the second phase of the commit protocol.
4722 */
bb7b40ae 4723void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
59105446
PNA
4724{
4725 if (type == NFT_DATA_VERDICT) {
4726 switch (data->verdict.code) {
4727 case NFT_JUMP:
4728 case NFT_GOTO:
4729 data->verdict.chain->use++;
4730 break;
4731 }
4732 }
4733}
4734
4735static void nft_set_elem_activate(const struct net *net,
4736 const struct nft_set *set,
4737 struct nft_set_elem *elem)
4738{
4739 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4740
4741 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4742 nft_data_hold(nft_set_ext_data(ext), set->dtype);
4743 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4744 (*nft_set_ext_obj(ext))->use++;
4745}
4746
4747static void nft_set_elem_deactivate(const struct net *net,
4748 const struct nft_set *set,
4749 struct nft_set_elem *elem)
4750{
4751 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4752
4753 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4754 nft_data_release(nft_set_ext_data(ext), set->dtype);
4755 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4756 (*nft_set_ext_obj(ext))->use--;
4757}
4758
60319eb1 4759static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
20a69341
PM
4760 const struct nlattr *attr)
4761{
4762 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3971ca14 4763 struct nft_set_ext_tmpl tmpl;
20a69341
PM
4764 struct nft_data_desc desc;
4765 struct nft_set_elem elem;
3971ca14 4766 struct nft_set_ext *ext;
60319eb1 4767 struct nft_trans *trans;
3971ca14
PNA
4768 u32 flags = 0;
4769 void *priv;
20a69341
PM
4770 int err;
4771
8cb08174
JB
4772 err = nla_parse_nested_deprecated(nla, NFTA_SET_ELEM_MAX, attr,
4773 nft_set_elem_policy, NULL);
20a69341
PM
4774 if (err < 0)
4775 goto err1;
4776
4777 err = -EINVAL;
4778 if (nla[NFTA_SET_ELEM_KEY] == NULL)
4779 goto err1;
4780
3971ca14
PNA
4781 nft_set_ext_prepare(&tmpl);
4782
4783 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
4784 if (err < 0)
4785 return err;
4786 if (flags != 0)
4787 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
4788
7d740264 4789 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
d0a11fc3 4790 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
4791 if (err < 0)
4792 goto err1;
4793
4794 err = -EINVAL;
4795 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
4796 goto err2;
4797
3971ca14
PNA
4798 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
4799
4800 err = -ENOMEM;
4801 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
79ebb5bb 4802 0, GFP_KERNEL);
3971ca14
PNA
4803 if (elem.priv == NULL)
4804 goto err2;
4805
4806 ext = nft_set_elem_ext(set, elem.priv);
4807 if (flags)
4808 *nft_set_ext_flags(ext) = flags;
4809
60319eb1 4810 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
609ccf08
JL
4811 if (trans == NULL) {
4812 err = -ENOMEM;
3971ca14 4813 goto err3;
609ccf08 4814 }
20a69341 4815
42a55769 4816 priv = set->ops->deactivate(ctx->net, set, &elem);
3971ca14 4817 if (priv == NULL) {
cc02e457 4818 err = -ENOENT;
3971ca14 4819 goto err4;
cc02e457 4820 }
3971ca14
PNA
4821 kfree(elem.priv);
4822 elem.priv = priv;
cc02e457 4823
59105446
PNA
4824 nft_set_elem_deactivate(ctx->net, set, &elem);
4825
60319eb1 4826 nft_trans_elem(trans) = elem;
46bbafce 4827 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
0dc13625 4828 return 0;
cc02e457 4829
3971ca14 4830err4:
cc02e457 4831 kfree(trans);
3971ca14
PNA
4832err3:
4833 kfree(elem.priv);
20a69341 4834err2:
59105446 4835 nft_data_release(&elem.key.val, desc.type);
20a69341
PM
4836err1:
4837 return err;
4838}
4839
8411b644 4840static int nft_flush_set(const struct nft_ctx *ctx,
de70185d 4841 struct nft_set *set,
8411b644 4842 const struct nft_set_iter *iter,
de70185d 4843 struct nft_set_elem *elem)
8411b644
PNA
4844{
4845 struct nft_trans *trans;
4846 int err;
4847
4848 trans = nft_trans_alloc_gfp(ctx, NFT_MSG_DELSETELEM,
4849 sizeof(struct nft_trans_elem), GFP_ATOMIC);
4850 if (!trans)
4851 return -ENOMEM;
4852
1ba1c414 4853 if (!set->ops->flush(ctx->net, set, elem->priv)) {
8411b644
PNA
4854 err = -ENOENT;
4855 goto err1;
4856 }
b2c11e4b 4857 set->ndeact++;
8411b644 4858
7acfda53 4859 nft_set_elem_deactivate(ctx->net, set, elem);
de70185d
PNA
4860 nft_trans_elem_set(trans) = set;
4861 nft_trans_elem(trans) = *elem;
8411b644
PNA
4862 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
4863
4864 return 0;
4865err1:
4866 kfree(trans);
4867 return err;
4868}
4869
633c9a84
PNA
4870static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
4871 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4872 const struct nlattr * const nla[],
4873 struct netlink_ext_ack *extack)
20a69341 4874{
f2a6d766 4875 u8 genmask = nft_genmask_next(net);
20a69341
PM
4876 const struct nlattr *attr;
4877 struct nft_set *set;
4878 struct nft_ctx ctx;
60319eb1 4879 int rem, err = 0;
20a69341 4880
36dd1bcc
PNA
4881 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, extack,
4882 genmask);
20a69341
PM
4883 if (err < 0)
4884 return err;
4885
cac20fcd 4886 set = nft_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET], genmask);
20a69341
PM
4887 if (IS_ERR(set))
4888 return PTR_ERR(set);
4889 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4890 return -EBUSY;
4891
8411b644 4892 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
baa2d42c
PNA
4893 struct nft_set_iter iter = {
4894 .genmask = genmask,
4895 .fn = nft_flush_set,
8411b644 4896 };
baa2d42c 4897 set->ops->walk(&ctx, set, &iter);
8411b644 4898
baa2d42c 4899 return iter.err;
8411b644
PNA
4900 }
4901
20a69341
PM
4902 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
4903 err = nft_del_setelem(&ctx, set, attr);
4904 if (err < 0)
60319eb1 4905 break;
4fefee57 4906
3dd0673a 4907 set->ndeact++;
20a69341 4908 }
60319eb1 4909 return err;
20a69341
PM
4910}
4911
cfed7e1b
PM
4912void nft_set_gc_batch_release(struct rcu_head *rcu)
4913{
4914 struct nft_set_gc_batch *gcb;
4915 unsigned int i;
4916
4917 gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
4918 for (i = 0; i < gcb->head.cnt; i++)
61f9e292 4919 nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
cfed7e1b
PM
4920 kfree(gcb);
4921}
4922EXPORT_SYMBOL_GPL(nft_set_gc_batch_release);
4923
4924struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
4925 gfp_t gfp)
4926{
4927 struct nft_set_gc_batch *gcb;
4928
4929 gcb = kzalloc(sizeof(*gcb), gfp);
4930 if (gcb == NULL)
4931 return gcb;
4932 gcb->head.set = set;
4933 return gcb;
4934}
4935EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
4936
e5009240
PNA
4937/*
4938 * Stateful objects
4939 */
4940
4941/**
4942 * nft_register_obj- register nf_tables stateful object type
4943 * @obj: object type
4944 *
4945 * Registers the object type for use with nf_tables. Returns zero on
4946 * success or a negative errno code otherwise.
4947 */
4948int nft_register_obj(struct nft_object_type *obj_type)
4949{
4950 if (obj_type->type == NFT_OBJECT_UNSPEC)
4951 return -EINVAL;
4952
4953 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4954 list_add_rcu(&obj_type->list, &nf_tables_objects);
4955 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4956 return 0;
4957}
4958EXPORT_SYMBOL_GPL(nft_register_obj);
4959
4960/**
4961 * nft_unregister_obj - unregister nf_tables object type
4962 * @obj: object type
4963 *
4964 * Unregisters the object type for use with nf_tables.
4965 */
4966void nft_unregister_obj(struct nft_object_type *obj_type)
4967{
4968 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4969 list_del_rcu(&obj_type->list);
4970 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4971}
4972EXPORT_SYMBOL_GPL(nft_unregister_obj);
4973
4d44175a
FW
4974struct nft_object *nft_obj_lookup(const struct net *net,
4975 const struct nft_table *table,
cac20fcd
PNA
4976 const struct nlattr *nla, u32 objtype,
4977 u8 genmask)
e5009240 4978{
4d44175a
FW
4979 struct nft_object_hash_key k = { .table = table };
4980 char search[NFT_OBJ_MAXNAMELEN];
4981 struct rhlist_head *tmp, *list;
e5009240
PNA
4982 struct nft_object *obj;
4983
4d44175a
FW
4984 nla_strlcpy(search, nla, sizeof(search));
4985 k.name = search;
4986
4987 WARN_ON_ONCE(!rcu_read_lock_held() &&
4988 !lockdep_commit_lock_is_held(net));
4989
4990 rcu_read_lock();
4991 list = rhltable_lookup(&nft_objname_ht, &k, nft_objname_ht_params);
4992 if (!list)
4993 goto out;
4994
4995 rhl_for_each_entry_rcu(obj, tmp, list, rhlhead) {
4996 if (objtype == obj->ops->type->type &&
4997 nft_active_genmask(obj, genmask)) {
4998 rcu_read_unlock();
e5009240 4999 return obj;
4d44175a 5000 }
e5009240 5001 }
4d44175a
FW
5002out:
5003 rcu_read_unlock();
e5009240
PNA
5004 return ERR_PTR(-ENOENT);
5005}
cac20fcd 5006EXPORT_SYMBOL_GPL(nft_obj_lookup);
e5009240 5007
cac20fcd
PNA
5008static struct nft_object *nft_obj_lookup_byhandle(const struct nft_table *table,
5009 const struct nlattr *nla,
5010 u32 objtype, u8 genmask)
3ecbfd65
HS
5011{
5012 struct nft_object *obj;
5013
5014 list_for_each_entry(obj, &table->objects, list) {
5015 if (be64_to_cpu(nla_get_be64(nla)) == obj->handle &&
5016 objtype == obj->ops->type->type &&
5017 nft_active_genmask(obj, genmask))
5018 return obj;
5019 }
5020 return ERR_PTR(-ENOENT);
5021}
5022
e5009240 5023static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
b2fbd044
LZ
5024 [NFTA_OBJ_TABLE] = { .type = NLA_STRING,
5025 .len = NFT_TABLE_MAXNAMELEN - 1 },
5026 [NFTA_OBJ_NAME] = { .type = NLA_STRING,
5027 .len = NFT_OBJ_MAXNAMELEN - 1 },
e5009240
PNA
5028 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
5029 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
3ecbfd65 5030 [NFTA_OBJ_HANDLE] = { .type = NLA_U64},
e5009240
PNA
5031};
5032
84fba055
FW
5033static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,
5034 const struct nft_object_type *type,
e5009240
PNA
5035 const struct nlattr *attr)
5036{
5b4c6e38 5037 struct nlattr **tb;
dfc46034 5038 const struct nft_object_ops *ops;
e5009240 5039 struct nft_object *obj;
5b4c6e38
GS
5040 int err = -ENOMEM;
5041
5042 tb = kmalloc_array(type->maxattr + 1, sizeof(*tb), GFP_KERNEL);
5043 if (!tb)
5044 goto err1;
e5009240
PNA
5045
5046 if (attr) {
8cb08174
JB
5047 err = nla_parse_nested_deprecated(tb, type->maxattr, attr,
5048 type->policy, NULL);
e5009240 5049 if (err < 0)
5b4c6e38 5050 goto err2;
e5009240
PNA
5051 } else {
5052 memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));
5053 }
5054
dfc46034
PBG
5055 if (type->select_ops) {
5056 ops = type->select_ops(ctx, (const struct nlattr * const *)tb);
5057 if (IS_ERR(ops)) {
5058 err = PTR_ERR(ops);
5b4c6e38 5059 goto err2;
dfc46034
PBG
5060 }
5061 } else {
5062 ops = type->ops;
5063 }
5064
e5009240 5065 err = -ENOMEM;
dfc46034 5066 obj = kzalloc(sizeof(*obj) + ops->size, GFP_KERNEL);
5b4c6e38
GS
5067 if (!obj)
5068 goto err2;
e5009240 5069
dfc46034 5070 err = ops->init(ctx, (const struct nlattr * const *)tb, obj);
e5009240 5071 if (err < 0)
5b4c6e38 5072 goto err3;
e5009240 5073
dfc46034
PBG
5074 obj->ops = ops;
5075
5b4c6e38 5076 kfree(tb);
e5009240 5077 return obj;
5b4c6e38 5078err3:
e5009240 5079 kfree(obj);
5b4c6e38
GS
5080err2:
5081 kfree(tb);
e5009240
PNA
5082err1:
5083 return ERR_PTR(err);
5084}
5085
5086static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
43da04a5 5087 struct nft_object *obj, bool reset)
e5009240
PNA
5088{
5089 struct nlattr *nest;
5090
ae0be8de 5091 nest = nla_nest_start_noflag(skb, attr);
e5009240
PNA
5092 if (!nest)
5093 goto nla_put_failure;
dfc46034 5094 if (obj->ops->dump(skb, obj, reset) < 0)
e5009240
PNA
5095 goto nla_put_failure;
5096 nla_nest_end(skb, nest);
5097 return 0;
5098
5099nla_put_failure:
5100 return -1;
5101}
5102
5103static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
5104{
5105 const struct nft_object_type *type;
5106
5107 list_for_each_entry(type, &nf_tables_objects, list) {
5108 if (objtype == type->type)
5109 return type;
5110 }
5111 return NULL;
5112}
5113
452238e8
FW
5114static const struct nft_object_type *
5115nft_obj_type_get(struct net *net, u32 objtype)
e5009240
PNA
5116{
5117 const struct nft_object_type *type;
5118
5119 type = __nft_obj_type_get(objtype);
5120 if (type != NULL && try_module_get(type->owner))
5121 return type;
5122
f102d66b 5123 lockdep_nfnl_nft_mutex_not_held();
e5009240
PNA
5124#ifdef CONFIG_MODULES
5125 if (type == NULL) {
452238e8 5126 nft_request_module(net, "nft-obj-%u", objtype);
e5009240
PNA
5127 if (__nft_obj_type_get(objtype))
5128 return ERR_PTR(-EAGAIN);
5129 }
5130#endif
5131 return ERR_PTR(-ENOENT);
5132}
5133
d62d0ba9
FFM
5134static int nf_tables_updobj(const struct nft_ctx *ctx,
5135 const struct nft_object_type *type,
5136 const struct nlattr *attr,
5137 struct nft_object *obj)
5138{
5139 struct nft_object *newobj;
5140 struct nft_trans *trans;
5141 int err;
5142
aa4095a1
FFM
5143 if (!obj->ops->update)
5144 return -EOPNOTSUPP;
5145
d62d0ba9
FFM
5146 trans = nft_trans_alloc(ctx, NFT_MSG_NEWOBJ,
5147 sizeof(struct nft_trans_obj));
5148 if (!trans)
5149 return -ENOMEM;
5150
5151 newobj = nft_obj_init(ctx, type, attr);
5152 if (IS_ERR(newobj)) {
5153 err = PTR_ERR(newobj);
b74ae961 5154 goto err_free_trans;
d62d0ba9
FFM
5155 }
5156
5157 nft_trans_obj(trans) = obj;
5158 nft_trans_obj_update(trans) = true;
5159 nft_trans_obj_newobj(trans) = newobj;
5160 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
5161
5162 return 0;
b74ae961
DC
5163
5164err_free_trans:
d62d0ba9 5165 kfree(trans);
d62d0ba9
FFM
5166 return err;
5167}
5168
e5009240
PNA
5169static int nf_tables_newobj(struct net *net, struct sock *nlsk,
5170 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
5171 const struct nlattr * const nla[],
5172 struct netlink_ext_ack *extack)
e5009240
PNA
5173{
5174 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5175 const struct nft_object_type *type;
5176 u8 genmask = nft_genmask_next(net);
5177 int family = nfmsg->nfgen_family;
e5009240
PNA
5178 struct nft_table *table;
5179 struct nft_object *obj;
5180 struct nft_ctx ctx;
5181 u32 objtype;
5182 int err;
5183
5184 if (!nla[NFTA_OBJ_TYPE] ||
5185 !nla[NFTA_OBJ_NAME] ||
5186 !nla[NFTA_OBJ_DATA])
5187 return -EINVAL;
5188
cac20fcd 5189 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask);
36dd1bcc
PNA
5190 if (IS_ERR(table)) {
5191 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 5192 return PTR_ERR(table);
36dd1bcc 5193 }
e5009240
PNA
5194
5195 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4d44175a 5196 obj = nft_obj_lookup(net, table, nla[NFTA_OBJ_NAME], objtype, genmask);
e5009240
PNA
5197 if (IS_ERR(obj)) {
5198 err = PTR_ERR(obj);
36dd1bcc
PNA
5199 if (err != -ENOENT) {
5200 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 5201 return err;
36dd1bcc 5202 }
1a28ad74 5203 } else {
36dd1bcc
PNA
5204 if (nlh->nlmsg_flags & NLM_F_EXCL) {
5205 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 5206 return -EEXIST;
36dd1bcc 5207 }
d62d0ba9
FFM
5208 if (nlh->nlmsg_flags & NLM_F_REPLACE)
5209 return -EOPNOTSUPP;
5210
5211 type = nft_obj_type_get(net, objtype);
5212 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
5213
5214 return nf_tables_updobj(&ctx, type, nla[NFTA_OBJ_DATA], obj);
e5009240
PNA
5215 }
5216
98319cb9 5217 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e5009240 5218
452238e8 5219 type = nft_obj_type_get(net, objtype);
e5009240
PNA
5220 if (IS_ERR(type))
5221 return PTR_ERR(type);
5222
84fba055 5223 obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
e5009240
PNA
5224 if (IS_ERR(obj)) {
5225 err = PTR_ERR(obj);
5226 goto err1;
5227 }
d152159b 5228 obj->key.table = table;
3ecbfd65
HS
5229 obj->handle = nf_tables_alloc_handle(table);
5230
d152159b
FW
5231 obj->key.name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
5232 if (!obj->key.name) {
61509575
PS
5233 err = -ENOMEM;
5234 goto err2;
5235 }
e5009240
PNA
5236
5237 err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj);
5238 if (err < 0)
61509575 5239 goto err3;
e5009240 5240
4d44175a
FW
5241 err = rhltable_insert(&nft_objname_ht, &obj->rhlhead,
5242 nft_objname_ht_params);
5243 if (err < 0)
5244 goto err4;
5245
e5009240
PNA
5246 list_add_tail_rcu(&obj->list, &table->objects);
5247 table->use++;
5248 return 0;
4d44175a
FW
5249err4:
5250 /* queued in transaction log */
5251 INIT_LIST_HEAD(&obj->list);
5252 return err;
61509575 5253err3:
d152159b 5254 kfree(obj->key.name);
e5009240 5255err2:
dfc46034 5256 if (obj->ops->destroy)
00bfb320 5257 obj->ops->destroy(&ctx, obj);
e5009240
PNA
5258 kfree(obj);
5259err1:
5260 module_put(type->owner);
5261 return err;
5262}
5263
5264static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
5265 u32 portid, u32 seq, int event, u32 flags,
5266 int family, const struct nft_table *table,
43da04a5 5267 struct nft_object *obj, bool reset)
e5009240
PNA
5268{
5269 struct nfgenmsg *nfmsg;
5270 struct nlmsghdr *nlh;
5271
dedb67c4 5272 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
e5009240
PNA
5273 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
5274 if (nlh == NULL)
5275 goto nla_put_failure;
5276
5277 nfmsg = nlmsg_data(nlh);
5278 nfmsg->nfgen_family = family;
5279 nfmsg->version = NFNETLINK_V0;
5280 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
5281
5282 if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
d152159b 5283 nla_put_string(skb, NFTA_OBJ_NAME, obj->key.name) ||
dfc46034 5284 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
e5009240 5285 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
3ecbfd65
HS
5286 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset) ||
5287 nla_put_be64(skb, NFTA_OBJ_HANDLE, cpu_to_be64(obj->handle),
5288 NFTA_OBJ_PAD))
e5009240
PNA
5289 goto nla_put_failure;
5290
5291 nlmsg_end(skb, nlh);
5292 return 0;
5293
5294nla_put_failure:
5295 nlmsg_trim(skb, nlh);
5296 return -1;
5297}
5298
a9fea2a3 5299struct nft_obj_filter {
e46abbcc 5300 char *table;
a9fea2a3
PNA
5301 u32 type;
5302};
5303
e5009240
PNA
5304static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
5305{
5306 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
e5009240 5307 const struct nft_table *table;
e5009240 5308 unsigned int idx = 0, s_idx = cb->args[0];
a9fea2a3 5309 struct nft_obj_filter *filter = cb->data;
e5009240
PNA
5310 struct net *net = sock_net(skb->sk);
5311 int family = nfmsg->nfgen_family;
43da04a5
PNA
5312 struct nft_object *obj;
5313 bool reset = false;
5314
5315 if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
5316 reset = true;
e5009240
PNA
5317
5318 rcu_read_lock();
5319 cb->seq = net->nft.base_seq;
5320
36596dad 5321 list_for_each_entry_rcu(table, &net->nft.tables, list) {
98319cb9 5322 if (family != NFPROTO_UNSPEC && family != table->family)
e5009240
PNA
5323 continue;
5324
36596dad
PNA
5325 list_for_each_entry_rcu(obj, &table->objects, list) {
5326 if (!nft_is_active(net, obj))
5327 goto cont;
5328 if (idx < s_idx)
5329 goto cont;
5330 if (idx > s_idx)
5331 memset(&cb->args[1], 0,
5332 sizeof(cb->args) - sizeof(cb->args[0]));
360cc79d 5333 if (filter && filter->table &&
36596dad
PNA
5334 strcmp(filter->table, table->name))
5335 goto cont;
5336 if (filter &&
5337 filter->type != NFT_OBJECT_UNSPEC &&
5338 obj->ops->type->type != filter->type)
5339 goto cont;
a9fea2a3 5340
36596dad
PNA
5341 if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
5342 cb->nlh->nlmsg_seq,
5343 NFT_MSG_NEWOBJ,
5344 NLM_F_MULTI | NLM_F_APPEND,
98319cb9 5345 table->family, table,
36596dad
PNA
5346 obj, reset) < 0)
5347 goto done;
e5009240 5348
36596dad 5349 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
e5009240 5350cont:
36596dad 5351 idx++;
e5009240
PNA
5352 }
5353 }
5354done:
5355 rcu_read_unlock();
5356
5357 cb->args[0] = idx;
5358 return skb->len;
5359}
5360
90fd131a 5361static int nf_tables_dump_obj_start(struct netlink_callback *cb)
a9fea2a3 5362{
90fd131a
FW
5363 const struct nlattr * const *nla = cb->data;
5364 struct nft_obj_filter *filter = NULL;
e46abbcc 5365
90fd131a
FW
5366 if (nla[NFTA_OBJ_TABLE] || nla[NFTA_OBJ_TYPE]) {
5367 filter = kzalloc(sizeof(*filter), GFP_ATOMIC);
5368 if (!filter)
5369 return -ENOMEM;
5370
5371 if (nla[NFTA_OBJ_TABLE]) {
5372 filter->table = nla_strdup(nla[NFTA_OBJ_TABLE], GFP_ATOMIC);
5373 if (!filter->table) {
5374 kfree(filter);
5375 return -ENOMEM;
5376 }
5377 }
5378
5379 if (nla[NFTA_OBJ_TYPE])
5380 filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
8bea728d 5381 }
a9fea2a3 5382
90fd131a 5383 cb->data = filter;
a9fea2a3
PNA
5384 return 0;
5385}
5386
90fd131a 5387static int nf_tables_dump_obj_done(struct netlink_callback *cb)
a9fea2a3 5388{
90fd131a 5389 struct nft_obj_filter *filter = cb->data;
a9fea2a3 5390
90fd131a
FW
5391 if (filter) {
5392 kfree(filter->table);
5393 kfree(filter);
e46abbcc 5394 }
a9fea2a3 5395
90fd131a 5396 return 0;
a9fea2a3
PNA
5397}
5398
d9adf22a 5399/* called with rcu_read_lock held */
e5009240
PNA
5400static int nf_tables_getobj(struct net *net, struct sock *nlsk,
5401 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
5402 const struct nlattr * const nla[],
5403 struct netlink_ext_ack *extack)
e5009240
PNA
5404{
5405 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5406 u8 genmask = nft_genmask_cur(net);
5407 int family = nfmsg->nfgen_family;
e5009240
PNA
5408 const struct nft_table *table;
5409 struct nft_object *obj;
5410 struct sk_buff *skb2;
43da04a5 5411 bool reset = false;
e5009240
PNA
5412 u32 objtype;
5413 int err;
5414
5415 if (nlh->nlmsg_flags & NLM_F_DUMP) {
5416 struct netlink_dump_control c = {
90fd131a 5417 .start = nf_tables_dump_obj_start,
e5009240 5418 .dump = nf_tables_dump_obj,
a9fea2a3 5419 .done = nf_tables_dump_obj_done,
d9adf22a 5420 .module = THIS_MODULE,
90fd131a 5421 .data = (void *)nla,
e5009240 5422 };
a9fea2a3 5423
d9adf22a 5424 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
e5009240
PNA
5425 }
5426
5427 if (!nla[NFTA_OBJ_NAME] ||
5428 !nla[NFTA_OBJ_TYPE])
5429 return -EINVAL;
5430
cac20fcd 5431 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask);
36dd1bcc
PNA
5432 if (IS_ERR(table)) {
5433 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 5434 return PTR_ERR(table);
36dd1bcc 5435 }
e5009240
PNA
5436
5437 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4d44175a 5438 obj = nft_obj_lookup(net, table, nla[NFTA_OBJ_NAME], objtype, genmask);
36dd1bcc
PNA
5439 if (IS_ERR(obj)) {
5440 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_NAME]);
e5009240 5441 return PTR_ERR(obj);
36dd1bcc 5442 }
e5009240 5443
d9adf22a 5444 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
e5009240
PNA
5445 if (!skb2)
5446 return -ENOMEM;
5447
43da04a5
PNA
5448 if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
5449 reset = true;
5450
e5009240
PNA
5451 err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
5452 nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
43da04a5 5453 family, table, obj, reset);
e5009240
PNA
5454 if (err < 0)
5455 goto err;
5456
5457 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
5458err:
5459 kfree_skb(skb2);
5460 return err;
e5009240
PNA
5461}
5462
00bfb320 5463static void nft_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
e5009240 5464{
dfc46034 5465 if (obj->ops->destroy)
00bfb320 5466 obj->ops->destroy(ctx, obj);
e5009240 5467
dfc46034 5468 module_put(obj->ops->type->owner);
d152159b 5469 kfree(obj->key.name);
e5009240
PNA
5470 kfree(obj);
5471}
5472
5473static int nf_tables_delobj(struct net *net, struct sock *nlsk,
04ba724b
PNA
5474 struct sk_buff *skb, const struct nlmsghdr *nlh,
5475 const struct nlattr * const nla[],
5476 struct netlink_ext_ack *extack)
e5009240
PNA
5477{
5478 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5479 u8 genmask = nft_genmask_next(net);
5480 int family = nfmsg->nfgen_family;
36dd1bcc 5481 const struct nlattr *attr;
e5009240
PNA
5482 struct nft_table *table;
5483 struct nft_object *obj;
5484 struct nft_ctx ctx;
5485 u32 objtype;
5486
5487 if (!nla[NFTA_OBJ_TYPE] ||
3ecbfd65 5488 (!nla[NFTA_OBJ_NAME] && !nla[NFTA_OBJ_HANDLE]))
e5009240
PNA
5489 return -EINVAL;
5490
cac20fcd 5491 table = nft_table_lookup(net, nla[NFTA_OBJ_TABLE], family, genmask);
36dd1bcc
PNA
5492 if (IS_ERR(table)) {
5493 NL_SET_BAD_ATTR(extack, nla[NFTA_OBJ_TABLE]);
e5009240 5494 return PTR_ERR(table);
36dd1bcc 5495 }
e5009240
PNA
5496
5497 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
36dd1bcc
PNA
5498 if (nla[NFTA_OBJ_HANDLE]) {
5499 attr = nla[NFTA_OBJ_HANDLE];
5500 obj = nft_obj_lookup_byhandle(table, attr, objtype, genmask);
5501 } else {
5502 attr = nla[NFTA_OBJ_NAME];
4d44175a 5503 obj = nft_obj_lookup(net, table, attr, objtype, genmask);
36dd1bcc
PNA
5504 }
5505
5506 if (IS_ERR(obj)) {
5507 NL_SET_BAD_ATTR(extack, attr);
e5009240 5508 return PTR_ERR(obj);
36dd1bcc
PNA
5509 }
5510 if (obj->use > 0) {
5511 NL_SET_BAD_ATTR(extack, attr);
e5009240 5512 return -EBUSY;
36dd1bcc 5513 }
e5009240 5514
98319cb9 5515 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
e5009240
PNA
5516
5517 return nft_delobj(&ctx, obj);
5518}
5519
d152159b 5520void nft_obj_notify(struct net *net, const struct nft_table *table,
25e94a99
PNA
5521 struct nft_object *obj, u32 portid, u32 seq, int event,
5522 int family, int report, gfp_t gfp)
e5009240
PNA
5523{
5524 struct sk_buff *skb;
5525 int err;
5526
2599e989
PNA
5527 if (!report &&
5528 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 5529 return;
e5009240 5530
2599e989 5531 skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
e5009240
PNA
5532 if (skb == NULL)
5533 goto err;
5534
2599e989
PNA
5535 err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
5536 table, obj, false);
e5009240
PNA
5537 if (err < 0) {
5538 kfree_skb(skb);
5539 goto err;
5540 }
5541
25e94a99
PNA
5542 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
5543 return;
e5009240 5544err:
25e94a99 5545 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
e5009240 5546}
2599e989
PNA
5547EXPORT_SYMBOL_GPL(nft_obj_notify);
5548
25e94a99
PNA
5549static void nf_tables_obj_notify(const struct nft_ctx *ctx,
5550 struct nft_object *obj, int event)
2599e989 5551{
25e94a99 5552 nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
36596dad 5553 ctx->family, ctx->report, GFP_KERNEL);
2599e989 5554}
e5009240 5555
3b49e2e9
PNA
5556/*
5557 * Flow tables
5558 */
5559void nft_register_flowtable_type(struct nf_flowtable_type *type)
5560{
5561 nfnl_lock(NFNL_SUBSYS_NFTABLES);
5562 list_add_tail_rcu(&type->list, &nf_tables_flowtables);
5563 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5564}
5565EXPORT_SYMBOL_GPL(nft_register_flowtable_type);
5566
5567void nft_unregister_flowtable_type(struct nf_flowtable_type *type)
5568{
5569 nfnl_lock(NFNL_SUBSYS_NFTABLES);
5570 list_del_rcu(&type->list);
5571 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
5572}
5573EXPORT_SYMBOL_GPL(nft_unregister_flowtable_type);
5574
5575static const struct nla_policy nft_flowtable_policy[NFTA_FLOWTABLE_MAX + 1] = {
5576 [NFTA_FLOWTABLE_TABLE] = { .type = NLA_STRING,
5577 .len = NFT_NAME_MAXLEN - 1 },
5578 [NFTA_FLOWTABLE_NAME] = { .type = NLA_STRING,
5579 .len = NFT_NAME_MAXLEN - 1 },
5580 [NFTA_FLOWTABLE_HOOK] = { .type = NLA_NESTED },
3ecbfd65 5581 [NFTA_FLOWTABLE_HANDLE] = { .type = NLA_U64 },
3b49e2e9
PNA
5582};
5583
cac20fcd
PNA
5584struct nft_flowtable *nft_flowtable_lookup(const struct nft_table *table,
5585 const struct nlattr *nla, u8 genmask)
3b49e2e9
PNA
5586{
5587 struct nft_flowtable *flowtable;
5588
d9adf22a 5589 list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
3b49e2e9
PNA
5590 if (!nla_strcmp(nla, flowtable->name) &&
5591 nft_active_genmask(flowtable, genmask))
5592 return flowtable;
5593 }
5594 return ERR_PTR(-ENOENT);
5595}
cac20fcd 5596EXPORT_SYMBOL_GPL(nft_flowtable_lookup);
3b49e2e9 5597
ae0662f8 5598static struct nft_flowtable *
cac20fcd
PNA
5599nft_flowtable_lookup_byhandle(const struct nft_table *table,
5600 const struct nlattr *nla, u8 genmask)
3ecbfd65
HS
5601{
5602 struct nft_flowtable *flowtable;
5603
5604 list_for_each_entry(flowtable, &table->flowtables, list) {
5605 if (be64_to_cpu(nla_get_be64(nla)) == flowtable->handle &&
5606 nft_active_genmask(flowtable, genmask))
5607 return flowtable;
5608 }
5609 return ERR_PTR(-ENOENT);
5610}
5611
3b49e2e9
PNA
5612static int nf_tables_parse_devices(const struct nft_ctx *ctx,
5613 const struct nlattr *attr,
5614 struct net_device *dev_array[], int *len)
5615{
5616 const struct nlattr *tmp;
5617 struct net_device *dev;
5618 char ifname[IFNAMSIZ];
5619 int rem, n = 0, err;
5620
5621 nla_for_each_nested(tmp, attr, rem) {
5622 if (nla_type(tmp) != NFTA_DEVICE_NAME) {
5623 err = -EINVAL;
5624 goto err1;
5625 }
5626
5627 nla_strlcpy(ifname, tmp, IFNAMSIZ);
90d2723c 5628 dev = __dev_get_by_name(ctx->net, ifname);
3b49e2e9
PNA
5629 if (!dev) {
5630 err = -ENOENT;
5631 goto err1;
5632 }
5633
5634 dev_array[n++] = dev;
5635 if (n == NFT_FLOWTABLE_DEVICE_MAX) {
5636 err = -EFBIG;
5637 goto err1;
5638 }
5639 }
5640 if (!len)
5641 return -EINVAL;
5642
5643 err = 0;
5644err1:
5645 *len = n;
5646 return err;
5647}
5648
5649static const struct nla_policy nft_flowtable_hook_policy[NFTA_FLOWTABLE_HOOK_MAX + 1] = {
5650 [NFTA_FLOWTABLE_HOOK_NUM] = { .type = NLA_U32 },
5651 [NFTA_FLOWTABLE_HOOK_PRIORITY] = { .type = NLA_U32 },
5652 [NFTA_FLOWTABLE_HOOK_DEVS] = { .type = NLA_NESTED },
5653};
5654
5655static int nf_tables_flowtable_parse_hook(const struct nft_ctx *ctx,
5656 const struct nlattr *attr,
5657 struct nft_flowtable *flowtable)
5658{
5659 struct net_device *dev_array[NFT_FLOWTABLE_DEVICE_MAX];
5660 struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1];
5661 struct nf_hook_ops *ops;
5662 int hooknum, priority;
5663 int err, n = 0, i;
5664
8cb08174
JB
5665 err = nla_parse_nested_deprecated(tb, NFTA_FLOWTABLE_HOOK_MAX, attr,
5666 nft_flowtable_hook_policy, NULL);
3b49e2e9
PNA
5667 if (err < 0)
5668 return err;
5669
5670 if (!tb[NFTA_FLOWTABLE_HOOK_NUM] ||
5671 !tb[NFTA_FLOWTABLE_HOOK_PRIORITY] ||
5672 !tb[NFTA_FLOWTABLE_HOOK_DEVS])
5673 return -EINVAL;
5674
5675 hooknum = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_NUM]));
fe19c04c 5676 if (hooknum != NF_NETDEV_INGRESS)
3b49e2e9
PNA
5677 return -EINVAL;
5678
5679 priority = ntohl(nla_get_be32(tb[NFTA_FLOWTABLE_HOOK_PRIORITY]));
5680
5681 err = nf_tables_parse_devices(ctx, tb[NFTA_FLOWTABLE_HOOK_DEVS],
5682 dev_array, &n);
5683 if (err < 0)
d92191aa 5684 return err;
3b49e2e9 5685
6396bb22 5686 ops = kcalloc(n, sizeof(struct nf_hook_ops), GFP_KERNEL);
90d2723c
PNA
5687 if (!ops)
5688 return -ENOMEM;
3b49e2e9 5689
0e839dfa
PNA
5690 flowtable->hooknum = hooknum;
5691 flowtable->priority = priority;
3b49e2e9
PNA
5692 flowtable->ops = ops;
5693 flowtable->ops_len = n;
5694
5695 for (i = 0; i < n; i++) {
5696 flowtable->ops[i].pf = NFPROTO_NETDEV;
5697 flowtable->ops[i].hooknum = hooknum;
5698 flowtable->ops[i].priority = priority;
17857d92 5699 flowtable->ops[i].priv = &flowtable->data;
3b49e2e9
PNA
5700 flowtable->ops[i].hook = flowtable->data.type->hook;
5701 flowtable->ops[i].dev = dev_array[i];
5702 }
5703
3b49e2e9
PNA
5704 return err;
5705}
5706
98319cb9 5707static const struct nf_flowtable_type *__nft_flowtable_type_get(u8 family)
3b49e2e9
PNA
5708{
5709 const struct nf_flowtable_type *type;
5710
5711 list_for_each_entry(type, &nf_tables_flowtables, list) {
98319cb9 5712 if (family == type->family)
3b49e2e9
PNA
5713 return type;
5714 }
5715 return NULL;
5716}
5717
452238e8
FW
5718static const struct nf_flowtable_type *
5719nft_flowtable_type_get(struct net *net, u8 family)
3b49e2e9
PNA
5720{
5721 const struct nf_flowtable_type *type;
5722
98319cb9 5723 type = __nft_flowtable_type_get(family);
3b49e2e9
PNA
5724 if (type != NULL && try_module_get(type->owner))
5725 return type;
5726
f102d66b 5727 lockdep_nfnl_nft_mutex_not_held();
3b49e2e9
PNA
5728#ifdef CONFIG_MODULES
5729 if (type == NULL) {
452238e8 5730 nft_request_module(net, "nf-flowtable-%u", family);
98319cb9 5731 if (__nft_flowtable_type_get(family))
3b49e2e9
PNA
5732 return ERR_PTR(-EAGAIN);
5733 }
5734#endif
5735 return ERR_PTR(-ENOENT);
5736}
5737
3b49e2e9
PNA
5738static void nft_unregister_flowtable_net_hooks(struct net *net,
5739 struct nft_flowtable *flowtable)
5740{
5741 int i;
5742
5743 for (i = 0; i < flowtable->ops_len; i++) {
5744 if (!flowtable->ops[i].dev)
5745 continue;
5746
5747 nf_unregister_net_hook(net, &flowtable->ops[i]);
5748 }
5749}
5750
5751static int nf_tables_newflowtable(struct net *net, struct sock *nlsk,
5752 struct sk_buff *skb,
5753 const struct nlmsghdr *nlh,
5754 const struct nlattr * const nla[],
5755 struct netlink_ext_ack *extack)
5756{
5757 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5758 const struct nf_flowtable_type *type;
32fc7187 5759 struct nft_flowtable *flowtable, *ft;
3b49e2e9
PNA
5760 u8 genmask = nft_genmask_next(net);
5761 int family = nfmsg->nfgen_family;
3b49e2e9
PNA
5762 struct nft_table *table;
5763 struct nft_ctx ctx;
5764 int err, i, k;
5765
5766 if (!nla[NFTA_FLOWTABLE_TABLE] ||
5767 !nla[NFTA_FLOWTABLE_NAME] ||
5768 !nla[NFTA_FLOWTABLE_HOOK])
5769 return -EINVAL;
5770
cac20fcd
PNA
5771 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
5772 genmask);
36dd1bcc
PNA
5773 if (IS_ERR(table)) {
5774 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_TABLE]);
3b49e2e9 5775 return PTR_ERR(table);
36dd1bcc 5776 }
3b49e2e9 5777
cac20fcd
PNA
5778 flowtable = nft_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME],
5779 genmask);
3b49e2e9
PNA
5780 if (IS_ERR(flowtable)) {
5781 err = PTR_ERR(flowtable);
36dd1bcc
PNA
5782 if (err != -ENOENT) {
5783 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_NAME]);
3b49e2e9 5784 return err;
36dd1bcc 5785 }
3b49e2e9 5786 } else {
36dd1bcc
PNA
5787 if (nlh->nlmsg_flags & NLM_F_EXCL) {
5788 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_NAME]);
3b49e2e9 5789 return -EEXIST;
36dd1bcc 5790 }
3b49e2e9
PNA
5791
5792 return 0;
5793 }
5794
98319cb9 5795 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
3b49e2e9
PNA
5796
5797 flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL);
5798 if (!flowtable)
5799 return -ENOMEM;
5800
5801 flowtable->table = table;
3ecbfd65
HS
5802 flowtable->handle = nf_tables_alloc_handle(table);
5803
3b49e2e9
PNA
5804 flowtable->name = nla_strdup(nla[NFTA_FLOWTABLE_NAME], GFP_KERNEL);
5805 if (!flowtable->name) {
5806 err = -ENOMEM;
5807 goto err1;
5808 }
5809
452238e8 5810 type = nft_flowtable_type_get(net, family);
3b49e2e9
PNA
5811 if (IS_ERR(type)) {
5812 err = PTR_ERR(type);
5813 goto err2;
5814 }
5815
5816 flowtable->data.type = type;
a268de77 5817 err = type->init(&flowtable->data);
3b49e2e9
PNA
5818 if (err < 0)
5819 goto err3;
5820
5821 err = nf_tables_flowtable_parse_hook(&ctx, nla[NFTA_FLOWTABLE_HOOK],
5822 flowtable);
5823 if (err < 0)
a268de77 5824 goto err4;
3b49e2e9
PNA
5825
5826 for (i = 0; i < flowtable->ops_len; i++) {
32fc7187
PNA
5827 if (!flowtable->ops[i].dev)
5828 continue;
5829
5830 list_for_each_entry(ft, &table->flowtables, list) {
5831 for (k = 0; k < ft->ops_len; k++) {
5832 if (!ft->ops[k].dev)
5833 continue;
5834
5835 if (flowtable->ops[i].dev == ft->ops[k].dev &&
5836 flowtable->ops[i].pf == ft->ops[k].pf) {
5837 err = -EBUSY;
a268de77 5838 goto err5;
32fc7187
PNA
5839 }
5840 }
5841 }
5842
3b49e2e9
PNA
5843 err = nf_register_net_hook(net, &flowtable->ops[i]);
5844 if (err < 0)
a268de77 5845 goto err5;
3b49e2e9
PNA
5846 }
5847
5848 err = nft_trans_flowtable_add(&ctx, NFT_MSG_NEWFLOWTABLE, flowtable);
5849 if (err < 0)
a268de77 5850 goto err6;
3b49e2e9
PNA
5851
5852 list_add_tail_rcu(&flowtable->list, &table->flowtables);
5853 table->use++;
5854
5855 return 0;
a268de77 5856err6:
3b49e2e9 5857 i = flowtable->ops_len;
a268de77 5858err5:
b8088dda 5859 for (k = i - 1; k >= 0; k--)
0e0d5002 5860 nf_unregister_net_hook(net, &flowtable->ops[k]);
3b49e2e9
PNA
5861
5862 kfree(flowtable->ops);
a268de77
FF
5863err4:
5864 flowtable->data.type->free(&flowtable->data);
3b49e2e9
PNA
5865err3:
5866 module_put(type->owner);
5867err2:
5868 kfree(flowtable->name);
5869err1:
5870 kfree(flowtable);
5871 return err;
5872}
5873
5874static int nf_tables_delflowtable(struct net *net, struct sock *nlsk,
5875 struct sk_buff *skb,
5876 const struct nlmsghdr *nlh,
5877 const struct nlattr * const nla[],
5878 struct netlink_ext_ack *extack)
5879{
5880 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
5881 u8 genmask = nft_genmask_next(net);
5882 int family = nfmsg->nfgen_family;
5883 struct nft_flowtable *flowtable;
36dd1bcc 5884 const struct nlattr *attr;
3b49e2e9
PNA
5885 struct nft_table *table;
5886 struct nft_ctx ctx;
5887
e603ea4b
PNA
5888 if (!nla[NFTA_FLOWTABLE_TABLE] ||
5889 (!nla[NFTA_FLOWTABLE_NAME] &&
5890 !nla[NFTA_FLOWTABLE_HANDLE]))
5891 return -EINVAL;
5892
cac20fcd
PNA
5893 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
5894 genmask);
36dd1bcc
PNA
5895 if (IS_ERR(table)) {
5896 NL_SET_BAD_ATTR(extack, nla[NFTA_FLOWTABLE_TABLE]);
3b49e2e9 5897 return PTR_ERR(table);
36dd1bcc 5898 }
3b49e2e9 5899
36dd1bcc
PNA
5900 if (nla[NFTA_FLOWTABLE_HANDLE]) {
5901 attr = nla[NFTA_FLOWTABLE_HANDLE];
5902 flowtable = nft_flowtable_lookup_byhandle(table, attr, genmask);
5903 } else {
5904 attr = nla[NFTA_FLOWTABLE_NAME];
5905 flowtable = nft_flowtable_lookup(table, attr, genmask);
5906 }
5907
5908 if (IS_ERR(flowtable)) {
5909 NL_SET_BAD_ATTR(extack, attr);
5910 return PTR_ERR(flowtable);
5911 }
5912 if (flowtable->use > 0) {
5913 NL_SET_BAD_ATTR(extack, attr);
3b49e2e9 5914 return -EBUSY;
36dd1bcc 5915 }
3b49e2e9 5916
98319cb9 5917 nft_ctx_init(&ctx, net, skb, nlh, family, table, NULL, nla);
3b49e2e9
PNA
5918
5919 return nft_delflowtable(&ctx, flowtable);
5920}
5921
5922static int nf_tables_fill_flowtable_info(struct sk_buff *skb, struct net *net,
5923 u32 portid, u32 seq, int event,
5924 u32 flags, int family,
5925 struct nft_flowtable *flowtable)
5926{
5927 struct nlattr *nest, *nest_devs;
5928 struct nfgenmsg *nfmsg;
5929 struct nlmsghdr *nlh;
5930 int i;
5931
5932 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
5933 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
5934 if (nlh == NULL)
5935 goto nla_put_failure;
5936
5937 nfmsg = nlmsg_data(nlh);
5938 nfmsg->nfgen_family = family;
5939 nfmsg->version = NFNETLINK_V0;
5940 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
5941
5942 if (nla_put_string(skb, NFTA_FLOWTABLE_TABLE, flowtable->table->name) ||
5943 nla_put_string(skb, NFTA_FLOWTABLE_NAME, flowtable->name) ||
3ecbfd65
HS
5944 nla_put_be32(skb, NFTA_FLOWTABLE_USE, htonl(flowtable->use)) ||
5945 nla_put_be64(skb, NFTA_FLOWTABLE_HANDLE, cpu_to_be64(flowtable->handle),
5946 NFTA_FLOWTABLE_PAD))
3b49e2e9
PNA
5947 goto nla_put_failure;
5948
ae0be8de 5949 nest = nla_nest_start_noflag(skb, NFTA_FLOWTABLE_HOOK);
eb895086
KL
5950 if (!nest)
5951 goto nla_put_failure;
3b49e2e9
PNA
5952 if (nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_NUM, htonl(flowtable->hooknum)) ||
5953 nla_put_be32(skb, NFTA_FLOWTABLE_HOOK_PRIORITY, htonl(flowtable->priority)))
5954 goto nla_put_failure;
5955
ae0be8de 5956 nest_devs = nla_nest_start_noflag(skb, NFTA_FLOWTABLE_HOOK_DEVS);
3b49e2e9
PNA
5957 if (!nest_devs)
5958 goto nla_put_failure;
5959
5960 for (i = 0; i < flowtable->ops_len; i++) {
b8088dda
FW
5961 const struct net_device *dev = READ_ONCE(flowtable->ops[i].dev);
5962
5963 if (dev &&
5964 nla_put_string(skb, NFTA_DEVICE_NAME, dev->name))
3b49e2e9
PNA
5965 goto nla_put_failure;
5966 }
5967 nla_nest_end(skb, nest_devs);
5968 nla_nest_end(skb, nest);
5969
5970 nlmsg_end(skb, nlh);
5971 return 0;
5972
5973nla_put_failure:
5974 nlmsg_trim(skb, nlh);
5975 return -1;
5976}
5977
5978struct nft_flowtable_filter {
5979 char *table;
5980};
5981
5982static int nf_tables_dump_flowtable(struct sk_buff *skb,
5983 struct netlink_callback *cb)
5984{
5985 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
5986 struct nft_flowtable_filter *filter = cb->data;
5987 unsigned int idx = 0, s_idx = cb->args[0];
5988 struct net *net = sock_net(skb->sk);
5989 int family = nfmsg->nfgen_family;
5990 struct nft_flowtable *flowtable;
3b49e2e9
PNA
5991 const struct nft_table *table;
5992
5993 rcu_read_lock();
5994 cb->seq = net->nft.base_seq;
5995
36596dad 5996 list_for_each_entry_rcu(table, &net->nft.tables, list) {
98319cb9 5997 if (family != NFPROTO_UNSPEC && family != table->family)
3b49e2e9
PNA
5998 continue;
5999
36596dad
PNA
6000 list_for_each_entry_rcu(flowtable, &table->flowtables, list) {
6001 if (!nft_is_active(net, flowtable))
6002 goto cont;
6003 if (idx < s_idx)
6004 goto cont;
6005 if (idx > s_idx)
6006 memset(&cb->args[1], 0,
6007 sizeof(cb->args) - sizeof(cb->args[0]));
360cc79d 6008 if (filter && filter->table &&
36596dad
PNA
6009 strcmp(filter->table, table->name))
6010 goto cont;
3b49e2e9 6011
36596dad
PNA
6012 if (nf_tables_fill_flowtable_info(skb, net, NETLINK_CB(cb->skb).portid,
6013 cb->nlh->nlmsg_seq,
6014 NFT_MSG_NEWFLOWTABLE,
6015 NLM_F_MULTI | NLM_F_APPEND,
98319cb9 6016 table->family, flowtable) < 0)
36596dad 6017 goto done;
3b49e2e9 6018
36596dad 6019 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
3b49e2e9 6020cont:
36596dad 6021 idx++;
3b49e2e9
PNA
6022 }
6023 }
6024done:
6025 rcu_read_unlock();
6026
6027 cb->args[0] = idx;
6028 return skb->len;
6029}
6030
90fd131a 6031static int nf_tables_dump_flowtable_start(struct netlink_callback *cb)
3b49e2e9 6032{
90fd131a
FW
6033 const struct nlattr * const *nla = cb->data;
6034 struct nft_flowtable_filter *filter = NULL;
3b49e2e9 6035
90fd131a
FW
6036 if (nla[NFTA_FLOWTABLE_TABLE]) {
6037 filter = kzalloc(sizeof(*filter), GFP_ATOMIC);
6038 if (!filter)
6039 return -ENOMEM;
3b49e2e9 6040
90fd131a
FW
6041 filter->table = nla_strdup(nla[NFTA_FLOWTABLE_TABLE],
6042 GFP_ATOMIC);
6043 if (!filter->table) {
6044 kfree(filter);
6045 return -ENOMEM;
6046 }
6047 }
3b49e2e9 6048
90fd131a 6049 cb->data = filter;
3b49e2e9
PNA
6050 return 0;
6051}
6052
90fd131a 6053static int nf_tables_dump_flowtable_done(struct netlink_callback *cb)
3b49e2e9 6054{
90fd131a 6055 struct nft_flowtable_filter *filter = cb->data;
3b49e2e9 6056
3b49e2e9 6057 if (!filter)
90fd131a 6058 return 0;
3b49e2e9 6059
90fd131a
FW
6060 kfree(filter->table);
6061 kfree(filter);
6062
6063 return 0;
3b49e2e9
PNA
6064}
6065
d9adf22a 6066/* called with rcu_read_lock held */
3b49e2e9
PNA
6067static int nf_tables_getflowtable(struct net *net, struct sock *nlsk,
6068 struct sk_buff *skb,
6069 const struct nlmsghdr *nlh,
6070 const struct nlattr * const nla[],
6071 struct netlink_ext_ack *extack)
6072{
6073 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
6074 u8 genmask = nft_genmask_cur(net);
6075 int family = nfmsg->nfgen_family;
6076 struct nft_flowtable *flowtable;
3b49e2e9
PNA
6077 const struct nft_table *table;
6078 struct sk_buff *skb2;
6079 int err;
6080
6081 if (nlh->nlmsg_flags & NLM_F_DUMP) {
6082 struct netlink_dump_control c = {
90fd131a 6083 .start = nf_tables_dump_flowtable_start,
3b49e2e9
PNA
6084 .dump = nf_tables_dump_flowtable,
6085 .done = nf_tables_dump_flowtable_done,
d9adf22a 6086 .module = THIS_MODULE,
90fd131a 6087 .data = (void *)nla,
3b49e2e9
PNA
6088 };
6089
d9adf22a 6090 return nft_netlink_dump_start_rcu(nlsk, skb, nlh, &c);
3b49e2e9
PNA
6091 }
6092
6093 if (!nla[NFTA_FLOWTABLE_NAME])
6094 return -EINVAL;
6095
cac20fcd
PNA
6096 table = nft_table_lookup(net, nla[NFTA_FLOWTABLE_TABLE], family,
6097 genmask);
3b49e2e9
PNA
6098 if (IS_ERR(table))
6099 return PTR_ERR(table);
6100
cac20fcd
PNA
6101 flowtable = nft_flowtable_lookup(table, nla[NFTA_FLOWTABLE_NAME],
6102 genmask);
03a0120f 6103 if (IS_ERR(flowtable))
3b49e2e9
PNA
6104 return PTR_ERR(flowtable);
6105
d9adf22a 6106 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
3b49e2e9
PNA
6107 if (!skb2)
6108 return -ENOMEM;
6109
6110 err = nf_tables_fill_flowtable_info(skb2, net, NETLINK_CB(skb).portid,
6111 nlh->nlmsg_seq,
6112 NFT_MSG_NEWFLOWTABLE, 0, family,
6113 flowtable);
6114 if (err < 0)
6115 goto err;
6116
6117 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
6118err:
6119 kfree_skb(skb2);
6120 return err;
6121}
6122
6123static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
6124 struct nft_flowtable *flowtable,
6125 int event)
6126{
6127 struct sk_buff *skb;
6128 int err;
6129
6130 if (ctx->report &&
6131 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
6132 return;
6133
6134 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
6135 if (skb == NULL)
6136 goto err;
6137
6138 err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid,
6139 ctx->seq, event, 0,
36596dad 6140 ctx->family, flowtable);
3b49e2e9
PNA
6141 if (err < 0) {
6142 kfree_skb(skb);
6143 goto err;
6144 }
6145
6146 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
6147 ctx->report, GFP_KERNEL);
6148 return;
6149err:
6150 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
6151}
6152
3b49e2e9
PNA
6153static void nf_tables_flowtable_destroy(struct nft_flowtable *flowtable)
6154{
c04a3f73 6155 kfree(flowtable->ops);
3b49e2e9 6156 kfree(flowtable->name);
b408c5b0 6157 flowtable->data.type->free(&flowtable->data);
3b49e2e9 6158 module_put(flowtable->data.type->owner);
a12486eb 6159 kfree(flowtable);
3b49e2e9
PNA
6160}
6161
84d7fce6
PNA
6162static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
6163 u32 portid, u32 seq)
6164{
6165 struct nlmsghdr *nlh;
6166 struct nfgenmsg *nfmsg;
784b4e61 6167 char buf[TASK_COMM_LEN];
dedb67c4 6168 int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN);
84d7fce6
PNA
6169
6170 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0);
6171 if (nlh == NULL)
6172 goto nla_put_failure;
6173
6174 nfmsg = nlmsg_data(nlh);
6175 nfmsg->nfgen_family = AF_UNSPEC;
6176 nfmsg->version = NFNETLINK_V0;
6177 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
6178
784b4e61
PS
6179 if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) ||
6180 nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
6181 nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
84d7fce6
PNA
6182 goto nla_put_failure;
6183
053c095a
JB
6184 nlmsg_end(skb, nlh);
6185 return 0;
84d7fce6
PNA
6186
6187nla_put_failure:
6188 nlmsg_trim(skb, nlh);
6189 return -EMSGSIZE;
6190}
6191
3b49e2e9
PNA
6192static void nft_flowtable_event(unsigned long event, struct net_device *dev,
6193 struct nft_flowtable *flowtable)
6194{
6195 int i;
6196
6197 for (i = 0; i < flowtable->ops_len; i++) {
6198 if (flowtable->ops[i].dev != dev)
6199 continue;
6200
6201 nf_unregister_net_hook(dev_net(dev), &flowtable->ops[i]);
6202 flowtable->ops[i].dev = NULL;
6203 break;
6204 }
6205}
6206
6207static int nf_tables_flowtable_event(struct notifier_block *this,
6208 unsigned long event, void *ptr)
6209{
6210 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
6211 struct nft_flowtable *flowtable;
6212 struct nft_table *table;
0a2cf5ee 6213 struct net *net;
3b49e2e9
PNA
6214
6215 if (event != NETDEV_UNREGISTER)
6216 return 0;
6217
6a48de01 6218 net = dev_net(dev);
9e619d87 6219 mutex_lock(&net->nft.commit_mutex);
0a2cf5ee 6220 list_for_each_entry(table, &net->nft.tables, list) {
36596dad
PNA
6221 list_for_each_entry(flowtable, &table->flowtables, list) {
6222 nft_flowtable_event(event, dev, flowtable);
3b49e2e9
PNA
6223 }
6224 }
9e619d87 6225 mutex_unlock(&net->nft.commit_mutex);
6a48de01 6226
3b49e2e9
PNA
6227 return NOTIFY_DONE;
6228}
6229
6230static struct notifier_block nf_tables_flowtable_notifier = {
6231 .notifier_call = nf_tables_flowtable_event,
6232};
6233
25e94a99
PNA
6234static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
6235 int event)
84d7fce6
PNA
6236{
6237 struct nlmsghdr *nlh = nlmsg_hdr(skb);
6238 struct sk_buff *skb2;
6239 int err;
6240
6241 if (nlmsg_report(nlh) &&
6242 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 6243 return;
84d7fce6 6244
84d7fce6
PNA
6245 skb2 = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
6246 if (skb2 == NULL)
6247 goto err;
6248
6249 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
6250 nlh->nlmsg_seq);
6251 if (err < 0) {
6252 kfree_skb(skb2);
6253 goto err;
6254 }
6255
25e94a99
PNA
6256 nfnetlink_send(skb2, net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
6257 nlmsg_report(nlh), GFP_KERNEL);
6258 return;
84d7fce6 6259err:
25e94a99
PNA
6260 nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
6261 -ENOBUFS);
84d7fce6
PNA
6262}
6263
7b8002a1
PNA
6264static int nf_tables_getgen(struct net *net, struct sock *nlsk,
6265 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
6266 const struct nlattr * const nla[],
6267 struct netlink_ext_ack *extack)
84d7fce6 6268{
84d7fce6
PNA
6269 struct sk_buff *skb2;
6270 int err;
6271
d9adf22a 6272 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
84d7fce6
PNA
6273 if (skb2 == NULL)
6274 return -ENOMEM;
6275
6276 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
6277 nlh->nlmsg_seq);
6278 if (err < 0)
6279 goto err;
6280
6281 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
6282err:
6283 kfree_skb(skb2);
6284 return err;
6285}
6286
96518518
PM
6287static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
6288 [NFT_MSG_NEWTABLE] = {
55dd6f93 6289 .call_batch = nf_tables_newtable,
96518518
PM
6290 .attr_count = NFTA_TABLE_MAX,
6291 .policy = nft_table_policy,
6292 },
6293 [NFT_MSG_GETTABLE] = {
d9adf22a 6294 .call_rcu = nf_tables_gettable,
96518518
PM
6295 .attr_count = NFTA_TABLE_MAX,
6296 .policy = nft_table_policy,
6297 },
6298 [NFT_MSG_DELTABLE] = {
55dd6f93 6299 .call_batch = nf_tables_deltable,
96518518
PM
6300 .attr_count = NFTA_TABLE_MAX,
6301 .policy = nft_table_policy,
6302 },
6303 [NFT_MSG_NEWCHAIN] = {
91c7b38d 6304 .call_batch = nf_tables_newchain,
96518518
PM
6305 .attr_count = NFTA_CHAIN_MAX,
6306 .policy = nft_chain_policy,
6307 },
6308 [NFT_MSG_GETCHAIN] = {
d9adf22a 6309 .call_rcu = nf_tables_getchain,
96518518
PM
6310 .attr_count = NFTA_CHAIN_MAX,
6311 .policy = nft_chain_policy,
6312 },
6313 [NFT_MSG_DELCHAIN] = {
91c7b38d 6314 .call_batch = nf_tables_delchain,
96518518
PM
6315 .attr_count = NFTA_CHAIN_MAX,
6316 .policy = nft_chain_policy,
6317 },
6318 [NFT_MSG_NEWRULE] = {
0628b123 6319 .call_batch = nf_tables_newrule,
96518518
PM
6320 .attr_count = NFTA_RULE_MAX,
6321 .policy = nft_rule_policy,
6322 },
6323 [NFT_MSG_GETRULE] = {
d9adf22a 6324 .call_rcu = nf_tables_getrule,
96518518
PM
6325 .attr_count = NFTA_RULE_MAX,
6326 .policy = nft_rule_policy,
6327 },
6328 [NFT_MSG_DELRULE] = {
0628b123 6329 .call_batch = nf_tables_delrule,
96518518
PM
6330 .attr_count = NFTA_RULE_MAX,
6331 .policy = nft_rule_policy,
6332 },
20a69341 6333 [NFT_MSG_NEWSET] = {
958bee14 6334 .call_batch = nf_tables_newset,
20a69341
PM
6335 .attr_count = NFTA_SET_MAX,
6336 .policy = nft_set_policy,
6337 },
6338 [NFT_MSG_GETSET] = {
d9adf22a 6339 .call_rcu = nf_tables_getset,
20a69341
PM
6340 .attr_count = NFTA_SET_MAX,
6341 .policy = nft_set_policy,
6342 },
6343 [NFT_MSG_DELSET] = {
958bee14 6344 .call_batch = nf_tables_delset,
20a69341
PM
6345 .attr_count = NFTA_SET_MAX,
6346 .policy = nft_set_policy,
6347 },
6348 [NFT_MSG_NEWSETELEM] = {
958bee14 6349 .call_batch = nf_tables_newsetelem,
20a69341
PM
6350 .attr_count = NFTA_SET_ELEM_LIST_MAX,
6351 .policy = nft_set_elem_list_policy,
6352 },
6353 [NFT_MSG_GETSETELEM] = {
d9adf22a 6354 .call_rcu = nf_tables_getsetelem,
20a69341
PM
6355 .attr_count = NFTA_SET_ELEM_LIST_MAX,
6356 .policy = nft_set_elem_list_policy,
6357 },
6358 [NFT_MSG_DELSETELEM] = {
958bee14 6359 .call_batch = nf_tables_delsetelem,
20a69341
PM
6360 .attr_count = NFTA_SET_ELEM_LIST_MAX,
6361 .policy = nft_set_elem_list_policy,
6362 },
84d7fce6 6363 [NFT_MSG_GETGEN] = {
d9adf22a 6364 .call_rcu = nf_tables_getgen,
84d7fce6 6365 },
e5009240
PNA
6366 [NFT_MSG_NEWOBJ] = {
6367 .call_batch = nf_tables_newobj,
6368 .attr_count = NFTA_OBJ_MAX,
6369 .policy = nft_obj_policy,
6370 },
6371 [NFT_MSG_GETOBJ] = {
d9adf22a 6372 .call_rcu = nf_tables_getobj,
e5009240
PNA
6373 .attr_count = NFTA_OBJ_MAX,
6374 .policy = nft_obj_policy,
6375 },
6376 [NFT_MSG_DELOBJ] = {
6377 .call_batch = nf_tables_delobj,
6378 .attr_count = NFTA_OBJ_MAX,
6379 .policy = nft_obj_policy,
6380 },
43da04a5 6381 [NFT_MSG_GETOBJ_RESET] = {
d9adf22a 6382 .call_rcu = nf_tables_getobj,
43da04a5
PNA
6383 .attr_count = NFTA_OBJ_MAX,
6384 .policy = nft_obj_policy,
6385 },
3b49e2e9
PNA
6386 [NFT_MSG_NEWFLOWTABLE] = {
6387 .call_batch = nf_tables_newflowtable,
6388 .attr_count = NFTA_FLOWTABLE_MAX,
6389 .policy = nft_flowtable_policy,
6390 },
6391 [NFT_MSG_GETFLOWTABLE] = {
d9adf22a 6392 .call_rcu = nf_tables_getflowtable,
3b49e2e9
PNA
6393 .attr_count = NFTA_FLOWTABLE_MAX,
6394 .policy = nft_flowtable_policy,
6395 },
6396 [NFT_MSG_DELFLOWTABLE] = {
6397 .call_batch = nf_tables_delflowtable,
6398 .attr_count = NFTA_FLOWTABLE_MAX,
6399 .policy = nft_flowtable_policy,
6400 },
96518518
PM
6401};
6402
a654de8f
PNA
6403static int nf_tables_validate(struct net *net)
6404{
6405 struct nft_table *table;
6406
6407 switch (net->nft.validate_state) {
6408 case NFT_VALIDATE_SKIP:
6409 break;
6410 case NFT_VALIDATE_NEED:
6411 nft_validate_state_update(net, NFT_VALIDATE_DO);
6412 /* fall through */
6413 case NFT_VALIDATE_DO:
6414 list_for_each_entry(table, &net->nft.tables, list) {
6415 if (nft_table_validate(net, table) < 0)
6416 return -EAGAIN;
6417 }
6418 break;
6419 }
6420
6421 return 0;
6422}
6423
66293c46
FW
6424/* a drop policy has to be deferred until all rules have been activated,
6425 * otherwise a large ruleset that contains a drop-policy base chain will
6426 * cause all packets to get dropped until the full transaction has been
6427 * processed.
6428 *
6429 * We defer the drop policy until the transaction has been finalized.
6430 */
6431static void nft_chain_commit_drop_policy(struct nft_trans *trans)
6432{
6433 struct nft_base_chain *basechain;
6434
6435 if (nft_trans_chain_policy(trans) != NF_DROP)
6436 return;
6437
6438 if (!nft_is_base_chain(trans->ctx.chain))
6439 return;
6440
6441 basechain = nft_base_chain(trans->ctx.chain);
6442 basechain->policy = NF_DROP;
6443}
6444
91c7b38d
PNA
6445static void nft_chain_commit_update(struct nft_trans *trans)
6446{
6447 struct nft_base_chain *basechain;
6448
1b2470e5
FW
6449 if (nft_trans_chain_name(trans)) {
6450 rhltable_remove(&trans->ctx.table->chains_ht,
6451 &trans->ctx.chain->rhlhead,
6452 nft_chain_ht_params);
d71efb59 6453 swap(trans->ctx.chain->name, nft_trans_chain_name(trans));
1b2470e5
FW
6454 rhltable_insert_key(&trans->ctx.table->chains_ht,
6455 trans->ctx.chain->name,
6456 &trans->ctx.chain->rhlhead,
6457 nft_chain_ht_params);
6458 }
91c7b38d 6459
f323d954 6460 if (!nft_is_base_chain(trans->ctx.chain))
91c7b38d
PNA
6461 return;
6462
53315ac6
FW
6463 nft_chain_stats_replace(trans);
6464
91c7b38d 6465 basechain = nft_base_chain(trans->ctx.chain);
91c7b38d
PNA
6466
6467 switch (nft_trans_chain_policy(trans)) {
6468 case NF_DROP:
6469 case NF_ACCEPT:
6470 basechain->policy = nft_trans_chain_policy(trans);
6471 break;
6472 }
6473}
6474
d62d0ba9
FFM
6475static void nft_obj_commit_update(struct nft_trans *trans)
6476{
6477 struct nft_object *newobj;
6478 struct nft_object *obj;
6479
6480 obj = nft_trans_obj(trans);
6481 newobj = nft_trans_obj_newobj(trans);
6482
6483 obj->ops->update(obj, newobj);
6484
6485 kfree(newobj);
6486}
6487
2f99aa31 6488static void nft_commit_release(struct nft_trans *trans)
c7c32e72 6489{
c7c32e72
PNA
6490 switch (trans->msg_type) {
6491 case NFT_MSG_DELTABLE:
6492 nf_tables_table_destroy(&trans->ctx);
6493 break;
9f8aac0b 6494 case NFT_MSG_NEWCHAIN:
53315ac6 6495 free_percpu(nft_trans_chain_stats(trans));
9f8aac0b
FW
6496 kfree(nft_trans_chain_name(trans));
6497 break;
c7c32e72 6498 case NFT_MSG_DELCHAIN:
43a605f2 6499 nf_tables_chain_destroy(&trans->ctx);
c7c32e72
PNA
6500 break;
6501 case NFT_MSG_DELRULE:
6502 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
6503 break;
6504 case NFT_MSG_DELSET:
6505 nft_set_destroy(nft_trans_set(trans));
6506 break;
61edafbb 6507 case NFT_MSG_DELSETELEM:
3453c927
PNA
6508 nf_tables_set_elem_destroy(&trans->ctx,
6509 nft_trans_elem_set(trans),
59105446 6510 nft_trans_elem(trans).priv);
61edafbb 6511 break;
e5009240 6512 case NFT_MSG_DELOBJ:
00bfb320 6513 nft_obj_destroy(&trans->ctx, nft_trans_obj(trans));
e5009240 6514 break;
3b49e2e9
PNA
6515 case NFT_MSG_DELFLOWTABLE:
6516 nf_tables_flowtable_destroy(nft_trans_flowtable(trans));
6517 break;
c7c32e72 6518 }
0935d558
FW
6519
6520 if (trans->put_net)
6521 put_net(trans->ctx.net);
6522
c7c32e72
PNA
6523 kfree(trans);
6524}
6525
0935d558 6526static void nf_tables_trans_destroy_work(struct work_struct *w)
2f99aa31
FW
6527{
6528 struct nft_trans *trans, *next;
0935d558
FW
6529 LIST_HEAD(head);
6530
6531 spin_lock(&nf_tables_destroy_list_lock);
6532 list_splice_init(&nf_tables_destroy_list, &head);
6533 spin_unlock(&nf_tables_destroy_list_lock);
2f99aa31 6534
0935d558 6535 if (list_empty(&head))
2f99aa31
FW
6536 return;
6537
6538 synchronize_rcu();
6539
0935d558 6540 list_for_each_entry_safe(trans, next, &head, list) {
2f99aa31
FW
6541 list_del(&trans->list);
6542 nft_commit_release(trans);
6543 }
6544}
6545
0cbc06b3
FW
6546static int nf_tables_commit_chain_prepare(struct net *net, struct nft_chain *chain)
6547{
6548 struct nft_rule *rule;
6549 unsigned int alloc = 0;
6550 int i;
6551
6552 /* already handled or inactive chain? */
6553 if (chain->rules_next || !nft_is_active_next(net, chain))
6554 return 0;
6555
6556 rule = list_entry(&chain->rules, struct nft_rule, list);
6557 i = 0;
6558
6559 list_for_each_entry_continue(rule, &chain->rules, list) {
6560 if (nft_is_active_next(net, rule))
6561 alloc++;
6562 }
6563
6564 chain->rules_next = nf_tables_chain_alloc_rules(chain, alloc);
6565 if (!chain->rules_next)
6566 return -ENOMEM;
6567
6568 list_for_each_entry_continue(rule, &chain->rules, list) {
6569 if (nft_is_active_next(net, rule))
6570 chain->rules_next[i++] = rule;
6571 }
6572
6573 chain->rules_next[i] = NULL;
6574 return 0;
6575}
6576
6577static void nf_tables_commit_chain_prepare_cancel(struct net *net)
6578{
6579 struct nft_trans *trans, *next;
6580
6581 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
6582 struct nft_chain *chain = trans->ctx.chain;
6583
6584 if (trans->msg_type == NFT_MSG_NEWRULE ||
6585 trans->msg_type == NFT_MSG_DELRULE) {
6586 kvfree(chain->rules_next);
6587 chain->rules_next = NULL;
6588 }
6589 }
6590}
6591
6592static void __nf_tables_commit_chain_free_rules_old(struct rcu_head *h)
6593{
6594 struct nft_rules_old *o = container_of(h, struct nft_rules_old, h);
6595
6596 kvfree(o->start);
6597}
6598
6599static void nf_tables_commit_chain_free_rules_old(struct nft_rule **rules)
6600{
6601 struct nft_rule **r = rules;
6602 struct nft_rules_old *old;
6603
6604 while (*r)
6605 r++;
6606
6607 r++; /* rcu_head is after end marker */
6608 old = (void *) r;
6609 old->start = rules;
6610
6611 call_rcu(&old->h, __nf_tables_commit_chain_free_rules_old);
6612}
6613
0fb39bbe 6614static void nf_tables_commit_chain(struct net *net, struct nft_chain *chain)
0cbc06b3
FW
6615{
6616 struct nft_rule **g0, **g1;
6617 bool next_genbit;
6618
6619 next_genbit = nft_gencursor_next(net);
6620
6621 g0 = rcu_dereference_protected(chain->rules_gen_0,
f102d66b 6622 lockdep_commit_lock_is_held(net));
0cbc06b3 6623 g1 = rcu_dereference_protected(chain->rules_gen_1,
f102d66b 6624 lockdep_commit_lock_is_held(net));
0cbc06b3
FW
6625
6626 /* No changes to this chain? */
6627 if (chain->rules_next == NULL) {
6628 /* chain had no change in last or next generation */
6629 if (g0 == g1)
6630 return;
6631 /*
6632 * chain had no change in this generation; make sure next
6633 * one uses same rules as current generation.
6634 */
6635 if (next_genbit) {
6636 rcu_assign_pointer(chain->rules_gen_1, g0);
6637 nf_tables_commit_chain_free_rules_old(g1);
6638 } else {
6639 rcu_assign_pointer(chain->rules_gen_0, g1);
6640 nf_tables_commit_chain_free_rules_old(g0);
6641 }
6642
6643 return;
6644 }
6645
6646 if (next_genbit)
6647 rcu_assign_pointer(chain->rules_gen_1, chain->rules_next);
6648 else
6649 rcu_assign_pointer(chain->rules_gen_0, chain->rules_next);
6650
6651 chain->rules_next = NULL;
6652
6653 if (g0 == g1)
6654 return;
6655
6656 if (next_genbit)
6657 nf_tables_commit_chain_free_rules_old(g1);
6658 else
6659 nf_tables_commit_chain_free_rules_old(g0);
6660}
6661
d152159b
FW
6662static void nft_obj_del(struct nft_object *obj)
6663{
4d44175a 6664 rhltable_remove(&nft_objname_ht, &obj->rhlhead, nft_objname_ht_params);
d152159b
FW
6665 list_del_rcu(&obj->list);
6666}
6667
1b2470e5
FW
6668static void nft_chain_del(struct nft_chain *chain)
6669{
6670 struct nft_table *table = chain->table;
6671
6672 WARN_ON_ONCE(rhltable_remove(&table->chains_ht, &chain->rhlhead,
6673 nft_chain_ht_params));
6674 list_del_rcu(&chain->list);
6675}
6676
0935d558
FW
6677static void nf_tables_commit_release(struct net *net)
6678{
6679 struct nft_trans *trans;
6680
6681 /* all side effects have to be made visible.
6682 * For example, if a chain named 'foo' has been deleted, a
6683 * new transaction must not find it anymore.
6684 *
6685 * Memory reclaim happens asynchronously from work queue
6686 * to prevent expensive synchronize_rcu() in commit phase.
6687 */
6688 if (list_empty(&net->nft.commit_list)) {
6689 mutex_unlock(&net->nft.commit_mutex);
6690 return;
6691 }
6692
6693 trans = list_last_entry(&net->nft.commit_list,
6694 struct nft_trans, list);
6695 get_net(trans->ctx.net);
6696 WARN_ON_ONCE(trans->put_net);
6697
6698 trans->put_net = true;
6699 spin_lock(&nf_tables_destroy_list_lock);
6700 list_splice_tail_init(&net->nft.commit_list, &nf_tables_destroy_list);
6701 spin_unlock(&nf_tables_destroy_list_lock);
6702
6703 mutex_unlock(&net->nft.commit_mutex);
6704
6705 schedule_work(&trans_destroy_work);
6706}
6707
5913beaf 6708static int nf_tables_commit(struct net *net, struct sk_buff *skb)
37082f93 6709{
37082f93 6710 struct nft_trans *trans, *next;
a3716e70 6711 struct nft_trans_elem *te;
0cbc06b3
FW
6712 struct nft_chain *chain;
6713 struct nft_table *table;
c9626a2c 6714 int err;
37082f93 6715
b8b27498
FW
6716 if (list_empty(&net->nft.commit_list)) {
6717 mutex_unlock(&net->nft.commit_mutex);
6718 return 0;
6719 }
6720
a654de8f
PNA
6721 /* 0. Validate ruleset, otherwise roll back for error reporting. */
6722 if (nf_tables_validate(net) < 0)
6723 return -EAGAIN;
6724
c9626a2c
PNA
6725 err = nft_flow_rule_offload_commit(net);
6726 if (err < 0)
6727 return err;
6728
0cbc06b3
FW
6729 /* 1. Allocate space for next generation rules_gen_X[] */
6730 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
6731 int ret;
37082f93 6732
0cbc06b3
FW
6733 if (trans->msg_type == NFT_MSG_NEWRULE ||
6734 trans->msg_type == NFT_MSG_DELRULE) {
6735 chain = trans->ctx.chain;
6736
6737 ret = nf_tables_commit_chain_prepare(net, chain);
6738 if (ret < 0) {
6739 nf_tables_commit_chain_prepare_cancel(net);
6740 return ret;
6741 }
6742 }
6743 }
37082f93 6744
0cbc06b3
FW
6745 /* step 2. Make rules_gen_X visible to packet path */
6746 list_for_each_entry(table, &net->nft.tables, list) {
0fb39bbe
FW
6747 list_for_each_entry(chain, &table->chains, list)
6748 nf_tables_commit_chain(net, chain);
0cbc06b3
FW
6749 }
6750
6751 /*
6752 * Bump generation counter, invalidate any dump in progress.
6753 * Cannot fail after this point.
37082f93 6754 */
0cbc06b3
FW
6755 while (++net->nft.base_seq == 0);
6756
6757 /* step 3. Start new generation, rules_gen_X now in use. */
6758 net->nft.gencursor = nft_gencursor_next(net);
37082f93
PNA
6759
6760 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
b380e5c7 6761 switch (trans->msg_type) {
55dd6f93
PNA
6762 case NFT_MSG_NEWTABLE:
6763 if (nft_trans_table_update(trans)) {
6764 if (!nft_trans_table_enable(trans)) {
664b0f8c 6765 nf_tables_table_disable(net,
55dd6f93
PNA
6766 trans->ctx.table);
6767 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
6768 }
6769 } else {
f2a6d766 6770 nft_clear(net, trans->ctx.table);
55dd6f93 6771 }
35151d84 6772 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
55dd6f93
PNA
6773 nft_trans_destroy(trans);
6774 break;
6775 case NFT_MSG_DELTABLE:
f2a6d766 6776 list_del_rcu(&trans->ctx.table->list);
35151d84 6777 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
55dd6f93 6778 break;
91c7b38d 6779 case NFT_MSG_NEWCHAIN:
9f8aac0b 6780 if (nft_trans_chain_update(trans)) {
91c7b38d 6781 nft_chain_commit_update(trans);
9f8aac0b
FW
6782 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
6783 /* trans destroyed after rcu grace period */
6784 } else {
66293c46 6785 nft_chain_commit_drop_policy(trans);
664b0f8c 6786 nft_clear(net, trans->ctx.chain);
9f8aac0b
FW
6787 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
6788 nft_trans_destroy(trans);
6789 }
91c7b38d
PNA
6790 break;
6791 case NFT_MSG_DELCHAIN:
1b2470e5 6792 nft_chain_del(trans->ctx.chain);
35151d84 6793 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
c974a3a3
PNA
6794 nf_tables_unregister_hook(trans->ctx.net,
6795 trans->ctx.table,
6796 trans->ctx.chain);
91c7b38d 6797 break;
b380e5c7 6798 case NFT_MSG_NEWRULE:
889f7ee7 6799 nft_clear(trans->ctx.net, nft_trans_rule(trans));
35151d84 6800 nf_tables_rule_notify(&trans->ctx,
37082f93 6801 nft_trans_rule(trans),
35151d84 6802 NFT_MSG_NEWRULE);
37082f93 6803 nft_trans_destroy(trans);
b380e5c7
PNA
6804 break;
6805 case NFT_MSG_DELRULE:
6806 list_del_rcu(&nft_trans_rule(trans)->list);
35151d84
PNA
6807 nf_tables_rule_notify(&trans->ctx,
6808 nft_trans_rule(trans),
6809 NFT_MSG_DELRULE);
f6ac8585
PNA
6810 nft_rule_expr_deactivate(&trans->ctx,
6811 nft_trans_rule(trans),
6812 NFT_TRANS_COMMIT);
b380e5c7 6813 break;
958bee14 6814 case NFT_MSG_NEWSET:
37a9cc52 6815 nft_clear(net, nft_trans_set(trans));
4fefee57
PNA
6816 /* This avoids hitting -EBUSY when deleting the table
6817 * from the transaction.
6818 */
408070d6 6819 if (nft_set_is_anonymous(nft_trans_set(trans)) &&
4fefee57
PNA
6820 !list_empty(&nft_trans_set(trans)->bindings))
6821 trans->ctx.table->use--;
6822
958bee14 6823 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 6824 NFT_MSG_NEWSET, GFP_KERNEL);
958bee14
PNA
6825 nft_trans_destroy(trans);
6826 break;
6827 case NFT_MSG_DELSET:
37a9cc52 6828 list_del_rcu(&nft_trans_set(trans)->list);
958bee14 6829 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 6830 NFT_MSG_DELSET, GFP_KERNEL);
958bee14 6831 break;
60319eb1 6832 case NFT_MSG_NEWSETELEM:
cc02e457
PM
6833 te = (struct nft_trans_elem *)trans->data;
6834
42a55769 6835 te->set->ops->activate(net, te->set, &te->elem);
cc02e457
PM
6836 nf_tables_setelem_notify(&trans->ctx, te->set,
6837 &te->elem,
60319eb1
PNA
6838 NFT_MSG_NEWSETELEM, 0);
6839 nft_trans_destroy(trans);
6840 break;
6841 case NFT_MSG_DELSETELEM:
a3716e70 6842 te = (struct nft_trans_elem *)trans->data;
fe2811eb 6843
a3716e70
PNA
6844 nf_tables_setelem_notify(&trans->ctx, te->set,
6845 &te->elem,
60319eb1 6846 NFT_MSG_DELSETELEM, 0);
5cb82a38 6847 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a
PM
6848 atomic_dec(&te->set->nelems);
6849 te->set->ndeact--;
60319eb1 6850 break;
e5009240 6851 case NFT_MSG_NEWOBJ:
d62d0ba9
FFM
6852 if (nft_trans_obj_update(trans)) {
6853 nft_obj_commit_update(trans);
6854 nf_tables_obj_notify(&trans->ctx,
6855 nft_trans_obj(trans),
6856 NFT_MSG_NEWOBJ);
6857 } else {
6858 nft_clear(net, nft_trans_obj(trans));
6859 nf_tables_obj_notify(&trans->ctx,
6860 nft_trans_obj(trans),
6861 NFT_MSG_NEWOBJ);
6862 nft_trans_destroy(trans);
6863 }
e5009240
PNA
6864 break;
6865 case NFT_MSG_DELOBJ:
d152159b 6866 nft_obj_del(nft_trans_obj(trans));
e5009240
PNA
6867 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
6868 NFT_MSG_DELOBJ);
6869 break;
3b49e2e9
PNA
6870 case NFT_MSG_NEWFLOWTABLE:
6871 nft_clear(net, nft_trans_flowtable(trans));
6872 nf_tables_flowtable_notify(&trans->ctx,
6873 nft_trans_flowtable(trans),
6874 NFT_MSG_NEWFLOWTABLE);
6875 nft_trans_destroy(trans);
6876 break;
6877 case NFT_MSG_DELFLOWTABLE:
6878 list_del_rcu(&nft_trans_flowtable(trans)->list);
6879 nf_tables_flowtable_notify(&trans->ctx,
6880 nft_trans_flowtable(trans),
6881 NFT_MSG_DELFLOWTABLE);
6882 nft_unregister_flowtable_net_hooks(net,
6883 nft_trans_flowtable(trans));
6884 break;
37082f93 6885 }
37082f93
PNA
6886 }
6887
84d7fce6 6888 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
0935d558 6889 nf_tables_commit_release(net);
37082f93
PNA
6890
6891 return 0;
6892}
6893
b326dd37 6894static void nf_tables_abort_release(struct nft_trans *trans)
c7c32e72 6895{
c7c32e72
PNA
6896 switch (trans->msg_type) {
6897 case NFT_MSG_NEWTABLE:
6898 nf_tables_table_destroy(&trans->ctx);
6899 break;
6900 case NFT_MSG_NEWCHAIN:
43a605f2 6901 nf_tables_chain_destroy(&trans->ctx);
c7c32e72
PNA
6902 break;
6903 case NFT_MSG_NEWRULE:
6904 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
6905 break;
6906 case NFT_MSG_NEWSET:
40ba1d9b 6907 nft_set_destroy(nft_trans_set(trans));
c7c32e72 6908 break;
61edafbb
PM
6909 case NFT_MSG_NEWSETELEM:
6910 nft_set_elem_destroy(nft_trans_elem_set(trans),
61f9e292 6911 nft_trans_elem(trans).priv, true);
61edafbb 6912 break;
e5009240 6913 case NFT_MSG_NEWOBJ:
00bfb320 6914 nft_obj_destroy(&trans->ctx, nft_trans_obj(trans));
e5009240 6915 break;
3b49e2e9
PNA
6916 case NFT_MSG_NEWFLOWTABLE:
6917 nf_tables_flowtable_destroy(nft_trans_flowtable(trans));
6918 break;
c7c32e72
PNA
6919 }
6920 kfree(trans);
6921}
6922
71ad00c5 6923static int __nf_tables_abort(struct net *net)
37082f93 6924{
37082f93 6925 struct nft_trans *trans, *next;
02263db0 6926 struct nft_trans_elem *te;
37082f93 6927
a907e36d
XL
6928 list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
6929 list) {
b380e5c7 6930 switch (trans->msg_type) {
55dd6f93
PNA
6931 case NFT_MSG_NEWTABLE:
6932 if (nft_trans_table_update(trans)) {
6933 if (nft_trans_table_enable(trans)) {
664b0f8c 6934 nf_tables_table_disable(net,
55dd6f93
PNA
6935 trans->ctx.table);
6936 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
6937 }
6938 nft_trans_destroy(trans);
6939 } else {
e688a7f8 6940 list_del_rcu(&trans->ctx.table->list);
55dd6f93
PNA
6941 }
6942 break;
6943 case NFT_MSG_DELTABLE:
f2a6d766 6944 nft_clear(trans->ctx.net, trans->ctx.table);
55dd6f93
PNA
6945 nft_trans_destroy(trans);
6946 break;
91c7b38d
PNA
6947 case NFT_MSG_NEWCHAIN:
6948 if (nft_trans_chain_update(trans)) {
982f4051 6949 free_percpu(nft_trans_chain_stats(trans));
9f8aac0b 6950 kfree(nft_trans_chain_name(trans));
91c7b38d
PNA
6951 nft_trans_destroy(trans);
6952 } else {
4fefee57 6953 trans->ctx.table->use--;
1b2470e5 6954 nft_chain_del(trans->ctx.chain);
c974a3a3
PNA
6955 nf_tables_unregister_hook(trans->ctx.net,
6956 trans->ctx.table,
6957 trans->ctx.chain);
91c7b38d
PNA
6958 }
6959 break;
6960 case NFT_MSG_DELCHAIN:
4fefee57 6961 trans->ctx.table->use++;
664b0f8c 6962 nft_clear(trans->ctx.net, trans->ctx.chain);
91c7b38d
PNA
6963 nft_trans_destroy(trans);
6964 break;
b380e5c7 6965 case NFT_MSG_NEWRULE:
4fefee57 6966 trans->ctx.chain->use--;
b380e5c7 6967 list_del_rcu(&nft_trans_rule(trans)->list);
f6ac8585
PNA
6968 nft_rule_expr_deactivate(&trans->ctx,
6969 nft_trans_rule(trans),
6970 NFT_TRANS_ABORT);
b380e5c7
PNA
6971 break;
6972 case NFT_MSG_DELRULE:
4fefee57 6973 trans->ctx.chain->use++;
889f7ee7 6974 nft_clear(trans->ctx.net, nft_trans_rule(trans));
bb7b40ae 6975 nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
37082f93 6976 nft_trans_destroy(trans);
b380e5c7 6977 break;
958bee14 6978 case NFT_MSG_NEWSET:
4fefee57 6979 trans->ctx.table->use--;
6a0a8d10 6980 if (nft_trans_set_bound(trans)) {
40ba1d9b
PNA
6981 nft_trans_destroy(trans);
6982 break;
6983 }
6984 list_del_rcu(&nft_trans_set(trans)->list);
958bee14
PNA
6985 break;
6986 case NFT_MSG_DELSET:
4fefee57 6987 trans->ctx.table->use++;
37a9cc52 6988 nft_clear(trans->ctx.net, nft_trans_set(trans));
958bee14
PNA
6989 nft_trans_destroy(trans);
6990 break;
60319eb1 6991 case NFT_MSG_NEWSETELEM:
6a0a8d10 6992 if (nft_trans_elem_set_bound(trans)) {
40ba1d9b
PNA
6993 nft_trans_destroy(trans);
6994 break;
6995 }
02263db0 6996 te = (struct nft_trans_elem *)trans->data;
5cb82a38 6997 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a 6998 atomic_dec(&te->set->nelems);
60319eb1
PNA
6999 break;
7000 case NFT_MSG_DELSETELEM:
cc02e457
PM
7001 te = (struct nft_trans_elem *)trans->data;
7002
59105446 7003 nft_set_elem_activate(net, te->set, &te->elem);
42a55769 7004 te->set->ops->activate(net, te->set, &te->elem);
3dd0673a 7005 te->set->ndeact--;
cc02e457 7006
e5009240
PNA
7007 nft_trans_destroy(trans);
7008 break;
7009 case NFT_MSG_NEWOBJ:
d62d0ba9
FFM
7010 if (nft_trans_obj_update(trans)) {
7011 kfree(nft_trans_obj_newobj(trans));
7012 nft_trans_destroy(trans);
7013 } else {
7014 trans->ctx.table->use--;
7015 nft_obj_del(nft_trans_obj(trans));
7016 }
e5009240
PNA
7017 break;
7018 case NFT_MSG_DELOBJ:
7019 trans->ctx.table->use++;
7020 nft_clear(trans->ctx.net, nft_trans_obj(trans));
60319eb1
PNA
7021 nft_trans_destroy(trans);
7022 break;
3b49e2e9
PNA
7023 case NFT_MSG_NEWFLOWTABLE:
7024 trans->ctx.table->use--;
7025 list_del_rcu(&nft_trans_flowtable(trans)->list);
7026 nft_unregister_flowtable_net_hooks(net,
7027 nft_trans_flowtable(trans));
7028 break;
7029 case NFT_MSG_DELFLOWTABLE:
7030 trans->ctx.table->use++;
7031 nft_clear(trans->ctx.net, nft_trans_flowtable(trans));
7032 nft_trans_destroy(trans);
7033 break;
37082f93 7034 }
37082f93
PNA
7035 }
7036
b326dd37
PNA
7037 synchronize_rcu();
7038
a1cee076
PNA
7039 list_for_each_entry_safe_reverse(trans, next,
7040 &net->nft.commit_list, list) {
c7c32e72 7041 list_del(&trans->list);
b326dd37 7042 nf_tables_abort_release(trans);
37082f93
PNA
7043 }
7044
7045 return 0;
7046}
7047
a654de8f
PNA
7048static void nf_tables_cleanup(struct net *net)
7049{
7050 nft_validate_state_update(net, NFT_VALIDATE_SKIP);
7051}
7052
71ad00c5
FW
7053static int nf_tables_abort(struct net *net, struct sk_buff *skb)
7054{
f102d66b
FW
7055 int ret = __nf_tables_abort(net);
7056
7057 mutex_unlock(&net->nft.commit_mutex);
7058
7059 return ret;
71ad00c5
FW
7060}
7061
74e8bcd2
PNA
7062static bool nf_tables_valid_genid(struct net *net, u32 genid)
7063{
f102d66b
FW
7064 bool genid_ok;
7065
7066 mutex_lock(&net->nft.commit_mutex);
7067
7068 genid_ok = genid == 0 || net->nft.base_seq == genid;
7069 if (!genid_ok)
7070 mutex_unlock(&net->nft.commit_mutex);
7071
7072 /* else, commit mutex has to be released by commit or abort function */
7073 return genid_ok;
74e8bcd2
PNA
7074}
7075
96518518
PM
7076static const struct nfnetlink_subsystem nf_tables_subsys = {
7077 .name = "nf_tables",
7078 .subsys_id = NFNL_SUBSYS_NFTABLES,
7079 .cb_count = NFT_MSG_MAX,
7080 .cb = nf_tables_cb,
0628b123
PNA
7081 .commit = nf_tables_commit,
7082 .abort = nf_tables_abort,
a654de8f 7083 .cleanup = nf_tables_cleanup,
74e8bcd2 7084 .valid_genid = nf_tables_valid_genid,
be2ab5b4 7085 .owner = THIS_MODULE,
96518518
PM
7086};
7087
7210e4e3 7088int nft_chain_validate_dependency(const struct nft_chain *chain,
32537e91 7089 enum nft_chain_types type)
7210e4e3
PNA
7090{
7091 const struct nft_base_chain *basechain;
7092
f323d954 7093 if (nft_is_base_chain(chain)) {
7210e4e3
PNA
7094 basechain = nft_base_chain(chain);
7095 if (basechain->type->type != type)
7096 return -EOPNOTSUPP;
7097 }
7098 return 0;
7099}
7100EXPORT_SYMBOL_GPL(nft_chain_validate_dependency);
7101
75e8d06d
PNA
7102int nft_chain_validate_hooks(const struct nft_chain *chain,
7103 unsigned int hook_flags)
7104{
7105 struct nft_base_chain *basechain;
7106
f323d954 7107 if (nft_is_base_chain(chain)) {
75e8d06d
PNA
7108 basechain = nft_base_chain(chain);
7109
c974a3a3 7110 if ((1 << basechain->ops.hooknum) & hook_flags)
75e8d06d
PNA
7111 return 0;
7112
7113 return -EOPNOTSUPP;
7114 }
7115
7116 return 0;
7117}
7118EXPORT_SYMBOL_GPL(nft_chain_validate_hooks);
7119
20a69341
PM
7120/*
7121 * Loop detection - walk through the ruleset beginning at the destination chain
7122 * of a new jump until either the source chain is reached (loop) or all
7123 * reachable chains have been traversed.
7124 *
7125 * The loop check is performed whenever a new jump verdict is added to an
7126 * expression or verdict map or a verdict map is bound to a new chain.
7127 */
7128
7129static int nf_tables_check_loops(const struct nft_ctx *ctx,
7130 const struct nft_chain *chain);
7131
7132static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
de70185d 7133 struct nft_set *set,
20a69341 7134 const struct nft_set_iter *iter,
de70185d 7135 struct nft_set_elem *elem)
20a69341 7136{
fe2811eb
PM
7137 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
7138 const struct nft_data *data;
7139
7140 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
7141 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
62f9c8b4
PNA
7142 return 0;
7143
fe2811eb 7144 data = nft_set_ext_data(ext);
1ca2e170 7145 switch (data->verdict.code) {
20a69341
PM
7146 case NFT_JUMP:
7147 case NFT_GOTO:
1ca2e170 7148 return nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
7149 default:
7150 return 0;
7151 }
7152}
7153
7154static int nf_tables_check_loops(const struct nft_ctx *ctx,
7155 const struct nft_chain *chain)
7156{
7157 const struct nft_rule *rule;
7158 const struct nft_expr *expr, *last;
de70185d 7159 struct nft_set *set;
20a69341
PM
7160 struct nft_set_binding *binding;
7161 struct nft_set_iter iter;
20a69341
PM
7162
7163 if (ctx->chain == chain)
7164 return -ELOOP;
7165
7166 list_for_each_entry(rule, &chain->rules, list) {
7167 nft_rule_for_each_expr(expr, last, rule) {
a654de8f
PNA
7168 struct nft_immediate_expr *priv;
7169 const struct nft_data *data;
0ca743a5
PNA
7170 int err;
7171
a654de8f 7172 if (strcmp(expr->ops->type->name, "immediate"))
20a69341
PM
7173 continue;
7174
a654de8f
PNA
7175 priv = nft_expr_priv(expr);
7176 if (priv->dreg != NFT_REG_VERDICT)
0ca743a5 7177 continue;
20a69341 7178
a654de8f 7179 data = &priv->data;
1ca2e170 7180 switch (data->verdict.code) {
20a69341
PM
7181 case NFT_JUMP:
7182 case NFT_GOTO:
1ca2e170
PM
7183 err = nf_tables_check_loops(ctx,
7184 data->verdict.chain);
20a69341
PM
7185 if (err < 0)
7186 return err;
7187 default:
7188 break;
7189 }
7190 }
7191 }
7192
7193 list_for_each_entry(set, &ctx->table->sets, list) {
37a9cc52
PNA
7194 if (!nft_is_active_next(ctx->net, set))
7195 continue;
20a69341
PM
7196 if (!(set->flags & NFT_SET_MAP) ||
7197 set->dtype != NFT_DATA_VERDICT)
7198 continue;
7199
7200 list_for_each_entry(binding, &set->bindings, list) {
11113e19
PM
7201 if (!(binding->flags & NFT_SET_MAP) ||
7202 binding->chain != chain)
20a69341
PM
7203 continue;
7204
8588ac09 7205 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
7206 iter.skip = 0;
7207 iter.count = 0;
7208 iter.err = 0;
7209 iter.fn = nf_tables_loop_check_setelem;
7210
7211 set->ops->walk(ctx, set, &iter);
7212 if (iter.err < 0)
7213 return iter.err;
7214 }
7215 }
7216
7217 return 0;
7218}
7219
36b701fa
LGL
7220/**
7221 * nft_parse_u32_check - fetch u32 attribute and check for maximum value
7222 *
7223 * @attr: netlink attribute to fetch value from
7224 * @max: maximum value to be stored in dest
7225 * @dest: pointer to the variable
7226 *
7227 * Parse, check and store a given u32 netlink attribute into variable.
7228 * This function returns -ERANGE if the value goes over maximum value.
7229 * Otherwise a 0 is returned and the attribute value is stored in the
7230 * destination variable.
7231 */
f1d505bb 7232int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
36b701fa 7233{
09525a09 7234 u32 val;
36b701fa
LGL
7235
7236 val = ntohl(nla_get_be32(attr));
7237 if (val > max)
7238 return -ERANGE;
7239
7240 *dest = val;
7241 return 0;
7242}
7243EXPORT_SYMBOL_GPL(nft_parse_u32_check);
7244
49499c3e
PM
7245/**
7246 * nft_parse_register - parse a register value from a netlink attribute
7247 *
7248 * @attr: netlink attribute
7249 *
7250 * Parse and translate a register value from a netlink attribute.
7251 * Registers used to be 128 bit wide, these register numbers will be
7252 * mapped to the corresponding 32 bit register numbers.
7253 */
b1c96ed3
PM
7254unsigned int nft_parse_register(const struct nlattr *attr)
7255{
49499c3e
PM
7256 unsigned int reg;
7257
7258 reg = ntohl(nla_get_be32(attr));
7259 switch (reg) {
7260 case NFT_REG_VERDICT...NFT_REG_4:
7261 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
7262 default:
7263 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
7264 }
b1c96ed3
PM
7265}
7266EXPORT_SYMBOL_GPL(nft_parse_register);
7267
49499c3e
PM
7268/**
7269 * nft_dump_register - dump a register value to a netlink attribute
7270 *
7271 * @skb: socket buffer
7272 * @attr: attribute number
7273 * @reg: register number
7274 *
7275 * Construct a netlink attribute containing the register number. For
7276 * compatibility reasons, register numbers being a multiple of 4 are
7277 * translated to the corresponding 128 bit register numbers.
7278 */
b1c96ed3
PM
7279int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
7280{
49499c3e
PM
7281 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
7282 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
7283 else
7284 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
7285
b1c96ed3
PM
7286 return nla_put_be32(skb, attr, htonl(reg));
7287}
7288EXPORT_SYMBOL_GPL(nft_dump_register);
7289
96518518 7290/**
d07db988 7291 * nft_validate_register_load - validate a load from a register
96518518
PM
7292 *
7293 * @reg: the register number
d07db988 7294 * @len: the length of the data
96518518
PM
7295 *
7296 * Validate that the input register is one of the general purpose
d07db988 7297 * registers and that the length of the load is within the bounds.
96518518 7298 */
d07db988 7299int nft_validate_register_load(enum nft_registers reg, unsigned int len)
96518518 7300{
49499c3e 7301 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
96518518 7302 return -EINVAL;
d07db988
PM
7303 if (len == 0)
7304 return -EINVAL;
49499c3e 7305 if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
d07db988 7306 return -ERANGE;
49499c3e 7307
96518518
PM
7308 return 0;
7309}
d07db988 7310EXPORT_SYMBOL_GPL(nft_validate_register_load);
96518518 7311
96518518 7312/**
1ec10212 7313 * nft_validate_register_store - validate an expressions' register store
96518518
PM
7314 *
7315 * @ctx: context of the expression performing the load
7316 * @reg: the destination register number
7317 * @data: the data to load
7318 * @type: the data type
45d9bcda 7319 * @len: the length of the data
96518518
PM
7320 *
7321 * Validate that a data load uses the appropriate data type for
45d9bcda
PM
7322 * the destination register and the length is within the bounds.
7323 * A value of NULL for the data means that its runtime gathered
58f40ab6 7324 * data.
96518518 7325 */
1ec10212
PM
7326int nft_validate_register_store(const struct nft_ctx *ctx,
7327 enum nft_registers reg,
7328 const struct nft_data *data,
7329 enum nft_data_types type, unsigned int len)
96518518 7330{
20a69341
PM
7331 int err;
7332
96518518
PM
7333 switch (reg) {
7334 case NFT_REG_VERDICT:
58f40ab6 7335 if (type != NFT_DATA_VERDICT)
96518518 7336 return -EINVAL;
20a69341 7337
58f40ab6 7338 if (data != NULL &&
1ca2e170
PM
7339 (data->verdict.code == NFT_GOTO ||
7340 data->verdict.code == NFT_JUMP)) {
7341 err = nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
7342 if (err < 0)
7343 return err;
20a69341
PM
7344 }
7345
96518518
PM
7346 return 0;
7347 default:
49499c3e 7348 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
27e6d201 7349 return -EINVAL;
45d9bcda
PM
7350 if (len == 0)
7351 return -EINVAL;
49499c3e
PM
7352 if (reg * NFT_REG32_SIZE + len >
7353 FIELD_SIZEOF(struct nft_regs, data))
45d9bcda 7354 return -ERANGE;
27e6d201 7355
96518518
PM
7356 if (data != NULL && type != NFT_DATA_VALUE)
7357 return -EINVAL;
7358 return 0;
7359 }
7360}
1ec10212 7361EXPORT_SYMBOL_GPL(nft_validate_register_store);
96518518
PM
7362
7363static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
7364 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
7365 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
7366 .len = NFT_CHAIN_MAXNAMELEN - 1 },
7367};
7368
7369static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
7370 struct nft_data_desc *desc, const struct nlattr *nla)
7371{
664b0f8c 7372 u8 genmask = nft_genmask_next(ctx->net);
96518518
PM
7373 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
7374 struct nft_chain *chain;
7375 int err;
7376
8cb08174
JB
7377 err = nla_parse_nested_deprecated(tb, NFTA_VERDICT_MAX, nla,
7378 nft_verdict_policy, NULL);
96518518
PM
7379 if (err < 0)
7380 return err;
7381
7382 if (!tb[NFTA_VERDICT_CODE])
7383 return -EINVAL;
1ca2e170 7384 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
96518518 7385
1ca2e170 7386 switch (data->verdict.code) {
e0abdadc 7387 default:
1ca2e170 7388 switch (data->verdict.code & NF_VERDICT_MASK) {
e0abdadc
PM
7389 case NF_ACCEPT:
7390 case NF_DROP:
7391 case NF_QUEUE:
7392 break;
7393 default:
7394 return -EINVAL;
7395 }
7396 /* fall through */
96518518
PM
7397 case NFT_CONTINUE:
7398 case NFT_BREAK:
7399 case NFT_RETURN:
96518518
PM
7400 break;
7401 case NFT_JUMP:
7402 case NFT_GOTO:
7403 if (!tb[NFTA_VERDICT_CHAIN])
7404 return -EINVAL;
f102d66b
FW
7405 chain = nft_chain_lookup(ctx->net, ctx->table,
7406 tb[NFTA_VERDICT_CHAIN], genmask);
96518518
PM
7407 if (IS_ERR(chain))
7408 return PTR_ERR(chain);
f323d954 7409 if (nft_is_base_chain(chain))
96518518
PM
7410 return -EOPNOTSUPP;
7411
96518518 7412 chain->use++;
1ca2e170 7413 data->verdict.chain = chain;
96518518 7414 break;
96518518
PM
7415 }
7416
4c4ed074 7417 desc->len = sizeof(data->verdict);
96518518
PM
7418 desc->type = NFT_DATA_VERDICT;
7419 return 0;
7420}
7421
7422static void nft_verdict_uninit(const struct nft_data *data)
7423{
1ca2e170 7424 switch (data->verdict.code) {
96518518
PM
7425 case NFT_JUMP:
7426 case NFT_GOTO:
1ca2e170 7427 data->verdict.chain->use--;
96518518
PM
7428 break;
7429 }
7430}
7431
33d5a7b1 7432int nft_verdict_dump(struct sk_buff *skb, int type, const struct nft_verdict *v)
96518518
PM
7433{
7434 struct nlattr *nest;
7435
ae0be8de 7436 nest = nla_nest_start_noflag(skb, type);
96518518
PM
7437 if (!nest)
7438 goto nla_put_failure;
7439
33d5a7b1 7440 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(v->code)))
96518518
PM
7441 goto nla_put_failure;
7442
33d5a7b1 7443 switch (v->code) {
96518518
PM
7444 case NFT_JUMP:
7445 case NFT_GOTO:
1ca2e170 7446 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
33d5a7b1 7447 v->chain->name))
96518518
PM
7448 goto nla_put_failure;
7449 }
7450 nla_nest_end(skb, nest);
7451 return 0;
7452
7453nla_put_failure:
7454 return -1;
7455}
7456
d0a11fc3
PM
7457static int nft_value_init(const struct nft_ctx *ctx,
7458 struct nft_data *data, unsigned int size,
96518518
PM
7459 struct nft_data_desc *desc, const struct nlattr *nla)
7460{
7461 unsigned int len;
7462
7463 len = nla_len(nla);
7464 if (len == 0)
7465 return -EINVAL;
d0a11fc3 7466 if (len > size)
96518518
PM
7467 return -EOVERFLOW;
7468
d0a11fc3 7469 nla_memcpy(data->data, nla, len);
96518518
PM
7470 desc->type = NFT_DATA_VALUE;
7471 desc->len = len;
7472 return 0;
7473}
7474
7475static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
7476 unsigned int len)
7477{
7478 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
7479}
7480
7481static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
d0a11fc3 7482 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
96518518
PM
7483 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
7484};
7485
7486/**
7487 * nft_data_init - parse nf_tables data netlink attributes
7488 *
7489 * @ctx: context of the expression using the data
7490 * @data: destination struct nft_data
d0a11fc3 7491 * @size: maximum data length
96518518
PM
7492 * @desc: data description
7493 * @nla: netlink attribute containing data
7494 *
7495 * Parse the netlink data attributes and initialize a struct nft_data.
7496 * The type and length of data are returned in the data description.
7497 *
7498 * The caller can indicate that it only wants to accept data of type
7499 * NFT_DATA_VALUE by passing NULL for the ctx argument.
7500 */
d0a11fc3
PM
7501int nft_data_init(const struct nft_ctx *ctx,
7502 struct nft_data *data, unsigned int size,
96518518
PM
7503 struct nft_data_desc *desc, const struct nlattr *nla)
7504{
7505 struct nlattr *tb[NFTA_DATA_MAX + 1];
7506 int err;
7507
8cb08174
JB
7508 err = nla_parse_nested_deprecated(tb, NFTA_DATA_MAX, nla,
7509 nft_data_policy, NULL);
96518518
PM
7510 if (err < 0)
7511 return err;
7512
7513 if (tb[NFTA_DATA_VALUE])
d0a11fc3
PM
7514 return nft_value_init(ctx, data, size, desc,
7515 tb[NFTA_DATA_VALUE]);
96518518
PM
7516 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
7517 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
7518 return -EINVAL;
7519}
7520EXPORT_SYMBOL_GPL(nft_data_init);
7521
7522/**
59105446 7523 * nft_data_release - release a nft_data item
96518518
PM
7524 *
7525 * @data: struct nft_data to release
7526 * @type: type of data
7527 *
7528 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
7529 * all others need to be released by calling this function.
7530 */
59105446 7531void nft_data_release(const struct nft_data *data, enum nft_data_types type)
96518518 7532{
960bd2c2 7533 if (type < NFT_DATA_VERDICT)
96518518 7534 return;
960bd2c2 7535 switch (type) {
96518518
PM
7536 case NFT_DATA_VERDICT:
7537 return nft_verdict_uninit(data);
7538 default:
7539 WARN_ON(1);
7540 }
7541}
59105446 7542EXPORT_SYMBOL_GPL(nft_data_release);
96518518
PM
7543
7544int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
7545 enum nft_data_types type, unsigned int len)
7546{
7547 struct nlattr *nest;
7548 int err;
7549
ae0be8de 7550 nest = nla_nest_start_noflag(skb, attr);
96518518
PM
7551 if (nest == NULL)
7552 return -1;
7553
7554 switch (type) {
7555 case NFT_DATA_VALUE:
7556 err = nft_value_dump(skb, data, len);
7557 break;
7558 case NFT_DATA_VERDICT:
33d5a7b1 7559 err = nft_verdict_dump(skb, NFTA_DATA_VERDICT, &data->verdict);
96518518
PM
7560 break;
7561 default:
7562 err = -EINVAL;
7563 WARN_ON(1);
7564 }
7565
7566 nla_nest_end(skb, nest);
7567 return err;
7568}
7569EXPORT_SYMBOL_GPL(nft_data_dump);
7570
5ebe0b0e
PNA
7571int __nft_release_basechain(struct nft_ctx *ctx)
7572{
7573 struct nft_rule *rule, *nr;
7574
fa5950e4
FW
7575 if (WARN_ON(!nft_is_base_chain(ctx->chain)))
7576 return 0;
5ebe0b0e 7577
c974a3a3 7578 nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
5ebe0b0e
PNA
7579 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
7580 list_del(&rule->list);
7581 ctx->chain->use--;
bb7b40ae 7582 nf_tables_rule_release(ctx, rule);
5ebe0b0e 7583 }
1b2470e5 7584 nft_chain_del(ctx->chain);
5ebe0b0e 7585 ctx->table->use--;
43a605f2 7586 nf_tables_chain_destroy(ctx);
5ebe0b0e
PNA
7587
7588 return 0;
7589}
7590EXPORT_SYMBOL_GPL(__nft_release_basechain);
7591
98319cb9 7592static void __nft_release_tables(struct net *net)
df05ef87 7593{
3b49e2e9 7594 struct nft_flowtable *flowtable, *nf;
df05ef87
PNA
7595 struct nft_table *table, *nt;
7596 struct nft_chain *chain, *nc;
e5009240 7597 struct nft_object *obj, *ne;
df05ef87
PNA
7598 struct nft_rule *rule, *nr;
7599 struct nft_set *set, *ns;
7600 struct nft_ctx ctx = {
7601 .net = net,
43a605f2 7602 .family = NFPROTO_NETDEV,
df05ef87
PNA
7603 };
7604
36596dad 7605 list_for_each_entry_safe(table, nt, &net->nft.tables, list) {
98319cb9 7606 ctx.family = table->family;
dd4cbef7 7607
df05ef87 7608 list_for_each_entry(chain, &table->chains, list)
c974a3a3 7609 nf_tables_unregister_hook(net, table, chain);
df05ef87
PNA
7610 /* No packets are walking on these chains anymore. */
7611 ctx.table = table;
7612 list_for_each_entry(chain, &table->chains, list) {
7613 ctx.chain = chain;
7614 list_for_each_entry_safe(rule, nr, &chain->rules, list) {
7615 list_del(&rule->list);
7616 chain->use--;
bb7b40ae 7617 nf_tables_rule_release(&ctx, rule);
df05ef87
PNA
7618 }
7619 }
3b49e2e9
PNA
7620 list_for_each_entry_safe(flowtable, nf, &table->flowtables, list) {
7621 list_del(&flowtable->list);
7622 table->use--;
7623 nf_tables_flowtable_destroy(flowtable);
7624 }
df05ef87
PNA
7625 list_for_each_entry_safe(set, ns, &table->sets, list) {
7626 list_del(&set->list);
7627 table->use--;
7628 nft_set_destroy(set);
7629 }
e5009240 7630 list_for_each_entry_safe(obj, ne, &table->objects, list) {
d152159b 7631 nft_obj_del(obj);
e5009240 7632 table->use--;
00bfb320 7633 nft_obj_destroy(&ctx, obj);
e5009240 7634 }
df05ef87 7635 list_for_each_entry_safe(chain, nc, &table->chains, list) {
43a605f2 7636 ctx.chain = chain;
1b2470e5 7637 nft_chain_del(chain);
df05ef87 7638 table->use--;
43a605f2 7639 nf_tables_chain_destroy(&ctx);
df05ef87
PNA
7640 }
7641 list_del(&table->list);
7642 nf_tables_table_destroy(&ctx);
7643 }
7644}
7645
dd4cbef7
PNA
7646static int __net_init nf_tables_init_net(struct net *net)
7647{
7648 INIT_LIST_HEAD(&net->nft.tables);
7649 INIT_LIST_HEAD(&net->nft.commit_list);
f102d66b 7650 mutex_init(&net->nft.commit_mutex);
dd4cbef7 7651 net->nft.base_seq = 1;
a654de8f
PNA
7652 net->nft.validate_state = NFT_VALIDATE_SKIP;
7653
dd4cbef7
PNA
7654 return 0;
7655}
7656
7657static void __net_exit nf_tables_exit_net(struct net *net)
7658{
f102d66b 7659 mutex_lock(&net->nft.commit_mutex);
71ad00c5
FW
7660 if (!list_empty(&net->nft.commit_list))
7661 __nf_tables_abort(net);
98319cb9 7662 __nft_release_tables(net);
f102d66b 7663 mutex_unlock(&net->nft.commit_mutex);
dd4cbef7 7664 WARN_ON_ONCE(!list_empty(&net->nft.tables));
dd4cbef7
PNA
7665}
7666
99633ab2
PNA
7667static struct pernet_operations nf_tables_net_ops = {
7668 .init = nf_tables_init_net,
613d0776 7669 .exit = nf_tables_exit_net,
99633ab2
PNA
7670};
7671
96518518
PM
7672static int __init nf_tables_module_init(void)
7673{
7674 int err;
7675
0935d558 7676 spin_lock_init(&nf_tables_destroy_list_lock);
d209df3e
FW
7677 err = register_pernet_subsys(&nf_tables_net_ops);
7678 if (err < 0)
7679 return err;
7680
7681 err = nft_chain_filter_init();
7682 if (err < 0)
7683 goto err1;
02c7b25e 7684
96518518
PM
7685 err = nf_tables_core_module_init();
7686 if (err < 0)
d209df3e 7687 goto err2;
96518518 7688
d209df3e 7689 err = register_netdevice_notifier(&nf_tables_flowtable_notifier);
96518518 7690 if (err < 0)
d209df3e 7691 goto err3;
96518518 7692
4d44175a
FW
7693 err = rhltable_init(&nft_objname_ht, &nft_objname_ht_params);
7694 if (err < 0)
7695 goto err4;
7696
d209df3e
FW
7697 /* must be last */
7698 err = nfnetlink_subsys_register(&nf_tables_subsys);
7699 if (err < 0)
4d44175a 7700 goto err5;
3b49e2e9 7701
c1deb065 7702 nft_chain_route_init();
3474a2c6
PNA
7703 nft_offload_init();
7704
d209df3e 7705 return err;
4d44175a
FW
7706err5:
7707 rhltable_destroy(&nft_objname_ht);
d209df3e
FW
7708err4:
7709 unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
7710err3:
96518518 7711 nf_tables_core_module_exit();
d209df3e
FW
7712err2:
7713 nft_chain_filter_fini();
7714err1:
7715 unregister_pernet_subsys(&nf_tables_net_ops);
96518518
PM
7716 return err;
7717}
7718
7719static void __exit nf_tables_module_exit(void)
7720{
3474a2c6 7721 nft_offload_exit();
96518518 7722 nfnetlink_subsys_unregister(&nf_tables_subsys);
3b49e2e9 7723 unregister_netdevice_notifier(&nf_tables_flowtable_notifier);
0a2cf5ee 7724 nft_chain_filter_fini();
c1deb065 7725 nft_chain_route_fini();
71ad00c5 7726 unregister_pernet_subsys(&nf_tables_net_ops);
0935d558 7727 cancel_work_sync(&trans_destroy_work);
1b1bc49c 7728 rcu_barrier();
4d44175a 7729 rhltable_destroy(&nft_objname_ht);
96518518 7730 nf_tables_core_module_exit();
96518518
PM
7731}
7732
7733module_init(nf_tables_module_init);
7734module_exit(nf_tables_module_exit);
7735
7736MODULE_LICENSE("GPL");
7737MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
7738MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);