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