--- src/sys/net/if_spppsubr.c.orig Thu Jun 14 22:18:23 2007 +++ src/sys/net/if_spppsubr.c Thu Jun 14 15:11:53 2007 @@ -4993,8 +4993,10 @@ /* set new address */ si->sin_addr.s_addr = htonl(src); ia = ifatoia(ifa); + INADDR_HASH_WLOCK(); LIST_REMOVE(ia, ia_hash); LIST_INSERT_HEAD(INADDR_HASH(si->sin_addr.s_addr), ia, ia_hash); + INADDR_HASH_WUNLOCK(); /* add new route */ error = rtinit(ifa, (int)RTM_ADD, RTF_HOST); --- src/sys/net/if_stf.c.orig Sun Oct 22 15:52:15 2006 +++ src/sys/net/if_stf.c Thu Jun 14 15:11:53 2007 @@ -374,9 +374,11 @@ continue; bcopy(GET_V4(&sin6->sin6_addr), &in, sizeof(in)); + INADDR_HASH_RLOCK(); LIST_FOREACH(ia4, INADDR_HASH(in.s_addr), ia_hash) if (ia4->ia_addr.sin_addr.s_addr == in.s_addr) break; + INADDR_HASH_RUNLOCK(); if (ia4 == NULL) continue; @@ -578,15 +580,16 @@ /* * reject packets with broadcast */ - for (ia4 = TAILQ_FIRST(&in_ifaddrhead); - ia4; - ia4 = TAILQ_NEXT(ia4, ia_link)) - { + INADDR_RLOCK(); + TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_link) { if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0) continue; - if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr) - return -1; + if (in->s_addr == ia4->ia_broadaddr.sin_addr.s_addr) { + INADDR_RUNLOCK(); + return (-1); + } } + INADDR_RUNLOCK(); /* * perform ingress filter --- src/sys/netatm/ipatm/ipatm_load.c.orig Sun Oct 30 22:44:39 2005 +++ src/sys/netatm/ipatm/ipatm_load.c Thu Jun 14 15:11:53 2007 @@ -453,10 +453,12 @@ /* * If IP address has been set, register it */ + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { if (ia->ia_ifp == ifp) break; } + INADDR_RUNLOCK(); if (ia) { err = ipatm_nifstat(NCM_SETADDR, nip, (intptr_t)ia); --- src/sys/netatm/ipatm/ipatm_output.c.orig Fri Jun 10 20:49:20 2005 +++ src/sys/netatm/ipatm/ipatm_output.c Thu Jun 14 15:11:53 2007 @@ -137,6 +137,7 @@ /* * Is packet for our interface address? */ + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { if (ia->ia_ifp != ifp) continue; @@ -147,9 +148,11 @@ * It's for us - hand packet to loopback driver */ (void) if_simloop(ifp, m, dst->sa_family, 0); + INADDR_RUNLOCK(); goto done; } } + INADDR_RUNLOCK(); /* * Is this a broadcast packet ?? --- src/sys/netinet/if_ether.c.orig Thu Jun 14 22:05:49 2007 +++ src/sys/netinet/if_ether.c Thu Jun 14 15:51:47 2007 @@ -42,6 +42,8 @@ #include #include +#include +#include #include #include #include @@ -246,12 +248,14 @@ } #endif + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { if (ia->ia_ifp == rt->rt_ifp && SIN(rt_key(rt))->sin_addr.s_addr == (IA_SIN(ia))->sin_addr.s_addr) break; } + INADDR_RUNLOCK(); if (ia) { /* * This test used to be @@ -600,16 +604,20 @@ * request for the virtual host ip. * XXX: This is really ugly! */ + INADDR_HASH_RLOCK(); LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) { if (((bridged && ia->ia_ifp->if_bridge != NULL) || (ia->ia_ifp == ifp)) && - itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) + itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { + INADDR_HASH_RUNLOCK(); goto match; + } #ifdef DEV_CARP if (ifp->if_carp != NULL && carp_iamatch(ifp->if_carp, ia, &isaddr, &enaddr) && itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { carp_match = 1; + INADDR_HASH_RUNLOCK(); goto match; } #endif @@ -617,22 +625,30 @@ LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash) if (((bridged && ia->ia_ifp->if_bridge != NULL) || (ia->ia_ifp == ifp)) && - isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) + isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { + INADDR_HASH_RUNLOCK(); goto match; + } + INADDR_HASH_RUNLOCK(); /* * No match, use the first inet address on the receive interface * as a dummy address for the rest of the function. */ + INADDR_RLOCK(); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) if (ifa->ifa_addr->sa_family == AF_INET) { ia = ifatoia(ifa); + INADDR_RUNLOCK(); goto match; } /* * If bridging, fall back to using any inet address. */ - if (!bridged || (ia = TAILQ_FIRST(&in_ifaddrhead)) == NULL) + if (!bridged || (ia = TAILQ_FIRST(&in_ifaddrhead)) == NULL) { + INADDR_RUNLOCK(); goto drop; + } + INADDR_RUNLOCK(); match: if (!enaddr) enaddr = (u_int8_t *)IF_LLADDR(ifp); --- src/sys/netinet/in_gif.c.orig Thu Jun 14 22:05:49 2007 +++ src/sys/netinet/in_gif.c Thu Jun 14 16:08:05 2007 @@ -35,6 +35,8 @@ #include "opt_inet6.h" #include +#include +#include #include #include #include @@ -350,12 +352,16 @@ return 0; } /* reject packets with broadcast on source */ + INADDR_RLOCK(); TAILQ_FOREACH(ia4, &in_ifaddrhead, ia_link) { if ((ia4->ia_ifa.ifa_ifp->if_flags & IFF_BROADCAST) == 0) continue; - if (ip->ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr) - return 0; + if (ip->ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr) { + INADDR_RUNLOCK(); + return (0); + } } + INADDR_RUNLOCK(); /* ingress filters on outer source */ if ((GIF2IFP(sc)->if_flags & IFF_LINK2) == 0 && ifp) { --- src/sys/netinet/ip_carp.c.orig Thu Jun 14 22:18:24 2007 +++ src/sys/netinet/ip_carp.c Thu Jun 14 15:11:53 2007 @@ -1443,6 +1443,7 @@ /* we have to do it by hands to check we won't match on us */ ia_if = NULL; own = 0; + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { /* and, yeah, we need a multicast-capable iface too */ if (ia->ia_ifp != SC2IFP(sc) && @@ -1455,6 +1456,7 @@ own++; } } + INADDR_RUNLOCK(); if (!ia_if) return (EADDRNOTAVAIL); --- src/sys/netinet/ip_fw2.c.orig Thu Jun 14 14:56:37 2007 +++ src/sys/netinet/ip_fw2.c Thu Jun 14 15:11:53 2007 @@ -2883,7 +2883,9 @@ if (is_ipv4) { struct ifnet *tif; + INADDR_HASH_RLOCK(); INADDR_TO_IFP(src_ip, tif); + INADDR_HASH_RUNLOCK(); match = (tif != NULL); } break; @@ -2916,7 +2918,9 @@ if (is_ipv4) { struct ifnet *tif; + INADDR_HASH_RLOCK(); INADDR_TO_IFP(dst_ip, tif); + INADDR_HASH_RUNLOCK(); match = (tif != NULL); } break; --- src/sys/netinet/ip_input.c.orig Thu Jun 14 22:05:50 2007 +++ src/sys/netinet/ip_input.c Thu Jun 14 15:11:53 2007 @@ -136,7 +136,9 @@ extern struct domain inetdomain; extern struct protosw inetsw[]; u_char ip_protox[IPPROTO_MAX]; +struct rwlock in_ifaddrlock; /* inet addr list lock */ struct in_ifaddrhead in_ifaddrhead; /* first inet address */ +struct rwlock in_ifaddrhashlock; /* inet addr hash table lock */ struct in_ifaddrhashhead *in_ifaddrhashtbl; /* inet addr hash table */ u_long in_ifaddrhmask; /* mask for hash table */ @@ -214,7 +216,9 @@ struct protosw *pr; int i; + rw_init(&in_ifaddrlock, "first inet address list"); TAILQ_INIT(&in_ifaddrhead); + rw_init(&in_ifaddrhashlock, "inet addr hash"); in_ifaddrhashtbl = hashinit(INADDR_NHASH, M_IFADDR, &in_ifaddrhmask); pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW); if (pr == NULL) @@ -495,6 +499,7 @@ /* * Check for exact addresses in the hash bucket. */ + INADDR_HASH_RLOCK(); LIST_FOREACH(ia, INADDR_HASH(ip->ip_dst.s_addr), ia_hash) { /* * If the address matches, verify that the packet @@ -502,9 +507,12 @@ * enabled. */ if (IA_SIN(ia)->sin_addr.s_addr == ip->ip_dst.s_addr && - (!checkif || ia->ia_ifp == m->m_pkthdr.rcvif)) + (!checkif || ia->ia_ifp == m->m_pkthdr.rcvif)) { + INADDR_HASH_RUNLOCK(); goto ours; } + } + INADDR_HASH_RUNLOCK(); /* * Check for broadcast addresses. * --- src/sys/netinet/in.c.orig Thu Jun 14 14:56:36 2007 +++ src/sys/netinet/in.c Thu Jun 14 15:52:13 2007 @@ -34,6 +34,8 @@ #include "opt_carp.h" #include +#include +#include #include #include #include @@ -86,15 +88,21 @@ register u_long i = ntohl(in.s_addr); register struct in_ifaddr *ia; + INADDR_RLOCK(); if (subnetsarelocal) { TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) - if ((i & ia->ia_netmask) == ia->ia_net) + if ((i & ia->ia_netmask) == ia->ia_net) { + INADDR_RUNLOCK(); return (1); + } } else { TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) - if ((i & ia->ia_subnetmask) == ia->ia_subnet) + if ((i & ia->ia_subnetmask) == ia->ia_subnet) { + INADDR_RUNLOCK(); return (1); } + } + INADDR_RUNLOCK(); return (0); } @@ -107,11 +115,15 @@ { struct in_ifaddr *ia; + INADDR_HASH_RLOCK(); LIST_FOREACH(ia, INADDR_HASH(in.s_addr), ia_hash) { - if (IA_SIN(ia)->sin_addr.s_addr == in.s_addr) - return 1; + if (IA_SIN(ia)->sin_addr.s_addr == in.s_addr) { + INADDR_HASH_RUNLOCK(); + return (1); } - return 0; + } + INADDR_HASH_RUNLOCK(); + return (0); } /* @@ -247,12 +259,14 @@ */ if (ifp) { dst = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; + INADDR_HASH_RLOCK(); LIST_FOREACH(iap, INADDR_HASH(dst.s_addr), ia_hash) if (iap->ia_ifp == ifp && iap->ia_addr.sin_addr.s_addr == dst.s_addr) { ia = iap; break; } + INADDR_HASH_RUNLOCK(); if (ia == NULL) TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { iap = ifatoia(ifa); @@ -272,17 +286,19 @@ if (ifp == 0) return (EADDRNOTAVAIL); if (ifra->ifra_addr.sin_family == AF_INET) { + INADDR_RLOCK(); for (oia = ia; ia; ia = TAILQ_NEXT(ia, ia_link)) { if (ia->ia_ifp == ifp && ia->ia_addr.sin_addr.s_addr == ifra->ifra_addr.sin_addr.s_addr) break; } + INADDR_RUNLOCK(); if ((ifp->if_flags & IFF_POINTOPOINT) && (cmd == SIOCAIFADDR) && (ifra->ifra_dstaddr.sin_addr.s_addr == INADDR_ANY)) { - return EDESTADDRREQ; + return (EDESTADDRREQ); } } if (cmd == SIOCDIFADDR && ia == 0) @@ -302,8 +318,6 @@ if (ia == (struct in_ifaddr *)0) { ia = (struct in_ifaddr *) malloc(sizeof *ia, M_IFADDR, M_WAITOK | M_ZERO); - if (ia == (struct in_ifaddr *)NULL) - return (ENOBUFS); /* * Protect from ipintr() traversing address list * while we're modifying it. @@ -325,7 +339,9 @@ } ia->ia_ifp = ifp; + INADDR_WLOCK(); TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link); + INADDR_WUNLOCK(); splx(s); iaIsNew = 1; } @@ -489,9 +505,13 @@ */ s = splnet(); TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); + INADDR_WLOCK(); TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link); + INADDR_WUNLOCK(); if (ia->ia_addr.sin_family == AF_INET) { + INADDR_HASH_WLOCK(); LIST_REMOVE(ia, ia_hash); + INADDR_HASH_WUNLOCK(); /* * If this is the last IPv4 address configured on this * interface, leave the all-hosts group. @@ -709,12 +729,14 @@ int s = splimp(), flags = RTF_UP, error = 0; oldaddr = ia->ia_addr; + INADDR_HASH_WLOCK(); if (oldaddr.sin_family == AF_INET) LIST_REMOVE(ia, ia_hash); ia->ia_addr = *sin; if (ia->ia_addr.sin_family == AF_INET) LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash); + INADDR_HASH_WUNLOCK(); /* * Give the interface a chance to initialize * if this is its first address, @@ -728,9 +750,11 @@ splx(s); /* LIST_REMOVE(ia, ia_hash) is done in in_control */ ia->ia_addr = oldaddr; + INADDR_HASH_WLOCK(); if (ia->ia_addr.sin_family == AF_INET) LIST_INSERT_HEAD(INADDR_HASH( ia->ia_addr.sin_addr.s_addr), ia, ia_hash); + INADDR_HASH_WUNLOCK(); return (error); } } @@ -811,6 +835,7 @@ prefix.s_addr &= mask.s_addr; } + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { p = ia->ia_addr.sin_addr; @@ -834,12 +859,16 @@ if (ia->ia_flags & IFA_ROUTE) { if (sameprefixcarponly && target->ia_ifp->if_type != IFT_CARP && - ia->ia_ifp->if_type != IFT_CARP) + ia->ia_ifp->if_type != IFT_CARP) { + INADDR_RUNLOCK(); return (EEXIST); - else + } else { + INADDR_RUNLOCK(); return (0); } } + } + INADDR_RUNLOCK(); /* * No-one seem to have this prefix route, so we try to insert it. @@ -847,7 +876,7 @@ error = rtinit(&target->ia_ifa, (int)RTM_ADD, flags); if (!error) target->ia_flags |= IFA_ROUTE; - return error; + return (error); } /* @@ -873,6 +902,7 @@ prefix.s_addr &= mask.s_addr; } + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { if (rtinitflags(ia)) p = ia->ia_dstaddr.sin_addr; @@ -904,16 +934,18 @@ rtinitflags(ia) | RTF_UP); if (error == 0) ia->ia_flags |= IFA_ROUTE; - return error; + INADDR_RUNLOCK(); + return (error); } } + INADDR_RUNLOCK(); /* * As no-one seem to have this prefix, we can remove the route. */ rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target)); target->ia_flags &= ~IFA_ROUTE; - return 0; + return (0); } #undef rtinitflags --- src/sys/netinet/raw_ip.c.orig Thu Jun 14 22:18:25 2007 +++ src/sys/netinet/raw_ip.c Thu Jun 14 15:33:59 2007 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -551,6 +552,7 @@ switch (cmd) { case PRC_IFDOWN: + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { if (ia->ia_ifa.ifa_addr == sa && (ia->ia_flags & IFA_ROUTE)) { @@ -568,13 +570,16 @@ break; } } + INADDR_RUNLOCK(); break; case PRC_IFUP: + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) { if (ia->ia_ifa.ifa_addr == sa) break; } + INADDR_RUNLOCK(); if (ia == 0 || (ia->ia_flags & IFA_ROUTE)) return; flags = RTF_UP; --- src/sys/netinet/in_var.h.orig Thu Jun 14 22:18:24 2007 +++ src/sys/netinet/in_var.h Thu Jun 14 15:11:53 2007 @@ -85,7 +85,11 @@ * Hash table for IP addresses. */ extern LIST_HEAD(in_ifaddrhashhead, in_ifaddr) *in_ifaddrhashtbl; +extern struct rwlock in_ifaddrhashlock; + extern TAILQ_HEAD(in_ifaddrhead, in_ifaddr) in_ifaddrhead; +extern struct rwlock in_ifaddrlock; + extern u_long in_ifaddrhmask; /* mask for hash table */ #define INADDR_NHASH_LOG2 9 @@ -94,6 +98,15 @@ #define INADDR_HASH(x) \ (&in_ifaddrhashtbl[INADDR_HASHVAL(x) & in_ifaddrhmask]) +#define INADDR_HASH_RLOCK() rw_rlock(&in_ifaddrhashlock) +#define INADDR_HASH_RUNLOCK() rw_runlock(&in_ifaddrhashlock) +#define INADDR_HASH_WLOCK() rw_wlock(&in_ifaddrhashlock) +#define INADDR_HASH_WUNLOCK() rw_wunlock(&in_ifaddrhashlock) + +#define INADDR_RLOCK() rw_rlock(&in_ifaddrlock) +#define INADDR_RUNLOCK() rw_runlock(&in_ifaddrlock) +#define INADDR_WLOCK() rw_wlock(&in_ifaddrlock) +#define INADDR_WUNLOCK() rw_wunlock(&in_ifaddrlock) /* * Macro for finding the internet address structure (in_ifaddr) * corresponding to one of our IP addresses (in_addr). --- src/sys/netinet/in_mcast.c.orig Tue Jun 12 20:24:53 2007 +++ src/sys/netinet/in_mcast.c Thu Jun 14 16:09:55 2007 @@ -40,6 +40,8 @@ __FBSDID("$FreeBSD: src/sys/netinet/in_mcast.c,v 1.1 2007/06/12 16:24:53 bms Exp $"); #include +#include +#include #include #include #include @@ -498,8 +500,11 @@ ssa->sin.sin_len = sizeof(struct sockaddr_in); ssa->sin.sin_addr = mreqs.imr_sourceaddr; - if (mreqs.imr_interface.s_addr != INADDR_ANY) + if (mreqs.imr_interface.s_addr != INADDR_ANY) { + INADDR_HASH_RLOCK(); INADDR_TO_IFP(mreqs.imr_interface, ifp); + INADDR_HASH_RUNLOCK(); + } if (sopt->sopt_name == IP_BLOCK_SOURCE) block = 1; @@ -876,7 +881,9 @@ mreqn.imr_address = imo->imo_multicast_addr; } else if (ifp != NULL) { mreqn.imr_ifindex = ifp->if_index; + INADDR_RLOCK(); IFP_TO_IA(ifp, ia); + INADDR_RUNLOCK(); if (ia != NULL) { mreqn.imr_address = IA_SIN(ia)->sin_addr; @@ -1000,7 +1007,9 @@ * address (usually this is the default route). */ if (mreqs.imr_interface.s_addr != INADDR_ANY) { + INADDR_HASH_RLOCK(); INADDR_TO_IFP(mreqs.imr_interface, ifp); + INADDR_HASH_RUNLOCK(); } else { struct route ro; @@ -1235,8 +1244,11 @@ ssa->sin.sin_addr = mreqs.imr_sourceaddr; } - if (gsa->sin.sin_addr.s_addr != INADDR_ANY) + if (gsa->sin.sin_addr.s_addr != INADDR_ANY) { + INADDR_HASH_RLOCK(); INADDR_TO_IFP(mreqs.imr_interface, ifp); + INADDR_HASH_RUNLOCK(); + } #ifdef DIAGNOSTIC if (bootverbose) { @@ -1409,7 +1421,9 @@ if (addr.s_addr == INADDR_ANY) { ifp = NULL; } else { + INADDR_HASH_RLOCK(); INADDR_TO_IFP(addr, ifp); + INADDR_HASH_RUNLOCK(); if (ifp == NULL) return (EADDRNOTAVAIL); } --- src/sys/netinet/in_pcb.c.orig Thu Jun 14 22:18:24 2007 +++ src/sys/netinet/in_pcb.c Thu Jun 14 16:08:18 2007 @@ -38,6 +38,8 @@ #include "opt_mac.h" #include +#include +#include #include #include #include @@ -599,6 +601,7 @@ if (error) return (error); } + INADDR_RLOCK(); if (!TAILQ_EMPTY(&in_ifaddrhead)) { /* * If the destination address is INADDR_ANY, @@ -615,6 +618,7 @@ faddr = satosin(&TAILQ_FIRST( &in_ifaddrhead)->ia_broadaddr)->sin_addr; } + INADDR_RUNLOCK(); if (laddr.s_addr == INADDR_ANY) { ia = (struct in_ifaddr *)0; /* @@ -658,9 +662,11 @@ imo = inp->inp_moptions; if (imo->imo_multicast_ifp != NULL) { ifp = imo->imo_multicast_ifp; + INADDR_RLOCK(); TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) if (ia->ia_ifp == ifp) break; + INADDR_RUNLOCK(); if (ia == 0) return (EADDRNOTAVAIL); } --- src/sys/netipsec/key.c.orig Thu Jun 14 14:56:38 2007 +++ src/sys/netipsec/key.c Thu Jun 14 15:11:53 2007 @@ -3701,16 +3701,16 @@ #ifdef INET case AF_INET: sin = (struct sockaddr_in *)sa; - for (ia = in_ifaddrhead.tqh_first; ia; - ia = ia->ia_link.tqe_next) - { + INADDR_RLOCK(); + TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) if (sin->sin_family == ia->ia_addr.sin_family && sin->sin_len == ia->ia_addr.sin_len && sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr) { - return 1; - } + INADDR_RUNLOCK(); + return (1); } + INADDR_RUNLOCK(); break; #endif #ifdef INET6 --- src/sys/netkey/key.c.orig Sat Aug 5 01:27:40 2006 +++ src/sys/netkey/key.c Thu Jun 14 15:11:53 2007 @@ -3932,16 +3932,16 @@ #ifdef INET case AF_INET: sin = (struct sockaddr_in *)sa; - for (ia = in_ifaddrhead.tqh_first; ia; - ia = ia->ia_link.tqe_next) - { + INADDR_RLOCK(); + TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) if (sin->sin_family == ia->ia_addr.sin_family && sin->sin_len == ia->ia_addr.sin_len && sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr) { - return 1; - } + INADDR_RUNLOCK(); + return (1); } + INADDR_RUNLOCK(); break; #endif #ifdef INET6 --- src/sys/nfsclient/nfs_vnops.c.orig Thu Jun 14 22:05:54 2007 +++ src/sys/nfsclient/nfs_vnops.c Thu Jun 14 16:27:24 2007 @@ -42,6 +42,8 @@ #include "opt_inet.h" #include +#include +#include #include #include #include @@ -1389,11 +1391,15 @@ *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); tl = nfsm_build(u_int32_t *, NFSX_V3CREATEVERF); #ifdef INET - if (!TAILQ_EMPTY(&in_ifaddrhead)) + INADDR_RLOCK(); + if (!TAILQ_EMPTY(&in_ifaddrhead)) { *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr.s_addr; - else + } else #endif *tl++ = create_verf; +#ifdef INET + INADDR_RUNLOCK(); +#endif *tl = ++create_verf; } else { *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED);