Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 May 2017 19:29:31 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r317697 - stable/11/sys/net
Message-ID:  <201705021929.v42JTVfA025021@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Tue May  2 19:29:31 2017
New Revision: 317697
URL: https://svnweb.freebsd.org/changeset/base/317697

Log:
  MFC r312979 (by loos):
  Do not update the lagg link layer address when destroying a lagg clone.
  
  This would enqueue an event to send the gratuitous arp on a dying lagg
  interface without any physical ports attached to it.
  
  Apart from that, the taskqueue_drain() on lagg_clone_destroy() runs too
  late, when the ifp data structure is already freed.  Fix that too.

Modified:
  stable/11/sys/net/if_lagg.c
  stable/11/sys/net/if_lagg.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/net/if_lagg.c
==============================================================================
--- stable/11/sys/net/if_lagg.c	Tue May  2 19:09:11 2017	(r317696)
+++ stable/11/sys/net/if_lagg.c	Tue May  2 19:29:31 2017	(r317697)
@@ -539,12 +539,15 @@ lagg_clone_destroy(struct ifnet *ifp)
 	EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
 
 	/* Shutdown and remove lagg ports */
-	while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL)
+	while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL) {
+		lp->lp_detaching = LAGG_CLONE_DESTROY;
 		lagg_port_destroy(lp, 1);
+	}
 	/* Unhook the aggregation protocol */
 	lagg_proto_detach(sc);
 	LAGG_UNLOCK_ASSERT(sc);
 
+	taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task);
 	ifmedia_removeall(&sc->sc_media);
 	ether_ifdetach(ifp);
 	if_free(ifp);
@@ -553,7 +556,6 @@ lagg_clone_destroy(struct ifnet *ifp)
 	SLIST_REMOVE(&V_lagg_list, sc, lagg_softc, sc_entries);
 	LAGG_LIST_UNLOCK();
 
-	taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task);
 	LAGG_LOCK_DESTROY(sc);
 	free(sc, M_DEVBUF);
 }
@@ -891,7 +893,7 @@ lagg_port_destroy(struct lagg_port *lp, 
 	 * Remove multicast addresses and interface flags from this port and
 	 * reset the MAC address, skip if the interface is being detached.
 	 */
-	if (!lp->lp_detaching) {
+	if (lp->lp_detaching == 0) {
 		lagg_ether_cmdmulti(lp, 0);
 		lagg_setflags(lp, 0);
 		lagg_port_lladdr(lp, lp->lp_lladdr, LAGG_LLQTYPE_PHYS);
@@ -924,7 +926,8 @@ lagg_port_destroy(struct lagg_port *lp, 
 			bcopy(lp0->lp_lladdr,
 			    lladdr, ETHER_ADDR_LEN);
 		}
-		lagg_lladdr(sc, lladdr);
+		if (lp->lp_detaching != LAGG_CLONE_DESTROY)
+			lagg_lladdr(sc, lladdr);
 
 		/* Mark lp0 as new primary */
 		sc->sc_primary = lp0;
@@ -939,7 +942,7 @@ lagg_port_destroy(struct lagg_port *lp, 
 	}
 
 	/* Remove any pending lladdr changes from the queue */
-	if (lp->lp_detaching) {
+	if (lp->lp_detaching != 0) {
 		SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
 			if (llq->llq_ifp == ifp) {
 				SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq,
@@ -1118,7 +1121,7 @@ lagg_port_ifdetach(void *arg __unused, s
 	sc = lp->lp_softc;
 
 	LAGG_WLOCK(sc);
-	lp->lp_detaching = 1;
+	lp->lp_detaching = LAGG_PORT_DETACH;
 	lagg_port_destroy(lp, 1);
 	LAGG_WUNLOCK(sc);
 }
@@ -1603,7 +1606,7 @@ lagg_ether_cmdmulti(struct lagg_port *lp
 	} else {
 		while ((mc = SLIST_FIRST(&lp->lp_mc_head)) != NULL) {
 			SLIST_REMOVE(&lp->lp_mc_head, mc, lagg_mc, mc_entries);
-			if (mc->mc_ifma && !lp->lp_detaching)
+			if (mc->mc_ifma && lp->lp_detaching == 0)
 				if_delmulti_ifma(mc->mc_ifma);
 			free(mc, M_DEVBUF);
 		}

Modified: stable/11/sys/net/if_lagg.h
==============================================================================
--- stable/11/sys/net/if_lagg.h	Tue May  2 19:09:11 2017	(r317696)
+++ stable/11/sys/net/if_lagg.h	Tue May  2 19:29:31 2017	(r317697)
@@ -261,6 +261,8 @@ struct lagg_port {
 	void				*lh_cookie;	/* if state hook */
 	void				*lp_psc;	/* protocol data */
 	int				lp_detaching;	/* ifnet is detaching */
+#define	LAGG_PORT_DETACH		0x01		/* detach lagg port */
+#define	LAGG_CLONE_DESTROY		0x02		/* destroy lagg clone */
 
 	SLIST_HEAD(__mclhd, lagg_mc)	lp_mc_head;	/* multicast addresses */
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201705021929.v42JTVfA025021>