From a7fe36b40b19de7766981ad47d69f44c8eb1466d Mon Sep 17 00:00:00 2001 From: mpi Date: Tue, 13 Oct 2015 10:16:17 +0000 Subject: [PATCH] Use rtisivalid(9) to check if the given (cached) route can be used. Note that after calling rtalloc(9) we only check if a route has been returned or not and do not check for its validity. This cannot be improved without a massive refactoring. The kernel currently *do* use !RTF_UP route due to a mismatch between the value of ifp->if_link_state and the IFF_UP|IFF_RUNNING code. I'd explain the RTF_UP flag as follow: . If a cached route entry w/o RTF_UP is passed to ip{6,}_output(), . call rtalloc(9) to see if a better entry is present in the tree. This is enough to support MPATH and route cache invalidation. ok bluhm@ --- sys/netinet/ip_output.c | 6 +++--- sys/netinet6/in6_src.c | 14 ++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 24ecc1b4bdb..11af574b2b4 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.300 2015/10/07 14:52:45 deraadt Exp $ */ +/* $OpenBSD: ip_output.c,v 1.301 2015/10/13 10:16:17 mpi Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -170,9 +170,9 @@ reroute: * If there is a cached route, check that it is to the same * destination and is still up. If not, free it and try again. */ - if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || + if (!rtisvalid(ro->ro_rt) || dst->sin_addr.s_addr != ip->ip_dst.s_addr || - ro->ro_tableid != m->m_pkthdr.ph_rtableid)) { + ro->ro_tableid != m->m_pkthdr.ph_rtableid) { rtfree(ro->ro_rt); ro->ro_rt = NULL; } diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 8ab08e25cfb..bbb916efece 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.62 2015/09/18 14:26:22 mpi Exp $ */ +/* $OpenBSD: in6_src.c,v 1.63 2015/10/13 10:16:17 mpi Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -252,13 +252,12 @@ in6_selectsrc(struct in6_addr **in6src, struct sockaddr_in6 *dstsock, * our src addr is taken from the i/f, else punt. */ if (ro) { - if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || - !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, dst))) { + if (!rtisvalid(ro->ro_rt) || + !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, dst)) { rtfree(ro->ro_rt); ro->ro_rt = NULL; } - if (ro->ro_rt == (struct rtentry *)0 || - ro->ro_rt->rt_ifp == (struct ifnet *)0) { + if (ro->ro_rt == NULL) { struct sockaddr_in6 *sa6; /* No route yet, so try to acquire one */ @@ -368,10 +367,9 @@ in6_selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts, * cached destination, in case of sharing the cache with IPv4. */ if (ro) { - if (ro->ro_rt && - (!(ro->ro_rt->rt_flags & RTF_UP) || + if (!rtisvalid(ro->ro_rt) || sin6tosa(&ro->ro_dst)->sa_family != AF_INET6 || - !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, dst))) { + !IN6_ARE_ADDR_EQUAL(&ro->ro_dst.sin6_addr, dst)) { rtfree(ro->ro_rt); ro->ro_rt = NULL; } -- 2.20.1