aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nf_conntrack_netlink.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2010-01-13 10:04:18 -0500
committerPatrick McHardy <kaber@trash.net>2010-01-13 10:04:18 -0500
commit9592a5c01e79dbc59eb56fa26b124e94ffcd0962 (patch)
treece206d7cc0f5bb65da1ba37b635116540a9b57cf /net/netfilter/nf_conntrack_netlink.c
parentcd8c20b650f49354722b8cc1f03320b004815a0a (diff)
netfilter: ctnetlink: netns support
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter/nf_conntrack_netlink.c')
-rw-r--r--net/netfilter/nf_conntrack_netlink.c65
1 files changed, 39 insertions, 26 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index d4c5d06677f..79478dfba27 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -30,6 +30,7 @@
30 30
31#include <linux/netfilter.h> 31#include <linux/netfilter.h>
32#include <net/netlink.h> 32#include <net/netlink.h>
33#include <net/sock.h>
33#include <net/netfilter/nf_conntrack.h> 34#include <net/netfilter/nf_conntrack.h>
34#include <net/netfilter/nf_conntrack_core.h> 35#include <net/netfilter/nf_conntrack_core.h>
35#include <net/netfilter/nf_conntrack_expect.h> 36#include <net/netfilter/nf_conntrack_expect.h>
@@ -456,6 +457,7 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct)
456static int 457static int
457ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item) 458ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
458{ 459{
460 struct net *net;
459 struct nlmsghdr *nlh; 461 struct nlmsghdr *nlh;
460 struct nfgenmsg *nfmsg; 462 struct nfgenmsg *nfmsg;
461 struct nlattr *nest_parms; 463 struct nlattr *nest_parms;
@@ -482,7 +484,8 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
482 } else 484 } else
483 return 0; 485 return 0;
484 486
485 if (!item->report && !nfnetlink_has_listeners(&init_net, group)) 487 net = nf_ct_net(ct);
488 if (!item->report && !nfnetlink_has_listeners(net, group))
486 return 0; 489 return 0;
487 490
488 skb = nlmsg_new(ctnetlink_nlmsg_size(ct), GFP_ATOMIC); 491 skb = nlmsg_new(ctnetlink_nlmsg_size(ct), GFP_ATOMIC);
@@ -559,7 +562,7 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
559 rcu_read_unlock(); 562 rcu_read_unlock();
560 563
561 nlmsg_end(skb, nlh); 564 nlmsg_end(skb, nlh);
562 err = nfnetlink_send(skb, &init_net, item->pid, group, item->report, 565 err = nfnetlink_send(skb, net, item->pid, group, item->report,
563 GFP_ATOMIC); 566 GFP_ATOMIC);
564 if (err == -ENOBUFS || err == -EAGAIN) 567 if (err == -ENOBUFS || err == -EAGAIN)
565 return -ENOBUFS; 568 return -ENOBUFS;
@@ -572,7 +575,7 @@ nla_put_failure:
572nlmsg_failure: 575nlmsg_failure:
573 kfree_skb(skb); 576 kfree_skb(skb);
574errout: 577errout:
575 nfnetlink_set_err(&init_net, 0, group, -ENOBUFS); 578 nfnetlink_set_err(net, 0, group, -ENOBUFS);
576 return 0; 579 return 0;
577} 580}
578#endif /* CONFIG_NF_CONNTRACK_EVENTS */ 581#endif /* CONFIG_NF_CONNTRACK_EVENTS */
@@ -587,6 +590,7 @@ static int ctnetlink_done(struct netlink_callback *cb)
587static int 590static int
588ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 591ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
589{ 592{
593 struct net *net = sock_net(skb->sk);
590 struct nf_conn *ct, *last; 594 struct nf_conn *ct, *last;
591 struct nf_conntrack_tuple_hash *h; 595 struct nf_conntrack_tuple_hash *h;
592 struct hlist_nulls_node *n; 596 struct hlist_nulls_node *n;
@@ -597,7 +601,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
597 last = (struct nf_conn *)cb->args[1]; 601 last = (struct nf_conn *)cb->args[1];
598 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { 602 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
599restart: 603restart:
600 hlist_nulls_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]], 604 hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[cb->args[0]],
601 hnnode) { 605 hnnode) {
602 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) 606 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
603 continue; 607 continue;
@@ -769,6 +773,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
769 const struct nlmsghdr *nlh, 773 const struct nlmsghdr *nlh,
770 const struct nlattr * const cda[]) 774 const struct nlattr * const cda[])
771{ 775{
776 struct net *net = sock_net(ctnl);
772 struct nf_conntrack_tuple_hash *h; 777 struct nf_conntrack_tuple_hash *h;
773 struct nf_conntrack_tuple tuple; 778 struct nf_conntrack_tuple tuple;
774 struct nf_conn *ct; 779 struct nf_conn *ct;
@@ -782,7 +787,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
782 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); 787 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
783 else { 788 else {
784 /* Flush the whole table */ 789 /* Flush the whole table */
785 nf_conntrack_flush_report(&init_net, 790 nf_conntrack_flush_report(net,
786 NETLINK_CB(skb).pid, 791 NETLINK_CB(skb).pid,
787 nlmsg_report(nlh)); 792 nlmsg_report(nlh));
788 return 0; 793 return 0;
@@ -791,7 +796,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
791 if (err < 0) 796 if (err < 0)
792 return err; 797 return err;
793 798
794 h = nf_conntrack_find_get(&init_net, &tuple); 799 h = nf_conntrack_find_get(net, &tuple);
795 if (!h) 800 if (!h)
796 return -ENOENT; 801 return -ENOENT;
797 802
@@ -829,6 +834,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
829 const struct nlmsghdr *nlh, 834 const struct nlmsghdr *nlh,
830 const struct nlattr * const cda[]) 835 const struct nlattr * const cda[])
831{ 836{
837 struct net *net = sock_net(ctnl);
832 struct nf_conntrack_tuple_hash *h; 838 struct nf_conntrack_tuple_hash *h;
833 struct nf_conntrack_tuple tuple; 839 struct nf_conntrack_tuple tuple;
834 struct nf_conn *ct; 840 struct nf_conn *ct;
@@ -851,7 +857,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
851 if (err < 0) 857 if (err < 0)
852 return err; 858 return err;
853 859
854 h = nf_conntrack_find_get(&init_net, &tuple); 860 h = nf_conntrack_find_get(net, &tuple);
855 if (!h) 861 if (!h)
856 return -ENOENT; 862 return -ENOENT;
857 863
@@ -1176,7 +1182,8 @@ ctnetlink_change_conntrack(struct nf_conn *ct,
1176} 1182}
1177 1183
1178static struct nf_conn * 1184static struct nf_conn *
1179ctnetlink_create_conntrack(const struct nlattr * const cda[], 1185ctnetlink_create_conntrack(struct net *net,
1186 const struct nlattr * const cda[],
1180 struct nf_conntrack_tuple *otuple, 1187 struct nf_conntrack_tuple *otuple,
1181 struct nf_conntrack_tuple *rtuple, 1188 struct nf_conntrack_tuple *rtuple,
1182 u8 u3) 1189 u8 u3)
@@ -1185,7 +1192,7 @@ ctnetlink_create_conntrack(const struct nlattr * const cda[],
1185 int err = -EINVAL; 1192 int err = -EINVAL;
1186 struct nf_conntrack_helper *helper; 1193 struct nf_conntrack_helper *helper;
1187 1194
1188 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_ATOMIC); 1195 ct = nf_conntrack_alloc(net, otuple, rtuple, GFP_ATOMIC);
1189 if (IS_ERR(ct)) 1196 if (IS_ERR(ct))
1190 return ERR_PTR(-ENOMEM); 1197 return ERR_PTR(-ENOMEM);
1191 1198
@@ -1286,7 +1293,7 @@ ctnetlink_create_conntrack(const struct nlattr * const cda[],
1286 if (err < 0) 1293 if (err < 0)
1287 goto err2; 1294 goto err2;
1288 1295
1289 master_h = nf_conntrack_find_get(&init_net, &master); 1296 master_h = nf_conntrack_find_get(net, &master);
1290 if (master_h == NULL) { 1297 if (master_h == NULL) {
1291 err = -ENOENT; 1298 err = -ENOENT;
1292 goto err2; 1299 goto err2;
@@ -1314,6 +1321,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1314 const struct nlmsghdr *nlh, 1321 const struct nlmsghdr *nlh,
1315 const struct nlattr * const cda[]) 1322 const struct nlattr * const cda[])
1316{ 1323{
1324 struct net *net = sock_net(ctnl);
1317 struct nf_conntrack_tuple otuple, rtuple; 1325 struct nf_conntrack_tuple otuple, rtuple;
1318 struct nf_conntrack_tuple_hash *h = NULL; 1326 struct nf_conntrack_tuple_hash *h = NULL;
1319 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1327 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -1334,9 +1342,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1334 1342
1335 spin_lock_bh(&nf_conntrack_lock); 1343 spin_lock_bh(&nf_conntrack_lock);
1336 if (cda[CTA_TUPLE_ORIG]) 1344 if (cda[CTA_TUPLE_ORIG])
1337 h = __nf_conntrack_find(&init_net, &otuple); 1345 h = __nf_conntrack_find(net, &otuple);
1338 else if (cda[CTA_TUPLE_REPLY]) 1346 else if (cda[CTA_TUPLE_REPLY])
1339 h = __nf_conntrack_find(&init_net, &rtuple); 1347 h = __nf_conntrack_find(net, &rtuple);
1340 1348
1341 if (h == NULL) { 1349 if (h == NULL) {
1342 err = -ENOENT; 1350 err = -ENOENT;
@@ -1344,7 +1352,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1344 struct nf_conn *ct; 1352 struct nf_conn *ct;
1345 enum ip_conntrack_events events; 1353 enum ip_conntrack_events events;
1346 1354
1347 ct = ctnetlink_create_conntrack(cda, &otuple, 1355 ct = ctnetlink_create_conntrack(net, cda, &otuple,
1348 &rtuple, u3); 1356 &rtuple, u3);
1349 if (IS_ERR(ct)) { 1357 if (IS_ERR(ct)) {
1350 err = PTR_ERR(ct); 1358 err = PTR_ERR(ct);
@@ -1526,9 +1534,10 @@ nla_put_failure:
1526static int 1534static int
1527ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) 1535ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
1528{ 1536{
1537 struct nf_conntrack_expect *exp = item->exp;
1538 struct net *net = nf_ct_exp_net(exp);
1529 struct nlmsghdr *nlh; 1539 struct nlmsghdr *nlh;
1530 struct nfgenmsg *nfmsg; 1540 struct nfgenmsg *nfmsg;
1531 struct nf_conntrack_expect *exp = item->exp;
1532 struct sk_buff *skb; 1541 struct sk_buff *skb;
1533 unsigned int type; 1542 unsigned int type;
1534 int flags = 0; 1543 int flags = 0;
@@ -1540,7 +1549,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
1540 return 0; 1549 return 0;
1541 1550
1542 if (!item->report && 1551 if (!item->report &&
1543 !nfnetlink_has_listeners(&init_net, NFNLGRP_CONNTRACK_EXP_NEW)) 1552 !nfnetlink_has_listeners(net, NFNLGRP_CONNTRACK_EXP_NEW))
1544 return 0; 1553 return 0;
1545 1554
1546 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 1555 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
@@ -1563,7 +1572,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
1563 rcu_read_unlock(); 1572 rcu_read_unlock();
1564 1573
1565 nlmsg_end(skb, nlh); 1574 nlmsg_end(skb, nlh);
1566 nfnetlink_send(skb, &init_net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, 1575 nfnetlink_send(skb, net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW,
1567 item->report, GFP_ATOMIC); 1576 item->report, GFP_ATOMIC);
1568 return 0; 1577 return 0;
1569 1578
@@ -1573,7 +1582,7 @@ nla_put_failure:
1573nlmsg_failure: 1582nlmsg_failure:
1574 kfree_skb(skb); 1583 kfree_skb(skb);
1575errout: 1584errout:
1576 nfnetlink_set_err(&init_net, 0, 0, -ENOBUFS); 1585 nfnetlink_set_err(net, 0, 0, -ENOBUFS);
1577 return 0; 1586 return 0;
1578} 1587}
1579#endif 1588#endif
@@ -1587,7 +1596,7 @@ static int ctnetlink_exp_done(struct netlink_callback *cb)
1587static int 1596static int
1588ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 1597ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1589{ 1598{
1590 struct net *net = &init_net; 1599 struct net *net = sock_net(skb->sk);
1591 struct nf_conntrack_expect *exp, *last; 1600 struct nf_conntrack_expect *exp, *last;
1592 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); 1601 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1593 struct hlist_node *n; 1602 struct hlist_node *n;
@@ -1640,6 +1649,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1640 const struct nlmsghdr *nlh, 1649 const struct nlmsghdr *nlh,
1641 const struct nlattr * const cda[]) 1650 const struct nlattr * const cda[])
1642{ 1651{
1652 struct net *net = sock_net(ctnl);
1643 struct nf_conntrack_tuple tuple; 1653 struct nf_conntrack_tuple tuple;
1644 struct nf_conntrack_expect *exp; 1654 struct nf_conntrack_expect *exp;
1645 struct sk_buff *skb2; 1655 struct sk_buff *skb2;
@@ -1661,7 +1671,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1661 if (err < 0) 1671 if (err < 0)
1662 return err; 1672 return err;
1663 1673
1664 exp = nf_ct_expect_find_get(&init_net, &tuple); 1674 exp = nf_ct_expect_find_get(net, &tuple);
1665 if (!exp) 1675 if (!exp)
1666 return -ENOENT; 1676 return -ENOENT;
1667 1677
@@ -1701,6 +1711,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1701 const struct nlmsghdr *nlh, 1711 const struct nlmsghdr *nlh,
1702 const struct nlattr * const cda[]) 1712 const struct nlattr * const cda[])
1703{ 1713{
1714 struct net *net = sock_net(ctnl);
1704 struct nf_conntrack_expect *exp; 1715 struct nf_conntrack_expect *exp;
1705 struct nf_conntrack_tuple tuple; 1716 struct nf_conntrack_tuple tuple;
1706 struct nf_conntrack_helper *h; 1717 struct nf_conntrack_helper *h;
@@ -1717,7 +1728,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1717 return err; 1728 return err;
1718 1729
1719 /* bump usage count to 2 */ 1730 /* bump usage count to 2 */
1720 exp = nf_ct_expect_find_get(&init_net, &tuple); 1731 exp = nf_ct_expect_find_get(net, &tuple);
1721 if (!exp) 1732 if (!exp)
1722 return -ENOENT; 1733 return -ENOENT;
1723 1734
@@ -1747,7 +1758,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1747 } 1758 }
1748 for (i = 0; i < nf_ct_expect_hsize; i++) { 1759 for (i = 0; i < nf_ct_expect_hsize; i++) {
1749 hlist_for_each_entry_safe(exp, n, next, 1760 hlist_for_each_entry_safe(exp, n, next,
1750 &init_net.ct.expect_hash[i], 1761 &net->ct.expect_hash[i],
1751 hnode) { 1762 hnode) {
1752 m_help = nfct_help(exp->master); 1763 m_help = nfct_help(exp->master);
1753 if (m_help->helper == h 1764 if (m_help->helper == h
@@ -1763,7 +1774,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1763 spin_lock_bh(&nf_conntrack_lock); 1774 spin_lock_bh(&nf_conntrack_lock);
1764 for (i = 0; i < nf_ct_expect_hsize; i++) { 1775 for (i = 0; i < nf_ct_expect_hsize; i++) {
1765 hlist_for_each_entry_safe(exp, n, next, 1776 hlist_for_each_entry_safe(exp, n, next,
1766 &init_net.ct.expect_hash[i], 1777 &net->ct.expect_hash[i],
1767 hnode) { 1778 hnode) {
1768 if (del_timer(&exp->timeout)) { 1779 if (del_timer(&exp->timeout)) {
1769 nf_ct_unlink_expect(exp); 1780 nf_ct_unlink_expect(exp);
@@ -1784,7 +1795,8 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x,
1784} 1795}
1785 1796
1786static int 1797static int
1787ctnetlink_create_expect(const struct nlattr * const cda[], u_int8_t u3, 1798ctnetlink_create_expect(struct net *net, const struct nlattr * const cda[],
1799 u_int8_t u3,
1788 u32 pid, int report) 1800 u32 pid, int report)
1789{ 1801{
1790 struct nf_conntrack_tuple tuple, mask, master_tuple; 1802 struct nf_conntrack_tuple tuple, mask, master_tuple;
@@ -1806,7 +1818,7 @@ ctnetlink_create_expect(const struct nlattr * const cda[], u_int8_t u3,
1806 return err; 1818 return err;
1807 1819
1808 /* Look for master conntrack of this expectation */ 1820 /* Look for master conntrack of this expectation */
1809 h = nf_conntrack_find_get(&init_net, &master_tuple); 1821 h = nf_conntrack_find_get(net, &master_tuple);
1810 if (!h) 1822 if (!h)
1811 return -ENOENT; 1823 return -ENOENT;
1812 ct = nf_ct_tuplehash_to_ctrack(h); 1824 ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1846,6 +1858,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1846 const struct nlmsghdr *nlh, 1858 const struct nlmsghdr *nlh,
1847 const struct nlattr * const cda[]) 1859 const struct nlattr * const cda[])
1848{ 1860{
1861 struct net *net = sock_net(ctnl);
1849 struct nf_conntrack_tuple tuple; 1862 struct nf_conntrack_tuple tuple;
1850 struct nf_conntrack_expect *exp; 1863 struct nf_conntrack_expect *exp;
1851 struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1864 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
@@ -1862,13 +1875,13 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1862 return err; 1875 return err;
1863 1876
1864 spin_lock_bh(&nf_conntrack_lock); 1877 spin_lock_bh(&nf_conntrack_lock);
1865 exp = __nf_ct_expect_find(&init_net, &tuple); 1878 exp = __nf_ct_expect_find(net, &tuple);
1866 1879
1867 if (!exp) { 1880 if (!exp) {
1868 spin_unlock_bh(&nf_conntrack_lock); 1881 spin_unlock_bh(&nf_conntrack_lock);
1869 err = -ENOENT; 1882 err = -ENOENT;
1870 if (nlh->nlmsg_flags & NLM_F_CREATE) { 1883 if (nlh->nlmsg_flags & NLM_F_CREATE) {
1871 err = ctnetlink_create_expect(cda, 1884 err = ctnetlink_create_expect(net, cda,
1872 u3, 1885 u3,
1873 NETLINK_CB(skb).pid, 1886 NETLINK_CB(skb).pid,
1874 nlmsg_report(nlh)); 1887 nlmsg_report(nlh));