aboutsummaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorMatt Macy <mmacy@FreeBSD.org>2018-05-29 00:53:53 +0000
committerMatt Macy <mmacy@FreeBSD.org>2018-05-29 00:53:53 +0000
commit1ebec5faf41f65a793b4f4217d7a67125c877510 (patch)
tree03d65f0506109173c2c435a4477f918c522ba37d /sys/net/if.c
parent20c44ba36bb677af339a0c1ddbee70b8a34e159a (diff)
downloadsrc-1ebec5faf41f65a793b4f4217d7a67125c877510.tar.gz
src-1ebec5faf41f65a793b4f4217d7a67125c877510.zip
route: fix missed ref adds
- ensure that we bump the ifa ref whenever we add a reference - defer freeing epoch protected references until after the if_purgaddrs loop
Notes
Notes: svn path=/head/; revision=334305
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 7cecaf73fe34..37ed26092c0c 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -967,7 +967,7 @@ if_purgeaddrs(struct ifnet *ifp)
{
struct ifaddr *ifa, *next;
- /* XXX cannot hold IF_ADDR_WLOCK over called functions. */
+ NET_EPOCH_ENTER();
CK_STAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) {
if (ifa->ifa_addr->sa_family == AF_LINK)
continue;
@@ -997,6 +997,7 @@ if_purgeaddrs(struct ifnet *ifp)
IF_ADDR_WUNLOCK(ifp);
ifa_free(ifa);
}
+ NET_EPOCH_EXIT();
}
/*
@@ -2196,6 +2197,10 @@ link_rtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info)
ifa = ifaof_ifpforaddr(dst, ifp);
if (ifa) {
oifa = rt->rt_ifa;
+ if (oifa != ifa) {
+ ifa_free(oifa);
+ ifa_ref(ifa);
+ }
rt->rt_ifa = ifa;
if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
ifa->ifa_rtrequest(cmd, rt, info);
@@ -3675,10 +3680,8 @@ if_delmulti_ifma_flags(struct ifmultiaddr *ifma, int flags)
CK_STAILQ_FOREACH(oifp, &V_ifnet, if_link)
if (ifp == oifp)
break;
- if (ifp != oifp) {
- printf("%s: ifnet %p disappeared\n", __func__, ifp);
+ if (ifp != oifp)
ifp = NULL;
- }
IFNET_RUNLOCK_NOSLEEP();
}
#endif