diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 130 |
1 files changed, 100 insertions, 30 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 498b927f68b..1587d0d9295 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -374,8 +374,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | |||
374 | "%s(): cannot allocate memory for statistics; dev=%s.\n", | 374 | "%s(): cannot allocate memory for statistics; dev=%s.\n", |
375 | __func__, dev->name)); | 375 | __func__, dev->name)); |
376 | neigh_parms_release(&nd_tbl, ndev->nd_parms); | 376 | neigh_parms_release(&nd_tbl, ndev->nd_parms); |
377 | ndev->dead = 1; | 377 | dev_put(dev); |
378 | in6_dev_finish_destroy(ndev); | 378 | kfree(ndev); |
379 | return NULL; | 379 | return NULL; |
380 | } | 380 | } |
381 | 381 | ||
@@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
656 | * layer address of our nexhop router | 656 | * layer address of our nexhop router |
657 | */ | 657 | */ |
658 | 658 | ||
659 | if (rt->rt6i_nexthop == NULL) | 659 | if (dst_get_neighbour_raw(&rt->dst) == NULL) |
660 | ifa->flags &= ~IFA_F_OPTIMISTIC; | 660 | ifa->flags &= ~IFA_F_OPTIMISTIC; |
661 | 661 | ||
662 | ifa->idev = idev; | 662 | ifa->idev = idev; |
@@ -824,12 +824,13 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i | |||
824 | { | 824 | { |
825 | struct inet6_dev *idev = ifp->idev; | 825 | struct inet6_dev *idev = ifp->idev; |
826 | struct in6_addr addr, *tmpaddr; | 826 | struct in6_addr addr, *tmpaddr; |
827 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age; | 827 | unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_tstamp, age; |
828 | unsigned long regen_advance; | 828 | unsigned long regen_advance; |
829 | int tmp_plen; | 829 | int tmp_plen; |
830 | int ret = 0; | 830 | int ret = 0; |
831 | int max_addresses; | 831 | int max_addresses; |
832 | u32 addr_flags; | 832 | u32 addr_flags; |
833 | unsigned long now = jiffies; | ||
833 | 834 | ||
834 | write_lock(&idev->lock); | 835 | write_lock(&idev->lock); |
835 | if (ift) { | 836 | if (ift) { |
@@ -874,7 +875,7 @@ retry: | |||
874 | goto out; | 875 | goto out; |
875 | } | 876 | } |
876 | memcpy(&addr.s6_addr[8], idev->rndid, 8); | 877 | memcpy(&addr.s6_addr[8], idev->rndid, 8); |
877 | age = (jiffies - ifp->tstamp) / HZ; | 878 | age = (now - ifp->tstamp) / HZ; |
878 | tmp_valid_lft = min_t(__u32, | 879 | tmp_valid_lft = min_t(__u32, |
879 | ifp->valid_lft, | 880 | ifp->valid_lft, |
880 | idev->cnf.temp_valid_lft + age); | 881 | idev->cnf.temp_valid_lft + age); |
@@ -884,7 +885,6 @@ retry: | |||
884 | idev->cnf.max_desync_factor); | 885 | idev->cnf.max_desync_factor); |
885 | tmp_plen = ifp->prefix_len; | 886 | tmp_plen = ifp->prefix_len; |
886 | max_addresses = idev->cnf.max_addresses; | 887 | max_addresses = idev->cnf.max_addresses; |
887 | tmp_cstamp = ifp->cstamp; | ||
888 | tmp_tstamp = ifp->tstamp; | 888 | tmp_tstamp = ifp->tstamp; |
889 | spin_unlock_bh(&ifp->lock); | 889 | spin_unlock_bh(&ifp->lock); |
890 | 890 | ||
@@ -929,7 +929,7 @@ retry: | |||
929 | ift->ifpub = ifp; | 929 | ift->ifpub = ifp; |
930 | ift->valid_lft = tmp_valid_lft; | 930 | ift->valid_lft = tmp_valid_lft; |
931 | ift->prefered_lft = tmp_prefered_lft; | 931 | ift->prefered_lft = tmp_prefered_lft; |
932 | ift->cstamp = tmp_cstamp; | 932 | ift->cstamp = now; |
933 | ift->tstamp = tmp_tstamp; | 933 | ift->tstamp = tmp_tstamp; |
934 | spin_unlock_bh(&ift->lock); | 934 | spin_unlock_bh(&ift->lock); |
935 | 935 | ||
@@ -1470,6 +1470,8 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr) | |||
1470 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | 1470 | static void addrconf_join_anycast(struct inet6_ifaddr *ifp) |
1471 | { | 1471 | { |
1472 | struct in6_addr addr; | 1472 | struct in6_addr addr; |
1473 | if (ifp->prefix_len == 127) /* RFC 6164 */ | ||
1474 | return; | ||
1473 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1475 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
1474 | if (ipv6_addr_any(&addr)) | 1476 | if (ipv6_addr_any(&addr)) |
1475 | return; | 1477 | return; |
@@ -1479,6 +1481,8 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | |||
1479 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1481 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) |
1480 | { | 1482 | { |
1481 | struct in6_addr addr; | 1483 | struct in6_addr addr; |
1484 | if (ifp->prefix_len == 127) /* RFC 6164 */ | ||
1485 | return; | ||
1482 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1486 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
1483 | if (ipv6_addr_any(&addr)) | 1487 | if (ipv6_addr_any(&addr)) |
1484 | return; | 1488 | return; |
@@ -1559,6 +1563,11 @@ static int addrconf_ifid_sit(u8 *eui, struct net_device *dev) | |||
1559 | return -1; | 1563 | return -1; |
1560 | } | 1564 | } |
1561 | 1565 | ||
1566 | static int addrconf_ifid_gre(u8 *eui, struct net_device *dev) | ||
1567 | { | ||
1568 | return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr); | ||
1569 | } | ||
1570 | |||
1562 | static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | 1571 | static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) |
1563 | { | 1572 | { |
1564 | switch (dev->type) { | 1573 | switch (dev->type) { |
@@ -1572,6 +1581,8 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | |||
1572 | return addrconf_ifid_infiniband(eui, dev); | 1581 | return addrconf_ifid_infiniband(eui, dev); |
1573 | case ARPHRD_SIT: | 1582 | case ARPHRD_SIT: |
1574 | return addrconf_ifid_sit(eui, dev); | 1583 | return addrconf_ifid_sit(eui, dev); |
1584 | case ARPHRD_IPGRE: | ||
1585 | return addrconf_ifid_gre(eui, dev); | ||
1575 | } | 1586 | } |
1576 | return -1; | 1587 | return -1; |
1577 | } | 1588 | } |
@@ -1988,25 +1999,50 @@ ok: | |||
1988 | #ifdef CONFIG_IPV6_PRIVACY | 1999 | #ifdef CONFIG_IPV6_PRIVACY |
1989 | read_lock_bh(&in6_dev->lock); | 2000 | read_lock_bh(&in6_dev->lock); |
1990 | /* update all temporary addresses in the list */ | 2001 | /* update all temporary addresses in the list */ |
1991 | list_for_each_entry(ift, &in6_dev->tempaddr_list, tmp_list) { | 2002 | list_for_each_entry(ift, &in6_dev->tempaddr_list, |
1992 | /* | 2003 | tmp_list) { |
1993 | * When adjusting the lifetimes of an existing | 2004 | int age, max_valid, max_prefered; |
1994 | * temporary address, only lower the lifetimes. | 2005 | |
1995 | * Implementations must not increase the | ||
1996 | * lifetimes of an existing temporary address | ||
1997 | * when processing a Prefix Information Option. | ||
1998 | */ | ||
1999 | if (ifp != ift->ifpub) | 2006 | if (ifp != ift->ifpub) |
2000 | continue; | 2007 | continue; |
2001 | 2008 | ||
2009 | /* | ||
2010 | * RFC 4941 section 3.3: | ||
2011 | * If a received option will extend the lifetime | ||
2012 | * of a public address, the lifetimes of | ||
2013 | * temporary addresses should be extended, | ||
2014 | * subject to the overall constraint that no | ||
2015 | * temporary addresses should ever remain | ||
2016 | * "valid" or "preferred" for a time longer than | ||
2017 | * (TEMP_VALID_LIFETIME) or | ||
2018 | * (TEMP_PREFERRED_LIFETIME - DESYNC_FACTOR), | ||
2019 | * respectively. | ||
2020 | */ | ||
2021 | age = (now - ift->cstamp) / HZ; | ||
2022 | max_valid = in6_dev->cnf.temp_valid_lft - age; | ||
2023 | if (max_valid < 0) | ||
2024 | max_valid = 0; | ||
2025 | |||
2026 | max_prefered = in6_dev->cnf.temp_prefered_lft - | ||
2027 | in6_dev->cnf.max_desync_factor - | ||
2028 | age; | ||
2029 | if (max_prefered < 0) | ||
2030 | max_prefered = 0; | ||
2031 | |||
2032 | if (valid_lft > max_valid) | ||
2033 | valid_lft = max_valid; | ||
2034 | |||
2035 | if (prefered_lft > max_prefered) | ||
2036 | prefered_lft = max_prefered; | ||
2037 | |||
2002 | spin_lock(&ift->lock); | 2038 | spin_lock(&ift->lock); |
2003 | flags = ift->flags; | 2039 | flags = ift->flags; |
2004 | if (ift->valid_lft > valid_lft && | 2040 | ift->valid_lft = valid_lft; |
2005 | ift->valid_lft - valid_lft > (jiffies - ift->tstamp) / HZ) | 2041 | ift->prefered_lft = prefered_lft; |
2006 | ift->valid_lft = valid_lft + (jiffies - ift->tstamp) / HZ; | 2042 | ift->tstamp = now; |
2007 | if (ift->prefered_lft > prefered_lft && | 2043 | if (prefered_lft > 0) |
2008 | ift->prefered_lft - prefered_lft > (jiffies - ift->tstamp) / HZ) | 2044 | ift->flags &= ~IFA_F_DEPRECATED; |
2009 | ift->prefered_lft = prefered_lft + (jiffies - ift->tstamp) / HZ; | 2045 | |
2010 | spin_unlock(&ift->lock); | 2046 | spin_unlock(&ift->lock); |
2011 | if (!(flags&IFA_F_TENTATIVE)) | 2047 | if (!(flags&IFA_F_TENTATIVE)) |
2012 | ipv6_ifa_notify(0, ift); | 2048 | ipv6_ifa_notify(0, ift); |
@@ -2014,9 +2050,11 @@ ok: | |||
2014 | 2050 | ||
2015 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { | 2051 | if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) { |
2016 | /* | 2052 | /* |
2017 | * When a new public address is created as described in [ADDRCONF], | 2053 | * When a new public address is created as |
2018 | * also create a new temporary address. Also create a temporary | 2054 | * described in [ADDRCONF], also create a new |
2019 | * address if it's enabled but no temporary address currently exists. | 2055 | * temporary address. Also create a temporary |
2056 | * address if it's enabled but no temporary | ||
2057 | * address currently exists. | ||
2020 | */ | 2058 | */ |
2021 | read_unlock_bh(&in6_dev->lock); | 2059 | read_unlock_bh(&in6_dev->lock); |
2022 | ipv6_create_tempaddr(ifp, NULL); | 2060 | ipv6_create_tempaddr(ifp, NULL); |
@@ -2423,6 +2461,29 @@ static void addrconf_sit_config(struct net_device *dev) | |||
2423 | } | 2461 | } |
2424 | #endif | 2462 | #endif |
2425 | 2463 | ||
2464 | #if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) | ||
2465 | static void addrconf_gre_config(struct net_device *dev) | ||
2466 | { | ||
2467 | struct inet6_dev *idev; | ||
2468 | struct in6_addr addr; | ||
2469 | |||
2470 | pr_info("ipv6: addrconf_gre_config(%s)\n", dev->name); | ||
2471 | |||
2472 | ASSERT_RTNL(); | ||
2473 | |||
2474 | if ((idev = ipv6_find_idev(dev)) == NULL) { | ||
2475 | printk(KERN_DEBUG "init gre: add_dev failed\n"); | ||
2476 | return; | ||
2477 | } | ||
2478 | |||
2479 | ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0); | ||
2480 | addrconf_prefix_route(&addr, 64, dev, 0, 0); | ||
2481 | |||
2482 | if (!ipv6_generate_eui64(addr.s6_addr + 8, dev)) | ||
2483 | addrconf_add_linklocal(idev, &addr); | ||
2484 | } | ||
2485 | #endif | ||
2486 | |||
2426 | static inline int | 2487 | static inline int |
2427 | ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) | 2488 | ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev) |
2428 | { | 2489 | { |
@@ -2539,6 +2600,11 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
2539 | addrconf_sit_config(dev); | 2600 | addrconf_sit_config(dev); |
2540 | break; | 2601 | break; |
2541 | #endif | 2602 | #endif |
2603 | #if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE) | ||
2604 | case ARPHRD_IPGRE: | ||
2605 | addrconf_gre_config(dev); | ||
2606 | break; | ||
2607 | #endif | ||
2542 | case ARPHRD_TUNNEL6: | 2608 | case ARPHRD_TUNNEL6: |
2543 | addrconf_ip6_tnl_config(dev); | 2609 | addrconf_ip6_tnl_config(dev); |
2544 | break; | 2610 | break; |
@@ -4692,16 +4758,20 @@ int __init addrconf_init(void) | |||
4692 | if (err < 0) | 4758 | if (err < 0) |
4693 | goto errout_af; | 4759 | goto errout_af; |
4694 | 4760 | ||
4695 | err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo); | 4761 | err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo, |
4762 | NULL); | ||
4696 | if (err < 0) | 4763 | if (err < 0) |
4697 | goto errout; | 4764 | goto errout; |
4698 | 4765 | ||
4699 | /* Only the first call to __rtnl_register can fail */ | 4766 | /* Only the first call to __rtnl_register can fail */ |
4700 | __rtnl_register(PF_INET6, RTM_NEWADDR, inet6_rtm_newaddr, NULL); | 4767 | __rtnl_register(PF_INET6, RTM_NEWADDR, inet6_rtm_newaddr, NULL, NULL); |
4701 | __rtnl_register(PF_INET6, RTM_DELADDR, inet6_rtm_deladdr, NULL); | 4768 | __rtnl_register(PF_INET6, RTM_DELADDR, inet6_rtm_deladdr, NULL, NULL); |
4702 | __rtnl_register(PF_INET6, RTM_GETADDR, inet6_rtm_getaddr, inet6_dump_ifaddr); | 4769 | __rtnl_register(PF_INET6, RTM_GETADDR, inet6_rtm_getaddr, |
4703 | __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr); | 4770 | inet6_dump_ifaddr, NULL); |
4704 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr); | 4771 | __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, |
4772 | inet6_dump_ifmcaddr, NULL); | ||
4773 | __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, | ||
4774 | inet6_dump_ifacaddr, NULL); | ||
4705 | 4775 | ||
4706 | ipv6_addr_label_rtnl_register(); | 4776 | ipv6_addr_label_rtnl_register(); |
4707 | 4777 | ||