Deleted Added
sdiff udiff text old ( 169227 ) new ( 169327 )
full compact
1/* $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $ */
2
3/*
4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/cdefs.h>
20__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 169327 2007-05-07 00:18:56Z thompsa $");
21
22#include "opt_inet.h"
23#include "opt_inet6.h"
24
25#include <sys/param.h>
26#include <sys/kernel.h>
27#include <sys/malloc.h>
28#include <sys/mbuf.h>

--- 804 unchanged lines hidden (view full) ---

833 if (unlock)
834 LAGG_UNLOCK(sc);
835 return (error);
836}
837
838static int
839lagg_ether_setmulti(struct lagg_softc *sc)
840{
841 struct lagg_port *lp;
842
843 LAGG_LOCK_ASSERT(sc);
844
845 /* First, remove any existing filter entries. */
846 lagg_ether_purgemulti(sc);
847
848 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
849 lagg_ether_cmdmulti(lp, 1);
850 }
851 return (0);
852}
853
854static int
855lagg_ether_cmdmulti(struct lagg_port *lp, int set)
856{
857 struct lagg_softc *sc = lp->lp_lagg;
858 struct ifnet *ifp = lp->lp_ifp;
859 struct ifnet *trifp = sc->sc_ifp;
860 struct lagg_mc *mc;
861 struct ifmultiaddr *ifma, *rifma = NULL;
862 struct sockaddr_dl sdl;
863 int error;
864
865 LAGG_LOCK_ASSERT(sc);
866
867 bzero((char *)&sdl, sizeof(sdl));
868 sdl.sdl_len = sizeof(sdl);
869 sdl.sdl_family = AF_LINK;
870 sdl.sdl_type = IFT_ETHER;
871 sdl.sdl_alen = ETHER_ADDR_LEN;
872 sdl.sdl_index = ifp->if_index;
873
874 if (set) {
875 TAILQ_FOREACH(ifma, &trifp->if_multiaddrs, ifma_link) {
876 if (ifma->ifma_addr->sa_family != AF_LINK)
877 continue;
878 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
879 LLADDR(&sdl), ETHER_ADDR_LEN);
880
881 error = if_addmulti(ifp, (struct sockaddr *)&sdl, &rifma);
882 if (error)
883 return (error);
884 mc = malloc(sizeof(struct lagg_mc), M_DEVBUF, M_NOWAIT);
885 if (mc == NULL)
886 return (ENOMEM);
887 mc->mc_ifma = rifma;
888 SLIST_INSERT_HEAD(&lp->lp_mc_head, mc, mc_entries);
889 }
890 } else {
891 while ((mc = SLIST_FIRST(&lp->lp_mc_head)) != NULL) {
892 SLIST_REMOVE(&lp->lp_mc_head, mc, lagg_mc, mc_entries);
893 if_delmulti_ifma(mc->mc_ifma);
894 free(mc, M_DEVBUF);
895 }
896 }
897 return (0);
898}
899
900static void
901lagg_ether_purgemulti(struct lagg_softc *sc)
902{
903 struct lagg_port *lp;
904
905 LAGG_LOCK_ASSERT(sc);
906
907 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
908 lagg_ether_cmdmulti(lp, 0);
909}
910
911/* Handle a ref counted flag that should be set on the lagg port as well */
912static int
913lagg_setflag(struct lagg_port *lp, int flag, int status,
914 int (*func)(struct ifnet *, int))
915{
916 struct lagg_softc *sc = lp->lp_lagg;

--- 663 unchanged lines hidden ---