From owner-svn-src-all@FreeBSD.ORG Tue Oct 14 19:48:58 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B03221065696; Tue, 14 Oct 2008 19:48:58 +0000 (UTC) (envelope-from dwmalone@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9D4448FC1E; Tue, 14 Oct 2008 19:48:58 +0000 (UTC) (envelope-from dwmalone@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id m9EJmwXp014702; Tue, 14 Oct 2008 19:48:58 GMT (envelope-from dwmalone@svn.freebsd.org) Received: (from dwmalone@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id m9EJmwbo014701; Tue, 14 Oct 2008 19:48:58 GMT (envelope-from dwmalone@svn.freebsd.org) Message-Id: <200810141948.m9EJmwbo014701@svn.freebsd.org> From: David Malone Date: Tue, 14 Oct 2008 19:48:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r183893 - in stable/7/sys: . dev/twa net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Oct 2008 19:48:58 -0000 Author: dwmalone Date: Tue Oct 14 19:48:58 2008 New Revision: 183893 URL: http://svn.freebsd.org/changeset/base/183893 Log: Some people's 6to4 routers seem to have been blowing up because of the unlocked route caching in if_stf. Add a mutex that protects access to cached route. Various versions of this patch were tested by Pekka Savola, Nick Sayer and Wouter Snels. Approved by: re (gnn) Modified: stable/7/sys/ (props changed) stable/7/sys/dev/twa/ (props changed) stable/7/sys/net/if_stf.c Modified: stable/7/sys/net/if_stf.c ============================================================================== --- stable/7/sys/net/if_stf.c Tue Oct 14 19:02:47 2008 (r183892) +++ stable/7/sys/net/if_stf.c Tue Oct 14 19:48:58 2008 (r183893) @@ -89,6 +89,7 @@ #include #include #include +#include #include #include @@ -119,6 +120,13 @@ #include +SYSCTL_DECL(_net_link); +SYSCTL_NODE(_net_link, IFT_STF, stf, CTLFLAG_RW, 0, "6to4 Interface"); + +static int stf_route_cache = 1; +SYSCTL_INT(_net_link_stf, OID_AUTO, route_cache, CTLFLAG_RW, + &stf_route_cache, 0, "Caching of IPv4 routes for 6to4 Output"); + #define STFNAME "stf" #define STFUNIT 0 @@ -137,15 +145,15 @@ struct stf_softc { struct route_in6 __sc_ro6; /* just for safety */ } __sc_ro46; #define sc_ro __sc_ro46.__sc_ro4 + struct mtx sc_ro_mtx; u_int sc_fibnum; const struct encaptab *encap_cookie; }; #define STF2IFP(sc) ((sc)->sc_ifp) /* - * XXXRW: Note that mutable fields in the softc are not currently locked: - * in particular, sc_ro needs to be protected from concurrent entrance - * of stf_output(). + * Note that mutable fields in the softc are not currently locked. + * We do lock sc_ro in stf_output though. */ static MALLOC_DEFINE(M_STF, STFNAME, "6to4 Tunnel Interface"); static const int ip_stf_ttl = 40; @@ -231,6 +239,7 @@ stf_clone_create(struct if_clone *ifc, c ifp->if_dname = ifc->ifc_name; ifp->if_dunit = IF_DUNIT_NONE; + mtx_init(&(sc)->sc_ro_mtx, "stf ro", NULL, MTX_DEF); sc->encap_cookie = encap_attach_func(AF_INET, IPPROTO_IPV6, stf_encapcheck, &in_stf_protosw, sc); if (sc->encap_cookie == NULL) { @@ -257,6 +266,7 @@ stf_clone_destroy(struct if_clone *ifc, err = encap_detach(sc->encap_cookie); KASSERT(err == 0, ("Unexpected error detaching encap_cookie")); + mtx_destroy(&(sc)->sc_ro_mtx); bpfdetach(ifp); if_detach(ifp); if_free(ifp); @@ -398,6 +408,7 @@ stf_output(ifp, m, dst, rt) { struct stf_softc *sc; struct sockaddr_in6 *dst6; + struct route *cached_route; struct in_addr in4; caddr_t ptr; struct sockaddr_in *dst4; @@ -406,9 +417,9 @@ stf_output(ifp, m, dst, rt) struct ip6_hdr *ip6; struct in6_ifaddr *ia6; u_int32_t af; -#ifdef MAC int error; +#ifdef MAC error = mac_check_ifnet_transmit(ifp, m); if (error) { m_freem(m); @@ -507,9 +518,15 @@ stf_output(ifp, m, dst, rt) else ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos); + if (!stf_route_cache) { + cached_route = NULL; + goto sendit; + } + /* - * XXXRW: Locking of sc_ro required. + * Do we have a cached route? */ + mtx_lock(&(sc)->sc_ro_mtx); dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst; if (dst4->sin_family != AF_INET || bcmp(&dst4->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)) != 0) { @@ -527,14 +544,21 @@ stf_output(ifp, m, dst, rt) rtalloc_fib(&sc->sc_ro, sc->sc_fibnum); if (sc->sc_ro.ro_rt == NULL) { m_freem(m); + mtx_unlock(&(sc)->sc_ro_mtx); ifp->if_oerrors++; return ENETUNREACH; } } + cached_route = &sc->sc_ro; +sendit: M_SETFIB(m, sc->sc_fibnum); ifp->if_opackets++; - return ip_output(m, NULL, &sc->sc_ro, 0, NULL, NULL); + error = ip_output(m, NULL, cached_route, 0, NULL, NULL); + + if (cached_route != NULL) + mtx_unlock(&(sc)->sc_ro_mtx); + return error; } static int