diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-09-01 12:50:04 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-09-01 12:50:04 +0000 |
commit | e75a4737e7e5686910f3af279fc62c313c1c4cd5 (patch) | |
tree | 3b35c8b5f595589015caa183c15d7f9fefa36298 /sys/net | |
parent | 514b1d9919dfdb0357e46564ba710e95b684e4a9 (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.c | 31 | ||||
-rw-r--r-- | sys/net/route.h | 3 |
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 |