aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-07-06 12:15:15 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-06 12:15:15 -0400
commitae3e4562e2ce0149a4424c994a282955700711e7 (patch)
treeaf7f75611e30d8502c2f3eee9f1f9e1aaa9f6534 /net/netfilter
parent73e20b761acf8678de2d55d92b90a623b8558a77 (diff)
parentc6ac37d8d8843fb1fdc34e4a2a41a4f027ab670c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains Netfilter updates for net-next, they are: 1) Don't use userspace datatypes in bridge netfilter code, from Tobin Harding. 2) Iterate only once over the expectation table when removing the helper module, instead of once per-netns, from Florian Westphal. 3) Extra sanitization in xt_hook_ops_alloc() to return error in case we ever pass zero hooks, xt_hook_ops_alloc(): 4) Handle NFPROTO_INET from the logging core infrastructure, from Liping Zhang. 5) Autoload loggers when TRACE target is used from rules, this doesn't change the behaviour in case the user already selected nfnetlink_log as preferred way to print tracing logs, also from Liping Zhang. 6) Conntrack slabs with SLAB_HWCACHE_ALIGN to allow rearranging fields by cache lines, increases the size of entries in 11% per entry. From Florian Westphal. 7) Skip zone comparison if CONFIG_NF_CONNTRACK_ZONES=n, from Florian. 8) Remove useless defensive check in nf_logger_find_get() from Shivani Bhardwaj. 9) Remove zone extension as place it in the conntrack object, this is always include in the hashing and we expect more intensive use of zones since containers are in place. Also from Florian Westphal. 10) Owner match now works from any namespace, from Eric Bierdeman. 11) Make sure we only reply with TCP reset to TCP traffic from nf_reject_ipv4, patch from Liping Zhang. 12) Introduce --nflog-size to indicate amount of network packet bytes that are copied to userspace via log message, from Vishwanath Pai. This obsoletes --nflog-range that has never worked, it was designed to achieve this but it has never worked. 13) Introduce generic macros for nf_tables object generation masks. 14) Use generation mask in table, chain and set objects in nf_tables. This allows fixes interferences with ongoing preparation phase of the commit protocol and object listings going on at the same time. This update is introduced in three patches, one per object. 15) Check if the object is active in the next generation for element deactivation in the rbtree implementation, given that deactivation happens from the commit phase path we have to observe the future status of the object. 16) Support for deletion of just added elements in the hash set type. 17) Allow to resize hashtable from /proc entry, not only from the obscure /sys entry that maps to the module parameter, from Florian Westphal. 18) Get rid of NFT_BASECHAIN_DISABLED, this code is not exercised anymore since we tear down the ruleset whenever the netdevice goes away. 19) Support for matching inverted set lookups, from Arturo Borrero. 20) Simplify the iptables_mangle_hook() by removing a superfluous extra branch. 21) Introduce ether_addr_equal_masked() and use it from the netfilter codebase, from Joe Perches. 22) Remove references to "Use netfilter MARK value as routing key" from the Netfilter Kconfig description given that this toggle doesn't exists already for 10 years, from Moritz Sichert. 23) Introduce generic NF_INVF() and use it from the xtables codebase, from Joe Perches. 24) Setting logger to NONE via /proc was not working unless explicit nul-termination was included in the string. This fixes seems to leave the former behaviour there, so we don't break backward. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/Kconfig10
-rw-r--r--net/netfilter/nf_conntrack_core.c76
-rw-r--r--net/netfilter/nf_conntrack_helper.c61
-rw-r--r--net/netfilter/nf_conntrack_standalone.c36
-rw-r--r--net/netfilter/nf_log.c33
-rw-r--r--net/netfilter/nf_tables_api.c366
-rw-r--r--net/netfilter/nfnetlink_log.c9
-rw-r--r--net/netfilter/nft_dynset.c7
-rw-r--r--net/netfilter/nft_hash.c6
-rw-r--r--net/netfilter/nft_log.c21
-rw-r--r--net/netfilter/nft_lookup.c43
-rw-r--r--net/netfilter/nft_rbtree.c2
-rw-r--r--net/netfilter/x_tables.c3
-rw-r--r--net/netfilter/xt_NFLOG.c3
-rw-r--r--net/netfilter/xt_TRACE.c25
-rw-r--r--net/netfilter/xt_owner.c41
-rw-r--r--net/netfilter/xt_tcpudp.c7
17 files changed, 428 insertions, 321 deletions
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 95e757c377f9..9266ceebd112 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -609,9 +609,8 @@ config NETFILTER_XT_MARK
609 The target allows you to create rules in the "mangle" table which alter 609 The target allows you to create rules in the "mangle" table which alter
610 the netfilter mark (nfmark) field associated with the packet. 610 the netfilter mark (nfmark) field associated with the packet.
611 611
612 Prior to routing, the nfmark can influence the routing method (see 612 Prior to routing, the nfmark can influence the routing method and can
613 "Use netfilter MARK value as routing key") and can also be used by 613 also be used by other subsystems to change their behavior.
614 other subsystems to change their behavior.
615 614
616config NETFILTER_XT_CONNMARK 615config NETFILTER_XT_CONNMARK
617 tristate 'ctmark target and match support' 616 tristate 'ctmark target and match support'
@@ -753,9 +752,8 @@ config NETFILTER_XT_TARGET_HMARK
753 752
754 The target allows you to create rules in the "raw" and "mangle" tables 753 The target allows you to create rules in the "raw" and "mangle" tables
755 which set the skbuff mark by means of hash calculation within a given 754 which set the skbuff mark by means of hash calculation within a given
756 range. The nfmark can influence the routing method (see "Use netfilter 755 range. The nfmark can influence the routing method and can also be used
757 MARK value as routing key") and can also be used by other subsystems to 756 by other subsystems to change their behaviour.
758 change their behaviour.
759 757
760 To compile it as a module, choose M here. If unsure, say N. 758 To compile it as a module, choose M here. If unsure, say N.
761 759
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index f204274a9b6b..153e33ffeeaa 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -327,16 +327,10 @@ struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
327 327
328 tmpl->status = IPS_TEMPLATE; 328 tmpl->status = IPS_TEMPLATE;
329 write_pnet(&tmpl->ct_net, net); 329 write_pnet(&tmpl->ct_net, net);
330 330 nf_ct_zone_add(tmpl, zone);
331 if (nf_ct_zone_add(tmpl, flags, zone) < 0)
332 goto out_free;
333
334 atomic_set(&tmpl->ct_general.use, 0); 331 atomic_set(&tmpl->ct_general.use, 0);
335 332
336 return tmpl; 333 return tmpl;
337out_free:
338 kfree(tmpl);
339 return NULL;
340} 334}
341EXPORT_SYMBOL_GPL(nf_ct_tmpl_alloc); 335EXPORT_SYMBOL_GPL(nf_ct_tmpl_alloc);
342 336
@@ -929,16 +923,13 @@ __nf_conntrack_alloc(struct net *net,
929 offsetof(struct nf_conn, proto) - 923 offsetof(struct nf_conn, proto) -
930 offsetof(struct nf_conn, __nfct_init_offset[0])); 924 offsetof(struct nf_conn, __nfct_init_offset[0]));
931 925
932 if (zone && nf_ct_zone_add(ct, GFP_ATOMIC, zone) < 0) 926 nf_ct_zone_add(ct, zone);
933 goto out_free;
934 927
935 /* Because we use RCU lookups, we set ct_general.use to zero before 928 /* Because we use RCU lookups, we set ct_general.use to zero before
936 * this is inserted in any list. 929 * this is inserted in any list.
937 */ 930 */
938 atomic_set(&ct->ct_general.use, 0); 931 atomic_set(&ct->ct_general.use, 0);
939 return ct; 932 return ct;
940out_free:
941 kmem_cache_free(nf_conntrack_cachep, ct);
942out: 933out:
943 atomic_dec(&net->ct.count); 934 atomic_dec(&net->ct.count);
944 return ERR_PTR(-ENOMEM); 935 return ERR_PTR(-ENOMEM);
@@ -1342,14 +1333,6 @@ bool __nf_ct_kill_acct(struct nf_conn *ct,
1342} 1333}
1343EXPORT_SYMBOL_GPL(__nf_ct_kill_acct); 1334EXPORT_SYMBOL_GPL(__nf_ct_kill_acct);
1344 1335
1345#ifdef CONFIG_NF_CONNTRACK_ZONES
1346static struct nf_ct_ext_type nf_ct_zone_extend __read_mostly = {
1347 .len = sizeof(struct nf_conntrack_zone),
1348 .align = __alignof__(struct nf_conntrack_zone),
1349 .id = NF_CT_EXT_ZONE,
1350};
1351#endif
1352
1353#if IS_ENABLED(CONFIG_NF_CT_NETLINK) 1336#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
1354 1337
1355#include <linux/netfilter/nfnetlink.h> 1338#include <linux/netfilter/nfnetlink.h>
@@ -1532,9 +1515,6 @@ void nf_conntrack_cleanup_end(void)
1532 1515
1533 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_htable_size); 1516 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_htable_size);
1534 1517
1535#ifdef CONFIG_NF_CONNTRACK_ZONES
1536 nf_ct_extend_unregister(&nf_ct_zone_extend);
1537#endif
1538 nf_conntrack_proto_fini(); 1518 nf_conntrack_proto_fini();
1539 nf_conntrack_seqadj_fini(); 1519 nf_conntrack_seqadj_fini();
1540 nf_conntrack_labels_fini(); 1520 nf_conntrack_labels_fini();
@@ -1617,24 +1597,14 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
1617} 1597}
1618EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable); 1598EXPORT_SYMBOL_GPL(nf_ct_alloc_hashtable);
1619 1599
1620int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) 1600int nf_conntrack_hash_resize(unsigned int hashsize)
1621{ 1601{
1622 int i, bucket, rc; 1602 int i, bucket;
1623 unsigned int hashsize, old_size; 1603 unsigned int old_size;
1624 struct hlist_nulls_head *hash, *old_hash; 1604 struct hlist_nulls_head *hash, *old_hash;
1625 struct nf_conntrack_tuple_hash *h; 1605 struct nf_conntrack_tuple_hash *h;
1626 struct nf_conn *ct; 1606 struct nf_conn *ct;
1627 1607
1628 if (current->nsproxy->net_ns != &init_net)
1629 return -EOPNOTSUPP;
1630
1631 /* On boot, we can set this without any fancy locking. */
1632 if (!nf_conntrack_htable_size)
1633 return param_set_uint(val, kp);
1634
1635 rc = kstrtouint(val, 0, &hashsize);
1636 if (rc)
1637 return rc;
1638 if (!hashsize) 1608 if (!hashsize)
1639 return -EINVAL; 1609 return -EINVAL;
1640 1610
@@ -1642,6 +1612,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1642 if (!hash) 1612 if (!hash)
1643 return -ENOMEM; 1613 return -ENOMEM;
1644 1614
1615 old_size = nf_conntrack_htable_size;
1616 if (old_size == hashsize) {
1617 nf_ct_free_hashtable(hash, hashsize);
1618 return 0;
1619 }
1620
1645 local_bh_disable(); 1621 local_bh_disable();
1646 nf_conntrack_all_lock(); 1622 nf_conntrack_all_lock();
1647 write_seqcount_begin(&nf_conntrack_generation); 1623 write_seqcount_begin(&nf_conntrack_generation);
@@ -1677,6 +1653,25 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1677 nf_ct_free_hashtable(old_hash, old_size); 1653 nf_ct_free_hashtable(old_hash, old_size);
1678 return 0; 1654 return 0;
1679} 1655}
1656
1657int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1658{
1659 unsigned int hashsize;
1660 int rc;
1661
1662 if (current->nsproxy->net_ns != &init_net)
1663 return -EOPNOTSUPP;
1664
1665 /* On boot, we can set this without any fancy locking. */
1666 if (!nf_conntrack_htable_size)
1667 return param_set_uint(val, kp);
1668
1669 rc = kstrtouint(val, 0, &hashsize);
1670 if (rc)
1671 return rc;
1672
1673 return nf_conntrack_hash_resize(hashsize);
1674}
1680EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize); 1675EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
1681 1676
1682module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, 1677module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
@@ -1733,7 +1728,7 @@ int nf_conntrack_init_start(void)
1733 1728
1734 nf_conntrack_cachep = kmem_cache_create("nf_conntrack", 1729 nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
1735 sizeof(struct nf_conn), 0, 1730 sizeof(struct nf_conn), 0,
1736 SLAB_DESTROY_BY_RCU, NULL); 1731 SLAB_DESTROY_BY_RCU | SLAB_HWCACHE_ALIGN, NULL);
1737 if (!nf_conntrack_cachep) 1732 if (!nf_conntrack_cachep)
1738 goto err_cachep; 1733 goto err_cachep;
1739 1734
@@ -1773,11 +1768,6 @@ int nf_conntrack_init_start(void)
1773 if (ret < 0) 1768 if (ret < 0)
1774 goto err_seqadj; 1769 goto err_seqadj;
1775 1770
1776#ifdef CONFIG_NF_CONNTRACK_ZONES
1777 ret = nf_ct_extend_register(&nf_ct_zone_extend);
1778 if (ret < 0)
1779 goto err_extend;
1780#endif
1781 ret = nf_conntrack_proto_init(); 1771 ret = nf_conntrack_proto_init();
1782 if (ret < 0) 1772 if (ret < 0)
1783 goto err_proto; 1773 goto err_proto;
@@ -1793,10 +1783,6 @@ int nf_conntrack_init_start(void)
1793 return 0; 1783 return 0;
1794 1784
1795err_proto: 1785err_proto:
1796#ifdef CONFIG_NF_CONNTRACK_ZONES
1797 nf_ct_extend_unregister(&nf_ct_zone_extend);
1798err_extend:
1799#endif
1800 nf_conntrack_seqadj_fini(); 1786 nf_conntrack_seqadj_fini();
1801err_seqadj: 1787err_seqadj:
1802 nf_conntrack_labels_fini(); 1788 nf_conntrack_labels_fini();
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 196cb39649e1..3a1a88b9bafa 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -389,11 +389,38 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
389 struct net *net) 389 struct net *net)
390{ 390{
391 struct nf_conntrack_tuple_hash *h; 391 struct nf_conntrack_tuple_hash *h;
392 const struct hlist_nulls_node *nn;
393 int cpu;
394
395 /* Get rid of expecteds, set helpers to NULL. */
396 for_each_possible_cpu(cpu) {
397 struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
398
399 spin_lock_bh(&pcpu->lock);
400 hlist_nulls_for_each_entry(h, nn, &pcpu->unconfirmed, hnnode)
401 unhelp(h, me);
402 spin_unlock_bh(&pcpu->lock);
403 }
404}
405
406void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
407{
408 struct nf_conntrack_tuple_hash *h;
392 struct nf_conntrack_expect *exp; 409 struct nf_conntrack_expect *exp;
393 const struct hlist_node *next; 410 const struct hlist_node *next;
394 const struct hlist_nulls_node *nn; 411 const struct hlist_nulls_node *nn;
412 struct net *net;
395 unsigned int i; 413 unsigned int i;
396 int cpu; 414
415 mutex_lock(&nf_ct_helper_mutex);
416 hlist_del_rcu(&me->hnode);
417 nf_ct_helper_count--;
418 mutex_unlock(&nf_ct_helper_mutex);
419
420 /* Make sure every nothing is still using the helper unless its a
421 * connection in the hash.
422 */
423 synchronize_rcu();
397 424
398 /* Get rid of expectations */ 425 /* Get rid of expectations */
399 spin_lock_bh(&nf_conntrack_expect_lock); 426 spin_lock_bh(&nf_conntrack_expect_lock);
@@ -413,15 +440,11 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
413 } 440 }
414 spin_unlock_bh(&nf_conntrack_expect_lock); 441 spin_unlock_bh(&nf_conntrack_expect_lock);
415 442
416 /* Get rid of expecteds, set helpers to NULL. */ 443 rtnl_lock();
417 for_each_possible_cpu(cpu) { 444 for_each_net(net)
418 struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); 445 __nf_conntrack_helper_unregister(me, net);
446 rtnl_unlock();
419 447
420 spin_lock_bh(&pcpu->lock);
421 hlist_nulls_for_each_entry(h, nn, &pcpu->unconfirmed, hnnode)
422 unhelp(h, me);
423 spin_unlock_bh(&pcpu->lock);
424 }
425 local_bh_disable(); 448 local_bh_disable();
426 for (i = 0; i < nf_conntrack_htable_size; i++) { 449 for (i = 0; i < nf_conntrack_htable_size; i++) {
427 nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]); 450 nf_conntrack_lock(&nf_conntrack_locks[i % CONNTRACK_LOCKS]);
@@ -433,26 +456,6 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
433 } 456 }
434 local_bh_enable(); 457 local_bh_enable();
435} 458}
436
437void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
438{
439 struct net *net;
440
441 mutex_lock(&nf_ct_helper_mutex);
442 hlist_del_rcu(&me->hnode);
443 nf_ct_helper_count--;
444 mutex_unlock(&nf_ct_helper_mutex);
445
446 /* Make sure every nothing is still using the helper unless its a
447 * connection in the hash.
448 */
449 synchronize_rcu();
450
451 rtnl_lock();
452 for_each_net(net)
453 __nf_conntrack_helper_unregister(me, net);
454 rtnl_unlock();
455}
456EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); 459EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
457 460
458static struct nf_ct_ext_type helper_extend __read_mostly = { 461static struct nf_ct_ext_type helper_extend __read_mostly = {
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index c026c472ea80..2aaa188ee961 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -434,8 +434,29 @@ static void nf_conntrack_standalone_fini_proc(struct net *net)
434 434
435#ifdef CONFIG_SYSCTL 435#ifdef CONFIG_SYSCTL
436/* Log invalid packets of a given protocol */ 436/* Log invalid packets of a given protocol */
437static int log_invalid_proto_min = 0; 437static int log_invalid_proto_min __read_mostly;
438static int log_invalid_proto_max = 255; 438static int log_invalid_proto_max __read_mostly = 255;
439
440/* size the user *wants to set */
441static unsigned int nf_conntrack_htable_size_user __read_mostly;
442
443static int
444nf_conntrack_hash_sysctl(struct ctl_table *table, int write,
445 void __user *buffer, size_t *lenp, loff_t *ppos)
446{
447 int ret;
448
449 ret = proc_dointvec(table, write, buffer, lenp, ppos);
450 if (ret < 0 || !write)
451 return ret;
452
453 /* update ret, we might not be able to satisfy request */
454 ret = nf_conntrack_hash_resize(nf_conntrack_htable_size_user);
455
456 /* update it to the actual value used by conntrack */
457 nf_conntrack_htable_size_user = nf_conntrack_htable_size;
458 return ret;
459}
439 460
440static struct ctl_table_header *nf_ct_netfilter_header; 461static struct ctl_table_header *nf_ct_netfilter_header;
441 462
@@ -456,10 +477,10 @@ static struct ctl_table nf_ct_sysctl_table[] = {
456 }, 477 },
457 { 478 {
458 .procname = "nf_conntrack_buckets", 479 .procname = "nf_conntrack_buckets",
459 .data = &nf_conntrack_htable_size, 480 .data = &nf_conntrack_htable_size_user,
460 .maxlen = sizeof(unsigned int), 481 .maxlen = sizeof(unsigned int),
461 .mode = 0444, 482 .mode = 0644,
462 .proc_handler = proc_dointvec, 483 .proc_handler = nf_conntrack_hash_sysctl,
463 }, 484 },
464 { 485 {
465 .procname = "nf_conntrack_checksum", 486 .procname = "nf_conntrack_checksum",
@@ -515,6 +536,9 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net)
515 if (net->user_ns != &init_user_ns) 536 if (net->user_ns != &init_user_ns)
516 table[0].procname = NULL; 537 table[0].procname = NULL;
517 538
539 if (!net_eq(&init_net, net))
540 table[2].mode = 0444;
541
518 net->ct.sysctl_header = register_net_sysctl(net, "net/netfilter", table); 542 net->ct.sysctl_header = register_net_sysctl(net, "net/netfilter", table);
519 if (!net->ct.sysctl_header) 543 if (!net->ct.sysctl_header)
520 goto out_unregister_netfilter; 544 goto out_unregister_netfilter;
@@ -604,6 +628,8 @@ static int __init nf_conntrack_standalone_init(void)
604 ret = -ENOMEM; 628 ret = -ENOMEM;
605 goto out_sysctl; 629 goto out_sysctl;
606 } 630 }
631
632 nf_conntrack_htable_size_user = nf_conntrack_htable_size;
607#endif 633#endif
608 634
609 ret = register_pernet_subsys(&nf_conntrack_net_ops); 635 ret = register_pernet_subsys(&nf_conntrack_net_ops);
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index a5d41dfa9f05..aa5847a16713 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -159,6 +159,20 @@ int nf_logger_find_get(int pf, enum nf_log_type type)
159 struct nf_logger *logger; 159 struct nf_logger *logger;
160 int ret = -ENOENT; 160 int ret = -ENOENT;
161 161
162 if (pf == NFPROTO_INET) {
163 ret = nf_logger_find_get(NFPROTO_IPV4, type);
164 if (ret < 0)
165 return ret;
166
167 ret = nf_logger_find_get(NFPROTO_IPV6, type);
168 if (ret < 0) {
169 nf_logger_put(NFPROTO_IPV4, type);
170 return ret;
171 }
172
173 return 0;
174 }
175
162 if (rcu_access_pointer(loggers[pf][type]) == NULL) 176 if (rcu_access_pointer(loggers[pf][type]) == NULL)
163 request_module("nf-logger-%u-%u", pf, type); 177 request_module("nf-logger-%u-%u", pf, type);
164 178
@@ -167,7 +181,7 @@ int nf_logger_find_get(int pf, enum nf_log_type type)
167 if (logger == NULL) 181 if (logger == NULL)
168 goto out; 182 goto out;
169 183
170 if (logger && try_module_get(logger->me)) 184 if (try_module_get(logger->me))
171 ret = 0; 185 ret = 0;
172out: 186out:
173 rcu_read_unlock(); 187 rcu_read_unlock();
@@ -179,6 +193,12 @@ void nf_logger_put(int pf, enum nf_log_type type)
179{ 193{
180 struct nf_logger *logger; 194 struct nf_logger *logger;
181 195
196 if (pf == NFPROTO_INET) {
197 nf_logger_put(NFPROTO_IPV4, type);
198 nf_logger_put(NFPROTO_IPV6, type);
199 return;
200 }
201
182 BUG_ON(loggers[pf][type] == NULL); 202 BUG_ON(loggers[pf][type] == NULL);
183 203
184 rcu_read_lock(); 204 rcu_read_lock();
@@ -398,16 +418,17 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,
398{ 418{
399 const struct nf_logger *logger; 419 const struct nf_logger *logger;
400 char buf[NFLOGGER_NAME_LEN]; 420 char buf[NFLOGGER_NAME_LEN];
401 size_t size = *lenp;
402 int r = 0; 421 int r = 0;
403 int tindex = (unsigned long)table->extra1; 422 int tindex = (unsigned long)table->extra1;
404 struct net *net = current->nsproxy->net_ns; 423 struct net *net = current->nsproxy->net_ns;
405 424
406 if (write) { 425 if (write) {
407 if (size > sizeof(buf)) 426 struct ctl_table tmp = *table;
408 size = sizeof(buf); 427
409 if (copy_from_user(buf, buffer, size)) 428 tmp.data = buf;
410 return -EFAULT; 429 r = proc_dostring(&tmp, write, buffer, lenp, ppos);
430 if (r)
431 return r;
411 432
412 if (!strcmp(buf, "NONE")) { 433 if (!strcmp(buf, "NONE")) {
413 nf_log_unbind_pf(net, tindex); 434 nf_log_unbind_pf(net, tindex);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 2c881871db38..18b7f8578ee0 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -131,29 +131,8 @@ static void nft_trans_destroy(struct nft_trans *trans)
131 kfree(trans); 131 kfree(trans);
132} 132}
133 133
134static int nft_register_basechain(struct nft_base_chain *basechain, 134static int nf_tables_register_hooks(struct net *net,
135 unsigned int hook_nops) 135 const struct nft_table *table,
136{
137 struct net *net = read_pnet(&basechain->pnet);
138
139 if (basechain->flags & NFT_BASECHAIN_DISABLED)
140 return 0;
141
142 return nf_register_net_hooks(net, basechain->ops, hook_nops);
143}
144
145static void nft_unregister_basechain(struct nft_base_chain *basechain,
146 unsigned int hook_nops)
147{
148 struct net *net = read_pnet(&basechain->pnet);
149
150 if (basechain->flags & NFT_BASECHAIN_DISABLED)
151 return;
152
153 nf_unregister_net_hooks(net, basechain->ops, hook_nops);
154}
155
156static int nf_tables_register_hooks(const struct nft_table *table,
157 struct nft_chain *chain, 136 struct nft_chain *chain,
158 unsigned int hook_nops) 137 unsigned int hook_nops)
159{ 138{
@@ -161,10 +140,12 @@ static int nf_tables_register_hooks(const struct nft_table *table,
161 !(chain->flags & NFT_BASE_CHAIN)) 140 !(chain->flags & NFT_BASE_CHAIN))
162 return 0; 141 return 0;
163 142
164 return nft_register_basechain(nft_base_chain(chain), hook_nops); 143 return nf_register_net_hooks(net, nft_base_chain(chain)->ops,
144 hook_nops);
165} 145}
166 146
167static void nf_tables_unregister_hooks(const struct nft_table *table, 147static void nf_tables_unregister_hooks(struct net *net,
148 const struct nft_table *table,
168 struct nft_chain *chain, 149 struct nft_chain *chain,
169 unsigned int hook_nops) 150 unsigned int hook_nops)
170{ 151{
@@ -172,12 +153,9 @@ static void nf_tables_unregister_hooks(const struct nft_table *table,
172 !(chain->flags & NFT_BASE_CHAIN)) 153 !(chain->flags & NFT_BASE_CHAIN))
173 return; 154 return;
174 155
175 nft_unregister_basechain(nft_base_chain(chain), hook_nops); 156 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, hook_nops);
176} 157}
177 158
178/* Internal table flags */
179#define NFT_TABLE_INACTIVE (1 << 15)
180
181static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type) 159static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
182{ 160{
183 struct nft_trans *trans; 161 struct nft_trans *trans;
@@ -187,7 +165,7 @@ static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
187 return -ENOMEM; 165 return -ENOMEM;
188 166
189 if (msg_type == NFT_MSG_NEWTABLE) 167 if (msg_type == NFT_MSG_NEWTABLE)
190 ctx->table->flags |= NFT_TABLE_INACTIVE; 168 nft_activate_next(ctx->net, ctx->table);
191 169
192 list_add_tail(&trans->list, &ctx->net->nft.commit_list); 170 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
193 return 0; 171 return 0;
@@ -201,7 +179,7 @@ static int nft_deltable(struct nft_ctx *ctx)
201 if (err < 0) 179 if (err < 0)
202 return err; 180 return err;
203 181
204 list_del_rcu(&ctx->table->list); 182 nft_deactivate_next(ctx->net, ctx->table);
205 return err; 183 return err;
206} 184}
207 185
@@ -214,7 +192,7 @@ static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
214 return -ENOMEM; 192 return -ENOMEM;
215 193
216 if (msg_type == NFT_MSG_NEWCHAIN) 194 if (msg_type == NFT_MSG_NEWCHAIN)
217 ctx->chain->flags |= NFT_CHAIN_INACTIVE; 195 nft_activate_next(ctx->net, ctx->chain);
218 196
219 list_add_tail(&trans->list, &ctx->net->nft.commit_list); 197 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
220 return 0; 198 return 0;
@@ -229,47 +207,17 @@ static int nft_delchain(struct nft_ctx *ctx)
229 return err; 207 return err;
230 208
231 ctx->table->use--; 209 ctx->table->use--;
232 list_del_rcu(&ctx->chain->list); 210 nft_deactivate_next(ctx->net, ctx->chain);
233 211
234 return err; 212 return err;
235} 213}
236 214
237static inline bool
238nft_rule_is_active(struct net *net, const struct nft_rule *rule)
239{
240 return (rule->genmask & nft_genmask_cur(net)) == 0;
241}
242
243static inline int
244nft_rule_is_active_next(struct net *net, const struct nft_rule *rule)
245{
246 return (rule->genmask & nft_genmask_next(net)) == 0;
247}
248
249static inline void
250nft_rule_activate_next(struct net *net, struct nft_rule *rule)
251{
252 /* Now inactive, will be active in the future */
253 rule->genmask = nft_genmask_cur(net);
254}
255
256static inline void
257nft_rule_deactivate_next(struct net *net, struct nft_rule *rule)
258{
259 rule->genmask = nft_genmask_next(net);
260}
261
262static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
263{
264 rule->genmask &= ~nft_genmask_next(net);
265}
266
267static int 215static int
268nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule) 216nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
269{ 217{
270 /* You cannot delete the same rule twice */ 218 /* You cannot delete the same rule twice */
271 if (nft_rule_is_active_next(ctx->net, rule)) { 219 if (nft_is_active_next(ctx->net, rule)) {
272 nft_rule_deactivate_next(ctx->net, rule); 220 nft_deactivate_next(ctx->net, rule);
273 ctx->chain->use--; 221 ctx->chain->use--;
274 return 0; 222 return 0;
275 } 223 }
@@ -322,9 +270,6 @@ static int nft_delrule_by_chain(struct nft_ctx *ctx)
322 return 0; 270 return 0;
323} 271}
324 272
325/* Internal set flag */
326#define NFT_SET_INACTIVE (1 << 15)
327
328static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type, 273static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
329 struct nft_set *set) 274 struct nft_set *set)
330{ 275{
@@ -337,7 +282,7 @@ static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
337 if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) { 282 if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
338 nft_trans_set_id(trans) = 283 nft_trans_set_id(trans) =
339 ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID])); 284 ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
340 set->flags |= NFT_SET_INACTIVE; 285 nft_activate_next(ctx->net, set);
341 } 286 }
342 nft_trans_set(trans) = set; 287 nft_trans_set(trans) = set;
343 list_add_tail(&trans->list, &ctx->net->nft.commit_list); 288 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
@@ -353,7 +298,7 @@ static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
353 if (err < 0) 298 if (err < 0)
354 return err; 299 return err;
355 300
356 list_del_rcu(&set->list); 301 nft_deactivate_next(ctx->net, set);
357 ctx->table->use--; 302 ctx->table->use--;
358 303
359 return err; 304 return err;
@@ -364,26 +309,29 @@ static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
364 */ 309 */
365 310
366static struct nft_table *nft_table_lookup(const struct nft_af_info *afi, 311static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
367 const struct nlattr *nla) 312 const struct nlattr *nla,
313 u8 genmask)
368{ 314{
369 struct nft_table *table; 315 struct nft_table *table;
370 316
371 list_for_each_entry(table, &afi->tables, list) { 317 list_for_each_entry(table, &afi->tables, list) {
372 if (!nla_strcmp(nla, table->name)) 318 if (!nla_strcmp(nla, table->name) &&
319 nft_active_genmask(table, genmask))
373 return table; 320 return table;
374 } 321 }
375 return NULL; 322 return NULL;
376} 323}
377 324
378static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi, 325static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
379 const struct nlattr *nla) 326 const struct nlattr *nla,
327 u8 genmask)
380{ 328{
381 struct nft_table *table; 329 struct nft_table *table;
382 330
383 if (nla == NULL) 331 if (nla == NULL)
384 return ERR_PTR(-EINVAL); 332 return ERR_PTR(-EINVAL);
385 333
386 table = nft_table_lookup(afi, nla); 334 table = nft_table_lookup(afi, nla, genmask);
387 if (table != NULL) 335 if (table != NULL)
388 return table; 336 return table;
389 337
@@ -524,6 +472,8 @@ static int nf_tables_dump_tables(struct sk_buff *skb,
524 if (idx > s_idx) 472 if (idx > s_idx)
525 memset(&cb->args[1], 0, 473 memset(&cb->args[1], 0,
526 sizeof(cb->args) - sizeof(cb->args[0])); 474 sizeof(cb->args) - sizeof(cb->args[0]));
475 if (!nft_is_active(net, table))
476 continue;
527 if (nf_tables_fill_table_info(skb, net, 477 if (nf_tables_fill_table_info(skb, net,
528 NETLINK_CB(cb->skb).portid, 478 NETLINK_CB(cb->skb).portid,
529 cb->nlh->nlmsg_seq, 479 cb->nlh->nlmsg_seq,
@@ -548,6 +498,7 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk,
548 const struct nlattr * const nla[]) 498 const struct nlattr * const nla[])
549{ 499{
550 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 500 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
501 u8 genmask = nft_genmask_cur(net);
551 const struct nft_af_info *afi; 502 const struct nft_af_info *afi;
552 const struct nft_table *table; 503 const struct nft_table *table;
553 struct sk_buff *skb2; 504 struct sk_buff *skb2;
@@ -565,11 +516,9 @@ static int nf_tables_gettable(struct net *net, struct sock *nlsk,
565 if (IS_ERR(afi)) 516 if (IS_ERR(afi))
566 return PTR_ERR(afi); 517 return PTR_ERR(afi);
567 518
568 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]); 519 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
569 if (IS_ERR(table)) 520 if (IS_ERR(table))
570 return PTR_ERR(table); 521 return PTR_ERR(table);
571 if (table->flags & NFT_TABLE_INACTIVE)
572 return -ENOENT;
573 522
574 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 523 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
575 if (!skb2) 524 if (!skb2)
@@ -588,17 +537,21 @@ err:
588 return err; 537 return err;
589} 538}
590 539
591static int nf_tables_table_enable(const struct nft_af_info *afi, 540static int nf_tables_table_enable(struct net *net,
541 const struct nft_af_info *afi,
592 struct nft_table *table) 542 struct nft_table *table)
593{ 543{
594 struct nft_chain *chain; 544 struct nft_chain *chain;
595 int err, i = 0; 545 int err, i = 0;
596 546
597 list_for_each_entry(chain, &table->chains, list) { 547 list_for_each_entry(chain, &table->chains, list) {
548 if (!nft_is_active_next(net, chain))
549 continue;
598 if (!(chain->flags & NFT_BASE_CHAIN)) 550 if (!(chain->flags & NFT_BASE_CHAIN))
599 continue; 551 continue;
600 552
601 err = nft_register_basechain(nft_base_chain(chain), afi->nops); 553 err = nf_register_net_hooks(net, nft_base_chain(chain)->ops,
554 afi->nops);
602 if (err < 0) 555 if (err < 0)
603 goto err; 556 goto err;
604 557
@@ -607,26 +560,34 @@ static int nf_tables_table_enable(const struct nft_af_info *afi,
607 return 0; 560 return 0;
608err: 561err:
609 list_for_each_entry(chain, &table->chains, list) { 562 list_for_each_entry(chain, &table->chains, list) {
563 if (!nft_is_active_next(net, chain))
564 continue;
610 if (!(chain->flags & NFT_BASE_CHAIN)) 565 if (!(chain->flags & NFT_BASE_CHAIN))
611 continue; 566 continue;
612 567
613 if (i-- <= 0) 568 if (i-- <= 0)
614 break; 569 break;
615 570
616 nft_unregister_basechain(nft_base_chain(chain), afi->nops); 571 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
572 afi->nops);
617 } 573 }
618 return err; 574 return err;
619} 575}
620 576
621static void nf_tables_table_disable(const struct nft_af_info *afi, 577static void nf_tables_table_disable(struct net *net,
578 const struct nft_af_info *afi,
622 struct nft_table *table) 579 struct nft_table *table)
623{ 580{
624 struct nft_chain *chain; 581 struct nft_chain *chain;
625 582
626 list_for_each_entry(chain, &table->chains, list) { 583 list_for_each_entry(chain, &table->chains, list) {
627 if (chain->flags & NFT_BASE_CHAIN) 584 if (!nft_is_active_next(net, chain))
628 nft_unregister_basechain(nft_base_chain(chain), 585 continue;
629 afi->nops); 586 if (!(chain->flags & NFT_BASE_CHAIN))
587 continue;
588
589 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
590 afi->nops);
630 } 591 }
631} 592}
632 593
@@ -656,7 +617,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
656 nft_trans_table_enable(trans) = false; 617 nft_trans_table_enable(trans) = false;
657 } else if (!(flags & NFT_TABLE_F_DORMANT) && 618 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
658 ctx->table->flags & NFT_TABLE_F_DORMANT) { 619 ctx->table->flags & NFT_TABLE_F_DORMANT) {
659 ret = nf_tables_table_enable(ctx->afi, ctx->table); 620 ret = nf_tables_table_enable(ctx->net, ctx->afi, ctx->table);
660 if (ret >= 0) { 621 if (ret >= 0) {
661 ctx->table->flags &= ~NFT_TABLE_F_DORMANT; 622 ctx->table->flags &= ~NFT_TABLE_F_DORMANT;
662 nft_trans_table_enable(trans) = true; 623 nft_trans_table_enable(trans) = true;
@@ -678,6 +639,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
678 const struct nlattr * const nla[]) 639 const struct nlattr * const nla[])
679{ 640{
680 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 641 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
642 u8 genmask = nft_genmask_next(net);
681 const struct nlattr *name; 643 const struct nlattr *name;
682 struct nft_af_info *afi; 644 struct nft_af_info *afi;
683 struct nft_table *table; 645 struct nft_table *table;
@@ -691,7 +653,7 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
691 return PTR_ERR(afi); 653 return PTR_ERR(afi);
692 654
693 name = nla[NFTA_TABLE_NAME]; 655 name = nla[NFTA_TABLE_NAME];
694 table = nf_tables_table_lookup(afi, name); 656 table = nf_tables_table_lookup(afi, name, genmask);
695 if (IS_ERR(table)) { 657 if (IS_ERR(table)) {
696 if (PTR_ERR(table) != -ENOENT) 658 if (PTR_ERR(table) != -ENOENT)
697 return PTR_ERR(table); 659 return PTR_ERR(table);
@@ -699,8 +661,6 @@ static int nf_tables_newtable(struct net *net, struct sock *nlsk,
699 } 661 }
700 662
701 if (table != NULL) { 663 if (table != NULL) {
702 if (table->flags & NFT_TABLE_INACTIVE)
703 return -ENOENT;
704 if (nlh->nlmsg_flags & NLM_F_EXCL) 664 if (nlh->nlmsg_flags & NLM_F_EXCL)
705 return -EEXIST; 665 return -EEXIST;
706 if (nlh->nlmsg_flags & NLM_F_REPLACE) 666 if (nlh->nlmsg_flags & NLM_F_REPLACE)
@@ -752,6 +712,9 @@ static int nft_flush_table(struct nft_ctx *ctx)
752 struct nft_set *set, *ns; 712 struct nft_set *set, *ns;
753 713
754 list_for_each_entry(chain, &ctx->table->chains, list) { 714 list_for_each_entry(chain, &ctx->table->chains, list) {
715 if (!nft_is_active_next(ctx->net, chain))
716 continue;
717
755 ctx->chain = chain; 718 ctx->chain = chain;
756 719
757 err = nft_delrule_by_chain(ctx); 720 err = nft_delrule_by_chain(ctx);
@@ -760,6 +723,9 @@ static int nft_flush_table(struct nft_ctx *ctx)
760 } 723 }
761 724
762 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) { 725 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
726 if (!nft_is_active_next(ctx->net, set))
727 continue;
728
763 if (set->flags & NFT_SET_ANONYMOUS && 729 if (set->flags & NFT_SET_ANONYMOUS &&
764 !list_empty(&set->bindings)) 730 !list_empty(&set->bindings))
765 continue; 731 continue;
@@ -770,6 +736,9 @@ static int nft_flush_table(struct nft_ctx *ctx)
770 } 736 }
771 737
772 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) { 738 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
739 if (!nft_is_active_next(ctx->net, chain))
740 continue;
741
773 ctx->chain = chain; 742 ctx->chain = chain;
774 743
775 err = nft_delchain(ctx); 744 err = nft_delchain(ctx);
@@ -795,6 +764,9 @@ static int nft_flush(struct nft_ctx *ctx, int family)
795 764
796 ctx->afi = afi; 765 ctx->afi = afi;
797 list_for_each_entry_safe(table, nt, &afi->tables, list) { 766 list_for_each_entry_safe(table, nt, &afi->tables, list) {
767 if (!nft_is_active_next(ctx->net, table))
768 continue;
769
798 if (nla[NFTA_TABLE_NAME] && 770 if (nla[NFTA_TABLE_NAME] &&
799 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0) 771 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
800 continue; 772 continue;
@@ -815,6 +787,7 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk,
815 const struct nlattr * const nla[]) 787 const struct nlattr * const nla[])
816{ 788{
817 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 789 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
790 u8 genmask = nft_genmask_next(net);
818 struct nft_af_info *afi; 791 struct nft_af_info *afi;
819 struct nft_table *table; 792 struct nft_table *table;
820 int family = nfmsg->nfgen_family; 793 int family = nfmsg->nfgen_family;
@@ -828,7 +801,7 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk,
828 if (IS_ERR(afi)) 801 if (IS_ERR(afi))
829 return PTR_ERR(afi); 802 return PTR_ERR(afi);
830 803
831 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]); 804 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
832 if (IS_ERR(table)) 805 if (IS_ERR(table))
833 return PTR_ERR(table); 806 return PTR_ERR(table);
834 807
@@ -875,12 +848,14 @@ EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
875 */ 848 */
876 849
877static struct nft_chain * 850static struct nft_chain *
878nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle) 851nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle,
852 u8 genmask)
879{ 853{
880 struct nft_chain *chain; 854 struct nft_chain *chain;
881 855
882 list_for_each_entry(chain, &table->chains, list) { 856 list_for_each_entry(chain, &table->chains, list) {
883 if (chain->handle == handle) 857 if (chain->handle == handle &&
858 nft_active_genmask(chain, genmask))
884 return chain; 859 return chain;
885 } 860 }
886 861
@@ -888,7 +863,8 @@ nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle)
888} 863}
889 864
890static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table, 865static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
891 const struct nlattr *nla) 866 const struct nlattr *nla,
867 u8 genmask)
892{ 868{
893 struct nft_chain *chain; 869 struct nft_chain *chain;
894 870
@@ -896,7 +872,8 @@ static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
896 return ERR_PTR(-EINVAL); 872 return ERR_PTR(-EINVAL);
897 873
898 list_for_each_entry(chain, &table->chains, list) { 874 list_for_each_entry(chain, &table->chains, list) {
899 if (!nla_strcmp(nla, chain->name)) 875 if (!nla_strcmp(nla, chain->name) &&
876 nft_active_genmask(chain, genmask))
900 return chain; 877 return chain;
901 } 878 }
902 879
@@ -1079,6 +1056,8 @@ static int nf_tables_dump_chains(struct sk_buff *skb,
1079 if (idx > s_idx) 1056 if (idx > s_idx)
1080 memset(&cb->args[1], 0, 1057 memset(&cb->args[1], 0,
1081 sizeof(cb->args) - sizeof(cb->args[0])); 1058 sizeof(cb->args) - sizeof(cb->args[0]));
1059 if (!nft_is_active(net, chain))
1060 continue;
1082 if (nf_tables_fill_chain_info(skb, net, 1061 if (nf_tables_fill_chain_info(skb, net,
1083 NETLINK_CB(cb->skb).portid, 1062 NETLINK_CB(cb->skb).portid,
1084 cb->nlh->nlmsg_seq, 1063 cb->nlh->nlmsg_seq,
@@ -1104,6 +1083,7 @@ static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1104 const struct nlattr * const nla[]) 1083 const struct nlattr * const nla[])
1105{ 1084{
1106 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1085 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1086 u8 genmask = nft_genmask_cur(net);
1107 const struct nft_af_info *afi; 1087 const struct nft_af_info *afi;
1108 const struct nft_table *table; 1088 const struct nft_table *table;
1109 const struct nft_chain *chain; 1089 const struct nft_chain *chain;
@@ -1122,17 +1102,13 @@ static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1122 if (IS_ERR(afi)) 1102 if (IS_ERR(afi))
1123 return PTR_ERR(afi); 1103 return PTR_ERR(afi);
1124 1104
1125 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]); 1105 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1126 if (IS_ERR(table)) 1106 if (IS_ERR(table))
1127 return PTR_ERR(table); 1107 return PTR_ERR(table);
1128 if (table->flags & NFT_TABLE_INACTIVE)
1129 return -ENOENT;
1130 1108
1131 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]); 1109 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
1132 if (IS_ERR(chain)) 1110 if (IS_ERR(chain))
1133 return PTR_ERR(chain); 1111 return PTR_ERR(chain);
1134 if (chain->flags & NFT_CHAIN_INACTIVE)
1135 return -ENOENT;
1136 1112
1137 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1113 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1138 if (!skb2) 1114 if (!skb2)
@@ -1231,6 +1207,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1231 struct nft_chain *chain; 1207 struct nft_chain *chain;
1232 struct nft_base_chain *basechain = NULL; 1208 struct nft_base_chain *basechain = NULL;
1233 struct nlattr *ha[NFTA_HOOK_MAX + 1]; 1209 struct nlattr *ha[NFTA_HOOK_MAX + 1];
1210 u8 genmask = nft_genmask_next(net);
1234 int family = nfmsg->nfgen_family; 1211 int family = nfmsg->nfgen_family;
1235 struct net_device *dev = NULL; 1212 struct net_device *dev = NULL;
1236 u8 policy = NF_ACCEPT; 1213 u8 policy = NF_ACCEPT;
@@ -1247,7 +1224,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1247 if (IS_ERR(afi)) 1224 if (IS_ERR(afi))
1248 return PTR_ERR(afi); 1225 return PTR_ERR(afi);
1249 1226
1250 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]); 1227 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1251 if (IS_ERR(table)) 1228 if (IS_ERR(table))
1252 return PTR_ERR(table); 1229 return PTR_ERR(table);
1253 1230
@@ -1256,11 +1233,11 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1256 1233
1257 if (nla[NFTA_CHAIN_HANDLE]) { 1234 if (nla[NFTA_CHAIN_HANDLE]) {
1258 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE])); 1235 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
1259 chain = nf_tables_chain_lookup_byhandle(table, handle); 1236 chain = nf_tables_chain_lookup_byhandle(table, handle, genmask);
1260 if (IS_ERR(chain)) 1237 if (IS_ERR(chain))
1261 return PTR_ERR(chain); 1238 return PTR_ERR(chain);
1262 } else { 1239 } else {
1263 chain = nf_tables_chain_lookup(table, name); 1240 chain = nf_tables_chain_lookup(table, name, genmask);
1264 if (IS_ERR(chain)) { 1241 if (IS_ERR(chain)) {
1265 if (PTR_ERR(chain) != -ENOENT) 1242 if (PTR_ERR(chain) != -ENOENT)
1266 return PTR_ERR(chain); 1243 return PTR_ERR(chain);
@@ -1291,16 +1268,20 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1291 struct nft_stats *stats = NULL; 1268 struct nft_stats *stats = NULL;
1292 struct nft_trans *trans; 1269 struct nft_trans *trans;
1293 1270
1294 if (chain->flags & NFT_CHAIN_INACTIVE)
1295 return -ENOENT;
1296 if (nlh->nlmsg_flags & NLM_F_EXCL) 1271 if (nlh->nlmsg_flags & NLM_F_EXCL)
1297 return -EEXIST; 1272 return -EEXIST;
1298 if (nlh->nlmsg_flags & NLM_F_REPLACE) 1273 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1299 return -EOPNOTSUPP; 1274 return -EOPNOTSUPP;
1300 1275
1301 if (nla[NFTA_CHAIN_HANDLE] && name && 1276 if (nla[NFTA_CHAIN_HANDLE] && name) {
1302 !IS_ERR(nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]))) 1277 struct nft_chain *chain2;
1303 return -EEXIST; 1278
1279 chain2 = nf_tables_chain_lookup(table,
1280 nla[NFTA_CHAIN_NAME],
1281 genmask);
1282 if (IS_ERR(chain2))
1283 return PTR_ERR(chain2);
1284 }
1304 1285
1305 if (nla[NFTA_CHAIN_COUNTERS]) { 1286 if (nla[NFTA_CHAIN_COUNTERS]) {
1306 if (!(chain->flags & NFT_BASE_CHAIN)) 1287 if (!(chain->flags & NFT_BASE_CHAIN))
@@ -1455,7 +1436,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1455 chain->table = table; 1436 chain->table = table;
1456 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN); 1437 nla_strlcpy(chain->name, name, NFT_CHAIN_MAXNAMELEN);
1457 1438
1458 err = nf_tables_register_hooks(table, chain, afi->nops); 1439 err = nf_tables_register_hooks(net, table, chain, afi->nops);
1459 if (err < 0) 1440 if (err < 0)
1460 goto err1; 1441 goto err1;
1461 1442
@@ -1468,7 +1449,7 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1468 list_add_tail_rcu(&chain->list, &table->chains); 1449 list_add_tail_rcu(&chain->list, &table->chains);
1469 return 0; 1450 return 0;
1470err2: 1451err2:
1471 nf_tables_unregister_hooks(table, chain, afi->nops); 1452 nf_tables_unregister_hooks(net, table, chain, afi->nops);
1472err1: 1453err1:
1473 nf_tables_chain_destroy(chain); 1454 nf_tables_chain_destroy(chain);
1474 return err; 1455 return err;
@@ -1479,6 +1460,7 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1479 const struct nlattr * const nla[]) 1460 const struct nlattr * const nla[])
1480{ 1461{
1481 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1462 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1463 u8 genmask = nft_genmask_next(net);
1482 struct nft_af_info *afi; 1464 struct nft_af_info *afi;
1483 struct nft_table *table; 1465 struct nft_table *table;
1484 struct nft_chain *chain; 1466 struct nft_chain *chain;
@@ -1489,11 +1471,11 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1489 if (IS_ERR(afi)) 1471 if (IS_ERR(afi))
1490 return PTR_ERR(afi); 1472 return PTR_ERR(afi);
1491 1473
1492 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]); 1474 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1493 if (IS_ERR(table)) 1475 if (IS_ERR(table))
1494 return PTR_ERR(table); 1476 return PTR_ERR(table);
1495 1477
1496 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]); 1478 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
1497 if (IS_ERR(chain)) 1479 if (IS_ERR(chain))
1498 return PTR_ERR(chain); 1480 return PTR_ERR(chain);
1499 if (chain->use > 0) 1481 if (chain->use > 0)
@@ -1898,7 +1880,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
1898 list_for_each_entry_rcu(table, &afi->tables, list) { 1880 list_for_each_entry_rcu(table, &afi->tables, list) {
1899 list_for_each_entry_rcu(chain, &table->chains, list) { 1881 list_for_each_entry_rcu(chain, &table->chains, list) {
1900 list_for_each_entry_rcu(rule, &chain->rules, list) { 1882 list_for_each_entry_rcu(rule, &chain->rules, list) {
1901 if (!nft_rule_is_active(net, rule)) 1883 if (!nft_is_active(net, rule))
1902 goto cont; 1884 goto cont;
1903 if (idx < s_idx) 1885 if (idx < s_idx)
1904 goto cont; 1886 goto cont;
@@ -1931,6 +1913,7 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk,
1931 const struct nlattr * const nla[]) 1913 const struct nlattr * const nla[])
1932{ 1914{
1933 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1915 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1916 u8 genmask = nft_genmask_cur(net);
1934 const struct nft_af_info *afi; 1917 const struct nft_af_info *afi;
1935 const struct nft_table *table; 1918 const struct nft_table *table;
1936 const struct nft_chain *chain; 1919 const struct nft_chain *chain;
@@ -1950,17 +1933,13 @@ static int nf_tables_getrule(struct net *net, struct sock *nlsk,
1950 if (IS_ERR(afi)) 1933 if (IS_ERR(afi))
1951 return PTR_ERR(afi); 1934 return PTR_ERR(afi);
1952 1935
1953 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]); 1936 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
1954 if (IS_ERR(table)) 1937 if (IS_ERR(table))
1955 return PTR_ERR(table); 1938 return PTR_ERR(table);
1956 if (table->flags & NFT_TABLE_INACTIVE)
1957 return -ENOENT;
1958 1939
1959 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); 1940 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
1960 if (IS_ERR(chain)) 1941 if (IS_ERR(chain))
1961 return PTR_ERR(chain); 1942 return PTR_ERR(chain);
1962 if (chain->flags & NFT_CHAIN_INACTIVE)
1963 return -ENOENT;
1964 1943
1965 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]); 1944 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
1966 if (IS_ERR(rule)) 1945 if (IS_ERR(rule))
@@ -2009,6 +1988,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2009 const struct nlattr * const nla[]) 1988 const struct nlattr * const nla[])
2010{ 1989{
2011 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1990 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1991 u8 genmask = nft_genmask_next(net);
2012 struct nft_af_info *afi; 1992 struct nft_af_info *afi;
2013 struct nft_table *table; 1993 struct nft_table *table;
2014 struct nft_chain *chain; 1994 struct nft_chain *chain;
@@ -2029,11 +2009,11 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2029 if (IS_ERR(afi)) 2009 if (IS_ERR(afi))
2030 return PTR_ERR(afi); 2010 return PTR_ERR(afi);
2031 2011
2032 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]); 2012 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
2033 if (IS_ERR(table)) 2013 if (IS_ERR(table))
2034 return PTR_ERR(table); 2014 return PTR_ERR(table);
2035 2015
2036 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); 2016 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
2037 if (IS_ERR(chain)) 2017 if (IS_ERR(chain))
2038 return PTR_ERR(chain); 2018 return PTR_ERR(chain);
2039 2019
@@ -2102,7 +2082,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2102 if (rule == NULL) 2082 if (rule == NULL)
2103 goto err1; 2083 goto err1;
2104 2084
2105 nft_rule_activate_next(net, rule); 2085 nft_activate_next(net, rule);
2106 2086
2107 rule->handle = handle; 2087 rule->handle = handle;
2108 rule->dlen = size; 2088 rule->dlen = size;
@@ -2124,14 +2104,14 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2124 } 2104 }
2125 2105
2126 if (nlh->nlmsg_flags & NLM_F_REPLACE) { 2106 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
2127 if (nft_rule_is_active_next(net, old_rule)) { 2107 if (nft_is_active_next(net, old_rule)) {
2128 trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE, 2108 trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
2129 old_rule); 2109 old_rule);
2130 if (trans == NULL) { 2110 if (trans == NULL) {
2131 err = -ENOMEM; 2111 err = -ENOMEM;
2132 goto err2; 2112 goto err2;
2133 } 2113 }
2134 nft_rule_deactivate_next(net, old_rule); 2114 nft_deactivate_next(net, old_rule);
2135 chain->use--; 2115 chain->use--;
2136 list_add_tail_rcu(&rule->list, &old_rule->list); 2116 list_add_tail_rcu(&rule->list, &old_rule->list);
2137 } else { 2117 } else {
@@ -2174,6 +2154,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2174 const struct nlattr * const nla[]) 2154 const struct nlattr * const nla[])
2175{ 2155{
2176 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2156 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2157 u8 genmask = nft_genmask_next(net);
2177 struct nft_af_info *afi; 2158 struct nft_af_info *afi;
2178 struct nft_table *table; 2159 struct nft_table *table;
2179 struct nft_chain *chain = NULL; 2160 struct nft_chain *chain = NULL;
@@ -2185,12 +2166,13 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2185 if (IS_ERR(afi)) 2166 if (IS_ERR(afi))
2186 return PTR_ERR(afi); 2167 return PTR_ERR(afi);
2187 2168
2188 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]); 2169 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
2189 if (IS_ERR(table)) 2170 if (IS_ERR(table))
2190 return PTR_ERR(table); 2171 return PTR_ERR(table);
2191 2172
2192 if (nla[NFTA_RULE_CHAIN]) { 2173 if (nla[NFTA_RULE_CHAIN]) {
2193 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); 2174 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN],
2175 genmask);
2194 if (IS_ERR(chain)) 2176 if (IS_ERR(chain))
2195 return PTR_ERR(chain); 2177 return PTR_ERR(chain);
2196 } 2178 }
@@ -2210,6 +2192,9 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2210 } 2192 }
2211 } else { 2193 } else {
2212 list_for_each_entry(chain, &table->chains, list) { 2194 list_for_each_entry(chain, &table->chains, list) {
2195 if (!nft_is_active_next(net, chain))
2196 continue;
2197
2213 ctx.chain = chain; 2198 ctx.chain = chain;
2214 err = nft_delrule_by_chain(&ctx); 2199 err = nft_delrule_by_chain(&ctx);
2215 if (err < 0) 2200 if (err < 0)
@@ -2339,7 +2324,8 @@ static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
2339static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net, 2324static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
2340 const struct sk_buff *skb, 2325 const struct sk_buff *skb,
2341 const struct nlmsghdr *nlh, 2326 const struct nlmsghdr *nlh,
2342 const struct nlattr * const nla[]) 2327 const struct nlattr * const nla[],
2328 u8 genmask)
2343{ 2329{
2344 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2330 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2345 struct nft_af_info *afi = NULL; 2331 struct nft_af_info *afi = NULL;
@@ -2355,7 +2341,8 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
2355 if (afi == NULL) 2341 if (afi == NULL)
2356 return -EAFNOSUPPORT; 2342 return -EAFNOSUPPORT;
2357 2343
2358 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); 2344 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE],
2345 genmask);
2359 if (IS_ERR(table)) 2346 if (IS_ERR(table))
2360 return PTR_ERR(table); 2347 return PTR_ERR(table);
2361 } 2348 }
@@ -2365,7 +2352,7 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
2365} 2352}
2366 2353
2367struct nft_set *nf_tables_set_lookup(const struct nft_table *table, 2354struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
2368 const struct nlattr *nla) 2355 const struct nlattr *nla, u8 genmask)
2369{ 2356{
2370 struct nft_set *set; 2357 struct nft_set *set;
2371 2358
@@ -2373,22 +2360,27 @@ struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
2373 return ERR_PTR(-EINVAL); 2360 return ERR_PTR(-EINVAL);
2374 2361
2375 list_for_each_entry(set, &table->sets, list) { 2362 list_for_each_entry(set, &table->sets, list) {
2376 if (!nla_strcmp(nla, set->name)) 2363 if (!nla_strcmp(nla, set->name) &&
2364 nft_active_genmask(set, genmask))
2377 return set; 2365 return set;
2378 } 2366 }
2379 return ERR_PTR(-ENOENT); 2367 return ERR_PTR(-ENOENT);
2380} 2368}
2381 2369
2382struct nft_set *nf_tables_set_lookup_byid(const struct net *net, 2370struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
2383 const struct nlattr *nla) 2371 const struct nlattr *nla,
2372 u8 genmask)
2384{ 2373{
2385 struct nft_trans *trans; 2374 struct nft_trans *trans;
2386 u32 id = ntohl(nla_get_be32(nla)); 2375 u32 id = ntohl(nla_get_be32(nla));
2387 2376
2388 list_for_each_entry(trans, &net->nft.commit_list, list) { 2377 list_for_each_entry(trans, &net->nft.commit_list, list) {
2378 struct nft_set *set = nft_trans_set(trans);
2379
2389 if (trans->msg_type == NFT_MSG_NEWSET && 2380 if (trans->msg_type == NFT_MSG_NEWSET &&
2390 id == nft_trans_set_id(trans)) 2381 id == nft_trans_set_id(trans) &&
2391 return nft_trans_set(trans); 2382 nft_active_genmask(set, genmask))
2383 return set;
2392 } 2384 }
2393 return ERR_PTR(-ENOENT); 2385 return ERR_PTR(-ENOENT);
2394} 2386}
@@ -2413,6 +2405,8 @@ cont:
2413 list_for_each_entry(i, &ctx->table->sets, list) { 2405 list_for_each_entry(i, &ctx->table->sets, list) {
2414 int tmp; 2406 int tmp;
2415 2407
2408 if (!nft_is_active_next(ctx->net, set))
2409 continue;
2416 if (!sscanf(i->name, name, &tmp)) 2410 if (!sscanf(i->name, name, &tmp))
2417 continue; 2411 continue;
2418 if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE) 2412 if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
@@ -2432,6 +2426,8 @@ cont:
2432 2426
2433 snprintf(set->name, sizeof(set->name), name, min + n); 2427 snprintf(set->name, sizeof(set->name), name, min + n);
2434 list_for_each_entry(i, &ctx->table->sets, list) { 2428 list_for_each_entry(i, &ctx->table->sets, list) {
2429 if (!nft_is_active_next(ctx->net, i))
2430 continue;
2435 if (!strcmp(set->name, i->name)) 2431 if (!strcmp(set->name, i->name))
2436 return -ENFILE; 2432 return -ENFILE;
2437 } 2433 }
@@ -2580,6 +2576,8 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
2580 list_for_each_entry_rcu(set, &table->sets, list) { 2576 list_for_each_entry_rcu(set, &table->sets, list) {
2581 if (idx < s_idx) 2577 if (idx < s_idx)
2582 goto cont; 2578 goto cont;
2579 if (!nft_is_active(net, set))
2580 goto cont;
2583 2581
2584 ctx_set = *ctx; 2582 ctx_set = *ctx;
2585 ctx_set.table = table; 2583 ctx_set.table = table;
@@ -2616,6 +2614,7 @@ static int nf_tables_getset(struct net *net, struct sock *nlsk,
2616 struct sk_buff *skb, const struct nlmsghdr *nlh, 2614 struct sk_buff *skb, const struct nlmsghdr *nlh,
2617 const struct nlattr * const nla[]) 2615 const struct nlattr * const nla[])
2618{ 2616{
2617 u8 genmask = nft_genmask_cur(net);
2619 const struct nft_set *set; 2618 const struct nft_set *set;
2620 struct nft_ctx ctx; 2619 struct nft_ctx ctx;
2621 struct sk_buff *skb2; 2620 struct sk_buff *skb2;
@@ -2623,7 +2622,7 @@ static int nf_tables_getset(struct net *net, struct sock *nlsk,
2623 int err; 2622 int err;
2624 2623
2625 /* Verify existence before starting dump */ 2624 /* Verify existence before starting dump */
2626 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla); 2625 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
2627 if (err < 0) 2626 if (err < 0)
2628 return err; 2627 return err;
2629 2628
@@ -2650,11 +2649,9 @@ static int nf_tables_getset(struct net *net, struct sock *nlsk,
2650 if (!nla[NFTA_SET_TABLE]) 2649 if (!nla[NFTA_SET_TABLE])
2651 return -EINVAL; 2650 return -EINVAL;
2652 2651
2653 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); 2652 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
2654 if (IS_ERR(set)) 2653 if (IS_ERR(set))
2655 return PTR_ERR(set); 2654 return PTR_ERR(set);
2656 if (set->flags & NFT_SET_INACTIVE)
2657 return -ENOENT;
2658 2655
2659 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 2656 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2660 if (skb2 == NULL) 2657 if (skb2 == NULL)
@@ -2693,6 +2690,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2693 const struct nlattr * const nla[]) 2690 const struct nlattr * const nla[])
2694{ 2691{
2695 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2692 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2693 u8 genmask = nft_genmask_next(net);
2696 const struct nft_set_ops *ops; 2694 const struct nft_set_ops *ops;
2697 struct nft_af_info *afi; 2695 struct nft_af_info *afi;
2698 struct nft_table *table; 2696 struct nft_table *table;
@@ -2790,13 +2788,13 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2790 if (IS_ERR(afi)) 2788 if (IS_ERR(afi))
2791 return PTR_ERR(afi); 2789 return PTR_ERR(afi);
2792 2790
2793 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); 2791 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], genmask);
2794 if (IS_ERR(table)) 2792 if (IS_ERR(table))
2795 return PTR_ERR(table); 2793 return PTR_ERR(table);
2796 2794
2797 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla); 2795 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
2798 2796
2799 set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME]); 2797 set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask);
2800 if (IS_ERR(set)) { 2798 if (IS_ERR(set)) {
2801 if (PTR_ERR(set) != -ENOENT) 2799 if (PTR_ERR(set) != -ENOENT)
2802 return PTR_ERR(set); 2800 return PTR_ERR(set);
@@ -2895,6 +2893,7 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
2895 const struct nlattr * const nla[]) 2893 const struct nlattr * const nla[])
2896{ 2894{
2897 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2895 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2896 u8 genmask = nft_genmask_next(net);
2898 struct nft_set *set; 2897 struct nft_set *set;
2899 struct nft_ctx ctx; 2898 struct nft_ctx ctx;
2900 int err; 2899 int err;
@@ -2904,11 +2903,11 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
2904 if (nla[NFTA_SET_TABLE] == NULL) 2903 if (nla[NFTA_SET_TABLE] == NULL)
2905 return -EINVAL; 2904 return -EINVAL;
2906 2905
2907 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla); 2906 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
2908 if (err < 0) 2907 if (err < 0)
2909 return err; 2908 return err;
2910 2909
2911 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); 2910 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
2912 if (IS_ERR(set)) 2911 if (IS_ERR(set))
2913 return PTR_ERR(set); 2912 return PTR_ERR(set);
2914 if (!list_empty(&set->bindings)) 2913 if (!list_empty(&set->bindings))
@@ -2973,7 +2972,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
2973 list_del_rcu(&binding->list); 2972 list_del_rcu(&binding->list);
2974 2973
2975 if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS && 2974 if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS &&
2976 !(set->flags & NFT_SET_INACTIVE)) 2975 nft_is_active(ctx->net, set))
2977 nf_tables_set_destroy(ctx, set); 2976 nf_tables_set_destroy(ctx, set);
2978} 2977}
2979 2978
@@ -3029,7 +3028,8 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
3029static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net, 3028static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
3030 const struct sk_buff *skb, 3029 const struct sk_buff *skb,
3031 const struct nlmsghdr *nlh, 3030 const struct nlmsghdr *nlh,
3032 const struct nlattr * const nla[]) 3031 const struct nlattr * const nla[],
3032 u8 genmask)
3033{ 3033{
3034 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 3034 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
3035 struct nft_af_info *afi; 3035 struct nft_af_info *afi;
@@ -3039,7 +3039,8 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
3039 if (IS_ERR(afi)) 3039 if (IS_ERR(afi))
3040 return PTR_ERR(afi); 3040 return PTR_ERR(afi);
3041 3041
3042 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]); 3042 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE],
3043 genmask);
3043 if (IS_ERR(table)) 3044 if (IS_ERR(table))
3044 return PTR_ERR(table); 3045 return PTR_ERR(table);
3045 3046
@@ -3136,6 +3137,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
3136static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) 3137static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3137{ 3138{
3138 struct net *net = sock_net(skb->sk); 3139 struct net *net = sock_net(skb->sk);
3140 u8 genmask = nft_genmask_cur(net);
3139 const struct nft_set *set; 3141 const struct nft_set *set;
3140 struct nft_set_dump_args args; 3142 struct nft_set_dump_args args;
3141 struct nft_ctx ctx; 3143 struct nft_ctx ctx;
@@ -3152,17 +3154,14 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3152 return err; 3154 return err;
3153 3155
3154 err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh, 3156 err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
3155 (void *)nla); 3157 (void *)nla, genmask);
3156 if (err < 0) 3158 if (err < 0)
3157 return err; 3159 return err;
3158 if (ctx.table->flags & NFT_TABLE_INACTIVE)
3159 return -ENOENT;
3160 3160
3161 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3161 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3162 genmask);
3162 if (IS_ERR(set)) 3163 if (IS_ERR(set))
3163 return PTR_ERR(set); 3164 return PTR_ERR(set);
3164 if (set->flags & NFT_SET_INACTIVE)
3165 return -ENOENT;
3166 3165
3167 event = NFT_MSG_NEWSETELEM; 3166 event = NFT_MSG_NEWSETELEM;
3168 event |= NFNL_SUBSYS_NFTABLES << 8; 3167 event |= NFNL_SUBSYS_NFTABLES << 8;
@@ -3216,21 +3215,19 @@ static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
3216 struct sk_buff *skb, const struct nlmsghdr *nlh, 3215 struct sk_buff *skb, const struct nlmsghdr *nlh,
3217 const struct nlattr * const nla[]) 3216 const struct nlattr * const nla[])
3218{ 3217{
3218 u8 genmask = nft_genmask_cur(net);
3219 const struct nft_set *set; 3219 const struct nft_set *set;
3220 struct nft_ctx ctx; 3220 struct nft_ctx ctx;
3221 int err; 3221 int err;
3222 3222
3223 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla); 3223 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3224 if (err < 0) 3224 if (err < 0)
3225 return err; 3225 return err;
3226 if (ctx.table->flags & NFT_TABLE_INACTIVE)
3227 return -ENOENT;
3228 3226
3229 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3227 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3228 genmask);
3230 if (IS_ERR(set)) 3229 if (IS_ERR(set))
3231 return PTR_ERR(set); 3230 return PTR_ERR(set);
3232 if (set->flags & NFT_SET_INACTIVE)
3233 return -ENOENT;
3234 3231
3235 if (nlh->nlmsg_flags & NLM_F_DUMP) { 3232 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3236 struct netlink_dump_control c = { 3233 struct netlink_dump_control c = {
@@ -3548,6 +3545,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
3548 struct sk_buff *skb, const struct nlmsghdr *nlh, 3545 struct sk_buff *skb, const struct nlmsghdr *nlh,
3549 const struct nlattr * const nla[]) 3546 const struct nlattr * const nla[])
3550{ 3547{
3548 u8 genmask = nft_genmask_next(net);
3551 const struct nlattr *attr; 3549 const struct nlattr *attr;
3552 struct nft_set *set; 3550 struct nft_set *set;
3553 struct nft_ctx ctx; 3551 struct nft_ctx ctx;
@@ -3556,15 +3554,17 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
3556 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) 3554 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3557 return -EINVAL; 3555 return -EINVAL;
3558 3556
3559 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla); 3557 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3560 if (err < 0) 3558 if (err < 0)
3561 return err; 3559 return err;
3562 3560
3563 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3561 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3562 genmask);
3564 if (IS_ERR(set)) { 3563 if (IS_ERR(set)) {
3565 if (nla[NFTA_SET_ELEM_LIST_SET_ID]) { 3564 if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
3566 set = nf_tables_set_lookup_byid(net, 3565 set = nf_tables_set_lookup_byid(net,
3567 nla[NFTA_SET_ELEM_LIST_SET_ID]); 3566 nla[NFTA_SET_ELEM_LIST_SET_ID],
3567 genmask);
3568 } 3568 }
3569 if (IS_ERR(set)) 3569 if (IS_ERR(set))
3570 return PTR_ERR(set); 3570 return PTR_ERR(set);
@@ -3670,6 +3670,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
3670 struct sk_buff *skb, const struct nlmsghdr *nlh, 3670 struct sk_buff *skb, const struct nlmsghdr *nlh,
3671 const struct nlattr * const nla[]) 3671 const struct nlattr * const nla[])
3672{ 3672{
3673 u8 genmask = nft_genmask_next(net);
3673 const struct nlattr *attr; 3674 const struct nlattr *attr;
3674 struct nft_set *set; 3675 struct nft_set *set;
3675 struct nft_ctx ctx; 3676 struct nft_ctx ctx;
@@ -3678,11 +3679,12 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
3678 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) 3679 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3679 return -EINVAL; 3680 return -EINVAL;
3680 3681
3681 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla); 3682 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3682 if (err < 0) 3683 if (err < 0)
3683 return err; 3684 return err;
3684 3685
3685 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3686 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3687 genmask);
3686 if (IS_ERR(set)) 3688 if (IS_ERR(set))
3687 return PTR_ERR(set); 3689 return PTR_ERR(set);
3688 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT) 3690 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
@@ -3950,36 +3952,40 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
3950 case NFT_MSG_NEWTABLE: 3952 case NFT_MSG_NEWTABLE:
3951 if (nft_trans_table_update(trans)) { 3953 if (nft_trans_table_update(trans)) {
3952 if (!nft_trans_table_enable(trans)) { 3954 if (!nft_trans_table_enable(trans)) {
3953 nf_tables_table_disable(trans->ctx.afi, 3955 nf_tables_table_disable(net,
3956 trans->ctx.afi,
3954 trans->ctx.table); 3957 trans->ctx.table);
3955 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT; 3958 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
3956 } 3959 }
3957 } else { 3960 } else {
3958 trans->ctx.table->flags &= ~NFT_TABLE_INACTIVE; 3961 nft_clear(net, trans->ctx.table);
3959 } 3962 }
3960 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE); 3963 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
3961 nft_trans_destroy(trans); 3964 nft_trans_destroy(trans);
3962 break; 3965 break;
3963 case NFT_MSG_DELTABLE: 3966 case NFT_MSG_DELTABLE:
3967 list_del_rcu(&trans->ctx.table->list);
3964 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE); 3968 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
3965 break; 3969 break;
3966 case NFT_MSG_NEWCHAIN: 3970 case NFT_MSG_NEWCHAIN:
3967 if (nft_trans_chain_update(trans)) 3971 if (nft_trans_chain_update(trans))
3968 nft_chain_commit_update(trans); 3972 nft_chain_commit_update(trans);
3969 else 3973 else
3970 trans->ctx.chain->flags &= ~NFT_CHAIN_INACTIVE; 3974 nft_clear(net, trans->ctx.chain);
3971 3975
3972 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN); 3976 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
3973 nft_trans_destroy(trans); 3977 nft_trans_destroy(trans);
3974 break; 3978 break;
3975 case NFT_MSG_DELCHAIN: 3979 case NFT_MSG_DELCHAIN:
3980 list_del_rcu(&trans->ctx.chain->list);
3976 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN); 3981 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
3977 nf_tables_unregister_hooks(trans->ctx.table, 3982 nf_tables_unregister_hooks(trans->ctx.net,
3983 trans->ctx.table,
3978 trans->ctx.chain, 3984 trans->ctx.chain,
3979 trans->ctx.afi->nops); 3985 trans->ctx.afi->nops);
3980 break; 3986 break;
3981 case NFT_MSG_NEWRULE: 3987 case NFT_MSG_NEWRULE:
3982 nft_rule_clear(trans->ctx.net, nft_trans_rule(trans)); 3988 nft_clear(trans->ctx.net, nft_trans_rule(trans));
3983 nf_tables_rule_notify(&trans->ctx, 3989 nf_tables_rule_notify(&trans->ctx,
3984 nft_trans_rule(trans), 3990 nft_trans_rule(trans),
3985 NFT_MSG_NEWRULE); 3991 NFT_MSG_NEWRULE);
@@ -3992,7 +3998,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
3992 NFT_MSG_DELRULE); 3998 NFT_MSG_DELRULE);
3993 break; 3999 break;
3994 case NFT_MSG_NEWSET: 4000 case NFT_MSG_NEWSET:
3995 nft_trans_set(trans)->flags &= ~NFT_SET_INACTIVE; 4001 nft_clear(net, nft_trans_set(trans));
3996 /* This avoids hitting -EBUSY when deleting the table 4002 /* This avoids hitting -EBUSY when deleting the table
3997 * from the transaction. 4003 * from the transaction.
3998 */ 4004 */
@@ -4005,6 +4011,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
4005 nft_trans_destroy(trans); 4011 nft_trans_destroy(trans);
4006 break; 4012 break;
4007 case NFT_MSG_DELSET: 4013 case NFT_MSG_DELSET:
4014 list_del_rcu(&nft_trans_set(trans)->list);
4008 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans), 4015 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
4009 NFT_MSG_DELSET, GFP_KERNEL); 4016 NFT_MSG_DELSET, GFP_KERNEL);
4010 break; 4017 break;
@@ -4076,7 +4083,8 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4076 case NFT_MSG_NEWTABLE: 4083 case NFT_MSG_NEWTABLE:
4077 if (nft_trans_table_update(trans)) { 4084 if (nft_trans_table_update(trans)) {
4078 if (nft_trans_table_enable(trans)) { 4085 if (nft_trans_table_enable(trans)) {
4079 nf_tables_table_disable(trans->ctx.afi, 4086 nf_tables_table_disable(net,
4087 trans->ctx.afi,
4080 trans->ctx.table); 4088 trans->ctx.table);
4081 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT; 4089 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
4082 } 4090 }
@@ -4086,8 +4094,7 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4086 } 4094 }
4087 break; 4095 break;
4088 case NFT_MSG_DELTABLE: 4096 case NFT_MSG_DELTABLE:
4089 list_add_tail_rcu(&trans->ctx.table->list, 4097 nft_clear(trans->ctx.net, trans->ctx.table);
4090 &trans->ctx.afi->tables);
4091 nft_trans_destroy(trans); 4098 nft_trans_destroy(trans);
4092 break; 4099 break;
4093 case NFT_MSG_NEWCHAIN: 4100 case NFT_MSG_NEWCHAIN:
@@ -4098,15 +4105,15 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4098 } else { 4105 } else {
4099 trans->ctx.table->use--; 4106 trans->ctx.table->use--;
4100 list_del_rcu(&trans->ctx.chain->list); 4107 list_del_rcu(&trans->ctx.chain->list);
4101 nf_tables_unregister_hooks(trans->ctx.table, 4108 nf_tables_unregister_hooks(trans->ctx.net,
4109 trans->ctx.table,
4102 trans->ctx.chain, 4110 trans->ctx.chain,
4103 trans->ctx.afi->nops); 4111 trans->ctx.afi->nops);
4104 } 4112 }
4105 break; 4113 break;
4106 case NFT_MSG_DELCHAIN: 4114 case NFT_MSG_DELCHAIN:
4107 trans->ctx.table->use++; 4115 trans->ctx.table->use++;
4108 list_add_tail_rcu(&trans->ctx.chain->list, 4116 nft_clear(trans->ctx.net, trans->ctx.chain);
4109 &trans->ctx.table->chains);
4110 nft_trans_destroy(trans); 4117 nft_trans_destroy(trans);
4111 break; 4118 break;
4112 case NFT_MSG_NEWRULE: 4119 case NFT_MSG_NEWRULE:
@@ -4115,7 +4122,7 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4115 break; 4122 break;
4116 case NFT_MSG_DELRULE: 4123 case NFT_MSG_DELRULE:
4117 trans->ctx.chain->use++; 4124 trans->ctx.chain->use++;
4118 nft_rule_clear(trans->ctx.net, nft_trans_rule(trans)); 4125 nft_clear(trans->ctx.net, nft_trans_rule(trans));
4119 nft_trans_destroy(trans); 4126 nft_trans_destroy(trans);
4120 break; 4127 break;
4121 case NFT_MSG_NEWSET: 4128 case NFT_MSG_NEWSET:
@@ -4124,8 +4131,7 @@ static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4124 break; 4131 break;
4125 case NFT_MSG_DELSET: 4132 case NFT_MSG_DELSET:
4126 trans->ctx.table->use++; 4133 trans->ctx.table->use++;
4127 list_add_tail_rcu(&nft_trans_set(trans)->list, 4134 nft_clear(trans->ctx.net, nft_trans_set(trans));
4128 &trans->ctx.table->sets);
4129 nft_trans_destroy(trans); 4135 nft_trans_destroy(trans);
4130 break; 4136 break;
4131 case NFT_MSG_NEWSETELEM: 4137 case NFT_MSG_NEWSETELEM:
@@ -4272,6 +4278,8 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
4272 } 4278 }
4273 4279
4274 list_for_each_entry(set, &ctx->table->sets, list) { 4280 list_for_each_entry(set, &ctx->table->sets, list) {
4281 if (!nft_is_active_next(ctx->net, set))
4282 continue;
4275 if (!(set->flags & NFT_SET_MAP) || 4283 if (!(set->flags & NFT_SET_MAP) ||
4276 set->dtype != NFT_DATA_VERDICT) 4284 set->dtype != NFT_DATA_VERDICT)
4277 continue; 4285 continue;
@@ -4430,6 +4438,7 @@ static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
4430static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data, 4438static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4431 struct nft_data_desc *desc, const struct nlattr *nla) 4439 struct nft_data_desc *desc, const struct nlattr *nla)
4432{ 4440{
4441 u8 genmask = nft_genmask_next(ctx->net);
4433 struct nlattr *tb[NFTA_VERDICT_MAX + 1]; 4442 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
4434 struct nft_chain *chain; 4443 struct nft_chain *chain;
4435 int err; 4444 int err;
@@ -4462,7 +4471,7 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4462 if (!tb[NFTA_VERDICT_CHAIN]) 4471 if (!tb[NFTA_VERDICT_CHAIN])
4463 return -EINVAL; 4472 return -EINVAL;
4464 chain = nf_tables_chain_lookup(ctx->table, 4473 chain = nf_tables_chain_lookup(ctx->table,
4465 tb[NFTA_VERDICT_CHAIN]); 4474 tb[NFTA_VERDICT_CHAIN], genmask);
4466 if (IS_ERR(chain)) 4475 if (IS_ERR(chain))
4467 return PTR_ERR(chain); 4476 return PTR_ERR(chain);
4468 if (chain->flags & NFT_BASE_CHAIN) 4477 if (chain->flags & NFT_BASE_CHAIN)
@@ -4640,7 +4649,7 @@ int __nft_release_basechain(struct nft_ctx *ctx)
4640 4649
4641 BUG_ON(!(ctx->chain->flags & NFT_BASE_CHAIN)); 4650 BUG_ON(!(ctx->chain->flags & NFT_BASE_CHAIN));
4642 4651
4643 nf_tables_unregister_hooks(ctx->chain->table, ctx->chain, 4652 nf_tables_unregister_hooks(ctx->net, ctx->chain->table, ctx->chain,
4644 ctx->afi->nops); 4653 ctx->afi->nops);
4645 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) { 4654 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
4646 list_del(&rule->list); 4655 list_del(&rule->list);
@@ -4669,7 +4678,8 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
4669 4678
4670 list_for_each_entry_safe(table, nt, &afi->tables, list) { 4679 list_for_each_entry_safe(table, nt, &afi->tables, list) {
4671 list_for_each_entry(chain, &table->chains, list) 4680 list_for_each_entry(chain, &table->chains, list)
4672 nf_tables_unregister_hooks(table, chain, afi->nops); 4681 nf_tables_unregister_hooks(net, table, chain,
4682 afi->nops);
4673 /* No packets are walking on these chains anymore. */ 4683 /* No packets are walking on these chains anymore. */
4674 ctx.table = table; 4684 ctx.table = table;
4675 list_for_each_entry(chain, &table->chains, list) { 4685 list_for_each_entry(chain, &table->chains, list) {
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 11f81c8385fc..cbcfdfb586a6 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -700,10 +700,13 @@ nfulnl_log_packet(struct net *net,
700 break; 700 break;
701 701
702 case NFULNL_COPY_PACKET: 702 case NFULNL_COPY_PACKET:
703 if (inst->copy_range > skb->len) 703 data_len = inst->copy_range;
704 if ((li->u.ulog.flags & NF_LOG_F_COPY_LEN) &&
705 (li->u.ulog.copy_len < data_len))
706 data_len = li->u.ulog.copy_len;
707
708 if (data_len > skb->len)
704 data_len = skb->len; 709 data_len = skb->len;
705 else
706 data_len = inst->copy_range;
707 710
708 size += nla_total_size(data_len); 711 size += nla_total_size(data_len);
709 break; 712 break;
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 78d4914fb39c..0af26699bf04 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -103,6 +103,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
103 const struct nlattr * const tb[]) 103 const struct nlattr * const tb[])
104{ 104{
105 struct nft_dynset *priv = nft_expr_priv(expr); 105 struct nft_dynset *priv = nft_expr_priv(expr);
106 u8 genmask = nft_genmask_next(ctx->net);
106 struct nft_set *set; 107 struct nft_set *set;
107 u64 timeout; 108 u64 timeout;
108 int err; 109 int err;
@@ -112,11 +113,13 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
112 tb[NFTA_DYNSET_SREG_KEY] == NULL) 113 tb[NFTA_DYNSET_SREG_KEY] == NULL)
113 return -EINVAL; 114 return -EINVAL;
114 115
115 set = nf_tables_set_lookup(ctx->table, tb[NFTA_DYNSET_SET_NAME]); 116 set = nf_tables_set_lookup(ctx->table, tb[NFTA_DYNSET_SET_NAME],
117 genmask);
116 if (IS_ERR(set)) { 118 if (IS_ERR(set)) {
117 if (tb[NFTA_DYNSET_SET_ID]) 119 if (tb[NFTA_DYNSET_SET_ID])
118 set = nf_tables_set_lookup_byid(ctx->net, 120 set = nf_tables_set_lookup_byid(ctx->net,
119 tb[NFTA_DYNSET_SET_ID]); 121 tb[NFTA_DYNSET_SET_ID],
122 genmask);
120 if (IS_ERR(set)) 123 if (IS_ERR(set))
121 return PTR_ERR(set); 124 return PTR_ERR(set);
122 } 125 }
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index f39c53a159eb..ea924816b7b8 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -153,9 +153,10 @@ static void *nft_hash_deactivate(const struct nft_set *set,
153 const struct nft_set_elem *elem) 153 const struct nft_set_elem *elem)
154{ 154{
155 struct nft_hash *priv = nft_set_priv(set); 155 struct nft_hash *priv = nft_set_priv(set);
156 struct net *net = read_pnet(&set->pnet);
156 struct nft_hash_elem *he; 157 struct nft_hash_elem *he;
157 struct nft_hash_cmp_arg arg = { 158 struct nft_hash_cmp_arg arg = {
158 .genmask = nft_genmask_next(read_pnet(&set->pnet)), 159 .genmask = nft_genmask_next(net),
159 .set = set, 160 .set = set,
160 .key = elem->key.val.data, 161 .key = elem->key.val.data,
161 }; 162 };
@@ -163,7 +164,8 @@ static void *nft_hash_deactivate(const struct nft_set *set,
163 rcu_read_lock(); 164 rcu_read_lock();
164 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params); 165 he = rhashtable_lookup_fast(&priv->ht, &arg, nft_hash_params);
165 if (he != NULL) { 166 if (he != NULL) {
166 if (!nft_set_elem_mark_busy(&he->ext)) 167 if (!nft_set_elem_mark_busy(&he->ext) ||
168 !nft_is_active(net, &he->ext))
167 nft_set_elem_change_active(set, &he->ext); 169 nft_set_elem_change_active(set, &he->ext);
168 else 170 else
169 he = NULL; 171 he = NULL;
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index 319c22b4bca2..713d66837705 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -52,7 +52,6 @@ static int nft_log_init(const struct nft_ctx *ctx,
52 struct nft_log *priv = nft_expr_priv(expr); 52 struct nft_log *priv = nft_expr_priv(expr);
53 struct nf_loginfo *li = &priv->loginfo; 53 struct nf_loginfo *li = &priv->loginfo;
54 const struct nlattr *nla; 54 const struct nlattr *nla;
55 int ret;
56 55
57 nla = tb[NFTA_LOG_PREFIX]; 56 nla = tb[NFTA_LOG_PREFIX];
58 if (nla != NULL) { 57 if (nla != NULL) {
@@ -97,19 +96,6 @@ static int nft_log_init(const struct nft_ctx *ctx,
97 break; 96 break;
98 } 97 }
99 98
100 if (ctx->afi->family == NFPROTO_INET) {
101 ret = nf_logger_find_get(NFPROTO_IPV4, li->type);
102 if (ret < 0)
103 return ret;
104
105 ret = nf_logger_find_get(NFPROTO_IPV6, li->type);
106 if (ret < 0) {
107 nf_logger_put(NFPROTO_IPV4, li->type);
108 return ret;
109 }
110 return 0;
111 }
112
113 return nf_logger_find_get(ctx->afi->family, li->type); 99 return nf_logger_find_get(ctx->afi->family, li->type);
114} 100}
115 101
@@ -122,12 +108,7 @@ static void nft_log_destroy(const struct nft_ctx *ctx,
122 if (priv->prefix != nft_log_null_prefix) 108 if (priv->prefix != nft_log_null_prefix)
123 kfree(priv->prefix); 109 kfree(priv->prefix);
124 110
125 if (ctx->afi->family == NFPROTO_INET) { 111 nf_logger_put(ctx->afi->family, li->type);
126 nf_logger_put(NFPROTO_IPV4, li->type);
127 nf_logger_put(NFPROTO_IPV6, li->type);
128 } else {
129 nf_logger_put(ctx->afi->family, li->type);
130 }
131} 112}
132 113
133static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr) 114static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr)
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index b3c31ef8015d..b8d18f598569 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -22,6 +22,7 @@ struct nft_lookup {
22 struct nft_set *set; 22 struct nft_set *set;
23 enum nft_registers sreg:8; 23 enum nft_registers sreg:8;
24 enum nft_registers dreg:8; 24 enum nft_registers dreg:8;
25 bool invert;
25 struct nft_set_binding binding; 26 struct nft_set_binding binding;
26}; 27};
27 28
@@ -32,14 +33,20 @@ static void nft_lookup_eval(const struct nft_expr *expr,
32 const struct nft_lookup *priv = nft_expr_priv(expr); 33 const struct nft_lookup *priv = nft_expr_priv(expr);
33 const struct nft_set *set = priv->set; 34 const struct nft_set *set = priv->set;
34 const struct nft_set_ext *ext; 35 const struct nft_set_ext *ext;
36 bool found;
35 37
36 if (set->ops->lookup(set, &regs->data[priv->sreg], &ext)) { 38 found = set->ops->lookup(set, &regs->data[priv->sreg], &ext) ^
37 if (set->flags & NFT_SET_MAP) 39 priv->invert;
38 nft_data_copy(&regs->data[priv->dreg], 40
39 nft_set_ext_data(ext), set->dlen); 41 if (!found) {
42 regs->verdict.code = NFT_BREAK;
40 return; 43 return;
41 } 44 }
42 regs->verdict.code = NFT_BREAK; 45
46 if (found && set->flags & NFT_SET_MAP)
47 nft_data_copy(&regs->data[priv->dreg],
48 nft_set_ext_data(ext), set->dlen);
49
43} 50}
44 51
45static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = { 52static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
@@ -47,6 +54,7 @@ static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
47 [NFTA_LOOKUP_SET_ID] = { .type = NLA_U32 }, 54 [NFTA_LOOKUP_SET_ID] = { .type = NLA_U32 },
48 [NFTA_LOOKUP_SREG] = { .type = NLA_U32 }, 55 [NFTA_LOOKUP_SREG] = { .type = NLA_U32 },
49 [NFTA_LOOKUP_DREG] = { .type = NLA_U32 }, 56 [NFTA_LOOKUP_DREG] = { .type = NLA_U32 },
57 [NFTA_LOOKUP_FLAGS] = { .type = NLA_U32 },
50}; 58};
51 59
52static int nft_lookup_init(const struct nft_ctx *ctx, 60static int nft_lookup_init(const struct nft_ctx *ctx,
@@ -54,18 +62,21 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
54 const struct nlattr * const tb[]) 62 const struct nlattr * const tb[])
55{ 63{
56 struct nft_lookup *priv = nft_expr_priv(expr); 64 struct nft_lookup *priv = nft_expr_priv(expr);
65 u8 genmask = nft_genmask_next(ctx->net);
57 struct nft_set *set; 66 struct nft_set *set;
67 u32 flags;
58 int err; 68 int err;
59 69
60 if (tb[NFTA_LOOKUP_SET] == NULL || 70 if (tb[NFTA_LOOKUP_SET] == NULL ||
61 tb[NFTA_LOOKUP_SREG] == NULL) 71 tb[NFTA_LOOKUP_SREG] == NULL)
62 return -EINVAL; 72 return -EINVAL;
63 73
64 set = nf_tables_set_lookup(ctx->table, tb[NFTA_LOOKUP_SET]); 74 set = nf_tables_set_lookup(ctx->table, tb[NFTA_LOOKUP_SET], genmask);
65 if (IS_ERR(set)) { 75 if (IS_ERR(set)) {
66 if (tb[NFTA_LOOKUP_SET_ID]) { 76 if (tb[NFTA_LOOKUP_SET_ID]) {
67 set = nf_tables_set_lookup_byid(ctx->net, 77 set = nf_tables_set_lookup_byid(ctx->net,
68 tb[NFTA_LOOKUP_SET_ID]); 78 tb[NFTA_LOOKUP_SET_ID],
79 genmask);
69 } 80 }
70 if (IS_ERR(set)) 81 if (IS_ERR(set))
71 return PTR_ERR(set); 82 return PTR_ERR(set);
@@ -79,7 +90,22 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
79 if (err < 0) 90 if (err < 0)
80 return err; 91 return err;
81 92
93 if (tb[NFTA_LOOKUP_FLAGS]) {
94 flags = ntohl(nla_get_be32(tb[NFTA_LOOKUP_FLAGS]));
95
96 if (flags & ~NFT_LOOKUP_F_INV)
97 return -EINVAL;
98
99 if (flags & NFT_LOOKUP_F_INV) {
100 if (set->flags & NFT_SET_MAP)
101 return -EINVAL;
102 priv->invert = true;
103 }
104 }
105
82 if (tb[NFTA_LOOKUP_DREG] != NULL) { 106 if (tb[NFTA_LOOKUP_DREG] != NULL) {
107 if (priv->invert)
108 return -EINVAL;
83 if (!(set->flags & NFT_SET_MAP)) 109 if (!(set->flags & NFT_SET_MAP))
84 return -EINVAL; 110 return -EINVAL;
85 111
@@ -112,6 +138,7 @@ static void nft_lookup_destroy(const struct nft_ctx *ctx,
112static int nft_lookup_dump(struct sk_buff *skb, const struct nft_expr *expr) 138static int nft_lookup_dump(struct sk_buff *skb, const struct nft_expr *expr)
113{ 139{
114 const struct nft_lookup *priv = nft_expr_priv(expr); 140 const struct nft_lookup *priv = nft_expr_priv(expr);
141 u32 flags = priv->invert ? NFT_LOOKUP_F_INV : 0;
115 142
116 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name)) 143 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name))
117 goto nla_put_failure; 144 goto nla_put_failure;
@@ -120,6 +147,8 @@ static int nft_lookup_dump(struct sk_buff *skb, const struct nft_expr *expr)
120 if (priv->set->flags & NFT_SET_MAP) 147 if (priv->set->flags & NFT_SET_MAP)
121 if (nft_dump_register(skb, NFTA_LOOKUP_DREG, priv->dreg)) 148 if (nft_dump_register(skb, NFTA_LOOKUP_DREG, priv->dreg))
122 goto nla_put_failure; 149 goto nla_put_failure;
150 if (nla_put_be32(skb, NFTA_LOOKUP_FLAGS, htonl(flags)))
151 goto nla_put_failure;
123 return 0; 152 return 0;
124 153
125nla_put_failure: 154nla_put_failure:
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c
index 7201d57b5a93..c0f638745adc 100644
--- a/net/netfilter/nft_rbtree.c
+++ b/net/netfilter/nft_rbtree.c
@@ -170,7 +170,7 @@ static void *nft_rbtree_deactivate(const struct nft_set *set,
170 const struct nft_rbtree *priv = nft_set_priv(set); 170 const struct nft_rbtree *priv = nft_set_priv(set);
171 const struct rb_node *parent = priv->root.rb_node; 171 const struct rb_node *parent = priv->root.rb_node;
172 struct nft_rbtree_elem *rbe, *this = elem->priv; 172 struct nft_rbtree_elem *rbe, *this = elem->priv;
173 u8 genmask = nft_genmask_cur(read_pnet(&set->pnet)); 173 u8 genmask = nft_genmask_next(read_pnet(&set->pnet));
174 int d; 174 int d;
175 175
176 while (parent != NULL) { 176 while (parent != NULL) {
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 2675d580c490..fe0e2db632c7 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1460,6 +1460,9 @@ xt_hook_ops_alloc(const struct xt_table *table, nf_hookfn *fn)
1460 uint8_t hooknum; 1460 uint8_t hooknum;
1461 struct nf_hook_ops *ops; 1461 struct nf_hook_ops *ops;
1462 1462
1463 if (!num_hooks)
1464 return ERR_PTR(-EINVAL);
1465
1463 ops = kmalloc(sizeof(*ops) * num_hooks, GFP_KERNEL); 1466 ops = kmalloc(sizeof(*ops) * num_hooks, GFP_KERNEL);
1464 if (ops == NULL) 1467 if (ops == NULL)
1465 return ERR_PTR(-ENOMEM); 1468 return ERR_PTR(-ENOMEM);
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
index a1fa2c800cb9..018eed7e1ff1 100644
--- a/net/netfilter/xt_NFLOG.c
+++ b/net/netfilter/xt_NFLOG.c
@@ -33,6 +33,9 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par)
33 li.u.ulog.group = info->group; 33 li.u.ulog.group = info->group;
34 li.u.ulog.qthreshold = info->threshold; 34 li.u.ulog.qthreshold = info->threshold;
35 35
36 if (info->flags & XT_NFLOG_F_COPY_LEN)
37 li.u.ulog.flags |= NF_LOG_F_COPY_LEN;
38
36 nfulnl_log_packet(net, par->family, par->hooknum, skb, par->in, 39 nfulnl_log_packet(net, par->family, par->hooknum, skb, par->in,
37 par->out, &li, info->prefix); 40 par->out, &li, info->prefix);
38 return XT_CONTINUE; 41 return XT_CONTINUE;
diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c
index df48967af382..858d189a1303 100644
--- a/net/netfilter/xt_TRACE.c
+++ b/net/netfilter/xt_TRACE.c
@@ -4,12 +4,23 @@
4#include <linux/skbuff.h> 4#include <linux/skbuff.h>
5 5
6#include <linux/netfilter/x_tables.h> 6#include <linux/netfilter/x_tables.h>
7#include <net/netfilter/nf_log.h>
7 8
8MODULE_DESCRIPTION("Xtables: packet flow tracing"); 9MODULE_DESCRIPTION("Xtables: packet flow tracing");
9MODULE_LICENSE("GPL"); 10MODULE_LICENSE("GPL");
10MODULE_ALIAS("ipt_TRACE"); 11MODULE_ALIAS("ipt_TRACE");
11MODULE_ALIAS("ip6t_TRACE"); 12MODULE_ALIAS("ip6t_TRACE");
12 13
14static int trace_tg_check(const struct xt_tgchk_param *par)
15{
16 return nf_logger_find_get(par->family, NF_LOG_TYPE_LOG);
17}
18
19static void trace_tg_destroy(const struct xt_tgdtor_param *par)
20{
21 nf_logger_put(par->family, NF_LOG_TYPE_LOG);
22}
23
13static unsigned int 24static unsigned int
14trace_tg(struct sk_buff *skb, const struct xt_action_param *par) 25trace_tg(struct sk_buff *skb, const struct xt_action_param *par)
15{ 26{
@@ -18,12 +29,14 @@ trace_tg(struct sk_buff *skb, const struct xt_action_param *par)
18} 29}
19 30
20static struct xt_target trace_tg_reg __read_mostly = { 31static struct xt_target trace_tg_reg __read_mostly = {
21 .name = "TRACE", 32 .name = "TRACE",
22 .revision = 0, 33 .revision = 0,
23 .family = NFPROTO_UNSPEC, 34 .family = NFPROTO_UNSPEC,
24 .table = "raw", 35 .table = "raw",
25 .target = trace_tg, 36 .target = trace_tg,
26 .me = THIS_MODULE, 37 .checkentry = trace_tg_check,
38 .destroy = trace_tg_destroy,
39 .me = THIS_MODULE,
27}; 40};
28 41
29static int __init trace_tg_init(void) 42static int __init trace_tg_init(void)
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 1302b475abcb..a20e731b5b6c 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -21,11 +21,39 @@
21static int owner_check(const struct xt_mtchk_param *par) 21static int owner_check(const struct xt_mtchk_param *par)
22{ 22{
23 struct xt_owner_match_info *info = par->matchinfo; 23 struct xt_owner_match_info *info = par->matchinfo;
24 struct net *net = par->net;
24 25
25 /* For now only allow adding matches from the initial user namespace */ 26 /* Only allow the common case where the userns of the writer
27 * matches the userns of the network namespace.
28 */
26 if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) && 29 if ((info->match & (XT_OWNER_UID|XT_OWNER_GID)) &&
27 (current_user_ns() != &init_user_ns)) 30 (current_user_ns() != net->user_ns))
28 return -EINVAL; 31 return -EINVAL;
32
33 /* Ensure the uids are valid */
34 if (info->match & XT_OWNER_UID) {
35 kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
36 kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
37
38 if (!uid_valid(uid_min) || !uid_valid(uid_max) ||
39 (info->uid_max < info->uid_min) ||
40 uid_lt(uid_max, uid_min)) {
41 return -EINVAL;
42 }
43 }
44
45 /* Ensure the gids are valid */
46 if (info->match & XT_OWNER_GID) {
47 kgid_t gid_min = make_kgid(net->user_ns, info->gid_min);
48 kgid_t gid_max = make_kgid(net->user_ns, info->gid_max);
49
50 if (!gid_valid(gid_min) || !gid_valid(gid_max) ||
51 (info->gid_max < info->gid_min) ||
52 gid_lt(gid_max, gid_min)) {
53 return -EINVAL;
54 }
55 }
56
29 return 0; 57 return 0;
30} 58}
31 59
@@ -35,6 +63,7 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
35 const struct xt_owner_match_info *info = par->matchinfo; 63 const struct xt_owner_match_info *info = par->matchinfo;
36 const struct file *filp; 64 const struct file *filp;
37 struct sock *sk = skb_to_full_sk(skb); 65 struct sock *sk = skb_to_full_sk(skb);
66 struct net *net = par->net;
38 67
39 if (sk == NULL || sk->sk_socket == NULL) 68 if (sk == NULL || sk->sk_socket == NULL)
40 return (info->match ^ info->invert) == 0; 69 return (info->match ^ info->invert) == 0;
@@ -51,8 +80,8 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
51 (XT_OWNER_UID | XT_OWNER_GID)) == 0; 80 (XT_OWNER_UID | XT_OWNER_GID)) == 0;
52 81
53 if (info->match & XT_OWNER_UID) { 82 if (info->match & XT_OWNER_UID) {
54 kuid_t uid_min = make_kuid(&init_user_ns, info->uid_min); 83 kuid_t uid_min = make_kuid(net->user_ns, info->uid_min);
55 kuid_t uid_max = make_kuid(&init_user_ns, info->uid_max); 84 kuid_t uid_max = make_kuid(net->user_ns, info->uid_max);
56 if ((uid_gte(filp->f_cred->fsuid, uid_min) && 85 if ((uid_gte(filp->f_cred->fsuid, uid_min) &&
57 uid_lte(filp->f_cred->fsuid, uid_max)) ^ 86 uid_lte(filp->f_cred->fsuid, uid_max)) ^
58 !(info->invert & XT_OWNER_UID)) 87 !(info->invert & XT_OWNER_UID))
@@ -60,8 +89,8 @@ owner_mt(const struct sk_buff *skb, struct xt_action_param *par)
60 } 89 }
61 90
62 if (info->match & XT_OWNER_GID) { 91 if (info->match & XT_OWNER_GID) {
63 kgid_t gid_min = make_kgid(&init_user_ns, info->gid_min); 92 kgid_t gid_min = make_kgid(net->user_ns, info->gid_min);
64 kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max); 93 kgid_t gid_max = make_kgid(net->user_ns, info->gid_max);
65 if ((gid_gte(filp->f_cred->fsgid, gid_min) && 94 if ((gid_gte(filp->f_cred->fsgid, gid_min) &&
66 gid_lte(filp->f_cred->fsgid, gid_max)) ^ 95 gid_lte(filp->f_cred->fsgid, gid_max)) ^
67 !(info->invert & XT_OWNER_GID)) 96 !(info->invert & XT_OWNER_GID))
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index c14d4645daa3..ade024c90f4f 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -83,8 +83,6 @@ static bool tcp_mt(const struct sk_buff *skb, struct xt_action_param *par)
83 return false; 83 return false;
84 } 84 }
85 85
86#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg)))
87
88 th = skb_header_pointer(skb, par->thoff, sizeof(_tcph), &_tcph); 86 th = skb_header_pointer(skb, par->thoff, sizeof(_tcph), &_tcph);
89 if (th == NULL) { 87 if (th == NULL) {
90 /* We've been asked to examine this packet, and we 88 /* We've been asked to examine this packet, and we
@@ -102,9 +100,8 @@ static bool tcp_mt(const struct sk_buff *skb, struct xt_action_param *par)
102 ntohs(th->dest), 100 ntohs(th->dest),
103 !!(tcpinfo->invflags & XT_TCP_INV_DSTPT))) 101 !!(tcpinfo->invflags & XT_TCP_INV_DSTPT)))
104 return false; 102 return false;
105 if (!FWINVTCP((((unsigned char *)th)[13] & tcpinfo->flg_mask) 103 if (!NF_INVF(tcpinfo, XT_TCP_INV_FLAGS,
106 == tcpinfo->flg_cmp, 104 (((unsigned char *)th)[13] & tcpinfo->flg_mask) == tcpinfo->flg_cmp))
107 XT_TCP_INV_FLAGS))
108 return false; 105 return false;
109 if (tcpinfo->option) { 106 if (tcpinfo->option) {
110 if (th->doff * 4 < sizeof(_tcph)) { 107 if (th->doff * 4 < sizeof(_tcph)) {