From 96851358e44ddb0d351f3721f4d0b07a7418a20c Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Mon, 24 Aug 2015 22:11:35 +0000 Subject: 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@ --- sys/net/route.c | 21 ++++++--------------- sys/net/rtsock.c | 12 ++++-------- 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, -- cgit v1.2.3