commit 6980269662ec2b601e3346ee23e82baa11c4a7c9 Author: Ryota Ozaki Date: Tue Apr 12 14:39:18 2016 +0900 Get rid of meaningless RTF_UP check The check is meaningless because - An obtained rtentry is ensured that it's always RTF_UP by rtcache, rtalloc1 and rtlookup. If the rtentry isn't changed (RTF_UP gets dropped) during processing, the check should be unnecessary - Even If not, i.e., an obtained rtentry can be changed during processing, checking only at the point doesn't help; the rtentry can be changed after the check Instead we have to ensure that RTF_UP isn't dropped if someone is using it somehow. Note that we already ensure that a rtentry being used isn't freed by rt_refcnt. diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index db23198..2c719a0 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -202,50 +202,20 @@ klock_if_output(struct ifnet * const ifp, struct mbuf * const m, * calling ifp's output routine. */ int -ip_hresolv_output(struct ifnet * const ifp0, struct mbuf * const m, - const struct sockaddr * const dst, struct rtentry *rt00) +ip_hresolv_output(struct ifnet * const ifp, struct mbuf * const m, + const struct sockaddr * const dst, struct rtentry *rt0) { int error = 0; - struct ifnet *ifp = ifp0; - struct rtentry *rt, *rt0, *gwrt; + struct rtentry *rt = rt0, *gwrt; #define RTFREE_IF_NEEDED(_rt) \ - if ((_rt) != NULL && (_rt) != rt00) \ + if ((_rt) != NULL && (_rt) != rt0) \ rtfree((_rt)); - rt0 = rt00; -retry: - if (!ip_hresolv_needed(ifp)) { - rt = rt0; + if (!ip_hresolv_needed(ifp)) goto out; - } - if (rt0 == NULL) { - rt = NULL; - goto out; - } - - rt = rt0; - - /* - * The following block is highly questionable. How did we get here - * with a !RTF_UP route? Does rtalloc1() always return an RTF_UP - * route? - */ - if ((rt->rt_flags & RTF_UP) == 0) { - rt = rtalloc1(dst, 1); - if (rt == NULL) { - error = EHOSTUNREACH; - goto bad; - } - rt0 = rt; - if (rt->rt_ifp != ifp) { - ifp = rt->rt_ifp; - goto retry; - } - } - - if ((rt->rt_flags & RTF_GATEWAY) == 0) + if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) == 0) goto out; gwrt = rt_get_gwroute(rt);