]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/netfilter/nf_tables_api.c
netfilter: nf_tables: add insert operation
[mirror_ubuntu-jammy-kernel.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>
16#include <linux/netfilter.h>
17#include <linux/netfilter/nfnetlink.h>
18#include <linux/netfilter/nf_tables.h>
19#include <net/netfilter/nf_tables_core.h>
20#include <net/netfilter/nf_tables.h>
99633ab2 21#include <net/net_namespace.h>
96518518
PM
22#include <net/sock.h>
23
96518518
PM
24static LIST_HEAD(nf_tables_expressions);
25
26/**
27 * nft_register_afinfo - register nf_tables address family info
28 *
29 * @afi: address family info to register
30 *
31 * Register the address family for use with nf_tables. Returns zero on
32 * success or a negative errno code otherwise.
33 */
99633ab2 34int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
96518518
PM
35{
36 INIT_LIST_HEAD(&afi->tables);
37 nfnl_lock(NFNL_SUBSYS_NFTABLES);
99633ab2 38 list_add_tail(&afi->list, &net->nft.af_info);
96518518
PM
39 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
40 return 0;
41}
42EXPORT_SYMBOL_GPL(nft_register_afinfo);
43
44/**
45 * nft_unregister_afinfo - unregister nf_tables address family info
46 *
47 * @afi: address family info to unregister
48 *
49 * Unregister the address family for use with nf_tables.
50 */
51void nft_unregister_afinfo(struct nft_af_info *afi)
52{
53 nfnl_lock(NFNL_SUBSYS_NFTABLES);
54 list_del(&afi->list);
55 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
56}
57EXPORT_SYMBOL_GPL(nft_unregister_afinfo);
58
99633ab2 59static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family)
96518518
PM
60{
61 struct nft_af_info *afi;
62
99633ab2 63 list_for_each_entry(afi, &net->nft.af_info, list) {
96518518
PM
64 if (afi->family == family)
65 return afi;
66 }
67 return NULL;
68}
69
99633ab2
PNA
70static struct nft_af_info *
71nf_tables_afinfo_lookup(struct net *net, int family, bool autoload)
96518518
PM
72{
73 struct nft_af_info *afi;
74
99633ab2 75 afi = nft_afinfo_lookup(net, family);
96518518
PM
76 if (afi != NULL)
77 return afi;
78#ifdef CONFIG_MODULES
79 if (autoload) {
80 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
81 request_module("nft-afinfo-%u", family);
82 nfnl_lock(NFNL_SUBSYS_NFTABLES);
99633ab2 83 afi = nft_afinfo_lookup(net, family);
96518518
PM
84 if (afi != NULL)
85 return ERR_PTR(-EAGAIN);
86 }
87#endif
88 return ERR_PTR(-EAFNOSUPPORT);
89}
90
91/*
92 * Tables
93 */
94
95static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
96 const struct nlattr *nla)
97{
98 struct nft_table *table;
99
100 list_for_each_entry(table, &afi->tables, list) {
101 if (!nla_strcmp(nla, table->name))
102 return table;
103 }
104 return NULL;
105}
106
107static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
9370761c 108 const struct nlattr *nla)
96518518
PM
109{
110 struct nft_table *table;
111
112 if (nla == NULL)
113 return ERR_PTR(-EINVAL);
114
115 table = nft_table_lookup(afi, nla);
116 if (table != NULL)
117 return table;
118
96518518
PM
119 return ERR_PTR(-ENOENT);
120}
121
122static inline u64 nf_tables_alloc_handle(struct nft_table *table)
123{
124 return ++table->hgenerator;
125}
126
9370761c
PNA
127static struct nf_chain_type *chain_type[AF_MAX][NFT_CHAIN_T_MAX];
128
129static int __nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
130{
131 int i;
132
133 for (i=0; i<NFT_CHAIN_T_MAX; i++) {
134 if (chain_type[family][i] != NULL &&
135 !nla_strcmp(nla, chain_type[family][i]->name))
136 return i;
137 }
138 return -1;
139}
140
141static int nf_tables_chain_type_lookup(const struct nft_af_info *afi,
142 const struct nlattr *nla,
143 bool autoload)
144{
145 int type;
146
147 type = __nf_tables_chain_type_lookup(afi->family, nla);
148#ifdef CONFIG_MODULES
149 if (type < 0 && autoload) {
150 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
151 request_module("nft-chain-%u-%*.s", afi->family,
152 nla_len(nla)-1, (const char *)nla_data(nla));
153 nfnl_lock(NFNL_SUBSYS_NFTABLES);
154 type = __nf_tables_chain_type_lookup(afi->family, nla);
155 }
156#endif
157 return type;
158}
159
96518518
PM
160static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
161 [NFTA_TABLE_NAME] = { .type = NLA_STRING },
9ddf6323 162 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
96518518
PM
163};
164
165static int nf_tables_fill_table_info(struct sk_buff *skb, u32 portid, u32 seq,
166 int event, u32 flags, int family,
167 const struct nft_table *table)
168{
169 struct nlmsghdr *nlh;
170 struct nfgenmsg *nfmsg;
171
172 event |= NFNL_SUBSYS_NFTABLES << 8;
173 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
174 if (nlh == NULL)
175 goto nla_put_failure;
176
177 nfmsg = nlmsg_data(nlh);
178 nfmsg->nfgen_family = family;
179 nfmsg->version = NFNETLINK_V0;
180 nfmsg->res_id = 0;
181
9ddf6323
PNA
182 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
183 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)))
96518518
PM
184 goto nla_put_failure;
185
186 return nlmsg_end(skb, nlh);
187
188nla_put_failure:
189 nlmsg_trim(skb, nlh);
190 return -1;
191}
192
193static int nf_tables_table_notify(const struct sk_buff *oskb,
194 const struct nlmsghdr *nlh,
195 const struct nft_table *table,
196 int event, int family)
197{
198 struct sk_buff *skb;
199 u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
200 u32 seq = nlh ? nlh->nlmsg_seq : 0;
201 struct net *net = oskb ? sock_net(oskb->sk) : &init_net;
202 bool report;
203 int err;
204
205 report = nlh ? nlmsg_report(nlh) : false;
206 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
207 return 0;
208
209 err = -ENOBUFS;
210 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
211 if (skb == NULL)
212 goto err;
213
214 err = nf_tables_fill_table_info(skb, portid, seq, event, 0,
215 family, table);
216 if (err < 0) {
217 kfree_skb(skb);
218 goto err;
219 }
220
221 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
222 GFP_KERNEL);
223err:
224 if (err < 0)
225 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
226 return err;
227}
228
229static int nf_tables_dump_tables(struct sk_buff *skb,
230 struct netlink_callback *cb)
231{
232 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
233 const struct nft_af_info *afi;
234 const struct nft_table *table;
235 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 236 struct net *net = sock_net(skb->sk);
96518518
PM
237 int family = nfmsg->nfgen_family;
238
99633ab2 239 list_for_each_entry(afi, &net->nft.af_info, list) {
96518518
PM
240 if (family != NFPROTO_UNSPEC && family != afi->family)
241 continue;
242
243 list_for_each_entry(table, &afi->tables, list) {
244 if (idx < s_idx)
245 goto cont;
246 if (idx > s_idx)
247 memset(&cb->args[1], 0,
248 sizeof(cb->args) - sizeof(cb->args[0]));
249 if (nf_tables_fill_table_info(skb,
250 NETLINK_CB(cb->skb).portid,
251 cb->nlh->nlmsg_seq,
252 NFT_MSG_NEWTABLE,
253 NLM_F_MULTI,
254 afi->family, table) < 0)
255 goto done;
256cont:
257 idx++;
258 }
259 }
260done:
261 cb->args[0] = idx;
262 return skb->len;
263}
264
265static int nf_tables_gettable(struct sock *nlsk, struct sk_buff *skb,
266 const struct nlmsghdr *nlh,
267 const struct nlattr * const nla[])
268{
269 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
270 const struct nft_af_info *afi;
271 const struct nft_table *table;
272 struct sk_buff *skb2;
99633ab2 273 struct net *net = sock_net(skb->sk);
96518518
PM
274 int family = nfmsg->nfgen_family;
275 int err;
276
277 if (nlh->nlmsg_flags & NLM_F_DUMP) {
278 struct netlink_dump_control c = {
279 .dump = nf_tables_dump_tables,
280 };
281 return netlink_dump_start(nlsk, skb, nlh, &c);
282 }
283
99633ab2 284 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
285 if (IS_ERR(afi))
286 return PTR_ERR(afi);
287
9370761c 288 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]);
96518518
PM
289 if (IS_ERR(table))
290 return PTR_ERR(table);
291
292 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
293 if (!skb2)
294 return -ENOMEM;
295
296 err = nf_tables_fill_table_info(skb2, NETLINK_CB(skb).portid,
297 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
298 family, table);
299 if (err < 0)
300 goto err;
301
302 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
303
304err:
305 kfree_skb(skb2);
306 return err;
307}
308
9ddf6323
PNA
309static int nf_tables_table_enable(struct nft_table *table)
310{
311 struct nft_chain *chain;
312 int err, i = 0;
313
314 list_for_each_entry(chain, &table->chains, list) {
315 err = nf_register_hook(&nft_base_chain(chain)->ops);
316 if (err < 0)
317 goto err;
318
319 i++;
320 }
321 return 0;
322err:
323 list_for_each_entry(chain, &table->chains, list) {
324 if (i-- <= 0)
325 break;
326
327 nf_unregister_hook(&nft_base_chain(chain)->ops);
328 }
329 return err;
330}
331
332static int nf_tables_table_disable(struct nft_table *table)
333{
334 struct nft_chain *chain;
335
336 list_for_each_entry(chain, &table->chains, list)
337 nf_unregister_hook(&nft_base_chain(chain)->ops);
338
339 return 0;
340}
341
342static int nf_tables_updtable(struct sock *nlsk, struct sk_buff *skb,
343 const struct nlmsghdr *nlh,
344 const struct nlattr * const nla[],
345 struct nft_af_info *afi, struct nft_table *table)
346{
347 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
348 int family = nfmsg->nfgen_family, ret = 0;
349
350 if (nla[NFTA_TABLE_FLAGS]) {
351 __be32 flags;
352
353 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
354 if (flags & ~NFT_TABLE_F_DORMANT)
355 return -EINVAL;
356
357 if ((flags & NFT_TABLE_F_DORMANT) &&
358 !(table->flags & NFT_TABLE_F_DORMANT)) {
359 ret = nf_tables_table_disable(table);
360 if (ret >= 0)
361 table->flags |= NFT_TABLE_F_DORMANT;
362 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
363 table->flags & NFT_TABLE_F_DORMANT) {
364 ret = nf_tables_table_enable(table);
365 if (ret >= 0)
366 table->flags &= ~NFT_TABLE_F_DORMANT;
367 }
368 if (ret < 0)
369 goto err;
370 }
371
372 nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
373err:
374 return ret;
375}
376
96518518
PM
377static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
378 const struct nlmsghdr *nlh,
379 const struct nlattr * const nla[])
380{
381 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
382 const struct nlattr *name;
383 struct nft_af_info *afi;
384 struct nft_table *table;
99633ab2 385 struct net *net = sock_net(skb->sk);
96518518
PM
386 int family = nfmsg->nfgen_family;
387
99633ab2 388 afi = nf_tables_afinfo_lookup(net, family, true);
96518518
PM
389 if (IS_ERR(afi))
390 return PTR_ERR(afi);
391
392 name = nla[NFTA_TABLE_NAME];
9370761c 393 table = nf_tables_table_lookup(afi, name);
96518518
PM
394 if (IS_ERR(table)) {
395 if (PTR_ERR(table) != -ENOENT)
396 return PTR_ERR(table);
397 table = NULL;
398 }
399
400 if (table != NULL) {
401 if (nlh->nlmsg_flags & NLM_F_EXCL)
402 return -EEXIST;
403 if (nlh->nlmsg_flags & NLM_F_REPLACE)
404 return -EOPNOTSUPP;
9ddf6323 405 return nf_tables_updtable(nlsk, skb, nlh, nla, afi, table);
96518518
PM
406 }
407
408 table = kzalloc(sizeof(*table) + nla_len(name), GFP_KERNEL);
409 if (table == NULL)
410 return -ENOMEM;
411
412 nla_strlcpy(table->name, name, nla_len(name));
413 INIT_LIST_HEAD(&table->chains);
20a69341 414 INIT_LIST_HEAD(&table->sets);
96518518 415
9ddf6323
PNA
416 if (nla[NFTA_TABLE_FLAGS]) {
417 __be32 flags;
418
419 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
420 if (flags & ~NFT_TABLE_F_DORMANT) {
421 kfree(table);
422 return -EINVAL;
423 }
424
425 table->flags |= flags;
426 }
427
96518518
PM
428 list_add_tail(&table->list, &afi->tables);
429 nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
430 return 0;
431}
432
433static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
434 const struct nlmsghdr *nlh,
435 const struct nlattr * const nla[])
436{
437 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
438 struct nft_af_info *afi;
439 struct nft_table *table;
99633ab2 440 struct net *net = sock_net(skb->sk);
96518518
PM
441 int family = nfmsg->nfgen_family;
442
99633ab2 443 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
444 if (IS_ERR(afi))
445 return PTR_ERR(afi);
446
9370761c 447 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]);
96518518
PM
448 if (IS_ERR(table))
449 return PTR_ERR(table);
450
96518518
PM
451 if (table->use)
452 return -EBUSY;
453
454 list_del(&table->list);
455 nf_tables_table_notify(skb, nlh, table, NFT_MSG_DELTABLE, family);
456 kfree(table);
457 return 0;
458}
459
9370761c 460int nft_register_chain_type(struct nf_chain_type *ctype)
96518518 461{
9370761c 462 int err = 0;
96518518
PM
463
464 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c
PNA
465 if (chain_type[ctype->family][ctype->type] != NULL) {
466 err = -EBUSY;
467 goto out;
96518518
PM
468 }
469
9370761c
PNA
470 if (!try_module_get(ctype->me))
471 goto out;
96518518 472
9370761c
PNA
473 chain_type[ctype->family][ctype->type] = ctype;
474out:
96518518
PM
475 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
476 return err;
477}
9370761c 478EXPORT_SYMBOL_GPL(nft_register_chain_type);
96518518 479
9370761c 480void nft_unregister_chain_type(struct nf_chain_type *ctype)
96518518 481{
96518518 482 nfnl_lock(NFNL_SUBSYS_NFTABLES);
9370761c
PNA
483 chain_type[ctype->family][ctype->type] = NULL;
484 module_put(ctype->me);
96518518
PM
485 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
486}
9370761c 487EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
96518518
PM
488
489/*
490 * Chains
491 */
492
493static struct nft_chain *
494nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle)
495{
496 struct nft_chain *chain;
497
498 list_for_each_entry(chain, &table->chains, list) {
499 if (chain->handle == handle)
500 return chain;
501 }
502
503 return ERR_PTR(-ENOENT);
504}
505
506static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
507 const struct nlattr *nla)
508{
509 struct nft_chain *chain;
510
511 if (nla == NULL)
512 return ERR_PTR(-EINVAL);
513
514 list_for_each_entry(chain, &table->chains, list) {
515 if (!nla_strcmp(nla, chain->name))
516 return chain;
517 }
518
519 return ERR_PTR(-ENOENT);
520}
521
522static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
523 [NFTA_CHAIN_TABLE] = { .type = NLA_STRING },
524 [NFTA_CHAIN_HANDLE] = { .type = NLA_U64 },
525 [NFTA_CHAIN_NAME] = { .type = NLA_STRING,
526 .len = NFT_CHAIN_MAXNAMELEN - 1 },
527 [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED },
0ca743a5 528 [NFTA_CHAIN_POLICY] = { .type = NLA_U32 },
9370761c 529 [NFTA_CHAIN_TYPE] = { .type = NLA_NUL_STRING },
0ca743a5 530 [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED },
96518518
PM
531};
532
533static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
534 [NFTA_HOOK_HOOKNUM] = { .type = NLA_U32 },
535 [NFTA_HOOK_PRIORITY] = { .type = NLA_U32 },
536};
537
0ca743a5
PNA
538static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
539{
540 struct nft_stats *cpu_stats, total;
541 struct nlattr *nest;
542 int cpu;
543
544 memset(&total, 0, sizeof(total));
545 for_each_possible_cpu(cpu) {
546 cpu_stats = per_cpu_ptr(stats, cpu);
547 total.pkts += cpu_stats->pkts;
548 total.bytes += cpu_stats->bytes;
549 }
550 nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS);
551 if (nest == NULL)
552 goto nla_put_failure;
553
554 if (nla_put_be64(skb, NFTA_COUNTER_PACKETS, cpu_to_be64(total.pkts)) ||
555 nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes)))
556 goto nla_put_failure;
557
558 nla_nest_end(skb, nest);
559 return 0;
560
561nla_put_failure:
562 return -ENOSPC;
563}
564
96518518
PM
565static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq,
566 int event, u32 flags, int family,
567 const struct nft_table *table,
568 const struct nft_chain *chain)
569{
570 struct nlmsghdr *nlh;
571 struct nfgenmsg *nfmsg;
572
573 event |= NFNL_SUBSYS_NFTABLES << 8;
574 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
575 if (nlh == NULL)
576 goto nla_put_failure;
577
578 nfmsg = nlmsg_data(nlh);
579 nfmsg->nfgen_family = family;
580 nfmsg->version = NFNETLINK_V0;
581 nfmsg->res_id = 0;
582
583 if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
584 goto nla_put_failure;
585 if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle)))
586 goto nla_put_failure;
587 if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
588 goto nla_put_failure;
589
590 if (chain->flags & NFT_BASE_CHAIN) {
0ca743a5
PNA
591 const struct nft_base_chain *basechain = nft_base_chain(chain);
592 const struct nf_hook_ops *ops = &basechain->ops;
593 struct nlattr *nest;
594
595 nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
96518518
PM
596 if (nest == NULL)
597 goto nla_put_failure;
598 if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum)))
599 goto nla_put_failure;
600 if (nla_put_be32(skb, NFTA_HOOK_PRIORITY, htonl(ops->priority)))
601 goto nla_put_failure;
602 nla_nest_end(skb, nest);
9370761c 603
0ca743a5
PNA
604 if (nla_put_be32(skb, NFTA_CHAIN_POLICY,
605 htonl(basechain->policy)))
606 goto nla_put_failure;
607
9370761c
PNA
608 if (nla_put_string(skb, NFTA_CHAIN_TYPE,
609 chain_type[ops->pf][nft_base_chain(chain)->type]->name))
610 goto nla_put_failure;
0ca743a5
PNA
611
612 if (nft_dump_stats(skb, nft_base_chain(chain)->stats))
613 goto nla_put_failure;
96518518
PM
614 }
615
0ca743a5
PNA
616 if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
617 goto nla_put_failure;
618
96518518
PM
619 return nlmsg_end(skb, nlh);
620
621nla_put_failure:
622 nlmsg_trim(skb, nlh);
623 return -1;
624}
625
626static int nf_tables_chain_notify(const struct sk_buff *oskb,
627 const struct nlmsghdr *nlh,
628 const struct nft_table *table,
629 const struct nft_chain *chain,
630 int event, int family)
631{
632 struct sk_buff *skb;
633 u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
634 struct net *net = oskb ? sock_net(oskb->sk) : &init_net;
635 u32 seq = nlh ? nlh->nlmsg_seq : 0;
636 bool report;
637 int err;
638
639 report = nlh ? nlmsg_report(nlh) : false;
640 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
641 return 0;
642
643 err = -ENOBUFS;
644 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
645 if (skb == NULL)
646 goto err;
647
648 err = nf_tables_fill_chain_info(skb, portid, seq, event, 0, family,
649 table, chain);
650 if (err < 0) {
651 kfree_skb(skb);
652 goto err;
653 }
654
655 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
656 GFP_KERNEL);
657err:
658 if (err < 0)
659 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
660 return err;
661}
662
663static int nf_tables_dump_chains(struct sk_buff *skb,
664 struct netlink_callback *cb)
665{
666 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
667 const struct nft_af_info *afi;
668 const struct nft_table *table;
669 const struct nft_chain *chain;
670 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 671 struct net *net = sock_net(skb->sk);
96518518
PM
672 int family = nfmsg->nfgen_family;
673
99633ab2 674 list_for_each_entry(afi, &net->nft.af_info, list) {
96518518
PM
675 if (family != NFPROTO_UNSPEC && family != afi->family)
676 continue;
677
678 list_for_each_entry(table, &afi->tables, list) {
679 list_for_each_entry(chain, &table->chains, list) {
680 if (idx < s_idx)
681 goto cont;
682 if (idx > s_idx)
683 memset(&cb->args[1], 0,
684 sizeof(cb->args) - sizeof(cb->args[0]));
685 if (nf_tables_fill_chain_info(skb, NETLINK_CB(cb->skb).portid,
686 cb->nlh->nlmsg_seq,
687 NFT_MSG_NEWCHAIN,
688 NLM_F_MULTI,
689 afi->family, table, chain) < 0)
690 goto done;
691cont:
692 idx++;
693 }
694 }
695 }
696done:
697 cb->args[0] = idx;
698 return skb->len;
699}
700
701
702static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb,
703 const struct nlmsghdr *nlh,
704 const struct nlattr * const nla[])
705{
706 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
707 const struct nft_af_info *afi;
708 const struct nft_table *table;
709 const struct nft_chain *chain;
710 struct sk_buff *skb2;
99633ab2 711 struct net *net = sock_net(skb->sk);
96518518
PM
712 int family = nfmsg->nfgen_family;
713 int err;
714
715 if (nlh->nlmsg_flags & NLM_F_DUMP) {
716 struct netlink_dump_control c = {
717 .dump = nf_tables_dump_chains,
718 };
719 return netlink_dump_start(nlsk, skb, nlh, &c);
720 }
721
99633ab2 722 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
723 if (IS_ERR(afi))
724 return PTR_ERR(afi);
725
9370761c 726 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
96518518
PM
727 if (IS_ERR(table))
728 return PTR_ERR(table);
729
730 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
731 if (IS_ERR(chain))
732 return PTR_ERR(chain);
733
734 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
735 if (!skb2)
736 return -ENOMEM;
737
738 err = nf_tables_fill_chain_info(skb2, NETLINK_CB(skb).portid,
739 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
740 family, table, chain);
741 if (err < 0)
742 goto err;
743
744 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
745
746err:
747 kfree_skb(skb2);
748 return err;
749}
750
0ca743a5
PNA
751static int
752nf_tables_chain_policy(struct nft_base_chain *chain, const struct nlattr *attr)
753{
754 switch (ntohl(nla_get_be32(attr))) {
755 case NF_DROP:
756 chain->policy = NF_DROP;
757 break;
758 case NF_ACCEPT:
759 chain->policy = NF_ACCEPT;
760 break;
761 default:
762 return -EINVAL;
763 }
764 return 0;
765}
766
767static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
768 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
769 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
770};
771
772static int
773nf_tables_counters(struct nft_base_chain *chain, const struct nlattr *attr)
774{
775 struct nlattr *tb[NFTA_COUNTER_MAX+1];
776 struct nft_stats __percpu *newstats;
777 struct nft_stats *stats;
778 int err;
779
780 err = nla_parse_nested(tb, NFTA_COUNTER_MAX, attr, nft_counter_policy);
781 if (err < 0)
782 return err;
783
784 if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
785 return -EINVAL;
786
787 newstats = alloc_percpu(struct nft_stats);
788 if (newstats == NULL)
789 return -ENOMEM;
790
791 /* Restore old counters on this cpu, no problem. Per-cpu statistics
792 * are not exposed to userspace.
793 */
794 stats = this_cpu_ptr(newstats);
795 stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
796 stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
797
798 if (chain->stats) {
799 /* nfnl_lock is held, add some nfnl function for this, later */
800 struct nft_stats __percpu *oldstats =
801 rcu_dereference_protected(chain->stats, 1);
802
803 rcu_assign_pointer(chain->stats, newstats);
804 synchronize_rcu();
805 free_percpu(oldstats);
806 } else
807 rcu_assign_pointer(chain->stats, newstats);
808
809 return 0;
810}
811
96518518
PM
812static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
813 const struct nlmsghdr *nlh,
814 const struct nlattr * const nla[])
815{
816 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
817 const struct nlattr * uninitialized_var(name);
818 const struct nft_af_info *afi;
819 struct nft_table *table;
820 struct nft_chain *chain;
0ca743a5 821 struct nft_base_chain *basechain = NULL;
96518518 822 struct nlattr *ha[NFTA_HOOK_MAX + 1];
99633ab2 823 struct net *net = sock_net(skb->sk);
96518518
PM
824 int family = nfmsg->nfgen_family;
825 u64 handle = 0;
826 int err;
827 bool create;
828
829 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
830
99633ab2 831 afi = nf_tables_afinfo_lookup(net, family, true);
96518518
PM
832 if (IS_ERR(afi))
833 return PTR_ERR(afi);
834
9370761c 835 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
96518518
PM
836 if (IS_ERR(table))
837 return PTR_ERR(table);
838
839 if (table->use == UINT_MAX)
840 return -EOVERFLOW;
841
842 chain = NULL;
843 name = nla[NFTA_CHAIN_NAME];
844
845 if (nla[NFTA_CHAIN_HANDLE]) {
846 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
847 chain = nf_tables_chain_lookup_byhandle(table, handle);
848 if (IS_ERR(chain))
849 return PTR_ERR(chain);
850 } else {
851 chain = nf_tables_chain_lookup(table, name);
852 if (IS_ERR(chain)) {
853 if (PTR_ERR(chain) != -ENOENT)
854 return PTR_ERR(chain);
855 chain = NULL;
856 }
857 }
858
859 if (chain != NULL) {
860 if (nlh->nlmsg_flags & NLM_F_EXCL)
861 return -EEXIST;
862 if (nlh->nlmsg_flags & NLM_F_REPLACE)
863 return -EOPNOTSUPP;
864
865 if (nla[NFTA_CHAIN_HANDLE] && name &&
866 !IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME])))
867 return -EEXIST;
868
0ca743a5
PNA
869 if (nla[NFTA_CHAIN_POLICY]) {
870 if (!(chain->flags & NFT_BASE_CHAIN))
871 return -EOPNOTSUPP;
872
873 err = nf_tables_chain_policy(nft_base_chain(chain),
874 nla[NFTA_CHAIN_POLICY]);
875 if (err < 0)
876 return err;
877 }
878
879 if (nla[NFTA_CHAIN_COUNTERS]) {
880 if (!(chain->flags & NFT_BASE_CHAIN))
881 return -EOPNOTSUPP;
882
883 err = nf_tables_counters(nft_base_chain(chain),
884 nla[NFTA_CHAIN_COUNTERS]);
885 if (err < 0)
886 return err;
887 }
888
96518518
PM
889 if (nla[NFTA_CHAIN_HANDLE] && name)
890 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
891
892 goto notify;
893 }
894
895 if (nla[NFTA_CHAIN_HOOK]) {
896 struct nf_hook_ops *ops;
9370761c
PNA
897 nf_hookfn *hookfn;
898 u32 hooknum;
899 int type = NFT_CHAIN_T_DEFAULT;
900
901 if (nla[NFTA_CHAIN_TYPE]) {
902 type = nf_tables_chain_type_lookup(afi,
903 nla[NFTA_CHAIN_TYPE],
904 create);
905 if (type < 0)
906 return -ENOENT;
907 }
96518518
PM
908
909 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
910 nft_hook_policy);
911 if (err < 0)
912 return err;
913 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
914 ha[NFTA_HOOK_PRIORITY] == NULL)
915 return -EINVAL;
9370761c
PNA
916
917 hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
918 if (hooknum >= afi->nhooks)
96518518
PM
919 return -EINVAL;
920
9370761c
PNA
921 hookfn = chain_type[family][type]->fn[hooknum];
922 if (hookfn == NULL)
923 return -EOPNOTSUPP;
924
96518518
PM
925 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
926 if (basechain == NULL)
927 return -ENOMEM;
9370761c
PNA
928
929 basechain->type = type;
96518518
PM
930 chain = &basechain->chain;
931
932 ops = &basechain->ops;
933 ops->pf = family;
934 ops->owner = afi->owner;
935 ops->hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
936 ops->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
937 ops->priv = chain;
9370761c 938 ops->hook = hookfn;
96518518
PM
939 if (afi->hooks[ops->hooknum])
940 ops->hook = afi->hooks[ops->hooknum];
941
942 chain->flags |= NFT_BASE_CHAIN;
0ca743a5
PNA
943
944 if (nla[NFTA_CHAIN_POLICY]) {
945 err = nf_tables_chain_policy(basechain,
946 nla[NFTA_CHAIN_POLICY]);
947 if (err < 0) {
948 free_percpu(basechain->stats);
949 kfree(basechain);
950 return err;
951 }
952 } else
953 basechain->policy = NF_ACCEPT;
954
955 if (nla[NFTA_CHAIN_COUNTERS]) {
956 err = nf_tables_counters(basechain,
957 nla[NFTA_CHAIN_COUNTERS]);
958 if (err < 0) {
959 free_percpu(basechain->stats);
960 kfree(basechain);
961 return err;
962 }
963 } else {
964 struct nft_stats __percpu *newstats;
965
966 newstats = alloc_percpu(struct nft_stats);
967 if (newstats == NULL)
968 return -ENOMEM;
969
970 rcu_assign_pointer(nft_base_chain(chain)->stats,
971 newstats);
972 }
96518518
PM
973 } else {
974 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
975 if (chain == NULL)
976 return -ENOMEM;
977 }
978
979 INIT_LIST_HEAD(&chain->rules);
980 chain->handle = nf_tables_alloc_handle(table);
981 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
982
9ddf6323
PNA
983 if (!(table->flags & NFT_TABLE_F_DORMANT) &&
984 chain->flags & NFT_BASE_CHAIN) {
0ca743a5
PNA
985 err = nf_register_hook(&nft_base_chain(chain)->ops);
986 if (err < 0) {
987 free_percpu(basechain->stats);
988 kfree(basechain);
989 return err;
990 }
991 }
9ddf6323
PNA
992 list_add_tail(&chain->list, &table->chains);
993 table->use++;
96518518
PM
994notify:
995 nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_NEWCHAIN,
996 family);
997 return 0;
998}
999
1000static void nf_tables_rcu_chain_destroy(struct rcu_head *head)
1001{
1002 struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
1003
1004 BUG_ON(chain->use > 0);
1005
0ca743a5
PNA
1006 if (chain->flags & NFT_BASE_CHAIN) {
1007 free_percpu(nft_base_chain(chain)->stats);
96518518 1008 kfree(nft_base_chain(chain));
0ca743a5 1009 } else
96518518
PM
1010 kfree(chain);
1011}
1012
1013static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
1014 const struct nlmsghdr *nlh,
1015 const struct nlattr * const nla[])
1016{
1017 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1018 const struct nft_af_info *afi;
1019 struct nft_table *table;
1020 struct nft_chain *chain;
99633ab2 1021 struct net *net = sock_net(skb->sk);
96518518
PM
1022 int family = nfmsg->nfgen_family;
1023
99633ab2 1024 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
1025 if (IS_ERR(afi))
1026 return PTR_ERR(afi);
1027
9370761c 1028 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
96518518
PM
1029 if (IS_ERR(table))
1030 return PTR_ERR(table);
1031
1032 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
1033 if (IS_ERR(chain))
1034 return PTR_ERR(chain);
1035
96518518
PM
1036 if (!list_empty(&chain->rules))
1037 return -EBUSY;
1038
1039 list_del(&chain->list);
1040 table->use--;
1041
9ddf6323
PNA
1042 if (!(table->flags & NFT_TABLE_F_DORMANT) &&
1043 chain->flags & NFT_BASE_CHAIN)
96518518
PM
1044 nf_unregister_hook(&nft_base_chain(chain)->ops);
1045
1046 nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_DELCHAIN,
1047 family);
1048
1049 /* Make sure all rule references are gone before this is released */
1050 call_rcu(&chain->rcu_head, nf_tables_rcu_chain_destroy);
1051 return 0;
1052}
1053
1054static void nft_ctx_init(struct nft_ctx *ctx,
20a69341
PM
1055 const struct sk_buff *skb,
1056 const struct nlmsghdr *nlh,
96518518
PM
1057 const struct nft_af_info *afi,
1058 const struct nft_table *table,
0ca743a5
PNA
1059 const struct nft_chain *chain,
1060 const struct nlattr * const *nla)
96518518 1061{
99633ab2 1062 ctx->net = sock_net(skb->sk);
20a69341
PM
1063 ctx->skb = skb;
1064 ctx->nlh = nlh;
96518518
PM
1065 ctx->afi = afi;
1066 ctx->table = table;
1067 ctx->chain = chain;
0ca743a5 1068 ctx->nla = nla;
96518518
PM
1069}
1070
1071/*
1072 * Expressions
1073 */
1074
1075/**
ef1f7df9
PM
1076 * nft_register_expr - register nf_tables expr type
1077 * @ops: expr type
96518518 1078 *
ef1f7df9 1079 * Registers the expr type for use with nf_tables. Returns zero on
96518518
PM
1080 * success or a negative errno code otherwise.
1081 */
ef1f7df9 1082int nft_register_expr(struct nft_expr_type *type)
96518518
PM
1083{
1084 nfnl_lock(NFNL_SUBSYS_NFTABLES);
ef1f7df9 1085 list_add_tail(&type->list, &nf_tables_expressions);
96518518
PM
1086 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1087 return 0;
1088}
1089EXPORT_SYMBOL_GPL(nft_register_expr);
1090
1091/**
ef1f7df9
PM
1092 * nft_unregister_expr - unregister nf_tables expr type
1093 * @ops: expr type
96518518 1094 *
ef1f7df9 1095 * Unregisters the expr typefor use with nf_tables.
96518518 1096 */
ef1f7df9 1097void nft_unregister_expr(struct nft_expr_type *type)
96518518
PM
1098{
1099 nfnl_lock(NFNL_SUBSYS_NFTABLES);
ef1f7df9 1100 list_del(&type->list);
96518518
PM
1101 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1102}
1103EXPORT_SYMBOL_GPL(nft_unregister_expr);
1104
ef1f7df9 1105static const struct nft_expr_type *__nft_expr_type_get(struct nlattr *nla)
96518518 1106{
ef1f7df9 1107 const struct nft_expr_type *type;
96518518 1108
ef1f7df9
PM
1109 list_for_each_entry(type, &nf_tables_expressions, list) {
1110 if (!nla_strcmp(nla, type->name))
1111 return type;
96518518
PM
1112 }
1113 return NULL;
1114}
1115
ef1f7df9 1116static const struct nft_expr_type *nft_expr_type_get(struct nlattr *nla)
96518518 1117{
ef1f7df9 1118 const struct nft_expr_type *type;
96518518
PM
1119
1120 if (nla == NULL)
1121 return ERR_PTR(-EINVAL);
1122
ef1f7df9
PM
1123 type = __nft_expr_type_get(nla);
1124 if (type != NULL && try_module_get(type->owner))
1125 return type;
96518518
PM
1126
1127#ifdef CONFIG_MODULES
ef1f7df9 1128 if (type == NULL) {
96518518
PM
1129 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1130 request_module("nft-expr-%.*s",
1131 nla_len(nla), (char *)nla_data(nla));
1132 nfnl_lock(NFNL_SUBSYS_NFTABLES);
ef1f7df9 1133 if (__nft_expr_type_get(nla))
96518518
PM
1134 return ERR_PTR(-EAGAIN);
1135 }
1136#endif
1137 return ERR_PTR(-ENOENT);
1138}
1139
1140static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
1141 [NFTA_EXPR_NAME] = { .type = NLA_STRING },
1142 [NFTA_EXPR_DATA] = { .type = NLA_NESTED },
1143};
1144
1145static int nf_tables_fill_expr_info(struct sk_buff *skb,
1146 const struct nft_expr *expr)
1147{
ef1f7df9 1148 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
96518518
PM
1149 goto nla_put_failure;
1150
1151 if (expr->ops->dump) {
1152 struct nlattr *data = nla_nest_start(skb, NFTA_EXPR_DATA);
1153 if (data == NULL)
1154 goto nla_put_failure;
1155 if (expr->ops->dump(skb, expr) < 0)
1156 goto nla_put_failure;
1157 nla_nest_end(skb, data);
1158 }
1159
1160 return skb->len;
1161
1162nla_put_failure:
1163 return -1;
1164};
1165
1166struct nft_expr_info {
1167 const struct nft_expr_ops *ops;
ef1f7df9 1168 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
96518518
PM
1169};
1170
0ca743a5
PNA
1171static int nf_tables_expr_parse(const struct nft_ctx *ctx,
1172 const struct nlattr *nla,
96518518
PM
1173 struct nft_expr_info *info)
1174{
ef1f7df9 1175 const struct nft_expr_type *type;
96518518 1176 const struct nft_expr_ops *ops;
ef1f7df9 1177 struct nlattr *tb[NFTA_EXPR_MAX + 1];
96518518
PM
1178 int err;
1179
ef1f7df9 1180 err = nla_parse_nested(tb, NFTA_EXPR_MAX, nla, nft_expr_policy);
96518518
PM
1181 if (err < 0)
1182 return err;
1183
ef1f7df9
PM
1184 type = nft_expr_type_get(tb[NFTA_EXPR_NAME]);
1185 if (IS_ERR(type))
1186 return PTR_ERR(type);
1187
1188 if (tb[NFTA_EXPR_DATA]) {
1189 err = nla_parse_nested(info->tb, type->maxattr,
1190 tb[NFTA_EXPR_DATA], type->policy);
1191 if (err < 0)
1192 goto err1;
1193 } else
1194 memset(info->tb, 0, sizeof(info->tb[0]) * (type->maxattr + 1));
1195
1196 if (type->select_ops != NULL) {
0ca743a5
PNA
1197 ops = type->select_ops(ctx,
1198 (const struct nlattr * const *)info->tb);
ef1f7df9
PM
1199 if (IS_ERR(ops)) {
1200 err = PTR_ERR(ops);
1201 goto err1;
1202 }
1203 } else
1204 ops = type->ops;
1205
96518518
PM
1206 info->ops = ops;
1207 return 0;
ef1f7df9
PM
1208
1209err1:
1210 module_put(type->owner);
1211 return err;
96518518
PM
1212}
1213
1214static int nf_tables_newexpr(const struct nft_ctx *ctx,
ef1f7df9 1215 const struct nft_expr_info *info,
96518518
PM
1216 struct nft_expr *expr)
1217{
1218 const struct nft_expr_ops *ops = info->ops;
1219 int err;
1220
1221 expr->ops = ops;
1222 if (ops->init) {
ef1f7df9 1223 err = ops->init(ctx, expr, (const struct nlattr **)info->tb);
96518518
PM
1224 if (err < 0)
1225 goto err1;
1226 }
1227
96518518
PM
1228 return 0;
1229
1230err1:
1231 expr->ops = NULL;
1232 return err;
1233}
1234
1235static void nf_tables_expr_destroy(struct nft_expr *expr)
1236{
1237 if (expr->ops->destroy)
1238 expr->ops->destroy(expr);
ef1f7df9 1239 module_put(expr->ops->type->owner);
96518518
PM
1240}
1241
1242/*
1243 * Rules
1244 */
1245
1246static struct nft_rule *__nf_tables_rule_lookup(const struct nft_chain *chain,
1247 u64 handle)
1248{
1249 struct nft_rule *rule;
1250
1251 // FIXME: this sucks
1252 list_for_each_entry(rule, &chain->rules, list) {
1253 if (handle == rule->handle)
1254 return rule;
1255 }
1256
1257 return ERR_PTR(-ENOENT);
1258}
1259
1260static struct nft_rule *nf_tables_rule_lookup(const struct nft_chain *chain,
1261 const struct nlattr *nla)
1262{
1263 if (nla == NULL)
1264 return ERR_PTR(-EINVAL);
1265
1266 return __nf_tables_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
1267}
1268
1269static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
1270 [NFTA_RULE_TABLE] = { .type = NLA_STRING },
1271 [NFTA_RULE_CHAIN] = { .type = NLA_STRING,
1272 .len = NFT_CHAIN_MAXNAMELEN - 1 },
1273 [NFTA_RULE_HANDLE] = { .type = NLA_U64 },
1274 [NFTA_RULE_EXPRESSIONS] = { .type = NLA_NESTED },
0ca743a5 1275 [NFTA_RULE_COMPAT] = { .type = NLA_NESTED },
5e948466 1276 [NFTA_RULE_POSITION] = { .type = NLA_U64 },
96518518
PM
1277};
1278
1279static int nf_tables_fill_rule_info(struct sk_buff *skb, u32 portid, u32 seq,
1280 int event, u32 flags, int family,
1281 const struct nft_table *table,
1282 const struct nft_chain *chain,
1283 const struct nft_rule *rule)
1284{
1285 struct nlmsghdr *nlh;
1286 struct nfgenmsg *nfmsg;
1287 const struct nft_expr *expr, *next;
1288 struct nlattr *list;
5e948466
EL
1289 const struct nft_rule *prule;
1290 int type = event | NFNL_SUBSYS_NFTABLES << 8;
96518518 1291
5e948466 1292 nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg),
96518518
PM
1293 flags);
1294 if (nlh == NULL)
1295 goto nla_put_failure;
1296
1297 nfmsg = nlmsg_data(nlh);
1298 nfmsg->nfgen_family = family;
1299 nfmsg->version = NFNETLINK_V0;
1300 nfmsg->res_id = 0;
1301
1302 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
1303 goto nla_put_failure;
1304 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
1305 goto nla_put_failure;
1306 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle)))
1307 goto nla_put_failure;
1308
5e948466
EL
1309 if ((event != NFT_MSG_DELRULE) && (rule->list.prev != &chain->rules)) {
1310 prule = list_entry(rule->list.prev, struct nft_rule, list);
1311 if (nla_put_be64(skb, NFTA_RULE_POSITION,
1312 cpu_to_be64(prule->handle)))
1313 goto nla_put_failure;
1314 }
1315
96518518
PM
1316 list = nla_nest_start(skb, NFTA_RULE_EXPRESSIONS);
1317 if (list == NULL)
1318 goto nla_put_failure;
1319 nft_rule_for_each_expr(expr, next, rule) {
1320 struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM);
1321 if (elem == NULL)
1322 goto nla_put_failure;
1323 if (nf_tables_fill_expr_info(skb, expr) < 0)
1324 goto nla_put_failure;
1325 nla_nest_end(skb, elem);
1326 }
1327 nla_nest_end(skb, list);
1328
1329 return nlmsg_end(skb, nlh);
1330
1331nla_put_failure:
1332 nlmsg_trim(skb, nlh);
1333 return -1;
1334}
1335
1336static int nf_tables_rule_notify(const struct sk_buff *oskb,
1337 const struct nlmsghdr *nlh,
1338 const struct nft_table *table,
1339 const struct nft_chain *chain,
1340 const struct nft_rule *rule,
1341 int event, u32 flags, int family)
1342{
1343 struct sk_buff *skb;
1344 u32 portid = NETLINK_CB(oskb).portid;
1345 struct net *net = oskb ? sock_net(oskb->sk) : &init_net;
1346 u32 seq = nlh->nlmsg_seq;
1347 bool report;
1348 int err;
1349
1350 report = nlmsg_report(nlh);
1351 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
1352 return 0;
1353
1354 err = -ENOBUFS;
1355 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1356 if (skb == NULL)
1357 goto err;
1358
1359 err = nf_tables_fill_rule_info(skb, portid, seq, event, flags,
1360 family, table, chain, rule);
1361 if (err < 0) {
1362 kfree_skb(skb);
1363 goto err;
1364 }
1365
1366 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
1367 GFP_KERNEL);
1368err:
1369 if (err < 0)
1370 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
1371 return err;
1372}
1373
1374static int nf_tables_dump_rules(struct sk_buff *skb,
1375 struct netlink_callback *cb)
1376{
1377 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1378 const struct nft_af_info *afi;
1379 const struct nft_table *table;
1380 const struct nft_chain *chain;
1381 const struct nft_rule *rule;
1382 unsigned int idx = 0, s_idx = cb->args[0];
99633ab2 1383 struct net *net = sock_net(skb->sk);
96518518
PM
1384 int family = nfmsg->nfgen_family;
1385
99633ab2 1386 list_for_each_entry(afi, &net->nft.af_info, list) {
96518518
PM
1387 if (family != NFPROTO_UNSPEC && family != afi->family)
1388 continue;
1389
1390 list_for_each_entry(table, &afi->tables, list) {
1391 list_for_each_entry(chain, &table->chains, list) {
1392 list_for_each_entry(rule, &chain->rules, list) {
1393 if (idx < s_idx)
1394 goto cont;
1395 if (idx > s_idx)
1396 memset(&cb->args[1], 0,
1397 sizeof(cb->args) - sizeof(cb->args[0]));
1398 if (nf_tables_fill_rule_info(skb, NETLINK_CB(cb->skb).portid,
1399 cb->nlh->nlmsg_seq,
1400 NFT_MSG_NEWRULE,
1401 NLM_F_MULTI | NLM_F_APPEND,
1402 afi->family, table, chain, rule) < 0)
1403 goto done;
1404cont:
1405 idx++;
1406 }
1407 }
1408 }
1409 }
1410done:
1411 cb->args[0] = idx;
1412 return skb->len;
1413}
1414
1415static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb,
1416 const struct nlmsghdr *nlh,
1417 const struct nlattr * const nla[])
1418{
1419 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1420 const struct nft_af_info *afi;
1421 const struct nft_table *table;
1422 const struct nft_chain *chain;
1423 const struct nft_rule *rule;
1424 struct sk_buff *skb2;
99633ab2 1425 struct net *net = sock_net(skb->sk);
96518518
PM
1426 int family = nfmsg->nfgen_family;
1427 int err;
1428
1429 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1430 struct netlink_dump_control c = {
1431 .dump = nf_tables_dump_rules,
1432 };
1433 return netlink_dump_start(nlsk, skb, nlh, &c);
1434 }
1435
99633ab2 1436 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
1437 if (IS_ERR(afi))
1438 return PTR_ERR(afi);
1439
9370761c 1440 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
96518518
PM
1441 if (IS_ERR(table))
1442 return PTR_ERR(table);
1443
1444 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1445 if (IS_ERR(chain))
1446 return PTR_ERR(chain);
1447
1448 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
1449 if (IS_ERR(rule))
1450 return PTR_ERR(rule);
1451
1452 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1453 if (!skb2)
1454 return -ENOMEM;
1455
1456 err = nf_tables_fill_rule_info(skb2, NETLINK_CB(skb).portid,
1457 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
1458 family, table, chain, rule);
1459 if (err < 0)
1460 goto err;
1461
1462 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1463
1464err:
1465 kfree_skb(skb2);
1466 return err;
1467}
1468
1469static void nf_tables_rcu_rule_destroy(struct rcu_head *head)
1470{
1471 struct nft_rule *rule = container_of(head, struct nft_rule, rcu_head);
1472 struct nft_expr *expr;
1473
1474 /*
1475 * Careful: some expressions might not be initialized in case this
1476 * is called on error from nf_tables_newrule().
1477 */
1478 expr = nft_expr_first(rule);
1479 while (expr->ops && expr != nft_expr_last(rule)) {
1480 nf_tables_expr_destroy(expr);
1481 expr = nft_expr_next(expr);
1482 }
1483 kfree(rule);
1484}
1485
1486static void nf_tables_rule_destroy(struct nft_rule *rule)
1487{
1488 call_rcu(&rule->rcu_head, nf_tables_rcu_rule_destroy);
1489}
1490
1491#define NFT_RULE_MAXEXPRS 128
1492
1493static struct nft_expr_info *info;
1494
1495static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1496 const struct nlmsghdr *nlh,
1497 const struct nlattr * const nla[])
1498{
1499 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1500 const struct nft_af_info *afi;
99633ab2 1501 struct net *net = sock_net(skb->sk);
96518518
PM
1502 struct nft_table *table;
1503 struct nft_chain *chain;
1504 struct nft_rule *rule, *old_rule = NULL;
1505 struct nft_expr *expr;
1506 struct nft_ctx ctx;
1507 struct nlattr *tmp;
1508 unsigned int size, i, n;
1509 int err, rem;
1510 bool create;
5e948466 1511 u64 handle, pos_handle;
96518518
PM
1512
1513 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
1514
99633ab2 1515 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
96518518
PM
1516 if (IS_ERR(afi))
1517 return PTR_ERR(afi);
1518
9370761c 1519 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
96518518
PM
1520 if (IS_ERR(table))
1521 return PTR_ERR(table);
1522
1523 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1524 if (IS_ERR(chain))
1525 return PTR_ERR(chain);
1526
1527 if (nla[NFTA_RULE_HANDLE]) {
1528 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
1529 rule = __nf_tables_rule_lookup(chain, handle);
1530 if (IS_ERR(rule))
1531 return PTR_ERR(rule);
1532
1533 if (nlh->nlmsg_flags & NLM_F_EXCL)
1534 return -EEXIST;
1535 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1536 old_rule = rule;
1537 else
1538 return -EOPNOTSUPP;
1539 } else {
1540 if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
1541 return -EINVAL;
1542 handle = nf_tables_alloc_handle(table);
1543 }
1544
5e948466
EL
1545 if (nla[NFTA_RULE_POSITION]) {
1546 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
1547 return -EOPNOTSUPP;
1548
1549 pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
1550 old_rule = __nf_tables_rule_lookup(chain, pos_handle);
1551 if (IS_ERR(old_rule))
1552 return PTR_ERR(old_rule);
1553 }
1554
0ca743a5
PNA
1555 nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
1556
96518518
PM
1557 n = 0;
1558 size = 0;
1559 if (nla[NFTA_RULE_EXPRESSIONS]) {
1560 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
1561 err = -EINVAL;
1562 if (nla_type(tmp) != NFTA_LIST_ELEM)
1563 goto err1;
1564 if (n == NFT_RULE_MAXEXPRS)
1565 goto err1;
0ca743a5 1566 err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
96518518
PM
1567 if (err < 0)
1568 goto err1;
1569 size += info[n].ops->size;
1570 n++;
1571 }
1572 }
1573
1574 err = -ENOMEM;
1575 rule = kzalloc(sizeof(*rule) + size, GFP_KERNEL);
1576 if (rule == NULL)
1577 goto err1;
1578
1579 rule->handle = handle;
1580 rule->dlen = size;
1581
96518518
PM
1582 expr = nft_expr_first(rule);
1583 for (i = 0; i < n; i++) {
1584 err = nf_tables_newexpr(&ctx, &info[i], expr);
1585 if (err < 0)
1586 goto err2;
ef1f7df9 1587 info[i].ops = NULL;
96518518
PM
1588 expr = nft_expr_next(expr);
1589 }
1590
96518518
PM
1591 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
1592 list_replace_rcu(&old_rule->list, &rule->list);
1593 nf_tables_rule_destroy(old_rule);
1594 } else if (nlh->nlmsg_flags & NLM_F_APPEND)
5e948466
EL
1595 if (old_rule)
1596 list_add_rcu(&rule->list, &old_rule->list);
1597 else
1598 list_add_tail_rcu(&rule->list, &chain->rules);
1599 else {
1600 if (old_rule)
1601 list_add_tail_rcu(&rule->list, &old_rule->list);
1602 else
1603 list_add_rcu(&rule->list, &chain->rules);
1604 }
96518518
PM
1605
1606 nf_tables_rule_notify(skb, nlh, table, chain, rule, NFT_MSG_NEWRULE,
1607 nlh->nlmsg_flags & (NLM_F_APPEND | NLM_F_REPLACE),
1608 nfmsg->nfgen_family);
1609 return 0;
1610
1611err2:
1612 nf_tables_rule_destroy(rule);
1613err1:
1614 for (i = 0; i < n; i++) {
1615 if (info[i].ops != NULL)
ef1f7df9 1616 module_put(info[i].ops->type->owner);
96518518
PM
1617 }
1618 return err;
1619}
1620
1621static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
1622 const struct nlmsghdr *nlh,
1623 const struct nlattr * const nla[])
1624{
1625 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1626 const struct nft_af_info *afi;
99633ab2 1627 struct net *net = sock_net(skb->sk);
96518518
PM
1628 const struct nft_table *table;
1629 struct nft_chain *chain;
1630 struct nft_rule *rule, *tmp;
1631 int family = nfmsg->nfgen_family;
1632
99633ab2 1633 afi = nf_tables_afinfo_lookup(net, family, false);
96518518
PM
1634 if (IS_ERR(afi))
1635 return PTR_ERR(afi);
1636
9370761c 1637 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
96518518
PM
1638 if (IS_ERR(table))
1639 return PTR_ERR(table);
1640
1641 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1642 if (IS_ERR(chain))
1643 return PTR_ERR(chain);
1644
1645 if (nla[NFTA_RULE_HANDLE]) {
1646 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
1647 if (IS_ERR(rule))
1648 return PTR_ERR(rule);
1649
1650 /* List removal must be visible before destroying expressions */
1651 list_del_rcu(&rule->list);
1652
1653 nf_tables_rule_notify(skb, nlh, table, chain, rule,
1654 NFT_MSG_DELRULE, 0, family);
1655 nf_tables_rule_destroy(rule);
1656 } else {
1657 /* Remove all rules in this chain */
1658 list_for_each_entry_safe(rule, tmp, &chain->rules, list) {
1659 list_del_rcu(&rule->list);
1660
1661 nf_tables_rule_notify(skb, nlh, table, chain, rule,
1662 NFT_MSG_DELRULE, 0, family);
1663 nf_tables_rule_destroy(rule);
1664 }
1665 }
1666
96518518
PM
1667 return 0;
1668}
1669
20a69341
PM
1670/*
1671 * Sets
1672 */
1673
1674static LIST_HEAD(nf_tables_set_ops);
1675
1676int nft_register_set(struct nft_set_ops *ops)
1677{
1678 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1679 list_add_tail(&ops->list, &nf_tables_set_ops);
1680 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1681 return 0;
1682}
1683EXPORT_SYMBOL_GPL(nft_register_set);
1684
1685void nft_unregister_set(struct nft_set_ops *ops)
1686{
1687 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1688 list_del(&ops->list);
1689 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1690}
1691EXPORT_SYMBOL_GPL(nft_unregister_set);
1692
1693static const struct nft_set_ops *nft_select_set_ops(const struct nlattr * const nla[])
1694{
1695 const struct nft_set_ops *ops;
1696 u32 features;
1697
1698#ifdef CONFIG_MODULES
1699 if (list_empty(&nf_tables_set_ops)) {
1700 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1701 request_module("nft-set");
1702 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1703 if (!list_empty(&nf_tables_set_ops))
1704 return ERR_PTR(-EAGAIN);
1705 }
1706#endif
1707 features = 0;
1708 if (nla[NFTA_SET_FLAGS] != NULL) {
1709 features = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
1710 features &= NFT_SET_INTERVAL | NFT_SET_MAP;
1711 }
1712
1713 // FIXME: implement selection properly
1714 list_for_each_entry(ops, &nf_tables_set_ops, list) {
1715 if ((ops->features & features) != features)
1716 continue;
1717 if (!try_module_get(ops->owner))
1718 continue;
1719 return ops;
1720 }
1721
1722 return ERR_PTR(-EOPNOTSUPP);
1723}
1724
1725static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
1726 [NFTA_SET_TABLE] = { .type = NLA_STRING },
1727 [NFTA_SET_NAME] = { .type = NLA_STRING },
1728 [NFTA_SET_FLAGS] = { .type = NLA_U32 },
1729 [NFTA_SET_KEY_TYPE] = { .type = NLA_U32 },
1730 [NFTA_SET_KEY_LEN] = { .type = NLA_U32 },
1731 [NFTA_SET_DATA_TYPE] = { .type = NLA_U32 },
1732 [NFTA_SET_DATA_LEN] = { .type = NLA_U32 },
1733};
1734
1735static int nft_ctx_init_from_setattr(struct nft_ctx *ctx,
1736 const struct sk_buff *skb,
1737 const struct nlmsghdr *nlh,
1738 const struct nlattr * const nla[])
1739{
99633ab2 1740 struct net *net = sock_net(skb->sk);
20a69341
PM
1741 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1742 const struct nft_af_info *afi;
1743 const struct nft_table *table = NULL;
1744
99633ab2 1745 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
20a69341
PM
1746 if (IS_ERR(afi))
1747 return PTR_ERR(afi);
1748
1749 if (nla[NFTA_SET_TABLE] != NULL) {
9370761c 1750 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
20a69341
PM
1751 if (IS_ERR(table))
1752 return PTR_ERR(table);
1753 }
1754
0ca743a5 1755 nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
20a69341
PM
1756 return 0;
1757}
1758
1759struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
1760 const struct nlattr *nla)
1761{
1762 struct nft_set *set;
1763
1764 if (nla == NULL)
1765 return ERR_PTR(-EINVAL);
1766
1767 list_for_each_entry(set, &table->sets, list) {
1768 if (!nla_strcmp(nla, set->name))
1769 return set;
1770 }
1771 return ERR_PTR(-ENOENT);
1772}
1773
1774static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
1775 const char *name)
1776{
1777 const struct nft_set *i;
1778 const char *p;
1779 unsigned long *inuse;
1780 unsigned int n = 0;
1781
1782 p = strnchr(name, IFNAMSIZ, '%');
1783 if (p != NULL) {
1784 if (p[1] != 'd' || strchr(p + 2, '%'))
1785 return -EINVAL;
1786
1787 inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
1788 if (inuse == NULL)
1789 return -ENOMEM;
1790
1791 list_for_each_entry(i, &ctx->table->sets, list) {
1792 if (!sscanf(i->name, name, &n))
1793 continue;
1794 if (n < 0 || n > BITS_PER_LONG * PAGE_SIZE)
1795 continue;
1796 set_bit(n, inuse);
1797 }
1798
1799 n = find_first_zero_bit(inuse, BITS_PER_LONG * PAGE_SIZE);
1800 free_page((unsigned long)inuse);
1801 }
1802
1803 snprintf(set->name, sizeof(set->name), name, n);
1804 list_for_each_entry(i, &ctx->table->sets, list) {
1805 if (!strcmp(set->name, i->name))
1806 return -ENFILE;
1807 }
1808 return 0;
1809}
1810
1811static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
1812 const struct nft_set *set, u16 event, u16 flags)
1813{
1814 struct nfgenmsg *nfmsg;
1815 struct nlmsghdr *nlh;
1816 u32 portid = NETLINK_CB(ctx->skb).portid;
1817 u32 seq = ctx->nlh->nlmsg_seq;
1818
1819 event |= NFNL_SUBSYS_NFTABLES << 8;
1820 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
1821 flags);
1822 if (nlh == NULL)
1823 goto nla_put_failure;
1824
1825 nfmsg = nlmsg_data(nlh);
1826 nfmsg->nfgen_family = ctx->afi->family;
1827 nfmsg->version = NFNETLINK_V0;
1828 nfmsg->res_id = 0;
1829
1830 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
1831 goto nla_put_failure;
1832 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
1833 goto nla_put_failure;
1834 if (set->flags != 0)
1835 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
1836 goto nla_put_failure;
1837
1838 if (nla_put_be32(skb, NFTA_SET_KEY_TYPE, htonl(set->ktype)))
1839 goto nla_put_failure;
1840 if (nla_put_be32(skb, NFTA_SET_KEY_LEN, htonl(set->klen)))
1841 goto nla_put_failure;
1842 if (set->flags & NFT_SET_MAP) {
1843 if (nla_put_be32(skb, NFTA_SET_DATA_TYPE, htonl(set->dtype)))
1844 goto nla_put_failure;
1845 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
1846 goto nla_put_failure;
1847 }
1848
1849 return nlmsg_end(skb, nlh);
1850
1851nla_put_failure:
1852 nlmsg_trim(skb, nlh);
1853 return -1;
1854}
1855
1856static int nf_tables_set_notify(const struct nft_ctx *ctx,
1857 const struct nft_set *set,
1858 int event)
1859{
1860 struct sk_buff *skb;
1861 u32 portid = NETLINK_CB(ctx->skb).portid;
20a69341
PM
1862 bool report;
1863 int err;
1864
1865 report = nlmsg_report(ctx->nlh);
99633ab2 1866 if (!report && !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
20a69341
PM
1867 return 0;
1868
1869 err = -ENOBUFS;
1870 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1871 if (skb == NULL)
1872 goto err;
1873
1874 err = nf_tables_fill_set(skb, ctx, set, event, 0);
1875 if (err < 0) {
1876 kfree_skb(skb);
1877 goto err;
1878 }
1879
99633ab2 1880 err = nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, report,
20a69341
PM
1881 GFP_KERNEL);
1882err:
1883 if (err < 0)
99633ab2 1884 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, err);
20a69341
PM
1885 return err;
1886}
1887
1888static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb,
1889 struct netlink_callback *cb)
1890{
1891 const struct nft_set *set;
1892 unsigned int idx = 0, s_idx = cb->args[0];
1893
1894 if (cb->args[1])
1895 return skb->len;
1896
1897 list_for_each_entry(set, &ctx->table->sets, list) {
1898 if (idx < s_idx)
1899 goto cont;
1900 if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
1901 NLM_F_MULTI) < 0) {
1902 cb->args[0] = idx;
1903 goto done;
1904 }
1905cont:
1906 idx++;
1907 }
1908 cb->args[1] = 1;
1909done:
1910 return skb->len;
1911}
1912
1913static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
1914 struct netlink_callback *cb)
1915{
1916 const struct nft_set *set;
1917 unsigned int idx = 0, s_idx = cb->args[0];
1918 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
1919
1920 if (cb->args[1])
1921 return skb->len;
1922
1923 list_for_each_entry(table, &ctx->afi->tables, list) {
1924 if (cur_table && cur_table != table)
1925 continue;
1926
1927 ctx->table = table;
1928 list_for_each_entry(set, &ctx->table->sets, list) {
1929 if (idx < s_idx)
1930 goto cont;
1931 if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
1932 NLM_F_MULTI) < 0) {
1933 cb->args[0] = idx;
1934 cb->args[2] = (unsigned long) table;
1935 goto done;
1936 }
1937cont:
1938 idx++;
1939 }
1940 }
1941 cb->args[1] = 1;
1942done:
1943 return skb->len;
1944}
1945
1946static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
1947{
1948 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1949 struct nlattr *nla[NFTA_SET_MAX + 1];
1950 struct nft_ctx ctx;
1951 int err, ret;
1952
1953 err = nlmsg_parse(cb->nlh, sizeof(*nfmsg), nla, NFTA_SET_MAX,
1954 nft_set_policy);
1955 if (err < 0)
1956 return err;
1957
1958 err = nft_ctx_init_from_setattr(&ctx, cb->skb, cb->nlh, (void *)nla);
1959 if (err < 0)
1960 return err;
1961
1962 if (ctx.table == NULL)
1963 ret = nf_tables_dump_sets_all(&ctx, skb, cb);
1964 else
1965 ret = nf_tables_dump_sets_table(&ctx, skb, cb);
1966
1967 return ret;
1968}
1969
1970static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
1971 const struct nlmsghdr *nlh,
1972 const struct nlattr * const nla[])
1973{
1974 const struct nft_set *set;
1975 struct nft_ctx ctx;
1976 struct sk_buff *skb2;
1977 int err;
1978
1979 /* Verify existance before starting dump */
1980 err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
1981 if (err < 0)
1982 return err;
1983
1984 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1985 struct netlink_dump_control c = {
1986 .dump = nf_tables_dump_sets,
1987 };
1988 return netlink_dump_start(nlsk, skb, nlh, &c);
1989 }
1990
1991 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
1992 if (IS_ERR(set))
1993 return PTR_ERR(set);
1994
1995 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1996 if (skb2 == NULL)
1997 return -ENOMEM;
1998
1999 err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
2000 if (err < 0)
2001 goto err;
2002
2003 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2004
2005err:
2006 kfree_skb(skb2);
2007 return err;
2008}
2009
2010static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2011 const struct nlmsghdr *nlh,
2012 const struct nlattr * const nla[])
2013{
2014 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2015 const struct nft_set_ops *ops;
2016 const struct nft_af_info *afi;
99633ab2 2017 struct net *net = sock_net(skb->sk);
20a69341
PM
2018 struct nft_table *table;
2019 struct nft_set *set;
2020 struct nft_ctx ctx;
2021 char name[IFNAMSIZ];
2022 unsigned int size;
2023 bool create;
2024 u32 ktype, klen, dlen, dtype, flags;
2025 int err;
2026
2027 if (nla[NFTA_SET_TABLE] == NULL ||
2028 nla[NFTA_SET_NAME] == NULL ||
2029 nla[NFTA_SET_KEY_LEN] == NULL)
2030 return -EINVAL;
2031
2032 ktype = NFT_DATA_VALUE;
2033 if (nla[NFTA_SET_KEY_TYPE] != NULL) {
2034 ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
2035 if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
2036 return -EINVAL;
2037 }
2038
2039 klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
2040 if (klen == 0 || klen > FIELD_SIZEOF(struct nft_data, data))
2041 return -EINVAL;
2042
2043 flags = 0;
2044 if (nla[NFTA_SET_FLAGS] != NULL) {
2045 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2046 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
2047 NFT_SET_INTERVAL | NFT_SET_MAP))
2048 return -EINVAL;
2049 }
2050
2051 dtype = 0;
2052 dlen = 0;
2053 if (nla[NFTA_SET_DATA_TYPE] != NULL) {
2054 if (!(flags & NFT_SET_MAP))
2055 return -EINVAL;
2056
2057 dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
2058 if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
2059 dtype != NFT_DATA_VERDICT)
2060 return -EINVAL;
2061
2062 if (dtype != NFT_DATA_VERDICT) {
2063 if (nla[NFTA_SET_DATA_LEN] == NULL)
2064 return -EINVAL;
2065 dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
2066 if (dlen == 0 ||
2067 dlen > FIELD_SIZEOF(struct nft_data, data))
2068 return -EINVAL;
2069 } else
2070 dlen = sizeof(struct nft_data);
2071 } else if (flags & NFT_SET_MAP)
2072 return -EINVAL;
2073
2074 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
2075
99633ab2 2076 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
20a69341
PM
2077 if (IS_ERR(afi))
2078 return PTR_ERR(afi);
2079
9370761c 2080 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
20a69341
PM
2081 if (IS_ERR(table))
2082 return PTR_ERR(table);
2083
0ca743a5 2084 nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
20a69341
PM
2085
2086 set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME]);
2087 if (IS_ERR(set)) {
2088 if (PTR_ERR(set) != -ENOENT)
2089 return PTR_ERR(set);
2090 set = NULL;
2091 }
2092
2093 if (set != NULL) {
2094 if (nlh->nlmsg_flags & NLM_F_EXCL)
2095 return -EEXIST;
2096 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2097 return -EOPNOTSUPP;
2098 return 0;
2099 }
2100
2101 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
2102 return -ENOENT;
2103
2104 ops = nft_select_set_ops(nla);
2105 if (IS_ERR(ops))
2106 return PTR_ERR(ops);
2107
2108 size = 0;
2109 if (ops->privsize != NULL)
2110 size = ops->privsize(nla);
2111
2112 err = -ENOMEM;
2113 set = kzalloc(sizeof(*set) + size, GFP_KERNEL);
2114 if (set == NULL)
2115 goto err1;
2116
2117 nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name));
2118 err = nf_tables_set_alloc_name(&ctx, set, name);
2119 if (err < 0)
2120 goto err2;
2121
2122 INIT_LIST_HEAD(&set->bindings);
2123 set->ops = ops;
2124 set->ktype = ktype;
2125 set->klen = klen;
2126 set->dtype = dtype;
2127 set->dlen = dlen;
2128 set->flags = flags;
2129
2130 err = ops->init(set, nla);
2131 if (err < 0)
2132 goto err2;
2133
2134 list_add_tail(&set->list, &table->sets);
2135 nf_tables_set_notify(&ctx, set, NFT_MSG_NEWSET);
2136 return 0;
2137
2138err2:
2139 kfree(set);
2140err1:
2141 module_put(ops->owner);
2142 return err;
2143}
2144
2145static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
2146{
2147 list_del(&set->list);
2148 if (!(set->flags & NFT_SET_ANONYMOUS))
2149 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET);
2150
2151 set->ops->destroy(set);
2152 module_put(set->ops->owner);
2153 kfree(set);
2154}
2155
2156static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
2157 const struct nlmsghdr *nlh,
2158 const struct nlattr * const nla[])
2159{
2160 struct nft_set *set;
2161 struct nft_ctx ctx;
2162 int err;
2163
2164 if (nla[NFTA_SET_TABLE] == NULL)
2165 return -EINVAL;
2166
2167 err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
2168 if (err < 0)
2169 return err;
2170
2171 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2172 if (IS_ERR(set))
2173 return PTR_ERR(set);
2174 if (!list_empty(&set->bindings))
2175 return -EBUSY;
2176
2177 nf_tables_set_destroy(&ctx, set);
2178 return 0;
2179}
2180
2181static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
2182 const struct nft_set *set,
2183 const struct nft_set_iter *iter,
2184 const struct nft_set_elem *elem)
2185{
2186 enum nft_registers dreg;
2187
2188 dreg = nft_type_to_reg(set->dtype);
2189 return nft_validate_data_load(ctx, dreg, &elem->data, set->dtype);
2190}
2191
2192int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
2193 struct nft_set_binding *binding)
2194{
2195 struct nft_set_binding *i;
2196 struct nft_set_iter iter;
2197
2198 if (!list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
2199 return -EBUSY;
2200
2201 if (set->flags & NFT_SET_MAP) {
2202 /* If the set is already bound to the same chain all
2203 * jumps are already validated for that chain.
2204 */
2205 list_for_each_entry(i, &set->bindings, list) {
2206 if (i->chain == binding->chain)
2207 goto bind;
2208 }
2209
2210 iter.skip = 0;
2211 iter.count = 0;
2212 iter.err = 0;
2213 iter.fn = nf_tables_bind_check_setelem;
2214
2215 set->ops->walk(ctx, set, &iter);
2216 if (iter.err < 0) {
2217 /* Destroy anonymous sets if binding fails */
2218 if (set->flags & NFT_SET_ANONYMOUS)
2219 nf_tables_set_destroy(ctx, set);
2220
2221 return iter.err;
2222 }
2223 }
2224bind:
2225 binding->chain = ctx->chain;
2226 list_add_tail(&binding->list, &set->bindings);
2227 return 0;
2228}
2229
2230void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
2231 struct nft_set_binding *binding)
2232{
2233 list_del(&binding->list);
2234
2235 if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
2236 nf_tables_set_destroy(ctx, set);
2237}
2238
2239/*
2240 * Set elements
2241 */
2242
2243static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
2244 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
2245 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
2246 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
2247};
2248
2249static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
2250 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING },
2251 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING },
2252 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
2253};
2254
2255static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
2256 const struct sk_buff *skb,
2257 const struct nlmsghdr *nlh,
2258 const struct nlattr * const nla[])
2259{
2260 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2261 const struct nft_af_info *afi;
2262 const struct nft_table *table;
99633ab2 2263 struct net *net = sock_net(skb->sk);
20a69341 2264
99633ab2 2265 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
20a69341
PM
2266 if (IS_ERR(afi))
2267 return PTR_ERR(afi);
2268
9370761c 2269 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]);
20a69341
PM
2270 if (IS_ERR(table))
2271 return PTR_ERR(table);
2272
0ca743a5 2273 nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
20a69341
PM
2274 return 0;
2275}
2276
2277static int nf_tables_fill_setelem(struct sk_buff *skb,
2278 const struct nft_set *set,
2279 const struct nft_set_elem *elem)
2280{
2281 unsigned char *b = skb_tail_pointer(skb);
2282 struct nlattr *nest;
2283
2284 nest = nla_nest_start(skb, NFTA_LIST_ELEM);
2285 if (nest == NULL)
2286 goto nla_put_failure;
2287
2288 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, &elem->key, NFT_DATA_VALUE,
2289 set->klen) < 0)
2290 goto nla_put_failure;
2291
2292 if (set->flags & NFT_SET_MAP &&
2293 !(elem->flags & NFT_SET_ELEM_INTERVAL_END) &&
2294 nft_data_dump(skb, NFTA_SET_ELEM_DATA, &elem->data,
2295 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
2296 set->dlen) < 0)
2297 goto nla_put_failure;
2298
2299 if (elem->flags != 0)
2300 if (nla_put_be32(skb, NFTA_SET_ELEM_FLAGS, htonl(elem->flags)))
2301 goto nla_put_failure;
2302
2303 nla_nest_end(skb, nest);
2304 return 0;
2305
2306nla_put_failure:
2307 nlmsg_trim(skb, b);
2308 return -EMSGSIZE;
2309}
2310
2311struct nft_set_dump_args {
2312 const struct netlink_callback *cb;
2313 struct nft_set_iter iter;
2314 struct sk_buff *skb;
2315};
2316
2317static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
2318 const struct nft_set *set,
2319 const struct nft_set_iter *iter,
2320 const struct nft_set_elem *elem)
2321{
2322 struct nft_set_dump_args *args;
2323
2324 args = container_of(iter, struct nft_set_dump_args, iter);
2325 return nf_tables_fill_setelem(args->skb, set, elem);
2326}
2327
2328static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
2329{
2330 const struct nft_set *set;
2331 struct nft_set_dump_args args;
2332 struct nft_ctx ctx;
2333 struct nlattr *nla[NFTA_SET_ELEM_LIST_MAX + 1];
2334 struct nfgenmsg *nfmsg;
2335 struct nlmsghdr *nlh;
2336 struct nlattr *nest;
2337 u32 portid, seq;
2338 int event, err;
2339
2340 nfmsg = nlmsg_data(cb->nlh);
2341 err = nlmsg_parse(cb->nlh, sizeof(*nfmsg), nla, NFTA_SET_ELEM_LIST_MAX,
2342 nft_set_elem_list_policy);
2343 if (err < 0)
2344 return err;
2345
2346 err = nft_ctx_init_from_elemattr(&ctx, cb->skb, cb->nlh, (void *)nla);
2347 if (err < 0)
2348 return err;
2349
2350 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2351 if (IS_ERR(set))
2352 return PTR_ERR(set);
2353
2354 event = NFT_MSG_NEWSETELEM;
2355 event |= NFNL_SUBSYS_NFTABLES << 8;
2356 portid = NETLINK_CB(cb->skb).portid;
2357 seq = cb->nlh->nlmsg_seq;
2358
2359 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
2360 NLM_F_MULTI);
2361 if (nlh == NULL)
2362 goto nla_put_failure;
2363
2364 nfmsg = nlmsg_data(nlh);
2365 nfmsg->nfgen_family = NFPROTO_UNSPEC;
2366 nfmsg->version = NFNETLINK_V0;
2367 nfmsg->res_id = 0;
2368
2369 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, ctx.table->name))
2370 goto nla_put_failure;
2371 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
2372 goto nla_put_failure;
2373
2374 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
2375 if (nest == NULL)
2376 goto nla_put_failure;
2377
2378 args.cb = cb;
2379 args.skb = skb;
2380 args.iter.skip = cb->args[0];
2381 args.iter.count = 0;
2382 args.iter.err = 0;
2383 args.iter.fn = nf_tables_dump_setelem;
2384 set->ops->walk(&ctx, set, &args.iter);
2385
2386 nla_nest_end(skb, nest);
2387 nlmsg_end(skb, nlh);
2388
2389 if (args.iter.err && args.iter.err != -EMSGSIZE)
2390 return args.iter.err;
2391 if (args.iter.count == cb->args[0])
2392 return 0;
2393
2394 cb->args[0] = args.iter.count;
2395 return skb->len;
2396
2397nla_put_failure:
2398 return -ENOSPC;
2399}
2400
2401static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb,
2402 const struct nlmsghdr *nlh,
2403 const struct nlattr * const nla[])
2404{
2405 const struct nft_set *set;
2406 struct nft_ctx ctx;
2407 int err;
2408
2409 err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla);
2410 if (err < 0)
2411 return err;
2412
2413 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2414 if (IS_ERR(set))
2415 return PTR_ERR(set);
2416
2417 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2418 struct netlink_dump_control c = {
2419 .dump = nf_tables_dump_set,
2420 };
2421 return netlink_dump_start(nlsk, skb, nlh, &c);
2422 }
2423 return -EOPNOTSUPP;
2424}
2425
2426static int nft_add_set_elem(const struct nft_ctx *ctx, struct nft_set *set,
2427 const struct nlattr *attr)
2428{
2429 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
2430 struct nft_data_desc d1, d2;
2431 struct nft_set_elem elem;
2432 struct nft_set_binding *binding;
2433 enum nft_registers dreg;
2434 int err;
2435
2436 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
2437 nft_set_elem_policy);
2438 if (err < 0)
2439 return err;
2440
2441 if (nla[NFTA_SET_ELEM_KEY] == NULL)
2442 return -EINVAL;
2443
2444 elem.flags = 0;
2445 if (nla[NFTA_SET_ELEM_FLAGS] != NULL) {
2446 elem.flags = ntohl(nla_get_be32(nla[NFTA_SET_ELEM_FLAGS]));
2447 if (elem.flags & ~NFT_SET_ELEM_INTERVAL_END)
2448 return -EINVAL;
2449 }
2450
2451 if (set->flags & NFT_SET_MAP) {
2452 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
2453 !(elem.flags & NFT_SET_ELEM_INTERVAL_END))
2454 return -EINVAL;
2455 } else {
2456 if (nla[NFTA_SET_ELEM_DATA] != NULL)
2457 return -EINVAL;
2458 }
2459
2460 err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]);
2461 if (err < 0)
2462 goto err1;
2463 err = -EINVAL;
2464 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
2465 goto err2;
2466
2467 err = -EEXIST;
2468 if (set->ops->get(set, &elem) == 0)
2469 goto err2;
2470
2471 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
2472 err = nft_data_init(ctx, &elem.data, &d2, nla[NFTA_SET_ELEM_DATA]);
2473 if (err < 0)
2474 goto err2;
2475
2476 err = -EINVAL;
2477 if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
2478 goto err3;
2479
2480 dreg = nft_type_to_reg(set->dtype);
2481 list_for_each_entry(binding, &set->bindings, list) {
2482 struct nft_ctx bind_ctx = {
2483 .afi = ctx->afi,
2484 .table = ctx->table,
2485 .chain = binding->chain,
2486 };
2487
2488 err = nft_validate_data_load(&bind_ctx, dreg,
2489 &elem.data, d2.type);
2490 if (err < 0)
2491 goto err3;
2492 }
2493 }
2494
2495 err = set->ops->insert(set, &elem);
2496 if (err < 0)
2497 goto err3;
2498
2499 return 0;
2500
2501err3:
2502 if (nla[NFTA_SET_ELEM_DATA] != NULL)
2503 nft_data_uninit(&elem.data, d2.type);
2504err2:
2505 nft_data_uninit(&elem.key, d1.type);
2506err1:
2507 return err;
2508}
2509
2510static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
2511 const struct nlmsghdr *nlh,
2512 const struct nlattr * const nla[])
2513{
2514 const struct nlattr *attr;
2515 struct nft_set *set;
2516 struct nft_ctx ctx;
2517 int rem, err;
2518
2519 err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla);
2520 if (err < 0)
2521 return err;
2522
2523 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2524 if (IS_ERR(set))
2525 return PTR_ERR(set);
2526 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
2527 return -EBUSY;
2528
2529 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
2530 err = nft_add_set_elem(&ctx, set, attr);
2531 if (err < 0)
2532 return err;
2533 }
2534 return 0;
2535}
2536
2537static int nft_del_setelem(const struct nft_ctx *ctx, struct nft_set *set,
2538 const struct nlattr *attr)
2539{
2540 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
2541 struct nft_data_desc desc;
2542 struct nft_set_elem elem;
2543 int err;
2544
2545 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
2546 nft_set_elem_policy);
2547 if (err < 0)
2548 goto err1;
2549
2550 err = -EINVAL;
2551 if (nla[NFTA_SET_ELEM_KEY] == NULL)
2552 goto err1;
2553
2554 err = nft_data_init(ctx, &elem.key, &desc, nla[NFTA_SET_ELEM_KEY]);
2555 if (err < 0)
2556 goto err1;
2557
2558 err = -EINVAL;
2559 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
2560 goto err2;
2561
2562 err = set->ops->get(set, &elem);
2563 if (err < 0)
2564 goto err2;
2565
2566 set->ops->remove(set, &elem);
2567
2568 nft_data_uninit(&elem.key, NFT_DATA_VALUE);
2569 if (set->flags & NFT_SET_MAP)
2570 nft_data_uninit(&elem.data, set->dtype);
2571
2572err2:
2573 nft_data_uninit(&elem.key, desc.type);
2574err1:
2575 return err;
2576}
2577
2578static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
2579 const struct nlmsghdr *nlh,
2580 const struct nlattr * const nla[])
2581{
2582 const struct nlattr *attr;
2583 struct nft_set *set;
2584 struct nft_ctx ctx;
2585 int rem, err;
2586
2587 err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla);
2588 if (err < 0)
2589 return err;
2590
2591 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2592 if (IS_ERR(set))
2593 return PTR_ERR(set);
2594 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
2595 return -EBUSY;
2596
2597 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
2598 err = nft_del_setelem(&ctx, set, attr);
2599 if (err < 0)
2600 return err;
2601 }
2602 return 0;
2603}
2604
96518518
PM
2605static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
2606 [NFT_MSG_NEWTABLE] = {
2607 .call = nf_tables_newtable,
2608 .attr_count = NFTA_TABLE_MAX,
2609 .policy = nft_table_policy,
2610 },
2611 [NFT_MSG_GETTABLE] = {
2612 .call = nf_tables_gettable,
2613 .attr_count = NFTA_TABLE_MAX,
2614 .policy = nft_table_policy,
2615 },
2616 [NFT_MSG_DELTABLE] = {
2617 .call = nf_tables_deltable,
2618 .attr_count = NFTA_TABLE_MAX,
2619 .policy = nft_table_policy,
2620 },
2621 [NFT_MSG_NEWCHAIN] = {
2622 .call = nf_tables_newchain,
2623 .attr_count = NFTA_CHAIN_MAX,
2624 .policy = nft_chain_policy,
2625 },
2626 [NFT_MSG_GETCHAIN] = {
2627 .call = nf_tables_getchain,
2628 .attr_count = NFTA_CHAIN_MAX,
2629 .policy = nft_chain_policy,
2630 },
2631 [NFT_MSG_DELCHAIN] = {
2632 .call = nf_tables_delchain,
2633 .attr_count = NFTA_CHAIN_MAX,
2634 .policy = nft_chain_policy,
2635 },
2636 [NFT_MSG_NEWRULE] = {
2637 .call = nf_tables_newrule,
2638 .attr_count = NFTA_RULE_MAX,
2639 .policy = nft_rule_policy,
2640 },
2641 [NFT_MSG_GETRULE] = {
2642 .call = nf_tables_getrule,
2643 .attr_count = NFTA_RULE_MAX,
2644 .policy = nft_rule_policy,
2645 },
2646 [NFT_MSG_DELRULE] = {
2647 .call = nf_tables_delrule,
2648 .attr_count = NFTA_RULE_MAX,
2649 .policy = nft_rule_policy,
2650 },
20a69341
PM
2651 [NFT_MSG_NEWSET] = {
2652 .call = nf_tables_newset,
2653 .attr_count = NFTA_SET_MAX,
2654 .policy = nft_set_policy,
2655 },
2656 [NFT_MSG_GETSET] = {
2657 .call = nf_tables_getset,
2658 .attr_count = NFTA_SET_MAX,
2659 .policy = nft_set_policy,
2660 },
2661 [NFT_MSG_DELSET] = {
2662 .call = nf_tables_delset,
2663 .attr_count = NFTA_SET_MAX,
2664 .policy = nft_set_policy,
2665 },
2666 [NFT_MSG_NEWSETELEM] = {
2667 .call = nf_tables_newsetelem,
2668 .attr_count = NFTA_SET_ELEM_LIST_MAX,
2669 .policy = nft_set_elem_list_policy,
2670 },
2671 [NFT_MSG_GETSETELEM] = {
2672 .call = nf_tables_getsetelem,
2673 .attr_count = NFTA_SET_ELEM_LIST_MAX,
2674 .policy = nft_set_elem_list_policy,
2675 },
2676 [NFT_MSG_DELSETELEM] = {
2677 .call = nf_tables_delsetelem,
2678 .attr_count = NFTA_SET_ELEM_LIST_MAX,
2679 .policy = nft_set_elem_list_policy,
2680 },
96518518
PM
2681};
2682
2683static const struct nfnetlink_subsystem nf_tables_subsys = {
2684 .name = "nf_tables",
2685 .subsys_id = NFNL_SUBSYS_NFTABLES,
2686 .cb_count = NFT_MSG_MAX,
2687 .cb = nf_tables_cb,
2688};
2689
20a69341
PM
2690/*
2691 * Loop detection - walk through the ruleset beginning at the destination chain
2692 * of a new jump until either the source chain is reached (loop) or all
2693 * reachable chains have been traversed.
2694 *
2695 * The loop check is performed whenever a new jump verdict is added to an
2696 * expression or verdict map or a verdict map is bound to a new chain.
2697 */
2698
2699static int nf_tables_check_loops(const struct nft_ctx *ctx,
2700 const struct nft_chain *chain);
2701
2702static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
2703 const struct nft_set *set,
2704 const struct nft_set_iter *iter,
2705 const struct nft_set_elem *elem)
2706{
2707 switch (elem->data.verdict) {
2708 case NFT_JUMP:
2709 case NFT_GOTO:
2710 return nf_tables_check_loops(ctx, elem->data.chain);
2711 default:
2712 return 0;
2713 }
2714}
2715
2716static int nf_tables_check_loops(const struct nft_ctx *ctx,
2717 const struct nft_chain *chain)
2718{
2719 const struct nft_rule *rule;
2720 const struct nft_expr *expr, *last;
20a69341
PM
2721 const struct nft_set *set;
2722 struct nft_set_binding *binding;
2723 struct nft_set_iter iter;
20a69341
PM
2724
2725 if (ctx->chain == chain)
2726 return -ELOOP;
2727
2728 list_for_each_entry(rule, &chain->rules, list) {
2729 nft_rule_for_each_expr(expr, last, rule) {
0ca743a5
PNA
2730 const struct nft_data *data = NULL;
2731 int err;
2732
2733 if (!expr->ops->validate)
20a69341
PM
2734 continue;
2735
0ca743a5
PNA
2736 err = expr->ops->validate(ctx, expr, &data);
2737 if (err < 0)
2738 return err;
2739
20a69341 2740 if (data == NULL)
0ca743a5 2741 continue;
20a69341
PM
2742
2743 switch (data->verdict) {
2744 case NFT_JUMP:
2745 case NFT_GOTO:
2746 err = nf_tables_check_loops(ctx, data->chain);
2747 if (err < 0)
2748 return err;
2749 default:
2750 break;
2751 }
2752 }
2753 }
2754
2755 list_for_each_entry(set, &ctx->table->sets, list) {
2756 if (!(set->flags & NFT_SET_MAP) ||
2757 set->dtype != NFT_DATA_VERDICT)
2758 continue;
2759
2760 list_for_each_entry(binding, &set->bindings, list) {
2761 if (binding->chain != chain)
2762 continue;
2763
2764 iter.skip = 0;
2765 iter.count = 0;
2766 iter.err = 0;
2767 iter.fn = nf_tables_loop_check_setelem;
2768
2769 set->ops->walk(ctx, set, &iter);
2770 if (iter.err < 0)
2771 return iter.err;
2772 }
2773 }
2774
2775 return 0;
2776}
2777
96518518
PM
2778/**
2779 * nft_validate_input_register - validate an expressions' input register
2780 *
2781 * @reg: the register number
2782 *
2783 * Validate that the input register is one of the general purpose
2784 * registers.
2785 */
2786int nft_validate_input_register(enum nft_registers reg)
2787{
2788 if (reg <= NFT_REG_VERDICT)
2789 return -EINVAL;
2790 if (reg > NFT_REG_MAX)
2791 return -ERANGE;
2792 return 0;
2793}
2794EXPORT_SYMBOL_GPL(nft_validate_input_register);
2795
2796/**
2797 * nft_validate_output_register - validate an expressions' output register
2798 *
2799 * @reg: the register number
2800 *
2801 * Validate that the output register is one of the general purpose
2802 * registers or the verdict register.
2803 */
2804int nft_validate_output_register(enum nft_registers reg)
2805{
2806 if (reg < NFT_REG_VERDICT)
2807 return -EINVAL;
2808 if (reg > NFT_REG_MAX)
2809 return -ERANGE;
2810 return 0;
2811}
2812EXPORT_SYMBOL_GPL(nft_validate_output_register);
2813
2814/**
2815 * nft_validate_data_load - validate an expressions' data load
2816 *
2817 * @ctx: context of the expression performing the load
2818 * @reg: the destination register number
2819 * @data: the data to load
2820 * @type: the data type
2821 *
2822 * Validate that a data load uses the appropriate data type for
2823 * the destination register. A value of NULL for the data means
2824 * that its runtime gathered data, which is always of type
2825 * NFT_DATA_VALUE.
2826 */
2827int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
2828 const struct nft_data *data,
2829 enum nft_data_types type)
2830{
20a69341
PM
2831 int err;
2832
96518518
PM
2833 switch (reg) {
2834 case NFT_REG_VERDICT:
2835 if (data == NULL || type != NFT_DATA_VERDICT)
2836 return -EINVAL;
20a69341
PM
2837
2838 if (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP) {
2839 err = nf_tables_check_loops(ctx, data->chain);
2840 if (err < 0)
2841 return err;
2842
2843 if (ctx->chain->level + 1 > data->chain->level) {
2844 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
2845 return -EMLINK;
2846 data->chain->level = ctx->chain->level + 1;
2847 }
2848 }
2849
96518518
PM
2850 return 0;
2851 default:
2852 if (data != NULL && type != NFT_DATA_VALUE)
2853 return -EINVAL;
2854 return 0;
2855 }
2856}
2857EXPORT_SYMBOL_GPL(nft_validate_data_load);
2858
2859static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
2860 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
2861 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
2862 .len = NFT_CHAIN_MAXNAMELEN - 1 },
2863};
2864
2865static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
2866 struct nft_data_desc *desc, const struct nlattr *nla)
2867{
2868 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
2869 struct nft_chain *chain;
2870 int err;
2871
2872 err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy);
2873 if (err < 0)
2874 return err;
2875
2876 if (!tb[NFTA_VERDICT_CODE])
2877 return -EINVAL;
2878 data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
2879
2880 switch (data->verdict) {
2881 case NF_ACCEPT:
2882 case NF_DROP:
2883 case NF_QUEUE:
2884 case NFT_CONTINUE:
2885 case NFT_BREAK:
2886 case NFT_RETURN:
2887 desc->len = sizeof(data->verdict);
2888 break;
2889 case NFT_JUMP:
2890 case NFT_GOTO:
2891 if (!tb[NFTA_VERDICT_CHAIN])
2892 return -EINVAL;
2893 chain = nf_tables_chain_lookup(ctx->table,
2894 tb[NFTA_VERDICT_CHAIN]);
2895 if (IS_ERR(chain))
2896 return PTR_ERR(chain);
2897 if (chain->flags & NFT_BASE_CHAIN)
2898 return -EOPNOTSUPP;
2899
96518518
PM
2900 chain->use++;
2901 data->chain = chain;
2902 desc->len = sizeof(data);
2903 break;
2904 default:
2905 return -EINVAL;
2906 }
2907
2908 desc->type = NFT_DATA_VERDICT;
2909 return 0;
2910}
2911
2912static void nft_verdict_uninit(const struct nft_data *data)
2913{
2914 switch (data->verdict) {
2915 case NFT_JUMP:
2916 case NFT_GOTO:
2917 data->chain->use--;
2918 break;
2919 }
2920}
2921
2922static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data)
2923{
2924 struct nlattr *nest;
2925
2926 nest = nla_nest_start(skb, NFTA_DATA_VERDICT);
2927 if (!nest)
2928 goto nla_put_failure;
2929
2930 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict)))
2931 goto nla_put_failure;
2932
2933 switch (data->verdict) {
2934 case NFT_JUMP:
2935 case NFT_GOTO:
2936 if (nla_put_string(skb, NFTA_VERDICT_CHAIN, data->chain->name))
2937 goto nla_put_failure;
2938 }
2939 nla_nest_end(skb, nest);
2940 return 0;
2941
2942nla_put_failure:
2943 return -1;
2944}
2945
2946static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
2947 struct nft_data_desc *desc, const struct nlattr *nla)
2948{
2949 unsigned int len;
2950
2951 len = nla_len(nla);
2952 if (len == 0)
2953 return -EINVAL;
2954 if (len > sizeof(data->data))
2955 return -EOVERFLOW;
2956
2957 nla_memcpy(data->data, nla, sizeof(data->data));
2958 desc->type = NFT_DATA_VALUE;
2959 desc->len = len;
2960 return 0;
2961}
2962
2963static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
2964 unsigned int len)
2965{
2966 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
2967}
2968
2969static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
2970 [NFTA_DATA_VALUE] = { .type = NLA_BINARY,
2971 .len = FIELD_SIZEOF(struct nft_data, data) },
2972 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
2973};
2974
2975/**
2976 * nft_data_init - parse nf_tables data netlink attributes
2977 *
2978 * @ctx: context of the expression using the data
2979 * @data: destination struct nft_data
2980 * @desc: data description
2981 * @nla: netlink attribute containing data
2982 *
2983 * Parse the netlink data attributes and initialize a struct nft_data.
2984 * The type and length of data are returned in the data description.
2985 *
2986 * The caller can indicate that it only wants to accept data of type
2987 * NFT_DATA_VALUE by passing NULL for the ctx argument.
2988 */
2989int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
2990 struct nft_data_desc *desc, const struct nlattr *nla)
2991{
2992 struct nlattr *tb[NFTA_DATA_MAX + 1];
2993 int err;
2994
2995 err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy);
2996 if (err < 0)
2997 return err;
2998
2999 if (tb[NFTA_DATA_VALUE])
3000 return nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]);
3001 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
3002 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
3003 return -EINVAL;
3004}
3005EXPORT_SYMBOL_GPL(nft_data_init);
3006
3007/**
3008 * nft_data_uninit - release a nft_data item
3009 *
3010 * @data: struct nft_data to release
3011 * @type: type of data
3012 *
3013 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
3014 * all others need to be released by calling this function.
3015 */
3016void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
3017{
3018 switch (type) {
3019 case NFT_DATA_VALUE:
3020 return;
3021 case NFT_DATA_VERDICT:
3022 return nft_verdict_uninit(data);
3023 default:
3024 WARN_ON(1);
3025 }
3026}
3027EXPORT_SYMBOL_GPL(nft_data_uninit);
3028
3029int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
3030 enum nft_data_types type, unsigned int len)
3031{
3032 struct nlattr *nest;
3033 int err;
3034
3035 nest = nla_nest_start(skb, attr);
3036 if (nest == NULL)
3037 return -1;
3038
3039 switch (type) {
3040 case NFT_DATA_VALUE:
3041 err = nft_value_dump(skb, data, len);
3042 break;
3043 case NFT_DATA_VERDICT:
3044 err = nft_verdict_dump(skb, data);
3045 break;
3046 default:
3047 err = -EINVAL;
3048 WARN_ON(1);
3049 }
3050
3051 nla_nest_end(skb, nest);
3052 return err;
3053}
3054EXPORT_SYMBOL_GPL(nft_data_dump);
3055
99633ab2
PNA
3056static int nf_tables_init_net(struct net *net)
3057{
3058 INIT_LIST_HEAD(&net->nft.af_info);
3059 return 0;
3060}
3061
3062static struct pernet_operations nf_tables_net_ops = {
3063 .init = nf_tables_init_net,
3064};
3065
96518518
PM
3066static int __init nf_tables_module_init(void)
3067{
3068 int err;
3069
3070 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
3071 GFP_KERNEL);
3072 if (info == NULL) {
3073 err = -ENOMEM;
3074 goto err1;
3075 }
3076
3077 err = nf_tables_core_module_init();
3078 if (err < 0)
3079 goto err2;
3080
3081 err = nfnetlink_subsys_register(&nf_tables_subsys);
3082 if (err < 0)
3083 goto err3;
3084
3085 pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
99633ab2 3086 return register_pernet_subsys(&nf_tables_net_ops);
96518518
PM
3087err3:
3088 nf_tables_core_module_exit();
3089err2:
3090 kfree(info);
3091err1:
3092 return err;
3093}
3094
3095static void __exit nf_tables_module_exit(void)
3096{
99633ab2 3097 unregister_pernet_subsys(&nf_tables_net_ops);
96518518
PM
3098 nfnetlink_subsys_unregister(&nf_tables_subsys);
3099 nf_tables_core_module_exit();
3100 kfree(info);
3101}
3102
3103module_init(nf_tables_module_init);
3104module_exit(nf_tables_module_exit);
3105
3106MODULE_LICENSE("GPL");
3107MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
3108MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);