From owner-svn-src-all@FreeBSD.ORG Sun Oct 7 18:57:53 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 032251065690; Sun, 7 Oct 2012 18:57:53 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E17008FC08; Sun, 7 Oct 2012 18:57:52 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q97IvqNH052665; Sun, 7 Oct 2012 18:57:52 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q97IvqVO052663; Sun, 7 Oct 2012 18:57:52 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <201210071857.q97IvqVO052663@svn.freebsd.org> From: John Baldwin Date: Sun, 7 Oct 2012 18:57:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r241328 - stable/8/sys/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: Sun, 07 Oct 2012 18:57:53 -0000 Author: jhb Date: Sun Oct 7 18:57:52 2012 New Revision: 241328 URL: http://svn.freebsd.org/changeset/base/241328 Log: MFC 239440,239519: Refine the changes made in r208212 to avoid bogus failures from if_delmulti() when clearing the configuration for a subinterface when the parent interface is being detached. The current code was still triggering an assertion in if_delmulti() due to the parent interface being partially detached. Fix this by not calling if_delmulti() at all if the parent interface is being detached. Warn if if_delmulti() fails when the parent is not being detached (but similar to 208212, still proceed with tearing down the vlan state). Modified: stable/8/sys/net/if_vlan.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/net/ (props changed) Modified: stable/8/sys/net/if_vlan.c ============================================================================== --- stable/8/sys/net/if_vlan.c Sun Oct 7 18:57:29 2012 (r241327) +++ stable/8/sys/net/if_vlan.c Sun Oct 7 18:57:52 2012 (r241328) @@ -188,7 +188,7 @@ static int vlan_setflags(struct ifnet *i static int vlan_setmulti(struct ifnet *ifp); static int vlan_transmit(struct ifnet *ifp, struct mbuf *m); static void vlan_unconfig(struct ifnet *ifp); -static void vlan_unconfig_locked(struct ifnet *ifp); +static void vlan_unconfig_locked(struct ifnet *ifp, int departing); static int vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag); static void vlan_link_state(struct ifnet *ifp, int link); static void vlan_capabilities(struct ifvlan *ifv); @@ -543,7 +543,7 @@ vlan_ifdetach(void *arg __unused, struct #ifdef VLAN_ARRAY for (i = 0; i < VLAN_ARRAY_SIZE; i++) if ((ifv = ifp->if_vlantrunk->vlans[i])) { - vlan_unconfig_locked(ifv->ifv_ifp); + vlan_unconfig_locked(ifv->ifv_ifp, 1); if (ifp->if_vlantrunk == NULL) break; } @@ -551,7 +551,7 @@ vlan_ifdetach(void *arg __unused, struct restart: for (i = 0; i < (1 << ifp->if_vlantrunk->hwidth); i++) if ((ifv = LIST_FIRST(&ifp->if_vlantrunk->hash[i]))) { - vlan_unconfig_locked(ifv->ifv_ifp); + vlan_unconfig_locked(ifv->ifv_ifp, 1); if (ifp->if_vlantrunk) goto restart; /* trunk->hwidth can change */ else @@ -821,7 +821,7 @@ vlan_clone_create(struct if_clone *ifc, error = vlan_config(ifv, p, tag); if (error != 0) { /* - * Since we've partialy failed, we need to back + * Since we've partially failed, we need to back * out all the way, otherwise userland could get * confused. Thus, we destroy the interface. */ @@ -1163,17 +1163,18 @@ vlan_unconfig(struct ifnet *ifp) { VLAN_LOCK(); - vlan_unconfig_locked(ifp); + vlan_unconfig_locked(ifp, 0); VLAN_UNLOCK(); } static void -vlan_unconfig_locked(struct ifnet *ifp) +vlan_unconfig_locked(struct ifnet *ifp, int departing) { struct ifvlantrunk *trunk; struct vlan_mc_entry *mc; struct ifvlan *ifv; struct ifnet *parent; + int error; VLAN_LOCK_ASSERT(); @@ -1204,13 +1205,21 @@ vlan_unconfig_locked(struct ifnet *ifp) ETHER_ADDR_LEN); /* - * This may fail if the parent interface is - * being detached. Regardless, we should do a - * best effort to free this interface as much - * as possible as all callers expect vlan - * destruction to succeed. + * If the parent interface is being detached, + * all its multicast addresses have already + * been removed. Warn about errors if + * if_delmulti() does fail, but don't abort as + * all callers expect vlan destruction to + * succeed. */ - (void)if_delmulti(parent, (struct sockaddr *)&sdl); + if (!departing) { + error = if_delmulti(parent, + (struct sockaddr *)&sdl); + if (error) + if_printf(ifp, + "Failed to delete multicast address from parent: %d\n", + error); + } SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries); free(mc, M_VLAN); }