Turns out that our stack does a very bad job at tracking which routes should be used or not based on the RTF_UP flag. So I'm not going to change that.
Nonetheless I'd like to use rtisvalid(9) for the existing route validity checks. This will allow me to move the guts of rt_checkgate() inside rtalloc(9). If rtalloc(9) returns a !RTF_UP route, we'll still try to use it, like it is now. This is good enough to le me make progress on unlocking the routing table. Ok? Index: netinet/ip_output.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_output.c,v retrieving revision 1.300 diff -u -p -r1.300 ip_output.c --- netinet/ip_output.c 7 Oct 2015 14:52:45 -0000 1.300 +++ netinet/ip_output.c 12 Oct 2015 11:42:52 -0000 @@ -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; } Index: netinet6/in6_src.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_src.c,v retrieving revision 1.62 diff -u -p -r1.62 in6_src.c --- netinet6/in6_src.c 18 Sep 2015 14:26:22 -0000 1.62 +++ netinet6/in6_src.c 12 Oct 2015 11:41:41 -0000 @@ -252,13 +252,12 @@ in6_selectsrc(struct in6_addr **in6src, * 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 *dst * 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; }