Date: Sun, 26 Apr 2009 19:05:40 +0000 (UTC) From: Robert Watson <rwatson@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r191528 - head/sys/netinet Message-ID: <200904261905.n3QJ5eDJ092034@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rwatson Date: Sun Apr 26 19:05:40 2009 New Revision: 191528 URL: http://svn.freebsd.org/changeset/base/191528 Log: Acquire IF_ADDR_LOCK() around most iterations over ifp->if_addrhead (colloquially known as if_addrlist). Currently not acquired around interface address loops that call out to the routing code due to potential lock order issues. MFC after: 3 weeks Modified: head/sys/netinet/ip_carp.c Modified: head/sys/netinet/ip_carp.c ============================================================================== --- head/sys/netinet/ip_carp.c Sun Apr 26 18:57:50 2009 (r191527) +++ head/sys/netinet/ip_carp.c Sun Apr 26 19:05:40 2009 (r191528) @@ -275,6 +275,7 @@ carp_hmac_prepare(struct carp_softc *sc) found = 0; last = cur; cur.s_addr = 0xffffffff; + IF_ADDR_LOCK(SC2IFP(sc)); TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) { in.s_addr = ifatoia(ifa)->ia_addr.sin_addr.s_addr; if (ifa->ifa_addr->sa_family == AF_INET && @@ -284,6 +285,7 @@ carp_hmac_prepare(struct carp_softc *sc) found++; } } + IF_ADDR_UNLOCK(SC2IFP(sc)); if (found) SHA1Update(&sc->sc_sha1, (void *)&cur, sizeof(cur)); } while (found); @@ -294,6 +296,7 @@ carp_hmac_prepare(struct carp_softc *sc) found = 0; last6 = cur6; memset(&cur6, 0xff, sizeof(cur6)); + IF_ADDR_LOCK(SC2IFP(sc)); TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) { in6 = ifatoia6(ifa)->ia_addr.sin6_addr; if (IN6_IS_SCOPE_EMBED(&in6)) @@ -305,6 +308,7 @@ carp_hmac_prepare(struct carp_softc *sc) found++; } } + IF_ADDR_UNLOCK(SC2IFP(sc)); if (found) SHA1Update(&sc->sc_sha1, (void *)&cur6, sizeof(cur6)); } while (found); @@ -1121,6 +1125,7 @@ carp_addrcount(struct carp_if *cif, stru (SC2IFP(vh)->if_flags & IFF_UP) && (SC2IFP(vh)->if_drv_flags & IFF_DRV_RUNNING)) || (type == CARP_COUNT_MASTER && vh->sc_state == MASTER)) { + IF_ADDR_LOCK(SC2IFP(vh)); TAILQ_FOREACH(ifa, &SC2IFP(vh)->if_addrlist, ifa_list) { if (ifa->ifa_addr->sa_family == AF_INET && @@ -1128,6 +1133,7 @@ carp_addrcount(struct carp_if *cif, stru ifatoia(ifa)->ia_addr.sin_addr.s_addr) count++; } + IF_ADDR_UNLOCK(SC2IFP(vh)); } } return (count); @@ -1166,6 +1172,7 @@ carp_iamatch(void *v, struct in_ifaddr * TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list) { if ((SC2IFP(vh)->if_flags & IFF_UP) && (SC2IFP(vh)->if_drv_flags & IFF_DRV_RUNNING)) { + IF_ADDR_LOCK(SC2IFP(vh)); TAILQ_FOREACH(ifa, &SC2IFP(vh)->if_addrlist, ifa_list) { if (ifa->ifa_addr->sa_family == @@ -1176,9 +1183,11 @@ carp_iamatch(void *v, struct in_ifaddr * if (vh->sc_state == MASTER) { *enaddr = IF_LLADDR(vh->sc_ifp); + IF_ADDR_UNLOCK(SC2IFP(vh)); CARP_UNLOCK(cif); return (1); } else { + IF_ADDR_UNLOCK(SC2IFP(vh)); CARP_UNLOCK(cif); return (0); } @@ -1186,6 +1195,7 @@ carp_iamatch(void *v, struct in_ifaddr * count++; } } + IF_ADDR_UNLOCK(SC2IFP(vh)); } } } else { @@ -1214,16 +1224,19 @@ carp_iamatch6(void *v, struct in6_addr * CARP_LOCK(cif); TAILQ_FOREACH(vh, &cif->vhif_vrs, sc_list) { + IF_ADDR_LOCK(SC2IFP(vh)); TAILQ_FOREACH(ifa, &SC2IFP(vh)->if_addrlist, ifa_list) { if (IN6_ARE_ADDR_EQUAL(taddr, &ifatoia6(ifa)->ia_addr.sin6_addr) && (SC2IFP(vh)->if_flags & IFF_UP) && (SC2IFP(vh)->if_drv_flags & IFF_DRV_RUNNING) && vh->sc_state == MASTER) { + IF_ADDR_UNLOCK(SC2IFP(vh)); CARP_UNLOCK(cif); return (ifa); } } + IF_ADDR_UNLOCK(SC2IFP(vh)); } CARP_UNLOCK(cif); @@ -1240,6 +1253,7 @@ carp_macmatch6(void *v, struct mbuf *m, CARP_LOCK(cif); TAILQ_FOREACH(sc, &cif->vhif_vrs, sc_list) { + IF_ADDR_LOCK(SC2IFP(sc)); TAILQ_FOREACH(ifa, &SC2IFP(sc)->if_addrlist, ifa_list) { if (IN6_ARE_ADDR_EQUAL(taddr, &ifatoia6(ifa)->ia_addr.sin6_addr) && @@ -1250,6 +1264,7 @@ carp_macmatch6(void *v, struct mbuf *m, sizeof(struct ifnet *), M_NOWAIT); if (mtag == NULL) { /* better a bit than nothing */ + IF_ADDR_UNLOCK(SC2IFP(sc)); CARP_UNLOCK(cif); return (IF_LLADDR(sc->sc_ifp)); } @@ -1257,10 +1272,12 @@ carp_macmatch6(void *v, struct mbuf *m, sizeof(struct ifnet *)); m_tag_prepend(m, mtag); + IF_ADDR_UNLOCK(SC2IFP(sc)); CARP_UNLOCK(cif); return (IF_LLADDR(sc->sc_ifp)); } } + IF_ADDR_UNLOCK(SC2IFP(sc)); } CARP_UNLOCK(cif);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904261905.n3QJ5eDJ092034>