netfilter: core: only allow one nat hook per hook point
[linux-block.git] / net / netfilter / nf_tables_api.c
CommitLineData
96518518 1/*
20a69341 2 * Copyright (c) 2007-2009 Patrick McHardy <kaber@trash.net>
96518518
PM
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 */
10
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/list.h>
14#include <linux/skbuff.h>
15#include <linux/netlink.h>
1ff75a3e 16#include <linux/vmalloc.h>
96518518
PM
17#include <linux/netfilter.h>
18#include <linux/netfilter/nfnetlink.h>
19#include <linux/netfilter/nf_tables.h>
20#include <net/netfilter/nf_tables_core.h>
21#include <net/netfilter/nf_tables.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);
96518518
PM
27
28/**
29 * nft_register_afinfo - register nf_tables address family info
30 *
31 * @afi: address family info to register
32 *
33 * Register the address family for use with nf_tables. Returns zero on
34 * success or a negative errno code otherwise.
35 */
99633ab2 36int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
96518518
PM
37{
38 INIT_LIST_HEAD(&afi->tables);
39 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 40 list_add_tail_rcu(&afi->list, &net->nft.af_info);
96518518
PM
41 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
42 return 0;
43}
44EXPORT_SYMBOL_GPL(nft_register_afinfo);
45
df05ef87
PNA
46static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi);
47
96518518
PM
48/**
49 * nft_unregister_afinfo - unregister nf_tables address family info
50 *
51 * @afi: address family info to unregister
52 *
53 * Unregister the address family for use with nf_tables.
54 */
df05ef87 55void nft_unregister_afinfo(struct net *net, struct nft_af_info *afi)
96518518
PM
56{
57 nfnl_lock(NFNL_SUBSYS_NFTABLES);
df05ef87 58 __nft_release_afinfo(net, afi);
e688a7f8 59 list_del_rcu(&afi->list);
96518518
PM
60 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
61}
62EXPORT_SYMBOL_GPL(nft_unregister_afinfo);
63
99633ab2 64static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family)
96518518
PM
65{
66 struct nft_af_info *afi;
67
99633ab2 68 list_for_each_entry(afi, &net->nft.af_info, list) {
96518518
PM
69 if (afi->family == family)
70 return afi;
71 }
72 return NULL;
73}
74
99633ab2
PNA
75static struct nft_af_info *
76nf_tables_afinfo_lookup(struct net *net, int family, bool autoload)
96518518
PM
77{
78 struct nft_af_info *afi;
79
99633ab2 80 afi = nft_afinfo_lookup(net, family);
96518518
PM
81 if (afi != NULL)
82 return afi;
83#ifdef CONFIG_MODULES
84 if (autoload) {
85 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
86 request_module("nft-afinfo-%u", family);
87 nfnl_lock(NFNL_SUBSYS_NFTABLES);
99633ab2 88 afi = nft_afinfo_lookup(net, family);
96518518
PM
89 if (afi != NULL)
90 return ERR_PTR(-EAGAIN);
91 }
92#endif
93 return ERR_PTR(-EAFNOSUPPORT);
94}
95
7c95f6d8 96static void nft_ctx_init(struct nft_ctx *ctx,
633c9a84 97 struct net *net,
7c95f6d8
PNA
98 const struct sk_buff *skb,
99 const struct nlmsghdr *nlh,
100 struct nft_af_info *afi,
101 struct nft_table *table,
102 struct nft_chain *chain,
103 const struct nlattr * const *nla)
104{
633c9a84 105 ctx->net = net;
128ad332
PNA
106 ctx->afi = afi;
107 ctx->table = table;
108 ctx->chain = chain;
109 ctx->nla = nla;
110 ctx->portid = NETLINK_CB(skb).portid;
111 ctx->report = nlmsg_report(nlh);
112 ctx->seq = nlh->nlmsg_seq;
7c95f6d8
PNA
113}
114
8411b644
PNA
115static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
116 int msg_type, u32 size, gfp_t gfp)
1081d11b
PNA
117{
118 struct nft_trans *trans;
119
8411b644 120 trans = kzalloc(sizeof(struct nft_trans) + size, gfp);
1081d11b
PNA
121 if (trans == NULL)
122 return NULL;
123
b380e5c7 124 trans->msg_type = msg_type;
1081d11b
PNA
125 trans->ctx = *ctx;
126
127 return trans;
128}
129
8411b644
PNA
130static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx,
131 int msg_type, u32 size)
132{
133 return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL);
134}
135
1081d11b
PNA
136static void nft_trans_destroy(struct nft_trans *trans)
137{
138 list_del(&trans->list);
139 kfree(trans);
140}
141
82bec71d
PNA
142static int nf_tables_register_hooks(struct net *net,
143 const struct nft_table *table,
d8ee8f7c
PNA
144 struct nft_chain *chain,
145 unsigned int hook_nops)
146{
147 if (table->flags & NFT_TABLE_F_DORMANT ||
f323d954 148 !nft_is_base_chain(chain))
d8ee8f7c
PNA
149 return 0;
150
82bec71d
PNA
151 return nf_register_net_hooks(net, nft_base_chain(chain)->ops,
152 hook_nops);
d8ee8f7c
PNA
153}
154
82bec71d
PNA
155static void nf_tables_unregister_hooks(struct net *net,
156 const struct nft_table *table,
d8ee8f7c 157 struct nft_chain *chain,
c5598794
AB
158 unsigned int hook_nops)
159{
d8ee8f7c 160 if (table->flags & NFT_TABLE_F_DORMANT ||
f323d954 161 !nft_is_base_chain(chain))
d8ee8f7c
PNA
162 return;
163
82bec71d 164 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, hook_nops);
c5598794
AB
165}
166
ee01d542
AB
167static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
168{
169 struct nft_trans *trans;
170
171 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
172 if (trans == NULL)
173 return -ENOMEM;
174
175 if (msg_type == NFT_MSG_NEWTABLE)
f2a6d766 176 nft_activate_next(ctx->net, ctx->table);
ee01d542
AB
177
178 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
179 return 0;
180}
181
182static int nft_deltable(struct nft_ctx *ctx)
183{
184 int err;
185
186 err = nft_trans_table_add(ctx, NFT_MSG_DELTABLE);
187 if (err < 0)
188 return err;
189
f2a6d766 190 nft_deactivate_next(ctx->net, ctx->table);
ee01d542
AB
191 return err;
192}
193
194static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
195{
196 struct nft_trans *trans;
197
198 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
199 if (trans == NULL)
200 return -ENOMEM;
201
202 if (msg_type == NFT_MSG_NEWCHAIN)
664b0f8c 203 nft_activate_next(ctx->net, ctx->chain);
ee01d542
AB
204
205 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
206 return 0;
207}
208
209static int nft_delchain(struct nft_ctx *ctx)
210{
211 int err;
212
213 err = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
214 if (err < 0)
215 return err;
216
217 ctx->table->use--;
664b0f8c 218 nft_deactivate_next(ctx->net, ctx->chain);
ee01d542
AB
219
220 return err;
221}
222
ee01d542
AB
223static int
224nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
225{
226 /* You cannot delete the same rule twice */
889f7ee7
PNA
227 if (nft_is_active_next(ctx->net, rule)) {
228 nft_deactivate_next(ctx->net, rule);
ee01d542
AB
229 ctx->chain->use--;
230 return 0;
231 }
232 return -ENOENT;
233}
234
235static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
236 struct nft_rule *rule)
237{
238 struct nft_trans *trans;
239
240 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
241 if (trans == NULL)
242 return NULL;
243
1a94e38d
PNA
244 if (msg_type == NFT_MSG_NEWRULE && ctx->nla[NFTA_RULE_ID] != NULL) {
245 nft_trans_rule_id(trans) =
246 ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
247 }
ee01d542
AB
248 nft_trans_rule(trans) = rule;
249 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
250
251 return trans;
252}
253
254static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
255{
256 struct nft_trans *trans;
257 int err;
258
259 trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
260 if (trans == NULL)
261 return -ENOMEM;
262
263 err = nf_tables_delrule_deactivate(ctx, rule);
264 if (err < 0) {
265 nft_trans_destroy(trans);
266 return err;
267 }
268
269 return 0;
270}
271
272static int nft_delrule_by_chain(struct nft_ctx *ctx)
273{
274 struct nft_rule *rule;
275 int err;
276
277 list_for_each_entry(rule, &ctx->chain->rules, list) {
278 err = nft_delrule(ctx, rule);
279 if (err < 0)
280 return err;
281 }
282 return 0;
283}
284
ee01d542
AB
285static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
286 struct nft_set *set)
287{
288 struct nft_trans *trans;
289
290 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
291 if (trans == NULL)
292 return -ENOMEM;
293
294 if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
295 nft_trans_set_id(trans) =
296 ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
37a9cc52 297 nft_activate_next(ctx->net, set);
ee01d542
AB
298 }
299 nft_trans_set(trans) = set;
300 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
301
302 return 0;
303}
304
305static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
306{
307 int err;
308
309 err = nft_trans_set_add(ctx, NFT_MSG_DELSET, set);
310 if (err < 0)
311 return err;
312
37a9cc52 313 nft_deactivate_next(ctx->net, set);
ee01d542
AB
314 ctx->table->use--;
315
316 return err;
317}
318
e5009240
PNA
319static int nft_trans_obj_add(struct nft_ctx *ctx, int msg_type,
320 struct nft_object *obj)
321{
322 struct nft_trans *trans;
323
324 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_obj));
325 if (trans == NULL)
326 return -ENOMEM;
327
328 if (msg_type == NFT_MSG_NEWOBJ)
329 nft_activate_next(ctx->net, obj);
330
331 nft_trans_obj(trans) = obj;
332 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
333
334 return 0;
335}
336
337static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj)
338{
339 int err;
340
341 err = nft_trans_obj_add(ctx, NFT_MSG_DELOBJ, obj);
342 if (err < 0)
343 return err;
344
345 nft_deactivate_next(ctx->net, obj);
346 ctx->table->use--;
347
348 return err;
349}
350
96518518
PM
351/*
352 * Tables
353 */
354
355static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
f2a6d766
PNA
356 const struct nlattr *nla,
357 u8 genmask)
96518518
PM
358{
359 struct nft_table *table;
360
361 list_for_each_entry(table, &afi->tables, list) {
f2a6d766
PNA
362 if (!nla_strcmp(nla, table->name) &&
363 nft_active_genmask(table, genmask))
96518518
PM
364 return table;
365 }
366 return NULL;
367}
368
369static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
f2a6d766
PNA
370 const struct nlattr *nla,
371 u8 genmask)
96518518
PM
372{
373 struct nft_table *table;
374
375 if (nla == NULL)
376 return ERR_PTR(-EINVAL);
377
f2a6d766 378 table = nft_table_lookup(afi, nla, genmask);
96518518
PM
379 if (table != NULL)
380 return table;
381
96518518
PM
382 return ERR_PTR(-ENOENT);
383}
384
385static inline u64 nf_tables_alloc_handle(struct nft_table *table)
386{
387 return ++table->hgenerator;
388}
389
d8297d4f 390static const struct nf_chain_type *chain_type[NFPROTO_NUMPROTO][NFT_CHAIN_T_MAX];
9370761c 391
2a37d755 392static const struct nf_chain_type *
baae3e62 393__nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
9370761c
PNA
394{
395 int i;
396
baae3e62 397 for (i = 0; i < NFT_CHAIN_T_MAX; i++) {
9370761c
PNA
398 if (chain_type[family][i] != NULL &&
399 !nla_strcmp(nla, chain_type[family][i]->name))
baae3e62 400 return chain_type[family][i];
9370761c 401 }
baae3e62 402 return NULL;
9370761c
PNA
403}
404
2a37d755 405static const struct nf_chain_type *
baae3e62
PM
406nf_tables_chain_type_lookup(const struct nft_af_info *afi,
407 const struct nlattr *nla,
408 bool autoload)
9370761c 409{
2a37d755 410 const struct nf_chain_type *type;
9370761c
PNA
411
412 type = __nf_tables_chain_type_lookup(afi->family, nla);
93b0806f
PM
413 if (type != NULL)
414 return type;
9370761c 415#ifdef CONFIG_MODULES
93b0806f 416 if (autoload) {
9370761c 417 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2fec6bb6
PNA
418 request_module("nft-chain-%u-%.*s", afi->family,
419 nla_len(nla), (const char *)nla_data(nla));
9370761c
PNA
420 nfnl_lock(NFNL_SUBSYS_NFTABLES);
421 type = __nf_tables_chain_type_lookup(afi->family, nla);
93b0806f
PM
422 if (type != NULL)
423 return ERR_PTR(-EAGAIN);
9370761c
PNA
424 }
425#endif
93b0806f 426 return ERR_PTR(-ENOENT);
9370761c
PNA
427}
428
96518518 429static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
1cae565e
PNA
430 [NFTA_TABLE_NAME] = { .type = NLA_STRING,
431 .len = NFT_TABLE_MAXNAMELEN - 1 },
9ddf6323 432 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
96518518
PM
433};
434
84d7fce6
PNA
435static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
436 u32 portid, u32 seq, int event, u32 flags,
437 int family, const struct nft_table *table)
96518518
PM
438{
439 struct nlmsghdr *nlh;
440 struct nfgenmsg *nfmsg;
441
dedb67c4 442 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
96518518
PM
443 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
444 if (nlh == NULL)
445 goto nla_put_failure;
446
447 nfmsg = nlmsg_data(nlh);
448 nfmsg->nfgen_family = family;
449 nfmsg->version = NFNETLINK_V0;
84d7fce6 450 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518 451
9ddf6323 452 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
d8bcc768
TB
453 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||
454 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
96518518
PM
455 goto nla_put_failure;
456
053c095a
JB
457 nlmsg_end(skb, nlh);
458 return 0;
96518518
PM
459
460nla_put_failure:
461 nlmsg_trim(skb, nlh);
462 return -1;
463}
464
25e94a99 465static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
96518518
PM
466{
467 struct sk_buff *skb;
96518518
PM
468 int err;
469
128ad332
PNA
470 if (!ctx->report &&
471 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 472 return;
96518518 473
96518518
PM
474 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
475 if (skb == NULL)
476 goto err;
477
84d7fce6
PNA
478 err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
479 event, 0, ctx->afi->family, ctx->table);
96518518
PM
480 if (err < 0) {
481 kfree_skb(skb);
482 goto err;
483 }
484
25e94a99
PNA
485 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
486 ctx->report, GFP_KERNEL);
487 return;
96518518 488err:
25e94a99 489 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
490}
491
492static int nf_tables_dump_tables(struct sk_buff *skb,
493 struct netlink_callback *cb)
494{
495 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
496 const struct nft_af_info *afi;
497 const struct nft_table *table;
498 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 499 struct net *net = sock_net(skb->sk);
96518518
PM
500 int family = nfmsg->nfgen_family;
501
e688a7f8 502 rcu_read_lock();
38e029f1
PNA
503 cb->seq = net->nft.base_seq;
504
e688a7f8 505 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
96518518
PM
506 if (family != NFPROTO_UNSPEC && family != afi->family)
507 continue;
508
e688a7f8 509 list_for_each_entry_rcu(table, &afi->tables, list) {
96518518
PM
510 if (idx < s_idx)
511 goto cont;
512 if (idx > s_idx)
513 memset(&cb->args[1], 0,
514 sizeof(cb->args) - sizeof(cb->args[0]));
f2a6d766
PNA
515 if (!nft_is_active(net, table))
516 continue;
84d7fce6 517 if (nf_tables_fill_table_info(skb, net,
96518518
PM
518 NETLINK_CB(cb->skb).portid,
519 cb->nlh->nlmsg_seq,
520 NFT_MSG_NEWTABLE,
521 NLM_F_MULTI,
522 afi->family, table) < 0)
523 goto done;
38e029f1
PNA
524
525 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518
PM
526cont:
527 idx++;
528 }
529 }
530done:
e688a7f8 531 rcu_read_unlock();
96518518
PM
532 cb->args[0] = idx;
533 return skb->len;
534}
535
7b8002a1
PNA
536static int nf_tables_gettable(struct net *net, struct sock *nlsk,
537 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
538 const struct nlattr * const nla[],
539 struct netlink_ext_ack *extack)
96518518
PM
540{
541 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 542 u8 genmask = nft_genmask_cur(net);
96518518
PM
543 const struct nft_af_info *afi;
544 const struct nft_table *table;
545 struct sk_buff *skb2;
546 int family = nfmsg->nfgen_family;
547 int err;
548
549 if (nlh->nlmsg_flags & NLM_F_DUMP) {
550 struct netlink_dump_control c = {
551 .dump = nf_tables_dump_tables,
552 };
553 return netlink_dump_start(nlsk, skb, nlh, &c);
554 }
555
99633ab2 556 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
557 if (IS_ERR(afi))
558 return PTR_ERR(afi);
559
f2a6d766 560 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
96518518
PM
561 if (IS_ERR(table))
562 return PTR_ERR(table);
563
564 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
565 if (!skb2)
566 return -ENOMEM;
567
84d7fce6 568 err = nf_tables_fill_table_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
569 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
570 family, table);
571 if (err < 0)
572 goto err;
573
574 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
575
576err:
577 kfree_skb(skb2);
578 return err;
579}
580
10435c11
F
581static void _nf_tables_table_disable(struct net *net,
582 const struct nft_af_info *afi,
583 struct nft_table *table,
584 u32 cnt)
585{
586 struct nft_chain *chain;
587 u32 i = 0;
588
589 list_for_each_entry(chain, &table->chains, list) {
590 if (!nft_is_active_next(net, chain))
591 continue;
f323d954 592 if (!nft_is_base_chain(chain))
10435c11
F
593 continue;
594
595 if (cnt && i++ == cnt)
596 break;
597
598 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
599 afi->nops);
600 }
601}
602
664b0f8c
PNA
603static int nf_tables_table_enable(struct net *net,
604 const struct nft_af_info *afi,
115a60b1 605 struct nft_table *table)
9ddf6323
PNA
606{
607 struct nft_chain *chain;
608 int err, i = 0;
609
610 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
611 if (!nft_is_active_next(net, chain))
612 continue;
f323d954 613 if (!nft_is_base_chain(chain))
d2012975
PNA
614 continue;
615
82bec71d
PNA
616 err = nf_register_net_hooks(net, nft_base_chain(chain)->ops,
617 afi->nops);
9ddf6323
PNA
618 if (err < 0)
619 goto err;
620
621 i++;
622 }
623 return 0;
624err:
10435c11
F
625 if (i)
626 _nf_tables_table_disable(net, afi, table, i);
9ddf6323
PNA
627 return err;
628}
629
664b0f8c
PNA
630static void nf_tables_table_disable(struct net *net,
631 const struct nft_af_info *afi,
d8ee8f7c 632 struct nft_table *table)
9ddf6323 633{
10435c11 634 _nf_tables_table_disable(net, afi, table, 0);
9ddf6323
PNA
635}
636
e1aaca93 637static int nf_tables_updtable(struct nft_ctx *ctx)
9ddf6323 638{
55dd6f93 639 struct nft_trans *trans;
e1aaca93 640 u32 flags;
55dd6f93 641 int ret = 0;
9ddf6323 642
e1aaca93
PNA
643 if (!ctx->nla[NFTA_TABLE_FLAGS])
644 return 0;
9ddf6323 645
e1aaca93
PNA
646 flags = ntohl(nla_get_be32(ctx->nla[NFTA_TABLE_FLAGS]));
647 if (flags & ~NFT_TABLE_F_DORMANT)
648 return -EINVAL;
649
63283dd2
PNA
650 if (flags == ctx->table->flags)
651 return 0;
652
55dd6f93
PNA
653 trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
654 sizeof(struct nft_trans_table));
655 if (trans == NULL)
656 return -ENOMEM;
9ddf6323 657
e1aaca93
PNA
658 if ((flags & NFT_TABLE_F_DORMANT) &&
659 !(ctx->table->flags & NFT_TABLE_F_DORMANT)) {
55dd6f93 660 nft_trans_table_enable(trans) = false;
e1aaca93
PNA
661 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
662 ctx->table->flags & NFT_TABLE_F_DORMANT) {
664b0f8c 663 ret = nf_tables_table_enable(ctx->net, ctx->afi, ctx->table);
55dd6f93 664 if (ret >= 0) {
e1aaca93 665 ctx->table->flags &= ~NFT_TABLE_F_DORMANT;
55dd6f93 666 nft_trans_table_enable(trans) = true;
9ddf6323 667 }
9ddf6323 668 }
e1aaca93
PNA
669 if (ret < 0)
670 goto err;
9ddf6323 671
55dd6f93
PNA
672 nft_trans_table_update(trans) = true;
673 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
674 return 0;
9ddf6323 675err:
55dd6f93 676 nft_trans_destroy(trans);
9ddf6323
PNA
677 return ret;
678}
679
633c9a84
PNA
680static int nf_tables_newtable(struct net *net, struct sock *nlsk,
681 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
682 const struct nlattr * const nla[],
683 struct netlink_ext_ack *extack)
96518518
PM
684{
685 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 686 u8 genmask = nft_genmask_next(net);
96518518
PM
687 const struct nlattr *name;
688 struct nft_af_info *afi;
689 struct nft_table *table;
690 int family = nfmsg->nfgen_family;
c5c1f975 691 u32 flags = 0;
e1aaca93 692 struct nft_ctx ctx;
55dd6f93 693 int err;
96518518 694
99633ab2 695 afi = nf_tables_afinfo_lookup(net, family, true);
96518518
PM
696 if (IS_ERR(afi))
697 return PTR_ERR(afi);
698
699 name = nla[NFTA_TABLE_NAME];
f2a6d766 700 table = nf_tables_table_lookup(afi, name, genmask);
96518518
PM
701 if (IS_ERR(table)) {
702 if (PTR_ERR(table) != -ENOENT)
703 return PTR_ERR(table);
1a28ad74 704 } else {
96518518
PM
705 if (nlh->nlmsg_flags & NLM_F_EXCL)
706 return -EEXIST;
707 if (nlh->nlmsg_flags & NLM_F_REPLACE)
708 return -EOPNOTSUPP;
e1aaca93 709
633c9a84 710 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
e1aaca93 711 return nf_tables_updtable(&ctx);
96518518
PM
712 }
713
c5c1f975
PM
714 if (nla[NFTA_TABLE_FLAGS]) {
715 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
716 if (flags & ~NFT_TABLE_F_DORMANT)
717 return -EINVAL;
718 }
719
ebddf1a8 720 err = -EAFNOSUPPORT;
7047f9d0 721 if (!try_module_get(afi->owner))
ebddf1a8 722 goto err1;
7047f9d0 723
ffdb210e 724 err = -ENOMEM;
1cae565e 725 table = kzalloc(sizeof(*table), GFP_KERNEL);
ffdb210e 726 if (table == NULL)
ebddf1a8 727 goto err2;
96518518 728
e46abbcc
PS
729 table->name = nla_strdup(name, GFP_KERNEL);
730 if (table->name == NULL)
731 goto err3;
732
96518518 733 INIT_LIST_HEAD(&table->chains);
20a69341 734 INIT_LIST_HEAD(&table->sets);
e5009240 735 INIT_LIST_HEAD(&table->objects);
c5c1f975 736 table->flags = flags;
9ddf6323 737
633c9a84 738 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
55dd6f93 739 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
ffdb210e 740 if (err < 0)
e46abbcc 741 goto err4;
ffdb210e 742
e688a7f8 743 list_add_tail_rcu(&table->list, &afi->tables);
96518518 744 return 0;
e46abbcc
PS
745err4:
746 kfree(table->name);
ebddf1a8 747err3:
ffdb210e 748 kfree(table);
ebddf1a8 749err2:
ffdb210e 750 module_put(afi->owner);
ebddf1a8 751err1:
ffdb210e 752 return err;
96518518
PM
753}
754
b9ac12ef
AB
755static int nft_flush_table(struct nft_ctx *ctx)
756{
757 int err;
758 struct nft_chain *chain, *nc;
e5009240 759 struct nft_object *obj, *ne;
b9ac12ef
AB
760 struct nft_set *set, *ns;
761
a2f18db0 762 list_for_each_entry(chain, &ctx->table->chains, list) {
664b0f8c
PNA
763 if (!nft_is_active_next(ctx->net, chain))
764 continue;
765
b9ac12ef
AB
766 ctx->chain = chain;
767
768 err = nft_delrule_by_chain(ctx);
769 if (err < 0)
770 goto out;
b9ac12ef
AB
771 }
772
773 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
37a9cc52
PNA
774 if (!nft_is_active_next(ctx->net, set))
775 continue;
776
b9ac12ef
AB
777 if (set->flags & NFT_SET_ANONYMOUS &&
778 !list_empty(&set->bindings))
779 continue;
780
781 err = nft_delset(ctx, set);
782 if (err < 0)
783 goto out;
784 }
785
e5009240
PNA
786 list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) {
787 err = nft_delobj(ctx, obj);
788 if (err < 0)
789 goto out;
790 }
791
a2f18db0 792 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
664b0f8c
PNA
793 if (!nft_is_active_next(ctx->net, chain))
794 continue;
795
a2f18db0
PNA
796 ctx->chain = chain;
797
798 err = nft_delchain(ctx);
799 if (err < 0)
800 goto out;
801 }
802
b9ac12ef
AB
803 err = nft_deltable(ctx);
804out:
805 return err;
806}
807
808static int nft_flush(struct nft_ctx *ctx, int family)
809{
810 struct nft_af_info *afi;
811 struct nft_table *table, *nt;
812 const struct nlattr * const *nla = ctx->nla;
813 int err = 0;
814
815 list_for_each_entry(afi, &ctx->net->nft.af_info, list) {
816 if (family != AF_UNSPEC && afi->family != family)
817 continue;
818
819 ctx->afi = afi;
820 list_for_each_entry_safe(table, nt, &afi->tables, list) {
f2a6d766
PNA
821 if (!nft_is_active_next(ctx->net, table))
822 continue;
823
b9ac12ef
AB
824 if (nla[NFTA_TABLE_NAME] &&
825 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
826 continue;
827
828 ctx->table = table;
829
830 err = nft_flush_table(ctx);
831 if (err < 0)
832 goto out;
833 }
834 }
835out:
836 return err;
837}
838
633c9a84
PNA
839static int nf_tables_deltable(struct net *net, struct sock *nlsk,
840 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
841 const struct nlattr * const nla[],
842 struct netlink_ext_ack *extack)
96518518
PM
843{
844 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 845 u8 genmask = nft_genmask_next(net);
96518518
PM
846 struct nft_af_info *afi;
847 struct nft_table *table;
ee01d542 848 int family = nfmsg->nfgen_family;
55dd6f93 849 struct nft_ctx ctx;
96518518 850
633c9a84 851 nft_ctx_init(&ctx, net, skb, nlh, NULL, NULL, NULL, nla);
b9ac12ef
AB
852 if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)
853 return nft_flush(&ctx, family);
854
99633ab2 855 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
856 if (IS_ERR(afi))
857 return PTR_ERR(afi);
858
f2a6d766 859 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
96518518
PM
860 if (IS_ERR(table))
861 return PTR_ERR(table);
96518518 862
a8278400
PNA
863 if (nlh->nlmsg_flags & NLM_F_NONREC &&
864 table->use > 0)
865 return -EBUSY;
866
b9ac12ef
AB
867 ctx.afi = afi;
868 ctx.table = table;
55dd6f93 869
b9ac12ef 870 return nft_flush_table(&ctx);
96518518
PM
871}
872
55dd6f93
PNA
873static void nf_tables_table_destroy(struct nft_ctx *ctx)
874{
4fefee57
PNA
875 BUG_ON(ctx->table->use > 0);
876
e46abbcc 877 kfree(ctx->table->name);
55dd6f93
PNA
878 kfree(ctx->table);
879 module_put(ctx->afi->owner);
880}
881
2a37d755 882int nft_register_chain_type(const struct nf_chain_type *ctype)
96518518 883{
9370761c 884 int err = 0;
96518518 885
d8297d4f
FW
886 if (WARN_ON(ctype->family >= NFPROTO_NUMPROTO))
887 return -EINVAL;
888
96518518 889 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c
PNA
890 if (chain_type[ctype->family][ctype->type] != NULL) {
891 err = -EBUSY;
892 goto out;
96518518 893 }
9370761c
PNA
894 chain_type[ctype->family][ctype->type] = ctype;
895out:
96518518
PM
896 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
897 return err;
898}
9370761c 899EXPORT_SYMBOL_GPL(nft_register_chain_type);
96518518 900
2a37d755 901void nft_unregister_chain_type(const struct nf_chain_type *ctype)
96518518 902{
96518518 903 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c 904 chain_type[ctype->family][ctype->type] = NULL;
96518518
PM
905 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
906}
9370761c 907EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
96518518
PM
908
909/*
910 * Chains
911 */
912
913static struct nft_chain *
664b0f8c
PNA
914nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle,
915 u8 genmask)
96518518
PM
916{
917 struct nft_chain *chain;
918
919 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
920 if (chain->handle == handle &&
921 nft_active_genmask(chain, genmask))
96518518
PM
922 return chain;
923 }
924
925 return ERR_PTR(-ENOENT);
926}
927
928static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
664b0f8c
PNA
929 const struct nlattr *nla,
930 u8 genmask)
96518518
PM
931{
932 struct nft_chain *chain;
933
934 if (nla == NULL)
935 return ERR_PTR(-EINVAL);
936
937 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
938 if (!nla_strcmp(nla, chain->name) &&
939 nft_active_genmask(chain, genmask))
96518518
PM
940 return chain;
941 }
942
943 return ERR_PTR(-ENOENT);
944}
945
946static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
b2fbd044
LZ
947 [NFTA_CHAIN_TABLE] = { .type = NLA_STRING,
948 .len = NFT_TABLE_MAXNAMELEN - 1 },
96518518
PM
949 [NFTA_CHAIN_HANDLE] = { .type = NLA_U64 },
950 [NFTA_CHAIN_NAME] = { .type = NLA_STRING,
951 .len = NFT_CHAIN_MAXNAMELEN - 1 },
952 [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED },
0ca743a5 953 [NFTA_CHAIN_POLICY] = { .type = NLA_U32 },
4c1f7818 954 [NFTA_CHAIN_TYPE] = { .type = NLA_STRING },
0ca743a5 955 [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED },
96518518
PM
956};
957
958static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
959 [NFTA_HOOK_HOOKNUM] = { .type = NLA_U32 },
960 [NFTA_HOOK_PRIORITY] = { .type = NLA_U32 },
2cbce139
PNA
961 [NFTA_HOOK_DEV] = { .type = NLA_STRING,
962 .len = IFNAMSIZ - 1 },
96518518
PM
963};
964
0ca743a5
PNA
965static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
966{
967 struct nft_stats *cpu_stats, total;
968 struct nlattr *nest;
ce355e20
ED
969 unsigned int seq;
970 u64 pkts, bytes;
0ca743a5
PNA
971 int cpu;
972
973 memset(&total, 0, sizeof(total));
974 for_each_possible_cpu(cpu) {
975 cpu_stats = per_cpu_ptr(stats, cpu);
ce355e20
ED
976 do {
977 seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
978 pkts = cpu_stats->pkts;
979 bytes = cpu_stats->bytes;
980 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
981 total.pkts += pkts;
982 total.bytes += bytes;
0ca743a5
PNA
983 }
984 nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS);
985 if (nest == NULL)
986 goto nla_put_failure;
987
b46f6ded
ND
988 if (nla_put_be64(skb, NFTA_COUNTER_PACKETS, cpu_to_be64(total.pkts),
989 NFTA_COUNTER_PAD) ||
990 nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
991 NFTA_COUNTER_PAD))
0ca743a5
PNA
992 goto nla_put_failure;
993
994 nla_nest_end(skb, nest);
995 return 0;
996
997nla_put_failure:
998 return -ENOSPC;
999}
1000
84d7fce6
PNA
1001static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
1002 u32 portid, u32 seq, int event, u32 flags,
1003 int family, const struct nft_table *table,
96518518
PM
1004 const struct nft_chain *chain)
1005{
1006 struct nlmsghdr *nlh;
1007 struct nfgenmsg *nfmsg;
1008
dedb67c4 1009 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
96518518
PM
1010 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
1011 if (nlh == NULL)
1012 goto nla_put_failure;
1013
1014 nfmsg = nlmsg_data(nlh);
1015 nfmsg->nfgen_family = family;
1016 nfmsg->version = NFNETLINK_V0;
84d7fce6 1017 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518
PM
1018
1019 if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
1020 goto nla_put_failure;
b46f6ded
ND
1021 if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
1022 NFTA_CHAIN_PAD))
96518518
PM
1023 goto nla_put_failure;
1024 if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
1025 goto nla_put_failure;
1026
f323d954 1027 if (nft_is_base_chain(chain)) {
0ca743a5 1028 const struct nft_base_chain *basechain = nft_base_chain(chain);
115a60b1 1029 const struct nf_hook_ops *ops = &basechain->ops[0];
0ca743a5
PNA
1030 struct nlattr *nest;
1031
1032 nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
96518518
PM
1033 if (nest == NULL)
1034 goto nla_put_failure;
1035 if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum)))
1036 goto nla_put_failure;
1037 if (nla_put_be32(skb, NFTA_HOOK_PRIORITY, htonl(ops->priority)))
1038 goto nla_put_failure;
2cbce139
PNA
1039 if (basechain->dev_name[0] &&
1040 nla_put_string(skb, NFTA_HOOK_DEV, basechain->dev_name))
1041 goto nla_put_failure;
96518518 1042 nla_nest_end(skb, nest);
9370761c 1043
0ca743a5
PNA
1044 if (nla_put_be32(skb, NFTA_CHAIN_POLICY,
1045 htonl(basechain->policy)))
1046 goto nla_put_failure;
1047
baae3e62
PM
1048 if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name))
1049 goto nla_put_failure;
0ca743a5 1050
5f9bfe0e 1051 if (basechain->stats && nft_dump_stats(skb, basechain->stats))
0ca743a5 1052 goto nla_put_failure;
96518518
PM
1053 }
1054
0ca743a5
PNA
1055 if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
1056 goto nla_put_failure;
1057
053c095a
JB
1058 nlmsg_end(skb, nlh);
1059 return 0;
96518518
PM
1060
1061nla_put_failure:
1062 nlmsg_trim(skb, nlh);
1063 return -1;
1064}
1065
25e94a99 1066static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
96518518
PM
1067{
1068 struct sk_buff *skb;
96518518
PM
1069 int err;
1070
128ad332
PNA
1071 if (!ctx->report &&
1072 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 1073 return;
96518518 1074
96518518
PM
1075 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1076 if (skb == NULL)
1077 goto err;
1078
84d7fce6
PNA
1079 err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
1080 event, 0, ctx->afi->family, ctx->table,
35151d84 1081 ctx->chain);
96518518
PM
1082 if (err < 0) {
1083 kfree_skb(skb);
1084 goto err;
1085 }
1086
25e94a99
PNA
1087 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1088 ctx->report, GFP_KERNEL);
1089 return;
96518518 1090err:
25e94a99 1091 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
1092}
1093
1094static int nf_tables_dump_chains(struct sk_buff *skb,
1095 struct netlink_callback *cb)
1096{
1097 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1098 const struct nft_af_info *afi;
1099 const struct nft_table *table;
1100 const struct nft_chain *chain;
1101 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 1102 struct net *net = sock_net(skb->sk);
96518518
PM
1103 int family = nfmsg->nfgen_family;
1104
e688a7f8 1105 rcu_read_lock();
38e029f1
PNA
1106 cb->seq = net->nft.base_seq;
1107
e688a7f8 1108 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
96518518
PM
1109 if (family != NFPROTO_UNSPEC && family != afi->family)
1110 continue;
1111
e688a7f8
PNA
1112 list_for_each_entry_rcu(table, &afi->tables, list) {
1113 list_for_each_entry_rcu(chain, &table->chains, list) {
96518518
PM
1114 if (idx < s_idx)
1115 goto cont;
1116 if (idx > s_idx)
1117 memset(&cb->args[1], 0,
1118 sizeof(cb->args) - sizeof(cb->args[0]));
664b0f8c
PNA
1119 if (!nft_is_active(net, chain))
1120 continue;
84d7fce6
PNA
1121 if (nf_tables_fill_chain_info(skb, net,
1122 NETLINK_CB(cb->skb).portid,
96518518
PM
1123 cb->nlh->nlmsg_seq,
1124 NFT_MSG_NEWCHAIN,
1125 NLM_F_MULTI,
1126 afi->family, table, chain) < 0)
1127 goto done;
38e029f1
PNA
1128
1129 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518
PM
1130cont:
1131 idx++;
1132 }
1133 }
1134 }
1135done:
e688a7f8 1136 rcu_read_unlock();
96518518
PM
1137 cb->args[0] = idx;
1138 return skb->len;
1139}
1140
7b8002a1
PNA
1141static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1142 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1143 const struct nlattr * const nla[],
1144 struct netlink_ext_ack *extack)
96518518
PM
1145{
1146 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1147 u8 genmask = nft_genmask_cur(net);
96518518
PM
1148 const struct nft_af_info *afi;
1149 const struct nft_table *table;
1150 const struct nft_chain *chain;
1151 struct sk_buff *skb2;
1152 int family = nfmsg->nfgen_family;
1153 int err;
1154
1155 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1156 struct netlink_dump_control c = {
1157 .dump = nf_tables_dump_chains,
1158 };
1159 return netlink_dump_start(nlsk, skb, nlh, &c);
1160 }
1161
99633ab2 1162 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
1163 if (IS_ERR(afi))
1164 return PTR_ERR(afi);
1165
f2a6d766 1166 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
96518518
PM
1167 if (IS_ERR(table))
1168 return PTR_ERR(table);
1169
664b0f8c 1170 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
96518518
PM
1171 if (IS_ERR(chain))
1172 return PTR_ERR(chain);
1173
1174 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1175 if (!skb2)
1176 return -ENOMEM;
1177
84d7fce6 1178 err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
1179 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
1180 family, table, chain);
1181 if (err < 0)
1182 goto err;
1183
1184 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1185
1186err:
1187 kfree_skb(skb2);
1188 return err;
1189}
1190
0ca743a5
PNA
1191static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
1192 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
1193 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
1194};
1195
ff3cd7b3 1196static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
0ca743a5
PNA
1197{
1198 struct nlattr *tb[NFTA_COUNTER_MAX+1];
1199 struct nft_stats __percpu *newstats;
1200 struct nft_stats *stats;
1201 int err;
1202
fceb6435
JB
1203 err = nla_parse_nested(tb, NFTA_COUNTER_MAX, attr, nft_counter_policy,
1204 NULL);
0ca743a5 1205 if (err < 0)
ff3cd7b3 1206 return ERR_PTR(err);
0ca743a5
PNA
1207
1208 if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
ff3cd7b3 1209 return ERR_PTR(-EINVAL);
0ca743a5 1210
ce355e20 1211 newstats = netdev_alloc_pcpu_stats(struct nft_stats);
0ca743a5 1212 if (newstats == NULL)
ff3cd7b3 1213 return ERR_PTR(-ENOMEM);
0ca743a5
PNA
1214
1215 /* Restore old counters on this cpu, no problem. Per-cpu statistics
1216 * are not exposed to userspace.
1217 */
e8781f70 1218 preempt_disable();
0ca743a5
PNA
1219 stats = this_cpu_ptr(newstats);
1220 stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
1221 stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
e8781f70 1222 preempt_enable();
0ca743a5 1223
ff3cd7b3
PNA
1224 return newstats;
1225}
1226
1227static void nft_chain_stats_replace(struct nft_base_chain *chain,
1228 struct nft_stats __percpu *newstats)
1229{
b88825de
PNA
1230 if (newstats == NULL)
1231 return;
1232
0ca743a5 1233 if (chain->stats) {
0ca743a5 1234 struct nft_stats __percpu *oldstats =
67a8fc27 1235 nft_dereference(chain->stats);
0ca743a5
PNA
1236
1237 rcu_assign_pointer(chain->stats, newstats);
1238 synchronize_rcu();
1239 free_percpu(oldstats);
1240 } else
1241 rcu_assign_pointer(chain->stats, newstats);
0ca743a5
PNA
1242}
1243
91c7b38d
PNA
1244static void nf_tables_chain_destroy(struct nft_chain *chain)
1245{
1246 BUG_ON(chain->use > 0);
1247
f323d954 1248 if (nft_is_base_chain(chain)) {
2cbce139
PNA
1249 struct nft_base_chain *basechain = nft_base_chain(chain);
1250
1251 module_put(basechain->type->owner);
1252 free_percpu(basechain->stats);
9f08ea84
PNA
1253 if (basechain->stats)
1254 static_branch_dec(&nft_counters_enabled);
2cbce139
PNA
1255 if (basechain->ops[0].dev != NULL)
1256 dev_put(basechain->ops[0].dev);
b7263e07 1257 kfree(chain->name);
2cbce139 1258 kfree(basechain);
91c7b38d 1259 } else {
b7263e07 1260 kfree(chain->name);
91c7b38d
PNA
1261 kfree(chain);
1262 }
1263}
1264
508f8ccd
PNA
1265struct nft_chain_hook {
1266 u32 num;
1267 u32 priority;
1268 const struct nf_chain_type *type;
1269 struct net_device *dev;
1270};
1271
1272static int nft_chain_parse_hook(struct net *net,
1273 const struct nlattr * const nla[],
1274 struct nft_af_info *afi,
1275 struct nft_chain_hook *hook, bool create)
1276{
1277 struct nlattr *ha[NFTA_HOOK_MAX + 1];
1278 const struct nf_chain_type *type;
1279 struct net_device *dev;
1280 int err;
1281
1282 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
fceb6435 1283 nft_hook_policy, NULL);
508f8ccd
PNA
1284 if (err < 0)
1285 return err;
1286
1287 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
1288 ha[NFTA_HOOK_PRIORITY] == NULL)
1289 return -EINVAL;
1290
1291 hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
1292 if (hook->num >= afi->nhooks)
1293 return -EINVAL;
1294
1295 hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
1296
1297 type = chain_type[afi->family][NFT_CHAIN_T_DEFAULT];
1298 if (nla[NFTA_CHAIN_TYPE]) {
1299 type = nf_tables_chain_type_lookup(afi, nla[NFTA_CHAIN_TYPE],
1300 create);
1301 if (IS_ERR(type))
1302 return PTR_ERR(type);
1303 }
1304 if (!(type->hook_mask & (1 << hook->num)))
1305 return -EOPNOTSUPP;
1306 if (!try_module_get(type->owner))
1307 return -ENOENT;
1308
1309 hook->type = type;
1310
1311 hook->dev = NULL;
1312 if (afi->flags & NFT_AF_NEEDS_DEV) {
1313 char ifname[IFNAMSIZ];
1314
1315 if (!ha[NFTA_HOOK_DEV]) {
1316 module_put(type->owner);
1317 return -EOPNOTSUPP;
1318 }
1319
1320 nla_strlcpy(ifname, ha[NFTA_HOOK_DEV], IFNAMSIZ);
1321 dev = dev_get_by_name(net, ifname);
1322 if (!dev) {
1323 module_put(type->owner);
1324 return -ENOENT;
1325 }
1326 hook->dev = dev;
1327 } else if (ha[NFTA_HOOK_DEV]) {
1328 module_put(type->owner);
1329 return -EOPNOTSUPP;
1330 }
1331
1332 return 0;
1333}
1334
1335static void nft_chain_release_hook(struct nft_chain_hook *hook)
1336{
1337 module_put(hook->type->owner);
1338 if (hook->dev != NULL)
1339 dev_put(hook->dev);
1340}
1341
4035285f
PNA
1342static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1343 u8 policy, bool create)
1344{
1345 const struct nlattr * const *nla = ctx->nla;
1346 struct nft_table *table = ctx->table;
1347 struct nft_af_info *afi = ctx->afi;
1348 struct nft_base_chain *basechain;
1349 struct nft_stats __percpu *stats;
1350 struct net *net = ctx->net;
1351 struct nft_chain *chain;
1352 unsigned int i;
1353 int err;
1354
1355 if (table->use == UINT_MAX)
1356 return -EOVERFLOW;
1357
1358 if (nla[NFTA_CHAIN_HOOK]) {
1359 struct nft_chain_hook hook;
1360 struct nf_hook_ops *ops;
1361 nf_hookfn *hookfn;
1362
1363 err = nft_chain_parse_hook(net, nla, afi, &hook, create);
1364 if (err < 0)
1365 return err;
1366
1367 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
1368 if (basechain == NULL) {
1369 nft_chain_release_hook(&hook);
1370 return -ENOMEM;
1371 }
1372
1373 if (hook.dev != NULL)
1374 strncpy(basechain->dev_name, hook.dev->name, IFNAMSIZ);
1375
1376 if (nla[NFTA_CHAIN_COUNTERS]) {
1377 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1378 if (IS_ERR(stats)) {
1379 nft_chain_release_hook(&hook);
1380 kfree(basechain);
1381 return PTR_ERR(stats);
1382 }
1383 basechain->stats = stats;
1384 static_branch_inc(&nft_counters_enabled);
1385 }
1386
1387 hookfn = hook.type->hooks[hook.num];
1388 basechain->type = hook.type;
1389 chain = &basechain->chain;
1390
1391 for (i = 0; i < afi->nops; i++) {
1392 ops = &basechain->ops[i];
1393 ops->pf = family;
1394 ops->hooknum = hook.num;
1395 ops->priority = hook.priority;
1396 ops->priv = chain;
1397 ops->hook = afi->hooks[ops->hooknum];
1398 ops->dev = hook.dev;
1399 if (hookfn)
1400 ops->hook = hookfn;
1401 if (afi->hook_ops_init)
1402 afi->hook_ops_init(ops, i);
f92b40a8
FW
1403 if (basechain->type->type == NFT_CHAIN_T_NAT)
1404 ops->nat_hook = true;
4035285f
PNA
1405 }
1406
1407 chain->flags |= NFT_BASE_CHAIN;
1408 basechain->policy = policy;
1409 } else {
1410 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1411 if (chain == NULL)
1412 return -ENOMEM;
1413 }
1414 INIT_LIST_HEAD(&chain->rules);
1415 chain->handle = nf_tables_alloc_handle(table);
1416 chain->table = table;
1417 chain->name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
1418 if (!chain->name) {
1419 err = -ENOMEM;
1420 goto err1;
1421 }
1422
1423 err = nf_tables_register_hooks(net, table, chain, afi->nops);
1424 if (err < 0)
1425 goto err1;
1426
1427 ctx->chain = chain;
1428 err = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
1429 if (err < 0)
1430 goto err2;
1431
1432 table->use++;
1433 list_add_tail_rcu(&chain->list, &table->chains);
1434
1435 return 0;
1436err2:
1437 nf_tables_unregister_hooks(net, table, chain, afi->nops);
1438err1:
1439 nf_tables_chain_destroy(chain);
1440
1441 return err;
1442}
1443
2c4a488a
PNA
1444static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
1445 bool create)
1446{
1447 const struct nlattr * const *nla = ctx->nla;
1448 struct nft_table *table = ctx->table;
1449 struct nft_chain *chain = ctx->chain;
1450 struct nft_af_info *afi = ctx->afi;
1451 struct nft_base_chain *basechain;
1452 struct nft_stats *stats = NULL;
1453 struct nft_chain_hook hook;
1454 const struct nlattr *name;
1455 struct nf_hook_ops *ops;
1456 struct nft_trans *trans;
1457 int err, i;
1458
1459 if (nla[NFTA_CHAIN_HOOK]) {
1460 if (!nft_is_base_chain(chain))
1461 return -EBUSY;
1462
1463 err = nft_chain_parse_hook(ctx->net, nla, ctx->afi, &hook,
1464 create);
1465 if (err < 0)
1466 return err;
1467
1468 basechain = nft_base_chain(chain);
1469 if (basechain->type != hook.type) {
1470 nft_chain_release_hook(&hook);
1471 return -EBUSY;
1472 }
1473
1474 for (i = 0; i < afi->nops; i++) {
1475 ops = &basechain->ops[i];
1476 if (ops->hooknum != hook.num ||
1477 ops->priority != hook.priority ||
1478 ops->dev != hook.dev) {
1479 nft_chain_release_hook(&hook);
1480 return -EBUSY;
1481 }
1482 }
1483 nft_chain_release_hook(&hook);
1484 }
1485
1486 if (nla[NFTA_CHAIN_HANDLE] &&
1487 nla[NFTA_CHAIN_NAME]) {
1488 struct nft_chain *chain2;
1489
1490 chain2 = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME],
1491 genmask);
0d18779b
JC
1492 if (!IS_ERR(chain2))
1493 return -EEXIST;
2c4a488a
PNA
1494 }
1495
1496 if (nla[NFTA_CHAIN_COUNTERS]) {
1497 if (!nft_is_base_chain(chain))
1498 return -EOPNOTSUPP;
1499
1500 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1501 if (IS_ERR(stats))
1502 return PTR_ERR(stats);
1503 }
1504
1505 trans = nft_trans_alloc(ctx, NFT_MSG_NEWCHAIN,
1506 sizeof(struct nft_trans_chain));
1507 if (trans == NULL) {
1508 free_percpu(stats);
1509 return -ENOMEM;
1510 }
1511
1512 nft_trans_chain_stats(trans) = stats;
1513 nft_trans_chain_update(trans) = true;
1514
1515 if (nla[NFTA_CHAIN_POLICY])
1516 nft_trans_chain_policy(trans) = policy;
1517 else
1518 nft_trans_chain_policy(trans) = -1;
1519
1520 name = nla[NFTA_CHAIN_NAME];
1521 if (nla[NFTA_CHAIN_HANDLE] && name) {
1522 nft_trans_chain_name(trans) =
1523 nla_strdup(name, GFP_KERNEL);
1524 if (!nft_trans_chain_name(trans)) {
1525 kfree(trans);
1526 free_percpu(stats);
1527 return -ENOMEM;
1528 }
1529 }
1530 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
1531
1532 return 0;
1533}
1534
633c9a84
PNA
1535static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1536 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1537 const struct nlattr * const nla[],
1538 struct netlink_ext_ack *extack)
96518518
PM
1539{
1540 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1541 const struct nlattr * uninitialized_var(name);
4035285f
PNA
1542 u8 genmask = nft_genmask_next(net);
1543 int family = nfmsg->nfgen_family;
7c95f6d8 1544 struct nft_af_info *afi;
96518518
PM
1545 struct nft_table *table;
1546 struct nft_chain *chain;
57de2a0c 1547 u8 policy = NF_ACCEPT;
4035285f 1548 struct nft_ctx ctx;
96518518 1549 u64 handle = 0;
96518518
PM
1550 bool create;
1551
1552 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
1553
99633ab2 1554 afi = nf_tables_afinfo_lookup(net, family, true);
96518518
PM
1555 if (IS_ERR(afi))
1556 return PTR_ERR(afi);
1557
f2a6d766 1558 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
96518518
PM
1559 if (IS_ERR(table))
1560 return PTR_ERR(table);
1561
96518518
PM
1562 chain = NULL;
1563 name = nla[NFTA_CHAIN_NAME];
1564
1565 if (nla[NFTA_CHAIN_HANDLE]) {
1566 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
664b0f8c 1567 chain = nf_tables_chain_lookup_byhandle(table, handle, genmask);
96518518
PM
1568 if (IS_ERR(chain))
1569 return PTR_ERR(chain);
1570 } else {
664b0f8c 1571 chain = nf_tables_chain_lookup(table, name, genmask);
96518518
PM
1572 if (IS_ERR(chain)) {
1573 if (PTR_ERR(chain) != -ENOENT)
1574 return PTR_ERR(chain);
1575 chain = NULL;
1576 }
1577 }
1578
57de2a0c 1579 if (nla[NFTA_CHAIN_POLICY]) {
f323d954
PNA
1580 if (chain != NULL &&
1581 !nft_is_base_chain(chain))
d6b6cb1d
PNA
1582 return -EOPNOTSUPP;
1583
1584 if (chain == NULL &&
57de2a0c
PM
1585 nla[NFTA_CHAIN_HOOK] == NULL)
1586 return -EOPNOTSUPP;
1587
8f46df18 1588 policy = ntohl(nla_get_be32(nla[NFTA_CHAIN_POLICY]));
57de2a0c
PM
1589 switch (policy) {
1590 case NF_DROP:
1591 case NF_ACCEPT:
1592 break;
1593 default:
1594 return -EINVAL;
1595 }
1596 }
1597
4035285f
PNA
1598 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
1599
96518518
PM
1600 if (chain != NULL) {
1601 if (nlh->nlmsg_flags & NLM_F_EXCL)
1602 return -EEXIST;
1603 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1604 return -EOPNOTSUPP;
1605
2c4a488a 1606 return nf_tables_updchain(&ctx, genmask, policy, create);
96518518
PM
1607 }
1608
4035285f 1609 return nf_tables_addchain(&ctx, family, genmask, policy, create);
96518518
PM
1610}
1611
633c9a84
PNA
1612static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1613 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
1614 const struct nlattr * const nla[],
1615 struct netlink_ext_ack *extack)
96518518
PM
1616{
1617 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 1618 u8 genmask = nft_genmask_next(net);
7c95f6d8 1619 struct nft_af_info *afi;
96518518
PM
1620 struct nft_table *table;
1621 struct nft_chain *chain;
9dee1474 1622 struct nft_rule *rule;
96518518 1623 int family = nfmsg->nfgen_family;
91c7b38d 1624 struct nft_ctx ctx;
9dee1474
PNA
1625 u32 use;
1626 int err;
96518518 1627
99633ab2 1628 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
1629 if (IS_ERR(afi))
1630 return PTR_ERR(afi);
1631
f2a6d766 1632 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
96518518
PM
1633 if (IS_ERR(table))
1634 return PTR_ERR(table);
1635
664b0f8c 1636 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
96518518
PM
1637 if (IS_ERR(chain))
1638 return PTR_ERR(chain);
9dee1474
PNA
1639
1640 if (nlh->nlmsg_flags & NLM_F_NONREC &&
1641 chain->use > 0)
96518518
PM
1642 return -EBUSY;
1643
633c9a84 1644 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
0165d932 1645
9dee1474
PNA
1646 use = chain->use;
1647 list_for_each_entry(rule, &chain->rules, list) {
1648 if (!nft_is_active_next(net, rule))
1649 continue;
1650 use--;
1651
1652 err = nft_delrule(&ctx, rule);
1653 if (err < 0)
1654 return err;
1655 }
1656
1657 /* There are rules and elements that are still holding references to us,
1658 * we cannot do a recursive removal in this case.
1659 */
1660 if (use > 0)
1661 return -EBUSY;
1662
ee01d542 1663 return nft_delchain(&ctx);
96518518
PM
1664}
1665
96518518
PM
1666/*
1667 * Expressions
1668 */
1669
1670/**
ef1f7df9
PM
1671 * nft_register_expr - register nf_tables expr type
1672 * @ops: expr type
96518518 1673 *
ef1f7df9 1674 * Registers the expr type for use with nf_tables. Returns zero on
96518518
PM
1675 * success or a negative errno code otherwise.
1676 */
ef1f7df9 1677int nft_register_expr(struct nft_expr_type *type)
96518518
PM
1678{
1679 nfnl_lock(NFNL_SUBSYS_NFTABLES);
758dbcec 1680 if (type->family == NFPROTO_UNSPEC)
e688a7f8 1681 list_add_tail_rcu(&type->list, &nf_tables_expressions);
758dbcec 1682 else
e688a7f8 1683 list_add_rcu(&type->list, &nf_tables_expressions);
96518518
PM
1684 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1685 return 0;
1686}
1687EXPORT_SYMBOL_GPL(nft_register_expr);
1688
1689/**
ef1f7df9
PM
1690 * nft_unregister_expr - unregister nf_tables expr type
1691 * @ops: expr type
96518518 1692 *
ef1f7df9 1693 * Unregisters the expr typefor use with nf_tables.
96518518 1694 */
ef1f7df9 1695void nft_unregister_expr(struct nft_expr_type *type)
96518518
PM
1696{
1697 nfnl_lock(NFNL_SUBSYS_NFTABLES);
e688a7f8 1698 list_del_rcu(&type->list);
96518518
PM
1699 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1700}
1701EXPORT_SYMBOL_GPL(nft_unregister_expr);
1702
64d46806
PM
1703static const struct nft_expr_type *__nft_expr_type_get(u8 family,
1704 struct nlattr *nla)
96518518 1705{
ef1f7df9 1706 const struct nft_expr_type *type;
96518518 1707
ef1f7df9 1708 list_for_each_entry(type, &nf_tables_expressions, list) {
64d46806
PM
1709 if (!nla_strcmp(nla, type->name) &&
1710 (!type->family || type->family == family))
ef1f7df9 1711 return type;
96518518
PM
1712 }
1713 return NULL;
1714}
1715
64d46806
PM
1716static const struct nft_expr_type *nft_expr_type_get(u8 family,
1717 struct nlattr *nla)
96518518 1718{
ef1f7df9 1719 const struct nft_expr_type *type;
96518518
PM
1720
1721 if (nla == NULL)
1722 return ERR_PTR(-EINVAL);
1723
64d46806 1724 type = __nft_expr_type_get(family, nla);
ef1f7df9
PM
1725 if (type != NULL && try_module_get(type->owner))
1726 return type;
96518518
PM
1727
1728#ifdef CONFIG_MODULES
ef1f7df9 1729 if (type == NULL) {
64d46806
PM
1730 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1731 request_module("nft-expr-%u-%.*s", family,
1732 nla_len(nla), (char *)nla_data(nla));
1733 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1734 if (__nft_expr_type_get(family, nla))
1735 return ERR_PTR(-EAGAIN);
1736
96518518
PM
1737 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1738 request_module("nft-expr-%.*s",
1739 nla_len(nla), (char *)nla_data(nla));
1740 nfnl_lock(NFNL_SUBSYS_NFTABLES);
64d46806 1741 if (__nft_expr_type_get(family, nla))
96518518
PM
1742 return ERR_PTR(-EAGAIN);
1743 }
1744#endif
1745 return ERR_PTR(-ENOENT);
1746}
1747
1748static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
1749 [NFTA_EXPR_NAME] = { .type = NLA_STRING },
1750 [NFTA_EXPR_DATA] = { .type = NLA_NESTED },
1751};
1752
1753static int nf_tables_fill_expr_info(struct sk_buff *skb,
1754 const struct nft_expr *expr)
1755{
ef1f7df9 1756 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
96518518
PM
1757 goto nla_put_failure;
1758
1759 if (expr->ops->dump) {
1760 struct nlattr *data = nla_nest_start(skb, NFTA_EXPR_DATA);
1761 if (data == NULL)
1762 goto nla_put_failure;
1763 if (expr->ops->dump(skb, expr) < 0)
1764 goto nla_put_failure;
1765 nla_nest_end(skb, data);
1766 }
1767
1768 return skb->len;
1769
1770nla_put_failure:
1771 return -1;
1772};
1773
0b2d8a7b
PM
1774int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
1775 const struct nft_expr *expr)
1776{
1777 struct nlattr *nest;
1778
1779 nest = nla_nest_start(skb, attr);
1780 if (!nest)
1781 goto nla_put_failure;
1782 if (nf_tables_fill_expr_info(skb, expr) < 0)
1783 goto nla_put_failure;
1784 nla_nest_end(skb, nest);
1785 return 0;
1786
1787nla_put_failure:
1788 return -1;
1789}
1790
96518518
PM
1791struct nft_expr_info {
1792 const struct nft_expr_ops *ops;
ef1f7df9 1793 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
96518518
PM
1794};
1795
0ca743a5
PNA
1796static int nf_tables_expr_parse(const struct nft_ctx *ctx,
1797 const struct nlattr *nla,
96518518
PM
1798 struct nft_expr_info *info)
1799{
ef1f7df9 1800 const struct nft_expr_type *type;
96518518 1801 const struct nft_expr_ops *ops;
ef1f7df9 1802 struct nlattr *tb[NFTA_EXPR_MAX + 1];
96518518
PM
1803 int err;
1804
fceb6435 1805 err = nla_parse_nested(tb, NFTA_EXPR_MAX, nla, nft_expr_policy, NULL);
96518518
PM
1806 if (err < 0)
1807 return err;
1808
64d46806 1809 type = nft_expr_type_get(ctx->afi->family, tb[NFTA_EXPR_NAME]);
ef1f7df9
PM
1810 if (IS_ERR(type))
1811 return PTR_ERR(type);
1812
1813 if (tb[NFTA_EXPR_DATA]) {
1814 err = nla_parse_nested(info->tb, type->maxattr,
fceb6435 1815 tb[NFTA_EXPR_DATA], type->policy, NULL);
ef1f7df9
PM
1816 if (err < 0)
1817 goto err1;
1818 } else
1819 memset(info->tb, 0, sizeof(info->tb[0]) * (type->maxattr + 1));
1820
1821 if (type->select_ops != NULL) {
0ca743a5
PNA
1822 ops = type->select_ops(ctx,
1823 (const struct nlattr * const *)info->tb);
ef1f7df9
PM
1824 if (IS_ERR(ops)) {
1825 err = PTR_ERR(ops);
1826 goto err1;
1827 }
1828 } else
1829 ops = type->ops;
1830
96518518
PM
1831 info->ops = ops;
1832 return 0;
ef1f7df9
PM
1833
1834err1:
1835 module_put(type->owner);
1836 return err;
96518518
PM
1837}
1838
1839static int nf_tables_newexpr(const struct nft_ctx *ctx,
ef1f7df9 1840 const struct nft_expr_info *info,
96518518
PM
1841 struct nft_expr *expr)
1842{
1843 const struct nft_expr_ops *ops = info->ops;
1844 int err;
1845
1846 expr->ops = ops;
1847 if (ops->init) {
ef1f7df9 1848 err = ops->init(ctx, expr, (const struct nlattr **)info->tb);
96518518
PM
1849 if (err < 0)
1850 goto err1;
1851 }
1852
c56e3956
LZ
1853 if (ops->validate) {
1854 const struct nft_data *data = NULL;
1855
1856 err = ops->validate(ctx, expr, &data);
1857 if (err < 0)
1858 goto err2;
1859 }
1860
96518518
PM
1861 return 0;
1862
c56e3956
LZ
1863err2:
1864 if (ops->destroy)
1865 ops->destroy(ctx, expr);
96518518
PM
1866err1:
1867 expr->ops = NULL;
1868 return err;
1869}
1870
62472bce
PM
1871static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
1872 struct nft_expr *expr)
96518518
PM
1873{
1874 if (expr->ops->destroy)
62472bce 1875 expr->ops->destroy(ctx, expr);
ef1f7df9 1876 module_put(expr->ops->type->owner);
96518518
PM
1877}
1878
0b2d8a7b
PM
1879struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
1880 const struct nlattr *nla)
1881{
1882 struct nft_expr_info info;
1883 struct nft_expr *expr;
1884 int err;
1885
1886 err = nf_tables_expr_parse(ctx, nla, &info);
1887 if (err < 0)
1888 goto err1;
1889
1890 err = -ENOMEM;
1891 expr = kzalloc(info.ops->size, GFP_KERNEL);
1892 if (expr == NULL)
1893 goto err2;
1894
1895 err = nf_tables_newexpr(ctx, &info, expr);
1896 if (err < 0)
6cafaf47 1897 goto err3;
0b2d8a7b
PM
1898
1899 return expr;
6cafaf47
LZ
1900err3:
1901 kfree(expr);
0b2d8a7b
PM
1902err2:
1903 module_put(info.ops->type->owner);
1904err1:
1905 return ERR_PTR(err);
1906}
1907
1908void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
1909{
1910 nf_tables_expr_destroy(ctx, expr);
1911 kfree(expr);
1912}
1913
96518518
PM
1914/*
1915 * Rules
1916 */
1917
1918static struct nft_rule *__nf_tables_rule_lookup(const struct nft_chain *chain,
1919 u64 handle)
1920{
1921 struct nft_rule *rule;
1922
1923 // FIXME: this sucks
1924 list_for_each_entry(rule, &chain->rules, list) {
1925 if (handle == rule->handle)
1926 return rule;
1927 }
1928
1929 return ERR_PTR(-ENOENT);
1930}
1931
1932static struct nft_rule *nf_tables_rule_lookup(const struct nft_chain *chain,
1933 const struct nlattr *nla)
1934{
1935 if (nla == NULL)
1936 return ERR_PTR(-EINVAL);
1937
1938 return __nf_tables_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
1939}
1940
1941static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
b2fbd044
LZ
1942 [NFTA_RULE_TABLE] = { .type = NLA_STRING,
1943 .len = NFT_TABLE_MAXNAMELEN - 1 },
96518518
PM
1944 [NFTA_RULE_CHAIN] = { .type = NLA_STRING,
1945 .len = NFT_CHAIN_MAXNAMELEN - 1 },
1946 [NFTA_RULE_HANDLE] = { .type = NLA_U64 },
1947 [NFTA_RULE_EXPRESSIONS] = { .type = NLA_NESTED },
0ca743a5 1948 [NFTA_RULE_COMPAT] = { .type = NLA_NESTED },
5e948466 1949 [NFTA_RULE_POSITION] = { .type = NLA_U64 },
0768b3b3
PNA
1950 [NFTA_RULE_USERDATA] = { .type = NLA_BINARY,
1951 .len = NFT_USERDATA_MAXLEN },
96518518
PM
1952};
1953
84d7fce6
PNA
1954static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
1955 u32 portid, u32 seq, int event,
1956 u32 flags, int family,
96518518
PM
1957 const struct nft_table *table,
1958 const struct nft_chain *chain,
1959 const struct nft_rule *rule)
1960{
1961 struct nlmsghdr *nlh;
1962 struct nfgenmsg *nfmsg;
1963 const struct nft_expr *expr, *next;
1964 struct nlattr *list;
5e948466 1965 const struct nft_rule *prule;
dedb67c4 1966 u16 type = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
96518518 1967
dedb67c4 1968 nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg), flags);
96518518
PM
1969 if (nlh == NULL)
1970 goto nla_put_failure;
1971
1972 nfmsg = nlmsg_data(nlh);
1973 nfmsg->nfgen_family = family;
1974 nfmsg->version = NFNETLINK_V0;
84d7fce6 1975 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
96518518
PM
1976
1977 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
1978 goto nla_put_failure;
1979 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
1980 goto nla_put_failure;
b46f6ded
ND
1981 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle),
1982 NFTA_RULE_PAD))
96518518
PM
1983 goto nla_put_failure;
1984
5e948466 1985 if ((event != NFT_MSG_DELRULE) && (rule->list.prev != &chain->rules)) {
cbbb40e2 1986 prule = list_prev_entry(rule, list);
5e948466 1987 if (nla_put_be64(skb, NFTA_RULE_POSITION,
b46f6ded
ND
1988 cpu_to_be64(prule->handle),
1989 NFTA_RULE_PAD))
5e948466
EL
1990 goto nla_put_failure;
1991 }
1992
96518518
PM
1993 list = nla_nest_start(skb, NFTA_RULE_EXPRESSIONS);
1994 if (list == NULL)
1995 goto nla_put_failure;
1996 nft_rule_for_each_expr(expr, next, rule) {
0b2d8a7b 1997 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
96518518 1998 goto nla_put_failure;
96518518
PM
1999 }
2000 nla_nest_end(skb, list);
2001
86f1ec32
PM
2002 if (rule->udata) {
2003 struct nft_userdata *udata = nft_userdata(rule);
2004 if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
2005 udata->data) < 0)
2006 goto nla_put_failure;
2007 }
0768b3b3 2008
053c095a
JB
2009 nlmsg_end(skb, nlh);
2010 return 0;
96518518
PM
2011
2012nla_put_failure:
2013 nlmsg_trim(skb, nlh);
2014 return -1;
2015}
2016
25e94a99
PNA
2017static void nf_tables_rule_notify(const struct nft_ctx *ctx,
2018 const struct nft_rule *rule, int event)
96518518
PM
2019{
2020 struct sk_buff *skb;
96518518
PM
2021 int err;
2022
128ad332
PNA
2023 if (!ctx->report &&
2024 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 2025 return;
96518518 2026
96518518
PM
2027 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2028 if (skb == NULL)
2029 goto err;
2030
84d7fce6
PNA
2031 err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
2032 event, 0, ctx->afi->family, ctx->table,
35151d84 2033 ctx->chain, rule);
96518518
PM
2034 if (err < 0) {
2035 kfree_skb(skb);
2036 goto err;
2037 }
2038
25e94a99
PNA
2039 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
2040 ctx->report, GFP_KERNEL);
2041 return;
96518518 2042err:
25e94a99 2043 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
96518518
PM
2044}
2045
6e1f760e 2046struct nft_rule_dump_ctx {
e46abbcc 2047 char *table;
b7263e07 2048 char *chain;
6e1f760e
PNA
2049};
2050
96518518
PM
2051static int nf_tables_dump_rules(struct sk_buff *skb,
2052 struct netlink_callback *cb)
2053{
2054 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
6e1f760e 2055 const struct nft_rule_dump_ctx *ctx = cb->data;
96518518
PM
2056 const struct nft_af_info *afi;
2057 const struct nft_table *table;
2058 const struct nft_chain *chain;
2059 const struct nft_rule *rule;
2060 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 2061 struct net *net = sock_net(skb->sk);
96518518
PM
2062 int family = nfmsg->nfgen_family;
2063
e688a7f8 2064 rcu_read_lock();
38e029f1
PNA
2065 cb->seq = net->nft.base_seq;
2066
e688a7f8 2067 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
96518518
PM
2068 if (family != NFPROTO_UNSPEC && family != afi->family)
2069 continue;
2070
e688a7f8 2071 list_for_each_entry_rcu(table, &afi->tables, list) {
e46abbcc 2072 if (ctx && ctx->table &&
6e1f760e
PNA
2073 strcmp(ctx->table, table->name) != 0)
2074 continue;
2075
e688a7f8 2076 list_for_each_entry_rcu(chain, &table->chains, list) {
6e1f760e
PNA
2077 if (ctx && ctx->chain[0] &&
2078 strcmp(ctx->chain, chain->name) != 0)
2079 continue;
2080
e688a7f8 2081 list_for_each_entry_rcu(rule, &chain->rules, list) {
889f7ee7 2082 if (!nft_is_active(net, rule))
0628b123 2083 goto cont;
96518518
PM
2084 if (idx < s_idx)
2085 goto cont;
2086 if (idx > s_idx)
2087 memset(&cb->args[1], 0,
2088 sizeof(cb->args) - sizeof(cb->args[0]));
84d7fce6 2089 if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
96518518
PM
2090 cb->nlh->nlmsg_seq,
2091 NFT_MSG_NEWRULE,
2092 NLM_F_MULTI | NLM_F_APPEND,
2093 afi->family, table, chain, rule) < 0)
2094 goto done;
38e029f1
PNA
2095
2096 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
96518518
PM
2097cont:
2098 idx++;
2099 }
2100 }
2101 }
2102 }
2103done:
e688a7f8
PNA
2104 rcu_read_unlock();
2105
96518518
PM
2106 cb->args[0] = idx;
2107 return skb->len;
2108}
2109
6e1f760e
PNA
2110static int nf_tables_dump_rules_done(struct netlink_callback *cb)
2111{
e46abbcc
PS
2112 struct nft_rule_dump_ctx *ctx = cb->data;
2113
2114 if (ctx) {
2115 kfree(ctx->table);
b7263e07 2116 kfree(ctx->chain);
e46abbcc
PS
2117 kfree(ctx);
2118 }
6e1f760e
PNA
2119 return 0;
2120}
2121
7b8002a1
PNA
2122static int nf_tables_getrule(struct net *net, struct sock *nlsk,
2123 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2124 const struct nlattr * const nla[],
2125 struct netlink_ext_ack *extack)
96518518
PM
2126{
2127 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2128 u8 genmask = nft_genmask_cur(net);
96518518
PM
2129 const struct nft_af_info *afi;
2130 const struct nft_table *table;
2131 const struct nft_chain *chain;
2132 const struct nft_rule *rule;
2133 struct sk_buff *skb2;
2134 int family = nfmsg->nfgen_family;
2135 int err;
2136
2137 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2138 struct netlink_dump_control c = {
2139 .dump = nf_tables_dump_rules,
6e1f760e 2140 .done = nf_tables_dump_rules_done,
96518518 2141 };
6e1f760e
PNA
2142
2143 if (nla[NFTA_RULE_TABLE] || nla[NFTA_RULE_CHAIN]) {
2144 struct nft_rule_dump_ctx *ctx;
2145
2146 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2147 if (!ctx)
2148 return -ENOMEM;
2149
e46abbcc
PS
2150 if (nla[NFTA_RULE_TABLE]) {
2151 ctx->table = nla_strdup(nla[NFTA_RULE_TABLE],
2152 GFP_KERNEL);
2153 if (!ctx->table) {
2154 kfree(ctx);
2155 return -ENOMEM;
2156 }
2157 }
b7263e07
PS
2158 if (nla[NFTA_RULE_CHAIN]) {
2159 ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN],
2160 GFP_KERNEL);
2161 if (!ctx->chain) {
2162 kfree(ctx->table);
2163 kfree(ctx);
2164 return -ENOMEM;
2165 }
2166 }
6e1f760e
PNA
2167 c.data = ctx;
2168 }
2169
96518518
PM
2170 return netlink_dump_start(nlsk, skb, nlh, &c);
2171 }
2172
99633ab2 2173 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
2174 if (IS_ERR(afi))
2175 return PTR_ERR(afi);
2176
f2a6d766 2177 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
96518518
PM
2178 if (IS_ERR(table))
2179 return PTR_ERR(table);
2180
664b0f8c 2181 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
96518518
PM
2182 if (IS_ERR(chain))
2183 return PTR_ERR(chain);
2184
2185 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
2186 if (IS_ERR(rule))
2187 return PTR_ERR(rule);
2188
2189 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2190 if (!skb2)
2191 return -ENOMEM;
2192
84d7fce6 2193 err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
96518518
PM
2194 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
2195 family, table, chain, rule);
2196 if (err < 0)
2197 goto err;
2198
2199 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2200
2201err:
2202 kfree_skb(skb2);
2203 return err;
2204}
2205
62472bce
PM
2206static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
2207 struct nft_rule *rule)
96518518 2208{
96518518
PM
2209 struct nft_expr *expr;
2210
2211 /*
2212 * Careful: some expressions might not be initialized in case this
2213 * is called on error from nf_tables_newrule().
2214 */
2215 expr = nft_expr_first(rule);
3e38df13 2216 while (expr != nft_expr_last(rule) && expr->ops) {
62472bce 2217 nf_tables_expr_destroy(ctx, expr);
96518518
PM
2218 expr = nft_expr_next(expr);
2219 }
2220 kfree(rule);
2221}
2222
1081d11b
PNA
2223#define NFT_RULE_MAXEXPRS 128
2224
2225static struct nft_expr_info *info;
2226
633c9a84
PNA
2227static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2228 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2229 const struct nlattr * const nla[],
2230 struct netlink_ext_ack *extack)
96518518
PM
2231{
2232 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2233 u8 genmask = nft_genmask_next(net);
7c95f6d8 2234 struct nft_af_info *afi;
96518518
PM
2235 struct nft_table *table;
2236 struct nft_chain *chain;
2237 struct nft_rule *rule, *old_rule = NULL;
86f1ec32 2238 struct nft_userdata *udata;
1081d11b 2239 struct nft_trans *trans = NULL;
96518518
PM
2240 struct nft_expr *expr;
2241 struct nft_ctx ctx;
2242 struct nlattr *tmp;
86f1ec32 2243 unsigned int size, i, n, ulen = 0, usize = 0;
96518518
PM
2244 int err, rem;
2245 bool create;
5e948466 2246 u64 handle, pos_handle;
96518518
PM
2247
2248 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
2249
99633ab2 2250 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
96518518
PM
2251 if (IS_ERR(afi))
2252 return PTR_ERR(afi);
2253
f2a6d766 2254 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
96518518
PM
2255 if (IS_ERR(table))
2256 return PTR_ERR(table);
2257
664b0f8c 2258 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
96518518
PM
2259 if (IS_ERR(chain))
2260 return PTR_ERR(chain);
2261
2262 if (nla[NFTA_RULE_HANDLE]) {
2263 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
2264 rule = __nf_tables_rule_lookup(chain, handle);
2265 if (IS_ERR(rule))
2266 return PTR_ERR(rule);
2267
2268 if (nlh->nlmsg_flags & NLM_F_EXCL)
2269 return -EEXIST;
2270 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2271 old_rule = rule;
2272 else
2273 return -EOPNOTSUPP;
2274 } else {
2275 if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
2276 return -EINVAL;
2277 handle = nf_tables_alloc_handle(table);
a0a7379e
PNA
2278
2279 if (chain->use == UINT_MAX)
2280 return -EOVERFLOW;
96518518
PM
2281 }
2282
5e948466
EL
2283 if (nla[NFTA_RULE_POSITION]) {
2284 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
2285 return -EOPNOTSUPP;
2286
2287 pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
2288 old_rule = __nf_tables_rule_lookup(chain, pos_handle);
2289 if (IS_ERR(old_rule))
2290 return PTR_ERR(old_rule);
2291 }
2292
633c9a84 2293 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
0ca743a5 2294
96518518
PM
2295 n = 0;
2296 size = 0;
2297 if (nla[NFTA_RULE_EXPRESSIONS]) {
2298 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
2299 err = -EINVAL;
2300 if (nla_type(tmp) != NFTA_LIST_ELEM)
2301 goto err1;
2302 if (n == NFT_RULE_MAXEXPRS)
2303 goto err1;
0ca743a5 2304 err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
96518518
PM
2305 if (err < 0)
2306 goto err1;
2307 size += info[n].ops->size;
2308 n++;
2309 }
2310 }
9889840f
PM
2311 /* Check for overflow of dlen field */
2312 err = -EFBIG;
2313 if (size >= 1 << 12)
2314 goto err1;
96518518 2315
86f1ec32 2316 if (nla[NFTA_RULE_USERDATA]) {
0768b3b3 2317 ulen = nla_len(nla[NFTA_RULE_USERDATA]);
86f1ec32
PM
2318 if (ulen > 0)
2319 usize = sizeof(struct nft_userdata) + ulen;
2320 }
0768b3b3 2321
96518518 2322 err = -ENOMEM;
86f1ec32 2323 rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
96518518
PM
2324 if (rule == NULL)
2325 goto err1;
2326
889f7ee7 2327 nft_activate_next(net, rule);
0628b123 2328
96518518
PM
2329 rule->handle = handle;
2330 rule->dlen = size;
86f1ec32 2331 rule->udata = ulen ? 1 : 0;
0768b3b3 2332
86f1ec32
PM
2333 if (ulen) {
2334 udata = nft_userdata(rule);
2335 udata->len = ulen - 1;
2336 nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
2337 }
96518518 2338
96518518
PM
2339 expr = nft_expr_first(rule);
2340 for (i = 0; i < n; i++) {
2341 err = nf_tables_newexpr(&ctx, &info[i], expr);
2342 if (err < 0)
2343 goto err2;
ef1f7df9 2344 info[i].ops = NULL;
96518518
PM
2345 expr = nft_expr_next(expr);
2346 }
2347
96518518 2348 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
889f7ee7 2349 if (nft_is_active_next(net, old_rule)) {
ac904ac8 2350 trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
b380e5c7 2351 old_rule);
1081d11b 2352 if (trans == NULL) {
0628b123
PNA
2353 err = -ENOMEM;
2354 goto err2;
2355 }
889f7ee7 2356 nft_deactivate_next(net, old_rule);
ac34b861 2357 chain->use--;
5bc5c307 2358 list_add_tail_rcu(&rule->list, &old_rule->list);
0628b123
PNA
2359 } else {
2360 err = -ENOENT;
2361 goto err2;
2362 }
96518518 2363 } else if (nlh->nlmsg_flags & NLM_F_APPEND)
5e948466
EL
2364 if (old_rule)
2365 list_add_rcu(&rule->list, &old_rule->list);
2366 else
2367 list_add_tail_rcu(&rule->list, &chain->rules);
2368 else {
2369 if (old_rule)
2370 list_add_tail_rcu(&rule->list, &old_rule->list);
2371 else
2372 list_add_rcu(&rule->list, &chain->rules);
2373 }
96518518 2374
b380e5c7 2375 if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
0628b123
PNA
2376 err = -ENOMEM;
2377 goto err3;
2378 }
4fefee57 2379 chain->use++;
96518518
PM
2380 return 0;
2381
0628b123
PNA
2382err3:
2383 list_del_rcu(&rule->list);
96518518 2384err2:
62472bce 2385 nf_tables_rule_destroy(&ctx, rule);
96518518
PM
2386err1:
2387 for (i = 0; i < n; i++) {
2388 if (info[i].ops != NULL)
ef1f7df9 2389 module_put(info[i].ops->type->owner);
96518518
PM
2390 }
2391 return err;
2392}
2393
1a94e38d
PNA
2394static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
2395 const struct nlattr *nla)
2396{
2397 u32 id = ntohl(nla_get_be32(nla));
2398 struct nft_trans *trans;
2399
2400 list_for_each_entry(trans, &net->nft.commit_list, list) {
2401 struct nft_rule *rule = nft_trans_rule(trans);
2402
2403 if (trans->msg_type == NFT_MSG_NEWRULE &&
2404 id == nft_trans_rule_id(trans))
2405 return rule;
2406 }
2407 return ERR_PTR(-ENOENT);
2408}
2409
633c9a84
PNA
2410static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2411 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2412 const struct nlattr * const nla[],
2413 struct netlink_ext_ack *extack)
96518518
PM
2414{
2415 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 2416 u8 genmask = nft_genmask_next(net);
7c95f6d8 2417 struct nft_af_info *afi;
7c95f6d8 2418 struct nft_table *table;
cf9dc09d
PNA
2419 struct nft_chain *chain = NULL;
2420 struct nft_rule *rule;
0628b123
PNA
2421 int family = nfmsg->nfgen_family, err = 0;
2422 struct nft_ctx ctx;
96518518 2423
99633ab2 2424 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
2425 if (IS_ERR(afi))
2426 return PTR_ERR(afi);
2427
f2a6d766 2428 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
96518518
PM
2429 if (IS_ERR(table))
2430 return PTR_ERR(table);
2431
cf9dc09d 2432 if (nla[NFTA_RULE_CHAIN]) {
664b0f8c
PNA
2433 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN],
2434 genmask);
cf9dc09d
PNA
2435 if (IS_ERR(chain))
2436 return PTR_ERR(chain);
2437 }
96518518 2438
633c9a84 2439 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
0628b123 2440
cf9dc09d
PNA
2441 if (chain) {
2442 if (nla[NFTA_RULE_HANDLE]) {
2443 rule = nf_tables_rule_lookup(chain,
2444 nla[NFTA_RULE_HANDLE]);
2445 if (IS_ERR(rule))
2446 return PTR_ERR(rule);
96518518 2447
1a94e38d
PNA
2448 err = nft_delrule(&ctx, rule);
2449 } else if (nla[NFTA_RULE_ID]) {
2450 rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
2451 if (IS_ERR(rule))
2452 return PTR_ERR(rule);
2453
5e266fe7 2454 err = nft_delrule(&ctx, rule);
cf9dc09d 2455 } else {
ce24b721 2456 err = nft_delrule_by_chain(&ctx);
cf9dc09d
PNA
2457 }
2458 } else {
2459 list_for_each_entry(chain, &table->chains, list) {
664b0f8c
PNA
2460 if (!nft_is_active_next(net, chain))
2461 continue;
2462
cf9dc09d 2463 ctx.chain = chain;
ce24b721 2464 err = nft_delrule_by_chain(&ctx);
0628b123
PNA
2465 if (err < 0)
2466 break;
2467 }
2468 }
2469
2470 return err;
2471}
2472
20a69341
PM
2473/*
2474 * Sets
2475 */
2476
2b664957 2477static LIST_HEAD(nf_tables_set_types);
20a69341 2478
2b664957 2479int nft_register_set(struct nft_set_type *type)
20a69341
PM
2480{
2481 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2b664957 2482 list_add_tail_rcu(&type->list, &nf_tables_set_types);
20a69341
PM
2483 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2484 return 0;
2485}
2486EXPORT_SYMBOL_GPL(nft_register_set);
2487
2b664957 2488void nft_unregister_set(struct nft_set_type *type)
20a69341
PM
2489{
2490 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2b664957 2491 list_del_rcu(&type->list);
20a69341
PM
2492 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2493}
2494EXPORT_SYMBOL_GPL(nft_unregister_set);
2495
2b664957
PNA
2496#define NFT_SET_FEATURES (NFT_SET_INTERVAL | NFT_SET_MAP | \
2497 NFT_SET_TIMEOUT | NFT_SET_OBJECT)
2498
2499static bool nft_set_ops_candidate(const struct nft_set_ops *ops, u32 flags)
2500{
2501 return (flags & ops->features) == (flags & NFT_SET_FEATURES);
2502}
2503
c50b960c
PM
2504/*
2505 * Select a set implementation based on the data characteristics and the
2506 * given policy. The total memory use might not be known if no size is
2507 * given, in that case the amount of memory per element is used.
2508 */
2509static const struct nft_set_ops *
2b664957
PNA
2510nft_select_set_ops(const struct nft_ctx *ctx,
2511 const struct nlattr * const nla[],
c50b960c
PM
2512 const struct nft_set_desc *desc,
2513 enum nft_set_policies policy)
20a69341 2514{
c50b960c
PM
2515 const struct nft_set_ops *ops, *bops;
2516 struct nft_set_estimate est, best;
2b664957
PNA
2517 const struct nft_set_type *type;
2518 u32 flags = 0;
20a69341
PM
2519
2520#ifdef CONFIG_MODULES
2b664957 2521 if (list_empty(&nf_tables_set_types)) {
20a69341
PM
2522 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2523 request_module("nft-set");
2524 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2b664957 2525 if (!list_empty(&nf_tables_set_types))
20a69341
PM
2526 return ERR_PTR(-EAGAIN);
2527 }
2528#endif
2b664957
PNA
2529 if (nla[NFTA_SET_FLAGS] != NULL)
2530 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
20a69341 2531
55af753c
PNA
2532 bops = NULL;
2533 best.size = ~0;
2534 best.lookup = ~0;
0b5a7874 2535 best.space = ~0;
c50b960c 2536
2b664957
PNA
2537 list_for_each_entry(type, &nf_tables_set_types, list) {
2538 if (!type->select_ops)
2539 ops = type->ops;
2540 else
2541 ops = type->select_ops(ctx, desc, flags);
2542 if (!ops)
2543 continue;
2544
2545 if (!nft_set_ops_candidate(ops, flags))
20a69341 2546 continue;
2b664957 2547 if (!ops->estimate(desc, flags, &est))
c50b960c
PM
2548 continue;
2549
2550 switch (policy) {
2551 case NFT_SET_POL_PERFORMANCE:
55af753c 2552 if (est.lookup < best.lookup)
c50b960c 2553 break;
644e334e
PNA
2554 if (est.lookup == best.lookup &&
2555 est.space < best.space)
2556 break;
c50b960c
PM
2557 continue;
2558 case NFT_SET_POL_MEMORY:
0b5a7874
PNA
2559 if (!desc->size) {
2560 if (est.space < best.space)
2561 break;
2562 if (est.space == best.space &&
2563 est.lookup < best.lookup)
2564 break;
2565 } else if (est.size < best.size) {
c50b960c 2566 break;
0b5a7874 2567 }
c50b960c
PM
2568 continue;
2569 default:
2570 break;
2571 }
2572
2b664957 2573 if (!try_module_get(type->owner))
20a69341 2574 continue;
c50b960c 2575 if (bops != NULL)
2b664957 2576 module_put(bops->type->owner);
c50b960c
PM
2577
2578 bops = ops;
2579 best = est;
20a69341
PM
2580 }
2581
c50b960c
PM
2582 if (bops != NULL)
2583 return bops;
2584
20a69341
PM
2585 return ERR_PTR(-EOPNOTSUPP);
2586}
2587
2588static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
b2fbd044
LZ
2589 [NFTA_SET_TABLE] = { .type = NLA_STRING,
2590 .len = NFT_TABLE_MAXNAMELEN - 1 },
a9bdd836 2591 [NFTA_SET_NAME] = { .type = NLA_STRING,
cb39ad8b 2592 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341
PM
2593 [NFTA_SET_FLAGS] = { .type = NLA_U32 },
2594 [NFTA_SET_KEY_TYPE] = { .type = NLA_U32 },
2595 [NFTA_SET_KEY_LEN] = { .type = NLA_U32 },
2596 [NFTA_SET_DATA_TYPE] = { .type = NLA_U32 },
2597 [NFTA_SET_DATA_LEN] = { .type = NLA_U32 },
c50b960c
PM
2598 [NFTA_SET_POLICY] = { .type = NLA_U32 },
2599 [NFTA_SET_DESC] = { .type = NLA_NESTED },
958bee14 2600 [NFTA_SET_ID] = { .type = NLA_U32 },
761da293
PM
2601 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
2602 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
e6d8ecac
CFG
2603 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
2604 .len = NFT_USERDATA_MAXLEN },
8aeff920 2605 [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },
c50b960c
PM
2606};
2607
2608static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
2609 [NFTA_SET_DESC_SIZE] = { .type = NLA_U32 },
20a69341
PM
2610};
2611
633c9a84 2612static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
2613 const struct sk_buff *skb,
2614 const struct nlmsghdr *nlh,
f2a6d766
PNA
2615 const struct nlattr * const nla[],
2616 u8 genmask)
20a69341
PM
2617{
2618 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7c95f6d8
PNA
2619 struct nft_af_info *afi = NULL;
2620 struct nft_table *table = NULL;
20a69341 2621
c9c8e485
PNA
2622 if (nfmsg->nfgen_family != NFPROTO_UNSPEC) {
2623 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
2624 if (IS_ERR(afi))
2625 return PTR_ERR(afi);
2626 }
20a69341
PM
2627
2628 if (nla[NFTA_SET_TABLE] != NULL) {
ec2c9935
PM
2629 if (afi == NULL)
2630 return -EAFNOSUPPORT;
2631
f2a6d766
PNA
2632 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE],
2633 genmask);
20a69341
PM
2634 if (IS_ERR(table))
2635 return PTR_ERR(table);
2636 }
2637
633c9a84 2638 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
20a69341
PM
2639 return 0;
2640}
2641
c7a72e3f
PNA
2642static struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
2643 const struct nlattr *nla, u8 genmask)
20a69341
PM
2644{
2645 struct nft_set *set;
2646
2647 if (nla == NULL)
2648 return ERR_PTR(-EINVAL);
2649
2650 list_for_each_entry(set, &table->sets, list) {
37a9cc52
PNA
2651 if (!nla_strcmp(nla, set->name) &&
2652 nft_active_genmask(set, genmask))
20a69341
PM
2653 return set;
2654 }
2655 return ERR_PTR(-ENOENT);
2656}
2657
c7a72e3f
PNA
2658static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
2659 const struct nlattr *nla,
2660 u8 genmask)
958bee14
PNA
2661{
2662 struct nft_trans *trans;
2663 u32 id = ntohl(nla_get_be32(nla));
2664
2665 list_for_each_entry(trans, &net->nft.commit_list, list) {
37a9cc52
PNA
2666 struct nft_set *set = nft_trans_set(trans);
2667
958bee14 2668 if (trans->msg_type == NFT_MSG_NEWSET &&
37a9cc52
PNA
2669 id == nft_trans_set_id(trans) &&
2670 nft_active_genmask(set, genmask))
2671 return set;
958bee14
PNA
2672 }
2673 return ERR_PTR(-ENOENT);
2674}
c7a72e3f
PNA
2675
2676struct nft_set *nft_set_lookup(const struct net *net,
2677 const struct nft_table *table,
2678 const struct nlattr *nla_set_name,
2679 const struct nlattr *nla_set_id,
2680 u8 genmask)
2681{
2682 struct nft_set *set;
2683
2684 set = nf_tables_set_lookup(table, nla_set_name, genmask);
2685 if (IS_ERR(set)) {
2686 if (!nla_set_id)
2687 return set;
2688
2689 set = nf_tables_set_lookup_byid(net, nla_set_id, genmask);
2690 }
2691 return set;
2692}
2693EXPORT_SYMBOL_GPL(nft_set_lookup);
958bee14 2694
20a69341
PM
2695static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
2696 const char *name)
2697{
2698 const struct nft_set *i;
2699 const char *p;
2700 unsigned long *inuse;
60eb1894 2701 unsigned int n = 0, min = 0;
20a69341 2702
38745490 2703 p = strchr(name, '%');
20a69341
PM
2704 if (p != NULL) {
2705 if (p[1] != 'd' || strchr(p + 2, '%'))
2706 return -EINVAL;
2707
2708 inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
2709 if (inuse == NULL)
2710 return -ENOMEM;
60eb1894 2711cont:
20a69341 2712 list_for_each_entry(i, &ctx->table->sets, list) {
14662917
DB
2713 int tmp;
2714
37a9cc52
PNA
2715 if (!nft_is_active_next(ctx->net, set))
2716 continue;
14662917 2717 if (!sscanf(i->name, name, &tmp))
20a69341 2718 continue;
60eb1894 2719 if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
20a69341 2720 continue;
14662917 2721
60eb1894 2722 set_bit(tmp - min, inuse);
20a69341
PM
2723 }
2724
53b70287 2725 n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
60eb1894
PM
2726 if (n >= BITS_PER_BYTE * PAGE_SIZE) {
2727 min += BITS_PER_BYTE * PAGE_SIZE;
2728 memset(inuse, 0, PAGE_SIZE);
2729 goto cont;
2730 }
20a69341
PM
2731 free_page((unsigned long)inuse);
2732 }
2733
38745490
PS
2734 set->name = kasprintf(GFP_KERNEL, name, min + n);
2735 if (!set->name)
2736 return -ENOMEM;
2737
20a69341 2738 list_for_each_entry(i, &ctx->table->sets, list) {
37a9cc52
PNA
2739 if (!nft_is_active_next(ctx->net, i))
2740 continue;
e63aaaa6
AY
2741 if (!strcmp(set->name, i->name)) {
2742 kfree(set->name);
20a69341 2743 return -ENFILE;
e63aaaa6 2744 }
20a69341
PM
2745 }
2746 return 0;
2747}
2748
2749static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
2750 const struct nft_set *set, u16 event, u16 flags)
2751{
2752 struct nfgenmsg *nfmsg;
2753 struct nlmsghdr *nlh;
c50b960c 2754 struct nlattr *desc;
128ad332
PNA
2755 u32 portid = ctx->portid;
2756 u32 seq = ctx->seq;
20a69341 2757
dedb67c4 2758 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
20a69341
PM
2759 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
2760 flags);
2761 if (nlh == NULL)
2762 goto nla_put_failure;
2763
2764 nfmsg = nlmsg_data(nlh);
2765 nfmsg->nfgen_family = ctx->afi->family;
2766 nfmsg->version = NFNETLINK_V0;
84d7fce6 2767 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
20a69341
PM
2768
2769 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
2770 goto nla_put_failure;
2771 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
2772 goto nla_put_failure;
2773 if (set->flags != 0)
2774 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
2775 goto nla_put_failure;
2776
2777 if (nla_put_be32(skb, NFTA_SET_KEY_TYPE, htonl(set->ktype)))
2778 goto nla_put_failure;
2779 if (nla_put_be32(skb, NFTA_SET_KEY_LEN, htonl(set->klen)))
2780 goto nla_put_failure;
2781 if (set->flags & NFT_SET_MAP) {
2782 if (nla_put_be32(skb, NFTA_SET_DATA_TYPE, htonl(set->dtype)))
2783 goto nla_put_failure;
2784 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
2785 goto nla_put_failure;
2786 }
8aeff920
PNA
2787 if (set->flags & NFT_SET_OBJECT &&
2788 nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
2789 goto nla_put_failure;
20a69341 2790
761da293 2791 if (set->timeout &&
d3e2a111
AP
2792 nla_put_be64(skb, NFTA_SET_TIMEOUT,
2793 cpu_to_be64(jiffies_to_msecs(set->timeout)),
b46f6ded 2794 NFTA_SET_PAD))
761da293
PM
2795 goto nla_put_failure;
2796 if (set->gc_int &&
2797 nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
2798 goto nla_put_failure;
2799
9363dc4b
AB
2800 if (set->policy != NFT_SET_POL_PERFORMANCE) {
2801 if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
2802 goto nla_put_failure;
2803 }
2804
e6d8ecac
CFG
2805 if (nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata))
2806 goto nla_put_failure;
2807
c50b960c
PM
2808 desc = nla_nest_start(skb, NFTA_SET_DESC);
2809 if (desc == NULL)
2810 goto nla_put_failure;
2811 if (set->size &&
2812 nla_put_be32(skb, NFTA_SET_DESC_SIZE, htonl(set->size)))
2813 goto nla_put_failure;
2814 nla_nest_end(skb, desc);
2815
053c095a
JB
2816 nlmsg_end(skb, nlh);
2817 return 0;
20a69341
PM
2818
2819nla_put_failure:
2820 nlmsg_trim(skb, nlh);
2821 return -1;
2822}
2823
25e94a99
PNA
2824static void nf_tables_set_notify(const struct nft_ctx *ctx,
2825 const struct nft_set *set, int event,
2826 gfp_t gfp_flags)
20a69341
PM
2827{
2828 struct sk_buff *skb;
128ad332 2829 u32 portid = ctx->portid;
20a69341
PM
2830 int err;
2831
128ad332
PNA
2832 if (!ctx->report &&
2833 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
25e94a99 2834 return;
20a69341 2835
31f8441c 2836 skb = nlmsg_new(NLMSG_GOODSIZE, gfp_flags);
20a69341
PM
2837 if (skb == NULL)
2838 goto err;
2839
2840 err = nf_tables_fill_set(skb, ctx, set, event, 0);
2841 if (err < 0) {
2842 kfree_skb(skb);
2843 goto err;
2844 }
2845
25e94a99
PNA
2846 nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, ctx->report,
2847 gfp_flags);
2848 return;
20a69341 2849err:
25e94a99 2850 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
20a69341
PM
2851}
2852
5b96af77 2853static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
c9c8e485
PNA
2854{
2855 const struct nft_set *set;
2856 unsigned int idx, s_idx = cb->args[0];
7c95f6d8 2857 struct nft_af_info *afi;
c9c8e485
PNA
2858 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
2859 struct net *net = sock_net(skb->sk);
2860 int cur_family = cb->args[3];
5b96af77 2861 struct nft_ctx *ctx = cb->data, ctx_set;
c9c8e485
PNA
2862
2863 if (cb->args[1])
2864 return skb->len;
2865
e688a7f8 2866 rcu_read_lock();
38e029f1
PNA
2867 cb->seq = net->nft.base_seq;
2868
e688a7f8 2869 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
5b96af77
PNA
2870 if (ctx->afi && ctx->afi != afi)
2871 continue;
2872
c9c8e485
PNA
2873 if (cur_family) {
2874 if (afi->family != cur_family)
2875 continue;
2876
2877 cur_family = 0;
2878 }
e688a7f8 2879 list_for_each_entry_rcu(table, &afi->tables, list) {
5b96af77
PNA
2880 if (ctx->table && ctx->table != table)
2881 continue;
2882
c9c8e485
PNA
2883 if (cur_table) {
2884 if (cur_table != table)
2885 continue;
2886
2887 cur_table = NULL;
2888 }
c9c8e485 2889 idx = 0;
5b96af77 2890 list_for_each_entry_rcu(set, &table->sets, list) {
c9c8e485
PNA
2891 if (idx < s_idx)
2892 goto cont;
37a9cc52
PNA
2893 if (!nft_is_active(net, set))
2894 goto cont;
5b96af77
PNA
2895
2896 ctx_set = *ctx;
2897 ctx_set.table = table;
2898 ctx_set.afi = afi;
2899 if (nf_tables_fill_set(skb, &ctx_set, set,
c9c8e485
PNA
2900 NFT_MSG_NEWSET,
2901 NLM_F_MULTI) < 0) {
2902 cb->args[0] = idx;
2903 cb->args[2] = (unsigned long) table;
2904 cb->args[3] = afi->family;
2905 goto done;
2906 }
38e029f1 2907 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
c9c8e485
PNA
2908cont:
2909 idx++;
2910 }
2911 if (s_idx)
2912 s_idx = 0;
2913 }
2914 }
2915 cb->args[1] = 1;
2916done:
e688a7f8 2917 rcu_read_unlock();
c9c8e485
PNA
2918 return skb->len;
2919}
2920
5b96af77 2921static int nf_tables_dump_sets_done(struct netlink_callback *cb)
20a69341 2922{
5b96af77
PNA
2923 kfree(cb->data);
2924 return 0;
20a69341
PM
2925}
2926
7b8002a1
PNA
2927static int nf_tables_getset(struct net *net, struct sock *nlsk,
2928 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2929 const struct nlattr * const nla[],
2930 struct netlink_ext_ack *extack)
20a69341 2931{
f2a6d766 2932 u8 genmask = nft_genmask_cur(net);
20a69341
PM
2933 const struct nft_set *set;
2934 struct nft_ctx ctx;
2935 struct sk_buff *skb2;
c9c8e485 2936 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
20a69341
PM
2937 int err;
2938
01cfa0a4 2939 /* Verify existence before starting dump */
f2a6d766 2940 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
2941 if (err < 0)
2942 return err;
2943
2944 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2945 struct netlink_dump_control c = {
2946 .dump = nf_tables_dump_sets,
5b96af77 2947 .done = nf_tables_dump_sets_done,
20a69341 2948 };
5b96af77
PNA
2949 struct nft_ctx *ctx_dump;
2950
2951 ctx_dump = kmalloc(sizeof(*ctx_dump), GFP_KERNEL);
2952 if (ctx_dump == NULL)
2953 return -ENOMEM;
2954
2955 *ctx_dump = ctx;
2956 c.data = ctx_dump;
2957
20a69341
PM
2958 return netlink_dump_start(nlsk, skb, nlh, &c);
2959 }
2960
c9c8e485
PNA
2961 /* Only accept unspec with dump */
2962 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
2963 return -EAFNOSUPPORT;
eaa2bcd6
PT
2964 if (!nla[NFTA_SET_TABLE])
2965 return -EINVAL;
c9c8e485 2966
37a9cc52 2967 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
2968 if (IS_ERR(set))
2969 return PTR_ERR(set);
2970
2971 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2972 if (skb2 == NULL)
2973 return -ENOMEM;
2974
2975 err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
2976 if (err < 0)
2977 goto err;
2978
2979 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2980
2981err:
2982 kfree_skb(skb2);
2983 return err;
2984}
2985
c50b960c
PM
2986static int nf_tables_set_desc_parse(const struct nft_ctx *ctx,
2987 struct nft_set_desc *desc,
2988 const struct nlattr *nla)
2989{
2990 struct nlattr *da[NFTA_SET_DESC_MAX + 1];
2991 int err;
2992
fceb6435
JB
2993 err = nla_parse_nested(da, NFTA_SET_DESC_MAX, nla,
2994 nft_set_desc_policy, NULL);
c50b960c
PM
2995 if (err < 0)
2996 return err;
2997
2998 if (da[NFTA_SET_DESC_SIZE] != NULL)
2999 desc->size = ntohl(nla_get_be32(da[NFTA_SET_DESC_SIZE]));
3000
3001 return 0;
3002}
3003
633c9a84
PNA
3004static int nf_tables_newset(struct net *net, struct sock *nlsk,
3005 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3006 const struct nlattr * const nla[],
3007 struct netlink_ext_ack *extack)
20a69341
PM
3008{
3009 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3010 u8 genmask = nft_genmask_next(net);
20a69341 3011 const struct nft_set_ops *ops;
7c95f6d8 3012 struct nft_af_info *afi;
20a69341
PM
3013 struct nft_table *table;
3014 struct nft_set *set;
3015 struct nft_ctx ctx;
38745490 3016 char *name;
20a69341
PM
3017 unsigned int size;
3018 bool create;
761da293 3019 u64 timeout;
8aeff920 3020 u32 ktype, dtype, flags, policy, gc_int, objtype;
c50b960c 3021 struct nft_set_desc desc;
e6d8ecac
CFG
3022 unsigned char *udata;
3023 u16 udlen;
20a69341
PM
3024 int err;
3025
3026 if (nla[NFTA_SET_TABLE] == NULL ||
3027 nla[NFTA_SET_NAME] == NULL ||
958bee14
PNA
3028 nla[NFTA_SET_KEY_LEN] == NULL ||
3029 nla[NFTA_SET_ID] == NULL)
20a69341
PM
3030 return -EINVAL;
3031
c50b960c
PM
3032 memset(&desc, 0, sizeof(desc));
3033
20a69341
PM
3034 ktype = NFT_DATA_VALUE;
3035 if (nla[NFTA_SET_KEY_TYPE] != NULL) {
3036 ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
3037 if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
3038 return -EINVAL;
3039 }
3040
c50b960c 3041 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
7d740264 3042 if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
3043 return -EINVAL;
3044
3045 flags = 0;
3046 if (nla[NFTA_SET_FLAGS] != NULL) {
3047 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
3048 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
7c6c6e95 3049 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
8aeff920
PNA
3050 NFT_SET_MAP | NFT_SET_EVAL |
3051 NFT_SET_OBJECT))
20a69341 3052 return -EINVAL;
8aeff920
PNA
3053 /* Only one of these operations is supported */
3054 if ((flags & (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT)) ==
3055 (NFT_SET_MAP | NFT_SET_EVAL | NFT_SET_OBJECT))
7c6c6e95 3056 return -EOPNOTSUPP;
20a69341
PM
3057 }
3058
3059 dtype = 0;
20a69341
PM
3060 if (nla[NFTA_SET_DATA_TYPE] != NULL) {
3061 if (!(flags & NFT_SET_MAP))
3062 return -EINVAL;
3063
3064 dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
3065 if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
3066 dtype != NFT_DATA_VERDICT)
3067 return -EINVAL;
3068
3069 if (dtype != NFT_DATA_VERDICT) {
3070 if (nla[NFTA_SET_DATA_LEN] == NULL)
3071 return -EINVAL;
c50b960c 3072 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
7d740264 3073 if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
20a69341
PM
3074 return -EINVAL;
3075 } else
7d740264 3076 desc.dlen = sizeof(struct nft_verdict);
20a69341
PM
3077 } else if (flags & NFT_SET_MAP)
3078 return -EINVAL;
3079
8aeff920
PNA
3080 if (nla[NFTA_SET_OBJ_TYPE] != NULL) {
3081 if (!(flags & NFT_SET_OBJECT))
3082 return -EINVAL;
3083
3084 objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
3085 if (objtype == NFT_OBJECT_UNSPEC ||
3086 objtype > NFT_OBJECT_MAX)
3087 return -EINVAL;
3088 } else if (flags & NFT_SET_OBJECT)
3089 return -EINVAL;
3090 else
3091 objtype = NFT_OBJECT_UNSPEC;
3092
761da293
PM
3093 timeout = 0;
3094 if (nla[NFTA_SET_TIMEOUT] != NULL) {
3095 if (!(flags & NFT_SET_TIMEOUT))
3096 return -EINVAL;
d3e2a111
AP
3097 timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
3098 nla[NFTA_SET_TIMEOUT])));
761da293
PM
3099 }
3100 gc_int = 0;
3101 if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
3102 if (!(flags & NFT_SET_TIMEOUT))
3103 return -EINVAL;
3104 gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
3105 }
3106
c50b960c
PM
3107 policy = NFT_SET_POL_PERFORMANCE;
3108 if (nla[NFTA_SET_POLICY] != NULL)
3109 policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
3110
3111 if (nla[NFTA_SET_DESC] != NULL) {
3112 err = nf_tables_set_desc_parse(&ctx, &desc, nla[NFTA_SET_DESC]);
3113 if (err < 0)
3114 return err;
3115 }
3116
20a69341
PM
3117 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
3118
99633ab2 3119 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
20a69341
PM
3120 if (IS_ERR(afi))
3121 return PTR_ERR(afi);
3122
f2a6d766 3123 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], genmask);
20a69341
PM
3124 if (IS_ERR(table))
3125 return PTR_ERR(table);
3126
633c9a84 3127 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
20a69341 3128
37a9cc52 3129 set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
3130 if (IS_ERR(set)) {
3131 if (PTR_ERR(set) != -ENOENT)
3132 return PTR_ERR(set);
1a28ad74 3133 } else {
20a69341
PM
3134 if (nlh->nlmsg_flags & NLM_F_EXCL)
3135 return -EEXIST;
3136 if (nlh->nlmsg_flags & NLM_F_REPLACE)
3137 return -EOPNOTSUPP;
3138 return 0;
3139 }
3140
3141 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
3142 return -ENOENT;
3143
2b664957 3144 ops = nft_select_set_ops(&ctx, nla, &desc, policy);
20a69341
PM
3145 if (IS_ERR(ops))
3146 return PTR_ERR(ops);
3147
e6d8ecac
CFG
3148 udlen = 0;
3149 if (nla[NFTA_SET_USERDATA])
3150 udlen = nla_len(nla[NFTA_SET_USERDATA]);
3151
20a69341
PM
3152 size = 0;
3153 if (ops->privsize != NULL)
347b408d 3154 size = ops->privsize(nla, &desc);
20a69341 3155
1ff75a3e
PNA
3156 set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
3157 if (!set) {
3158 err = -ENOMEM;
20a69341 3159 goto err1;
1ff75a3e 3160 }
20a69341 3161
38745490
PS
3162 name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
3163 if (!name) {
3164 err = -ENOMEM;
3165 goto err2;
3166 }
3167
20a69341 3168 err = nf_tables_set_alloc_name(&ctx, set, name);
38745490 3169 kfree(name);
20a69341
PM
3170 if (err < 0)
3171 goto err2;
3172
e6d8ecac
CFG
3173 udata = NULL;
3174 if (udlen) {
3175 udata = set->data + size;
3176 nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
3177 }
3178
20a69341
PM
3179 INIT_LIST_HEAD(&set->bindings);
3180 set->ops = ops;
3181 set->ktype = ktype;
c50b960c 3182 set->klen = desc.klen;
20a69341 3183 set->dtype = dtype;
8aeff920 3184 set->objtype = objtype;
c50b960c 3185 set->dlen = desc.dlen;
20a69341 3186 set->flags = flags;
c50b960c 3187 set->size = desc.size;
9363dc4b 3188 set->policy = policy;
e6d8ecac
CFG
3189 set->udlen = udlen;
3190 set->udata = udata;
761da293
PM
3191 set->timeout = timeout;
3192 set->gc_int = gc_int;
20a69341 3193
c50b960c 3194 err = ops->init(set, &desc, nla);
20a69341
PM
3195 if (err < 0)
3196 goto err2;
3197
958bee14 3198 err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
20a69341 3199 if (err < 0)
c17c3cdf 3200 goto err3;
20a69341 3201
e688a7f8 3202 list_add_tail_rcu(&set->list, &table->sets);
4fefee57 3203 table->use++;
20a69341
PM
3204 return 0;
3205
c17c3cdf
LZ
3206err3:
3207 ops->destroy(set);
20a69341 3208err2:
1ff75a3e 3209 kvfree(set);
20a69341 3210err1:
2b664957 3211 module_put(ops->type->owner);
20a69341
PM
3212 return err;
3213}
3214
958bee14 3215static void nft_set_destroy(struct nft_set *set)
20a69341 3216{
20a69341 3217 set->ops->destroy(set);
2b664957 3218 module_put(set->ops->type->owner);
38745490 3219 kfree(set->name);
1ff75a3e 3220 kvfree(set);
20a69341
PM
3221}
3222
958bee14
PNA
3223static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
3224{
e688a7f8 3225 list_del_rcu(&set->list);
31f8441c 3226 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC);
958bee14
PNA
3227 nft_set_destroy(set);
3228}
3229
633c9a84
PNA
3230static int nf_tables_delset(struct net *net, struct sock *nlsk,
3231 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3232 const struct nlattr * const nla[],
3233 struct netlink_ext_ack *extack)
20a69341 3234{
c9c8e485 3235 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
f2a6d766 3236 u8 genmask = nft_genmask_next(net);
20a69341
PM
3237 struct nft_set *set;
3238 struct nft_ctx ctx;
3239 int err;
3240
ec2c9935
PM
3241 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
3242 return -EAFNOSUPPORT;
20a69341
PM
3243 if (nla[NFTA_SET_TABLE] == NULL)
3244 return -EINVAL;
3245
f2a6d766 3246 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
3247 if (err < 0)
3248 return err;
3249
37a9cc52 3250 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
20a69341
PM
3251 if (IS_ERR(set))
3252 return PTR_ERR(set);
a8278400
PNA
3253
3254 if (!list_empty(&set->bindings) ||
3255 (nlh->nlmsg_flags & NLM_F_NONREC && atomic_read(&set->nelems) > 0))
20a69341
PM
3256 return -EBUSY;
3257
ee01d542 3258 return nft_delset(&ctx, set);
20a69341
PM
3259}
3260
3261static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
de70185d 3262 struct nft_set *set,
20a69341 3263 const struct nft_set_iter *iter,
de70185d 3264 struct nft_set_elem *elem)
20a69341 3265{
fe2811eb 3266 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3267 enum nft_registers dreg;
3268
3269 dreg = nft_type_to_reg(set->dtype);
1ec10212
PM
3270 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
3271 set->dtype == NFT_DATA_VERDICT ?
3272 NFT_DATA_VERDICT : NFT_DATA_VALUE,
3273 set->dlen);
20a69341
PM
3274}
3275
3276int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
3277 struct nft_set_binding *binding)
3278{
3279 struct nft_set_binding *i;
3280 struct nft_set_iter iter;
3281
3282 if (!list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
3283 return -EBUSY;
3284
11113e19 3285 if (binding->flags & NFT_SET_MAP) {
20a69341
PM
3286 /* If the set is already bound to the same chain all
3287 * jumps are already validated for that chain.
3288 */
3289 list_for_each_entry(i, &set->bindings, list) {
a4684402 3290 if (i->flags & NFT_SET_MAP &&
11113e19 3291 i->chain == binding->chain)
20a69341
PM
3292 goto bind;
3293 }
3294
8588ac09 3295 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
3296 iter.skip = 0;
3297 iter.count = 0;
3298 iter.err = 0;
3299 iter.fn = nf_tables_bind_check_setelem;
3300
3301 set->ops->walk(ctx, set, &iter);
a02f4248 3302 if (iter.err < 0)
20a69341 3303 return iter.err;
20a69341
PM
3304 }
3305bind:
3306 binding->chain = ctx->chain;
e688a7f8 3307 list_add_tail_rcu(&binding->list, &set->bindings);
20a69341
PM
3308 return 0;
3309}
63aea290 3310EXPORT_SYMBOL_GPL(nf_tables_bind_set);
20a69341
PM
3311
3312void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
3313 struct nft_set_binding *binding)
3314{
e688a7f8 3315 list_del_rcu(&binding->list);
20a69341 3316
958bee14 3317 if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS &&
37a9cc52 3318 nft_is_active(ctx->net, set))
20a69341
PM
3319 nf_tables_set_destroy(ctx, set);
3320}
63aea290 3321EXPORT_SYMBOL_GPL(nf_tables_unbind_set);
20a69341 3322
3ac4c07a
PM
3323const struct nft_set_ext_type nft_set_ext_types[] = {
3324 [NFT_SET_EXT_KEY] = {
7d740264 3325 .align = __alignof__(u32),
3ac4c07a
PM
3326 },
3327 [NFT_SET_EXT_DATA] = {
7d740264 3328 .align = __alignof__(u32),
3ac4c07a 3329 },
f25ad2e9
PM
3330 [NFT_SET_EXT_EXPR] = {
3331 .align = __alignof__(struct nft_expr),
3332 },
8aeff920
PNA
3333 [NFT_SET_EXT_OBJREF] = {
3334 .len = sizeof(struct nft_object *),
3335 .align = __alignof__(struct nft_object *),
3336 },
3ac4c07a
PM
3337 [NFT_SET_EXT_FLAGS] = {
3338 .len = sizeof(u8),
3339 .align = __alignof__(u8),
3340 },
c3e1b005
PM
3341 [NFT_SET_EXT_TIMEOUT] = {
3342 .len = sizeof(u64),
3343 .align = __alignof__(u64),
3344 },
3345 [NFT_SET_EXT_EXPIRATION] = {
3346 .len = sizeof(unsigned long),
3347 .align = __alignof__(unsigned long),
3348 },
68e942e8
PM
3349 [NFT_SET_EXT_USERDATA] = {
3350 .len = sizeof(struct nft_userdata),
3351 .align = __alignof__(struct nft_userdata),
3352 },
3ac4c07a
PM
3353};
3354EXPORT_SYMBOL_GPL(nft_set_ext_types);
3355
20a69341
PM
3356/*
3357 * Set elements
3358 */
3359
3360static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
3361 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
3362 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
3363 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
c3e1b005 3364 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
68e942e8
PM
3365 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY,
3366 .len = NFT_USERDATA_MAXLEN },
20a69341
PM
3367};
3368
3369static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
b2fbd044
LZ
3370 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING,
3371 .len = NFT_TABLE_MAXNAMELEN - 1 },
3372 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING,
3373 .len = NFT_SET_MAXNAMELEN - 1 },
20a69341 3374 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
958bee14 3375 [NFTA_SET_ELEM_LIST_SET_ID] = { .type = NLA_U32 },
20a69341
PM
3376};
3377
633c9a84 3378static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
20a69341
PM
3379 const struct sk_buff *skb,
3380 const struct nlmsghdr *nlh,
f2a6d766
PNA
3381 const struct nlattr * const nla[],
3382 u8 genmask)
20a69341
PM
3383{
3384 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7c95f6d8
PNA
3385 struct nft_af_info *afi;
3386 struct nft_table *table;
20a69341 3387
99633ab2 3388 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
20a69341
PM
3389 if (IS_ERR(afi))
3390 return PTR_ERR(afi);
3391
f2a6d766
PNA
3392 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE],
3393 genmask);
20a69341
PM
3394 if (IS_ERR(table))
3395 return PTR_ERR(table);
3396
633c9a84 3397 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
20a69341
PM
3398 return 0;
3399}
3400
3401static int nf_tables_fill_setelem(struct sk_buff *skb,
3402 const struct nft_set *set,
3403 const struct nft_set_elem *elem)
3404{
fe2811eb 3405 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
20a69341
PM
3406 unsigned char *b = skb_tail_pointer(skb);
3407 struct nlattr *nest;
3408
3409 nest = nla_nest_start(skb, NFTA_LIST_ELEM);
3410 if (nest == NULL)
3411 goto nla_put_failure;
3412
fe2811eb
PM
3413 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, nft_set_ext_key(ext),
3414 NFT_DATA_VALUE, set->klen) < 0)
20a69341
PM
3415 goto nla_put_failure;
3416
fe2811eb
PM
3417 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3418 nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
20a69341
PM
3419 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
3420 set->dlen) < 0)
3421 goto nla_put_failure;
3422
f25ad2e9
PM
3423 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
3424 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
3425 goto nla_put_failure;
3426
8aeff920
PNA
3427 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3428 nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
3429 (*nft_set_ext_obj(ext))->name) < 0)
3430 goto nla_put_failure;
3431
fe2811eb
PM
3432 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
3433 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
3434 htonl(*nft_set_ext_flags(ext))))
3435 goto nla_put_failure;
20a69341 3436
c3e1b005
PM
3437 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
3438 nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
d3e2a111
AP
3439 cpu_to_be64(jiffies_to_msecs(
3440 *nft_set_ext_timeout(ext))),
b46f6ded 3441 NFTA_SET_ELEM_PAD))
c3e1b005
PM
3442 goto nla_put_failure;
3443
3444 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
3445 unsigned long expires, now = jiffies;
3446
3447 expires = *nft_set_ext_expiration(ext);
3448 if (time_before(now, expires))
3449 expires -= now;
3450 else
3451 expires = 0;
3452
3453 if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
b46f6ded
ND
3454 cpu_to_be64(jiffies_to_msecs(expires)),
3455 NFTA_SET_ELEM_PAD))
c3e1b005
PM
3456 goto nla_put_failure;
3457 }
3458
68e942e8
PM
3459 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
3460 struct nft_userdata *udata;
3461
3462 udata = nft_set_ext_userdata(ext);
3463 if (nla_put(skb, NFTA_SET_ELEM_USERDATA,
3464 udata->len + 1, udata->data))
3465 goto nla_put_failure;
3466 }
3467
20a69341
PM
3468 nla_nest_end(skb, nest);
3469 return 0;
3470
3471nla_put_failure:
3472 nlmsg_trim(skb, b);
3473 return -EMSGSIZE;
3474}
3475
3476struct nft_set_dump_args {
3477 const struct netlink_callback *cb;
3478 struct nft_set_iter iter;
3479 struct sk_buff *skb;
3480};
3481
3482static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
de70185d 3483 struct nft_set *set,
20a69341 3484 const struct nft_set_iter *iter,
de70185d 3485 struct nft_set_elem *elem)
20a69341
PM
3486{
3487 struct nft_set_dump_args *args;
3488
3489 args = container_of(iter, struct nft_set_dump_args, iter);
3490 return nf_tables_fill_setelem(args->skb, set, elem);
3491}
3492
fa803605
LZ
3493struct nft_set_dump_ctx {
3494 const struct nft_set *set;
3495 struct nft_ctx ctx;
3496};
3497
20a69341
PM
3498static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3499{
fa803605 3500 struct nft_set_dump_ctx *dump_ctx = cb->data;
633c9a84 3501 struct net *net = sock_net(skb->sk);
fa803605
LZ
3502 struct nft_af_info *afi;
3503 struct nft_table *table;
de70185d 3504 struct nft_set *set;
20a69341 3505 struct nft_set_dump_args args;
fa803605 3506 bool set_found = false;
20a69341
PM
3507 struct nfgenmsg *nfmsg;
3508 struct nlmsghdr *nlh;
3509 struct nlattr *nest;
3510 u32 portid, seq;
fa803605 3511 int event;
20a69341 3512
fa803605
LZ
3513 rcu_read_lock();
3514 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
3515 if (afi != dump_ctx->ctx.afi)
3516 continue;
20a69341 3517
fa803605
LZ
3518 list_for_each_entry_rcu(table, &afi->tables, list) {
3519 if (table != dump_ctx->ctx.table)
3520 continue;
20a69341 3521
fa803605
LZ
3522 list_for_each_entry_rcu(set, &table->sets, list) {
3523 if (set == dump_ctx->set) {
3524 set_found = true;
3525 break;
3526 }
3527 }
3528 break;
3529 }
3530 break;
3531 }
3532
3533 if (!set_found) {
3534 rcu_read_unlock();
3535 return -ENOENT;
3536 }
20a69341 3537
dedb67c4 3538 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSETELEM);
20a69341
PM
3539 portid = NETLINK_CB(cb->skb).portid;
3540 seq = cb->nlh->nlmsg_seq;
3541
3542 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3543 NLM_F_MULTI);
3544 if (nlh == NULL)
3545 goto nla_put_failure;
3546
3547 nfmsg = nlmsg_data(nlh);
fa803605 3548 nfmsg->nfgen_family = afi->family;
20a69341 3549 nfmsg->version = NFNETLINK_V0;
fa803605 3550 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
20a69341 3551
fa803605 3552 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, table->name))
20a69341
PM
3553 goto nla_put_failure;
3554 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
3555 goto nla_put_failure;
3556
3557 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3558 if (nest == NULL)
3559 goto nla_put_failure;
3560
8588ac09
PNA
3561 args.cb = cb;
3562 args.skb = skb;
fa803605 3563 args.iter.genmask = nft_genmask_cur(net);
8588ac09
PNA
3564 args.iter.skip = cb->args[0];
3565 args.iter.count = 0;
3566 args.iter.err = 0;
3567 args.iter.fn = nf_tables_dump_setelem;
fa803605
LZ
3568 set->ops->walk(&dump_ctx->ctx, set, &args.iter);
3569 rcu_read_unlock();
20a69341
PM
3570
3571 nla_nest_end(skb, nest);
3572 nlmsg_end(skb, nlh);
3573
3574 if (args.iter.err && args.iter.err != -EMSGSIZE)
3575 return args.iter.err;
3576 if (args.iter.count == cb->args[0])
3577 return 0;
3578
3579 cb->args[0] = args.iter.count;
3580 return skb->len;
3581
3582nla_put_failure:
fa803605 3583 rcu_read_unlock();
20a69341
PM
3584 return -ENOSPC;
3585}
3586
fa803605
LZ
3587static int nf_tables_dump_set_done(struct netlink_callback *cb)
3588{
3589 kfree(cb->data);
3590 return 0;
3591}
3592
d60ce62f
AB
3593static int nf_tables_fill_setelem_info(struct sk_buff *skb,
3594 const struct nft_ctx *ctx, u32 seq,
3595 u32 portid, int event, u16 flags,
3596 const struct nft_set *set,
3597 const struct nft_set_elem *elem)
3598{
3599 struct nfgenmsg *nfmsg;
3600 struct nlmsghdr *nlh;
3601 struct nlattr *nest;
3602 int err;
3603
dedb67c4 3604 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
d60ce62f
AB
3605 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3606 flags);
3607 if (nlh == NULL)
3608 goto nla_put_failure;
3609
3610 nfmsg = nlmsg_data(nlh);
3611 nfmsg->nfgen_family = ctx->afi->family;
3612 nfmsg->version = NFNETLINK_V0;
84d7fce6 3613 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
d60ce62f
AB
3614
3615 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
3616 goto nla_put_failure;
3617 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
3618 goto nla_put_failure;
3619
3620 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3621 if (nest == NULL)
3622 goto nla_put_failure;
3623
3624 err = nf_tables_fill_setelem(skb, set, elem);
3625 if (err < 0)
3626 goto nla_put_failure;
3627
3628 nla_nest_end(skb, nest);
3629
053c095a
JB
3630 nlmsg_end(skb, nlh);
3631 return 0;
d60ce62f
AB
3632
3633nla_put_failure:
3634 nlmsg_trim(skb, nlh);
3635 return -1;
3636}
3637
ba0e4d99
PNA
3638static int nft_setelem_parse_flags(const struct nft_set *set,
3639 const struct nlattr *attr, u32 *flags)
3640{
3641 if (attr == NULL)
3642 return 0;
3643
3644 *flags = ntohl(nla_get_be32(attr));
3645 if (*flags & ~NFT_SET_ELEM_INTERVAL_END)
3646 return -EINVAL;
3647 if (!(set->flags & NFT_SET_INTERVAL) &&
3648 *flags & NFT_SET_ELEM_INTERVAL_END)
3649 return -EINVAL;
3650
3651 return 0;
3652}
3653
3654static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3655 const struct nlattr *attr)
3656{
3657 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3658 const struct nft_set_ext *ext;
3659 struct nft_data_desc desc;
3660 struct nft_set_elem elem;
3661 struct sk_buff *skb;
3662 uint32_t flags = 0;
3663 void *priv;
3664 int err;
3665
3666 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
3667 nft_set_elem_policy, NULL);
3668 if (err < 0)
3669 return err;
3670
3671 if (!nla[NFTA_SET_ELEM_KEY])
3672 return -EINVAL;
3673
3674 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
3675 if (err < 0)
3676 return err;
3677
3678 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
3679 nla[NFTA_SET_ELEM_KEY]);
3680 if (err < 0)
3681 return err;
3682
3683 err = -EINVAL;
3684 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
3685 return err;
3686
3687 priv = set->ops->get(ctx->net, set, &elem, flags);
3688 if (IS_ERR(priv))
3689 return PTR_ERR(priv);
3690
3691 elem.priv = priv;
3692 ext = nft_set_elem_ext(set, &elem);
3693
3694 err = -ENOMEM;
3695 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3696 if (skb == NULL)
3697 goto err1;
3698
3699 err = nf_tables_fill_setelem_info(skb, ctx, ctx->seq, ctx->portid,
3700 NFT_MSG_NEWSETELEM, 0, set, &elem);
3701 if (err < 0)
3702 goto err2;
3703
3704 err = nfnetlink_unicast(skb, ctx->net, ctx->portid, MSG_DONTWAIT);
3705 /* This avoids a loop in nfnetlink. */
3706 if (err < 0)
3707 goto err1;
3708
3709 return 0;
3710err2:
3711 kfree_skb(skb);
3712err1:
3713 /* this avoids a loop in nfnetlink. */
3714 return err == -EAGAIN ? -ENOBUFS : err;
3715}
3716
3717static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
3718 struct sk_buff *skb, const struct nlmsghdr *nlh,
3719 const struct nlattr * const nla[],
3720 struct netlink_ext_ack *extack)
3721{
3722 u8 genmask = nft_genmask_cur(net);
3723 struct nft_set *set;
3724 struct nlattr *attr;
3725 struct nft_ctx ctx;
3726 int rem, err = 0;
3727
3728 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3729 if (err < 0)
3730 return err;
3731
3732 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3733 genmask);
3734 if (IS_ERR(set))
3735 return PTR_ERR(set);
3736
3737 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3738 struct netlink_dump_control c = {
3739 .dump = nf_tables_dump_set,
3740 .done = nf_tables_dump_set_done,
3741 };
3742 struct nft_set_dump_ctx *dump_ctx;
3743
3744 dump_ctx = kmalloc(sizeof(*dump_ctx), GFP_KERNEL);
3745 if (!dump_ctx)
3746 return -ENOMEM;
3747
3748 dump_ctx->set = set;
3749 dump_ctx->ctx = ctx;
3750
3751 c.data = dump_ctx;
3752 return netlink_dump_start(nlsk, skb, nlh, &c);
3753 }
3754
3755 if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS])
3756 return -EINVAL;
3757
3758 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
3759 err = nft_get_set_elem(&ctx, set, attr);
3760 if (err < 0)
3761 break;
3762 }
3763
3764 return err;
3765}
3766
25e94a99
PNA
3767static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
3768 const struct nft_set *set,
3769 const struct nft_set_elem *elem,
3770 int event, u16 flags)
d60ce62f 3771{
128ad332
PNA
3772 struct net *net = ctx->net;
3773 u32 portid = ctx->portid;
d60ce62f
AB
3774 struct sk_buff *skb;
3775 int err;
3776
128ad332 3777 if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 3778 return;
d60ce62f 3779
d60ce62f
AB
3780 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3781 if (skb == NULL)
3782 goto err;
3783
3784 err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
3785 set, elem);
3786 if (err < 0) {
3787 kfree_skb(skb);
3788 goto err;
3789 }
3790
25e94a99
PNA
3791 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
3792 GFP_KERNEL);
3793 return;
d60ce62f 3794err:
25e94a99 3795 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
d60ce62f
AB
3796}
3797
60319eb1
PNA
3798static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3799 int msg_type,
3800 struct nft_set *set)
3801{
3802 struct nft_trans *trans;
3803
3804 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_elem));
3805 if (trans == NULL)
3806 return NULL;
3807
3808 nft_trans_elem_set(trans) = set;
3809 return trans;
3810}
3811
22fe54d5
PM
3812void *nft_set_elem_init(const struct nft_set *set,
3813 const struct nft_set_ext_tmpl *tmpl,
49499c3e 3814 const u32 *key, const u32 *data,
22fe54d5 3815 u64 timeout, gfp_t gfp)
fe2811eb
PM
3816{
3817 struct nft_set_ext *ext;
3818 void *elem;
3819
3820 elem = kzalloc(set->ops->elemsize + tmpl->len, gfp);
3821 if (elem == NULL)
3822 return NULL;
3823
3824 ext = nft_set_elem_ext(set, elem);
3825 nft_set_ext_init(ext, tmpl);
3826
3827 memcpy(nft_set_ext_key(ext), key, set->klen);
3828 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3829 memcpy(nft_set_ext_data(ext), data, set->dlen);
c3e1b005
PM
3830 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
3831 *nft_set_ext_expiration(ext) =
d3e2a111 3832 jiffies + timeout;
c3e1b005
PM
3833 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
3834 *nft_set_ext_timeout(ext) = timeout;
fe2811eb
PM
3835
3836 return elem;
3837}
3838
61f9e292
LZ
3839void nft_set_elem_destroy(const struct nft_set *set, void *elem,
3840 bool destroy_expr)
61edafbb
PM
3841{
3842 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3843
59105446 3844 nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
61edafbb 3845 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
59105446 3846 nft_data_release(nft_set_ext_data(ext), set->dtype);
61f9e292 3847 if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
f25ad2e9 3848 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
8aeff920
PNA
3849 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
3850 (*nft_set_ext_obj(ext))->use--;
61edafbb
PM
3851 kfree(elem);
3852}
3853EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
3854
59105446
PNA
3855/* Only called from commit path, nft_set_elem_deactivate() already deals with
3856 * the refcounting from the preparation phase.
3857 */
3858static void nf_tables_set_elem_destroy(const struct nft_set *set, void *elem)
3859{
3860 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3861
3862 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
3863 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
3864 kfree(elem);
3865}
3866
60319eb1 3867static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
c016c7e4 3868 const struct nlattr *attr, u32 nlmsg_flags)
20a69341
PM
3869{
3870 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
8aeff920 3871 u8 genmask = nft_genmask_next(ctx->net);
20a69341 3872 struct nft_data_desc d1, d2;
fe2811eb 3873 struct nft_set_ext_tmpl tmpl;
c016c7e4 3874 struct nft_set_ext *ext, *ext2;
20a69341
PM
3875 struct nft_set_elem elem;
3876 struct nft_set_binding *binding;
8aeff920 3877 struct nft_object *obj = NULL;
68e942e8 3878 struct nft_userdata *udata;
fe2811eb 3879 struct nft_data data;
20a69341 3880 enum nft_registers dreg;
60319eb1 3881 struct nft_trans *trans;
0e9091d6 3882 u32 flags = 0;
c3e1b005 3883 u64 timeout;
68e942e8 3884 u8 ulen;
20a69341
PM
3885 int err;
3886
3887 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
fceb6435 3888 nft_set_elem_policy, NULL);
20a69341
PM
3889 if (err < 0)
3890 return err;
3891
3892 if (nla[NFTA_SET_ELEM_KEY] == NULL)
3893 return -EINVAL;
3894
fe2811eb
PM
3895 nft_set_ext_prepare(&tmpl);
3896
0e9091d6
PNA
3897 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
3898 if (err < 0)
3899 return err;
3900 if (flags != 0)
3901 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
20a69341
PM
3902
3903 if (set->flags & NFT_SET_MAP) {
3904 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
fe2811eb 3905 !(flags & NFT_SET_ELEM_INTERVAL_END))
20a69341 3906 return -EINVAL;
bd7fc645 3907 if (nla[NFTA_SET_ELEM_DATA] != NULL &&
fe2811eb 3908 flags & NFT_SET_ELEM_INTERVAL_END)
bd7fc645 3909 return -EINVAL;
20a69341
PM
3910 } else {
3911 if (nla[NFTA_SET_ELEM_DATA] != NULL)
3912 return -EINVAL;
3913 }
3914
c3e1b005
PM
3915 timeout = 0;
3916 if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
3917 if (!(set->flags & NFT_SET_TIMEOUT))
3918 return -EINVAL;
d3e2a111
AP
3919 timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
3920 nla[NFTA_SET_ELEM_TIMEOUT])));
c3e1b005
PM
3921 } else if (set->flags & NFT_SET_TIMEOUT) {
3922 timeout = set->timeout;
3923 }
3924
7d740264 3925 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
d0a11fc3 3926 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
3927 if (err < 0)
3928 goto err1;
3929 err = -EINVAL;
3930 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
3931 goto err2;
3932
7d740264 3933 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
c3e1b005
PM
3934 if (timeout > 0) {
3935 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
3936 if (timeout != set->timeout)
3937 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
3938 }
fe2811eb 3939
8aeff920
PNA
3940 if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
3941 if (!(set->flags & NFT_SET_OBJECT)) {
3942 err = -EINVAL;
3943 goto err2;
3944 }
3945 obj = nf_tables_obj_lookup(ctx->table, nla[NFTA_SET_ELEM_OBJREF],
3946 set->objtype, genmask);
3947 if (IS_ERR(obj)) {
3948 err = PTR_ERR(obj);
3949 goto err2;
3950 }
3951 nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
3952 }
3953
20a69341 3954 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
d0a11fc3
PM
3955 err = nft_data_init(ctx, &data, sizeof(data), &d2,
3956 nla[NFTA_SET_ELEM_DATA]);
20a69341
PM
3957 if (err < 0)
3958 goto err2;
3959
3960 err = -EINVAL;
3961 if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
3962 goto err3;
3963
3964 dreg = nft_type_to_reg(set->dtype);
3965 list_for_each_entry(binding, &set->bindings, list) {
3966 struct nft_ctx bind_ctx = {
58c78e10 3967 .net = ctx->net,
20a69341
PM
3968 .afi = ctx->afi,
3969 .table = ctx->table,
7c95f6d8 3970 .chain = (struct nft_chain *)binding->chain,
20a69341
PM
3971 };
3972
11113e19
PM
3973 if (!(binding->flags & NFT_SET_MAP))
3974 continue;
3975
1ec10212
PM
3976 err = nft_validate_register_store(&bind_ctx, dreg,
3977 &data,
3978 d2.type, d2.len);
20a69341
PM
3979 if (err < 0)
3980 goto err3;
3981 }
fe2811eb 3982
7d740264 3983 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
20a69341
PM
3984 }
3985
68e942e8
PM
3986 /* The full maximum length of userdata can exceed the maximum
3987 * offset value (U8_MAX) for following extensions, therefor it
3988 * must be the last extension added.
3989 */
3990 ulen = 0;
3991 if (nla[NFTA_SET_ELEM_USERDATA] != NULL) {
3992 ulen = nla_len(nla[NFTA_SET_ELEM_USERDATA]);
3993 if (ulen > 0)
3994 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_USERDATA,
3995 ulen);
3996 }
3997
fe2811eb 3998 err = -ENOMEM;
7d740264 3999 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
c3e1b005 4000 timeout, GFP_KERNEL);
fe2811eb
PM
4001 if (elem.priv == NULL)
4002 goto err3;
4003
4004 ext = nft_set_elem_ext(set, elem.priv);
4005 if (flags)
4006 *nft_set_ext_flags(ext) = flags;
68e942e8
PM
4007 if (ulen > 0) {
4008 udata = nft_set_ext_userdata(ext);
4009 udata->len = ulen - 1;
4010 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
4011 }
8aeff920
PNA
4012 if (obj) {
4013 *nft_set_ext_obj(ext) = obj;
4014 obj->use++;
4015 }
fe2811eb 4016
60319eb1
PNA
4017 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
4018 if (trans == NULL)
fe2811eb 4019 goto err4;
60319eb1 4020
69086658 4021 ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
c016c7e4
PNA
4022 err = set->ops->insert(ctx->net, set, &elem, &ext2);
4023 if (err) {
4024 if (err == -EEXIST) {
9744a6fc
PNA
4025 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
4026 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
4027 nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
4028 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF))
4029 return -EBUSY;
8aeff920
PNA
4030 if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
4031 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
4032 memcmp(nft_set_ext_data(ext),
4033 nft_set_ext_data(ext2), set->dlen) != 0) ||
4034 (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
4035 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
4036 *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
c016c7e4
PNA
4037 err = -EBUSY;
4038 else if (!(nlmsg_flags & NLM_F_EXCL))
4039 err = 0;
4040 }
fe2811eb 4041 goto err5;
c016c7e4 4042 }
20a69341 4043
35d0ac90
PNA
4044 if (set->size &&
4045 !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) {
4046 err = -ENFILE;
4047 goto err6;
4048 }
4049
60319eb1 4050 nft_trans_elem(trans) = elem;
46bbafce 4051 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
20a69341
PM
4052 return 0;
4053
35d0ac90 4054err6:
5cb82a38 4055 set->ops->remove(ctx->net, set, &elem);
fe2811eb 4056err5:
60319eb1 4057 kfree(trans);
fe2811eb
PM
4058err4:
4059 kfree(elem.priv);
20a69341
PM
4060err3:
4061 if (nla[NFTA_SET_ELEM_DATA] != NULL)
59105446 4062 nft_data_release(&data, d2.type);
20a69341 4063err2:
59105446 4064 nft_data_release(&elem.key.val, d1.type);
20a69341
PM
4065err1:
4066 return err;
4067}
4068
633c9a84
PNA
4069static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
4070 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4071 const struct nlattr * const nla[],
4072 struct netlink_ext_ack *extack)
20a69341 4073{
f2a6d766 4074 u8 genmask = nft_genmask_next(net);
20a69341
PM
4075 const struct nlattr *attr;
4076 struct nft_set *set;
4077 struct nft_ctx ctx;
60319eb1 4078 int rem, err = 0;
20a69341 4079
7d5570ca
PNA
4080 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
4081 return -EINVAL;
4082
f2a6d766 4083 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
4084 if (err < 0)
4085 return err;
4086
37a9cc52
PNA
4087 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
4088 genmask);
958bee14
PNA
4089 if (IS_ERR(set)) {
4090 if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
4091 set = nf_tables_set_lookup_byid(net,
37a9cc52
PNA
4092 nla[NFTA_SET_ELEM_LIST_SET_ID],
4093 genmask);
958bee14
PNA
4094 }
4095 if (IS_ERR(set))
4096 return PTR_ERR(set);
4097 }
4098
20a69341
PM
4099 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4100 return -EBUSY;
4101
4102 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
c016c7e4 4103 err = nft_add_set_elem(&ctx, set, attr, nlh->nlmsg_flags);
35d0ac90 4104 if (err < 0)
60319eb1 4105 break;
20a69341 4106 }
60319eb1 4107 return err;
20a69341
PM
4108}
4109
59105446
PNA
4110/**
4111 * nft_data_hold - hold a nft_data item
4112 *
4113 * @data: struct nft_data to release
4114 * @type: type of data
4115 *
4116 * Hold a nft_data item. NFT_DATA_VALUE types can be silently discarded,
4117 * NFT_DATA_VERDICT bumps the reference to chains in case of NFT_JUMP and
4118 * NFT_GOTO verdicts. This function must be called on active data objects
4119 * from the second phase of the commit protocol.
4120 */
4121static void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
4122{
4123 if (type == NFT_DATA_VERDICT) {
4124 switch (data->verdict.code) {
4125 case NFT_JUMP:
4126 case NFT_GOTO:
4127 data->verdict.chain->use++;
4128 break;
4129 }
4130 }
4131}
4132
4133static void nft_set_elem_activate(const struct net *net,
4134 const struct nft_set *set,
4135 struct nft_set_elem *elem)
4136{
4137 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4138
4139 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4140 nft_data_hold(nft_set_ext_data(ext), set->dtype);
4141 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4142 (*nft_set_ext_obj(ext))->use++;
4143}
4144
4145static void nft_set_elem_deactivate(const struct net *net,
4146 const struct nft_set *set,
4147 struct nft_set_elem *elem)
4148{
4149 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4150
4151 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4152 nft_data_release(nft_set_ext_data(ext), set->dtype);
4153 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4154 (*nft_set_ext_obj(ext))->use--;
4155}
4156
60319eb1 4157static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
20a69341
PM
4158 const struct nlattr *attr)
4159{
4160 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3971ca14 4161 struct nft_set_ext_tmpl tmpl;
20a69341
PM
4162 struct nft_data_desc desc;
4163 struct nft_set_elem elem;
3971ca14 4164 struct nft_set_ext *ext;
60319eb1 4165 struct nft_trans *trans;
3971ca14
PNA
4166 u32 flags = 0;
4167 void *priv;
20a69341
PM
4168 int err;
4169
4170 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
fceb6435 4171 nft_set_elem_policy, NULL);
20a69341
PM
4172 if (err < 0)
4173 goto err1;
4174
4175 err = -EINVAL;
4176 if (nla[NFTA_SET_ELEM_KEY] == NULL)
4177 goto err1;
4178
3971ca14
PNA
4179 nft_set_ext_prepare(&tmpl);
4180
4181 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
4182 if (err < 0)
4183 return err;
4184 if (flags != 0)
4185 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
4186
7d740264 4187 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
d0a11fc3 4188 nla[NFTA_SET_ELEM_KEY]);
20a69341
PM
4189 if (err < 0)
4190 goto err1;
4191
4192 err = -EINVAL;
4193 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
4194 goto err2;
4195
3971ca14
PNA
4196 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
4197
4198 err = -ENOMEM;
4199 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
4200 GFP_KERNEL);
4201 if (elem.priv == NULL)
4202 goto err2;
4203
4204 ext = nft_set_elem_ext(set, elem.priv);
4205 if (flags)
4206 *nft_set_ext_flags(ext) = flags;
4207
60319eb1 4208 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
609ccf08
JL
4209 if (trans == NULL) {
4210 err = -ENOMEM;
3971ca14 4211 goto err3;
609ccf08 4212 }
20a69341 4213
42a55769 4214 priv = set->ops->deactivate(ctx->net, set, &elem);
3971ca14 4215 if (priv == NULL) {
cc02e457 4216 err = -ENOENT;
3971ca14 4217 goto err4;
cc02e457 4218 }
3971ca14
PNA
4219 kfree(elem.priv);
4220 elem.priv = priv;
cc02e457 4221
59105446
PNA
4222 nft_set_elem_deactivate(ctx->net, set, &elem);
4223
60319eb1 4224 nft_trans_elem(trans) = elem;
46bbafce 4225 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
0dc13625 4226 return 0;
cc02e457 4227
3971ca14 4228err4:
cc02e457 4229 kfree(trans);
3971ca14
PNA
4230err3:
4231 kfree(elem.priv);
20a69341 4232err2:
59105446 4233 nft_data_release(&elem.key.val, desc.type);
20a69341
PM
4234err1:
4235 return err;
4236}
4237
8411b644 4238static int nft_flush_set(const struct nft_ctx *ctx,
de70185d 4239 struct nft_set *set,
8411b644 4240 const struct nft_set_iter *iter,
de70185d 4241 struct nft_set_elem *elem)
8411b644
PNA
4242{
4243 struct nft_trans *trans;
4244 int err;
4245
4246 trans = nft_trans_alloc_gfp(ctx, NFT_MSG_DELSETELEM,
4247 sizeof(struct nft_trans_elem), GFP_ATOMIC);
4248 if (!trans)
4249 return -ENOMEM;
4250
1ba1c414 4251 if (!set->ops->flush(ctx->net, set, elem->priv)) {
8411b644
PNA
4252 err = -ENOENT;
4253 goto err1;
4254 }
b2c11e4b 4255 set->ndeact++;
8411b644 4256
de70185d
PNA
4257 nft_trans_elem_set(trans) = set;
4258 nft_trans_elem(trans) = *elem;
8411b644
PNA
4259 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
4260
4261 return 0;
4262err1:
4263 kfree(trans);
4264 return err;
4265}
4266
633c9a84
PNA
4267static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
4268 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4269 const struct nlattr * const nla[],
4270 struct netlink_ext_ack *extack)
20a69341 4271{
f2a6d766 4272 u8 genmask = nft_genmask_next(net);
20a69341
PM
4273 const struct nlattr *attr;
4274 struct nft_set *set;
4275 struct nft_ctx ctx;
60319eb1 4276 int rem, err = 0;
20a69341 4277
f2a6d766 4278 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
20a69341
PM
4279 if (err < 0)
4280 return err;
4281
37a9cc52
PNA
4282 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
4283 genmask);
20a69341
PM
4284 if (IS_ERR(set))
4285 return PTR_ERR(set);
4286 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4287 return -EBUSY;
4288
8411b644 4289 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
baa2d42c
PNA
4290 struct nft_set_iter iter = {
4291 .genmask = genmask,
4292 .fn = nft_flush_set,
8411b644 4293 };
baa2d42c 4294 set->ops->walk(&ctx, set, &iter);
8411b644 4295
baa2d42c 4296 return iter.err;
8411b644
PNA
4297 }
4298
20a69341
PM
4299 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
4300 err = nft_del_setelem(&ctx, set, attr);
4301 if (err < 0)
60319eb1 4302 break;
4fefee57 4303
3dd0673a 4304 set->ndeact++;
20a69341 4305 }
60319eb1 4306 return err;
20a69341
PM
4307}
4308
cfed7e1b
PM
4309void nft_set_gc_batch_release(struct rcu_head *rcu)
4310{
4311 struct nft_set_gc_batch *gcb;
4312 unsigned int i;
4313
4314 gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
4315 for (i = 0; i < gcb->head.cnt; i++)
61f9e292 4316 nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
cfed7e1b
PM
4317 kfree(gcb);
4318}
4319EXPORT_SYMBOL_GPL(nft_set_gc_batch_release);
4320
4321struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
4322 gfp_t gfp)
4323{
4324 struct nft_set_gc_batch *gcb;
4325
4326 gcb = kzalloc(sizeof(*gcb), gfp);
4327 if (gcb == NULL)
4328 return gcb;
4329 gcb->head.set = set;
4330 return gcb;
4331}
4332EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
4333
e5009240
PNA
4334/*
4335 * Stateful objects
4336 */
4337
4338/**
4339 * nft_register_obj- register nf_tables stateful object type
4340 * @obj: object type
4341 *
4342 * Registers the object type for use with nf_tables. Returns zero on
4343 * success or a negative errno code otherwise.
4344 */
4345int nft_register_obj(struct nft_object_type *obj_type)
4346{
4347 if (obj_type->type == NFT_OBJECT_UNSPEC)
4348 return -EINVAL;
4349
4350 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4351 list_add_rcu(&obj_type->list, &nf_tables_objects);
4352 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4353 return 0;
4354}
4355EXPORT_SYMBOL_GPL(nft_register_obj);
4356
4357/**
4358 * nft_unregister_obj - unregister nf_tables object type
4359 * @obj: object type
4360 *
4361 * Unregisters the object type for use with nf_tables.
4362 */
4363void nft_unregister_obj(struct nft_object_type *obj_type)
4364{
4365 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4366 list_del_rcu(&obj_type->list);
4367 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4368}
4369EXPORT_SYMBOL_GPL(nft_unregister_obj);
4370
4371struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
4372 const struct nlattr *nla,
4373 u32 objtype, u8 genmask)
4374{
4375 struct nft_object *obj;
4376
4377 list_for_each_entry(obj, &table->objects, list) {
4378 if (!nla_strcmp(nla, obj->name) &&
dfc46034 4379 objtype == obj->ops->type->type &&
e5009240
PNA
4380 nft_active_genmask(obj, genmask))
4381 return obj;
4382 }
4383 return ERR_PTR(-ENOENT);
4384}
4385EXPORT_SYMBOL_GPL(nf_tables_obj_lookup);
4386
4387static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
b2fbd044
LZ
4388 [NFTA_OBJ_TABLE] = { .type = NLA_STRING,
4389 .len = NFT_TABLE_MAXNAMELEN - 1 },
4390 [NFTA_OBJ_NAME] = { .type = NLA_STRING,
4391 .len = NFT_OBJ_MAXNAMELEN - 1 },
e5009240
PNA
4392 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
4393 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
4394};
4395
84fba055
FW
4396static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,
4397 const struct nft_object_type *type,
e5009240
PNA
4398 const struct nlattr *attr)
4399{
4400 struct nlattr *tb[type->maxattr + 1];
dfc46034 4401 const struct nft_object_ops *ops;
e5009240
PNA
4402 struct nft_object *obj;
4403 int err;
4404
4405 if (attr) {
fceb6435
JB
4406 err = nla_parse_nested(tb, type->maxattr, attr, type->policy,
4407 NULL);
e5009240
PNA
4408 if (err < 0)
4409 goto err1;
4410 } else {
4411 memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));
4412 }
4413
dfc46034
PBG
4414 if (type->select_ops) {
4415 ops = type->select_ops(ctx, (const struct nlattr * const *)tb);
4416 if (IS_ERR(ops)) {
4417 err = PTR_ERR(ops);
4418 goto err1;
4419 }
4420 } else {
4421 ops = type->ops;
4422 }
4423
e5009240 4424 err = -ENOMEM;
dfc46034 4425 obj = kzalloc(sizeof(*obj) + ops->size, GFP_KERNEL);
e5009240
PNA
4426 if (obj == NULL)
4427 goto err1;
4428
dfc46034 4429 err = ops->init(ctx, (const struct nlattr * const *)tb, obj);
e5009240
PNA
4430 if (err < 0)
4431 goto err2;
4432
dfc46034
PBG
4433 obj->ops = ops;
4434
e5009240
PNA
4435 return obj;
4436err2:
4437 kfree(obj);
4438err1:
4439 return ERR_PTR(err);
4440}
4441
4442static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
43da04a5 4443 struct nft_object *obj, bool reset)
e5009240
PNA
4444{
4445 struct nlattr *nest;
4446
4447 nest = nla_nest_start(skb, attr);
4448 if (!nest)
4449 goto nla_put_failure;
dfc46034 4450 if (obj->ops->dump(skb, obj, reset) < 0)
e5009240
PNA
4451 goto nla_put_failure;
4452 nla_nest_end(skb, nest);
4453 return 0;
4454
4455nla_put_failure:
4456 return -1;
4457}
4458
4459static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
4460{
4461 const struct nft_object_type *type;
4462
4463 list_for_each_entry(type, &nf_tables_objects, list) {
4464 if (objtype == type->type)
4465 return type;
4466 }
4467 return NULL;
4468}
4469
4470static const struct nft_object_type *nft_obj_type_get(u32 objtype)
4471{
4472 const struct nft_object_type *type;
4473
4474 type = __nft_obj_type_get(objtype);
4475 if (type != NULL && try_module_get(type->owner))
4476 return type;
4477
4478#ifdef CONFIG_MODULES
4479 if (type == NULL) {
4480 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4481 request_module("nft-obj-%u", objtype);
4482 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4483 if (__nft_obj_type_get(objtype))
4484 return ERR_PTR(-EAGAIN);
4485 }
4486#endif
4487 return ERR_PTR(-ENOENT);
4488}
4489
4490static int nf_tables_newobj(struct net *net, struct sock *nlsk,
4491 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4492 const struct nlattr * const nla[],
4493 struct netlink_ext_ack *extack)
e5009240
PNA
4494{
4495 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4496 const struct nft_object_type *type;
4497 u8 genmask = nft_genmask_next(net);
4498 int family = nfmsg->nfgen_family;
4499 struct nft_af_info *afi;
4500 struct nft_table *table;
4501 struct nft_object *obj;
4502 struct nft_ctx ctx;
4503 u32 objtype;
4504 int err;
4505
4506 if (!nla[NFTA_OBJ_TYPE] ||
4507 !nla[NFTA_OBJ_NAME] ||
4508 !nla[NFTA_OBJ_DATA])
4509 return -EINVAL;
4510
4511 afi = nf_tables_afinfo_lookup(net, family, true);
4512 if (IS_ERR(afi))
4513 return PTR_ERR(afi);
4514
4515 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4516 if (IS_ERR(table))
4517 return PTR_ERR(table);
4518
4519 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4520 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4521 if (IS_ERR(obj)) {
4522 err = PTR_ERR(obj);
4523 if (err != -ENOENT)
4524 return err;
4525
1a28ad74 4526 } else {
e5009240
PNA
4527 if (nlh->nlmsg_flags & NLM_F_EXCL)
4528 return -EEXIST;
4529
4530 return 0;
4531 }
4532
4533 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4534
4535 type = nft_obj_type_get(objtype);
4536 if (IS_ERR(type))
4537 return PTR_ERR(type);
4538
84fba055 4539 obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
e5009240
PNA
4540 if (IS_ERR(obj)) {
4541 err = PTR_ERR(obj);
4542 goto err1;
4543 }
18965317 4544 obj->table = table;
61509575
PS
4545 obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
4546 if (!obj->name) {
4547 err = -ENOMEM;
4548 goto err2;
4549 }
e5009240
PNA
4550
4551 err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj);
4552 if (err < 0)
61509575 4553 goto err3;
e5009240
PNA
4554
4555 list_add_tail_rcu(&obj->list, &table->objects);
4556 table->use++;
4557 return 0;
61509575
PS
4558err3:
4559 kfree(obj->name);
e5009240 4560err2:
dfc46034
PBG
4561 if (obj->ops->destroy)
4562 obj->ops->destroy(obj);
e5009240
PNA
4563 kfree(obj);
4564err1:
4565 module_put(type->owner);
4566 return err;
4567}
4568
4569static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
4570 u32 portid, u32 seq, int event, u32 flags,
4571 int family, const struct nft_table *table,
43da04a5 4572 struct nft_object *obj, bool reset)
e5009240
PNA
4573{
4574 struct nfgenmsg *nfmsg;
4575 struct nlmsghdr *nlh;
4576
dedb67c4 4577 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
e5009240
PNA
4578 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
4579 if (nlh == NULL)
4580 goto nla_put_failure;
4581
4582 nfmsg = nlmsg_data(nlh);
4583 nfmsg->nfgen_family = family;
4584 nfmsg->version = NFNETLINK_V0;
4585 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4586
4587 if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
4588 nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
dfc46034 4589 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
e5009240 4590 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
43da04a5 4591 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
e5009240
PNA
4592 goto nla_put_failure;
4593
4594 nlmsg_end(skb, nlh);
4595 return 0;
4596
4597nla_put_failure:
4598 nlmsg_trim(skb, nlh);
4599 return -1;
4600}
4601
a9fea2a3 4602struct nft_obj_filter {
e46abbcc 4603 char *table;
a9fea2a3
PNA
4604 u32 type;
4605};
4606
e5009240
PNA
4607static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
4608{
4609 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
4610 const struct nft_af_info *afi;
4611 const struct nft_table *table;
e5009240 4612 unsigned int idx = 0, s_idx = cb->args[0];
a9fea2a3 4613 struct nft_obj_filter *filter = cb->data;
e5009240
PNA
4614 struct net *net = sock_net(skb->sk);
4615 int family = nfmsg->nfgen_family;
43da04a5
PNA
4616 struct nft_object *obj;
4617 bool reset = false;
4618
4619 if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4620 reset = true;
e5009240
PNA
4621
4622 rcu_read_lock();
4623 cb->seq = net->nft.base_seq;
4624
4625 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
4626 if (family != NFPROTO_UNSPEC && family != afi->family)
4627 continue;
4628
4629 list_for_each_entry_rcu(table, &afi->tables, list) {
4630 list_for_each_entry_rcu(obj, &table->objects, list) {
4631 if (!nft_is_active(net, obj))
4632 goto cont;
4633 if (idx < s_idx)
4634 goto cont;
4635 if (idx > s_idx)
4636 memset(&cb->args[1], 0,
4637 sizeof(cb->args) - sizeof(cb->args[0]));
d21e540b 4638 if (filter && filter->table[0] &&
a9fea2a3
PNA
4639 strcmp(filter->table, table->name))
4640 goto cont;
d21e540b
LZ
4641 if (filter &&
4642 filter->type != NFT_OBJECT_UNSPEC &&
dfc46034 4643 obj->ops->type->type != filter->type)
a9fea2a3
PNA
4644 goto cont;
4645
e5009240
PNA
4646 if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
4647 cb->nlh->nlmsg_seq,
4648 NFT_MSG_NEWOBJ,
4649 NLM_F_MULTI | NLM_F_APPEND,
43da04a5 4650 afi->family, table, obj, reset) < 0)
e5009240
PNA
4651 goto done;
4652
4653 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4654cont:
4655 idx++;
4656 }
4657 }
4658 }
4659done:
4660 rcu_read_unlock();
4661
4662 cb->args[0] = idx;
4663 return skb->len;
4664}
4665
a9fea2a3
PNA
4666static int nf_tables_dump_obj_done(struct netlink_callback *cb)
4667{
e46abbcc
PS
4668 struct nft_obj_filter *filter = cb->data;
4669
4670 kfree(filter->table);
4671 kfree(filter);
a9fea2a3
PNA
4672
4673 return 0;
4674}
4675
4676static struct nft_obj_filter *
4677nft_obj_filter_alloc(const struct nlattr * const nla[])
4678{
4679 struct nft_obj_filter *filter;
4680
4681 filter = kzalloc(sizeof(*filter), GFP_KERNEL);
4682 if (!filter)
4683 return ERR_PTR(-ENOMEM);
4684
e46abbcc
PS
4685 if (nla[NFTA_OBJ_TABLE]) {
4686 filter->table = nla_strdup(nla[NFTA_OBJ_TABLE], GFP_KERNEL);
4687 if (!filter->table) {
4688 kfree(filter);
4689 return ERR_PTR(-ENOMEM);
4690 }
4691 }
a9fea2a3
PNA
4692 if (nla[NFTA_OBJ_TYPE])
4693 filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4694
4695 return filter;
4696}
4697
e5009240
PNA
4698static int nf_tables_getobj(struct net *net, struct sock *nlsk,
4699 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4700 const struct nlattr * const nla[],
4701 struct netlink_ext_ack *extack)
e5009240
PNA
4702{
4703 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4704 u8 genmask = nft_genmask_cur(net);
4705 int family = nfmsg->nfgen_family;
4706 const struct nft_af_info *afi;
4707 const struct nft_table *table;
4708 struct nft_object *obj;
4709 struct sk_buff *skb2;
43da04a5 4710 bool reset = false;
e5009240
PNA
4711 u32 objtype;
4712 int err;
4713
4714 if (nlh->nlmsg_flags & NLM_F_DUMP) {
4715 struct netlink_dump_control c = {
4716 .dump = nf_tables_dump_obj,
a9fea2a3 4717 .done = nf_tables_dump_obj_done,
e5009240 4718 };
a9fea2a3
PNA
4719
4720 if (nla[NFTA_OBJ_TABLE] ||
4721 nla[NFTA_OBJ_TYPE]) {
4722 struct nft_obj_filter *filter;
4723
4724 filter = nft_obj_filter_alloc(nla);
4725 if (IS_ERR(filter))
4726 return -ENOMEM;
4727
4728 c.data = filter;
4729 }
e5009240
PNA
4730 return netlink_dump_start(nlsk, skb, nlh, &c);
4731 }
4732
4733 if (!nla[NFTA_OBJ_NAME] ||
4734 !nla[NFTA_OBJ_TYPE])
4735 return -EINVAL;
4736
4737 afi = nf_tables_afinfo_lookup(net, family, false);
4738 if (IS_ERR(afi))
4739 return PTR_ERR(afi);
4740
4741 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4742 if (IS_ERR(table))
4743 return PTR_ERR(table);
4744
4745 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4746 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4747 if (IS_ERR(obj))
4748 return PTR_ERR(obj);
4749
4750 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
4751 if (!skb2)
4752 return -ENOMEM;
4753
43da04a5
PNA
4754 if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4755 reset = true;
4756
e5009240
PNA
4757 err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
4758 nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
43da04a5 4759 family, table, obj, reset);
e5009240
PNA
4760 if (err < 0)
4761 goto err;
4762
4763 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4764err:
4765 kfree_skb(skb2);
4766 return err;
e5009240
PNA
4767}
4768
4769static void nft_obj_destroy(struct nft_object *obj)
4770{
dfc46034
PBG
4771 if (obj->ops->destroy)
4772 obj->ops->destroy(obj);
e5009240 4773
dfc46034 4774 module_put(obj->ops->type->owner);
61509575 4775 kfree(obj->name);
e5009240
PNA
4776 kfree(obj);
4777}
4778
4779static int nf_tables_delobj(struct net *net, struct sock *nlsk,
04ba724b
PNA
4780 struct sk_buff *skb, const struct nlmsghdr *nlh,
4781 const struct nlattr * const nla[],
4782 struct netlink_ext_ack *extack)
e5009240
PNA
4783{
4784 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4785 u8 genmask = nft_genmask_next(net);
4786 int family = nfmsg->nfgen_family;
4787 struct nft_af_info *afi;
4788 struct nft_table *table;
4789 struct nft_object *obj;
4790 struct nft_ctx ctx;
4791 u32 objtype;
4792
4793 if (!nla[NFTA_OBJ_TYPE] ||
4794 !nla[NFTA_OBJ_NAME])
4795 return -EINVAL;
4796
4797 afi = nf_tables_afinfo_lookup(net, family, true);
4798 if (IS_ERR(afi))
4799 return PTR_ERR(afi);
4800
4801 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4802 if (IS_ERR(table))
4803 return PTR_ERR(table);
4804
4805 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4806 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4807 if (IS_ERR(obj))
4808 return PTR_ERR(obj);
4809 if (obj->use > 0)
4810 return -EBUSY;
4811
4812 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4813
4814 return nft_delobj(&ctx, obj);
4815}
4816
25e94a99
PNA
4817void nft_obj_notify(struct net *net, struct nft_table *table,
4818 struct nft_object *obj, u32 portid, u32 seq, int event,
4819 int family, int report, gfp_t gfp)
e5009240
PNA
4820{
4821 struct sk_buff *skb;
4822 int err;
4823
2599e989
PNA
4824 if (!report &&
4825 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 4826 return;
e5009240 4827
2599e989 4828 skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
e5009240
PNA
4829 if (skb == NULL)
4830 goto err;
4831
2599e989
PNA
4832 err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
4833 table, obj, false);
e5009240
PNA
4834 if (err < 0) {
4835 kfree_skb(skb);
4836 goto err;
4837 }
4838
25e94a99
PNA
4839 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
4840 return;
e5009240 4841err:
25e94a99 4842 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
e5009240 4843}
2599e989
PNA
4844EXPORT_SYMBOL_GPL(nft_obj_notify);
4845
25e94a99
PNA
4846static void nf_tables_obj_notify(const struct nft_ctx *ctx,
4847 struct nft_object *obj, int event)
2599e989 4848{
25e94a99
PNA
4849 nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
4850 ctx->afi->family, ctx->report, GFP_KERNEL);
2599e989 4851}
e5009240 4852
84d7fce6
PNA
4853static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
4854 u32 portid, u32 seq)
4855{
4856 struct nlmsghdr *nlh;
4857 struct nfgenmsg *nfmsg;
784b4e61 4858 char buf[TASK_COMM_LEN];
dedb67c4 4859 int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN);
84d7fce6
PNA
4860
4861 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0);
4862 if (nlh == NULL)
4863 goto nla_put_failure;
4864
4865 nfmsg = nlmsg_data(nlh);
4866 nfmsg->nfgen_family = AF_UNSPEC;
4867 nfmsg->version = NFNETLINK_V0;
4868 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4869
784b4e61
PS
4870 if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) ||
4871 nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
4872 nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
84d7fce6
PNA
4873 goto nla_put_failure;
4874
053c095a
JB
4875 nlmsg_end(skb, nlh);
4876 return 0;
84d7fce6
PNA
4877
4878nla_put_failure:
4879 nlmsg_trim(skb, nlh);
4880 return -EMSGSIZE;
4881}
4882
25e94a99
PNA
4883static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
4884 int event)
84d7fce6
PNA
4885{
4886 struct nlmsghdr *nlh = nlmsg_hdr(skb);
4887 struct sk_buff *skb2;
4888 int err;
4889
4890 if (nlmsg_report(nlh) &&
4891 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
25e94a99 4892 return;
84d7fce6 4893
84d7fce6
PNA
4894 skb2 = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
4895 if (skb2 == NULL)
4896 goto err;
4897
4898 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
4899 nlh->nlmsg_seq);
4900 if (err < 0) {
4901 kfree_skb(skb2);
4902 goto err;
4903 }
4904
25e94a99
PNA
4905 nfnetlink_send(skb2, net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4906 nlmsg_report(nlh), GFP_KERNEL);
4907 return;
84d7fce6 4908err:
25e94a99
PNA
4909 nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4910 -ENOBUFS);
84d7fce6
PNA
4911}
4912
7b8002a1
PNA
4913static int nf_tables_getgen(struct net *net, struct sock *nlsk,
4914 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
4915 const struct nlattr * const nla[],
4916 struct netlink_ext_ack *extack)
84d7fce6 4917{
84d7fce6
PNA
4918 struct sk_buff *skb2;
4919 int err;
4920
4921 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
4922 if (skb2 == NULL)
4923 return -ENOMEM;
4924
4925 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
4926 nlh->nlmsg_seq);
4927 if (err < 0)
4928 goto err;
4929
4930 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4931err:
4932 kfree_skb(skb2);
4933 return err;
4934}
4935
96518518
PM
4936static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
4937 [NFT_MSG_NEWTABLE] = {
55dd6f93 4938 .call_batch = nf_tables_newtable,
96518518
PM
4939 .attr_count = NFTA_TABLE_MAX,
4940 .policy = nft_table_policy,
4941 },
4942 [NFT_MSG_GETTABLE] = {
4943 .call = nf_tables_gettable,
4944 .attr_count = NFTA_TABLE_MAX,
4945 .policy = nft_table_policy,
4946 },
4947 [NFT_MSG_DELTABLE] = {
55dd6f93 4948 .call_batch = nf_tables_deltable,
96518518
PM
4949 .attr_count = NFTA_TABLE_MAX,
4950 .policy = nft_table_policy,
4951 },
4952 [NFT_MSG_NEWCHAIN] = {
91c7b38d 4953 .call_batch = nf_tables_newchain,
96518518
PM
4954 .attr_count = NFTA_CHAIN_MAX,
4955 .policy = nft_chain_policy,
4956 },
4957 [NFT_MSG_GETCHAIN] = {
4958 .call = nf_tables_getchain,
4959 .attr_count = NFTA_CHAIN_MAX,
4960 .policy = nft_chain_policy,
4961 },
4962 [NFT_MSG_DELCHAIN] = {
91c7b38d 4963 .call_batch = nf_tables_delchain,
96518518
PM
4964 .attr_count = NFTA_CHAIN_MAX,
4965 .policy = nft_chain_policy,
4966 },
4967 [NFT_MSG_NEWRULE] = {
0628b123 4968 .call_batch = nf_tables_newrule,
96518518
PM
4969 .attr_count = NFTA_RULE_MAX,
4970 .policy = nft_rule_policy,
4971 },
4972 [NFT_MSG_GETRULE] = {
4973 .call = nf_tables_getrule,
4974 .attr_count = NFTA_RULE_MAX,
4975 .policy = nft_rule_policy,
4976 },
4977 [NFT_MSG_DELRULE] = {
0628b123 4978 .call_batch = nf_tables_delrule,
96518518
PM
4979 .attr_count = NFTA_RULE_MAX,
4980 .policy = nft_rule_policy,
4981 },
20a69341 4982 [NFT_MSG_NEWSET] = {
958bee14 4983 .call_batch = nf_tables_newset,
20a69341
PM
4984 .attr_count = NFTA_SET_MAX,
4985 .policy = nft_set_policy,
4986 },
4987 [NFT_MSG_GETSET] = {
4988 .call = nf_tables_getset,
4989 .attr_count = NFTA_SET_MAX,
4990 .policy = nft_set_policy,
4991 },
4992 [NFT_MSG_DELSET] = {
958bee14 4993 .call_batch = nf_tables_delset,
20a69341
PM
4994 .attr_count = NFTA_SET_MAX,
4995 .policy = nft_set_policy,
4996 },
4997 [NFT_MSG_NEWSETELEM] = {
958bee14 4998 .call_batch = nf_tables_newsetelem,
20a69341
PM
4999 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5000 .policy = nft_set_elem_list_policy,
5001 },
5002 [NFT_MSG_GETSETELEM] = {
5003 .call = nf_tables_getsetelem,
5004 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5005 .policy = nft_set_elem_list_policy,
5006 },
5007 [NFT_MSG_DELSETELEM] = {
958bee14 5008 .call_batch = nf_tables_delsetelem,
20a69341
PM
5009 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5010 .policy = nft_set_elem_list_policy,
5011 },
84d7fce6
PNA
5012 [NFT_MSG_GETGEN] = {
5013 .call = nf_tables_getgen,
5014 },
e5009240
PNA
5015 [NFT_MSG_NEWOBJ] = {
5016 .call_batch = nf_tables_newobj,
5017 .attr_count = NFTA_OBJ_MAX,
5018 .policy = nft_obj_policy,
5019 },
5020 [NFT_MSG_GETOBJ] = {
5021 .call = nf_tables_getobj,
5022 .attr_count = NFTA_OBJ_MAX,
5023 .policy = nft_obj_policy,
5024 },
5025 [NFT_MSG_DELOBJ] = {
5026 .call_batch = nf_tables_delobj,
5027 .attr_count = NFTA_OBJ_MAX,
5028 .policy = nft_obj_policy,
5029 },
43da04a5
PNA
5030 [NFT_MSG_GETOBJ_RESET] = {
5031 .call = nf_tables_getobj,
5032 .attr_count = NFTA_OBJ_MAX,
5033 .policy = nft_obj_policy,
5034 },
96518518
PM
5035};
5036
91c7b38d
PNA
5037static void nft_chain_commit_update(struct nft_trans *trans)
5038{
5039 struct nft_base_chain *basechain;
5040
b7263e07 5041 if (nft_trans_chain_name(trans))
91c7b38d
PNA
5042 strcpy(trans->ctx.chain->name, nft_trans_chain_name(trans));
5043
f323d954 5044 if (!nft_is_base_chain(trans->ctx.chain))
91c7b38d
PNA
5045 return;
5046
5047 basechain = nft_base_chain(trans->ctx.chain);
5048 nft_chain_stats_replace(basechain, nft_trans_chain_stats(trans));
5049
5050 switch (nft_trans_chain_policy(trans)) {
5051 case NF_DROP:
5052 case NF_ACCEPT:
5053 basechain->policy = nft_trans_chain_policy(trans);
5054 break;
5055 }
5056}
5057
b326dd37 5058static void nf_tables_commit_release(struct nft_trans *trans)
c7c32e72 5059{
c7c32e72
PNA
5060 switch (trans->msg_type) {
5061 case NFT_MSG_DELTABLE:
5062 nf_tables_table_destroy(&trans->ctx);
5063 break;
5064 case NFT_MSG_DELCHAIN:
5065 nf_tables_chain_destroy(trans->ctx.chain);
5066 break;
5067 case NFT_MSG_DELRULE:
5068 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
5069 break;
5070 case NFT_MSG_DELSET:
5071 nft_set_destroy(nft_trans_set(trans));
5072 break;
61edafbb 5073 case NFT_MSG_DELSETELEM:
59105446
PNA
5074 nf_tables_set_elem_destroy(nft_trans_elem_set(trans),
5075 nft_trans_elem(trans).priv);
61edafbb 5076 break;
e5009240
PNA
5077 case NFT_MSG_DELOBJ:
5078 nft_obj_destroy(nft_trans_obj(trans));
5079 break;
c7c32e72
PNA
5080 }
5081 kfree(trans);
5082}
5083
5913beaf 5084static int nf_tables_commit(struct net *net, struct sk_buff *skb)
37082f93 5085{
37082f93 5086 struct nft_trans *trans, *next;
a3716e70 5087 struct nft_trans_elem *te;
37082f93
PNA
5088
5089 /* Bump generation counter, invalidate any dump in progress */
38e029f1 5090 while (++net->nft.base_seq == 0);
37082f93
PNA
5091
5092 /* A new generation has just started */
ea4bd995 5093 net->nft.gencursor = nft_gencursor_next(net);
37082f93
PNA
5094
5095 /* Make sure all packets have left the previous generation before
5096 * purging old rules.
5097 */
5098 synchronize_rcu();
5099
5100 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
b380e5c7 5101 switch (trans->msg_type) {
55dd6f93
PNA
5102 case NFT_MSG_NEWTABLE:
5103 if (nft_trans_table_update(trans)) {
5104 if (!nft_trans_table_enable(trans)) {
664b0f8c
PNA
5105 nf_tables_table_disable(net,
5106 trans->ctx.afi,
55dd6f93
PNA
5107 trans->ctx.table);
5108 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
5109 }
5110 } else {
f2a6d766 5111 nft_clear(net, trans->ctx.table);
55dd6f93 5112 }
35151d84 5113 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
55dd6f93
PNA
5114 nft_trans_destroy(trans);
5115 break;
5116 case NFT_MSG_DELTABLE:
f2a6d766 5117 list_del_rcu(&trans->ctx.table->list);
35151d84 5118 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
55dd6f93 5119 break;
91c7b38d
PNA
5120 case NFT_MSG_NEWCHAIN:
5121 if (nft_trans_chain_update(trans))
5122 nft_chain_commit_update(trans);
4fefee57 5123 else
664b0f8c 5124 nft_clear(net, trans->ctx.chain);
4fefee57 5125
35151d84 5126 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
91c7b38d
PNA
5127 nft_trans_destroy(trans);
5128 break;
5129 case NFT_MSG_DELCHAIN:
664b0f8c 5130 list_del_rcu(&trans->ctx.chain->list);
35151d84 5131 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
82bec71d
PNA
5132 nf_tables_unregister_hooks(trans->ctx.net,
5133 trans->ctx.table,
c5598794
AB
5134 trans->ctx.chain,
5135 trans->ctx.afi->nops);
91c7b38d 5136 break;
b380e5c7 5137 case NFT_MSG_NEWRULE:
889f7ee7 5138 nft_clear(trans->ctx.net, nft_trans_rule(trans));
35151d84 5139 nf_tables_rule_notify(&trans->ctx,
37082f93 5140 nft_trans_rule(trans),
35151d84 5141 NFT_MSG_NEWRULE);
37082f93 5142 nft_trans_destroy(trans);
b380e5c7
PNA
5143 break;
5144 case NFT_MSG_DELRULE:
5145 list_del_rcu(&nft_trans_rule(trans)->list);
35151d84
PNA
5146 nf_tables_rule_notify(&trans->ctx,
5147 nft_trans_rule(trans),
5148 NFT_MSG_DELRULE);
b380e5c7 5149 break;
958bee14 5150 case NFT_MSG_NEWSET:
37a9cc52 5151 nft_clear(net, nft_trans_set(trans));
4fefee57
PNA
5152 /* This avoids hitting -EBUSY when deleting the table
5153 * from the transaction.
5154 */
5155 if (nft_trans_set(trans)->flags & NFT_SET_ANONYMOUS &&
5156 !list_empty(&nft_trans_set(trans)->bindings))
5157 trans->ctx.table->use--;
5158
958bee14 5159 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 5160 NFT_MSG_NEWSET, GFP_KERNEL);
958bee14
PNA
5161 nft_trans_destroy(trans);
5162 break;
5163 case NFT_MSG_DELSET:
37a9cc52 5164 list_del_rcu(&nft_trans_set(trans)->list);
958bee14 5165 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
31f8441c 5166 NFT_MSG_DELSET, GFP_KERNEL);
958bee14 5167 break;
60319eb1 5168 case NFT_MSG_NEWSETELEM:
cc02e457
PM
5169 te = (struct nft_trans_elem *)trans->data;
5170
42a55769 5171 te->set->ops->activate(net, te->set, &te->elem);
cc02e457
PM
5172 nf_tables_setelem_notify(&trans->ctx, te->set,
5173 &te->elem,
60319eb1
PNA
5174 NFT_MSG_NEWSETELEM, 0);
5175 nft_trans_destroy(trans);
5176 break;
5177 case NFT_MSG_DELSETELEM:
a3716e70 5178 te = (struct nft_trans_elem *)trans->data;
fe2811eb 5179
a3716e70
PNA
5180 nf_tables_setelem_notify(&trans->ctx, te->set,
5181 &te->elem,
60319eb1 5182 NFT_MSG_DELSETELEM, 0);
5cb82a38 5183 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a
PM
5184 atomic_dec(&te->set->nelems);
5185 te->set->ndeact--;
60319eb1 5186 break;
e5009240
PNA
5187 case NFT_MSG_NEWOBJ:
5188 nft_clear(net, nft_trans_obj(trans));
5189 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
5190 NFT_MSG_NEWOBJ);
5191 nft_trans_destroy(trans);
5192 break;
5193 case NFT_MSG_DELOBJ:
5194 list_del_rcu(&nft_trans_obj(trans)->list);
5195 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
5196 NFT_MSG_DELOBJ);
5197 break;
37082f93 5198 }
37082f93
PNA
5199 }
5200
b326dd37
PNA
5201 synchronize_rcu();
5202
37082f93 5203 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
c7c32e72 5204 list_del(&trans->list);
b326dd37 5205 nf_tables_commit_release(trans);
37082f93 5206 }
84d7fce6
PNA
5207
5208 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
37082f93
PNA
5209
5210 return 0;
5211}
5212
b326dd37 5213static void nf_tables_abort_release(struct nft_trans *trans)
c7c32e72 5214{
c7c32e72
PNA
5215 switch (trans->msg_type) {
5216 case NFT_MSG_NEWTABLE:
5217 nf_tables_table_destroy(&trans->ctx);
5218 break;
5219 case NFT_MSG_NEWCHAIN:
5220 nf_tables_chain_destroy(trans->ctx.chain);
5221 break;
5222 case NFT_MSG_NEWRULE:
5223 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
5224 break;
5225 case NFT_MSG_NEWSET:
5226 nft_set_destroy(nft_trans_set(trans));
5227 break;
61edafbb
PM
5228 case NFT_MSG_NEWSETELEM:
5229 nft_set_elem_destroy(nft_trans_elem_set(trans),
61f9e292 5230 nft_trans_elem(trans).priv, true);
61edafbb 5231 break;
e5009240
PNA
5232 case NFT_MSG_NEWOBJ:
5233 nft_obj_destroy(nft_trans_obj(trans));
5234 break;
c7c32e72
PNA
5235 }
5236 kfree(trans);
5237}
5238
5913beaf 5239static int nf_tables_abort(struct net *net, struct sk_buff *skb)
37082f93 5240{
37082f93 5241 struct nft_trans *trans, *next;
02263db0 5242 struct nft_trans_elem *te;
37082f93 5243
a907e36d
XL
5244 list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
5245 list) {
b380e5c7 5246 switch (trans->msg_type) {
55dd6f93
PNA
5247 case NFT_MSG_NEWTABLE:
5248 if (nft_trans_table_update(trans)) {
5249 if (nft_trans_table_enable(trans)) {
664b0f8c
PNA
5250 nf_tables_table_disable(net,
5251 trans->ctx.afi,
55dd6f93
PNA
5252 trans->ctx.table);
5253 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
5254 }
5255 nft_trans_destroy(trans);
5256 } else {
e688a7f8 5257 list_del_rcu(&trans->ctx.table->list);
55dd6f93
PNA
5258 }
5259 break;
5260 case NFT_MSG_DELTABLE:
f2a6d766 5261 nft_clear(trans->ctx.net, trans->ctx.table);
55dd6f93
PNA
5262 nft_trans_destroy(trans);
5263 break;
91c7b38d
PNA
5264 case NFT_MSG_NEWCHAIN:
5265 if (nft_trans_chain_update(trans)) {
982f4051 5266 free_percpu(nft_trans_chain_stats(trans));
91c7b38d
PNA
5267
5268 nft_trans_destroy(trans);
5269 } else {
4fefee57 5270 trans->ctx.table->use--;
e688a7f8 5271 list_del_rcu(&trans->ctx.chain->list);
82bec71d
PNA
5272 nf_tables_unregister_hooks(trans->ctx.net,
5273 trans->ctx.table,
c5598794
AB
5274 trans->ctx.chain,
5275 trans->ctx.afi->nops);
91c7b38d
PNA
5276 }
5277 break;
5278 case NFT_MSG_DELCHAIN:
4fefee57 5279 trans->ctx.table->use++;
664b0f8c 5280 nft_clear(trans->ctx.net, trans->ctx.chain);
91c7b38d
PNA
5281 nft_trans_destroy(trans);
5282 break;
b380e5c7 5283 case NFT_MSG_NEWRULE:
4fefee57 5284 trans->ctx.chain->use--;
b380e5c7
PNA
5285 list_del_rcu(&nft_trans_rule(trans)->list);
5286 break;
5287 case NFT_MSG_DELRULE:
4fefee57 5288 trans->ctx.chain->use++;
889f7ee7 5289 nft_clear(trans->ctx.net, nft_trans_rule(trans));
37082f93 5290 nft_trans_destroy(trans);
b380e5c7 5291 break;
958bee14 5292 case NFT_MSG_NEWSET:
4fefee57 5293 trans->ctx.table->use--;
e688a7f8 5294 list_del_rcu(&nft_trans_set(trans)->list);
958bee14
PNA
5295 break;
5296 case NFT_MSG_DELSET:
4fefee57 5297 trans->ctx.table->use++;
37a9cc52 5298 nft_clear(trans->ctx.net, nft_trans_set(trans));
958bee14
PNA
5299 nft_trans_destroy(trans);
5300 break;
60319eb1 5301 case NFT_MSG_NEWSETELEM:
02263db0 5302 te = (struct nft_trans_elem *)trans->data;
fe2811eb 5303
5cb82a38 5304 te->set->ops->remove(net, te->set, &te->elem);
3dd0673a 5305 atomic_dec(&te->set->nelems);
60319eb1
PNA
5306 break;
5307 case NFT_MSG_DELSETELEM:
cc02e457
PM
5308 te = (struct nft_trans_elem *)trans->data;
5309
59105446 5310 nft_set_elem_activate(net, te->set, &te->elem);
42a55769 5311 te->set->ops->activate(net, te->set, &te->elem);
3dd0673a 5312 te->set->ndeact--;
cc02e457 5313
e5009240
PNA
5314 nft_trans_destroy(trans);
5315 break;
5316 case NFT_MSG_NEWOBJ:
5317 trans->ctx.table->use--;
5318 list_del_rcu(&nft_trans_obj(trans)->list);
5319 break;
5320 case NFT_MSG_DELOBJ:
5321 trans->ctx.table->use++;
5322 nft_clear(trans->ctx.net, nft_trans_obj(trans));
60319eb1
PNA
5323 nft_trans_destroy(trans);
5324 break;
37082f93 5325 }
37082f93
PNA
5326 }
5327
b326dd37
PNA
5328 synchronize_rcu();
5329
a1cee076
PNA
5330 list_for_each_entry_safe_reverse(trans, next,
5331 &net->nft.commit_list, list) {
c7c32e72 5332 list_del(&trans->list);
b326dd37 5333 nf_tables_abort_release(trans);
37082f93
PNA
5334 }
5335
5336 return 0;
5337}
5338
74e8bcd2
PNA
5339static bool nf_tables_valid_genid(struct net *net, u32 genid)
5340{
5341 return net->nft.base_seq == genid;
5342}
5343
96518518
PM
5344static const struct nfnetlink_subsystem nf_tables_subsys = {
5345 .name = "nf_tables",
5346 .subsys_id = NFNL_SUBSYS_NFTABLES,
5347 .cb_count = NFT_MSG_MAX,
5348 .cb = nf_tables_cb,
0628b123
PNA
5349 .commit = nf_tables_commit,
5350 .abort = nf_tables_abort,
74e8bcd2 5351 .valid_genid = nf_tables_valid_genid,
96518518
PM
5352};
5353
7210e4e3
PNA
5354int nft_chain_validate_dependency(const struct nft_chain *chain,
5355 enum nft_chain_type type)
5356{
5357 const struct nft_base_chain *basechain;
5358
f323d954 5359 if (nft_is_base_chain(chain)) {
7210e4e3
PNA
5360 basechain = nft_base_chain(chain);
5361 if (basechain->type->type != type)
5362 return -EOPNOTSUPP;
5363 }
5364 return 0;
5365}
5366EXPORT_SYMBOL_GPL(nft_chain_validate_dependency);
5367
75e8d06d
PNA
5368int nft_chain_validate_hooks(const struct nft_chain *chain,
5369 unsigned int hook_flags)
5370{
5371 struct nft_base_chain *basechain;
5372
f323d954 5373 if (nft_is_base_chain(chain)) {
75e8d06d
PNA
5374 basechain = nft_base_chain(chain);
5375
5376 if ((1 << basechain->ops[0].hooknum) & hook_flags)
5377 return 0;
5378
5379 return -EOPNOTSUPP;
5380 }
5381
5382 return 0;
5383}
5384EXPORT_SYMBOL_GPL(nft_chain_validate_hooks);
5385
20a69341
PM
5386/*
5387 * Loop detection - walk through the ruleset beginning at the destination chain
5388 * of a new jump until either the source chain is reached (loop) or all
5389 * reachable chains have been traversed.
5390 *
5391 * The loop check is performed whenever a new jump verdict is added to an
5392 * expression or verdict map or a verdict map is bound to a new chain.
5393 */
5394
5395static int nf_tables_check_loops(const struct nft_ctx *ctx,
5396 const struct nft_chain *chain);
5397
5398static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
de70185d 5399 struct nft_set *set,
20a69341 5400 const struct nft_set_iter *iter,
de70185d 5401 struct nft_set_elem *elem)
20a69341 5402{
fe2811eb
PM
5403 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
5404 const struct nft_data *data;
5405
5406 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
5407 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
62f9c8b4
PNA
5408 return 0;
5409
fe2811eb 5410 data = nft_set_ext_data(ext);
1ca2e170 5411 switch (data->verdict.code) {
20a69341
PM
5412 case NFT_JUMP:
5413 case NFT_GOTO:
1ca2e170 5414 return nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
5415 default:
5416 return 0;
5417 }
5418}
5419
5420static int nf_tables_check_loops(const struct nft_ctx *ctx,
5421 const struct nft_chain *chain)
5422{
5423 const struct nft_rule *rule;
5424 const struct nft_expr *expr, *last;
de70185d 5425 struct nft_set *set;
20a69341
PM
5426 struct nft_set_binding *binding;
5427 struct nft_set_iter iter;
20a69341
PM
5428
5429 if (ctx->chain == chain)
5430 return -ELOOP;
5431
5432 list_for_each_entry(rule, &chain->rules, list) {
5433 nft_rule_for_each_expr(expr, last, rule) {
0ca743a5
PNA
5434 const struct nft_data *data = NULL;
5435 int err;
5436
5437 if (!expr->ops->validate)
20a69341
PM
5438 continue;
5439
0ca743a5
PNA
5440 err = expr->ops->validate(ctx, expr, &data);
5441 if (err < 0)
5442 return err;
5443
20a69341 5444 if (data == NULL)
0ca743a5 5445 continue;
20a69341 5446
1ca2e170 5447 switch (data->verdict.code) {
20a69341
PM
5448 case NFT_JUMP:
5449 case NFT_GOTO:
1ca2e170
PM
5450 err = nf_tables_check_loops(ctx,
5451 data->verdict.chain);
20a69341
PM
5452 if (err < 0)
5453 return err;
5454 default:
5455 break;
5456 }
5457 }
5458 }
5459
5460 list_for_each_entry(set, &ctx->table->sets, list) {
37a9cc52
PNA
5461 if (!nft_is_active_next(ctx->net, set))
5462 continue;
20a69341
PM
5463 if (!(set->flags & NFT_SET_MAP) ||
5464 set->dtype != NFT_DATA_VERDICT)
5465 continue;
5466
5467 list_for_each_entry(binding, &set->bindings, list) {
11113e19
PM
5468 if (!(binding->flags & NFT_SET_MAP) ||
5469 binding->chain != chain)
20a69341
PM
5470 continue;
5471
8588ac09 5472 iter.genmask = nft_genmask_next(ctx->net);
20a69341
PM
5473 iter.skip = 0;
5474 iter.count = 0;
5475 iter.err = 0;
5476 iter.fn = nf_tables_loop_check_setelem;
5477
5478 set->ops->walk(ctx, set, &iter);
5479 if (iter.err < 0)
5480 return iter.err;
5481 }
5482 }
5483
5484 return 0;
5485}
5486
36b701fa
LGL
5487/**
5488 * nft_parse_u32_check - fetch u32 attribute and check for maximum value
5489 *
5490 * @attr: netlink attribute to fetch value from
5491 * @max: maximum value to be stored in dest
5492 * @dest: pointer to the variable
5493 *
5494 * Parse, check and store a given u32 netlink attribute into variable.
5495 * This function returns -ERANGE if the value goes over maximum value.
5496 * Otherwise a 0 is returned and the attribute value is stored in the
5497 * destination variable.
5498 */
f1d505bb 5499int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
36b701fa 5500{
09525a09 5501 u32 val;
36b701fa
LGL
5502
5503 val = ntohl(nla_get_be32(attr));
5504 if (val > max)
5505 return -ERANGE;
5506
5507 *dest = val;
5508 return 0;
5509}
5510EXPORT_SYMBOL_GPL(nft_parse_u32_check);
5511
49499c3e
PM
5512/**
5513 * nft_parse_register - parse a register value from a netlink attribute
5514 *
5515 * @attr: netlink attribute
5516 *
5517 * Parse and translate a register value from a netlink attribute.
5518 * Registers used to be 128 bit wide, these register numbers will be
5519 * mapped to the corresponding 32 bit register numbers.
5520 */
b1c96ed3
PM
5521unsigned int nft_parse_register(const struct nlattr *attr)
5522{
49499c3e
PM
5523 unsigned int reg;
5524
5525 reg = ntohl(nla_get_be32(attr));
5526 switch (reg) {
5527 case NFT_REG_VERDICT...NFT_REG_4:
5528 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
5529 default:
5530 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
5531 }
b1c96ed3
PM
5532}
5533EXPORT_SYMBOL_GPL(nft_parse_register);
5534
49499c3e
PM
5535/**
5536 * nft_dump_register - dump a register value to a netlink attribute
5537 *
5538 * @skb: socket buffer
5539 * @attr: attribute number
5540 * @reg: register number
5541 *
5542 * Construct a netlink attribute containing the register number. For
5543 * compatibility reasons, register numbers being a multiple of 4 are
5544 * translated to the corresponding 128 bit register numbers.
5545 */
b1c96ed3
PM
5546int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
5547{
49499c3e
PM
5548 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
5549 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
5550 else
5551 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
5552
b1c96ed3
PM
5553 return nla_put_be32(skb, attr, htonl(reg));
5554}
5555EXPORT_SYMBOL_GPL(nft_dump_register);
5556
96518518 5557/**
d07db988 5558 * nft_validate_register_load - validate a load from a register
96518518
PM
5559 *
5560 * @reg: the register number
d07db988 5561 * @len: the length of the data
96518518
PM
5562 *
5563 * Validate that the input register is one of the general purpose
d07db988 5564 * registers and that the length of the load is within the bounds.
96518518 5565 */
d07db988 5566int nft_validate_register_load(enum nft_registers reg, unsigned int len)
96518518 5567{
49499c3e 5568 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
96518518 5569 return -EINVAL;
d07db988
PM
5570 if (len == 0)
5571 return -EINVAL;
49499c3e 5572 if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
d07db988 5573 return -ERANGE;
49499c3e 5574
96518518
PM
5575 return 0;
5576}
d07db988 5577EXPORT_SYMBOL_GPL(nft_validate_register_load);
96518518 5578
96518518 5579/**
1ec10212 5580 * nft_validate_register_store - validate an expressions' register store
96518518
PM
5581 *
5582 * @ctx: context of the expression performing the load
5583 * @reg: the destination register number
5584 * @data: the data to load
5585 * @type: the data type
45d9bcda 5586 * @len: the length of the data
96518518
PM
5587 *
5588 * Validate that a data load uses the appropriate data type for
45d9bcda
PM
5589 * the destination register and the length is within the bounds.
5590 * A value of NULL for the data means that its runtime gathered
58f40ab6 5591 * data.
96518518 5592 */
1ec10212
PM
5593int nft_validate_register_store(const struct nft_ctx *ctx,
5594 enum nft_registers reg,
5595 const struct nft_data *data,
5596 enum nft_data_types type, unsigned int len)
96518518 5597{
20a69341
PM
5598 int err;
5599
96518518
PM
5600 switch (reg) {
5601 case NFT_REG_VERDICT:
58f40ab6 5602 if (type != NFT_DATA_VERDICT)
96518518 5603 return -EINVAL;
20a69341 5604
58f40ab6 5605 if (data != NULL &&
1ca2e170
PM
5606 (data->verdict.code == NFT_GOTO ||
5607 data->verdict.code == NFT_JUMP)) {
5608 err = nf_tables_check_loops(ctx, data->verdict.chain);
20a69341
PM
5609 if (err < 0)
5610 return err;
5611
1ca2e170
PM
5612 if (ctx->chain->level + 1 >
5613 data->verdict.chain->level) {
20a69341
PM
5614 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
5615 return -EMLINK;
1ca2e170 5616 data->verdict.chain->level = ctx->chain->level + 1;
20a69341
PM
5617 }
5618 }
5619
96518518
PM
5620 return 0;
5621 default:
49499c3e 5622 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
27e6d201 5623 return -EINVAL;
45d9bcda
PM
5624 if (len == 0)
5625 return -EINVAL;
49499c3e
PM
5626 if (reg * NFT_REG32_SIZE + len >
5627 FIELD_SIZEOF(struct nft_regs, data))
45d9bcda 5628 return -ERANGE;
27e6d201 5629
96518518
PM
5630 if (data != NULL && type != NFT_DATA_VALUE)
5631 return -EINVAL;
5632 return 0;
5633 }
5634}
1ec10212 5635EXPORT_SYMBOL_GPL(nft_validate_register_store);
96518518
PM
5636
5637static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
5638 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
5639 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
5640 .len = NFT_CHAIN_MAXNAMELEN - 1 },
5641};
5642
5643static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
5644 struct nft_data_desc *desc, const struct nlattr *nla)
5645{
664b0f8c 5646 u8 genmask = nft_genmask_next(ctx->net);
96518518
PM
5647 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
5648 struct nft_chain *chain;
5649 int err;
5650
fceb6435
JB
5651 err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy,
5652 NULL);
96518518
PM
5653 if (err < 0)
5654 return err;
5655
5656 if (!tb[NFTA_VERDICT_CODE])
5657 return -EINVAL;
1ca2e170 5658 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
96518518 5659
1ca2e170 5660 switch (data->verdict.code) {
e0abdadc 5661 default:
1ca2e170 5662 switch (data->verdict.code & NF_VERDICT_MASK) {
e0abdadc
PM
5663 case NF_ACCEPT:
5664 case NF_DROP:
5665 case NF_QUEUE:
5666 break;
5667 default:
5668 return -EINVAL;
5669 }
5670 /* fall through */
96518518
PM
5671 case NFT_CONTINUE:
5672 case NFT_BREAK:
5673 case NFT_RETURN:
96518518
PM
5674 break;
5675 case NFT_JUMP:
5676 case NFT_GOTO:
5677 if (!tb[NFTA_VERDICT_CHAIN])
5678 return -EINVAL;
5679 chain = nf_tables_chain_lookup(ctx->table,
664b0f8c 5680 tb[NFTA_VERDICT_CHAIN], genmask);
96518518
PM
5681 if (IS_ERR(chain))
5682 return PTR_ERR(chain);
f323d954 5683 if (nft_is_base_chain(chain))
96518518
PM
5684 return -EOPNOTSUPP;
5685
96518518 5686 chain->use++;
1ca2e170 5687 data->verdict.chain = chain;
96518518 5688 break;
96518518
PM
5689 }
5690
4c4ed074 5691 desc->len = sizeof(data->verdict);
96518518
PM
5692 desc->type = NFT_DATA_VERDICT;
5693 return 0;
5694}
5695
5696static void nft_verdict_uninit(const struct nft_data *data)
5697{
1ca2e170 5698 switch (data->verdict.code) {
96518518
PM
5699 case NFT_JUMP:
5700 case NFT_GOTO:
1ca2e170 5701 data->verdict.chain->use--;
96518518
PM
5702 break;
5703 }
5704}
5705
33d5a7b1 5706int nft_verdict_dump(struct sk_buff *skb, int type, const struct nft_verdict *v)
96518518
PM
5707{
5708 struct nlattr *nest;
5709
33d5a7b1 5710 nest = nla_nest_start(skb, type);
96518518
PM
5711 if (!nest)
5712 goto nla_put_failure;
5713
33d5a7b1 5714 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(v->code)))
96518518
PM
5715 goto nla_put_failure;
5716
33d5a7b1 5717 switch (v->code) {
96518518
PM
5718 case NFT_JUMP:
5719 case NFT_GOTO:
1ca2e170 5720 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
33d5a7b1 5721 v->chain->name))
96518518
PM
5722 goto nla_put_failure;
5723 }
5724 nla_nest_end(skb, nest);
5725 return 0;
5726
5727nla_put_failure:
5728 return -1;
5729}
5730
d0a11fc3
PM
5731static int nft_value_init(const struct nft_ctx *ctx,
5732 struct nft_data *data, unsigned int size,
96518518
PM
5733 struct nft_data_desc *desc, const struct nlattr *nla)
5734{
5735 unsigned int len;
5736
5737 len = nla_len(nla);
5738 if (len == 0)
5739 return -EINVAL;
d0a11fc3 5740 if (len > size)
96518518
PM
5741 return -EOVERFLOW;
5742
d0a11fc3 5743 nla_memcpy(data->data, nla, len);
96518518
PM
5744 desc->type = NFT_DATA_VALUE;
5745 desc->len = len;
5746 return 0;
5747}
5748
5749static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
5750 unsigned int len)
5751{
5752 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
5753}
5754
5755static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
d0a11fc3 5756 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
96518518
PM
5757 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
5758};
5759
5760/**
5761 * nft_data_init - parse nf_tables data netlink attributes
5762 *
5763 * @ctx: context of the expression using the data
5764 * @data: destination struct nft_data
d0a11fc3 5765 * @size: maximum data length
96518518
PM
5766 * @desc: data description
5767 * @nla: netlink attribute containing data
5768 *
5769 * Parse the netlink data attributes and initialize a struct nft_data.
5770 * The type and length of data are returned in the data description.
5771 *
5772 * The caller can indicate that it only wants to accept data of type
5773 * NFT_DATA_VALUE by passing NULL for the ctx argument.
5774 */
d0a11fc3
PM
5775int nft_data_init(const struct nft_ctx *ctx,
5776 struct nft_data *data, unsigned int size,
96518518
PM
5777 struct nft_data_desc *desc, const struct nlattr *nla)
5778{
5779 struct nlattr *tb[NFTA_DATA_MAX + 1];
5780 int err;
5781
fceb6435 5782 err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy, NULL);
96518518
PM
5783 if (err < 0)
5784 return err;
5785
5786 if (tb[NFTA_DATA_VALUE])
d0a11fc3
PM
5787 return nft_value_init(ctx, data, size, desc,
5788 tb[NFTA_DATA_VALUE]);
96518518
PM
5789 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
5790 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
5791 return -EINVAL;
5792}
5793EXPORT_SYMBOL_GPL(nft_data_init);
5794
5795/**
59105446 5796 * nft_data_release - release a nft_data item
96518518
PM
5797 *
5798 * @data: struct nft_data to release
5799 * @type: type of data
5800 *
5801 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
5802 * all others need to be released by calling this function.
5803 */
59105446 5804void nft_data_release(const struct nft_data *data, enum nft_data_types type)
96518518 5805{
960bd2c2 5806 if (type < NFT_DATA_VERDICT)
96518518 5807 return;
960bd2c2 5808 switch (type) {
96518518
PM
5809 case NFT_DATA_VERDICT:
5810 return nft_verdict_uninit(data);
5811 default:
5812 WARN_ON(1);
5813 }
5814}
59105446 5815EXPORT_SYMBOL_GPL(nft_data_release);
96518518
PM
5816
5817int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
5818 enum nft_data_types type, unsigned int len)
5819{
5820 struct nlattr *nest;
5821 int err;
5822
5823 nest = nla_nest_start(skb, attr);
5824 if (nest == NULL)
5825 return -1;
5826
5827 switch (type) {
5828 case NFT_DATA_VALUE:
5829 err = nft_value_dump(skb, data, len);
5830 break;
5831 case NFT_DATA_VERDICT:
33d5a7b1 5832 err = nft_verdict_dump(skb, NFTA_DATA_VERDICT, &data->verdict);
96518518
PM
5833 break;
5834 default:
5835 err = -EINVAL;
5836 WARN_ON(1);
5837 }
5838
5839 nla_nest_end(skb, nest);
5840 return err;
5841}
5842EXPORT_SYMBOL_GPL(nft_data_dump);
5843
df05ef87 5844static int __net_init nf_tables_init_net(struct net *net)
99633ab2
PNA
5845{
5846 INIT_LIST_HEAD(&net->nft.af_info);
0628b123 5847 INIT_LIST_HEAD(&net->nft.commit_list);
38e029f1 5848 net->nft.base_seq = 1;
99633ab2
PNA
5849 return 0;
5850}
5851
613d0776
VA
5852static void __net_exit nf_tables_exit_net(struct net *net)
5853{
5854 WARN_ON_ONCE(!list_empty(&net->nft.af_info));
5855 WARN_ON_ONCE(!list_empty(&net->nft.commit_list));
5856}
5857
5ebe0b0e
PNA
5858int __nft_release_basechain(struct nft_ctx *ctx)
5859{
5860 struct nft_rule *rule, *nr;
5861
f323d954 5862 BUG_ON(!nft_is_base_chain(ctx->chain));
5ebe0b0e 5863
82bec71d 5864 nf_tables_unregister_hooks(ctx->net, ctx->chain->table, ctx->chain,
5ebe0b0e
PNA
5865 ctx->afi->nops);
5866 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
5867 list_del(&rule->list);
5868 ctx->chain->use--;
5869 nf_tables_rule_destroy(ctx, rule);
5870 }
5871 list_del(&ctx->chain->list);
5872 ctx->table->use--;
5873 nf_tables_chain_destroy(ctx->chain);
5874
5875 return 0;
5876}
5877EXPORT_SYMBOL_GPL(__nft_release_basechain);
5878
df05ef87
PNA
5879/* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */
5880static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
5881{
5882 struct nft_table *table, *nt;
5883 struct nft_chain *chain, *nc;
e5009240 5884 struct nft_object *obj, *ne;
df05ef87
PNA
5885 struct nft_rule *rule, *nr;
5886 struct nft_set *set, *ns;
5887 struct nft_ctx ctx = {
5888 .net = net,
5889 .afi = afi,
5890 };
5891
5892 list_for_each_entry_safe(table, nt, &afi->tables, list) {
5893 list_for_each_entry(chain, &table->chains, list)
82bec71d
PNA
5894 nf_tables_unregister_hooks(net, table, chain,
5895 afi->nops);
df05ef87
PNA
5896 /* No packets are walking on these chains anymore. */
5897 ctx.table = table;
5898 list_for_each_entry(chain, &table->chains, list) {
5899 ctx.chain = chain;
5900 list_for_each_entry_safe(rule, nr, &chain->rules, list) {
5901 list_del(&rule->list);
5902 chain->use--;
5903 nf_tables_rule_destroy(&ctx, rule);
5904 }
5905 }
5906 list_for_each_entry_safe(set, ns, &table->sets, list) {
5907 list_del(&set->list);
5908 table->use--;
5909 nft_set_destroy(set);
5910 }
e5009240
PNA
5911 list_for_each_entry_safe(obj, ne, &table->objects, list) {
5912 list_del(&obj->list);
5913 table->use--;
5914 nft_obj_destroy(obj);
5915 }
df05ef87
PNA
5916 list_for_each_entry_safe(chain, nc, &table->chains, list) {
5917 list_del(&chain->list);
5918 table->use--;
5919 nf_tables_chain_destroy(chain);
5920 }
5921 list_del(&table->list);
5922 nf_tables_table_destroy(&ctx);
5923 }
5924}
5925
99633ab2
PNA
5926static struct pernet_operations nf_tables_net_ops = {
5927 .init = nf_tables_init_net,
613d0776 5928 .exit = nf_tables_exit_net,
99633ab2
PNA
5929};
5930
96518518
PM
5931static int __init nf_tables_module_init(void)
5932{
5933 int err;
5934
5935 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
5936 GFP_KERNEL);
5937 if (info == NULL) {
5938 err = -ENOMEM;
5939 goto err1;
5940 }
5941
5942 err = nf_tables_core_module_init();
5943 if (err < 0)
5944 goto err2;
5945
5946 err = nfnetlink_subsys_register(&nf_tables_subsys);
5947 if (err < 0)
5948 goto err3;
5949
5950 pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
99633ab2 5951 return register_pernet_subsys(&nf_tables_net_ops);
96518518
PM
5952err3:
5953 nf_tables_core_module_exit();
5954err2:
5955 kfree(info);
5956err1:
5957 return err;
5958}
5959
5960static void __exit nf_tables_module_exit(void)
5961{
99633ab2 5962 unregister_pernet_subsys(&nf_tables_net_ops);
96518518 5963 nfnetlink_subsys_unregister(&nf_tables_subsys);
1b1bc49c 5964 rcu_barrier();
96518518
PM
5965 nf_tables_core_module_exit();
5966 kfree(info);
5967}
5968
5969module_init(nf_tables_module_init);
5970module_exit(nf_tables_module_exit);
5971
5972MODULE_LICENSE("GPL");
5973MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
5974MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);