Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet ip_output: zero iproute structure only when need...



details:   https://anonhg.NetBSD.org/src/rev/db16a47d9cb1
branches:  trunk
changeset: 796491:db16a47d9cb1
user:      rmind <rmind%NetBSD.org@localhost>
date:      Fri Jun 06 00:11:19 2014 +0000

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

diffstat:

 sys/netinet/ip_output.c |  110 ++++++++++++++++++++++++-----------------------
 1 files changed, 57 insertions(+), 53 deletions(-)

diffs (237 lines):

diff -r a17b4096221f -r db16a47d9cb1 sys/netinet/ip_output.c
--- a/sys/netinet/ip_output.c   Thu Jun 05 23:48:16 2014 +0000
+++ b/sys/netinet/ip_output.c   Fri Jun 06 00:11:19 2014 +0000
@@ -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 @@
        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 @@
        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 @@
        /*
         * 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 @@
                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 @@
                 */
                if (in_nullhost(ip->ip_src)) {
                        struct in_ifaddr *xia;
+                       struct ifaddr *xifa;
 
                        IFP_TO_IA(ifp, xia);
                        if (!xia) {
@@ -378,14 +380,16 @@
                        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 @@
        }
 
        /*
-        * 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 @@
                        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 @@
        /*
         * 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 @@
         */
        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 @@
                        }
                }
 
+               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 @@
        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);



Home | Main Index | Thread Index | Old Index