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