addrconf.c (bcdd553fd3037d8700082ec4cbb6b25437ea06d6) addrconf.c (e21e8467d3188a36f7f0af0d4b9aae74e23fda0e)
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 67 unchanged lines hidden (view full) ---

76#include <net/pkt_sched.h>
77#include <linux/if_tunnel.h>
78#include <linux/rtnetlink.h>
79
80#ifdef CONFIG_IPV6_PRIVACY
81#include <linux/random.h>
82#endif
83
1/*
2 * IPv6 Address [auto]configuration
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
8 *

--- 67 unchanged lines hidden (view full) ---

76#include <net/pkt_sched.h>
77#include <linux/if_tunnel.h>
78#include <linux/rtnetlink.h>
79
80#ifdef CONFIG_IPV6_PRIVACY
81#include <linux/random.h>
82#endif
83
84#include <asm/uaccess.h>
84#include <linux/uaccess.h>
85#include <asm/unaligned.h>
86
87#include <linux/proc_fs.h>
88#include <linux/seq_file.h>
89
90/* Set to 3 to get tracing... */
91#define ACONF_DEBUG 2
92
93#if ACONF_DEBUG >= 3
94#define ADBG(x) printk x
95#else
96#define ADBG(x)
97#endif
98
99#define INFINITY_LIFE_TIME 0xFFFFFFFF
85#include <asm/unaligned.h>
86
87#include <linux/proc_fs.h>
88#include <linux/seq_file.h>
89
90/* Set to 3 to get tracing... */
91#define ACONF_DEBUG 2
92
93#if ACONF_DEBUG >= 3
94#define ADBG(x) printk x
95#else
96#define ADBG(x)
97#endif
98
99#define INFINITY_LIFE_TIME 0xFFFFFFFF
100#define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b)))
100#define TIME_DELTA(a, b) ((unsigned long)((long)(a) - (long)(b)))
101
102#ifdef CONFIG_SYSCTL
103static void addrconf_sysctl_register(struct inet6_dev *idev);
104static void addrconf_sysctl_unregister(struct inet6_dev *idev);
105#else
106static inline void addrconf_sysctl_register(struct inet6_dev *idev)
107{
108}

--- 135 unchanged lines hidden (view full) ---

244}
245
246static void addrconf_del_timer(struct inet6_ifaddr *ifp)
247{
248 if (del_timer(&ifp->timer))
249 __in6_ifa_put(ifp);
250}
251
101
102#ifdef CONFIG_SYSCTL
103static void addrconf_sysctl_register(struct inet6_dev *idev);
104static void addrconf_sysctl_unregister(struct inet6_dev *idev);
105#else
106static inline void addrconf_sysctl_register(struct inet6_dev *idev)
107{
108}

--- 135 unchanged lines hidden (view full) ---

244}
245
246static void addrconf_del_timer(struct inet6_ifaddr *ifp)
247{
248 if (del_timer(&ifp->timer))
249 __in6_ifa_put(ifp);
250}
251
252enum addrconf_timer_t
253{
252enum addrconf_timer_t {
254 AC_NONE,
255 AC_DAD,
256 AC_RS,
257};
258
259static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
260 enum addrconf_timer_t what,
261 unsigned long when)
262{
263 if (!del_timer(&ifp->timer))
264 in6_ifa_hold(ifp);
265
266 switch (what) {
267 case AC_DAD:
268 ifp->timer.function = addrconf_dad_timer;
269 break;
270 case AC_RS:
271 ifp->timer.function = addrconf_rs_timer;
272 break;
253 AC_NONE,
254 AC_DAD,
255 AC_RS,
256};
257
258static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
259 enum addrconf_timer_t what,
260 unsigned long when)
261{
262 if (!del_timer(&ifp->timer))
263 in6_ifa_hold(ifp);
264
265 switch (what) {
266 case AC_DAD:
267 ifp->timer.function = addrconf_dad_timer;
268 break;
269 case AC_RS:
270 ifp->timer.function = addrconf_rs_timer;
271 break;
273 default:;
272 default:
273 break;
274 }
275 ifp->timer.expires = jiffies + when;
276 add_timer(&ifp->timer);
277}
278
279static int snmp6_alloc_dev(struct inet6_dev *idev)
280{
281 if (snmp_mib_init((void __percpu **)idev->stats.ipv6,

--- 38 unchanged lines hidden (view full) ---

320 WARN_ON(!list_empty(&idev->addr_list));
321 WARN_ON(idev->mc_list != NULL);
322
323#ifdef NET_REFCNT_DEBUG
324 printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL");
325#endif
326 dev_put(dev);
327 if (!idev->dead) {
274 }
275 ifp->timer.expires = jiffies + when;
276 add_timer(&ifp->timer);
277}
278
279static int snmp6_alloc_dev(struct inet6_dev *idev)
280{
281 if (snmp_mib_init((void __percpu **)idev->stats.ipv6,

--- 38 unchanged lines hidden (view full) ---

320 WARN_ON(!list_empty(&idev->addr_list));
321 WARN_ON(idev->mc_list != NULL);
322
323#ifdef NET_REFCNT_DEBUG
324 printk(KERN_DEBUG "in6_dev_finish_destroy: %s\n", dev ? dev->name : "NIL");
325#endif
326 dev_put(dev);
327 if (!idev->dead) {
328 printk("Freeing alive inet6 device %p\n", idev);
328 pr_warning("Freeing alive inet6 device %p\n", idev);
329 return;
330 }
331 snmp6_free_dev(idev);
332 call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);
333}
334
335EXPORT_SYMBOL(in6_dev_finish_destroy);
336

--- 99 unchanged lines hidden (view full) ---

436}
437
438static struct inet6_dev * ipv6_find_idev(struct net_device *dev)
439{
440 struct inet6_dev *idev;
441
442 ASSERT_RTNL();
443
329 return;
330 }
331 snmp6_free_dev(idev);
332 call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);
333}
334
335EXPORT_SYMBOL(in6_dev_finish_destroy);
336

--- 99 unchanged lines hidden (view full) ---

436}
437
438static struct inet6_dev * ipv6_find_idev(struct net_device *dev)
439{
440 struct inet6_dev *idev;
441
442 ASSERT_RTNL();
443
444 if ((idev = __in6_dev_get(dev)) == NULL) {
445 if ((idev = ipv6_add_dev(dev)) == NULL)
444 idev = __in6_dev_get(dev);
445 if (!idev) {
446 idev = ipv6_add_dev(dev);
447 if (!idev)
446 return NULL;
447 }
448
449 if (dev->flags&IFF_UP)
450 ipv6_mc_up(idev);
451 return idev;
452}
453

--- 85 unchanged lines hidden (view full) ---

539
540#ifdef NET_REFCNT_DEBUG
541 printk(KERN_DEBUG "inet6_ifa_finish_destroy\n");
542#endif
543
544 in6_dev_put(ifp->idev);
545
546 if (del_timer(&ifp->timer))
448 return NULL;
449 }
450
451 if (dev->flags&IFF_UP)
452 ipv6_mc_up(idev);
453 return idev;
454}
455

--- 85 unchanged lines hidden (view full) ---

541
542#ifdef NET_REFCNT_DEBUG
543 printk(KERN_DEBUG "inet6_ifa_finish_destroy\n");
544#endif
545
546 in6_dev_put(ifp->idev);
547
548 if (del_timer(&ifp->timer))
547 printk("Timer is still running, when freeing ifa=%p\n", ifp);
549 pr_notice("Timer is still running, when freeing ifa=%p\n", ifp);
548
549 if (!ifp->dead) {
550
551 if (!ifp->dead) {
550 printk("Freeing alive inet6 address %p\n", ifp);
552 pr_warning("Freeing alive inet6 address %p\n", ifp);
551 return;
552 }
553 dst_release(&ifp->rt->u.dst);
554
555 call_rcu(&ifp->rcu, inet6_ifa_finish_destroy_rcu);
556}
557
558static void

--- 661 unchanged lines hidden (view full) ---

1220
1221 if (!hiscore->ifa)
1222 return -EADDRNOTAVAIL;
1223
1224 ipv6_addr_copy(saddr, &hiscore->ifa->addr);
1225 in6_ifa_put(hiscore->ifa);
1226 return 0;
1227}
553 return;
554 }
555 dst_release(&ifp->rt->u.dst);
556
557 call_rcu(&ifp->rcu, inet6_ifa_finish_destroy_rcu);
558}
559
560static void

--- 661 unchanged lines hidden (view full) ---

1222
1223 if (!hiscore->ifa)
1224 return -EADDRNOTAVAIL;
1225
1226 ipv6_addr_copy(saddr, &hiscore->ifa->addr);
1227 in6_ifa_put(hiscore->ifa);
1228 return 0;
1229}
1228
1229EXPORT_SYMBOL(ipv6_dev_get_saddr);
1230
1231int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
1232 unsigned char banned_flags)
1233{
1234 struct inet6_dev *idev;
1235 int err = -EADDRNOTAVAIL;
1236
1237 rcu_read_lock();
1230EXPORT_SYMBOL(ipv6_dev_get_saddr);
1231
1232int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
1233 unsigned char banned_flags)
1234{
1235 struct inet6_dev *idev;
1236 int err = -EADDRNOTAVAIL;
1237
1238 rcu_read_lock();
1238 if ((idev = __in6_dev_get(dev)) != NULL) {
1239 idev = __in6_dev_get(dev);
1240 if (idev) {
1239 struct inet6_ifaddr *ifp;
1240
1241 read_lock_bh(&idev->lock);
1242 list_for_each_entry(ifp, &idev->addr_list, if_list) {
1243 if (ifp->scope == IFA_LINK &&
1244 !(ifp->flags & banned_flags)) {
1245 ipv6_addr_copy(addr, &ifp->addr);
1246 err = 0;

--- 473 unchanged lines hidden (view full) ---

1720}
1721
1722static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
1723{
1724 struct inet6_dev *idev;
1725
1726 ASSERT_RTNL();
1727
1241 struct inet6_ifaddr *ifp;
1242
1243 read_lock_bh(&idev->lock);
1244 list_for_each_entry(ifp, &idev->addr_list, if_list) {
1245 if (ifp->scope == IFA_LINK &&
1246 !(ifp->flags & banned_flags)) {
1247 ipv6_addr_copy(addr, &ifp->addr);
1248 err = 0;

--- 473 unchanged lines hidden (view full) ---

1722}
1723
1724static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
1725{
1726 struct inet6_dev *idev;
1727
1728 ASSERT_RTNL();
1729
1728 if ((idev = ipv6_find_idev(dev)) == NULL)
1730 idev = ipv6_find_idev(dev);
1731 if (!idev)
1729 return NULL;
1730
1731 /* Add default multicast route */
1732 addrconf_add_mroute(dev);
1733
1734 /* Add link local route */
1735 addrconf_add_lroute(dev);
1736 return idev;

--- 691 unchanged lines hidden (view full) ---

2428 */
2429
2430static void addrconf_ip6_tnl_config(struct net_device *dev)
2431{
2432 struct inet6_dev *idev;
2433
2434 ASSERT_RTNL();
2435
1732 return NULL;
1733
1734 /* Add default multicast route */
1735 addrconf_add_mroute(dev);
1736
1737 /* Add link local route */
1738 addrconf_add_lroute(dev);
1739 return idev;

--- 691 unchanged lines hidden (view full) ---

2431 */
2432
2433static void addrconf_ip6_tnl_config(struct net_device *dev)
2434{
2435 struct inet6_dev *idev;
2436
2437 ASSERT_RTNL();
2438
2436 if ((idev = addrconf_add_dev(dev)) == NULL) {
2439 idev = addrconf_add_dev(dev);
2440 if (!idev) {
2437 printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n");
2438 return;
2439 }
2440 ip6_tnl_add_linklocal(idev);
2441}
2442
2443static int addrconf_notify(struct notifier_block *this, unsigned long event,
2444 void * data)
2445{
2446 struct net_device *dev = (struct net_device *) data;
2447 struct inet6_dev *idev = __in6_dev_get(dev);
2448 int run_pending = 0;
2449 int err;
2450
2441 printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n");
2442 return;
2443 }
2444 ip6_tnl_add_linklocal(idev);
2445}
2446
2447static int addrconf_notify(struct notifier_block *this, unsigned long event,
2448 void * data)
2449{
2450 struct net_device *dev = (struct net_device *) data;
2451 struct inet6_dev *idev = __in6_dev_get(dev);
2452 int run_pending = 0;
2453 int err;
2454
2451 switch(event) {
2455 switch (event) {
2452 case NETDEV_REGISTER:
2453 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
2454 idev = ipv6_add_dev(dev);
2455 if (!idev)
2456 return notifier_from_errno(-ENOMEM);
2457 }
2458 break;
2459

--- 35 unchanged lines hidden (view full) ---

2495 printk(KERN_INFO
2496 "ADDRCONF(NETDEV_CHANGE): %s: "
2497 "link becomes ready\n",
2498 dev->name);
2499
2500 run_pending = 1;
2501 }
2502
2456 case NETDEV_REGISTER:
2457 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
2458 idev = ipv6_add_dev(dev);
2459 if (!idev)
2460 return notifier_from_errno(-ENOMEM);
2461 }
2462 break;
2463

--- 35 unchanged lines hidden (view full) ---

2499 printk(KERN_INFO
2500 "ADDRCONF(NETDEV_CHANGE): %s: "
2501 "link becomes ready\n",
2502 dev->name);
2503
2504 run_pending = 1;
2505 }
2506
2503 switch(dev->type) {
2507 switch (dev->type) {
2504#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2505 case ARPHRD_SIT:
2506 addrconf_sit_config(dev);
2507 break;
2508#endif
2509 case ARPHRD_TUNNEL6:
2510 addrconf_ip6_tnl_config(dev);
2511 break;

--- 320 unchanged lines hidden (view full) ---

2832 addrconf_dad_stop(ifp, 0);
2833 return;
2834 }
2835
2836 /*
2837 * Optimistic nodes can start receiving
2838 * Frames right away
2839 */
2508#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2509 case ARPHRD_SIT:
2510 addrconf_sit_config(dev);
2511 break;
2512#endif
2513 case ARPHRD_TUNNEL6:
2514 addrconf_ip6_tnl_config(dev);
2515 break;

--- 320 unchanged lines hidden (view full) ---

2836 addrconf_dad_stop(ifp, 0);
2837 return;
2838 }
2839
2840 /*
2841 * Optimistic nodes can start receiving
2842 * Frames right away
2843 */
2840 if(ifp->flags & IFA_F_OPTIMISTIC)
2844 if (ifp->flags & IFA_F_OPTIMISTIC)
2841 ip6_ins_rt(ifp->rt);
2842
2843 addrconf_dad_kick(ifp);
2844 spin_unlock(&ifp->lock);
2845out:
2846 read_unlock_bh(&idev->lock);
2847}
2848

--- 33 unchanged lines hidden (view full) ---

2882 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
2883 ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any);
2884out:
2885 in6_ifa_put(ifp);
2886}
2887
2888static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2889{
2845 ip6_ins_rt(ifp->rt);
2846
2847 addrconf_dad_kick(ifp);
2848 spin_unlock(&ifp->lock);
2849out:
2850 read_unlock_bh(&idev->lock);
2851}
2852

--- 33 unchanged lines hidden (view full) ---

2886 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
2887 ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any);
2888out:
2889 in6_ifa_put(ifp);
2890}
2891
2892static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2893{
2890 struct net_device * dev = ifp->idev->dev;
2894 struct net_device *dev = ifp->idev->dev;
2891
2892 /*
2893 * Configure the address for reception. Now it is valid.
2894 */
2895
2896 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2897
2898 /* If added prefix is link local and forwarding is off,

--- 14 unchanged lines hidden (view full) ---

2913 spin_lock_bh(&ifp->lock);
2914 ifp->probes = 1;
2915 ifp->idev->if_flags |= IF_RS_SENT;
2916 addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval);
2917 spin_unlock_bh(&ifp->lock);
2918 }
2919}
2920
2895
2896 /*
2897 * Configure the address for reception. Now it is valid.
2898 */
2899
2900 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2901
2902 /* If added prefix is link local and forwarding is off,

--- 14 unchanged lines hidden (view full) ---

2917 spin_lock_bh(&ifp->lock);
2918 ifp->probes = 1;
2919 ifp->idev->if_flags |= IF_RS_SENT;
2920 addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval);
2921 spin_unlock_bh(&ifp->lock);
2922 }
2923}
2924
2921static void addrconf_dad_run(struct inet6_dev *idev) {
2925static void addrconf_dad_run(struct inet6_dev *idev)
2926{
2922 struct inet6_ifaddr *ifp;
2923
2924 read_lock_bh(&idev->lock);
2925 list_for_each_entry(ifp, &idev->addr_list, if_list) {
2926 spin_lock(&ifp->lock);
2927 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2928 spin_unlock(&ifp->lock);
2929 continue;

--- 48 unchanged lines hidden (view full) ---

2978 return NULL;
2979}
2980
2981static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
2982{
2983 struct inet6_ifaddr *ifa = if6_get_first(seq);
2984
2985 if (ifa)
2927 struct inet6_ifaddr *ifp;
2928
2929 read_lock_bh(&idev->lock);
2930 list_for_each_entry(ifp, &idev->addr_list, if_list) {
2931 spin_lock(&ifp->lock);
2932 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2933 spin_unlock(&ifp->lock);
2934 continue;

--- 48 unchanged lines hidden (view full) ---

2983 return NULL;
2984}
2985
2986static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
2987{
2988 struct inet6_ifaddr *ifa = if6_get_first(seq);
2989
2990 if (ifa)
2986 while(pos && (ifa = if6_get_next(seq, ifa)) != NULL)
2991 while (pos && (ifa = if6_get_next(seq, ifa)) != NULL)
2987 --pos;
2988 return pos ? NULL : ifa;
2989}
2990
2991static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
2992 __acquires(rcu)
2993{
2994 rcu_read_lock_bh();

--- 492 unchanged lines hidden (view full) ---

3487 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3488 nlmsg_cancel(skb, nlh);
3489 return -EMSGSIZE;
3490 }
3491
3492 return nlmsg_end(skb, nlh);
3493}
3494
2992 --pos;
2993 return pos ? NULL : ifa;
2994}
2995
2996static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
2997 __acquires(rcu)
2998{
2999 rcu_read_lock_bh();

--- 492 unchanged lines hidden (view full) ---

3492 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3493 nlmsg_cancel(skb, nlh);
3494 return -EMSGSIZE;
3495 }
3496
3497 return nlmsg_end(skb, nlh);
3498}
3499
3495enum addr_type_t
3496{
3500enum addr_type_t {
3497 UNICAST_ADDR,
3498 MULTICAST_ADDR,
3499 ANYCAST_ADDR,
3500};
3501
3502/* called with rcu_read_lock() */
3503static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3504 struct netlink_callback *cb, enum addr_type_t type,

--- 82 unchanged lines hidden (view full) ---

3587 idx = 0;
3588 head = &net->dev_index_head[h];
3589 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3590 if (idx < s_idx)
3591 goto cont;
3592 if (idx > s_idx)
3593 s_ip_idx = 0;
3594 ip_idx = 0;
3501 UNICAST_ADDR,
3502 MULTICAST_ADDR,
3503 ANYCAST_ADDR,
3504};
3505
3506/* called with rcu_read_lock() */
3507static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3508 struct netlink_callback *cb, enum addr_type_t type,

--- 82 unchanged lines hidden (view full) ---

3591 idx = 0;
3592 head = &net->dev_index_head[h];
3593 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3594 if (idx < s_idx)
3595 goto cont;
3596 if (idx > s_idx)
3597 s_ip_idx = 0;
3598 ip_idx = 0;
3595 if ((idev = __in6_dev_get(dev)) == NULL)
3599 idev = __in6_dev_get(dev);
3600 if (!idev)
3596 goto cont;
3597
3598 if (in6_dump_addrs(idev, skb, cb, type,
3599 s_ip_idx, &ip_idx) <= 0)
3600 goto done;
3601cont:
3602 idx++;
3603 }

--- 50 unchanged lines hidden (view full) ---

3654 err = -EINVAL;
3655 goto errout;
3656 }
3657
3658 ifm = nlmsg_data(nlh);
3659 if (ifm->ifa_index)
3660 dev = __dev_get_by_index(net, ifm->ifa_index);
3661
3601 goto cont;
3602
3603 if (in6_dump_addrs(idev, skb, cb, type,
3604 s_ip_idx, &ip_idx) <= 0)
3605 goto done;
3606cont:
3607 idx++;
3608 }

--- 50 unchanged lines hidden (view full) ---

3659 err = -EINVAL;
3660 goto errout;
3661 }
3662
3663 ifm = nlmsg_data(nlh);
3664 if (ifm->ifa_index)
3665 dev = __dev_get_by_index(net, ifm->ifa_index);
3666
3662 if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) {
3667 ifa = ipv6_get_ifaddr(net, addr, dev, 1);
3668 if (!ifa) {
3663 err = -EADDRNOTAVAIL;
3664 goto errout;
3665 }
3666
3669 err = -EADDRNOTAVAIL;
3670 goto errout;
3671 }
3672
3667 if ((skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL)) == NULL) {
3673 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL);
3674 if (!skb) {
3668 err = -ENOBUFS;
3669 goto errout_ifa;
3670 }
3671
3672 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3673 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3674 if (err < 0) {
3675 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */

--- 108 unchanged lines hidden (view full) ---

3784 put_unaligned(snmp_fold_field(mib, i), &stats[i]);
3785
3786 memset(&stats[items], 0, pad);
3787}
3788
3789static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3790 int bytes)
3791{
3675 err = -ENOBUFS;
3676 goto errout_ifa;
3677 }
3678
3679 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3680 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3681 if (err < 0) {
3682 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */

--- 108 unchanged lines hidden (view full) ---

3791 put_unaligned(snmp_fold_field(mib, i), &stats[i]);
3792
3793 memset(&stats[items], 0, pad);
3794}
3795
3796static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3797 int bytes)
3798{
3792 switch(attrtype) {
3799 switch (attrtype) {
3793 case IFLA_INET6_STATS:
3794 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3795 break;
3796 case IFLA_INET6_ICMP6STATS:
3797 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3798 break;
3799 }
3800}

--- 335 unchanged lines hidden (view full) ---

4136{
4137 struct ctl_table_header *sysctl_header;
4138 ctl_table addrconf_vars[DEVCONF_MAX+1];
4139 char *dev_name;
4140} addrconf_sysctl __read_mostly = {
4141 .sysctl_header = NULL,
4142 .addrconf_vars = {
4143 {
3800 case IFLA_INET6_STATS:
3801 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3802 break;
3803 case IFLA_INET6_ICMP6STATS:
3804 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3805 break;
3806 }
3807}

--- 335 unchanged lines hidden (view full) ---

4143{
4144 struct ctl_table_header *sysctl_header;
4145 ctl_table addrconf_vars[DEVCONF_MAX+1];
4146 char *dev_name;
4147} addrconf_sysctl __read_mostly = {
4148 .sysctl_header = NULL,
4149 .addrconf_vars = {
4150 {
4144 .procname = "forwarding",
4145 .data = &ipv6_devconf.forwarding,
4146 .maxlen = sizeof(int),
4147 .mode = 0644,
4148 .proc_handler = addrconf_sysctl_forward,
4151 .procname = "forwarding",
4152 .data = &ipv6_devconf.forwarding,
4153 .maxlen = sizeof(int),
4154 .mode = 0644,
4155 .proc_handler = addrconf_sysctl_forward,
4149 },
4150 {
4156 },
4157 {
4151 .procname = "hop_limit",
4152 .data = &ipv6_devconf.hop_limit,
4153 .maxlen = sizeof(int),
4154 .mode = 0644,
4155 .proc_handler = proc_dointvec,
4158 .procname = "hop_limit",
4159 .data = &ipv6_devconf.hop_limit,
4160 .maxlen = sizeof(int),
4161 .mode = 0644,
4162 .proc_handler = proc_dointvec,
4156 },
4157 {
4163 },
4164 {
4158 .procname = "mtu",
4159 .data = &ipv6_devconf.mtu6,
4160 .maxlen = sizeof(int),
4161 .mode = 0644,
4162 .proc_handler = proc_dointvec,
4165 .procname = "mtu",
4166 .data = &ipv6_devconf.mtu6,
4167 .maxlen = sizeof(int),
4168 .mode = 0644,
4169 .proc_handler = proc_dointvec,
4163 },
4164 {
4170 },
4171 {
4165 .procname = "accept_ra",
4166 .data = &ipv6_devconf.accept_ra,
4167 .maxlen = sizeof(int),
4168 .mode = 0644,
4169 .proc_handler = proc_dointvec,
4172 .procname = "accept_ra",
4173 .data = &ipv6_devconf.accept_ra,
4174 .maxlen = sizeof(int),
4175 .mode = 0644,
4176 .proc_handler = proc_dointvec,
4170 },
4171 {
4177 },
4178 {
4172 .procname = "accept_redirects",
4173 .data = &ipv6_devconf.accept_redirects,
4174 .maxlen = sizeof(int),
4175 .mode = 0644,
4176 .proc_handler = proc_dointvec,
4179 .procname = "accept_redirects",
4180 .data = &ipv6_devconf.accept_redirects,
4181 .maxlen = sizeof(int),
4182 .mode = 0644,
4183 .proc_handler = proc_dointvec,
4177 },
4178 {
4184 },
4185 {
4179 .procname = "autoconf",
4180 .data = &ipv6_devconf.autoconf,
4181 .maxlen = sizeof(int),
4182 .mode = 0644,
4183 .proc_handler = proc_dointvec,
4186 .procname = "autoconf",
4187 .data = &ipv6_devconf.autoconf,
4188 .maxlen = sizeof(int),
4189 .mode = 0644,
4190 .proc_handler = proc_dointvec,
4184 },
4185 {
4191 },
4192 {
4186 .procname = "dad_transmits",
4187 .data = &ipv6_devconf.dad_transmits,
4188 .maxlen = sizeof(int),
4189 .mode = 0644,
4190 .proc_handler = proc_dointvec,
4193 .procname = "dad_transmits",
4194 .data = &ipv6_devconf.dad_transmits,
4195 .maxlen = sizeof(int),
4196 .mode = 0644,
4197 .proc_handler = proc_dointvec,
4191 },
4192 {
4198 },
4199 {
4193 .procname = "router_solicitations",
4194 .data = &ipv6_devconf.rtr_solicits,
4195 .maxlen = sizeof(int),
4196 .mode = 0644,
4197 .proc_handler = proc_dointvec,
4200 .procname = "router_solicitations",
4201 .data = &ipv6_devconf.rtr_solicits,
4202 .maxlen = sizeof(int),
4203 .mode = 0644,
4204 .proc_handler = proc_dointvec,
4198 },
4199 {
4205 },
4206 {
4200 .procname = "router_solicitation_interval",
4201 .data = &ipv6_devconf.rtr_solicit_interval,
4202 .maxlen = sizeof(int),
4203 .mode = 0644,
4204 .proc_handler = proc_dointvec_jiffies,
4207 .procname = "router_solicitation_interval",
4208 .data = &ipv6_devconf.rtr_solicit_interval,
4209 .maxlen = sizeof(int),
4210 .mode = 0644,
4211 .proc_handler = proc_dointvec_jiffies,
4205 },
4206 {
4212 },
4213 {
4207 .procname = "router_solicitation_delay",
4208 .data = &ipv6_devconf.rtr_solicit_delay,
4209 .maxlen = sizeof(int),
4210 .mode = 0644,
4211 .proc_handler = proc_dointvec_jiffies,
4214 .procname = "router_solicitation_delay",
4215 .data = &ipv6_devconf.rtr_solicit_delay,
4216 .maxlen = sizeof(int),
4217 .mode = 0644,
4218 .proc_handler = proc_dointvec_jiffies,
4212 },
4213 {
4219 },
4220 {
4214 .procname = "force_mld_version",
4215 .data = &ipv6_devconf.force_mld_version,
4216 .maxlen = sizeof(int),
4217 .mode = 0644,
4218 .proc_handler = proc_dointvec,
4221 .procname = "force_mld_version",
4222 .data = &ipv6_devconf.force_mld_version,
4223 .maxlen = sizeof(int),
4224 .mode = 0644,
4225 .proc_handler = proc_dointvec,
4219 },
4220#ifdef CONFIG_IPV6_PRIVACY
4221 {
4226 },
4227#ifdef CONFIG_IPV6_PRIVACY
4228 {
4222 .procname = "use_tempaddr",
4223 .data = &ipv6_devconf.use_tempaddr,
4224 .maxlen = sizeof(int),
4225 .mode = 0644,
4226 .proc_handler = proc_dointvec,
4229 .procname = "use_tempaddr",
4230 .data = &ipv6_devconf.use_tempaddr,
4231 .maxlen = sizeof(int),
4232 .mode = 0644,
4233 .proc_handler = proc_dointvec,
4227 },
4228 {
4234 },
4235 {
4229 .procname = "temp_valid_lft",
4230 .data = &ipv6_devconf.temp_valid_lft,
4231 .maxlen = sizeof(int),
4232 .mode = 0644,
4233 .proc_handler = proc_dointvec,
4236 .procname = "temp_valid_lft",
4237 .data = &ipv6_devconf.temp_valid_lft,
4238 .maxlen = sizeof(int),
4239 .mode = 0644,
4240 .proc_handler = proc_dointvec,
4234 },
4235 {
4241 },
4242 {
4236 .procname = "temp_prefered_lft",
4237 .data = &ipv6_devconf.temp_prefered_lft,
4238 .maxlen = sizeof(int),
4239 .mode = 0644,
4240 .proc_handler = proc_dointvec,
4243 .procname = "temp_prefered_lft",
4244 .data = &ipv6_devconf.temp_prefered_lft,
4245 .maxlen = sizeof(int),
4246 .mode = 0644,
4247 .proc_handler = proc_dointvec,
4241 },
4242 {
4248 },
4249 {
4243 .procname = "regen_max_retry",
4244 .data = &ipv6_devconf.regen_max_retry,
4245 .maxlen = sizeof(int),
4246 .mode = 0644,
4247 .proc_handler = proc_dointvec,
4250 .procname = "regen_max_retry",
4251 .data = &ipv6_devconf.regen_max_retry,
4252 .maxlen = sizeof(int),
4253 .mode = 0644,
4254 .proc_handler = proc_dointvec,
4248 },
4249 {
4255 },
4256 {
4250 .procname = "max_desync_factor",
4251 .data = &ipv6_devconf.max_desync_factor,
4252 .maxlen = sizeof(int),
4253 .mode = 0644,
4254 .proc_handler = proc_dointvec,
4257 .procname = "max_desync_factor",
4258 .data = &ipv6_devconf.max_desync_factor,
4259 .maxlen = sizeof(int),
4260 .mode = 0644,
4261 .proc_handler = proc_dointvec,
4255 },
4256#endif
4257 {
4262 },
4263#endif
4264 {
4258 .procname = "max_addresses",
4259 .data = &ipv6_devconf.max_addresses,
4260 .maxlen = sizeof(int),
4261 .mode = 0644,
4262 .proc_handler = proc_dointvec,
4265 .procname = "max_addresses",
4266 .data = &ipv6_devconf.max_addresses,
4267 .maxlen = sizeof(int),
4268 .mode = 0644,
4269 .proc_handler = proc_dointvec,
4263 },
4264 {
4270 },
4271 {
4265 .procname = "accept_ra_defrtr",
4266 .data = &ipv6_devconf.accept_ra_defrtr,
4267 .maxlen = sizeof(int),
4268 .mode = 0644,
4269 .proc_handler = proc_dointvec,
4272 .procname = "accept_ra_defrtr",
4273 .data = &ipv6_devconf.accept_ra_defrtr,
4274 .maxlen = sizeof(int),
4275 .mode = 0644,
4276 .proc_handler = proc_dointvec,
4270 },
4271 {
4277 },
4278 {
4272 .procname = "accept_ra_pinfo",
4273 .data = &ipv6_devconf.accept_ra_pinfo,
4274 .maxlen = sizeof(int),
4275 .mode = 0644,
4276 .proc_handler = proc_dointvec,
4279 .procname = "accept_ra_pinfo",
4280 .data = &ipv6_devconf.accept_ra_pinfo,
4281 .maxlen = sizeof(int),
4282 .mode = 0644,
4283 .proc_handler = proc_dointvec,
4277 },
4278#ifdef CONFIG_IPV6_ROUTER_PREF
4279 {
4284 },
4285#ifdef CONFIG_IPV6_ROUTER_PREF
4286 {
4280 .procname = "accept_ra_rtr_pref",
4281 .data = &ipv6_devconf.accept_ra_rtr_pref,
4282 .maxlen = sizeof(int),
4283 .mode = 0644,
4284 .proc_handler = proc_dointvec,
4287 .procname = "accept_ra_rtr_pref",
4288 .data = &ipv6_devconf.accept_ra_rtr_pref,
4289 .maxlen = sizeof(int),
4290 .mode = 0644,
4291 .proc_handler = proc_dointvec,
4285 },
4286 {
4292 },
4293 {
4287 .procname = "router_probe_interval",
4288 .data = &ipv6_devconf.rtr_probe_interval,
4289 .maxlen = sizeof(int),
4290 .mode = 0644,
4291 .proc_handler = proc_dointvec_jiffies,
4294 .procname = "router_probe_interval",
4295 .data = &ipv6_devconf.rtr_probe_interval,
4296 .maxlen = sizeof(int),
4297 .mode = 0644,
4298 .proc_handler = proc_dointvec_jiffies,
4292 },
4293#ifdef CONFIG_IPV6_ROUTE_INFO
4294 {
4299 },
4300#ifdef CONFIG_IPV6_ROUTE_INFO
4301 {
4295 .procname = "accept_ra_rt_info_max_plen",
4296 .data = &ipv6_devconf.accept_ra_rt_info_max_plen,
4297 .maxlen = sizeof(int),
4298 .mode = 0644,
4299 .proc_handler = proc_dointvec,
4302 .procname = "accept_ra_rt_info_max_plen",
4303 .data = &ipv6_devconf.accept_ra_rt_info_max_plen,
4304 .maxlen = sizeof(int),
4305 .mode = 0644,
4306 .proc_handler = proc_dointvec,
4300 },
4301#endif
4302#endif
4303 {
4307 },
4308#endif
4309#endif
4310 {
4304 .procname = "proxy_ndp",
4305 .data = &ipv6_devconf.proxy_ndp,
4306 .maxlen = sizeof(int),
4307 .mode = 0644,
4308 .proc_handler = proc_dointvec,
4311 .procname = "proxy_ndp",
4312 .data = &ipv6_devconf.proxy_ndp,
4313 .maxlen = sizeof(int),
4314 .mode = 0644,
4315 .proc_handler = proc_dointvec,
4309 },
4310 {
4316 },
4317 {
4311 .procname = "accept_source_route",
4312 .data = &ipv6_devconf.accept_source_route,
4313 .maxlen = sizeof(int),
4314 .mode = 0644,
4315 .proc_handler = proc_dointvec,
4318 .procname = "accept_source_route",
4319 .data = &ipv6_devconf.accept_source_route,
4320 .maxlen = sizeof(int),
4321 .mode = 0644,
4322 .proc_handler = proc_dointvec,
4316 },
4317#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
4318 {
4323 },
4324#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
4325 {
4319 .procname = "optimistic_dad",
4320 .data = &ipv6_devconf.optimistic_dad,
4321 .maxlen = sizeof(int),
4322 .mode = 0644,
4323 .proc_handler = proc_dointvec,
4326 .procname = "optimistic_dad",
4327 .data = &ipv6_devconf.optimistic_dad,
4328 .maxlen = sizeof(int),
4329 .mode = 0644,
4330 .proc_handler = proc_dointvec,
4324
4325 },
4326#endif
4327#ifdef CONFIG_IPV6_MROUTE
4328 {
4331
4332 },
4333#endif
4334#ifdef CONFIG_IPV6_MROUTE
4335 {
4329 .procname = "mc_forwarding",
4330 .data = &ipv6_devconf.mc_forwarding,
4331 .maxlen = sizeof(int),
4332 .mode = 0444,
4333 .proc_handler = proc_dointvec,
4336 .procname = "mc_forwarding",
4337 .data = &ipv6_devconf.mc_forwarding,
4338 .maxlen = sizeof(int),
4339 .mode = 0444,
4340 .proc_handler = proc_dointvec,
4334 },
4335#endif
4336 {
4341 },
4342#endif
4343 {
4337 .procname = "disable_ipv6",
4338 .data = &ipv6_devconf.disable_ipv6,
4339 .maxlen = sizeof(int),
4340 .mode = 0644,
4341 .proc_handler = addrconf_sysctl_disable,
4344 .procname = "disable_ipv6",
4345 .data = &ipv6_devconf.disable_ipv6,
4346 .maxlen = sizeof(int),
4347 .mode = 0644,
4348 .proc_handler = addrconf_sysctl_disable,
4342 },
4343 {
4349 },
4350 {
4344 .procname = "accept_dad",
4345 .data = &ipv6_devconf.accept_dad,
4346 .maxlen = sizeof(int),
4347 .mode = 0644,
4348 .proc_handler = proc_dointvec,
4351 .procname = "accept_dad",
4352 .data = &ipv6_devconf.accept_dad,
4353 .maxlen = sizeof(int),
4354 .mode = 0644,
4355 .proc_handler = proc_dointvec,
4349 },
4350 {
4351 .procname = "force_tllao",
4352 .data = &ipv6_devconf.force_tllao,
4353 .maxlen = sizeof(int),
4354 .mode = 0644,
4355 .proc_handler = proc_dointvec
4356 },

--- 20 unchanged lines hidden (view full) ---

4377 };
4378
4379
4380 t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
4381 if (t == NULL)
4382 goto out;
4383
4384 for (i = 0; t->addrconf_vars[i].data; i++) {
4356 },
4357 {
4358 .procname = "force_tllao",
4359 .data = &ipv6_devconf.force_tllao,
4360 .maxlen = sizeof(int),
4361 .mode = 0644,
4362 .proc_handler = proc_dointvec
4363 },

--- 20 unchanged lines hidden (view full) ---

4384 };
4385
4386
4387 t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
4388 if (t == NULL)
4389 goto out;
4390
4391 for (i = 0; t->addrconf_vars[i].data; i++) {
4385 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
4392 t->addrconf_vars[i].data += (char *)p - (char *)&ipv6_devconf;
4386 t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
4387 t->addrconf_vars[i].extra2 = net;
4388 }
4389
4390 /*
4391 * Make a copy of dev_name, because '.procname' is regarded as const
4392 * by sysctl and we wouldn't want anyone to change it under our feet
4393 * (see SIOCSIFNAME).

--- 120 unchanged lines hidden (view full) ---

4514/*
4515 * Device notifier
4516 */
4517
4518int register_inet6addr_notifier(struct notifier_block *nb)
4519{
4520 return atomic_notifier_chain_register(&inet6addr_chain, nb);
4521}
4393 t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
4394 t->addrconf_vars[i].extra2 = net;
4395 }
4396
4397 /*
4398 * Make a copy of dev_name, because '.procname' is regarded as const
4399 * by sysctl and we wouldn't want anyone to change it under our feet
4400 * (see SIOCSIFNAME).

--- 120 unchanged lines hidden (view full) ---

4521/*
4522 * Device notifier
4523 */
4524
4525int register_inet6addr_notifier(struct notifier_block *nb)
4526{
4527 return atomic_notifier_chain_register(&inet6addr_chain, nb);
4528}
4522
4523EXPORT_SYMBOL(register_inet6addr_notifier);
4524
4525int unregister_inet6addr_notifier(struct notifier_block *nb)
4526{
4529EXPORT_SYMBOL(register_inet6addr_notifier);
4530
4531int unregister_inet6addr_notifier(struct notifier_block *nb)
4532{
4527 return atomic_notifier_chain_unregister(&inet6addr_chain,nb);
4533 return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
4528}
4534}
4529
4530EXPORT_SYMBOL(unregister_inet6addr_notifier);
4531
4532/*
4533 * Init / cleanup code
4534 */
4535
4536int __init addrconf_init(void)
4537{
4538 int i, err;
4539
4535EXPORT_SYMBOL(unregister_inet6addr_notifier);
4536
4537/*
4538 * Init / cleanup code
4539 */
4540
4541int __init addrconf_init(void)
4542{
4543 int i, err;
4544
4540 if ((err = ipv6_addr_label_init()) < 0) {
4541 printk(KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n",
4542 err);
4545 err = ipv6_addr_label_init();
4546 if (err < 0) {
4547 printk(KERN_CRIT "IPv6 Addrconf:"
4548 " cannot initialize default policy table: %d.\n", err);
4543 return err;
4544 }
4545
4546 register_pernet_subsys(&addrconf_ops);
4547
4548 /* The addrconf netdev notifier requires that loopback_dev
4549 * has it's ipv6 private information allocated and setup
4550 * before it can bring up and give link-local addresses

--- 80 unchanged lines hidden ---
4549 return err;
4550 }
4551
4552 register_pernet_subsys(&addrconf_ops);
4553
4554 /* The addrconf netdev notifier requires that loopback_dev
4555 * has it's ipv6 private information allocated and setup
4556 * before it can bring up and give link-local addresses

--- 80 unchanged lines hidden ---