summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2018-02-20 12:43:03 +0000
committermpi <mpi@openbsd.org>2018-02-20 12:43:03 +0000
commit3faac5dafca6aff40c5796be7987b18327924c62 (patch)
tree48e46f0bb98ad1b019450de3bf89a0cd763c2fab
parentIntroduce enternewpgrp() & enterthispgrp(), from FreeBSD via guenther@. (diff)
downloadwireguard-openbsd-3faac5dafca6aff40c5796be7987b18327924c62.tar.xz
wireguard-openbsd-3faac5dafca6aff40c5796be7987b18327924c62.zip
Removing an RTF_CLONING route entry should not invalidate an RTF_CACHED
entry that has been cloned from a different RTF_CLONING route. Bug report & ok friehm@
-rw-r--r--sys/net/route.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index acd6c1d3b62..8a5cbd62e93 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.371 2018/02/10 09:17:56 mpi Exp $ */
+/* $OpenBSD: route.c,v 1.372 2018/02/20 12:43:03 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -707,26 +707,31 @@ rtequal(struct rtentry *a, struct rtentry *b)
int
rtflushclone1(struct rtentry *rt, void *arg, u_int id)
{
- struct rtentry *parent = arg;
+ struct rtentry *cloningrt = arg;
struct ifnet *ifp;
int error;
- ifp = if_get(rt->rt_ifidx);
+ if (!ISSET(rt->rt_flags, RTF_CLONED))
+ return 0;
+
+ /* Cached route must stay alive as long as their parent are alive. */
+ if (ISSET(rt->rt_flags, RTF_CACHED) && (rt->rt_parent != cloningrt))
+ return 0;
+ if (!rtequal(rt->rt_parent, cloningrt))
+ return 0;
/*
* This happens when an interface with a RTF_CLONING route is
* being detached. In this case it's safe to bail because all
* the routes are being purged by rt_ifa_purge().
*/
+ ifp = if_get(rt->rt_ifidx);
if (ifp == NULL)
return 0;
- if (ISSET(rt->rt_flags, RTF_CLONED) && rtequal(rt->rt_parent, parent)) {
- error = rtdeletemsg(rt, ifp, id);
- if (error == 0)
- error = EAGAIN;
- } else
- error = 0;
+ error = rtdeletemsg(rt, ifp, id);
+ if (error == 0)
+ error = EAGAIN;
if_put(ifp);
return error;