summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet6/in6_ifattach.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netinet6/in6_ifattach.c')
-rw-r--r--freebsd/sys/netinet6/in6_ifattach.c72
1 files changed, 32 insertions, 40 deletions
diff --git a/freebsd/sys/netinet6/in6_ifattach.c b/freebsd/sys/netinet6/in6_ifattach.c
index c2134c6f..bb150eb1 100644
--- a/freebsd/sys/netinet6/in6_ifattach.c
+++ b/freebsd/sys/netinet6/in6_ifattach.c
@@ -249,7 +249,7 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
static u_int8_t allone[8] =
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- IF_ADDR_LOCK(ifp);
+ IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_LINK)
continue;
@@ -261,7 +261,7 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
goto found;
}
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
@@ -273,6 +273,7 @@ found:
/* get EUI64 */
switch (ifp->if_type) {
case IFT_ETHER:
+ case IFT_L2VLAN:
case IFT_FDDI:
case IFT_ISO88025:
case IFT_ATM:
@@ -287,7 +288,7 @@ found:
/* look at IEEE802/EUI64 only */
if (addrlen != 8 && addrlen != 6) {
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
@@ -297,11 +298,11 @@ found:
* card insertion.
*/
if (bcmp(addr, allzero, addrlen) == 0) {
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
if (bcmp(addr, allone, addrlen) == 0) {
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
@@ -322,11 +323,11 @@ found:
case IFT_ARCNET:
if (addrlen != 1) {
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
if (!addr[0]) {
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
@@ -350,17 +351,17 @@ found:
* identifier source (can be renumbered).
* we don't do this.
*/
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
default:
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
/* sanity check: g bit must not indicate "group" */
if (EUI64_GROUP(in6)) {
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
@@ -373,11 +374,11 @@ found:
*/
if ((in6->s6_addr[8] & ~(EUI64_GBIT | EUI64_UBIT)) == 0x00 &&
bcmp(&in6->s6_addr[9], allzero, 7) == 0) {
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return -1;
}
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
return 0;
}
@@ -410,7 +411,7 @@ get_ifid(struct ifnet *ifp0, struct ifnet *altifp,
/* next, try to get it from some other hardware interface */
IFNET_RLOCK_NOSLEEP();
- for (ifp = V_ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) {
+ TAILQ_FOREACH(ifp, &V_ifnet, if_list) {
if (ifp == ifp0)
continue;
if (in6_get_hw_ifid(ifp, in6) != 0)
@@ -518,12 +519,8 @@ in6_ifattach_linklocal(struct ifnet *ifp, struct ifnet *altifp)
}
ia = in6ifa_ifpforlinklocal(ifp, 0); /* ia must not be NULL */
-#ifdef DIAGNOSTIC
- if (!ia) {
- panic("ia == NULL in in6_ifattach_linklocal");
- /* NOTREACHED */
- }
-#endif
+ KASSERT(ia != NULL, ("%s: ia == NULL, ifp=%p", __func__, ifp));
+
ifa_free(&ia->ia_ifa);
/*
@@ -798,7 +795,6 @@ in6_ifdetach(struct ifnet *ifp)
struct ifaddr *ifa, *next;
struct radix_node_head *rnh;
struct rtentry *rt;
- short rtflags;
struct sockaddr_in6 sin6;
struct in6_multi_mship *imm;
@@ -824,26 +820,19 @@ in6_ifdetach(struct ifnet *ifp)
/*
* leave from multicast groups we have joined for the interface
*/
- while ((imm = ia->ia6_memberships.lh_first) != NULL) {
+ while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
LIST_REMOVE(imm, i6mm_chain);
in6_leavegroup(imm);
}
- /* remove from the routing table */
- if ((ia->ia_flags & IFA_ROUTE) &&
- (rt = rtalloc1((struct sockaddr *)&ia->ia_addr, 0, 0UL))) {
- rtflags = rt->rt_flags;
- RTFREE_LOCKED(rt);
- rtrequest(RTM_DELETE, (struct sockaddr *)&ia->ia_addr,
- (struct sockaddr *)&ia->ia_addr,
- (struct sockaddr *)&ia->ia_prefixmask,
- rtflags, (struct rtentry **)0);
- }
+ /* 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_LOCK(ifp);
+ IF_ADDR_WLOCK(ifp);
TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_WUNLOCK(ifp);
ifa_free(ifa); /* if_addrhead */
IN6_IFADDR_WLOCK();
@@ -867,7 +856,10 @@ in6_ifdetach(struct ifnet *ifp)
*/
nd6_purge(ifp);
- /* remove route to link-local allnodes multicast (ff02::1) */
+ /*
+ * 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;
@@ -876,10 +868,11 @@ in6_ifdetach(struct ifnet *ifp)
/* XXX: should not fail */
return;
/* XXX grab lock first to avoid LOR */
- rnh = rt_tables_get_rnh(0, AF_INET6);
+ rnh = rt_tables_get_rnh(RT_DEFAULT_FIB, AF_INET6);
if (rnh != NULL) {
RADIX_NODE_HEAD_LOCK(rnh);
- rt = rtalloc1((struct sockaddr *)&sin6, 0, RTF_RNH_LOCKED);
+ rt = in6_rtalloc1((struct sockaddr *)&sin6, 0, RTF_RNH_LOCKED,
+ RT_DEFAULT_FIB);
if (rt) {
if (rt->rt_ifp == ifp)
rtexpunge(rt);
@@ -927,8 +920,7 @@ in6_tmpaddrtimer(void *arg)
V_ip6_temp_regen_advance) * hz, in6_tmpaddrtimer, curvnet);
bzero(nullbuf, sizeof(nullbuf));
- for (ifp = TAILQ_FIRST(&V_ifnet); ifp;
- ifp = TAILQ_NEXT(ifp, if_list)) {
+ TAILQ_FOREACH(ifp, &V_ifnet, if_list) {
ndi = ND_IFINFO(ifp);
if (bcmp(ndi->randomid, nullbuf, sizeof(nullbuf)) != 0) {
/*
@@ -959,7 +951,7 @@ in6_purgemaddrs(struct ifnet *ifp)
* We need to do this as IF_ADDR_LOCK() may be re-acquired
* by code further down.
*/
- IF_ADDR_LOCK(ifp);
+ IF_ADDR_RLOCK(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET6 ||
ifma->ifma_protospec == NULL)
@@ -967,7 +959,7 @@ in6_purgemaddrs(struct ifnet *ifp)
inm = (struct in6_multi *)ifma->ifma_protospec;
LIST_INSERT_HEAD(&purgeinms, inm, in6m_entry);
}
- IF_ADDR_UNLOCK(ifp);
+ IF_ADDR_RUNLOCK(ifp);
LIST_FOREACH_SAFE(inm, &purgeinms, in6m_entry, tinm) {
LIST_REMOVE(inm, in6m_entry);