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