diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2013-03-05 18:42:06 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-06 15:40:53 -0500 |
commit | 7a6742003f3c8650c4d3f9edcae1cf8a5cdda276 (patch) | |
tree | 26b37b324a5efe81c42af647ed701107e3c05077 /net/ipv4 | |
parent | 753f993911b32e479b4fab5d228dc07c11d1e7e7 (diff) |
netconf: add the handler to dump entries
It's useful to be able to get the initial state of all entries. The patch adds
the support for IPv4 and IPv6.
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/devinet.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index f678507bc829..af57bbae05b9 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1791,6 +1791,74 @@ errout: | |||
1791 | return err; | 1791 | return err; |
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | static int inet_netconf_dump_devconf(struct sk_buff *skb, | ||
1795 | struct netlink_callback *cb) | ||
1796 | { | ||
1797 | struct net *net = sock_net(skb->sk); | ||
1798 | int h, s_h; | ||
1799 | int idx, s_idx; | ||
1800 | struct net_device *dev; | ||
1801 | struct in_device *in_dev; | ||
1802 | struct hlist_head *head; | ||
1803 | |||
1804 | s_h = cb->args[0]; | ||
1805 | s_idx = idx = cb->args[1]; | ||
1806 | |||
1807 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | ||
1808 | idx = 0; | ||
1809 | head = &net->dev_index_head[h]; | ||
1810 | rcu_read_lock(); | ||
1811 | hlist_for_each_entry_rcu(dev, head, index_hlist) { | ||
1812 | if (idx < s_idx) | ||
1813 | goto cont; | ||
1814 | in_dev = __in_dev_get_rcu(dev); | ||
1815 | if (!in_dev) | ||
1816 | goto cont; | ||
1817 | |||
1818 | if (inet_netconf_fill_devconf(skb, dev->ifindex, | ||
1819 | &in_dev->cnf, | ||
1820 | NETLINK_CB(cb->skb).portid, | ||
1821 | cb->nlh->nlmsg_seq, | ||
1822 | RTM_NEWNETCONF, | ||
1823 | NLM_F_MULTI, | ||
1824 | -1) <= 0) { | ||
1825 | rcu_read_unlock(); | ||
1826 | goto done; | ||
1827 | } | ||
1828 | cont: | ||
1829 | idx++; | ||
1830 | } | ||
1831 | rcu_read_unlock(); | ||
1832 | } | ||
1833 | if (h == NETDEV_HASHENTRIES) { | ||
1834 | if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL, | ||
1835 | net->ipv4.devconf_all, | ||
1836 | NETLINK_CB(cb->skb).portid, | ||
1837 | cb->nlh->nlmsg_seq, | ||
1838 | RTM_NEWNETCONF, NLM_F_MULTI, | ||
1839 | -1) <= 0) | ||
1840 | goto done; | ||
1841 | else | ||
1842 | h++; | ||
1843 | } | ||
1844 | if (h == NETDEV_HASHENTRIES + 1) { | ||
1845 | if (inet_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT, | ||
1846 | net->ipv4.devconf_dflt, | ||
1847 | NETLINK_CB(cb->skb).portid, | ||
1848 | cb->nlh->nlmsg_seq, | ||
1849 | RTM_NEWNETCONF, NLM_F_MULTI, | ||
1850 | -1) <= 0) | ||
1851 | goto done; | ||
1852 | else | ||
1853 | h++; | ||
1854 | } | ||
1855 | done: | ||
1856 | cb->args[0] = h; | ||
1857 | cb->args[1] = idx; | ||
1858 | |||
1859 | return skb->len; | ||
1860 | } | ||
1861 | |||
1794 | #ifdef CONFIG_SYSCTL | 1862 | #ifdef CONFIG_SYSCTL |
1795 | 1863 | ||
1796 | static void devinet_copy_dflt_conf(struct net *net, int i) | 1864 | static void devinet_copy_dflt_conf(struct net *net, int i) |
@@ -2195,6 +2263,6 @@ void __init devinet_init(void) | |||
2195 | rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, NULL); | 2263 | rtnl_register(PF_INET, RTM_DELADDR, inet_rtm_deladdr, NULL, NULL); |
2196 | rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, NULL); | 2264 | rtnl_register(PF_INET, RTM_GETADDR, NULL, inet_dump_ifaddr, NULL); |
2197 | rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf, | 2265 | rtnl_register(PF_INET, RTM_GETNETCONF, inet_netconf_get_devconf, |
2198 | NULL, NULL); | 2266 | inet_netconf_dump_devconf, NULL); |
2199 | } | 2267 | } |
2200 | 2268 | ||