aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-01-08 20:53:16 -0500
committerDavid S. Miller <davem@davemloft.net>2016-01-08 20:53:16 -0500
commit9b59377b756670d9516e72276b6c4efa92137b5f (patch)
treedfbabe7271af5c501bc429901efbd14ff8ab4670 /net/netfilter
parent7d39721466175a075abc9662ca790fe81bf78864 (diff)
parent48f66c905a976bf0ff092fc24f08d9addd82a245 (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) Release nf_tables objects on netns destructions via nft_release_afinfo(). 2) Destroy basechain and rules on netdevice removal in the new netdev family. 3) Get rid of defensive check against removal of inactive objects in nf_tables. 4) Pass down netns pointer to our existing nfnetlink callbacks, as well as commit() and abort() nfnetlink callbacks. 5) Allow to invert limit expression in nf_tables, so we can throttle overlimit traffic. 6) Add packet duplication for the netdev family. 7) Add forward expression for the netdev family. 8) Define pr_fmt() in conntrack helpers. 9) Don't leave nfqueue configuration on inconsistent state in case of errors, from Ken-ichirou MATSUZAWA, follow up patches are also from him. 10) Skip queue option handling after unbind. 11) Return error on unknown both in nfqueue and nflog command. 12) Autoload ctnetlink when NFQA_CFG_F_CONNTRACK is set. 13) Add new NFTA_SET_USERDATA attribute to store user data in sets, from Carlos Falgueras. 14) Add support for 64 bit byteordering changes nf_tables, from Florian Westphal. 15) Add conntrack byte/packet counter matching support to nf_tables, also from Florian. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/Kconfig22
-rw-r--r--net/netfilter/Makefile7
-rw-r--r--net/netfilter/ipset/ip_set_core.c108
-rw-r--r--net/netfilter/nf_conntrack_ftp.c17
-rw-r--r--net/netfilter/nf_conntrack_irc.c7
-rw-r--r--net/netfilter/nf_conntrack_netlink.c96
-rw-r--r--net/netfilter/nf_conntrack_sane.c19
-rw-r--r--net/netfilter/nf_conntrack_sip.c5
-rw-r--r--net/netfilter/nf_conntrack_tftp.c7
-rw-r--r--net/netfilter/nf_dup_netdev.c40
-rw-r--r--net/netfilter/nf_tables_api.c164
-rw-r--r--net/netfilter/nf_tables_inet.c2
-rw-r--r--net/netfilter/nf_tables_netdev.c47
-rw-r--r--net/netfilter/nfnetlink.c12
-rw-r--r--net/netfilter/nfnetlink_acct.c21
-rw-r--r--net/netfilter/nfnetlink_cthelper.c18
-rw-r--r--net/netfilter/nfnetlink_cttimeout.c42
-rw-r--r--net/netfilter/nfnetlink_log.c17
-rw-r--r--net/netfilter/nfnetlink_queue.c123
-rw-r--r--net/netfilter/nft_byteorder.c23
-rw-r--r--net/netfilter/nft_compat.c6
-rw-r--r--net/netfilter/nft_ct.c38
-rw-r--r--net/netfilter/nft_dup_netdev.c97
-rw-r--r--net/netfilter/nft_fwd_netdev.c98
-rw-r--r--net/netfilter/nft_limit.c16
-rw-r--r--net/netfilter/xt_osf.c7
26 files changed, 705 insertions, 354 deletions
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 4692782b5280..8c067e6663a1 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -563,6 +563,28 @@ config NFT_COMPAT
563 x_tables match/target extensions over the nf_tables 563 x_tables match/target extensions over the nf_tables
564 framework. 564 framework.
565 565
566if NF_TABLES_NETDEV
567
568config NF_DUP_NETDEV
569 tristate "Netfilter packet duplication support"
570 help
571 This option enables the generic packet duplication infrastructure
572 for Netfilter.
573
574config NFT_DUP_NETDEV
575 tristate "Netfilter nf_tables netdev packet duplication support"
576 select NF_DUP_NETDEV
577 help
578 This option enables packet duplication for the "netdev" family.
579
580config NFT_FWD_NETDEV
581 tristate "Netfilter nf_tables netdev packet forwarding support"
582 select NF_DUP_NETDEV
583 help
584 This option enables packet forwarding for the "netdev" family.
585
586endif # NF_TABLES_NETDEV
587
566endif # NF_TABLES 588endif # NF_TABLES
567 589
568config NETFILTER_XTABLES 590config NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 22934846b5d1..69134541d65b 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -66,6 +66,9 @@ obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
66# SYNPROXY 66# SYNPROXY
67obj-$(CONFIG_NETFILTER_SYNPROXY) += nf_synproxy_core.o 67obj-$(CONFIG_NETFILTER_SYNPROXY) += nf_synproxy_core.o
68 68
69# generic packet duplication from netdev family
70obj-$(CONFIG_NF_DUP_NETDEV) += nf_dup_netdev.o
71
69# nf_tables 72# nf_tables
70nf_tables-objs += nf_tables_core.o nf_tables_api.o nf_tables_trace.o 73nf_tables-objs += nf_tables_core.o nf_tables_api.o nf_tables_trace.o
71nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o nft_dynset.o 74nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o nft_dynset.o
@@ -90,6 +93,10 @@ obj-$(CONFIG_NFT_LOG) += nft_log.o
90obj-$(CONFIG_NFT_MASQ) += nft_masq.o 93obj-$(CONFIG_NFT_MASQ) += nft_masq.o
91obj-$(CONFIG_NFT_REDIR) += nft_redir.o 94obj-$(CONFIG_NFT_REDIR) += nft_redir.o
92 95
96# nf_tables netdev
97obj-$(CONFIG_NFT_DUP_NETDEV) += nft_dup_netdev.o
98obj-$(CONFIG_NFT_FWD_NETDEV) += nft_fwd_netdev.o
99
93# generic X tables 100# generic X tables
94obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 101obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
95 102
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 54f3d7cb23e6..95db43fc0303 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -825,20 +825,17 @@ find_free_id(struct ip_set_net *inst, const char *name, ip_set_id_t *index,
825 return 0; 825 return 0;
826} 826}
827 827
828static int 828static int ip_set_none(struct net *net, struct sock *ctnl, struct sk_buff *skb,
829ip_set_none(struct sock *ctnl, struct sk_buff *skb, 829 const struct nlmsghdr *nlh,
830 const struct nlmsghdr *nlh, 830 const struct nlattr * const attr[])
831 const struct nlattr * const attr[])
832{ 831{
833 return -EOPNOTSUPP; 832 return -EOPNOTSUPP;
834} 833}
835 834
836static int 835static int ip_set_create(struct net *net, struct sock *ctnl,
837ip_set_create(struct sock *ctnl, struct sk_buff *skb, 836 struct sk_buff *skb, const struct nlmsghdr *nlh,
838 const struct nlmsghdr *nlh, 837 const struct nlattr * const attr[])
839 const struct nlattr * const attr[])
840{ 838{
841 struct net *net = sock_net(ctnl);
842 struct ip_set_net *inst = ip_set_pernet(net); 839 struct ip_set_net *inst = ip_set_pernet(net);
843 struct ip_set *set, *clash = NULL; 840 struct ip_set *set, *clash = NULL;
844 ip_set_id_t index = IPSET_INVALID_ID; 841 ip_set_id_t index = IPSET_INVALID_ID;
@@ -976,12 +973,11 @@ ip_set_destroy_set(struct ip_set *set)
976 kfree(set); 973 kfree(set);
977} 974}
978 975
979static int 976static int ip_set_destroy(struct net *net, struct sock *ctnl,
980ip_set_destroy(struct sock *ctnl, struct sk_buff *skb, 977 struct sk_buff *skb, const struct nlmsghdr *nlh,
981 const struct nlmsghdr *nlh, 978 const struct nlattr * const attr[])
982 const struct nlattr * const attr[])
983{ 979{
984 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 980 struct ip_set_net *inst = ip_set_pernet(net);
985 struct ip_set *s; 981 struct ip_set *s;
986 ip_set_id_t i; 982 ip_set_id_t i;
987 int ret = 0; 983 int ret = 0;
@@ -1052,12 +1048,11 @@ ip_set_flush_set(struct ip_set *set)
1052 spin_unlock_bh(&set->lock); 1048 spin_unlock_bh(&set->lock);
1053} 1049}
1054 1050
1055static int 1051static int ip_set_flush(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1056ip_set_flush(struct sock *ctnl, struct sk_buff *skb, 1052 const struct nlmsghdr *nlh,
1057 const struct nlmsghdr *nlh, 1053 const struct nlattr * const attr[])
1058 const struct nlattr * const attr[])
1059{ 1054{
1060 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 1055 struct ip_set_net *inst = ip_set_pernet(net);
1061 struct ip_set *s; 1056 struct ip_set *s;
1062 ip_set_id_t i; 1057 ip_set_id_t i;
1063 1058
@@ -1092,12 +1087,11 @@ ip_set_setname2_policy[IPSET_ATTR_CMD_MAX + 1] = {
1092 .len = IPSET_MAXNAMELEN - 1 }, 1087 .len = IPSET_MAXNAMELEN - 1 },
1093}; 1088};
1094 1089
1095static int 1090static int ip_set_rename(struct net *net, struct sock *ctnl,
1096ip_set_rename(struct sock *ctnl, struct sk_buff *skb, 1091 struct sk_buff *skb, const struct nlmsghdr *nlh,
1097 const struct nlmsghdr *nlh, 1092 const struct nlattr * const attr[])
1098 const struct nlattr * const attr[])
1099{ 1093{
1100 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 1094 struct ip_set_net *inst = ip_set_pernet(net);
1101 struct ip_set *set, *s; 1095 struct ip_set *set, *s;
1102 const char *name2; 1096 const char *name2;
1103 ip_set_id_t i; 1097 ip_set_id_t i;
@@ -1142,12 +1136,11 @@ out:
1142 * so the ip_set_list always contains valid pointers to the sets. 1136 * so the ip_set_list always contains valid pointers to the sets.
1143 */ 1137 */
1144 1138
1145static int 1139static int ip_set_swap(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1146ip_set_swap(struct sock *ctnl, struct sk_buff *skb, 1140 const struct nlmsghdr *nlh,
1147 const struct nlmsghdr *nlh, 1141 const struct nlattr * const attr[])
1148 const struct nlattr * const attr[])
1149{ 1142{
1150 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 1143 struct ip_set_net *inst = ip_set_pernet(net);
1151 struct ip_set *from, *to; 1144 struct ip_set *from, *to;
1152 ip_set_id_t from_id, to_id; 1145 ip_set_id_t from_id, to_id;
1153 char from_name[IPSET_MAXNAMELEN]; 1146 char from_name[IPSET_MAXNAMELEN];
@@ -1413,10 +1406,9 @@ out:
1413 return ret < 0 ? ret : skb->len; 1406 return ret < 0 ? ret : skb->len;
1414} 1407}
1415 1408
1416static int 1409static int ip_set_dump(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1417ip_set_dump(struct sock *ctnl, struct sk_buff *skb, 1410 const struct nlmsghdr *nlh,
1418 const struct nlmsghdr *nlh, 1411 const struct nlattr * const attr[])
1419 const struct nlattr * const attr[])
1420{ 1412{
1421 if (unlikely(protocol_failed(attr))) 1413 if (unlikely(protocol_failed(attr)))
1422 return -IPSET_ERR_PROTOCOL; 1414 return -IPSET_ERR_PROTOCOL;
@@ -1500,12 +1492,11 @@ call_ad(struct sock *ctnl, struct sk_buff *skb, struct ip_set *set,
1500 return ret; 1492 return ret;
1501} 1493}
1502 1494
1503static int 1495static int ip_set_uadd(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1504ip_set_uadd(struct sock *ctnl, struct sk_buff *skb, 1496 const struct nlmsghdr *nlh,
1505 const struct nlmsghdr *nlh, 1497 const struct nlattr * const attr[])
1506 const struct nlattr * const attr[])
1507{ 1498{
1508 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 1499 struct ip_set_net *inst = ip_set_pernet(net);
1509 struct ip_set *set; 1500 struct ip_set *set;
1510 struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {}; 1501 struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {};
1511 const struct nlattr *nla; 1502 const struct nlattr *nla;
@@ -1555,12 +1546,11 @@ ip_set_uadd(struct sock *ctnl, struct sk_buff *skb,
1555 return ret; 1546 return ret;
1556} 1547}
1557 1548
1558static int 1549static int ip_set_udel(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1559ip_set_udel(struct sock *ctnl, struct sk_buff *skb, 1550 const struct nlmsghdr *nlh,
1560 const struct nlmsghdr *nlh, 1551 const struct nlattr * const attr[])
1561 const struct nlattr * const attr[])
1562{ 1552{
1563 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 1553 struct ip_set_net *inst = ip_set_pernet(net);
1564 struct ip_set *set; 1554 struct ip_set *set;
1565 struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {}; 1555 struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {};
1566 const struct nlattr *nla; 1556 const struct nlattr *nla;
@@ -1610,12 +1600,11 @@ ip_set_udel(struct sock *ctnl, struct sk_buff *skb,
1610 return ret; 1600 return ret;
1611} 1601}
1612 1602
1613static int 1603static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1614ip_set_utest(struct sock *ctnl, struct sk_buff *skb, 1604 const struct nlmsghdr *nlh,
1615 const struct nlmsghdr *nlh, 1605 const struct nlattr * const attr[])
1616 const struct nlattr * const attr[])
1617{ 1606{
1618 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 1607 struct ip_set_net *inst = ip_set_pernet(net);
1619 struct ip_set *set; 1608 struct ip_set *set;
1620 struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {}; 1609 struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {};
1621 int ret = 0; 1610 int ret = 0;
@@ -1646,12 +1635,11 @@ ip_set_utest(struct sock *ctnl, struct sk_buff *skb,
1646 1635
1647/* Get headed data of a set */ 1636/* Get headed data of a set */
1648 1637
1649static int 1638static int ip_set_header(struct net *net, struct sock *ctnl,
1650ip_set_header(struct sock *ctnl, struct sk_buff *skb, 1639 struct sk_buff *skb, const struct nlmsghdr *nlh,
1651 const struct nlmsghdr *nlh, 1640 const struct nlattr * const attr[])
1652 const struct nlattr * const attr[])
1653{ 1641{
1654 struct ip_set_net *inst = ip_set_pernet(sock_net(ctnl)); 1642 struct ip_set_net *inst = ip_set_pernet(net);
1655 const struct ip_set *set; 1643 const struct ip_set *set;
1656 struct sk_buff *skb2; 1644 struct sk_buff *skb2;
1657 struct nlmsghdr *nlh2; 1645 struct nlmsghdr *nlh2;
@@ -1703,10 +1691,9 @@ static const struct nla_policy ip_set_type_policy[IPSET_ATTR_CMD_MAX + 1] = {
1703 [IPSET_ATTR_FAMILY] = { .type = NLA_U8 }, 1691 [IPSET_ATTR_FAMILY] = { .type = NLA_U8 },
1704}; 1692};
1705 1693
1706static int 1694static int ip_set_type(struct net *net, struct sock *ctnl, struct sk_buff *skb,
1707ip_set_type(struct sock *ctnl, struct sk_buff *skb, 1695 const struct nlmsghdr *nlh,
1708 const struct nlmsghdr *nlh, 1696 const struct nlattr * const attr[])
1709 const struct nlattr * const attr[])
1710{ 1697{
1711 struct sk_buff *skb2; 1698 struct sk_buff *skb2;
1712 struct nlmsghdr *nlh2; 1699 struct nlmsghdr *nlh2;
@@ -1762,10 +1749,9 @@ ip_set_protocol_policy[IPSET_ATTR_CMD_MAX + 1] = {
1762 [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 }, 1749 [IPSET_ATTR_PROTOCOL] = { .type = NLA_U8 },
1763}; 1750};
1764 1751
1765static int 1752static int ip_set_protocol(struct net *net, struct sock *ctnl,
1766ip_set_protocol(struct sock *ctnl, struct sk_buff *skb, 1753 struct sk_buff *skb, const struct nlmsghdr *nlh,
1767 const struct nlmsghdr *nlh, 1754 const struct nlattr * const attr[])
1768 const struct nlattr * const attr[])
1769{ 1755{
1770 struct sk_buff *skb2; 1756 struct sk_buff *skb2;
1771 struct nlmsghdr *nlh2; 1757 struct nlmsghdr *nlh2;
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index b666959f17c0..883c691ec8d0 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -10,6 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
13#include <linux/module.h> 15#include <linux/module.h>
14#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
15#include <linux/netfilter.h> 17#include <linux/netfilter.h>
@@ -505,11 +507,11 @@ skip_nl_seq:
505 different IP address. Simply don't record it for 507 different IP address. Simply don't record it for
506 NAT. */ 508 NAT. */
507 if (cmd.l3num == PF_INET) { 509 if (cmd.l3num == PF_INET) {
508 pr_debug("conntrack_ftp: NOT RECORDING: %pI4 != %pI4\n", 510 pr_debug("NOT RECORDING: %pI4 != %pI4\n",
509 &cmd.u3.ip, 511 &cmd.u3.ip,
510 &ct->tuplehash[dir].tuple.src.u3.ip); 512 &ct->tuplehash[dir].tuple.src.u3.ip);
511 } else { 513 } else {
512 pr_debug("conntrack_ftp: NOT RECORDING: %pI6 != %pI6\n", 514 pr_debug("NOT RECORDING: %pI6 != %pI6\n",
513 cmd.u3.ip6, 515 cmd.u3.ip6,
514 ct->tuplehash[dir].tuple.src.u3.ip6); 516 ct->tuplehash[dir].tuple.src.u3.ip6);
515 } 517 }
@@ -586,8 +588,7 @@ static void nf_conntrack_ftp_fini(void)
586 if (ftp[i][j].me == NULL) 588 if (ftp[i][j].me == NULL)
587 continue; 589 continue;
588 590
589 pr_debug("nf_ct_ftp: unregistering helper for pf: %d " 591 pr_debug("unregistering helper for pf: %d port: %d\n",
590 "port: %d\n",
591 ftp[i][j].tuple.src.l3num, ports[i]); 592 ftp[i][j].tuple.src.l3num, ports[i]);
592 nf_conntrack_helper_unregister(&ftp[i][j]); 593 nf_conntrack_helper_unregister(&ftp[i][j]);
593 } 594 }
@@ -625,14 +626,12 @@ static int __init nf_conntrack_ftp_init(void)
625 else 626 else
626 sprintf(ftp[i][j].name, "ftp-%d", ports[i]); 627 sprintf(ftp[i][j].name, "ftp-%d", ports[i]);
627 628
628 pr_debug("nf_ct_ftp: registering helper for pf: %d " 629 pr_debug("registering helper for pf: %d port: %d\n",
629 "port: %d\n",
630 ftp[i][j].tuple.src.l3num, ports[i]); 630 ftp[i][j].tuple.src.l3num, ports[i]);
631 ret = nf_conntrack_helper_register(&ftp[i][j]); 631 ret = nf_conntrack_helper_register(&ftp[i][j]);
632 if (ret) { 632 if (ret) {
633 printk(KERN_ERR "nf_ct_ftp: failed to register" 633 pr_err("failed to register helper for pf: %d port: %d\n",
634 " helper for pf: %d port: %d\n", 634 ftp[i][j].tuple.src.l3num, ports[i]);
635 ftp[i][j].tuple.src.l3num, ports[i]);
636 nf_conntrack_ftp_fini(); 635 nf_conntrack_ftp_fini();
637 return ret; 636 return ret;
638 } 637 }
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 0fd2976db7ee..8b6da2719600 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -9,6 +9,8 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
12#include <linux/module.h> 14#include <linux/module.h>
13#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
14#include <linux/skbuff.h> 16#include <linux/skbuff.h>
@@ -237,7 +239,7 @@ static int __init nf_conntrack_irc_init(void)
237 int i, ret; 239 int i, ret;
238 240
239 if (max_dcc_channels < 1) { 241 if (max_dcc_channels < 1) {
240 printk(KERN_ERR "nf_ct_irc: max_dcc_channels must not be zero\n"); 242 pr_err("max_dcc_channels must not be zero\n");
241 return -EINVAL; 243 return -EINVAL;
242 } 244 }
243 245
@@ -267,8 +269,7 @@ static int __init nf_conntrack_irc_init(void)
267 269
268 ret = nf_conntrack_helper_register(&irc[i]); 270 ret = nf_conntrack_helper_register(&irc[i]);
269 if (ret) { 271 if (ret) {
270 printk(KERN_ERR "nf_ct_irc: failed to register helper " 272 pr_err("failed to register helper for pf: %u port: %u\n",
271 "for pf: %u port: %u\n",
272 irc[i].tuple.src.l3num, ports[i]); 273 irc[i].tuple.src.l3num, ports[i]);
273 nf_conntrack_irc_fini(); 274 nf_conntrack_irc_fini();
274 return ret; 275 return ret;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9f5272968abb..dbb1bb3edb45 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1113,12 +1113,11 @@ static int ctnetlink_flush_conntrack(struct net *net,
1113 return 0; 1113 return 0;
1114} 1114}
1115 1115
1116static int 1116static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl,
1117ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 1117 struct sk_buff *skb,
1118 const struct nlmsghdr *nlh, 1118 const struct nlmsghdr *nlh,
1119 const struct nlattr * const cda[]) 1119 const struct nlattr * const cda[])
1120{ 1120{
1121 struct net *net = sock_net(ctnl);
1122 struct nf_conntrack_tuple_hash *h; 1121 struct nf_conntrack_tuple_hash *h;
1123 struct nf_conntrack_tuple tuple; 1122 struct nf_conntrack_tuple tuple;
1124 struct nf_conn *ct; 1123 struct nf_conn *ct;
@@ -1168,12 +1167,11 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
1168 return 0; 1167 return 0;
1169} 1168}
1170 1169
1171static int 1170static int ctnetlink_get_conntrack(struct net *net, struct sock *ctnl,
1172ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, 1171 struct sk_buff *skb,
1173 const struct nlmsghdr *nlh, 1172 const struct nlmsghdr *nlh,
1174 const struct nlattr * const cda[]) 1173 const struct nlattr * const cda[])
1175{ 1174{
1176 struct net *net = sock_net(ctnl);
1177 struct nf_conntrack_tuple_hash *h; 1175 struct nf_conntrack_tuple_hash *h;
1178 struct nf_conntrack_tuple tuple; 1176 struct nf_conntrack_tuple tuple;
1179 struct nf_conn *ct; 1177 struct nf_conn *ct;
@@ -1330,10 +1328,10 @@ ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
1330 return ctnetlink_dump_list(skb, cb, true); 1328 return ctnetlink_dump_list(skb, cb, true);
1331} 1329}
1332 1330
1333static int 1331static int ctnetlink_get_ct_dying(struct net *net, struct sock *ctnl,
1334ctnetlink_get_ct_dying(struct sock *ctnl, struct sk_buff *skb, 1332 struct sk_buff *skb,
1335 const struct nlmsghdr *nlh, 1333 const struct nlmsghdr *nlh,
1336 const struct nlattr * const cda[]) 1334 const struct nlattr * const cda[])
1337{ 1335{
1338 if (nlh->nlmsg_flags & NLM_F_DUMP) { 1336 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1339 struct netlink_dump_control c = { 1337 struct netlink_dump_control c = {
@@ -1352,10 +1350,10 @@ ctnetlink_dump_unconfirmed(struct sk_buff *skb, struct netlink_callback *cb)
1352 return ctnetlink_dump_list(skb, cb, false); 1350 return ctnetlink_dump_list(skb, cb, false);
1353} 1351}
1354 1352
1355static int 1353static int ctnetlink_get_ct_unconfirmed(struct net *net, struct sock *ctnl,
1356ctnetlink_get_ct_unconfirmed(struct sock *ctnl, struct sk_buff *skb, 1354 struct sk_buff *skb,
1357 const struct nlmsghdr *nlh, 1355 const struct nlmsghdr *nlh,
1358 const struct nlattr * const cda[]) 1356 const struct nlattr * const cda[])
1359{ 1357{
1360 if (nlh->nlmsg_flags & NLM_F_DUMP) { 1358 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1361 struct netlink_dump_control c = { 1359 struct netlink_dump_control c = {
@@ -1865,12 +1863,11 @@ err1:
1865 return ERR_PTR(err); 1863 return ERR_PTR(err);
1866} 1864}
1867 1865
1868static int 1866static int ctnetlink_new_conntrack(struct net *net, struct sock *ctnl,
1869ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, 1867 struct sk_buff *skb,
1870 const struct nlmsghdr *nlh, 1868 const struct nlmsghdr *nlh,
1871 const struct nlattr * const cda[]) 1869 const struct nlattr * const cda[])
1872{ 1870{
1873 struct net *net = sock_net(ctnl);
1874 struct nf_conntrack_tuple otuple, rtuple; 1871 struct nf_conntrack_tuple otuple, rtuple;
1875 struct nf_conntrack_tuple_hash *h = NULL; 1872 struct nf_conntrack_tuple_hash *h = NULL;
1876 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1873 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -2034,10 +2031,10 @@ ctnetlink_ct_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
2034 return skb->len; 2031 return skb->len;
2035} 2032}
2036 2033
2037static int 2034static int ctnetlink_stat_ct_cpu(struct net *net, struct sock *ctnl,
2038ctnetlink_stat_ct_cpu(struct sock *ctnl, struct sk_buff *skb, 2035 struct sk_buff *skb,
2039 const struct nlmsghdr *nlh, 2036 const struct nlmsghdr *nlh,
2040 const struct nlattr * const cda[]) 2037 const struct nlattr * const cda[])
2041{ 2038{
2042 if (nlh->nlmsg_flags & NLM_F_DUMP) { 2039 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2043 struct netlink_dump_control c = { 2040 struct netlink_dump_control c = {
@@ -2080,10 +2077,9 @@ nlmsg_failure:
2080 return -1; 2077 return -1;
2081} 2078}
2082 2079
2083static int 2080static int ctnetlink_stat_ct(struct net *net, struct sock *ctnl,
2084ctnetlink_stat_ct(struct sock *ctnl, struct sk_buff *skb, 2081 struct sk_buff *skb, const struct nlmsghdr *nlh,
2085 const struct nlmsghdr *nlh, 2082 const struct nlattr * const cda[])
2086 const struct nlattr * const cda[])
2087{ 2083{
2088 struct sk_buff *skb2; 2084 struct sk_buff *skb2;
2089 int err; 2085 int err;
@@ -2729,12 +2725,12 @@ out:
2729 return skb->len; 2725 return skb->len;
2730} 2726}
2731 2727
2732static int ctnetlink_dump_exp_ct(struct sock *ctnl, struct sk_buff *skb, 2728static int ctnetlink_dump_exp_ct(struct net *net, struct sock *ctnl,
2729 struct sk_buff *skb,
2733 const struct nlmsghdr *nlh, 2730 const struct nlmsghdr *nlh,
2734 const struct nlattr * const cda[]) 2731 const struct nlattr * const cda[])
2735{ 2732{
2736 int err; 2733 int err;
2737 struct net *net = sock_net(ctnl);
2738 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2734 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2739 u_int8_t u3 = nfmsg->nfgen_family; 2735 u_int8_t u3 = nfmsg->nfgen_family;
2740 struct nf_conntrack_tuple tuple; 2736 struct nf_conntrack_tuple tuple;
@@ -2768,12 +2764,10 @@ static int ctnetlink_dump_exp_ct(struct sock *ctnl, struct sk_buff *skb,
2768 return err; 2764 return err;
2769} 2765}
2770 2766
2771static int 2767static int ctnetlink_get_expect(struct net *net, struct sock *ctnl,
2772ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, 2768 struct sk_buff *skb, const struct nlmsghdr *nlh,
2773 const struct nlmsghdr *nlh, 2769 const struct nlattr * const cda[])
2774 const struct nlattr * const cda[])
2775{ 2770{
2776 struct net *net = sock_net(ctnl);
2777 struct nf_conntrack_tuple tuple; 2771 struct nf_conntrack_tuple tuple;
2778 struct nf_conntrack_expect *exp; 2772 struct nf_conntrack_expect *exp;
2779 struct sk_buff *skb2; 2773 struct sk_buff *skb2;
@@ -2784,7 +2778,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
2784 2778
2785 if (nlh->nlmsg_flags & NLM_F_DUMP) { 2779 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2786 if (cda[CTA_EXPECT_MASTER]) 2780 if (cda[CTA_EXPECT_MASTER])
2787 return ctnetlink_dump_exp_ct(ctnl, skb, nlh, cda); 2781 return ctnetlink_dump_exp_ct(net, ctnl, skb, nlh, cda);
2788 else { 2782 else {
2789 struct netlink_dump_control c = { 2783 struct netlink_dump_control c = {
2790 .dump = ctnetlink_exp_dump_table, 2784 .dump = ctnetlink_exp_dump_table,
@@ -2850,12 +2844,10 @@ out:
2850 return err == -EAGAIN ? -ENOBUFS : err; 2844 return err == -EAGAIN ? -ENOBUFS : err;
2851} 2845}
2852 2846
2853static int 2847static int ctnetlink_del_expect(struct net *net, struct sock *ctnl,
2854ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, 2848 struct sk_buff *skb, const struct nlmsghdr *nlh,
2855 const struct nlmsghdr *nlh, 2849 const struct nlattr * const cda[])
2856 const struct nlattr * const cda[])
2857{ 2850{
2858 struct net *net = sock_net(ctnl);
2859 struct nf_conntrack_expect *exp; 2851 struct nf_conntrack_expect *exp;
2860 struct nf_conntrack_tuple tuple; 2852 struct nf_conntrack_tuple tuple;
2861 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 2853 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -3136,12 +3128,10 @@ err_ct:
3136 return err; 3128 return err;
3137} 3129}
3138 3130
3139static int 3131static int ctnetlink_new_expect(struct net *net, struct sock *ctnl,
3140ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, 3132 struct sk_buff *skb, const struct nlmsghdr *nlh,
3141 const struct nlmsghdr *nlh, 3133 const struct nlattr * const cda[])
3142 const struct nlattr * const cda[])
3143{ 3134{
3144 struct net *net = sock_net(ctnl);
3145 struct nf_conntrack_tuple tuple; 3135 struct nf_conntrack_tuple tuple;
3146 struct nf_conntrack_expect *exp; 3136 struct nf_conntrack_expect *exp;
3147 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 3137 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -3242,10 +3232,10 @@ ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
3242 return skb->len; 3232 return skb->len;
3243} 3233}
3244 3234
3245static int 3235static int ctnetlink_stat_exp_cpu(struct net *net, struct sock *ctnl,
3246ctnetlink_stat_exp_cpu(struct sock *ctnl, struct sk_buff *skb, 3236 struct sk_buff *skb,
3247 const struct nlmsghdr *nlh, 3237 const struct nlmsghdr *nlh,
3248 const struct nlattr * const cda[]) 3238 const struct nlattr * const cda[])
3249{ 3239{
3250 if (nlh->nlmsg_flags & NLM_F_DUMP) { 3240 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3251 struct netlink_dump_control c = { 3241 struct netlink_dump_control c = {
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index 4a2134fd3fcb..7523a575f6d1 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -17,6 +17,8 @@
17 * published by the Free Software Foundation. 17 * published by the Free Software Foundation.
18 */ 18 */
19 19
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21
20#include <linux/module.h> 22#include <linux/module.h>
21#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
22#include <linux/netfilter.h> 24#include <linux/netfilter.h>
@@ -120,14 +122,14 @@ static int help(struct sk_buff *skb,
120 ct_sane_info->state = SANE_STATE_NORMAL; 122 ct_sane_info->state = SANE_STATE_NORMAL;
121 123
122 if (datalen < sizeof(struct sane_reply_net_start)) { 124 if (datalen < sizeof(struct sane_reply_net_start)) {
123 pr_debug("nf_ct_sane: NET_START reply too short\n"); 125 pr_debug("NET_START reply too short\n");
124 goto out; 126 goto out;
125 } 127 }
126 128
127 reply = sb_ptr; 129 reply = sb_ptr;
128 if (reply->status != htonl(SANE_STATUS_SUCCESS)) { 130 if (reply->status != htonl(SANE_STATUS_SUCCESS)) {
129 /* saned refused the command */ 131 /* saned refused the command */
130 pr_debug("nf_ct_sane: unsuccessful SANE_STATUS = %u\n", 132 pr_debug("unsuccessful SANE_STATUS = %u\n",
131 ntohl(reply->status)); 133 ntohl(reply->status));
132 goto out; 134 goto out;
133 } 135 }
@@ -148,7 +150,7 @@ static int help(struct sk_buff *skb,
148 &tuple->src.u3, &tuple->dst.u3, 150 &tuple->src.u3, &tuple->dst.u3,
149 IPPROTO_TCP, NULL, &reply->port); 151 IPPROTO_TCP, NULL, &reply->port);
150 152
151 pr_debug("nf_ct_sane: expect: "); 153 pr_debug("expect: ");
152 nf_ct_dump_tuple(&exp->tuple); 154 nf_ct_dump_tuple(&exp->tuple);
153 155
154 /* Can't expect this? Best to drop packet now. */ 156 /* Can't expect this? Best to drop packet now. */
@@ -178,8 +180,7 @@ static void nf_conntrack_sane_fini(void)
178 180
179 for (i = 0; i < ports_c; i++) { 181 for (i = 0; i < ports_c; i++) {
180 for (j = 0; j < 2; j++) { 182 for (j = 0; j < 2; j++) {
181 pr_debug("nf_ct_sane: unregistering helper for pf: %d " 183 pr_debug("unregistering helper for pf: %d port: %d\n",
182 "port: %d\n",
183 sane[i][j].tuple.src.l3num, ports[i]); 184 sane[i][j].tuple.src.l3num, ports[i]);
184 nf_conntrack_helper_unregister(&sane[i][j]); 185 nf_conntrack_helper_unregister(&sane[i][j]);
185 } 186 }
@@ -216,14 +217,12 @@ static int __init nf_conntrack_sane_init(void)
216 else 217 else
217 sprintf(sane[i][j].name, "sane-%d", ports[i]); 218 sprintf(sane[i][j].name, "sane-%d", ports[i]);
218 219
219 pr_debug("nf_ct_sane: registering helper for pf: %d " 220 pr_debug("registering helper for pf: %d port: %d\n",
220 "port: %d\n",
221 sane[i][j].tuple.src.l3num, ports[i]); 221 sane[i][j].tuple.src.l3num, ports[i]);
222 ret = nf_conntrack_helper_register(&sane[i][j]); 222 ret = nf_conntrack_helper_register(&sane[i][j]);
223 if (ret) { 223 if (ret) {
224 printk(KERN_ERR "nf_ct_sane: failed to " 224 pr_err("failed to register helper for pf: %d port: %d\n",
225 "register helper for pf: %d port: %d\n", 225 sane[i][j].tuple.src.l3num, ports[i]);
226 sane[i][j].tuple.src.l3num, ports[i]);
227 nf_conntrack_sane_fini(); 226 nf_conntrack_sane_fini();
228 return ret; 227 return ret;
229 } 228 }
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 885b4aba3695..3e06402739e0 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -10,6 +10,8 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
13#include <linux/module.h> 15#include <linux/module.h>
14#include <linux/ctype.h> 16#include <linux/ctype.h>
15#include <linux/skbuff.h> 17#include <linux/skbuff.h>
@@ -1665,8 +1667,7 @@ static int __init nf_conntrack_sip_init(void)
1665 1667
1666 ret = nf_conntrack_helper_register(&sip[i][j]); 1668 ret = nf_conntrack_helper_register(&sip[i][j]);
1667 if (ret) { 1669 if (ret) {
1668 printk(KERN_ERR "nf_ct_sip: failed to register" 1670 pr_err("failed to register helper for pf: %u port: %u\n",
1669 " helper for pf: %u port: %u\n",
1670 sip[i][j].tuple.src.l3num, ports[i]); 1671 sip[i][j].tuple.src.l3num, ports[i]);
1671 nf_conntrack_sip_fini(); 1672 nf_conntrack_sip_fini();
1672 return ret; 1673 return ret;
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index e68ab4fbd71f..36f964066461 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -5,6 +5,8 @@
5 * published by the Free Software Foundation. 5 * published by the Free Software Foundation.
6 */ 6 */
7 7
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
8#include <linux/module.h> 10#include <linux/module.h>
9#include <linux/moduleparam.h> 11#include <linux/moduleparam.h>
10#include <linux/in.h> 12#include <linux/in.h>
@@ -138,9 +140,8 @@ static int __init nf_conntrack_tftp_init(void)
138 140
139 ret = nf_conntrack_helper_register(&tftp[i][j]); 141 ret = nf_conntrack_helper_register(&tftp[i][j]);
140 if (ret) { 142 if (ret) {
141 printk(KERN_ERR "nf_ct_tftp: failed to register" 143 pr_err("failed to register helper for pf: %u port: %u\n",
142 " helper for pf: %u port: %u\n", 144 tftp[i][j].tuple.src.l3num, ports[i]);
143 tftp[i][j].tuple.src.l3num, ports[i]);
144 nf_conntrack_tftp_fini(); 145 nf_conntrack_tftp_fini();
145 return ret; 146 return ret;
146 } 147 }
diff --git a/net/netfilter/nf_dup_netdev.c b/net/netfilter/nf_dup_netdev.c
new file mode 100644
index 000000000000..8414ee1a0319
--- /dev/null
+++ b/net/netfilter/nf_dup_netdev.c
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 2015 Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/netlink.h>
13#include <linux/netfilter.h>
14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_tables.h>
16
17void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif)
18{
19 struct net_device *dev;
20 struct sk_buff *skb;
21
22 dev = dev_get_by_index_rcu(pkt->net, oif);
23 if (dev == NULL)
24 return;
25
26 skb = skb_clone(pkt->skb, GFP_ATOMIC);
27 if (skb == NULL)
28 return;
29
30 if (skb_mac_header_was_set(skb))
31 skb_push(skb, skb->mac_len);
32
33 skb->dev = dev;
34 skb_sender_cpu_clear(skb);
35 dev_queue_xmit(skb);
36}
37EXPORT_SYMBOL_GPL(nf_dup_netdev_egress);
38
39MODULE_LICENSE("GPL");
40MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 4a23f77c363a..2011977cd79d 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -41,6 +41,8 @@ int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
41} 41}
42EXPORT_SYMBOL_GPL(nft_register_afinfo); 42EXPORT_SYMBOL_GPL(nft_register_afinfo);
43 43
44static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi);
45
44/** 46/**
45 * nft_unregister_afinfo - unregister nf_tables address family info 47 * nft_unregister_afinfo - unregister nf_tables address family info
46 * 48 *
@@ -48,9 +50,10 @@ EXPORT_SYMBOL_GPL(nft_register_afinfo);
48 * 50 *
49 * Unregister the address family for use with nf_tables. 51 * Unregister the address family for use with nf_tables.
50 */ 52 */
51void nft_unregister_afinfo(struct nft_af_info *afi) 53void nft_unregister_afinfo(struct net *net, struct nft_af_info *afi)
52{ 54{
53 nfnl_lock(NFNL_SUBSYS_NFTABLES); 55 nfnl_lock(NFNL_SUBSYS_NFTABLES);
56 __nft_release_afinfo(net, afi);
54 list_del_rcu(&afi->list); 57 list_del_rcu(&afi->list);
55 nfnl_unlock(NFNL_SUBSYS_NFTABLES); 58 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
56} 59}
@@ -128,8 +131,8 @@ static void nft_trans_destroy(struct nft_trans *trans)
128 kfree(trans); 131 kfree(trans);
129} 132}
130 133
131int nft_register_basechain(struct nft_base_chain *basechain, 134static int nft_register_basechain(struct nft_base_chain *basechain,
132 unsigned int hook_nops) 135 unsigned int hook_nops)
133{ 136{
134 struct net *net = read_pnet(&basechain->pnet); 137 struct net *net = read_pnet(&basechain->pnet);
135 138
@@ -138,10 +141,9 @@ int nft_register_basechain(struct nft_base_chain *basechain,
138 141
139 return nf_register_net_hooks(net, basechain->ops, hook_nops); 142 return nf_register_net_hooks(net, basechain->ops, hook_nops);
140} 143}
141EXPORT_SYMBOL_GPL(nft_register_basechain);
142 144
143void nft_unregister_basechain(struct nft_base_chain *basechain, 145static void nft_unregister_basechain(struct nft_base_chain *basechain,
144 unsigned int hook_nops) 146 unsigned int hook_nops)
145{ 147{
146 struct net *net = read_pnet(&basechain->pnet); 148 struct net *net = read_pnet(&basechain->pnet);
147 149
@@ -150,7 +152,6 @@ void nft_unregister_basechain(struct nft_base_chain *basechain,
150 152
151 nf_unregister_net_hooks(net, basechain->ops, hook_nops); 153 nf_unregister_net_hooks(net, basechain->ops, hook_nops);
152} 154}
153EXPORT_SYMBOL_GPL(nft_unregister_basechain);
154 155
155static int nf_tables_register_hooks(const struct nft_table *table, 156static int nf_tables_register_hooks(const struct nft_table *table,
156 struct nft_chain *chain, 157 struct nft_chain *chain,
@@ -542,15 +543,14 @@ done:
542 return skb->len; 543 return skb->len;
543} 544}
544 545
545static int nf_tables_gettable(struct sock *nlsk, struct sk_buff *skb, 546static int nf_tables_gettable(struct net *net, struct sock *nlsk,
546 const struct nlmsghdr *nlh, 547 struct sk_buff *skb, const struct nlmsghdr *nlh,
547 const struct nlattr * const nla[]) 548 const struct nlattr * const nla[])
548{ 549{
549 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 550 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
550 const struct nft_af_info *afi; 551 const struct nft_af_info *afi;
551 const struct nft_table *table; 552 const struct nft_table *table;
552 struct sk_buff *skb2; 553 struct sk_buff *skb2;
553 struct net *net = sock_net(skb->sk);
554 int family = nfmsg->nfgen_family; 554 int family = nfmsg->nfgen_family;
555 int err; 555 int err;
556 556
@@ -831,8 +831,6 @@ static int nf_tables_deltable(struct net *net, struct sock *nlsk,
831 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]); 831 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME]);
832 if (IS_ERR(table)) 832 if (IS_ERR(table))
833 return PTR_ERR(table); 833 return PTR_ERR(table);
834 if (table->flags & NFT_TABLE_INACTIVE)
835 return -ENOENT;
836 834
837 ctx.afi = afi; 835 ctx.afi = afi;
838 ctx.table = table; 836 ctx.table = table;
@@ -1098,8 +1096,8 @@ done:
1098 return skb->len; 1096 return skb->len;
1099} 1097}
1100 1098
1101static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb, 1099static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1102 const struct nlmsghdr *nlh, 1100 struct sk_buff *skb, const struct nlmsghdr *nlh,
1103 const struct nlattr * const nla[]) 1101 const struct nlattr * const nla[])
1104{ 1102{
1105 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1103 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -1107,7 +1105,6 @@ static int nf_tables_getchain(struct sock *nlsk, struct sk_buff *skb,
1107 const struct nft_table *table; 1105 const struct nft_table *table;
1108 const struct nft_chain *chain; 1106 const struct nft_chain *chain;
1109 struct sk_buff *skb2; 1107 struct sk_buff *skb2;
1110 struct net *net = sock_net(skb->sk);
1111 int family = nfmsg->nfgen_family; 1108 int family = nfmsg->nfgen_family;
1112 int err; 1109 int err;
1113 1110
@@ -1492,14 +1489,10 @@ static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1492 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]); 1489 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE]);
1493 if (IS_ERR(table)) 1490 if (IS_ERR(table))
1494 return PTR_ERR(table); 1491 return PTR_ERR(table);
1495 if (table->flags & NFT_TABLE_INACTIVE)
1496 return -ENOENT;
1497 1492
1498 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]); 1493 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME]);
1499 if (IS_ERR(chain)) 1494 if (IS_ERR(chain))
1500 return PTR_ERR(chain); 1495 return PTR_ERR(chain);
1501 if (chain->flags & NFT_CHAIN_INACTIVE)
1502 return -ENOENT;
1503 if (chain->use > 0) 1496 if (chain->use > 0)
1504 return -EBUSY; 1497 return -EBUSY;
1505 1498
@@ -1928,8 +1921,8 @@ done:
1928 return skb->len; 1921 return skb->len;
1929} 1922}
1930 1923
1931static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb, 1924static int nf_tables_getrule(struct net *net, struct sock *nlsk,
1932 const struct nlmsghdr *nlh, 1925 struct sk_buff *skb, const struct nlmsghdr *nlh,
1933 const struct nlattr * const nla[]) 1926 const struct nlattr * const nla[])
1934{ 1927{
1935 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1928 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -1938,7 +1931,6 @@ static int nf_tables_getrule(struct sock *nlsk, struct sk_buff *skb,
1938 const struct nft_chain *chain; 1931 const struct nft_chain *chain;
1939 const struct nft_rule *rule; 1932 const struct nft_rule *rule;
1940 struct sk_buff *skb2; 1933 struct sk_buff *skb2;
1941 struct net *net = sock_net(skb->sk);
1942 int family = nfmsg->nfgen_family; 1934 int family = nfmsg->nfgen_family;
1943 int err; 1935 int err;
1944 1936
@@ -2191,8 +2183,6 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2191 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]); 2183 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE]);
2192 if (IS_ERR(table)) 2184 if (IS_ERR(table))
2193 return PTR_ERR(table); 2185 return PTR_ERR(table);
2194 if (table->flags & NFT_TABLE_INACTIVE)
2195 return -ENOENT;
2196 2186
2197 if (nla[NFTA_RULE_CHAIN]) { 2187 if (nla[NFTA_RULE_CHAIN]) {
2198 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]); 2188 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN]);
@@ -2333,6 +2323,8 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
2333 [NFTA_SET_ID] = { .type = NLA_U32 }, 2323 [NFTA_SET_ID] = { .type = NLA_U32 },
2334 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 }, 2324 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
2335 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 }, 2325 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
2326 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
2327 .len = NFT_USERDATA_MAXLEN },
2336}; 2328};
2337 2329
2338static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = { 2330static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
@@ -2361,8 +2353,6 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
2361 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); 2353 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
2362 if (IS_ERR(table)) 2354 if (IS_ERR(table))
2363 return PTR_ERR(table); 2355 return PTR_ERR(table);
2364 if (table->flags & NFT_TABLE_INACTIVE)
2365 return -ENOENT;
2366 } 2356 }
2367 2357
2368 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla); 2358 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
@@ -2494,6 +2484,9 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
2494 goto nla_put_failure; 2484 goto nla_put_failure;
2495 } 2485 }
2496 2486
2487 if (nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata))
2488 goto nla_put_failure;
2489
2497 desc = nla_nest_start(skb, NFTA_SET_DESC); 2490 desc = nla_nest_start(skb, NFTA_SET_DESC);
2498 if (desc == NULL) 2491 if (desc == NULL)
2499 goto nla_put_failure; 2492 goto nla_put_failure;
@@ -2613,11 +2606,10 @@ static int nf_tables_dump_sets_done(struct netlink_callback *cb)
2613 return 0; 2606 return 0;
2614} 2607}
2615 2608
2616static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb, 2609static int nf_tables_getset(struct net *net, struct sock *nlsk,
2617 const struct nlmsghdr *nlh, 2610 struct sk_buff *skb, const struct nlmsghdr *nlh,
2618 const struct nlattr * const nla[]) 2611 const struct nlattr * const nla[])
2619{ 2612{
2620 struct net *net = sock_net(skb->sk);
2621 const struct nft_set *set; 2613 const struct nft_set *set;
2622 struct nft_ctx ctx; 2614 struct nft_ctx ctx;
2623 struct sk_buff *skb2; 2615 struct sk_buff *skb2;
@@ -2704,6 +2696,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2704 u64 timeout; 2696 u64 timeout;
2705 u32 ktype, dtype, flags, policy, gc_int; 2697 u32 ktype, dtype, flags, policy, gc_int;
2706 struct nft_set_desc desc; 2698 struct nft_set_desc desc;
2699 unsigned char *udata;
2700 u16 udlen;
2707 int err; 2701 int err;
2708 2702
2709 if (nla[NFTA_SET_TABLE] == NULL || 2703 if (nla[NFTA_SET_TABLE] == NULL ||
@@ -2816,12 +2810,16 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2816 if (IS_ERR(ops)) 2810 if (IS_ERR(ops))
2817 return PTR_ERR(ops); 2811 return PTR_ERR(ops);
2818 2812
2813 udlen = 0;
2814 if (nla[NFTA_SET_USERDATA])
2815 udlen = nla_len(nla[NFTA_SET_USERDATA]);
2816
2819 size = 0; 2817 size = 0;
2820 if (ops->privsize != NULL) 2818 if (ops->privsize != NULL)
2821 size = ops->privsize(nla); 2819 size = ops->privsize(nla);
2822 2820
2823 err = -ENOMEM; 2821 err = -ENOMEM;
2824 set = kzalloc(sizeof(*set) + size, GFP_KERNEL); 2822 set = kzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
2825 if (set == NULL) 2823 if (set == NULL)
2826 goto err1; 2824 goto err1;
2827 2825
@@ -2830,6 +2828,12 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2830 if (err < 0) 2828 if (err < 0)
2831 goto err2; 2829 goto err2;
2832 2830
2831 udata = NULL;
2832 if (udlen) {
2833 udata = set->data + size;
2834 nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
2835 }
2836
2833 INIT_LIST_HEAD(&set->bindings); 2837 INIT_LIST_HEAD(&set->bindings);
2834 write_pnet(&set->pnet, net); 2838 write_pnet(&set->pnet, net);
2835 set->ops = ops; 2839 set->ops = ops;
@@ -2840,6 +2844,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
2840 set->flags = flags; 2844 set->flags = flags;
2841 set->size = desc.size; 2845 set->size = desc.size;
2842 set->policy = policy; 2846 set->policy = policy;
2847 set->udlen = udlen;
2848 set->udata = udata;
2843 set->timeout = timeout; 2849 set->timeout = timeout;
2844 set->gc_int = gc_int; 2850 set->gc_int = gc_int;
2845 2851
@@ -2897,8 +2903,6 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,
2897 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); 2903 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2898 if (IS_ERR(set)) 2904 if (IS_ERR(set))
2899 return PTR_ERR(set); 2905 return PTR_ERR(set);
2900 if (set->flags & NFT_SET_INACTIVE)
2901 return -ENOENT;
2902 if (!list_empty(&set->bindings)) 2906 if (!list_empty(&set->bindings))
2903 return -EBUSY; 2907 return -EBUSY;
2904 2908
@@ -3021,8 +3025,7 @@ static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX +
3021static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net, 3025static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
3022 const struct sk_buff *skb, 3026 const struct sk_buff *skb,
3023 const struct nlmsghdr *nlh, 3027 const struct nlmsghdr *nlh,
3024 const struct nlattr * const nla[], 3028 const struct nlattr * const nla[])
3025 bool trans)
3026{ 3029{
3027 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 3030 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
3028 struct nft_af_info *afi; 3031 struct nft_af_info *afi;
@@ -3035,8 +3038,6 @@ static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
3035 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]); 3038 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE]);
3036 if (IS_ERR(table)) 3039 if (IS_ERR(table))
3037 return PTR_ERR(table); 3040 return PTR_ERR(table);
3038 if (!trans && (table->flags & NFT_TABLE_INACTIVE))
3039 return -ENOENT;
3040 3041
3041 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla); 3042 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
3042 return 0; 3043 return 0;
@@ -3145,9 +3146,11 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3145 return err; 3146 return err;
3146 3147
3147 err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh, 3148 err = nft_ctx_init_from_elemattr(&ctx, net, cb->skb, cb->nlh,
3148 (void *)nla, false); 3149 (void *)nla);
3149 if (err < 0) 3150 if (err < 0)
3150 return err; 3151 return err;
3152 if (ctx.table->flags & NFT_TABLE_INACTIVE)
3153 return -ENOENT;
3151 3154
3152 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3155 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3153 if (IS_ERR(set)) 3156 if (IS_ERR(set))
@@ -3202,18 +3205,19 @@ nla_put_failure:
3202 return -ENOSPC; 3205 return -ENOSPC;
3203} 3206}
3204 3207
3205static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb, 3208static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
3206 const struct nlmsghdr *nlh, 3209 struct sk_buff *skb, const struct nlmsghdr *nlh,
3207 const struct nlattr * const nla[]) 3210 const struct nlattr * const nla[])
3208{ 3211{
3209 struct net *net = sock_net(skb->sk);
3210 const struct nft_set *set; 3212 const struct nft_set *set;
3211 struct nft_ctx ctx; 3213 struct nft_ctx ctx;
3212 int err; 3214 int err;
3213 3215
3214 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false); 3216 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla);
3215 if (err < 0) 3217 if (err < 0)
3216 return err; 3218 return err;
3219 if (ctx.table->flags & NFT_TABLE_INACTIVE)
3220 return -ENOENT;
3217 3221
3218 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]); 3222 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET]);
3219 if (IS_ERR(set)) 3223 if (IS_ERR(set))
@@ -3535,7 +3539,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
3535 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) 3539 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3536 return -EINVAL; 3540 return -EINVAL;
3537 3541
3538 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, true); 3542 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla);
3539 if (err < 0) 3543 if (err < 0)
3540 return err; 3544 return err;
3541 3545
@@ -3629,7 +3633,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
3629 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) 3633 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
3630 return -EINVAL; 3634 return -EINVAL;
3631 3635
3632 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, false); 3636 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla);
3633 if (err < 0) 3637 if (err < 0)
3634 return err; 3638 return err;
3635 3639
@@ -3733,11 +3737,10 @@ err:
3733 return err; 3737 return err;
3734} 3738}
3735 3739
3736static int nf_tables_getgen(struct sock *nlsk, struct sk_buff *skb, 3740static int nf_tables_getgen(struct net *net, struct sock *nlsk,
3737 const struct nlmsghdr *nlh, 3741 struct sk_buff *skb, const struct nlmsghdr *nlh,
3738 const struct nlattr * const nla[]) 3742 const struct nlattr * const nla[])
3739{ 3743{
3740 struct net *net = sock_net(skb->sk);
3741 struct sk_buff *skb2; 3744 struct sk_buff *skb2;
3742 int err; 3745 int err;
3743 3746
@@ -3881,9 +3884,8 @@ static void nf_tables_commit_release(struct nft_trans *trans)
3881 kfree(trans); 3884 kfree(trans);
3882} 3885}
3883 3886
3884static int nf_tables_commit(struct sk_buff *skb) 3887static int nf_tables_commit(struct net *net, struct sk_buff *skb)
3885{ 3888{
3886 struct net *net = sock_net(skb->sk);
3887 struct nft_trans *trans, *next; 3889 struct nft_trans *trans, *next;
3888 struct nft_trans_elem *te; 3890 struct nft_trans_elem *te;
3889 3891
@@ -4018,9 +4020,8 @@ static void nf_tables_abort_release(struct nft_trans *trans)
4018 kfree(trans); 4020 kfree(trans);
4019} 4021}
4020 4022
4021static int nf_tables_abort(struct sk_buff *skb) 4023static int nf_tables_abort(struct net *net, struct sk_buff *skb)
4022{ 4024{
4023 struct net *net = sock_net(skb->sk);
4024 struct nft_trans *trans, *next; 4025 struct nft_trans *trans, *next;
4025 struct nft_trans_elem *te; 4026 struct nft_trans_elem *te;
4026 4027
@@ -4579,7 +4580,7 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
4579} 4580}
4580EXPORT_SYMBOL_GPL(nft_data_dump); 4581EXPORT_SYMBOL_GPL(nft_data_dump);
4581 4582
4582static int nf_tables_init_net(struct net *net) 4583static int __net_init nf_tables_init_net(struct net *net)
4583{ 4584{
4584 INIT_LIST_HEAD(&net->nft.af_info); 4585 INIT_LIST_HEAD(&net->nft.af_info);
4585 INIT_LIST_HEAD(&net->nft.commit_list); 4586 INIT_LIST_HEAD(&net->nft.commit_list);
@@ -4587,6 +4588,67 @@ static int nf_tables_init_net(struct net *net)
4587 return 0; 4588 return 0;
4588} 4589}
4589 4590
4591int __nft_release_basechain(struct nft_ctx *ctx)
4592{
4593 struct nft_rule *rule, *nr;
4594
4595 BUG_ON(!(ctx->chain->flags & NFT_BASE_CHAIN));
4596
4597 nf_tables_unregister_hooks(ctx->chain->table, ctx->chain,
4598 ctx->afi->nops);
4599 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
4600 list_del(&rule->list);
4601 ctx->chain->use--;
4602 nf_tables_rule_destroy(ctx, rule);
4603 }
4604 list_del(&ctx->chain->list);
4605 ctx->table->use--;
4606 nf_tables_chain_destroy(ctx->chain);
4607
4608 return 0;
4609}
4610EXPORT_SYMBOL_GPL(__nft_release_basechain);
4611
4612/* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */
4613static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
4614{
4615 struct nft_table *table, *nt;
4616 struct nft_chain *chain, *nc;
4617 struct nft_rule *rule, *nr;
4618 struct nft_set *set, *ns;
4619 struct nft_ctx ctx = {
4620 .net = net,
4621 .afi = afi,
4622 };
4623
4624 list_for_each_entry_safe(table, nt, &afi->tables, list) {
4625 list_for_each_entry(chain, &table->chains, list)
4626 nf_tables_unregister_hooks(table, chain, afi->nops);
4627 /* No packets are walking on these chains anymore. */
4628 ctx.table = table;
4629 list_for_each_entry(chain, &table->chains, list) {
4630 ctx.chain = chain;
4631 list_for_each_entry_safe(rule, nr, &chain->rules, list) {
4632 list_del(&rule->list);
4633 chain->use--;
4634 nf_tables_rule_destroy(&ctx, rule);
4635 }
4636 }
4637 list_for_each_entry_safe(set, ns, &table->sets, list) {
4638 list_del(&set->list);
4639 table->use--;
4640 nft_set_destroy(set);
4641 }
4642 list_for_each_entry_safe(chain, nc, &table->chains, list) {
4643 list_del(&chain->list);
4644 table->use--;
4645 nf_tables_chain_destroy(chain);
4646 }
4647 list_del(&table->list);
4648 nf_tables_table_destroy(&ctx);
4649 }
4650}
4651
4590static struct pernet_operations nf_tables_net_ops = { 4652static struct pernet_operations nf_tables_net_ops = {
4591 .init = nf_tables_init_net, 4653 .init = nf_tables_init_net,
4592}; 4654};
diff --git a/net/netfilter/nf_tables_inet.c b/net/netfilter/nf_tables_inet.c
index 9dd2d216cfc1..6b5f76295d3d 100644
--- a/net/netfilter/nf_tables_inet.c
+++ b/net/netfilter/nf_tables_inet.c
@@ -57,7 +57,7 @@ err:
57 57
58static void __net_exit nf_tables_inet_exit_net(struct net *net) 58static void __net_exit nf_tables_inet_exit_net(struct net *net)
59{ 59{
60 nft_unregister_afinfo(net->nft.inet); 60 nft_unregister_afinfo(net, net->nft.inet);
61 kfree(net->nft.inet); 61 kfree(net->nft.inet);
62} 62}
63 63
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c
index edb3502f2016..b6605e000801 100644
--- a/net/netfilter/nf_tables_netdev.c
+++ b/net/netfilter/nf_tables_netdev.c
@@ -139,7 +139,7 @@ err:
139 139
140static void nf_tables_netdev_exit_net(struct net *net) 140static void nf_tables_netdev_exit_net(struct net *net)
141{ 141{
142 nft_unregister_afinfo(net->nft.netdev); 142 nft_unregister_afinfo(net, net->nft.netdev);
143 kfree(net->nft.netdev); 143 kfree(net->nft.netdev);
144} 144}
145 145
@@ -156,35 +156,17 @@ static const struct nf_chain_type nft_filter_chain_netdev = {
156 .hook_mask = (1 << NF_NETDEV_INGRESS), 156 .hook_mask = (1 << NF_NETDEV_INGRESS),
157}; 157};
158 158
159static void nft_netdev_event(unsigned long event, struct nft_af_info *afi, 159static void nft_netdev_event(unsigned long event, struct net_device *dev,
160 struct net_device *dev, struct nft_table *table, 160 struct nft_ctx *ctx)
161 struct nft_base_chain *basechain)
162{ 161{
163 switch (event) { 162 struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
164 case NETDEV_REGISTER:
165 if (strcmp(basechain->dev_name, dev->name) != 0)
166 return;
167 163
168 BUG_ON(!(basechain->flags & NFT_BASECHAIN_DISABLED)); 164 switch (event) {
169
170 dev_hold(dev);
171 basechain->ops[0].dev = dev;
172 basechain->flags &= ~NFT_BASECHAIN_DISABLED;
173 if (!(table->flags & NFT_TABLE_F_DORMANT))
174 nft_register_basechain(basechain, afi->nops);
175 break;
176 case NETDEV_UNREGISTER: 165 case NETDEV_UNREGISTER:
177 if (strcmp(basechain->dev_name, dev->name) != 0) 166 if (strcmp(basechain->dev_name, dev->name) != 0)
178 return; 167 return;
179 168
180 BUG_ON(basechain->flags & NFT_BASECHAIN_DISABLED); 169 __nft_release_basechain(ctx);
181
182 if (!(table->flags & NFT_TABLE_F_DORMANT))
183 nft_unregister_basechain(basechain, afi->nops);
184
185 dev_put(basechain->ops[0].dev);
186 basechain->ops[0].dev = NULL;
187 basechain->flags |= NFT_BASECHAIN_DISABLED;
188 break; 170 break;
189 case NETDEV_CHANGENAME: 171 case NETDEV_CHANGENAME:
190 if (dev->ifindex != basechain->ops[0].dev->ifindex) 172 if (dev->ifindex != basechain->ops[0].dev->ifindex)
@@ -201,20 +183,29 @@ static int nf_tables_netdev_event(struct notifier_block *this,
201 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 183 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
202 struct nft_af_info *afi; 184 struct nft_af_info *afi;
203 struct nft_table *table; 185 struct nft_table *table;
204 struct nft_chain *chain; 186 struct nft_chain *chain, *nr;
187 struct nft_ctx ctx = {
188 .net = dev_net(dev),
189 };
190
191 if (event != NETDEV_UNREGISTER &&
192 event != NETDEV_CHANGENAME)
193 return NOTIFY_DONE;
205 194
206 nfnl_lock(NFNL_SUBSYS_NFTABLES); 195 nfnl_lock(NFNL_SUBSYS_NFTABLES);
207 list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) { 196 list_for_each_entry(afi, &dev_net(dev)->nft.af_info, list) {
197 ctx.afi = afi;
208 if (afi->family != NFPROTO_NETDEV) 198 if (afi->family != NFPROTO_NETDEV)
209 continue; 199 continue;
210 200
211 list_for_each_entry(table, &afi->tables, list) { 201 list_for_each_entry(table, &afi->tables, list) {
212 list_for_each_entry(chain, &table->chains, list) { 202 ctx.table = table;
203 list_for_each_entry_safe(chain, nr, &table->chains, list) {
213 if (!(chain->flags & NFT_BASE_CHAIN)) 204 if (!(chain->flags & NFT_BASE_CHAIN))
214 continue; 205 continue;
215 206
216 nft_netdev_event(event, afi, dev, table, 207 ctx.chain = chain;
217 nft_base_chain(chain)); 208 nft_netdev_event(event, dev, &ctx);
218 } 209 }
219 } 210 }
220 } 211 }
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 9ed453465167..a7ba23353dab 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -206,7 +206,7 @@ replay:
206 } 206 }
207 207
208 if (nc->call_rcu) { 208 if (nc->call_rcu) {
209 err = nc->call_rcu(net->nfnl, skb, nlh, 209 err = nc->call_rcu(net, net->nfnl, skb, nlh,
210 (const struct nlattr **)cda); 210 (const struct nlattr **)cda);
211 rcu_read_unlock(); 211 rcu_read_unlock();
212 } else { 212 } else {
@@ -216,8 +216,8 @@ replay:
216 nfnetlink_find_client(type, ss) != nc) 216 nfnetlink_find_client(type, ss) != nc)
217 err = -EAGAIN; 217 err = -EAGAIN;
218 else if (nc->call) 218 else if (nc->call)
219 err = nc->call(net->nfnl, skb, nlh, 219 err = nc->call(net, net->nfnl, skb, nlh,
220 (const struct nlattr **)cda); 220 (const struct nlattr **)cda);
221 else 221 else
222 err = -EINVAL; 222 err = -EINVAL;
223 nfnl_unlock(subsys_id); 223 nfnl_unlock(subsys_id);
@@ -425,15 +425,15 @@ next:
425 } 425 }
426done: 426done:
427 if (status & NFNL_BATCH_REPLAY) { 427 if (status & NFNL_BATCH_REPLAY) {
428 ss->abort(oskb); 428 ss->abort(net, oskb);
429 nfnl_err_reset(&err_list); 429 nfnl_err_reset(&err_list);
430 nfnl_unlock(subsys_id); 430 nfnl_unlock(subsys_id);
431 kfree_skb(skb); 431 kfree_skb(skb);
432 goto replay; 432 goto replay;
433 } else if (status == NFNL_BATCH_DONE) { 433 } else if (status == NFNL_BATCH_DONE) {
434 ss->commit(oskb); 434 ss->commit(net, oskb);
435 } else { 435 } else {
436 ss->abort(oskb); 436 ss->abort(net, oskb);
437 } 437 }
438 438
439 nfnl_err_deliver(&err_list, oskb); 439 nfnl_err_deliver(&err_list, oskb);
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
index fefbf5f0b28d..5274b04c42a6 100644
--- a/net/netfilter/nfnetlink_acct.c
+++ b/net/netfilter/nfnetlink_acct.c
@@ -46,12 +46,11 @@ struct nfacct_filter {
46#define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES) 46#define NFACCT_F_QUOTA (NFACCT_F_QUOTA_PKTS | NFACCT_F_QUOTA_BYTES)
47#define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */ 47#define NFACCT_OVERQUOTA_BIT 2 /* NFACCT_F_OVERQUOTA */
48 48
49static int 49static int nfnl_acct_new(struct net *net, struct sock *nfnl,
50nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, 50 struct sk_buff *skb, const struct nlmsghdr *nlh,
51 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 51 const struct nlattr * const tb[])
52{ 52{
53 struct nf_acct *nfacct, *matching = NULL; 53 struct nf_acct *nfacct, *matching = NULL;
54 struct net *net = sock_net(nfnl);
55 char *acct_name; 54 char *acct_name;
56 unsigned int size = 0; 55 unsigned int size = 0;
57 u32 flags = 0; 56 u32 flags = 0;
@@ -253,11 +252,10 @@ nfacct_filter_alloc(const struct nlattr * const attr)
253 return filter; 252 return filter;
254} 253}
255 254
256static int 255static int nfnl_acct_get(struct net *net, struct sock *nfnl,
257nfnl_acct_get(struct sock *nfnl, struct sk_buff *skb, 256 struct sk_buff *skb, const struct nlmsghdr *nlh,
258 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 257 const struct nlattr * const tb[])
259{ 258{
260 struct net *net = sock_net(nfnl);
261 int ret = -ENOENT; 259 int ret = -ENOENT;
262 struct nf_acct *cur; 260 struct nf_acct *cur;
263 char *acct_name; 261 char *acct_name;
@@ -333,11 +331,10 @@ static int nfnl_acct_try_del(struct nf_acct *cur)
333 return ret; 331 return ret;
334} 332}
335 333
336static int 334static int nfnl_acct_del(struct net *net, struct sock *nfnl,
337nfnl_acct_del(struct sock *nfnl, struct sk_buff *skb, 335 struct sk_buff *skb, const struct nlmsghdr *nlh,
338 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 336 const struct nlattr * const tb[])
339{ 337{
340 struct net *net = sock_net(nfnl);
341 char *acct_name; 338 char *acct_name;
342 struct nf_acct *cur; 339 struct nf_acct *cur;
343 int ret = -ENOENT; 340 int ret = -ENOENT;
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index 54330fb5efaf..e924e95fcc7f 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -286,9 +286,9 @@ nfnl_cthelper_update(const struct nlattr * const tb[],
286 return 0; 286 return 0;
287} 287}
288 288
289static int 289static int nfnl_cthelper_new(struct net *net, struct sock *nfnl,
290nfnl_cthelper_new(struct sock *nfnl, struct sk_buff *skb, 290 struct sk_buff *skb, const struct nlmsghdr *nlh,
291 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 291 const struct nlattr * const tb[])
292{ 292{
293 const char *helper_name; 293 const char *helper_name;
294 struct nf_conntrack_helper *cur, *helper = NULL; 294 struct nf_conntrack_helper *cur, *helper = NULL;
@@ -498,9 +498,9 @@ out:
498 return skb->len; 498 return skb->len;
499} 499}
500 500
501static int 501static int nfnl_cthelper_get(struct net *net, struct sock *nfnl,
502nfnl_cthelper_get(struct sock *nfnl, struct sk_buff *skb, 502 struct sk_buff *skb, const struct nlmsghdr *nlh,
503 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 503 const struct nlattr * const tb[])
504{ 504{
505 int ret = -ENOENT, i; 505 int ret = -ENOENT, i;
506 struct nf_conntrack_helper *cur; 506 struct nf_conntrack_helper *cur;
@@ -570,9 +570,9 @@ nfnl_cthelper_get(struct sock *nfnl, struct sk_buff *skb,
570 return ret; 570 return ret;
571} 571}
572 572
573static int 573static int nfnl_cthelper_del(struct net *net, struct sock *nfnl,
574nfnl_cthelper_del(struct sock *nfnl, struct sk_buff *skb, 574 struct sk_buff *skb, const struct nlmsghdr *nlh,
575 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 575 const struct nlattr * const tb[])
576{ 576{
577 char *helper_name = NULL; 577 char *helper_name = NULL;
578 struct nf_conntrack_helper *cur; 578 struct nf_conntrack_helper *cur;
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 3921d544f5ba..5d010f27ac01 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -65,16 +65,15 @@ ctnl_timeout_parse_policy(void *timeouts, struct nf_conntrack_l4proto *l4proto,
65 return ret; 65 return ret;
66} 66}
67 67
68static int 68static int cttimeout_new_timeout(struct net *net, struct sock *ctnl,
69cttimeout_new_timeout(struct sock *ctnl, struct sk_buff *skb, 69 struct sk_buff *skb,
70 const struct nlmsghdr *nlh, 70 const struct nlmsghdr *nlh,
71 const struct nlattr * const cda[]) 71 const struct nlattr * const cda[])
72{ 72{
73 __u16 l3num; 73 __u16 l3num;
74 __u8 l4num; 74 __u8 l4num;
75 struct nf_conntrack_l4proto *l4proto; 75 struct nf_conntrack_l4proto *l4proto;
76 struct ctnl_timeout *timeout, *matching = NULL; 76 struct ctnl_timeout *timeout, *matching = NULL;
77 struct net *net = sock_net(skb->sk);
78 char *name; 77 char *name;
79 int ret; 78 int ret;
80 79
@@ -239,12 +238,11 @@ ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb)
239 return skb->len; 238 return skb->len;
240} 239}
241 240
242static int 241static int cttimeout_get_timeout(struct net *net, struct sock *ctnl,
243cttimeout_get_timeout(struct sock *ctnl, struct sk_buff *skb, 242 struct sk_buff *skb,
244 const struct nlmsghdr *nlh, 243 const struct nlmsghdr *nlh,
245 const struct nlattr * const cda[]) 244 const struct nlattr * const cda[])
246{ 245{
247 struct net *net = sock_net(skb->sk);
248 int ret = -ENOENT; 246 int ret = -ENOENT;
249 char *name; 247 char *name;
250 struct ctnl_timeout *cur; 248 struct ctnl_timeout *cur;
@@ -339,15 +337,14 @@ static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout)
339 return ret; 337 return ret;
340} 338}
341 339
342static int 340static int cttimeout_del_timeout(struct net *net, struct sock *ctnl,
343cttimeout_del_timeout(struct sock *ctnl, struct sk_buff *skb, 341 struct sk_buff *skb,
344 const struct nlmsghdr *nlh, 342 const struct nlmsghdr *nlh,
345 const struct nlattr * const cda[]) 343 const struct nlattr * const cda[])
346{ 344{
347 struct net *net = sock_net(skb->sk);
348 char *name;
349 struct ctnl_timeout *cur; 345 struct ctnl_timeout *cur;
350 int ret = -ENOENT; 346 int ret = -ENOENT;
347 char *name;
351 348
352 if (!cda[CTA_TIMEOUT_NAME]) { 349 if (!cda[CTA_TIMEOUT_NAME]) {
353 list_for_each_entry(cur, &net->nfct_timeout_list, head) 350 list_for_each_entry(cur, &net->nfct_timeout_list, head)
@@ -370,15 +367,14 @@ cttimeout_del_timeout(struct sock *ctnl, struct sk_buff *skb,
370 return ret; 367 return ret;
371} 368}
372 369
373static int 370static int cttimeout_default_set(struct net *net, struct sock *ctnl,
374cttimeout_default_set(struct sock *ctnl, struct sk_buff *skb, 371 struct sk_buff *skb,
375 const struct nlmsghdr *nlh, 372 const struct nlmsghdr *nlh,
376 const struct nlattr * const cda[]) 373 const struct nlattr * const cda[])
377{ 374{
378 __u16 l3num; 375 __u16 l3num;
379 __u8 l4num; 376 __u8 l4num;
380 struct nf_conntrack_l4proto *l4proto; 377 struct nf_conntrack_l4proto *l4proto;
381 struct net *net = sock_net(skb->sk);
382 unsigned int *timeouts; 378 unsigned int *timeouts;
383 int ret; 379 int ret;
384 380
@@ -460,14 +456,14 @@ nla_put_failure:
460 return -1; 456 return -1;
461} 457}
462 458
463static int cttimeout_default_get(struct sock *ctnl, struct sk_buff *skb, 459static int cttimeout_default_get(struct net *net, struct sock *ctnl,
460 struct sk_buff *skb,
464 const struct nlmsghdr *nlh, 461 const struct nlmsghdr *nlh,
465 const struct nlattr * const cda[]) 462 const struct nlattr * const cda[])
466{ 463{
467 __u16 l3num; 464 __u16 l3num;
468 __u8 l4num; 465 __u8 l4num;
469 struct nf_conntrack_l4proto *l4proto; 466 struct nf_conntrack_l4proto *l4proto;
470 struct net *net = sock_net(skb->sk);
471 struct sk_buff *skb2; 467 struct sk_buff *skb2;
472 int ret, err; 468 int ret, err;
473 469
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 70b6bd3b781e..8ca932057c13 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -785,10 +785,9 @@ static struct notifier_block nfulnl_rtnl_notifier = {
785 .notifier_call = nfulnl_rcv_nl_event, 785 .notifier_call = nfulnl_rcv_nl_event,
786}; 786};
787 787
788static int 788static int nfulnl_recv_unsupp(struct net *net, struct sock *ctnl,
789nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb, 789 struct sk_buff *skb, const struct nlmsghdr *nlh,
790 const struct nlmsghdr *nlh, 790 const struct nlattr * const nfqa[])
791 const struct nlattr * const nfqa[])
792{ 791{
793 return -ENOTSUPP; 792 return -ENOTSUPP;
794} 793}
@@ -809,16 +808,14 @@ static const struct nla_policy nfula_cfg_policy[NFULA_CFG_MAX+1] = {
809 [NFULA_CFG_FLAGS] = { .type = NLA_U16 }, 808 [NFULA_CFG_FLAGS] = { .type = NLA_U16 },
810}; 809};
811 810
812static int 811static int nfulnl_recv_config(struct net *net, struct sock *ctnl,
813nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, 812 struct sk_buff *skb, const struct nlmsghdr *nlh,
814 const struct nlmsghdr *nlh, 813 const struct nlattr * const nfula[])
815 const struct nlattr * const nfula[])
816{ 814{
817 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 815 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
818 u_int16_t group_num = ntohs(nfmsg->res_id); 816 u_int16_t group_num = ntohs(nfmsg->res_id);
819 struct nfulnl_instance *inst; 817 struct nfulnl_instance *inst;
820 struct nfulnl_msg_config_cmd *cmd = NULL; 818 struct nfulnl_msg_config_cmd *cmd = NULL;
821 struct net *net = sock_net(ctnl);
822 struct nfnl_log_net *log = nfnl_log_pernet(net); 819 struct nfnl_log_net *log = nfnl_log_pernet(net);
823 int ret = 0; 820 int ret = 0;
824 u16 flags = 0; 821 u16 flags = 0;
@@ -891,7 +888,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
891 goto out_put; 888 goto out_put;
892 default: 889 default:
893 ret = -ENOTSUPP; 890 ret = -ENOTSUPP;
894 break; 891 goto out_put;
895 } 892 }
896 } else if (!inst) { 893 } else if (!inst) {
897 ret = -ENODEV; 894 ret = -ENODEV;
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 861c6615253b..1d3936587ace 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -957,10 +957,10 @@ static int nfq_id_after(unsigned int id, unsigned int max)
957 return (int)(id - max) > 0; 957 return (int)(id - max) > 0;
958} 958}
959 959
960static int 960static int nfqnl_recv_verdict_batch(struct net *net, struct sock *ctnl,
961nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb, 961 struct sk_buff *skb,
962 const struct nlmsghdr *nlh, 962 const struct nlmsghdr *nlh,
963 const struct nlattr * const nfqa[]) 963 const struct nlattr * const nfqa[])
964{ 964{
965 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 965 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
966 struct nf_queue_entry *entry, *tmp; 966 struct nf_queue_entry *entry, *tmp;
@@ -969,8 +969,6 @@ nfqnl_recv_verdict_batch(struct sock *ctnl, struct sk_buff *skb,
969 struct nfqnl_instance *queue; 969 struct nfqnl_instance *queue;
970 LIST_HEAD(batch_list); 970 LIST_HEAD(batch_list);
971 u16 queue_num = ntohs(nfmsg->res_id); 971 u16 queue_num = ntohs(nfmsg->res_id);
972
973 struct net *net = sock_net(ctnl);
974 struct nfnl_queue_net *q = nfnl_queue_pernet(net); 972 struct nfnl_queue_net *q = nfnl_queue_pernet(net);
975 973
976 queue = verdict_instance_lookup(q, queue_num, 974 queue = verdict_instance_lookup(q, queue_num,
@@ -1029,14 +1027,13 @@ static struct nf_conn *nfqnl_ct_parse(struct nfnl_ct_hook *nfnl_ct,
1029 return ct; 1027 return ct;
1030} 1028}
1031 1029
1032static int 1030static int nfqnl_recv_verdict(struct net *net, struct sock *ctnl,
1033nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, 1031 struct sk_buff *skb,
1034 const struct nlmsghdr *nlh, 1032 const struct nlmsghdr *nlh,
1035 const struct nlattr * const nfqa[]) 1033 const struct nlattr * const nfqa[])
1036{ 1034{
1037 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1035 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1038 u_int16_t queue_num = ntohs(nfmsg->res_id); 1036 u_int16_t queue_num = ntohs(nfmsg->res_id);
1039
1040 struct nfqnl_msg_verdict_hdr *vhdr; 1037 struct nfqnl_msg_verdict_hdr *vhdr;
1041 struct nfqnl_instance *queue; 1038 struct nfqnl_instance *queue;
1042 unsigned int verdict; 1039 unsigned int verdict;
@@ -1044,8 +1041,6 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
1044 enum ip_conntrack_info uninitialized_var(ctinfo); 1041 enum ip_conntrack_info uninitialized_var(ctinfo);
1045 struct nfnl_ct_hook *nfnl_ct; 1042 struct nfnl_ct_hook *nfnl_ct;
1046 struct nf_conn *ct = NULL; 1043 struct nf_conn *ct = NULL;
1047
1048 struct net *net = sock_net(ctnl);
1049 struct nfnl_queue_net *q = nfnl_queue_pernet(net); 1044 struct nfnl_queue_net *q = nfnl_queue_pernet(net);
1050 1045
1051 queue = instance_lookup(q, queue_num); 1046 queue = instance_lookup(q, queue_num);
@@ -1092,10 +1087,9 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
1092 return 0; 1087 return 0;
1093} 1088}
1094 1089
1095static int 1090static int nfqnl_recv_unsupp(struct net *net, struct sock *ctnl,
1096nfqnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb, 1091 struct sk_buff *skb, const struct nlmsghdr *nlh,
1097 const struct nlmsghdr *nlh, 1092 const struct nlattr * const nfqa[])
1098 const struct nlattr * const nfqa[])
1099{ 1093{
1100 return -ENOTSUPP; 1094 return -ENOTSUPP;
1101} 1095}
@@ -1110,17 +1104,16 @@ static const struct nf_queue_handler nfqh = {
1110 .nf_hook_drop = &nfqnl_nf_hook_drop, 1104 .nf_hook_drop = &nfqnl_nf_hook_drop,
1111}; 1105};
1112 1106
1113static int 1107static int nfqnl_recv_config(struct net *net, struct sock *ctnl,
1114nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, 1108 struct sk_buff *skb, const struct nlmsghdr *nlh,
1115 const struct nlmsghdr *nlh, 1109 const struct nlattr * const nfqa[])
1116 const struct nlattr * const nfqa[])
1117{ 1110{
1118 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1111 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1119 u_int16_t queue_num = ntohs(nfmsg->res_id); 1112 u_int16_t queue_num = ntohs(nfmsg->res_id);
1120 struct nfqnl_instance *queue; 1113 struct nfqnl_instance *queue;
1121 struct nfqnl_msg_config_cmd *cmd = NULL; 1114 struct nfqnl_msg_config_cmd *cmd = NULL;
1122 struct net *net = sock_net(ctnl);
1123 struct nfnl_queue_net *q = nfnl_queue_pernet(net); 1115 struct nfnl_queue_net *q = nfnl_queue_pernet(net);
1116 __u32 flags = 0, mask = 0;
1124 int ret = 0; 1117 int ret = 0;
1125 1118
1126 if (nfqa[NFQA_CFG_CMD]) { 1119 if (nfqa[NFQA_CFG_CMD]) {
@@ -1133,6 +1126,40 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
1133 } 1126 }
1134 } 1127 }
1135 1128
1129 /* Check if we support these flags in first place, dependencies should
1130 * be there too not to break atomicity.
1131 */
1132 if (nfqa[NFQA_CFG_FLAGS]) {
1133 if (!nfqa[NFQA_CFG_MASK]) {
1134 /* A mask is needed to specify which flags are being
1135 * changed.
1136 */
1137 return -EINVAL;
1138 }
1139
1140 flags = ntohl(nla_get_be32(nfqa[NFQA_CFG_FLAGS]));
1141 mask = ntohl(nla_get_be32(nfqa[NFQA_CFG_MASK]));
1142
1143 if (flags >= NFQA_CFG_F_MAX)
1144 return -EOPNOTSUPP;
1145
1146#if !IS_ENABLED(CONFIG_NETWORK_SECMARK)
1147 if (flags & mask & NFQA_CFG_F_SECCTX)
1148 return -EOPNOTSUPP;
1149#endif
1150 if ((flags & mask & NFQA_CFG_F_CONNTRACK) &&
1151 !rcu_access_pointer(nfnl_ct_hook)) {
1152#ifdef CONFIG_MODULES
1153 nfnl_unlock(NFNL_SUBSYS_QUEUE);
1154 request_module("ip_conntrack_netlink");
1155 nfnl_lock(NFNL_SUBSYS_QUEUE);
1156 if (rcu_access_pointer(nfnl_ct_hook))
1157 return -EAGAIN;
1158#endif
1159 return -EOPNOTSUPP;
1160 }
1161 }
1162
1136 rcu_read_lock(); 1163 rcu_read_lock();
1137 queue = instance_lookup(q, queue_num); 1164 queue = instance_lookup(q, queue_num);
1138 if (queue && queue->peer_portid != NETLINK_CB(skb).portid) { 1165 if (queue && queue->peer_portid != NETLINK_CB(skb).portid) {
@@ -1160,70 +1187,38 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
1160 goto err_out_unlock; 1187 goto err_out_unlock;
1161 } 1188 }
1162 instance_destroy(q, queue); 1189 instance_destroy(q, queue);
1163 break; 1190 goto err_out_unlock;
1164 case NFQNL_CFG_CMD_PF_BIND: 1191 case NFQNL_CFG_CMD_PF_BIND:
1165 case NFQNL_CFG_CMD_PF_UNBIND: 1192 case NFQNL_CFG_CMD_PF_UNBIND:
1166 break; 1193 break;
1167 default: 1194 default:
1168 ret = -ENOTSUPP; 1195 ret = -ENOTSUPP;
1169 break; 1196 goto err_out_unlock;
1170 } 1197 }
1171 } 1198 }
1172 1199
1200 if (!queue) {
1201 ret = -ENODEV;
1202 goto err_out_unlock;
1203 }
1204
1173 if (nfqa[NFQA_CFG_PARAMS]) { 1205 if (nfqa[NFQA_CFG_PARAMS]) {
1174 struct nfqnl_msg_config_params *params; 1206 struct nfqnl_msg_config_params *params =
1207 nla_data(nfqa[NFQA_CFG_PARAMS]);
1175 1208
1176 if (!queue) {
1177 ret = -ENODEV;
1178 goto err_out_unlock;
1179 }
1180 params = nla_data(nfqa[NFQA_CFG_PARAMS]);
1181 nfqnl_set_mode(queue, params->copy_mode, 1209 nfqnl_set_mode(queue, params->copy_mode,
1182 ntohl(params->copy_range)); 1210 ntohl(params->copy_range));
1183 } 1211 }
1184 1212
1185 if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) { 1213 if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) {
1186 __be32 *queue_maxlen; 1214 __be32 *queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]);
1187 1215
1188 if (!queue) {
1189 ret = -ENODEV;
1190 goto err_out_unlock;
1191 }
1192 queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]);
1193 spin_lock_bh(&queue->lock); 1216 spin_lock_bh(&queue->lock);
1194 queue->queue_maxlen = ntohl(*queue_maxlen); 1217 queue->queue_maxlen = ntohl(*queue_maxlen);
1195 spin_unlock_bh(&queue->lock); 1218 spin_unlock_bh(&queue->lock);
1196 } 1219 }
1197 1220
1198 if (nfqa[NFQA_CFG_FLAGS]) { 1221 if (nfqa[NFQA_CFG_FLAGS]) {
1199 __u32 flags, mask;
1200
1201 if (!queue) {
1202 ret = -ENODEV;
1203 goto err_out_unlock;
1204 }
1205
1206 if (!nfqa[NFQA_CFG_MASK]) {
1207 /* A mask is needed to specify which flags are being
1208 * changed.
1209 */
1210 ret = -EINVAL;
1211 goto err_out_unlock;
1212 }
1213
1214 flags = ntohl(nla_get_be32(nfqa[NFQA_CFG_FLAGS]));
1215 mask = ntohl(nla_get_be32(nfqa[NFQA_CFG_MASK]));
1216
1217 if (flags >= NFQA_CFG_F_MAX) {
1218 ret = -EOPNOTSUPP;
1219 goto err_out_unlock;
1220 }
1221#if !IS_ENABLED(CONFIG_NETWORK_SECMARK)
1222 if (flags & mask & NFQA_CFG_F_SECCTX) {
1223 ret = -EOPNOTSUPP;
1224 goto err_out_unlock;
1225 }
1226#endif
1227 spin_lock_bh(&queue->lock); 1222 spin_lock_bh(&queue->lock);
1228 queue->flags &= ~mask; 1223 queue->flags &= ~mask;
1229 queue->flags |= flags & mask; 1224 queue->flags |= flags & mask;
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index fde5145f2e36..383c17138399 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -8,6 +8,7 @@
8 * Development of this code funded by Astaro AG (http://www.astaro.com/) 8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 */ 9 */
10 10
11#include <asm/unaligned.h>
11#include <linux/kernel.h> 12#include <linux/kernel.h>
12#include <linux/init.h> 13#include <linux/init.h>
13#include <linux/module.h> 14#include <linux/module.h>
@@ -39,6 +40,27 @@ static void nft_byteorder_eval(const struct nft_expr *expr,
39 d = (void *)dst; 40 d = (void *)dst;
40 41
41 switch (priv->size) { 42 switch (priv->size) {
43 case 8: {
44 u64 src64;
45
46 switch (priv->op) {
47 case NFT_BYTEORDER_NTOH:
48 for (i = 0; i < priv->len / 8; i++) {
49 src64 = get_unaligned_be64(&src[i]);
50 src64 = be64_to_cpu((__force __be64)src64);
51 put_unaligned_be64(src64, &dst[i]);
52 }
53 break;
54 case NFT_BYTEORDER_HTON:
55 for (i = 0; i < priv->len / 8; i++) {
56 src64 = get_unaligned_be64(&src[i]);
57 src64 = (__force u64)cpu_to_be64(src64);
58 put_unaligned_be64(src64, &dst[i]);
59 }
60 break;
61 }
62 break;
63 }
42 case 4: 64 case 4:
43 switch (priv->op) { 65 switch (priv->op) {
44 case NFT_BYTEORDER_NTOH: 66 case NFT_BYTEORDER_NTOH:
@@ -101,6 +123,7 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
101 switch (priv->size) { 123 switch (priv->size) {
102 case 2: 124 case 2:
103 case 4: 125 case 4:
126 case 8:
104 break; 127 break;
105 default: 128 default:
106 return -EINVAL; 129 return -EINVAL;
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 9c8fab00164b..454841baa4d0 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -519,9 +519,9 @@ nla_put_failure:
519 return -1; 519 return -1;
520} 520}
521 521
522static int 522static int nfnl_compat_get(struct net *net, struct sock *nfnl,
523nfnl_compat_get(struct sock *nfnl, struct sk_buff *skb, 523 struct sk_buff *skb, const struct nlmsghdr *nlh,
524 const struct nlmsghdr *nlh, const struct nlattr * const tb[]) 524 const struct nlattr * const tb[])
525{ 525{
526 int ret = 0, target; 526 int ret = 0, target;
527 struct nfgenmsg *nfmsg; 527 struct nfgenmsg *nfmsg;
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 939921532764..a0eb2161e3ef 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -16,6 +16,7 @@
16#include <linux/netfilter/nf_tables.h> 16#include <linux/netfilter/nf_tables.h>
17#include <net/netfilter/nf_tables.h> 17#include <net/netfilter/nf_tables.h>
18#include <net/netfilter/nf_conntrack.h> 18#include <net/netfilter/nf_conntrack.h>
19#include <net/netfilter/nf_conntrack_acct.h>
19#include <net/netfilter/nf_conntrack_tuple.h> 20#include <net/netfilter/nf_conntrack_tuple.h>
20#include <net/netfilter/nf_conntrack_helper.h> 21#include <net/netfilter/nf_conntrack_helper.h>
21#include <net/netfilter/nf_conntrack_ecache.h> 22#include <net/netfilter/nf_conntrack_ecache.h>
@@ -30,6 +31,18 @@ struct nft_ct {
30 }; 31 };
31}; 32};
32 33
34static u64 nft_ct_get_eval_counter(const struct nf_conn_counter *c,
35 enum nft_ct_keys k,
36 enum ip_conntrack_dir d)
37{
38 if (d < IP_CT_DIR_MAX)
39 return k == NFT_CT_BYTES ? atomic64_read(&c[d].bytes) :
40 atomic64_read(&c[d].packets);
41
42 return nft_ct_get_eval_counter(c, k, IP_CT_DIR_ORIGINAL) +
43 nft_ct_get_eval_counter(c, k, IP_CT_DIR_REPLY);
44}
45
33static void nft_ct_get_eval(const struct nft_expr *expr, 46static void nft_ct_get_eval(const struct nft_expr *expr,
34 struct nft_regs *regs, 47 struct nft_regs *regs,
35 const struct nft_pktinfo *pkt) 48 const struct nft_pktinfo *pkt)
@@ -114,6 +127,17 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
114 NF_CT_LABELS_MAX_SIZE - size); 127 NF_CT_LABELS_MAX_SIZE - size);
115 return; 128 return;
116 } 129 }
130 case NFT_CT_BYTES: /* fallthrough */
131 case NFT_CT_PKTS: {
132 const struct nf_conn_acct *acct = nf_conn_acct_find(ct);
133 u64 count = 0;
134
135 if (acct)
136 count = nft_ct_get_eval_counter(acct->counter,
137 priv->key, priv->dir);
138 memcpy(dest, &count, sizeof(count));
139 return;
140 }
117#endif 141#endif
118 default: 142 default:
119 break; 143 break;
@@ -291,6 +315,13 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
291 return -EINVAL; 315 return -EINVAL;
292 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all); 316 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
293 break; 317 break;
318 case NFT_CT_BYTES:
319 case NFT_CT_PKTS:
320 /* no direction? return sum of original + reply */
321 if (tb[NFTA_CT_DIRECTION] == NULL)
322 priv->dir = IP_CT_DIR_MAX;
323 len = sizeof(u64);
324 break;
294 default: 325 default:
295 return -EOPNOTSUPP; 326 return -EOPNOTSUPP;
296 } 327 }
@@ -374,6 +405,13 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
374 case NFT_CT_PROTO_DST: 405 case NFT_CT_PROTO_DST:
375 if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir)) 406 if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
376 goto nla_put_failure; 407 goto nla_put_failure;
408 break;
409 case NFT_CT_BYTES:
410 case NFT_CT_PKTS:
411 if (priv->dir < IP_CT_DIR_MAX &&
412 nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
413 goto nla_put_failure;
414 break;
377 default: 415 default:
378 break; 416 break;
379 } 417 }
diff --git a/net/netfilter/nft_dup_netdev.c b/net/netfilter/nft_dup_netdev.c
new file mode 100644
index 000000000000..2cc1e0ef56e8
--- /dev/null
+++ b/net/netfilter/nft_dup_netdev.c
@@ -0,0 +1,97 @@
1/*
2 * Copyright (c) 2015 Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/netlink.h>
13#include <linux/netfilter.h>
14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_tables.h>
16#include <net/netfilter/nf_dup_netdev.h>
17
18struct nft_dup_netdev {
19 enum nft_registers sreg_dev:8;
20};
21
22static void nft_dup_netdev_eval(const struct nft_expr *expr,
23 struct nft_regs *regs,
24 const struct nft_pktinfo *pkt)
25{
26 struct nft_dup_netdev *priv = nft_expr_priv(expr);
27 int oif = regs->data[priv->sreg_dev];
28
29 nf_dup_netdev_egress(pkt, oif);
30}
31
32static const struct nla_policy nft_dup_netdev_policy[NFTA_DUP_MAX + 1] = {
33 [NFTA_DUP_SREG_DEV] = { .type = NLA_U32 },
34};
35
36static int nft_dup_netdev_init(const struct nft_ctx *ctx,
37 const struct nft_expr *expr,
38 const struct nlattr * const tb[])
39{
40 struct nft_dup_netdev *priv = nft_expr_priv(expr);
41
42 if (tb[NFTA_DUP_SREG_DEV] == NULL)
43 return -EINVAL;
44
45 priv->sreg_dev = nft_parse_register(tb[NFTA_DUP_SREG_DEV]);
46 return nft_validate_register_load(priv->sreg_dev, sizeof(int));
47}
48
49static const struct nft_expr_ops nft_dup_netdev_ingress_ops;
50
51static int nft_dup_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
52{
53 struct nft_dup_netdev *priv = nft_expr_priv(expr);
54
55 if (nft_dump_register(skb, NFTA_DUP_SREG_DEV, priv->sreg_dev))
56 goto nla_put_failure;
57
58 return 0;
59
60nla_put_failure:
61 return -1;
62}
63
64static struct nft_expr_type nft_dup_netdev_type;
65static const struct nft_expr_ops nft_dup_netdev_ops = {
66 .type = &nft_dup_netdev_type,
67 .size = NFT_EXPR_SIZE(sizeof(struct nft_dup_netdev)),
68 .eval = nft_dup_netdev_eval,
69 .init = nft_dup_netdev_init,
70 .dump = nft_dup_netdev_dump,
71};
72
73static struct nft_expr_type nft_dup_netdev_type __read_mostly = {
74 .family = NFPROTO_NETDEV,
75 .name = "dup",
76 .ops = &nft_dup_netdev_ops,
77 .policy = nft_dup_netdev_policy,
78 .maxattr = NFTA_DUP_MAX,
79 .owner = THIS_MODULE,
80};
81
82static int __init nft_dup_netdev_module_init(void)
83{
84 return nft_register_expr(&nft_dup_netdev_type);
85}
86
87static void __exit nft_dup_netdev_module_exit(void)
88{
89 nft_unregister_expr(&nft_dup_netdev_type);
90}
91
92module_init(nft_dup_netdev_module_init);
93module_exit(nft_dup_netdev_module_exit);
94
95MODULE_LICENSE("GPL");
96MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
97MODULE_ALIAS_NFT_AF_EXPR(5, "dup");
diff --git a/net/netfilter/nft_fwd_netdev.c b/net/netfilter/nft_fwd_netdev.c
new file mode 100644
index 000000000000..763ebc3e0b2b
--- /dev/null
+++ b/net/netfilter/nft_fwd_netdev.c
@@ -0,0 +1,98 @@
1/*
2 * Copyright (c) 2015 Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 */
8
9#include <linux/kernel.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/netlink.h>
13#include <linux/netfilter.h>
14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_tables.h>
16#include <net/netfilter/nf_dup_netdev.h>
17
18struct nft_fwd_netdev {
19 enum nft_registers sreg_dev:8;
20};
21
22static void nft_fwd_netdev_eval(const struct nft_expr *expr,
23 struct nft_regs *regs,
24 const struct nft_pktinfo *pkt)
25{
26 struct nft_fwd_netdev *priv = nft_expr_priv(expr);
27 int oif = regs->data[priv->sreg_dev];
28
29 nf_dup_netdev_egress(pkt, oif);
30 regs->verdict.code = NF_DROP;
31}
32
33static const struct nla_policy nft_fwd_netdev_policy[NFTA_FWD_MAX + 1] = {
34 [NFTA_FWD_SREG_DEV] = { .type = NLA_U32 },
35};
36
37static int nft_fwd_netdev_init(const struct nft_ctx *ctx,
38 const struct nft_expr *expr,
39 const struct nlattr * const tb[])
40{
41 struct nft_fwd_netdev *priv = nft_expr_priv(expr);
42
43 if (tb[NFTA_FWD_SREG_DEV] == NULL)
44 return -EINVAL;
45
46 priv->sreg_dev = nft_parse_register(tb[NFTA_FWD_SREG_DEV]);
47 return nft_validate_register_load(priv->sreg_dev, sizeof(int));
48}
49
50static const struct nft_expr_ops nft_fwd_netdev_ingress_ops;
51
52static int nft_fwd_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr)
53{
54 struct nft_fwd_netdev *priv = nft_expr_priv(expr);
55
56 if (nft_dump_register(skb, NFTA_FWD_SREG_DEV, priv->sreg_dev))
57 goto nla_put_failure;
58
59 return 0;
60
61nla_put_failure:
62 return -1;
63}
64
65static struct nft_expr_type nft_fwd_netdev_type;
66static const struct nft_expr_ops nft_fwd_netdev_ops = {
67 .type = &nft_fwd_netdev_type,
68 .size = NFT_EXPR_SIZE(sizeof(struct nft_fwd_netdev)),
69 .eval = nft_fwd_netdev_eval,
70 .init = nft_fwd_netdev_init,
71 .dump = nft_fwd_netdev_dump,
72};
73
74static struct nft_expr_type nft_fwd_netdev_type __read_mostly = {
75 .family = NFPROTO_NETDEV,
76 .name = "fwd",
77 .ops = &nft_fwd_netdev_ops,
78 .policy = nft_fwd_netdev_policy,
79 .maxattr = NFTA_FWD_MAX,
80 .owner = THIS_MODULE,
81};
82
83static int __init nft_fwd_netdev_module_init(void)
84{
85 return nft_register_expr(&nft_fwd_netdev_type);
86}
87
88static void __exit nft_fwd_netdev_module_exit(void)
89{
90 nft_unregister_expr(&nft_fwd_netdev_type);
91}
92
93module_init(nft_fwd_netdev_module_init);
94module_exit(nft_fwd_netdev_module_exit);
95
96MODULE_LICENSE("GPL");
97MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
98MODULE_ALIAS_NFT_AF_EXPR(5, "fwd");
diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
index 5d67938f8b2f..99d18578afc6 100644
--- a/net/netfilter/nft_limit.c
+++ b/net/netfilter/nft_limit.c
@@ -26,6 +26,7 @@ struct nft_limit {
26 u64 rate; 26 u64 rate;
27 u64 nsecs; 27 u64 nsecs;
28 u32 burst; 28 u32 burst;
29 bool invert;
29}; 30};
30 31
31static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost) 32static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost)
@@ -44,11 +45,11 @@ static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost)
44 if (delta >= 0) { 45 if (delta >= 0) {
45 limit->tokens = delta; 46 limit->tokens = delta;
46 spin_unlock_bh(&limit_lock); 47 spin_unlock_bh(&limit_lock);
47 return false; 48 return limit->invert;
48 } 49 }
49 limit->tokens = tokens; 50 limit->tokens = tokens;
50 spin_unlock_bh(&limit_lock); 51 spin_unlock_bh(&limit_lock);
51 return true; 52 return !limit->invert;
52} 53}
53 54
54static int nft_limit_init(struct nft_limit *limit, 55static int nft_limit_init(struct nft_limit *limit,
@@ -78,6 +79,12 @@ static int nft_limit_init(struct nft_limit *limit,
78 79
79 limit->rate = rate; 80 limit->rate = rate;
80 } 81 }
82 if (tb[NFTA_LIMIT_FLAGS]) {
83 u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
84
85 if (flags & NFT_LIMIT_F_INV)
86 limit->invert = true;
87 }
81 limit->last = ktime_get_ns(); 88 limit->last = ktime_get_ns();
82 89
83 return 0; 90 return 0;
@@ -86,13 +93,15 @@ static int nft_limit_init(struct nft_limit *limit,
86static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit, 93static int nft_limit_dump(struct sk_buff *skb, const struct nft_limit *limit,
87 enum nft_limit_type type) 94 enum nft_limit_type type)
88{ 95{
96 u32 flags = limit->invert ? NFT_LIMIT_F_INV : 0;
89 u64 secs = div_u64(limit->nsecs, NSEC_PER_SEC); 97 u64 secs = div_u64(limit->nsecs, NSEC_PER_SEC);
90 u64 rate = limit->rate - limit->burst; 98 u64 rate = limit->rate - limit->burst;
91 99
92 if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(rate)) || 100 if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(rate)) ||
93 nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(secs)) || 101 nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(secs)) ||
94 nla_put_be32(skb, NFTA_LIMIT_BURST, htonl(limit->burst)) || 102 nla_put_be32(skb, NFTA_LIMIT_BURST, htonl(limit->burst)) ||
95 nla_put_be32(skb, NFTA_LIMIT_TYPE, htonl(type))) 103 nla_put_be32(skb, NFTA_LIMIT_TYPE, htonl(type)) ||
104 nla_put_be32(skb, NFTA_LIMIT_FLAGS, htonl(flags)))
96 goto nla_put_failure; 105 goto nla_put_failure;
97 return 0; 106 return 0;
98 107
@@ -120,6 +129,7 @@ static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = {
120 [NFTA_LIMIT_UNIT] = { .type = NLA_U64 }, 129 [NFTA_LIMIT_UNIT] = { .type = NLA_U64 },
121 [NFTA_LIMIT_BURST] = { .type = NLA_U32 }, 130 [NFTA_LIMIT_BURST] = { .type = NLA_U32 },
122 [NFTA_LIMIT_TYPE] = { .type = NLA_U32 }, 131 [NFTA_LIMIT_TYPE] = { .type = NLA_U32 },
132 [NFTA_LIMIT_FLAGS] = { .type = NLA_U32 },
123}; 133};
124 134
125static int nft_limit_pkts_init(const struct nft_ctx *ctx, 135static int nft_limit_pkts_init(const struct nft_ctx *ctx,
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
index df8801e02a32..4e3c3affd285 100644
--- a/net/netfilter/xt_osf.c
+++ b/net/netfilter/xt_osf.c
@@ -61,8 +61,8 @@ static const struct nla_policy xt_osf_policy[OSF_ATTR_MAX + 1] = {
61 [OSF_ATTR_FINGER] = { .len = sizeof(struct xt_osf_user_finger) }, 61 [OSF_ATTR_FINGER] = { .len = sizeof(struct xt_osf_user_finger) },
62}; 62};
63 63
64static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb, 64static int xt_osf_add_callback(struct net *net, struct sock *ctnl,
65 const struct nlmsghdr *nlh, 65 struct sk_buff *skb, const struct nlmsghdr *nlh,
66 const struct nlattr * const osf_attrs[]) 66 const struct nlattr * const osf_attrs[])
67{ 67{
68 struct xt_osf_user_finger *f; 68 struct xt_osf_user_finger *f;
@@ -104,7 +104,8 @@ static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb,
104 return err; 104 return err;
105} 105}
106 106
107static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb, 107static int xt_osf_remove_callback(struct net *net, struct sock *ctnl,
108 struct sk_buff *skb,
108 const struct nlmsghdr *nlh, 109 const struct nlmsghdr *nlh,
109 const struct nlattr * const osf_attrs[]) 110 const struct nlattr * const osf_attrs[])
110{ 111{