Module Name:    src
Committed By:   rmind
Date:           Fri Jun  6 00:11:19 UTC 2014

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

Log Message:
ip_output: zero iproute structure only when needed; reduce the scope
of some variables.


To generate a diff of this commit:
cvs rdiff -u -r1.229 -r1.230 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.229 src/sys/netinet/ip_output.c:1.230
--- src/sys/netinet/ip_output.c:1.229	Fri May 30 01:39:03 2014
+++ src/sys/netinet/ip_output.c	Fri Jun  6 00:11:19 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_output.c,v 1.229 2014/05/30 01:39:03 christos Exp $	*/
+/*	$NetBSD: ip_output.c,v 1.230 2014/06/06 00:11:19 rmind 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.229 2014/05/30 01:39:03 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.230 2014/06/06 00:11:19 rmind Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -161,7 +161,6 @@ ip_output(struct mbuf *m0, ...)
 	struct route iproute;
 	const struct sockaddr_in *dst;
 	struct in_ifaddr *ia;
-	struct ifaddr *xifa;
 	struct mbuf *opt;
 	struct route *ro;
 	int flags, sw_csum;
@@ -173,7 +172,7 @@ ip_output(struct mbuf *m0, ...)
 	struct secpolicy *sp = NULL;
 #endif
 	bool natt_frag = false;
-	bool __unused done = false;
+	bool rtmtu_nolock;
 	union {
 		struct sockaddr		dst;
 		struct sockaddr_in	dst4;
@@ -221,9 +220,10 @@ ip_output(struct mbuf *m0, ...)
 	/*
 	 * Route packet.
 	 */
-	memset(&iproute, 0, sizeof(iproute));
-	if (ro == NULL)
+	if (ro == NULL) {
+		memset(&iproute, 0, sizeof(iproute));
 		ro = &iproute;
+	}
 	sockaddr_in_init(&u.dst4, &ip->ip_dst, 0);
 	dst = satocsin(rtcache_getdst(ro));
 
@@ -277,6 +277,7 @@ ip_output(struct mbuf *m0, ...)
 		if (rt->rt_flags & RTF_GATEWAY)
 			dst = satosin(rt->rt_gateway);
 	}
+	rtmtu_nolock = rt && (rt->rt_rmx.rmx_locks & RTV_MTU) == 0;
 
 	if (IN_MULTICAST(ip->ip_dst.s_addr) ||
 	    (ip->ip_dst.s_addr == INADDR_BROADCAST)) {
@@ -320,6 +321,7 @@ ip_output(struct mbuf *m0, ...)
 		 */
 		if (in_nullhost(ip->ip_src)) {
 			struct in_ifaddr *xia;
+			struct ifaddr *xifa;
 
 			IFP_TO_IA(ifp, xia);
 			if (!xia) {
@@ -378,14 +380,16 @@ ip_output(struct mbuf *m0, ...)
 			m_freem(m);
 			goto done;
 		}
-
 		goto sendit;
 	}
+
 	/*
 	 * If source address not specified yet, use address
 	 * of outgoing interface.
 	 */
 	if (in_nullhost(ip->ip_src)) {
+		struct ifaddr *xifa;
+
 		xifa = &ia->ia_ifa;
 		if (xifa->ifa_getifa != NULL)
 			ia = ifatoia((*xifa->ifa_getifa)(xifa, rdst));
@@ -403,9 +407,8 @@ ip_output(struct mbuf *m0, ...)
 	}
 
 	/*
-	 * Look for broadcast address and
-	 * and verify user is allowed to send
-	 * such a packet.
+	 * Look for broadcast address and and verify user is allowed to
+	 * send such a packet.
 	 */
 	if (in_broadcast(dst->sin_addr, ifp)) {
 		if ((ifp->if_flags & IFF_BROADCAST) == 0) {
@@ -450,20 +453,23 @@ sendit:
 			ip->ip_id = ip_newid_range(ia, num);
 		}
 	}
+
 	/*
 	 * If we're doing Path MTU Discovery, we need to set DF unless
 	 * the route's MTU is locked.
 	 */
-	if ((flags & IP_MTUDISC) != 0 && rt != NULL &&
-	    (rt->rt_rmx.rmx_locks & RTV_MTU) == 0)
+	if ((flags & IP_MTUDISC) != 0 && rtmtu_nolock) {
 		ip->ip_off |= htons(IP_DF);
+	}
 
 #ifdef IPSEC
 	if (ipsec_used) {
+		bool ipsec_done = false;
+
 		/* Perform IPsec processing, if any. */
 		error = ipsec4_output(m, so, flags, &sp, &mtu, &natt_frag,
-		    &done);
-		if (error || done)
+		    &ipsec_done);
+		if (error || ipsec_done)
 			goto done;
 	}
 #endif
@@ -471,7 +477,8 @@ sendit:
 	/*
 	 * Run through list of hooks for output packets.
 	 */
-	if ((error = pfil_run_hooks(inet_pfil_hook, &m, ifp, PFIL_OUT)) != 0)
+	error = pfil_run_hooks(inet_pfil_hook, &m, ifp, PFIL_OUT);
+	if (error)
 		goto done;
 	if (m == NULL)
 		goto done;
@@ -500,6 +507,8 @@ sendit:
 	 */
 	if (ntohs(ip->ip_len) <= mtu ||
 	    (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) != 0) {
+		const struct sockaddr *sa;
+
 #if IFA_STATS
 		if (ia)
 			ia->ia_ifa.ifa_data.ifad_outbytes += ntohs(ip->ip_len);
@@ -533,22 +542,15 @@ sendit:
 			}
 		}
 
+		sa = (m->m_flags & M_MCAST) ? sintocsa(rdst) : sintocsa(dst);
 		if (__predict_true(
 		    (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) == 0 ||
 		    (ifp->if_capenable & IFCAP_TSOv4) != 0)) {
 			KERNEL_LOCK(1, NULL);
-			error =
-			    (*ifp->if_output)(ifp, m,
-				(m->m_flags & M_MCAST) ?
-				    sintocsa(rdst) : sintocsa(dst),
-				rt);
+			error = (*ifp->if_output)(ifp, m, sa, rt);
 			KERNEL_UNLOCK_ONE(NULL);
 		} else {
-			error =
-			    ip_tso_output(ifp, m,
-				(m->m_flags & M_MCAST) ?
-				    sintocsa(rdst) : sintocsa(dst),
-				rt);
+			error = ip_tso_output(ifp, m, sa, rt);
 		}
 		goto done;
 	}
@@ -593,39 +595,41 @@ sendit:
 	for (; m; m = m0) {
 		m0 = m->m_nextpkt;
 		m->m_nextpkt = 0;
-		if (error == 0) {
+		if (error) {
+			m_freem(m);
+			continue;
+		}
 #if IFA_STATS
-			if (ia)
-				ia->ia_ifa.ifa_data.ifad_outbytes +=
-				    ntohs(ip->ip_len);
+		if (ia)
+			ia->ia_ifa.ifa_data.ifad_outbytes += ntohs(ip->ip_len);
 #endif
-			/*
-			 * If we get there, the packet has not been handled by
-			 * IPsec whereas it should have. Now that it has been
-			 * fragmented, re-inject it in ip_output so that IPsec
-			 * processing can occur.
-			 */
-			if (natt_frag) {
-				error = ip_output(m, opt, ro,
-				    flags | IP_RAWOUTPUT | IP_NOIPNEWID,
-				    imo, so);
-			} else {
-				KASSERT((m->m_pkthdr.csum_flags &
-				    (M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0);
-				KERNEL_LOCK(1, NULL);
-				error = (*ifp->if_output)(ifp, m,
-				    (m->m_flags & M_MCAST) ?
-				    sintocsa(rdst) : sintocsa(dst), rt);
-				KERNEL_UNLOCK_ONE(NULL);
-			}
-		} else
-			m_freem(m);
+		/*
+		 * If we get there, the packet has not been handled by
+		 * IPsec whereas it should have. Now that it has been
+		 * fragmented, re-inject it in ip_output so that IPsec
+		 * processing can occur.
+		 */
+		if (natt_frag) {
+			error = ip_output(m, opt, ro,
+			    flags | IP_RAWOUTPUT | IP_NOIPNEWID,
+			    imo, so);
+		} else {
+			KASSERT((m->m_pkthdr.csum_flags &
+			    (M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0);
+			KERNEL_LOCK(1, NULL);
+			error = (*ifp->if_output)(ifp, m,
+			    (m->m_flags & M_MCAST) ?
+			    sintocsa(rdst) : sintocsa(dst), rt);
+			KERNEL_UNLOCK_ONE(NULL);
+		}
 	}
-
-	if (error == 0)
+	if (error == 0) {
 		IP_STATINC(IP_STAT_FRAGMENTED);
+	}
 done:
-	rtcache_free(&iproute);
+	if (ro == &iproute) {
+		rtcache_free(&iproute);
+	}
 #ifdef IPSEC
 	if (sp) {
 		KEY_FREESP(&sp);

Reply via email to