Module Name:    src
Committed By:   ozaki-r
Date:           Mon Apr 18 01:28:06 UTC 2016

Modified Files:
        src/sys/netinet: ip_output.c

Log Message:
Get rid of meaningless RTF_UP check from ip_hresolv_output

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 (i.e., 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.

Proposed on tech-kern and tech-net.


To generate a diff of this commit:
cvs rdiff -u -r1.248 -r1.249 src/sys/netinet/ip_output.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/ip_output.c
diff -u src/sys/netinet/ip_output.c:1.248 src/sys/netinet/ip_output.c:1.249
--- src/sys/netinet/ip_output.c:1.248	Wed Jan 20 22:12:22 2016
+++ src/sys/netinet/ip_output.c	Mon Apr 18 01:28:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_output.c,v 1.248 2016/01/20 22:12:22 riastradh Exp $	*/
+/*	$NetBSD: ip_output.c,v 1.249 2016/04/18 01:28:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.248 2016/01/20 22:12:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.249 2016/04/18 01:28:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -202,50 +202,20 @@ klock_if_output(struct ifnet * const ifp
  * 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);

Reply via email to