--- sys/netinet6/in6_ifattach.c (svn+ssh://svn.freebsd.org/base/head) (revision 261548) +++ sys/netinet6/in6_ifattach.c (working copy) @@ -452,7 +452,6 @@ success: static int in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp) { - struct in6_ifaddr *ia; struct in6_aliasreq ifra; struct nd_prefixctl pr0; int error; @@ -463,10 +462,8 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct i in6_prepare_ifra(&ifra, NULL, &in6mask64); ifra.ifra_addr.sin6_addr.s6_addr32[0] = htonl(0xfe800000); - ifra.ifra_addr.sin6_addr.s6_addr32[1] = 0; if ((ifp->if_flags & IFF_LOOPBACK) != 0) { - ifra.ifra_addr.sin6_addr.s6_addr32[2] = 0; - ifra.ifra_addr.sin6_addr.s6_addr32[3] = htonl(1); + ifra.ifra_addr.sin6_addr.s6_addr32[3] = IPV6_ADDR_INT32_ONE; } else { if (get_ifid(ifp, altifp, &ifra.ifra_addr.sin6_addr) != 0) { nd6log((LOG_ERR, @@ -474,9 +471,6 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct i return (-1); } } - if (in6_setscope(&ifra.ifra_addr.sin6_addr, ifp, NULL)) - return (-1); - /* link-local addresses should NEVER expire. */ ifra.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME; ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; @@ -502,12 +496,6 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct i if_name(ifp), error)); return (-1); } - - ia = in6ifa_ifpforlinklocal(ifp, 0); /* ia must not be NULL */ - KASSERT(ia != NULL, ("%s: ia == NULL, ifp=%p", __func__, ifp)); - - ifa_free(&ia->ia_ifa); - /* * Make the link-local prefix (fe80::%link/64) as on-link. * Since we'd like to manage prefixes separately from addresses, @@ -662,9 +650,6 @@ in6_nigroup0(struct ifnet *ifp, const char *name, /* Copy the first 32 bits of 128-bit hash into the address. */ bcopy(digest, &in6->s6_addr32[3], sizeof(in6->s6_addr32[3])); } - if (in6_setscope(in6, ifp, NULL)) - return (-1); /* XXX: should not fail */ - return 0; } @@ -775,12 +760,7 @@ in6_ifattach(struct ifnet *ifp, struct ifnet *alti void in6_ifdetach(struct ifnet *ifp) { - struct in6_ifaddr *ia; struct ifaddr *ifa, *next; - struct radix_node_head *rnh; - struct rtentry *rt; - struct sockaddr_in6 sin6; - struct in6_multi_mship *imm; if (ifp->if_afdata[AF_INET6] == NULL) return; @@ -795,39 +775,6 @@ in6_ifdetach(struct ifnet *ifp) in6_purgeaddr(ifa); } - /* undo everything done by in6_ifattach(), just in case */ - TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) { - if (ifa->ifa_addr->sa_family != AF_INET6 - || !IN6_IS_ADDR_LINKLOCAL(&satosin6(&ifa->ifa_addr)->sin6_addr)) { - continue; - } - - ia = (struct in6_ifaddr *)ifa; - - /* - * leave from multicast groups we have joined for the interface - */ - while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) { - LIST_REMOVE(imm, i6mm_chain); - in6_leavegroup(imm); - } - - /* Remove link-local from the routing table. */ - if (ia->ia_flags & IFA_ROUTE) - (void)rtinit(&ia->ia_ifa, RTM_DELETE, ia->ia_flags); - - /* remove from the linked list */ - IF_ADDR_WLOCK(ifp); - TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); - IF_ADDR_WUNLOCK(ifp); - ifa_free(ifa); /* if_addrhead */ - - IN6_IFADDR_WLOCK(); - TAILQ_REMOVE(&V_in6_ifaddrhead, ia, ia_link); - IN6_IFADDR_WUNLOCK(); - ifa_free(ifa); - } - in6_pcbpurgeif0(&V_udbinfo, ifp); in6_pcbpurgeif0(&V_ripcbinfo, ifp); /* leave from all multicast groups joined */ @@ -842,31 +789,6 @@ in6_ifdetach(struct ifnet *ifp) * (Or can we just delay calling nd6_purge until at this point?) */ nd6_purge(ifp); - - /* - * Remove route to link-local allnodes multicast (ff02::1). - * These only get automatically installed for the default FIB. - */ - bzero(&sin6, sizeof(sin6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_family = AF_INET6; - sin6.sin6_addr = in6addr_linklocal_allnodes; - if (in6_setscope(&sin6.sin6_addr, ifp, NULL)) - /* XXX: should not fail */ - return; - /* XXX grab lock first to avoid LOR */ - rnh = rt_tables_get_rnh(RT_DEFAULT_FIB, AF_INET6); - if (rnh != NULL) { - RADIX_NODE_HEAD_LOCK(rnh); - rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, RTF_RNH_LOCKED, - RT_DEFAULT_FIB); - if (rt) { - if (rt->rt_ifp == ifp) - rtexpunge(rt); - RTFREE_LOCKED(rt); - } - RADIX_NODE_HEAD_UNLOCK(rnh); - } } int