Mechanical cleanup of epoch(9) usage in network stack.

- Remove macros that covertly create epoch_tracker on thread stack. Such
  macros a quite unsafe, e.g. will produce a buggy code if same macro is
  used in embedded scopes. Explicitly declare epoch_tracker always.

- Unmask interface list IFNET_RLOCK_NOSLEEP(), interface address list
  IF_ADDR_RLOCK() and interface AF specific data IF_AFDATA_RLOCK() read
  locking macros to what they actually are - the net_epoch.
  Keeping them as is is very misleading. They all are named FOO_RLOCK(),
  while they no longer have lock semantics. Now they allow recursion and
  what's more important they now no longer guarantee protection against
  their companion WLOCK macros.
  Note: INP_HASH_RLOCK() has same problems, but not touched by this commit.

This is non functional mechanical change. The only functionally changed
functions are ni6_addrs() and ni6_store_addrs(), where we no longer enter
epoch recursively.

Discussed with:	jtl, gallatin
This commit is contained in:
glebius 2019-01-09 01:11:19 +00:00
parent 2e6756f35d
commit 6d8cc191f9
40 changed files with 472 additions and 357 deletions

View File

@ -37,6 +37,7 @@ static inline struct net_device *
ip_dev_find(struct vnet *vnet, uint32_t addr)
{
struct sockaddr_in sin;
struct epoch_tracker et;
struct ifaddr *ifa;
struct ifnet *ifp;
@ -44,7 +45,7 @@ ip_dev_find(struct vnet *vnet, uint32_t addr)
sin.sin_addr.s_addr = addr;
sin.sin_len = sizeof(sin);
sin.sin_family = AF_INET;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
CURVNET_SET_QUIET(vnet);
ifa = ifa_ifwithaddr((struct sockaddr *)&sin);
CURVNET_RESTORE();
@ -54,7 +55,7 @@ ip_dev_find(struct vnet *vnet, uint32_t addr)
} else {
ifp = NULL;
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (ifp);
}
@ -62,6 +63,7 @@ static inline struct net_device *
ip6_dev_find(struct vnet *vnet, struct in6_addr addr, uint16_t scope_id)
{
struct sockaddr_in6 sin6;
struct epoch_tracker et;
struct ifaddr *ifa;
struct ifnet *ifp;
@ -74,7 +76,7 @@ ip6_dev_find(struct vnet *vnet, struct in6_addr addr, uint16_t scope_id)
/* embed the IPv6 scope ID */
sin6.sin6_addr.s6_addr16[1] = htons(scope_id);
}
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
CURVNET_SET_QUIET(vnet);
ifa = ifa_ifwithaddr((struct sockaddr *)&sin6);
CURVNET_RESTORE();
@ -84,7 +86,7 @@ ip6_dev_find(struct vnet *vnet, struct in6_addr addr, uint16_t scope_id)
} else {
ifp = NULL;
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (ifp);
}

View File

@ -91,6 +91,7 @@ wtap_node_write(struct cdev *dev, struct uio *uio, int ioflag)
struct ifnet *ifp;
struct wtap_softc *sc;
uint8_t buf[1024];
struct epoch_tracker et;
int buf_len;
uprintf("write device %s \"echo.\"\n", devtoname(dev));
@ -106,7 +107,7 @@ wtap_node_write(struct cdev *dev, struct uio *uio, int ioflag)
m_copyback(m, 0, buf_len, buf);
CURVNET_SET(TD_TO_VNET(curthread));
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
printf("ifp->if_xname = %s\n", ifp->if_xname);
@ -119,7 +120,7 @@ wtap_node_write(struct cdev *dev, struct uio *uio, int ioflag)
}
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
CURVNET_RESTORE();
return(err);

View File

@ -410,11 +410,11 @@ tbr_timeout(arg)
{
VNET_ITERATOR_DECL(vnet_iter);
struct ifnet *ifp;
int active, s;
struct epoch_tracker et;
int active;
active = 0;
s = splnet();
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
VNET_LIST_RLOCK_NOSLEEP();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
@ -431,8 +431,7 @@ tbr_timeout(arg)
CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK_NOSLEEP();
IFNET_RUNLOCK_NOSLEEP();
splx(s);
NET_EPOCH_EXIT(et);
if (active > 0)
CALLOUT_RESET(&tbr_callout, 1, tbr_timeout, (void *)0);
else

View File

@ -2022,6 +2022,7 @@ bstp_same_bridgeid(uint64_t id1, uint64_t id2)
void
bstp_reinit(struct bstp_state *bs)
{
struct epoch_tracker et;
struct bstp_port *bp;
struct ifnet *ifp, *mif;
u_char *e_addr;
@ -2042,7 +2043,7 @@ bstp_reinit(struct bstp_state *bs)
* from is part of this bridge, so we can have more than one independent
* bridges in the same STP domain.
*/
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (ifp->if_type != IFT_ETHER)
continue; /* Not Ethernet */
@ -2062,7 +2063,7 @@ bstp_reinit(struct bstp_state *bs)
continue;
}
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
if (mif == NULL)
goto disablestp;

View File

@ -351,16 +351,17 @@ ifnet_byindex(u_short idx)
struct ifnet *
ifnet_byindex_ref(u_short idx)
{
struct epoch_tracker et;
struct ifnet *ifp;
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
ifp = ifnet_byindex_locked(idx);
if (ifp == NULL || (ifp->if_flags & IFF_DYING)) {
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (NULL);
}
if_ref(ifp);
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (ifp);
}
@ -424,14 +425,15 @@ ifnet_setbyindex(u_short idx, struct ifnet *ifp)
struct ifaddr *
ifaddr_byindex(u_short idx)
{
struct epoch_tracker et;
struct ifnet *ifp;
struct ifaddr *ifa = NULL;
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
ifp = ifnet_byindex_locked(idx);
if (ifp != NULL && (ifa = ifp->if_addr) != NULL)
ifa_ref(ifa);
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (ifa);
}
@ -967,12 +969,14 @@ if_purgeaddrs(struct ifnet *ifp)
struct ifaddr *ifa;
while (1) {
NET_EPOCH_ENTER();
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_LINK)
break;
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
if (ifa == NULL)
break;
@ -1609,38 +1613,39 @@ ifgr_groups_get(void *ifgrp)
static int
if_getgroup(struct ifgroupreq *ifgr, struct ifnet *ifp)
{
struct epoch_tracker et;
int len, error;
struct ifg_list *ifgl;
struct ifg_req ifgrq, *ifgp;
if (ifgr->ifgr_len == 0) {
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
ifgr->ifgr_len += sizeof(struct ifg_req);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (0);
}
len = ifgr->ifgr_len;
ifgp = ifgr_groups_get(ifgr);
/* XXX: wire */
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
if (len < sizeof(ifgrq)) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (EINVAL);
}
bzero(&ifgrq, sizeof ifgrq);
strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
sizeof(ifgrq.ifgrq_group));
if ((error = copyout(&ifgrq, ifgp, sizeof(struct ifg_req)))) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (error);
}
len -= sizeof(ifgrq);
ifgp++;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (0);
}
@ -1954,11 +1959,12 @@ ifa_ifwithaddr(const struct sockaddr *addr)
int
ifa_ifwithaddr_check(const struct sockaddr *addr)
{
struct epoch_tracker et;
int rc;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
rc = (ifa_ifwithaddr(addr) != NULL);
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (rc);
}
@ -2187,6 +2193,7 @@ ifa_preferred(struct ifaddr *cur, struct ifaddr *next)
static void
link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
{
struct epoch_tracker et;
struct ifaddr *ifa, *oifa;
struct sockaddr *dst;
struct ifnet *ifp;
@ -2194,7 +2201,7 @@ link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == NULL) ||
((ifp = ifa->ifa_ifp) == NULL) || ((dst = rt_key(rt)) == NULL))
return;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
ifa = ifaof_ifpforaddr(dst, ifp);
if (ifa) {
oifa = rt->rt_ifa;
@ -2206,7 +2213,7 @@ link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
ifa->ifa_rtrequest(cmd, rt, info);
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
struct sockaddr_dl *
@ -2407,9 +2414,10 @@ if_qflush(struct ifnet *ifp)
struct ifnet *
ifunit_ref(const char *name)
{
struct epoch_tracker et;
struct ifnet *ifp;
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0 &&
!(ifp->if_flags & IFF_DYING))
@ -2417,21 +2425,22 @@ ifunit_ref(const char *name)
}
if (ifp != NULL)
if_ref(ifp);
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (ifp);
}
struct ifnet *
ifunit(const char *name)
{
struct epoch_tracker et;
struct ifnet *ifp;
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (strncmp(name, ifp->if_xname, IFNAMSIZ) == 0)
break;
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (ifp);
}
@ -2819,6 +2828,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
return (EINVAL);
if (cmd == SIOCADDMULTI) {
struct epoch_tracker et;
struct ifmultiaddr *ifma;
/*
@ -2828,9 +2838,9 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
* lose a race while we check if the membership
* already exists.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
ifma = if_findmulti(ifp, &ifr->ifr_addr);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ifma != NULL)
error = EADDRINUSE;
else
@ -3253,6 +3263,7 @@ ifconf(u_long cmd, caddr_t data)
IFNET_RLOCK();
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
struct epoch_tracker et;
int addrs;
/*
@ -3269,7 +3280,7 @@ ifconf(u_long cmd, caddr_t data)
}
addrs = 0;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct sockaddr *sa = ifa->ifa_addr;
@ -3297,7 +3308,7 @@ ifconf(u_long cmd, caddr_t data)
if (sbuf_error(sb) == 0)
valid_len = sbuf_len(sb);
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (addrs == 0) {
sbuf_bcat(sb, &ifr, sizeof(ifr));
max_len += sizeof(ifr);
@ -3604,15 +3615,16 @@ if_delmulti(struct ifnet *ifp, struct sockaddr *sa)
struct ifmultiaddr *ifma;
int lastref;
#ifdef INVARIANTS
struct epoch_tracker et;
struct ifnet *oifp;
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(oifp, &V_ifnet, if_link)
if (ifp == oifp)
break;
if (ifp != oifp)
ifp = NULL;
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
KASSERT(ifp != NULL, ("%s: ifnet went away", __func__));
#endif
@ -3678,15 +3690,16 @@ if_delmulti_ifma_flags(struct ifmultiaddr *ifma, int flags)
if (ifp == NULL) {
printf("%s: ifma_ifp seems to be detached\n", __func__);
} else {
struct epoch_tracker et;
struct ifnet *oifp;
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(oifp, &V_ifnet, if_link)
if (ifp == oifp)
break;
if (ifp != oifp)
ifp = NULL;
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
}
#endif
/*
@ -3810,10 +3823,11 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
struct sockaddr_dl *sdl;
struct ifaddr *ifa;
struct ifreq ifr;
struct epoch_tracker et;
int rc;
rc = 0;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
ifa = ifp->if_addr;
if (ifa == NULL) {
rc = EINVAL;
@ -3847,7 +3861,7 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
* to re-init it in order to reprogram its
* address filter.
*/
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
if ((ifp->if_flags & IFF_UP) != 0) {
if (ifp->if_ioctl) {
ifp->if_flags &= ~IFF_UP;
@ -3863,7 +3877,7 @@ if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
EVENTHANDLER_INVOKE(iflladdr_event, ifp);
return (0);
out:
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (rc);
}

View File

@ -90,6 +90,7 @@ static int htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f,
static int
lltable_dump_af(struct lltable *llt, struct sysctl_req *wr)
{
struct epoch_tracker et;
int error;
LLTABLE_LIST_LOCK_ASSERT();
@ -98,10 +99,10 @@ lltable_dump_af(struct lltable *llt, struct sysctl_req *wr)
return (0);
error = 0;
IF_AFDATA_RLOCK(llt->llt_ifp);
NET_EPOCH_ENTER(et);
error = lltable_foreach_lle(llt,
(llt_foreach_cb_t *)llt->llt_dump_entry, wr);
IF_AFDATA_RUNLOCK(llt->llt_ifp);
NET_EPOCH_EXIT(et);
return (error);
}
@ -453,11 +454,12 @@ struct llentry *
llentry_alloc(struct ifnet *ifp, struct lltable *lt,
struct sockaddr_storage *dst)
{
struct epoch_tracker et;
struct llentry *la, *la_tmp;
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
la = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (la != NULL) {
LLE_ADDREF(la);

View File

@ -398,19 +398,15 @@ struct ifnet {
*/
#define IF_ADDR_LOCK_INIT(if) mtx_init(&(if)->if_addr_lock, "if_addr_lock", NULL, MTX_DEF)
#define IF_ADDR_LOCK_DESTROY(if) mtx_destroy(&(if)->if_addr_lock)
#define IF_ADDR_RLOCK(if) struct epoch_tracker if_addr_et; epoch_enter_preempt(net_epoch_preempt, &if_addr_et);
#define IF_ADDR_RUNLOCK(if) epoch_exit_preempt(net_epoch_preempt, &if_addr_et);
#define IF_ADDR_WLOCK(if) mtx_lock(&(if)->if_addr_lock)
#define IF_ADDR_WUNLOCK(if) mtx_unlock(&(if)->if_addr_lock)
#define IF_ADDR_LOCK_ASSERT(if) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(if)->if_addr_lock))
#define IF_ADDR_WLOCK_ASSERT(if) mtx_assert(&(if)->if_addr_lock, MA_OWNED)
#define NET_EPOCH_ENTER() struct epoch_tracker nep_et; epoch_enter_preempt(net_epoch_preempt, &nep_et)
#define NET_EPOCH_ENTER_ET(et) epoch_enter_preempt(net_epoch_preempt, &(et))
#define NET_EPOCH_EXIT() epoch_exit_preempt(net_epoch_preempt, &nep_et)
#define NET_EPOCH_EXIT_ET(et) epoch_exit_preempt(net_epoch_preempt, &(et))
#define NET_EPOCH_WAIT() epoch_wait_preempt(net_epoch_preempt)
#define NET_EPOCH_ENTER(et) epoch_enter_preempt(net_epoch_preempt, &(et))
#define NET_EPOCH_EXIT(et) epoch_exit_preempt(net_epoch_preempt, &(et))
#define NET_EPOCH_WAIT() epoch_wait_preempt(net_epoch_preempt)
#define NET_EPOCH_ASSERT() MPASS(in_epoch(net_epoch_preempt))
/*
* Function variations on locking macros intended to be used by loadable
@ -490,16 +486,13 @@ EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
mtx_init(&(ifp)->if_afdata_lock, "if_afdata", NULL, MTX_DEF)
#define IF_AFDATA_WLOCK(ifp) mtx_lock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_RLOCK(ifp) struct epoch_tracker if_afdata_et; epoch_enter_preempt(net_epoch_preempt, &if_afdata_et)
#define IF_AFDATA_WUNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_RUNLOCK(ifp) epoch_exit_preempt(net_epoch_preempt, &if_afdata_et)
#define IF_AFDATA_LOCK(ifp) IF_AFDATA_WLOCK(ifp)
#define IF_AFDATA_UNLOCK(ifp) IF_AFDATA_WUNLOCK(ifp)
#define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_lock)
#define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_lock)
#define IF_AFDATA_LOCK_ASSERT(ifp) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(ifp)->if_afdata_lock))
#define IF_AFDATA_RLOCK_ASSERT(ifp) MPASS(in_epoch(net_epoch_preempt));
#define IF_AFDATA_WLOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_lock, MA_OWNED)
#define IF_AFDATA_UNLOCK_ASSERT(ifp) mtx_assert(&(ifp)->if_afdata_lock, MA_NOTOWNED)
@ -583,16 +576,13 @@ extern struct sx ifnet_sxlock;
* write, but also whether it was acquired with sleep support or not.
*/
#define IFNET_RLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_SLOCKED)
#define IFNET_RLOCK_NOSLEEP_ASSERT() MPASS(in_epoch(net_epoch_preempt))
#define IFNET_WLOCK_ASSERT() do { \
sx_assert(&ifnet_sxlock, SA_XLOCKED); \
rw_assert(&ifnet_rwlock, RA_WLOCKED); \
} while (0)
#define IFNET_RLOCK() sx_slock(&ifnet_sxlock)
#define IFNET_RLOCK_NOSLEEP() struct epoch_tracker ifnet_rlock_et; epoch_enter_preempt(net_epoch_preempt, &ifnet_rlock_et)
#define IFNET_RUNLOCK() sx_sunlock(&ifnet_sxlock)
#define IFNET_RUNLOCK_NOSLEEP() epoch_exit_preempt(net_epoch_preempt, &ifnet_rlock_et)
/*
* Look up an ifnet given its index; the _ref variant also acquires a

View File

@ -233,10 +233,6 @@ static struct sx _VLAN_SX_ID;
#define VLAN_LOCKING_DESTROY() \
sx_destroy(&_VLAN_SX_ID)
#define VLAN_RLOCK() NET_EPOCH_ENTER();
#define VLAN_RUNLOCK() NET_EPOCH_EXIT();
#define VLAN_RLOCK_ASSERT() MPASS(in_epoch(net_epoch_preempt))
#define VLAN_SLOCK() sx_slock(&_VLAN_SX_ID)
#define VLAN_SUNLOCK() sx_sunlock(&_VLAN_SX_ID)
#define VLAN_XLOCK() sx_xlock(&_VLAN_SX_ID)
@ -252,11 +248,8 @@ static struct sx _VLAN_SX_ID;
*/
#define TRUNK_LOCK_INIT(trunk) mtx_init(&(trunk)->lock, vlanname, NULL, MTX_DEF)
#define TRUNK_LOCK_DESTROY(trunk) mtx_destroy(&(trunk)->lock)
#define TRUNK_RLOCK(trunk) NET_EPOCH_ENTER()
#define TRUNK_WLOCK(trunk) mtx_lock(&(trunk)->lock)
#define TRUNK_RUNLOCK(trunk) NET_EPOCH_EXIT();
#define TRUNK_WUNLOCK(trunk) mtx_unlock(&(trunk)->lock)
#define TRUNK_RLOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt))
#define TRUNK_LOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(trunk)->lock))
#define TRUNK_WLOCK_ASSERT(trunk) mtx_assert(&(trunk)->lock, MA_OWNED);
@ -472,7 +465,7 @@ vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid)
{
struct ifvlan *ifv;
TRUNK_RLOCK_ASSERT(trunk);
NET_EPOCH_ASSERT();
CK_SLIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list)
if (ifv->ifv_vid == vid)
@ -617,16 +610,17 @@ vlan_setmulti(struct ifnet *ifp)
static void
vlan_iflladdr(void *arg __unused, struct ifnet *ifp)
{
struct epoch_tracker et;
struct ifvlan *ifv;
struct ifnet *ifv_ifp;
struct ifvlantrunk *trunk;
struct sockaddr_dl *sdl;
/* Need the rmlock since this is run on taskqueue_swi. */
VLAN_RLOCK();
NET_EPOCH_ENTER(et);
trunk = ifp->if_vlantrunk;
if (trunk == NULL) {
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return;
}
@ -652,7 +646,7 @@ vlan_iflladdr(void *arg __unused, struct ifnet *ifp)
taskqueue_enqueue(taskqueue_thread, &ifv->lladdr_task);
}
TRUNK_WUNLOCK(trunk);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
}
/*
@ -698,17 +692,18 @@ vlan_ifdetach(void *arg __unused, struct ifnet *ifp)
static struct ifnet *
vlan_trunkdev(struct ifnet *ifp)
{
struct epoch_tracker et;
struct ifvlan *ifv;
if (ifp->if_type != IFT_L2VLAN)
return (NULL);
VLAN_RLOCK();
NET_EPOCH_ENTER(et);
ifv = ifp->if_softc;
ifp = NULL;
if (ifv->ifv_trunk)
ifp = PARENT(ifv);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return (ifp);
}
@ -780,20 +775,21 @@ vlan_setcookie(struct ifnet *ifp, void *cookie)
static struct ifnet *
vlan_devat(struct ifnet *ifp, uint16_t vid)
{
struct epoch_tracker et;
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
VLAN_RLOCK();
NET_EPOCH_ENTER(et);
trunk = ifp->if_vlantrunk;
if (trunk == NULL) {
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return (NULL);
}
ifp = NULL;
ifv = vlan_gethash(trunk, vid);
if (ifv)
ifp = ifv->ifv_ifp;
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return (ifp);
}
@ -1133,15 +1129,16 @@ vlan_init(void *foo __unused)
static int
vlan_transmit(struct ifnet *ifp, struct mbuf *m)
{
struct epoch_tracker et;
struct ifvlan *ifv;
struct ifnet *p;
int error, len, mcast;
VLAN_RLOCK();
NET_EPOCH_ENTER(et);
ifv = ifp->if_softc;
if (TRUNK(ifv) == NULL) {
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
m_freem(m);
return (ENETDOWN);
}
@ -1157,14 +1154,14 @@ vlan_transmit(struct ifnet *ifp, struct mbuf *m)
*/
if (!UP_AND_RUNNING(p)) {
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
m_freem(m);
return (ENETDOWN);
}
if (!ether_8021q_frame(&m, ifp, p, ifv->ifv_vid, ifv->ifv_pcp)) {
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return (0);
}
@ -1178,7 +1175,7 @@ vlan_transmit(struct ifnet *ifp, struct mbuf *m)
if_inc_counter(ifp, IFCOUNTER_OMCASTS, mcast);
} else
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return (error);
}
@ -1193,15 +1190,16 @@ vlan_qflush(struct ifnet *ifp __unused)
static void
vlan_input(struct ifnet *ifp, struct mbuf *m)
{
struct epoch_tracker et;
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
struct m_tag *mtag;
uint16_t vid, tag;
VLAN_RLOCK();
NET_EPOCH_ENTER(et);
trunk = ifp->if_vlantrunk;
if (trunk == NULL) {
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
m_freem(m);
return;
}
@ -1224,7 +1222,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
if (m->m_len < sizeof(*evl) &&
(m = m_pullup(m, sizeof(*evl))) == NULL) {
if_printf(ifp, "cannot pullup VLAN header\n");
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return;
}
evl = mtod(m, struct ether_vlan_header *);
@ -1247,7 +1245,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
__func__, ifp->if_xname, ifp->if_type);
#endif
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
m_freem(m);
return;
}
@ -1257,7 +1255,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
ifv = vlan_gethash(trunk, vid);
if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) {
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
m_freem(m);
return;
@ -1277,7 +1275,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
sizeof(uint8_t), M_NOWAIT);
if (mtag == NULL) {
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
m_freem(m);
return;
}
@ -1288,7 +1286,7 @@ vlan_input(struct ifnet *ifp, struct mbuf *m)
m->m_pkthdr.rcvif = ifv->ifv_ifp;
if_inc_counter(ifv->ifv_ifp, IFCOUNTER_IPACKETS, 1);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
/* Pass it back through the parent's input routine. */
(*ifv->ifv_ifp->if_input)(ifv->ifv_ifp, m);
@ -1314,6 +1312,7 @@ vlan_lladdr_fn(void *arg, int pending __unused)
static int
vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid)
{
struct epoch_tracker et;
struct ifvlantrunk *trunk;
struct ifnet *ifp;
int error = 0;
@ -1413,9 +1412,9 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid)
ifp->if_link_state = p->if_link_state;
TRUNK_RLOCK(TRUNK(ifv));
NET_EPOCH_ENTER(et);
vlan_capabilities(ifv);
TRUNK_RUNLOCK(TRUNK(ifv));
NET_EPOCH_EXIT(et);
/*
* Set up our interface address to reflect the underlying
@ -1587,14 +1586,15 @@ vlan_setflags(struct ifnet *ifp, int status)
static void
vlan_link_state(struct ifnet *ifp)
{
struct epoch_tracker et;
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
/* Called from a taskqueue_swi task, so we cannot sleep. */
VLAN_RLOCK();
NET_EPOCH_ENTER(et);
trunk = ifp->if_vlantrunk;
if (trunk == NULL) {
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
return;
}
@ -1605,7 +1605,7 @@ vlan_link_state(struct ifnet *ifp)
trunk->parent->if_link_state);
}
TRUNK_WUNLOCK(trunk);
VLAN_RUNLOCK();
NET_EPOCH_EXIT(et);
}
static void
@ -1618,7 +1618,7 @@ vlan_capabilities(struct ifvlan *ifv)
u_long hwa = 0;
VLAN_SXLOCK_ASSERT();
TRUNK_RLOCK_ASSERT(TRUNK(ifv));
NET_EPOCH_ASSERT();
p = PARENT(ifv);
ifp = ifv->ifv_ifp;
@ -1710,6 +1710,7 @@ vlan_capabilities(struct ifvlan *ifv)
static void
vlan_trunk_capabilities(struct ifnet *ifp)
{
struct epoch_tracker et;
struct ifvlantrunk *trunk;
struct ifvlan *ifv;
@ -1719,11 +1720,11 @@ vlan_trunk_capabilities(struct ifnet *ifp)
VLAN_SUNLOCK();
return;
}
TRUNK_RLOCK(trunk);
NET_EPOCH_ENTER(et);
VLAN_FOREACH(ifv, trunk) {
vlan_capabilities(ifv);
}
TRUNK_RUNLOCK(trunk);
NET_EPOCH_EXIT(et);
VLAN_SUNLOCK();
}
@ -1915,9 +1916,11 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
ifv->ifv_capenable = ifr->ifr_reqcap;
trunk = TRUNK(ifv);
if (trunk != NULL) {
TRUNK_RLOCK(trunk);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
vlan_capabilities(ifv);
TRUNK_RUNLOCK(trunk);
NET_EPOCH_EXIT(et);
}
VLAN_SUNLOCK();
break;

View File

@ -593,11 +593,12 @@ rtredirect_fib(struct sockaddr *dst,
int error = 0;
short *stat = NULL;
struct rt_addrinfo info;
struct epoch_tracker et;
struct ifaddr *ifa;
struct rib_head *rnh;
ifa = NULL;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
rnh = rt_tables_get_rnh(fibnum, dst->sa_family);
if (rnh == NULL) {
error = EAFNOSUPPORT;
@ -692,7 +693,7 @@ rtredirect_fib(struct sockaddr *dst,
if (rt)
RTFREE_LOCKED(rt);
out:
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
if (error)
V_rtstat.rts_badredirect++;
else if (stat != NULL)
@ -1279,6 +1280,7 @@ rt_notifydelete(struct rtentry *rt, struct rt_addrinfo *info)
int
rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
{
struct epoch_tracker et;
struct ifaddr *ifa;
int needref, error;
@ -1288,7 +1290,7 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
*/
error = 0;
needref = (info->rti_ifa == NULL);
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
if (info->rti_ifp == NULL && ifpaddr != NULL &&
ifpaddr->sa_family == AF_LINK &&
(ifa = ifa_ifwithnet(ifpaddr, 0, fibnum)) != NULL) {
@ -1316,7 +1318,7 @@ rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum)
ifa_ref(info->rti_ifa);
} else
error = ENETUNREACH;
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (error);
}

View File

@ -440,6 +440,9 @@ static int
rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
struct rtentry *rt, union sockaddr_union *saun, struct ucred *cred)
{
#if defined(INET) || defined(INET6)
struct epoch_tracker et;
#endif
/* First, see if the returned address is part of the jail. */
if (prison_if(cred, rt->rt_ifa->ifa_addr) == 0) {
@ -460,7 +463,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
* Try to find an address on the given outgoing interface
* that belongs to the jail.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct sockaddr *sa;
sa = ifa->ifa_addr;
@ -472,7 +475,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (!found) {
/*
* As a last resort return the 'default' jail address.
@ -502,7 +505,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
* Try to find an address on the given outgoing interface
* that belongs to the jail.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct sockaddr *sa;
sa = ifa->ifa_addr;
@ -515,7 +518,7 @@ rtm_get_jailed(struct rt_addrinfo *info, struct ifnet *ifp,
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (!found) {
/*
* As a last resort return the 'default' jail address.
@ -786,16 +789,17 @@ route_output(struct mbuf *m, struct socket *so, ...)
if (rt->rt_ifp != NULL &&
rt->rt_ifp->if_type == IFT_PROPVIRTUAL) {
struct epoch_tracker et;
struct ifaddr *ifa;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
ifa = ifa_ifwithnet(info.rti_info[RTAX_DST], 1,
RT_ALL_FIBS);
if (ifa != NULL)
rt_maskedcopy(ifa->ifa_addr,
&laddr,
ifa->ifa_netmask);
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
} else
rt_maskedcopy(rt->rt_ifa->ifa_addr,
&laddr,
@ -1559,7 +1563,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
struct rt_addrinfo info;
struct sockaddr_storage ss;
IFNET_RLOCK_NOSLEEP_ASSERT();
NET_EPOCH_ASSERT();
if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))
return 0;
@ -1753,7 +1757,7 @@ sysctl_iflist(int af, struct walkarg *w)
bzero((caddr_t)&info, sizeof(info));
bzero(&ifd, sizeof(ifd));
NET_EPOCH_ENTER_ET(et);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (w->w_arg && w->w_arg != ifp->if_index)
continue;
@ -1803,7 +1807,7 @@ sysctl_iflist(int af, struct walkarg *w)
info.rti_info[RTAX_BRD] = NULL;
}
done:
NET_EPOCH_EXIT_ET(et);
NET_EPOCH_EXIT(et);
return (error);
}
@ -1811,6 +1815,7 @@ static int
sysctl_ifmalist(int af, struct walkarg *w)
{
struct rt_addrinfo info;
struct epoch_tracker et;
struct ifaddr *ifa;
struct ifmultiaddr *ifma;
struct ifnet *ifp;
@ -1819,13 +1824,13 @@ sysctl_ifmalist(int af, struct walkarg *w)
error = 0;
bzero((caddr_t)&info, sizeof(info));
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (w->w_arg && w->w_arg != ifp->if_index)
continue;
ifa = ifp->if_addr;
info.rti_info[RTAX_IFP] = ifa ? ifa->ifa_addr : NULL;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (af && af != ifma->ifma_addr->sa_family)
continue;
@ -1852,11 +1857,11 @@ sysctl_ifmalist(int af, struct walkarg *w)
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (error != 0)
break;
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (error);
}
@ -1935,11 +1940,13 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
for (error = 0; error == 0 && i <= lim; i++) {
rnh = rt_tables_get_rnh(fib, i);
if (rnh != NULL) {
struct epoch_tracker et;
RIB_RLOCK(rnh);
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
error = rnh->rnh_walktree(&rnh->head,
sysctl_dumpentry, &w);
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
RIB_RUNLOCK(rnh);
} else if (af != 0)
error = EAFNOSUPPORT;

View File

@ -359,9 +359,10 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
* The caller did not supply a source address, try to find
* a compatible one among those assigned to this interface.
*/
struct epoch_tracker et;
struct ifaddr *ifa;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
@ -379,7 +380,7 @@ arprequest(struct ifnet *ifp, const struct in_addr *sip,
IA_MASKSIN(ifa)->sin_addr.s_addr))
break; /* found it. */
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (sip == NULL) {
printf("%s: cannot find matching address\n", __func__);
return;
@ -459,9 +460,11 @@ arpresolve_full(struct ifnet *ifp, int is_gw, int flags, struct mbuf *m,
*plle = NULL;
if ((flags & LLE_CREATE) == 0) {
IF_AFDATA_RLOCK(ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
if (la == NULL && (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
la = lltable_alloc_entry(LLTABLE(ifp), 0, dst);
@ -593,6 +596,7 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
const struct sockaddr *dst, u_char *desten, uint32_t *pflags,
struct llentry **plle)
{
struct epoch_tracker et;
struct llentry *la = NULL;
if (pflags != NULL)
@ -614,7 +618,7 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
}
}
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
la = lla_lookup(LLTABLE(ifp), plle ? LLE_EXCLUSIVE : LLE_UNLOCKED, dst);
if (la != NULL && (la->r_flags & RLLE_VALID) != 0) {
/* Entry found, let's copy lle info */
@ -628,12 +632,12 @@ arpresolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
*plle = la;
LLE_WUNLOCK(la);
}
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (0);
}
if (plle && la)
LLE_WUNLOCK(la);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (arpresolve_full(ifp, is_gw, la == NULL ? LLE_CREATE : 0, m, dst,
desten, pflags, plle));
@ -778,6 +782,7 @@ in_arpinput(struct mbuf *m)
int lladdr_off;
int error;
char addrbuf[INET_ADDRSTRLEN];
struct epoch_tracker et;
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_family = AF_INET;
@ -870,17 +875,17 @@ in_arpinput(struct mbuf *m)
* No match, use the first inet address on the receive interface
* as a dummy address for the rest of the function.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
if (ifa->ifa_addr->sa_family == AF_INET &&
(ifa->ifa_carp == NULL ||
(*carp_iamatch_p)(ifa, &enaddr))) {
ia = ifatoia(ifa);
ifa_ref(ifa);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto match;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
/*
* If bridging, fall back to using any inet address.
@ -937,9 +942,9 @@ in_arpinput(struct mbuf *m)
sin.sin_family = AF_INET;
sin.sin_addr = isaddr;
dst = (struct sockaddr *)&sin;
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (la != NULL)
arp_check_update_lle(ah, isaddr, ifp, bridged, la);
else if (itaddr.s_addr == myaddr.s_addr) {
@ -1017,9 +1022,9 @@ in_arpinput(struct mbuf *m)
struct llentry *lle = NULL;
sin.sin_addr = itaddr;
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);

View File

@ -692,6 +692,7 @@ static int
igmp_input_v1_query(struct ifnet *ifp, const struct ip *ip,
const struct igmp *igmp)
{
struct epoch_tracker et;
struct ifmultiaddr *ifma;
struct igmp_ifsoftc *igi;
struct in_multi *inm;
@ -733,7 +734,7 @@ igmp_input_v1_query(struct ifnet *ifp, const struct ip *ip,
* for the interface on which the query arrived,
* except those which are already running.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET ||
ifma->ifma_protospec == NULL)
@ -761,7 +762,7 @@ igmp_input_v1_query(struct ifnet *ifp, const struct ip *ip,
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
out_locked:
IGMP_UNLOCK();
@ -777,6 +778,7 @@ static int
igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip,
const struct igmp *igmp)
{
struct epoch_tracker et;
struct ifmultiaddr *ifma;
struct igmp_ifsoftc *igi;
struct in_multi *inm;
@ -834,7 +836,7 @@ igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip,
*/
CTR2(KTR_IGMPV3, "process v2 general query on ifp %p(%s)",
ifp, ifp->if_xname);
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET ||
ifma->ifma_protospec == NULL)
@ -842,7 +844,7 @@ igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip,
inm = (struct in_multi *)ifma->ifma_protospec;
igmp_v2_update_group(inm, timer);
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
} else {
/*
* Group-specific IGMPv2 query, we need only
@ -1218,11 +1220,13 @@ 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)) {
NET_EPOCH_ENTER();
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
IFP_TO_IA(ifp, ia, &in_ifa_tracker);
if (ia != NULL)
ip->ip_src.s_addr = htonl(ia->ia_subnet);
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
CTR3(KTR_IGMPV3, "process v1 report 0x%08x on ifp %p(%s)",
@ -1307,6 +1311,7 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip,
/*const*/ struct igmp *igmp)
{
struct rm_priotracker in_ifa_tracker;
struct epoch_tracker et;
struct in_ifaddr *ia;
struct in_multi *inm;
@ -1315,23 +1320,23 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip,
* leave requires knowing that we are the only member of a
* group.
*/
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
IFP_TO_IA(ifp, ia, &in_ifa_tracker);
if (ia != NULL && in_hosteq(ip->ip_src, IA_SIN(ia)->sin_addr)) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (0);
}
IGMPSTAT_INC(igps_rcv_reports);
if (ifp->if_flags & IFF_LOOPBACK) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (0);
}
if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr)) ||
!in_hosteq(igmp->igmp_group, ip->ip_dst)) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
IGMPSTAT_INC(igps_rcv_badreports);
return (EINVAL);
}
@ -1347,7 +1352,7 @@ igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip,
if (ia != NULL)
ip->ip_src.s_addr = htonl(ia->ia_subnet);
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
CTR3(KTR_IGMPV3, "process v2 report 0x%08x on ifp %p(%s)",
ntohl(igmp->igmp_group.s_addr), ifp, ifp->if_xname);
@ -1989,6 +1994,7 @@ igmp_v3_cancel_link_timers(struct igmp_ifsoftc *igi)
struct ifnet *ifp;
struct in_multi *inm;
struct in_multi_head inm_free_tmp;
struct epoch_tracker et;
CTR3(KTR_IGMPV3, "%s: cancel v3 timers on ifp %p(%s)", __func__,
igi->igi_ifp, igi->igi_ifp->if_xname);
@ -2009,7 +2015,7 @@ igmp_v3_cancel_link_timers(struct igmp_ifsoftc *igi)
* for all memberships scoped to this link.
*/
ifp = igi->igi_ifp;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET ||
ifma->ifma_protospec == NULL)
@ -2054,7 +2060,7 @@ igmp_v3_cancel_link_timers(struct igmp_ifsoftc *igi)
inm->inm_timer = 0;
mbufq_drain(&inm->inm_scq);
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
inm_release_list_deferred(&inm_free_tmp);
}
@ -3297,6 +3303,7 @@ igmp_v3_merge_state_changes(struct in_multi *inm, struct mbufq *scq)
static void
igmp_v3_dispatch_general_query(struct igmp_ifsoftc *igi)
{
struct epoch_tracker et;
struct ifmultiaddr *ifma;
struct ifnet *ifp;
struct in_multi *inm;
@ -3319,7 +3326,7 @@ igmp_v3_dispatch_general_query(struct igmp_ifsoftc *igi)
ifp = igi->igi_ifp;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET ||
ifma->ifma_protospec == NULL)
@ -3350,7 +3357,7 @@ igmp_v3_dispatch_general_query(struct igmp_ifsoftc *igi)
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
send:
loop = (igi->igi_flags & IGIF_LOOPBACK) ? 1 : 0;
@ -3522,13 +3529,14 @@ igmp_v3_encap_report(struct ifnet *ifp, struct mbuf *m)
ip->ip_src.s_addr = INADDR_ANY;
if (m->m_flags & M_IGMP_LOOP) {
struct epoch_tracker et;
struct in_ifaddr *ia;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
IFP_TO_IA(ifp, ia, &in_ifa_tracker);
if (ia != NULL)
ip->ip_src = ia->ia_addr.sin_addr;
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
ip->ip_dst.s_addr = htonl(INADDR_ALLRPTS_GROUP);

View File

@ -139,20 +139,21 @@ in_localip(struct in_addr in)
int
in_ifhasaddr(struct ifnet *ifp, struct in_addr in)
{
struct epoch_tracker et;
struct ifaddr *ifa;
struct in_ifaddr *ia;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
ia = (struct in_ifaddr *)ifa;
if (ia->ia_addr.sin_addr.s_addr == in.s_addr) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (1);
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (0);
}
@ -228,6 +229,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
{
struct ifreq *ifr = (struct ifreq *)data;
struct sockaddr_in *addr = (struct sockaddr_in *)&ifr->ifr_addr;
struct epoch_tracker et;
struct ifaddr *ifa;
struct in_ifaddr *ia;
int error;
@ -277,7 +279,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
* address was specified, find that one instead of the
* first one on the interface, if possible.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
@ -295,7 +297,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
}
if (ifa == NULL) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
}
@ -326,7 +328,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
break;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (error);
}
@ -340,6 +342,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
const struct sockaddr_in *mask = &ifra->ifra_mask;
const struct sockaddr_in *dstaddr = &ifra->ifra_dstaddr;
const int vhid = (cmd == SIOCAIFADDR) ? ifra->ifra_vhid : 0;
struct epoch_tracker et;
struct ifaddr *ifa;
struct in_ifaddr *ia;
bool iaIsFirst;
@ -376,7 +379,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
*/
iaIsFirst = true;
ia = NULL;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct in_ifaddr *it;
@ -389,7 +392,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
prison_check_ip4(td->td_ucred, &addr->sin_addr) == 0)
ia = it;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ia != NULL)
(void )in_difaddr_ioctl(cmd, data, ifp, td);
@ -919,7 +922,7 @@ in_ifscrub_all(void)
IFNET_RLOCK();
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
/* Cannot lock here - lock recursion. */
/* IF_ADDR_RLOCK(ifp); */
/* NET_EPOCH_ENTER(et); */
CK_STAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, nifa) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
@ -935,7 +938,7 @@ in_ifscrub_all(void)
(void)in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr,
ifp, NULL);
}
/* IF_ADDR_RUNLOCK(ifp); */
/* NET_EPOCH_EXIT(et); */
in_purgemaddrs(ifp);
igmp_domifdetach(ifp);
}
@ -967,6 +970,7 @@ in_ifaddr_broadcast(struct in_addr in, struct in_ifaddr *ia)
int
in_broadcast(struct in_addr in, struct ifnet *ifp)
{
struct epoch_tracker et;
struct ifaddr *ifa;
int found;
@ -980,14 +984,14 @@ in_broadcast(struct in_addr in, struct ifnet *ifp)
* Look through the list of addresses for a match
* with a broadcast address.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
if (ifa->ifa_addr->sa_family == AF_INET &&
in_ifaddr_broadcast(in, (struct in_ifaddr *)ifa)) {
found = 1;
break;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (found);
}

View File

@ -367,12 +367,13 @@ inm_lookup_locked(struct ifnet *ifp, const struct in_addr ina)
struct in_multi *
inm_lookup(struct ifnet *ifp, const struct in_addr ina)
{
struct epoch_tracker et;
struct in_multi *inm;
IN_MULTI_LIST_LOCK_ASSERT();
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
inm = inm_lookup_locked(ifp, ina);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (inm);
}
@ -1887,13 +1888,15 @@ inp_getmoptions(struct inpcb *inp, struct sockopt *sopt)
if (!in_nullhost(imo->imo_multicast_addr)) {
mreqn.imr_address = imo->imo_multicast_addr;
} else if (ifp != NULL) {
struct epoch_tracker et;
mreqn.imr_ifindex = ifp->if_index;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
IFP_TO_IA(ifp, ia, &in_ifa_tracker);
if (ia != NULL)
mreqn.imr_address =
IA_SIN(ia)->sin_addr;
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
}
INP_WUNLOCK(inp);
@ -2966,6 +2969,7 @@ static int
sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS)
{
struct in_addr src, group;
struct epoch_tracker et;
struct ifnet *ifp;
struct ifmultiaddr *ifma;
struct in_multi *inm;
@ -3012,7 +3016,7 @@ sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS)
IN_MULTI_LIST_LOCK();
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET ||
ifma->ifma_protospec == NULL)
@ -3041,7 +3045,7 @@ sysctl_ip_mcast_filters(SYSCTL_HANDLER_ARGS)
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
IN_MULTI_LIST_UNLOCK();

View File

@ -1012,6 +1012,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
struct sockaddr *sa;
struct sockaddr_in *sin;
struct route sro;
struct epoch_tracker et;
int error;
KASSERT(laddr != NULL, ("%s: laddr NULL", __func__));
@ -1047,7 +1048,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
* network and try to find a corresponding interface to take
* the source address from.
*/
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
if (sro.ro_rt == NULL || sro.ro_rt->rt_ifp == NULL) {
struct in_ifaddr *ia;
struct ifnet *ifp;
@ -1211,7 +1212,7 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
}
done:
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
if (sro.ro_rt != NULL)
RTFREE(sro.ro_rt);
return (error);

View File

@ -632,12 +632,12 @@ int inp_so_options(const struct inpcb *inp);
#define INP_INFO_LOCK_INIT(ipi, d) \
mtx_init(&(ipi)->ipi_lock, (d), NULL, MTX_DEF| MTX_RECURSE)
#define INP_INFO_LOCK_DESTROY(ipi) mtx_destroy(&(ipi)->ipi_lock)
#define INP_INFO_RLOCK_ET(ipi, et) NET_EPOCH_ENTER_ET((et))
#define INP_INFO_RLOCK_ET(ipi, et) NET_EPOCH_ENTER((et))
#define INP_INFO_WLOCK(ipi) mtx_lock(&(ipi)->ipi_lock)
#define INP_INFO_TRY_WLOCK(ipi) mtx_trylock(&(ipi)->ipi_lock)
#define INP_INFO_WLOCKED(ipi) mtx_owned(&(ipi)->ipi_lock)
#define INP_INFO_RUNLOCK_ET(ipi, et) NET_EPOCH_EXIT_ET((et))
#define INP_INFO_RUNLOCK_TP(ipi, tp) NET_EPOCH_EXIT_ET(*(tp)->t_inpcb->inp_et)
#define INP_INFO_RUNLOCK_ET(ipi, et) NET_EPOCH_EXIT((et))
#define INP_INFO_RUNLOCK_TP(ipi, tp) NET_EPOCH_EXIT(*(tp)->t_inpcb->inp_et)
#define INP_INFO_WUNLOCK(ipi) mtx_unlock(&(ipi)->ipi_lock)
#define INP_INFO_LOCK_ASSERT(ipi) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(ipi)->ipi_lock))
#define INP_INFO_RLOCK_ASSERT(ipi) MPASS(in_epoch(net_epoch_preempt))
@ -670,8 +670,8 @@ int inp_so_options(const struct inpcb *inp);
#define INP_HASH_RLOCK(ipi) struct epoch_tracker inp_hash_et; epoch_enter_preempt(net_epoch_preempt, &inp_hash_et)
#define INP_HASH_RLOCK_ET(ipi, et) epoch_enter_preempt(net_epoch_preempt, &(et))
#define INP_HASH_WLOCK(ipi) mtx_lock(&(ipi)->ipi_hash_lock)
#define INP_HASH_RUNLOCK(ipi) NET_EPOCH_EXIT_ET(inp_hash_et)
#define INP_HASH_RUNLOCK_ET(ipi, et) NET_EPOCH_EXIT_ET((et))
#define INP_HASH_RUNLOCK(ipi) NET_EPOCH_EXIT(inp_hash_et)
#define INP_HASH_RUNLOCK_ET(ipi, et) NET_EPOCH_EXIT((et))
#define INP_HASH_WUNLOCK(ipi) mtx_unlock(&(ipi)->ipi_hash_lock)
#define INP_HASH_LOCK_ASSERT(ipi) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(ipi)->ipi_hash_lock))
#define INP_HASH_WLOCK_ASSERT(ipi) mtx_assert(&(ipi)->ipi_hash_lock, MA_OWNED);

View File

@ -644,6 +644,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
struct carp_softc *sc;
uint64_t tmp_counter;
struct timeval sc_tv, ch_tv;
struct epoch_tracker et;
int error;
/*
@ -657,7 +658,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
* (these should never happen, and as noted above, we may
* miss real loops; this is just a double-check).
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
error = 0;
match = NULL;
IFNET_FOREACH_IFA(ifp, ifa) {
@ -671,7 +672,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af)
ifa = error ? NULL : match;
if (ifa != NULL)
ifa_ref(ifa);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ifa == NULL) {
if (error == ELOOP) {
@ -879,18 +880,19 @@ carp_send_ad_error(struct carp_softc *sc, int error)
static struct ifaddr *
carp_best_ifa(int af, struct ifnet *ifp)
{
struct epoch_tracker et;
struct ifaddr *ifa, *best;
if (af >= AF_MAX)
return (NULL);
best = NULL;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family == af &&
(best == NULL || ifa_preferred(best, ifa)))
best = ifa;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (best != NULL)
ifa_ref(best);
return (best);
@ -1167,10 +1169,11 @@ carp_send_na(struct carp_softc *sc)
struct ifaddr *
carp_iamatch6(struct ifnet *ifp, struct in6_addr *taddr)
{
struct epoch_tracker et;
struct ifaddr *ifa;
ifa = NULL;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1182,7 +1185,7 @@ carp_iamatch6(struct ifnet *ifp, struct in6_addr *taddr)
ifa_ref(ifa);
break;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (ifa);
}
@ -1190,16 +1193,17 @@ carp_iamatch6(struct ifnet *ifp, struct in6_addr *taddr)
caddr_t
carp_macmatch6(struct ifnet *ifp, struct mbuf *m, const struct in6_addr *taddr)
{
struct epoch_tracker et;
struct ifaddr *ifa;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
IFNET_FOREACH_IFA(ifp, ifa)
if (ifa->ifa_addr->sa_family == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(taddr, IFA_IN6(ifa))) {
struct carp_softc *sc = ifa->ifa_carp;
struct m_tag *mtag;
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
mtag = m_tag_get(PACKET_TAG_CARP,
sizeof(struct carp_softc *), M_NOWAIT);
@ -1212,7 +1216,7 @@ carp_macmatch6(struct ifnet *ifp, struct mbuf *m, const struct in6_addr *taddr)
return (LLADDR(&sc->sc_addr));
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (NULL);
}

View File

@ -465,19 +465,20 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
* Clear the port and the ifname to make sure
* there are no distractions for ifa_ifwithaddr.
*/
struct epoch_tracker et;
struct ifaddr *ifa;
bzero(sin->sin_zero, sizeof(sin->sin_zero));
sin->sin_port = 0;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
ifa = ifa_ifwithaddr((struct sockaddr *) sin);
if (ifa == NULL) {
error = EADDRNOTAVAIL;
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
goto cantsend;
}
m->m_pkthdr.rcvif = ifa->ifa_ifp;
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
#ifdef MAC
mac_socket_create_mbuf(so, m);

View File

@ -393,6 +393,7 @@ stdreply: icmpelen = max(8, min(V_icmp_quotelen, ntohs(oip->ip_len) -
int
icmp_input(struct mbuf **mp, int *offp, int proto)
{
struct epoch_tracker et;
struct icmp *icp;
struct in_ifaddr *ia;
struct mbuf *m = *mp;
@ -420,7 +421,7 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
inet_ntoa_r(ip->ip_dst, dstbuf), icmplen);
}
#endif
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
if (icmplen < ICMP_MINLEN) {
ICMPSTAT_INC(icps_tooshort);
goto freeit;
@ -428,7 +429,7 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
i = hlen + min(icmplen, ICMP_ADVLENMIN);
if (m->m_len < i && (m = m_pullup(m, i)) == NULL) {
ICMPSTAT_INC(icps_tooshort);
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (IPPROTO_DONE);
}
ip = mtod(m, struct ip *);
@ -546,7 +547,7 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
if (m->m_len < i && (m = m_pullup(m, i)) == NULL) {
/* This should actually not happen */
ICMPSTAT_INC(icps_tooshort);
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (IPPROTO_DONE);
}
ip = mtod(m, struct ip *);
@ -639,7 +640,7 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
ICMPSTAT_INC(icps_reflect);
ICMPSTAT_INC(icps_outhist[icp->icmp_type]);
icmp_reflect(m);
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (IPPROTO_DONE);
case ICMP_REDIRECT:
@ -716,13 +717,13 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
}
raw:
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
*mp = m;
rip_input(mp, offp, proto);
return (IPPROTO_DONE);
freeit:
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
m_freem(m);
return (IPPROTO_DONE);
}
@ -734,6 +735,7 @@ static void
icmp_reflect(struct mbuf *m)
{
struct rm_priotracker in_ifa_tracker;
struct epoch_tracker et;
struct ip *ip = mtod(m, struct ip *);
struct ifaddr *ifa;
struct ifnet *ifp;
@ -777,7 +779,7 @@ icmp_reflect(struct mbuf *m)
*/
ifp = m->m_pkthdr.rcvif;
if (ifp != NULL && ifp->if_flags & IFF_BROADCAST) {
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
@ -785,11 +787,11 @@ icmp_reflect(struct mbuf *m)
if (satosin(&ia->ia_broadaddr)->sin_addr.s_addr ==
t.s_addr) {
t = IA_SIN(ia)->sin_addr;
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto match;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
/*
* If the packet was transiting through us, use the address of
@ -798,16 +800,16 @@ icmp_reflect(struct mbuf *m)
* criteria apply.
*/
if (V_icmp_rfi && ifp != NULL) {
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
ia = ifatoia(ifa);
t = IA_SIN(ia)->sin_addr;
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto match;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
/*
* If the incoming packet was not addressed directly to us, use
@ -816,16 +818,16 @@ icmp_reflect(struct mbuf *m)
* with normal source selection.
*/
if (V_reply_src[0] != '\0' && (ifp = ifunit(V_reply_src))) {
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
ia = ifatoia(ifa);
t = IA_SIN(ia)->sin_addr;
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto match;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
/*
* If the packet was transiting through us, use the address of

View File

@ -709,7 +709,9 @@ ip_input(struct mbuf *m)
* into the stack for SIMPLEX interfaces handled by ether_output().
*/
if (ifp != NULL && ifp->if_flags & IFF_BROADCAST) {
IF_ADDR_RLOCK(ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET)
continue;
@ -719,7 +721,7 @@ ip_input(struct mbuf *m)
counter_u64_add(ia->ia_ifa.ifa_ipackets, 1);
counter_u64_add(ia->ia_ifa.ifa_ibytes,
m->m_pkthdr.len);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto ours;
}
#ifdef BOOTP_COMPAT
@ -727,12 +729,12 @@ ip_input(struct mbuf *m)
counter_u64_add(ia->ia_ifa.ifa_ipackets, 1);
counter_u64_add(ia->ia_ifa.ifa_ibytes,
m->m_pkthdr.len);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto ours;
}
#endif
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
ia = NULL;
}
/* RFC 3927 2.7: Do not forward datagrams for 169.254.0.0/16. */
@ -952,6 +954,7 @@ ip_forward(struct mbuf *m, int srcrt)
struct sockaddr_in *sin;
struct in_addr dest;
struct route ro;
struct epoch_tracker et;
int error, type = 0, code = 0, mtu = 0;
if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) {
@ -980,7 +983,7 @@ ip_forward(struct mbuf *m, int srcrt)
#else
in_rtalloc_ign(&ro, 0, M_GETFIB(m));
#endif
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
if (ro.ro_rt != NULL) {
ia = ifatoia(ro.ro_rt->rt_ifa);
} else
@ -1132,7 +1135,7 @@ ip_forward(struct mbuf *m, int srcrt)
}
icmp_error(mcopy, type, code, dest.s_addr, mtu);
out:
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
#define CHECK_SO_CT(sp, ct) \

View File

@ -874,16 +874,18 @@ add_vif(struct vifctl *vifcp)
*/
ifp = NULL;
} else {
struct epoch_tracker et;
sin.sin_addr = vifcp->vifc_lcl_addr;
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
ifa = ifa_ifwithaddr((struct sockaddr *)&sin);
if (ifa == NULL) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
VIF_UNLOCK();
return EADDRNOTAVAIL;
}
ifp = ifa->ifa_ifp;
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
if ((vifcp->vifc_flags & VIFF_TUNNEL) != 0) {

View File

@ -109,6 +109,7 @@ ip_dooptions(struct mbuf *m, int pass)
uint32_t ntime;
struct nhop4_extended nh_ext;
struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
struct epoch_tracker et;
/* Ignore or reject packets with IP options. */
if (V_ip_doopts == 0)
@ -119,7 +120,7 @@ ip_dooptions(struct mbuf *m, int pass)
goto bad_unlocked;
}
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
dst = ip->ip_dst;
cp = (u_char *)(ip + 1);
cnt = (ip->ip_hl << 2) - sizeof (struct ip);
@ -225,7 +226,7 @@ ip_dooptions(struct mbuf *m, int pass)
#endif
IPSTAT_INC(ips_cantforward);
m_freem(m);
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (1);
}
}
@ -380,14 +381,14 @@ ip_dooptions(struct mbuf *m, int pass)
cp[IPOPT_OFFSET] += sizeof(uint32_t);
}
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
if (forward && V_ipforwarding) {
ip_forward(m, 1);
return (1);
}
return (0);
bad:
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
bad_unlocked:
icmp_error(m, type, code, 0, 0);
IPSTAT_INC(ips_badoptions);

View File

@ -215,6 +215,7 @@ 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 epoch_tracker et;
struct ip *ip;
struct ifnet *ifp = NULL; /* keep compiler happy */
struct mbuf *m0;
@ -285,7 +286,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
dst->sin_len = sizeof(*dst);
dst->sin_addr = ip->ip_dst;
}
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
again:
/*
* Validate route against routing table additions;
@ -733,7 +734,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
* calling RTFREE on it again.
*/
ro->ro_rt = NULL;
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (error);
bad:
m_freem(m);

View File

@ -1061,6 +1061,7 @@ static struct cdev *netdump_cdev;
static int
netdump_configure(struct netdump_conf *conf, struct thread *td)
{
struct epoch_tracker et;
struct ifnet *ifp;
CURVNET_SET(TD_TO_VNET(td));
@ -1068,13 +1069,13 @@ netdump_configure(struct netdump_conf *conf, struct thread *td)
CURVNET_RESTORE();
return (EINVAL);
}
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (strcmp(ifp->if_xname, conf->ndc_iface) == 0)
break;
}
/* XXX ref */
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
CURVNET_RESTORE();
if (ifp == NULL)

View File

@ -208,11 +208,13 @@ sctp_init_ifns_for_vrf(int vrfid)
IFNET_RLOCK();
CK_STAILQ_FOREACH(ifn, &MODULE_GLOBAL(ifnet), if_link) {
struct epoch_tracker et;
if (sctp_is_desired_interface_type(ifn) == 0) {
/* non desired type */
continue;
}
IF_ADDR_RLOCK(ifn);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifn->if_addrhead, ifa_link) {
if (ifa->ifa_addr == NULL) {
continue;
@ -265,7 +267,7 @@ sctp_init_ifns_for_vrf(int vrfid)
sctp_ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
}
}
IF_ADDR_RUNLOCK(ifn);
NET_EPOCH_EXIT(et);
}
IFNET_RUNLOCK();
}

View File

@ -1655,6 +1655,7 @@ static int
ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp,
struct in6_addr *subj)
{
struct epoch_tracker et;
struct ifnet *ifp;
struct in6_ifaddr *ifa6;
struct ifaddr *ifa;
@ -1676,10 +1677,9 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp,
}
}
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
addrsofif = 0;
IF_ADDR_RLOCK(ifp);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1730,16 +1730,15 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp,
}
addrsofif++; /* count the address */
}
IF_ADDR_RUNLOCK(ifp);
if (iffound) {
*ifpp = ifp;
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (addrsofif);
}
addrs += addrsofif;
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (addrs);
}
@ -1748,6 +1747,7 @@ static int
ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6,
struct ifnet *ifp0, int resid)
{
struct epoch_tracker et;
struct ifnet *ifp;
struct in6_ifaddr *ifa6;
struct ifaddr *ifa;
@ -1760,12 +1760,11 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6,
if (ifp0 == NULL && !(niflags & NI_NODEADDR_FLAG_ALL))
return (0); /* needless to copy */
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
ifp = ifp0 ? ifp0 : CK_STAILQ_FIRST(&V_ifnet);
again:
for (; ifp; ifp = CK_STAILQ_NEXT(ifp, if_link)) {
IF_ADDR_RLOCK(ifp);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1820,13 +1819,12 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6,
/* now we can copy the address */
if (resid < sizeof(struct in6_addr) +
sizeof(u_int32_t)) {
IF_ADDR_RUNLOCK(ifp);
/*
* We give up much more copy.
* Set the truncate flag and return.
*/
nni6->ni_flags |= NI_NODEADDR_FLAG_TRUNCATE;
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (copied);
}
@ -1867,7 +1865,6 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6,
resid -= (sizeof(struct in6_addr) + sizeof(u_int32_t));
copied += (sizeof(struct in6_addr) + sizeof(u_int32_t));
}
IF_ADDR_RUNLOCK(ifp);
if (ifp0) /* we need search only on the specified IF */
break;
}
@ -1879,7 +1876,7 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6,
goto again;
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
return (copied);
}
@ -2561,13 +2558,14 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
{
/* target lladdr option */
struct epoch_tracker et;
int len;
struct nd_opt_hdr *nd_opt;
char *lladdr;
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
ln = nd6_lookup(router_ll6, 0, ifp);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ln == NULL)
goto nolladdropt;

View File

@ -1388,13 +1388,15 @@ in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia,
* if this is its first address,
*/
if (hostIsNew != 0) {
IF_ADDR_RLOCK(ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
ifacount++;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
if (ifacount <= 1 && ifp->if_ioctl) {
@ -1472,9 +1474,10 @@ in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia,
struct in6_ifaddr *
in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
{
struct epoch_tracker et;
struct ifaddr *ifa;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1486,7 +1489,7 @@ in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return ((struct in6_ifaddr *)ifa);
}
@ -1523,9 +1526,10 @@ in6ifa_ifwithaddr(const struct in6_addr *addr, uint32_t zoneid)
struct in6_ifaddr *
in6ifa_ifpwithaddr(struct ifnet *ifp, const struct in6_addr *addr)
{
struct epoch_tracker et;
struct ifaddr *ifa;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1534,7 +1538,7 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, const struct in6_addr *addr)
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return ((struct in6_ifaddr *)ifa);
}
@ -1545,12 +1549,13 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, const struct in6_addr *addr)
struct in6_ifaddr *
in6ifa_llaonifp(struct ifnet *ifp)
{
struct epoch_tracker et;
struct sockaddr_in6 *sin6;
struct ifaddr *ifa;
if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)
return (NULL);
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1560,7 +1565,7 @@ in6ifa_llaonifp(struct ifnet *ifp)
IN6_IS_ADDR_MC_NODELOCAL(&sin6->sin6_addr))
break;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return ((struct in6_ifaddr *)ifa);
}
@ -1697,6 +1702,7 @@ int
in6_ifhasaddr(struct ifnet *ifp, struct in6_addr *addr)
{
struct in6_addr in6;
struct epoch_tracker et;
struct ifaddr *ifa;
struct in6_ifaddr *ia6;
@ -1705,17 +1711,17 @@ in6_ifhasaddr(struct ifnet *ifp, struct in6_addr *addr)
return (0);
in6_setscope(&in6, ifp, NULL);
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
ia6 = (struct in6_ifaddr *)ifa;
if (IN6_ARE_ADDR_EQUAL(&ia6->ia_addr.sin6_addr, &in6)) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (1);
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (0);
}
@ -1819,6 +1825,7 @@ in6_prefixlen2mask(struct in6_addr *maskp, int len)
struct in6_ifaddr *
in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
{
struct epoch_tracker et;
int dst_scope = in6_addrscope(dst), blen = -1, tlen;
struct ifaddr *ifa;
struct in6_ifaddr *besta = NULL;
@ -1832,7 +1839,7 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
* If two or more, return one which matches the dst longest.
* If none, return one of global addresses assigned other ifs.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1866,7 +1873,7 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
}
if (besta) {
ifa_ref(&besta->ia_ifa);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (besta);
}
@ -1887,23 +1894,23 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
if (ifa != NULL)
ifa_ref(ifa);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (struct in6_ifaddr *)ifa;
}
/* use the last-resort values, that are, deprecated addresses */
if (dep[0]) {
ifa_ref((struct ifaddr *)dep[0]);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return dep[0];
}
if (dep[1]) {
ifa_ref((struct ifaddr *)dep[1]);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return dep[1];
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return NULL;
}
@ -1913,10 +1920,11 @@ in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
void
in6_if_up(struct ifnet *ifp)
{
struct epoch_tracker et;
struct ifaddr *ifa;
struct in6_ifaddr *ia;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1932,7 +1940,7 @@ in6_if_up(struct ifnet *ifp)
arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz));
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
/*
* special cases, like 6to4, are handled in in6_ifattach
@ -1973,10 +1981,11 @@ in6if_do_dad(struct ifnet *ifp)
void
in6_setmaxmtu(void)
{
struct epoch_tracker et;
unsigned long maxmtu = 0;
struct ifnet *ifp;
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
/* this function can be called during ifnet initialization */
if (!ifp->if_afdata[AF_INET6])
@ -1985,7 +1994,7 @@ in6_setmaxmtu(void)
IN6_LINKMTU(ifp) > maxmtu)
maxmtu = IN6_LINKMTU(ifp);
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
if (maxmtu) /* update only when maxmtu is positive */
V_in6_maxmtu = maxmtu;
}
@ -2163,18 +2172,19 @@ in6_lltable_rtcheck(struct ifnet *ifp,
fibnum = V_rt_add_addr_allfibs ? RT_DEFAULT_FIB : ifp->if_fib;
error = fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6);
if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) {
struct epoch_tracker et;
struct ifaddr *ifa;
/*
* Create an ND6 cache for an IPv6 neighbor
* that is not covered by our own prefix.
*/
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
ifa = ifaof_ifpforaddr(l3addr, ifp);
if (ifa != NULL) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return 0;
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
log(LOG_INFO, "IPv6 address: \"%s\" is not on the network\n",
ip6_sprintf(ip6buf, &sin6->sin6_addr));
return EINVAL;

View File

@ -240,6 +240,7 @@ generate_tmp_ifid(u_int8_t *seed0, const u_int8_t *seed1, u_int8_t *ret)
int
in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
{
struct epoch_tracker et;
struct ifaddr *ifa;
struct sockaddr_dl *sdl;
u_int8_t *addr;
@ -248,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_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_LINK)
continue;
@ -260,7 +261,7 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
goto found;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
@ -283,7 +284,7 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
/* look at IEEE802/EUI64 only */
if (addrlen != 8 && addrlen != 6) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
}
@ -293,11 +294,11 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
* card insertion.
*/
if (bcmp(addr, allzero, addrlen) == 0) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
}
if (bcmp(addr, allone, addrlen) == 0) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
}
@ -324,17 +325,17 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
* identifier source (can be renumbered).
* we don't do this.
*/
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
default:
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
}
/* sanity check: g bit must not indicate "group" */
if (EUI64_GROUP(in6)) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
}
@ -347,11 +348,11 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6)
*/
if ((in6->s6_addr[8] & ~(EUI64_GBIT | EUI64_UBIT)) == 0x00 &&
bcmp(&in6->s6_addr[9], allzero, 7) == 0) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return -1;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return 0;
}
@ -366,6 +367,7 @@ static int
get_ifid(struct ifnet *ifp0, struct ifnet *altifp,
struct in6_addr *in6)
{
struct epoch_tracker et;
struct ifnet *ifp;
/* first, try to get it from the interface itself */
@ -383,7 +385,7 @@ get_ifid(struct ifnet *ifp0, struct ifnet *altifp,
}
/* next, try to get it from some other hardware interface */
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (ifp == ifp0)
continue;
@ -398,11 +400,11 @@ get_ifid(struct ifnet *ifp0, struct ifnet *altifp,
nd6log((LOG_DEBUG,
"%s: borrow interface identifier from %s\n",
if_name(ifp0), if_name(ifp)));
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
goto success;
}
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
/* last resort: get from random number source */
if (get_rand_ifid(ifp, in6) == 0) {

View File

@ -1316,8 +1316,10 @@ in6_joingroup_locked(struct ifnet *ifp, const struct in6_addr *mcaddr,
out_in6m_release:
if (error) {
struct epoch_tracker et;
CTR2(KTR_MLD, "%s: dropping ref on %p", __func__, inm);
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_protospec == inm) {
ifma->ifma_protospec = NULL;
@ -1326,7 +1328,7 @@ in6_joingroup_locked(struct ifnet *ifp, const struct in6_addr *mcaddr,
}
in6m_disconnect(inm);
in6m_release_deferred(inm);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
} else {
*pinm = inm;
}
@ -2812,6 +2814,7 @@ sysctl_ip6_mcast_filters(SYSCTL_HANDLER_ARGS)
{
struct in6_addr mcaddr;
struct in6_addr src;
struct epoch_tracker et;
struct ifnet *ifp;
struct ifmultiaddr *ifma;
struct in6_multi *inm;
@ -2866,7 +2869,7 @@ sysctl_ip6_mcast_filters(SYSCTL_HANDLER_ARGS)
IN6_MULTI_LOCK();
IN6_MULTI_LIST_LOCK();
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET6 ||
ifma->ifma_protospec == NULL)
@ -2895,7 +2898,7 @@ sysctl_ip6_mcast_filters(SYSCTL_HANDLER_ARGS)
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
IN6_MULTI_LIST_UNLOCK();
IN6_MULTI_UNLOCK();

View File

@ -180,14 +180,15 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam,
(SO_REUSEADDR|SO_REUSEPORT_LB)) != 0)
reuseport_lb = SO_REUSEADDR|SO_REUSEPORT_LB;
} else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
struct epoch_tracker et;
struct ifaddr *ifa;
sin6->sin6_port = 0; /* yech... */
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
if ((ifa = ifa_ifwithaddr((struct sockaddr *)sin6)) ==
NULL &&
(inp->inp_flags & INP_BINDANY) == 0) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
}
@ -200,10 +201,10 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam,
if (ifa != NULL &&
((struct in6_ifaddr *)ifa)->ia6_flags &
(IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|IN6_IFF_DETACHED)) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
}
if (lport) {
struct inpcb *t;

View File

@ -749,12 +749,13 @@ in6m_lookup_locked(struct ifnet *ifp, const struct in6_addr *mcaddr)
static __inline struct in6_multi *
in6m_lookup(struct ifnet *ifp, const struct in6_addr *mcaddr)
{
struct epoch_tracker et;
struct in6_multi *inm;
IN6_MULTI_LIST_LOCK();
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
inm = in6m_lookup_locked(ifp, mcaddr);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
IN6_MULTI_LIST_UNLOCK();
return (inm);

View File

@ -628,6 +628,7 @@ static int
mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
/*const*/ struct mld_hdr *mld)
{
struct epoch_tracker et;
struct ifmultiaddr *ifma;
struct mld_ifsoftc *mli;
struct in6_multi *inm;
@ -695,7 +696,7 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
if (timer == 0)
timer = 1;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
if (is_general_query) {
/*
* For each reporting group joined on this
@ -727,7 +728,7 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
in6_clearscope(&mld->mld_addr);
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
MLD_UNLOCK();
IN6_MULTI_LIST_UNLOCK();
@ -924,6 +925,8 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
V_interface_timers_running6 = 1;
}
} else {
struct epoch_tracker et;
/*
* MLDv2 Group-specific or Group-and-source-specific Query.
*
@ -932,10 +935,10 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
* Queries for groups we are not a member of on this
* link are simply ignored.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
inm = in6m_lookup_locked(ifp, &mld->mld_addr);
if (inm == NULL) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto out_locked;
}
if (nsrc > 0) {
@ -943,7 +946,7 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
&V_mld_gsrdelay)) {
CTR1(KTR_MLD, "%s: GS query throttled.",
__func__);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
goto out_locked;
}
}
@ -961,7 +964,7 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6,
/* XXX Clear embedded scope ID as userland won't expect it. */
in6_clearscope(&mld->mld_addr);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
out_locked:
@ -1096,6 +1099,7 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6,
/*const*/ struct mld_hdr *mld)
{
struct in6_addr src, dst;
struct epoch_tracker et;
struct in6_ifaddr *ia;
struct in6_multi *inm;
#ifdef KTR
@ -1171,7 +1175,7 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6,
IN6_MULTI_LIST_LOCK();
MLD_LOCK();
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
/*
* MLDv1 report suppression.
@ -1219,7 +1223,7 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6,
}
out_locked:
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
MLD_UNLOCK();
IN6_MULTI_LIST_UNLOCK();
@ -2983,6 +2987,7 @@ mld_v2_merge_state_changes(struct in6_multi *inm, struct mbufq *scq)
static void
mld_v2_dispatch_general_query(struct mld_ifsoftc *mli)
{
struct epoch_tracker et;
struct ifmultiaddr *ifma;
struct ifnet *ifp;
struct in6_multi *inm;
@ -3005,7 +3010,7 @@ mld_v2_dispatch_general_query(struct mld_ifsoftc *mli)
ifp = mli->mli_ifp;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_INET6 ||
ifma->ifma_protospec == NULL)
@ -3036,7 +3041,7 @@ mld_v2_dispatch_general_query(struct mld_ifsoftc *mli)
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
send:
mld_dispatch_queue(&mli->mli_gq, MLD_MAX_RESPONSE_BURST);

View File

@ -298,9 +298,10 @@ nd6_ifattach(struct ifnet *ifp)
void
nd6_ifdetach(struct ifnet *ifp, struct nd_ifinfo *nd)
{
struct epoch_tracker et;
struct ifaddr *ifa, *next;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -308,7 +309,7 @@ nd6_ifdetach(struct ifnet *ifp, struct nd_ifinfo *nd)
/* stop DAD processing */
nd6_dad_stop(ifa);
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
free(nd, M_IP6NDP);
}
@ -1062,12 +1063,13 @@ nd6_timer(void *arg)
static int
regen_tmpaddr(struct in6_ifaddr *ia6)
{
struct epoch_tracker et;
struct ifaddr *ifa;
struct ifnet *ifp;
struct in6_ifaddr *public_ifa6 = NULL;
ifp = ia6->ia_ifa.ifa_ifp;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct in6_ifaddr *it6;
@ -1108,7 +1110,7 @@ regen_tmpaddr(struct in6_ifaddr *ia6)
}
if (public_ifa6 != NULL)
ifa_ref(&public_ifa6->ia_ifa);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (public_ifa6 != NULL) {
int e;
@ -1343,17 +1345,19 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
* a p2p interface, the address should be a neighbor.
*/
if (ifp->if_flags & IFF_POINTOPOINT) {
IF_ADDR_RLOCK(ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != addr->sin6_family)
continue;
if (ifa->ifa_dstaddr != NULL &&
sa_equal(addr, ifa->ifa_dstaddr)) {
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return 1;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
/*
@ -1377,6 +1381,7 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
int
nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
{
struct epoch_tracker et;
struct llentry *lle;
int rc = 0;
@ -1388,12 +1393,12 @@ nd6_is_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp)
* Even if the address matches none of our addresses, it might be
* in the neighbor cache.
*/
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
if ((lle = nd6_lookup(&addr->sin6_addr, 0, ifp)) != NULL) {
LLE_RUNLOCK(lle);
rc = 1;
}
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (rc);
}
@ -1622,6 +1627,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
struct in6_ndireq *ndi = (struct in6_ndireq *)data;
struct in6_nbrinfo *nbi = (struct in6_nbrinfo *)data;
struct in6_ndifreq *ndif = (struct in6_ndifreq *)data;
struct epoch_tracker et;
int error = 0;
if (ifp->if_afdata[AF_INET6] == NULL)
@ -1686,7 +1692,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
* do not clear ND6_IFF_IFDISABLED.
* See RFC 4862, Section 5.4.5.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
@ -1695,7 +1701,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
break;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ifa != NULL) {
/* LLA is duplicated. */
@ -1716,7 +1722,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
if (V_ip6_dad_count > 0 &&
(ND_IFINFO(ifp)->flags & ND6_IFF_NO_DAD) == 0) {
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead,
ifa_link) {
if (ifa->ifa_addr->sa_family !=
@ -1725,7 +1731,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
ia = (struct in6_ifaddr *)ifa;
ia->ia6_flags |= IN6_IFF_TENTATIVE;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
}
@ -1744,7 +1750,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
* address is assigned, and IFF_UP, try to
* assign one.
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead,
ifa_link) {
if (ifa->ifa_addr->sa_family !=
@ -1754,7 +1760,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
if (IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
break;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ifa != NULL)
/* No LLA is configured. */
in6_ifattach(ifp, NULL);
@ -1831,9 +1837,9 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
if ((error = in6_setscope(&nb_addr, ifp, NULL)) != 0)
return (error);
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
ln = nd6_lookup(&nb_addr, 0, ifp);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ln == NULL) {
error = EINVAL;
@ -1958,6 +1964,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
int flags;
uint16_t router = 0;
struct sockaddr_in6 sin6;
struct epoch_tracker et;
struct mbuf *chain = NULL;
u_char linkhdr[LLE_MAX_LINKHDR];
size_t linkhdrsize;
@ -1982,9 +1989,9 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
* description on it in NS section (RFC 2461 7.2.3).
*/
flags = lladdr ? LLE_EXCLUSIVE : 0;
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
ln = nd6_lookup(from, flags, ifp);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
is_newentry = 0;
if (ln == NULL) {
flags |= LLE_EXCLUSIVE;
@ -2126,13 +2133,14 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
static void
nd6_slowtimo(void *arg)
{
struct epoch_tracker et;
CURVNET_SET((struct vnet *) arg);
struct nd_ifinfo *nd6if;
struct ifnet *ifp;
callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
nd6_slowtimo, curvnet);
IFNET_RLOCK_NOSLEEP();
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
if (ifp->if_afdata[AF_INET6] == NULL)
continue;
@ -2149,7 +2157,7 @@ nd6_slowtimo(void *arg)
nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
}
}
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
CURVNET_RESTORE();
}
@ -2242,6 +2250,7 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
const struct sockaddr *sa_dst, u_char *desten, uint32_t *pflags,
struct llentry **plle)
{
struct epoch_tracker et;
struct llentry *ln = NULL;
const struct sockaddr_in6 *dst6;
@ -2270,7 +2279,7 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
}
}
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
ln = nd6_lookup(&dst6->sin6_addr, plle ? LLE_EXCLUSIVE : LLE_UNLOCKED,
ifp);
if (ln != NULL && (ln->r_flags & RLLE_VALID) != 0) {
@ -2290,11 +2299,11 @@ nd6_resolve(struct ifnet *ifp, int is_gw, struct mbuf *m,
*plle = ln;
LLE_WUNLOCK(ln);
}
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (0);
} else if (plle && ln)
LLE_WUNLOCK(ln);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (nd6_resolve_slow(ifp, 0, m, dst6, desten, pflags, plle));
}
@ -2328,9 +2337,11 @@ nd6_resolve_slow(struct ifnet *ifp, int flags, struct mbuf *m,
* or an anycast address(i.e. not a multicast).
*/
if (lle == NULL) {
IF_AFDATA_RLOCK(ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
lle = nd6_lookup(&dst->sin6_addr, LLE_EXCLUSIVE, ifp);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if ((lle == NULL) && nd6_is_addr_neighbor(dst, ifp)) {
/*
* Since nd6_is_addr_neighbor() internally calls nd6_lookup(),

View File

@ -613,6 +613,7 @@ nd6_ns_output(struct ifnet *ifp, const struct in6_addr *saddr6,
void
nd6_na_input(struct mbuf *m, int off, int icmp6len)
{
struct epoch_tracker et;
struct ifnet *ifp = m->m_pkthdr.rcvif;
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct nd_neighbor_advert *nd_na;
@ -740,9 +741,9 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
* If no neighbor cache entry is found, NA SHOULD silently be
* discarded.
*/
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
ln = nd6_lookup(&taddr6, LLE_EXCLUSIVE, ifp);
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ln == NULL) {
goto freeit;
}

View File

@ -511,11 +511,13 @@ nd6_rtmsg(int cmd, struct rtentry *rt)
info.rti_info[RTAX_NETMASK] = rt_mask(rt);
ifp = rt->rt_ifp;
if (ifp != NULL) {
IF_ADDR_RLOCK(ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
ifa = CK_STAILQ_FIRST(&ifp->if_addrhead);
info.rti_info[RTAX_IFP] = ifa->ifa_addr;
ifa_ref(ifa);
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
} else
ifa = NULL;
@ -789,6 +791,7 @@ defrouter_del(struct nd_defrouter *dr)
void
defrouter_select_fib(int fibnum)
{
struct epoch_tracker et;
struct nd_defrouter *dr, *selected_dr, *installed_dr;
struct llentry *ln = NULL;
@ -815,14 +818,14 @@ defrouter_select_fib(int fibnum)
*/
selected_dr = installed_dr = NULL;
TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
IF_AFDATA_RLOCK(dr->ifp);
NET_EPOCH_ENTER(et);
if (selected_dr == NULL && dr->ifp->if_fib == fibnum &&
(ln = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) &&
ND6_IS_LLINFO_PROBREACH(ln)) {
selected_dr = dr;
defrouter_ref(selected_dr);
}
IF_AFDATA_RUNLOCK(dr->ifp);
NET_EPOCH_EXIT(et);
if (ln != NULL) {
LLE_RUNLOCK(ln);
ln = NULL;
@ -866,7 +869,7 @@ defrouter_select_fib(int fibnum)
}
}
} else if (installed_dr != NULL) {
IF_AFDATA_RLOCK(installed_dr->ifp);
NET_EPOCH_ENTER(et);
if ((ln = nd6_lookup(&installed_dr->rtaddr, 0,
installed_dr->ifp)) &&
ND6_IS_LLINFO_PROBREACH(ln) &&
@ -875,7 +878,7 @@ defrouter_select_fib(int fibnum)
defrouter_rele(selected_dr);
selected_dr = installed_dr;
}
IF_AFDATA_RUNLOCK(installed_dr->ifp);
NET_EPOCH_EXIT(et);
if (ln != NULL)
LLE_RUNLOCK(ln);
}
@ -1271,6 +1274,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
int auth;
struct in6_addrlifetime lt6_tmp;
char ip6buf[INET6_ADDRSTRLEN];
struct epoch_tracker et;
auth = 0;
if (m) {
@ -1384,7 +1388,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
* consider autoconfigured addresses while RFC2462 simply said
* "address".
*/
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
struct in6_ifaddr *ifa6;
u_int32_t remaininglifetime;
@ -1507,7 +1511,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
ifa6->ia6_lifetime = lt6_tmp;
ifa6->ia6_updatetime = time_uptime;
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
if (ia6_match == NULL && new->ndpr_vltime) {
int ifidlen;
@ -1596,6 +1600,7 @@ prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
static struct nd_pfxrouter *
find_pfxlist_reachable_router(struct nd_prefix *pr)
{
struct epoch_tracker et;
struct nd_pfxrouter *pfxrtr;
struct llentry *ln;
int canreach;
@ -1603,9 +1608,9 @@ find_pfxlist_reachable_router(struct nd_prefix *pr)
ND6_LOCK_ASSERT();
LIST_FOREACH(pfxrtr, &pr->ndpr_advrtrs, pfr_entry) {
IF_AFDATA_RLOCK(pfxrtr->router->ifp);
NET_EPOCH_ENTER(et);
ln = nd6_lookup(&pfxrtr->router->rtaddr, 0, pfxrtr->router->ifp);
IF_AFDATA_RUNLOCK(pfxrtr->router->ifp);
NET_EPOCH_EXIT(et);
if (ln == NULL)
continue;
canreach = ND6_IS_LLINFO_PROBREACH(ln);
@ -1944,15 +1949,17 @@ nd6_prefix_onlink(struct nd_prefix *pr)
ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
IN6_IFF_NOTREADY | IN6_IFF_ANYCAST);
if (ifa == NULL) {
struct epoch_tracker et;
/* XXX: freebsd does not have ifa_ifwithaf */
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family == AF_INET6) {
ifa_ref(ifa);
break;
}
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
/* should we care about ia6_flags? */
}
if (ifa == NULL) {

View File

@ -727,6 +727,7 @@ rip6_disconnect(struct socket *so)
static int
rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct epoch_tracker et;
struct inpcb *inp;
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)nam;
struct ifaddr *ifa = NULL;
@ -744,20 +745,20 @@ rip6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
if ((error = sa6_embedscope(addr, V_ip6_use_defzone)) != 0)
return (error);
NET_EPOCH_ENTER();
NET_EPOCH_ENTER(et);
if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) &&
(ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
}
if (ifa != NULL &&
((struct in6_ifaddr *)ifa)->ia6_flags &
(IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|
IN6_IFF_DETACHED|IN6_IFF_DEPRECATED)) {
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
return (EADDRNOTAVAIL);
}
NET_EPOCH_EXIT();
NET_EPOCH_EXIT(et);
INP_INFO_WLOCK(&V_ripcbinfo);
INP_WLOCK(inp);
inp->in6p_laddr = addr->sin6_addr;

View File

@ -209,19 +209,20 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist)
static int
scope6_get(struct ifnet *ifp, struct scope6_id *idlist)
{
struct epoch_tracker et;
struct scope6_id *sid;
/* We only need to lock the interface's afdata for SID() to work. */
IF_AFDATA_RLOCK(ifp);
NET_EPOCH_ENTER(et);
sid = SID(ifp);
if (sid == NULL) { /* paranoid? */
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (EINVAL);
}
*idlist = *sid;
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
return (0);
}
@ -418,10 +419,12 @@ in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id)
zoneid = ifp->if_index;
in6->s6_addr16[1] = htons(zoneid & 0xffff); /* XXX */
} else if (scope != IPV6_ADDR_SCOPE_GLOBAL) {
IF_AFDATA_RLOCK(ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
sid = SID(ifp);
zoneid = sid->s6id_list[scope];
IF_AFDATA_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
}

View File

@ -300,13 +300,15 @@ pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
return (1);
if (rule_kif->pfik_group != NULL) {
IF_ADDR_RLOCK(packet_kif->pfik_ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next)
if (p->ifgl_group == rule_kif->pfik_group) {
IF_ADDR_RUNLOCK(packet_kif->pfik_ifp);
NET_EPOCH_EXIT(et);
return (1);
}
IF_ADDR_RUNLOCK(packet_kif->pfik_ifp);
NET_EPOCH_EXIT(et);
}
@ -473,11 +475,13 @@ pfi_kif_update(struct pfi_kif *kif)
/* again for all groups kif is member of */
if (kif->pfik_ifp != NULL) {
IF_ADDR_RLOCK(kif->pfik_ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next)
pfi_kif_update((struct pfi_kif *)
ifgl->ifgl_group->ifg_pf_kif);
IF_ADDR_RUNLOCK(kif->pfik_ifp);
NET_EPOCH_EXIT(et);
}
}
@ -513,10 +517,12 @@ pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
if (kif->pfik_ifp != NULL)
pfi_instance_add(kif->pfik_ifp, net, flags);
else if (kif->pfik_group != NULL) {
IFNET_RLOCK_NOSLEEP();
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
pfi_instance_add(ifgm->ifgm_ifp, net, flags);
IFNET_RUNLOCK_NOSLEEP();
NET_EPOCH_EXIT(et);
}
if ((e = pfr_set_addrs(&kt->pfrkt_t, V_pfi_buffer, V_pfi_buffer_cnt, &size2,
@ -528,11 +534,12 @@ pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
static void
pfi_instance_add(struct ifnet *ifp, int net, int flags)
{
struct epoch_tracker et;
struct ifaddr *ia;
int got4 = 0, got6 = 0;
int net2, af;
IF_ADDR_RLOCK(ifp);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
if (ia->ifa_addr == NULL)
continue;
@ -590,7 +597,7 @@ pfi_instance_add(struct ifnet *ifp, int net, int flags)
else
pfi_address_add(ia->ifa_addr, af, net2);
}
IF_ADDR_RUNLOCK(ifp);
NET_EPOCH_EXIT(et);
}
static void
@ -758,15 +765,17 @@ pfi_skip_if(const char *filter, struct pfi_kif *p)
if (filter[n-1] >= '0' && filter[n-1] <= '9')
return (1); /* group names may not end in a digit */
if (p->pfik_ifp != NULL) {
IF_ADDR_RLOCK(p->pfik_ifp);
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(i, &p->pfik_ifp->if_groups, ifgl_next) {
if (!strncmp(i->ifgl_group->ifg_group, filter,
IFNAMSIZ)) {
IF_ADDR_RUNLOCK(p->pfik_ifp);
NET_EPOCH_EXIT(et);
return (0); /* iface is in group "filter" */
}
}
IF_ADDR_RUNLOCK(p->pfik_ifp);
NET_EPOCH_EXIT(et);
}
return (1);
}

View File

@ -186,6 +186,8 @@ roce_gid_update_addr_callback(struct ib_device *device, u8 port,
CURVNET_SET(vnet_iter);
IFNET_RLOCK();
CK_STAILQ_FOREACH(idev, &V_ifnet, if_link) {
struct epoch_tracker et;
if (idev != ndev) {
if (idev->if_type != IFT_L2VLAN)
continue;
@ -194,7 +196,7 @@ roce_gid_update_addr_callback(struct ib_device *device, u8 port,
}
/* clone address information for IPv4 and IPv6 */
IF_ADDR_RLOCK(idev);
NET_EPOCH_ENTER(et);
#if defined(INET)
CK_STAILQ_FOREACH(ifa, &idev->if_addrhead, ifa_link) {
if (ifa->ifa_addr == NULL ||
@ -232,7 +234,7 @@ roce_gid_update_addr_callback(struct ib_device *device, u8 port,
STAILQ_INSERT_TAIL(&ipx_head, entry, entry);
}
#endif
IF_ADDR_RUNLOCK(idev);
NET_EPOCH_EXIT(et);
}
IFNET_RUNLOCK();
CURVNET_RESTORE();

View File

@ -1150,11 +1150,12 @@ ipoib_remove_one(struct ib_device *device, void *client_data)
static int
ipoib_match_dev_addr(const struct sockaddr *addr, struct net_device *dev)
{
struct epoch_tracker et;
struct ifaddr *ifa;
int retval = 0;
CURVNET_SET(dev->if_vnet);
IF_ADDR_RLOCK(dev);
NET_EPOCH_ENTER(et);
CK_STAILQ_FOREACH(ifa, &dev->if_addrhead, ifa_link) {
if (ifa->ifa_addr == NULL ||
ifa->ifa_addr->sa_family != addr->sa_family ||
@ -1166,7 +1167,7 @@ ipoib_match_dev_addr(const struct sockaddr *addr, struct net_device *dev)
break;
}
}
IF_ADDR_RUNLOCK(dev);
NET_EPOCH_EXIT(et);
CURVNET_RESTORE();
return (retval);