From owner-svn-src-all@FreeBSD.ORG Thu Apr 23 11:51:53 2009 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 799DA106566C; Thu, 23 Apr 2009 11:51:53 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 672358FC1B; Thu, 23 Apr 2009 11:51:53 +0000 (UTC) (envelope-from rwatson@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 n3NBpr4K086270; Thu, 23 Apr 2009 11:51:53 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3NBprBx086266; Thu, 23 Apr 2009 11:51:53 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <200904231151.n3NBprBx086266@svn.freebsd.org> From: Robert Watson Date: Thu, 23 Apr 2009 11:51:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r191418 - in head/sys: conf 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: Thu, 23 Apr 2009 11:51:54 -0000 Author: rwatson Date: Thu Apr 23 11:51:53 2009 New Revision: 191418 URL: http://svn.freebsd.org/changeset/base/191418 Log: During if_detach(), invoke if_dead() to set the ifnet's function pointers to "dead" implementations that no-op rather than invoking the device driver. This would generally be unexpected and possibly quite badly handled by most device drivers after if_detach() has completed. Reviewed by: bms MFC after: 3 weeks Added: head/sys/net/if_dead.c (contents, props changed) Modified: head/sys/conf/files head/sys/net/if.c head/sys/net/if_var.h Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Thu Apr 23 10:59:40 2009 (r191417) +++ head/sys/conf/files Thu Apr 23 11:51:53 2009 (r191418) @@ -2152,6 +2152,7 @@ net/if_arcsubr.c optional arcnet net/if_atmsubr.c optional atm net/if_bridge.c optional bridge | if_bridge net/if_clone.c standard +net/if_dead.c standard net/if_disc.c optional disc net/if_edsc.c optional edsc net/if_ef.c optional ef Modified: head/sys/net/if.c ============================================================================== --- head/sys/net/if.c Thu Apr 23 10:59:40 2009 (r191417) +++ head/sys/net/if.c Thu Apr 23 11:51:53 2009 (r191418) @@ -929,6 +929,11 @@ if_detach(struct ifnet *ifp) if_purgemaddrs(ifp); /* + * Prevent further calls into the device driver via ifnet. + */ + if_dead(ifp); + + /* * Remove link ifaddr pointer and maybe decrement if_index. * Clean up all addresses. */ Added: head/sys/net/if_dead.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/net/if_dead.c Thu Apr 23 11:51:53 2009 (r191418) @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2009 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * When an interface has been detached but not yet freed, we set the various + * ifnet function pointers to "ifdead" versions. This prevents unexpected + * calls from the network stack into the device driver after if_detach() has + * returned. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include + +static int +ifdead_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa, + struct route *ro) +{ + + m_freem(m); + return (ENXIO); +} + +static void +ifdead_input(struct ifnet *ifp, struct mbuf *m) +{ + + m_freem(m); +} + +static void +ifdead_start(struct ifnet *ifp) +{ + +} + +static int +ifdead_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + + return (ENXIO); +} + +static void +ifdead_watchdog(struct ifnet *ifp) +{ + +} + +static int +ifdead_resolvemulti(struct ifnet *ifp, struct sockaddr **llsa, + struct sockaddr *sa) +{ + + *llsa = NULL; + return (ENXIO); +} + +static void +ifdead_qflush(struct ifnet *ifp) +{ + +} + +static int +ifdead_transmit(struct ifnet *ifp, struct mbuf *m) +{ + + m_freem(m); + return (ENXIO); +} + +void +if_dead(struct ifnet *ifp) +{ + + ifp->if_output = ifdead_output; + ifp->if_input = ifdead_input; + ifp->if_start = ifdead_start; + ifp->if_ioctl = ifdead_ioctl; + ifp->if_watchdog = ifdead_watchdog; + ifp->if_resolvemulti = ifdead_resolvemulti; + ifp->if_qflush = ifdead_qflush; + ifp->if_transmit = ifdead_transmit; +} Modified: head/sys/net/if_var.h ============================================================================== --- head/sys/net/if_var.h Thu Apr 23 10:59:40 2009 (r191417) +++ head/sys/net/if_var.h Thu Apr 23 11:51:53 2009 (r191418) @@ -753,6 +753,7 @@ int if_addmulti(struct ifnet *, struct s int if_allmulti(struct ifnet *, int); struct ifnet* if_alloc(u_char); void if_attach(struct ifnet *); +void if_dead(struct ifnet *); int if_delmulti(struct ifnet *, struct sockaddr *); void if_delmulti_ifma(struct ifmultiaddr *); void if_detach(struct ifnet *);