summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-08-24 22:11:35 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-08-24 22:11:35 +0000
commit96851358e44ddb0d351f3721f4d0b07a7418a20c (patch)
tree7e3d6506f230674d99ec3789bee10dfdcf7d8e4e
parentef294708a1db22bb19dd2650336e49b8ed5eeadf (diff)
Always increment the reference counter of the returned route entry in
rtrequest1(9). This simplifies rtfree(9) dances and will prevent another CPU to free the entry before we're done with it as soon as routing functions can be executed in parallel. ok bluhm@, mikeb@
-rw-r--r--sys/net/route.c21
-rw-r--r--sys/net/rtsock.c12
-rw-r--r--sys/netinet6/nd6_rtr.c19
3 files changed, 13 insertions, 39 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 56adb555ec9..69d128d1608 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.224 2015/08/20 12:39:43 mpi Exp $ */
+/* $OpenBSD: route.c,v 1.225 2015/08/24 22:11:33 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -570,14 +570,9 @@ rtdeletemsg(struct rtentry *rt, u_int tableid)
info.rti_flags = rt->rt_flags;
ifp = rt->rt_ifp;
error = rtrequest1(RTM_DELETE, &info, rt->rt_priority, &rt, tableid);
-
rt_missmsg(RTM_DELETE, &info, info.rti_flags, ifp, error, tableid);
-
- /* Adjust the refcount */
- if (error == 0 && rt->rt_refcnt <= 0) {
- rt->rt_refcnt++;
+ if (error == 0)
rtfree(rt);
- }
return (error);
}
@@ -820,12 +815,11 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
ifa->ifa_rtrequest(RTM_DELETE, rt);
rttrash++;
- if (ret_nrt)
+ rt->rt_refcnt++;
+ if (ret_nrt != NULL)
*ret_nrt = rt;
- else if (rt->rt_refcnt <= 0) {
- rt->rt_refcnt++;
+ else
rtfree(rt);
- }
break;
case RTM_RESOLVE:
@@ -1271,10 +1265,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags, struct sockaddr *dst)
rt_sendmsg(rt, RTM_DELETE, rtableid);
if (flags & RTF_LOCAL)
rt_sendaddrmsg(rt, RTM_DELADDR);
- if (rt->rt_refcnt <= 0) {
- rt->rt_refcnt++;
- rtfree(rt);
- }
+ rtfree(rt);
}
if (m != NULL)
m_free(m);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index d95cbc6654a..291bc3e2be1 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.168 2015/08/19 13:27:38 bluhm Exp $ */
+/* $OpenBSD: rtsock.c,v 1.169 2015/08/24 22:11:33 mpi Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -593,8 +593,7 @@ route_output(struct mbuf *m, ...)
error = EINVAL;
goto flush;
}
- error = rtrequest1(rtm->rtm_type, &info, prio, &saved_nrt,
- tableid);
+ error = rtrequest1(RTM_ADD, &info, prio, &saved_nrt, tableid);
if (error == 0) {
rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
&saved_nrt->rt_rmx);
@@ -606,12 +605,9 @@ route_output(struct mbuf *m, ...)
}
break;
case RTM_DELETE:
- error = rtrequest1(rtm->rtm_type, &info, prio, &saved_nrt,
- tableid);
- if (error == 0) {
- (rt = saved_nrt)->rt_refcnt++;
+ error = rtrequest1(RTM_DELETE, &info, prio, &rt, tableid);
+ if (error == 0)
goto report;
- }
break;
case RTM_GET:
case RTM_CHANGE:
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index bd06a1871b7..9c4a8df3683 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_rtr.c,v 1.117 2015/08/24 15:58:35 mpi Exp $ */
+/* $OpenBSD: nd6_rtr.c,v 1.118 2015/08/24 22:11:34 mpi Exp $ */
/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */
/*
@@ -732,14 +732,7 @@ defrouter_delreq(struct nd_defrouter *dr)
dr->ifp->if_rdomain);
if (error == 0) {
rt_sendmsg(rt, RTM_DELETE, dr->ifp->if_rdomain);
- if (rt->rt_refcnt <= 0) {
- /*
- * XXX: borrowed from the RTM_DELETE case of
- * rtrequest1().
- */
- rt->rt_refcnt++;
- rtfree(rt);
- }
+ rtfree(rt);
}
dr->installed = 0;
@@ -1904,8 +1897,8 @@ nd6_prefix_offlink(struct nd_prefix *pr)
if (error == 0) {
pr->ndpr_stateflags &= ~NDPRF_ONLINK;
- /* report the route deletion to the routing socket. */
rt_sendmsg(rt, RTM_DELETE, ifp->if_rdomain);
+ rtfree(rt);
/*
* There might be the same prefix on another interface,
@@ -1946,12 +1939,6 @@ nd6_prefix_offlink(struct nd_prefix *pr)
}
}
}
-
- if (rt->rt_refcnt <= 0) {
- /* XXX: we should free the entry ourselves. */
- rt->rt_refcnt++;
- rtfree(rt);
- }
} else {
/* XXX: can we still set the NDPRF_ONLINK flag? */
nd6log((LOG_ERR,