diff options
author | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-04-20 10:02:01 -0400 |
commit | 62910554656cdcd6b6f84a5154c4155aae4ca231 (patch) | |
tree | dcf14004f6fd2ef7154362ff948bfeba0f3ea92d /net/ipv6 | |
parent | 22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff) | |
parent | ab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
Documentation/feature-removal-schedule.txt
net/ipv6/netfilter/ip6t_REJECT.c
net/netfilter/xt_limit.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6')
39 files changed, 517 insertions, 498 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3381b4317c27..7cba8845242f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #include <linux/route.h> | 53 | #include <linux/route.h> |
54 | #include <linux/inetdevice.h> | 54 | #include <linux/inetdevice.h> |
55 | #include <linux/init.h> | 55 | #include <linux/init.h> |
56 | #include <linux/slab.h> | ||
56 | #ifdef CONFIG_SYSCTL | 57 | #ifdef CONFIG_SYSCTL |
57 | #include <linux/sysctl.h> | 58 | #include <linux/sysctl.h> |
58 | #endif | 59 | #endif |
@@ -81,7 +82,7 @@ | |||
81 | #include <linux/random.h> | 82 | #include <linux/random.h> |
82 | #endif | 83 | #endif |
83 | 84 | ||
84 | #include <asm/uaccess.h> | 85 | #include <linux/uaccess.h> |
85 | #include <asm/unaligned.h> | 86 | #include <asm/unaligned.h> |
86 | 87 | ||
87 | #include <linux/proc_fs.h> | 88 | #include <linux/proc_fs.h> |
@@ -97,7 +98,11 @@ | |||
97 | #endif | 98 | #endif |
98 | 99 | ||
99 | #define INFINITY_LIFE_TIME 0xFFFFFFFF | 100 | #define INFINITY_LIFE_TIME 0xFFFFFFFF |
100 | #define TIME_DELTA(a,b) ((unsigned long)((long)(a) - (long)(b))) | 101 | #define TIME_DELTA(a, b) ((unsigned long)((long)(a) - (long)(b))) |
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) | ||
101 | 106 | ||
102 | #ifdef CONFIG_SYSCTL | 107 | #ifdef CONFIG_SYSCTL |
103 | static void addrconf_sysctl_register(struct inet6_dev *idev); | 108 | static void addrconf_sysctl_register(struct inet6_dev *idev); |
@@ -126,8 +131,8 @@ static int ipv6_count_addresses(struct inet6_dev *idev); | |||
126 | /* | 131 | /* |
127 | * Configured unicast address hash table | 132 | * Configured unicast address hash table |
128 | */ | 133 | */ |
129 | static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE]; | 134 | static struct hlist_head inet6_addr_lst[IN6_ADDR_HSIZE]; |
130 | static DEFINE_RWLOCK(addrconf_hash_lock); | 135 | static DEFINE_SPINLOCK(addrconf_hash_lock); |
131 | 136 | ||
132 | static void addrconf_verify(unsigned long); | 137 | static void addrconf_verify(unsigned long); |
133 | 138 | ||
@@ -137,8 +142,8 @@ static DEFINE_SPINLOCK(addrconf_verify_lock); | |||
137 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp); | 142 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp); |
138 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); | 143 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp); |
139 | 144 | ||
140 | static void addrconf_bonding_change(struct net_device *dev, | 145 | static void addrconf_type_change(struct net_device *dev, |
141 | unsigned long event); | 146 | unsigned long event); |
142 | static int addrconf_ifdown(struct net_device *dev, int how); | 147 | static int addrconf_ifdown(struct net_device *dev, int how); |
143 | 148 | ||
144 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); | 149 | static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags); |
@@ -151,8 +156,8 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); | |||
151 | 156 | ||
152 | static void inet6_prefix_notify(int event, struct inet6_dev *idev, | 157 | static void inet6_prefix_notify(int event, struct inet6_dev *idev, |
153 | struct prefix_info *pinfo); | 158 | struct prefix_info *pinfo); |
154 | static int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | 159 | static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, |
155 | struct net_device *dev); | 160 | struct net_device *dev); |
156 | 161 | ||
157 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); | 162 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); |
158 | 163 | ||
@@ -249,8 +254,7 @@ static void addrconf_del_timer(struct inet6_ifaddr *ifp) | |||
249 | __in6_ifa_put(ifp); | 254 | __in6_ifa_put(ifp); |
250 | } | 255 | } |
251 | 256 | ||
252 | enum addrconf_timer_t | 257 | enum addrconf_timer_t { |
253 | { | ||
254 | AC_NONE, | 258 | AC_NONE, |
255 | AC_DAD, | 259 | AC_DAD, |
256 | AC_RS, | 260 | AC_RS, |
@@ -270,7 +274,8 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp, | |||
270 | case AC_RS: | 274 | case AC_RS: |
271 | ifp->timer.function = addrconf_rs_timer; | 275 | ifp->timer.function = addrconf_rs_timer; |
272 | break; | 276 | break; |
273 | default:; | 277 | default: |
278 | break; | ||
274 | } | 279 | } |
275 | ifp->timer.expires = jiffies + when; | 280 | ifp->timer.expires = jiffies + when; |
276 | add_timer(&ifp->timer); | 281 | add_timer(&ifp->timer); |
@@ -317,7 +322,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) | |||
317 | { | 322 | { |
318 | struct net_device *dev = idev->dev; | 323 | struct net_device *dev = idev->dev; |
319 | 324 | ||
320 | WARN_ON(idev->addr_list != NULL); | 325 | WARN_ON(!list_empty(&idev->addr_list)); |
321 | WARN_ON(idev->mc_list != NULL); | 326 | WARN_ON(idev->mc_list != NULL); |
322 | 327 | ||
323 | #ifdef NET_REFCNT_DEBUG | 328 | #ifdef NET_REFCNT_DEBUG |
@@ -325,7 +330,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) | |||
325 | #endif | 330 | #endif |
326 | dev_put(dev); | 331 | dev_put(dev); |
327 | if (!idev->dead) { | 332 | if (!idev->dead) { |
328 | printk("Freeing alive inet6 device %p\n", idev); | 333 | pr_warning("Freeing alive inet6 device %p\n", idev); |
329 | return; | 334 | return; |
330 | } | 335 | } |
331 | snmp6_free_dev(idev); | 336 | snmp6_free_dev(idev); |
@@ -350,6 +355,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
350 | 355 | ||
351 | rwlock_init(&ndev->lock); | 356 | rwlock_init(&ndev->lock); |
352 | ndev->dev = dev; | 357 | ndev->dev = dev; |
358 | INIT_LIST_HEAD(&ndev->addr_list); | ||
359 | |||
353 | memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf)); | 360 | memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf)); |
354 | ndev->cnf.mtu6 = dev->mtu; | 361 | ndev->cnf.mtu6 = dev->mtu; |
355 | ndev->cnf.sysctl = NULL; | 362 | ndev->cnf.sysctl = NULL; |
@@ -401,6 +408,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
401 | #endif | 408 | #endif |
402 | 409 | ||
403 | #ifdef CONFIG_IPV6_PRIVACY | 410 | #ifdef CONFIG_IPV6_PRIVACY |
411 | INIT_LIST_HEAD(&ndev->tempaddr_list); | ||
404 | setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev); | 412 | setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev); |
405 | if ((dev->flags&IFF_LOOPBACK) || | 413 | if ((dev->flags&IFF_LOOPBACK) || |
406 | dev->type == ARPHRD_TUNNEL || | 414 | dev->type == ARPHRD_TUNNEL || |
@@ -438,8 +446,10 @@ static struct inet6_dev * ipv6_find_idev(struct net_device *dev) | |||
438 | 446 | ||
439 | ASSERT_RTNL(); | 447 | ASSERT_RTNL(); |
440 | 448 | ||
441 | if ((idev = __in6_dev_get(dev)) == NULL) { | 449 | idev = __in6_dev_get(dev); |
442 | if ((idev = ipv6_add_dev(dev)) == NULL) | 450 | if (!idev) { |
451 | idev = ipv6_add_dev(dev); | ||
452 | if (!idev) | ||
443 | return NULL; | 453 | return NULL; |
444 | } | 454 | } |
445 | 455 | ||
@@ -465,7 +475,8 @@ static void dev_forward_change(struct inet6_dev *idev) | |||
465 | else | 475 | else |
466 | ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters); | 476 | ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters); |
467 | } | 477 | } |
468 | for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) { | 478 | |
479 | list_for_each_entry(ifa, &idev->addr_list, if_list) { | ||
469 | if (ifa->flags&IFA_F_TENTATIVE) | 480 | if (ifa->flags&IFA_F_TENTATIVE) |
470 | continue; | 481 | continue; |
471 | if (idev->cnf.forwarding) | 482 | if (idev->cnf.forwarding) |
@@ -522,12 +533,16 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old) | |||
522 | } | 533 | } |
523 | #endif | 534 | #endif |
524 | 535 | ||
525 | /* Nobody refers to this ifaddr, destroy it */ | 536 | static 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 | } | ||
526 | 541 | ||
542 | /* Nobody refers to this ifaddr, destroy it */ | ||
527 | void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | 543 | void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) |
528 | { | 544 | { |
529 | WARN_ON(ifp->if_next != NULL); | 545 | WARN_ON(!hlist_unhashed(&ifp->addr_lst)); |
530 | WARN_ON(ifp->lst_next != NULL); | ||
531 | 546 | ||
532 | #ifdef NET_REFCNT_DEBUG | 547 | #ifdef NET_REFCNT_DEBUG |
533 | printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); | 548 | printk(KERN_DEBUG "inet6_ifa_finish_destroy\n"); |
@@ -536,54 +551,45 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) | |||
536 | in6_dev_put(ifp->idev); | 551 | in6_dev_put(ifp->idev); |
537 | 552 | ||
538 | if (del_timer(&ifp->timer)) | 553 | if (del_timer(&ifp->timer)) |
539 | printk("Timer is still running, when freeing ifa=%p\n", ifp); | 554 | pr_notice("Timer is still running, when freeing ifa=%p\n", ifp); |
540 | 555 | ||
541 | if (!ifp->dead) { | 556 | if (!ifp->dead) { |
542 | printk("Freeing alive inet6 address %p\n", ifp); | 557 | pr_warning("Freeing alive inet6 address %p\n", ifp); |
543 | return; | 558 | return; |
544 | } | 559 | } |
545 | dst_release(&ifp->rt->u.dst); | 560 | dst_release(&ifp->rt->u.dst); |
546 | 561 | ||
547 | kfree(ifp); | 562 | call_rcu(&ifp->rcu, inet6_ifa_finish_destroy_rcu); |
548 | } | 563 | } |
549 | 564 | ||
550 | static void | 565 | static void |
551 | ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) | 566 | ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp) |
552 | { | 567 | { |
553 | struct inet6_ifaddr *ifa, **ifap; | 568 | struct list_head *p; |
554 | int ifp_scope = ipv6_addr_src_scope(&ifp->addr); | 569 | int ifp_scope = ipv6_addr_src_scope(&ifp->addr); |
555 | 570 | ||
556 | /* | 571 | /* |
557 | * Each device address list is sorted in order of scope - | 572 | * Each device address list is sorted in order of scope - |
558 | * global before linklocal. | 573 | * global before linklocal. |
559 | */ | 574 | */ |
560 | for (ifap = &idev->addr_list; (ifa = *ifap) != NULL; | 575 | list_for_each(p, &idev->addr_list) { |
561 | ifap = &ifa->if_next) { | 576 | struct inet6_ifaddr *ifa |
577 | = list_entry(p, struct inet6_ifaddr, if_list); | ||
562 | if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr)) | 578 | if (ifp_scope >= ipv6_addr_src_scope(&ifa->addr)) |
563 | break; | 579 | break; |
564 | } | 580 | } |
565 | 581 | ||
566 | ifp->if_next = *ifap; | 582 | list_add_tail(&ifp->if_list, p); |
567 | *ifap = ifp; | ||
568 | } | 583 | } |
569 | 584 | ||
570 | /* | 585 | static u32 ipv6_addr_hash(const struct in6_addr *addr) |
571 | * Hash function taken from net_alias.c | ||
572 | */ | ||
573 | static u8 ipv6_addr_hash(const struct in6_addr *addr) | ||
574 | { | 586 | { |
575 | __u32 word; | ||
576 | |||
577 | /* | 587 | /* |
578 | * We perform the hash function over the last 64 bits of the address | 588 | * We perform the hash function over the last 64 bits of the address |
579 | * This will include the IEEE address token on links that support it. | 589 | * This will include the IEEE address token on links that support it. |
580 | */ | 590 | */ |
581 | 591 | return jhash_2words(addr->s6_addr32[2], addr->s6_addr32[3], 0) | |
582 | word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]); | 592 | & (IN6_ADDR_HSIZE - 1); |
583 | word ^= (word >> 16); | ||
584 | word ^= (word >> 8); | ||
585 | |||
586 | return ((word ^ (word >> 4)) & 0x0f); | ||
587 | } | 593 | } |
588 | 594 | ||
589 | /* On success it returns ifp with increased reference count */ | 595 | /* On success it returns ifp with increased reference count */ |
@@ -594,7 +600,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
594 | { | 600 | { |
595 | struct inet6_ifaddr *ifa = NULL; | 601 | struct inet6_ifaddr *ifa = NULL; |
596 | struct rt6_info *rt; | 602 | struct rt6_info *rt; |
597 | int hash; | 603 | unsigned int hash; |
598 | int err = 0; | 604 | int err = 0; |
599 | int addr_type = ipv6_addr_type(addr); | 605 | int addr_type = ipv6_addr_type(addr); |
600 | 606 | ||
@@ -615,7 +621,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
615 | goto out2; | 621 | goto out2; |
616 | } | 622 | } |
617 | 623 | ||
618 | write_lock(&addrconf_hash_lock); | 624 | spin_lock(&addrconf_hash_lock); |
619 | 625 | ||
620 | /* Ignore adding duplicate addresses on an interface */ | 626 | /* Ignore adding duplicate addresses on an interface */ |
621 | if (ipv6_chk_same_addr(dev_net(idev->dev), addr, idev->dev)) { | 627 | if (ipv6_chk_same_addr(dev_net(idev->dev), addr, idev->dev)) { |
@@ -642,6 +648,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
642 | 648 | ||
643 | spin_lock_init(&ifa->lock); | 649 | spin_lock_init(&ifa->lock); |
644 | init_timer(&ifa->timer); | 650 | init_timer(&ifa->timer); |
651 | INIT_HLIST_NODE(&ifa->addr_lst); | ||
645 | ifa->timer.data = (unsigned long) ifa; | 652 | ifa->timer.data = (unsigned long) ifa; |
646 | ifa->scope = scope; | 653 | ifa->scope = scope; |
647 | ifa->prefix_len = pfxlen; | 654 | ifa->prefix_len = pfxlen; |
@@ -668,10 +675,8 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
668 | /* Add to big hash table */ | 675 | /* Add to big hash table */ |
669 | hash = ipv6_addr_hash(addr); | 676 | hash = ipv6_addr_hash(addr); |
670 | 677 | ||
671 | ifa->lst_next = inet6_addr_lst[hash]; | 678 | hlist_add_head_rcu(&ifa->addr_lst, &inet6_addr_lst[hash]); |
672 | inet6_addr_lst[hash] = ifa; | 679 | spin_unlock(&addrconf_hash_lock); |
673 | in6_ifa_hold(ifa); | ||
674 | write_unlock(&addrconf_hash_lock); | ||
675 | 680 | ||
676 | write_lock(&idev->lock); | 681 | write_lock(&idev->lock); |
677 | /* Add to inet6_dev unicast addr list. */ | 682 | /* Add to inet6_dev unicast addr list. */ |
@@ -679,8 +684,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
679 | 684 | ||
680 | #ifdef CONFIG_IPV6_PRIVACY | 685 | #ifdef CONFIG_IPV6_PRIVACY |
681 | if (ifa->flags&IFA_F_TEMPORARY) { | 686 | if (ifa->flags&IFA_F_TEMPORARY) { |
682 | ifa->tmp_next = idev->tempaddr_list; | 687 | list_add(&ifa->tmp_list, &idev->tempaddr_list); |
683 | idev->tempaddr_list = ifa; | ||
684 | in6_ifa_hold(ifa); | 688 | in6_ifa_hold(ifa); |
685 | } | 689 | } |
686 | #endif | 690 | #endif |
@@ -699,7 +703,7 @@ out2: | |||
699 | 703 | ||
700 | return ifa; | 704 | return ifa; |
701 | out: | 705 | out: |
702 | write_unlock(&addrconf_hash_lock); | 706 | spin_unlock(&addrconf_hash_lock); |
703 | goto out2; | 707 | goto out2; |
704 | } | 708 | } |
705 | 709 | ||
@@ -707,7 +711,7 @@ out: | |||
707 | 711 | ||
708 | static void ipv6_del_addr(struct inet6_ifaddr *ifp) | 712 | static void ipv6_del_addr(struct inet6_ifaddr *ifp) |
709 | { | 713 | { |
710 | struct inet6_ifaddr *ifa, **ifap; | 714 | struct inet6_ifaddr *ifa, *ifn; |
711 | struct inet6_dev *idev = ifp->idev; | 715 | struct inet6_dev *idev = ifp->idev; |
712 | int hash; | 716 | int hash; |
713 | int deleted = 0, onlink = 0; | 717 | int deleted = 0, onlink = 0; |
@@ -717,42 +721,27 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
717 | 721 | ||
718 | ifp->dead = 1; | 722 | ifp->dead = 1; |
719 | 723 | ||
720 | write_lock_bh(&addrconf_hash_lock); | 724 | spin_lock_bh(&addrconf_hash_lock); |
721 | for (ifap = &inet6_addr_lst[hash]; (ifa=*ifap) != NULL; | 725 | hlist_del_init_rcu(&ifp->addr_lst); |
722 | ifap = &ifa->lst_next) { | 726 | spin_unlock_bh(&addrconf_hash_lock); |
723 | if (ifa == ifp) { | ||
724 | *ifap = ifa->lst_next; | ||
725 | __in6_ifa_put(ifp); | ||
726 | ifa->lst_next = NULL; | ||
727 | break; | ||
728 | } | ||
729 | } | ||
730 | write_unlock_bh(&addrconf_hash_lock); | ||
731 | 727 | ||
732 | write_lock_bh(&idev->lock); | 728 | write_lock_bh(&idev->lock); |
733 | #ifdef CONFIG_IPV6_PRIVACY | 729 | #ifdef CONFIG_IPV6_PRIVACY |
734 | if (ifp->flags&IFA_F_TEMPORARY) { | 730 | if (ifp->flags&IFA_F_TEMPORARY) { |
735 | for (ifap = &idev->tempaddr_list; (ifa=*ifap) != NULL; | 731 | list_del(&ifp->tmp_list); |
736 | ifap = &ifa->tmp_next) { | 732 | if (ifp->ifpub) { |
737 | if (ifa == ifp) { | 733 | in6_ifa_put(ifp->ifpub); |
738 | *ifap = ifa->tmp_next; | 734 | ifp->ifpub = NULL; |
739 | if (ifp->ifpub) { | ||
740 | in6_ifa_put(ifp->ifpub); | ||
741 | ifp->ifpub = NULL; | ||
742 | } | ||
743 | __in6_ifa_put(ifp); | ||
744 | ifa->tmp_next = NULL; | ||
745 | break; | ||
746 | } | ||
747 | } | 735 | } |
736 | __in6_ifa_put(ifp); | ||
748 | } | 737 | } |
749 | #endif | 738 | #endif |
750 | 739 | ||
751 | for (ifap = &idev->addr_list; (ifa=*ifap) != NULL;) { | 740 | list_for_each_entry_safe(ifa, ifn, &idev->addr_list, if_list) { |
752 | if (ifa == ifp) { | 741 | if (ifa == ifp) { |
753 | *ifap = ifa->if_next; | 742 | list_del_init(&ifp->if_list); |
754 | __in6_ifa_put(ifp); | 743 | __in6_ifa_put(ifp); |
755 | ifa->if_next = NULL; | 744 | |
756 | if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0) | 745 | if (!(ifp->flags & IFA_F_PERMANENT) || onlink > 0) |
757 | break; | 746 | break; |
758 | deleted = 1; | 747 | deleted = 1; |
@@ -785,7 +774,6 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
785 | } | 774 | } |
786 | } | 775 | } |
787 | } | 776 | } |
788 | ifap = &ifa->if_next; | ||
789 | } | 777 | } |
790 | write_unlock_bh(&idev->lock); | 778 | write_unlock_bh(&idev->lock); |
791 | 779 | ||
@@ -1164,7 +1152,7 @@ int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev, | |||
1164 | continue; | 1152 | continue; |
1165 | 1153 | ||
1166 | read_lock_bh(&idev->lock); | 1154 | read_lock_bh(&idev->lock); |
1167 | for (score->ifa = idev->addr_list; score->ifa; score->ifa = score->ifa->if_next) { | 1155 | list_for_each_entry(score->ifa, &idev->addr_list, if_list) { |
1168 | int i; | 1156 | int i; |
1169 | 1157 | ||
1170 | /* | 1158 | /* |
@@ -1242,7 +1230,6 @@ try_nextdev: | |||
1242 | in6_ifa_put(hiscore->ifa); | 1230 | in6_ifa_put(hiscore->ifa); |
1243 | return 0; | 1231 | return 0; |
1244 | } | 1232 | } |
1245 | |||
1246 | EXPORT_SYMBOL(ipv6_dev_get_saddr); | 1233 | EXPORT_SYMBOL(ipv6_dev_get_saddr); |
1247 | 1234 | ||
1248 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | 1235 | int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, |
@@ -1252,12 +1239,14 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, | |||
1252 | int err = -EADDRNOTAVAIL; | 1239 | int err = -EADDRNOTAVAIL; |
1253 | 1240 | ||
1254 | rcu_read_lock(); | 1241 | rcu_read_lock(); |
1255 | if ((idev = __in6_dev_get(dev)) != NULL) { | 1242 | idev = __in6_dev_get(dev); |
1243 | if (idev) { | ||
1256 | struct inet6_ifaddr *ifp; | 1244 | struct inet6_ifaddr *ifp; |
1257 | 1245 | ||
1258 | read_lock_bh(&idev->lock); | 1246 | read_lock_bh(&idev->lock); |
1259 | for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { | 1247 | list_for_each_entry(ifp, &idev->addr_list, if_list) { |
1260 | if (ifp->scope == IFA_LINK && !(ifp->flags & banned_flags)) { | 1248 | if (ifp->scope == IFA_LINK && |
1249 | !(ifp->flags & banned_flags)) { | ||
1261 | ipv6_addr_copy(addr, &ifp->addr); | 1250 | ipv6_addr_copy(addr, &ifp->addr); |
1262 | err = 0; | 1251 | err = 0; |
1263 | break; | 1252 | break; |
@@ -1275,7 +1264,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev) | |||
1275 | struct inet6_ifaddr *ifp; | 1264 | struct inet6_ifaddr *ifp; |
1276 | 1265 | ||
1277 | read_lock_bh(&idev->lock); | 1266 | read_lock_bh(&idev->lock); |
1278 | for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) | 1267 | list_for_each_entry(ifp, &idev->addr_list, if_list) |
1279 | cnt++; | 1268 | cnt++; |
1280 | read_unlock_bh(&idev->lock); | 1269 | read_unlock_bh(&idev->lock); |
1281 | return cnt; | 1270 | return cnt; |
@@ -1284,11 +1273,12 @@ static int ipv6_count_addresses(struct inet6_dev *idev) | |||
1284 | int ipv6_chk_addr(struct net *net, struct in6_addr *addr, | 1273 | int ipv6_chk_addr(struct net *net, struct in6_addr *addr, |
1285 | struct net_device *dev, int strict) | 1274 | struct net_device *dev, int strict) |
1286 | { | 1275 | { |
1287 | struct inet6_ifaddr * ifp; | 1276 | struct inet6_ifaddr *ifp = NULL; |
1288 | u8 hash = ipv6_addr_hash(addr); | 1277 | struct hlist_node *node; |
1278 | unsigned int hash = ipv6_addr_hash(addr); | ||
1289 | 1279 | ||
1290 | read_lock_bh(&addrconf_hash_lock); | 1280 | rcu_read_lock_bh(); |
1291 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1281 | hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[hash], addr_lst) { |
1292 | if (!net_eq(dev_net(ifp->idev->dev), net)) | 1282 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1293 | continue; | 1283 | continue; |
1294 | if (ipv6_addr_equal(&ifp->addr, addr) && | 1284 | if (ipv6_addr_equal(&ifp->addr, addr) && |
@@ -1298,27 +1288,28 @@ int ipv6_chk_addr(struct net *net, struct in6_addr *addr, | |||
1298 | break; | 1288 | break; |
1299 | } | 1289 | } |
1300 | } | 1290 | } |
1301 | read_unlock_bh(&addrconf_hash_lock); | 1291 | rcu_read_unlock_bh(); |
1292 | |||
1302 | return ifp != NULL; | 1293 | return ifp != NULL; |
1303 | } | 1294 | } |
1304 | EXPORT_SYMBOL(ipv6_chk_addr); | 1295 | EXPORT_SYMBOL(ipv6_chk_addr); |
1305 | 1296 | ||
1306 | static | 1297 | static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, |
1307 | int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | 1298 | struct net_device *dev) |
1308 | struct net_device *dev) | ||
1309 | { | 1299 | { |
1310 | struct inet6_ifaddr * ifp; | 1300 | unsigned int hash = ipv6_addr_hash(addr); |
1311 | u8 hash = ipv6_addr_hash(addr); | 1301 | struct inet6_ifaddr *ifp; |
1302 | struct hlist_node *node; | ||
1312 | 1303 | ||
1313 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1304 | hlist_for_each_entry(ifp, node, &inet6_addr_lst[hash], addr_lst) { |
1314 | if (!net_eq(dev_net(ifp->idev->dev), net)) | 1305 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1315 | continue; | 1306 | continue; |
1316 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1307 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1317 | if (dev == NULL || ifp->idev->dev == dev) | 1308 | if (dev == NULL || ifp->idev->dev == dev) |
1318 | break; | 1309 | return true; |
1319 | } | 1310 | } |
1320 | } | 1311 | } |
1321 | return ifp != NULL; | 1312 | return false; |
1322 | } | 1313 | } |
1323 | 1314 | ||
1324 | int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev) | 1315 | int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev) |
@@ -1332,7 +1323,7 @@ int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev) | |||
1332 | idev = __in6_dev_get(dev); | 1323 | idev = __in6_dev_get(dev); |
1333 | if (idev) { | 1324 | if (idev) { |
1334 | read_lock_bh(&idev->lock); | 1325 | read_lock_bh(&idev->lock); |
1335 | for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) { | 1326 | list_for_each_entry(ifa, &idev->addr_list, if_list) { |
1336 | onlink = ipv6_prefix_equal(addr, &ifa->addr, | 1327 | onlink = ipv6_prefix_equal(addr, &ifa->addr, |
1337 | ifa->prefix_len); | 1328 | ifa->prefix_len); |
1338 | if (onlink) | 1329 | if (onlink) |
@@ -1349,24 +1340,26 @@ EXPORT_SYMBOL(ipv6_chk_prefix); | |||
1349 | struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr, | 1340 | struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr, |
1350 | struct net_device *dev, int strict) | 1341 | struct net_device *dev, int strict) |
1351 | { | 1342 | { |
1352 | struct inet6_ifaddr * ifp; | 1343 | struct inet6_ifaddr *ifp, *result = NULL; |
1353 | u8 hash = ipv6_addr_hash(addr); | 1344 | unsigned int hash = ipv6_addr_hash(addr); |
1345 | struct hlist_node *node; | ||
1354 | 1346 | ||
1355 | read_lock_bh(&addrconf_hash_lock); | 1347 | rcu_read_lock_bh(); |
1356 | for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { | 1348 | hlist_for_each_entry_rcu(ifp, node, &inet6_addr_lst[hash], addr_lst) { |
1357 | if (!net_eq(dev_net(ifp->idev->dev), net)) | 1349 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
1358 | continue; | 1350 | continue; |
1359 | if (ipv6_addr_equal(&ifp->addr, addr)) { | 1351 | if (ipv6_addr_equal(&ifp->addr, addr)) { |
1360 | if (dev == NULL || ifp->idev->dev == dev || | 1352 | if (dev == NULL || ifp->idev->dev == dev || |
1361 | !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) { | 1353 | !(ifp->scope&(IFA_LINK|IFA_HOST) || strict)) { |
1354 | result = ifp; | ||
1362 | in6_ifa_hold(ifp); | 1355 | in6_ifa_hold(ifp); |
1363 | break; | 1356 | break; |
1364 | } | 1357 | } |
1365 | } | 1358 | } |
1366 | } | 1359 | } |
1367 | read_unlock_bh(&addrconf_hash_lock); | 1360 | rcu_read_unlock_bh(); |
1368 | 1361 | ||
1369 | return ifp; | 1362 | return result; |
1370 | } | 1363 | } |
1371 | 1364 | ||
1372 | /* Gets referenced address, destroys ifaddr */ | 1365 | /* Gets referenced address, destroys ifaddr */ |
@@ -1569,7 +1562,7 @@ static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev) | |||
1569 | struct inet6_ifaddr *ifp; | 1562 | struct inet6_ifaddr *ifp; |
1570 | 1563 | ||
1571 | read_lock_bh(&idev->lock); | 1564 | read_lock_bh(&idev->lock); |
1572 | for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { | 1565 | list_for_each_entry(ifp, &idev->addr_list, if_list) { |
1573 | if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { | 1566 | if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { |
1574 | memcpy(eui, ifp->addr.s6_addr+8, 8); | 1567 | memcpy(eui, ifp->addr.s6_addr+8, 8); |
1575 | err = 0; | 1568 | err = 0; |
@@ -1737,7 +1730,8 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev) | |||
1737 | 1730 | ||
1738 | ASSERT_RTNL(); | 1731 | ASSERT_RTNL(); |
1739 | 1732 | ||
1740 | if ((idev = ipv6_find_idev(dev)) == NULL) | 1733 | idev = ipv6_find_idev(dev); |
1734 | if (!idev) | ||
1741 | return NULL; | 1735 | return NULL; |
1742 | 1736 | ||
1743 | /* Add default multicast route */ | 1737 | /* Add default multicast route */ |
@@ -1970,7 +1964,7 @@ ok: | |||
1970 | #ifdef CONFIG_IPV6_PRIVACY | 1964 | #ifdef CONFIG_IPV6_PRIVACY |
1971 | read_lock_bh(&in6_dev->lock); | 1965 | read_lock_bh(&in6_dev->lock); |
1972 | /* update all temporary addresses in the list */ | 1966 | /* update all temporary addresses in the list */ |
1973 | for (ift=in6_dev->tempaddr_list; ift; ift=ift->tmp_next) { | 1967 | list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) { |
1974 | /* | 1968 | /* |
1975 | * When adjusting the lifetimes of an existing | 1969 | * When adjusting the lifetimes of an existing |
1976 | * temporary address, only lower the lifetimes. | 1970 | * temporary address, only lower the lifetimes. |
@@ -2173,7 +2167,7 @@ static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2173 | return -ENXIO; | 2167 | return -ENXIO; |
2174 | 2168 | ||
2175 | read_lock_bh(&idev->lock); | 2169 | read_lock_bh(&idev->lock); |
2176 | for (ifp = idev->addr_list; ifp; ifp=ifp->if_next) { | 2170 | list_for_each_entry(ifp, &idev->addr_list, if_list) { |
2177 | if (ifp->prefix_len == plen && | 2171 | if (ifp->prefix_len == plen && |
2178 | ipv6_addr_equal(pfx, &ifp->addr)) { | 2172 | ipv6_addr_equal(pfx, &ifp->addr)) { |
2179 | in6_ifa_hold(ifp); | 2173 | in6_ifa_hold(ifp); |
@@ -2184,7 +2178,7 @@ static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, | |||
2184 | /* If the last address is deleted administratively, | 2178 | /* If the last address is deleted administratively, |
2185 | disable IPv6 on this interface. | 2179 | disable IPv6 on this interface. |
2186 | */ | 2180 | */ |
2187 | if (idev->addr_list == NULL) | 2181 | if (list_empty(&idev->addr_list)) |
2188 | addrconf_ifdown(idev->dev, 1); | 2182 | addrconf_ifdown(idev->dev, 1); |
2189 | return 0; | 2183 | return 0; |
2190 | } | 2184 | } |
@@ -2445,7 +2439,8 @@ static void addrconf_ip6_tnl_config(struct net_device *dev) | |||
2445 | 2439 | ||
2446 | ASSERT_RTNL(); | 2440 | ASSERT_RTNL(); |
2447 | 2441 | ||
2448 | if ((idev = addrconf_add_dev(dev)) == NULL) { | 2442 | idev = addrconf_add_dev(dev); |
2443 | if (!idev) { | ||
2449 | printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); | 2444 | printk(KERN_DEBUG "init ip6-ip6: add_dev failed\n"); |
2450 | return; | 2445 | return; |
2451 | } | 2446 | } |
@@ -2460,7 +2455,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2460 | int run_pending = 0; | 2455 | int run_pending = 0; |
2461 | int err; | 2456 | int err; |
2462 | 2457 | ||
2463 | switch(event) { | 2458 | switch (event) { |
2464 | case NETDEV_REGISTER: | 2459 | case NETDEV_REGISTER: |
2465 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { | 2460 | if (!idev && dev->mtu >= IPV6_MIN_MTU) { |
2466 | idev = ipv6_add_dev(dev); | 2461 | idev = ipv6_add_dev(dev); |
@@ -2468,6 +2463,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2468 | return notifier_from_errno(-ENOMEM); | 2463 | return notifier_from_errno(-ENOMEM); |
2469 | } | 2464 | } |
2470 | break; | 2465 | break; |
2466 | |||
2471 | case NETDEV_UP: | 2467 | case NETDEV_UP: |
2472 | case NETDEV_CHANGE: | 2468 | case NETDEV_CHANGE: |
2473 | if (dev->flags & IFF_SLAVE) | 2469 | if (dev->flags & IFF_SLAVE) |
@@ -2497,10 +2493,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2497 | } | 2493 | } |
2498 | 2494 | ||
2499 | if (idev) { | 2495 | if (idev) { |
2500 | if (idev->if_flags & IF_READY) { | 2496 | if (idev->if_flags & IF_READY) |
2501 | /* device is already configured. */ | 2497 | /* device is already configured. */ |
2502 | break; | 2498 | break; |
2503 | } | ||
2504 | idev->if_flags |= IF_READY; | 2499 | idev->if_flags |= IF_READY; |
2505 | } | 2500 | } |
2506 | 2501 | ||
@@ -2512,7 +2507,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2512 | run_pending = 1; | 2507 | run_pending = 1; |
2513 | } | 2508 | } |
2514 | 2509 | ||
2515 | switch(dev->type) { | 2510 | switch (dev->type) { |
2516 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) | 2511 | #if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE) |
2517 | case ARPHRD_SIT: | 2512 | case ARPHRD_SIT: |
2518 | addrconf_sit_config(dev); | 2513 | addrconf_sit_config(dev); |
@@ -2529,25 +2524,30 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2529 | addrconf_dev_config(dev); | 2524 | addrconf_dev_config(dev); |
2530 | break; | 2525 | break; |
2531 | } | 2526 | } |
2527 | |||
2532 | if (idev) { | 2528 | if (idev) { |
2533 | if (run_pending) | 2529 | if (run_pending) |
2534 | addrconf_dad_run(idev); | 2530 | addrconf_dad_run(idev); |
2535 | 2531 | ||
2536 | /* If the MTU changed during the interface down, when the | 2532 | /* |
2537 | interface up, the changed MTU must be reflected in the | 2533 | * If the MTU changed during the interface down, |
2538 | idev as well as routers. | 2534 | * when the interface up, the changed MTU must be |
2535 | * reflected in the idev as well as routers. | ||
2539 | */ | 2536 | */ |
2540 | if (idev->cnf.mtu6 != dev->mtu && dev->mtu >= IPV6_MIN_MTU) { | 2537 | if (idev->cnf.mtu6 != dev->mtu && |
2538 | dev->mtu >= IPV6_MIN_MTU) { | ||
2541 | rt6_mtu_change(dev, dev->mtu); | 2539 | rt6_mtu_change(dev, dev->mtu); |
2542 | idev->cnf.mtu6 = dev->mtu; | 2540 | idev->cnf.mtu6 = dev->mtu; |
2543 | } | 2541 | } |
2544 | idev->tstamp = jiffies; | 2542 | idev->tstamp = jiffies; |
2545 | inet6_ifinfo_notify(RTM_NEWLINK, idev); | 2543 | inet6_ifinfo_notify(RTM_NEWLINK, idev); |
2546 | /* If the changed mtu during down is lower than IPV6_MIN_MTU | 2544 | |
2547 | stop IPv6 on this interface. | 2545 | /* |
2546 | * If the changed mtu during down is lower than | ||
2547 | * IPV6_MIN_MTU stop IPv6 on this interface. | ||
2548 | */ | 2548 | */ |
2549 | if (dev->mtu < IPV6_MIN_MTU) | 2549 | if (dev->mtu < IPV6_MIN_MTU) |
2550 | addrconf_ifdown(dev, event != NETDEV_DOWN); | 2550 | addrconf_ifdown(dev, 1); |
2551 | } | 2551 | } |
2552 | break; | 2552 | break; |
2553 | 2553 | ||
@@ -2564,7 +2564,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2564 | break; | 2564 | break; |
2565 | } | 2565 | } |
2566 | 2566 | ||
2567 | /* MTU falled under IPV6_MIN_MTU. Stop IPv6 on this interface. */ | 2567 | /* |
2568 | * MTU falled under IPV6_MIN_MTU. | ||
2569 | * Stop IPv6 on this interface. | ||
2570 | */ | ||
2568 | 2571 | ||
2569 | case NETDEV_DOWN: | 2572 | case NETDEV_DOWN: |
2570 | case NETDEV_UNREGISTER: | 2573 | case NETDEV_UNREGISTER: |
@@ -2584,9 +2587,10 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2584 | return notifier_from_errno(err); | 2587 | return notifier_from_errno(err); |
2585 | } | 2588 | } |
2586 | break; | 2589 | break; |
2587 | case NETDEV_BONDING_OLDTYPE: | 2590 | |
2588 | case NETDEV_BONDING_NEWTYPE: | 2591 | case NETDEV_PRE_TYPE_CHANGE: |
2589 | addrconf_bonding_change(dev, event); | 2592 | case NETDEV_POST_TYPE_CHANGE: |
2593 | addrconf_type_change(dev, event); | ||
2590 | break; | 2594 | break; |
2591 | } | 2595 | } |
2592 | 2596 | ||
@@ -2598,28 +2602,27 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2598 | */ | 2602 | */ |
2599 | static struct notifier_block ipv6_dev_notf = { | 2603 | static struct notifier_block ipv6_dev_notf = { |
2600 | .notifier_call = addrconf_notify, | 2604 | .notifier_call = addrconf_notify, |
2601 | .priority = 0 | ||
2602 | }; | 2605 | }; |
2603 | 2606 | ||
2604 | static void addrconf_bonding_change(struct net_device *dev, unsigned long event) | 2607 | static void addrconf_type_change(struct net_device *dev, unsigned long event) |
2605 | { | 2608 | { |
2606 | struct inet6_dev *idev; | 2609 | struct inet6_dev *idev; |
2607 | ASSERT_RTNL(); | 2610 | ASSERT_RTNL(); |
2608 | 2611 | ||
2609 | idev = __in6_dev_get(dev); | 2612 | idev = __in6_dev_get(dev); |
2610 | 2613 | ||
2611 | if (event == NETDEV_BONDING_NEWTYPE) | 2614 | if (event == NETDEV_POST_TYPE_CHANGE) |
2612 | ipv6_mc_remap(idev); | 2615 | ipv6_mc_remap(idev); |
2613 | else if (event == NETDEV_BONDING_OLDTYPE) | 2616 | else if (event == NETDEV_PRE_TYPE_CHANGE) |
2614 | ipv6_mc_unmap(idev); | 2617 | ipv6_mc_unmap(idev); |
2615 | } | 2618 | } |
2616 | 2619 | ||
2617 | static int addrconf_ifdown(struct net_device *dev, int how) | 2620 | static int addrconf_ifdown(struct net_device *dev, int how) |
2618 | { | 2621 | { |
2619 | struct inet6_dev *idev; | ||
2620 | struct inet6_ifaddr *ifa, *keep_list, **bifa; | ||
2621 | struct net *net = dev_net(dev); | 2622 | struct net *net = dev_net(dev); |
2622 | int i; | 2623 | struct inet6_dev *idev; |
2624 | struct inet6_ifaddr *ifa; | ||
2625 | LIST_HEAD(keep_list); | ||
2623 | 2626 | ||
2624 | ASSERT_RTNL(); | 2627 | ASSERT_RTNL(); |
2625 | 2628 | ||
@@ -2630,8 +2633,9 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2630 | if (idev == NULL) | 2633 | if (idev == NULL) |
2631 | return -ENODEV; | 2634 | return -ENODEV; |
2632 | 2635 | ||
2633 | /* Step 1: remove reference to ipv6 device from parent device. | 2636 | /* |
2634 | Do not dev_put! | 2637 | * Step 1: remove reference to ipv6 device from parent device. |
2638 | * Do not dev_put! | ||
2635 | */ | 2639 | */ |
2636 | if (how) { | 2640 | if (how) { |
2637 | idev->dead = 1; | 2641 | idev->dead = 1; |
@@ -2644,40 +2648,21 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2644 | 2648 | ||
2645 | } | 2649 | } |
2646 | 2650 | ||
2647 | /* Step 2: clear hash table */ | ||
2648 | for (i=0; i<IN6_ADDR_HSIZE; i++) { | ||
2649 | bifa = &inet6_addr_lst[i]; | ||
2650 | |||
2651 | write_lock_bh(&addrconf_hash_lock); | ||
2652 | while ((ifa = *bifa) != NULL) { | ||
2653 | if (ifa->idev == idev && | ||
2654 | (how || !(ifa->flags&IFA_F_PERMANENT) || | ||
2655 | ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { | ||
2656 | *bifa = ifa->lst_next; | ||
2657 | ifa->lst_next = NULL; | ||
2658 | __in6_ifa_put(ifa); | ||
2659 | continue; | ||
2660 | } | ||
2661 | bifa = &ifa->lst_next; | ||
2662 | } | ||
2663 | write_unlock_bh(&addrconf_hash_lock); | ||
2664 | } | ||
2665 | |||
2666 | write_lock_bh(&idev->lock); | 2651 | write_lock_bh(&idev->lock); |
2667 | 2652 | ||
2668 | /* Step 3: clear flags for stateless addrconf */ | 2653 | /* Step 2: clear flags for stateless addrconf */ |
2669 | if (!how) | 2654 | if (!how) |
2670 | idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY); | 2655 | idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY); |
2671 | 2656 | ||
2672 | /* Step 4: clear address list */ | ||
2673 | #ifdef CONFIG_IPV6_PRIVACY | 2657 | #ifdef CONFIG_IPV6_PRIVACY |
2674 | if (how && del_timer(&idev->regen_timer)) | 2658 | if (how && del_timer(&idev->regen_timer)) |
2675 | in6_dev_put(idev); | 2659 | in6_dev_put(idev); |
2676 | 2660 | ||
2677 | /* clear tempaddr list */ | 2661 | /* Step 3: clear tempaddr list */ |
2678 | while ((ifa = idev->tempaddr_list) != NULL) { | 2662 | while (!list_empty(&idev->tempaddr_list)) { |
2679 | idev->tempaddr_list = ifa->tmp_next; | 2663 | ifa = list_first_entry(&idev->tempaddr_list, |
2680 | ifa->tmp_next = NULL; | 2664 | struct inet6_ifaddr, tmp_list); |
2665 | list_del(&ifa->tmp_list); | ||
2681 | ifa->dead = 1; | 2666 | ifa->dead = 1; |
2682 | write_unlock_bh(&idev->lock); | 2667 | write_unlock_bh(&idev->lock); |
2683 | spin_lock_bh(&ifa->lock); | 2668 | spin_lock_bh(&ifa->lock); |
@@ -2691,23 +2676,18 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2691 | write_lock_bh(&idev->lock); | 2676 | write_lock_bh(&idev->lock); |
2692 | } | 2677 | } |
2693 | #endif | 2678 | #endif |
2694 | keep_list = NULL; | ||
2695 | bifa = &keep_list; | ||
2696 | while ((ifa = idev->addr_list) != NULL) { | ||
2697 | idev->addr_list = ifa->if_next; | ||
2698 | ifa->if_next = NULL; | ||
2699 | 2679 | ||
2680 | while (!list_empty(&idev->addr_list)) { | ||
2681 | ifa = list_first_entry(&idev->addr_list, | ||
2682 | struct inet6_ifaddr, if_list); | ||
2700 | addrconf_del_timer(ifa); | 2683 | addrconf_del_timer(ifa); |
2701 | 2684 | ||
2702 | /* If just doing link down, and address is permanent | 2685 | /* If just doing link down, and address is permanent |
2703 | and not link-local, then retain it. */ | 2686 | and not link-local, then retain it. */ |
2704 | if (how == 0 && | 2687 | if (!how && |
2705 | (ifa->flags&IFA_F_PERMANENT) && | 2688 | (ifa->flags&IFA_F_PERMANENT) && |
2706 | !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { | 2689 | !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) { |
2707 | 2690 | list_move_tail(&ifa->if_list, &keep_list); | |
2708 | /* Move to holding list */ | ||
2709 | *bifa = ifa; | ||
2710 | bifa = &ifa->if_next; | ||
2711 | 2691 | ||
2712 | /* If not doing DAD on this address, just keep it. */ | 2692 | /* If not doing DAD on this address, just keep it. */ |
2713 | if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || | 2693 | if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) || |
@@ -2722,24 +2702,32 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2722 | /* Flag it for later restoration when link comes up */ | 2702 | /* Flag it for later restoration when link comes up */ |
2723 | ifa->flags |= IFA_F_TENTATIVE; | 2703 | ifa->flags |= IFA_F_TENTATIVE; |
2724 | in6_ifa_hold(ifa); | 2704 | in6_ifa_hold(ifa); |
2705 | write_unlock_bh(&idev->lock); | ||
2725 | } else { | 2706 | } else { |
2707 | list_del(&ifa->if_list); | ||
2726 | ifa->dead = 1; | 2708 | ifa->dead = 1; |
2709 | write_unlock_bh(&idev->lock); | ||
2710 | |||
2711 | /* clear hash table */ | ||
2712 | spin_lock_bh(&addrconf_hash_lock); | ||
2713 | hlist_del_init_rcu(&ifa->addr_lst); | ||
2714 | spin_unlock_bh(&addrconf_hash_lock); | ||
2727 | } | 2715 | } |
2728 | write_unlock_bh(&idev->lock); | ||
2729 | 2716 | ||
2730 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | 2717 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
2731 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); | 2718 | if (ifa->dead) |
2719 | atomic_notifier_call_chain(&inet6addr_chain, | ||
2720 | NETDEV_DOWN, ifa); | ||
2732 | in6_ifa_put(ifa); | 2721 | in6_ifa_put(ifa); |
2733 | 2722 | ||
2734 | write_lock_bh(&idev->lock); | 2723 | write_lock_bh(&idev->lock); |
2735 | } | 2724 | } |
2736 | 2725 | ||
2737 | idev->addr_list = keep_list; | 2726 | list_splice(&keep_list, &idev->addr_list); |
2738 | 2727 | ||
2739 | write_unlock_bh(&idev->lock); | 2728 | write_unlock_bh(&idev->lock); |
2740 | 2729 | ||
2741 | /* Step 5: Discard multicast list */ | 2730 | /* Step 5: Discard multicast list */ |
2742 | |||
2743 | if (how) | 2731 | if (how) |
2744 | ipv6_mc_destroy_dev(idev); | 2732 | ipv6_mc_destroy_dev(idev); |
2745 | else | 2733 | else |
@@ -2747,8 +2735,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2747 | 2735 | ||
2748 | idev->tstamp = jiffies; | 2736 | idev->tstamp = jiffies; |
2749 | 2737 | ||
2750 | /* Shot the device (if unregistered) */ | 2738 | /* Last: Shot the device (if unregistered) */ |
2751 | |||
2752 | if (how) { | 2739 | if (how) { |
2753 | addrconf_sysctl_unregister(idev); | 2740 | addrconf_sysctl_unregister(idev); |
2754 | neigh_parms_release(&nd_tbl, idev->nd_parms); | 2741 | neigh_parms_release(&nd_tbl, idev->nd_parms); |
@@ -2859,7 +2846,7 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp, u32 flags) | |||
2859 | * Optimistic nodes can start receiving | 2846 | * Optimistic nodes can start receiving |
2860 | * Frames right away | 2847 | * Frames right away |
2861 | */ | 2848 | */ |
2862 | if(ifp->flags & IFA_F_OPTIMISTIC) | 2849 | if (ifp->flags & IFA_F_OPTIMISTIC) |
2863 | ip6_ins_rt(ifp->rt); | 2850 | ip6_ins_rt(ifp->rt); |
2864 | 2851 | ||
2865 | addrconf_dad_kick(ifp); | 2852 | addrconf_dad_kick(ifp); |
@@ -2909,7 +2896,7 @@ out: | |||
2909 | 2896 | ||
2910 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | 2897 | static void addrconf_dad_completed(struct inet6_ifaddr *ifp) |
2911 | { | 2898 | { |
2912 | struct net_device * dev = ifp->idev->dev; | 2899 | struct net_device *dev = ifp->idev->dev; |
2913 | 2900 | ||
2914 | /* | 2901 | /* |
2915 | * Configure the address for reception. Now it is valid. | 2902 | * Configure the address for reception. Now it is valid. |
@@ -2940,11 +2927,12 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) | |||
2940 | } | 2927 | } |
2941 | } | 2928 | } |
2942 | 2929 | ||
2943 | static void addrconf_dad_run(struct inet6_dev *idev) { | 2930 | static void addrconf_dad_run(struct inet6_dev *idev) |
2931 | { | ||
2944 | struct inet6_ifaddr *ifp; | 2932 | struct inet6_ifaddr *ifp; |
2945 | 2933 | ||
2946 | read_lock_bh(&idev->lock); | 2934 | read_lock_bh(&idev->lock); |
2947 | for (ifp = idev->addr_list; ifp; ifp = ifp->if_next) { | 2935 | list_for_each_entry(ifp, &idev->addr_list, if_list) { |
2948 | spin_lock(&ifp->lock); | 2936 | spin_lock(&ifp->lock); |
2949 | if (!(ifp->flags & IFA_F_TENTATIVE)) { | 2937 | if (!(ifp->flags & IFA_F_TENTATIVE)) { |
2950 | spin_unlock(&ifp->lock); | 2938 | spin_unlock(&ifp->lock); |
@@ -2969,36 +2957,35 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq) | |||
2969 | struct net *net = seq_file_net(seq); | 2957 | struct net *net = seq_file_net(seq); |
2970 | 2958 | ||
2971 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { | 2959 | for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) { |
2972 | ifa = inet6_addr_lst[state->bucket]; | 2960 | struct hlist_node *n; |
2973 | 2961 | hlist_for_each_entry_rcu(ifa, n, &inet6_addr_lst[state->bucket], | |
2974 | while (ifa && !net_eq(dev_net(ifa->idev->dev), net)) | 2962 | addr_lst) |
2975 | ifa = ifa->lst_next; | 2963 | if (net_eq(dev_net(ifa->idev->dev), net)) |
2976 | if (ifa) | 2964 | return ifa; |
2977 | break; | ||
2978 | } | 2965 | } |
2979 | return ifa; | 2966 | return NULL; |
2980 | } | 2967 | } |
2981 | 2968 | ||
2982 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa) | 2969 | static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, |
2970 | struct inet6_ifaddr *ifa) | ||
2983 | { | 2971 | { |
2984 | struct if6_iter_state *state = seq->private; | 2972 | struct if6_iter_state *state = seq->private; |
2985 | struct net *net = seq_file_net(seq); | 2973 | struct net *net = seq_file_net(seq); |
2974 | struct hlist_node *n = &ifa->addr_lst; | ||
2986 | 2975 | ||
2987 | ifa = ifa->lst_next; | 2976 | hlist_for_each_entry_continue_rcu(ifa, n, addr_lst) |
2988 | try_again: | 2977 | if (net_eq(dev_net(ifa->idev->dev), net)) |
2989 | if (ifa) { | 2978 | return ifa; |
2990 | if (!net_eq(dev_net(ifa->idev->dev), net)) { | ||
2991 | ifa = ifa->lst_next; | ||
2992 | goto try_again; | ||
2993 | } | ||
2994 | } | ||
2995 | 2979 | ||
2996 | if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) { | 2980 | while (++state->bucket < IN6_ADDR_HSIZE) { |
2997 | ifa = inet6_addr_lst[state->bucket]; | 2981 | hlist_for_each_entry(ifa, n, |
2998 | goto try_again; | 2982 | &inet6_addr_lst[state->bucket], addr_lst) { |
2983 | if (net_eq(dev_net(ifa->idev->dev), net)) | ||
2984 | return ifa; | ||
2985 | } | ||
2999 | } | 2986 | } |
3000 | 2987 | ||
3001 | return ifa; | 2988 | return NULL; |
3002 | } | 2989 | } |
3003 | 2990 | ||
3004 | static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos) | 2991 | static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos) |
@@ -3006,15 +2993,15 @@ static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos) | |||
3006 | struct inet6_ifaddr *ifa = if6_get_first(seq); | 2993 | struct inet6_ifaddr *ifa = if6_get_first(seq); |
3007 | 2994 | ||
3008 | if (ifa) | 2995 | if (ifa) |
3009 | while(pos && (ifa = if6_get_next(seq, ifa)) != NULL) | 2996 | while (pos && (ifa = if6_get_next(seq, ifa)) != NULL) |
3010 | --pos; | 2997 | --pos; |
3011 | return pos ? NULL : ifa; | 2998 | return pos ? NULL : ifa; |
3012 | } | 2999 | } |
3013 | 3000 | ||
3014 | static void *if6_seq_start(struct seq_file *seq, loff_t *pos) | 3001 | static void *if6_seq_start(struct seq_file *seq, loff_t *pos) |
3015 | __acquires(addrconf_hash_lock) | 3002 | __acquires(rcu) |
3016 | { | 3003 | { |
3017 | read_lock_bh(&addrconf_hash_lock); | 3004 | rcu_read_lock_bh(); |
3018 | return if6_get_idx(seq, *pos); | 3005 | return if6_get_idx(seq, *pos); |
3019 | } | 3006 | } |
3020 | 3007 | ||
@@ -3028,9 +3015,9 @@ static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
3028 | } | 3015 | } |
3029 | 3016 | ||
3030 | static void if6_seq_stop(struct seq_file *seq, void *v) | 3017 | static void if6_seq_stop(struct seq_file *seq, void *v) |
3031 | __releases(addrconf_hash_lock) | 3018 | __releases(rcu) |
3032 | { | 3019 | { |
3033 | read_unlock_bh(&addrconf_hash_lock); | 3020 | rcu_read_unlock_bh(); |
3034 | } | 3021 | } |
3035 | 3022 | ||
3036 | static int if6_seq_show(struct seq_file *seq, void *v) | 3023 | static int if6_seq_show(struct seq_file *seq, void *v) |
@@ -3100,10 +3087,12 @@ void if6_proc_exit(void) | |||
3100 | int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) | 3087 | int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) |
3101 | { | 3088 | { |
3102 | int ret = 0; | 3089 | int ret = 0; |
3103 | struct inet6_ifaddr * ifp; | 3090 | struct inet6_ifaddr *ifp = NULL; |
3104 | u8 hash = ipv6_addr_hash(addr); | 3091 | struct hlist_node *n; |
3105 | read_lock_bh(&addrconf_hash_lock); | 3092 | unsigned int hash = ipv6_addr_hash(addr); |
3106 | for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { | 3093 | |
3094 | rcu_read_lock_bh(); | ||
3095 | hlist_for_each_entry_rcu(ifp, n, &inet6_addr_lst[hash], addr_lst) { | ||
3107 | if (!net_eq(dev_net(ifp->idev->dev), net)) | 3096 | if (!net_eq(dev_net(ifp->idev->dev), net)) |
3108 | continue; | 3097 | continue; |
3109 | if (ipv6_addr_equal(&ifp->addr, addr) && | 3098 | if (ipv6_addr_equal(&ifp->addr, addr) && |
@@ -3112,7 +3101,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) | |||
3112 | break; | 3101 | break; |
3113 | } | 3102 | } |
3114 | } | 3103 | } |
3115 | read_unlock_bh(&addrconf_hash_lock); | 3104 | rcu_read_unlock_bh(); |
3116 | return ret; | 3105 | return ret; |
3117 | } | 3106 | } |
3118 | #endif | 3107 | #endif |
@@ -3123,43 +3112,35 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) | |||
3123 | 3112 | ||
3124 | static void addrconf_verify(unsigned long foo) | 3113 | static void addrconf_verify(unsigned long foo) |
3125 | { | 3114 | { |
3115 | unsigned long now, next, next_sec, next_sched; | ||
3126 | struct inet6_ifaddr *ifp; | 3116 | struct inet6_ifaddr *ifp; |
3127 | unsigned long now, next; | 3117 | struct hlist_node *node; |
3128 | int i; | 3118 | int i; |
3129 | 3119 | ||
3130 | spin_lock_bh(&addrconf_verify_lock); | 3120 | rcu_read_lock_bh(); |
3121 | spin_lock(&addrconf_verify_lock); | ||
3131 | now = jiffies; | 3122 | now = jiffies; |
3132 | next = now + ADDR_CHECK_FREQUENCY; | 3123 | next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); |
3133 | 3124 | ||
3134 | del_timer(&addr_chk_timer); | 3125 | del_timer(&addr_chk_timer); |
3135 | 3126 | ||
3136 | for (i=0; i < IN6_ADDR_HSIZE; i++) { | 3127 | for (i = 0; i < IN6_ADDR_HSIZE; i++) { |
3137 | |||
3138 | restart: | 3128 | restart: |
3139 | read_lock(&addrconf_hash_lock); | 3129 | hlist_for_each_entry_rcu(ifp, node, |
3140 | for (ifp=inet6_addr_lst[i]; ifp; ifp=ifp->lst_next) { | 3130 | &inet6_addr_lst[i], addr_lst) { |
3141 | unsigned long age; | 3131 | unsigned long age; |
3142 | #ifdef CONFIG_IPV6_PRIVACY | ||
3143 | unsigned long regen_advance; | ||
3144 | #endif | ||
3145 | 3132 | ||
3146 | if (ifp->flags & IFA_F_PERMANENT) | 3133 | if (ifp->flags & IFA_F_PERMANENT) |
3147 | continue; | 3134 | continue; |
3148 | 3135 | ||
3149 | spin_lock(&ifp->lock); | 3136 | spin_lock(&ifp->lock); |
3150 | age = (now - ifp->tstamp) / HZ; | 3137 | /* We try to batch several events at once. */ |
3151 | 3138 | age = (now - ifp->tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ; | |
3152 | #ifdef CONFIG_IPV6_PRIVACY | ||
3153 | regen_advance = ifp->idev->cnf.regen_max_retry * | ||
3154 | ifp->idev->cnf.dad_transmits * | ||
3155 | ifp->idev->nd_parms->retrans_time / HZ; | ||
3156 | #endif | ||
3157 | 3139 | ||
3158 | if (ifp->valid_lft != INFINITY_LIFE_TIME && | 3140 | if (ifp->valid_lft != INFINITY_LIFE_TIME && |
3159 | age >= ifp->valid_lft) { | 3141 | age >= ifp->valid_lft) { |
3160 | spin_unlock(&ifp->lock); | 3142 | spin_unlock(&ifp->lock); |
3161 | in6_ifa_hold(ifp); | 3143 | in6_ifa_hold(ifp); |
3162 | read_unlock(&addrconf_hash_lock); | ||
3163 | ipv6_del_addr(ifp); | 3144 | ipv6_del_addr(ifp); |
3164 | goto restart; | 3145 | goto restart; |
3165 | } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) { | 3146 | } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) { |
@@ -3181,7 +3162,6 @@ restart: | |||
3181 | 3162 | ||
3182 | if (deprecate) { | 3163 | if (deprecate) { |
3183 | in6_ifa_hold(ifp); | 3164 | in6_ifa_hold(ifp); |
3184 | read_unlock(&addrconf_hash_lock); | ||
3185 | 3165 | ||
3186 | ipv6_ifa_notify(0, ifp); | 3166 | ipv6_ifa_notify(0, ifp); |
3187 | in6_ifa_put(ifp); | 3167 | in6_ifa_put(ifp); |
@@ -3190,6 +3170,10 @@ restart: | |||
3190 | #ifdef CONFIG_IPV6_PRIVACY | 3170 | #ifdef CONFIG_IPV6_PRIVACY |
3191 | } else if ((ifp->flags&IFA_F_TEMPORARY) && | 3171 | } else if ((ifp->flags&IFA_F_TEMPORARY) && |
3192 | !(ifp->flags&IFA_F_TENTATIVE)) { | 3172 | !(ifp->flags&IFA_F_TENTATIVE)) { |
3173 | unsigned long regen_advance = ifp->idev->cnf.regen_max_retry * | ||
3174 | ifp->idev->cnf.dad_transmits * | ||
3175 | ifp->idev->nd_parms->retrans_time / HZ; | ||
3176 | |||
3193 | if (age >= ifp->prefered_lft - regen_advance) { | 3177 | if (age >= ifp->prefered_lft - regen_advance) { |
3194 | struct inet6_ifaddr *ifpub = ifp->ifpub; | 3178 | struct inet6_ifaddr *ifpub = ifp->ifpub; |
3195 | if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next)) | 3179 | if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next)) |
@@ -3199,7 +3183,7 @@ restart: | |||
3199 | in6_ifa_hold(ifp); | 3183 | in6_ifa_hold(ifp); |
3200 | in6_ifa_hold(ifpub); | 3184 | in6_ifa_hold(ifpub); |
3201 | spin_unlock(&ifp->lock); | 3185 | spin_unlock(&ifp->lock); |
3202 | read_unlock(&addrconf_hash_lock); | 3186 | |
3203 | spin_lock(&ifpub->lock); | 3187 | spin_lock(&ifpub->lock); |
3204 | ifpub->regen_count = 0; | 3188 | ifpub->regen_count = 0; |
3205 | spin_unlock(&ifpub->lock); | 3189 | spin_unlock(&ifpub->lock); |
@@ -3219,12 +3203,26 @@ restart: | |||
3219 | spin_unlock(&ifp->lock); | 3203 | spin_unlock(&ifp->lock); |
3220 | } | 3204 | } |
3221 | } | 3205 | } |
3222 | read_unlock(&addrconf_hash_lock); | ||
3223 | } | 3206 | } |
3224 | 3207 | ||
3225 | addr_chk_timer.expires = time_before(next, jiffies + HZ) ? jiffies + HZ : next; | 3208 | next_sec = round_jiffies_up(next); |
3209 | next_sched = next; | ||
3210 | |||
3211 | /* If rounded timeout is accurate enough, accept it. */ | ||
3212 | if (time_before(next_sec, next + ADDRCONF_TIMER_FUZZ)) | ||
3213 | next_sched = next_sec; | ||
3214 | |||
3215 | /* And minimum interval is ADDRCONF_TIMER_FUZZ_MAX. */ | ||
3216 | if (time_before(next_sched, jiffies + ADDRCONF_TIMER_FUZZ_MAX)) | ||
3217 | next_sched = jiffies + ADDRCONF_TIMER_FUZZ_MAX; | ||
3218 | |||
3219 | ADBG((KERN_DEBUG "now = %lu, schedule = %lu, rounded schedule = %lu => %lu\n", | ||
3220 | now, next, next_sec, next_sched)); | ||
3221 | |||
3222 | addr_chk_timer.expires = next_sched; | ||
3226 | add_timer(&addr_chk_timer); | 3223 | add_timer(&addr_chk_timer); |
3227 | spin_unlock_bh(&addrconf_verify_lock); | 3224 | spin_unlock(&addrconf_verify_lock); |
3225 | rcu_read_unlock_bh(); | ||
3228 | } | 3226 | } |
3229 | 3227 | ||
3230 | static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) | 3228 | static struct in6_addr *extract_addr(struct nlattr *addr, struct nlattr *local) |
@@ -3514,8 +3512,7 @@ static int inet6_fill_ifacaddr(struct sk_buff *skb, struct ifacaddr6 *ifaca, | |||
3514 | return nlmsg_end(skb, nlh); | 3512 | return nlmsg_end(skb, nlh); |
3515 | } | 3513 | } |
3516 | 3514 | ||
3517 | enum addr_type_t | 3515 | enum addr_type_t { |
3518 | { | ||
3519 | UNICAST_ADDR, | 3516 | UNICAST_ADDR, |
3520 | MULTICAST_ADDR, | 3517 | MULTICAST_ADDR, |
3521 | ANYCAST_ADDR, | 3518 | ANYCAST_ADDR, |
@@ -3526,7 +3523,6 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, | |||
3526 | struct netlink_callback *cb, enum addr_type_t type, | 3523 | struct netlink_callback *cb, enum addr_type_t type, |
3527 | int s_ip_idx, int *p_ip_idx) | 3524 | int s_ip_idx, int *p_ip_idx) |
3528 | { | 3525 | { |
3529 | struct inet6_ifaddr *ifa; | ||
3530 | struct ifmcaddr6 *ifmca; | 3526 | struct ifmcaddr6 *ifmca; |
3531 | struct ifacaddr6 *ifaca; | 3527 | struct ifacaddr6 *ifaca; |
3532 | int err = 1; | 3528 | int err = 1; |
@@ -3534,11 +3530,12 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, | |||
3534 | 3530 | ||
3535 | read_lock_bh(&idev->lock); | 3531 | read_lock_bh(&idev->lock); |
3536 | switch (type) { | 3532 | switch (type) { |
3537 | case UNICAST_ADDR: | 3533 | case UNICAST_ADDR: { |
3534 | struct inet6_ifaddr *ifa; | ||
3535 | |||
3538 | /* unicast address incl. temp addr */ | 3536 | /* unicast address incl. temp addr */ |
3539 | for (ifa = idev->addr_list; ifa; | 3537 | list_for_each_entry(ifa, &idev->addr_list, if_list) { |
3540 | ifa = ifa->if_next, ip_idx++) { | 3538 | if (++ip_idx < s_ip_idx) |
3541 | if (ip_idx < s_ip_idx) | ||
3542 | continue; | 3539 | continue; |
3543 | err = inet6_fill_ifaddr(skb, ifa, | 3540 | err = inet6_fill_ifaddr(skb, ifa, |
3544 | NETLINK_CB(cb->skb).pid, | 3541 | NETLINK_CB(cb->skb).pid, |
@@ -3549,6 +3546,7 @@ static int in6_dump_addrs(struct inet6_dev *idev, struct sk_buff *skb, | |||
3549 | break; | 3546 | break; |
3550 | } | 3547 | } |
3551 | break; | 3548 | break; |
3549 | } | ||
3552 | case MULTICAST_ADDR: | 3550 | case MULTICAST_ADDR: |
3553 | /* multicast address */ | 3551 | /* multicast address */ |
3554 | for (ifmca = idev->mc_list; ifmca; | 3552 | for (ifmca = idev->mc_list; ifmca; |
@@ -3610,10 +3608,11 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, | |||
3610 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { | 3608 | hlist_for_each_entry_rcu(dev, node, head, index_hlist) { |
3611 | if (idx < s_idx) | 3609 | if (idx < s_idx) |
3612 | goto cont; | 3610 | goto cont; |
3613 | if (idx > s_idx) | 3611 | if (h > s_h || idx > s_idx) |
3614 | s_ip_idx = 0; | 3612 | s_ip_idx = 0; |
3615 | ip_idx = 0; | 3613 | ip_idx = 0; |
3616 | if ((idev = __in6_dev_get(dev)) == NULL) | 3614 | idev = __in6_dev_get(dev); |
3615 | if (!idev) | ||
3617 | goto cont; | 3616 | goto cont; |
3618 | 3617 | ||
3619 | if (in6_dump_addrs(idev, skb, cb, type, | 3618 | if (in6_dump_addrs(idev, skb, cb, type, |
@@ -3680,12 +3679,14 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh, | |||
3680 | if (ifm->ifa_index) | 3679 | if (ifm->ifa_index) |
3681 | dev = __dev_get_by_index(net, ifm->ifa_index); | 3680 | dev = __dev_get_by_index(net, ifm->ifa_index); |
3682 | 3681 | ||
3683 | if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) { | 3682 | ifa = ipv6_get_ifaddr(net, addr, dev, 1); |
3683 | if (!ifa) { | ||
3684 | err = -EADDRNOTAVAIL; | 3684 | err = -EADDRNOTAVAIL; |
3685 | goto errout; | 3685 | goto errout; |
3686 | } | 3686 | } |
3687 | 3687 | ||
3688 | if ((skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL)) == NULL) { | 3688 | skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_KERNEL); |
3689 | if (!skb) { | ||
3689 | err = -ENOBUFS; | 3690 | err = -ENOBUFS; |
3690 | goto errout_ifa; | 3691 | goto errout_ifa; |
3691 | } | 3692 | } |
@@ -3810,7 +3811,7 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib, | |||
3810 | static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, | 3811 | static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, |
3811 | int bytes) | 3812 | int bytes) |
3812 | { | 3813 | { |
3813 | switch(attrtype) { | 3814 | switch (attrtype) { |
3814 | case IFLA_INET6_STATS: | 3815 | case IFLA_INET6_STATS: |
3815 | __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); | 3816 | __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); |
3816 | break; | 3817 | break; |
@@ -4046,7 +4047,8 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
4046 | addrconf_leave_anycast(ifp); | 4047 | addrconf_leave_anycast(ifp); |
4047 | addrconf_leave_solict(ifp->idev, &ifp->addr); | 4048 | addrconf_leave_solict(ifp->idev, &ifp->addr); |
4048 | dst_hold(&ifp->rt->u.dst); | 4049 | dst_hold(&ifp->rt->u.dst); |
4049 | if (ip6_del_rt(ifp->rt)) | 4050 | |
4051 | if (ifp->dead && ip6_del_rt(ifp->rt)) | ||
4050 | dst_free(&ifp->rt->u.dst); | 4052 | dst_free(&ifp->rt->u.dst); |
4051 | break; | 4053 | break; |
4052 | } | 4054 | } |
@@ -4162,211 +4164,211 @@ static struct addrconf_sysctl_table | |||
4162 | .sysctl_header = NULL, | 4164 | .sysctl_header = NULL, |
4163 | .addrconf_vars = { | 4165 | .addrconf_vars = { |
4164 | { | 4166 | { |
4165 | .procname = "forwarding", | 4167 | .procname = "forwarding", |
4166 | .data = &ipv6_devconf.forwarding, | 4168 | .data = &ipv6_devconf.forwarding, |
4167 | .maxlen = sizeof(int), | 4169 | .maxlen = sizeof(int), |
4168 | .mode = 0644, | 4170 | .mode = 0644, |
4169 | .proc_handler = addrconf_sysctl_forward, | 4171 | .proc_handler = addrconf_sysctl_forward, |
4170 | }, | 4172 | }, |
4171 | { | 4173 | { |
4172 | .procname = "hop_limit", | 4174 | .procname = "hop_limit", |
4173 | .data = &ipv6_devconf.hop_limit, | 4175 | .data = &ipv6_devconf.hop_limit, |
4174 | .maxlen = sizeof(int), | 4176 | .maxlen = sizeof(int), |
4175 | .mode = 0644, | 4177 | .mode = 0644, |
4176 | .proc_handler = proc_dointvec, | 4178 | .proc_handler = proc_dointvec, |
4177 | }, | 4179 | }, |
4178 | { | 4180 | { |
4179 | .procname = "mtu", | 4181 | .procname = "mtu", |
4180 | .data = &ipv6_devconf.mtu6, | 4182 | .data = &ipv6_devconf.mtu6, |
4181 | .maxlen = sizeof(int), | 4183 | .maxlen = sizeof(int), |
4182 | .mode = 0644, | 4184 | .mode = 0644, |
4183 | .proc_handler = proc_dointvec, | 4185 | .proc_handler = proc_dointvec, |
4184 | }, | 4186 | }, |
4185 | { | 4187 | { |
4186 | .procname = "accept_ra", | 4188 | .procname = "accept_ra", |
4187 | .data = &ipv6_devconf.accept_ra, | 4189 | .data = &ipv6_devconf.accept_ra, |
4188 | .maxlen = sizeof(int), | 4190 | .maxlen = sizeof(int), |
4189 | .mode = 0644, | 4191 | .mode = 0644, |
4190 | .proc_handler = proc_dointvec, | 4192 | .proc_handler = proc_dointvec, |
4191 | }, | 4193 | }, |
4192 | { | 4194 | { |
4193 | .procname = "accept_redirects", | 4195 | .procname = "accept_redirects", |
4194 | .data = &ipv6_devconf.accept_redirects, | 4196 | .data = &ipv6_devconf.accept_redirects, |
4195 | .maxlen = sizeof(int), | 4197 | .maxlen = sizeof(int), |
4196 | .mode = 0644, | 4198 | .mode = 0644, |
4197 | .proc_handler = proc_dointvec, | 4199 | .proc_handler = proc_dointvec, |
4198 | }, | 4200 | }, |
4199 | { | 4201 | { |
4200 | .procname = "autoconf", | 4202 | .procname = "autoconf", |
4201 | .data = &ipv6_devconf.autoconf, | 4203 | .data = &ipv6_devconf.autoconf, |
4202 | .maxlen = sizeof(int), | 4204 | .maxlen = sizeof(int), |
4203 | .mode = 0644, | 4205 | .mode = 0644, |
4204 | .proc_handler = proc_dointvec, | 4206 | .proc_handler = proc_dointvec, |
4205 | }, | 4207 | }, |
4206 | { | 4208 | { |
4207 | .procname = "dad_transmits", | 4209 | .procname = "dad_transmits", |
4208 | .data = &ipv6_devconf.dad_transmits, | 4210 | .data = &ipv6_devconf.dad_transmits, |
4209 | .maxlen = sizeof(int), | 4211 | .maxlen = sizeof(int), |
4210 | .mode = 0644, | 4212 | .mode = 0644, |
4211 | .proc_handler = proc_dointvec, | 4213 | .proc_handler = proc_dointvec, |
4212 | }, | 4214 | }, |
4213 | { | 4215 | { |
4214 | .procname = "router_solicitations", | 4216 | .procname = "router_solicitations", |
4215 | .data = &ipv6_devconf.rtr_solicits, | 4217 | .data = &ipv6_devconf.rtr_solicits, |
4216 | .maxlen = sizeof(int), | 4218 | .maxlen = sizeof(int), |
4217 | .mode = 0644, | 4219 | .mode = 0644, |
4218 | .proc_handler = proc_dointvec, | 4220 | .proc_handler = proc_dointvec, |
4219 | }, | 4221 | }, |
4220 | { | 4222 | { |
4221 | .procname = "router_solicitation_interval", | 4223 | .procname = "router_solicitation_interval", |
4222 | .data = &ipv6_devconf.rtr_solicit_interval, | 4224 | .data = &ipv6_devconf.rtr_solicit_interval, |
4223 | .maxlen = sizeof(int), | 4225 | .maxlen = sizeof(int), |
4224 | .mode = 0644, | 4226 | .mode = 0644, |
4225 | .proc_handler = proc_dointvec_jiffies, | 4227 | .proc_handler = proc_dointvec_jiffies, |
4226 | }, | 4228 | }, |
4227 | { | 4229 | { |
4228 | .procname = "router_solicitation_delay", | 4230 | .procname = "router_solicitation_delay", |
4229 | .data = &ipv6_devconf.rtr_solicit_delay, | 4231 | .data = &ipv6_devconf.rtr_solicit_delay, |
4230 | .maxlen = sizeof(int), | 4232 | .maxlen = sizeof(int), |
4231 | .mode = 0644, | 4233 | .mode = 0644, |
4232 | .proc_handler = proc_dointvec_jiffies, | 4234 | .proc_handler = proc_dointvec_jiffies, |
4233 | }, | 4235 | }, |
4234 | { | 4236 | { |
4235 | .procname = "force_mld_version", | 4237 | .procname = "force_mld_version", |
4236 | .data = &ipv6_devconf.force_mld_version, | 4238 | .data = &ipv6_devconf.force_mld_version, |
4237 | .maxlen = sizeof(int), | 4239 | .maxlen = sizeof(int), |
4238 | .mode = 0644, | 4240 | .mode = 0644, |
4239 | .proc_handler = proc_dointvec, | 4241 | .proc_handler = proc_dointvec, |
4240 | }, | 4242 | }, |
4241 | #ifdef CONFIG_IPV6_PRIVACY | 4243 | #ifdef CONFIG_IPV6_PRIVACY |
4242 | { | 4244 | { |
4243 | .procname = "use_tempaddr", | 4245 | .procname = "use_tempaddr", |
4244 | .data = &ipv6_devconf.use_tempaddr, | 4246 | .data = &ipv6_devconf.use_tempaddr, |
4245 | .maxlen = sizeof(int), | 4247 | .maxlen = sizeof(int), |
4246 | .mode = 0644, | 4248 | .mode = 0644, |
4247 | .proc_handler = proc_dointvec, | 4249 | .proc_handler = proc_dointvec, |
4248 | }, | 4250 | }, |
4249 | { | 4251 | { |
4250 | .procname = "temp_valid_lft", | 4252 | .procname = "temp_valid_lft", |
4251 | .data = &ipv6_devconf.temp_valid_lft, | 4253 | .data = &ipv6_devconf.temp_valid_lft, |
4252 | .maxlen = sizeof(int), | 4254 | .maxlen = sizeof(int), |
4253 | .mode = 0644, | 4255 | .mode = 0644, |
4254 | .proc_handler = proc_dointvec, | 4256 | .proc_handler = proc_dointvec, |
4255 | }, | 4257 | }, |
4256 | { | 4258 | { |
4257 | .procname = "temp_prefered_lft", | 4259 | .procname = "temp_prefered_lft", |
4258 | .data = &ipv6_devconf.temp_prefered_lft, | 4260 | .data = &ipv6_devconf.temp_prefered_lft, |
4259 | .maxlen = sizeof(int), | 4261 | .maxlen = sizeof(int), |
4260 | .mode = 0644, | 4262 | .mode = 0644, |
4261 | .proc_handler = proc_dointvec, | 4263 | .proc_handler = proc_dointvec, |
4262 | }, | 4264 | }, |
4263 | { | 4265 | { |
4264 | .procname = "regen_max_retry", | 4266 | .procname = "regen_max_retry", |
4265 | .data = &ipv6_devconf.regen_max_retry, | 4267 | .data = &ipv6_devconf.regen_max_retry, |
4266 | .maxlen = sizeof(int), | 4268 | .maxlen = sizeof(int), |
4267 | .mode = 0644, | 4269 | .mode = 0644, |
4268 | .proc_handler = proc_dointvec, | 4270 | .proc_handler = proc_dointvec, |
4269 | }, | 4271 | }, |
4270 | { | 4272 | { |
4271 | .procname = "max_desync_factor", | 4273 | .procname = "max_desync_factor", |
4272 | .data = &ipv6_devconf.max_desync_factor, | 4274 | .data = &ipv6_devconf.max_desync_factor, |
4273 | .maxlen = sizeof(int), | 4275 | .maxlen = sizeof(int), |
4274 | .mode = 0644, | 4276 | .mode = 0644, |
4275 | .proc_handler = proc_dointvec, | 4277 | .proc_handler = proc_dointvec, |
4276 | }, | 4278 | }, |
4277 | #endif | 4279 | #endif |
4278 | { | 4280 | { |
4279 | .procname = "max_addresses", | 4281 | .procname = "max_addresses", |
4280 | .data = &ipv6_devconf.max_addresses, | 4282 | .data = &ipv6_devconf.max_addresses, |
4281 | .maxlen = sizeof(int), | 4283 | .maxlen = sizeof(int), |
4282 | .mode = 0644, | 4284 | .mode = 0644, |
4283 | .proc_handler = proc_dointvec, | 4285 | .proc_handler = proc_dointvec, |
4284 | }, | 4286 | }, |
4285 | { | 4287 | { |
4286 | .procname = "accept_ra_defrtr", | 4288 | .procname = "accept_ra_defrtr", |
4287 | .data = &ipv6_devconf.accept_ra_defrtr, | 4289 | .data = &ipv6_devconf.accept_ra_defrtr, |
4288 | .maxlen = sizeof(int), | 4290 | .maxlen = sizeof(int), |
4289 | .mode = 0644, | 4291 | .mode = 0644, |
4290 | .proc_handler = proc_dointvec, | 4292 | .proc_handler = proc_dointvec, |
4291 | }, | 4293 | }, |
4292 | { | 4294 | { |
4293 | .procname = "accept_ra_pinfo", | 4295 | .procname = "accept_ra_pinfo", |
4294 | .data = &ipv6_devconf.accept_ra_pinfo, | 4296 | .data = &ipv6_devconf.accept_ra_pinfo, |
4295 | .maxlen = sizeof(int), | 4297 | .maxlen = sizeof(int), |
4296 | .mode = 0644, | 4298 | .mode = 0644, |
4297 | .proc_handler = proc_dointvec, | 4299 | .proc_handler = proc_dointvec, |
4298 | }, | 4300 | }, |
4299 | #ifdef CONFIG_IPV6_ROUTER_PREF | 4301 | #ifdef CONFIG_IPV6_ROUTER_PREF |
4300 | { | 4302 | { |
4301 | .procname = "accept_ra_rtr_pref", | 4303 | .procname = "accept_ra_rtr_pref", |
4302 | .data = &ipv6_devconf.accept_ra_rtr_pref, | 4304 | .data = &ipv6_devconf.accept_ra_rtr_pref, |
4303 | .maxlen = sizeof(int), | 4305 | .maxlen = sizeof(int), |
4304 | .mode = 0644, | 4306 | .mode = 0644, |
4305 | .proc_handler = proc_dointvec, | 4307 | .proc_handler = proc_dointvec, |
4306 | }, | 4308 | }, |
4307 | { | 4309 | { |
4308 | .procname = "router_probe_interval", | 4310 | .procname = "router_probe_interval", |
4309 | .data = &ipv6_devconf.rtr_probe_interval, | 4311 | .data = &ipv6_devconf.rtr_probe_interval, |
4310 | .maxlen = sizeof(int), | 4312 | .maxlen = sizeof(int), |
4311 | .mode = 0644, | 4313 | .mode = 0644, |
4312 | .proc_handler = proc_dointvec_jiffies, | 4314 | .proc_handler = proc_dointvec_jiffies, |
4313 | }, | 4315 | }, |
4314 | #ifdef CONFIG_IPV6_ROUTE_INFO | 4316 | #ifdef CONFIG_IPV6_ROUTE_INFO |
4315 | { | 4317 | { |
4316 | .procname = "accept_ra_rt_info_max_plen", | 4318 | .procname = "accept_ra_rt_info_max_plen", |
4317 | .data = &ipv6_devconf.accept_ra_rt_info_max_plen, | 4319 | .data = &ipv6_devconf.accept_ra_rt_info_max_plen, |
4318 | .maxlen = sizeof(int), | 4320 | .maxlen = sizeof(int), |
4319 | .mode = 0644, | 4321 | .mode = 0644, |
4320 | .proc_handler = proc_dointvec, | 4322 | .proc_handler = proc_dointvec, |
4321 | }, | 4323 | }, |
4322 | #endif | 4324 | #endif |
4323 | #endif | 4325 | #endif |
4324 | { | 4326 | { |
4325 | .procname = "proxy_ndp", | 4327 | .procname = "proxy_ndp", |
4326 | .data = &ipv6_devconf.proxy_ndp, | 4328 | .data = &ipv6_devconf.proxy_ndp, |
4327 | .maxlen = sizeof(int), | 4329 | .maxlen = sizeof(int), |
4328 | .mode = 0644, | 4330 | .mode = 0644, |
4329 | .proc_handler = proc_dointvec, | 4331 | .proc_handler = proc_dointvec, |
4330 | }, | 4332 | }, |
4331 | { | 4333 | { |
4332 | .procname = "accept_source_route", | 4334 | .procname = "accept_source_route", |
4333 | .data = &ipv6_devconf.accept_source_route, | 4335 | .data = &ipv6_devconf.accept_source_route, |
4334 | .maxlen = sizeof(int), | 4336 | .maxlen = sizeof(int), |
4335 | .mode = 0644, | 4337 | .mode = 0644, |
4336 | .proc_handler = proc_dointvec, | 4338 | .proc_handler = proc_dointvec, |
4337 | }, | 4339 | }, |
4338 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD | 4340 | #ifdef CONFIG_IPV6_OPTIMISTIC_DAD |
4339 | { | 4341 | { |
4340 | .procname = "optimistic_dad", | 4342 | .procname = "optimistic_dad", |
4341 | .data = &ipv6_devconf.optimistic_dad, | 4343 | .data = &ipv6_devconf.optimistic_dad, |
4342 | .maxlen = sizeof(int), | 4344 | .maxlen = sizeof(int), |
4343 | .mode = 0644, | 4345 | .mode = 0644, |
4344 | .proc_handler = proc_dointvec, | 4346 | .proc_handler = proc_dointvec, |
4345 | 4347 | ||
4346 | }, | 4348 | }, |
4347 | #endif | 4349 | #endif |
4348 | #ifdef CONFIG_IPV6_MROUTE | 4350 | #ifdef CONFIG_IPV6_MROUTE |
4349 | { | 4351 | { |
4350 | .procname = "mc_forwarding", | 4352 | .procname = "mc_forwarding", |
4351 | .data = &ipv6_devconf.mc_forwarding, | 4353 | .data = &ipv6_devconf.mc_forwarding, |
4352 | .maxlen = sizeof(int), | 4354 | .maxlen = sizeof(int), |
4353 | .mode = 0444, | 4355 | .mode = 0444, |
4354 | .proc_handler = proc_dointvec, | 4356 | .proc_handler = proc_dointvec, |
4355 | }, | 4357 | }, |
4356 | #endif | 4358 | #endif |
4357 | { | 4359 | { |
4358 | .procname = "disable_ipv6", | 4360 | .procname = "disable_ipv6", |
4359 | .data = &ipv6_devconf.disable_ipv6, | 4361 | .data = &ipv6_devconf.disable_ipv6, |
4360 | .maxlen = sizeof(int), | 4362 | .maxlen = sizeof(int), |
4361 | .mode = 0644, | 4363 | .mode = 0644, |
4362 | .proc_handler = addrconf_sysctl_disable, | 4364 | .proc_handler = addrconf_sysctl_disable, |
4363 | }, | 4365 | }, |
4364 | { | 4366 | { |
4365 | .procname = "accept_dad", | 4367 | .procname = "accept_dad", |
4366 | .data = &ipv6_devconf.accept_dad, | 4368 | .data = &ipv6_devconf.accept_dad, |
4367 | .maxlen = sizeof(int), | 4369 | .maxlen = sizeof(int), |
4368 | .mode = 0644, | 4370 | .mode = 0644, |
4369 | .proc_handler = proc_dointvec, | 4371 | .proc_handler = proc_dointvec, |
4370 | }, | 4372 | }, |
4371 | { | 4373 | { |
4372 | .procname = "force_tllao", | 4374 | .procname = "force_tllao", |
@@ -4402,8 +4404,8 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name, | |||
4402 | if (t == NULL) | 4404 | if (t == NULL) |
4403 | goto out; | 4405 | goto out; |
4404 | 4406 | ||
4405 | for (i=0; t->addrconf_vars[i].data; i++) { | 4407 | for (i = 0; t->addrconf_vars[i].data; i++) { |
4406 | t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf; | 4408 | t->addrconf_vars[i].data += (char *)p - (char *)&ipv6_devconf; |
4407 | t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */ | 4409 | t->addrconf_vars[i].extra1 = idev; /* embedded; no ref */ |
4408 | t->addrconf_vars[i].extra2 = net; | 4410 | t->addrconf_vars[i].extra2 = net; |
4409 | } | 4411 | } |
@@ -4540,14 +4542,12 @@ int register_inet6addr_notifier(struct notifier_block *nb) | |||
4540 | { | 4542 | { |
4541 | return atomic_notifier_chain_register(&inet6addr_chain, nb); | 4543 | return atomic_notifier_chain_register(&inet6addr_chain, nb); |
4542 | } | 4544 | } |
4543 | |||
4544 | EXPORT_SYMBOL(register_inet6addr_notifier); | 4545 | EXPORT_SYMBOL(register_inet6addr_notifier); |
4545 | 4546 | ||
4546 | int unregister_inet6addr_notifier(struct notifier_block *nb) | 4547 | int unregister_inet6addr_notifier(struct notifier_block *nb) |
4547 | { | 4548 | { |
4548 | return atomic_notifier_chain_unregister(&inet6addr_chain,nb); | 4549 | return atomic_notifier_chain_unregister(&inet6addr_chain, nb); |
4549 | } | 4550 | } |
4550 | |||
4551 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | 4551 | EXPORT_SYMBOL(unregister_inet6addr_notifier); |
4552 | 4552 | ||
4553 | /* | 4553 | /* |
@@ -4556,11 +4556,12 @@ EXPORT_SYMBOL(unregister_inet6addr_notifier); | |||
4556 | 4556 | ||
4557 | int __init addrconf_init(void) | 4557 | int __init addrconf_init(void) |
4558 | { | 4558 | { |
4559 | int err; | 4559 | int i, err; |
4560 | 4560 | ||
4561 | if ((err = ipv6_addr_label_init()) < 0) { | 4561 | err = ipv6_addr_label_init(); |
4562 | printk(KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n", | 4562 | if (err < 0) { |
4563 | err); | 4563 | printk(KERN_CRIT "IPv6 Addrconf:" |
4564 | " cannot initialize default policy table: %d.\n", err); | ||
4564 | return err; | 4565 | return err; |
4565 | } | 4566 | } |
4566 | 4567 | ||
@@ -4591,6 +4592,9 @@ int __init addrconf_init(void) | |||
4591 | if (err) | 4592 | if (err) |
4592 | goto errlo; | 4593 | goto errlo; |
4593 | 4594 | ||
4595 | for (i = 0; i < IN6_ADDR_HSIZE; i++) | ||
4596 | INIT_HLIST_HEAD(&inet6_addr_lst[i]); | ||
4597 | |||
4594 | register_netdevice_notifier(&ipv6_dev_notf); | 4598 | register_netdevice_notifier(&ipv6_dev_notf); |
4595 | 4599 | ||
4596 | addrconf_verify(0); | 4600 | addrconf_verify(0); |
@@ -4619,7 +4623,6 @@ errlo: | |||
4619 | 4623 | ||
4620 | void addrconf_cleanup(void) | 4624 | void addrconf_cleanup(void) |
4621 | { | 4625 | { |
4622 | struct inet6_ifaddr *ifa; | ||
4623 | struct net_device *dev; | 4626 | struct net_device *dev; |
4624 | int i; | 4627 | int i; |
4625 | 4628 | ||
@@ -4639,20 +4642,10 @@ void addrconf_cleanup(void) | |||
4639 | /* | 4642 | /* |
4640 | * Check hash table. | 4643 | * Check hash table. |
4641 | */ | 4644 | */ |
4642 | write_lock_bh(&addrconf_hash_lock); | 4645 | spin_lock_bh(&addrconf_hash_lock); |
4643 | for (i=0; i < IN6_ADDR_HSIZE; i++) { | 4646 | for (i = 0; i < IN6_ADDR_HSIZE; i++) |
4644 | for (ifa=inet6_addr_lst[i]; ifa; ) { | 4647 | WARN_ON(!hlist_empty(&inet6_addr_lst[i])); |
4645 | struct inet6_ifaddr *bifa; | 4648 | spin_unlock_bh(&addrconf_hash_lock); |
4646 | |||
4647 | bifa = ifa; | ||
4648 | ifa = ifa->lst_next; | ||
4649 | printk(KERN_DEBUG "bug: IPv6 address leakage detected: ifa=%p\n", bifa); | ||
4650 | /* Do not free it; something is wrong. | ||
4651 | Now we can investigate it with debugger. | ||
4652 | */ | ||
4653 | } | ||
4654 | } | ||
4655 | write_unlock_bh(&addrconf_hash_lock); | ||
4656 | 4649 | ||
4657 | del_timer(&addr_chk_timer); | 4650 | del_timer(&addr_chk_timer); |
4658 | rtnl_unlock(); | 4651 | rtnl_unlock(); |
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 6ff73c4c126a..ae404c9a746c 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/list.h> | 13 | #include <linux/list.h> |
14 | #include <linux/rcupdate.h> | 14 | #include <linux/rcupdate.h> |
15 | #include <linux/in6.h> | 15 | #include <linux/in6.h> |
16 | #include <linux/slab.h> | ||
16 | #include <net/addrconf.h> | 17 | #include <net/addrconf.h> |
17 | #include <linux/if_addrlabel.h> | 18 | #include <linux/if_addrlabel.h> |
18 | #include <linux/netlink.h> | 19 | #include <linux/netlink.h> |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 37d14e735c27..3192aa02ba5d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
37 | #include <linux/stat.h> | 37 | #include <linux/stat.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | #include <linux/inet.h> | 41 | #include <linux/inet.h> |
41 | #include <linux/netdevice.h> | 42 | #include <linux/netdevice.h> |
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 5ac89025f9de..ee82d4ef26ce 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include <crypto/hash.h> | 27 | #include <crypto/hash.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/slab.h> | ||
29 | #include <net/ip.h> | 30 | #include <net/ip.h> |
30 | #include <net/ah.h> | 31 | #include <net/ah.h> |
31 | #include <linux/crypto.h> | 32 | #include <linux/crypto.h> |
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index c4f6ca32fa74..b5b07054508a 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/seq_file.h> | 31 | #include <linux/seq_file.h> |
32 | #include <linux/slab.h> | ||
32 | 33 | ||
33 | #include <net/net_namespace.h> | 34 | #include <net/net_namespace.h> |
34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index e6f9cdf780fe..622dc7939a1b 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/in6.h> | 21 | #include <linux/in6.h> |
22 | #include <linux/ipv6.h> | 22 | #include <linux/ipv6.h> |
23 | #include <linux/route.h> | 23 | #include <linux/route.h> |
24 | #include <linux/slab.h> | ||
24 | 25 | ||
25 | #include <net/ipv6.h> | 26 | #include <net/ipv6.h> |
26 | #include <net/ndisc.h> | 27 | #include <net/ndisc.h> |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 074f2c084f9f..8a659f92d17a 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
30 | #include <linux/in6.h> | 30 | #include <linux/in6.h> |
31 | #include <linux/icmpv6.h> | 31 | #include <linux/icmpv6.h> |
32 | #include <linux/slab.h> | ||
32 | 33 | ||
33 | #include <net/dst.h> | 34 | #include <net/dst.h> |
34 | #include <net/sock.h> | 35 | #include <net/sock.h> |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 5e463c43fcc2..8124f16f2ac2 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -208,7 +208,6 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
208 | { | 208 | { |
209 | struct fib6_rule *rule6 = (struct fib6_rule *) rule; | 209 | struct fib6_rule *rule6 = (struct fib6_rule *) rule; |
210 | 210 | ||
211 | frh->family = AF_INET6; | ||
212 | frh->dst_len = rule6->dst.plen; | 211 | frh->dst_len = rule6->dst.plen; |
213 | frh->src_len = rule6->src.plen; | 212 | frh->src_len = rule6->src.plen; |
214 | frh->tos = rule6->tclass; | 213 | frh->tos = rule6->tclass; |
@@ -239,7 +238,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | |||
239 | } | 238 | } |
240 | 239 | ||
241 | static struct fib_rules_ops fib6_rules_ops_template = { | 240 | static struct fib_rules_ops fib6_rules_ops_template = { |
242 | .family = AF_INET6, | 241 | .family = FIB_RULES_IPV6, |
243 | .rule_size = sizeof(struct fib6_rule), | 242 | .rule_size = sizeof(struct fib6_rule), |
244 | .addr_size = sizeof(struct in6_addr), | 243 | .addr_size = sizeof(struct in6_addr), |
245 | .action = fib6_rule_action, | 244 | .action = fib6_rule_action, |
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index eb9abe24bdf0..12d2fa42657d 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/init.h> | 41 | #include <linux/init.h> |
42 | #include <linux/netfilter.h> | 42 | #include <linux/netfilter.h> |
43 | #include <linux/slab.h> | ||
43 | 44 | ||
44 | #ifdef CONFIG_SYSCTL | 45 | #ifdef CONFIG_SYSCTL |
45 | #include <linux/sysctl.h> | 46 | #include <linux/sysctl.h> |
@@ -482,6 +483,7 @@ route_done: | |||
482 | np->tclass, NULL, &fl, (struct rt6_info*)dst, | 483 | np->tclass, NULL, &fl, (struct rt6_info*)dst, |
483 | MSG_DONTWAIT); | 484 | MSG_DONTWAIT); |
484 | if (err) { | 485 | if (err) { |
486 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); | ||
485 | ip6_flush_pending_frames(sk); | 487 | ip6_flush_pending_frames(sk); |
486 | goto out_put; | 488 | goto out_put; |
487 | } | 489 | } |
@@ -562,6 +564,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb) | |||
562 | (struct rt6_info*)dst, MSG_DONTWAIT); | 564 | (struct rt6_info*)dst, MSG_DONTWAIT); |
563 | 565 | ||
564 | if (err) { | 566 | if (err) { |
567 | ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); | ||
565 | ip6_flush_pending_frames(sk); | 568 | ip6_flush_pending_frames(sk); |
566 | goto out_put; | 569 | goto out_put; |
567 | } | 570 | } |
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index 3516e6fe2e56..0c5e3c3b7fd5 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/in6.h> | 17 | #include <linux/in6.h> |
18 | #include <linux/ipv6.h> | 18 | #include <linux/ipv6.h> |
19 | #include <linux/jhash.h> | 19 | #include <linux/jhash.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | #include <net/addrconf.h> | 22 | #include <net/addrconf.h> |
22 | #include <net/inet_connection_sock.h> | 23 | #include <net/inet_connection_sock.h> |
@@ -177,7 +178,7 @@ struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie) | |||
177 | return dst; | 178 | return dst; |
178 | } | 179 | } |
179 | 180 | ||
180 | int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | 181 | int inet6_csk_xmit(struct sk_buff *skb) |
181 | { | 182 | { |
182 | struct sock *sk = skb->sk; | 183 | struct sock *sk = skb->sk; |
183 | struct inet_sock *inet = inet_sk(sk); | 184 | struct inet_sock *inet = inet_sk(sk); |
@@ -233,7 +234,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) | |||
233 | /* Restore final destination back after routing done */ | 234 | /* Restore final destination back after routing done */ |
234 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | 235 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); |
235 | 236 | ||
236 | return ip6_xmit(sk, skb, &fl, np->opt, 0); | 237 | return ip6_xmit(sk, skb, &fl, np->opt); |
237 | } | 238 | } |
238 | 239 | ||
239 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); | 240 | EXPORT_SYMBOL_GPL(inet6_csk_xmit); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 2f9847924fa5..dc6e0b8f260d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/in6.h> | 26 | #include <linux/in6.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/list.h> | 28 | #include <linux/list.h> |
29 | #include <linux/slab.h> | ||
29 | 30 | ||
30 | #ifdef CONFIG_PROC_FS | 31 | #ifdef CONFIG_PROC_FS |
31 | #include <linux/proc_fs.h> | 32 | #include <linux/proc_fs.h> |
@@ -127,12 +128,23 @@ static __inline__ u32 fib6_new_sernum(void) | |||
127 | /* | 128 | /* |
128 | * test bit | 129 | * test bit |
129 | */ | 130 | */ |
131 | #if defined(__LITTLE_ENDIAN) | ||
132 | # define BITOP_BE32_SWIZZLE (0x1F & ~7) | ||
133 | #else | ||
134 | # define BITOP_BE32_SWIZZLE 0 | ||
135 | #endif | ||
130 | 136 | ||
131 | static __inline__ __be32 addr_bit_set(void *token, int fn_bit) | 137 | static __inline__ __be32 addr_bit_set(void *token, int fn_bit) |
132 | { | 138 | { |
133 | __be32 *addr = token; | 139 | __be32 *addr = token; |
134 | 140 | /* | |
135 | return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5]; | 141 | * Here, |
142 | * 1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f) | ||
143 | * is optimized version of | ||
144 | * htonl(1 << ((~fn_bit)&0x1F)) | ||
145 | * See include/asm-generic/bitops/le.h. | ||
146 | */ | ||
147 | return (1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) & addr[fn_bit >> 5]; | ||
136 | } | 148 | } |
137 | 149 | ||
138 | static __inline__ struct fib6_node * node_alloc(void) | 150 | static __inline__ struct fib6_node * node_alloc(void) |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index e41eba8aacf1..14e23216eb28 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/route.h> | 20 | #include <linux/route.h> |
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/slab.h> | ||
23 | 24 | ||
24 | #include <net/net_namespace.h> | 25 | #include <net/net_namespace.h> |
25 | #include <net/sock.h> | 26 | #include <net/sock.h> |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 2c01dc65794d..a83e9209cecc 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/in6.h> | 28 | #include <linux/in6.h> |
29 | #include <linux/icmpv6.h> | 29 | #include <linux/icmpv6.h> |
30 | #include <linux/mroute6.h> | 30 | #include <linux/mroute6.h> |
31 | #include <linux/slab.h> | ||
31 | 32 | ||
32 | #include <linux/netfilter.h> | 33 | #include <linux/netfilter.h> |
33 | #include <linux/netfilter_ipv6.h> | 34 | #include <linux/netfilter_ipv6.h> |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index c10a38a71a5e..7f12e30cfa73 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/tcp.h> | 37 | #include <linux/tcp.h> |
38 | #include <linux/route.h> | 38 | #include <linux/route.h> |
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/slab.h> | ||
40 | 41 | ||
41 | #include <linux/netfilter.h> | 42 | #include <linux/netfilter.h> |
42 | #include <linux/netfilter_ipv6.h> | 43 | #include <linux/netfilter_ipv6.h> |
@@ -178,11 +179,11 @@ int ip6_output(struct sk_buff *skb) | |||
178 | } | 179 | } |
179 | 180 | ||
180 | /* | 181 | /* |
181 | * xmit an sk_buff (used by TCP) | 182 | * xmit an sk_buff (used by TCP, SCTP and DCCP) |
182 | */ | 183 | */ |
183 | 184 | ||
184 | int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | 185 | int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, |
185 | struct ipv6_txoptions *opt, int ipfragok) | 186 | struct ipv6_txoptions *opt) |
186 | { | 187 | { |
187 | struct net *net = sock_net(sk); | 188 | struct net *net = sock_net(sk); |
188 | struct ipv6_pinfo *np = inet6_sk(sk); | 189 | struct ipv6_pinfo *np = inet6_sk(sk); |
@@ -228,10 +229,6 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
228 | skb_reset_network_header(skb); | 229 | skb_reset_network_header(skb); |
229 | hdr = ipv6_hdr(skb); | 230 | hdr = ipv6_hdr(skb); |
230 | 231 | ||
231 | /* Allow local fragmentation. */ | ||
232 | if (ipfragok) | ||
233 | skb->local_df = 1; | ||
234 | |||
235 | /* | 232 | /* |
236 | * Fill in the IPv6 header | 233 | * Fill in the IPv6 header |
237 | */ | 234 | */ |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 138980eec214..2599870747ec 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/route.h> | 37 | #include <linux/route.h> |
38 | #include <linux/rtnetlink.h> | 38 | #include <linux/rtnetlink.h> |
39 | #include <linux/netfilter_ipv6.h> | 39 | #include <linux/netfilter_ipv6.h> |
40 | #include <linux/slab.h> | ||
40 | 41 | ||
41 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
42 | #include <asm/atomic.h> | 43 | #include <asm/atomic.h> |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 430372e0bf24..e0b530ca394c 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/slab.h> | ||
36 | #include <net/protocol.h> | 37 | #include <net/protocol.h> |
37 | #include <linux/skbuff.h> | 38 | #include <linux/skbuff.h> |
38 | #include <net/sock.h> | 39 | #include <net/sock.h> |
@@ -1113,6 +1114,9 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock) | |||
1113 | unsigned char ttls[MAXMIFS]; | 1114 | unsigned char ttls[MAXMIFS]; |
1114 | int i; | 1115 | int i; |
1115 | 1116 | ||
1117 | if (mfc->mf6cc_parent >= MAXMIFS) | ||
1118 | return -ENFILE; | ||
1119 | |||
1116 | memset(ttls, 255, MAXMIFS); | 1120 | memset(ttls, 255, MAXMIFS); |
1117 | for (i = 0; i < MAXMIFS; i++) { | 1121 | for (i = 0; i < MAXMIFS; i++) { |
1118 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) | 1122 | if (IF_ISSET(i, &mfc->mf6cc_ifset)) |
@@ -1692,17 +1696,20 @@ ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) | |||
1692 | int ct; | 1696 | int ct; |
1693 | struct rtnexthop *nhp; | 1697 | struct rtnexthop *nhp; |
1694 | struct net *net = mfc6_net(c); | 1698 | struct net *net = mfc6_net(c); |
1695 | struct net_device *dev = net->ipv6.vif6_table[c->mf6c_parent].dev; | ||
1696 | u8 *b = skb_tail_pointer(skb); | 1699 | u8 *b = skb_tail_pointer(skb); |
1697 | struct rtattr *mp_head; | 1700 | struct rtattr *mp_head; |
1698 | 1701 | ||
1699 | if (dev) | 1702 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
1700 | RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); | 1703 | if (c->mf6c_parent > MAXMIFS) |
1704 | return -ENOENT; | ||
1705 | |||
1706 | if (MIF_EXISTS(net, c->mf6c_parent)) | ||
1707 | RTA_PUT(skb, RTA_IIF, 4, &net->ipv6.vif6_table[c->mf6c_parent].dev->ifindex); | ||
1701 | 1708 | ||
1702 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 1709 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); |
1703 | 1710 | ||
1704 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 1711 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
1705 | if (c->mfc_un.res.ttls[ct] < 255) { | 1712 | if (MIF_EXISTS(net, ct) && c->mfc_un.res.ttls[ct] < 255) { |
1706 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 1713 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) |
1707 | goto rtattr_failure; | 1714 | goto rtattr_failure; |
1708 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 1715 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 430454ee5ead..1160400e9dbd 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/sysctl.h> | 37 | #include <linux/sysctl.h> |
38 | #include <linux/netfilter.h> | 38 | #include <linux/netfilter.h> |
39 | #include <linux/slab.h> | ||
39 | 40 | ||
40 | #include <net/sock.h> | 41 | #include <net/sock.h> |
41 | #include <net/snmp.h> | 42 | #include <net/snmp.h> |
@@ -113,9 +114,9 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk, | |||
113 | } | 114 | } |
114 | opt = xchg(&inet6_sk(sk)->opt, opt); | 115 | opt = xchg(&inet6_sk(sk)->opt, opt); |
115 | } else { | 116 | } else { |
116 | write_lock(&sk->sk_dst_lock); | 117 | spin_lock(&sk->sk_dst_lock); |
117 | opt = xchg(&inet6_sk(sk)->opt, opt); | 118 | opt = xchg(&inet6_sk(sk)->opt, opt); |
118 | write_unlock(&sk->sk_dst_lock); | 119 | spin_unlock(&sk->sk_dst_lock); |
119 | } | 120 | } |
120 | sk_dst_reset(sk); | 121 | sk_dst_reset(sk); |
121 | 122 | ||
@@ -970,14 +971,13 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
970 | case IPV6_MTU: | 971 | case IPV6_MTU: |
971 | { | 972 | { |
972 | struct dst_entry *dst; | 973 | struct dst_entry *dst; |
974 | |||
973 | val = 0; | 975 | val = 0; |
974 | lock_sock(sk); | 976 | rcu_read_lock(); |
975 | dst = sk_dst_get(sk); | 977 | dst = __sk_dst_get(sk); |
976 | if (dst) { | 978 | if (dst) |
977 | val = dst_mtu(dst); | 979 | val = dst_mtu(dst); |
978 | dst_release(dst); | 980 | rcu_read_unlock(); |
979 | } | ||
980 | release_sock(sk); | ||
981 | if (!val) | 981 | if (!val) |
982 | return -ENOTCONN; | 982 | return -ENOTCONN; |
983 | break; | 983 | break; |
@@ -1065,12 +1065,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1065 | else | 1065 | else |
1066 | val = np->mcast_hops; | 1066 | val = np->mcast_hops; |
1067 | 1067 | ||
1068 | dst = sk_dst_get(sk); | 1068 | if (val < 0) { |
1069 | if (dst) { | 1069 | rcu_read_lock(); |
1070 | if (val < 0) | 1070 | dst = __sk_dst_get(sk); |
1071 | if (dst) | ||
1071 | val = ip6_dst_hoplimit(dst); | 1072 | val = ip6_dst_hoplimit(dst); |
1072 | dst_release(dst); | 1073 | rcu_read_unlock(); |
1073 | } | 1074 | } |
1075 | |||
1074 | if (val < 0) | 1076 | if (val < 0) |
1075 | val = sock_net(sk)->ipv6.devconf_all->hop_limit; | 1077 | val = sock_net(sk)->ipv6.devconf_all->hop_limit; |
1076 | break; | 1078 | break; |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 773b9d18b748..f9d05ce4e03a 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/init.h> | 43 | #include <linux/init.h> |
44 | #include <linux/proc_fs.h> | 44 | #include <linux/proc_fs.h> |
45 | #include <linux/seq_file.h> | 45 | #include <linux/seq_file.h> |
46 | #include <linux/slab.h> | ||
46 | 47 | ||
47 | #include <linux/netfilter.h> | 48 | #include <linux/netfilter.h> |
48 | #include <linux/netfilter_ipv6.h> | 49 | #include <linux/netfilter_ipv6.h> |
@@ -714,7 +715,7 @@ static void igmp6_group_added(struct ifmcaddr6 *mc) | |||
714 | if (!(mc->mca_flags&MAF_LOADED)) { | 715 | if (!(mc->mca_flags&MAF_LOADED)) { |
715 | mc->mca_flags |= MAF_LOADED; | 716 | mc->mca_flags |= MAF_LOADED; |
716 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) | 717 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) |
717 | dev_mc_add(dev, buf, dev->addr_len, 0); | 718 | dev_mc_add(dev, buf); |
718 | } | 719 | } |
719 | spin_unlock_bh(&mc->mca_lock); | 720 | spin_unlock_bh(&mc->mca_lock); |
720 | 721 | ||
@@ -740,7 +741,7 @@ static void igmp6_group_dropped(struct ifmcaddr6 *mc) | |||
740 | if (mc->mca_flags&MAF_LOADED) { | 741 | if (mc->mca_flags&MAF_LOADED) { |
741 | mc->mca_flags &= ~MAF_LOADED; | 742 | mc->mca_flags &= ~MAF_LOADED; |
742 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) | 743 | if (ndisc_mc_map(&mc->mca_addr, buf, dev, 0) == 0) |
743 | dev_mc_delete(dev, buf, dev->addr_len, 0); | 744 | dev_mc_del(dev, buf); |
744 | } | 745 | } |
745 | 746 | ||
746 | if (mc->mca_flags & MAF_NOREPORT) | 747 | if (mc->mca_flags & MAF_NOREPORT) |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 8e96a350f52f..3f7c12b70a26 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <linux/route.h> | 59 | #include <linux/route.h> |
60 | #include <linux/init.h> | 60 | #include <linux/init.h> |
61 | #include <linux/rcupdate.h> | 61 | #include <linux/rcupdate.h> |
62 | #include <linux/slab.h> | ||
62 | #ifdef CONFIG_SYSCTL | 63 | #ifdef CONFIG_SYSCTL |
63 | #include <linux/sysctl.h> | 64 | #include <linux/sysctl.h> |
64 | #endif | 65 | #endif |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 39856a25189c..8656eb75520c 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/proc_fs.h> | 25 | #include <linux/proc_fs.h> |
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/slab.h> | ||
28 | #include <net/net_namespace.h> | 29 | #include <net/net_namespace.h> |
29 | #include <net/sock.h> | 30 | #include <net/sock.h> |
30 | #include <net/ipv6.h> | 31 | #include <net/ipv6.h> |
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c index dad97622ed72..af1d6494ac39 100644 --- a/net/ipv6/netfilter/ip6t_REJECT.c +++ b/net/ipv6/netfilter/ip6t_REJECT.c | |||
@@ -15,6 +15,8 @@ | |||
15 | * 2 of the License, or (at your option) any later version. | 15 | * 2 of the License, or (at your option) any later version. |
16 | */ | 16 | */ |
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
18 | |||
19 | #include <linux/gfp.h> | ||
18 | #include <linux/module.h> | 20 | #include <linux/module.h> |
19 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
20 | #include <linux/icmpv6.h> | 22 | #include <linux/icmpv6.h> |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index 5e6acdae6d80..e424e7c8f824 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
@@ -145,11 +145,11 @@ hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par) | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /* Step to the next */ | 147 | /* Step to the next */ |
148 | pr_debug("len%04X \n", optlen); | 148 | pr_debug("len%04X\n", optlen); |
149 | 149 | ||
150 | if ((ptr > skb->len - optlen || hdrlen < optlen) && | 150 | if ((ptr > skb->len - optlen || hdrlen < optlen) && |
151 | temp < optinfo->optsnr - 1) { | 151 | temp < optinfo->optsnr - 1) { |
152 | pr_debug("new pointer is too large! \n"); | 152 | pr_debug("new pointer is too large!\n"); |
153 | break; | 153 | break; |
154 | } | 154 | } |
155 | ptr += optlen; | 155 | ptr += optlen; |
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c index 36b72cafc227..d6fc9aff3163 100644 --- a/net/ipv6/netfilter/ip6table_filter.c +++ b/net/ipv6/netfilter/ip6table_filter.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
14 | #include <linux/netfilter_ipv6/ip6_tables.h> | 14 | #include <linux/netfilter_ipv6/ip6_tables.h> |
15 | #include <linux/slab.h> | ||
15 | 16 | ||
16 | MODULE_LICENSE("GPL"); | 17 | MODULE_LICENSE("GPL"); |
17 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | 18 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); |
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c index 7844e557c0ec..6a102b57f356 100644 --- a/net/ipv6/netfilter/ip6table_mangle.c +++ b/net/ipv6/netfilter/ip6table_mangle.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/netfilter_ipv6/ip6_tables.h> | 12 | #include <linux/netfilter_ipv6/ip6_tables.h> |
13 | #include <linux/slab.h> | ||
13 | 14 | ||
14 | MODULE_LICENSE("GPL"); | 15 | MODULE_LICENSE("GPL"); |
15 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); | 16 | MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); |
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c index aef31a29de9e..5b9926a011bd 100644 --- a/net/ipv6/netfilter/ip6table_raw.c +++ b/net/ipv6/netfilter/ip6table_raw.c | |||
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/netfilter_ipv6/ip6_tables.h> | 7 | #include <linux/netfilter_ipv6/ip6_tables.h> |
8 | #include <linux/slab.h> | ||
8 | 9 | ||
9 | #define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) | 10 | #define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) |
10 | 11 | ||
@@ -13,7 +14,7 @@ static const struct xt_table packet_raw = { | |||
13 | .valid_hooks = RAW_VALID_HOOKS, | 14 | .valid_hooks = RAW_VALID_HOOKS, |
14 | .me = THIS_MODULE, | 15 | .me = THIS_MODULE, |
15 | .af = NFPROTO_IPV6, | 16 | .af = NFPROTO_IPV6, |
16 | .priority = NF_IP6_PRI_FIRST, | 17 | .priority = NF_IP6_PRI_RAW, |
17 | }; | 18 | }; |
18 | 19 | ||
19 | /* The work comes in here from netfilter.c. */ | 20 | /* The work comes in here from netfilter.c. */ |
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c index 0824d865aa9b..91aa2b4d83c9 100644 --- a/net/ipv6/netfilter/ip6table_security.c +++ b/net/ipv6/netfilter/ip6table_security.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/netfilter_ipv6/ip6_tables.h> | 19 | #include <linux/netfilter_ipv6/ip6_tables.h> |
20 | #include <linux/slab.h> | ||
20 | 21 | ||
21 | MODULE_LICENSE("GPL"); | 22 | MODULE_LICENSE("GPL"); |
22 | MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>"); | 23 | MODULE_AUTHOR("James Morris <jmorris <at> redhat.com>"); |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 8f80e245f370..6fb890187de0 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/ipv6.h> | 27 | #include <linux/ipv6.h> |
28 | #include <linux/icmpv6.h> | 28 | #include <linux/icmpv6.h> |
29 | #include <linux/random.h> | 29 | #include <linux/random.h> |
30 | #include <linux/slab.h> | ||
30 | 31 | ||
31 | #include <net/sock.h> | 32 | #include <net/sock.h> |
32 | #include <net/snmp.h> | 33 | #include <net/snmp.h> |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 58344c0fbd13..458eabfbe130 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -97,6 +97,7 @@ static const struct snmp_mib snmp6_icmp6_list[] = { | |||
97 | SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS), | 97 | SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS), |
98 | SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), | 98 | SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), |
99 | SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), | 99 | SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), |
100 | SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS), | ||
100 | SNMP_MIB_SENTINEL | 101 | SNMP_MIB_SENTINEL |
101 | }; | 102 | }; |
102 | 103 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index e9e1f774b0b7..554b48b6e993 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/types.h> | 22 | #include <linux/types.h> |
23 | #include <linux/socket.h> | 23 | #include <linux/socket.h> |
24 | #include <linux/slab.h> | ||
24 | #include <linux/sockios.h> | 25 | #include <linux/sockios.h> |
25 | #include <linux/net.h> | 26 | #include <linux/net.h> |
26 | #include <linux/in6.h> | 27 | #include <linux/in6.h> |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index a555156e9779..6d4292ff5854 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/random.h> | 41 | #include <linux/random.h> |
42 | #include <linux/jhash.h> | 42 | #include <linux/jhash.h> |
43 | #include <linux/skbuff.h> | 43 | #include <linux/skbuff.h> |
44 | #include <linux/slab.h> | ||
44 | 45 | ||
45 | #include <net/sock.h> | 46 | #include <net/sock.h> |
46 | #include <net/snmp.h> | 47 | #include <net/snmp.h> |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 52cd3eff31dc..c2438e8cb9d0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/seq_file.h> | 41 | #include <linux/seq_file.h> |
42 | #include <linux/nsproxy.h> | 42 | #include <linux/nsproxy.h> |
43 | #include <linux/slab.h> | ||
43 | #include <net/net_namespace.h> | 44 | #include <net/net_namespace.h> |
44 | #include <net/snmp.h> | 45 | #include <net/snmp.h> |
45 | #include <net/ipv6.h> | 46 | #include <net/ipv6.h> |
@@ -879,7 +880,7 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie) | |||
879 | 880 | ||
880 | rt = (struct rt6_info *) dst; | 881 | rt = (struct rt6_info *) dst; |
881 | 882 | ||
882 | if (rt && rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) | 883 | if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) |
883 | return dst; | 884 | return dst; |
884 | 885 | ||
885 | return NULL; | 886 | return NULL; |
@@ -890,12 +891,17 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst) | |||
890 | struct rt6_info *rt = (struct rt6_info *) dst; | 891 | struct rt6_info *rt = (struct rt6_info *) dst; |
891 | 892 | ||
892 | if (rt) { | 893 | if (rt) { |
893 | if (rt->rt6i_flags & RTF_CACHE) | 894 | if (rt->rt6i_flags & RTF_CACHE) { |
894 | ip6_del_rt(rt); | 895 | if (rt6_check_expired(rt)) { |
895 | else | 896 | ip6_del_rt(rt); |
897 | dst = NULL; | ||
898 | } | ||
899 | } else { | ||
896 | dst_release(dst); | 900 | dst_release(dst); |
901 | dst = NULL; | ||
902 | } | ||
897 | } | 903 | } |
898 | return NULL; | 904 | return dst; |
899 | } | 905 | } |
900 | 906 | ||
901 | static void ip6_link_failure(struct sk_buff *skb) | 907 | static void ip6_link_failure(struct sk_buff *skb) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b1eea811be48..5abae10cd884 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
29 | #include <linux/if_arp.h> | 29 | #include <linux/if_arp.h> |
30 | #include <linux/icmp.h> | 30 | #include <linux/icmp.h> |
31 | #include <linux/slab.h> | ||
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include <linux/init.h> | 33 | #include <linux/init.h> |
33 | #include <linux/netfilter_ipv4.h> | 34 | #include <linux/netfilter_ipv4.h> |
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index f841d93bf987..fa1d8f4e0051 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/sysctl.h> | 9 | #include <linux/sysctl.h> |
10 | #include <linux/in6.h> | 10 | #include <linux/in6.h> |
11 | #include <linux/ipv6.h> | 11 | #include <linux/ipv6.h> |
12 | #include <linux/slab.h> | ||
12 | #include <net/ndisc.h> | 13 | #include <net/ndisc.h> |
13 | #include <net/ipv6.h> | 14 | #include <net/ipv6.h> |
14 | #include <net/addrconf.h> | 15 | #include <net/addrconf.h> |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9b6dbba80d31..bd5ef7b6e48e 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/jhash.h> | 38 | #include <linux/jhash.h> |
39 | #include <linux/ipsec.h> | 39 | #include <linux/ipsec.h> |
40 | #include <linux/times.h> | 40 | #include <linux/times.h> |
41 | #include <linux/slab.h> | ||
41 | 42 | ||
42 | #include <linux/ipv6.h> | 43 | #include <linux/ipv6.h> |
43 | #include <linux/icmpv6.h> | 44 | #include <linux/icmpv6.h> |
@@ -74,6 +75,9 @@ static void tcp_v6_reqsk_send_ack(struct sock *sk, struct sk_buff *skb, | |||
74 | struct request_sock *req); | 75 | struct request_sock *req); |
75 | 76 | ||
76 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); | 77 | static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb); |
78 | static void __tcp_v6_send_check(struct sk_buff *skb, | ||
79 | struct in6_addr *saddr, | ||
80 | struct in6_addr *daddr); | ||
77 | 81 | ||
78 | static const struct inet_connection_sock_af_ops ipv6_mapped; | 82 | static const struct inet_connection_sock_af_ops ipv6_mapped; |
79 | static const struct inet_connection_sock_af_ops ipv6_specific; | 83 | static const struct inet_connection_sock_af_ops ipv6_specific; |
@@ -502,14 +506,10 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
502 | 506 | ||
503 | skb = tcp_make_synack(sk, dst, req, rvp); | 507 | skb = tcp_make_synack(sk, dst, req, rvp); |
504 | if (skb) { | 508 | if (skb) { |
505 | struct tcphdr *th = tcp_hdr(skb); | 509 | __tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr); |
506 | |||
507 | th->check = tcp_v6_check(skb->len, | ||
508 | &treq->loc_addr, &treq->rmt_addr, | ||
509 | csum_partial(th, skb->len, skb->csum)); | ||
510 | 510 | ||
511 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); | 511 | ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); |
512 | err = ip6_xmit(sk, skb, &fl, opt, 0); | 512 | err = ip6_xmit(sk, skb, &fl, opt); |
513 | err = net_xmit_eval(err); | 513 | err = net_xmit_eval(err); |
514 | } | 514 | } |
515 | 515 | ||
@@ -917,22 +917,29 @@ static struct timewait_sock_ops tcp6_timewait_sock_ops = { | |||
917 | .twsk_destructor= tcp_twsk_destructor, | 917 | .twsk_destructor= tcp_twsk_destructor, |
918 | }; | 918 | }; |
919 | 919 | ||
920 | static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) | 920 | static void __tcp_v6_send_check(struct sk_buff *skb, |
921 | struct in6_addr *saddr, struct in6_addr *daddr) | ||
921 | { | 922 | { |
922 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
923 | struct tcphdr *th = tcp_hdr(skb); | 923 | struct tcphdr *th = tcp_hdr(skb); |
924 | 924 | ||
925 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 925 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
926 | th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); | 926 | th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0); |
927 | skb->csum_start = skb_transport_header(skb) - skb->head; | 927 | skb->csum_start = skb_transport_header(skb) - skb->head; |
928 | skb->csum_offset = offsetof(struct tcphdr, check); | 928 | skb->csum_offset = offsetof(struct tcphdr, check); |
929 | } else { | 929 | } else { |
930 | th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, | 930 | th->check = tcp_v6_check(skb->len, saddr, daddr, |
931 | csum_partial(th, th->doff<<2, | 931 | csum_partial(th, th->doff << 2, |
932 | skb->csum)); | 932 | skb->csum)); |
933 | } | 933 | } |
934 | } | 934 | } |
935 | 935 | ||
936 | static void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb) | ||
937 | { | ||
938 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
939 | |||
940 | __tcp_v6_send_check(skb, &np->saddr, &np->daddr); | ||
941 | } | ||
942 | |||
936 | static int tcp_v6_gso_send_check(struct sk_buff *skb) | 943 | static int tcp_v6_gso_send_check(struct sk_buff *skb) |
937 | { | 944 | { |
938 | struct ipv6hdr *ipv6h; | 945 | struct ipv6hdr *ipv6h; |
@@ -945,11 +952,8 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb) | |||
945 | th = tcp_hdr(skb); | 952 | th = tcp_hdr(skb); |
946 | 953 | ||
947 | th->check = 0; | 954 | th->check = 0; |
948 | th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len, | ||
949 | IPPROTO_TCP, 0); | ||
950 | skb->csum_start = skb_transport_header(skb) - skb->head; | ||
951 | skb->csum_offset = offsetof(struct tcphdr, check); | ||
952 | skb->ip_summed = CHECKSUM_PARTIAL; | 955 | skb->ip_summed = CHECKSUM_PARTIAL; |
956 | __tcp_v6_send_check(skb, &ipv6h->saddr, &ipv6h->daddr); | ||
953 | return 0; | 957 | return 0; |
954 | } | 958 | } |
955 | 959 | ||
@@ -1052,9 +1056,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1052 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); | 1056 | ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr); |
1053 | ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); | 1057 | ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr); |
1054 | 1058 | ||
1055 | t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst, | 1059 | __tcp_v6_send_check(buff, &fl.fl6_src, &fl.fl6_dst); |
1056 | tot_len, IPPROTO_TCP, | ||
1057 | buff->csum); | ||
1058 | 1060 | ||
1059 | fl.proto = IPPROTO_TCP; | 1061 | fl.proto = IPPROTO_TCP; |
1060 | fl.oif = inet6_iif(skb); | 1062 | fl.oif = inet6_iif(skb); |
@@ -1069,7 +1071,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win, | |||
1069 | if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { | 1071 | if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { |
1070 | if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { | 1072 | if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { |
1071 | skb_dst_set(buff, dst); | 1073 | skb_dst_set(buff, dst); |
1072 | ip6_xmit(ctl_sk, buff, &fl, NULL, 0); | 1074 | ip6_xmit(ctl_sk, buff, &fl, NULL); |
1073 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); | 1075 | TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); |
1074 | if (rst) | 1076 | if (rst) |
1075 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); | 1077 | TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); |
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index e17bc1dfc1a4..fc3c86a47452 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
26 | #include <linux/netdevice.h> | 26 | #include <linux/netdevice.h> |
27 | #include <linux/skbuff.h> | 27 | #include <linux/skbuff.h> |
28 | #include <linux/slab.h> | ||
28 | #include <net/ipv6.h> | 29 | #include <net/ipv6.h> |
29 | #include <net/protocol.h> | 30 | #include <net/protocol.h> |
30 | #include <net/xfrm.h> | 31 | #include <net/xfrm.h> |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 3c0c9c755c92..90824852f598 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
37 | #include <linux/slab.h> | ||
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | 39 | ||
39 | #include <net/ndisc.h> | 40 | #include <net/ndisc.h> |
@@ -258,8 +259,8 @@ static struct sock *__udp6_lib_lookup(struct net *net, | |||
258 | if (hslot->count < hslot2->count) | 259 | if (hslot->count < hslot2->count) |
259 | goto begin; | 260 | goto begin; |
260 | 261 | ||
261 | result = udp6_lib_lookup2(net, &in6addr_any, sport, | 262 | result = udp6_lib_lookup2(net, saddr, sport, |
262 | daddr, hnum, dif, | 263 | &in6addr_any, hnum, dif, |
263 | hslot2, slot2); | 264 | hslot2, slot2); |
264 | } | 265 | } |
265 | rcu_read_unlock(); | 266 | rcu_read_unlock(); |
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 3927832227b9..b809812c8d30 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> | 5 | * Copyright (c) 2004-2006 Herbert Xu <herbert@gondor.apana.org.au> |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/gfp.h> | ||
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
9 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index ae181651c75a..8c452fd5ceae 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -67,36 +67,6 @@ static int xfrm6_get_saddr(struct net *net, | |||
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | 69 | ||
70 | static struct dst_entry * | ||
71 | __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy) | ||
72 | { | ||
73 | struct dst_entry *dst; | ||
74 | |||
75 | /* Still not clear if we should set fl->fl6_{src,dst}... */ | ||
76 | read_lock_bh(&policy->lock); | ||
77 | for (dst = policy->bundles; dst; dst = dst->next) { | ||
78 | struct xfrm_dst *xdst = (struct xfrm_dst*)dst; | ||
79 | struct in6_addr fl_dst_prefix, fl_src_prefix; | ||
80 | |||
81 | ipv6_addr_prefix(&fl_dst_prefix, | ||
82 | &fl->fl6_dst, | ||
83 | xdst->u.rt6.rt6i_dst.plen); | ||
84 | ipv6_addr_prefix(&fl_src_prefix, | ||
85 | &fl->fl6_src, | ||
86 | xdst->u.rt6.rt6i_src.plen); | ||
87 | if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) && | ||
88 | ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) && | ||
89 | xfrm_bundle_ok(policy, xdst, fl, AF_INET6, | ||
90 | (xdst->u.rt6.rt6i_dst.plen != 128 || | ||
91 | xdst->u.rt6.rt6i_src.plen != 128))) { | ||
92 | dst_clone(dst); | ||
93 | break; | ||
94 | } | ||
95 | } | ||
96 | read_unlock_bh(&policy->lock); | ||
97 | return dst; | ||
98 | } | ||
99 | |||
100 | static int xfrm6_get_tos(struct flowi *fl) | 70 | static int xfrm6_get_tos(struct flowi *fl) |
101 | { | 71 | { |
102 | return 0; | 72 | return 0; |
@@ -291,7 +261,6 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { | |||
291 | .dst_ops = &xfrm6_dst_ops, | 261 | .dst_ops = &xfrm6_dst_ops, |
292 | .dst_lookup = xfrm6_dst_lookup, | 262 | .dst_lookup = xfrm6_dst_lookup, |
293 | .get_saddr = xfrm6_get_saddr, | 263 | .get_saddr = xfrm6_get_saddr, |
294 | .find_bundle = __xfrm6_find_bundle, | ||
295 | .decode_session = _decode_session6, | 264 | .decode_session = _decode_session6, |
296 | .get_tos = xfrm6_get_tos, | 265 | .get_tos = xfrm6_get_tos, |
297 | .init_path = xfrm6_init_path, | 266 | .init_path = xfrm6_init_path, |
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index fa85a7d22dc4..2ce3a8278f26 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
@@ -23,6 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/xfrm.h> | 25 | #include <linux/xfrm.h> |
26 | #include <linux/slab.h> | ||
26 | #include <linux/rculist.h> | 27 | #include <linux/rculist.h> |
27 | #include <net/ip.h> | 28 | #include <net/ip.h> |
28 | #include <net/xfrm.h> | 29 | #include <net/xfrm.h> |