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>
23 static LIST_HEAD(nf_tables_afinfo
);
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 nft_af_info
*afi
)
36 INIT_LIST_HEAD(&afi
->tables
);
37 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
38 list_add_tail(&afi
->list
, &nf_tables_afinfo
);
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(int family
)
61 struct nft_af_info
*afi
;
63 list_for_each_entry(afi
, &nf_tables_afinfo
, list
) {
64 if (afi
->family
== family
)
70 static struct nft_af_info
*nf_tables_afinfo_lookup(int family
, bool autoload
)
72 struct nft_af_info
*afi
;
74 afi
= nft_afinfo_lookup(family
);
79 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
80 request_module("nft-afinfo-%u", family
);
81 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
82 afi
= nft_afinfo_lookup(family
);
84 return ERR_PTR(-EAGAIN
);
87 return ERR_PTR(-EAFNOSUPPORT
);
94 static struct nft_table
*nft_table_lookup(const struct nft_af_info
*afi
,
95 const struct nlattr
*nla
)
97 struct nft_table
*table
;
99 list_for_each_entry(table
, &afi
->tables
, list
) {
100 if (!nla_strcmp(nla
, table
->name
))
106 static struct nft_table
*nf_tables_table_lookup(const struct nft_af_info
*afi
,
107 const struct nlattr
*nla
,
110 struct nft_table
*table
;
113 return ERR_PTR(-EINVAL
);
115 table
= nft_table_lookup(afi
, nla
);
119 #ifdef CONFIG_MODULES
121 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
122 request_module("nft-table-%u-%*.s", afi
->family
,
123 nla_len(nla
)-1, (const char *)nla_data(nla
));
124 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
125 if (nft_table_lookup(afi
, nla
))
126 return ERR_PTR(-EAGAIN
);
129 return ERR_PTR(-ENOENT
);
132 static inline u64
nf_tables_alloc_handle(struct nft_table
*table
)
134 return ++table
->hgenerator
;
137 static const struct nla_policy nft_table_policy
[NFTA_TABLE_MAX
+ 1] = {
138 [NFTA_TABLE_NAME
] = { .type
= NLA_STRING
},
141 static int nf_tables_fill_table_info(struct sk_buff
*skb
, u32 portid
, u32 seq
,
142 int event
, u32 flags
, int family
,
143 const struct nft_table
*table
)
145 struct nlmsghdr
*nlh
;
146 struct nfgenmsg
*nfmsg
;
148 event
|= NFNL_SUBSYS_NFTABLES
<< 8;
149 nlh
= nlmsg_put(skb
, portid
, seq
, event
, sizeof(struct nfgenmsg
), flags
);
151 goto nla_put_failure
;
153 nfmsg
= nlmsg_data(nlh
);
154 nfmsg
->nfgen_family
= family
;
155 nfmsg
->version
= NFNETLINK_V0
;
158 if (nla_put_string(skb
, NFTA_TABLE_NAME
, table
->name
))
159 goto nla_put_failure
;
161 return nlmsg_end(skb
, nlh
);
164 nlmsg_trim(skb
, nlh
);
168 static int nf_tables_table_notify(const struct sk_buff
*oskb
,
169 const struct nlmsghdr
*nlh
,
170 const struct nft_table
*table
,
171 int event
, int family
)
174 u32 portid
= oskb
? NETLINK_CB(oskb
).portid
: 0;
175 u32 seq
= nlh
? nlh
->nlmsg_seq
: 0;
176 struct net
*net
= oskb
? sock_net(oskb
->sk
) : &init_net
;
180 report
= nlh
? nlmsg_report(nlh
) : false;
181 if (!report
&& !nfnetlink_has_listeners(net
, NFNLGRP_NFTABLES
))
185 skb
= nlmsg_new(NLMSG_GOODSIZE
, GFP_KERNEL
);
189 err
= nf_tables_fill_table_info(skb
, portid
, seq
, event
, 0,
196 err
= nfnetlink_send(skb
, net
, portid
, NFNLGRP_NFTABLES
, report
,
200 nfnetlink_set_err(net
, portid
, NFNLGRP_NFTABLES
, err
);
204 static int nf_tables_dump_tables(struct sk_buff
*skb
,
205 struct netlink_callback
*cb
)
207 const struct nfgenmsg
*nfmsg
= nlmsg_data(cb
->nlh
);
208 const struct nft_af_info
*afi
;
209 const struct nft_table
*table
;
210 unsigned int idx
= 0, s_idx
= cb
->args
[0];
211 int family
= nfmsg
->nfgen_family
;
213 list_for_each_entry(afi
, &nf_tables_afinfo
, list
) {
214 if (family
!= NFPROTO_UNSPEC
&& family
!= afi
->family
)
217 list_for_each_entry(table
, &afi
->tables
, list
) {
221 memset(&cb
->args
[1], 0,
222 sizeof(cb
->args
) - sizeof(cb
->args
[0]));
223 if (nf_tables_fill_table_info(skb
,
224 NETLINK_CB(cb
->skb
).portid
,
228 afi
->family
, table
) < 0)
239 static int nf_tables_gettable(struct sock
*nlsk
, struct sk_buff
*skb
,
240 const struct nlmsghdr
*nlh
,
241 const struct nlattr
* const nla
[])
243 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
244 const struct nft_af_info
*afi
;
245 const struct nft_table
*table
;
246 struct sk_buff
*skb2
;
247 int family
= nfmsg
->nfgen_family
;
250 if (nlh
->nlmsg_flags
& NLM_F_DUMP
) {
251 struct netlink_dump_control c
= {
252 .dump
= nf_tables_dump_tables
,
254 return netlink_dump_start(nlsk
, skb
, nlh
, &c
);
257 afi
= nf_tables_afinfo_lookup(family
, false);
261 table
= nf_tables_table_lookup(afi
, nla
[NFTA_TABLE_NAME
], false);
263 return PTR_ERR(table
);
265 skb2
= alloc_skb(NLMSG_GOODSIZE
, GFP_KERNEL
);
269 err
= nf_tables_fill_table_info(skb2
, NETLINK_CB(skb
).portid
,
270 nlh
->nlmsg_seq
, NFT_MSG_NEWTABLE
, 0,
275 return nlmsg_unicast(nlsk
, skb2
, NETLINK_CB(skb
).portid
);
282 static int nf_tables_newtable(struct sock
*nlsk
, struct sk_buff
*skb
,
283 const struct nlmsghdr
*nlh
,
284 const struct nlattr
* const nla
[])
286 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
287 const struct nlattr
*name
;
288 struct nft_af_info
*afi
;
289 struct nft_table
*table
;
290 int family
= nfmsg
->nfgen_family
;
292 afi
= nf_tables_afinfo_lookup(family
, true);
296 name
= nla
[NFTA_TABLE_NAME
];
297 table
= nf_tables_table_lookup(afi
, name
, false);
299 if (PTR_ERR(table
) != -ENOENT
)
300 return PTR_ERR(table
);
305 if (nlh
->nlmsg_flags
& NLM_F_EXCL
)
307 if (nlh
->nlmsg_flags
& NLM_F_REPLACE
)
312 table
= kzalloc(sizeof(*table
) + nla_len(name
), GFP_KERNEL
);
316 nla_strlcpy(table
->name
, name
, nla_len(name
));
317 INIT_LIST_HEAD(&table
->chains
);
318 INIT_LIST_HEAD(&table
->sets
);
320 list_add_tail(&table
->list
, &afi
->tables
);
321 nf_tables_table_notify(skb
, nlh
, table
, NFT_MSG_NEWTABLE
, family
);
325 static int nf_tables_deltable(struct sock
*nlsk
, struct sk_buff
*skb
,
326 const struct nlmsghdr
*nlh
,
327 const struct nlattr
* const nla
[])
329 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
330 struct nft_af_info
*afi
;
331 struct nft_table
*table
;
332 int family
= nfmsg
->nfgen_family
;
334 afi
= nf_tables_afinfo_lookup(family
, false);
338 table
= nf_tables_table_lookup(afi
, nla
[NFTA_TABLE_NAME
], false);
340 return PTR_ERR(table
);
342 if (table
->flags
& NFT_TABLE_BUILTIN
)
348 list_del(&table
->list
);
349 nf_tables_table_notify(skb
, nlh
, table
, NFT_MSG_DELTABLE
, family
);
354 static struct nft_table
*__nf_tables_table_lookup(const struct nft_af_info
*afi
,
357 struct nft_table
*table
;
359 list_for_each_entry(table
, &afi
->tables
, list
) {
360 if (!strcmp(name
, table
->name
))
364 return ERR_PTR(-ENOENT
);
367 static int nf_tables_chain_notify(const struct sk_buff
*oskb
,
368 const struct nlmsghdr
*nlh
,
369 const struct nft_table
*table
,
370 const struct nft_chain
*chain
,
371 int event
, int family
);
374 * nft_register_table - register a built-in table
376 * @table: the table to register
377 * @family: protocol family to register table with
379 * Register a built-in table for use with nf_tables. Returns zero on
380 * success or a negative errno code otherwise.
382 int nft_register_table(struct nft_table
*table
, int family
)
384 struct nft_af_info
*afi
;
386 struct nft_chain
*chain
;
389 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
391 afi
= nf_tables_afinfo_lookup(family
, true);
399 t
= __nf_tables_table_lookup(afi
, table
->name
);
412 table
->flags
|= NFT_TABLE_BUILTIN
;
413 INIT_LIST_HEAD(&table
->sets
);
414 list_add_tail(&table
->list
, &afi
->tables
);
415 nf_tables_table_notify(NULL
, NULL
, table
, NFT_MSG_NEWTABLE
, family
);
416 list_for_each_entry(chain
, &table
->chains
, list
)
417 nf_tables_chain_notify(NULL
, NULL
, table
, chain
,
418 NFT_MSG_NEWCHAIN
, family
);
421 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
424 EXPORT_SYMBOL_GPL(nft_register_table
);
427 * nft_unregister_table - unregister a built-in table
429 * @table: the table to unregister
430 * @family: protocol family to unregister table with
432 * Unregister a built-in table for use with nf_tables.
434 void nft_unregister_table(struct nft_table
*table
, int family
)
436 struct nft_chain
*chain
;
438 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
439 list_del(&table
->list
);
440 list_for_each_entry(chain
, &table
->chains
, list
)
441 nf_tables_chain_notify(NULL
, NULL
, table
, chain
,
442 NFT_MSG_DELCHAIN
, family
);
443 nf_tables_table_notify(NULL
, NULL
, table
, NFT_MSG_DELTABLE
, family
);
444 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
446 EXPORT_SYMBOL_GPL(nft_unregister_table
);
452 static struct nft_chain
*
453 nf_tables_chain_lookup_byhandle(const struct nft_table
*table
, u64 handle
)
455 struct nft_chain
*chain
;
457 list_for_each_entry(chain
, &table
->chains
, list
) {
458 if (chain
->handle
== handle
)
462 return ERR_PTR(-ENOENT
);
465 static struct nft_chain
*nf_tables_chain_lookup(const struct nft_table
*table
,
466 const struct nlattr
*nla
)
468 struct nft_chain
*chain
;
471 return ERR_PTR(-EINVAL
);
473 list_for_each_entry(chain
, &table
->chains
, list
) {
474 if (!nla_strcmp(nla
, chain
->name
))
478 return ERR_PTR(-ENOENT
);
481 static const struct nla_policy nft_chain_policy
[NFTA_CHAIN_MAX
+ 1] = {
482 [NFTA_CHAIN_TABLE
] = { .type
= NLA_STRING
},
483 [NFTA_CHAIN_HANDLE
] = { .type
= NLA_U64
},
484 [NFTA_CHAIN_NAME
] = { .type
= NLA_STRING
,
485 .len
= NFT_CHAIN_MAXNAMELEN
- 1 },
486 [NFTA_CHAIN_HOOK
] = { .type
= NLA_NESTED
},
489 static const struct nla_policy nft_hook_policy
[NFTA_HOOK_MAX
+ 1] = {
490 [NFTA_HOOK_HOOKNUM
] = { .type
= NLA_U32
},
491 [NFTA_HOOK_PRIORITY
] = { .type
= NLA_U32
},
494 static int nf_tables_fill_chain_info(struct sk_buff
*skb
, u32 portid
, u32 seq
,
495 int event
, u32 flags
, int family
,
496 const struct nft_table
*table
,
497 const struct nft_chain
*chain
)
499 struct nlmsghdr
*nlh
;
500 struct nfgenmsg
*nfmsg
;
502 event
|= NFNL_SUBSYS_NFTABLES
<< 8;
503 nlh
= nlmsg_put(skb
, portid
, seq
, event
, sizeof(struct nfgenmsg
), flags
);
505 goto nla_put_failure
;
507 nfmsg
= nlmsg_data(nlh
);
508 nfmsg
->nfgen_family
= family
;
509 nfmsg
->version
= NFNETLINK_V0
;
512 if (nla_put_string(skb
, NFTA_CHAIN_TABLE
, table
->name
))
513 goto nla_put_failure
;
514 if (nla_put_be64(skb
, NFTA_CHAIN_HANDLE
, cpu_to_be64(chain
->handle
)))
515 goto nla_put_failure
;
516 if (nla_put_string(skb
, NFTA_CHAIN_NAME
, chain
->name
))
517 goto nla_put_failure
;
519 if (chain
->flags
& NFT_BASE_CHAIN
) {
520 const struct nf_hook_ops
*ops
= &nft_base_chain(chain
)->ops
;
521 struct nlattr
*nest
= nla_nest_start(skb
, NFTA_CHAIN_HOOK
);
523 goto nla_put_failure
;
524 if (nla_put_be32(skb
, NFTA_HOOK_HOOKNUM
, htonl(ops
->hooknum
)))
525 goto nla_put_failure
;
526 if (nla_put_be32(skb
, NFTA_HOOK_PRIORITY
, htonl(ops
->priority
)))
527 goto nla_put_failure
;
528 nla_nest_end(skb
, nest
);
531 return nlmsg_end(skb
, nlh
);
534 nlmsg_trim(skb
, nlh
);
538 static int nf_tables_chain_notify(const struct sk_buff
*oskb
,
539 const struct nlmsghdr
*nlh
,
540 const struct nft_table
*table
,
541 const struct nft_chain
*chain
,
542 int event
, int family
)
545 u32 portid
= oskb
? NETLINK_CB(oskb
).portid
: 0;
546 struct net
*net
= oskb
? sock_net(oskb
->sk
) : &init_net
;
547 u32 seq
= nlh
? nlh
->nlmsg_seq
: 0;
551 report
= nlh
? nlmsg_report(nlh
) : false;
552 if (!report
&& !nfnetlink_has_listeners(net
, NFNLGRP_NFTABLES
))
556 skb
= nlmsg_new(NLMSG_GOODSIZE
, GFP_KERNEL
);
560 err
= nf_tables_fill_chain_info(skb
, portid
, seq
, event
, 0, family
,
567 err
= nfnetlink_send(skb
, net
, portid
, NFNLGRP_NFTABLES
, report
,
571 nfnetlink_set_err(net
, portid
, NFNLGRP_NFTABLES
, err
);
575 static int nf_tables_dump_chains(struct sk_buff
*skb
,
576 struct netlink_callback
*cb
)
578 const struct nfgenmsg
*nfmsg
= nlmsg_data(cb
->nlh
);
579 const struct nft_af_info
*afi
;
580 const struct nft_table
*table
;
581 const struct nft_chain
*chain
;
582 unsigned int idx
= 0, s_idx
= cb
->args
[0];
583 int family
= nfmsg
->nfgen_family
;
585 list_for_each_entry(afi
, &nf_tables_afinfo
, list
) {
586 if (family
!= NFPROTO_UNSPEC
&& family
!= afi
->family
)
589 list_for_each_entry(table
, &afi
->tables
, list
) {
590 list_for_each_entry(chain
, &table
->chains
, list
) {
594 memset(&cb
->args
[1], 0,
595 sizeof(cb
->args
) - sizeof(cb
->args
[0]));
596 if (nf_tables_fill_chain_info(skb
, NETLINK_CB(cb
->skb
).portid
,
600 afi
->family
, table
, chain
) < 0)
613 static int nf_tables_getchain(struct sock
*nlsk
, struct sk_buff
*skb
,
614 const struct nlmsghdr
*nlh
,
615 const struct nlattr
* const nla
[])
617 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
618 const struct nft_af_info
*afi
;
619 const struct nft_table
*table
;
620 const struct nft_chain
*chain
;
621 struct sk_buff
*skb2
;
622 int family
= nfmsg
->nfgen_family
;
625 if (nlh
->nlmsg_flags
& NLM_F_DUMP
) {
626 struct netlink_dump_control c
= {
627 .dump
= nf_tables_dump_chains
,
629 return netlink_dump_start(nlsk
, skb
, nlh
, &c
);
632 afi
= nf_tables_afinfo_lookup(family
, false);
636 table
= nf_tables_table_lookup(afi
, nla
[NFTA_CHAIN_TABLE
], false);
638 return PTR_ERR(table
);
640 chain
= nf_tables_chain_lookup(table
, nla
[NFTA_CHAIN_NAME
]);
642 return PTR_ERR(chain
);
644 skb2
= alloc_skb(NLMSG_GOODSIZE
, GFP_KERNEL
);
648 err
= nf_tables_fill_chain_info(skb2
, NETLINK_CB(skb
).portid
,
649 nlh
->nlmsg_seq
, NFT_MSG_NEWCHAIN
, 0,
650 family
, table
, chain
);
654 return nlmsg_unicast(nlsk
, skb2
, NETLINK_CB(skb
).portid
);
661 static int nf_tables_newchain(struct sock
*nlsk
, struct sk_buff
*skb
,
662 const struct nlmsghdr
*nlh
,
663 const struct nlattr
* const nla
[])
665 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
666 const struct nlattr
* uninitialized_var(name
);
667 const struct nft_af_info
*afi
;
668 struct nft_table
*table
;
669 struct nft_chain
*chain
;
670 struct nft_base_chain
*basechain
;
671 struct nlattr
*ha
[NFTA_HOOK_MAX
+ 1];
672 int family
= nfmsg
->nfgen_family
;
677 create
= nlh
->nlmsg_flags
& NLM_F_CREATE
? true : false;
679 afi
= nf_tables_afinfo_lookup(family
, true);
683 table
= nf_tables_table_lookup(afi
, nla
[NFTA_CHAIN_TABLE
], create
);
685 return PTR_ERR(table
);
687 if (table
->use
== UINT_MAX
)
691 name
= nla
[NFTA_CHAIN_NAME
];
693 if (nla
[NFTA_CHAIN_HANDLE
]) {
694 handle
= be64_to_cpu(nla_get_be64(nla
[NFTA_CHAIN_HANDLE
]));
695 chain
= nf_tables_chain_lookup_byhandle(table
, handle
);
697 return PTR_ERR(chain
);
699 chain
= nf_tables_chain_lookup(table
, name
);
701 if (PTR_ERR(chain
) != -ENOENT
)
702 return PTR_ERR(chain
);
708 if (nlh
->nlmsg_flags
& NLM_F_EXCL
)
710 if (nlh
->nlmsg_flags
& NLM_F_REPLACE
)
713 if (nla
[NFTA_CHAIN_HANDLE
] && name
&&
714 !IS_ERR(nf_tables_chain_lookup(table
, nla
[NFTA_CHAIN_NAME
])))
717 if (nla
[NFTA_CHAIN_HANDLE
] && name
)
718 nla_strlcpy(chain
->name
, name
, NFT_CHAIN_MAXNAMELEN
);
723 if (nla
[NFTA_CHAIN_HOOK
]) {
724 struct nf_hook_ops
*ops
;
726 err
= nla_parse_nested(ha
, NFTA_HOOK_MAX
, nla
[NFTA_CHAIN_HOOK
],
730 if (ha
[NFTA_HOOK_HOOKNUM
] == NULL
||
731 ha
[NFTA_HOOK_PRIORITY
] == NULL
)
733 if (ntohl(nla_get_be32(ha
[NFTA_HOOK_HOOKNUM
])) >= afi
->nhooks
)
736 basechain
= kzalloc(sizeof(*basechain
), GFP_KERNEL
);
737 if (basechain
== NULL
)
739 chain
= &basechain
->chain
;
741 ops
= &basechain
->ops
;
743 ops
->owner
= afi
->owner
;
744 ops
->hooknum
= ntohl(nla_get_be32(ha
[NFTA_HOOK_HOOKNUM
]));
745 ops
->priority
= ntohl(nla_get_be32(ha
[NFTA_HOOK_PRIORITY
]));
747 ops
->hook
= nft_do_chain
;
748 if (afi
->hooks
[ops
->hooknum
])
749 ops
->hook
= afi
->hooks
[ops
->hooknum
];
751 chain
->flags
|= NFT_BASE_CHAIN
;
753 chain
= kzalloc(sizeof(*chain
), GFP_KERNEL
);
758 INIT_LIST_HEAD(&chain
->rules
);
759 chain
->handle
= nf_tables_alloc_handle(table
);
760 nla_strlcpy(chain
->name
, name
, NFT_CHAIN_MAXNAMELEN
);
762 list_add_tail(&chain
->list
, &table
->chains
);
765 nf_tables_chain_notify(skb
, nlh
, table
, chain
, NFT_MSG_NEWCHAIN
,
770 static void nf_tables_rcu_chain_destroy(struct rcu_head
*head
)
772 struct nft_chain
*chain
= container_of(head
, struct nft_chain
, rcu_head
);
774 BUG_ON(chain
->use
> 0);
776 if (chain
->flags
& NFT_BASE_CHAIN
)
777 kfree(nft_base_chain(chain
));
782 static int nf_tables_delchain(struct sock
*nlsk
, struct sk_buff
*skb
,
783 const struct nlmsghdr
*nlh
,
784 const struct nlattr
* const nla
[])
786 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
787 const struct nft_af_info
*afi
;
788 struct nft_table
*table
;
789 struct nft_chain
*chain
;
790 int family
= nfmsg
->nfgen_family
;
792 afi
= nf_tables_afinfo_lookup(family
, false);
796 table
= nf_tables_table_lookup(afi
, nla
[NFTA_CHAIN_TABLE
], false);
798 return PTR_ERR(table
);
800 chain
= nf_tables_chain_lookup(table
, nla
[NFTA_CHAIN_NAME
]);
802 return PTR_ERR(chain
);
804 if (chain
->flags
& NFT_CHAIN_BUILTIN
)
807 if (!list_empty(&chain
->rules
))
810 list_del(&chain
->list
);
813 if (chain
->flags
& NFT_BASE_CHAIN
)
814 nf_unregister_hook(&nft_base_chain(chain
)->ops
);
816 nf_tables_chain_notify(skb
, nlh
, table
, chain
, NFT_MSG_DELCHAIN
,
819 /* Make sure all rule references are gone before this is released */
820 call_rcu(&chain
->rcu_head
, nf_tables_rcu_chain_destroy
);
824 static void nft_ctx_init(struct nft_ctx
*ctx
,
825 const struct sk_buff
*skb
,
826 const struct nlmsghdr
*nlh
,
827 const struct nft_af_info
*afi
,
828 const struct nft_table
*table
,
829 const struct nft_chain
*chain
)
843 * nft_register_expr - register nf_tables expr operations
844 * @ops: expr operations
846 * Registers the expr operations for use with nf_tables. Returns zero on
847 * success or a negative errno code otherwise.
849 int nft_register_expr(struct nft_expr_ops
*ops
)
851 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
852 list_add_tail(&ops
->list
, &nf_tables_expressions
);
853 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
856 EXPORT_SYMBOL_GPL(nft_register_expr
);
859 * nft_unregister_expr - unregister nf_tables expr operations
860 * @ops: expr operations
862 * Unregisters the expr operations for use with nf_tables.
864 void nft_unregister_expr(struct nft_expr_ops
*ops
)
866 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
867 list_del(&ops
->list
);
868 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
870 EXPORT_SYMBOL_GPL(nft_unregister_expr
);
872 static const struct nft_expr_ops
*__nft_expr_ops_get(struct nlattr
*nla
)
874 const struct nft_expr_ops
*ops
;
876 list_for_each_entry(ops
, &nf_tables_expressions
, list
) {
877 if (!nla_strcmp(nla
, ops
->name
))
883 static const struct nft_expr_ops
*nft_expr_ops_get(struct nlattr
*nla
)
885 const struct nft_expr_ops
*ops
;
888 return ERR_PTR(-EINVAL
);
890 ops
= __nft_expr_ops_get(nla
);
891 if (ops
!= NULL
&& try_module_get(ops
->owner
))
894 #ifdef CONFIG_MODULES
896 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
897 request_module("nft-expr-%.*s",
898 nla_len(nla
), (char *)nla_data(nla
));
899 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
900 if (__nft_expr_ops_get(nla
))
901 return ERR_PTR(-EAGAIN
);
904 return ERR_PTR(-ENOENT
);
907 static const struct nla_policy nft_expr_policy
[NFTA_EXPR_MAX
+ 1] = {
908 [NFTA_EXPR_NAME
] = { .type
= NLA_STRING
},
909 [NFTA_EXPR_DATA
] = { .type
= NLA_NESTED
},
912 static int nf_tables_fill_expr_info(struct sk_buff
*skb
,
913 const struct nft_expr
*expr
)
915 if (nla_put_string(skb
, NFTA_EXPR_NAME
, expr
->ops
->name
))
916 goto nla_put_failure
;
918 if (expr
->ops
->dump
) {
919 struct nlattr
*data
= nla_nest_start(skb
, NFTA_EXPR_DATA
);
921 goto nla_put_failure
;
922 if (expr
->ops
->dump(skb
, expr
) < 0)
923 goto nla_put_failure
;
924 nla_nest_end(skb
, data
);
933 struct nft_expr_info
{
934 const struct nft_expr_ops
*ops
;
935 struct nlattr
*tb
[NFTA_EXPR_MAX
+ 1];
938 static int nf_tables_expr_parse(const struct nlattr
*nla
,
939 struct nft_expr_info
*info
)
941 const struct nft_expr_ops
*ops
;
944 err
= nla_parse_nested(info
->tb
, NFTA_EXPR_MAX
, nla
, nft_expr_policy
);
948 ops
= nft_expr_ops_get(info
->tb
[NFTA_EXPR_NAME
]);
955 static int nf_tables_newexpr(const struct nft_ctx
*ctx
,
956 struct nft_expr_info
*info
,
957 struct nft_expr
*expr
)
959 const struct nft_expr_ops
*ops
= info
->ops
;
964 struct nlattr
*ma
[ops
->maxattr
+ 1];
966 if (info
->tb
[NFTA_EXPR_DATA
]) {
967 err
= nla_parse_nested(ma
, ops
->maxattr
,
968 info
->tb
[NFTA_EXPR_DATA
],
973 memset(ma
, 0, sizeof(ma
[0]) * (ops
->maxattr
+ 1));
975 err
= ops
->init(ctx
, expr
, (const struct nlattr
**)ma
);
988 static void nf_tables_expr_destroy(struct nft_expr
*expr
)
990 if (expr
->ops
->destroy
)
991 expr
->ops
->destroy(expr
);
992 module_put(expr
->ops
->owner
);
999 static struct nft_rule
*__nf_tables_rule_lookup(const struct nft_chain
*chain
,
1002 struct nft_rule
*rule
;
1004 // FIXME: this sucks
1005 list_for_each_entry(rule
, &chain
->rules
, list
) {
1006 if (handle
== rule
->handle
)
1010 return ERR_PTR(-ENOENT
);
1013 static struct nft_rule
*nf_tables_rule_lookup(const struct nft_chain
*chain
,
1014 const struct nlattr
*nla
)
1017 return ERR_PTR(-EINVAL
);
1019 return __nf_tables_rule_lookup(chain
, be64_to_cpu(nla_get_be64(nla
)));
1022 static const struct nla_policy nft_rule_policy
[NFTA_RULE_MAX
+ 1] = {
1023 [NFTA_RULE_TABLE
] = { .type
= NLA_STRING
},
1024 [NFTA_RULE_CHAIN
] = { .type
= NLA_STRING
,
1025 .len
= NFT_CHAIN_MAXNAMELEN
- 1 },
1026 [NFTA_RULE_HANDLE
] = { .type
= NLA_U64
},
1027 [NFTA_RULE_EXPRESSIONS
] = { .type
= NLA_NESTED
},
1030 static int nf_tables_fill_rule_info(struct sk_buff
*skb
, u32 portid
, u32 seq
,
1031 int event
, u32 flags
, int family
,
1032 const struct nft_table
*table
,
1033 const struct nft_chain
*chain
,
1034 const struct nft_rule
*rule
)
1036 struct nlmsghdr
*nlh
;
1037 struct nfgenmsg
*nfmsg
;
1038 const struct nft_expr
*expr
, *next
;
1039 struct nlattr
*list
;
1041 event
|= NFNL_SUBSYS_NFTABLES
<< 8;
1042 nlh
= nlmsg_put(skb
, portid
, seq
, event
, sizeof(struct nfgenmsg
),
1045 goto nla_put_failure
;
1047 nfmsg
= nlmsg_data(nlh
);
1048 nfmsg
->nfgen_family
= family
;
1049 nfmsg
->version
= NFNETLINK_V0
;
1052 if (nla_put_string(skb
, NFTA_RULE_TABLE
, table
->name
))
1053 goto nla_put_failure
;
1054 if (nla_put_string(skb
, NFTA_RULE_CHAIN
, chain
->name
))
1055 goto nla_put_failure
;
1056 if (nla_put_be64(skb
, NFTA_RULE_HANDLE
, cpu_to_be64(rule
->handle
)))
1057 goto nla_put_failure
;
1059 list
= nla_nest_start(skb
, NFTA_RULE_EXPRESSIONS
);
1061 goto nla_put_failure
;
1062 nft_rule_for_each_expr(expr
, next
, rule
) {
1063 struct nlattr
*elem
= nla_nest_start(skb
, NFTA_LIST_ELEM
);
1065 goto nla_put_failure
;
1066 if (nf_tables_fill_expr_info(skb
, expr
) < 0)
1067 goto nla_put_failure
;
1068 nla_nest_end(skb
, elem
);
1070 nla_nest_end(skb
, list
);
1072 return nlmsg_end(skb
, nlh
);
1075 nlmsg_trim(skb
, nlh
);
1079 static int nf_tables_rule_notify(const struct sk_buff
*oskb
,
1080 const struct nlmsghdr
*nlh
,
1081 const struct nft_table
*table
,
1082 const struct nft_chain
*chain
,
1083 const struct nft_rule
*rule
,
1084 int event
, u32 flags
, int family
)
1086 struct sk_buff
*skb
;
1087 u32 portid
= NETLINK_CB(oskb
).portid
;
1088 struct net
*net
= oskb
? sock_net(oskb
->sk
) : &init_net
;
1089 u32 seq
= nlh
->nlmsg_seq
;
1093 report
= nlmsg_report(nlh
);
1094 if (!report
&& !nfnetlink_has_listeners(net
, NFNLGRP_NFTABLES
))
1098 skb
= nlmsg_new(NLMSG_GOODSIZE
, GFP_KERNEL
);
1102 err
= nf_tables_fill_rule_info(skb
, portid
, seq
, event
, flags
,
1103 family
, table
, chain
, rule
);
1109 err
= nfnetlink_send(skb
, net
, portid
, NFNLGRP_NFTABLES
, report
,
1113 nfnetlink_set_err(net
, portid
, NFNLGRP_NFTABLES
, err
);
1117 static int nf_tables_dump_rules(struct sk_buff
*skb
,
1118 struct netlink_callback
*cb
)
1120 const struct nfgenmsg
*nfmsg
= nlmsg_data(cb
->nlh
);
1121 const struct nft_af_info
*afi
;
1122 const struct nft_table
*table
;
1123 const struct nft_chain
*chain
;
1124 const struct nft_rule
*rule
;
1125 unsigned int idx
= 0, s_idx
= cb
->args
[0];
1126 int family
= nfmsg
->nfgen_family
;
1128 list_for_each_entry(afi
, &nf_tables_afinfo
, list
) {
1129 if (family
!= NFPROTO_UNSPEC
&& family
!= afi
->family
)
1132 list_for_each_entry(table
, &afi
->tables
, list
) {
1133 list_for_each_entry(chain
, &table
->chains
, list
) {
1134 list_for_each_entry(rule
, &chain
->rules
, list
) {
1138 memset(&cb
->args
[1], 0,
1139 sizeof(cb
->args
) - sizeof(cb
->args
[0]));
1140 if (nf_tables_fill_rule_info(skb
, NETLINK_CB(cb
->skb
).portid
,
1143 NLM_F_MULTI
| NLM_F_APPEND
,
1144 afi
->family
, table
, chain
, rule
) < 0)
1157 static int nf_tables_getrule(struct sock
*nlsk
, struct sk_buff
*skb
,
1158 const struct nlmsghdr
*nlh
,
1159 const struct nlattr
* const nla
[])
1161 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
1162 const struct nft_af_info
*afi
;
1163 const struct nft_table
*table
;
1164 const struct nft_chain
*chain
;
1165 const struct nft_rule
*rule
;
1166 struct sk_buff
*skb2
;
1167 int family
= nfmsg
->nfgen_family
;
1170 if (nlh
->nlmsg_flags
& NLM_F_DUMP
) {
1171 struct netlink_dump_control c
= {
1172 .dump
= nf_tables_dump_rules
,
1174 return netlink_dump_start(nlsk
, skb
, nlh
, &c
);
1177 afi
= nf_tables_afinfo_lookup(family
, false);
1179 return PTR_ERR(afi
);
1181 table
= nf_tables_table_lookup(afi
, nla
[NFTA_RULE_TABLE
], false);
1183 return PTR_ERR(table
);
1185 chain
= nf_tables_chain_lookup(table
, nla
[NFTA_RULE_CHAIN
]);
1187 return PTR_ERR(chain
);
1189 rule
= nf_tables_rule_lookup(chain
, nla
[NFTA_RULE_HANDLE
]);
1191 return PTR_ERR(rule
);
1193 skb2
= alloc_skb(NLMSG_GOODSIZE
, GFP_KERNEL
);
1197 err
= nf_tables_fill_rule_info(skb2
, NETLINK_CB(skb
).portid
,
1198 nlh
->nlmsg_seq
, NFT_MSG_NEWRULE
, 0,
1199 family
, table
, chain
, rule
);
1203 return nlmsg_unicast(nlsk
, skb2
, NETLINK_CB(skb
).portid
);
1210 static void nf_tables_rcu_rule_destroy(struct rcu_head
*head
)
1212 struct nft_rule
*rule
= container_of(head
, struct nft_rule
, rcu_head
);
1213 struct nft_expr
*expr
;
1216 * Careful: some expressions might not be initialized in case this
1217 * is called on error from nf_tables_newrule().
1219 expr
= nft_expr_first(rule
);
1220 while (expr
->ops
&& expr
!= nft_expr_last(rule
)) {
1221 nf_tables_expr_destroy(expr
);
1222 expr
= nft_expr_next(expr
);
1227 static void nf_tables_rule_destroy(struct nft_rule
*rule
)
1229 call_rcu(&rule
->rcu_head
, nf_tables_rcu_rule_destroy
);
1232 #define NFT_RULE_MAXEXPRS 128
1234 static struct nft_expr_info
*info
;
1236 static int nf_tables_newrule(struct sock
*nlsk
, struct sk_buff
*skb
,
1237 const struct nlmsghdr
*nlh
,
1238 const struct nlattr
* const nla
[])
1240 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
1241 const struct nft_af_info
*afi
;
1242 struct nft_table
*table
;
1243 struct nft_chain
*chain
;
1244 struct nft_rule
*rule
, *old_rule
= NULL
;
1245 struct nft_expr
*expr
;
1248 unsigned int size
, i
, n
;
1253 create
= nlh
->nlmsg_flags
& NLM_F_CREATE
? true : false;
1255 afi
= nf_tables_afinfo_lookup(nfmsg
->nfgen_family
, create
);
1257 return PTR_ERR(afi
);
1259 table
= nf_tables_table_lookup(afi
, nla
[NFTA_RULE_TABLE
], create
);
1261 return PTR_ERR(table
);
1263 chain
= nf_tables_chain_lookup(table
, nla
[NFTA_RULE_CHAIN
]);
1265 return PTR_ERR(chain
);
1267 if (nla
[NFTA_RULE_HANDLE
]) {
1268 handle
= be64_to_cpu(nla_get_be64(nla
[NFTA_RULE_HANDLE
]));
1269 rule
= __nf_tables_rule_lookup(chain
, handle
);
1271 return PTR_ERR(rule
);
1273 if (nlh
->nlmsg_flags
& NLM_F_EXCL
)
1275 if (nlh
->nlmsg_flags
& NLM_F_REPLACE
)
1280 if (!create
|| nlh
->nlmsg_flags
& NLM_F_REPLACE
)
1282 handle
= nf_tables_alloc_handle(table
);
1287 if (nla
[NFTA_RULE_EXPRESSIONS
]) {
1288 nla_for_each_nested(tmp
, nla
[NFTA_RULE_EXPRESSIONS
], rem
) {
1290 if (nla_type(tmp
) != NFTA_LIST_ELEM
)
1292 if (n
== NFT_RULE_MAXEXPRS
)
1294 err
= nf_tables_expr_parse(tmp
, &info
[n
]);
1297 size
+= info
[n
].ops
->size
;
1303 rule
= kzalloc(sizeof(*rule
) + size
, GFP_KERNEL
);
1307 rule
->handle
= handle
;
1310 nft_ctx_init(&ctx
, skb
, nlh
, afi
, table
, chain
);
1311 expr
= nft_expr_first(rule
);
1312 for (i
= 0; i
< n
; i
++) {
1313 err
= nf_tables_newexpr(&ctx
, &info
[i
], expr
);
1316 expr
= nft_expr_next(expr
);
1319 /* Register hook when first rule is inserted into a base chain */
1320 if (list_empty(&chain
->rules
) && chain
->flags
& NFT_BASE_CHAIN
) {
1321 err
= nf_register_hook(&nft_base_chain(chain
)->ops
);
1326 if (nlh
->nlmsg_flags
& NLM_F_REPLACE
) {
1327 list_replace_rcu(&old_rule
->list
, &rule
->list
);
1328 nf_tables_rule_destroy(old_rule
);
1329 } else if (nlh
->nlmsg_flags
& NLM_F_APPEND
)
1330 list_add_tail_rcu(&rule
->list
, &chain
->rules
);
1332 list_add_rcu(&rule
->list
, &chain
->rules
);
1334 nf_tables_rule_notify(skb
, nlh
, table
, chain
, rule
, NFT_MSG_NEWRULE
,
1335 nlh
->nlmsg_flags
& (NLM_F_APPEND
| NLM_F_REPLACE
),
1336 nfmsg
->nfgen_family
);
1340 nf_tables_rule_destroy(rule
);
1342 for (i
= 0; i
< n
; i
++) {
1343 if (info
[i
].ops
!= NULL
)
1344 module_put(info
[i
].ops
->owner
);
1349 static int nf_tables_delrule(struct sock
*nlsk
, struct sk_buff
*skb
,
1350 const struct nlmsghdr
*nlh
,
1351 const struct nlattr
* const nla
[])
1353 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
1354 const struct nft_af_info
*afi
;
1355 const struct nft_table
*table
;
1356 struct nft_chain
*chain
;
1357 struct nft_rule
*rule
, *tmp
;
1358 int family
= nfmsg
->nfgen_family
;
1360 afi
= nf_tables_afinfo_lookup(family
, false);
1362 return PTR_ERR(afi
);
1364 table
= nf_tables_table_lookup(afi
, nla
[NFTA_RULE_TABLE
], false);
1366 return PTR_ERR(table
);
1368 chain
= nf_tables_chain_lookup(table
, nla
[NFTA_RULE_CHAIN
]);
1370 return PTR_ERR(chain
);
1372 if (nla
[NFTA_RULE_HANDLE
]) {
1373 rule
= nf_tables_rule_lookup(chain
, nla
[NFTA_RULE_HANDLE
]);
1375 return PTR_ERR(rule
);
1377 /* List removal must be visible before destroying expressions */
1378 list_del_rcu(&rule
->list
);
1380 nf_tables_rule_notify(skb
, nlh
, table
, chain
, rule
,
1381 NFT_MSG_DELRULE
, 0, family
);
1382 nf_tables_rule_destroy(rule
);
1384 /* Remove all rules in this chain */
1385 list_for_each_entry_safe(rule
, tmp
, &chain
->rules
, list
) {
1386 list_del_rcu(&rule
->list
);
1388 nf_tables_rule_notify(skb
, nlh
, table
, chain
, rule
,
1389 NFT_MSG_DELRULE
, 0, family
);
1390 nf_tables_rule_destroy(rule
);
1394 /* Unregister hook when last rule from base chain is deleted */
1395 if (list_empty(&chain
->rules
) && chain
->flags
& NFT_BASE_CHAIN
)
1396 nf_unregister_hook(&nft_base_chain(chain
)->ops
);
1405 static LIST_HEAD(nf_tables_set_ops
);
1407 int nft_register_set(struct nft_set_ops
*ops
)
1409 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
1410 list_add_tail(&ops
->list
, &nf_tables_set_ops
);
1411 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
1414 EXPORT_SYMBOL_GPL(nft_register_set
);
1416 void nft_unregister_set(struct nft_set_ops
*ops
)
1418 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
1419 list_del(&ops
->list
);
1420 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
1422 EXPORT_SYMBOL_GPL(nft_unregister_set
);
1424 static const struct nft_set_ops
*nft_select_set_ops(const struct nlattr
* const nla
[])
1426 const struct nft_set_ops
*ops
;
1429 #ifdef CONFIG_MODULES
1430 if (list_empty(&nf_tables_set_ops
)) {
1431 nfnl_unlock(NFNL_SUBSYS_NFTABLES
);
1432 request_module("nft-set");
1433 nfnl_lock(NFNL_SUBSYS_NFTABLES
);
1434 if (!list_empty(&nf_tables_set_ops
))
1435 return ERR_PTR(-EAGAIN
);
1439 if (nla
[NFTA_SET_FLAGS
] != NULL
) {
1440 features
= ntohl(nla_get_be32(nla
[NFTA_SET_FLAGS
]));
1441 features
&= NFT_SET_INTERVAL
| NFT_SET_MAP
;
1444 // FIXME: implement selection properly
1445 list_for_each_entry(ops
, &nf_tables_set_ops
, list
) {
1446 if ((ops
->features
& features
) != features
)
1448 if (!try_module_get(ops
->owner
))
1453 return ERR_PTR(-EOPNOTSUPP
);
1456 static const struct nla_policy nft_set_policy
[NFTA_SET_MAX
+ 1] = {
1457 [NFTA_SET_TABLE
] = { .type
= NLA_STRING
},
1458 [NFTA_SET_NAME
] = { .type
= NLA_STRING
},
1459 [NFTA_SET_FLAGS
] = { .type
= NLA_U32
},
1460 [NFTA_SET_KEY_TYPE
] = { .type
= NLA_U32
},
1461 [NFTA_SET_KEY_LEN
] = { .type
= NLA_U32
},
1462 [NFTA_SET_DATA_TYPE
] = { .type
= NLA_U32
},
1463 [NFTA_SET_DATA_LEN
] = { .type
= NLA_U32
},
1466 static int nft_ctx_init_from_setattr(struct nft_ctx
*ctx
,
1467 const struct sk_buff
*skb
,
1468 const struct nlmsghdr
*nlh
,
1469 const struct nlattr
* const nla
[])
1471 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
1472 const struct nft_af_info
*afi
;
1473 const struct nft_table
*table
= NULL
;
1475 afi
= nf_tables_afinfo_lookup(nfmsg
->nfgen_family
, false);
1477 return PTR_ERR(afi
);
1479 if (nla
[NFTA_SET_TABLE
] != NULL
) {
1480 table
= nf_tables_table_lookup(afi
, nla
[NFTA_SET_TABLE
], false);
1482 return PTR_ERR(table
);
1485 nft_ctx_init(ctx
, skb
, nlh
, afi
, table
, NULL
);
1489 struct nft_set
*nf_tables_set_lookup(const struct nft_table
*table
,
1490 const struct nlattr
*nla
)
1492 struct nft_set
*set
;
1495 return ERR_PTR(-EINVAL
);
1497 list_for_each_entry(set
, &table
->sets
, list
) {
1498 if (!nla_strcmp(nla
, set
->name
))
1501 return ERR_PTR(-ENOENT
);
1504 static int nf_tables_set_alloc_name(struct nft_ctx
*ctx
, struct nft_set
*set
,
1507 const struct nft_set
*i
;
1509 unsigned long *inuse
;
1512 p
= strnchr(name
, IFNAMSIZ
, '%');
1514 if (p
[1] != 'd' || strchr(p
+ 2, '%'))
1517 inuse
= (unsigned long *)get_zeroed_page(GFP_KERNEL
);
1521 list_for_each_entry(i
, &ctx
->table
->sets
, list
) {
1522 if (!sscanf(i
->name
, name
, &n
))
1524 if (n
< 0 || n
> BITS_PER_LONG
* PAGE_SIZE
)
1529 n
= find_first_zero_bit(inuse
, BITS_PER_LONG
* PAGE_SIZE
);
1530 free_page((unsigned long)inuse
);
1533 snprintf(set
->name
, sizeof(set
->name
), name
, n
);
1534 list_for_each_entry(i
, &ctx
->table
->sets
, list
) {
1535 if (!strcmp(set
->name
, i
->name
))
1541 static int nf_tables_fill_set(struct sk_buff
*skb
, const struct nft_ctx
*ctx
,
1542 const struct nft_set
*set
, u16 event
, u16 flags
)
1544 struct nfgenmsg
*nfmsg
;
1545 struct nlmsghdr
*nlh
;
1546 u32 portid
= NETLINK_CB(ctx
->skb
).portid
;
1547 u32 seq
= ctx
->nlh
->nlmsg_seq
;
1549 event
|= NFNL_SUBSYS_NFTABLES
<< 8;
1550 nlh
= nlmsg_put(skb
, portid
, seq
, event
, sizeof(struct nfgenmsg
),
1553 goto nla_put_failure
;
1555 nfmsg
= nlmsg_data(nlh
);
1556 nfmsg
->nfgen_family
= ctx
->afi
->family
;
1557 nfmsg
->version
= NFNETLINK_V0
;
1560 if (nla_put_string(skb
, NFTA_SET_TABLE
, ctx
->table
->name
))
1561 goto nla_put_failure
;
1562 if (nla_put_string(skb
, NFTA_SET_NAME
, set
->name
))
1563 goto nla_put_failure
;
1564 if (set
->flags
!= 0)
1565 if (nla_put_be32(skb
, NFTA_SET_FLAGS
, htonl(set
->flags
)))
1566 goto nla_put_failure
;
1568 if (nla_put_be32(skb
, NFTA_SET_KEY_TYPE
, htonl(set
->ktype
)))
1569 goto nla_put_failure
;
1570 if (nla_put_be32(skb
, NFTA_SET_KEY_LEN
, htonl(set
->klen
)))
1571 goto nla_put_failure
;
1572 if (set
->flags
& NFT_SET_MAP
) {
1573 if (nla_put_be32(skb
, NFTA_SET_DATA_TYPE
, htonl(set
->dtype
)))
1574 goto nla_put_failure
;
1575 if (nla_put_be32(skb
, NFTA_SET_DATA_LEN
, htonl(set
->dlen
)))
1576 goto nla_put_failure
;
1579 return nlmsg_end(skb
, nlh
);
1582 nlmsg_trim(skb
, nlh
);
1586 static int nf_tables_set_notify(const struct nft_ctx
*ctx
,
1587 const struct nft_set
*set
,
1590 struct sk_buff
*skb
;
1591 u32 portid
= NETLINK_CB(ctx
->skb
).portid
;
1592 struct net
*net
= sock_net(ctx
->skb
->sk
);
1596 report
= nlmsg_report(ctx
->nlh
);
1597 if (!report
&& !nfnetlink_has_listeners(net
, NFNLGRP_NFTABLES
))
1601 skb
= nlmsg_new(NLMSG_GOODSIZE
, GFP_KERNEL
);
1605 err
= nf_tables_fill_set(skb
, ctx
, set
, event
, 0);
1611 err
= nfnetlink_send(skb
, net
, portid
, NFNLGRP_NFTABLES
, report
,
1615 nfnetlink_set_err(net
, portid
, NFNLGRP_NFTABLES
, err
);
1619 static int nf_tables_dump_sets_table(struct nft_ctx
*ctx
, struct sk_buff
*skb
,
1620 struct netlink_callback
*cb
)
1622 const struct nft_set
*set
;
1623 unsigned int idx
= 0, s_idx
= cb
->args
[0];
1628 list_for_each_entry(set
, &ctx
->table
->sets
, list
) {
1631 if (nf_tables_fill_set(skb
, ctx
, set
, NFT_MSG_NEWSET
,
1644 static int nf_tables_dump_sets_all(struct nft_ctx
*ctx
, struct sk_buff
*skb
,
1645 struct netlink_callback
*cb
)
1647 const struct nft_set
*set
;
1648 unsigned int idx
= 0, s_idx
= cb
->args
[0];
1649 struct nft_table
*table
, *cur_table
= (struct nft_table
*)cb
->args
[2];
1654 list_for_each_entry(table
, &ctx
->afi
->tables
, list
) {
1655 if (cur_table
&& cur_table
!= table
)
1659 list_for_each_entry(set
, &ctx
->table
->sets
, list
) {
1662 if (nf_tables_fill_set(skb
, ctx
, set
, NFT_MSG_NEWSET
,
1665 cb
->args
[2] = (unsigned long) table
;
1677 static int nf_tables_dump_sets(struct sk_buff
*skb
, struct netlink_callback
*cb
)
1679 const struct nfgenmsg
*nfmsg
= nlmsg_data(cb
->nlh
);
1680 struct nlattr
*nla
[NFTA_SET_MAX
+ 1];
1684 err
= nlmsg_parse(cb
->nlh
, sizeof(*nfmsg
), nla
, NFTA_SET_MAX
,
1689 err
= nft_ctx_init_from_setattr(&ctx
, cb
->skb
, cb
->nlh
, (void *)nla
);
1693 if (ctx
.table
== NULL
)
1694 ret
= nf_tables_dump_sets_all(&ctx
, skb
, cb
);
1696 ret
= nf_tables_dump_sets_table(&ctx
, skb
, cb
);
1701 static int nf_tables_getset(struct sock
*nlsk
, struct sk_buff
*skb
,
1702 const struct nlmsghdr
*nlh
,
1703 const struct nlattr
* const nla
[])
1705 const struct nft_set
*set
;
1707 struct sk_buff
*skb2
;
1710 /* Verify existance before starting dump */
1711 err
= nft_ctx_init_from_setattr(&ctx
, skb
, nlh
, nla
);
1715 if (nlh
->nlmsg_flags
& NLM_F_DUMP
) {
1716 struct netlink_dump_control c
= {
1717 .dump
= nf_tables_dump_sets
,
1719 return netlink_dump_start(nlsk
, skb
, nlh
, &c
);
1722 set
= nf_tables_set_lookup(ctx
.table
, nla
[NFTA_SET_NAME
]);
1724 return PTR_ERR(set
);
1726 skb2
= alloc_skb(NLMSG_GOODSIZE
, GFP_KERNEL
);
1730 err
= nf_tables_fill_set(skb2
, &ctx
, set
, NFT_MSG_NEWSET
, 0);
1734 return nlmsg_unicast(nlsk
, skb2
, NETLINK_CB(skb
).portid
);
1741 static int nf_tables_newset(struct sock
*nlsk
, struct sk_buff
*skb
,
1742 const struct nlmsghdr
*nlh
,
1743 const struct nlattr
* const nla
[])
1745 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
1746 const struct nft_set_ops
*ops
;
1747 const struct nft_af_info
*afi
;
1748 struct nft_table
*table
;
1749 struct nft_set
*set
;
1751 char name
[IFNAMSIZ
];
1754 u32 ktype
, klen
, dlen
, dtype
, flags
;
1757 if (nla
[NFTA_SET_TABLE
] == NULL
||
1758 nla
[NFTA_SET_NAME
] == NULL
||
1759 nla
[NFTA_SET_KEY_LEN
] == NULL
)
1762 ktype
= NFT_DATA_VALUE
;
1763 if (nla
[NFTA_SET_KEY_TYPE
] != NULL
) {
1764 ktype
= ntohl(nla_get_be32(nla
[NFTA_SET_KEY_TYPE
]));
1765 if ((ktype
& NFT_DATA_RESERVED_MASK
) == NFT_DATA_RESERVED_MASK
)
1769 klen
= ntohl(nla_get_be32(nla
[NFTA_SET_KEY_LEN
]));
1770 if (klen
== 0 || klen
> FIELD_SIZEOF(struct nft_data
, data
))
1774 if (nla
[NFTA_SET_FLAGS
] != NULL
) {
1775 flags
= ntohl(nla_get_be32(nla
[NFTA_SET_FLAGS
]));
1776 if (flags
& ~(NFT_SET_ANONYMOUS
| NFT_SET_CONSTANT
|
1777 NFT_SET_INTERVAL
| NFT_SET_MAP
))
1783 if (nla
[NFTA_SET_DATA_TYPE
] != NULL
) {
1784 if (!(flags
& NFT_SET_MAP
))
1787 dtype
= ntohl(nla_get_be32(nla
[NFTA_SET_DATA_TYPE
]));
1788 if ((dtype
& NFT_DATA_RESERVED_MASK
) == NFT_DATA_RESERVED_MASK
&&
1789 dtype
!= NFT_DATA_VERDICT
)
1792 if (dtype
!= NFT_DATA_VERDICT
) {
1793 if (nla
[NFTA_SET_DATA_LEN
] == NULL
)
1795 dlen
= ntohl(nla_get_be32(nla
[NFTA_SET_DATA_LEN
]));
1797 dlen
> FIELD_SIZEOF(struct nft_data
, data
))
1800 dlen
= sizeof(struct nft_data
);
1801 } else if (flags
& NFT_SET_MAP
)
1804 create
= nlh
->nlmsg_flags
& NLM_F_CREATE
? true : false;
1806 afi
= nf_tables_afinfo_lookup(nfmsg
->nfgen_family
, create
);
1808 return PTR_ERR(afi
);
1810 table
= nf_tables_table_lookup(afi
, nla
[NFTA_SET_TABLE
], create
);
1812 return PTR_ERR(table
);
1814 nft_ctx_init(&ctx
, skb
, nlh
, afi
, table
, NULL
);
1816 set
= nf_tables_set_lookup(table
, nla
[NFTA_SET_NAME
]);
1818 if (PTR_ERR(set
) != -ENOENT
)
1819 return PTR_ERR(set
);
1824 if (nlh
->nlmsg_flags
& NLM_F_EXCL
)
1826 if (nlh
->nlmsg_flags
& NLM_F_REPLACE
)
1831 if (!(nlh
->nlmsg_flags
& NLM_F_CREATE
))
1834 ops
= nft_select_set_ops(nla
);
1836 return PTR_ERR(ops
);
1839 if (ops
->privsize
!= NULL
)
1840 size
= ops
->privsize(nla
);
1843 set
= kzalloc(sizeof(*set
) + size
, GFP_KERNEL
);
1847 nla_strlcpy(name
, nla
[NFTA_SET_NAME
], sizeof(set
->name
));
1848 err
= nf_tables_set_alloc_name(&ctx
, set
, name
);
1852 INIT_LIST_HEAD(&set
->bindings
);
1860 err
= ops
->init(set
, nla
);
1864 list_add_tail(&set
->list
, &table
->sets
);
1865 nf_tables_set_notify(&ctx
, set
, NFT_MSG_NEWSET
);
1871 module_put(ops
->owner
);
1875 static void nf_tables_set_destroy(const struct nft_ctx
*ctx
, struct nft_set
*set
)
1877 list_del(&set
->list
);
1878 if (!(set
->flags
& NFT_SET_ANONYMOUS
))
1879 nf_tables_set_notify(ctx
, set
, NFT_MSG_DELSET
);
1881 set
->ops
->destroy(set
);
1882 module_put(set
->ops
->owner
);
1886 static int nf_tables_delset(struct sock
*nlsk
, struct sk_buff
*skb
,
1887 const struct nlmsghdr
*nlh
,
1888 const struct nlattr
* const nla
[])
1890 struct nft_set
*set
;
1894 if (nla
[NFTA_SET_TABLE
] == NULL
)
1897 err
= nft_ctx_init_from_setattr(&ctx
, skb
, nlh
, nla
);
1901 set
= nf_tables_set_lookup(ctx
.table
, nla
[NFTA_SET_NAME
]);
1903 return PTR_ERR(set
);
1904 if (!list_empty(&set
->bindings
))
1907 nf_tables_set_destroy(&ctx
, set
);
1911 static int nf_tables_bind_check_setelem(const struct nft_ctx
*ctx
,
1912 const struct nft_set
*set
,
1913 const struct nft_set_iter
*iter
,
1914 const struct nft_set_elem
*elem
)
1916 enum nft_registers dreg
;
1918 dreg
= nft_type_to_reg(set
->dtype
);
1919 return nft_validate_data_load(ctx
, dreg
, &elem
->data
, set
->dtype
);
1922 int nf_tables_bind_set(const struct nft_ctx
*ctx
, struct nft_set
*set
,
1923 struct nft_set_binding
*binding
)
1925 struct nft_set_binding
*i
;
1926 struct nft_set_iter iter
;
1928 if (!list_empty(&set
->bindings
) && set
->flags
& NFT_SET_ANONYMOUS
)
1931 if (set
->flags
& NFT_SET_MAP
) {
1932 /* If the set is already bound to the same chain all
1933 * jumps are already validated for that chain.
1935 list_for_each_entry(i
, &set
->bindings
, list
) {
1936 if (i
->chain
== binding
->chain
)
1943 iter
.fn
= nf_tables_bind_check_setelem
;
1945 set
->ops
->walk(ctx
, set
, &iter
);
1947 /* Destroy anonymous sets if binding fails */
1948 if (set
->flags
& NFT_SET_ANONYMOUS
)
1949 nf_tables_set_destroy(ctx
, set
);
1955 binding
->chain
= ctx
->chain
;
1956 list_add_tail(&binding
->list
, &set
->bindings
);
1960 void nf_tables_unbind_set(const struct nft_ctx
*ctx
, struct nft_set
*set
,
1961 struct nft_set_binding
*binding
)
1963 list_del(&binding
->list
);
1965 if (list_empty(&set
->bindings
) && set
->flags
& NFT_SET_ANONYMOUS
)
1966 nf_tables_set_destroy(ctx
, set
);
1973 static const struct nla_policy nft_set_elem_policy
[NFTA_SET_ELEM_MAX
+ 1] = {
1974 [NFTA_SET_ELEM_KEY
] = { .type
= NLA_NESTED
},
1975 [NFTA_SET_ELEM_DATA
] = { .type
= NLA_NESTED
},
1976 [NFTA_SET_ELEM_FLAGS
] = { .type
= NLA_U32
},
1979 static const struct nla_policy nft_set_elem_list_policy
[NFTA_SET_ELEM_LIST_MAX
+ 1] = {
1980 [NFTA_SET_ELEM_LIST_TABLE
] = { .type
= NLA_STRING
},
1981 [NFTA_SET_ELEM_LIST_SET
] = { .type
= NLA_STRING
},
1982 [NFTA_SET_ELEM_LIST_ELEMENTS
] = { .type
= NLA_NESTED
},
1985 static int nft_ctx_init_from_elemattr(struct nft_ctx
*ctx
,
1986 const struct sk_buff
*skb
,
1987 const struct nlmsghdr
*nlh
,
1988 const struct nlattr
* const nla
[])
1990 const struct nfgenmsg
*nfmsg
= nlmsg_data(nlh
);
1991 const struct nft_af_info
*afi
;
1992 const struct nft_table
*table
;
1994 afi
= nf_tables_afinfo_lookup(nfmsg
->nfgen_family
, false);
1996 return PTR_ERR(afi
);
1998 table
= nf_tables_table_lookup(afi
, nla
[NFTA_SET_ELEM_LIST_TABLE
], false);
2000 return PTR_ERR(table
);
2002 nft_ctx_init(ctx
, skb
, nlh
, afi
, table
, NULL
);
2006 static int nf_tables_fill_setelem(struct sk_buff
*skb
,
2007 const struct nft_set
*set
,
2008 const struct nft_set_elem
*elem
)
2010 unsigned char *b
= skb_tail_pointer(skb
);
2011 struct nlattr
*nest
;
2013 nest
= nla_nest_start(skb
, NFTA_LIST_ELEM
);
2015 goto nla_put_failure
;
2017 if (nft_data_dump(skb
, NFTA_SET_ELEM_KEY
, &elem
->key
, NFT_DATA_VALUE
,
2019 goto nla_put_failure
;
2021 if (set
->flags
& NFT_SET_MAP
&&
2022 !(elem
->flags
& NFT_SET_ELEM_INTERVAL_END
) &&
2023 nft_data_dump(skb
, NFTA_SET_ELEM_DATA
, &elem
->data
,
2024 set
->dtype
== NFT_DATA_VERDICT
? NFT_DATA_VERDICT
: NFT_DATA_VALUE
,
2026 goto nla_put_failure
;
2028 if (elem
->flags
!= 0)
2029 if (nla_put_be32(skb
, NFTA_SET_ELEM_FLAGS
, htonl(elem
->flags
)))
2030 goto nla_put_failure
;
2032 nla_nest_end(skb
, nest
);
2040 struct nft_set_dump_args
{
2041 const struct netlink_callback
*cb
;
2042 struct nft_set_iter iter
;
2043 struct sk_buff
*skb
;
2046 static int nf_tables_dump_setelem(const struct nft_ctx
*ctx
,
2047 const struct nft_set
*set
,
2048 const struct nft_set_iter
*iter
,
2049 const struct nft_set_elem
*elem
)
2051 struct nft_set_dump_args
*args
;
2053 args
= container_of(iter
, struct nft_set_dump_args
, iter
);
2054 return nf_tables_fill_setelem(args
->skb
, set
, elem
);
2057 static int nf_tables_dump_set(struct sk_buff
*skb
, struct netlink_callback
*cb
)
2059 const struct nft_set
*set
;
2060 struct nft_set_dump_args args
;
2062 struct nlattr
*nla
[NFTA_SET_ELEM_LIST_MAX
+ 1];
2063 struct nfgenmsg
*nfmsg
;
2064 struct nlmsghdr
*nlh
;
2065 struct nlattr
*nest
;
2069 nfmsg
= nlmsg_data(cb
->nlh
);
2070 err
= nlmsg_parse(cb
->nlh
, sizeof(*nfmsg
), nla
, NFTA_SET_ELEM_LIST_MAX
,
2071 nft_set_elem_list_policy
);
2075 err
= nft_ctx_init_from_elemattr(&ctx
, cb
->skb
, cb
->nlh
, (void *)nla
);
2079 set
= nf_tables_set_lookup(ctx
.table
, nla
[NFTA_SET_ELEM_LIST_SET
]);
2081 return PTR_ERR(set
);
2083 event
= NFT_MSG_NEWSETELEM
;
2084 event
|= NFNL_SUBSYS_NFTABLES
<< 8;
2085 portid
= NETLINK_CB(cb
->skb
).portid
;
2086 seq
= cb
->nlh
->nlmsg_seq
;
2088 nlh
= nlmsg_put(skb
, portid
, seq
, event
, sizeof(struct nfgenmsg
),
2091 goto nla_put_failure
;
2093 nfmsg
= nlmsg_data(nlh
);
2094 nfmsg
->nfgen_family
= NFPROTO_UNSPEC
;
2095 nfmsg
->version
= NFNETLINK_V0
;
2098 if (nla_put_string(skb
, NFTA_SET_ELEM_LIST_TABLE
, ctx
.table
->name
))
2099 goto nla_put_failure
;
2100 if (nla_put_string(skb
, NFTA_SET_ELEM_LIST_SET
, set
->name
))
2101 goto nla_put_failure
;
2103 nest
= nla_nest_start(skb
, NFTA_SET_ELEM_LIST_ELEMENTS
);
2105 goto nla_put_failure
;
2109 args
.iter
.skip
= cb
->args
[0];
2110 args
.iter
.count
= 0;
2112 args
.iter
.fn
= nf_tables_dump_setelem
;
2113 set
->ops
->walk(&ctx
, set
, &args
.iter
);
2115 nla_nest_end(skb
, nest
);
2116 nlmsg_end(skb
, nlh
);
2118 if (args
.iter
.err
&& args
.iter
.err
!= -EMSGSIZE
)
2119 return args
.iter
.err
;
2120 if (args
.iter
.count
== cb
->args
[0])
2123 cb
->args
[0] = args
.iter
.count
;
2130 static int nf_tables_getsetelem(struct sock
*nlsk
, struct sk_buff
*skb
,
2131 const struct nlmsghdr
*nlh
,
2132 const struct nlattr
* const nla
[])
2134 const struct nft_set
*set
;
2138 err
= nft_ctx_init_from_elemattr(&ctx
, skb
, nlh
, nla
);
2142 set
= nf_tables_set_lookup(ctx
.table
, nla
[NFTA_SET_ELEM_LIST_SET
]);
2144 return PTR_ERR(set
);
2146 if (nlh
->nlmsg_flags
& NLM_F_DUMP
) {
2147 struct netlink_dump_control c
= {
2148 .dump
= nf_tables_dump_set
,
2150 return netlink_dump_start(nlsk
, skb
, nlh
, &c
);
2155 static int nft_add_set_elem(const struct nft_ctx
*ctx
, struct nft_set
*set
,
2156 const struct nlattr
*attr
)
2158 struct nlattr
*nla
[NFTA_SET_ELEM_MAX
+ 1];
2159 struct nft_data_desc d1
, d2
;
2160 struct nft_set_elem elem
;
2161 struct nft_set_binding
*binding
;
2162 enum nft_registers dreg
;
2165 err
= nla_parse_nested(nla
, NFTA_SET_ELEM_MAX
, attr
,
2166 nft_set_elem_policy
);
2170 if (nla
[NFTA_SET_ELEM_KEY
] == NULL
)
2174 if (nla
[NFTA_SET_ELEM_FLAGS
] != NULL
) {
2175 elem
.flags
= ntohl(nla_get_be32(nla
[NFTA_SET_ELEM_FLAGS
]));
2176 if (elem
.flags
& ~NFT_SET_ELEM_INTERVAL_END
)
2180 if (set
->flags
& NFT_SET_MAP
) {
2181 if (nla
[NFTA_SET_ELEM_DATA
] == NULL
&&
2182 !(elem
.flags
& NFT_SET_ELEM_INTERVAL_END
))
2185 if (nla
[NFTA_SET_ELEM_DATA
] != NULL
)
2189 err
= nft_data_init(ctx
, &elem
.key
, &d1
, nla
[NFTA_SET_ELEM_KEY
]);
2193 if (d1
.type
!= NFT_DATA_VALUE
|| d1
.len
!= set
->klen
)
2197 if (set
->ops
->get(set
, &elem
) == 0)
2200 if (nla
[NFTA_SET_ELEM_DATA
] != NULL
) {
2201 err
= nft_data_init(ctx
, &elem
.data
, &d2
, nla
[NFTA_SET_ELEM_DATA
]);
2206 if (set
->dtype
!= NFT_DATA_VERDICT
&& d2
.len
!= set
->dlen
)
2209 dreg
= nft_type_to_reg(set
->dtype
);
2210 list_for_each_entry(binding
, &set
->bindings
, list
) {
2211 struct nft_ctx bind_ctx
= {
2213 .table
= ctx
->table
,
2214 .chain
= binding
->chain
,
2217 err
= nft_validate_data_load(&bind_ctx
, dreg
,
2218 &elem
.data
, d2
.type
);
2224 err
= set
->ops
->insert(set
, &elem
);
2231 if (nla
[NFTA_SET_ELEM_DATA
] != NULL
)
2232 nft_data_uninit(&elem
.data
, d2
.type
);
2234 nft_data_uninit(&elem
.key
, d1
.type
);
2239 static int nf_tables_newsetelem(struct sock
*nlsk
, struct sk_buff
*skb
,
2240 const struct nlmsghdr
*nlh
,
2241 const struct nlattr
* const nla
[])
2243 const struct nlattr
*attr
;
2244 struct nft_set
*set
;
2248 err
= nft_ctx_init_from_elemattr(&ctx
, skb
, nlh
, nla
);
2252 set
= nf_tables_set_lookup(ctx
.table
, nla
[NFTA_SET_ELEM_LIST_SET
]);
2254 return PTR_ERR(set
);
2255 if (!list_empty(&set
->bindings
) && set
->flags
& NFT_SET_CONSTANT
)
2258 nla_for_each_nested(attr
, nla
[NFTA_SET_ELEM_LIST_ELEMENTS
], rem
) {
2259 err
= nft_add_set_elem(&ctx
, set
, attr
);
2266 static int nft_del_setelem(const struct nft_ctx
*ctx
, struct nft_set
*set
,
2267 const struct nlattr
*attr
)
2269 struct nlattr
*nla
[NFTA_SET_ELEM_MAX
+ 1];
2270 struct nft_data_desc desc
;
2271 struct nft_set_elem elem
;
2274 err
= nla_parse_nested(nla
, NFTA_SET_ELEM_MAX
, attr
,
2275 nft_set_elem_policy
);
2280 if (nla
[NFTA_SET_ELEM_KEY
] == NULL
)
2283 err
= nft_data_init(ctx
, &elem
.key
, &desc
, nla
[NFTA_SET_ELEM_KEY
]);
2288 if (desc
.type
!= NFT_DATA_VALUE
|| desc
.len
!= set
->klen
)
2291 err
= set
->ops
->get(set
, &elem
);
2295 set
->ops
->remove(set
, &elem
);
2297 nft_data_uninit(&elem
.key
, NFT_DATA_VALUE
);
2298 if (set
->flags
& NFT_SET_MAP
)
2299 nft_data_uninit(&elem
.data
, set
->dtype
);
2302 nft_data_uninit(&elem
.key
, desc
.type
);
2307 static int nf_tables_delsetelem(struct sock
*nlsk
, struct sk_buff
*skb
,
2308 const struct nlmsghdr
*nlh
,
2309 const struct nlattr
* const nla
[])
2311 const struct nlattr
*attr
;
2312 struct nft_set
*set
;
2316 err
= nft_ctx_init_from_elemattr(&ctx
, skb
, nlh
, nla
);
2320 set
= nf_tables_set_lookup(ctx
.table
, nla
[NFTA_SET_ELEM_LIST_SET
]);
2322 return PTR_ERR(set
);
2323 if (!list_empty(&set
->bindings
) && set
->flags
& NFT_SET_CONSTANT
)
2326 nla_for_each_nested(attr
, nla
[NFTA_SET_ELEM_LIST_ELEMENTS
], rem
) {
2327 err
= nft_del_setelem(&ctx
, set
, attr
);
2334 static const struct nfnl_callback nf_tables_cb
[NFT_MSG_MAX
] = {
2335 [NFT_MSG_NEWTABLE
] = {
2336 .call
= nf_tables_newtable
,
2337 .attr_count
= NFTA_TABLE_MAX
,
2338 .policy
= nft_table_policy
,
2340 [NFT_MSG_GETTABLE
] = {
2341 .call
= nf_tables_gettable
,
2342 .attr_count
= NFTA_TABLE_MAX
,
2343 .policy
= nft_table_policy
,
2345 [NFT_MSG_DELTABLE
] = {
2346 .call
= nf_tables_deltable
,
2347 .attr_count
= NFTA_TABLE_MAX
,
2348 .policy
= nft_table_policy
,
2350 [NFT_MSG_NEWCHAIN
] = {
2351 .call
= nf_tables_newchain
,
2352 .attr_count
= NFTA_CHAIN_MAX
,
2353 .policy
= nft_chain_policy
,
2355 [NFT_MSG_GETCHAIN
] = {
2356 .call
= nf_tables_getchain
,
2357 .attr_count
= NFTA_CHAIN_MAX
,
2358 .policy
= nft_chain_policy
,
2360 [NFT_MSG_DELCHAIN
] = {
2361 .call
= nf_tables_delchain
,
2362 .attr_count
= NFTA_CHAIN_MAX
,
2363 .policy
= nft_chain_policy
,
2365 [NFT_MSG_NEWRULE
] = {
2366 .call
= nf_tables_newrule
,
2367 .attr_count
= NFTA_RULE_MAX
,
2368 .policy
= nft_rule_policy
,
2370 [NFT_MSG_GETRULE
] = {
2371 .call
= nf_tables_getrule
,
2372 .attr_count
= NFTA_RULE_MAX
,
2373 .policy
= nft_rule_policy
,
2375 [NFT_MSG_DELRULE
] = {
2376 .call
= nf_tables_delrule
,
2377 .attr_count
= NFTA_RULE_MAX
,
2378 .policy
= nft_rule_policy
,
2380 [NFT_MSG_NEWSET
] = {
2381 .call
= nf_tables_newset
,
2382 .attr_count
= NFTA_SET_MAX
,
2383 .policy
= nft_set_policy
,
2385 [NFT_MSG_GETSET
] = {
2386 .call
= nf_tables_getset
,
2387 .attr_count
= NFTA_SET_MAX
,
2388 .policy
= nft_set_policy
,
2390 [NFT_MSG_DELSET
] = {
2391 .call
= nf_tables_delset
,
2392 .attr_count
= NFTA_SET_MAX
,
2393 .policy
= nft_set_policy
,
2395 [NFT_MSG_NEWSETELEM
] = {
2396 .call
= nf_tables_newsetelem
,
2397 .attr_count
= NFTA_SET_ELEM_LIST_MAX
,
2398 .policy
= nft_set_elem_list_policy
,
2400 [NFT_MSG_GETSETELEM
] = {
2401 .call
= nf_tables_getsetelem
,
2402 .attr_count
= NFTA_SET_ELEM_LIST_MAX
,
2403 .policy
= nft_set_elem_list_policy
,
2405 [NFT_MSG_DELSETELEM
] = {
2406 .call
= nf_tables_delsetelem
,
2407 .attr_count
= NFTA_SET_ELEM_LIST_MAX
,
2408 .policy
= nft_set_elem_list_policy
,
2412 static const struct nfnetlink_subsystem nf_tables_subsys
= {
2413 .name
= "nf_tables",
2414 .subsys_id
= NFNL_SUBSYS_NFTABLES
,
2415 .cb_count
= NFT_MSG_MAX
,
2420 * Loop detection - walk through the ruleset beginning at the destination chain
2421 * of a new jump until either the source chain is reached (loop) or all
2422 * reachable chains have been traversed.
2424 * The loop check is performed whenever a new jump verdict is added to an
2425 * expression or verdict map or a verdict map is bound to a new chain.
2428 static int nf_tables_check_loops(const struct nft_ctx
*ctx
,
2429 const struct nft_chain
*chain
);
2431 static int nf_tables_loop_check_setelem(const struct nft_ctx
*ctx
,
2432 const struct nft_set
*set
,
2433 const struct nft_set_iter
*iter
,
2434 const struct nft_set_elem
*elem
)
2436 switch (elem
->data
.verdict
) {
2439 return nf_tables_check_loops(ctx
, elem
->data
.chain
);
2445 static int nf_tables_check_loops(const struct nft_ctx
*ctx
,
2446 const struct nft_chain
*chain
)
2448 const struct nft_rule
*rule
;
2449 const struct nft_expr
*expr
, *last
;
2450 const struct nft_data
*data
;
2451 const struct nft_set
*set
;
2452 struct nft_set_binding
*binding
;
2453 struct nft_set_iter iter
;
2456 if (ctx
->chain
== chain
)
2459 list_for_each_entry(rule
, &chain
->rules
, list
) {
2460 nft_rule_for_each_expr(expr
, last
, rule
) {
2461 if (!expr
->ops
->get_verdict
)
2464 data
= expr
->ops
->get_verdict(expr
);
2468 switch (data
->verdict
) {
2471 err
= nf_tables_check_loops(ctx
, data
->chain
);
2480 list_for_each_entry(set
, &ctx
->table
->sets
, list
) {
2481 if (!(set
->flags
& NFT_SET_MAP
) ||
2482 set
->dtype
!= NFT_DATA_VERDICT
)
2485 list_for_each_entry(binding
, &set
->bindings
, list
) {
2486 if (binding
->chain
!= chain
)
2492 iter
.fn
= nf_tables_loop_check_setelem
;
2494 set
->ops
->walk(ctx
, set
, &iter
);
2504 * nft_validate_input_register - validate an expressions' input register
2506 * @reg: the register number
2508 * Validate that the input register is one of the general purpose
2511 int nft_validate_input_register(enum nft_registers reg
)
2513 if (reg
<= NFT_REG_VERDICT
)
2515 if (reg
> NFT_REG_MAX
)
2519 EXPORT_SYMBOL_GPL(nft_validate_input_register
);
2522 * nft_validate_output_register - validate an expressions' output register
2524 * @reg: the register number
2526 * Validate that the output register is one of the general purpose
2527 * registers or the verdict register.
2529 int nft_validate_output_register(enum nft_registers reg
)
2531 if (reg
< NFT_REG_VERDICT
)
2533 if (reg
> NFT_REG_MAX
)
2537 EXPORT_SYMBOL_GPL(nft_validate_output_register
);
2540 * nft_validate_data_load - validate an expressions' data load
2542 * @ctx: context of the expression performing the load
2543 * @reg: the destination register number
2544 * @data: the data to load
2545 * @type: the data type
2547 * Validate that a data load uses the appropriate data type for
2548 * the destination register. A value of NULL for the data means
2549 * that its runtime gathered data, which is always of type
2552 int nft_validate_data_load(const struct nft_ctx
*ctx
, enum nft_registers reg
,
2553 const struct nft_data
*data
,
2554 enum nft_data_types type
)
2559 case NFT_REG_VERDICT
:
2560 if (data
== NULL
|| type
!= NFT_DATA_VERDICT
)
2563 if (data
->verdict
== NFT_GOTO
|| data
->verdict
== NFT_JUMP
) {
2564 err
= nf_tables_check_loops(ctx
, data
->chain
);
2568 if (ctx
->chain
->level
+ 1 > data
->chain
->level
) {
2569 if (ctx
->chain
->level
+ 1 == NFT_JUMP_STACK_SIZE
)
2571 data
->chain
->level
= ctx
->chain
->level
+ 1;
2577 if (data
!= NULL
&& type
!= NFT_DATA_VALUE
)
2582 EXPORT_SYMBOL_GPL(nft_validate_data_load
);
2584 static const struct nla_policy nft_verdict_policy
[NFTA_VERDICT_MAX
+ 1] = {
2585 [NFTA_VERDICT_CODE
] = { .type
= NLA_U32
},
2586 [NFTA_VERDICT_CHAIN
] = { .type
= NLA_STRING
,
2587 .len
= NFT_CHAIN_MAXNAMELEN
- 1 },
2590 static int nft_verdict_init(const struct nft_ctx
*ctx
, struct nft_data
*data
,
2591 struct nft_data_desc
*desc
, const struct nlattr
*nla
)
2593 struct nlattr
*tb
[NFTA_VERDICT_MAX
+ 1];
2594 struct nft_chain
*chain
;
2597 err
= nla_parse_nested(tb
, NFTA_VERDICT_MAX
, nla
, nft_verdict_policy
);
2601 if (!tb
[NFTA_VERDICT_CODE
])
2603 data
->verdict
= ntohl(nla_get_be32(tb
[NFTA_VERDICT_CODE
]));
2605 switch (data
->verdict
) {
2612 desc
->len
= sizeof(data
->verdict
);
2616 if (!tb
[NFTA_VERDICT_CHAIN
])
2618 chain
= nf_tables_chain_lookup(ctx
->table
,
2619 tb
[NFTA_VERDICT_CHAIN
]);
2621 return PTR_ERR(chain
);
2622 if (chain
->flags
& NFT_BASE_CHAIN
)
2626 data
->chain
= chain
;
2627 desc
->len
= sizeof(data
);
2633 desc
->type
= NFT_DATA_VERDICT
;
2637 static void nft_verdict_uninit(const struct nft_data
*data
)
2639 switch (data
->verdict
) {
2647 static int nft_verdict_dump(struct sk_buff
*skb
, const struct nft_data
*data
)
2649 struct nlattr
*nest
;
2651 nest
= nla_nest_start(skb
, NFTA_DATA_VERDICT
);
2653 goto nla_put_failure
;
2655 if (nla_put_be32(skb
, NFTA_VERDICT_CODE
, htonl(data
->verdict
)))
2656 goto nla_put_failure
;
2658 switch (data
->verdict
) {
2661 if (nla_put_string(skb
, NFTA_VERDICT_CHAIN
, data
->chain
->name
))
2662 goto nla_put_failure
;
2664 nla_nest_end(skb
, nest
);
2671 static int nft_value_init(const struct nft_ctx
*ctx
, struct nft_data
*data
,
2672 struct nft_data_desc
*desc
, const struct nlattr
*nla
)
2679 if (len
> sizeof(data
->data
))
2682 nla_memcpy(data
->data
, nla
, sizeof(data
->data
));
2683 desc
->type
= NFT_DATA_VALUE
;
2688 static int nft_value_dump(struct sk_buff
*skb
, const struct nft_data
*data
,
2691 return nla_put(skb
, NFTA_DATA_VALUE
, len
, data
->data
);
2694 static const struct nla_policy nft_data_policy
[NFTA_DATA_MAX
+ 1] = {
2695 [NFTA_DATA_VALUE
] = { .type
= NLA_BINARY
,
2696 .len
= FIELD_SIZEOF(struct nft_data
, data
) },
2697 [NFTA_DATA_VERDICT
] = { .type
= NLA_NESTED
},
2701 * nft_data_init - parse nf_tables data netlink attributes
2703 * @ctx: context of the expression using the data
2704 * @data: destination struct nft_data
2705 * @desc: data description
2706 * @nla: netlink attribute containing data
2708 * Parse the netlink data attributes and initialize a struct nft_data.
2709 * The type and length of data are returned in the data description.
2711 * The caller can indicate that it only wants to accept data of type
2712 * NFT_DATA_VALUE by passing NULL for the ctx argument.
2714 int nft_data_init(const struct nft_ctx
*ctx
, struct nft_data
*data
,
2715 struct nft_data_desc
*desc
, const struct nlattr
*nla
)
2717 struct nlattr
*tb
[NFTA_DATA_MAX
+ 1];
2720 err
= nla_parse_nested(tb
, NFTA_DATA_MAX
, nla
, nft_data_policy
);
2724 if (tb
[NFTA_DATA_VALUE
])
2725 return nft_value_init(ctx
, data
, desc
, tb
[NFTA_DATA_VALUE
]);
2726 if (tb
[NFTA_DATA_VERDICT
] && ctx
!= NULL
)
2727 return nft_verdict_init(ctx
, data
, desc
, tb
[NFTA_DATA_VERDICT
]);
2730 EXPORT_SYMBOL_GPL(nft_data_init
);
2733 * nft_data_uninit - release a nft_data item
2735 * @data: struct nft_data to release
2736 * @type: type of data
2738 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
2739 * all others need to be released by calling this function.
2741 void nft_data_uninit(const struct nft_data
*data
, enum nft_data_types type
)
2744 case NFT_DATA_VALUE
:
2746 case NFT_DATA_VERDICT
:
2747 return nft_verdict_uninit(data
);
2752 EXPORT_SYMBOL_GPL(nft_data_uninit
);
2754 int nft_data_dump(struct sk_buff
*skb
, int attr
, const struct nft_data
*data
,
2755 enum nft_data_types type
, unsigned int len
)
2757 struct nlattr
*nest
;
2760 nest
= nla_nest_start(skb
, attr
);
2765 case NFT_DATA_VALUE
:
2766 err
= nft_value_dump(skb
, data
, len
);
2768 case NFT_DATA_VERDICT
:
2769 err
= nft_verdict_dump(skb
, data
);
2776 nla_nest_end(skb
, nest
);
2779 EXPORT_SYMBOL_GPL(nft_data_dump
);
2781 static int __init
nf_tables_module_init(void)
2785 info
= kmalloc(sizeof(struct nft_expr_info
) * NFT_RULE_MAXEXPRS
,
2792 err
= nf_tables_core_module_init();
2796 err
= nfnetlink_subsys_register(&nf_tables_subsys
);
2800 pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
2803 nf_tables_core_module_exit();
2810 static void __exit
nf_tables_module_exit(void)
2812 nfnetlink_subsys_unregister(&nf_tables_subsys
);
2813 nf_tables_core_module_exit();
2817 module_init(nf_tables_module_init
);
2818 module_exit(nf_tables_module_exit
);
2820 MODULE_LICENSE("GPL");
2821 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
2822 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES
);