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 | |
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')
-rw-r--r-- | net/ipv4/devinet.c | 70 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 70 |
2 files changed, 138 insertions, 2 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 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index f2c7e615f902..fa36a677490f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -605,6 +605,74 @@ errout: | |||
605 | return err; | 605 | return err; |
606 | } | 606 | } |
607 | 607 | ||
608 | static int inet6_netconf_dump_devconf(struct sk_buff *skb, | ||
609 | struct netlink_callback *cb) | ||
610 | { | ||
611 | struct net *net = sock_net(skb->sk); | ||
612 | int h, s_h; | ||
613 | int idx, s_idx; | ||
614 | struct net_device *dev; | ||
615 | struct inet6_dev *idev; | ||
616 | struct hlist_head *head; | ||
617 | |||
618 | s_h = cb->args[0]; | ||
619 | s_idx = idx = cb->args[1]; | ||
620 | |||
621 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | ||
622 | idx = 0; | ||
623 | head = &net->dev_index_head[h]; | ||
624 | rcu_read_lock(); | ||
625 | hlist_for_each_entry_rcu(dev, head, index_hlist) { | ||
626 | if (idx < s_idx) | ||
627 | goto cont; | ||
628 | idev = __in6_dev_get(dev); | ||
629 | if (!idev) | ||
630 | goto cont; | ||
631 | |||
632 | if (inet6_netconf_fill_devconf(skb, dev->ifindex, | ||
633 | &idev->cnf, | ||
634 | NETLINK_CB(cb->skb).portid, | ||
635 | cb->nlh->nlmsg_seq, | ||
636 | RTM_NEWNETCONF, | ||
637 | NLM_F_MULTI, | ||
638 | -1) <= 0) { | ||
639 | rcu_read_unlock(); | ||
640 | goto done; | ||
641 | } | ||
642 | cont: | ||
643 | idx++; | ||
644 | } | ||
645 | rcu_read_unlock(); | ||
646 | } | ||
647 | if (h == NETDEV_HASHENTRIES) { | ||
648 | if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_ALL, | ||
649 | net->ipv6.devconf_all, | ||
650 | NETLINK_CB(cb->skb).portid, | ||
651 | cb->nlh->nlmsg_seq, | ||
652 | RTM_NEWNETCONF, NLM_F_MULTI, | ||
653 | -1) <= 0) | ||
654 | goto done; | ||
655 | else | ||
656 | h++; | ||
657 | } | ||
658 | if (h == NETDEV_HASHENTRIES + 1) { | ||
659 | if (inet6_netconf_fill_devconf(skb, NETCONFA_IFINDEX_DEFAULT, | ||
660 | net->ipv6.devconf_dflt, | ||
661 | NETLINK_CB(cb->skb).portid, | ||
662 | cb->nlh->nlmsg_seq, | ||
663 | RTM_NEWNETCONF, NLM_F_MULTI, | ||
664 | -1) <= 0) | ||
665 | goto done; | ||
666 | else | ||
667 | h++; | ||
668 | } | ||
669 | done: | ||
670 | cb->args[0] = h; | ||
671 | cb->args[1] = idx; | ||
672 | |||
673 | return skb->len; | ||
674 | } | ||
675 | |||
608 | #ifdef CONFIG_SYSCTL | 676 | #ifdef CONFIG_SYSCTL |
609 | static void dev_forward_change(struct inet6_dev *idev) | 677 | static void dev_forward_change(struct inet6_dev *idev) |
610 | { | 678 | { |
@@ -4940,7 +5008,7 @@ int __init addrconf_init(void) | |||
4940 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, | 5008 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, |
4941 | inet6_dump_ifacaddr, NULL); | 5009 | inet6_dump_ifacaddr, NULL); |
4942 | __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, | 5010 | __rtnl_register(PF_INET6, RTM_GETNETCONF, inet6_netconf_get_devconf, |
4943 | NULL, NULL); | 5011 | inet6_netconf_dump_devconf, NULL); |
4944 | 5012 | ||
4945 | ipv6_addr_label_rtnl_register(); | 5013 | ipv6_addr_label_rtnl_register(); |
4946 | 5014 | ||