aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipmr.c
diff options
context:
space:
mode:
authorBenjamin Thery <benjamin.thery@bull.net>2009-01-21 23:56:22 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-22 16:57:41 -0500
commitf6bb451476be53d456e73bcfd82356afd680bbb0 (patch)
tree2b82f1523dbf4e0adfdfb214388b64df3ecacc99 /net/ipv4/ipmr.c
parent6c5143dbcfe50ac722965dc7d096abbeeec8bb33 (diff)
netns: ipmr: declare ipmr /proc/net entries per-namespace
Declare IPv4 multicast forwarding /proc/net entries per-namespace: /proc/net/ip_mr_vif /proc/net/ip_mr_cache Signed-off-by: Benjamin Thery <benjamin.thery@bull.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r--net/ipv4/ipmr.c101
1 files changed, 62 insertions, 39 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 346e67b50d6c..a4fd97f1920c 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1671,17 +1671,19 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
1671 * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif 1671 * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif
1672 */ 1672 */
1673struct ipmr_vif_iter { 1673struct ipmr_vif_iter {
1674 struct seq_net_private p;
1674 int ct; 1675 int ct;
1675}; 1676};
1676 1677
1677static struct vif_device *ipmr_vif_seq_idx(struct ipmr_vif_iter *iter, 1678static struct vif_device *ipmr_vif_seq_idx(struct net *net,
1679 struct ipmr_vif_iter *iter,
1678 loff_t pos) 1680 loff_t pos)
1679{ 1681{
1680 for (iter->ct = 0; iter->ct < init_net.ipv4.maxvif; ++iter->ct) { 1682 for (iter->ct = 0; iter->ct < net->ipv4.maxvif; ++iter->ct) {
1681 if (!VIF_EXISTS(&init_net, iter->ct)) 1683 if (!VIF_EXISTS(net, iter->ct))
1682 continue; 1684 continue;
1683 if (pos-- == 0) 1685 if (pos-- == 0)
1684 return &init_net.ipv4.vif_table[iter->ct]; 1686 return &net->ipv4.vif_table[iter->ct];
1685 } 1687 }
1686 return NULL; 1688 return NULL;
1687} 1689}
@@ -1689,23 +1691,26 @@ static struct vif_device *ipmr_vif_seq_idx(struct ipmr_vif_iter *iter,
1689static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) 1691static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos)
1690 __acquires(mrt_lock) 1692 __acquires(mrt_lock)
1691{ 1693{
1694 struct net *net = seq_file_net(seq);
1695
1692 read_lock(&mrt_lock); 1696 read_lock(&mrt_lock);
1693 return *pos ? ipmr_vif_seq_idx(seq->private, *pos - 1) 1697 return *pos ? ipmr_vif_seq_idx(net, seq->private, *pos - 1)
1694 : SEQ_START_TOKEN; 1698 : SEQ_START_TOKEN;
1695} 1699}
1696 1700
1697static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos) 1701static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1698{ 1702{
1699 struct ipmr_vif_iter *iter = seq->private; 1703 struct ipmr_vif_iter *iter = seq->private;
1704 struct net *net = seq_file_net(seq);
1700 1705
1701 ++*pos; 1706 ++*pos;
1702 if (v == SEQ_START_TOKEN) 1707 if (v == SEQ_START_TOKEN)
1703 return ipmr_vif_seq_idx(iter, 0); 1708 return ipmr_vif_seq_idx(net, iter, 0);
1704 1709
1705 while (++iter->ct < init_net.ipv4.maxvif) { 1710 while (++iter->ct < net->ipv4.maxvif) {
1706 if (!VIF_EXISTS(&init_net, iter->ct)) 1711 if (!VIF_EXISTS(net, iter->ct))
1707 continue; 1712 continue;
1708 return &init_net.ipv4.vif_table[iter->ct]; 1713 return &net->ipv4.vif_table[iter->ct];
1709 } 1714 }
1710 return NULL; 1715 return NULL;
1711} 1716}
@@ -1718,6 +1723,8 @@ static void ipmr_vif_seq_stop(struct seq_file *seq, void *v)
1718 1723
1719static int ipmr_vif_seq_show(struct seq_file *seq, void *v) 1724static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
1720{ 1725{
1726 struct net *net = seq_file_net(seq);
1727
1721 if (v == SEQ_START_TOKEN) { 1728 if (v == SEQ_START_TOKEN) {
1722 seq_puts(seq, 1729 seq_puts(seq,
1723 "Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote\n"); 1730 "Interface BytesIn PktsIn BytesOut PktsOut Flags Local Remote\n");
@@ -1727,7 +1734,7 @@ static int ipmr_vif_seq_show(struct seq_file *seq, void *v)
1727 1734
1728 seq_printf(seq, 1735 seq_printf(seq,
1729 "%2Zd %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n", 1736 "%2Zd %-10s %8ld %7ld %8ld %7ld %05X %08X %08X\n",
1730 vif - init_net.ipv4.vif_table, 1737 vif - net->ipv4.vif_table,
1731 name, vif->bytes_in, vif->pkt_in, 1738 name, vif->bytes_in, vif->pkt_in,
1732 vif->bytes_out, vif->pkt_out, 1739 vif->bytes_out, vif->pkt_out,
1733 vif->flags, vif->local, vif->remote); 1740 vif->flags, vif->local, vif->remote);
@@ -1744,8 +1751,8 @@ static const struct seq_operations ipmr_vif_seq_ops = {
1744 1751
1745static int ipmr_vif_open(struct inode *inode, struct file *file) 1752static int ipmr_vif_open(struct inode *inode, struct file *file)
1746{ 1753{
1747 return seq_open_private(file, &ipmr_vif_seq_ops, 1754 return seq_open_net(inode, file, &ipmr_vif_seq_ops,
1748 sizeof(struct ipmr_vif_iter)); 1755 sizeof(struct ipmr_vif_iter));
1749} 1756}
1750 1757
1751static const struct file_operations ipmr_vif_fops = { 1758static const struct file_operations ipmr_vif_fops = {
@@ -1753,23 +1760,25 @@ static const struct file_operations ipmr_vif_fops = {
1753 .open = ipmr_vif_open, 1760 .open = ipmr_vif_open,
1754 .read = seq_read, 1761 .read = seq_read,
1755 .llseek = seq_lseek, 1762 .llseek = seq_lseek,
1756 .release = seq_release_private, 1763 .release = seq_release_net,
1757}; 1764};
1758 1765
1759struct ipmr_mfc_iter { 1766struct ipmr_mfc_iter {
1767 struct seq_net_private p;
1760 struct mfc_cache **cache; 1768 struct mfc_cache **cache;
1761 int ct; 1769 int ct;
1762}; 1770};
1763 1771
1764 1772
1765static struct mfc_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos) 1773static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net,
1774 struct ipmr_mfc_iter *it, loff_t pos)
1766{ 1775{
1767 struct mfc_cache *mfc; 1776 struct mfc_cache *mfc;
1768 1777
1769 it->cache = init_net.ipv4.mfc_cache_array; 1778 it->cache = net->ipv4.mfc_cache_array;
1770 read_lock(&mrt_lock); 1779 read_lock(&mrt_lock);
1771 for (it->ct = 0; it->ct < MFC_LINES; it->ct++) 1780 for (it->ct = 0; it->ct < MFC_LINES; it->ct++)
1772 for (mfc = init_net.ipv4.mfc_cache_array[it->ct]; 1781 for (mfc = net->ipv4.mfc_cache_array[it->ct];
1773 mfc; mfc = mfc->next) 1782 mfc; mfc = mfc->next)
1774 if (pos-- == 0) 1783 if (pos-- == 0)
1775 return mfc; 1784 return mfc;
@@ -1778,7 +1787,8 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
1778 it->cache = &mfc_unres_queue; 1787 it->cache = &mfc_unres_queue;
1779 spin_lock_bh(&mfc_unres_lock); 1788 spin_lock_bh(&mfc_unres_lock);
1780 for (mfc = mfc_unres_queue; mfc; mfc = mfc->next) 1789 for (mfc = mfc_unres_queue; mfc; mfc = mfc->next)
1781 if (pos-- == 0) 1790 if (net_eq(mfc_net(mfc), net) &&
1791 pos-- == 0)
1782 return mfc; 1792 return mfc;
1783 spin_unlock_bh(&mfc_unres_lock); 1793 spin_unlock_bh(&mfc_unres_lock);
1784 1794
@@ -1790,9 +1800,11 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos)
1790static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) 1800static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
1791{ 1801{
1792 struct ipmr_mfc_iter *it = seq->private; 1802 struct ipmr_mfc_iter *it = seq->private;
1803 struct net *net = seq_file_net(seq);
1804
1793 it->cache = NULL; 1805 it->cache = NULL;
1794 it->ct = 0; 1806 it->ct = 0;
1795 return *pos ? ipmr_mfc_seq_idx(seq->private, *pos - 1) 1807 return *pos ? ipmr_mfc_seq_idx(net, seq->private, *pos - 1)
1796 : SEQ_START_TOKEN; 1808 : SEQ_START_TOKEN;
1797} 1809}
1798 1810
@@ -1800,11 +1812,12 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1800{ 1812{
1801 struct mfc_cache *mfc = v; 1813 struct mfc_cache *mfc = v;
1802 struct ipmr_mfc_iter *it = seq->private; 1814 struct ipmr_mfc_iter *it = seq->private;
1815 struct net *net = seq_file_net(seq);
1803 1816
1804 ++*pos; 1817 ++*pos;
1805 1818
1806 if (v == SEQ_START_TOKEN) 1819 if (v == SEQ_START_TOKEN)
1807 return ipmr_mfc_seq_idx(seq->private, 0); 1820 return ipmr_mfc_seq_idx(net, seq->private, 0);
1808 1821
1809 if (mfc->next) 1822 if (mfc->next)
1810 return mfc->next; 1823 return mfc->next;
@@ -1812,10 +1825,10 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1812 if (it->cache == &mfc_unres_queue) 1825 if (it->cache == &mfc_unres_queue)
1813 goto end_of_list; 1826 goto end_of_list;
1814 1827
1815 BUG_ON(it->cache != init_net.ipv4.mfc_cache_array); 1828 BUG_ON(it->cache != net->ipv4.mfc_cache_array);
1816 1829
1817 while (++it->ct < MFC_LINES) { 1830 while (++it->ct < MFC_LINES) {
1818 mfc = init_net.ipv4.mfc_cache_array[it->ct]; 1831 mfc = net->ipv4.mfc_cache_array[it->ct];
1819 if (mfc) 1832 if (mfc)
1820 return mfc; 1833 return mfc;
1821 } 1834 }
@@ -1827,6 +1840,8 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1827 1840
1828 spin_lock_bh(&mfc_unres_lock); 1841 spin_lock_bh(&mfc_unres_lock);
1829 mfc = mfc_unres_queue; 1842 mfc = mfc_unres_queue;
1843 while (mfc && !net_eq(mfc_net(mfc), net))
1844 mfc = mfc->next;
1830 if (mfc) 1845 if (mfc)
1831 return mfc; 1846 return mfc;
1832 1847
@@ -1840,16 +1855,18 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1840static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) 1855static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v)
1841{ 1856{
1842 struct ipmr_mfc_iter *it = seq->private; 1857 struct ipmr_mfc_iter *it = seq->private;
1858 struct net *net = seq_file_net(seq);
1843 1859
1844 if (it->cache == &mfc_unres_queue) 1860 if (it->cache == &mfc_unres_queue)
1845 spin_unlock_bh(&mfc_unres_lock); 1861 spin_unlock_bh(&mfc_unres_lock);
1846 else if (it->cache == init_net.ipv4.mfc_cache_array) 1862 else if (it->cache == net->ipv4.mfc_cache_array)
1847 read_unlock(&mrt_lock); 1863 read_unlock(&mrt_lock);
1848} 1864}
1849 1865
1850static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) 1866static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
1851{ 1867{
1852 int n; 1868 int n;
1869 struct net *net = seq_file_net(seq);
1853 1870
1854 if (v == SEQ_START_TOKEN) { 1871 if (v == SEQ_START_TOKEN) {
1855 seq_puts(seq, 1872 seq_puts(seq,
@@ -1870,7 +1887,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v)
1870 mfc->mfc_un.res.wrong_if); 1887 mfc->mfc_un.res.wrong_if);
1871 for (n = mfc->mfc_un.res.minvif; 1888 for (n = mfc->mfc_un.res.minvif;
1872 n < mfc->mfc_un.res.maxvif; n++ ) { 1889 n < mfc->mfc_un.res.maxvif; n++ ) {
1873 if (VIF_EXISTS(&init_net, n) && 1890 if (VIF_EXISTS(net, n) &&
1874 mfc->mfc_un.res.ttls[n] < 255) 1891 mfc->mfc_un.res.ttls[n] < 255)
1875 seq_printf(seq, 1892 seq_printf(seq,
1876 " %2d:%-3d", 1893 " %2d:%-3d",
@@ -1896,8 +1913,8 @@ static const struct seq_operations ipmr_mfc_seq_ops = {
1896 1913
1897static int ipmr_mfc_open(struct inode *inode, struct file *file) 1914static int ipmr_mfc_open(struct inode *inode, struct file *file)
1898{ 1915{
1899 return seq_open_private(file, &ipmr_mfc_seq_ops, 1916 return seq_open_net(inode, file, &ipmr_mfc_seq_ops,
1900 sizeof(struct ipmr_mfc_iter)); 1917 sizeof(struct ipmr_mfc_iter));
1901} 1918}
1902 1919
1903static const struct file_operations ipmr_mfc_fops = { 1920static const struct file_operations ipmr_mfc_fops = {
@@ -1905,7 +1922,7 @@ static const struct file_operations ipmr_mfc_fops = {
1905 .open = ipmr_mfc_open, 1922 .open = ipmr_mfc_open,
1906 .read = seq_read, 1923 .read = seq_read,
1907 .llseek = seq_lseek, 1924 .llseek = seq_lseek,
1908 .release = seq_release_private, 1925 .release = seq_release_net,
1909}; 1926};
1910#endif 1927#endif
1911 1928
@@ -1942,8 +1959,22 @@ static int __net_init ipmr_net_init(struct net *net)
1942#ifdef CONFIG_IP_PIMSM 1959#ifdef CONFIG_IP_PIMSM
1943 net->ipv4.mroute_reg_vif_num = -1; 1960 net->ipv4.mroute_reg_vif_num = -1;
1944#endif 1961#endif
1962
1963#ifdef CONFIG_PROC_FS
1964 err = -ENOMEM;
1965 if (!proc_net_fops_create(net, "ip_mr_vif", 0, &ipmr_vif_fops))
1966 goto proc_vif_fail;
1967 if (!proc_net_fops_create(net, "ip_mr_cache", 0, &ipmr_mfc_fops))
1968 goto proc_cache_fail;
1969#endif
1945 return 0; 1970 return 0;
1946 1971
1972#ifdef CONFIG_PROC_FS
1973proc_cache_fail:
1974 proc_net_remove(net, "ip_mr_vif");
1975proc_vif_fail:
1976 kfree(net->ipv4.mfc_cache_array);
1977#endif
1947fail_mfc_cache: 1978fail_mfc_cache:
1948 kfree(net->ipv4.vif_table); 1979 kfree(net->ipv4.vif_table);
1949fail: 1980fail:
@@ -1952,6 +1983,10 @@ fail:
1952 1983
1953static void __net_exit ipmr_net_exit(struct net *net) 1984static void __net_exit ipmr_net_exit(struct net *net)
1954{ 1985{
1986#ifdef CONFIG_PROC_FS
1987 proc_net_remove(net, "ip_mr_cache");
1988 proc_net_remove(net, "ip_mr_vif");
1989#endif
1955 kfree(net->ipv4.mfc_cache_array); 1990 kfree(net->ipv4.mfc_cache_array);
1956 kfree(net->ipv4.vif_table); 1991 kfree(net->ipv4.vif_table);
1957} 1992}
@@ -1980,20 +2015,8 @@ int __init ip_mr_init(void)
1980 err = register_netdevice_notifier(&ip_mr_notifier); 2015 err = register_netdevice_notifier(&ip_mr_notifier);
1981 if (err) 2016 if (err)
1982 goto reg_notif_fail; 2017 goto reg_notif_fail;
1983#ifdef CONFIG_PROC_FS
1984 err = -ENOMEM;
1985 if (!proc_net_fops_create(&init_net, "ip_mr_vif", 0, &ipmr_vif_fops))
1986 goto proc_vif_fail;
1987 if (!proc_net_fops_create(&init_net, "ip_mr_cache", 0, &ipmr_mfc_fops))
1988 goto proc_cache_fail;
1989#endif
1990 return 0; 2018 return 0;
1991#ifdef CONFIG_PROC_FS 2019
1992proc_cache_fail:
1993 proc_net_remove(&init_net, "ip_mr_vif");
1994proc_vif_fail:
1995 unregister_netdevice_notifier(&ip_mr_notifier);
1996#endif
1997reg_notif_fail: 2020reg_notif_fail:
1998 del_timer(&ipmr_expire_timer); 2021 del_timer(&ipmr_expire_timer);
1999 unregister_pernet_subsys(&ipmr_net_ops); 2022 unregister_pernet_subsys(&ipmr_net_ops);