addrconf.c (0b28330e39bbe0ffee4c56b09fc415fcec595ea3) addrconf.c (eedf042a63ffef050ebc015de19b52dc065e830b)
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 *

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

77#include <net/pkt_sched.h>
78#include <linux/if_tunnel.h>
79#include <linux/rtnetlink.h>
80
81#ifdef CONFIG_IPV6_PRIVACY
82#include <linux/random.h>
83#endif
84
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 *

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

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

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

122#endif
123
124static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
125static int ipv6_count_addresses(struct inet6_dev *idev);
126
127/*
128 * Configured unicast address hash table
129 */
107#ifdef CONFIG_SYSCTL
108static void addrconf_sysctl_register(struct inet6_dev *idev);
109static void addrconf_sysctl_unregister(struct inet6_dev *idev);
110#else
111static inline void addrconf_sysctl_register(struct inet6_dev *idev)
112{
113}
114

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

126#endif
127
128static int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
129static int ipv6_count_addresses(struct inet6_dev *idev);
130
131/*
132 * Configured unicast address hash table
133 */
130static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE];
131static DEFINE_RWLOCK(addrconf_hash_lock);
134static struct hlist_head inet6_addr_lst[IN6_ADDR_HSIZE];
135static DEFINE_SPINLOCK(addrconf_hash_lock);
132
133static void addrconf_verify(unsigned long);
134
135static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
136static DEFINE_SPINLOCK(addrconf_verify_lock);
137
138static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
139static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
140
136
137static void addrconf_verify(unsigned long);
138
139static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0);
140static DEFINE_SPINLOCK(addrconf_verify_lock);
141
142static void addrconf_join_anycast(struct inet6_ifaddr *ifp);
143static void addrconf_leave_anycast(struct inet6_ifaddr *ifp);
144
141static void addrconf_bonding_change(struct net_device *dev,
142 unsigned long event);
145static void addrconf_type_change(struct net_device *dev,
146 unsigned long event);
143static int addrconf_ifdown(struct net_device *dev, int how);
144
145static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
146static void addrconf_dad_timer(unsigned long data);
147static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
148static void addrconf_dad_run(struct inet6_dev *idev);
149static void addrconf_rs_timer(unsigned long data);
150static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
151static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
152
153static void inet6_prefix_notify(int event, struct inet6_dev *idev,
154 struct prefix_info *pinfo);
147static int addrconf_ifdown(struct net_device *dev, int how);
148
149static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags);
150static void addrconf_dad_timer(unsigned long data);
151static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
152static void addrconf_dad_run(struct inet6_dev *idev);
153static void addrconf_rs_timer(unsigned long data);
154static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
155static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
156
157static void inet6_prefix_notify(int event, struct inet6_dev *idev,
158 struct prefix_info *pinfo);
155static int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
156 struct net_device *dev);
159static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
160 struct net_device *dev);
157
158static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
159
160static struct ipv6_devconf ipv6_devconf __read_mostly = {
161 .forwarding = 0,
162 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
163 .mtu6 = IPV6_MIN_MTU,
164 .accept_ra = 1,

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

245}
246
247static void addrconf_del_timer(struct inet6_ifaddr *ifp)
248{
249 if (del_timer(&ifp->timer))
250 __in6_ifa_put(ifp);
251}
252
161
162static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
163
164static struct ipv6_devconf ipv6_devconf __read_mostly = {
165 .forwarding = 0,
166 .hop_limit = IPV6_DEFAULT_HOPLIMIT,
167 .mtu6 = IPV6_MIN_MTU,
168 .accept_ra = 1,

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

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

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

313 struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu);
314 kfree(idev);
315}
316
317void in6_dev_finish_destroy(struct inet6_dev *idev)
318{
319 struct net_device *dev = idev->dev;
320
279 }
280 ifp->timer.expires = jiffies + when;
281 add_timer(&ifp->timer);
282}
283
284static int snmp6_alloc_dev(struct inet6_dev *idev)
285{
286 if (snmp_mib_init((void __percpu **)idev->stats.ipv6,

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

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

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

346
347 ndev = kzalloc(sizeof(struct inet6_dev), GFP_KERNEL);
348
349 if (ndev == NULL)
350 return NULL;
351
352 rwlock_init(&ndev->lock);
353 ndev->dev = dev;
334 return;
335 }
336 snmp6_free_dev(idev);
337 call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu);
338}
339
340EXPORT_SYMBOL(in6_dev_finish_destroy);
341

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

350
351 ndev = kzalloc(sizeof(struct inet6_dev), GFP_KERNEL);
352
353 if (ndev == NULL)
354 return NULL;
355
356 rwlock_init(&ndev->lock);
357 ndev->dev = dev;
358 INIT_LIST_HEAD(&ndev->addr_list);
359
354 memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
355 ndev->cnf.mtu6 = dev->mtu;
356 ndev->cnf.sysctl = NULL;
357 ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
358 if (ndev->nd_parms == NULL) {
359 kfree(ndev);
360 return NULL;
361 }

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

397 printk(KERN_INFO
398 "%s: Disabled Multicast RS\n",
399 dev->name);
400 ndev->cnf.rtr_solicits = 0;
401 }
402#endif
403
404#ifdef CONFIG_IPV6_PRIVACY
360 memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
361 ndev->cnf.mtu6 = dev->mtu;
362 ndev->cnf.sysctl = NULL;
363 ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
364 if (ndev->nd_parms == NULL) {
365 kfree(ndev);
366 return NULL;
367 }

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

403 printk(KERN_INFO
404 "%s: Disabled Multicast RS\n",
405 dev->name);
406 ndev->cnf.rtr_solicits = 0;
407 }
408#endif
409
410#ifdef CONFIG_IPV6_PRIVACY
411 INIT_LIST_HEAD(&ndev->tempaddr_list);
405 setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev);
406 if ((dev->flags&IFF_LOOPBACK) ||
407 dev->type == ARPHRD_TUNNEL ||
408 dev->type == ARPHRD_TUNNEL6 ||
409 dev->type == ARPHRD_SIT ||
410 dev->type == ARPHRD_NONE) {
411 printk(KERN_INFO
412 "%s: Disabled Privacy Extensions\n",

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

434}
435
436static struct inet6_dev * ipv6_find_idev(struct net_device *dev)
437{
438 struct inet6_dev *idev;
439
440 ASSERT_RTNL();
441
412 setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev);
413 if ((dev->flags&IFF_LOOPBACK) ||
414 dev->type == ARPHRD_TUNNEL ||
415 dev->type == ARPHRD_TUNNEL6 ||
416 dev->type == ARPHRD_SIT ||
417 dev->type == ARPHRD_NONE) {
418 printk(KERN_INFO
419 "%s: Disabled Privacy Extensions\n",

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

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

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

461 if (idev->cnf.forwarding)
462 dev_disable_lro(dev);
463 if (dev && (dev->flags & IFF_MULTICAST)) {
464 if (idev->cnf.forwarding)
465 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
466 else
467 ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters);
468 }
453 return NULL;
454 }
455
456 if (dev->flags&IFF_UP)
457 ipv6_mc_up(idev);
458 return idev;
459}
460

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

470 if (idev->cnf.forwarding)
471 dev_disable_lro(dev);
472 if (dev && (dev->flags & IFF_MULTICAST)) {
473 if (idev->cnf.forwarding)
474 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
475 else
476 ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters);
477 }
469 for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
478
479 list_for_each_entry(ifa, &idev->addr_list, if_list) {
470 if (ifa->flags&IFA_F_TENTATIVE)
471 continue;
472 if (idev->cnf.forwarding)
473 addrconf_join_anycast(ifa);
474 else
475 addrconf_leave_anycast(ifa);
476 }
477}

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

518 rtnl_unlock();
519
520 if (*p)
521 rt6_purge_dflt_routers(net);
522 return 1;
523}
524#endif
525
480 if (ifa->flags&IFA_F_TENTATIVE)
481 continue;
482 if (idev->cnf.forwarding)
483 addrconf_join_anycast(ifa);
484 else
485 addrconf_leave_anycast(ifa);
486 }
487}

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

528 rtnl_unlock();
529
530 if (*p)
531 rt6_purge_dflt_routers(net);
532 return 1;
533}
534#endif
535
526/* Nobody refers to this ifaddr, destroy it */
536static void inet6_ifa_finish_destroy_rcu(struct rcu_head *head)
537{
538 struct inet6_ifaddr *ifp = container_of(head, struct inet6_ifaddr, rcu);
539 kfree(ifp);
540}
527
541
542/* Nobody refers to this ifaddr, destroy it */
528void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
529{
543void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
544{
530 WARN_ON(ifp->if_next != NULL);
531 WARN_ON(ifp->lst_next != NULL);
545 WARN_ON(!hlist_unhashed(&ifp->addr_lst));
532
533#ifdef NET_REFCNT_DEBUG
534 printk(KERN_DEBUG "inet6_ifa_finish_destroy\n");
535#endif
536
537 in6_dev_put(ifp->idev);
538
539 if (del_timer(&ifp->timer))
546
547#ifdef NET_REFCNT_DEBUG
548 printk(KERN_DEBUG "inet6_ifa_finish_destroy\n");
549#endif
550
551 in6_dev_put(ifp->idev);
552
553 if (del_timer(&ifp->timer))
540 printk("Timer is still running, when freeing ifa=%p\n", ifp);
554 pr_notice("Timer is still running, when freeing ifa=%p\n", ifp);
541
542 if (!ifp->dead) {
555
556 if (!ifp->dead) {
543 printk("Freeing alive inet6 address %p\n", ifp);
557 pr_warning("Freeing alive inet6 address %p\n", ifp);
544 return;
545 }
546 dst_release(&ifp->rt->u.dst);
547
558 return;
559 }
560 dst_release(&ifp->rt->u.dst);
561
548 kfree(ifp);
562 call_rcu(&ifp->rcu, inet6_ifa_finish_destroy_rcu);
549}
550
551static void
552ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
553{
563}
564
565static void
566ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
567{
554 struct inet6_ifaddr *ifa, **ifap;
568 struct list_head *p;
555 int ifp_scope = ipv6_addr_src_scope(&ifp->addr);
556
557 /*
558 * Each device address list is sorted in order of scope -
559 * global before linklocal.
560 */
569 int ifp_scope = ipv6_addr_src_scope(&ifp->addr);
570
571 /*
572 * Each device address list is sorted in order of scope -
573 * global before linklocal.
574 */
561 for (ifap = &idev->addr_list; (ifa = *ifap) != NULL;
562 ifap = &ifa->if_next) {
575 list_for_each(p, &idev->addr_list) {
576 struct inet6_ifaddr *ifa
577 = list_entry(p, struct inet6_ifaddr, if_list);
563 if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr))
564 break;
565 }
566
578 if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr))
579 break;
580 }
581
567 ifp->if_next = *ifap;
568 *ifap = ifp;
582 list_add_tail(&ifp->if_list, p);
569}
570
583}
584
571/*
572 * Hash function taken from net_alias.c
573 */
574static u8 ipv6_addr_hash(const struct in6_addr *addr)
585static u32 ipv6_addr_hash(const struct in6_addr *addr)
575{
586{
576 __u32 word;
577
578 /*
579 * We perform the hash function over the last 64 bits of the address
580 * This will include the IEEE address token on links that support it.
581 */
587 /*
588 * We perform the hash function over the last 64 bits of the address
589 * This will include the IEEE address token on links that support it.
590 */
582
583 word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]);
584 word ^= (word >> 16);
585 word ^= (word >> 8);
586
587 return ((word ^ (word >> 4)) & 0x0f);
591 return jhash_2words((__force u32)addr->s6_addr32[2],
592 (__force u32)addr->s6_addr32[3], 0)
593 & (IN6_ADDR_HSIZE - 1);
588}
589
590/* On success it returns ifp with increased reference count */
591
592static struct inet6_ifaddr *
593ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
594 int scope, u32 flags)
595{
596 struct inet6_ifaddr *ifa = NULL;
597 struct rt6_info *rt;
594}
595
596/* On success it returns ifp with increased reference count */
597
598static struct inet6_ifaddr *
599ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
600 int scope, u32 flags)
601{
602 struct inet6_ifaddr *ifa = NULL;
603 struct rt6_info *rt;
598 int hash;
604 unsigned int hash;
599 int err = 0;
600 int addr_type = ipv6_addr_type(addr);
601
602 if (addr_type == IPV6_ADDR_ANY ||
603 addr_type & IPV6_ADDR_MULTICAST ||
604 (!(idev->dev->flags & IFF_LOOPBACK) &&
605 addr_type & IPV6_ADDR_LOOPBACK))
606 return ERR_PTR(-EADDRNOTAVAIL);

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

611 goto out2;
612 }
613
614 if (idev->cnf.disable_ipv6) {
615 err = -EACCES;
616 goto out2;
617 }
618
605 int err = 0;
606 int addr_type = ipv6_addr_type(addr);
607
608 if (addr_type == IPV6_ADDR_ANY ||
609 addr_type & IPV6_ADDR_MULTICAST ||
610 (!(idev->dev->flags & IFF_LOOPBACK) &&
611 addr_type & IPV6_ADDR_LOOPBACK))
612 return ERR_PTR(-EADDRNOTAVAIL);

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

617 goto out2;
618 }
619
620 if (idev->cnf.disable_ipv6) {
621 err = -EACCES;
622 goto out2;
623 }
624
619 write_lock(&addrconf_hash_lock);
625 spin_lock(&addrconf_hash_lock);
620
621 /* Ignore adding duplicate addresses on an interface */
622 if (ipv6_chk_same_addr(dev_net(idev->dev), addr, idev->dev)) {
623 ADBG(("ipv6_add_addr: already assigned\n"));
624 err = -EEXIST;
625 goto out;
626 }
627

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

638 err = PTR_ERR(rt);
639 goto out;
640 }
641
642 ipv6_addr_copy(&ifa->addr, addr);
643
644 spin_lock_init(&ifa->lock);
645 init_timer(&ifa->timer);
626
627 /* Ignore adding duplicate addresses on an interface */
628 if (ipv6_chk_same_addr(dev_net(idev->dev), addr, idev->dev)) {
629 ADBG(("ipv6_add_addr: already assigned\n"));
630 err = -EEXIST;
631 goto out;
632 }
633

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

644 err = PTR_ERR(rt);
645 goto out;
646 }
647
648 ipv6_addr_copy(&ifa->addr, addr);
649
650 spin_lock_init(&ifa->lock);
651 init_timer(&ifa->timer);
652 INIT_HLIST_NODE(&ifa->addr_lst);
646 ifa->timer.data = (unsigned long) ifa;
647 ifa->scope = scope;
648 ifa->prefix_len = pfxlen;
649 ifa->flags = flags | IFA_F_TENTATIVE;
650 ifa->cstamp = ifa->tstamp = jiffies;
651
652 ifa->rt = rt;
653

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

664 ifa->idev = idev;
665 in6_dev_hold(idev);
666 /* For caller */
667 in6_ifa_hold(ifa);
668
669 /* Add to big hash table */
670 hash = ipv6_addr_hash(addr);
671
653 ifa->timer.data = (unsigned long) ifa;
654 ifa->scope = scope;
655 ifa->prefix_len = pfxlen;
656 ifa->flags = flags | IFA_F_TENTATIVE;
657 ifa->cstamp = ifa->tstamp = jiffies;
658
659 ifa->rt = rt;
660

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

671 ifa->idev = idev;
672 in6_dev_hold(idev);
673 /* For caller */
674 in6_ifa_hold(ifa);
675
676 /* Add to big hash table */
677 hash = ipv6_addr_hash(addr);
678
672 ifa->lst_next = inet6_addr_lst[hash];
673 inet6_addr_lst[hash] = ifa;
674 in6_ifa_hold(ifa);
675 write_unlock(&addrconf_hash_lock);
679 hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]);
680 spin_unlock(&addrconf_hash_lock);
676
677 write_lock(&idev->lock);
678 /* Add to inet6_dev unicast addr list. */
679 ipv6_link_dev_addr(idev, ifa);
680
681#ifdef CONFIG_IPV6_PRIVACY
682 if (ifa->flags&IFA_F_TEMPORARY) {
681
682 write_lock(&idev->lock);
683 /* Add to inet6_dev unicast addr list. */
684 ipv6_link_dev_addr(idev, ifa);
685
686#ifdef CONFIG_IPV6_PRIVACY
687 if (ifa->flags&IFA_F_TEMPORARY) {
683 ifa->tmp_next = idev->tempaddr_list;
684 idev->tempaddr_list = ifa;
688 list_add(&ifa->tmp_list, &idev->tempaddr_list);
685 in6_ifa_hold(ifa);
686 }
687#endif
688
689 in6_ifa_hold(ifa);
690 write_unlock(&idev->lock);
691out2:
692 rcu_read_unlock_bh();
693
694 if (likely(err == 0))
695 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa);
696 else {
697 kfree(ifa);
698 ifa = ERR_PTR(err);
699 }
700
701 return ifa;
702out:
689 in6_ifa_hold(ifa);
690 }
691#endif
692
693 in6_ifa_hold(ifa);
694 write_unlock(&idev->lock);
695out2:
696 rcu_read_unlock_bh();
697
698 if (likely(err == 0))
699 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa);
700 else {
701 kfree(ifa);
702 ifa = ERR_PTR(err);
703 }
704
705 return ifa;
706out:
703 write_unlock(&addrconf_hash_lock);
707 spin_unlock(&addrconf_hash_lock);
704 goto out2;
705}
706
707/* This function wants to get referenced ifp and releases it before return */
708
709static void ipv6_del_addr(struct inet6_ifaddr *ifp)
710{
708 goto out2;
709}
710
711/* This function wants to get referenced ifp and releases it before return */
712
713static void ipv6_del_addr(struct inet6_ifaddr *ifp)
714{
711 struct inet6_ifaddr *ifa, **ifap;
715 struct inet6_ifaddr *ifa, *ifn;
712 struct inet6_dev *idev = ifp->idev;
713 int hash;
714 int deleted = 0, onlink = 0;
715 unsigned long expires = jiffies;
716
717 hash = ipv6_addr_hash(&ifp->addr);
718
719 ifp->dead = 1;
720
716 struct inet6_dev *idev = ifp->idev;
717 int hash;
718 int deleted = 0, onlink = 0;
719 unsigned long expires = jiffies;
720
721 hash = ipv6_addr_hash(&ifp->addr);
722
723 ifp->dead = 1;
724
721 write_lock_bh(&addrconf_hash_lock);
722 for (ifap = &inet6_addr_lst[hash]; (ifa=*ifap) != NULL;
723 ifap = &ifa->lst_next) {
724 if (ifa == ifp) {
725 *ifap = ifa->lst_next;
726 __in6_ifa_put(ifp);
727 ifa->lst_next = NULL;
728 break;
729 }
730 }
731 write_unlock_bh(&addrconf_hash_lock);
725 spin_lock_bh(&addrconf_hash_lock);
726 hlist_del_init_rcu(&ifp->addr_lst);
727 spin_unlock_bh(&addrconf_hash_lock);
732
733 write_lock_bh(&idev->lock);
734#ifdef CONFIG_IPV6_PRIVACY
735 if (ifp->flags&IFA_F_TEMPORARY) {
728
729 write_lock_bh(&idev->lock);
730#ifdef CONFIG_IPV6_PRIVACY
731 if (ifp->flags&IFA_F_TEMPORARY) {
736 for (ifap = &idev->tempaddr_list; (ifa=*ifap) != NULL;
737 ifap = &ifa->tmp_next) {
738 if (ifa == ifp) {
739 *ifap = ifa->tmp_next;
740 if (ifp->ifpub) {
741 in6_ifa_put(ifp->ifpub);
742 ifp->ifpub = NULL;
743 }
744 __in6_ifa_put(ifp);
745 ifa->tmp_next = NULL;
746 break;
747 }
732 list_del(&ifp->tmp_list);
733 if (ifp->ifpub) {
734 in6_ifa_put(ifp->ifpub);
735 ifp->ifpub = NULL;
748 }
736 }
737 __in6_ifa_put(ifp);
749 }
750#endif
751
738 }
739#endif
740
752 for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) {
741 list_for_each_entry_safe(ifa, ifn, &idev->addr_list, if_list) {
753 if (ifa == ifp) {
742 if (ifa == ifp) {
754 *ifap = ifa->if_next;
743 list_del_init(&ifp->if_list);
755 __in6_ifa_put(ifp);
744 __in6_ifa_put(ifp);
756 ifa->if_next = NULL;
745
757 if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
758 break;
759 deleted = 1;
760 continue;
761 } else if (ifp->flags & IFA_F_PERMANENT) {
762 if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
763 ifp->prefix_len)) {
764 if (ifa->flags & IFA_F_PERMANENT) {

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

781 */
782 if (time_before(expires,
783 ifa->tstamp + lifetime * HZ))
784 expires = ifa->tstamp + lifetime * HZ;
785 spin_unlock(&ifa->lock);
786 }
787 }
788 }
746 if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0)
747 break;
748 deleted = 1;
749 continue;
750 } else if (ifp->flags & IFA_F_PERMANENT) {
751 if (ipv6_prefix_equal(&ifa->addr, &ifp->addr,
752 ifp->prefix_len)) {
753 if (ifa->flags & IFA_F_PERMANENT) {

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

770 */
771 if (time_before(expires,
772 ifa->tstamp + lifetime * HZ))
773 expires = ifa->tstamp + lifetime * HZ;
774 spin_unlock(&ifa->lock);
775 }
776 }
777 }
789 ifap = &ifa->if_next;
790 }
791 write_unlock_bh(&idev->lock);
792
793 addrconf_del_timer(ifp);
794
795 ipv6_ifa_notify(RTM_DELADDR, ifp);
796
797 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp);

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

1160 dst.ifindex && dev->ifindex != dst.ifindex)
1161 continue;
1162
1163 idev = __in6_dev_get(dev);
1164 if (!idev)
1165 continue;
1166
1167 read_lock_bh(&idev->lock);
778 }
779 write_unlock_bh(&idev->lock);
780
781 addrconf_del_timer(ifp);
782
783 ipv6_ifa_notify(RTM_DELADDR, ifp);
784
785 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp);

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

1148 dst.ifindex && dev->ifindex != dst.ifindex)
1149 continue;
1150
1151 idev = __in6_dev_get(dev);
1152 if (!idev)
1153 continue;
1154
1155 read_lock_bh(&idev->lock);
1168 for (score->ifa = idev->addr_list; score->ifa; score->ifa = score->ifa->if_next) {
1156 list_for_each_entry(score->ifa, &idev->addr_list, if_list) {
1169 int i;
1170
1171 /*
1172 * - Tentative Address (RFC2462 section 5.4)
1173 * - A tentative address is not considered
1174 * "assigned to an interface" in the traditional
1175 * sense, unless it is also flagged as optimistic.
1176 * - Candidate Source Address (section 4)

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

1238
1239 if (!hiscore->ifa)
1240 return -EADDRNOTAVAIL;
1241
1242 ipv6_addr_copy(saddr, &hiscore->ifa->addr);
1243 in6_ifa_put(hiscore->ifa);
1244 return 0;
1245}
1157 int i;
1158
1159 /*
1160 * - Tentative Address (RFC2462 section 5.4)
1161 * - A tentative address is not considered
1162 * "assigned to an interface" in the traditional
1163 * sense, unless it is also flagged as optimistic.
1164 * - Candidate Source Address (section 4)

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

1226
1227 if (!hiscore->ifa)
1228 return -EADDRNOTAVAIL;
1229
1230 ipv6_addr_copy(saddr, &hiscore->ifa->addr);
1231 in6_ifa_put(hiscore->ifa);
1232 return 0;
1233}
1246
1247EXPORT_SYMBOL(ipv6_dev_get_saddr);
1248
1249int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
1250 unsigned char banned_flags)
1251{
1252 struct inet6_dev *idev;
1253 int err = -EADDRNOTAVAIL;
1254
1255 rcu_read_lock();
1234EXPORT_SYMBOL(ipv6_dev_get_saddr);
1235
1236int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
1237 unsigned char banned_flags)
1238{
1239 struct inet6_dev *idev;
1240 int err = -EADDRNOTAVAIL;
1241
1242 rcu_read_lock();
1256 if ((idev = __in6_dev_get(dev)) != NULL) {
1243 idev = __in6_dev_get(dev);
1244 if (idev) {
1257 struct inet6_ifaddr *ifp;
1258
1259 read_lock_bh(&idev->lock);
1245 struct inet6_ifaddr *ifp;
1246
1247 read_lock_bh(&idev->lock);
1260 for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
1261 if (ifp->scope == IFA_LINK && !(ifp->flags & banned_flags)) {
1248 list_for_each_entry(ifp, &idev->addr_list, if_list) {
1249 if (ifp->scope == IFA_LINK &&
1250 !(ifp->flags & banned_flags)) {
1262 ipv6_addr_copy(addr, &ifp->addr);
1263 err = 0;
1264 break;
1265 }
1266 }
1267 read_unlock_bh(&idev->lock);
1268 }
1269 rcu_read_unlock();
1270 return err;
1271}
1272
1273static int ipv6_count_addresses(struct inet6_dev *idev)
1274{
1275 int cnt = 0;
1276 struct inet6_ifaddr *ifp;
1277
1278 read_lock_bh(&idev->lock);
1251 ipv6_addr_copy(addr, &ifp->addr);
1252 err = 0;
1253 break;
1254 }
1255 }
1256 read_unlock_bh(&idev->lock);
1257 }
1258 rcu_read_unlock();
1259 return err;
1260}
1261
1262static int ipv6_count_addresses(struct inet6_dev *idev)
1263{
1264 int cnt = 0;
1265 struct inet6_ifaddr *ifp;
1266
1267 read_lock_bh(&idev->lock);
1279 for (ifp=idev->addr_list; ifp; ifp=ifp->if_next)
1268 list_for_each_entry(ifp, &idev->addr_list, if_list)
1280 cnt++;
1281 read_unlock_bh(&idev->lock);
1282 return cnt;
1283}
1284
1285int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
1286 struct net_device *dev, int strict)
1287{
1269 cnt++;
1270 read_unlock_bh(&idev->lock);
1271 return cnt;
1272}
1273
1274int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
1275 struct net_device *dev, int strict)
1276{
1288 struct inet6_ifaddr * ifp;
1289 u8 hash = ipv6_addr_hash(addr);
1277 struct inet6_ifaddr *ifp;
1278 struct hlist_node *node;
1279 unsigned int hash = ipv6_addr_hash(addr);
1290
1280
1291 read_lock_bh(&addrconf_hash_lock);
1292 for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
1281 rcu_read_lock_bh();
1282 hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[hash], addr_lst) {
1293 if (!net_eq(dev_net(ifp->idev->dev), net))
1294 continue;
1295 if (ipv6_addr_equal(&ifp->addr, addr) &&
1283 if (!net_eq(dev_net(ifp->idev->dev), net))
1284 continue;
1285 if (ipv6_addr_equal(&ifp->addr, addr) &&
1296 !(ifp->flags&IFA_F_TENTATIVE)) {
1297 if (dev == NULL || ifp->idev->dev == dev ||
1298 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))
1299 break;
1286 !(ifp->flags&IFA_F_TENTATIVE) &&
1287 (dev == NULL || ifp->idev->dev == dev ||
1288 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
1289 rcu_read_unlock_bh();
1290 return 1;
1300 }
1301 }
1291 }
1292 }
1302 read_unlock_bh(&addrconf_hash_lock);
1303 return ifp != NULL;
1293
1294 rcu_read_unlock_bh();
1295 return 0;
1304}
1305EXPORT_SYMBOL(ipv6_chk_addr);
1306
1296}
1297EXPORT_SYMBOL(ipv6_chk_addr);
1298
1307static
1308int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
1309 struct net_device *dev)
1299static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
1300 struct net_device *dev)
1310{
1301{
1311 struct inet6_ifaddr * ifp;
1312 u8 hash = ipv6_addr_hash(addr);
1302 unsigned int hash = ipv6_addr_hash(addr);
1303 struct inet6_ifaddr *ifp;
1304 struct hlist_node *node;
1313
1305
1314 for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
1306 hlist_for_each_entry(ifp, node, &inet6_addr_lst[hash], addr_lst) {
1315 if (!net_eq(dev_net(ifp->idev->dev), net))
1316 continue;
1317 if (ipv6_addr_equal(&ifp->addr, addr)) {
1318 if (dev == NULL || ifp->idev->dev == dev)
1307 if (!net_eq(dev_net(ifp->idev->dev), net))
1308 continue;
1309 if (ipv6_addr_equal(&ifp->addr, addr)) {
1310 if (dev == NULL || ifp->idev->dev == dev)
1319 break;
1311 return true;
1320 }
1321 }
1312 }
1313 }
1322 return ifp != NULL;
1314 return false;
1323}
1324
1325int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev)
1326{
1327 struct inet6_dev *idev;
1328 struct inet6_ifaddr *ifa;
1329 int onlink;
1330
1331 onlink = 0;
1332 rcu_read_lock();
1333 idev = __in6_dev_get(dev);
1334 if (idev) {
1335 read_lock_bh(&idev->lock);
1315}
1316
1317int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev)
1318{
1319 struct inet6_dev *idev;
1320 struct inet6_ifaddr *ifa;
1321 int onlink;
1322
1323 onlink = 0;
1324 rcu_read_lock();
1325 idev = __in6_dev_get(dev);
1326 if (idev) {
1327 read_lock_bh(&idev->lock);
1336 for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
1328 list_for_each_entry(ifa, &idev->addr_list, if_list) {
1337 onlink = ipv6_prefix_equal(addr, &ifa->addr,
1338 ifa->prefix_len);
1339 if (onlink)
1340 break;
1341 }
1342 read_unlock_bh(&idev->lock);
1343 }
1344 rcu_read_unlock();
1345 return onlink;
1346}
1347
1348EXPORT_SYMBOL(ipv6_chk_prefix);
1349
1350struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,
1351 struct net_device *dev, int strict)
1352{
1329 onlink = ipv6_prefix_equal(addr, &ifa->addr,
1330 ifa->prefix_len);
1331 if (onlink)
1332 break;
1333 }
1334 read_unlock_bh(&idev->lock);
1335 }
1336 rcu_read_unlock();
1337 return onlink;
1338}
1339
1340EXPORT_SYMBOL(ipv6_chk_prefix);
1341
1342struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,
1343 struct net_device *dev, int strict)
1344{
1353 struct inet6_ifaddr * ifp;
1354 u8 hash = ipv6_addr_hash(addr);
1345 struct inet6_ifaddr *ifp, *result = NULL;
1346 unsigned int hash = ipv6_addr_hash(addr);
1347 struct hlist_node *node;
1355
1348
1356 read_lock_bh(&addrconf_hash_lock);
1357 for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
1349 rcu_read_lock_bh();
1350 hlist_for_each_entry_rcu_bh(ifp, node, &inet6_addr_lst[hash], addr_lst) {
1358 if (!net_eq(dev_net(ifp->idev->dev), net))
1359 continue;
1360 if (ipv6_addr_equal(&ifp->addr, addr)) {
1361 if (dev == NULL || ifp->idev->dev == dev ||
1362 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) {
1351 if (!net_eq(dev_net(ifp->idev->dev), net))
1352 continue;
1353 if (ipv6_addr_equal(&ifp->addr, addr)) {
1354 if (dev == NULL || ifp->idev->dev == dev ||
1355 !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) {
1356 result = ifp;
1363 in6_ifa_hold(ifp);
1364 break;
1365 }
1366 }
1367 }
1357 in6_ifa_hold(ifp);
1358 break;
1359 }
1360 }
1361 }
1368 read_unlock_bh(&addrconf_hash_lock);
1362 rcu_read_unlock_bh();
1369
1363
1370 return ifp;
1364 return result;
1371}
1372
1373/* Gets referenced address, destroys ifaddr */
1374
1375static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
1376{
1377 if (ifp->flags&IFA_F_PERMANENT) {
1378 spin_lock_bh(&ifp->lock);

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

1565}
1566
1567static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
1568{
1569 int err = -1;
1570 struct inet6_ifaddr *ifp;
1571
1572 read_lock_bh(&idev->lock);
1365}
1366
1367/* Gets referenced address, destroys ifaddr */
1368
1369static void addrconf_dad_stop(struct inet6_ifaddr *ifp, int dad_failed)
1370{
1371 if (ifp->flags&IFA_F_PERMANENT) {
1372 spin_lock_bh(&ifp->lock);

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

1559}
1560
1561static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
1562{
1563 int err = -1;
1564 struct inet6_ifaddr *ifp;
1565
1566 read_lock_bh(&idev->lock);
1573 for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) {
1567 list_for_each_entry(ifp, &idev->addr_list, if_list) {
1574 if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
1575 memcpy(eui, ifp->addr.s6_addr+8, 8);
1576 err = 0;
1577 break;
1578 }
1579 }
1580 read_unlock_bh(&idev->lock);
1581 return err;

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

1733}
1734
1735static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
1736{
1737 struct inet6_dev *idev;
1738
1739 ASSERT_RTNL();
1740
1568 if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) {
1569 memcpy(eui, ifp->addr.s6_addr+8, 8);
1570 err = 0;
1571 break;
1572 }
1573 }
1574 read_unlock_bh(&idev->lock);
1575 return err;

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

1727}
1728
1729static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
1730{
1731 struct inet6_dev *idev;
1732
1733 ASSERT_RTNL();
1734
1741 if ((idev = ipv6_find_idev(dev)) == NULL)
1735 idev = ipv6_find_idev(dev);
1736 if (!idev)
1742 return NULL;
1743
1744 /* Add default multicast route */
1745 addrconf_add_mroute(dev);
1746
1747 /* Add link local route */
1748 addrconf_add_lroute(dev);
1749 return idev;

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

1966 if (!(flags&IFA_F_TENTATIVE))
1967 ipv6_ifa_notify(0, ifp);
1968 } else
1969 spin_unlock(&ifp->lock);
1970
1971#ifdef CONFIG_IPV6_PRIVACY
1972 read_lock_bh(&in6_dev->lock);
1973 /* update all temporary addresses in the list */
1737 return NULL;
1738
1739 /* Add default multicast route */
1740 addrconf_add_mroute(dev);
1741
1742 /* Add link local route */
1743 addrconf_add_lroute(dev);
1744 return idev;

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

1961 if (!(flags&IFA_F_TENTATIVE))
1962 ipv6_ifa_notify(0, ifp);
1963 } else
1964 spin_unlock(&ifp->lock);
1965
1966#ifdef CONFIG_IPV6_PRIVACY
1967 read_lock_bh(&in6_dev->lock);
1968 /* update all temporary addresses in the list */
1974 for (ift=in6_dev->tempaddr_list; ift; ift=ift->tmp_next) {
1969 list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) {
1975 /*
1976 * When adjusting the lifetimes of an existing
1977 * temporary address, only lower the lifetimes.
1978 * Implementations must not increase the
1979 * lifetimes of an existing temporary address
1980 * when processing a Prefix Information Option.
1981 */
1982 if (ifp != ift->ifpub)

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

2169 dev = __dev_get_by_index(net, ifindex);
2170 if (!dev)
2171 return -ENODEV;
2172
2173 if ((idev = __in6_dev_get(dev)) == NULL)
2174 return -ENXIO;
2175
2176 read_lock_bh(&idev->lock);
1970 /*
1971 * When adjusting the lifetimes of an existing
1972 * temporary address, only lower the lifetimes.
1973 * Implementations must not increase the
1974 * lifetimes of an existing temporary address
1975 * when processing a Prefix Information Option.
1976 */
1977 if (ifp != ift->ifpub)

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

2164 dev = __dev_get_by_index(net, ifindex);
2165 if (!dev)
2166 return -ENODEV;
2167
2168 if ((idev = __in6_dev_get(dev)) == NULL)
2169 return -ENXIO;
2170
2171 read_lock_bh(&idev->lock);
2177 for (ifp = idev->addr_list; ifp; ifp=ifp->if_next) {
2172 list_for_each_entry(ifp, &idev->addr_list, if_list) {
2178 if (ifp->prefix_len == plen &&
2179 ipv6_addr_equal(pfx, &ifp->addr)) {
2180 in6_ifa_hold(ifp);
2181 read_unlock_bh(&idev->lock);
2182
2183 ipv6_del_addr(ifp);
2184
2185 /* If the last address is deleted administratively,
2186 disable IPv6 on this interface.
2187 */
2173 if (ifp->prefix_len == plen &&
2174 ipv6_addr_equal(pfx, &ifp->addr)) {
2175 in6_ifa_hold(ifp);
2176 read_unlock_bh(&idev->lock);
2177
2178 ipv6_del_addr(ifp);
2179
2180 /* If the last address is deleted administratively,
2181 disable IPv6 on this interface.
2182 */
2188 if (idev->addr_list == NULL)
2183 if (list_empty(&idev->addr_list))
2189 addrconf_ifdown(idev->dev, 1);
2190 return 0;
2191 }
2192 }
2193 read_unlock_bh(&idev->lock);
2194 return -EADDRNOTAVAIL;
2195}
2196

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

2441 */
2442
2443static void addrconf_ip6_tnl_config(struct net_device *dev)
2444{
2445 struct inet6_dev *idev;
2446
2447 ASSERT_RTNL();
2448
2184 addrconf_ifdown(idev->dev, 1);
2185 return 0;
2186 }
2187 }
2188 read_unlock_bh(&idev->lock);
2189 return -EADDRNOTAVAIL;
2190}
2191

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

2436 */
2437
2438static void addrconf_ip6_tnl_config(struct net_device *dev)
2439{
2440 struct inet6_dev *idev;
2441
2442 ASSERT_RTNL();
2443
2449 if ((idev = addrconf_add_dev(dev)) == NULL) {
2444 idev = addrconf_add_dev(dev);
2445 if (!idev) {
2450 printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n");
2451 return;
2452 }
2453 ip6_tnl_add_linklocal(idev);
2454}
2455
2456static int addrconf_notify(struct notifier_block *this, unsigned long event,
2457 void * data)
2458{
2459 struct net_device *dev = (struct net_device *) data;
2460 struct inet6_dev *idev = __in6_dev_get(dev);
2461 int run_pending = 0;
2462 int err;
2463
2446 printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n");
2447 return;
2448 }
2449 ip6_tnl_add_linklocal(idev);
2450}
2451
2452static int addrconf_notify(struct notifier_block *this, unsigned long event,
2453 void * data)
2454{
2455 struct net_device *dev = (struct net_device *) data;
2456 struct inet6_dev *idev = __in6_dev_get(dev);
2457 int run_pending = 0;
2458 int err;
2459
2464 switch(event) {
2460 switch (event) {
2465 case NETDEV_REGISTER:
2466 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
2467 idev = ipv6_add_dev(dev);
2468 if (!idev)
2469 return notifier_from_errno(-ENOMEM);
2470 }
2471 break;
2461 case NETDEV_REGISTER:
2462 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
2463 idev = ipv6_add_dev(dev);
2464 if (!idev)
2465 return notifier_from_errno(-ENOMEM);
2466 }
2467 break;
2468
2472 case NETDEV_UP:
2473 case NETDEV_CHANGE:
2474 if (dev->flags & IFF_SLAVE)
2475 break;
2476
2477 if (event == NETDEV_UP) {
2478 if (!addrconf_qdisc_ok(dev)) {
2479 /* device is not ready yet. */

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

2493 }
2494 } else {
2495 if (!addrconf_qdisc_ok(dev)) {
2496 /* device is still not ready. */
2497 break;
2498 }
2499
2500 if (idev) {
2469 case NETDEV_UP:
2470 case NETDEV_CHANGE:
2471 if (dev->flags & IFF_SLAVE)
2472 break;
2473
2474 if (event == NETDEV_UP) {
2475 if (!addrconf_qdisc_ok(dev)) {
2476 /* device is not ready yet. */

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

2490 }
2491 } else {
2492 if (!addrconf_qdisc_ok(dev)) {
2493 /* device is still not ready. */
2494 break;
2495 }
2496
2497 if (idev) {
2501 if (idev->if_flags & IF_READY) {
2498 if (idev->if_flags & IF_READY)
2502 /* device is already configured. */
2503 break;
2499 /* device is already configured. */
2500 break;
2504 }
2505 idev->if_flags |= IF_READY;
2506 }
2507
2508 printk(KERN_INFO
2509 "ADDRCONF(NETDEV_CHANGE): %s: "
2510 "link becomes ready\n",
2511 dev->name);
2512
2513 run_pending = 1;
2514 }
2515
2501 idev->if_flags |= IF_READY;
2502 }
2503
2504 printk(KERN_INFO
2505 "ADDRCONF(NETDEV_CHANGE): %s: "
2506 "link becomes ready\n",
2507 dev->name);
2508
2509 run_pending = 1;
2510 }
2511
2516 switch(dev->type) {
2512 switch (dev->type) {
2517#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2518 case ARPHRD_SIT:
2519 addrconf_sit_config(dev);
2520 break;
2521#endif
2522 case ARPHRD_TUNNEL6:
2523 addrconf_ip6_tnl_config(dev);
2524 break;
2525 case ARPHRD_LOOPBACK:
2526 init_loopback(dev);
2527 break;
2528
2529 default:
2530 addrconf_dev_config(dev);
2531 break;
2532 }
2513#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
2514 case ARPHRD_SIT:
2515 addrconf_sit_config(dev);
2516 break;
2517#endif
2518 case ARPHRD_TUNNEL6:
2519 addrconf_ip6_tnl_config(dev);
2520 break;
2521 case ARPHRD_LOOPBACK:
2522 init_loopback(dev);
2523 break;
2524
2525 default:
2526 addrconf_dev_config(dev);
2527 break;
2528 }
2529
2533 if (idev) {
2534 if (run_pending)
2535 addrconf_dad_run(idev);
2536
2530 if (idev) {
2531 if (run_pending)
2532 addrconf_dad_run(idev);
2533
2537 /* If the MTU changed during the interface down, when the
2538 interface up, the changed MTU must be reflected in the
2539 idev as well as routers.
2534 /*
2535 * If the MTU changed during the interface down,
2536 * when the interface up, the changed MTU must be
2537 * reflected in the idev as well as routers.
2540 */
2538 */
2541 if (idev->cnf.mtu6 != dev->mtu && dev->mtu >= IPV6_MIN_MTU) {
2539 if (idev->cnf.mtu6 != dev->mtu &&
2540 dev->mtu >= IPV6_MIN_MTU) {
2542 rt6_mtu_change(dev, dev->mtu);
2543 idev->cnf.mtu6 = dev->mtu;
2544 }
2545 idev->tstamp = jiffies;
2546 inet6_ifinfo_notify(RTM_NEWLINK, idev);
2541 rt6_mtu_change(dev, dev->mtu);
2542 idev->cnf.mtu6 = dev->mtu;
2543 }
2544 idev->tstamp = jiffies;
2545 inet6_ifinfo_notify(RTM_NEWLINK, idev);
2547 /* If the changed mtu during down is lower than IPV6_MIN_MTU
2548 stop IPv6 on this interface.
2546
2547 /*
2548 * If the changed mtu during down is lower than
2549 * IPV6_MIN_MTU stop IPv6 on this interface.
2549 */
2550 if (dev->mtu < IPV6_MIN_MTU)
2550 */
2551 if (dev->mtu < IPV6_MIN_MTU)
2551 addrconf_ifdown(dev, event != NETDEV_DOWN);
2552 addrconf_ifdown(dev, 1);
2552 }
2553 break;
2554
2555 case NETDEV_CHANGEMTU:
2556 if (idev && dev->mtu >= IPV6_MIN_MTU) {
2557 rt6_mtu_change(dev, dev->mtu);
2558 idev->cnf.mtu6 = dev->mtu;
2559 break;
2560 }
2561
2562 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
2563 idev = ipv6_add_dev(dev);
2564 if (idev)
2565 break;
2566 }
2567
2553 }
2554 break;
2555
2556 case NETDEV_CHANGEMTU:
2557 if (idev && dev->mtu >= IPV6_MIN_MTU) {
2558 rt6_mtu_change(dev, dev->mtu);
2559 idev->cnf.mtu6 = dev->mtu;
2560 break;
2561 }
2562
2563 if (!idev && dev->mtu >= IPV6_MIN_MTU) {
2564 idev = ipv6_add_dev(dev);
2565 if (idev)
2566 break;
2567 }
2568
2568 /* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */
2569 /*
2570 * MTU falled under IPV6_MIN_MTU.
2571 * Stop IPv6 on this interface.
2572 */
2569
2570 case NETDEV_DOWN:
2571 case NETDEV_UNREGISTER:
2572 /*
2573 * Remove all addresses from this interface.
2574 */
2575 addrconf_ifdown(dev, event != NETDEV_DOWN);
2576 break;
2577
2578 case NETDEV_CHANGENAME:
2579 if (idev) {
2580 snmp6_unregister_dev(idev);
2581 addrconf_sysctl_unregister(idev);
2582 addrconf_sysctl_register(idev);
2583 err = snmp6_register_dev(idev);
2584 if (err)
2585 return notifier_from_errno(err);
2586 }
2587 break;
2573
2574 case NETDEV_DOWN:
2575 case NETDEV_UNREGISTER:
2576 /*
2577 * Remove all addresses from this interface.
2578 */
2579 addrconf_ifdown(dev, event != NETDEV_DOWN);
2580 break;
2581
2582 case NETDEV_CHANGENAME:
2583 if (idev) {
2584 snmp6_unregister_dev(idev);
2585 addrconf_sysctl_unregister(idev);
2586 addrconf_sysctl_register(idev);
2587 err = snmp6_register_dev(idev);
2588 if (err)
2589 return notifier_from_errno(err);
2590 }
2591 break;
2588 case NETDEV_BONDING_OLDTYPE:
2589 case NETDEV_BONDING_NEWTYPE:
2590 addrconf_bonding_change(dev, event);
2592
2593 case NETDEV_PRE_TYPE_CHANGE:
2594 case NETDEV_POST_TYPE_CHANGE:
2595 addrconf_type_change(dev, event);
2591 break;
2592 }
2593
2594 return NOTIFY_OK;
2595}
2596
2597/*
2598 * addrconf module should be notified of a device going up
2599 */
2600static struct notifier_block ipv6_dev_notf = {
2601 .notifier_call = addrconf_notify,
2596 break;
2597 }
2598
2599 return NOTIFY_OK;
2600}
2601
2602/*
2603 * addrconf module should be notified of a device going up
2604 */
2605static struct notifier_block ipv6_dev_notf = {
2606 .notifier_call = addrconf_notify,
2602 .priority = 0
2603};
2604
2607};
2608
2605static void addrconf_bonding_change(struct net_device *dev, unsigned long event)
2609static void addrconf_type_change(struct net_device *dev, unsigned long event)
2606{
2607 struct inet6_dev *idev;
2608 ASSERT_RTNL();
2609
2610 idev = __in6_dev_get(dev);
2611
2610{
2611 struct inet6_dev *idev;
2612 ASSERT_RTNL();
2613
2614 idev = __in6_dev_get(dev);
2615
2612 if (event == NETDEV_BONDING_NEWTYPE)
2616 if (event == NETDEV_POST_TYPE_CHANGE)
2613 ipv6_mc_remap(idev);
2617 ipv6_mc_remap(idev);
2614 else if (event == NETDEV_BONDING_OLDTYPE)
2618 else if (event == NETDEV_PRE_TYPE_CHANGE)
2615 ipv6_mc_unmap(idev);
2616}
2617
2618static int addrconf_ifdown(struct net_device *dev, int how)
2619{
2619 ipv6_mc_unmap(idev);
2620}
2621
2622static int addrconf_ifdown(struct net_device *dev, int how)
2623{
2620 struct inet6_dev *idev;
2621 struct inet6_ifaddr *ifa, *keep_list, **bifa;
2622 struct net *net = dev_net(dev);
2624 struct net *net = dev_net(dev);
2623 int i;
2625 struct inet6_dev *idev;
2626 struct inet6_ifaddr *ifa;
2627 LIST_HEAD(keep_list);
2624
2625 ASSERT_RTNL();
2626
2627 rt6_ifdown(net, dev);
2628 neigh_ifdown(&nd_tbl, dev);
2629
2630 idev = __in6_dev_get(dev);
2631 if (idev == NULL)
2632 return -ENODEV;
2633
2628
2629 ASSERT_RTNL();
2630
2631 rt6_ifdown(net, dev);
2632 neigh_ifdown(&nd_tbl, dev);
2633
2634 idev = __in6_dev_get(dev);
2635 if (idev == NULL)
2636 return -ENODEV;
2637
2634 /* Step 1: remove reference to ipv6 device from parent device.
2635 Do not dev_put!
2638 /*
2639 * Step 1: remove reference to ipv6 device from parent device.
2640 * Do not dev_put!
2636 */
2637 if (how) {
2638 idev->dead = 1;
2639
2640 /* protected by rtnl_lock */
2641 rcu_assign_pointer(dev->ip6_ptr, NULL);
2642
2643 /* Step 1.5: remove snmp6 entry */
2644 snmp6_unregister_dev(idev);
2645
2646 }
2647
2641 */
2642 if (how) {
2643 idev->dead = 1;
2644
2645 /* protected by rtnl_lock */
2646 rcu_assign_pointer(dev->ip6_ptr, NULL);
2647
2648 /* Step 1.5: remove snmp6 entry */
2649 snmp6_unregister_dev(idev);
2650
2651 }
2652
2648 /* Step 2: clear hash table */
2649 for (i=0; i<IN6_ADDR_HSIZE; i++) {
2650 bifa = &inet6_addr_lst[i];
2651
2652 write_lock_bh(&addrconf_hash_lock);
2653 while ((ifa = *bifa) != NULL) {
2654 if (ifa->idev == idev &&
2655 (how || !(ifa->flags&IFA_F_PERMANENT) ||
2656 ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2657 *bifa = ifa->lst_next;
2658 ifa->lst_next = NULL;
2659 __in6_ifa_put(ifa);
2660 continue;
2661 }
2662 bifa = &ifa->lst_next;
2663 }
2664 write_unlock_bh(&addrconf_hash_lock);
2665 }
2666
2667 write_lock_bh(&idev->lock);
2668
2653 write_lock_bh(&idev->lock);
2654
2669 /* Step 3: clear flags for stateless addrconf */
2655 /* Step 2: clear flags for stateless addrconf */
2670 if (!how)
2671 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
2672
2656 if (!how)
2657 idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
2658
2673 /* Step 4: clear address list */
2674#ifdef CONFIG_IPV6_PRIVACY
2675 if (how && del_timer(&idev->regen_timer))
2676 in6_dev_put(idev);
2677
2659#ifdef CONFIG_IPV6_PRIVACY
2660 if (how && del_timer(&idev->regen_timer))
2661 in6_dev_put(idev);
2662
2678 /* clear tempaddr list */
2679 while ((ifa = idev->tempaddr_list) != NULL) {
2680 idev->tempaddr_list = ifa->tmp_next;
2681 ifa->tmp_next = NULL;
2663 /* Step 3: clear tempaddr list */
2664 while (!list_empty(&idev->tempaddr_list)) {
2665 ifa = list_first_entry(&idev->tempaddr_list,
2666 struct inet6_ifaddr, tmp_list);
2667 list_del(&ifa->tmp_list);
2682 ifa->dead = 1;
2683 write_unlock_bh(&idev->lock);
2684 spin_lock_bh(&ifa->lock);
2685
2686 if (ifa->ifpub) {
2687 in6_ifa_put(ifa->ifpub);
2688 ifa->ifpub = NULL;
2689 }
2690 spin_unlock_bh(&ifa->lock);
2691 in6_ifa_put(ifa);
2692 write_lock_bh(&idev->lock);
2693 }
2694#endif
2668 ifa->dead = 1;
2669 write_unlock_bh(&idev->lock);
2670 spin_lock_bh(&ifa->lock);
2671
2672 if (ifa->ifpub) {
2673 in6_ifa_put(ifa->ifpub);
2674 ifa->ifpub = NULL;
2675 }
2676 spin_unlock_bh(&ifa->lock);
2677 in6_ifa_put(ifa);
2678 write_lock_bh(&idev->lock);
2679 }
2680#endif
2695 keep_list = NULL;
2696 bifa = &keep_list;
2697 while ((ifa = idev->addr_list) != NULL) {
2698 idev->addr_list = ifa->if_next;
2699 ifa->if_next = NULL;
2700
2681
2682 while (!list_empty(&idev->addr_list)) {
2683 ifa = list_first_entry(&idev->addr_list,
2684 struct inet6_ifaddr, if_list);
2701 addrconf_del_timer(ifa);
2702
2703 /* If just doing link down, and address is permanent
2704 and not link-local, then retain it. */
2685 addrconf_del_timer(ifa);
2686
2687 /* If just doing link down, and address is permanent
2688 and not link-local, then retain it. */
2705 if (how == 0 &&
2689 if (!how &&
2706 (ifa->flags&IFA_F_PERMANENT) &&
2707 !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2690 (ifa->flags&IFA_F_PERMANENT) &&
2691 !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2692 list_move_tail(&ifa->if_list, &keep_list);
2708
2693
2709 /* Move to holding list */
2710 *bifa = ifa;
2711 bifa = &ifa->if_next;
2712
2713 /* If not doing DAD on this address, just keep it. */
2714 if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
2715 idev->cnf.accept_dad <= 0 ||
2716 (ifa->flags & IFA_F_NODAD))
2717 continue;
2718
2719 /* If it was tentative already, no need to notify */
2720 if (ifa->flags & IFA_F_TENTATIVE)
2721 continue;
2722
2723 /* Flag it for later restoration when link comes up */
2724 ifa->flags |= IFA_F_TENTATIVE;
2725 in6_ifa_hold(ifa);
2694 /* If not doing DAD on this address, just keep it. */
2695 if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
2696 idev->cnf.accept_dad <= 0 ||
2697 (ifa->flags & IFA_F_NODAD))
2698 continue;
2699
2700 /* If it was tentative already, no need to notify */
2701 if (ifa->flags & IFA_F_TENTATIVE)
2702 continue;
2703
2704 /* Flag it for later restoration when link comes up */
2705 ifa->flags |= IFA_F_TENTATIVE;
2706 in6_ifa_hold(ifa);
2707 write_unlock_bh(&idev->lock);
2726 } else {
2708 } else {
2709 list_del(&ifa->if_list);
2727 ifa->dead = 1;
2710 ifa->dead = 1;
2711 write_unlock_bh(&idev->lock);
2712
2713 /* clear hash table */
2714 spin_lock_bh(&addrconf_hash_lock);
2715 hlist_del_init_rcu(&ifa->addr_lst);
2716 spin_unlock_bh(&addrconf_hash_lock);
2728 }
2717 }
2729 write_unlock_bh(&idev->lock);
2730
2731 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2718
2719 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2732 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
2720 if (ifa->dead)
2721 atomic_notifier_call_chain(&inet6addr_chain,
2722 NETDEV_DOWN, ifa);
2733 in6_ifa_put(ifa);
2734
2735 write_lock_bh(&idev->lock);
2736 }
2737
2723 in6_ifa_put(ifa);
2724
2725 write_lock_bh(&idev->lock);
2726 }
2727
2738 idev->addr_list = keep_list;
2728 list_splice(&keep_list, &idev->addr_list);
2739
2740 write_unlock_bh(&idev->lock);
2741
2742 /* Step 5: Discard multicast list */
2729
2730 write_unlock_bh(&idev->lock);
2731
2732 /* Step 5: Discard multicast list */
2743
2744 if (how)
2745 ipv6_mc_destroy_dev(idev);
2746 else
2747 ipv6_mc_down(idev);
2748
2749 idev->tstamp = jiffies;
2750
2733 if (how)
2734 ipv6_mc_destroy_dev(idev);
2735 else
2736 ipv6_mc_down(idev);
2737
2738 idev->tstamp = jiffies;
2739
2751 /* Shot the device (if unregistered) */
2752
2740 /* Last: Shot the device (if unregistered) */
2753 if (how) {
2754 addrconf_sysctl_unregister(idev);
2755 neigh_parms_release(&nd_tbl, idev->nd_parms);
2756 neigh_ifdown(&nd_tbl, dev);
2757 in6_dev_put(idev);
2758 }
2759 return 0;
2760}

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

2855 addrconf_dad_stop(ifp, 0);
2856 return;
2857 }
2858
2859 /*
2860 * Optimistic nodes can start receiving
2861 * Frames right away
2862 */
2741 if (how) {
2742 addrconf_sysctl_unregister(idev);
2743 neigh_parms_release(&nd_tbl, idev->nd_parms);
2744 neigh_ifdown(&nd_tbl, dev);
2745 in6_dev_put(idev);
2746 }
2747 return 0;
2748}

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

2843 addrconf_dad_stop(ifp, 0);
2844 return;
2845 }
2846
2847 /*
2848 * Optimistic nodes can start receiving
2849 * Frames right away
2850 */
2863 if(ifp->flags & IFA_F_OPTIMISTIC)
2851 if (ifp->flags & IFA_F_OPTIMISTIC)
2864 ip6_ins_rt(ifp->rt);
2865
2866 addrconf_dad_kick(ifp);
2867 spin_unlock(&ifp->lock);
2868out:
2869 read_unlock_bh(&idev->lock);
2870}
2871

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

2905 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
2906 ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any);
2907out:
2908 in6_ifa_put(ifp);
2909}
2910
2911static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2912{
2852 ip6_ins_rt(ifp->rt);
2853
2854 addrconf_dad_kick(ifp);
2855 spin_unlock(&ifp->lock);
2856out:
2857 read_unlock_bh(&idev->lock);
2858}
2859

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

2893 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
2894 ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any);
2895out:
2896 in6_ifa_put(ifp);
2897}
2898
2899static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2900{
2913 struct net_device * dev = ifp->idev->dev;
2901 struct net_device *dev = ifp->idev->dev;
2914
2915 /*
2916 * Configure the address for reception. Now it is valid.
2917 */
2918
2919 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2920
2921 /* If added prefix is link local and forwarding is off,

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

2936 spin_lock_bh(&ifp->lock);
2937 ifp->probes = 1;
2938 ifp->idev->if_flags |= IF_RS_SENT;
2939 addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval);
2940 spin_unlock_bh(&ifp->lock);
2941 }
2942}
2943
2902
2903 /*
2904 * Configure the address for reception. Now it is valid.
2905 */
2906
2907 ipv6_ifa_notify(RTM_NEWADDR, ifp);
2908
2909 /* If added prefix is link local and forwarding is off,

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

2924 spin_lock_bh(&ifp->lock);
2925 ifp->probes = 1;
2926 ifp->idev->if_flags |= IF_RS_SENT;
2927 addrconf_mod_timer(ifp, AC_RS, ifp->idev->cnf.rtr_solicit_interval);
2928 spin_unlock_bh(&ifp->lock);
2929 }
2930}
2931
2944static void addrconf_dad_run(struct inet6_dev *idev) {
2932static void addrconf_dad_run(struct inet6_dev *idev)
2933{
2945 struct inet6_ifaddr *ifp;
2946
2947 read_lock_bh(&idev->lock);
2934 struct inet6_ifaddr *ifp;
2935
2936 read_lock_bh(&idev->lock);
2948 for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) {
2937 list_for_each_entry(ifp, &idev->addr_list, if_list) {
2949 spin_lock(&ifp->lock);
2950 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2951 spin_unlock(&ifp->lock);
2952 continue;
2953 }
2954 spin_unlock(&ifp->lock);
2955 addrconf_dad_kick(ifp);
2956 }

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

2965
2966static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
2967{
2968 struct inet6_ifaddr *ifa = NULL;
2969 struct if6_iter_state *state = seq->private;
2970 struct net *net = seq_file_net(seq);
2971
2972 for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
2938 spin_lock(&ifp->lock);
2939 if (!(ifp->flags & IFA_F_TENTATIVE)) {
2940 spin_unlock(&ifp->lock);
2941 continue;
2942 }
2943 spin_unlock(&ifp->lock);
2944 addrconf_dad_kick(ifp);
2945 }

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

2954
2955static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
2956{
2957 struct inet6_ifaddr *ifa = NULL;
2958 struct if6_iter_state *state = seq->private;
2959 struct net *net = seq_file_net(seq);
2960
2961 for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
2973 ifa = inet6_addr_lst[state->bucket];
2974
2975 while (ifa && !net_eq(dev_net(ifa->idev->dev), net))
2976 ifa = ifa->lst_next;
2977 if (ifa)
2978 break;
2962 struct hlist_node *n;
2963 hlist_for_each_entry_rcu_bh(ifa, n, &inet6_addr_lst[state->bucket],
2964 addr_lst)
2965 if (net_eq(dev_net(ifa->idev->dev), net))
2966 return ifa;
2979 }
2967 }
2980 return ifa;
2968 return NULL;
2981}
2982
2969}
2970
2983static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa)
2971static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
2972 struct inet6_ifaddr *ifa)
2984{
2985 struct if6_iter_state *state = seq->private;
2986 struct net *net = seq_file_net(seq);
2973{
2974 struct if6_iter_state *state = seq->private;
2975 struct net *net = seq_file_net(seq);
2976 struct hlist_node *n = &ifa->addr_lst;
2987
2977
2988 ifa = ifa->lst_next;
2989try_again:
2990 if (ifa) {
2991 if (!net_eq(dev_net(ifa->idev->dev), net)) {
2992 ifa = ifa->lst_next;
2993 goto try_again;
2978 hlist_for_each_entry_continue_rcu_bh(ifa, n, addr_lst)
2979 if (net_eq(dev_net(ifa->idev->dev), net))
2980 return ifa;
2981
2982 while (++state->bucket < IN6_ADDR_HSIZE) {
2983 hlist_for_each_entry_rcu_bh(ifa, n,
2984 &inet6_addr_lst[state->bucket], addr_lst) {
2985 if (net_eq(dev_net(ifa->idev->dev), net))
2986 return ifa;
2994 }
2995 }
2996
2987 }
2988 }
2989
2997 if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) {
2998 ifa = inet6_addr_lst[state->bucket];
2999 goto try_again;
3000 }
3001
3002 return ifa;
2990 return NULL;
3003}
3004
3005static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
3006{
3007 struct inet6_ifaddr *ifa = if6_get_first(seq);
3008
3009 if (ifa)
2991}
2992
2993static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
2994{
2995 struct inet6_ifaddr *ifa = if6_get_first(seq);
2996
2997 if (ifa)
3010 while(pos && (ifa = if6_get_next(seq, ifa)) != NULL)
2998 while (pos && (ifa = if6_get_next(seq, ifa)) != NULL)
3011 --pos;
3012 return pos ? NULL : ifa;
3013}
3014
3015static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
2999 --pos;
3000 return pos ? NULL : ifa;
3001}
3002
3003static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
3016 __acquires(addrconf_hash_lock)
3004 __acquires(rcu_bh)
3017{
3005{
3018 read_lock_bh(&addrconf_hash_lock);
3006 rcu_read_lock_bh();
3019 return if6_get_idx(seq, *pos);
3020}
3021
3022static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3023{
3024 struct inet6_ifaddr *ifa;
3025
3026 ifa = if6_get_next(seq, v);
3027 ++*pos;
3028 return ifa;
3029}
3030
3031static void if6_seq_stop(struct seq_file *seq, void *v)
3007 return if6_get_idx(seq, *pos);
3008}
3009
3010static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
3011{
3012 struct inet6_ifaddr *ifa;
3013
3014 ifa = if6_get_next(seq, v);
3015 ++*pos;
3016 return ifa;
3017}
3018
3019static void if6_seq_stop(struct seq_file *seq, void *v)
3032 __releases(addrconf_hash_lock)
3020 __releases(rcu_bh)
3033{
3021{
3034 read_unlock_bh(&addrconf_hash_lock);
3022 rcu_read_unlock_bh();
3035}
3036
3037static int if6_seq_show(struct seq_file *seq, void *v)
3038{
3039 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
3040 seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
3041 &ifp->addr,
3042 ifp->idev->dev->ifindex,

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

3096}
3097#endif /* CONFIG_PROC_FS */
3098
3099#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
3100/* Check if address is a home address configured on any interface. */
3101int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
3102{
3103 int ret = 0;
3023}
3024
3025static int if6_seq_show(struct seq_file *seq, void *v)
3026{
3027 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
3028 seq_printf(seq, "%pi6 %02x %02x %02x %02x %8s\n",
3029 &ifp->addr,
3030 ifp->idev->dev->ifindex,

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

3084}
3085#endif /* CONFIG_PROC_FS */
3086
3087#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
3088/* Check if address is a home address configured on any interface. */
3089int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
3090{
3091 int ret = 0;
3104 struct inet6_ifaddr * ifp;
3105 u8 hash = ipv6_addr_hash(addr);
3106 read_lock_bh(&addrconf_hash_lock);
3107 for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
3092 struct inet6_ifaddr *ifp = NULL;
3093 struct hlist_node *n;
3094 unsigned int hash = ipv6_addr_hash(addr);
3095
3096 rcu_read_lock_bh();
3097 hlist_for_each_entry_rcu_bh(ifp, n, &inet6_addr_lst[hash], addr_lst) {
3108 if (!net_eq(dev_net(ifp->idev->dev), net))
3109 continue;
3110 if (ipv6_addr_equal(&ifp->addr, addr) &&
3111 (ifp->flags & IFA_F_HOMEADDRESS)) {
3112 ret = 1;
3113 break;
3114 }
3115 }
3098 if (!net_eq(dev_net(ifp->idev->dev), net))
3099 continue;
3100 if (ipv6_addr_equal(&ifp->addr, addr) &&
3101 (ifp->flags & IFA_F_HOMEADDRESS)) {
3102 ret = 1;
3103 break;
3104 }
3105 }
3116 read_unlock_bh(&addrconf_hash_lock);
3106 rcu_read_unlock_bh();
3117 return ret;
3118}
3119#endif
3120
3121/*
3122 * Periodic address status verification
3123 */
3124
3125static void addrconf_verify(unsigned long foo)
3126{
3107 return ret;
3108}
3109#endif
3110
3111/*
3112 * Periodic address status verification
3113 */
3114
3115static void addrconf_verify(unsigned long foo)
3116{
3117 unsigned long now, next, next_sec, next_sched;
3127 struct inet6_ifaddr *ifp;
3118 struct inet6_ifaddr *ifp;
3128 unsigned long now, next;
3119 struct hlist_node *node;
3129 int i;
3130
3120 int i;
3121
3131 spin_lock_bh(&addrconf_verify_lock);
3122 rcu_read_lock_bh();
3123 spin_lock(&addrconf_verify_lock);
3132 now = jiffies;
3124 now = jiffies;
3133 next = now + ADDR_CHECK_FREQUENCY;
3125 next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY);
3134
3135 del_timer(&addr_chk_timer);
3136
3126
3127 del_timer(&addr_chk_timer);
3128
3137 for (i=0; i < IN6_ADDR_HSIZE; i++) {
3138
3129 for (i = 0; i < IN6_ADDR_HSIZE; i++) {
3139restart:
3130restart:
3140 read_lock(&addrconf_hash_lock);
3141 for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) {
3131 hlist_for_each_entry_rcu_bh(ifp, node,
3132 &inet6_addr_lst[i], addr_lst) {
3142 unsigned long age;
3133 unsigned long age;
3143#ifdef CONFIG_IPV6_PRIVACY
3144 unsigned long regen_advance;
3145#endif
3146
3147 if (ifp->flags & IFA_F_PERMANENT)
3148 continue;
3149
3150 spin_lock(&ifp->lock);
3134
3135 if (ifp->flags & IFA_F_PERMANENT)
3136 continue;
3137
3138 spin_lock(&ifp->lock);
3151 age = (now - ifp->tstamp) / HZ;
3139 /* We try to batch several events at once. */
3140 age = (now - ifp->tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
3152
3141
3153#ifdef CONFIG_IPV6_PRIVACY
3154 regen_advance = ifp->idev->cnf.regen_max_retry *
3155 ifp->idev->cnf.dad_transmits *
3156 ifp->idev->nd_parms->retrans_time / HZ;
3157#endif
3158
3159 if (ifp->valid_lft != INFINITY_LIFE_TIME &&
3160 age >= ifp->valid_lft) {
3161 spin_unlock(&ifp->lock);
3162 in6_ifa_hold(ifp);
3142 if (ifp->valid_lft != INFINITY_LIFE_TIME &&
3143 age >= ifp->valid_lft) {
3144 spin_unlock(&ifp->lock);
3145 in6_ifa_hold(ifp);
3163 read_unlock(&addrconf_hash_lock);
3164 ipv6_del_addr(ifp);
3165 goto restart;
3166 } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) {
3167 spin_unlock(&ifp->lock);
3168 continue;
3169 } else if (age >= ifp->prefered_lft) {
3170 /* jiffies - ifp->tstamp > age >= ifp->prefered_lft */
3171 int deprecate = 0;

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

3177
3178 if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next))
3179 next = ifp->tstamp + ifp->valid_lft * HZ;
3180
3181 spin_unlock(&ifp->lock);
3182
3183 if (deprecate) {
3184 in6_ifa_hold(ifp);
3146 ipv6_del_addr(ifp);
3147 goto restart;
3148 } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) {
3149 spin_unlock(&ifp->lock);
3150 continue;
3151 } else if (age >= ifp->prefered_lft) {
3152 /* jiffies - ifp->tstamp > age >= ifp->prefered_lft */
3153 int deprecate = 0;

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

3159
3160 if (time_before(ifp->tstamp + ifp->valid_lft * HZ, next))
3161 next = ifp->tstamp + ifp->valid_lft * HZ;
3162
3163 spin_unlock(&ifp->lock);
3164
3165 if (deprecate) {
3166 in6_ifa_hold(ifp);
3185 read_unlock(&addrconf_hash_lock);
3186
3187 ipv6_ifa_notify(0, ifp);
3188 in6_ifa_put(ifp);
3189 goto restart;
3190 }
3191#ifdef CONFIG_IPV6_PRIVACY
3192 } else if ((ifp->flags&IFA_F_TEMPORARY) &&
3193 !(ifp->flags&IFA_F_TENTATIVE)) {
3167
3168 ipv6_ifa_notify(0, ifp);
3169 in6_ifa_put(ifp);
3170 goto restart;
3171 }
3172#ifdef CONFIG_IPV6_PRIVACY
3173 } else if ((ifp->flags&IFA_F_TEMPORARY) &&
3174 !(ifp->flags&IFA_F_TENTATIVE)) {
3175 unsigned long regen_advance = ifp->idev->cnf.regen_max_retry *
3176 ifp->idev->cnf.dad_transmits *
3177 ifp->idev->nd_parms->retrans_time / HZ;
3178
3194 if (age >= ifp->prefered_lft - regen_advance) {
3195 struct inet6_ifaddr *ifpub = ifp->ifpub;
3196 if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
3197 next = ifp->tstamp + ifp->prefered_lft * HZ;
3198 if (!ifp->regen_count && ifpub) {
3199 ifp->regen_count++;
3200 in6_ifa_hold(ifp);
3201 in6_ifa_hold(ifpub);
3202 spin_unlock(&ifp->lock);
3179 if (age >= ifp->prefered_lft - regen_advance) {
3180 struct inet6_ifaddr *ifpub = ifp->ifpub;
3181 if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
3182 next = ifp->tstamp + ifp->prefered_lft * HZ;
3183 if (!ifp->regen_count && ifpub) {
3184 ifp->regen_count++;
3185 in6_ifa_hold(ifp);
3186 in6_ifa_hold(ifpub);
3187 spin_unlock(&ifp->lock);
3203 read_unlock(&addrconf_hash_lock);
3188
3204 spin_lock(&ifpub->lock);
3205 ifpub->regen_count = 0;
3206 spin_unlock(&ifpub->lock);
3207 ipv6_create_tempaddr(ifpub, ifp);
3208 in6_ifa_put(ifpub);
3209 in6_ifa_put(ifp);
3210 goto restart;
3211 }
3212 } else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
3213 next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
3214 spin_unlock(&ifp->lock);
3215#endif
3216 } else {
3217 /* ifp->prefered_lft <= ifp->valid_lft */
3218 if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
3219 next = ifp->tstamp + ifp->prefered_lft * HZ;
3220 spin_unlock(&ifp->lock);
3221 }
3222 }
3189 spin_lock(&ifpub->lock);
3190 ifpub->regen_count = 0;
3191 spin_unlock(&ifpub->lock);
3192 ipv6_create_tempaddr(ifpub, ifp);
3193 in6_ifa_put(ifpub);
3194 in6_ifa_put(ifp);
3195 goto restart;
3196 }
3197 } else if (time_before(ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ, next))
3198 next = ifp->tstamp + ifp->prefered_lft * HZ - regen_advance * HZ;
3199 spin_unlock(&ifp->lock);
3200#endif
3201 } else {
3202 /* ifp->prefered_lft <= ifp->valid_lft */
3203 if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
3204 next = ifp->tstamp + ifp->prefered_lft * HZ;
3205 spin_unlock(&ifp->lock);
3206 }
3207 }
3223 read_unlock(&addrconf_hash_lock);
3224 }
3225
3208 }
3209
3226 addr_chk_timer.expires = time_before(next, jiffies + HZ) ? jiffies + HZ : next;
3210 next_sec = round_jiffies_up(next);
3211 next_sched = next;
3212
3213 /* If rounded timeout is accurate enough, accept it. */
3214 if (time_before(next_sec, next + ADDRCONF_TIMER_FUZZ))
3215 next_sched = next_sec;
3216
3217 /* And minimum interval is ADDRCONF_TIMER_FUZZ_MAX. */
3218 if (time_before(next_sched, jiffies + ADDRCONF_TIMER_FUZZ_MAX))
3219 next_sched = jiffies + ADDRCONF_TIMER_FUZZ_MAX;
3220
3221 ADBG((KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n",
3222 now, next, next_sec, next_sched));
3223
3224 addr_chk_timer.expires = next_sched;
3227 add_timer(&addr_chk_timer);
3225 add_timer(&addr_chk_timer);
3228 spin_unlock_bh(&addrconf_verify_lock);
3226 spin_unlock(&addrconf_verify_lock);
3227 rcu_read_unlock_bh();
3229}
3230
3231static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
3232{
3233 struct in6_addr *pfx = NULL;
3234
3235 if (addr)
3236 pfx = nla_data(addr);

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

3510 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3511 nlmsg_cancel(skb, nlh);
3512 return -EMSGSIZE;
3513 }
3514
3515 return nlmsg_end(skb, nlh);
3516}
3517
3228}
3229
3230static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local)
3231{
3232 struct in6_addr *pfx = NULL;
3233
3234 if (addr)
3235 pfx = nla_data(addr);

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

3509 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME) < 0) {
3510 nlmsg_cancel(skb, nlh);
3511 return -EMSGSIZE;
3512 }
3513
3514 return nlmsg_end(skb, nlh);
3515}
3516
3518enum addr_type_t
3519{
3517enum addr_type_t {
3520 UNICAST_ADDR,
3521 MULTICAST_ADDR,
3522 ANYCAST_ADDR,
3523};
3524
3525/* called with rcu_read_lock() */
3526static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3527 struct netlink_callback *cb, enum addr_type_t type,
3528 int s_ip_idx, int *p_ip_idx)
3529{
3518 UNICAST_ADDR,
3519 MULTICAST_ADDR,
3520 ANYCAST_ADDR,
3521};
3522
3523/* called with rcu_read_lock() */
3524static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb,
3525 struct netlink_callback *cb, enum addr_type_t type,
3526 int s_ip_idx, int *p_ip_idx)
3527{
3530 struct inet6_ifaddr *ifa;
3531 struct ifmcaddr6 *ifmca;
3532 struct ifacaddr6 *ifaca;
3533 int err = 1;
3534 int ip_idx = *p_ip_idx;
3535
3536 read_lock_bh(&idev->lock);
3537 switch (type) {
3528 struct ifmcaddr6 *ifmca;
3529 struct ifacaddr6 *ifaca;
3530 int err = 1;
3531 int ip_idx = *p_ip_idx;
3532
3533 read_lock_bh(&idev->lock);
3534 switch (type) {
3538 case UNICAST_ADDR:
3535 case UNICAST_ADDR: {
3536 struct inet6_ifaddr *ifa;
3537
3539 /* unicast address incl. temp addr */
3538 /* unicast address incl. temp addr */
3540 for (ifa = idev->addr_list; ifa;
3541 ifa = ifa->if_next, ip_idx++) {
3542 if (ip_idx < s_ip_idx)
3539 list_for_each_entry(ifa, &idev->addr_list, if_list) {
3540 if (++ip_idx < s_ip_idx)
3543 continue;
3544 err = inet6_fill_ifaddr(skb, ifa,
3545 NETLINK_CB(cb->skb).pid,
3546 cb->nlh->nlmsg_seq,
3547 RTM_NEWADDR,
3548 NLM_F_MULTI);
3549 if (err <= 0)
3550 break;
3551 }
3552 break;
3541 continue;
3542 err = inet6_fill_ifaddr(skb, ifa,
3543 NETLINK_CB(cb->skb).pid,
3544 cb->nlh->nlmsg_seq,
3545 RTM_NEWADDR,
3546 NLM_F_MULTI);
3547 if (err <= 0)
3548 break;
3549 }
3550 break;
3551 }
3553 case MULTICAST_ADDR:
3554 /* multicast address */
3555 for (ifmca = idev->mc_list; ifmca;
3556 ifmca = ifmca->next, ip_idx++) {
3557 if (ip_idx < s_ip_idx)
3558 continue;
3559 err = inet6_fill_ifmcaddr(skb, ifmca,
3560 NETLINK_CB(cb->skb).pid,

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

3609 idx = 0;
3610 head = &net->dev_index_head[h];
3611 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3612 if (idx < s_idx)
3613 goto cont;
3614 if (h > s_h || idx > s_idx)
3615 s_ip_idx = 0;
3616 ip_idx = 0;
3552 case MULTICAST_ADDR:
3553 /* multicast address */
3554 for (ifmca = idev->mc_list; ifmca;
3555 ifmca = ifmca->next, ip_idx++) {
3556 if (ip_idx < s_ip_idx)
3557 continue;
3558 err = inet6_fill_ifmcaddr(skb, ifmca,
3559 NETLINK_CB(cb->skb).pid,

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

3608 idx = 0;
3609 head = &net->dev_index_head[h];
3610 hlist_for_each_entry_rcu(dev, node, head, index_hlist) {
3611 if (idx < s_idx)
3612 goto cont;
3613 if (h > s_h || idx > s_idx)
3614 s_ip_idx = 0;
3615 ip_idx = 0;
3617 if ((idev = __in6_dev_get(dev)) == NULL)
3616 idev = __in6_dev_get(dev);
3617 if (!idev)
3618 goto cont;
3619
3620 if (in6_dump_addrs(idev, skb, cb, type,
3621 s_ip_idx, &ip_idx) <= 0)
3622 goto done;
3623cont:
3624 idx++;
3625 }

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

3676 err = -EINVAL;
3677 goto errout;
3678 }
3679
3680 ifm = nlmsg_data(nlh);
3681 if (ifm->ifa_index)
3682 dev = __dev_get_by_index(net, ifm->ifa_index);
3683
3618 goto cont;
3619
3620 if (in6_dump_addrs(idev, skb, cb, type,
3621 s_ip_idx, &ip_idx) <= 0)
3622 goto done;
3623cont:
3624 idx++;
3625 }

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

3676 err = -EINVAL;
3677 goto errout;
3678 }
3679
3680 ifm = nlmsg_data(nlh);
3681 if (ifm->ifa_index)
3682 dev = __dev_get_by_index(net, ifm->ifa_index);
3683
3684 if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) {
3684 ifa = ipv6_get_ifaddr(net, addr, dev, 1);
3685 if (!ifa) {
3685 err = -EADDRNOTAVAIL;
3686 goto errout;
3687 }
3688
3686 err = -EADDRNOTAVAIL;
3687 goto errout;
3688 }
3689
3689 if ((skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL)) == NULL) {
3690 skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL);
3691 if (!skb) {
3690 err = -ENOBUFS;
3691 goto errout_ifa;
3692 }
3693
3694 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3695 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3696 if (err < 0) {
3697 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */

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

3806 put_unaligned(snmp_fold_field(mib, i), &stats[i]);
3807
3808 memset(&stats[items], 0, pad);
3809}
3810
3811static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3812 int bytes)
3813{
3692 err = -ENOBUFS;
3693 goto errout_ifa;
3694 }
3695
3696 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3697 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3698 if (err < 0) {
3699 /* -EMSGSIZE implies BUG in inet6_ifaddr_msgsize() */

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

3808 put_unaligned(snmp_fold_field(mib, i), &stats[i]);
3809
3810 memset(&stats[items], 0, pad);
3811}
3812
3813static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3814 int bytes)
3815{
3814 switch(attrtype) {
3816 switch (attrtype) {
3815 case IFLA_INET6_STATS:
3816 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3817 break;
3818 case IFLA_INET6_ICMP6STATS:
3819 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3820 break;
3821 }
3822}

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

4042 if (ifp->idev->cnf.forwarding)
4043 addrconf_join_anycast(ifp);
4044 break;
4045 case RTM_DELADDR:
4046 if (ifp->idev->cnf.forwarding)
4047 addrconf_leave_anycast(ifp);
4048 addrconf_leave_solict(ifp->idev, &ifp->addr);
4049 dst_hold(&ifp->rt->u.dst);
3817 case IFLA_INET6_STATS:
3818 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3819 break;
3820 case IFLA_INET6_ICMP6STATS:
3821 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3822 break;
3823 }
3824}

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

4044 if (ifp->idev->cnf.forwarding)
4045 addrconf_join_anycast(ifp);
4046 break;
4047 case RTM_DELADDR:
4048 if (ifp->idev->cnf.forwarding)
4049 addrconf_leave_anycast(ifp);
4050 addrconf_leave_solict(ifp->idev, &ifp->addr);
4051 dst_hold(&ifp->rt->u.dst);
4050 if (ip6_del_rt(ifp->rt))
4052
4053 if (ifp->dead && ip6_del_rt(ifp->rt))
4051 dst_free(&ifp->rt->u.dst);
4052 break;
4053 }
4054}
4055
4056static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
4057{
4058 rcu_read_lock_bh();

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

4158{
4159 struct ctl_table_header *sysctl_header;
4160 ctl_table addrconf_vars[DEVCONF_MAX+1];
4161 char *dev_name;
4162} addrconf_sysctl __read_mostly = {
4163 .sysctl_header = NULL,
4164 .addrconf_vars = {
4165 {
4054 dst_free(&ifp->rt->u.dst);
4055 break;
4056 }
4057}
4058
4059static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
4060{
4061 rcu_read_lock_bh();

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

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

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

4398 { },
4399 };
4400
4401
4402 t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
4403 if (t == NULL)
4404 goto out;
4405
4374 },
4375 {
4376 .procname = "force_tllao",
4377 .data = &ipv6_devconf.force_tllao,
4378 .maxlen = sizeof(int),
4379 .mode = 0644,
4380 .proc_handler = proc_dointvec
4381 },

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

4401 { },
4402 };
4403
4404
4405 t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
4406 if (t == NULL)
4407 goto out;
4408
4406 for (i=0; t->addrconf_vars[i].data; i++) {
4407 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
4409 for (i = 0; t->addrconf_vars[i].data; i++) {
4410 t->addrconf_vars[i].data += (char *)p - (char *)&ipv6_devconf;
4408 t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
4409 t->addrconf_vars[i].extra2 = net;
4410 }
4411
4412 /*
4413 * Make a copy of dev_name, because '.procname' is regarded as const
4414 * by sysctl and we wouldn't want anyone to change it under our feet
4415 * (see SIOCSIFNAME).

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

4536/*
4537 * Device notifier
4538 */
4539
4540int register_inet6addr_notifier(struct notifier_block *nb)
4541{
4542 return atomic_notifier_chain_register(&inet6addr_chain, nb);
4543}
4411 t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */
4412 t->addrconf_vars[i].extra2 = net;
4413 }
4414
4415 /*
4416 * Make a copy of dev_name, because '.procname' is regarded as const
4417 * by sysctl and we wouldn't want anyone to change it under our feet
4418 * (see SIOCSIFNAME).

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

4539/*
4540 * Device notifier
4541 */
4542
4543int register_inet6addr_notifier(struct notifier_block *nb)
4544{
4545 return atomic_notifier_chain_register(&inet6addr_chain, nb);
4546}
4544
4545EXPORT_SYMBOL(register_inet6addr_notifier);
4546
4547int unregister_inet6addr_notifier(struct notifier_block *nb)
4548{
4547EXPORT_SYMBOL(register_inet6addr_notifier);
4548
4549int unregister_inet6addr_notifier(struct notifier_block *nb)
4550{
4549 return atomic_notifier_chain_unregister(&inet6addr_chain,nb);
4551 return atomic_notifier_chain_unregister(&inet6addr_chain, nb);
4550}
4552}
4551
4552EXPORT_SYMBOL(unregister_inet6addr_notifier);
4553
4554/*
4555 * Init / cleanup code
4556 */
4557
4558int __init addrconf_init(void)
4559{
4553EXPORT_SYMBOL(unregister_inet6addr_notifier);
4554
4555/*
4556 * Init / cleanup code
4557 */
4558
4559int __init addrconf_init(void)
4560{
4560 int err;
4561 int i, err;
4561
4562
4562 if ((err = ipv6_addr_label_init()) < 0) {
4563 printk(KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n",
4564 err);
4563 err = ipv6_addr_label_init();
4564 if (err < 0) {
4565 printk(KERN_CRIT "IPv6 Addrconf:"
4566 " cannot initialize default policy table: %d.\n", err);
4565 return err;
4566 }
4567
4568 register_pernet_subsys(&addrconf_ops);
4569
4570 /* The addrconf netdev notifier requires that loopback_dev
4571 * has it's ipv6 private information allocated and setup
4572 * before it can bring up and give link-local addresses

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

4587 */
4588 rtnl_lock();
4589 if (!ipv6_add_dev(init_net.loopback_dev))
4590 err = -ENOMEM;
4591 rtnl_unlock();
4592 if (err)
4593 goto errlo;
4594
4567 return err;
4568 }
4569
4570 register_pernet_subsys(&addrconf_ops);
4571
4572 /* The addrconf netdev notifier requires that loopback_dev
4573 * has it's ipv6 private information allocated and setup
4574 * before it can bring up and give link-local addresses

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

4589 */
4590 rtnl_lock();
4591 if (!ipv6_add_dev(init_net.loopback_dev))
4592 err = -ENOMEM;
4593 rtnl_unlock();
4594 if (err)
4595 goto errlo;
4596
4597 for (i = 0; i < IN6_ADDR_HSIZE; i++)
4598 INIT_HLIST_HEAD(&inet6_addr_lst[i]);
4599
4595 register_netdevice_notifier(&ipv6_dev_notf);
4596
4597 addrconf_verify(0);
4598
4599 err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo);
4600 if (err < 0)
4601 goto errout;
4602

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

4615errlo:
4616 unregister_pernet_subsys(&addrconf_ops);
4617
4618 return err;
4619}
4620
4621void addrconf_cleanup(void)
4622{
4600 register_netdevice_notifier(&ipv6_dev_notf);
4601
4602 addrconf_verify(0);
4603
4604 err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo);
4605 if (err < 0)
4606 goto errout;
4607

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

4620errlo:
4621 unregister_pernet_subsys(&addrconf_ops);
4622
4623 return err;
4624}
4625
4626void addrconf_cleanup(void)
4627{
4623 struct inet6_ifaddr *ifa;
4624 struct net_device *dev;
4625 int i;
4626
4627 unregister_netdevice_notifier(&ipv6_dev_notf);
4628 unregister_pernet_subsys(&addrconf_ops);
4629
4630 rtnl_lock();
4631
4632 /* clean dev list */
4633 for_each_netdev(&init_net, dev) {
4634 if (__in6_dev_get(dev) == NULL)
4635 continue;
4636 addrconf_ifdown(dev, 1);
4637 }
4638 addrconf_ifdown(init_net.loopback_dev, 2);
4639
4640 /*
4641 * Check hash table.
4642 */
4628 struct net_device *dev;
4629 int i;
4630
4631 unregister_netdevice_notifier(&ipv6_dev_notf);
4632 unregister_pernet_subsys(&addrconf_ops);
4633
4634 rtnl_lock();
4635
4636 /* clean dev list */
4637 for_each_netdev(&init_net, dev) {
4638 if (__in6_dev_get(dev) == NULL)
4639 continue;
4640 addrconf_ifdown(dev, 1);
4641 }
4642 addrconf_ifdown(init_net.loopback_dev, 2);
4643
4644 /*
4645 * Check hash table.
4646 */
4643 write_lock_bh(&addrconf_hash_lock);
4644 for (i=0; i < IN6_ADDR_HSIZE; i++) {
4645 for (ifa=inet6_addr_lst[i]; ifa; ) {
4646 struct inet6_ifaddr *bifa;
4647 spin_lock_bh(&addrconf_hash_lock);
4648 for (i = 0; i < IN6_ADDR_HSIZE; i++)
4649 WARN_ON(!hlist_empty(&inet6_addr_lst[i]));
4650 spin_unlock_bh(&addrconf_hash_lock);
4647
4651
4648 bifa = ifa;
4649 ifa = ifa->lst_next;
4650 printk(KERN_DEBUG "bug: IPv6 address leakage detected: ifa=%p\n", bifa);
4651 /* Do not free it; something is wrong.
4652 Now we can investigate it with debugger.
4653 */
4654 }
4655 }
4656 write_unlock_bh(&addrconf_hash_lock);
4657
4658 del_timer(&addr_chk_timer);
4659 rtnl_unlock();
4660}
4652 del_timer(&addr_chk_timer);
4653 rtnl_unlock();
4654}