summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-09-01 12:50:04 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-09-01 12:50:04 +0000
commite75a4737e7e5686910f3af279fc62c313c1c4cd5 (patch)
tree3b35c8b5f595589015caa183c15d7f9fefa36298 /sys/net
parent514b1d9919dfdb0357e46564ba710e95b684e4a9 (diff)
Introduce rtisvalid(9) a function to check if a (cached) route entry
can be used or should be released by rtfree(9). It currently checks if the route is UP and is not attached to a stall ifa. ok bluhm@, claudio@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/route.c31
-rw-r--r--sys/net/route.h3
2 files changed, 24 insertions, 10 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 7ae25cb5a93..b6b5e7e03d7 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.227 2015/09/01 10:04:51 mpi Exp $ */
+/* $OpenBSD: route.c,v 1.228 2015/09/01 12:50:03 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -300,6 +300,25 @@ rtable_exists(u_int id) /* verify table with that ID exists */
return (1);
}
+/*
+ * Returns 1 if the (cached) ``rt'' entry is still valid, 0 otherwise.
+ */
+int
+rtisvalid(struct rtentry *rt)
+{
+ if (rt == NULL)
+ return (0);
+
+ if ((rt->rt_flags & RTF_UP) == 0)
+ return (0);
+
+ /* Routes attached to stall ifas should be freed. */
+ if (rt->rt_ifa == NULL || rt->rt_ifa->ifa_ifp == NULL)
+ return (0);
+
+ return (1);
+}
+
struct rtentry *
rtalloc(struct sockaddr *dst, int flags, unsigned int tableid)
{
@@ -659,19 +678,13 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
}
if (ifa == NULL) {
struct rtentry *rt = rtalloc(gateway, 0, rtableid);
- if (rt == NULL)
- return (NULL);
/* The gateway must be local if the same address family. */
- if ((rt->rt_flags & RTF_GATEWAY) &&
- rt_key(rt)->sa_family == dst->sa_family) {
+ if (!rtisvalid(rt) || ((rt->rt_flags & RTF_GATEWAY) &&
+ rt_key(rt)->sa_family == dst->sa_family)) {
rtfree(rt);
return (NULL);
}
ifa = rt->rt_ifa;
- if (ifa == NULL || ifa->ifa_ifp == NULL) {
- rtfree(rt);
- return (NULL);
- }
rtfree(rt);
}
if (ifa->ifa_addr->sa_family != dst->sa_family) {
diff --git a/sys/net/route.h b/sys/net/route.h
index 5491b45ccab..26d58590cc4 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.110 2015/08/20 12:39:43 mpi Exp $ */
+/* $OpenBSD: route.h,v 1.111 2015/09/01 12:50:03 mpi Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -377,6 +377,7 @@ void rt_timer_queue_destroy(struct rttimer_queue *);
unsigned long rt_timer_queue_count(struct rttimer_queue *);
void rt_timer_timer(void *);
+int rtisvalid(struct rtentry *);
#ifdef SMALL_KERNEL
#define rtalloc_mpath(dst, s, rid) rtalloc((dst), RT_REPORT|RT_RESOLVE, (rid))
#else