Mart Tõnso reported [0] a weird case related to the use of ifa_ifwithnet().
The problem is that ifa_ifwithroute() does not always use route entries but the poor's man routing table: ifa_ifwithnet(). This is misleading because one cannot understand why "# route add" is not coherent with "# route get". So I'd like to commit the diff below which always use the route table unless an interface index is specified in the gateway. Mart Tõnso confirmed it fixes his issue. ok? [0] https://marc.info/?l=openbsd-misc&m=146046751201006&w=2 Index: net/route.c =================================================================== RCS file: /cvs/src/sys/net/route.c,v retrieving revision 1.298 diff -u -p -r1.298 route.c --- net/route.c 26 Mar 2016 21:56:04 -0000 1.298 +++ net/route.c 13 Apr 2016 07:38:11 -0000 @@ -740,20 +740,16 @@ ifa_ifwithroute(int flags, struct sockad ifa = ifaof_ifpforaddr(dst, ifp); if_put(ifp); } else { - ifa = ifa_ifwithnet(gateway, rtableid); - } - } - if (ifa == NULL) { - struct rtentry *rt = rtalloc(gateway, 0, rtableid); - /* The gateway must be local if the same address family. */ - if (!rtisvalid(rt) || ((rt->rt_flags & RTF_GATEWAY) && - rt_key(rt)->sa_family == dst->sa_family)) { + struct rtentry *rt; + + rt = rtalloc(gateway, RT_RESOLVE, rtableid); + if (rt != NULL) + ifa = rt->rt_ifa; rtfree(rt); - return (NULL); } - ifa = rt->rt_ifa; - rtfree(rt); } + if (ifa == NULL) + return (NULL); if (ifa->ifa_addr->sa_family != dst->sa_family) { struct ifaddr *oifa = ifa; ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
