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 
*/
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to