Module Name: src Committed By: knakahara Date: Thu Sep 21 09:42:03 UTC 2017
Modified Files: src/sys/net: if_gif.c if_gif.h src/sys/netinet: in_gif.c src/sys/netinet6: in6_gif.c Log Message: add lock for percpu route like l2tp(4). To generate a diff of this commit: cvs rdiff -u -r1.128 -r1.129 src/sys/net/if_gif.c cvs rdiff -u -r1.25 -r1.26 src/sys/net/if_gif.h cvs rdiff -u -r1.87 -r1.88 src/sys/netinet/in_gif.c cvs rdiff -u -r1.85 -r1.86 src/sys/netinet6/in6_gif.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_gif.c diff -u src/sys/net/if_gif.c:1.128 src/sys/net/if_gif.c:1.129 --- src/sys/net/if_gif.c:1.128 Tue Aug 8 03:14:50 2017 +++ src/sys/net/if_gif.c Thu Sep 21 09:42:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_gif.c,v 1.128 2017/08/08 03:14:50 knakahara Exp $ */ +/* $NetBSD: if_gif.c,v 1.129 2017/09/21 09:42:03 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.128 2017/08/08 03:14:50 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.129 2017/09/21 09:42:03 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -98,6 +98,9 @@ __KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1 */ static LIST_HEAD(, gif_softc) gif_softc_list; +static void gif_ro_init_pc(void *, void *, struct cpu_info *); +static void gif_ro_fini_pc(void *, void *, struct cpu_info *); + static void gifattach0(struct gif_softc *); static int gif_output(struct ifnet *, struct mbuf *, const struct sockaddr *, const struct rtentry *); @@ -238,7 +241,9 @@ gif_clone_create(struct if_clone *ifc, i gifattach0(sc); - sc->gif_ro_percpu = percpu_alloc(sizeof(struct route)); + sc->gif_ro_percpu = percpu_alloc(sizeof(struct gif_ro)); + percpu_foreach(sc->gif_ro_percpu, gif_ro_init_pc, NULL); + LIST_INSERT_HEAD(&gif_softc_list, sc, gif_list); return (0); } @@ -270,12 +275,30 @@ gifattach0(struct gif_softc *sc) bpf_attach(&sc->gif_if, DLT_NULL, sizeof(u_int)); } +static void +gif_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) +{ + struct gif_ro *gro = p; + + mutex_init(&gro->gr_lock, MUTEX_DEFAULT, IPL_NONE); +} + +static void +gif_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) +{ + struct gif_ro *gro = p; + + rtcache_free(&gro->gr_ro); + + mutex_destroy(&gro->gr_lock); +} + void gif_rtcache_free_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) { - struct route *ro = p; + struct gif_ro *gro = p; - rtcache_free(ro); + rtcache_free(&gro->gr_ro); } static int @@ -288,8 +311,10 @@ gif_clone_destroy(struct ifnet *ifp) gif_delete_tunnel(&sc->gif_if); bpf_detach(ifp); if_detach(ifp); - percpu_foreach(sc->gif_ro_percpu, gif_rtcache_free_pc, NULL); - percpu_free(sc->gif_ro_percpu, sizeof(struct route)); + + percpu_foreach(sc->gif_ro_percpu, gif_ro_fini_pc, NULL); + percpu_free(sc->gif_ro_percpu, sizeof(struct gif_ro)); + kmem_free(sc, sizeof(struct gif_softc)); return (0); Index: src/sys/net/if_gif.h diff -u src/sys/net/if_gif.h:1.25 src/sys/net/if_gif.h:1.26 --- src/sys/net/if_gif.h:1.25 Wed Dec 14 11:19:15 2016 +++ src/sys/net/if_gif.h Thu Sep 21 09:42:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_gif.h,v 1.25 2016/12/14 11:19:15 knakahara Exp $ */ +/* $NetBSD: if_gif.h,v 1.26 2017/09/21 09:42:03 knakahara Exp $ */ /* $KAME: if_gif.h,v 1.23 2001/07/27 09:21:42 itojun Exp $ */ /* @@ -49,11 +49,16 @@ struct encaptab; +struct gif_ro { + struct route gr_ro; + kmutex_t gr_lock; +}; + struct gif_softc { struct ifnet gif_if; /* common area - must be at the top */ struct sockaddr *gif_psrc; /* Physical src addr */ struct sockaddr *gif_pdst; /* Physical dst addr */ - percpu_t *gif_ro_percpu; + percpu_t *gif_ro_percpu; /* struct gif_ro */ int gif_flags; const struct encaptab *encap_cookie4; const struct encaptab *encap_cookie6; Index: src/sys/netinet/in_gif.c diff -u src/sys/netinet/in_gif.c:1.87 src/sys/netinet/in_gif.c:1.88 --- src/sys/netinet/in_gif.c:1.87 Fri Jan 6 03:25:13 2017 +++ src/sys/netinet/in_gif.c Thu Sep 21 09:42:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: in_gif.c,v 1.87 2017/01/06 03:25:13 knakahara Exp $ */ +/* $NetBSD: in_gif.c,v 1.88 2017/09/21 09:42:03 knakahara Exp $ */ /* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.87 2017/01/06 03:25:13 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.88 2017/09/21 09:42:03 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -84,6 +84,7 @@ in_gif_output(struct ifnet *ifp, int fam { struct rtentry *rt; struct route *ro; + struct gif_ro *gro; struct gif_softc *sc = ifp->if_softc; struct sockaddr_in *sin_src = satosin(sc->gif_psrc); struct sockaddr_in *sin_dst = satosin(sc->gif_pdst); @@ -166,8 +167,11 @@ in_gif_output(struct ifnet *ifp, int fam return ENOBUFS; bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip)); - ro = percpu_getref(sc->gif_ro_percpu); + gro = percpu_getref(sc->gif_ro_percpu); + mutex_enter(&gro->gr_lock); + ro = &gro->gr_ro; if ((rt = rtcache_lookup(ro, sc->gif_pdst)) == NULL) { + mutex_exit(&gro->gr_lock); percpu_putref(sc->gif_ro_percpu); m_freem(m); return ENETUNREACH; @@ -177,6 +181,7 @@ in_gif_output(struct ifnet *ifp, int fam if (rt->rt_ifp == ifp) { rtcache_unref(rt, ro); rtcache_free(ro); + mutex_exit(&gro->gr_lock); percpu_putref(sc->gif_ro_percpu); m_freem(m); return ENETUNREACH; /*XXX*/ @@ -184,6 +189,7 @@ in_gif_output(struct ifnet *ifp, int fam rtcache_unref(rt, ro); error = ip_output(m, NULL, ro, 0, NULL, NULL); + mutex_exit(&gro->gr_lock); percpu_putref(sc->gif_ro_percpu); return (error); } Index: src/sys/netinet6/in6_gif.c diff -u src/sys/netinet6/in6_gif.c:1.85 src/sys/netinet6/in6_gif.c:1.86 --- src/sys/netinet6/in6_gif.c:1.85 Mon Jan 16 15:44:47 2017 +++ src/sys/netinet6/in6_gif.c Thu Sep 21 09:42:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_gif.c,v 1.85 2017/01/16 15:44:47 christos Exp $ */ +/* $NetBSD: in6_gif.c,v 1.86 2017/09/21 09:42:03 knakahara Exp $ */ /* $KAME: in6_gif.c,v 1.62 2001/07/29 04:27:25 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.85 2017/01/16 15:44:47 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.86 2017/09/21 09:42:03 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -87,6 +87,7 @@ in6_gif_output(struct ifnet *ifp, int fa { struct rtentry *rt; struct route *ro; + struct gif_ro *gro; struct gif_softc *sc = ifp->if_softc; struct sockaddr_in6 *sin6_src = satosin6(sc->gif_psrc); struct sockaddr_in6 *sin6_dst = satosin6(sc->gif_pdst); @@ -172,9 +173,12 @@ in6_gif_output(struct ifnet *ifp, int fa ip6->ip6_flow &= ~ntohl(0xff00000); ip6->ip6_flow |= htonl((u_int32_t)otos << 20); - ro = percpu_getref(sc->gif_ro_percpu); + gro = percpu_getref(sc->gif_ro_percpu); + mutex_enter(&gro->gr_lock); + ro = &gro->gr_ro; rt = rtcache_lookup(ro, sc->gif_pdst); if (rt == NULL) { + mutex_exit(&gro->gr_lock); percpu_putref(sc->gif_ro_percpu); m_freem(m); return ENETUNREACH; @@ -184,6 +188,7 @@ in6_gif_output(struct ifnet *ifp, int fa if (rt->rt_ifp == ifp) { rtcache_unref(rt, ro); rtcache_free(ro); + mutex_exit(&gro->gr_lock); percpu_putref(sc->gif_ro_percpu); m_freem(m); return ENETUNREACH; /* XXX */ @@ -200,6 +205,7 @@ in6_gif_output(struct ifnet *ifp, int fa #else error = ip6_output(m, 0, ro, 0, NULL, NULL, NULL); #endif + mutex_exit(&gro->gr_lock); percpu_putref(sc->gif_ro_percpu); return (error); }