diff options
author | hsu <hsu@FreeBSD.org> | 2002-12-22 05:35:03 +0000 |
---|---|---|
committer | hsu <hsu@FreeBSD.org> | 2002-12-22 05:35:03 +0000 |
commit | 82e1e3bab0d3abe1018a0b56559c154485f2f676 (patch) | |
tree | d0f9ee7e6f9d8014e6f8f94ab6965e85c268792e /sys | |
parent | 2afef11c570b7b725c3145fc710f8dcd8d7ed4e0 (diff) | |
download | FreeBSD-src-82e1e3bab0d3abe1018a0b56559c154485f2f676.zip FreeBSD-src-82e1e3bab0d3abe1018a0b56559c154485f2f676.tar.gz |
SMP locking for ifnet list.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/compat/linprocfs/linprocfs.c | 2 | ||||
-rw-r--r-- | sys/compat/linux/linux_ioctl.c | 14 | ||||
-rw-r--r-- | sys/compat/svr4/svr4_sockio.c | 5 | ||||
-rw-r--r-- | sys/contrib/ipfilter/netinet/fil.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_uuid.c | 6 | ||||
-rw-r--r-- | sys/net/bridge.c | 32 | ||||
-rw-r--r-- | sys/net/if.c | 20 | ||||
-rw-r--r-- | sys/net/if_ef.c | 5 | ||||
-rw-r--r-- | sys/net/if_var.h | 7 | ||||
-rw-r--r-- | sys/net/rtsock.c | 7 | ||||
-rw-r--r-- | sys/netatm/atm_if.c | 2 | ||||
-rw-r--r-- | sys/netatm/atm_usrreq.c | 3 | ||||
-rw-r--r-- | sys/netgraph/ng_ether.c | 2 | ||||
-rw-r--r-- | sys/netgraph/ng_gif.c | 2 | ||||
-rw-r--r-- | sys/netgraph/ng_source.c | 2 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 10 | ||||
-rw-r--r-- | sys/netinet6/in6.c | 4 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 7 | ||||
-rw-r--r-- | sys/netipsec/xform_ipip.c | 4 | ||||
-rw-r--r-- | sys/nfsclient/bootp_subr.c | 4 | ||||
-rw-r--r-- | sys/nfsclient/nfs_diskless.c | 6 |
21 files changed, 126 insertions, 24 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index aca3f06..1ccd25a 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -725,6 +725,7 @@ linprocfs_donetdev(PFS_FILL_ARGS) "bytes packets errs drop fifo frame compressed", "bytes packets errs drop fifo frame compressed"); + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { linux_ifname(ifp, ifname, sizeof ifname); sbuf_printf(sb, "%6.6s:", ifname); @@ -733,6 +734,7 @@ linprocfs_donetdev(PFS_FILL_ARGS) sbuf_printf(sb, "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n", 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL); } + IFNET_RUNLOCK(); return (0); } diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 9714433..186b84c 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -1907,12 +1907,16 @@ linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen) /* Determine the (relative) unit number for ethernet interfaces */ ethno = 0; + IFNET_RLOCK(); TAILQ_FOREACH(ifscan, &ifnet, if_link) { - if (ifscan == ifp) + if (ifscan == ifp) { + IFNET_RUNLOCK(); return (snprintf(buffer, buflen, "eth%d", ethno)); + } if (IFP_IS_ETH(ifscan)) ethno++; } + IFNET_RUNLOCK(); return (0); } @@ -1942,6 +1946,7 @@ ifname_linux_to_bsd(const char *lxname, char *bsdname) return (NULL); index = 0; is_eth = (len == 3 && !strncmp(lxname, "eth", len)) ? 1 : 0; + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { /* * Allow Linux programs to use FreeBSD names. Don't presume @@ -1954,6 +1959,7 @@ ifname_linux_to_bsd(const char *lxname, char *bsdname) if (is_eth && IFP_IS_ETH(ifp) && unit == index++) break; } + IFNET_RUNLOCK(); if (ifp != NULL) snprintf(bsdname, IFNAMSIZ, "%s%d", ifp->if_name, ifp->if_unit); return (ifp); @@ -1993,6 +1999,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) ethno = 0; /* Return all AF_INET addresses of all interfaces */ + IFNET_RLOCK(); /* could sleep XXX */ TAILQ_FOREACH(ifp, &ifnet, if_link) { if (uio.uio_resid <= 0) break; @@ -2019,11 +2026,14 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) error = uiomove((caddr_t)&ifr, sizeof ifr, &uio); - if (error != 0) + if (error != 0) { + IFNET_RUNLOCK(); return (error); + } } } } + IFNET_RUNLOCK(); ifc.ifc_len -= uio.uio_resid; error = copyout(&ifc, uifc, sizeof ifc); diff --git a/sys/compat/svr4/svr4_sockio.c b/sys/compat/svr4/svr4_sockio.c index 8dc65a8..8ecd1d4 100644 --- a/sys/compat/svr4/svr4_sockio.c +++ b/sys/compat/svr4/svr4_sockio.c @@ -100,7 +100,7 @@ svr4_sock_ioctl(fp, td, retval, fd, cmd, data) * fix is to make SVR4_SIOCGIFCONF return only one * entry per physical interface? */ - + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) if (TAILQ_FIRST(&ifp->if_addrhead) == NULL) ifnum++; @@ -108,8 +108,7 @@ svr4_sock_ioctl(fp, td, retval, fd, cmd, data) TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) ifnum++; - - + IFNET_RUNLOCK(); DPRINTF(("SIOCGIFNUM %d\n", ifnum)); return copyout(&ifnum, data, sizeof(ifnum)); } diff --git a/sys/contrib/ipfilter/netinet/fil.c b/sys/contrib/ipfilter/netinet/fil.c index 1f8f435..434e9e6 100644 --- a/sys/contrib/ipfilter/netinet/fil.c +++ b/sys/contrib/ipfilter/netinet/fil.c @@ -1963,6 +1963,9 @@ void frsync() (defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)) # if (NetBSD >= 199905) || defined(__OpenBSD__) for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) +# elif defined(__FreeBSD_version) && (__FreeBSD_version >= 500043) + IFNET_RLOCK(); + TAILQ_FOREACH(ifp, &ifnet, if_link) # else for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) # endif @@ -1973,6 +1976,9 @@ void frsync() ip_natsync(ifp); ip_statesync(ifp); } +# if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043) + IFNET_RUNLOCK(); +# endif ip_natsync((struct ifnet *)-1); # endif /* !SOLARIS */ diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c index 5d0cb74..d28cb36 100644 --- a/sys/kern/kern_uuid.c +++ b/sys/kern/kern_uuid.c @@ -91,7 +91,7 @@ uuid_node(uint16_t *node) struct sockaddr_dl *sdl; int i; - /* XXX: lock ifnet. */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { /* Walk the address list */ TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -100,12 +100,12 @@ uuid_node(uint16_t *node) sdl->sdl_type == IFT_ETHER) { /* Got a MAC address. */ bcopy(LLADDR(sdl), node, UUID_NODE_LEN); - /* XXX: unlock ifnet. */ + IFNET_RUNLOCK(); return; } } } - /* XXX: unlock ifnet. */ + IFNET_RUNLOCK(); for (i = 0; i < (UUID_NODE_LEN>>1); i++) node[i] = (uint16_t)arc4random(); diff --git a/sys/net/bridge.c b/sys/net/bridge.c index 295c208..13c36cd 100644 --- a/sys/net/bridge.c +++ b/sys/net/bridge.c @@ -302,6 +302,7 @@ bridge_off(void) int i, s; DEB(printf("bridge_off: n_clusters %d\n", n_clusters);) + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { struct bdg_softc *b; @@ -322,6 +323,7 @@ bridge_off(void) b->cluster = NULL; bdg_stats.s[ifp->if_index].name[0] = '\0'; } + IFNET_RUNLOCK(); /* flush_tables */ s = splimp(); @@ -345,6 +347,7 @@ bridge_on(void) struct ifnet *ifp ; int s ; + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { struct bdg_softc *b = &ifp2sc[ifp->if_index]; @@ -370,6 +373,7 @@ bridge_on(void) b->flags &= ~IFF_MUTE; } } + IFNET_RUNLOCK(); } /** @@ -435,6 +439,7 @@ parse_bdg_cfg() /* * now search in interface list for a matching name */ + IFNET_RLOCK(); /* could sleep XXX */ TAILQ_FOREACH(ifp, &ifnet, if_link) { char buf[IFNAMSIZ]; @@ -460,6 +465,7 @@ parse_bdg_cfg() break ; } } + IFNET_RUNLOCK(); if (!found) printf("interface %s Not found in bridge\n", beg); *p = c; @@ -847,17 +853,10 @@ bdg_forward(struct mbuf *m0, struct ifnet *dst) printf("xx ouch, bdg_forward for local pkt\n"); return m0; } - if (dst == BDG_BCAST || dst == BDG_MCAST || dst == BDG_UNKNOWN) { - ifp = TAILQ_FIRST(&ifnet) ; /* scan all ports */ - once = 0 ; - if (dst != BDG_UNKNOWN) /* need a copy for the local stack */ - shared = 1 ; - } else { - ifp = dst ; - once = 1 ; + if (dst == BDG_BCAST || dst == BDG_MCAST) { + /* need a copy for the local stack */ + shared = 1 ; } - if ((uintptr_t)(ifp) <= (u_int)BDG_FORWARD) - panic("bdg_forward: bad dst"); /* * Do filtering in a very similar way to what is done in ip_output. @@ -1023,6 +1022,17 @@ forward: real_dst = src ; last = NULL; + IFNET_RLOCK(); + if (dst == BDG_BCAST || dst == BDG_MCAST || dst == BDG_UNKNOWN) { + ifp = TAILQ_FIRST(&ifnet) ; /* scan all ports */ + once = 0 ; + } else { + ifp = dst ; + once = 1 ; + } + if ((uintptr_t)(ifp) <= (u_int)BDG_FORWARD) + panic("bdg_forward: bad dst"); + for (;;) { if (last) { /* need to forward packet leftover from previous loop */ struct mbuf *m ; @@ -1032,6 +1042,7 @@ forward: } else { m = m_copypacket(m0, M_DONTWAIT); if (m == NULL) { + IFNET_RUNLOCK(); printf("bdg_forward: sorry, m_copypacket failed!\n"); bdg_dropped++ ; return m0 ; /* the original is still there... */ @@ -1062,6 +1073,7 @@ forward: if (ifp == NULL) once = 1 ; } + IFNET_RUNLOCK(); DEB(bdg_fw_ticks += (u_long)(rdtsc() - ticks) ; bdg_fw_count++ ; if (bdg_fw_count != 0) bdg_fw_avg = bdg_fw_ticks/bdg_fw_count; ) return m0 ; diff --git a/sys/net/if.c b/sys/net/if.c index 10c6c10..42f2590 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -102,6 +102,7 @@ int if_index = 0; struct ifindex_entry *ifindex_table = NULL; int ifqmaxlen = IFQ_MAXLEN; struct ifnethead ifnet; /* depend on static init XXX */ +struct mtx ifnet_lock; int if_cloners_count; LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); @@ -263,6 +264,7 @@ if_init(dummy) void *dummy; { + IFNET_LOCK_INIT(); TAILQ_INIT(&ifnet); SLIST_INIT(&ifklist); if_grow(); /* create initial table */ @@ -295,6 +297,7 @@ if_check(dummy) int s; s = splimp(); + IFNET_RLOCK(); /* could sleep on rare error; mostly okay XXX */ TAILQ_FOREACH(ifp, &ifnet, if_link) { if (ifp->if_snd.ifq_maxlen == 0) { printf("%s%d XXX: driver didn't set ifq_maxlen\n", @@ -308,6 +311,7 @@ if_check(dummy) MTX_NETWORK_LOCK, MTX_DEF); } } + IFNET_RUNLOCK(); splx(s); if_slowtimo(0); } @@ -376,7 +380,9 @@ if_attach(ifp) register struct sockaddr_dl *sdl; register struct ifaddr *ifa; + IFNET_WLOCK(); TAILQ_INSERT_TAIL(&ifnet, ifp, if_link); + IFNET_WUNLOCK(); /* * XXX - * The old code would work if the interface passed a pre-existing @@ -537,7 +543,9 @@ if_detach(ifp) mac_destroy_ifnet(ifp); #endif /* MAC */ KNOTE(&ifp->if_klist, NOTE_EXIT); + IFNET_WLOCK(); TAILQ_REMOVE(&ifnet, ifp, if_link); + IFNET_WUNLOCK(); mtx_destroy(&ifp->if_snd.ifq_mtx); splx(s); } @@ -846,6 +854,7 @@ ifa_ifwithaddr(addr) struct ifnet *ifp; struct ifaddr *ifa; + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != addr->sa_family) @@ -861,6 +870,7 @@ ifa_ifwithaddr(addr) } ifa = NULL; done: + IFNET_RUNLOCK(); return (ifa); } @@ -875,6 +885,7 @@ ifa_ifwithdstaddr(addr) struct ifnet *ifp; struct ifaddr *ifa; + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if ((ifp->if_flags & IFF_POINTOPOINT) == 0) continue; @@ -887,6 +898,7 @@ ifa_ifwithdstaddr(addr) } ifa = NULL; done: + IFNET_RUNLOCK(); return (ifa); } @@ -918,6 +930,7 @@ ifa_ifwithnet(addr) * Scan though each interface, looking for ones that have * addresses in this address family. */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { register char *cp, *cp2, *cp3; @@ -980,6 +993,7 @@ next: continue; } ifa = ifa_maybe; done: + IFNET_RUNLOCK(); return (ifa); } @@ -1162,12 +1176,14 @@ if_slowtimo(arg) register struct ifnet *ifp; int s = splimp(); + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (ifp->if_timer == 0 || --ifp->if_timer) continue; if (ifp->if_watchdog) (*ifp->if_watchdog)(ifp); } + IFNET_RUNLOCK(); splx(s); timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); } @@ -1192,6 +1208,7 @@ ifunit(const char *name) * Devices should really be known as /dev/fooN, not /dev/net/fooN. */ snprintf(namebuf, IFNAMSIZ, "%s/%s", net_cdevsw.d_name, name); + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { dev = ifdev_byindex(ifp->if_index); if (strcmp(devtoname(dev), namebuf) == 0) @@ -1199,6 +1216,7 @@ ifunit(const char *name) if (dev_named(dev, name)) break; } + IFNET_RUNLOCK(); return (ifp); } @@ -1625,6 +1643,7 @@ ifconf(cmd, data) int space = ifc->ifc_len, error = 0; ifrp = ifc->ifc_req; + IFNET_RLOCK(); /* could sleep XXX */ TAILQ_FOREACH(ifp, &ifnet, if_link) { char workbuf[64]; int ifnlen, addrs; @@ -1695,6 +1714,7 @@ ifconf(cmd, data) ifrp++; } } + IFNET_RUNLOCK(); ifc->ifc_len -= space; return (error); } diff --git a/sys/net/if_ef.c b/sys/net/if_ef.c index d297faf..b064d38 100644 --- a/sys/net/if_ef.c +++ b/sys/net/if_ef.c @@ -163,8 +163,9 @@ ef_detach(struct efnet *sc) } } } - + IFNET_WLOCK(); TAILQ_REMOVE(&ifnet, ifp, if_link); + IFNET_WUNLOCK(); splx(s); return 0; } @@ -508,6 +509,7 @@ ef_load(void) struct ef_link *efl = NULL; int error = 0, d; + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (ifp->if_type != IFT_ETHER) continue; EFDEBUG("Found interface %s%d\n", ifp->if_name, ifp->if_unit); @@ -538,6 +540,7 @@ ef_load(void) efcount++; SLIST_INSERT_HEAD(&efdev, efl, el_next); } + IFNET_RUNLOCK(); if (error) { if (efl) SLIST_INSERT_HEAD(&efdev, efl, el_next); diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 3e3300e..fa4082b 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -410,6 +410,13 @@ struct ifmultiaddr { IFA_UNLOCK(ifa); \ } while (0) +extern struct mtx ifnet_lock; +#define IFNET_LOCK_INIT() mtx_init(&ifnet_lock, "ifnet", NULL, MTX_DEF) +#define IFNET_WLOCK() mtx_lock(&ifnet_lock) +#define IFNET_WUNLOCK() mtx_unlock(&ifnet_lock) +#define IFNET_RLOCK() IFNET_WLOCK() +#define IFNET_RUNLOCK() IFNET_WUNLOCK() + struct ifindex_entry { struct ifnet *ife_ifnet; struct ifaddr *ife_ifnet_addr; diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index d8ec489..40f2ee1 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -414,11 +414,12 @@ route_output(m, so) /* new gateway could require new ifaddr, ifp; flags may also be different; ifp may be specified by ll sockaddr when protocol address is ambiguous */ -#define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), (a1)->sa_len) == 0) +/* compare two sockaddr structures */ +#define sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0) if ((rt->rt_flags & RTF_GATEWAY && gate != NULL) || ifpaddr != NULL || (ifaaddr != NULL && - !equal(ifaaddr, rt->rt_ifa->ifa_addr))) { + !sa_equal(ifaaddr, rt->rt_ifa->ifa_addr))) { if ((error = rt_getifa(&info)) != 0) senderr(error); } @@ -946,6 +947,7 @@ sysctl_iflist(af, w) int len, error = 0; bzero((caddr_t)&info, sizeof(info)); + /* IFNET_RLOCK(); */ /* could sleep XXX */ TAILQ_FOREACH(ifp, &ifnet, if_link) { if (w->w_arg && w->w_arg != ifp->if_index) continue; @@ -991,6 +993,7 @@ sysctl_iflist(af, w) ifaaddr = netmask = brdaddr = 0; } done: + /* IFNET_RUNLOCK(); */ /* XXX */ return (error); } diff --git a/sys/netatm/atm_if.c b/sys/netatm/atm_if.c index 2065312..e5fdb6b 100644 --- a/sys/netatm/atm_if.c +++ b/sys/netatm/atm_if.c @@ -875,7 +875,9 @@ atm_nif_detach(nip) /* * Remove from system interface list (ie. if_detach()) */ + IFNET_WLOCK(); TAILQ_REMOVE(&ifnet, ifp, if_link); + IFNET_WUNLOCK(); /* * Remove from physical interface list diff --git a/sys/netatm/atm_usrreq.c b/sys/netatm/atm_usrreq.c index 4abc66b..e050b6c 100644 --- a/sys/netatm/atm_usrreq.c +++ b/sys/netatm/atm_usrreq.c @@ -394,6 +394,7 @@ atm_dgram_control(so, cmd, data, ifp, td) /* * Make sure prefix name is unique */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp2, &ifnet, if_link) { if (!strcmp(ifp2->if_name, asp->asr_nif_pref)) { /* @@ -407,9 +408,11 @@ atm_dgram_control(so, cmd, data, ifp, td) } if (nip) continue; + IFNET_RUNLOCK(); ATM_RETERR(EEXIST); } } + IFNET_RUNLOCK(); /* * Let interface handle it from here diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index da2012f..041999c 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -728,11 +728,13 @@ ng_ether_mod_event(module_t mod, int event, void *data) ng_ether_input_orphan_p = ng_ether_input_orphan; /* Create nodes for any already-existing Ethernet interfaces */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (ifp->if_type == IFT_ETHER || ifp->if_type == IFT_L2VLAN) ng_ether_attach(ifp); } + IFNET_RUNLOCK(); break; case MOD_UNLOAD: diff --git a/sys/netgraph/ng_gif.c b/sys/netgraph/ng_gif.c index c2c87eb..2d99959 100644 --- a/sys/netgraph/ng_gif.c +++ b/sys/netgraph/ng_gif.c @@ -564,10 +564,12 @@ ng_gif_mod_event(module_t mod, int event, void *data) ng_gif_input_orphan_p = ng_gif_input_orphan; /* Create nodes for any already-existing gif interfaces */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (ifp->if_type == IFT_GIF) ng_gif_attach(ifp); } + IFNET_RUNLOCK(); break; case MOD_UNLOAD: diff --git a/sys/netgraph/ng_source.c b/sys/netgraph/ng_source.c index b2e976c..78525e8 100644 --- a/sys/netgraph/ng_source.c +++ b/sys/netgraph/ng_source.c @@ -481,10 +481,12 @@ ng_source_store_output_ifp(sc_p sc, struct ng_mesg *msg) * way of verifying if_index is valid since if_indexlim is * local to if_attach() */ + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (ifp->if_index == if_index) break; } + IFNET_RUNLOCK(); if (ifp == NULL) { printf("%s: can't find interface %d\n", __FUNCTION__, if_index); diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index edb41f7..9e3015d 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1672,6 +1672,7 @@ ni6_addrs(ni6, m, ifpp, subj) } } + IFNET_RLOCK(); for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { addrsofif = 0; @@ -1729,11 +1730,13 @@ ni6_addrs(ni6, m, ifpp, subj) } if (iffound) { *ifpp = ifp; + IFNET_RUNLOCK(); return(addrsofif); } addrs += addrsofif; } + IFNET_RUNLOCK(); return(addrs); } @@ -1755,9 +1758,9 @@ ni6_store_addrs(ni6, nni6, ifp0, resid) if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL)) return(0); /* needless to copy */ - + + IFNET_RLOCK(); again: - for (; ifp; ifp = TAILQ_NEXT(ifp, if_list)) { for (ifa = ifp->if_addrlist.tqh_first; ifa; @@ -1823,6 +1826,7 @@ ni6_store_addrs(ni6, nni6, ifp0, resid) */ nni6->ni_flags |= NI_NODEADDR_FLAG_TRUNCATE; + IFNET_RUNLOCK(); return(copied); } @@ -1877,6 +1881,8 @@ ni6_store_addrs(ni6, nni6, ifp0, resid) goto again; } + IFNET_RUNLOCK(); + return(copied); } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index bb38bde..c450dea 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1973,6 +1973,7 @@ in6_ifawithscope(oifp, dst) * Comparing an interface with the outgoing interface will be done * only at the final stage of tiebreaking. */ + IFNET_RLOCK(); for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { /* @@ -2204,6 +2205,7 @@ in6_ifawithscope(oifp, dst) best_scope = in6_addrscope(&ifa_best->ia_addr.sin6_addr); } } + IFNET_RUNLOCK(); /* count statistics for future improvements */ if (ifa_best == NULL) @@ -2385,12 +2387,14 @@ in6_setmaxmtu() unsigned long maxmtu = 0; struct ifnet *ifp; + IFNET_RLOCK(); for (ifp = TAILQ_FIRST(&ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { if ((ifp->if_flags & IFF_LOOPBACK) == 0 && nd_ifinfo[ifp->if_index].linkmtu > maxmtu) maxmtu = nd_ifinfo[ifp->if_index].linkmtu; } + IFNET_RUNLOCK(); if (maxmtu) /* update only when maxmtu is positive */ in6_maxmtu = maxmtu; } diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 9150a36..5abcca1 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -381,6 +381,7 @@ get_ifid(ifp0, altifp, in6) } /* next, try to get it from some other hardware interface */ + IFNET_RLOCK(); for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) { if (ifp == ifp0) @@ -396,9 +397,11 @@ get_ifid(ifp0, altifp, in6) nd6log((LOG_DEBUG, "%s: borrow interface identifier from %s\n", if_name(ifp0), if_name(ifp))); + IFNET_RUNLOCK(); goto success; } } + IFNET_RUNLOCK(); /* last resort: get from random number source */ if (get_rand_ifid(ifp, in6) == 0) { @@ -688,6 +691,7 @@ in6_nigroup_attach(name, namelen) if (in6_nigroup(NULL, name, namelen, &mltaddr.sin6_addr) != 0) return; + IFNET_RLOCK(); for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) { mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); @@ -701,6 +705,7 @@ in6_nigroup_attach(name, namelen) } } } + IFNET_RUNLOCK(); } void @@ -718,6 +723,7 @@ in6_nigroup_detach(name, namelen) if (in6_nigroup(NULL, name, namelen, &mltaddr.sin6_addr) != 0) return; + IFNET_RLOCK(); for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next) { mltaddr.sin6_addr.s6_addr16[1] = htons(ifp->if_index); @@ -725,6 +731,7 @@ in6_nigroup_detach(name, namelen) if (in6m) in6_delmulti(in6m); } + IFNET_RUNLOCK(); } /* diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c index a9c0edb..9d49a3e 100644 --- a/sys/netipsec/xform_ipip.c +++ b/sys/netipsec/xform_ipip.c @@ -309,6 +309,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) if ((m->m_pkthdr.rcvif == NULL || !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) && ipip_allow != 2) { + IFNET_RLOCK(); for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) { for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; @@ -325,6 +326,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) ipo->ip_src.s_addr) { ipipstat.ipips_spoof++; m_freem(m); + IFNET_RUNLOCK(); return; } } @@ -341,6 +343,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) { ipipstat.ipips_spoof++; m_freem(m); + IFNET_RUNLOCK(); return; } @@ -348,6 +351,7 @@ _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp) #endif /* INET6 */ } } + IFNET_RUNLOCK(); } /* Statistics */ diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index a9c504f..50f3b1f 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -401,6 +401,7 @@ bootpboot_p_iflist(void) struct ifaddr *ifa; printf("Interface list:\n"); + IFNET_RLOCK(); /* could sleep, but okay for debugging XXX */ for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; ifp = TAILQ_NEXT(ifp, if_link)) { @@ -410,6 +411,7 @@ bootpboot_p_iflist(void) if (ifa->ifa_addr->sa_family == AF_INET) bootpboot_p_if(ifp, ifa); } + IFNET_RUNLOCK(); } #endif /* defined(BOOTP_DEBUG) */ @@ -1689,6 +1691,7 @@ bootpc_init(void) __XSTRING(BOOTP_WIRED_TO)); #endif bzero(&ifctx->ireq, sizeof(ifctx->ireq)); + IFNET_RLOCK(); for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; ifp = TAILQ_NEXT(ifp, if_link)) { @@ -1712,6 +1715,7 @@ bootpc_init(void) gctx->lastinterface = ifctx; ifctx = allocifctx(gctx); } + IFNET_RUNLOCK(); free(ifctx, M_TEMP); if (gctx->interfaces == NULL) { diff --git a/sys/nfsclient/nfs_diskless.c b/sys/nfsclient/nfs_diskless.c index 791c61e..c5f167e 100644 --- a/sys/nfsclient/nfs_diskless.c +++ b/sys/nfsclient/nfs_diskless.c @@ -102,6 +102,7 @@ nfs_setup_diskless(void) return; } ifa = NULL; + IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if ((ifa->ifa_addr->sa_family == AF_LINK) && @@ -110,11 +111,14 @@ nfs_setup_diskless(void) (sdl->sdl_alen == ourdl.sdl_alen) && !bcmp(sdl->sdl_data + sdl->sdl_nlen, ourdl.sdl_data + ourdl.sdl_nlen, - sdl->sdl_alen)) + sdl->sdl_alen)) { + IFNET_RUNLOCK(); goto match_done; + } } } } + IFNET_RUNLOCK(); printf("nfs_diskless: no interface\n"); return; /* no matching interface */ match_done: |