Source-Changes-HG archive

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

[src/netbsd-8]: src/sys Pull up following revision(s) (requested by knakahara...



details:   https://anonhg.NetBSD.org/src/rev/5f90bd0e08cb
branches:  netbsd-8
changeset: 434524:5f90bd0e08cb
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Jan 02 10:48:51 2018 +0000

description:
Pull up following revision(s) (requested by knakahara in ticket #462):
        sys/net/if_gif.c: revision 1.133, 1.134, 1.137
        sys/net/if_gif.h: revision 1.28-1.29
        sys/netinet/in_gif.c: revision 1.90-1.91
        sys/netinet/in_gif.h: revision 1.18
        sys/netinet6/in6_gif.c: revision 1.88-1.89
        sys/netinet6/in6_gif.h: revision 1.17
preserve gif(4) configs by psref(9) like vlan(4) and l2tp(4).
After Tx side does not use softint, gif(4) can use psref(9) for config
preservation like vlan(4) and l2tp(4).
update locking notes later.
--
update gif(4) locking notes.
--
IFF_RUNNING checking in Rx and Tx processing is unnecessary now.
Because the configs of gif (members of gif_var) are protected by psref(9).
--
remove duplicated null ckeck

diffstat:

 sys/net/if_gif.c       |  494 +++++++++++++++++++++++++++---------------------
 sys/net/if_gif.h       |   83 ++++++-
 sys/netinet/in_gif.c   |  109 +++++-----
 sys/netinet/in_gif.h   |   12 +-
 sys/netinet6/in6_gif.c |  108 +++++----
 sys/netinet6/in6_gif.h |   12 +-
 6 files changed, 476 insertions(+), 342 deletions(-)

diffs (truncated from 1601 to 300 lines):

diff -r cbc1c869639d -r 5f90bd0e08cb sys/net/if_gif.c
--- a/sys/net/if_gif.c  Tue Jan 02 10:39:57 2018 +0000
+++ b/sys/net/if_gif.c  Tue Jan 02 10:48:51 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_gif.c,v 1.126.2.6 2018/01/02 10:20:33 snj Exp $     */
+/*     $NetBSD: if_gif.c,v 1.126.2.7 2018/01/02 10:48:51 snj Exp $     */
 /*     $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $    */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.126.2.6 2018/01/02 10:20:33 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.126.2.7 2018/01/02 10:48:51 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -57,6 +57,9 @@
 #include <sys/xcall.h>
 #include <sys/device.h>
 #include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/pserialize.h>
+#include <sys/psref.h>
 
 #include <net/if.h>
 #include <net/if_types.h>
@@ -102,6 +105,9 @@
        kmutex_t lock;
 } gif_softcs __cacheline_aligned;
 
+pserialize_t gif_psz __read_mostly;
+struct psref_class *gv_psref_class __read_mostly;
+
 static void    gif_ro_init_pc(void *, void *, struct cpu_info *);
 static void    gif_ro_fini_pc(void *, void *, struct cpu_info *);
 
@@ -110,6 +116,7 @@
                           const struct sockaddr *, const struct rtentry *);
 static void    gif_start(struct ifnet *);
 static int     gif_transmit(struct ifnet *, struct mbuf *);
+static int     gif_transmit_direct(struct gif_variant *, struct mbuf *);
 static int     gif_ioctl(struct ifnet *, u_long, void *);
 static int     gif_set_tunnel(struct ifnet *, struct sockaddr *,
                               struct sockaddr *);
@@ -119,9 +126,10 @@
 static int     gif_clone_destroy(struct ifnet *);
 static int     gif_check_nesting(struct ifnet *, struct mbuf *);
 
-static int     gif_encap_attach(struct gif_softc *);
-static int     gif_encap_detach(struct gif_softc *);
-static void    gif_encap_pause(struct gif_softc *);
+static int     gif_encap_attach(struct gif_variant *);
+static int     gif_encap_detach(struct gif_variant *);
+
+static void    gif_update_variant(struct gif_softc *, struct gif_variant *);
 
 static struct if_clone gif_cloner =
     IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy);
@@ -216,6 +224,9 @@
        LIST_INIT(&gif_softcs.list);
        if_clone_attach(&gif_cloner);
 
+       gif_psz = pserialize_create();
+       gv_psref_class = psref_class_create("gifvar", IPL_SOFTNET);
+
        gif_sysctl_setup();
 }
 
@@ -231,6 +242,9 @@
        }
 
        if (error == 0) {
+               psref_class_destroy(gv_psref_class);
+               pserialize_destroy(gif_psz);
+
                if_clone_detach(&gif_cloner);
                sysctl_teardown(&gif_sysctl);
        }
@@ -242,6 +256,7 @@
 gif_clone_create(struct if_clone *ifc, int unit)
 {
        struct gif_softc *sc;
+       struct gif_variant *var;
        int rv;
 
        sc = kmem_zalloc(sizeof(struct gif_softc), KM_SLEEP);
@@ -254,6 +269,12 @@
                return rv;
        }
 
+       var = kmem_zalloc(sizeof(*var), KM_SLEEP);
+       var->gv_softc = sc;
+       psref_target_init(&var->gv_psref, gv_psref_class);
+
+       sc->gif_var = var;
+       mutex_init(&sc->gif_lock, MUTEX_DEFAULT, IPL_NONE);
        sc->gif_ro_percpu = percpu_alloc(sizeof(struct gif_ro));
        percpu_foreach(sc->gif_ro_percpu, gif_ro_init_pc, NULL);
 
@@ -268,8 +289,6 @@
 {
        int rv;
 
-       sc->encap_cookie4 = sc->encap_cookie6 = NULL;
-
        sc->gif_if.if_addrlen = 0;
        sc->gif_if.if_mtu    = GIF_MTU;
        sc->gif_if.if_flags  = IFF_POINTOPOINT | IFF_MULTICAST;
@@ -325,6 +344,7 @@
 gif_clone_destroy(struct ifnet *ifp)
 {
        struct gif_softc *sc = (void *) ifp;
+       struct gif_variant *var;
 
        LIST_REMOVE(sc, gif_list);
 
@@ -335,6 +355,10 @@
        percpu_foreach(sc->gif_ro_percpu, gif_ro_fini_pc, NULL);
        percpu_free(sc->gif_ro_percpu, sizeof(struct gif_ro));
 
+       mutex_destroy(&sc->gif_lock);
+
+       var = sc->gif_var;
+       kmem_free(var, sizeof(*var));
        kmem_free(sc, sizeof(struct gif_softc));
 
        return 0;
@@ -346,18 +370,21 @@
 {
        struct ip ip;
        struct gif_softc *sc;
+       struct gif_variant *var;
+       struct psref psref;
+       int ret = 0;
 
        sc = arg;
        if (sc == NULL)
                return 0;
 
-       if ((sc->gif_if.if_flags & (IFF_UP|IFF_RUNNING))
-           != (IFF_UP|IFF_RUNNING))
+       if ((sc->gif_if.if_flags & IFF_UP) == 0)
                return 0;
 
+       var = gif_getref_variant(sc, &psref);
        /* no physical address */
-       if (!sc->gif_psrc || !sc->gif_pdst)
-               return 0;
+       if (var->gv_psrc == NULL || var->gv_pdst == NULL)
+               goto out;
 
        switch (proto) {
 #ifdef INET
@@ -369,36 +396,42 @@
                break;
 #endif
        default:
-               return 0;
+               goto out;
        }
 
        /* Bail on short packets */
        KASSERT(m->m_flags & M_PKTHDR);
        if (m->m_pkthdr.len < sizeof(ip))
-               return 0;
+               goto  out;
 
        m_copydata(m, 0, sizeof(ip), &ip);
 
        switch (ip.ip_v) {
 #ifdef INET
        case 4:
-               if (sc->gif_psrc->sa_family != AF_INET ||
-                   sc->gif_pdst->sa_family != AF_INET)
-                       return 0;
-               return gif_encapcheck4(m, off, proto, arg);
+               if (var->gv_psrc->sa_family != AF_INET ||
+                   var->gv_pdst->sa_family != AF_INET)
+                       goto out;
+               ret = gif_encapcheck4(m, off, proto, var);
+               break;
 #endif
 #ifdef INET6
        case 6:
                if (m->m_pkthdr.len < sizeof(struct ip6_hdr))
-                       return 0;
-               if (sc->gif_psrc->sa_family != AF_INET6 ||
-                   sc->gif_pdst->sa_family != AF_INET6)
-                       return 0;
-               return gif_encapcheck6(m, off, proto, arg);
+                       goto out;
+               if (var->gv_psrc->sa_family != AF_INET6 ||
+                   var->gv_pdst->sa_family != AF_INET6)
+                       goto out;
+               ret = gif_encapcheck6(m, off, proto, var);
+               break;
 #endif
        default:
-               return 0;
+               goto out;
        }
+
+out:
+       gif_putref_variant(var, &psref);
+       return ret;
 }
 #endif
 
@@ -444,6 +477,8 @@
     const struct rtentry *rt)
 {
        struct gif_softc *sc = ifp->if_softc;
+       struct gif_variant *var = NULL;
+       struct psref psref;
        int error = 0;
 
        IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
@@ -453,16 +488,22 @@
                goto end;
        }
 
-       m->m_flags &= ~(M_BCAST|M_MCAST);
-       if (((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) ||
-           sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
+       if ((ifp->if_flags & IFF_UP) == 0) {
                m_freem(m);
                error = ENETDOWN;
                goto end;
        }
 
+       var = gif_getref_variant(sc, &psref);
+       if (var->gv_psrc == NULL || var->gv_pdst == NULL) {
+               m_freem(m);
+               error = ENETDOWN;
+               goto end;
+       }
        /* XXX should we check if our outer source is legal? */
 
+       m->m_flags &= ~(M_BCAST|M_MCAST);
+
        /* use DLT_NULL encapsulation here to pass inner af type */
        M_PREPEND(m, sizeof(int), M_DONTWAIT);
        if (!m) {
@@ -475,8 +516,10 @@
        m->m_pkthdr.csum_flags = 0;
        m->m_pkthdr.csum_data = 0;
 
-       error = if_transmit_lock(ifp, m);
-  end:
+       error = gif_transmit_direct(var, m);
+end:
+       if (var != NULL)
+               gif_putref_variant(var, &psref);
        if (error)
                ifp->if_oerrors++;
        return error;
@@ -486,12 +529,17 @@
 gif_start(struct ifnet *ifp)
 {
        struct gif_softc *sc;
+       struct gif_variant *var;
        struct mbuf *m;
+       struct psref psref;
        int family;
        int len;
        int error;
 
        sc = ifp->if_softc;
+       var = gif_getref_variant(sc, &psref);
+
+       KASSERT(var->gv_output != NULL);
 
        /* output processing */
        while (1) {
@@ -513,33 +561,7 @@
 
                len = m->m_pkthdr.len;
 
-               /* dispatch to output logic based on outer AF */
-               switch (sc->gif_psrc->sa_family) {
-#ifdef INET
-               case AF_INET:
-                       /* XXX
-                        * To add mutex_enter(softnet_lock) or
-                        * KASSERT(mutex_owned(softnet_lock)) here, we shold
-                        * coordinate softnet_lock between in6_if_up() and
-                        * in6_purgeif().
-                        */
-                       error = in_gif_output(ifp, family, m);
-                       break;
-#endif
-#ifdef INET6
-               case AF_INET6:
-                       /* XXX
-                        * the same as in_gif_output()
-                        */
-                       error = in6_gif_output(ifp, family, m);
-                       break;



Home | Main Index | Thread Index | Old Index