diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-08-24 22:11:35 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-08-24 22:11:35 +0000 |
commit | 96851358e44ddb0d351f3721f4d0b07a7418a20c (patch) | |
tree | 7e3d6506f230674d99ec3789bee10dfdcf7d8e4e | |
parent | ef294708a1db22bb19dd2650336e49b8ed5eeadf (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.c | 21 | ||||
-rw-r--r-- | sys/net/rtsock.c | 12 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 19 |
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, |