diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c index a980fba80a77..d0a248892e4f 100644 --- a/sys/dev/cxgbe/tom/t4_tom.c +++ b/sys/dev/cxgbe/tom/t4_tom.c @@ -36,9 +36,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include #include #include @@ -762,6 +764,7 @@ t4_clip_task(void *arg, int count) static void update_clip_table(struct adapter *sc, struct tom_data *td) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; struct in6_addr *lip, tlip; struct clip_head stale; @@ -770,7 +773,7 @@ update_clip_table(struct adapter *sc, struct tom_data *td) ASSERT_SYNCHRONIZED_OP(sc); - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); mtx_lock(&td->clip_table_lock); if (gen == td->clip_gen) @@ -862,7 +865,7 @@ update_clip_table(struct adapter *sc, struct tom_data *td) td->clip_gen = gen; done: mtx_unlock(&td->clip_table_lock); - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); } static void diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 6743981c9009..841a0f20741e 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -28,7 +28,9 @@ #include #include +#include #include +#include #include #include #include diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index aed2a37379d6..23905783d0db 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -84,10 +84,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -530,6 +532,7 @@ stf_checkaddr4(sc, in, inifp) struct in_addr *in; struct ifnet *inifp; /* incoming interface */ { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia4; /* @@ -553,16 +556,16 @@ stf_checkaddr4(sc, in, inifp) /* * reject packets with broadcast */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia4, &V_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) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return -1; } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * perform ingress filter diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index aa370d6f904d..1012e93c2863 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -42,12 +42,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -563,6 +565,7 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_log_per_second, static void in_arpinput(struct mbuf *m) { + struct rm_priotracker in_ifa_tracker; struct arphdr *ah; struct ifnet *ifp = m->m_pkthdr.rcvif; struct llentry *la = NULL; @@ -621,7 +624,7 @@ in_arpinput(struct mbuf *m) * of the receive interface. (This will change slightly * when we have clusters of interfaces). */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) { if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) || ia->ia_ifp == ifp) && @@ -629,7 +632,7 @@ in_arpinput(struct mbuf *m) (ia->ia_ifa.ifa_carp == NULL || (*carp_iamatch_p)(&ia->ia_ifa, &enaddr))) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } @@ -638,7 +641,7 @@ in_arpinput(struct mbuf *m) ia->ia_ifp == ifp) && isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } @@ -657,13 +660,13 @@ in_arpinput(struct mbuf *m) if (BDG_MEMBER_MATCHES_ARP(itaddr.s_addr, ifp, ia)) { ifa_ref(&ia->ia_ifa); ifp = ia->ia_ifp; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } } #undef BDG_MEMBER_MATCHES_ARP - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * No match, use the first inet address on the receive interface @@ -684,13 +687,13 @@ in_arpinput(struct mbuf *m) /* * If bridging, fall back to using any inet address. */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); if (!bridged || (ia = TAILQ_FIRST(&V_in_ifaddrhead)) == NULL) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto drop; } ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); match: if (!enaddr) enaddr = (u_int8_t *)IF_LLADDR(ifp); diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index a094a499f7bf..185f5c2b5a04 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -58,6 +58,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include #include @@ -1215,6 +1217,7 @@ static int igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip, /*const*/ struct igmp *igmp) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_multi *inm; @@ -1237,7 +1240,7 @@ igmp_input_v1_report(struct ifnet *ifp, /*const*/ struct ip *ip, * Replace 0.0.0.0 with the subnet address if told to do so. */ if (V_igmp_recvifkludge && in_nullhost(ip->ip_src)) { - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL) { ip->ip_src.s_addr = htonl(ia->ia_subnet); ifa_free(&ia->ia_ifa); @@ -1323,6 +1326,7 @@ static int igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip, /*const*/ struct igmp *igmp) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_multi *inm; @@ -1331,7 +1335,7 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip, * leave requires knowing that we are the only member of a * group. */ - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL && in_hosteq(ip->ip_src, IA_SIN(ia)->sin_addr)) { ifa_free(&ia->ia_ifa); return (0); @@ -3487,6 +3491,7 @@ igmp_intr(struct mbuf *m) static struct mbuf * igmp_v3_encap_report(struct ifnet *ifp, struct mbuf *m) { + struct rm_priotracker in_ifa_tracker; struct igmp_report *igmp; struct ip *ip; int hdrlen, igmpreclen; @@ -3535,7 +3540,7 @@ igmp_v3_encap_report(struct ifnet *ifp, struct mbuf *m) if (m->m_flags & M_IGMP_LOOP) { struct in_ifaddr *ia; - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL) { ip->ip_src = ia->ia_addr.sin_addr; ifa_free(&ia->ia_ifa); diff --git a/sys/netinet/in.c b/sys/netinet/in.c index f47492ddaf1a..c2c7ce089c22 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -44,7 +44,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include #include @@ -93,17 +95,18 @@ SX_SYSINIT(in_control_sx, &in_control_sx, "in_control"); int in_localaddr(struct in_addr in) { + struct rm_priotracker in_ifa_tracker; register u_long i = ntohl(in.s_addr); register struct in_ifaddr *ia; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if ((i & ia->ia_subnetmask) == ia->ia_subnet) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (1); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (0); } @@ -114,16 +117,17 @@ in_localaddr(struct in_addr in) int in_localip(struct in_addr in) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(ia, INADDR_HASH(in.s_addr), ia_hash) { if (IA_SIN(ia)->sin_addr.s_addr == in.s_addr) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (1); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (0); } @@ -158,18 +162,19 @@ in_ifhasaddr(struct ifnet *ifp, struct in_addr in) static struct in_ifaddr * in_localip_more(struct in_ifaddr *ia) { + struct rm_priotracker in_ifa_tracker; in_addr_t in = IA_SIN(ia)->sin_addr.s_addr; struct in_ifaddr *it; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(it, INADDR_HASH(in), ia_hash) { if (it != ia && IA_SIN(it)->sin_addr.s_addr == in) { ifa_ref(&it->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (it); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (NULL); } @@ -646,6 +651,7 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td) int in_addprefix(struct in_ifaddr *target, int flags) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; int error; @@ -659,7 +665,7 @@ in_addprefix(struct in_ifaddr *target, int flags) prefix.s_addr &= mask.s_addr; } - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); /* Look for an existing address with the same prefix, mask, and fib */ TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { @@ -687,13 +693,13 @@ in_addprefix(struct in_ifaddr *target, int flags) #ifdef RADIX_MPATH if (ia->ia_addr.sin_addr.s_addr == target->ia_addr.sin_addr.s_addr) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (EEXIST); } else break; #endif if (V_nosameprefix) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (EEXIST); } else { int fibnum; @@ -701,12 +707,12 @@ in_addprefix(struct in_ifaddr *target, int flags) fibnum = V_rt_add_addr_allfibs ? RT_ALL_FIBS : target->ia_ifp->if_fib; rt_addrmsg(RTM_ADD, &target->ia_ifa, fibnum); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return (0); } } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * No-one seem to have this prefix route, so we try to insert it. @@ -725,6 +731,7 @@ in_addprefix(struct in_ifaddr *target, int flags) int in_scrubprefix(struct in_ifaddr *target, u_int flags) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct in_addr prefix, mask, p, m; int error = 0; @@ -775,7 +782,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) return (0); } - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (rtinitflags(ia)) { p = ia->ia_dstaddr.sin_addr; @@ -802,7 +809,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) */ if ((ia->ia_flags & IFA_ROUTE) == 0) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); error = rtinit(&(target->ia_ifa), (int)RTM_DELETE, rtinitflags(target)); if (error == 0) @@ -821,7 +828,7 @@ in_scrubprefix(struct in_ifaddr *target, u_int flags) return (error); } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * remove all L2 entries on the given prefix diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c index 93557f8f335b..c168780c7283 100644 --- a/sys/netinet/in_mcast.c +++ b/sys/netinet/in_mcast.c @@ -38,9 +38,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include #include #include @@ -1748,6 +1750,7 @@ inp_get_source_filters(struct inpcb *inp, struct sockopt *sopt) int inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) { + struct rm_priotracker in_ifa_tracker; struct ip_mreqn mreqn; struct ip_moptions *imo; struct ifnet *ifp; @@ -1787,7 +1790,7 @@ inp_getmoptions(struct inpcb *inp, struct sockopt *sopt) mreqn.imr_address = imo->imo_multicast_addr; } else if (ifp != NULL) { mreqn.imr_ifindex = ifp->if_index; - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia != NULL) { mreqn.imr_address = IA_SIN(ia)->sin_addr; @@ -1878,6 +1881,7 @@ static struct ifnet * inp_lookup_mcast_ifp(const struct inpcb *inp, const struct sockaddr_in *gsin, const struct in_addr ina) { + struct rm_priotracker in_ifa_tracker; struct ifnet *ifp; KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__)); @@ -1902,7 +1906,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, struct ifnet *mifp; mifp = NULL; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { mifp = ia->ia_ifp; if (!(mifp->if_flags & IFF_LOOPBACK) && @@ -1911,7 +1915,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp, break; } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index bc48e105f69b..965932486db3 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -47,11 +47,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -992,6 +994,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, u_short *lportp, in_addr_t *faddrp, u_short *fportp, struct inpcb **oinpp, struct ucred *cred) { + struct rm_priotracker in_ifa_tracker; struct sockaddr_in *sin = (struct sockaddr_in *)nam; struct in_ifaddr *ia; struct inpcb *oinp; @@ -1028,20 +1031,20 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, * choose the broadcast address for that interface. */ if (faddr.s_addr == INADDR_ANY) { - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); faddr = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); if (cred != NULL && (error = prison_get_ip4(cred, &faddr)) != 0) return (error); } else if (faddr.s_addr == (u_long)INADDR_BROADCAST) { - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); if (TAILQ_FIRST(&V_in_ifaddrhead)->ia_ifp->if_flags & IFF_BROADCAST) faddr = satosin(&TAILQ_FIRST( &V_in_ifaddrhead)->ia_broadaddr)->sin_addr; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } if (laddr.s_addr == INADDR_ANY) { @@ -1059,7 +1062,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, imo = inp->inp_moptions; if (imo->imo_multicast_ifp != NULL) { ifp = imo->imo_multicast_ifp; - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if ((ia->ia_ifp == ifp) && (cred == NULL || @@ -1073,7 +1076,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam, laddr = ia->ia_addr.sin_addr; error = 0; } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); } } if (error) diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 0318fb2ff9a2..f9e98128bc1c 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -119,15 +119,15 @@ VNET_DECLARE(u_long, in_ifaddrhmask); /* mask for hash table */ #define INADDR_HASH(x) \ (&V_in_ifaddrhashtbl[INADDR_HASHVAL(x) & V_in_ifaddrhmask]) -extern struct rwlock in_ifaddr_lock; +extern struct rmlock in_ifaddr_lock; -#define IN_IFADDR_LOCK_ASSERT() rw_assert(&in_ifaddr_lock, RA_LOCKED) -#define IN_IFADDR_RLOCK() rw_rlock(&in_ifaddr_lock) -#define IN_IFADDR_RLOCK_ASSERT() rw_assert(&in_ifaddr_lock, RA_RLOCKED) -#define IN_IFADDR_RUNLOCK() rw_runlock(&in_ifaddr_lock) -#define IN_IFADDR_WLOCK() rw_wlock(&in_ifaddr_lock) -#define IN_IFADDR_WLOCK_ASSERT() rw_assert(&in_ifaddr_lock, RA_WLOCKED) -#define IN_IFADDR_WUNLOCK() rw_wunlock(&in_ifaddr_lock) +#define IN_IFADDR_LOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_LOCKED) +#define IN_IFADDR_RLOCK(t) rm_rlock(&in_ifaddr_lock, (t)) +#define IN_IFADDR_RLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_RLOCKED) +#define IN_IFADDR_RUNLOCK(t) rm_runlock(&in_ifaddr_lock, (t)) +#define IN_IFADDR_WLOCK() rm_wlock(&in_ifaddr_lock) +#define IN_IFADDR_WLOCK_ASSERT() rm_assert(&in_ifaddr_lock, RA_WLOCKED) +#define IN_IFADDR_WUNLOCK() rm_wunlock(&in_ifaddr_lock) /* * Macro for finding the internet address structure (in_ifaddr) @@ -161,18 +161,19 @@ do { \ * Macro for finding the internet address structure (in_ifaddr) corresponding * to a given interface (ifnet structure). */ -#define IFP_TO_IA(ifp, ia) \ +#define IFP_TO_IA(ifp, ia, t) \ /* struct ifnet *ifp; */ \ /* struct in_ifaddr *ia; */ \ + /* struct rm_priotracker *t; */ \ do { \ - IN_IFADDR_RLOCK(); \ + IN_IFADDR_RLOCK((t)); \ for ((ia) = TAILQ_FIRST(&V_in_ifaddrhead); \ (ia) != NULL && (ia)->ia_ifp != (ifp); \ (ia) = TAILQ_NEXT((ia), ia_link)) \ continue; \ if ((ia) != NULL) \ ifa_ref(&(ia)->ia_ifa); \ - IN_IFADDR_RUNLOCK(); \ + IN_IFADDR_RUNLOCK((t)); \ } while (0) /* diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index b6b967f6d59c..57553f547f75 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -647,6 +649,7 @@ icmp_input(struct mbuf **mp, int *offp, int proto) static void icmp_reflect(struct mbuf *m) { + struct rm_priotracker in_ifa_tracker; struct ip *ip = mtod(m, struct ip *); struct ifaddr *ifa; struct ifnet *ifp; @@ -672,15 +675,15 @@ icmp_reflect(struct mbuf *m) * If the incoming packet was addressed directly to one of our * own addresses, use dst as the src for the reply. */ - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); LIST_FOREACH(ia, INADDR_HASH(t.s_addr), ia_hash) { if (t.s_addr == IA_SIN(ia)->sin_addr.s_addr) { t = IA_SIN(ia)->sin_addr; - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); goto match; } } - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * If the incoming packet was addressed to one of our broadcast diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 4140edac5460..e1cbb43c87f7 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -97,8 +98,8 @@ extern void ipreass_slowtimo(void); extern void ipreass_destroy(void); #endif -struct rwlock in_ifaddr_lock; -RW_SYSINIT(in_ifaddr_lock, &in_ifaddr_lock, "in_ifaddr_lock"); +struct rmlock in_ifaddr_lock; +RM_SYSINIT(in_ifaddr_lock, &in_ifaddr_lock, "in_ifaddr_lock"); VNET_DEFINE(int, rsvp_on); diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 588bc0542a31..c75698113290 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -44,11 +44,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -120,6 +122,7 @@ int ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp) { + struct rm_priotracker in_ifa_tracker; struct ip *ip; struct ifnet *ifp = NULL; /* keep compiler happy */ struct mbuf *m0; @@ -258,7 +261,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, * packets if the interface is specified. */ ifp = imo->imo_multicast_ifp; - IFP_TO_IA(ifp, ia); + IFP_TO_IA(ifp, ia, &in_ifa_tracker); if (ia) have_ia_ref = 1; isbroadcast = 0; /* fool gcc */ diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index a71d8ec86f71..4e9fedaac817 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -724,6 +725,7 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt) void rip_ctlinput(int cmd, struct sockaddr *sa, void *vip) { + struct rm_priotracker in_ifa_tracker; struct in_ifaddr *ia; struct ifnet *ifp; int err; @@ -731,12 +733,12 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip) switch (cmd) { case PRC_IFDOWN: - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (ia->ia_ifa.ifa_addr == sa && (ia->ia_flags & IFA_ROUTE)) { ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); /* * in_scrubprefix() kills the interface route. */ @@ -753,21 +755,21 @@ rip_ctlinput(int cmd, struct sockaddr *sa, void *vip) } } if (ia == NULL) /* If ia matched, already unlocked. */ - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); break; case PRC_IFUP: - IN_IFADDR_RLOCK(); + IN_IFADDR_RLOCK(&in_ifa_tracker); TAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) { if (ia->ia_ifa.ifa_addr == sa) break; } if (ia == NULL || (ia->ia_flags & IFA_ROUTE)) { - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); return; } ifa_ref(&ia->ia_ifa); - IN_IFADDR_RUNLOCK(); + IN_IFADDR_RUNLOCK(&in_ifa_tracker); flags = RTF_UP; ifp = ia->ia_ifa.ifa_ifp; diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 4340150a7f14..754a5f334231 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -80,6 +80,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -1499,9 +1501,10 @@ in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags) struct in6_ifaddr * in6ifa_ifwithaddr(const struct in6_addr *addr, uint32_t zoneid) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); LIST_FOREACH(ia, IN6ADDR_HASH(addr), ia6_hash) { if (IN6_ARE_ADDR_EQUAL(IA6_IN6(ia), addr)) { if (zoneid != 0 && @@ -1511,7 +1514,7 @@ in6ifa_ifwithaddr(const struct in6_addr *addr, uint32_t zoneid) break; } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (ia); } @@ -1649,20 +1652,21 @@ ip6_sprintf(char *ip6buf, const struct in6_addr *addr) int in6_localaddr(struct in6_addr *in6) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; if (IN6_IS_ADDR_LOOPBACK(in6) || IN6_IS_ADDR_LINKLOCAL(in6)) return 1; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { if (IN6_ARE_MASKED_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr, &ia->ia_prefixmask.sin6_addr)) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return 1; } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); } @@ -1674,16 +1678,17 @@ in6_localaddr(struct in6_addr *in6) int in6_localip(struct in6_addr *in6) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); LIST_FOREACH(ia, IN6ADDR_HASH(in6), ia6_hash) { if (IN6_ARE_ADDR_EQUAL(in6, &ia->ia_addr.sin6_addr)) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (1); } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); } @@ -1720,19 +1725,20 @@ in6_ifhasaddr(struct ifnet *ifp, struct in6_addr *addr) int in6_is_addr_deprecated(struct sockaddr_in6 *sa6) { + struct rm_priotracker in6_ifa_tracker; struct in6_ifaddr *ia; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); LIST_FOREACH(ia, IN6ADDR_HASH(&sa6->sin6_addr), ia6_hash) { if (IN6_ARE_ADDR_EQUAL(IA6_IN6(ia), &sa6->sin6_addr)) { if (ia->ia6_flags & IN6_IFF_DEPRECATED) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (1); /* true */ } break; } } - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); /* false */ } diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 8c25e982cdeb..d8a32d504aa4 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -39,7 +39,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include #include #include diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 227f234206a8..d77324ff6538 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -178,6 +179,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, struct inpcb *inp, struct route_in6 *ro, struct ucred *cred, struct ifnet **ifpp, struct in6_addr *srcp) { + struct rm_priotracker in6_ifa_tracker; struct in6_addr dst, tmp; struct ifnet *ifp = NULL, *oifp = NULL; struct in6_ifaddr *ia = NULL, *ia_best = NULL; @@ -303,7 +305,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, return (error); rule = 0; - IN6_IFADDR_RLOCK(); + IN6_IFADDR_RLOCK(&in6_ifa_tracker); TAILQ_FOREACH(ia, &V_in6_ifaddrhead, ia_link) { int new_scope = -1, new_matchlen = -1; struct in6_addrpolicy *new_policy = NULL; @@ -501,7 +503,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, } if ((ia = ia_best) == NULL) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); IP6STAT_INC(ip6s_sources_none); return (EADDRNOTAVAIL); } @@ -518,7 +520,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, tmp = ia->ia_addr.sin6_addr; if (cred != NULL && prison_local_ip6(cred, &tmp, (inp != NULL && (inp->inp_flags & IN6P_IPV6_V6ONLY) != 0)) != 0) { - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); IP6STAT_INC(ip6s_sources_none); return (EADDRNOTAVAIL); } @@ -537,7 +539,7 @@ in6_selectsrc(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, IP6STAT_INC(ip6s_sources_otherscope[best_scope]); if (IFA6_IS_DEPRECATED(ia)) IP6STAT_INC(ip6s_sources_deprecated[best_scope]); - IN6_IFADDR_RUNLOCK(); + IN6_IFADDR_RUNLOCK(&in6_ifa_tracker); return (0); } diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index a486ce188287..81ca8396da6e 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -535,14 +535,14 @@ in6_addrhash(const struct in6_addr *in6) return (fnv_32_buf(&x, sizeof(x), FNV1_32_INIT)); } -extern struct rwlock in6_ifaddr_lock; -#define IN6_IFADDR_LOCK_ASSERT( ) rw_assert(&in6_ifaddr_lock, RA_LOCKED) -#define IN6_IFADDR_RLOCK() rw_rlock(&in6_ifaddr_lock) -#define IN6_IFADDR_RLOCK_ASSERT() rw_assert(&in6_ifaddr_lock, RA_RLOCKED) -#define IN6_IFADDR_RUNLOCK() rw_runlock(&in6_ifaddr_lock) -#define IN6_IFADDR_WLOCK() rw_wlock(&in6_ifaddr_lock) -#define IN6_IFADDR_WLOCK_ASSERT() rw_assert(&in6_ifaddr_lock, RA_WLOCKED) -#define IN6_IFADDR_WUNLOCK() rw_wunlock(&in6_ifaddr_lock) +extern struct rmlock in6_ifaddr_lock; +#define IN6_IFADDR_LOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_LOCKED) +#define IN6_IFADDR_RLOCK(t) rm_rlock(&in6_ifaddr_lock, (t)) +#define IN6_IFADDR_RLOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_RLOCKED) +#define IN6_IFADDR_RUNLOCK(t) rm_runlock(&in6_ifaddr_lock, (t)) +#define IN6_IFADDR_WLOCK() rm_wlock(&in6_ifaddr_lock) +#define IN6_IFADDR_WLOCK_ASSERT() rm_assert(&in6_ifaddr_lock, RA_WLOCKED) +#define IN6_IFADDR_WUNLOCK() rm_wunlock(&in6_ifaddr_lock) #define in6_ifstat_inc(ifp, tag) \ do { \ diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 78e8ef3b6b39..e4e388f3712c 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -82,6 +82,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -144,8 +146,8 @@ VNET_PCPUSTAT_SYSINIT(ip6stat); VNET_PCPUSTAT_SYSUNINIT(ip6stat); #endif /* VIMAGE */ -struct rwlock in6_ifaddr_lock; -RW_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); +struct rmlock in6_ifaddr_lock; +RM_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); static void ip6_init2(void *); static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);