net: Abstract dst->neighbour accesses behind helpers.
[deliverable/linux.git] / net / ipv6 / addrconf.c
index 498b927f68be44248c60fc47a816b0dd171e483c..a06c53c14d841e07083ca9dbab9423bf607d914d 100644 (file)
@@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
         * layer address of our nexhop router
         */
 
-       if (rt->rt6i_nexthop == NULL)
+       if (dst_get_neighbour(&rt->dst) == NULL)
                ifa->flags &= ~IFA_F_OPTIMISTIC;
 
        ifa->idev = idev;
@@ -1470,6 +1470,8 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
 {
        struct in6_addr addr;
+       if (ifp->prefix_len == 127) /* RFC 6164 */
+               return;
        ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
        if (ipv6_addr_any(&addr))
                return;
@@ -1559,6 +1561,11 @@ static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
        return -1;
 }
 
+static int addrconf_ifid_gre(u8 *eui, struct net_device *dev)
+{
+       return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr);
+}
+
 static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
 {
        switch (dev->type) {
@@ -1572,6 +1579,8 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
                return addrconf_ifid_infiniband(eui, dev);
        case ARPHRD_SIT:
                return addrconf_ifid_sit(eui, dev);
+       case ARPHRD_IPGRE:
+               return addrconf_ifid_gre(eui, dev);
        }
        return -1;
 }
@@ -2423,6 +2432,29 @@ static void addrconf_sit_config(struct net_device *dev)
 }
 #endif
 
+#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE)
+static void addrconf_gre_config(struct net_device *dev)
+{
+       struct inet6_dev *idev;
+       struct in6_addr addr;
+
+       pr_info("ipv6: addrconf_gre_config(%s)\n", dev->name);
+
+       ASSERT_RTNL();
+
+       if ((idev = ipv6_find_idev(dev)) == NULL) {
+               printk(KERN_DEBUG "init gre: add_dev failed\n");
+               return;
+       }
+
+       ipv6_addr_set(&addr,  htonl(0xFE800000), 0, 0, 0);
+       addrconf_prefix_route(&addr, 64, dev, 0, 0);
+
+       if (!ipv6_generate_eui64(addr.s6_addr + 8, dev))
+               addrconf_add_linklocal(idev, &addr);
+}
+#endif
+
 static inline int
 ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev)
 {
@@ -2538,6 +2570,11 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
                case ARPHRD_SIT:
                        addrconf_sit_config(dev);
                        break;
+#endif
+#if defined(CONFIG_NET_IPGRE) || defined(CONFIG_NET_IPGRE_MODULE)
+               case ARPHRD_IPGRE:
+                       addrconf_gre_config(dev);
+                       break;
 #endif
                case ARPHRD_TUNNEL6:
                        addrconf_ip6_tnl_config(dev);
@@ -4692,16 +4729,20 @@ int __init addrconf_init(void)
        if (err < 0)
                goto errout_af;
 
-       err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo);
+       err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo,
+                             NULL);
        if (err < 0)
                goto errout;
 
        /* Only the first call to __rtnl_register can fail */
-       __rtnl_register(PF_INET6, RTM_NEWADDR, inet6_rtm_newaddr, NULL);
-       __rtnl_register(PF_INET6, RTM_DELADDR, inet6_rtm_deladdr, NULL);
-       __rtnl_register(PF_INET6, RTM_GETADDR, inet6_rtm_getaddr, inet6_dump_ifaddr);
-       __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr);
-       __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr);
+       __rtnl_register(PF_INET6, RTM_NEWADDR, inet6_rtm_newaddr, NULL, NULL);
+       __rtnl_register(PF_INET6, RTM_DELADDR, inet6_rtm_deladdr, NULL, NULL);
+       __rtnl_register(PF_INET6, RTM_GETADDR, inet6_rtm_getaddr,
+                       inet6_dump_ifaddr, NULL);
+       __rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL,
+                       inet6_dump_ifmcaddr, NULL);
+       __rtnl_register(PF_INET6, RTM_GETANYCAST, NULL,
+                       inet6_dump_ifacaddr, NULL);
 
        ipv6_addr_label_rtnl_register();
 
This page took 0.041331 seconds and 5 git commands to generate.