diff options
author | Benjamin Thery <benjamin.thery@bull.net> | 2009-01-21 23:56:22 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-01-22 16:57:41 -0500 |
commit | f6bb451476be53d456e73bcfd82356afd680bbb0 (patch) | |
tree | 2b82f1523dbf4e0adfdfb214388b64df3ecacc99 /net/ipv4/ipmr.c | |
parent | 6c5143dbcfe50ac722965dc7d096abbeeec8bb33 (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.c | 101 |
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 | */ |
1673 | struct ipmr_vif_iter { | 1673 | struct ipmr_vif_iter { |
1674 | struct seq_net_private p; | ||
1674 | int ct; | 1675 | int ct; |
1675 | }; | 1676 | }; |
1676 | 1677 | ||
1677 | static struct vif_device *ipmr_vif_seq_idx(struct ipmr_vif_iter *iter, | 1678 | static 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, | |||
1689 | static void *ipmr_vif_seq_start(struct seq_file *seq, loff_t *pos) | 1691 | static 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 | ||
1697 | static void *ipmr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 1701 | static 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 | ||
1719 | static int ipmr_vif_seq_show(struct seq_file *seq, void *v) | 1724 | static 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 | ||
1745 | static int ipmr_vif_open(struct inode *inode, struct file *file) | 1752 | static 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 | ||
1751 | static const struct file_operations ipmr_vif_fops = { | 1758 | static 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 | ||
1759 | struct ipmr_mfc_iter { | 1766 | struct 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 | ||
1765 | static struct mfc_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos) | 1773 | static 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) | |||
1790 | static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) | 1800 | static 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) | |||
1840 | static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) | 1855 | static 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 | ||
1850 | static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) | 1866 | static 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 | ||
1897 | static int ipmr_mfc_open(struct inode *inode, struct file *file) | 1914 | static 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 | ||
1903 | static const struct file_operations ipmr_mfc_fops = { | 1920 | static 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 | ||
1973 | proc_cache_fail: | ||
1974 | proc_net_remove(net, "ip_mr_vif"); | ||
1975 | proc_vif_fail: | ||
1976 | kfree(net->ipv4.mfc_cache_array); | ||
1977 | #endif | ||
1947 | fail_mfc_cache: | 1978 | fail_mfc_cache: |
1948 | kfree(net->ipv4.vif_table); | 1979 | kfree(net->ipv4.vif_table); |
1949 | fail: | 1980 | fail: |
@@ -1952,6 +1983,10 @@ fail: | |||
1952 | 1983 | ||
1953 | static void __net_exit ipmr_net_exit(struct net *net) | 1984 | static 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 | |
1992 | proc_cache_fail: | ||
1993 | proc_net_remove(&init_net, "ip_mr_vif"); | ||
1994 | proc_vif_fail: | ||
1995 | unregister_netdevice_notifier(&ip_mr_notifier); | ||
1996 | #endif | ||
1997 | reg_notif_fail: | 2020 | reg_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); |