From d74fd34568f94989f705982766bc9059a8a4c341 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 7 May 2007 00:18:56 +0000 Subject: [PATCH] Change from using if_delmulti() to if_delmulti_ifma() as it simplifies the code and is safe to use if the ifp has disappeared. Suggested by: bms --- sys/net/ieee8023ad_lacp.c | 18 ++------ sys/net/ieee8023ad_lacp.h | 1 + sys/net/if_lagg.c | 87 +++++++++++++-------------------------- sys/net/if_lagg.h | 12 ++---- 4 files changed, 37 insertions(+), 81 deletions(-) diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index 68d8d40e5ded..2753c9869369 100644 --- a/sys/net/ieee8023ad_lacp.c +++ b/sys/net/ieee8023ad_lacp.c @@ -453,6 +453,7 @@ lacp_port_create(struct lagg_port *lgp) lp->lp_ifp = ifp; lp->lp_lagg = lgp; lp->lp_lsc = lsc; + lp->lp_ifma = rifma; LIST_INSERT_HEAD(&lsc->lsc_ports, lp, lp_next); @@ -471,9 +472,7 @@ void lacp_port_destroy(struct lagg_port *lgp) { struct lacp_port *lp = LACP_PORT(lgp); - struct ifnet *ifp = lgp->lp_ifp; - struct sockaddr_dl sdl; - int i, error; + int i; LAGG_LOCK_ASSERT(lgp->lp_lagg); @@ -486,18 +485,7 @@ lacp_port_destroy(struct lagg_port *lgp) lacp_unselect(lp); lgp->lp_flags &= ~LAGG_PORT_DISABLED; - bzero((char *)&sdl, sizeof(sdl)); - sdl.sdl_len = sizeof(sdl); - sdl.sdl_family = AF_LINK; - sdl.sdl_index = ifp->if_index; - sdl.sdl_type = IFT_ETHER; - sdl.sdl_alen = ETHER_ADDR_LEN; - - bcopy(ðermulticastaddr_slowprotocols, - LLADDR(&sdl), ETHER_ADDR_LEN); - error = if_delmulti(ifp, (struct sockaddr *)&sdl); - if (error) - printf("%s: DELMULTI failed on %s\n", __func__, lgp->lp_ifname); + if_delmulti_ifma(lp->lp_ifma); LIST_REMOVE(lp, lp_next); free(lp, M_DEVBUF); diff --git a/sys/net/ieee8023ad_lacp.h b/sys/net/ieee8023ad_lacp.h index 5b053dd0fd70..21ed62ec8b2f 100644 --- a/sys/net/ieee8023ad_lacp.h +++ b/sys/net/ieee8023ad_lacp.h @@ -190,6 +190,7 @@ struct lacp_port { int lp_flags; u_int lp_media; /* XXX redundant */ int lp_timer[LACP_NTIMER]; + struct ifmultiaddr *lp_ifma; struct lacp_aggregator *lp_aggregator; }; diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index b6ccdbb1a72b..bb23d29ca22c 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -838,48 +838,16 @@ out: static int lagg_ether_setmulti(struct lagg_softc *sc) { - struct ifnet *trifp = sc->sc_ifp; - struct ifnet *ifp; - struct ifmultiaddr *ifma, *rifma = NULL; - struct lagg_port *lp; - struct lagg_mc *mc; - struct sockaddr_dl sdl; - int error; + struct lagg_port *lp; LAGG_LOCK_ASSERT(sc); - bzero((char *)&sdl, sizeof(sdl)); - sdl.sdl_len = sizeof(sdl); - sdl.sdl_family = AF_LINK; - sdl.sdl_type = IFT_ETHER; - sdl.sdl_alen = ETHER_ADDR_LEN; - /* First, remove any existing filter entries. */ lagg_ether_purgemulti(sc); - /* Now program new ones. */ - TAILQ_FOREACH(ifma, &trifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - mc = malloc(sizeof(struct lagg_mc), M_DEVBUF, M_NOWAIT); - if (mc == NULL) - return (ENOMEM); - bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), - (char *)&mc->mc_addr, ETHER_ADDR_LEN); - SLIST_INSERT_HEAD(&sc->sc_mc_head, mc, mc_entries); - bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), - LLADDR(&sdl), ETHER_ADDR_LEN); - - /* do all the ports */ - SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { - ifp = lp->lp_ifp; - sdl.sdl_index = ifp->if_index; - error = if_addmulti(ifp, (struct sockaddr *)&sdl, &rifma); - if (error) - return (error); - } - } - + SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) { + lagg_ether_cmdmulti(lp, 1); + } return (0); } @@ -887,11 +855,12 @@ static int lagg_ether_cmdmulti(struct lagg_port *lp, int set) { struct lagg_softc *sc = lp->lp_lagg; - struct ifnet *ifp = lp->lp_ifp;; - struct lagg_mc *mc; - struct ifmultiaddr *rifma = NULL; - struct sockaddr_dl sdl; - int error; + struct ifnet *ifp = lp->lp_ifp; + struct ifnet *trifp = sc->sc_ifp; + struct lagg_mc *mc; + struct ifmultiaddr *ifma, *rifma = NULL; + struct sockaddr_dl sdl; + int error; LAGG_LOCK_ASSERT(sc); @@ -902,18 +871,27 @@ lagg_ether_cmdmulti(struct lagg_port *lp, int set) sdl.sdl_alen = ETHER_ADDR_LEN; sdl.sdl_index = ifp->if_index; - SLIST_FOREACH(mc, &sc->sc_mc_head, mc_entries) { - bcopy((char *)&mc->mc_addr, LLADDR(&sdl), ETHER_ADDR_LEN); + if (set) { + TAILQ_FOREACH(ifma, &trifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), + LLADDR(&sdl), ETHER_ADDR_LEN); - if (set) error = if_addmulti(ifp, (struct sockaddr *)&sdl, &rifma); - else - error = if_delmulti(ifp, (struct sockaddr *)&sdl); - - if (error) { - printf("cmdmulti error on %s, set = %d\n", - ifp->if_xname, set); - return (error); + if (error) + return (error); + mc = malloc(sizeof(struct lagg_mc), M_DEVBUF, M_NOWAIT); + if (mc == NULL) + return (ENOMEM); + mc->mc_ifma = rifma; + SLIST_INSERT_HEAD(&lp->lp_mc_head, mc, mc_entries); + } + } else { + while ((mc = SLIST_FIRST(&lp->lp_mc_head)) != NULL) { + SLIST_REMOVE(&lp->lp_mc_head, mc, lagg_mc, mc_entries); + if_delmulti_ifma(mc->mc_ifma); + free(mc, M_DEVBUF); } } return (0); @@ -923,18 +901,11 @@ static void lagg_ether_purgemulti(struct lagg_softc *sc) { struct lagg_port *lp; - struct lagg_mc *mc; LAGG_LOCK_ASSERT(sc); - /* remove from ports */ SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) lagg_ether_cmdmulti(lp, 0); - - while ((mc = SLIST_FIRST(&sc->sc_mc_head)) != NULL) { - SLIST_REMOVE(&sc->sc_mc_head, mc, lagg_mc, mc_entries); - free(mc, M_DEVBUF); - } } /* Handle a ref counted flag that should be set on the lagg port as well */ diff --git a/sys/net/if_lagg.h b/sys/net/if_lagg.h index a717d39edaf7..3c648f05d560 100644 --- a/sys/net/if_lagg.h +++ b/sys/net/if_lagg.h @@ -136,12 +136,8 @@ struct lagg_lb { }; struct lagg_mc { - union { - struct ether_multi *mcu_enm; - } mc_u; - struct sockaddr_storage mc_addr; - - SLIST_ENTRY(lagg_mc) mc_entries; + struct ifmultiaddr *mc_ifma; + SLIST_ENTRY(lagg_mc) mc_entries; }; struct lagg_softc { @@ -156,8 +152,6 @@ struct lagg_softc { SLIST_HEAD(__tplhd, lagg_port) sc_ports; /* list of interfaces */ SLIST_ENTRY(lagg_softc) sc_entries; - SLIST_HEAD(__mclhd, lagg_mc) sc_mc_head; /* multicast addresses */ - /* lagg protocol callbacks */ int (*sc_detach)(struct lagg_softc *); int (*sc_start)(struct lagg_softc *, struct mbuf *); @@ -183,6 +177,8 @@ struct lagg_port { void *lh_cookie; /* if state hook */ caddr_t lp_psc; /* protocol data */ + SLIST_HEAD(__mclhd, lagg_mc) lp_mc_head; /* multicast addresses */ + /* Redirected callbacks */ int (*lp_ioctl)(struct ifnet *, u_long, caddr_t); int (*lp_output)(struct ifnet *, struct mbuf *, struct sockaddr *,