2 * Copyright (c) 2007-2009 Patrick McHardy <kaber@trash.net>
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.
8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
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>
21 #include <net/net_namespace.h>
24 static LIST_HEAD(nf_tables_expressions);
27 * nft_register_afinfo - register nf_tables address family info
29 * @afi: address family info to register
31 * Register the address family for use with nf_tables. Returns zero on
32 * success or a negative errno code otherwise.
34 int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
36 INIT_LIST_HEAD(&afi->tables);
37 nfnl_lock(NFNL_SUBSYS_NFTABLES);
38 list_add_tail(&afi->list, &net->nft.af_info);
39 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
42 EXPORT_SYMBOL_GPL(nft_register_afinfo);
45 * nft_unregister_afinfo - unregister nf_tables address family info
47 * @afi: address family info to unregister
49 * Unregister the address family for use with nf_tables.
51 void nft_unregister_afinfo(struct nft_af_info *afi)
53 nfnl_lock(NFNL_SUBSYS_NFTABLES);
55 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
57 EXPORT_SYMBOL_GPL(nft_unregister_afinfo);
59 static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family)
61 struct nft_af_info *afi;
63 list_for_each_entry(afi, &net->nft.af_info, list) {
64 if (afi->family == family)
70 static struct nft_af_info *
71 nf_tables_afinfo_lookup(struct net *net, int family, bool autoload)
73 struct nft_af_info *afi;
75 afi = nft_afinfo_lookup(net, family);
80 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
81 request_module("nft-afinfo-%u", family);
82 nfnl_lock(NFNL_SUBSYS_NFTABLES);
83 afi = nft_afinfo_lookup(net, family);
85 return ERR_PTR(-EAGAIN);
88 return ERR_PTR(-EAFNOSUPPORT);
95 static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
96 const struct nlattr *nla)
98 struct nft_table *table;
100 list_for_each_entry(table, &afi->tables, list) {
101 if (!nla_strcmp(nla, table->name))
107 static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
108 const struct nlattr *nla)
110 struct nft_table *table;
113 return ERR_PTR(-EINVAL);
115 table = nft_table_lookup(afi, nla);
119 return ERR_PTR(-ENOENT);
122 static inline u64 nf_tables_alloc_handle(struct nft_table *table)
124 return ++table->hgenerator;
127 static struct nf_chain_type *chain_type[AF_MAX][NFT_CHAIN_T_MAX];
129 static int __nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
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))
141 static int nf_tables_chain_type_lookup(const struct nft_af_info *afi,
142 const struct nlattr *nla,
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);
160 static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
161 [NFTA_TABLE_NAME] = { .type = NLA_STRING },
162 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
165 static 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)
169 struct nlmsghdr *nlh;
170 struct nfgenmsg *nfmsg;
172 event |= NFNL_SUBSYS_NFTABLES << 8;
173 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
175 goto nla_put_failure;
177 nfmsg = nlmsg_data(nlh);
178 nfmsg->nfgen_family = family;
179 nfmsg->version = NFNETLINK_V0;
182 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
183 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)))
184 goto nla_put_failure;
186 return nlmsg_end(skb, nlh);
189 nlmsg_trim(skb, nlh);
193 static 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)
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;
205 report = nlh ? nlmsg_report(nlh) : false;
206 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
210 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
214 err = nf_tables_fill_table_info(skb, portid, seq, event, 0,
221 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
225 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
229 static int nf_tables_dump_tables(struct sk_buff *skb,
230 struct netlink_callback *cb)
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];
236 struct net *net = sock_net(skb->sk);
237 int family = nfmsg->nfgen_family;
239 list_for_each_entry(afi, &net->nft.af_info, list) {
240 if (family != NFPROTO_UNSPEC && family != afi->family)
243 list_for_each_entry(table, &afi->tables, list) {
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,
254 afi->family, table) < 0)
265 static int nf_tables_gettable(struct sock *nlsk, struct sk_buff *skb,
266 const struct nlmsghdr *nlh,
267 const struct nlattr * const nla[])
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;
273 struct net *net = sock_net(skb->sk);
274 int family = nfmsg->nfgen_family;
277 if (nlh->nlmsg_flags & NLM_F_DUMP) {
278 struct netlink_dump_control c = {
279 .dump = nf_tables_dump_tables,
281 return netlink_dump_start(nlsk, skb, nlh, &c);
284 afi = nf_tables_afinfo_lookup(net, family, false);
288 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]);
290 return PTR_ERR(table);
292 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
296 err = nf_tables_fill_table_info(skb2, NETLINK_CB(skb).portid,
297 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
302 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
309 static int nf_tables_table_enable(struct nft_table *table)
311 struct nft_chain *chain;
314 list_for_each_entry(chain, &table->chains, list) {
315 err = nf_register_hook(&nft_base_chain(chain)->ops);
323 list_for_each_entry(chain, &table->chains, list) {
327 nf_unregister_hook(&nft_base_chain(chain)->ops);
332 static int nf_tables_table_disable(struct nft_table *table)
334 struct nft_chain *chain;
336 list_for_each_entry(chain, &table->chains, list)
337 nf_unregister_hook(&nft_base_chain(chain)->ops);
342 static 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)
347 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
348 int family = nfmsg->nfgen_family, ret = 0;
350 if (nla[NFTA_TABLE_FLAGS]) {
353 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
354 if (flags & ~NFT_TABLE_F_DORMANT)
357 if ((flags & NFT_TABLE_F_DORMANT) &&
358 !(table->flags & NFT_TABLE_F_DORMANT)) {
359 ret = nf_tables_table_disable(table);
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);
366 table->flags &= ~NFT_TABLE_F_DORMANT;
372 nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
377 static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
378 const struct nlmsghdr *nlh,
379 const struct nlattr * const nla[])
381 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
382 const struct nlattr *name;
383 struct nft_af_info *afi;
384 struct nft_table *table;
385 struct net *net = sock_net(skb->sk);
386 int family = nfmsg->nfgen_family;
388 afi = nf_tables_afinfo_lookup(net, family, true);
392 name = nla[NFTA_TABLE_NAME];
393 table = nf_tables_table_lookup(afi, name);
395 if (PTR_ERR(table) != -ENOENT)
396 return PTR_ERR(table);
401 if (nlh->nlmsg_flags & NLM_F_EXCL)
403 if (nlh->nlmsg_flags & NLM_F_REPLACE)
405 return nf_tables_updtable(nlsk, skb, nlh, nla, afi, table);
408 table = kzalloc(sizeof(*table) + nla_len(name), GFP_KERNEL);
412 nla_strlcpy(table->name, name, nla_len(name));
413 INIT_LIST_HEAD(&table->chains);
414 INIT_LIST_HEAD(&table->sets);
416 if (nla[NFTA_TABLE_FLAGS]) {
419 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
420 if (flags & ~NFT_TABLE_F_DORMANT) {
425 table->flags |= flags;
428 list_add_tail(&table->list, &afi->tables);
429 nf_tables_table_notify(skb, nlh, table, NFT_MSG_NEWTABLE, family);
433 static int nf_tables_deltable(struct sock *nlsk, struct sk_buff *skb,
434 const struct nlmsghdr *nlh,
435 const struct nlattr * const nla[])
437 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
438 struct nft_af_info *afi;
439 struct nft_table *table;
440 struct net *net = sock_net(skb->sk);
441 int family = nfmsg->nfgen_family;
443 afi = nf_tables_afinfo_lookup(net, family, false);
447 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]);
449 return PTR_ERR(table);
454 list_del(&table->list);
455 nf_tables_table_notify(skb, nlh, table, NFT_MSG_DELTABLE, family);
460 int nft_register_chain_type(struct nf_chain_type *ctype)
464 nfnl_lock(NFNL_SUBSYS_NFTABLES);
465 if (chain_type[ctype->family][ctype->type] != NULL) {
470 if (!try_module_get(ctype->me))
473 chain_type[ctype->family][ctype->type] = ctype;
475 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
478 EXPORT_SYMBOL_GPL(nft_register_chain_type);
480 void nft_unregister_chain_type(struct nf_chain_type *ctype)
482 nfnl_lock(NFNL_SUBSYS_NFTABLES);
483 chain_type[ctype->family][ctype->type] = NULL;
484 module_put(ctype->me);
485 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
487 EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
493 static struct nft_chain *
494 nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle)
496 struct nft_chain *chain;
498 list_for_each_entry(chain, &table->chains, list) {
499 if (chain->handle == handle)
503 return ERR_PTR(-ENOENT);
506 static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
507 const struct nlattr *nla)
509 struct nft_chain *chain;
512 return ERR_PTR(-EINVAL);
514 list_for_each_entry(chain, &table->chains, list) {
515 if (!nla_strcmp(nla, chain->name))
519 return ERR_PTR(-ENOENT);
522 static 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 },
528 [NFTA_CHAIN_POLICY] = { .type = NLA_U32 },
529 [NFTA_CHAIN_TYPE] = { .type = NLA_NUL_STRING },
530 [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED },
533 static 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 },
538 static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
540 struct nft_stats *cpu_stats, total;
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;
550 nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS);
552 goto nla_put_failure;
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;
558 nla_nest_end(skb, nest);
565 static 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)
570 struct nlmsghdr *nlh;
571 struct nfgenmsg *nfmsg;
573 event |= NFNL_SUBSYS_NFTABLES << 8;
574 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
576 goto nla_put_failure;
578 nfmsg = nlmsg_data(nlh);
579 nfmsg->nfgen_family = family;
580 nfmsg->version = NFNETLINK_V0;
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;
590 if (chain->flags & NFT_BASE_CHAIN) {
591 const struct nft_base_chain *basechain = nft_base_chain(chain);
592 const struct nf_hook_ops *ops = &basechain->ops;
595 nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
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);
604 if (nla_put_be32(skb, NFTA_CHAIN_POLICY,
605 htonl(basechain->policy)))
606 goto nla_put_failure;
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;
612 if (nft_dump_stats(skb, nft_base_chain(chain)->stats))
613 goto nla_put_failure;
616 if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
617 goto nla_put_failure;
619 return nlmsg_end(skb, nlh);
622 nlmsg_trim(skb, nlh);
626 static 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)
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;
639 report = nlh ? nlmsg_report(nlh) : false;
640 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
644 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
648 err = nf_tables_fill_chain_info(skb, portid, seq, event, 0, family,
655 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
659 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
663 static int nf_tables_dump_chains(struct sk_buff *skb,
664 struct netlink_callback *cb)
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];
671 struct net *net = sock_net(skb->sk);
672 int family = nfmsg->nfgen_family;
674 list_for_each_entry(afi, &net->nft.af_info, list) {
675 if (family != NFPROTO_UNSPEC && family != afi->family)
678 list_for_each_entry(table, &afi->tables, list) {
679 list_for_each_entry(chain, &table->chains, list) {
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,
689 afi->family, table, chain) < 0)
702 static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb,
703 const struct nlmsghdr *nlh,
704 const struct nlattr * const nla[])
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;
711 struct net *net = sock_net(skb->sk);
712 int family = nfmsg->nfgen_family;
715 if (nlh->nlmsg_flags & NLM_F_DUMP) {
716 struct netlink_dump_control c = {
717 .dump = nf_tables_dump_chains,
719 return netlink_dump_start(nlsk, skb, nlh, &c);
722 afi = nf_tables_afinfo_lookup(net, family, false);
726 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
728 return PTR_ERR(table);
730 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
732 return PTR_ERR(chain);
734 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
738 err = nf_tables_fill_chain_info(skb2, NETLINK_CB(skb).portid,
739 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
740 family, table, chain);
744 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
752 nf_tables_chain_policy(struct nft_base_chain *chain, const struct nlattr *attr)
754 switch (ntohl(nla_get_be32(attr))) {
756 chain->policy = NF_DROP;
759 chain->policy = NF_ACCEPT;
767 static 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 },
773 nf_tables_counters(struct nft_base_chain *chain, const struct nlattr *attr)
775 struct nlattr *tb[NFTA_COUNTER_MAX+1];
776 struct nft_stats __percpu *newstats;
777 struct nft_stats *stats;
780 err = nla_parse_nested(tb, NFTA_COUNTER_MAX, attr, nft_counter_policy);
784 if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
787 newstats = alloc_percpu(struct nft_stats);
788 if (newstats == NULL)
791 /* Restore old counters on this cpu, no problem. Per-cpu statistics
792 * are not exposed to userspace.
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]));
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);
803 rcu_assign_pointer(chain->stats, newstats);
805 free_percpu(oldstats);
807 rcu_assign_pointer(chain->stats, newstats);
812 static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
813 const struct nlmsghdr *nlh,
814 const struct nlattr * const nla[])
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;
821 struct nft_base_chain *basechain = NULL;
822 struct nlattr *ha[NFTA_HOOK_MAX + 1];
823 struct net *net = sock_net(skb->sk);
824 int family = nfmsg->nfgen_family;
829 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
831 afi = nf_tables_afinfo_lookup(net, family, true);
835 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
837 return PTR_ERR(table);
839 if (table->use == UINT_MAX)
843 name = nla[NFTA_CHAIN_NAME];
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);
849 return PTR_ERR(chain);
851 chain = nf_tables_chain_lookup(table, name);
853 if (PTR_ERR(chain) != -ENOENT)
854 return PTR_ERR(chain);
860 if (nlh->nlmsg_flags & NLM_F_EXCL)
862 if (nlh->nlmsg_flags & NLM_F_REPLACE)
865 if (nla[NFTA_CHAIN_HANDLE] && name &&
866 !IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME])))
869 if (nla[NFTA_CHAIN_POLICY]) {
870 if (!(chain->flags & NFT_BASE_CHAIN))
873 err = nf_tables_chain_policy(nft_base_chain(chain),
874 nla[NFTA_CHAIN_POLICY]);
879 if (nla[NFTA_CHAIN_COUNTERS]) {
880 if (!(chain->flags & NFT_BASE_CHAIN))
883 err = nf_tables_counters(nft_base_chain(chain),
884 nla[NFTA_CHAIN_COUNTERS]);
889 if (nla[NFTA_CHAIN_HANDLE] && name)
890 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
895 if (nla[NFTA_CHAIN_HOOK]) {
896 struct nf_hook_ops *ops;
899 int type = NFT_CHAIN_T_DEFAULT;
901 if (nla[NFTA_CHAIN_TYPE]) {
902 type = nf_tables_chain_type_lookup(afi,
903 nla[NFTA_CHAIN_TYPE],
909 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
913 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
914 ha[NFTA_HOOK_PRIORITY] == NULL)
917 hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
918 if (hooknum >= afi->nhooks)
921 hookfn = chain_type[family][type]->fn[hooknum];
925 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
926 if (basechain == NULL)
929 basechain->type = type;
930 chain = &basechain->chain;
932 ops = &basechain->ops;
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]));
939 if (afi->hooks[ops->hooknum])
940 ops->hook = afi->hooks[ops->hooknum];
942 chain->flags |= NFT_BASE_CHAIN;
944 if (nla[NFTA_CHAIN_POLICY]) {
945 err = nf_tables_chain_policy(basechain,
946 nla[NFTA_CHAIN_POLICY]);
948 free_percpu(basechain->stats);
953 basechain->policy = NF_ACCEPT;
955 if (nla[NFTA_CHAIN_COUNTERS]) {
956 err = nf_tables_counters(basechain,
957 nla[NFTA_CHAIN_COUNTERS]);
959 free_percpu(basechain->stats);
964 struct nft_stats __percpu *newstats;
966 newstats = alloc_percpu(struct nft_stats);
967 if (newstats == NULL)
970 rcu_assign_pointer(nft_base_chain(chain)->stats,
974 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
979 INIT_LIST_HEAD(&chain->rules);
980 chain->handle = nf_tables_alloc_handle(table);
981 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
983 if (!(table->flags & NFT_TABLE_F_DORMANT) &&
984 chain->flags & NFT_BASE_CHAIN) {
985 err = nf_register_hook(&nft_base_chain(chain)->ops);
987 free_percpu(basechain->stats);
992 list_add_tail(&chain->list, &table->chains);
995 nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_NEWCHAIN,
1000 static void nf_tables_rcu_chain_destroy(struct rcu_head *head)
1002 struct nft_chain *chain = container_of(head, struct nft_chain, rcu_head);
1004 BUG_ON(chain->use > 0);
1006 if (chain->flags & NFT_BASE_CHAIN) {
1007 free_percpu(nft_base_chain(chain)->stats);
1008 kfree(nft_base_chain(chain));
1013 static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
1014 const struct nlmsghdr *nlh,
1015 const struct nlattr * const nla[])
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;
1021 struct net *net = sock_net(skb->sk);
1022 int family = nfmsg->nfgen_family;
1024 afi = nf_tables_afinfo_lookup(net, family, false);
1026 return PTR_ERR(afi);
1028 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
1030 return PTR_ERR(table);
1032 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
1034 return PTR_ERR(chain);
1036 if (!list_empty(&chain->rules))
1039 list_del(&chain->list);
1042 if (!(table->flags & NFT_TABLE_F_DORMANT) &&
1043 chain->flags & NFT_BASE_CHAIN)
1044 nf_unregister_hook(&nft_base_chain(chain)->ops);
1046 nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_DELCHAIN,
1049 /* Make sure all rule references are gone before this is released */
1050 call_rcu(&chain->rcu_head, nf_tables_rcu_chain_destroy);
1054 static void nft_ctx_init(struct nft_ctx *ctx,
1055 const struct sk_buff *skb,
1056 const struct nlmsghdr *nlh,
1057 const struct nft_af_info *afi,
1058 const struct nft_table *table,
1059 const struct nft_chain *chain,
1060 const struct nlattr * const *nla)
1062 ctx->net = sock_net(skb->sk);
1076 * nft_register_expr - register nf_tables expr type
1079 * Registers the expr type for use with nf_tables. Returns zero on
1080 * success or a negative errno code otherwise.
1082 int nft_register_expr(struct nft_expr_type *type)
1084 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1085 list_add_tail(&type->list, &nf_tables_expressions);
1086 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1089 EXPORT_SYMBOL_GPL(nft_register_expr);
1092 * nft_unregister_expr - unregister nf_tables expr type
1095 * Unregisters the expr typefor use with nf_tables.
1097 void nft_unregister_expr(struct nft_expr_type *type)
1099 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1100 list_del(&type->list);
1101 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1103 EXPORT_SYMBOL_GPL(nft_unregister_expr);
1105 static const struct nft_expr_type *__nft_expr_type_get(struct nlattr *nla)
1107 const struct nft_expr_type *type;
1109 list_for_each_entry(type, &nf_tables_expressions, list) {
1110 if (!nla_strcmp(nla, type->name))
1116 static const struct nft_expr_type *nft_expr_type_get(struct nlattr *nla)
1118 const struct nft_expr_type *type;
1121 return ERR_PTR(-EINVAL);
1123 type = __nft_expr_type_get(nla);
1124 if (type != NULL && try_module_get(type->owner))
1127 #ifdef CONFIG_MODULES
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);
1133 if (__nft_expr_type_get(nla))
1134 return ERR_PTR(-EAGAIN);
1137 return ERR_PTR(-ENOENT);
1140 static 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 },
1145 static int nf_tables_fill_expr_info(struct sk_buff *skb,
1146 const struct nft_expr *expr)
1148 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
1149 goto nla_put_failure;
1151 if (expr->ops->dump) {
1152 struct nlattr *data = nla_nest_start(skb, NFTA_EXPR_DATA);
1154 goto nla_put_failure;
1155 if (expr->ops->dump(skb, expr) < 0)
1156 goto nla_put_failure;
1157 nla_nest_end(skb, data);
1166 struct nft_expr_info {
1167 const struct nft_expr_ops *ops;
1168 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
1171 static int nf_tables_expr_parse(const struct nft_ctx *ctx,
1172 const struct nlattr *nla,
1173 struct nft_expr_info *info)
1175 const struct nft_expr_type *type;
1176 const struct nft_expr_ops *ops;
1177 struct nlattr *tb[NFTA_EXPR_MAX + 1];
1180 err = nla_parse_nested(tb, NFTA_EXPR_MAX, nla, nft_expr_policy);
1184 type = nft_expr_type_get(tb[NFTA_EXPR_NAME]);
1186 return PTR_ERR(type);
1188 if (tb[NFTA_EXPR_DATA]) {
1189 err = nla_parse_nested(info->tb, type->maxattr,
1190 tb[NFTA_EXPR_DATA], type->policy);
1194 memset(info->tb, 0, sizeof(info->tb[0]) * (type->maxattr + 1));
1196 if (type->select_ops != NULL) {
1197 ops = type->select_ops(ctx,
1198 (const struct nlattr * const *)info->tb);
1210 module_put(type->owner);
1214 static int nf_tables_newexpr(const struct nft_ctx *ctx,
1215 const struct nft_expr_info *info,
1216 struct nft_expr *expr)
1218 const struct nft_expr_ops *ops = info->ops;
1223 err = ops->init(ctx, expr, (const struct nlattr **)info->tb);
1235 static void nf_tables_expr_destroy(struct nft_expr *expr)
1237 if (expr->ops->destroy)
1238 expr->ops->destroy(expr);
1239 module_put(expr->ops->type->owner);
1246 static struct nft_rule *__nf_tables_rule_lookup(const struct nft_chain *chain,
1249 struct nft_rule *rule;
1251 // FIXME: this sucks
1252 list_for_each_entry(rule, &chain->rules, list) {
1253 if (handle == rule->handle)
1257 return ERR_PTR(-ENOENT);
1260 static struct nft_rule *nf_tables_rule_lookup(const struct nft_chain *chain,
1261 const struct nlattr *nla)
1264 return ERR_PTR(-EINVAL);
1266 return __nf_tables_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
1269 static 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 },
1275 [NFTA_RULE_COMPAT] = { .type = NLA_NESTED },
1278 static int nf_tables_fill_rule_info(struct sk_buff *skb, u32 portid, u32 seq,
1279 int event, u32 flags, int family,
1280 const struct nft_table *table,
1281 const struct nft_chain *chain,
1282 const struct nft_rule *rule)
1284 struct nlmsghdr *nlh;
1285 struct nfgenmsg *nfmsg;
1286 const struct nft_expr *expr, *next;
1287 struct nlattr *list;
1289 event |= NFNL_SUBSYS_NFTABLES << 8;
1290 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
1293 goto nla_put_failure;
1295 nfmsg = nlmsg_data(nlh);
1296 nfmsg->nfgen_family = family;
1297 nfmsg->version = NFNETLINK_V0;
1300 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
1301 goto nla_put_failure;
1302 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
1303 goto nla_put_failure;
1304 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle)))
1305 goto nla_put_failure;
1307 list = nla_nest_start(skb, NFTA_RULE_EXPRESSIONS);
1309 goto nla_put_failure;
1310 nft_rule_for_each_expr(expr, next, rule) {
1311 struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM);
1313 goto nla_put_failure;
1314 if (nf_tables_fill_expr_info(skb, expr) < 0)
1315 goto nla_put_failure;
1316 nla_nest_end(skb, elem);
1318 nla_nest_end(skb, list);
1320 return nlmsg_end(skb, nlh);
1323 nlmsg_trim(skb, nlh);
1327 static int nf_tables_rule_notify(const struct sk_buff *oskb,
1328 const struct nlmsghdr *nlh,
1329 const struct nft_table *table,
1330 const struct nft_chain *chain,
1331 const struct nft_rule *rule,
1332 int event, u32 flags, int family)
1334 struct sk_buff *skb;
1335 u32 portid = NETLINK_CB(oskb).portid;
1336 struct net *net = oskb ? sock_net(oskb->sk) : &init_net;
1337 u32 seq = nlh->nlmsg_seq;
1341 report = nlmsg_report(nlh);
1342 if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
1346 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1350 err = nf_tables_fill_rule_info(skb, portid, seq, event, flags,
1351 family, table, chain, rule);
1357 err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report,
1361 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
1365 static int nf_tables_dump_rules(struct sk_buff *skb,
1366 struct netlink_callback *cb)
1368 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1369 const struct nft_af_info *afi;
1370 const struct nft_table *table;
1371 const struct nft_chain *chain;
1372 const struct nft_rule *rule;
1373 unsigned int idx = 0, s_idx = cb->args[0];
1374 struct net *net = sock_net(skb->sk);
1375 int family = nfmsg->nfgen_family;
1377 list_for_each_entry(afi, &net->nft.af_info, list) {
1378 if (family != NFPROTO_UNSPEC && family != afi->family)
1381 list_for_each_entry(table, &afi->tables, list) {
1382 list_for_each_entry(chain, &table->chains, list) {
1383 list_for_each_entry(rule, &chain->rules, list) {
1387 memset(&cb->args[1], 0,
1388 sizeof(cb->args) - sizeof(cb->args[0]));
1389 if (nf_tables_fill_rule_info(skb, NETLINK_CB(cb->skb).portid,
1392 NLM_F_MULTI | NLM_F_APPEND,
1393 afi->family, table, chain, rule) < 0)
1406 static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb,
1407 const struct nlmsghdr *nlh,
1408 const struct nlattr * const nla[])
1410 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1411 const struct nft_af_info *afi;
1412 const struct nft_table *table;
1413 const struct nft_chain *chain;
1414 const struct nft_rule *rule;
1415 struct sk_buff *skb2;
1416 struct net *net = sock_net(skb->sk);
1417 int family = nfmsg->nfgen_family;
1420 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1421 struct netlink_dump_control c = {
1422 .dump = nf_tables_dump_rules,
1424 return netlink_dump_start(nlsk, skb, nlh, &c);
1427 afi = nf_tables_afinfo_lookup(net, family, false);
1429 return PTR_ERR(afi);
1431 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
1433 return PTR_ERR(table);
1435 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1437 return PTR_ERR(chain);
1439 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
1441 return PTR_ERR(rule);
1443 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1447 err = nf_tables_fill_rule_info(skb2, NETLINK_CB(skb).portid,
1448 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
1449 family, table, chain, rule);
1453 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1460 static void nf_tables_rcu_rule_destroy(struct rcu_head *head)
1462 struct nft_rule *rule = container_of(head, struct nft_rule, rcu_head);
1463 struct nft_expr *expr;
1466 * Careful: some expressions might not be initialized in case this
1467 * is called on error from nf_tables_newrule().
1469 expr = nft_expr_first(rule);
1470 while (expr->ops && expr != nft_expr_last(rule)) {
1471 nf_tables_expr_destroy(expr);
1472 expr = nft_expr_next(expr);
1477 static void nf_tables_rule_destroy(struct nft_rule *rule)
1479 call_rcu(&rule->rcu_head, nf_tables_rcu_rule_destroy);
1482 #define NFT_RULE_MAXEXPRS 128
1484 static struct nft_expr_info *info;
1486 static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
1487 const struct nlmsghdr *nlh,
1488 const struct nlattr * const nla[])
1490 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1491 const struct nft_af_info *afi;
1492 struct net *net = sock_net(skb->sk);
1493 struct nft_table *table;
1494 struct nft_chain *chain;
1495 struct nft_rule *rule, *old_rule = NULL;
1496 struct nft_expr *expr;
1499 unsigned int size, i, n;
1504 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
1506 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
1508 return PTR_ERR(afi);
1510 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
1512 return PTR_ERR(table);
1514 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1516 return PTR_ERR(chain);
1518 if (nla[NFTA_RULE_HANDLE]) {
1519 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
1520 rule = __nf_tables_rule_lookup(chain, handle);
1522 return PTR_ERR(rule);
1524 if (nlh->nlmsg_flags & NLM_F_EXCL)
1526 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1531 if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
1533 handle = nf_tables_alloc_handle(table);
1536 nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
1540 if (nla[NFTA_RULE_EXPRESSIONS]) {
1541 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
1543 if (nla_type(tmp) != NFTA_LIST_ELEM)
1545 if (n == NFT_RULE_MAXEXPRS)
1547 err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
1550 size += info[n].ops->size;
1556 rule = kzalloc(sizeof(*rule) + size, GFP_KERNEL);
1560 rule->handle = handle;
1563 expr = nft_expr_first(rule);
1564 for (i = 0; i < n; i++) {
1565 err = nf_tables_newexpr(&ctx, &info[i], expr);
1569 expr = nft_expr_next(expr);
1572 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
1573 list_replace_rcu(&old_rule->list, &rule->list);
1574 nf_tables_rule_destroy(old_rule);
1575 } else if (nlh->nlmsg_flags & NLM_F_APPEND)
1576 list_add_tail_rcu(&rule->list, &chain->rules);
1578 list_add_rcu(&rule->list, &chain->rules);
1580 nf_tables_rule_notify(skb, nlh, table, chain, rule, NFT_MSG_NEWRULE,
1581 nlh->nlmsg_flags & (NLM_F_APPEND | NLM_F_REPLACE),
1582 nfmsg->nfgen_family);
1586 nf_tables_rule_destroy(rule);
1588 for (i = 0; i < n; i++) {
1589 if (info[i].ops != NULL)
1590 module_put(info[i].ops->type->owner);
1595 static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
1596 const struct nlmsghdr *nlh,
1597 const struct nlattr * const nla[])
1599 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1600 const struct nft_af_info *afi;
1601 struct net *net = sock_net(skb->sk);
1602 const struct nft_table *table;
1603 struct nft_chain *chain;
1604 struct nft_rule *rule, *tmp;
1605 int family = nfmsg->nfgen_family;
1607 afi = nf_tables_afinfo_lookup(net, family, false);
1609 return PTR_ERR(afi);
1611 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
1613 return PTR_ERR(table);
1615 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
1617 return PTR_ERR(chain);
1619 if (nla[NFTA_RULE_HANDLE]) {
1620 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
1622 return PTR_ERR(rule);
1624 /* List removal must be visible before destroying expressions */
1625 list_del_rcu(&rule->list);
1627 nf_tables_rule_notify(skb, nlh, table, chain, rule,
1628 NFT_MSG_DELRULE, 0, family);
1629 nf_tables_rule_destroy(rule);
1631 /* Remove all rules in this chain */
1632 list_for_each_entry_safe(rule, tmp, &chain->rules, list) {
1633 list_del_rcu(&rule->list);
1635 nf_tables_rule_notify(skb, nlh, table, chain, rule,
1636 NFT_MSG_DELRULE, 0, family);
1637 nf_tables_rule_destroy(rule);
1648 static LIST_HEAD(nf_tables_set_ops);
1650 int nft_register_set(struct nft_set_ops *ops)
1652 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1653 list_add_tail(&ops->list, &nf_tables_set_ops);
1654 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1657 EXPORT_SYMBOL_GPL(nft_register_set);
1659 void nft_unregister_set(struct nft_set_ops *ops)
1661 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1662 list_del(&ops->list);
1663 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1665 EXPORT_SYMBOL_GPL(nft_unregister_set);
1667 static const struct nft_set_ops *nft_select_set_ops(const struct nlattr * const nla[])
1669 const struct nft_set_ops *ops;
1672 #ifdef CONFIG_MODULES
1673 if (list_empty(&nf_tables_set_ops)) {
1674 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1675 request_module("nft-set");
1676 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1677 if (!list_empty(&nf_tables_set_ops))
1678 return ERR_PTR(-EAGAIN);
1682 if (nla[NFTA_SET_FLAGS] != NULL) {
1683 features = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
1684 features &= NFT_SET_INTERVAL | NFT_SET_MAP;
1687 // FIXME: implement selection properly
1688 list_for_each_entry(ops, &nf_tables_set_ops, list) {
1689 if ((ops->features & features) != features)
1691 if (!try_module_get(ops->owner))
1696 return ERR_PTR(-EOPNOTSUPP);
1699 static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
1700 [NFTA_SET_TABLE] = { .type = NLA_STRING },
1701 [NFTA_SET_NAME] = { .type = NLA_STRING },
1702 [NFTA_SET_FLAGS] = { .type = NLA_U32 },
1703 [NFTA_SET_KEY_TYPE] = { .type = NLA_U32 },
1704 [NFTA_SET_KEY_LEN] = { .type = NLA_U32 },
1705 [NFTA_SET_DATA_TYPE] = { .type = NLA_U32 },
1706 [NFTA_SET_DATA_LEN] = { .type = NLA_U32 },
1709 static int nft_ctx_init_from_setattr(struct nft_ctx *ctx,
1710 const struct sk_buff *skb,
1711 const struct nlmsghdr *nlh,
1712 const struct nlattr * const nla[])
1714 struct net *net = sock_net(skb->sk);
1715 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1716 const struct nft_af_info *afi;
1717 const struct nft_table *table = NULL;
1719 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
1721 return PTR_ERR(afi);
1723 if (nla[NFTA_SET_TABLE] != NULL) {
1724 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
1726 return PTR_ERR(table);
1729 nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
1733 struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
1734 const struct nlattr *nla)
1736 struct nft_set *set;
1739 return ERR_PTR(-EINVAL);
1741 list_for_each_entry(set, &table->sets, list) {
1742 if (!nla_strcmp(nla, set->name))
1745 return ERR_PTR(-ENOENT);
1748 static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
1751 const struct nft_set *i;
1753 unsigned long *inuse;
1756 p = strnchr(name, IFNAMSIZ, '%');
1758 if (p[1] != 'd' || strchr(p + 2, '%'))
1761 inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
1765 list_for_each_entry(i, &ctx->table->sets, list) {
1766 if (!sscanf(i->name, name, &n))
1768 if (n < 0 || n > BITS_PER_LONG * PAGE_SIZE)
1773 n = find_first_zero_bit(inuse, BITS_PER_LONG * PAGE_SIZE);
1774 free_page((unsigned long)inuse);
1777 snprintf(set->name, sizeof(set->name), name, n);
1778 list_for_each_entry(i, &ctx->table->sets, list) {
1779 if (!strcmp(set->name, i->name))
1785 static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
1786 const struct nft_set *set, u16 event, u16 flags)
1788 struct nfgenmsg *nfmsg;
1789 struct nlmsghdr *nlh;
1790 u32 portid = NETLINK_CB(ctx->skb).portid;
1791 u32 seq = ctx->nlh->nlmsg_seq;
1793 event |= NFNL_SUBSYS_NFTABLES << 8;
1794 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
1797 goto nla_put_failure;
1799 nfmsg = nlmsg_data(nlh);
1800 nfmsg->nfgen_family = ctx->afi->family;
1801 nfmsg->version = NFNETLINK_V0;
1804 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
1805 goto nla_put_failure;
1806 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
1807 goto nla_put_failure;
1808 if (set->flags != 0)
1809 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
1810 goto nla_put_failure;
1812 if (nla_put_be32(skb, NFTA_SET_KEY_TYPE, htonl(set->ktype)))
1813 goto nla_put_failure;
1814 if (nla_put_be32(skb, NFTA_SET_KEY_LEN, htonl(set->klen)))
1815 goto nla_put_failure;
1816 if (set->flags & NFT_SET_MAP) {
1817 if (nla_put_be32(skb, NFTA_SET_DATA_TYPE, htonl(set->dtype)))
1818 goto nla_put_failure;
1819 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
1820 goto nla_put_failure;
1823 return nlmsg_end(skb, nlh);
1826 nlmsg_trim(skb, nlh);
1830 static int nf_tables_set_notify(const struct nft_ctx *ctx,
1831 const struct nft_set *set,
1834 struct sk_buff *skb;
1835 u32 portid = NETLINK_CB(ctx->skb).portid;
1839 report = nlmsg_report(ctx->nlh);
1840 if (!report && !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
1844 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1848 err = nf_tables_fill_set(skb, ctx, set, event, 0);
1854 err = nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, report,
1858 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, err);
1862 static int nf_tables_dump_sets_table(struct nft_ctx *ctx, struct sk_buff *skb,
1863 struct netlink_callback *cb)
1865 const struct nft_set *set;
1866 unsigned int idx = 0, s_idx = cb->args[0];
1871 list_for_each_entry(set, &ctx->table->sets, list) {
1874 if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
1887 static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
1888 struct netlink_callback *cb)
1890 const struct nft_set *set;
1891 unsigned int idx = 0, s_idx = cb->args[0];
1892 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
1897 list_for_each_entry(table, &ctx->afi->tables, list) {
1898 if (cur_table && cur_table != table)
1902 list_for_each_entry(set, &ctx->table->sets, list) {
1905 if (nf_tables_fill_set(skb, ctx, set, NFT_MSG_NEWSET,
1908 cb->args[2] = (unsigned long) table;
1920 static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
1922 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1923 struct nlattr *nla[NFTA_SET_MAX + 1];
1927 err = nlmsg_parse(cb->nlh, sizeof(*nfmsg), nla, NFTA_SET_MAX,
1932 err = nft_ctx_init_from_setattr(&ctx, cb->skb, cb->nlh, (void *)nla);
1936 if (ctx.table == NULL)
1937 ret = nf_tables_dump_sets_all(&ctx, skb, cb);
1939 ret = nf_tables_dump_sets_table(&ctx, skb, cb);
1944 static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
1945 const struct nlmsghdr *nlh,
1946 const struct nlattr * const nla[])
1948 const struct nft_set *set;
1950 struct sk_buff *skb2;
1953 /* Verify existance before starting dump */
1954 err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
1958 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1959 struct netlink_dump_control c = {
1960 .dump = nf_tables_dump_sets,
1962 return netlink_dump_start(nlsk, skb, nlh, &c);
1965 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
1967 return PTR_ERR(set);
1969 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1973 err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
1977 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1984 static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
1985 const struct nlmsghdr *nlh,
1986 const struct nlattr * const nla[])
1988 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1989 const struct nft_set_ops *ops;
1990 const struct nft_af_info *afi;
1991 struct net *net = sock_net(skb->sk);
1992 struct nft_table *table;
1993 struct nft_set *set;
1995 char name[IFNAMSIZ];
1998 u32 ktype, klen, dlen, dtype, flags;
2001 if (nla[NFTA_SET_TABLE] == NULL ||
2002 nla[NFTA_SET_NAME] == NULL ||
2003 nla[NFTA_SET_KEY_LEN] == NULL)
2006 ktype = NFT_DATA_VALUE;
2007 if (nla[NFTA_SET_KEY_TYPE] != NULL) {
2008 ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
2009 if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
2013 klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
2014 if (klen == 0 || klen > FIELD_SIZEOF(struct nft_data, data))
2018 if (nla[NFTA_SET_FLAGS] != NULL) {
2019 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2020 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
2021 NFT_SET_INTERVAL | NFT_SET_MAP))
2027 if (nla[NFTA_SET_DATA_TYPE] != NULL) {
2028 if (!(flags & NFT_SET_MAP))
2031 dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
2032 if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
2033 dtype != NFT_DATA_VERDICT)
2036 if (dtype != NFT_DATA_VERDICT) {
2037 if (nla[NFTA_SET_DATA_LEN] == NULL)
2039 dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
2041 dlen > FIELD_SIZEOF(struct nft_data, data))
2044 dlen = sizeof(struct nft_data);
2045 } else if (flags & NFT_SET_MAP)
2048 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
2050 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
2052 return PTR_ERR(afi);
2054 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
2056 return PTR_ERR(table);
2058 nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
2060 set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME]);
2062 if (PTR_ERR(set) != -ENOENT)
2063 return PTR_ERR(set);
2068 if (nlh->nlmsg_flags & NLM_F_EXCL)
2070 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2075 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
2078 ops = nft_select_set_ops(nla);
2080 return PTR_ERR(ops);
2083 if (ops->privsize != NULL)
2084 size = ops->privsize(nla);
2087 set = kzalloc(sizeof(*set) + size, GFP_KERNEL);
2091 nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name));
2092 err = nf_tables_set_alloc_name(&ctx, set, name);
2096 INIT_LIST_HEAD(&set->bindings);
2104 err = ops->init(set, nla);
2108 list_add_tail(&set->list, &table->sets);
2109 nf_tables_set_notify(&ctx, set, NFT_MSG_NEWSET);
2115 module_put(ops->owner);
2119 static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
2121 list_del(&set->list);
2122 if (!(set->flags & NFT_SET_ANONYMOUS))
2123 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET);
2125 set->ops->destroy(set);
2126 module_put(set->ops->owner);
2130 static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
2131 const struct nlmsghdr *nlh,
2132 const struct nlattr * const nla[])
2134 struct nft_set *set;
2138 if (nla[NFTA_SET_TABLE] == NULL)
2141 err = nft_ctx_init_from_setattr(&ctx, skb, nlh, nla);
2145 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2147 return PTR_ERR(set);
2148 if (!list_empty(&set->bindings))
2151 nf_tables_set_destroy(&ctx, set);
2155 static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
2156 const struct nft_set *set,
2157 const struct nft_set_iter *iter,
2158 const struct nft_set_elem *elem)
2160 enum nft_registers dreg;
2162 dreg = nft_type_to_reg(set->dtype);
2163 return nft_validate_data_load(ctx, dreg, &elem->data, set->dtype);
2166 int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
2167 struct nft_set_binding *binding)
2169 struct nft_set_binding *i;
2170 struct nft_set_iter iter;
2172 if (!list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
2175 if (set->flags & NFT_SET_MAP) {
2176 /* If the set is already bound to the same chain all
2177 * jumps are already validated for that chain.
2179 list_for_each_entry(i, &set->bindings, list) {
2180 if (i->chain == binding->chain)
2187 iter.fn = nf_tables_bind_check_setelem;
2189 set->ops->walk(ctx, set, &iter);
2191 /* Destroy anonymous sets if binding fails */
2192 if (set->flags & NFT_SET_ANONYMOUS)
2193 nf_tables_set_destroy(ctx, set);
2199 binding->chain = ctx->chain;
2200 list_add_tail(&binding->list, &set->bindings);
2204 void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
2205 struct nft_set_binding *binding)
2207 list_del(&binding->list);
2209 if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
2210 nf_tables_set_destroy(ctx, set);
2217 static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
2218 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
2219 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
2220 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
2223 static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
2224 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING },
2225 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING },
2226 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
2229 static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx,
2230 const struct sk_buff *skb,
2231 const struct nlmsghdr *nlh,
2232 const struct nlattr * const nla[])
2234 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2235 const struct nft_af_info *afi;
2236 const struct nft_table *table;
2237 struct net *net = sock_net(skb->sk);
2239 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
2241 return PTR_ERR(afi);
2243 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]);
2245 return PTR_ERR(table);
2247 nft_ctx_init(ctx, skb, nlh, afi, table, NULL, nla);
2251 static int nf_tables_fill_setelem(struct sk_buff *skb,
2252 const struct nft_set *set,
2253 const struct nft_set_elem *elem)
2255 unsigned char *b = skb_tail_pointer(skb);
2256 struct nlattr *nest;
2258 nest = nla_nest_start(skb, NFTA_LIST_ELEM);
2260 goto nla_put_failure;
2262 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, &elem->key, NFT_DATA_VALUE,
2264 goto nla_put_failure;
2266 if (set->flags & NFT_SET_MAP &&
2267 !(elem->flags & NFT_SET_ELEM_INTERVAL_END) &&
2268 nft_data_dump(skb, NFTA_SET_ELEM_DATA, &elem->data,
2269 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
2271 goto nla_put_failure;
2273 if (elem->flags != 0)
2274 if (nla_put_be32(skb, NFTA_SET_ELEM_FLAGS, htonl(elem->flags)))
2275 goto nla_put_failure;
2277 nla_nest_end(skb, nest);
2285 struct nft_set_dump_args {
2286 const struct netlink_callback *cb;
2287 struct nft_set_iter iter;
2288 struct sk_buff *skb;
2291 static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
2292 const struct nft_set *set,
2293 const struct nft_set_iter *iter,
2294 const struct nft_set_elem *elem)
2296 struct nft_set_dump_args *args;
2298 args = container_of(iter, struct nft_set_dump_args, iter);
2299 return nf_tables_fill_setelem(args->skb, set, elem);
2302 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
2304 const struct nft_set *set;
2305 struct nft_set_dump_args args;
2307 struct nlattr *nla[NFTA_SET_ELEM_LIST_MAX + 1];
2308 struct nfgenmsg *nfmsg;
2309 struct nlmsghdr *nlh;
2310 struct nlattr *nest;
2314 nfmsg = nlmsg_data(cb->nlh);
2315 err = nlmsg_parse(cb->nlh, sizeof(*nfmsg), nla, NFTA_SET_ELEM_LIST_MAX,
2316 nft_set_elem_list_policy);
2320 err = nft_ctx_init_from_elemattr(&ctx, cb->skb, cb->nlh, (void *)nla);
2324 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2326 return PTR_ERR(set);
2328 event = NFT_MSG_NEWSETELEM;
2329 event |= NFNL_SUBSYS_NFTABLES << 8;
2330 portid = NETLINK_CB(cb->skb).portid;
2331 seq = cb->nlh->nlmsg_seq;
2333 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
2336 goto nla_put_failure;
2338 nfmsg = nlmsg_data(nlh);
2339 nfmsg->nfgen_family = NFPROTO_UNSPEC;
2340 nfmsg->version = NFNETLINK_V0;
2343 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, ctx.table->name))
2344 goto nla_put_failure;
2345 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
2346 goto nla_put_failure;
2348 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
2350 goto nla_put_failure;
2354 args.iter.skip = cb->args[0];
2355 args.iter.count = 0;
2357 args.iter.fn = nf_tables_dump_setelem;
2358 set->ops->walk(&ctx, set, &args.iter);
2360 nla_nest_end(skb, nest);
2361 nlmsg_end(skb, nlh);
2363 if (args.iter.err && args.iter.err != -EMSGSIZE)
2364 return args.iter.err;
2365 if (args.iter.count == cb->args[0])
2368 cb->args[0] = args.iter.count;
2375 static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb,
2376 const struct nlmsghdr *nlh,
2377 const struct nlattr * const nla[])
2379 const struct nft_set *set;
2383 err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla);
2387 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2389 return PTR_ERR(set);
2391 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2392 struct netlink_dump_control c = {
2393 .dump = nf_tables_dump_set,
2395 return netlink_dump_start(nlsk, skb, nlh, &c);
2400 static int nft_add_set_elem(const struct nft_ctx *ctx, struct nft_set *set,
2401 const struct nlattr *attr)
2403 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
2404 struct nft_data_desc d1, d2;
2405 struct nft_set_elem elem;
2406 struct nft_set_binding *binding;
2407 enum nft_registers dreg;
2410 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
2411 nft_set_elem_policy);
2415 if (nla[NFTA_SET_ELEM_KEY] == NULL)
2419 if (nla[NFTA_SET_ELEM_FLAGS] != NULL) {
2420 elem.flags = ntohl(nla_get_be32(nla[NFTA_SET_ELEM_FLAGS]));
2421 if (elem.flags & ~NFT_SET_ELEM_INTERVAL_END)
2425 if (set->flags & NFT_SET_MAP) {
2426 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
2427 !(elem.flags & NFT_SET_ELEM_INTERVAL_END))
2430 if (nla[NFTA_SET_ELEM_DATA] != NULL)
2434 err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]);
2438 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
2442 if (set->ops->get(set, &elem) == 0)
2445 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
2446 err = nft_data_init(ctx, &elem.data, &d2, nla[NFTA_SET_ELEM_DATA]);
2451 if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
2454 dreg = nft_type_to_reg(set->dtype);
2455 list_for_each_entry(binding, &set->bindings, list) {
2456 struct nft_ctx bind_ctx = {
2458 .table = ctx->table,
2459 .chain = binding->chain,
2462 err = nft_validate_data_load(&bind_ctx, dreg,
2463 &elem.data, d2.type);
2469 err = set->ops->insert(set, &elem);
2476 if (nla[NFTA_SET_ELEM_DATA] != NULL)
2477 nft_data_uninit(&elem.data, d2.type);
2479 nft_data_uninit(&elem.key, d1.type);
2484 static int nf_tables_newsetelem(struct sock *nlsk, struct sk_buff *skb,
2485 const struct nlmsghdr *nlh,
2486 const struct nlattr * const nla[])
2488 const struct nlattr *attr;
2489 struct nft_set *set;
2493 err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla);
2497 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2499 return PTR_ERR(set);
2500 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
2503 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
2504 err = nft_add_set_elem(&ctx, set, attr);
2511 static int nft_del_setelem(const struct nft_ctx *ctx, struct nft_set *set,
2512 const struct nlattr *attr)
2514 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
2515 struct nft_data_desc desc;
2516 struct nft_set_elem elem;
2519 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
2520 nft_set_elem_policy);
2525 if (nla[NFTA_SET_ELEM_KEY] == NULL)
2528 err = nft_data_init(ctx, &elem.key, &desc, nla[NFTA_SET_ELEM_KEY]);
2533 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
2536 err = set->ops->get(set, &elem);
2540 set->ops->remove(set, &elem);
2542 nft_data_uninit(&elem.key, NFT_DATA_VALUE);
2543 if (set->flags & NFT_SET_MAP)
2544 nft_data_uninit(&elem.data, set->dtype);
2547 nft_data_uninit(&elem.key, desc.type);
2552 static int nf_tables_delsetelem(struct sock *nlsk, struct sk_buff *skb,
2553 const struct nlmsghdr *nlh,
2554 const struct nlattr * const nla[])
2556 const struct nlattr *attr;
2557 struct nft_set *set;
2561 err = nft_ctx_init_from_elemattr(&ctx, skb, nlh, nla);
2565 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
2567 return PTR_ERR(set);
2568 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
2571 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
2572 err = nft_del_setelem(&ctx, set, attr);
2579 static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
2580 [NFT_MSG_NEWTABLE] = {
2581 .call = nf_tables_newtable,
2582 .attr_count = NFTA_TABLE_MAX,
2583 .policy = nft_table_policy,
2585 [NFT_MSG_GETTABLE] = {
2586 .call = nf_tables_gettable,
2587 .attr_count = NFTA_TABLE_MAX,
2588 .policy = nft_table_policy,
2590 [NFT_MSG_DELTABLE] = {
2591 .call = nf_tables_deltable,
2592 .attr_count = NFTA_TABLE_MAX,
2593 .policy = nft_table_policy,
2595 [NFT_MSG_NEWCHAIN] = {
2596 .call = nf_tables_newchain,
2597 .attr_count = NFTA_CHAIN_MAX,
2598 .policy = nft_chain_policy,
2600 [NFT_MSG_GETCHAIN] = {
2601 .call = nf_tables_getchain,
2602 .attr_count = NFTA_CHAIN_MAX,
2603 .policy = nft_chain_policy,
2605 [NFT_MSG_DELCHAIN] = {
2606 .call = nf_tables_delchain,
2607 .attr_count = NFTA_CHAIN_MAX,
2608 .policy = nft_chain_policy,
2610 [NFT_MSG_NEWRULE] = {
2611 .call = nf_tables_newrule,
2612 .attr_count = NFTA_RULE_MAX,
2613 .policy = nft_rule_policy,
2615 [NFT_MSG_GETRULE] = {
2616 .call = nf_tables_getrule,
2617 .attr_count = NFTA_RULE_MAX,
2618 .policy = nft_rule_policy,
2620 [NFT_MSG_DELRULE] = {
2621 .call = nf_tables_delrule,
2622 .attr_count = NFTA_RULE_MAX,
2623 .policy = nft_rule_policy,
2625 [NFT_MSG_NEWSET] = {
2626 .call = nf_tables_newset,
2627 .attr_count = NFTA_SET_MAX,
2628 .policy = nft_set_policy,
2630 [NFT_MSG_GETSET] = {
2631 .call = nf_tables_getset,
2632 .attr_count = NFTA_SET_MAX,
2633 .policy = nft_set_policy,
2635 [NFT_MSG_DELSET] = {
2636 .call = nf_tables_delset,
2637 .attr_count = NFTA_SET_MAX,
2638 .policy = nft_set_policy,
2640 [NFT_MSG_NEWSETELEM] = {
2641 .call = nf_tables_newsetelem,
2642 .attr_count = NFTA_SET_ELEM_LIST_MAX,
2643 .policy = nft_set_elem_list_policy,
2645 [NFT_MSG_GETSETELEM] = {
2646 .call = nf_tables_getsetelem,
2647 .attr_count = NFTA_SET_ELEM_LIST_MAX,
2648 .policy = nft_set_elem_list_policy,
2650 [NFT_MSG_DELSETELEM] = {
2651 .call = nf_tables_delsetelem,
2652 .attr_count = NFTA_SET_ELEM_LIST_MAX,
2653 .policy = nft_set_elem_list_policy,
2657 static const struct nfnetlink_subsystem nf_tables_subsys = {
2658 .name = "nf_tables",
2659 .subsys_id = NFNL_SUBSYS_NFTABLES,
2660 .cb_count = NFT_MSG_MAX,
2665 * Loop detection - walk through the ruleset beginning at the destination chain
2666 * of a new jump until either the source chain is reached (loop) or all
2667 * reachable chains have been traversed.
2669 * The loop check is performed whenever a new jump verdict is added to an
2670 * expression or verdict map or a verdict map is bound to a new chain.
2673 static int nf_tables_check_loops(const struct nft_ctx *ctx,
2674 const struct nft_chain *chain);
2676 static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
2677 const struct nft_set *set,
2678 const struct nft_set_iter *iter,
2679 const struct nft_set_elem *elem)
2681 switch (elem->data.verdict) {
2684 return nf_tables_check_loops(ctx, elem->data.chain);
2690 static int nf_tables_check_loops(const struct nft_ctx *ctx,
2691 const struct nft_chain *chain)
2693 const struct nft_rule *rule;
2694 const struct nft_expr *expr, *last;
2695 const struct nft_set *set;
2696 struct nft_set_binding *binding;
2697 struct nft_set_iter iter;
2699 if (ctx->chain == chain)
2702 list_for_each_entry(rule, &chain->rules, list) {
2703 nft_rule_for_each_expr(expr, last, rule) {
2704 const struct nft_data *data = NULL;
2707 if (!expr->ops->validate)
2710 err = expr->ops->validate(ctx, expr, &data);
2717 switch (data->verdict) {
2720 err = nf_tables_check_loops(ctx, data->chain);
2729 list_for_each_entry(set, &ctx->table->sets, list) {
2730 if (!(set->flags & NFT_SET_MAP) ||
2731 set->dtype != NFT_DATA_VERDICT)
2734 list_for_each_entry(binding, &set->bindings, list) {
2735 if (binding->chain != chain)
2741 iter.fn = nf_tables_loop_check_setelem;
2743 set->ops->walk(ctx, set, &iter);
2753 * nft_validate_input_register - validate an expressions' input register
2755 * @reg: the register number
2757 * Validate that the input register is one of the general purpose
2760 int nft_validate_input_register(enum nft_registers reg)
2762 if (reg <= NFT_REG_VERDICT)
2764 if (reg > NFT_REG_MAX)
2768 EXPORT_SYMBOL_GPL(nft_validate_input_register);
2771 * nft_validate_output_register - validate an expressions' output register
2773 * @reg: the register number
2775 * Validate that the output register is one of the general purpose
2776 * registers or the verdict register.
2778 int nft_validate_output_register(enum nft_registers reg)
2780 if (reg < NFT_REG_VERDICT)
2782 if (reg > NFT_REG_MAX)
2786 EXPORT_SYMBOL_GPL(nft_validate_output_register);
2789 * nft_validate_data_load - validate an expressions' data load
2791 * @ctx: context of the expression performing the load
2792 * @reg: the destination register number
2793 * @data: the data to load
2794 * @type: the data type
2796 * Validate that a data load uses the appropriate data type for
2797 * the destination register. A value of NULL for the data means
2798 * that its runtime gathered data, which is always of type
2801 int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg,
2802 const struct nft_data *data,
2803 enum nft_data_types type)
2808 case NFT_REG_VERDICT:
2809 if (data == NULL || type != NFT_DATA_VERDICT)
2812 if (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP) {
2813 err = nf_tables_check_loops(ctx, data->chain);
2817 if (ctx->chain->level + 1 > data->chain->level) {
2818 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
2820 data->chain->level = ctx->chain->level + 1;
2826 if (data != NULL && type != NFT_DATA_VALUE)
2831 EXPORT_SYMBOL_GPL(nft_validate_data_load);
2833 static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
2834 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
2835 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
2836 .len = NFT_CHAIN_MAXNAMELEN - 1 },
2839 static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
2840 struct nft_data_desc *desc, const struct nlattr *nla)
2842 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
2843 struct nft_chain *chain;
2846 err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy);
2850 if (!tb[NFTA_VERDICT_CODE])
2852 data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
2854 switch (data->verdict) {
2861 desc->len = sizeof(data->verdict);
2865 if (!tb[NFTA_VERDICT_CHAIN])
2867 chain = nf_tables_chain_lookup(ctx->table,
2868 tb[NFTA_VERDICT_CHAIN]);
2870 return PTR_ERR(chain);
2871 if (chain->flags & NFT_BASE_CHAIN)
2875 data->chain = chain;
2876 desc->len = sizeof(data);
2882 desc->type = NFT_DATA_VERDICT;
2886 static void nft_verdict_uninit(const struct nft_data *data)
2888 switch (data->verdict) {
2896 static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data)
2898 struct nlattr *nest;
2900 nest = nla_nest_start(skb, NFTA_DATA_VERDICT);
2902 goto nla_put_failure;
2904 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict)))
2905 goto nla_put_failure;
2907 switch (data->verdict) {
2910 if (nla_put_string(skb, NFTA_VERDICT_CHAIN, data->chain->name))
2911 goto nla_put_failure;
2913 nla_nest_end(skb, nest);
2920 static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
2921 struct nft_data_desc *desc, const struct nlattr *nla)
2928 if (len > sizeof(data->data))
2931 nla_memcpy(data->data, nla, sizeof(data->data));
2932 desc->type = NFT_DATA_VALUE;
2937 static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
2940 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
2943 static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
2944 [NFTA_DATA_VALUE] = { .type = NLA_BINARY,
2945 .len = FIELD_SIZEOF(struct nft_data, data) },
2946 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
2950 * nft_data_init - parse nf_tables data netlink attributes
2952 * @ctx: context of the expression using the data
2953 * @data: destination struct nft_data
2954 * @desc: data description
2955 * @nla: netlink attribute containing data
2957 * Parse the netlink data attributes and initialize a struct nft_data.
2958 * The type and length of data are returned in the data description.
2960 * The caller can indicate that it only wants to accept data of type
2961 * NFT_DATA_VALUE by passing NULL for the ctx argument.
2963 int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
2964 struct nft_data_desc *desc, const struct nlattr *nla)
2966 struct nlattr *tb[NFTA_DATA_MAX + 1];
2969 err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy);
2973 if (tb[NFTA_DATA_VALUE])
2974 return nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]);
2975 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
2976 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
2979 EXPORT_SYMBOL_GPL(nft_data_init);
2982 * nft_data_uninit - release a nft_data item
2984 * @data: struct nft_data to release
2985 * @type: type of data
2987 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
2988 * all others need to be released by calling this function.
2990 void nft_data_uninit(const struct nft_data *data, enum nft_data_types type)
2993 case NFT_DATA_VALUE:
2995 case NFT_DATA_VERDICT:
2996 return nft_verdict_uninit(data);
3001 EXPORT_SYMBOL_GPL(nft_data_uninit);
3003 int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
3004 enum nft_data_types type, unsigned int len)
3006 struct nlattr *nest;
3009 nest = nla_nest_start(skb, attr);
3014 case NFT_DATA_VALUE:
3015 err = nft_value_dump(skb, data, len);
3017 case NFT_DATA_VERDICT:
3018 err = nft_verdict_dump(skb, data);
3025 nla_nest_end(skb, nest);
3028 EXPORT_SYMBOL_GPL(nft_data_dump);
3030 static int nf_tables_init_net(struct net *net)
3032 INIT_LIST_HEAD(&net->nft.af_info);
3036 static struct pernet_operations nf_tables_net_ops = {
3037 .init = nf_tables_init_net,
3040 static int __init nf_tables_module_init(void)
3044 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
3051 err = nf_tables_core_module_init();
3055 err = nfnetlink_subsys_register(&nf_tables_subsys);
3059 pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
3060 return register_pernet_subsys(&nf_tables_net_ops);
3062 nf_tables_core_module_exit();
3069 static void __exit nf_tables_module_exit(void)
3071 unregister_pernet_subsys(&nf_tables_net_ops);
3072 nfnetlink_subsys_unregister(&nf_tables_subsys);
3073 nf_tables_core_module_exit();
3077 module_init(nf_tables_module_init);
3078 module_exit(nf_tables_module_exit);
3080 MODULE_LICENSE("GPL");
3081 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
3082 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);