Source-Changes-HG archive

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

[src/trunk]: src/sys Pull out route lookups from L2 output routines



details:   https://anonhg.NetBSD.org/src/rev/5756cee88193
branches:  trunk
changeset: 808839:5756cee88193
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Thu Jun 04 09:19:59 2015 +0000

description:
Pull out route lookups from L2 output routines

Route lookups for routes of RTF_GATEWAY were done in L2 output
routines such as ether_output, but they should be done in L3
i.e., before L2 output routines. This change places the lookups
between L3 output routines (say ip_output) and the L2 output
routines.

The change is based on dyoung's patch submitted in the thread:
https://mail-index.netbsd.org/tech-net/2013/02/01/msg003847.html
You can find out detailed investigations by dyoung about the
issue in there.

Note that the change introduces a workaround for MPLS. ether_output
knew that it needs to fill the ethertype of a frame as MPLS,
based on a tag of an original route (rtentry), but now we don't
pass it to ehter_output. So we have to tell that in another way.
We use mtag to do so for now, which introduces some overhead.
We should fix it somehow in the future.

Discussed on tech-kern and tech-net.

diffstat:

 sys/net/if_arcsubr.c      |   30 +------
 sys/net/if_atmsubr.c      |   34 +--------
 sys/net/if_ecosubr.c      |   39 +---------
 sys/net/if_ethersubr.c    |   54 ++-----------
 sys/net/if_fddisubr.c     |   33 +-------
 sys/net/if_hippisubr.c    |   40 +---------
 sys/net/if_ieee1394subr.c |   41 +---------
 sys/net/if_mpls.c         |    9 +-
 sys/netinet/in_offload.c  |   11 +-
 sys/netinet/ip_output.c   |  178 +++++++++++++++++++++++++++++++++++++++++----
 sys/netinet/ip_var.h      |    5 +-
 sys/sys/mbuf.h            |    4 +-
 12 files changed, 210 insertions(+), 268 deletions(-)

diffs (truncated from 870 to 300 lines):

diff -r b80e2ca5efb8 -r 5756cee88193 sys/net/if_arcsubr.c
--- a/sys/net/if_arcsubr.c      Thu Jun 04 09:17:52 2015 +0000
+++ b/sys/net/if_arcsubr.c      Thu Jun 04 09:19:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_arcsubr.c,v 1.66 2014/06/05 23:48:16 rmind Exp $    */
+/*     $NetBSD: if_arcsubr.c,v 1.67 2015/06/04 09:19:59 ozaki-r Exp $  */
 
 /*
  * Copyright (c) 1994, 1995 Ignatios Souvatzis
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arcsubr.c,v 1.66 2014/06/05 23:48:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arcsubr.c,v 1.67 2015/06/04 09:19:59 ozaki-r Exp $");
 
 #include "opt_inet.h"
 
@@ -111,10 +111,9 @@
  */
 static int
 arc_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
-    struct rtentry *rt0)
+    struct rtentry *rt)
 {
        struct mbuf             *m, *m1, *mcopy;
-       struct rtentry          *rt;
        struct arccom           *ac;
        const struct arc_header *cah;
        struct arc_header       *ah;
@@ -134,29 +133,6 @@
 
        myself = *CLLADDR(ifp->if_sadl);
 
-       if ((rt = rt0)) {
-               if ((rt->rt_flags & RTF_UP) == 0) {
-                       if ((rt0 = rt = rtalloc1(dst, 1)))
-                               rt->rt_refcnt--;
-                       else
-                               senderr(EHOSTUNREACH);
-               }
-               if (rt->rt_flags & RTF_GATEWAY) {
-                       if (rt->rt_gwroute == 0)
-                               goto lookup;
-                       if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
-                               rtfree(rt); rt = rt0;
-                       lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
-                               if ((rt = rt->rt_gwroute) == 0)
-                                       senderr(EHOSTUNREACH);
-                       }
-               }
-               if (rt->rt_flags & RTF_REJECT)
-                       if (rt->rt_rmx.rmx_expire == 0 ||
-                           time_second < rt->rt_rmx.rmx_expire)
-                               senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
-       }
-
        /*
         * if the queueing discipline needs packet classification,
         * do it before prepending link headers.
diff -r b80e2ca5efb8 -r 5756cee88193 sys/net/if_atmsubr.c
--- a/sys/net/if_atmsubr.c      Thu Jun 04 09:17:52 2015 +0000
+++ b/sys/net/if_atmsubr.c      Thu Jun 04 09:19:59 2015 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: if_atmsubr.c,v 1.52 2014/06/05 23:48:16 rmind Exp $       */
+/*      $NetBSD: if_atmsubr.c,v 1.53 2015/06/04 09:19:59 ozaki-r Exp $       */
 
 /*
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_atmsubr.c,v 1.52 2014/06/05 23:48:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_atmsubr.c,v 1.53 2015/06/04 09:19:59 ozaki-r Exp $");
 
 #include "opt_inet.h"
 #include "opt_gateway.h"
@@ -89,13 +89,12 @@
 
 int
 atm_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
-    struct rtentry *rt0)
+    struct rtentry *rt)
 {
        uint16_t etype = 0;                     /* if using LLC/SNAP */
        int error = 0, sz;
        struct atm_pseudohdr atmdst, *ad;
        struct mbuf *m = m0;
-       struct rtentry *rt;
        struct atmllc *atmllc;
        uint32_t atm_flags;
        ALTQ_DECL(struct altq_pktattr pktattr;)
@@ -111,33 +110,6 @@
             (dst != NULL ? dst->sa_family : AF_UNSPEC), &pktattr);
 
        /*
-        * check route
-        */
-       if ((rt = rt0) != NULL) {
-
-               if ((rt->rt_flags & RTF_UP) == 0) { /* route went down! */
-                       if ((rt0 = rt = RTALLOC1(dst, 0)) != NULL)
-                               rt->rt_refcnt--;
-                       else
-                               senderr(EHOSTUNREACH);
-               }
-
-               if (rt->rt_flags & RTF_GATEWAY) {
-                       if (rt->rt_gwroute == 0)
-                               goto lookup;
-                       if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
-                               rtfree(rt); rt = rt0;
-                       lookup: rt->rt_gwroute = RTALLOC1(rt->rt_gateway, 0);
-                               if ((rt = rt->rt_gwroute) == 0)
-                                       senderr(EHOSTUNREACH);
-                       }
-               }
-
-               /* XXX: put RTF_REJECT code here if doing ATMARP */
-
-       }
-
-       /*
         * check for non-native ATM traffic   (dst != NULL)
         */
        if (dst) {
diff -r b80e2ca5efb8 -r 5756cee88193 sys/net/if_ecosubr.c
--- a/sys/net/if_ecosubr.c      Thu Jun 04 09:17:52 2015 +0000
+++ b/sys/net/if_ecosubr.c      Thu Jun 04 09:19:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ecosubr.c,v 1.42 2015/05/20 09:17:18 ozaki-r Exp $  */
+/*     $NetBSD: if_ecosubr.c,v 1.43 2015/06/04 09:19:59 ozaki-r Exp $  */
 
 /*-
  * Copyright (c) 2001 Ben Harris
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.42 2015/05/20 09:17:18 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.43 2015/06/04 09:19:59 ozaki-r Exp $");
 
 #include "opt_inet.h"
 
@@ -161,12 +161,11 @@
 
 static int
 eco_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
-    struct rtentry *rt0)
+    struct rtentry *rt)
 {
        struct eco_header ehdr, *eh;
        int error;
        struct mbuf *m = m0, *mcopy = NULL;
-       struct rtentry *rt;
        int hdrcmplt;
        int retry_delay, retry_count;
        struct m_tag *mtag;
@@ -181,38 +180,6 @@
 
        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
                senderr(ENETDOWN);
-       if ((rt = rt0) != NULL) {
-               if ((rt->rt_flags & RTF_UP) == 0) {
-                       if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) {
-                               rt->rt_refcnt--;
-                               if (rt->rt_ifp != ifp)
-                                       return (*rt->rt_ifp->if_output)
-                                                       (ifp, m0, dst, rt);
-                       } else
-                               senderr(EHOSTUNREACH);
-               }
-               if ((rt->rt_flags & RTF_GATEWAY)) {
-                       if (rt->rt_gwroute == 0)
-                               goto lookup;
-                       if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
-                               rtfree(rt); rt = rt0;
-                       lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
-                               if ((rt = rt->rt_gwroute) == 0)
-                                       senderr(EHOSTUNREACH);
-                               /* the "G" test below also prevents rt == rt0 */
-                               if ((rt->rt_flags & RTF_GATEWAY) ||
-                                   (rt->rt_ifp != ifp)) {
-                                       rt->rt_refcnt--;
-                                       rt0->rt_gwroute = 0;
-                                       senderr(EHOSTUNREACH);
-                               }
-                       }
-               }
-               if (rt->rt_flags & RTF_REJECT)
-                       if (rt->rt_rmx.rmx_expire == 0 ||
-                           time_second < rt->rt_rmx.rmx_expire)
-                               senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
-       }
        /*
         * If the queueing discipline needs packet classification,
         * do it before prepending link headers.
diff -r b80e2ca5efb8 -r 5756cee88193 sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c    Thu Jun 04 09:17:52 2015 +0000
+++ b/sys/net/if_ethersubr.c    Thu Jun 04 09:19:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ethersubr.c,v 1.209 2015/05/25 08:29:01 ozaki-r Exp $       */
+/*     $NetBSD: if_ethersubr.c,v 1.210 2015/06/04 09:19:59 ozaki-r Exp $       */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.209 2015/05/25 08:29:01 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.210 2015/06/04 09:19:59 ozaki-r Exp $");
 
 #include "opt_inet.h"
 #include "opt_atalk.h"
@@ -192,13 +192,12 @@
 static int
 ether_output(struct ifnet * const ifp0, struct mbuf * const m0,
        const struct sockaddr * const dst,
-       struct rtentry *rt0)
+       struct rtentry *rt)
 {
        uint16_t etype = 0;
        int error = 0, hdrcmplt = 0;
        uint8_t esrc[6], edst[6];
        struct mbuf *m = m0;
-       struct rtentry *rt;
        struct mbuf *mcopy = NULL;
        struct ether_header *eh;
        struct ifnet *ifp = ifp0;
@@ -226,7 +225,7 @@
                if (dst != NULL && ifp0->if_link_state == LINK_STATE_UP &&
                    (ifa = ifa_ifwithaddr(dst)) != NULL &&
                    ifa->ifa_ifp == ifp0)
-                       return looutput(ifp0, m, dst, rt0);
+                       return looutput(ifp0, m, dst, rt);
 
                ifp = ifp->if_carpdev;
                /* ac = (struct arpcom *)ifp; */
@@ -239,38 +238,6 @@
 
        if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
                senderr(ENETDOWN);
-       if ((rt = rt0) != NULL) {
-               if ((rt->rt_flags & RTF_UP) == 0) {
-                       if ((rt0 = rt = rtalloc1(dst, 1)) != NULL) {
-                               rt->rt_refcnt--;
-                               if (rt->rt_ifp != ifp)
-                                       return (*rt->rt_ifp->if_output)
-                                                       (ifp, m0, dst, rt);
-                       } else
-                               senderr(EHOSTUNREACH);
-               }
-               if ((rt->rt_flags & RTF_GATEWAY)) {
-                       if (rt->rt_gwroute == NULL)
-                               goto lookup;
-                       if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
-                               rtfree(rt); rt = rt0;
-                       lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1);
-                               if ((rt = rt->rt_gwroute) == NULL)
-                                       senderr(EHOSTUNREACH);
-                               /* the "G" test below also prevents rt == rt0 */
-                               if ((rt->rt_flags & RTF_GATEWAY) ||
-                                   (rt->rt_ifp != ifp)) {
-                                       rt->rt_refcnt--;
-                                       rt0->rt_gwroute = NULL;
-                                       senderr(EHOSTUNREACH);
-                               }
-                       }
-               }
-               if (rt->rt_flags & RTF_REJECT)
-                       if (rt->rt_rmx.rmx_expire == 0 ||
-                           (u_long) time_second < rt->rt_rmx.rmx_expire)
-                               senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
-       }
 
        switch (dst->sa_family) {
 
@@ -386,13 +353,14 @@
        }
 
 #ifdef MPLS
-       if (rt0 != NULL && rt_gettag(rt0) != NULL &&
-           rt_gettag(rt0)->sa_family == AF_MPLS &&
-           (m->m_flags & (M_MCAST | M_BCAST)) == 0) {
-               union mpls_shim msh;
-               msh.s_addr = MPLS_GETSADDR(rt0);
-               if (msh.shim.label != MPLS_LABEL_IMPLNULL)
+       {
+               struct m_tag *mtag;
+               mtag = m_tag_find(m, PACKET_TAG_MPLS, NULL);
+               if (mtag != NULL) {
+                       /* Having the tag itself indicates it's MPLS */
                        etype = htons(ETHERTYPE_MPLS);
+                       m_tag_delete(m, mtag);
+               }
        }
 #endif
 



Home | Main Index | Thread Index | Old Index