summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2014-12-29 11:53:59 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2014-12-29 11:53:59 +0000
commitd97ba7c30eb5559f8bc676a7f6eb22b6db8d8ce8 (patch)
treec6c65204f194df9304eba8a35ac201ce5b91b1ae /sys
parentc9431520221ee6197a91e89b3796a4d783ddb6ab (diff)
Assert that rtrequest1(9) is always called at IPL_SOFTNET instead of
doing a spl dance. This matters for RTM_DELETE because a deleted route entry is always returned without having its reference counter increased when an `rtp' argument is given. In this case, we do not want to call splx() that might free this route. Inputs from millert@, ok blambert@, mikeb@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/route.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index d6b616be00d..05f56763c50 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.195 2014/12/19 18:57:17 bluhm Exp $ */
+/* $OpenBSD: route.c,v 1.196 2014/12/29 11:53:58 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -709,28 +709,29 @@ int
rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
struct rtentry **ret_nrt, u_int tableid)
{
- int s = splsoftnet(); int error = 0;
struct rtentry *rt, *crt;
struct radix_node *rn;
struct radix_node_head *rnh;
struct ifaddr *ifa;
struct sockaddr *ndst;
struct sockaddr_rtlabel *sa_rl, sa_rl2;
+ int error;
#ifdef MPLS
struct sockaddr_mpls *sa_mpls;
#endif
-#define senderr(x) { error = x ; goto bad; }
+
+ splsoftassert(IPL_SOFTNET);
if ((rnh = rtable_get(tableid, info->rti_info[RTAX_DST]->sa_family)) ==
NULL)
- senderr(EAFNOSUPPORT);
+ return (EAFNOSUPPORT);
if (info->rti_flags & RTF_HOST)
info->rti_info[RTAX_NETMASK] = NULL;
switch (req) {
case RTM_DELETE:
if ((rn = rnh->rnh_lookup(info->rti_info[RTAX_DST],
info->rti_info[RTAX_NETMASK], rnh)) == NULL)
- senderr(ESRCH);
+ return (ESRCH);
rt = (struct rtentry *)rn;
#ifndef SMALL_KERNEL
/*
@@ -744,7 +745,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
if (!rt ||
(!info->rti_info[RTAX_GATEWAY] &&
rt->rt_flags & RTF_MPATH))
- senderr(ESRCH);
+ return (ESRCH);
}
#endif
@@ -755,11 +756,11 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
*/
if ((rt->rt_flags & (RTF_LOCAL|RTF_BROADCAST)) &&
prio != RTP_LOCAL)
- senderr(EINVAL);
+ return (EINVAL);
if ((rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST],
info->rti_info[RTAX_NETMASK], rnh, rn)) == NULL)
- senderr(ESRCH);
+ return (ESRCH);
rt = (struct rtentry *)rn;
/* clean up any cloned children */
@@ -794,9 +795,9 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
case RTM_RESOLVE:
if (ret_nrt == NULL || (rt = *ret_nrt) == NULL)
- senderr(EINVAL);
+ return (EINVAL);
if ((rt->rt_flags & RTF_CLONING) == 0)
- senderr(EINVAL);
+ return (EINVAL);
if (rt->rt_ifa->ifa_ifp) {
info->rti_ifa = rt->rt_ifa;
} else {
@@ -822,11 +823,11 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
case RTM_ADD:
if (info->rti_ifa == NULL && (error = rt_getifa(info, tableid)))
- senderr(error);
+ return (error);
ifa = info->rti_ifa;
rt = pool_get(&rtentry_pool, PR_NOWAIT | PR_ZERO);
if (rt == NULL)
- senderr(ENOBUFS);
+ return (ENOBUFS);
rt->rt_flags = info->rti_flags;
@@ -837,7 +838,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
if ((error = rt_setgate(rt, info->rti_info[RTAX_DST],
info->rti_info[RTAX_GATEWAY], tableid))) {
pool_put(&rtentry_pool, rt);
- senderr(error);
+ return (error);
}
ndst = rt_key(rt);
if (info->rti_info[RTAX_NETMASK] != NULL) {
@@ -856,7 +857,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
rtfree(rt->rt_gwroute);
free(rt_key(rt), M_RTABLE, 0);
pool_put(&rtentry_pool, rt);
- senderr(EEXIST);
+ return (EEXIST);
}
/* check the link state since the table supports it */
if (LINK_STATE_IS_UP(ifa->ifa_ifp->if_link_state) &&
@@ -893,7 +894,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
rtfree(rt->rt_gwroute);
free(rt_key(rt), M_RTABLE, 0);
pool_put(&rtentry_pool, rt);
- senderr(ENOMEM);
+ return (ENOMEM);
}
rt_mpls = (struct rt_mpls *)rt->rt_llinfo;
@@ -963,7 +964,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
rtfree(rt->rt_gwroute);
free(rt_key(rt), M_RTABLE, 0);
pool_put(&rtentry_pool, rt);
- senderr(EEXIST);
+ return (EEXIST);
}
if (ifa->ifa_rtrequest)
@@ -981,9 +982,8 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio,
info->rti_info[RTAX_NETMASK]);
break;
}
-bad:
- splx(s);
- return (error);
+
+ return (0);
}
int