Page MenuHomeFreeBSD

D17599.diff
No OneTemporary

D17599.diff

Index: sys/net/if.c
===================================================================
--- sys/net/if.c
+++ sys/net/if.c
@@ -425,12 +425,12 @@
ifaddr_byindex(u_short idx)
{
struct ifnet *ifp;
- struct ifaddr *ifa = NULL;
+ struct ifaddr *ifa;
IFNET_RLOCK_NOSLEEP();
ifp = ifnet_byindex_locked(idx);
- if (ifp != NULL && (ifa = ifp->if_addr) != NULL)
- ifa_ref(ifa);
+ if (ifp == NULL || (ifa = ifp->if_addr) == NULL || ifa_ref(ifa) == 0)
+ ifa = NULL; /* failure */
IFNET_RUNLOCK_NOSLEEP();
return (ifa);
}
@@ -969,7 +969,7 @@
while (1) {
NET_EPOCH_ENTER();
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (ifa->ifa_addr->sa_family != AF_LINK)
+ if (ifa->ifa_addr->sa_family != AF_LINK && ifa_ref(ifa) != 0)
break;
}
NET_EPOCH_EXIT();
@@ -987,20 +987,22 @@
ifr.ifra_broadaddr = *ifa->ifa_dstaddr;
if (in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp,
NULL) == 0)
- continue;
+ goto skip;
}
#endif /* INET */
#ifdef INET6
if (ifa->ifa_addr->sa_family == AF_INET6) {
in6_purgeaddr(ifa);
/* ifp_addrhead is already updated */
- continue;
+ goto skip;
}
#endif /* INET6 */
IF_ADDR_WLOCK(ifp);
CK_STAILQ_REMOVE(&ifp->if_addrhead, ifa, ifaddr, ifa_link);
IF_ADDR_WUNLOCK(ifp);
ifa_free(ifa);
+skip:
+ ifa_free(ifa);
}
}
@@ -1834,11 +1836,11 @@
return (NULL);
}
-void
+int
ifa_ref(struct ifaddr *ifa)
{
- refcount_acquire(&ifa->ifa_refcnt);
+ return (refcount_acquire_if_not_zero(&ifa->ifa_refcnt));
}
static void
@@ -2205,12 +2207,9 @@
return;
NET_EPOCH_ENTER();
ifa = ifaof_ifpforaddr(dst, ifp);
- if (ifa) {
+ if (ifa != NULL && ifa_ref(ifa) != 0) {
oifa = rt->rt_ifa;
- if (oifa != ifa) {
- ifa_free(oifa);
- ifa_ref(ifa);
- }
+ ifa_free(oifa);
rt->rt_ifa = ifa;
if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
ifa->ifa_rtrequest(cmd, rt, info);
Index: sys/net/if_spppsubr.c
===================================================================
--- sys/net/if_spppsubr.c
+++ sys/net/if_spppsubr.c
@@ -4882,10 +4882,8 @@
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family == AF_INET) {
si = (struct sockaddr_in *)ifa->ifa_addr;
- if (si != NULL) {
- ifa_ref(ifa);
+ if (si != NULL && ifa_ref(ifa) != 0)
break;
- }
}
}
if_addr_runlock(ifp);
@@ -4999,8 +4997,9 @@
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
- if (sin6 && IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- ifa_ref(ifa);
+ if (sin6 != NULL &&
+ IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
+ ifa_ref(ifa) != 0) {
break;
}
}
Index: sys/net/if_var.h
===================================================================
--- sys/net/if_var.h
+++ sys/net/if_var.h
@@ -548,7 +548,7 @@
struct ifaddr * ifa_alloc(size_t size, int flags);
void ifa_free(struct ifaddr *ifa);
-void ifa_ref(struct ifaddr *ifa);
+int ifa_ref(struct ifaddr *ifa) __result_use_check;
/*
* Multicast address structure. This is analogous to the ifaddr
Index: sys/net/route.c
===================================================================
--- sys/net/route.c
+++ sys/net/route.c
@@ -652,19 +652,22 @@
RTFREE_LOCKED(rt);
flags |= RTF_DYNAMIC;
- bzero((caddr_t)&info, sizeof(info));
- info.rti_info[RTAX_DST] = dst;
- info.rti_info[RTAX_GATEWAY] = gateway;
- info.rti_info[RTAX_NETMASK] = netmask;
- ifa_ref(ifa);
- info.rti_ifa = ifa;
- info.rti_flags = flags;
- error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
- if (rt != NULL) {
- RT_LOCK(rt);
- flags = rt->rt_flags;
+
+ if (ifa_ref(ifa) != 0) {
+ bzero((caddr_t)&info, sizeof(info));
+ info.rti_info[RTAX_DST] = dst;
+ info.rti_info[RTAX_GATEWAY] = gateway;
+ info.rti_info[RTAX_NETMASK] = netmask;
+ info.rti_ifa = ifa;
+ info.rti_flags = flags;
+ error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum);
+ if (rt != NULL) {
+ RT_LOCK(rt);
+ flags = rt->rt_flags;
+ }
+ } else {
+ error = ENXIO;
}
-
stat = &V_rtstat.rts_dynamic;
} else {
@@ -903,7 +906,8 @@
info->rti_flags = rt->rt_flags;
info->rti_ifp = rt->rt_ifp;
info->rti_ifa = rt->rt_ifa;
- ifa_ref(info->rti_ifa);
+ if (ifa_ref(info->rti_ifa) == 0)
+ return (ENXIO);
if (flags & NHR_REF) {
/* Do 'traditional' refcouting */
if_ref(info->rti_ifp);
@@ -1313,7 +1317,8 @@
if (needref && info->rti_ifa != NULL) {
if (info->rti_ifp == NULL)
info->rti_ifp = info->rti_ifa->ifa_ifp;
- ifa_ref(info->rti_ifa);
+ if (ifa_ref(info->rti_ifa) == 0)
+ error = ENXIO;
} else
error = ENETUNREACH;
NET_EPOCH_EXIT();
@@ -1627,7 +1632,11 @@
* examine the ifa and ifa->ifa_ifp if it so desires.
*/
ifa = info->rti_ifa;
- ifa_ref(ifa);
+ if (ifa_ref(ifa) == 0) {
+ R_Free(rt_key(rt));
+ uma_zfree(V_rtzone, rt);
+ return (ENXIO);
+ }
rt->rt_ifa = ifa;
rt->rt_ifp = ifa->ifa_ifp;
rt->rt_weight = 1;
@@ -1805,7 +1814,11 @@
}
if (info->rti_ifa != NULL && info->rti_ifa != rt->rt_ifa) {
- ifa_ref(info->rti_ifa);
+ if (ifa_ref(info->rti_ifa) == 0) {
+ error = ENXIO;
+ free_ifa = 0;
+ goto bad;
+ }
rt->rt_ifa = info->rti_ifa;
rt->rt_ifp = info->rti_ifp;
}
@@ -1970,6 +1983,8 @@
}
if (dst->sa_len == 0)
return(EINVAL);
+ if (ifa_ref(ifa) == 0)
+ return (ENXIO);
switch (dst->sa_family) {
case AF_INET6:
case AF_INET:
@@ -2063,7 +2078,8 @@
* Do the actual request
*/
bzero((caddr_t)&info, sizeof(info));
- ifa_ref(ifa);
+ if (ifa_ref(ifa) == 0)
+ panic("Cannot get reference on ifa\n");
info.rti_ifa = ifa;
info.rti_flags = flags |
(ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED;
@@ -2095,7 +2111,8 @@
if (memcmp(rt->rt_ifa->ifa_addr,
ifa->ifa_addr, ifa->ifa_addr->sa_len)) {
ifa_free(rt->rt_ifa);
- ifa_ref(ifa);
+ if (ifa_ref(ifa) == 0)
+ panic("Cannot get reference on ifa\n");
rt->rt_ifp = ifa->ifa_ifp;
rt->rt_ifa = ifa;
}
@@ -2150,6 +2167,7 @@
error = a_failure;
}
}
+ ifa_free(ifa);
return (error);
}
Index: sys/netinet/if_ether.c
===================================================================
--- sys/netinet/if_ether.c
+++ sys/netinet/if_ether.c
@@ -843,8 +843,8 @@
ia->ia_ifp == ifp) &&
itaddr.s_addr == ia->ia_addr.sin_addr.s_addr &&
(ia->ia_ifa.ifa_carp == NULL ||
- (*carp_iamatch_p)(&ia->ia_ifa, &enaddr))) {
- ifa_ref(&ia->ia_ifa);
+ (*carp_iamatch_p)(&ia->ia_ifa, &enaddr)) &&
+ ifa_ref(&ia->ia_ifa) != 0) {
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
goto match;
}
@@ -852,8 +852,8 @@
LIST_FOREACH(ia, INADDR_HASH(isaddr.s_addr), ia_hash)
if (((bridged && ia->ia_ifp->if_bridge == ifp->if_bridge) ||
ia->ia_ifp == ifp) &&
- isaddr.s_addr == ia->ia_addr.sin_addr.s_addr) {
- ifa_ref(&ia->ia_ifa);
+ isaddr.s_addr == ia->ia_addr.sin_addr.s_addr &&
+ ifa_ref(&ia->ia_ifa) != 0) {
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
goto match;
}
@@ -870,8 +870,8 @@
*/
if (is_bridge) {
LIST_FOREACH(ia, INADDR_HASH(itaddr.s_addr), ia_hash) {
- if (BDG_MEMBER_MATCHES_ARP(itaddr.s_addr, ifp, ia)) {
- ifa_ref(&ia->ia_ifa);
+ if (BDG_MEMBER_MATCHES_ARP(itaddr.s_addr, ifp, ia) &&
+ ifa_ref(&ia->ia_ifa) != 0) {
ifp = ia->ia_ifp;
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
goto match;
@@ -889,9 +889,9 @@
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))) {
+ (*carp_iamatch_p)(ifa, &enaddr)) &&
+ ifa_ref(ifa) != 0) {
ia = ifatoia(ifa);
- ifa_ref(ifa);
IF_ADDR_RUNLOCK(ifp);
goto match;
}
@@ -901,11 +901,11 @@
* If bridging, fall back to using any inet address.
*/
IN_IFADDR_RLOCK(&in_ifa_tracker);
- if (!bridged || (ia = CK_STAILQ_FIRST(&V_in_ifaddrhead)) == NULL) {
+ if (!bridged || (ia = CK_STAILQ_FIRST(&V_in_ifaddrhead)) == NULL ||
+ ifa_ref(&ia->ia_ifa) == 0) {
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
goto drop;
}
- ifa_ref(&ia->ia_ifa);
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
match:
if (!enaddr)
@@ -1399,9 +1399,10 @@
IF_ADDR_WLOCK(ia->ia_ifa.ifa_ifp);
ia->ia_garp_count = 0;
- if (callout_reset(&ia->ia_garp_timer, (1 << ia->ia_garp_count) * hz,
- garp_rexmit, ia) == 0) {
- ifa_ref(ifa);
+ if (ifa_ref(ifa) != 0 &&
+ callout_reset(&ia->ia_garp_timer, (1 << ia->ia_garp_count) * hz,
+ garp_rexmit, ia) != 0) {
+ ifa_free(ifa);
}
IF_ADDR_WUNLOCK(ia->ia_ifa.ifa_ifp);
}
Index: sys/netinet/in.c
===================================================================
--- sys/netinet/in.c
+++ sys/netinet/in.c
@@ -170,8 +170,8 @@
IN_IFADDR_RLOCK(&in_ifa_tracker);
LIST_FOREACH(it, INADDR_HASH(in), ia_hash) {
- if (it != ia && IA_SIN(it)->sin_addr.s_addr == in) {
- ifa_ref(&it->ia_ifa);
+ if (it != ia && IA_SIN(it)->sin_addr.s_addr == in &&
+ ifa_ref(&it->ia_ifa) != 0) {
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
return (it);
}
@@ -458,11 +458,12 @@
CK_STAILQ_INSERT_TAIL(&ifp->if_addrhead, ifa, ifa_link);
IF_ADDR_WUNLOCK(ifp);
- ifa_ref(ifa); /* in_ifaddrhead */
- IN_IFADDR_WLOCK();
- CK_STAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link);
- LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
- IN_IFADDR_WUNLOCK();
+ if (ifa_ref(ifa) != 0) {
+ IN_IFADDR_WLOCK();
+ CK_STAILQ_INSERT_TAIL(&V_in_ifaddrhead, ia, ia_link);
+ LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
+ IN_IFADDR_WUNLOCK();
+ }
/*
* Give the interface a chance to initialize
@@ -865,8 +866,8 @@
* the route itself to it. Make sure that routing daemons
* get a heads-up.
*/
- if ((ia->ia_flags & IFA_ROUTE) == 0) {
- ifa_ref(&ia->ia_ifa);
+ if ((ia->ia_flags & IFA_ROUTE) == 0 &&
+ ifa_ref(&ia->ia_ifa) != 0) {
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
error = rtinit(&(target->ia_ifa), (int)RTM_DELETE,
rtinitflags(target));
Index: sys/netinet/ip_carp.c
===================================================================
--- sys/netinet/ip_carp.c
+++ sys/netinet/ip_carp.c
@@ -669,8 +669,8 @@
error = ELOOP;
}
ifa = error ? NULL : match;
- if (ifa != NULL)
- ifa_ref(ifa);
+ if (ifa != NULL && ifa_ref(ifa) == 0)
+ ifa = NULL;
IF_ADDR_RUNLOCK(ifp);
if (ifa == NULL) {
@@ -891,8 +891,8 @@
best = ifa;
}
IF_ADDR_RUNLOCK(ifp);
- if (best != NULL)
- ifa_ref(best);
+ if (best != NULL && ifa_ref(best) == 0)
+ best = NULL;
return (best);
}
@@ -1176,10 +1176,10 @@
continue;
if (!IN6_ARE_ADDR_EQUAL(taddr, IFA_IN6(ifa)))
continue;
- if (ifa->ifa_carp && ifa->ifa_carp->sc_state != MASTER)
+ if ((ifa->ifa_carp && ifa->ifa_carp->sc_state != MASTER) ||
+ ifa_ref(ifa) == 0) {
ifa = NULL;
- else
- ifa_ref(ifa);
+ }
break;
}
IF_ADDR_RUNLOCK(ifp);
@@ -1890,6 +1890,9 @@
KASSERT(ifa->ifa_carp == NULL, ("%s: ifa %p attached", __func__, ifa));
+ if (ifa_ref(ifa) == 0)
+ return (ENXIO);
+
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
@@ -1899,28 +1902,28 @@
#endif
break;
default:
- return (EPROTOTYPE);
+ error = EPROTOTYPE;
+ goto err;
}
sx_xlock(&carp_sx);
if (ifp->if_carp == NULL) {
- sx_xunlock(&carp_sx);
- return (ENOPROTOOPT);
+ error = ENOPROTOOPT;
+ goto err_unlock;
}
IFNET_FOREACH_CARP(ifp, sc)
if (sc->sc_vhid == vhid)
break;
if (sc == NULL) {
- sx_xunlock(&carp_sx);
- return (ENOENT);
+ error = ENOENT;
+ goto err_unlock;
}
error = carp_multicast_setup(cif, ifa->ifa_addr->sa_family);
if (error) {
CIF_FREE(cif);
- sx_xunlock(&carp_sx);
- return (error);
+ goto err_unlock;
}
index = sc->sc_naddrs + sc->sc_naddrs6 + 1;
@@ -1942,8 +1945,6 @@
#endif
}
- ifa_ref(ifa);
-
CARP_LOCK(sc);
sc->sc_ifas[index - 1] = ifa;
ifa->ifa_carp = sc;
@@ -1954,6 +1955,12 @@
sx_xunlock(&carp_sx);
return (0);
+
+err_unlock:
+ sx_xunlock(&carp_sx);
+err:
+ ifa_free(ifa);
+ return (error);
}
void
Index: sys/netinet/raw_ip.c
===================================================================
--- sys/netinet/raw_ip.c
+++ sys/netinet/raw_ip.c
@@ -758,8 +758,8 @@
IN_IFADDR_RLOCK(&in_ifa_tracker);
CK_STAILQ_FOREACH(ia, &V_in_ifaddrhead, ia_link) {
if (ia->ia_ifa.ifa_addr == sa
- && (ia->ia_flags & IFA_ROUTE)) {
- ifa_ref(&ia->ia_ifa);
+ && (ia->ia_flags & IFA_ROUTE) &&
+ ifa_ref(&ia->ia_ifa) != 0) {
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
/*
* in_scrubprefix() kills the interface route.
@@ -786,11 +786,11 @@
if (ia->ia_ifa.ifa_addr == sa)
break;
}
- if (ia == NULL || (ia->ia_flags & IFA_ROUTE)) {
+ if (ia == NULL || (ia->ia_flags & IFA_ROUTE) ||
+ ifa_ref(&ia->ia_ifa) == 0) {
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
return;
}
- ifa_ref(&ia->ia_ifa);
IN_IFADDR_RUNLOCK(&in_ifa_tracker);
flags = RTF_UP;
ifp = ia->ia_ifa.ifa_ifp;
Index: sys/netinet6/in6.c
===================================================================
--- sys/netinet6/in6.c
+++ sys/netinet6/in6.c
@@ -1118,17 +1118,17 @@
}
ia->ia_ifp = ifp;
- ifa_ref(&ia->ia_ifa); /* if_addrhead */
- IF_ADDR_WLOCK(ifp);
- CK_STAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
- IF_ADDR_WUNLOCK(ifp);
-
- ifa_ref(&ia->ia_ifa); /* in6_ifaddrhead */
- IN6_IFADDR_WLOCK();
- CK_STAILQ_INSERT_TAIL(&V_in6_ifaddrhead, ia, ia_link);
- CK_LIST_INSERT_HEAD(IN6ADDR_HASH(&ia->ia_addr.sin6_addr), ia, ia6_hash);
- IN6_IFADDR_WUNLOCK();
-
+ if (ifa_ref(&ia->ia_ifa) != 0) {
+ IF_ADDR_WLOCK(ifp);
+ CK_STAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
+ IF_ADDR_WUNLOCK(ifp);
+ }
+ if (ifa_ref(&ia->ia_ifa) != 0) {
+ IN6_IFADDR_WLOCK();
+ CK_STAILQ_INSERT_TAIL(&V_in6_ifaddrhead, ia, ia_link);
+ CK_LIST_INSERT_HEAD(IN6ADDR_HASH(&ia->ia_addr.sin6_addr), ia, ia6_hash);
+ IN6_IFADDR_WUNLOCK();
+ }
return (ia);
}
@@ -1457,11 +1457,11 @@
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
"Invoking IPv6 network device address event may sleep");
- ifa_ref(&ia->ia_ifa);
- EVENTHANDLER_INVOKE(ifaddr_event_ext, ifp, &ia->ia_ifa,
- IFADDR_EVENT_ADD);
- ifa_free(&ia->ia_ifa);
-
+ if (ifa_ref(&ia->ia_ifa) != 0) {
+ EVENTHANDLER_INVOKE(ifaddr_event_ext, ifp, &ia->ia_ifa,
+ IFADDR_EVENT_ADD);
+ ifa_free(&ia->ia_ifa);
+ }
return (error);
}
@@ -1480,10 +1480,8 @@
continue;
if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) {
if ((((struct in6_ifaddr *)ifa)->ia6_flags &
- ignoreflags) != 0)
- continue;
- ifa_ref(ifa);
- break;
+ ignoreflags) == 0 && ifa_ref(ifa) != 0)
+ break;
}
}
IF_ADDR_RUNLOCK(ifp);
@@ -1508,8 +1506,8 @@
if (zoneid != 0 &&
zoneid != ia->ia_addr.sin6_scope_id)
continue;
- ifa_ref(&ia->ia_ifa);
- break;
+ if (ifa_ref(&ia->ia_ifa) != 0)
+ break;
}
}
IN6_IFADDR_RUNLOCK(&in6_ifa_tracker);
@@ -1529,10 +1527,9 @@
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
- if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa))) {
- ifa_ref(ifa);
+ if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa)) &&
+ ifa_ref(ifa) != 0)
break;
- }
}
IF_ADDR_RUNLOCK(ifp);
@@ -1864,8 +1861,7 @@
besta = (struct in6_ifaddr *)ifa;
}
}
- if (besta) {
- ifa_ref(&besta->ia_ifa);
+ if (besta && ifa_ref(&besta->ia_ifa) != 0) {
IF_ADDR_RUNLOCK(ifp);
return (besta);
}
@@ -1884,21 +1880,18 @@
dep[1] = (struct in6_ifaddr *)ifa;
continue;
}
-
- if (ifa != NULL)
- ifa_ref(ifa);
+ if (ifa_ref(ifa) == 0)
+ continue;
IF_ADDR_RUNLOCK(ifp);
return (struct in6_ifaddr *)ifa;
}
/* use the last-resort values, that are, deprecated addresses */
- if (dep[0]) {
- ifa_ref((struct ifaddr *)dep[0]);
+ if (dep[0] && ifa_ref((struct ifaddr *)dep[0]) != 0) {
IF_ADDR_RUNLOCK(ifp);
return dep[0];
}
- if (dep[1]) {
- ifa_ref((struct ifaddr *)dep[1]);
+ if (dep[1] && ifa_ref((struct ifaddr *)dep[1]) != 0) {
IF_ADDR_RUNLOCK(ifp);
return dep[1];
}
Index: sys/netinet6/nd6.c
===================================================================
--- sys/netinet6/nd6.c
+++ sys/netinet6/nd6.c
@@ -1106,8 +1106,9 @@
if (!IFA6_IS_DEPRECATED(it6))
public_ifa6 = it6;
}
- if (public_ifa6 != NULL)
- ifa_ref(&public_ifa6->ia_ifa);
+ if (public_ifa6 != NULL &&
+ ifa_ref(&public_ifa6->ia_ifa) == 0)
+ public_ifa6 = NULL;
IF_ADDR_RUNLOCK(ifp);
if (public_ifa6 != NULL) {
Index: sys/netinet6/nd6_nbr.c
===================================================================
--- sys/netinet6/nd6_nbr.c
+++ sys/netinet6/nd6_nbr.c
@@ -1261,12 +1261,16 @@
return;
}
+ if (ifa_ref(ifa) == 0)
+ return; /* Network address has been freed */
+
dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT | M_ZERO);
if (dp == NULL) {
log(LOG_ERR, "nd6_dad_start: memory allocation failed for "
"%s(%s)\n",
ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
+ ifa_free(ifa);
return;
}
callout_init(&dp->dad_timer_ch, 0);
@@ -1283,7 +1287,6 @@
* (re)initialization.
*/
dp->dad_ifa = ifa;
- ifa_ref(dp->dad_ifa);
dp->dad_count = V_ip6_dad_count;
dp->dad_ns_icount = dp->dad_na_icount = 0;
dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
Index: sys/netinet6/nd6_rtr.c
===================================================================
--- sys/netinet6/nd6_rtr.c
+++ sys/netinet6/nd6_rtr.c
@@ -480,7 +480,8 @@
IF_ADDR_RLOCK(ifp);
ifa = CK_STAILQ_FIRST(&ifp->if_addrhead);
info.rti_info[RTAX_IFP] = ifa->ifa_addr;
- ifa_ref(ifa);
+ if (ifa_ref(ifa) == 0)
+ ifa = NULL;
IF_ADDR_RUNLOCK(ifp);
info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
} else
@@ -1909,8 +1910,8 @@
/* XXX: freebsd does not have ifa_ifwithaf */
IF_ADDR_RLOCK(ifp);
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (ifa->ifa_addr->sa_family == AF_INET6) {
- ifa_ref(ifa);
+ if (ifa->ifa_addr->sa_family == AF_INET6 &&
+ ifa_ref(ifa) != 0) {
break;
}
}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 15, 8:54 PM (17 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28755567
Default Alt Text
D17599.diff (17 KB)

Event Timeline