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} |