Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys preserve gif(4) configs by psref(9) like vlan(4) and l2t...
details: https://anonhg.NetBSD.org/src/rev/420ff1ab6e22
branches: trunk
changeset: 357778:420ff1ab6e22
user: knakahara <knakahara%NetBSD.org@localhost>
date: Mon Nov 27 05:02:22 2017 +0000
description:
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.
diffstat:
sys/net/if_gif.c | 494 +++++++++++++++++++++++++++---------------------
sys/net/if_gif.h | 72 ++++++-
sys/netinet/in_gif.c | 107 +++++-----
sys/netinet/in_gif.h | 12 +-
sys/netinet6/in6_gif.c | 106 +++++----
sys/netinet6/in6_gif.h | 12 +-
6 files changed, 470 insertions(+), 333 deletions(-)
diffs (truncated from 1578 to 300 lines):
diff -r ca870021d587 -r 420ff1ab6e22 sys/net/if_gif.c
--- a/sys/net/if_gif.c Mon Nov 27 01:34:06 2017 +0000
+++ b/sys/net/if_gif.c Mon Nov 27 05:02:22 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_gif.c,v 1.132 2017/11/16 03:07:18 ozaki-r Exp $ */
+/* $NetBSD: if_gif.c,v 1.133 2017/11/27 05:02:22 knakahara 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.132 2017/11/16 03:07:18 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.133 2017/11/27 05:02:22 knakahara 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,6 +370,9 @@
{
struct ip ip;
struct gif_softc *sc;
+ struct gif_variant *var;
+ struct psref psref;
+ int ret = 0;
sc = arg;
if (sc == NULL)
@@ -355,9 +382,13 @@
!= (IFF_UP|IFF_RUNNING))
return 0;
+ var = gif_getref_variant(sc, &psref);
+ if (var->gv_psrc == NULL || var->gv_pdst == NULL)
+ goto out;
+
/* no physical address */
- if (!sc->gif_psrc || !sc->gif_pdst)
- return 0;
+ if (!var->gv_psrc || !var->gv_pdst)
+ goto out;
switch (proto) {
#ifdef INET
@@ -369,36 +400,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 +481,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 +492,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|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
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 +520,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 +533,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 +565,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