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:
parent
2e6756f35d
commit
6d8cc191f9
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
78
sys/net/if.c
78
sys/net/if.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user