Home | History | Annotate | Line # | Download | only in lagg
      1 /*	$NetBSD: if_lagg.c,v 1.74 2025/07/30 02:16:54 ozaki-r Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2005, 2006 Reyk Floeter <reyk (at) openbsd.org>
      5  * Copyright (c) 2007 Andrew Thompson <thompsa (at) FreeBSD.org>
      6  * Copyright (c) 2014, 2016 Marcelo Araujo <araujo (at) FreeBSD.org>
      7  * Copyright (c) 2021, Internet Initiative Japan Inc.
      8  *
      9  * Permission to use, copy, modify, and distribute this software for any
     10  * purpose with or without fee is hereby granted, provided that the above
     11  * copyright notice and this permission notice appear in all copies.
     12  *
     13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     20  */
     21 
     22 #include <sys/cdefs.h>
     23 __KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.74 2025/07/30 02:16:54 ozaki-r Exp $");
     24 
     25 #ifdef _KERNEL_OPT
     26 #include "opt_inet.h"
     27 #include "opt_lagg.h"
     28 #endif
     29 
     30 #include <sys/param.h>
     31 #include <sys/types.h>
     32 
     33 #include <sys/cprng.h>
     34 #include <sys/cpu.h>
     35 #include <sys/device.h>
     36 #include <sys/evcnt.h>
     37 #include <sys/hash.h>
     38 #include <sys/kmem.h>
     39 #include <sys/module.h>
     40 #include <sys/pserialize.h>
     41 #include <sys/pslist.h>
     42 #include <sys/psref.h>
     43 #include <sys/sysctl.h>
     44 #include <sys/syslog.h>
     45 #include <sys/workqueue.h>
     46 
     47 #include <net/bpf.h>
     48 #include <net/if.h>
     49 #include <net/if_dl.h>
     50 #include <net/if_ether.h>
     51 #include <net/if_media.h>
     52 #include <net/if_types.h>
     53 #include <net/if_vlanvar.h>
     54 #include <netinet/ip.h>
     55 #include <netinet/ip6.h>
     56 #include <netinet/tcp.h>
     57 #include <netinet/udp.h>
     58 
     59 #if defined(INET) || defined(INET6)
     60 #include <netinet/in.h>
     61 #endif
     62 
     63 #ifdef INET6
     64 #include <netinet6/in6_ifattach.h>
     65 #include <netinet6/in6_var.h>
     66 #endif
     67 
     68 #include <net/lagg/if_lagg.h>
     69 #include <net/lagg/if_laggproto.h>
     70 
     71 #include "ioconf.h"
     72 
     73 enum lagg_portctrl {
     74 	LAGG_PORTCTRL_ALLOC,
     75 	LAGG_PORTCTRL_FREE,
     76 	LAGG_PORTCTRL_START,
     77 	LAGG_PORTCTRL_STOP
     78 };
     79 
     80 enum lagg_iftypes {
     81 	LAGG_IF_TYPE_ETHERNET,
     82 };
     83 
     84 static const struct lagg_proto lagg_protos[] = {
     85 	[LAGG_PROTO_NONE] = {
     86 		.pr_num = LAGG_PROTO_NONE,
     87 		.pr_attach = lagg_none_attach,
     88 	},
     89 	[LAGG_PROTO_LACP] = {
     90 		.pr_num = LAGG_PROTO_LACP,
     91 		.pr_attach = lacp_attach,
     92 		.pr_detach = lacp_detach,
     93 		.pr_up = lacp_up,
     94 		.pr_down = lacp_down,
     95 		.pr_transmit = lacp_transmit,
     96 		.pr_input = lacp_input,
     97 		.pr_allocport = lacp_allocport,
     98 		.pr_freeport = lacp_freeport,
     99 		.pr_startport = lacp_startport,
    100 		.pr_stopport = lacp_stopport,
    101 		.pr_protostat = lacp_protostat,
    102 		.pr_portstat = lacp_portstat,
    103 		.pr_linkstate = lacp_linkstate_ifnet_locked,
    104 		.pr_ioctl = lacp_ioctl,
    105 	},
    106 	[LAGG_PROTO_FAILOVER] = {
    107 		.pr_num = LAGG_PROTO_FAILOVER,
    108 		.pr_attach = lagg_fail_attach,
    109 		.pr_detach = lagg_common_detach,
    110 		.pr_transmit = lagg_fail_transmit,
    111 		.pr_input = lagg_fail_input,
    112 		.pr_allocport = lagg_common_allocport,
    113 		.pr_freeport = lagg_common_freeport,
    114 		.pr_startport = lagg_common_startport,
    115 		.pr_stopport = lagg_common_stopport,
    116 		.pr_portstat = lagg_fail_portstat,
    117 		.pr_linkstate = lagg_common_linkstate_ifnet_locked,
    118 		.pr_ioctl = lagg_fail_ioctl,
    119 	},
    120 	[LAGG_PROTO_LOADBALANCE] = {
    121 		.pr_num = LAGG_PROTO_LOADBALANCE,
    122 		.pr_attach = lagg_lb_attach,
    123 		.pr_detach = lagg_common_detach,
    124 		.pr_transmit = lagg_lb_transmit,
    125 		.pr_input = lagg_lb_input,
    126 		.pr_allocport = lagg_common_allocport,
    127 		.pr_freeport = lagg_common_freeport,
    128 		.pr_startport = lagg_lb_startport,
    129 		.pr_stopport = lagg_lb_stopport,
    130 		.pr_portstat = lagg_lb_portstat,
    131 		.pr_linkstate = lagg_common_linkstate_ifnet_locked,
    132 	},
    133 };
    134 
    135 static int	lagg_chg_sadl(struct ifnet *, const uint8_t *, size_t);
    136 static void	lagg_input_ethernet(struct ifnet *, struct mbuf *);
    137 static int	lagg_clone_create(struct if_clone *, int);
    138 static int	lagg_clone_destroy(struct ifnet *);
    139 static int	lagg_init(struct ifnet *);
    140 static int	lagg_init_locked(struct lagg_softc *);
    141 static void	lagg_stop(struct ifnet *, int);
    142 static void	lagg_stop_locked(struct lagg_softc *);
    143 static int	lagg_ioctl(struct ifnet *, u_long, void *);
    144 static int	lagg_transmit(struct ifnet *, struct mbuf *);
    145 static void	lagg_start(struct ifnet *);
    146 static int	lagg_media_change(struct ifnet *);
    147 static void	lagg_media_status(struct ifnet *, struct ifmediareq *);
    148 static int	lagg_vlan_cb(struct ethercom *, uint16_t, bool);
    149 static void	lagg_linkstate_changed(void *);
    150 static void	lagg_ifdetach(void *);
    151 static struct lagg_softc *
    152 		lagg_softc_alloc(enum lagg_iftypes);
    153 static void	lagg_softc_free(struct lagg_softc *);
    154 static int	lagg_setup_sysctls(struct lagg_softc *);
    155 static void	lagg_teardown_sysctls(struct lagg_softc *);
    156 static int	lagg_proto_attach(struct lagg_softc *, lagg_proto,
    157 		    struct lagg_proto_softc **);
    158 static void	lagg_proto_detach(struct lagg_variant *);
    159 static int	lagg_proto_up(struct lagg_softc *);
    160 static void	lagg_proto_down(struct lagg_softc *);
    161 static int	lagg_proto_allocport(struct lagg_softc *, struct lagg_port *);
    162 static void	lagg_proto_freeport(struct lagg_softc *, struct lagg_port *);
    163 static void	lagg_proto_startport(struct lagg_softc *,
    164 		    struct lagg_port *);
    165 static void	lagg_proto_stopport(struct lagg_softc *,
    166 		    struct lagg_port *);
    167 static struct mbuf *
    168 		lagg_proto_input(struct lagg_softc *, struct lagg_port *,
    169 		    struct mbuf *);
    170 static void	lagg_proto_linkstate(struct lagg_softc *, struct lagg_port *);
    171 static int	lagg_proto_ioctl(struct lagg_softc *, struct lagg_req *);
    172 static int	lagg_get_stats(struct lagg_softc *, struct lagg_req *, size_t);
    173 static int	lagg_pr_attach(struct lagg_softc *, lagg_proto);
    174 static void	lagg_pr_detach(struct lagg_softc *);
    175 static int	lagg_addport(struct lagg_softc *, struct ifnet *);
    176 static int	lagg_delport(struct lagg_softc *, struct ifnet *);
    177 static int	lagg_delport_all(struct lagg_softc *);
    178 static int	lagg_port_ioctl(struct ifnet *, u_long, void *);
    179 static int	lagg_port_output(struct ifnet *, struct mbuf *,
    180 		    const struct sockaddr *, const struct rtentry *);
    181 static void	lagg_config_promisc(struct lagg_softc *, struct lagg_port *);
    182 static void	lagg_unconfig_promisc(struct lagg_softc *, struct lagg_port *);
    183 static struct lagg_variant *
    184 		lagg_variant_getref(struct lagg_softc *, struct psref *);
    185 static void	lagg_variant_putref(struct lagg_variant *, struct psref *);
    186 static int	lagg_ether_addmulti(struct lagg_softc *, struct ifreq *);
    187 static int	lagg_ether_delmulti(struct lagg_softc *, struct ifreq *);
    188 static void	lagg_port_syncmulti(struct lagg_softc *, struct lagg_port *);
    189 static void	lagg_port_purgemulti(struct lagg_softc *, struct lagg_port *);
    190 static int	lagg_port_setup(struct lagg_softc *, struct lagg_port *,
    191 		    struct ifnet *);
    192 static void	lagg_port_teardown(struct lagg_softc *, struct lagg_port *,
    193 		    bool);
    194 static void	lagg_port_syncvlan(struct lagg_softc *, struct lagg_port *);
    195 static void	lagg_port_purgevlan(struct lagg_softc *, struct lagg_port *);
    196 static void	lagg_capabilities_update(struct lagg_softc *);
    197 static void	lagg_sync_ifcaps(struct lagg_softc *);
    198 static void	lagg_sync_ethcaps(struct lagg_softc *);
    199 static void	lagg_sync_sadl(struct lagg_softc *);
    200 
    201 static struct if_clone	 lagg_cloner =
    202     IF_CLONE_INITIALIZER("lagg", lagg_clone_create, lagg_clone_destroy);
    203 static unsigned int	 lagg_count;
    204 static struct psref_class
    205 		*lagg_psref_class __read_mostly;
    206 static struct psref_class
    207 		*lagg_port_psref_class __read_mostly;
    208 
    209 static enum lagg_iftypes
    210 		 lagg_iftype = LAGG_IF_TYPE_ETHERNET;
    211 
    212 #ifdef LAGG_DEBUG
    213 #define __LAGGDEBUGUSED
    214 #define LAGG_DPRINTF(_sc, _fmt, _args...)	do {	\
    215 	printf("%s: " _fmt, (_sc) != NULL ?		\
    216 	(_sc)->sc_if.if_xname : "lagg", ##_args);		\
    217 } while (0)
    218 #else
    219 #define __LAGGDEBUGUSED				__unused
    220 #define LAGG_DPRINTF(_sc, _fmt, _args...)	__nothing
    221 #endif
    222 
    223 #ifndef LAGG_SETCAPS_RETRY
    224 #define LAGG_SETCAPS_RETRY	(LAGG_MAX_PORTS * 2)
    225 #endif
    226 
    227 static size_t
    228 lagg_sizeof_softc(enum lagg_iftypes ift)
    229 {
    230 	struct lagg_softc *_dummy = NULL;
    231 	size_t s;
    232 
    233 	s = sizeof(*_dummy) - sizeof(_dummy->sc_if);
    234 
    235 	switch (ift) {
    236 	case LAGG_IF_TYPE_ETHERNET:
    237 		s += sizeof(struct ethercom);
    238 		break;
    239 	default:
    240 		s += sizeof(struct ifnet);
    241 		break;
    242 	}
    243 
    244 	return s;
    245 }
    246 
    247 static void
    248 lagg_evcnt_attach(struct lagg_softc *sc,
    249     struct evcnt *ev, const char *name)
    250 {
    251 
    252 	evcnt_attach_dynamic(ev, EVCNT_TYPE_MISC, NULL,
    253 	    sc->sc_evgroup, name);
    254 }
    255 
    256 static void
    257 lagg_in6_ifattach(struct ifnet *ifp)
    258 {
    259 
    260 #ifdef INET6
    261 	KERNEL_LOCK_UNLESS_NET_MPSAFE();
    262 	if (in6_present) {
    263 		if (ISSET(ifp->if_flags, IFF_UP))
    264 			in6_ifattach(ifp, NULL);
    265 	}
    266 	KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
    267 #endif
    268 }
    269 
    270 static void
    271 lagg_in6_ifdetach(struct ifnet *ifp)
    272 {
    273 
    274 #ifdef INET6
    275 	KERNEL_LOCK_UNLESS_NET_MPSAFE();
    276 	if (in6_present)
    277 		in6_ifdetach(ifp);
    278 	KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
    279 #endif
    280 }
    281 
    282 static int
    283 lagg_lp_ioctl(struct lagg_port *lp, u_long cmd, void *data)
    284 {
    285 	struct ifnet *ifp_port;
    286 	int error;
    287 
    288 	if (lp->lp_ioctl == NULL)
    289 		return EINVAL;
    290 
    291 	ifp_port = lp->lp_ifp;
    292 	IFNET_LOCK(ifp_port);
    293 	error = lp->lp_ioctl(ifp_port, cmd, data);
    294 	IFNET_UNLOCK(ifp_port);
    295 
    296 	return error;
    297 }
    298 
    299 static bool
    300 lagg_lladdr_equal(const uint8_t *a, const uint8_t *b)
    301 {
    302 
    303 	if (memcmp(a, b, ETHER_ADDR_LEN) == 0)
    304 		return true;
    305 
    306 	return false;
    307 }
    308 
    309 static void
    310 lagg_lladdr_cpy(uint8_t *dst, const uint8_t *src)
    311 {
    312 
    313 	memcpy(dst, src, ETHER_ADDR_LEN);
    314 }
    315 
    316 void
    317 laggattach(int n)
    318 {
    319 
    320 	/*
    321 	 * Nothing to do here, initialization is handled by the
    322 	 * module initialization code in lagginit() below).
    323 	 */
    324 }
    325 
    326 static void
    327 lagginit(void)
    328 {
    329 	size_t i;
    330 
    331 	lagg_psref_class = psref_class_create("laggvariant", IPL_SOFTNET);
    332 	lagg_port_psref_class = psref_class_create("laggport", IPL_SOFTNET);
    333 
    334 	for (i = 0; i < LAGG_PROTO_MAX; i++) {
    335 		if (lagg_protos[i].pr_init != NULL)
    336 			lagg_protos[i].pr_init();
    337 	}
    338 
    339 	if_clone_attach(&lagg_cloner);
    340 }
    341 
    342 static int
    343 laggdetach(void)
    344 {
    345 	size_t i;
    346 
    347 	if (lagg_count > 0)
    348 		return EBUSY;
    349 
    350 	if_clone_detach(&lagg_cloner);
    351 
    352 	for (i = 0; i < LAGG_PROTO_MAX; i++) {
    353 		if (lagg_protos[i].pr_fini != NULL)
    354 			lagg_protos[i].pr_fini();
    355 	}
    356 
    357 	psref_class_destroy(lagg_port_psref_class);
    358 	psref_class_destroy(lagg_psref_class);
    359 
    360 	return 0;
    361 }
    362 
    363 static int
    364 lagg_clone_create(struct if_clone *ifc, int unit)
    365 {
    366 	struct lagg_softc *sc;
    367 	struct ifnet *ifp;
    368 	struct ethercom *ec;
    369 	int error;
    370 
    371 	sc = lagg_softc_alloc(lagg_iftype);
    372 	ifp = &sc->sc_if;
    373 
    374 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTNET);
    375 	sc->sc_psz = pserialize_create();
    376 	SIMPLEQ_INIT(&sc->sc_ports);
    377 	LIST_INIT(&sc->sc_mclist);
    378 	TAILQ_INIT(&sc->sc_vtags);
    379 	sc->sc_hash_mac = true;
    380 	sc->sc_hash_ipaddr = true;
    381 	sc->sc_hash_ip6addr = true;
    382 	sc->sc_hash_tcp = true;
    383 	sc->sc_hash_udp = true;
    384 
    385 	if_initname(ifp, ifc->ifc_name, unit);
    386 	ifp->if_softc = sc;
    387 	ifp->if_init = lagg_init;
    388 	ifp->if_stop = lagg_stop;
    389 	ifp->if_ioctl = lagg_ioctl;
    390 	ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
    391 	ifp->if_extflags = IFEF_MPSAFE;
    392 	ifp->if_transmit = lagg_transmit;
    393 	ifp->if_start = lagg_start;
    394 	IFQ_SET_READY(&ifp->if_snd);
    395 
    396 	error = lagg_setup_sysctls(sc);
    397 	if (error != 0)
    398 		goto destroy_psz;
    399 
    400 	/*XXX dependent on ethernet */
    401 	ifmedia_init_with_lock(&sc->sc_media, 0, lagg_media_change,
    402 	    lagg_media_status, &sc->sc_lock);
    403 	ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
    404 	ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
    405 
    406 	if_initialize(ifp);
    407 
    408 	switch (lagg_iftype) {
    409 	case LAGG_IF_TYPE_ETHERNET:
    410 		ec = (struct ethercom *)ifp;
    411 		cprng_fast(sc->sc_lladdr_rand, sizeof(sc->sc_lladdr_rand));
    412 		sc->sc_lladdr_rand[0] &= 0xFE; /* clear I/G bit */
    413 		sc->sc_lladdr_rand[0] |= 0x02; /* set G/L bit */
    414 		lagg_lladdr_cpy(sc->sc_lladdr, sc->sc_lladdr_rand);
    415 		ether_set_vlan_cb(ec, lagg_vlan_cb);
    416 
    417 		/*
    418 		 * notify ETHERCAP_VLAN_HWTAGGING to ether_ifattach
    419 		 * to handle VLAN tag, stripped by hardware, in bpf(4)
    420 		 */
    421 		ec->ec_capabilities = ETHERCAP_VLAN_HWTAGGING;
    422 
    423 		ether_ifattach(ifp, sc->sc_lladdr_rand);
    424 		break;
    425 	default:
    426 		panic("unknown if type");
    427 	}
    428 
    429 	snprintf(sc->sc_evgroup, sizeof(sc->sc_evgroup),
    430 	    "%s", ifp->if_xname);
    431 	lagg_evcnt_attach(sc, &sc->sc_novar, "no lagg variant");
    432 	if_link_state_change(&sc->sc_if, LINK_STATE_DOWN);
    433 	lagg_setup_sysctls(sc);
    434 	(void)lagg_pr_attach(sc, LAGG_PROTO_NONE);
    435 	if_register(ifp);
    436 	lagg_count++;
    437 
    438 	return 0;
    439 
    440 destroy_psz:
    441 	pserialize_destroy(sc->sc_psz);
    442 	mutex_destroy(&sc->sc_lock);
    443 	lagg_softc_free(sc);
    444 
    445 	return error;
    446 }
    447 
    448 static int
    449 lagg_clone_destroy(struct ifnet *ifp)
    450 {
    451 	struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
    452 	struct lagg_port *lp;
    453 
    454 	lagg_stop(ifp, 1);
    455 
    456 	IFNET_LOCK(ifp);
    457 	LAGG_LOCK(sc);
    458 	while ((lp = LAGG_PORTS_FIRST(sc)) != NULL) {
    459 		lagg_port_teardown(sc, lp, false);
    460 	}
    461 	LAGG_UNLOCK(sc);
    462 	IFNET_UNLOCK(ifp);
    463 
    464 	switch (ifp->if_type) {
    465 	case IFT_ETHER:
    466 		ether_ifdetach(ifp);
    467 		KASSERT(TAILQ_EMPTY(&sc->sc_vtags));
    468 		break;
    469 	}
    470 
    471 	if_detach(ifp);
    472 	ifmedia_fini(&sc->sc_media);
    473 	lagg_pr_detach(sc);
    474 	evcnt_detach(&sc->sc_novar);
    475 	lagg_teardown_sysctls(sc);
    476 
    477 	pserialize_destroy(sc->sc_psz);
    478 	mutex_destroy(&sc->sc_lock);
    479 	lagg_softc_free(sc);
    480 
    481 	if (lagg_count > 0)
    482 		lagg_count--;
    483 
    484 	return 0;
    485 }
    486 
    487 static int
    488 lagg_init(struct ifnet *ifp)
    489 {
    490 	struct lagg_softc *sc;
    491 	int rv;
    492 
    493 	sc = ifp->if_softc;
    494 	LAGG_LOCK(sc);
    495 	rv = lagg_init_locked(sc);
    496 	LAGG_UNLOCK(sc);
    497 
    498 	return rv;
    499 }
    500 
    501 static int
    502 lagg_init_locked(struct lagg_softc *sc)
    503 {
    504 	struct ifnet *ifp = &sc->sc_if;
    505 	int rv;
    506 
    507 	KASSERT(LAGG_LOCKED(sc));
    508 
    509 	if (ISSET(ifp->if_flags, IFF_RUNNING))
    510 		lagg_stop_locked(sc);
    511 
    512 	lagg_sync_sadl(sc);
    513 
    514 	SET(ifp->if_flags, IFF_RUNNING);
    515 
    516 	rv = lagg_proto_up(sc);
    517 	if (rv != 0)
    518 		lagg_stop_locked(sc);
    519 
    520 	return rv;
    521 }
    522 
    523 static void
    524 lagg_stop(struct ifnet *ifp, int disable __unused)
    525 {
    526 	struct lagg_softc *sc;
    527 
    528 	sc = ifp->if_softc;
    529 	LAGG_LOCK(sc);
    530 	lagg_stop_locked(sc);
    531 	LAGG_UNLOCK(sc);
    532 }
    533 
    534 static void
    535 lagg_stop_locked(struct lagg_softc *sc)
    536 {
    537 	struct ifnet *ifp = &sc->sc_if;
    538 
    539 	KASSERT(LAGG_LOCKED(sc));
    540 
    541 	if (!ISSET(ifp->if_flags, IFF_RUNNING))
    542 		return;
    543 
    544 	CLR(ifp->if_flags, IFF_RUNNING);
    545 	lagg_proto_down(sc);
    546 
    547 }
    548 
    549 static int
    550 lagg_config(struct lagg_softc *sc, struct lagg_req *lrq)
    551 {
    552 	struct ifnet *ifp_port;
    553 	struct laggreqport *rp;
    554 	struct lagg_port *lp;
    555 	struct psref psref;
    556 	size_t i;
    557 	int error, bound;
    558 
    559 	error = 0;
    560 	bound = curlwp_bind();
    561 
    562 	switch (lrq->lrq_ioctl) {
    563 	case LAGGIOC_SETPROTO:
    564 		if (lrq->lrq_proto >= LAGG_PROTO_MAX) {
    565 			error = EPROTONOSUPPORT;
    566 			break;
    567 		}
    568 
    569 		error = lagg_delport_all(sc);
    570 		if (error != 0)
    571 			break;
    572 		error = lagg_pr_attach(sc, lrq->lrq_proto);
    573 		if (error != 0)
    574 			break;
    575 
    576 		for (i = 0; i < lrq->lrq_nports; i++) {
    577 			rp = &lrq->lrq_reqports[i];
    578 			ifp_port = if_get(rp->rp_portname, &psref);
    579 			if (ifp_port == NULL) {
    580 				error = ENOENT;
    581 				break;	/* break for */
    582 			}
    583 
    584 			error = lagg_addport(sc, ifp_port);
    585 			if_put(ifp_port, &psref);
    586 
    587 			if (error != 0)
    588 				break;	/* break for */
    589 		}
    590 		break;	/* break switch */
    591 	case LAGGIOC_ADDPORT:
    592 		rp = &lrq->lrq_reqports[0];
    593 		ifp_port = if_get(rp->rp_portname, &psref);
    594 		if (ifp_port == NULL) {
    595 			error = ENOENT;
    596 			break;
    597 		}
    598 
    599 		error = lagg_addport(sc, ifp_port);
    600 		if_put(ifp_port, &psref);
    601 		break;
    602 	case LAGGIOC_DELPORT:
    603 		rp = &lrq->lrq_reqports[0];
    604 		ifp_port = if_get(rp->rp_portname, &psref);
    605 		if (ifp_port == NULL) {
    606 			error = ENOENT;
    607 			break;
    608 		}
    609 
    610 		error = lagg_delport(sc, ifp_port);
    611 		if_put(ifp_port, &psref);
    612 		break;
    613 	case LAGGIOC_SETPORTPRI:
    614 		rp = &lrq->lrq_reqports[0];
    615 		ifp_port = if_get(rp->rp_portname, &psref);
    616 		if (ifp_port == NULL) {
    617 			error = ENOENT;
    618 			break;
    619 		}
    620 
    621 		lp = ifp_port->if_lagg;
    622 		if (lp == NULL || lp->lp_softc != sc) {
    623 			if_put(ifp_port, &psref);
    624 			error = ENOENT;
    625 			break;
    626 		}
    627 
    628 		lp->lp_prio = rp->rp_prio;
    629 
    630 		/* restart protocol */
    631 		LAGG_LOCK(sc);
    632 		lagg_proto_stopport(sc, lp);
    633 		lagg_proto_startport(sc, lp);
    634 		LAGG_UNLOCK(sc);
    635 		if_put(ifp_port, &psref);
    636 		break;
    637 	case LAGGIOC_SETPROTOOPT:
    638 		error = lagg_proto_ioctl(sc, lrq);
    639 		break;
    640 	default:
    641 		error = ENOTTY;
    642 	}
    643 
    644 	curlwp_bindx(bound);
    645 	return error;
    646 }
    647 
    648 static int
    649 lagg_ioctl(struct ifnet *ifp, u_long cmd, void *data)
    650 {
    651 	struct lagg_softc *sc;
    652 	struct ifreq *ifr = (struct ifreq *)data;
    653 	struct lagg_req laggreq, *laggresp;
    654 	struct lagg_port *lp;
    655 	size_t allocsiz, outlen, nports;
    656 	char *outbuf;
    657 	void *buf;
    658 	int error = 0, rv;
    659 
    660 	sc = ifp->if_softc;
    661 
    662 	switch (cmd) {
    663 	case SIOCGLAGG:
    664 		error = copyin(ifr->ifr_data, &laggreq, sizeof(laggreq));
    665 		if (error != 0)
    666 			break;
    667 
    668 		nports = sc->sc_nports;
    669 		nports = MIN(nports, laggreq.lrq_nports);
    670 
    671 		allocsiz = sizeof(*laggresp)
    672 		    + sizeof(laggresp->lrq_reqports[0]) * nports;
    673 		laggresp = kmem_zalloc(allocsiz, KM_SLEEP);
    674 
    675 		rv = lagg_get_stats(sc, laggresp, nports);
    676 
    677 		outbuf = (char *)laggresp;
    678 
    679 		nports = MIN(laggresp->lrq_nports, nports);
    680 		outlen = sizeof(*laggresp)
    681 		    + sizeof(laggresp->lrq_reqports[0]) * nports;
    682 
    683 		error = copyout(outbuf, ifr->ifr_data, outlen);
    684 		kmem_free(outbuf, allocsiz);
    685 
    686 		if (error == 0 && rv != 0)
    687 			error = rv;
    688 
    689 		break;
    690 	case SIOCSLAGG:
    691 		error = copyin(ifr->ifr_data, &laggreq, sizeof(laggreq));
    692 		if (error != 0)
    693 			break;
    694 
    695 		nports = laggreq.lrq_nports;
    696 		if (nports > LAGG_MAX_PORTS) {
    697 			error = ENOMEM;
    698 			break;
    699 		} else if (nports > 0) {
    700 			allocsiz = sizeof(struct lagg_req)
    701 			    + sizeof(struct laggreqport) * nports;
    702 			buf = kmem_alloc(allocsiz, KM_SLEEP);
    703 
    704 			error = copyin(ifr->ifr_data, buf, allocsiz);
    705 			if (error != 0) {
    706 				kmem_free(buf, allocsiz);
    707 				break;
    708 			}
    709 		} else {
    710 			buf = (void *)&laggreq;
    711 			allocsiz = 0;
    712 		}
    713 
    714 		error = lagg_config(sc, buf);
    715 		if (allocsiz > 0)
    716 			kmem_free(buf, allocsiz);
    717 		break;
    718 	case SIOCSIFFLAGS:
    719 		error = ifioctl_common(ifp, cmd, data);
    720 		if (error != 0)
    721 			break;
    722 
    723 		switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
    724 		case IFF_RUNNING:
    725 			if_stop(ifp, 1);
    726 			break;
    727 		case IFF_UP:
    728 			error = if_init(ifp);
    729 			break;
    730 		}
    731 
    732 		if (error != 0)
    733 			break;
    734 
    735 		/* Set flags on ports too */
    736 		LAGG_LOCK(sc);
    737 		LAGG_PORTS_FOREACH(sc, lp) {
    738 			(void)lagg_config_promisc(sc, lp);
    739 		}
    740 		LAGG_UNLOCK(sc);
    741 		break;
    742 	case SIOCSIFMTU:
    743 		/* set the MTU to each port */
    744 		LAGG_LOCK(sc);
    745 		LAGG_PORTS_FOREACH(sc, lp) {
    746 			error = lagg_lp_ioctl(lp, cmd, (void *)ifr);
    747 
    748 			if (error != 0) {
    749 				LAGG_LOG(sc, LOG_ERR,
    750 				    "failed to change MTU to %d on port %s, "
    751 				    "reverting all ports to original "
    752 				    "MTU(%" PRIu64 ")\n",
    753 				    ifr->ifr_mtu, lp->lp_ifp->if_xname,
    754 				    ifp->if_mtu);
    755 				break;
    756 			}
    757 		}
    758 		LAGG_UNLOCK(sc);
    759 
    760 		/* set the MTU to the lagg interface */
    761 		if (error == 0)
    762 			error = ether_ioctl(ifp, cmd, data);
    763 
    764 		if (error != 0) {
    765 			/* undo the changed MTU */
    766 			ifr->ifr_mtu = ifp->if_mtu;
    767 
    768 			LAGG_LOCK(sc);
    769 			LAGG_PORTS_FOREACH(sc, lp) {
    770 				if (lp->lp_ioctl != NULL)
    771 					lagg_lp_ioctl(lp, cmd, (void *)ifr);
    772 			}
    773 			LAGG_UNLOCK(sc);
    774 		}
    775 		break;
    776 	case SIOCADDMULTI:
    777 		if (sc->sc_if.if_type == IFT_ETHER) {
    778 			error = lagg_ether_addmulti(sc, ifr);
    779 		} else {
    780 			error = EPROTONOSUPPORT;
    781 		}
    782 		break;
    783 	case SIOCDELMULTI:
    784 		if (sc->sc_if.if_type == IFT_ETHER) {
    785 			error = lagg_ether_delmulti(sc, ifr);
    786 		} else {
    787 			error = EPROTONOSUPPORT;
    788 		}
    789 		break;
    790 	case SIOCSIFCAP:
    791 		error = ether_ioctl(ifp, cmd, data);
    792 		if (error == 0)
    793 			lagg_sync_ifcaps(sc);
    794 		break;
    795 	case SIOCSETHERCAP:
    796 		error = ether_ioctl(ifp, cmd, data);
    797 		if (error == 0)
    798 			lagg_sync_ethcaps(sc);
    799 		break;
    800 	default:
    801 		error = ether_ioctl(ifp, cmd, data);
    802 	}
    803 	return error;
    804 }
    805 
    806 static int
    807 lagg_setup_sysctls(struct lagg_softc *sc)
    808 {
    809 	struct sysctllog **slog;
    810 	const struct sysctlnode **rnode, *hashnode;
    811 	const char *ifname;
    812 	int error;
    813 
    814 	slog = &sc->sc_sysctllog;
    815 	rnode = &sc->sc_sysctlnode;
    816 	ifname = sc->sc_if.if_xname;
    817 
    818 	error = sysctl_createv(slog, 0, NULL, rnode,
    819 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, ifname,
    820 	    SYSCTL_DESCR("lagg information and settings"),
    821 	    NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL);
    822 	if (error != 0)
    823 		goto done;
    824 
    825 	error = sysctl_createv(slog, 0, rnode, &hashnode,
    826 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hash",
    827 	    SYSCTL_DESCR("hash calculation settings"),
    828 	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL);
    829 	if (error != 0)
    830 		goto done;
    831 
    832 	error = sysctl_createv(slog, 0, &hashnode, NULL,
    833 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "macaddr",
    834 	    SYSCTL_DESCR("use src/dst mac addresses"),
    835 	    NULL, 0, &sc->sc_hash_mac, 0, CTL_CREATE, CTL_EOL);
    836 	if (error != 0)
    837 		goto done;
    838 
    839 	error = sysctl_createv(slog, 0, &hashnode, NULL,
    840 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "ipaddr",
    841 	    SYSCTL_DESCR("use src/dst IPv4 addresses"),
    842 	    NULL, 0, &sc->sc_hash_ipaddr, 0, CTL_CREATE, CTL_EOL);
    843 	if (error != 0)
    844 		goto done;
    845 
    846 	error = sysctl_createv(slog, 0, &hashnode, NULL,
    847 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "ip6addr",
    848 	    SYSCTL_DESCR("use src/dst IPv6 addresses"),
    849 	    NULL, 0, &sc->sc_hash_ip6addr, 0, CTL_CREATE, CTL_EOL);
    850 	if (error != 0)
    851 		goto done;
    852 
    853 	error = sysctl_createv(slog, 0, &hashnode, NULL,
    854 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "tcp",
    855 	    SYSCTL_DESCR("use TCP src/dst port"),
    856 	    NULL, 0, &sc->sc_hash_tcp, 0, CTL_CREATE, CTL_EOL);
    857 	if (error != 0)
    858 		goto done;
    859 
    860 	error = sysctl_createv(slog, 0, &hashnode, NULL,
    861 	   CTLFLAG_READWRITE, CTLTYPE_BOOL, "udp",
    862 	   SYSCTL_DESCR("use UDP src/dst port"),
    863 	   NULL, 0, &sc->sc_hash_udp, 0, CTL_CREATE, CTL_EOL);
    864 done:
    865 	if (error != 0) {
    866 		LAGG_LOG(sc, LOG_ERR, "unable to create sysctl node\n");
    867 		sysctl_teardown(slog);
    868 	}
    869 
    870 	return error;
    871 }
    872 
    873 static void
    874 lagg_teardown_sysctls(struct lagg_softc *sc)
    875 {
    876 
    877 	sc->sc_sysctlnode = NULL;
    878 	sysctl_teardown(&sc->sc_sysctllog);
    879 }
    880 
    881 uint32_t
    882 lagg_hashmbuf(struct lagg_softc *sc, struct mbuf *m)
    883 {
    884 	union {
    885 		struct ether_header _eh;
    886 		struct ether_vlan_header _evl;
    887 		struct ip _ip;
    888 		struct ip6_hdr _ip6;
    889 		struct tcphdr _th;
    890 		struct udphdr _uh;
    891 	} buf;
    892 	const struct ether_header *eh;
    893 	const struct ether_vlan_header *evl;
    894 	const struct ip *ip;
    895 	const struct ip6_hdr *ip6;
    896 	const struct tcphdr *th;
    897 	const struct udphdr *uh;
    898 	uint32_t hash, hash_src, hash_dst;
    899 	uint32_t flowlabel;
    900 	uint16_t etype, vlantag;
    901 	uint8_t proto;
    902 	size_t off;
    903 
    904 	KASSERT(ISSET(m->m_flags, M_PKTHDR));
    905 
    906 	hash = HASH32_BUF_INIT;
    907 	hash_src = HASH32_BUF_INIT;
    908 	hash_dst = HASH32_BUF_INIT;
    909 
    910 #define LAGG_HASH_ADD(hp, v) do {		\
    911 	*(hp) = hash32_buf(&(v), sizeof(v), *(hp));	\
    912 } while(0)
    913 
    914 	eh = lagg_m_extract(m, 0, sizeof(*eh), __alignof(*eh), &buf);
    915 	if (eh == NULL)
    916 		goto out;
    917 
    918 	off = ETHER_HDR_LEN;
    919 	etype = ntohs(eh->ether_type);
    920 
    921 	if (etype == ETHERTYPE_VLAN) {
    922 		evl = lagg_m_extract(m, 0, sizeof(*evl), __alignof(*evl),
    923 		    &buf);
    924 		if (evl == NULL)
    925 			goto out;
    926 
    927 		vlantag = ntohs(evl->evl_tag);
    928 		etype = ntohs(evl->evl_proto);
    929 		off += ETHER_VLAN_ENCAP_LEN;
    930 	} else if (vlan_has_tag(m)) {
    931 		vlantag = vlan_get_tag(m);
    932 	} else {
    933 		vlantag = 0;
    934 	}
    935 
    936 	if (sc->sc_hash_mac) {
    937 		LAGG_HASH_ADD(&hash_dst, eh->ether_dhost);
    938 		LAGG_HASH_ADD(&hash_src, eh->ether_shost);
    939 		LAGG_HASH_ADD(&hash, vlantag);
    940 	}
    941 
    942 	switch (etype) {
    943 	case ETHERTYPE_IP:
    944 		ip = lagg_m_extract(m, off, sizeof(*ip), __alignof(*ip), &buf);
    945 		if (ip == NULL)
    946 			goto out;
    947 
    948 		if (sc->sc_hash_ipaddr) {
    949 			LAGG_HASH_ADD(&hash_src, ip->ip_src);
    950 			LAGG_HASH_ADD(&hash_dst, ip->ip_dst);
    951 			LAGG_HASH_ADD(&hash, ip->ip_p);
    952 		}
    953 		off += ip->ip_hl << 2;
    954 		proto = ip->ip_p;
    955 		break;
    956 	case ETHERTYPE_IPV6:
    957 		ip6 = lagg_m_extract(m, off, sizeof(*ip6), __alignof(*ip6),
    958 		    &buf);
    959 		if (ip6 == NULL)
    960 			goto out;
    961 
    962 		if (sc->sc_hash_ip6addr) {
    963 			LAGG_HASH_ADD(&hash_src, ip6->ip6_src);
    964 			LAGG_HASH_ADD(&hash_dst, ip6->ip6_dst);
    965 			flowlabel = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
    966 			LAGG_HASH_ADD(&hash, flowlabel);
    967 		}
    968 		proto = ip6->ip6_nxt;
    969 		off += sizeof(*ip6);
    970 		break;
    971 
    972 	default:
    973 		return hash;
    974 	}
    975 
    976 	switch (proto) {
    977 	case IPPROTO_TCP:
    978 		th = lagg_m_extract(m, off, sizeof(*th), __alignof(*th), &buf);
    979 		if (th == NULL)
    980 			goto out;
    981 
    982 		if (sc->sc_hash_tcp) {
    983 			LAGG_HASH_ADD(&hash_src, th->th_sport);
    984 			LAGG_HASH_ADD(&hash_dst, th->th_dport);
    985 		}
    986 		break;
    987 	case IPPROTO_UDP:
    988 		uh = lagg_m_extract(m, off, sizeof(*uh), __alignof(*uh), &buf);
    989 		if (uh == NULL)
    990 			goto out;
    991 
    992 		if (sc->sc_hash_udp) {
    993 			LAGG_HASH_ADD(&hash_src, uh->uh_sport);
    994 			LAGG_HASH_ADD(&hash_dst, uh->uh_dport);
    995 		}
    996 		break;
    997 	}
    998 
    999 out:
   1000 	hash_src ^= hash_dst;
   1001 	LAGG_HASH_ADD(&hash, hash_src);
   1002 #undef LAGG_HASH_ADD
   1003 
   1004 	return hash;
   1005 }
   1006 
   1007 static int
   1008 lagg_tx_common(struct ifnet *ifp, struct mbuf *m)
   1009 {
   1010 	struct lagg_variant *var;
   1011 	lagg_proto pr;
   1012 	struct psref psref;
   1013 	int error;
   1014 
   1015 	var = lagg_variant_getref(ifp->if_softc, &psref);
   1016 
   1017 	if (__predict_false(var == NULL)) {
   1018 		m_freem(m);
   1019 		if_statinc(ifp, if_oerrors);
   1020 		return ENOENT;
   1021 	}
   1022 
   1023 	pr = var->lv_proto;
   1024 	if (__predict_true(lagg_protos[pr].pr_transmit != NULL)) {
   1025 		error = lagg_protos[pr].pr_transmit(var->lv_psc, m);
   1026 		/* mbuf is already freed */
   1027 	} else {
   1028 		m_freem(m);
   1029 		if_statinc(ifp, if_oerrors);
   1030 		error = EIO;
   1031 	}
   1032 
   1033 	lagg_variant_putref(var, &psref);
   1034 
   1035 	return error;
   1036 }
   1037 
   1038 static int
   1039 lagg_transmit(struct ifnet *ifp, struct mbuf *m)
   1040 {
   1041 
   1042 	return lagg_tx_common(ifp, m);
   1043 }
   1044 
   1045 static void
   1046 lagg_start(struct ifnet *ifp)
   1047 {
   1048 	struct mbuf *m;
   1049 
   1050 	for (;;) {
   1051 		IFQ_DEQUEUE(&ifp->if_snd, m);
   1052 		if (m == NULL)
   1053 			break;
   1054 
   1055 		(void)lagg_tx_common(ifp, m);
   1056 	}
   1057 }
   1058 
   1059 void
   1060 lagg_output(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m)
   1061 {
   1062 	struct ifnet *ifp;
   1063 	int len, error;
   1064 	short mflags;
   1065 
   1066 	ifp = &sc->sc_if;
   1067 	len = m->m_pkthdr.len;
   1068 	mflags = m->m_flags;
   1069 
   1070 	error = pfil_run_hooks(ifp->if_pfil, &m, ifp, PFIL_OUT);
   1071 	if (error != 0) {
   1072 		m_freem(m);
   1073 		return;
   1074 	}
   1075 	bpf_mtap(ifp, m, BPF_D_OUT);
   1076 
   1077 	error = lagg_port_xmit(lp, m);
   1078 	if (error) {
   1079 		/* mbuf is already freed */
   1080 		if_statinc(ifp, if_oerrors);
   1081 	} else {
   1082 		net_stat_ref_t nsr = IF_STAT_GETREF(ifp);
   1083 		if_statinc_ref(ifp, nsr, if_opackets);
   1084 		if_statadd_ref(ifp, nsr, if_obytes, len);
   1085 		if (mflags & M_MCAST)
   1086 			if_statinc_ref(ifp, nsr, if_omcasts);
   1087 		IF_STAT_PUTREF(ifp);
   1088 	}
   1089 }
   1090 
   1091 static struct mbuf *
   1092 lagg_proto_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m)
   1093 {
   1094 	struct psref psref;
   1095 	struct lagg_variant *var;
   1096 	lagg_proto pr;
   1097 
   1098 	var = lagg_variant_getref(sc, &psref);
   1099 
   1100 	if (var == NULL) {
   1101 		sc->sc_novar.ev_count++;
   1102 		m_freem(m);
   1103 		return NULL;
   1104 	}
   1105 
   1106 	pr = var->lv_proto;
   1107 
   1108 	if (lagg_protos[pr].pr_input != NULL) {
   1109 		m = lagg_protos[pr].pr_input(var->lv_psc, lp, m);
   1110 	} else {
   1111 		m_freem(m);
   1112 		m = NULL;
   1113 	}
   1114 
   1115 	lagg_variant_putref(var, &psref);
   1116 
   1117 	return m;
   1118 }
   1119 
   1120 static void
   1121 lagg_input_ethernet(struct ifnet *ifp_port, struct mbuf *m)
   1122 {
   1123 	struct ifnet *ifp;
   1124 	struct psref psref;
   1125 	struct lagg_port *lp;
   1126 	struct ether_header *eh;
   1127 	int s;
   1128 
   1129 	/* sanity check */
   1130 	s = pserialize_read_enter();
   1131 	lp = atomic_load_consume(&ifp_port->if_lagg);
   1132 	if (lp == NULL) {
   1133 		/* This interface is not a member of lagg */
   1134 		pserialize_read_exit(s);
   1135 		m_freem(m);
   1136 		if_statinc(ifp_port, if_ierrors);
   1137 		return;
   1138 	}
   1139 	lagg_port_getref(lp, &psref);
   1140 	pserialize_read_exit(s);
   1141 
   1142 	ifp = &lp->lp_softc->sc_if;
   1143 
   1144 	if (__predict_false(m->m_len < (int)sizeof(*eh))) {
   1145 		if ((m = m_pullup(m, sizeof(*eh))) == NULL) {
   1146 			if_statinc(ifp, if_ierrors);
   1147 			goto out;
   1148 		}
   1149 	}
   1150 
   1151 	eh = mtod(m, struct ether_header *);
   1152 
   1153 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
   1154 		/*
   1155 		 * If this is not a simplex interface, drop the packet
   1156 		 * if it came from us.
   1157 		 */
   1158 		if ((ifp->if_flags & IFF_SIMPLEX) == 0 &&
   1159 		    memcmp(CLLADDR(ifp->if_sadl), eh->ether_shost,
   1160 		    ETHER_ADDR_LEN) == 0) {
   1161 			goto drop;
   1162 		}
   1163 
   1164 		if_statinc(ifp_port, if_imcasts);
   1165 	} else {
   1166 		/*
   1167 		 * Drop promiscuously received packets
   1168 		 * if we are not in promiscuous mode.
   1169 		 */
   1170 		if ((ifp->if_flags & IFF_PROMISC) == 0 &&
   1171 		    (ifp_port->if_flags & IFF_PROMISC) != 0 &&
   1172 		    memcmp(CLLADDR(ifp->if_sadl), eh->ether_dhost,
   1173 		    ETHER_ADDR_LEN) != 0)
   1174 			goto drop;
   1175 	}
   1176 
   1177 	if_statadd(ifp_port, if_ibytes, m->m_pkthdr.len);
   1178 
   1179 	if (pfil_run_hooks(ifp_port->if_pfil, &m,
   1180 	    ifp_port, PFIL_IN) != 0) {
   1181 		m_freem(m);
   1182 		m = NULL;
   1183 		goto out;
   1184 	}
   1185 
   1186 	m = lagg_proto_input(lp->lp_softc, lp, m);
   1187 	if (m != NULL) {
   1188 		m_set_rcvif(m, ifp);
   1189 		m->m_flags &= ~M_PROMISC;
   1190 		if_input(ifp, m);
   1191 	}
   1192 
   1193 out:
   1194 	lagg_port_putref(lp, &psref);
   1195 	return;
   1196 
   1197 drop:
   1198 	lagg_port_putref(lp, &psref);
   1199 	m_freem(m);
   1200 	if_statinc(ifp_port, if_iqdrops);
   1201 	return;
   1202 }
   1203 
   1204 static int
   1205 lagg_media_change(struct ifnet *ifp)
   1206 {
   1207 
   1208 	if (ISSET(ifp->if_flags, IFF_DEBUG))
   1209 		printf("%s: ignore media change\n", ifp->if_xname);
   1210 
   1211 	return 0;
   1212 }
   1213 
   1214 static void
   1215 lagg_media_status(struct ifnet *ifp, struct ifmediareq *imr)
   1216 {
   1217 	struct lagg_softc *sc;
   1218 	struct lagg_port *lp;
   1219 
   1220 	sc = ifp->if_softc;
   1221 
   1222 	imr->ifm_status = IFM_AVALID;
   1223 	imr->ifm_active = IFM_ETHER | IFM_AUTO;
   1224 
   1225 	LAGG_LOCK(sc);
   1226 
   1227 	imr->ifm_active |= sc->sc_media_active;
   1228 
   1229 	LAGG_PORTS_FOREACH(sc, lp) {
   1230 		if (lagg_portactive(lp))
   1231 			imr->ifm_status |= IFM_ACTIVE;
   1232 	}
   1233 	LAGG_UNLOCK(sc);
   1234 }
   1235 
   1236 static uint64_t
   1237 lagg_search_media_type(uint64_t linkspeed)
   1238 {
   1239 
   1240 	if (linkspeed == IF_Gbps(40))
   1241 		return IFM_40G_T | IFM_FDX;
   1242 
   1243 	if (linkspeed == IF_Gbps(25))
   1244 		return IFM_25G_T | IFM_FDX;
   1245 
   1246 	if (linkspeed == IF_Gbps(10))
   1247 		return IFM_10G_T | IFM_FDX;
   1248 
   1249 	if (linkspeed == IF_Gbps(5))
   1250 		return IFM_5000_T | IFM_FDX;
   1251 
   1252 	if (linkspeed == IF_Mbps(2500))
   1253 		return IFM_2500_T | IFM_FDX;
   1254 
   1255 	if (linkspeed == IF_Gbps(1))
   1256 		return IFM_1000_T | IFM_FDX;
   1257 
   1258 	if (linkspeed == IF_Mbps(100))
   1259 		return IFM_100_TX | IFM_FDX;
   1260 
   1261 	if (linkspeed == IF_Mbps(10))
   1262 		return IFM_10_T | IFM_FDX;
   1263 
   1264 	return 0;
   1265 }
   1266 
   1267 void
   1268 lagg_set_linkspeed(struct lagg_softc *sc, uint64_t linkspeed)
   1269 {
   1270 	struct ifnet *ifp;
   1271 
   1272 	ifp = &sc->sc_if;
   1273 
   1274 	KASSERT(LAGG_LOCKED(sc));
   1275 
   1276 	ifp->if_baudrate = linkspeed;
   1277 
   1278 	sc->sc_media_active =
   1279 	    lagg_search_media_type(linkspeed);
   1280 }
   1281 
   1282 static int
   1283 lagg_port_vlan_cb(struct lagg_port *lp,
   1284     struct lagg_vlantag *lvt, bool set)
   1285 {
   1286 	struct ifnet *ifp_port;
   1287 	int error;
   1288 
   1289 	if (lp->lp_iftype != IFT_ETHER)
   1290 		return 0;
   1291 
   1292 	error = 0;
   1293 	ifp_port = lp->lp_ifp;
   1294 
   1295 	if (set) {
   1296 		error = ether_add_vlantag(ifp_port,
   1297 		    lvt->lvt_vtag, NULL);
   1298 	} else {
   1299 		error = ether_del_vlantag(ifp_port,
   1300 		    lvt->lvt_vtag);
   1301 	}
   1302 
   1303 	return error;
   1304 }
   1305 
   1306 static int
   1307 lagg_vlan_cb(struct ethercom *ec, uint16_t vtag, bool set)
   1308 {
   1309 	struct ifnet *ifp;
   1310 	struct lagg_softc *sc;
   1311 	struct lagg_vlantag *lvt, *lvt0;
   1312 	struct lagg_port *lp;
   1313 	int error;
   1314 
   1315 	ifp = (struct ifnet *)ec;
   1316 	sc = ifp->if_softc;
   1317 
   1318 	if (set) {
   1319 		lvt = kmem_zalloc(sizeof(*lvt), KM_SLEEP);
   1320 		lvt->lvt_vtag = vtag;
   1321 		TAILQ_INSERT_TAIL(&sc->sc_vtags, lvt, lvt_entry);
   1322 	} else {
   1323 		TAILQ_FOREACH_SAFE(lvt, &sc->sc_vtags, lvt_entry, lvt0) {
   1324 			if (lvt->lvt_vtag == vtag) {
   1325 				TAILQ_REMOVE(&sc->sc_vtags, lvt, lvt_entry);
   1326 				break;
   1327 			}
   1328 		}
   1329 
   1330 		if (lvt == NULL)
   1331 			return ENOENT;
   1332 	}
   1333 
   1334 	KASSERT(lvt != NULL);
   1335 	LAGG_PORTS_FOREACH(sc, lp) {
   1336 		error = lagg_port_vlan_cb(lp, lvt, set);
   1337 		if (error != 0) {
   1338 			LAGG_LOG(sc, LOG_WARNING,
   1339 			    "%s failed to configure vlan on %d\n",
   1340 			    lp->lp_ifp->if_xname, error);
   1341 		}
   1342 	}
   1343 
   1344 	return 0;
   1345 }
   1346 
   1347 static struct lagg_softc *
   1348 lagg_softc_alloc(enum lagg_iftypes ift)
   1349 {
   1350 	struct lagg_softc *sc;
   1351 	size_t s;
   1352 
   1353 	s = lagg_sizeof_softc(ift);
   1354 	KASSERT(s > 0);
   1355 
   1356 	sc = kmem_zalloc(s, KM_SLEEP);
   1357 	KASSERT(sc != NULL);
   1358 
   1359 	return sc;
   1360 }
   1361 
   1362 static void
   1363 lagg_softc_free(struct lagg_softc *sc)
   1364 {
   1365 
   1366 	kmem_free(sc,
   1367 	    lagg_sizeof_softc(sc->sc_iftype));
   1368 }
   1369 
   1370 static void
   1371 lagg_variant_update(struct lagg_softc *sc, struct lagg_variant *newvar)
   1372 {
   1373 	struct lagg_variant *oldvar;
   1374 
   1375 	KASSERT(LAGG_LOCKED(sc));
   1376 
   1377 	psref_target_init(&newvar->lv_psref, lagg_psref_class);
   1378 
   1379 	oldvar = sc->sc_var;
   1380 	atomic_store_release(&sc->sc_var, newvar);
   1381 	pserialize_perform(sc->sc_psz);
   1382 
   1383 	if (__predict_true(oldvar != NULL))
   1384 		psref_target_destroy(&oldvar->lv_psref, lagg_psref_class);
   1385 }
   1386 
   1387 static struct lagg_variant *
   1388 lagg_variant_getref(struct lagg_softc *sc, struct psref *psref)
   1389 {
   1390 	struct lagg_variant *var;
   1391 	int s;
   1392 
   1393 	s = pserialize_read_enter();
   1394 	var = atomic_load_consume(&sc->sc_var);
   1395 	if (var == NULL) {
   1396 		pserialize_read_exit(s);
   1397 		return NULL;
   1398 	}
   1399 
   1400 	psref_acquire(psref, &var->lv_psref, lagg_psref_class);
   1401 	pserialize_read_exit(s);
   1402 
   1403 	return var;
   1404 }
   1405 
   1406 static void
   1407 lagg_variant_putref(struct lagg_variant *var, struct psref *psref)
   1408 {
   1409 
   1410 	if (__predict_false(var == NULL))
   1411 		return;
   1412 	psref_release(psref, &var->lv_psref, lagg_psref_class);
   1413 }
   1414 
   1415 static int
   1416 lagg_proto_attach(struct lagg_softc *sc, lagg_proto pr,
   1417     struct lagg_proto_softc **psc)
   1418 {
   1419 
   1420 	KASSERT(lagg_protos[pr].pr_attach != NULL);
   1421 	return lagg_protos[pr].pr_attach(sc, psc);
   1422 }
   1423 
   1424 static void
   1425 lagg_proto_detach(struct lagg_variant *oldvar)
   1426 {
   1427 	lagg_proto pr;
   1428 
   1429 	pr = oldvar->lv_proto;
   1430 
   1431 	if (lagg_protos[pr].pr_detach == NULL)
   1432 		return;
   1433 
   1434 	lagg_protos[pr].pr_detach(oldvar->lv_psc);
   1435 }
   1436 
   1437 static int
   1438 lagg_proto_updown(struct lagg_softc *sc, bool is_up)
   1439 {
   1440 	struct lagg_variant *var;
   1441 	struct psref psref;
   1442 	lagg_proto pr;
   1443 	int error, bound;
   1444 
   1445 	error = 0;
   1446 	bound = curlwp_bind();
   1447 
   1448 	var = lagg_variant_getref(sc, &psref);
   1449 	if (var == NULL) {
   1450 		curlwp_bindx(bound);
   1451 		return ENXIO;
   1452 	}
   1453 
   1454 	pr = var->lv_proto;
   1455 
   1456 	if (is_up && lagg_protos[pr].pr_up != NULL) {
   1457 		error = lagg_protos[pr].pr_up(var->lv_psc);
   1458 	} else if (!is_up && lagg_protos[pr].pr_down != NULL) {
   1459 		lagg_protos[pr].pr_down(var->lv_psc);
   1460 	}
   1461 
   1462 	lagg_variant_putref(var, &psref);
   1463 	curlwp_bindx(bound);
   1464 
   1465 	return error;
   1466 }
   1467 
   1468 static int
   1469 lagg_proto_up(struct lagg_softc *sc)
   1470 {
   1471 
   1472 	return lagg_proto_updown(sc, true);
   1473 }
   1474 
   1475 static void
   1476 lagg_proto_down(struct lagg_softc *sc)
   1477 {
   1478 
   1479 	(void)lagg_proto_updown(sc, false);
   1480 }
   1481 
   1482 static int
   1483 lagg_proto_portctrl(struct lagg_softc *sc, struct lagg_port *lp,
   1484     enum lagg_portctrl ctrl)
   1485 {
   1486 	struct lagg_variant *var;
   1487 	struct psref psref;
   1488 	lagg_proto pr;
   1489 	int error, bound;
   1490 
   1491 	error = 0;
   1492 	bound = curlwp_bind();
   1493 
   1494 	var = lagg_variant_getref(sc, &psref);
   1495 	if (var == NULL) {
   1496 		curlwp_bindx(bound);
   1497 		return ENXIO;
   1498 	}
   1499 
   1500 	pr = var->lv_proto;
   1501 
   1502 	switch (ctrl) {
   1503 	case LAGG_PORTCTRL_ALLOC:
   1504 		if (lagg_protos[pr].pr_allocport == NULL) {
   1505 			goto nosupport;
   1506 		}
   1507 		error = lagg_protos[pr].pr_allocport(var->lv_psc, lp);
   1508 		break;
   1509 	case LAGG_PORTCTRL_FREE:
   1510 		if (lagg_protos[pr].pr_freeport == NULL) {
   1511 			goto nosupport;
   1512 		}
   1513 		lagg_protos[pr].pr_freeport(var->lv_psc, lp);
   1514 		break;
   1515 	case LAGG_PORTCTRL_START:
   1516 		if (lagg_protos[pr].pr_startport == NULL) {
   1517 			goto nosupport;
   1518 		}
   1519 		lagg_protos[pr].pr_startport(var->lv_psc, lp);
   1520 		break;
   1521 	case LAGG_PORTCTRL_STOP:
   1522 		if (lagg_protos[pr].pr_stopport == NULL) {
   1523 			goto nosupport;
   1524 		}
   1525 		lagg_protos[pr].pr_stopport(var->lv_psc, lp);
   1526 		break;
   1527 	default:
   1528 		goto nosupport;
   1529 	}
   1530 
   1531 	lagg_variant_putref(var, &psref);
   1532 	curlwp_bindx(bound);
   1533 	return error;
   1534 
   1535 nosupport:
   1536 	lagg_variant_putref(var, &psref);
   1537 	curlwp_bindx(bound);
   1538 	return EPROTONOSUPPORT;
   1539 }
   1540 
   1541 static int
   1542 lagg_proto_allocport(struct lagg_softc *sc, struct lagg_port *lp)
   1543 {
   1544 
   1545 	return lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_ALLOC);
   1546 }
   1547 
   1548 static void
   1549 lagg_proto_freeport(struct lagg_softc *sc, struct lagg_port *lp)
   1550 {
   1551 
   1552 	lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_FREE);
   1553 }
   1554 
   1555 static void
   1556 lagg_proto_startport(struct lagg_softc *sc, struct lagg_port *lp)
   1557 {
   1558 
   1559 	lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_START);
   1560 }
   1561 
   1562 static void
   1563 lagg_proto_stopport(struct lagg_softc *sc, struct lagg_port *lp)
   1564 {
   1565 
   1566 	lagg_proto_portctrl(sc, lp, LAGG_PORTCTRL_STOP);
   1567 }
   1568 
   1569 static void
   1570 lagg_proto_linkstate(struct lagg_softc *sc, struct lagg_port *lp)
   1571 {
   1572 	struct lagg_variant *var;
   1573 	struct psref psref;
   1574 	lagg_proto pr;
   1575 	int bound;
   1576 
   1577 	KASSERT(IFNET_LOCKED(lp->lp_ifp));
   1578 
   1579 	bound = curlwp_bind();
   1580 	var = lagg_variant_getref(sc, &psref);
   1581 
   1582 	if (var == NULL) {
   1583 		curlwp_bindx(bound);
   1584 		return;
   1585 	}
   1586 
   1587 	pr = var->lv_proto;
   1588 
   1589 	if (lagg_protos[pr].pr_linkstate)
   1590 		lagg_protos[pr].pr_linkstate(var->lv_psc, lp);
   1591 
   1592 	lagg_variant_putref(var, &psref);
   1593 	curlwp_bindx(bound);
   1594 }
   1595 
   1596 static void
   1597 lagg_proto_stat(struct lagg_variant *var, struct laggreqproto *resp)
   1598 {
   1599 	lagg_proto pr;
   1600 
   1601 	pr = var->lv_proto;
   1602 
   1603 	if (lagg_protos[pr].pr_protostat != NULL)
   1604 		lagg_protos[pr].pr_protostat(var->lv_psc, resp);
   1605 }
   1606 
   1607 static void
   1608 lagg_proto_portstat(struct lagg_variant *var, struct lagg_port *lp,
   1609     struct laggreqport *resp)
   1610 {
   1611 	lagg_proto pr;
   1612 
   1613 	pr = var->lv_proto;
   1614 
   1615 	if (lagg_protos[pr].pr_portstat != NULL)
   1616 		lagg_protos[pr].pr_portstat(var->lv_psc, lp, resp);
   1617 }
   1618 
   1619 static int
   1620 lagg_proto_ioctl(struct lagg_softc *sc, struct lagg_req *lreq)
   1621 {
   1622 	struct lagg_variant *var;
   1623 	struct psref psref;
   1624 	lagg_proto pr;
   1625 	int bound, error;
   1626 
   1627 	error = ENOTTY;
   1628 	bound = curlwp_bind();
   1629 	var = lagg_variant_getref(sc, &psref);
   1630 
   1631 	if (var == NULL) {
   1632 		error = ENXIO;
   1633 		goto done;
   1634 	}
   1635 
   1636 	pr = var->lv_proto;
   1637 	if (pr != lreq->lrq_proto) {
   1638 		error = EBUSY;
   1639 		goto done;
   1640 	}
   1641 
   1642 	if (lagg_protos[pr].pr_ioctl != NULL) {
   1643 		error = lagg_protos[pr].pr_ioctl(var->lv_psc,
   1644 		    &lreq->lrq_reqproto);
   1645 	}
   1646 
   1647 done:
   1648 	if (var != NULL)
   1649 		lagg_variant_putref(var, &psref);
   1650 	curlwp_bindx(bound);
   1651 	return error;
   1652 }
   1653 
   1654 static int
   1655 lagg_pr_attach(struct lagg_softc *sc, lagg_proto pr)
   1656 {
   1657 	struct lagg_variant *newvar, *oldvar;
   1658 	struct lagg_proto_softc *psc;
   1659 	int error;
   1660 
   1661 	error = 0;
   1662 	newvar = kmem_alloc(sizeof(*newvar), KM_SLEEP);
   1663 
   1664 	LAGG_LOCK(sc);
   1665 	oldvar = sc->sc_var;
   1666 
   1667 	if (oldvar != NULL && oldvar->lv_proto == pr) {
   1668 		error = 0;
   1669 		goto failed;
   1670 	}
   1671 
   1672 	error = lagg_proto_attach(sc, pr, &psc);
   1673 	if (error != 0)
   1674 		goto failed;
   1675 
   1676 	newvar->lv_proto = pr;
   1677 	newvar->lv_psc = psc;
   1678 	lagg_variant_update(sc, newvar);
   1679 	lagg_set_linkspeed(sc, 0);
   1680 	LAGG_UNLOCK(sc);
   1681 
   1682 	if (oldvar != NULL) {
   1683 		lagg_proto_detach(oldvar);
   1684 		kmem_free(oldvar, sizeof(*oldvar));
   1685 	}
   1686 
   1687 	return 0;
   1688 
   1689 failed:
   1690 	LAGG_UNLOCK(sc);
   1691 	kmem_free(newvar, sizeof(*newvar));
   1692 
   1693 	return error;
   1694 }
   1695 
   1696 static void
   1697 lagg_pr_detach(struct lagg_softc *sc)
   1698 {
   1699 	struct lagg_variant *var;
   1700 
   1701 	LAGG_LOCK(sc);
   1702 	var = sc->sc_var;
   1703 	atomic_store_release(&sc->sc_var, NULL);
   1704 	LAGG_UNLOCK(sc);
   1705 	pserialize_perform(sc->sc_psz);
   1706 
   1707 	if (var != NULL)
   1708 		lagg_proto_detach(var);
   1709 
   1710 
   1711 	if (var != NULL)
   1712 		kmem_free(var, sizeof(*var));
   1713 }
   1714 
   1715 static int
   1716 lagg_ether_addmulti(struct lagg_softc *sc, struct ifreq *ifr)
   1717 {
   1718 	struct lagg_port *lp;
   1719 	struct lagg_mc_entry *mc;
   1720 	struct ethercom *ec;
   1721 	const struct sockaddr *sa;
   1722 	uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
   1723 	int error;
   1724 
   1725 	if (sc->sc_if.if_type != IFT_ETHER)
   1726 		return EPROTONOSUPPORT;
   1727 
   1728 	ec = (struct ethercom *)&sc->sc_if;
   1729 	sa = ifreq_getaddr(SIOCADDMULTI, ifr);
   1730 
   1731 	error = ether_addmulti(sa, ec);
   1732 	if (error != ENETRESET)
   1733 		return error;
   1734 
   1735 	error = ether_multiaddr(sa, addrlo, addrhi);
   1736 	KASSERT(error == 0);
   1737 
   1738 	mc = kmem_zalloc(sizeof(*mc), KM_SLEEP);
   1739 
   1740 	ETHER_LOCK(ec);
   1741 	mc->mc_enm = ether_lookup_multi(addrlo, addrhi, ec);
   1742 	ETHER_UNLOCK(ec);
   1743 
   1744 	KASSERT(mc->mc_enm != NULL);
   1745 
   1746 	LAGG_LOCK(sc);
   1747 	LAGG_PORTS_FOREACH(sc, lp) {
   1748 		(void)lagg_lp_ioctl(lp, SIOCADDMULTI, (void *)ifr);
   1749 	}
   1750 	LAGG_UNLOCK(sc);
   1751 
   1752 	KASSERT(sa->sa_len <= sizeof(mc->mc_addr));
   1753 	memcpy(&mc->mc_addr, sa, sa->sa_len);
   1754 	LIST_INSERT_HEAD(&sc->sc_mclist, mc, mc_entry);
   1755 
   1756 	return 0;
   1757 }
   1758 
   1759 static int
   1760 lagg_ether_delmulti(struct lagg_softc *sc, struct ifreq *ifr)
   1761 {
   1762 	struct lagg_port *lp;
   1763 	struct lagg_mc_entry *mc;
   1764 	const struct sockaddr *sa;
   1765 	struct ethercom *ec;
   1766 	struct ether_multi *enm;
   1767 	uint8_t addrlo[ETHER_ADDR_LEN], addrhi[ETHER_ADDR_LEN];
   1768 	int error;
   1769 
   1770 	ec = (struct ethercom *)&sc->sc_if;
   1771 	sa = ifreq_getaddr(SIOCDELMULTI, ifr);
   1772 	error = ether_multiaddr(sa, addrlo, addrhi);
   1773 	if (error != 0)
   1774 		return error;
   1775 
   1776 	ETHER_LOCK(ec);
   1777 	enm = ether_lookup_multi(addrlo, addrhi, ec);
   1778 	ETHER_UNLOCK(ec);
   1779 
   1780 	if (enm == NULL)
   1781 		return ENOENT;
   1782 
   1783 	LIST_FOREACH(mc, &sc->sc_mclist, mc_entry) {
   1784 		if (mc->mc_enm == enm)
   1785 			break;
   1786 	}
   1787 
   1788 	if (mc == NULL)
   1789 		return ENOENT;
   1790 
   1791 	error = ether_delmulti(sa, ec);
   1792 	if (error != ENETRESET)
   1793 		return error;
   1794 
   1795 	LAGG_LOCK(sc);
   1796 	LAGG_PORTS_FOREACH(sc, lp) {
   1797 		(void)lagg_lp_ioctl(lp, SIOCDELMULTI, (void *)ifr);
   1798 	}
   1799 	LAGG_UNLOCK(sc);
   1800 
   1801 	LIST_REMOVE(mc, mc_entry);
   1802 	kmem_free(mc, sizeof(*mc));
   1803 
   1804 	return 0;
   1805 }
   1806 
   1807 static void
   1808 lagg_port_multi(struct lagg_softc *sc, struct lagg_port *lp,
   1809     u_long cmd)
   1810 {
   1811 	struct lagg_mc_entry *mc;
   1812 	struct ifreq ifr;
   1813 	struct ifnet *ifp_port;
   1814 	const struct sockaddr *sa;
   1815 
   1816 	ifp_port = lp->lp_ifp;
   1817 
   1818 	memset(&ifr, 0, sizeof(ifr));
   1819 	strlcpy(ifr.ifr_name, ifp_port->if_xname, sizeof(ifr.ifr_name));
   1820 
   1821 	LIST_FOREACH(mc, &sc->sc_mclist, mc_entry) {
   1822 		sa = (struct sockaddr *)&mc->mc_addr;
   1823 		KASSERT(sizeof(ifr.ifr_space) >= sa->sa_len);
   1824 		memcpy(&ifr.ifr_addr, sa, sa->sa_len);
   1825 		(void)lagg_lp_ioctl(lp, cmd, (void *)&ifr);
   1826 	}
   1827 
   1828 }
   1829 
   1830 static void
   1831 lagg_port_syncmulti(struct lagg_softc *sc, struct lagg_port *lp)
   1832 {
   1833 
   1834 	lagg_port_multi(sc, lp, SIOCADDMULTI);
   1835 }
   1836 
   1837 static void
   1838 lagg_port_purgemulti(struct lagg_softc *sc, struct lagg_port *lp)
   1839 {
   1840 
   1841 	lagg_port_multi(sc, lp, SIOCDELMULTI);
   1842 }
   1843 
   1844 static void
   1845 lagg_port_vlan(struct lagg_softc *sc, struct lagg_port *lp,
   1846     bool set)
   1847 {
   1848 	struct lagg_vlantag *lvt;
   1849 	int error;
   1850 
   1851 	TAILQ_FOREACH(lvt, &sc->sc_vtags, lvt_entry) {
   1852 		error = lagg_port_vlan_cb(lp, lvt, set);
   1853 		if (error != 0) {
   1854 			LAGG_LOG(sc, LOG_WARNING,
   1855 			    "%s failed to configure vlan on %d\n",
   1856 			    lp->lp_ifp->if_xname, error);
   1857 		}
   1858 	}
   1859 }
   1860 
   1861 static void
   1862 lagg_port_syncvlan(struct lagg_softc *sc, struct lagg_port *lp)
   1863 
   1864 {
   1865 	lagg_port_vlan(sc, lp, true);
   1866 }
   1867 
   1868 static void
   1869 lagg_port_purgevlan(struct lagg_softc *sc, struct lagg_port *lp)
   1870 {
   1871 
   1872 	lagg_port_vlan(sc, lp, false);
   1873 }
   1874 
   1875 static int
   1876 lagg_setifcaps(struct lagg_port *lp, uint64_t cap)
   1877 {
   1878 	struct ifcapreq ifcr;
   1879 	int error;
   1880 
   1881 	if (lp->lp_ifp->if_capenable == cap)
   1882 		return 0;
   1883 
   1884 	memset(&ifcr, 0, sizeof(ifcr));
   1885 	ifcr.ifcr_capenable = cap;
   1886 
   1887 	IFNET_LOCK(lp->lp_ifp);
   1888 	error = LAGG_PORT_IOCTL(lp, SIOCSIFCAP, &ifcr);
   1889 	IFNET_UNLOCK(lp->lp_ifp);
   1890 
   1891 	return error;
   1892 }
   1893 
   1894 static void
   1895 lagg_sync_ifcaps(struct lagg_softc *sc)
   1896 {
   1897 	struct lagg_port *lp;
   1898 	struct ifnet *ifp;
   1899 	int error = 0;
   1900 
   1901 	ifp = (struct ifnet *)&sc->sc_if;
   1902 
   1903 	LAGG_LOCK(sc);
   1904 	LAGG_PORTS_FOREACH(sc, lp) {
   1905 		error = lagg_setifcaps(lp, ifp->if_capenable);
   1906 
   1907 		if (error != 0) {
   1908 			LAGG_LOG(sc, LOG_WARNING,
   1909 			    "failed to update capabilities "
   1910 			    "of %s, error=%d\n",
   1911 			    lp->lp_ifp->if_xname, error);
   1912 		}
   1913 	}
   1914 	LAGG_UNLOCK(sc);
   1915 }
   1916 
   1917 static int
   1918 lagg_setethcaps(struct lagg_port *lp, int cap)
   1919 {
   1920 	struct ethercom *ec;
   1921 	struct eccapreq eccr;
   1922 	int error;
   1923 
   1924 	KASSERT(lp->lp_iftype == IFT_ETHER);
   1925 	ec = (struct ethercom *)lp->lp_ifp;
   1926 
   1927 	if (ec->ec_capenable == cap)
   1928 		return 0;
   1929 
   1930 	memset(&eccr, 0, sizeof(eccr));
   1931 	eccr.eccr_capenable = cap;
   1932 
   1933 	IFNET_LOCK(lp->lp_ifp);
   1934 	error = LAGG_PORT_IOCTL(lp, SIOCSETHERCAP, &eccr);
   1935 	IFNET_UNLOCK(lp->lp_ifp);
   1936 
   1937 	return error;
   1938 }
   1939 
   1940 static void
   1941 lagg_sync_ethcaps(struct lagg_softc *sc)
   1942 {
   1943 	struct ethercom *ec;
   1944 	struct lagg_port *lp;
   1945 	int error;
   1946 
   1947 	ec = (struct ethercom *)&sc->sc_if;
   1948 
   1949 	LAGG_LOCK(sc);
   1950 	LAGG_PORTS_FOREACH(sc, lp) {
   1951 		if (lp->lp_iftype != IFT_ETHER)
   1952 			continue;
   1953 
   1954 		error = lagg_setethcaps(lp, ec->ec_capenable);
   1955 		if (error != 0) {
   1956 			LAGG_LOG(sc, LOG_WARNING,
   1957 			    "failed to update ether "
   1958 			    "capabilities"" of %s, error=%d\n",
   1959 			    lp->lp_ifp->if_xname, error);
   1960 		}
   1961 
   1962 	}
   1963 	LAGG_UNLOCK(sc);
   1964 }
   1965 
   1966 static void
   1967 lagg_ifcap_update(struct lagg_softc *sc)
   1968 {
   1969 	struct ifnet *ifp;
   1970 	struct lagg_port *lp;
   1971 	uint64_t cap, ena, pena;
   1972 	size_t i;
   1973 
   1974 	KASSERT(LAGG_LOCKED(sc));
   1975 
   1976 	/* Get common capabilities for the lagg ports */
   1977 	ena = ~(uint64_t)0;
   1978 	cap = ~(uint64_t)0;
   1979 	LAGG_PORTS_FOREACH(sc, lp) {
   1980 		ena &= lp->lp_ifp->if_capenable;
   1981 		cap &= lp->lp_ifp->if_capabilities;
   1982 	}
   1983 
   1984 	if (ena == ~(uint64_t)0)
   1985 		ena = 0;
   1986 	if (cap == ~(uint64_t)0)
   1987 		cap = 0;
   1988 
   1989 	/*
   1990 	 * Apply common enabled capabilities back to the lagg ports.
   1991 	 * May require several iterations if they are dependent.
   1992 	 */
   1993 	for (i = 0; i < LAGG_SETCAPS_RETRY; i++) {
   1994 		pena = ena;
   1995 		LAGG_PORTS_FOREACH(sc, lp) {
   1996 			lagg_setifcaps(lp, ena);
   1997 			ena &= lp->lp_ifp->if_capenable;
   1998 		}
   1999 
   2000 		if (pena == ena)
   2001 			break;
   2002 	}
   2003 
   2004 	if (pena != ena) {
   2005 		LAGG_LOG(sc, LOG_DEBUG, "couldn't set "
   2006 		    "capabilities 0x%08"PRIx64"\n", pena);
   2007 	}
   2008 
   2009 	ifp = &sc->sc_if;
   2010 
   2011 	if (ifp->if_capabilities != cap ||
   2012 	    ifp->if_capenable != ena) {
   2013 		ifp->if_capabilities = cap;
   2014 		ifp->if_capenable = ena;
   2015 
   2016 		LAGG_LOG(sc, LOG_DEBUG,"capabilities "
   2017 		    "0x%08"PRIx64" enabled 0x%08"PRIx64"\n",
   2018 		    cap, ena);
   2019 	}
   2020 }
   2021 
   2022 static void
   2023 lagg_ethercap_update(struct lagg_softc *sc)
   2024 {
   2025 	struct ethercom *ec;
   2026 	struct lagg_port *lp;
   2027 	int cap, ena, pena;
   2028 	size_t i;
   2029 
   2030 	KASSERT(LAGG_LOCKED(sc));
   2031 
   2032 	if (sc->sc_if.if_type != IFT_ETHER)
   2033 		return;
   2034 
   2035 	if (SIMPLEQ_EMPTY(&sc->sc_ports)) {
   2036 		ena = 0;
   2037 		cap = ETHERCAP_VLAN_HWTAGGING;
   2038 	} else {
   2039 		/* Get common enabled capabilities for the lagg ports */
   2040 		ena = ~0;
   2041 		cap = ~0;
   2042 		LAGG_PORTS_FOREACH(sc, lp) {
   2043 			switch (lp->lp_iftype) {
   2044 			case IFT_ETHER:
   2045 				ec = (struct ethercom *)lp->lp_ifp;
   2046 				ena &= ec->ec_capenable;
   2047 				cap &= ec->ec_capabilities;
   2048 				break;
   2049 			case IFT_L2TP:
   2050 				ena &= (ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU);
   2051 				cap &= (ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU);
   2052 				break;
   2053 			default:
   2054 				ena = 0;
   2055 				cap = 0;
   2056 			}
   2057 		}
   2058 	}
   2059 
   2060 	/*
   2061 	 * Apply common enabled capabilities back to the lagg ports.
   2062 	 * May require several iterations if they are dependent.
   2063 	 */
   2064 	for (i = 0; i < LAGG_SETCAPS_RETRY; i++) {
   2065 		pena = ena;
   2066 		LAGG_PORTS_FOREACH(sc, lp) {
   2067 			if (lp->lp_iftype != IFT_ETHER)
   2068 				continue;
   2069 
   2070 			ec = (struct ethercom *)lp->lp_ifp;
   2071 			lagg_setethcaps(lp, ena);
   2072 			ena &= ec->ec_capenable;
   2073 		}
   2074 
   2075 		if (pena == ena)
   2076 			break;
   2077 	}
   2078 
   2079 	if (pena != ena) {
   2080 		LAGG_LOG(sc, LOG_DEBUG, "couldn't set "
   2081 		    "ether capabilities 0x%08x\n", pena);
   2082 	}
   2083 
   2084 	ec = (struct ethercom *)&sc->sc_if;
   2085 
   2086 	if (ec->ec_capabilities != cap ||
   2087 	    ec->ec_capenable != ena) {
   2088 		ec->ec_capabilities = cap;
   2089 		ec->ec_capenable = ena;
   2090 
   2091 		LAGG_LOG(sc, LOG_DEBUG,
   2092 		    "ether capabilities 0x%08x"
   2093 		    " enabled 0x%08x\n", cap, ena);
   2094 	}
   2095 }
   2096 
   2097 static void
   2098 lagg_capabilities_update(struct lagg_softc *sc)
   2099 {
   2100 
   2101 	lagg_ifcap_update(sc);
   2102 	lagg_ethercap_update(sc);
   2103 }
   2104 
   2105 static int
   2106 lagg_setmtu(struct ifnet *ifp, uint64_t mtu)
   2107 {
   2108 	struct lagg_softc *sc __LAGGDEBUGUSED;
   2109 	struct lagg_port *lp;
   2110 	struct ifreq ifr;
   2111 	int error;
   2112 
   2113 	KASSERT(IFNET_LOCKED(ifp));
   2114 
   2115 	memset(&ifr, 0, sizeof(ifr));
   2116 	ifr.ifr_mtu = mtu;
   2117 	lp = ifp->if_lagg;
   2118 
   2119 	if (lp != NULL) {
   2120 		/* ioctl for port interface */
   2121 		error = lp->lp_ioctl(ifp, SIOCSIFMTU, &ifr);
   2122 		sc = lp->lp_softc;
   2123 	} else {
   2124 		/* ioctl for lagg interface */
   2125 		error = ether_ioctl(ifp, SIOCSIFMTU, &ifr);
   2126 		sc = ifp->if_softc;
   2127 	}
   2128 
   2129 	if (error != 0) {
   2130 		LAGG_DPRINTF(sc,
   2131 		    "couldn't change MTU for %s\n",
   2132 		    ifp->if_xname);
   2133 	}
   2134 
   2135 	return error;
   2136 }
   2137 
   2138 static void
   2139 lagg_port_setsadl(struct lagg_port *lp, const uint8_t *lladdr)
   2140 {
   2141 	struct ifnet *ifp_port;
   2142 	int error;
   2143 
   2144 	ifp_port = lp->lp_ifp;
   2145 
   2146 	KASSERT(LAGG_LOCKED(lp->lp_softc));
   2147 	KASSERT(IFNET_LOCKED(ifp_port));
   2148 
   2149 	switch (lp->lp_iftype) {
   2150 	case IFT_ETHER:
   2151 		if (lladdr == NULL) {
   2152 			lladdr = lp->lp_lladdr;
   2153 		} else {
   2154 			if (lagg_lladdr_equal(lladdr,
   2155 			    CLLADDR(ifp_port->if_sadl)))
   2156 				break;
   2157 		}
   2158 
   2159 		lagg_chg_sadl(ifp_port,
   2160 		    lladdr, ETHER_ADDR_LEN);
   2161 
   2162 		if (ifp_port->if_init != NULL) {
   2163 			error = 0;
   2164 			/* Apply updated ifp_port->if_sadl to the device */
   2165 			if (ISSET(ifp_port->if_flags, IFF_RUNNING))
   2166 				error = if_init(ifp_port);
   2167 
   2168 			if (error != 0) {
   2169 				LAGG_LOG(lp->lp_softc, LOG_WARNING,
   2170 				    "%s failed to if_init() on %d\n",
   2171 				    ifp_port->if_xname, error);
   2172 			}
   2173 		}
   2174 		break;
   2175 	default:
   2176 		if_alloc_sadl(ifp_port);
   2177 		break;
   2178 	}
   2179 }
   2180 
   2181 static void
   2182 lagg_if_setsadl(struct lagg_softc *sc, uint8_t *lladdr)
   2183 {
   2184 	struct ifnet *ifp;
   2185 
   2186 	KASSERT(LAGG_LOCKED(sc));
   2187 
   2188 	ifp = &sc->sc_if;
   2189 
   2190 	if (lagg_lladdr_equal(CLLADDR(ifp->if_sadl), lladdr))
   2191 		return;
   2192 
   2193 	lagg_chg_sadl(ifp, lladdr, ETHER_ADDR_LEN);
   2194 
   2195 	LAGG_UNLOCK(sc);
   2196 	lagg_in6_ifdetach(ifp);
   2197 	lagg_in6_ifattach(ifp);
   2198 	LAGG_LOCK(sc);
   2199 
   2200 	lagg_sync_sadl(sc);
   2201 }
   2202 
   2203 static void
   2204 lagg_sync_sadl(struct lagg_softc *sc)
   2205 {
   2206 	struct ifnet *ifp;
   2207 	struct lagg_port *lp;
   2208 	const uint8_t *lla;
   2209 
   2210 	ifp = &sc->sc_if;
   2211 	KASSERT(IFNET_LOCKED(ifp));
   2212 
   2213 	lla = CLLADDR(ifp->if_sadl);
   2214 	if (lagg_lladdr_equal(lla, sc->sc_lladdr))
   2215 		return;
   2216 
   2217 	lagg_lladdr_cpy(sc->sc_lladdr, lla);
   2218 
   2219 	LAGG_PORTS_FOREACH(sc, lp) {
   2220 		IFNET_LOCK(lp->lp_ifp);
   2221 		lagg_port_setsadl(lp, lla);
   2222 		IFNET_UNLOCK(lp->lp_ifp);
   2223 	}
   2224 }
   2225 
   2226 static int
   2227 lagg_port_setup(struct lagg_softc *sc,
   2228     struct lagg_port *lp, struct ifnet *ifp_port)
   2229 {
   2230 	struct ifnet *ifp;
   2231 	u_char if_type;
   2232 	int error;
   2233 	bool stopped, use_lagg_sadl;
   2234 
   2235 	KASSERT(LAGG_LOCKED(sc));
   2236 	IFNET_ASSERT_UNLOCKED(ifp_port);
   2237 
   2238 	ifp = &sc->sc_if;
   2239 
   2240 	use_lagg_sadl = true;
   2241 	if (SIMPLEQ_EMPTY(&sc->sc_ports) &&
   2242 	    ifp_port->if_type == IFT_ETHER) {
   2243 		if (lagg_lladdr_equal(CLLADDR(ifp->if_sadl),
   2244 		    sc->sc_lladdr_rand))
   2245 			use_lagg_sadl = false;
   2246 	}
   2247 
   2248 	if (&sc->sc_if == ifp_port) {
   2249 		LAGG_DPRINTF(sc, "cannot add a lagg to itself as a port\n");
   2250 		return EINVAL;
   2251 	}
   2252 
   2253 	if (sc->sc_nports > LAGG_MAX_PORTS)
   2254 		return ENOSPC;
   2255 
   2256 	if (ifp_port->if_lagg != NULL) {
   2257 		lp = (struct lagg_port *)ifp_port->if_lagg;
   2258 		if (lp->lp_softc == sc)
   2259 			return EEXIST;
   2260 		return EBUSY;
   2261 	}
   2262 
   2263 	switch (ifp_port->if_type) {
   2264 	case IFT_ETHER:
   2265 	case IFT_L2TP:
   2266 		if (VLAN_ATTACHED((struct ethercom *)ifp_port))
   2267 			return EBUSY;
   2268 
   2269 		if_type = IFT_IEEE8023ADLAG;
   2270 		break;
   2271 	default:
   2272 		return ENOTSUP;
   2273 	}
   2274 
   2275 	error = 0;
   2276 	stopped = false;
   2277 	lp->lp_softc = sc;
   2278 	lp->lp_prio = LAGG_PORT_PRIO;
   2279 	lp->lp_linkstate_hook = if_linkstate_change_establish(ifp_port,
   2280 	    lagg_linkstate_changed, ifp_port);
   2281 	lp->lp_ifdetach_hook = ether_ifdetachhook_establish(ifp_port,
   2282 	    lagg_ifdetach, ifp_port);
   2283 	psref_target_init(&lp->lp_psref, lagg_port_psref_class);
   2284 
   2285 	IFNET_LOCK(ifp_port);
   2286 	/* stop packet processing */
   2287 	if (ISSET(ifp_port->if_flags, IFF_RUNNING) &&
   2288 	    ifp_port->if_init != NULL) {
   2289 		if_stop(ifp_port, 0);
   2290 		stopped = true;
   2291 	}
   2292 
   2293 	/* to delete ipv6 link local address */
   2294 	lagg_in6_ifdetach(ifp_port);
   2295 
   2296 	/* backup members */
   2297 	lp->lp_iftype = ifp_port->if_type;
   2298 	lp->lp_ioctl = ifp_port->if_ioctl;
   2299 	lp->lp_input = ifp_port->_if_input;
   2300 	lp->lp_output = ifp_port->if_output;
   2301 	lp->lp_ifcapenable = ifp_port->if_capenable;
   2302 	lp->lp_mtu = ifp_port->if_mtu;
   2303 	if (lp->lp_iftype == IFT_ETHER) {
   2304 		struct ethercom *ec;
   2305 		ec = (struct ethercom *)ifp_port;
   2306 
   2307 		lagg_lladdr_cpy(lp->lp_lladdr, CLLADDR(ifp_port->if_sadl));
   2308 		lp->lp_eccapenable = ec->ec_capenable;
   2309 	}
   2310 
   2311 	/* change callbacks and others */
   2312 	atomic_store_release(&ifp_port->if_lagg, (void *)lp);
   2313 	ifp_port->if_type = if_type;
   2314 	ifp_port->if_ioctl = lagg_port_ioctl;
   2315 	ifp_port->_if_input = lagg_input_ethernet;
   2316 	ifp_port->if_output = lagg_port_output;
   2317 
   2318 	/* update Link address */
   2319 	if (use_lagg_sadl) {
   2320 		lagg_port_setsadl(lp, CLLADDR(ifp->if_sadl));
   2321 	} else {
   2322 		/* update if_type in if_sadl */
   2323 		if (lp->lp_iftype != ifp_port->if_type)
   2324 			lagg_port_setsadl(lp, NULL);
   2325 	}
   2326 
   2327 	error = lagg_setmtu(ifp_port, ifp->if_mtu);
   2328 	if (error != 0)
   2329 		goto restore_sadl;
   2330 
   2331 	error = lagg_proto_allocport(sc, lp);
   2332 	if (error != 0)
   2333 		goto restore_mtu;
   2334 
   2335 	/* restart packet processing */
   2336 	if (stopped) {
   2337 		error = if_init(ifp_port);
   2338 		if (error != 0)
   2339 			goto free_port;
   2340 	}
   2341 
   2342 	/* setup of ifp_port is complete */
   2343 	IFNET_UNLOCK(ifp_port);
   2344 
   2345 	/* copy sadl from added port to lagg */
   2346 	if (!use_lagg_sadl)
   2347 		lagg_if_setsadl(sc, lp->lp_lladdr);
   2348 
   2349 	SIMPLEQ_INSERT_TAIL(&sc->sc_ports, lp, lp_entry);
   2350 	sc->sc_nports++;
   2351 
   2352 	lagg_capabilities_update(sc);
   2353 	lagg_port_syncmulti(sc, lp);
   2354 	lagg_port_syncvlan(sc, lp);
   2355 	lagg_config_promisc(sc, lp);
   2356 
   2357 	lagg_proto_startport(sc, lp);
   2358 
   2359 	return 0;
   2360 
   2361 free_port:
   2362 	KASSERT(IFNET_LOCKED(ifp_port));
   2363 	lagg_proto_freeport(sc, lp);
   2364 restore_mtu:
   2365 	KASSERT(IFNET_LOCKED(ifp_port));
   2366 	if (ifp_port->if_mtu != lp->lp_mtu)
   2367 		lagg_setmtu(ifp_port, lp->lp_mtu);
   2368 restore_sadl:
   2369 	KASSERT(IFNET_LOCKED(ifp_port));
   2370 
   2371 	/* restore if_type before changing sadl */
   2372 	if_type = ifp_port->if_type;
   2373 	ifp_port->if_type = lp->lp_iftype;
   2374 
   2375 	if (!SIMPLEQ_EMPTY(&sc->sc_ports)) {
   2376 		lagg_port_setsadl(lp, lp->lp_lladdr);
   2377 	} else {
   2378 		if (ifp_port->if_type != if_type)
   2379 		lagg_port_setsadl(lp, NULL);
   2380 	}
   2381 
   2382 	lagg_in6_ifattach(ifp_port);
   2383 	if (stopped) {
   2384 		if (if_init(ifp_port) != 0) {
   2385 			LAGG_LOG(sc, LOG_WARNING,
   2386 			    "couldn't re-start port %s\n",
   2387 			    ifp_port->if_xname);
   2388 		}
   2389 	}
   2390 
   2391 	ifp_port->if_ioctl = lp->lp_ioctl;
   2392 	ifp_port->_if_input = lp->lp_input;
   2393 	ifp_port->if_output = lp->lp_output;
   2394 	atomic_store_release(&ifp_port->if_lagg, NULL);
   2395 	IFNET_UNLOCK(ifp_port);
   2396 
   2397 	psref_target_destroy(&lp->lp_psref, lagg_port_psref_class);
   2398 	if_linkstate_change_disestablish(ifp_port,
   2399 	    lp->lp_linkstate_hook, NULL);
   2400 	ether_ifdetachhook_disestablish(ifp_port,
   2401 	    lp->lp_ifdetach_hook, &sc->sc_lock);
   2402 
   2403 	return error;
   2404 }
   2405 
   2406 static void
   2407 lagg_port_teardown(struct lagg_softc *sc, struct lagg_port *lp,
   2408     bool is_ifdetach)
   2409 {
   2410 	struct ifnet *ifp, *ifp_port;
   2411 	bool stopped, is_1st_port, iftype_changed;
   2412 
   2413 	KASSERT(LAGG_LOCKED(sc));
   2414 
   2415 	ifp = &sc->sc_if;
   2416 	ifp_port = lp->lp_ifp;
   2417 	stopped = false;
   2418 	is_1st_port =
   2419 	    SIMPLEQ_FIRST(&sc->sc_ports) == lp ? true : false;
   2420 
   2421 	ether_ifdetachhook_disestablish(ifp_port,
   2422 	    lp->lp_ifdetach_hook, &sc->sc_lock);
   2423 
   2424 	if (ifp_port->if_lagg == NULL) {
   2425 		/* already done in lagg_ifdetach() */
   2426 		return;
   2427 	}
   2428 
   2429 	if_linkstate_change_disestablish(ifp_port,
   2430 	    lp->lp_linkstate_hook, NULL);
   2431 
   2432 	lagg_proto_stopport(sc, lp);
   2433 
   2434 	lagg_port_purgemulti(sc, lp);
   2435 	lagg_port_purgevlan(sc, lp);
   2436 	if (is_ifdetach == false) {
   2437 		lagg_unconfig_promisc(sc, lp);
   2438 		lagg_setifcaps(lp, lp->lp_ifcapenable);
   2439 		if (lp->lp_iftype == IFT_ETHER)
   2440 			lagg_setethcaps(lp, lp->lp_eccapenable);
   2441 	}
   2442 
   2443 	SIMPLEQ_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entry);
   2444 	sc->sc_nports--;
   2445 
   2446 	if (is_1st_port) {
   2447 		if (lp->lp_iftype == IFT_ETHER &&
   2448 		    lagg_lladdr_equal(lp->lp_lladdr,
   2449 		    CLLADDR(ifp->if_sadl))) {
   2450 			struct lagg_port *lp0;
   2451 			uint8_t *lla;
   2452 
   2453 			lp0 = SIMPLEQ_FIRST(&sc->sc_ports);
   2454 			if (lp0 != NULL &&
   2455 			    lp0->lp_iftype == IFT_ETHER) {
   2456 				lla = lp0->lp_lladdr;
   2457 			} else {
   2458 				lla = sc->sc_lladdr_rand;
   2459 			}
   2460 
   2461 			lagg_if_setsadl(sc, lla);
   2462 		}
   2463 	}
   2464 
   2465 	IFNET_LOCK(ifp_port);
   2466 	/* stop packet processing */
   2467 	if (ISSET(ifp_port->if_flags, IFF_RUNNING) &&
   2468 	    ifp_port->if_init != NULL) {
   2469 		if_stop(ifp_port, 0);
   2470 		stopped = true;
   2471 	}
   2472 
   2473 	lagg_proto_freeport(sc, lp);
   2474 
   2475 	/* change if_type before set sadl */
   2476 	iftype_changed = ifp_port->if_type != lp->lp_iftype ?
   2477 	    true : false;
   2478 	ifp_port->if_type = lp->lp_iftype;
   2479 
   2480 	if (is_ifdetach == false) {
   2481 		if (iftype_changed &&
   2482 		    lagg_lladdr_equal(CLLADDR(ifp_port->if_sadl),
   2483 		    lp->lp_lladdr)) {
   2484 			lagg_port_setsadl(lp, NULL);
   2485 		}
   2486 		lagg_port_setsadl(lp, lp->lp_lladdr);
   2487 		lagg_in6_ifattach(ifp_port);
   2488 		(void)lagg_setmtu(ifp_port, lp->lp_mtu);
   2489 	}
   2490 
   2491 	ifp_port->_if_input = lp->lp_input;
   2492 	ifp_port->if_output = lp->lp_output;
   2493 	if (ifp_port->if_ioctl == lagg_port_ioctl)
   2494 		ifp_port->if_ioctl = lp->lp_ioctl;
   2495 	atomic_store_release(&ifp_port->if_lagg, NULL);
   2496 	pserialize_perform(sc->sc_psz);
   2497 
   2498 	/* to assign ipv6 link local address */
   2499 	if (is_ifdetach == false) {
   2500 		lagg_in6_ifattach(ifp_port);
   2501 	}
   2502 
   2503 	/* restart packet processing */
   2504 	if (stopped) {
   2505 		int error;
   2506 		error = if_init(ifp_port);
   2507 		if (error != 0) {
   2508 			LAGG_LOG(sc, LOG_WARNING,
   2509 			    "%s failed to if_init() on %d\n",
   2510 			    ifp_port->if_xname, error);
   2511 		}
   2512 	}
   2513 	IFNET_UNLOCK(ifp_port);
   2514 
   2515 	psref_target_destroy(&lp->lp_psref, lagg_port_psref_class);
   2516 	kmem_free(lp, sizeof(*lp));
   2517 }
   2518 
   2519 static int
   2520 lagg_addport(struct lagg_softc *sc, struct ifnet *ifp_port)
   2521 {
   2522 	struct lagg_port *lp;
   2523 	int error;
   2524 
   2525 	lp = kmem_zalloc(sizeof(*lp), KM_SLEEP);
   2526 	lp->lp_ifp = ifp_port;
   2527 
   2528 	LAGG_LOCK(sc);
   2529 	error = lagg_port_setup(sc, lp, ifp_port);
   2530 	LAGG_UNLOCK(sc);
   2531 
   2532 	if (error != 0)
   2533 		kmem_free(lp, sizeof(*lp));
   2534 
   2535 	return error;
   2536 }
   2537 
   2538 static int
   2539 lagg_delport(struct lagg_softc *sc, struct ifnet *ifp_port)
   2540 {
   2541 	struct lagg_port *lp;
   2542 	int error;
   2543 
   2544 	KASSERT(IFNET_LOCKED(&sc->sc_if));
   2545 
   2546 	error = 0;
   2547 	LAGG_LOCK(sc);
   2548 	lp = ifp_port->if_lagg;
   2549 	if (lp == NULL || lp->lp_softc != sc) {
   2550 		error = ENOENT;
   2551 		goto out;
   2552 	}
   2553 
   2554 	if (lp->lp_ifdetaching) {
   2555 		error = EBUSY;
   2556 		goto out;
   2557 	}
   2558 
   2559 	lagg_port_teardown(sc, lp, false);
   2560 
   2561 out:
   2562 	LAGG_UNLOCK(sc);
   2563 
   2564 	return error;
   2565 }
   2566 
   2567 static int
   2568 lagg_delport_all(struct lagg_softc *sc)
   2569 {
   2570 	struct lagg_port *lp;
   2571 	int error;
   2572 
   2573 	KASSERT(IFNET_LOCKED(&sc->sc_if));
   2574 
   2575 	error = 0;
   2576 
   2577 	LAGG_LOCK(sc);
   2578 	while ((lp = LAGG_PORTS_FIRST(sc)) != NULL) {
   2579 		if (lp->lp_ifdetaching) {
   2580 			error = EBUSY;
   2581 			continue;
   2582 		}
   2583 
   2584 		lagg_port_teardown(sc, lp, false);
   2585 	}
   2586 
   2587 	LAGG_UNLOCK(sc);
   2588 
   2589 	return error;
   2590 }
   2591 
   2592 static int
   2593 lagg_get_stats(struct lagg_softc *sc, struct lagg_req *resp,
   2594     size_t nports)
   2595 {
   2596 	struct lagg_variant *var;
   2597 	struct lagg_port *lp;
   2598 	struct laggreqport *port;
   2599 	struct psref psref;
   2600 	struct ifnet *ifp;
   2601 	int bound;
   2602 	size_t n;
   2603 
   2604 	bound = curlwp_bind();
   2605 	var = lagg_variant_getref(sc, &psref);
   2606 	if (var == NULL) {
   2607 		curlwp_bindx(bound);
   2608 		return ENOENT;
   2609 	}
   2610 
   2611 	resp->lrq_proto = var->lv_proto;
   2612 
   2613 	lagg_proto_stat(var, &resp->lrq_reqproto);
   2614 
   2615 	n = 0;
   2616 	LAGG_LOCK(sc);
   2617 	LAGG_PORTS_FOREACH(sc, lp) {
   2618 		if (n < nports) {
   2619 			port = &resp->lrq_reqports[n];
   2620 
   2621 			ifp = lp->lp_ifp;
   2622 			strlcpy(port->rp_portname, ifp->if_xname,
   2623 			    sizeof(port->rp_portname));
   2624 
   2625 			port->rp_prio = lp->lp_prio;
   2626 			port->rp_flags = lp->lp_flags;
   2627 			lagg_proto_portstat(var, lp, port);
   2628 		}
   2629 		n++;
   2630 	}
   2631 	LAGG_UNLOCK(sc);
   2632 
   2633 	resp->lrq_nports = n;
   2634 
   2635 	lagg_variant_putref(var, &psref);
   2636 	curlwp_bindx(bound);
   2637 
   2638 	if (resp->lrq_nports > nports) {
   2639 		return ENOBUFS;
   2640 	}
   2641 	return 0;
   2642 }
   2643 
   2644 static void
   2645 lagg_config_promisc(struct lagg_softc *sc, struct lagg_port *lp)
   2646 {
   2647 	struct ifnet *ifp, *ifp_port;
   2648 	int error;
   2649 	bool promisc;
   2650 
   2651 	KASSERT(LAGG_LOCKED(sc));
   2652 
   2653 	ifp = &sc->sc_if;
   2654 	ifp_port = lp->lp_ifp;
   2655 
   2656 	if (lp->lp_iftype == IFT_ETHER) {
   2657 		promisc = ISSET(ifp->if_flags, IFF_PROMISC) ?
   2658 		    true : false;
   2659 	} else {
   2660 		promisc = true;
   2661 	}
   2662 
   2663 	if (lp->lp_promisc == promisc)
   2664 		return;
   2665 
   2666 	error = ifpromisc(ifp_port, promisc ? 1 : 0);
   2667 	if (error == ENETRESET) {
   2668 		error = ifp_port->if_init(ifp_port);
   2669 	}
   2670 
   2671 	if (error == 0) {
   2672 		lp->lp_promisc = promisc;
   2673 	} else {
   2674 		LAGG_LOG(sc, LOG_WARNING,
   2675 		    "couldn't %s promisc on %s\n",
   2676 		    promisc ? "set" : "unset",
   2677 		    ifp_port->if_xname);
   2678 	}
   2679 }
   2680 
   2681 static void
   2682 lagg_unconfig_promisc(struct lagg_softc *sc, struct lagg_port *lp)
   2683 {
   2684 	struct ifnet *ifp_port;
   2685 	int error;
   2686 
   2687 	KASSERT(LAGG_LOCKED(sc));
   2688 
   2689 	ifp_port = lp->lp_ifp;
   2690 
   2691 	if (lp->lp_promisc == false)
   2692 		return;
   2693 
   2694 	error = ifpromisc(ifp_port, 0);
   2695 	if (error == ENETRESET) {
   2696 		error = ifp_port->if_init(ifp_port);
   2697 	}
   2698 
   2699 	if (error != 0) {
   2700 		LAGG_LOG(sc, LOG_WARNING,
   2701 		    "couldn't unset promisc on %s\n",
   2702 		    ifp_port->if_xname);
   2703 	}
   2704 }
   2705 
   2706 static int
   2707 lagg_port_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   2708 {
   2709 	struct lagg_softc *sc;
   2710 	struct lagg_port *lp;
   2711 	int error = 0;
   2712 	u_int ifflags;
   2713 
   2714 	if ((lp = ifp->if_lagg) == NULL)
   2715 		goto fallback;
   2716 
   2717 	sc = lp->lp_softc;
   2718 	KASSERT(sc != NULL);
   2719 
   2720 	KASSERT(IFNET_LOCKED(lp->lp_ifp));
   2721 
   2722 	switch (cmd) {
   2723 	case SIOCSIFCAP:
   2724 	case SIOCSIFMTU:
   2725 	case SIOCSETHERCAP:
   2726 		/* Do not allow the setting to be changed once joined */
   2727 		error = EINVAL;
   2728 		break;
   2729 	case SIOCSIFFLAGS:
   2730 		ifflags = ifp->if_flags;
   2731 		error = LAGG_PORT_IOCTL(lp, cmd, data);
   2732 		ifflags ^= ifp->if_flags;
   2733 
   2734 		if ((ifflags & (IFF_UP | IFF_RUNNING)) != 0)
   2735 			lagg_proto_linkstate(sc, lp);
   2736 		break;
   2737 	default:
   2738 		goto fallback;
   2739 	}
   2740 
   2741 	return error;
   2742 fallback:
   2743 	if (lp != NULL) {
   2744 		error = LAGG_PORT_IOCTL(lp, cmd, data);
   2745 	} else {
   2746 		error = ENOTTY;
   2747 	}
   2748 
   2749 	return error;
   2750 }
   2751 
   2752 static int
   2753 lagg_port_output(struct ifnet *ifp, struct mbuf *m,
   2754     const struct sockaddr *dst, const struct rtentry *rt)
   2755 {
   2756 	struct lagg_port *lp = ifp->if_lagg;
   2757 	int error = 0;
   2758 
   2759 	switch (dst->sa_family) {
   2760 	case pseudo_AF_HDRCMPLT:
   2761 	case AF_UNSPEC:
   2762 		if (lp != NULL)
   2763 			error = lp->lp_output(ifp, m, dst, rt);
   2764 		else
   2765 			error = ENETDOWN;
   2766 		break;
   2767 	default:
   2768 		m_freem(m);
   2769 		error = ENETDOWN;
   2770 	}
   2771 
   2772 	return error;
   2773 }
   2774 
   2775 void
   2776 lagg_ifdetach(void *xifp_port)
   2777 {
   2778 	struct ifnet *ifp_port = xifp_port;
   2779 	struct lagg_port *lp;
   2780 	struct lagg_softc *sc;
   2781 	int s;
   2782 
   2783 	IFNET_ASSERT_UNLOCKED(ifp_port);
   2784 
   2785 	s = pserialize_read_enter();
   2786 	lp = atomic_load_consume(&ifp_port->if_lagg);
   2787 	if (lp == NULL) {
   2788 		pserialize_read_exit(s);
   2789 		return;
   2790 	} else {
   2791 		sc = lp->lp_softc;
   2792 		KASSERT(sc != NULL);
   2793 	}
   2794 	pserialize_read_exit(s);
   2795 
   2796 	LAGG_LOCK(sc);
   2797 	lp = ifp_port->if_lagg;
   2798 	if (lp == NULL) {
   2799 		LAGG_UNLOCK(sc);
   2800 		return;
   2801 	}
   2802 
   2803 	/*
   2804 	 * mark as a detaching to prevent other
   2805 	 * lagg_port_teardown() processings with IFNET_LOCK() held
   2806 	 */
   2807 	lp->lp_ifdetaching = true;
   2808 
   2809 	LAGG_UNLOCK(sc);
   2810 
   2811 	IFNET_LOCK(&sc->sc_if);
   2812 	LAGG_LOCK(sc);
   2813 	lp = ifp_port->if_lagg;
   2814 	if (lp != NULL) {
   2815 		lagg_port_teardown(sc, lp, true);
   2816 	}
   2817 	LAGG_UNLOCK(sc);
   2818 	IFNET_UNLOCK(&sc->sc_if);
   2819 }
   2820 
   2821 void
   2822 lagg_linkstate_changed(void *xifp)
   2823 {
   2824 	struct ifnet *ifp = xifp;
   2825 	struct lagg_port *lp;
   2826 	struct psref psref;
   2827 	int s, bound;
   2828 
   2829 	s = pserialize_read_enter();
   2830 	lp = atomic_load_consume(&ifp->if_lagg);
   2831 	if (lp != NULL) {
   2832 		bound = curlwp_bind();
   2833 		lagg_port_getref(lp, &psref);
   2834 	} else {
   2835 		pserialize_read_exit(s);
   2836 		return;
   2837 	}
   2838 	pserialize_read_exit(s);
   2839 
   2840 	KASSERT(IFNET_LOCKED(lp->lp_ifp));
   2841 
   2842 	lagg_proto_linkstate(lp->lp_softc, lp);
   2843 
   2844 	lagg_port_putref(lp, &psref);
   2845 	curlwp_bindx(bound);
   2846 }
   2847 
   2848 void
   2849 lagg_port_getref(struct lagg_port *lp, struct psref *psref)
   2850 {
   2851 
   2852 	psref_acquire(psref, &lp->lp_psref, lagg_port_psref_class);
   2853 }
   2854 
   2855 void
   2856 lagg_port_putref(struct lagg_port *lp, struct psref *psref)
   2857 {
   2858 
   2859 	psref_release(psref, &lp->lp_psref, lagg_port_psref_class);
   2860 }
   2861 
   2862 static void
   2863 lagg_workq_work(struct work *wk, void *context)
   2864 {
   2865 	struct lagg_work *lw;
   2866 
   2867 	lw = container_of(wk, struct lagg_work, lw_cookie);
   2868 
   2869 	atomic_cas_uint(&lw->lw_state, LAGG_WORK_ENQUEUED, LAGG_WORK_IDLE);
   2870 	lw->lw_func(lw, lw->lw_arg);
   2871 }
   2872 
   2873 struct workqueue *
   2874 lagg_workq_create(const char *name, pri_t prio, int ipl, int flags)
   2875 {
   2876 	struct workqueue *wq;
   2877 	int error;
   2878 
   2879 	error = workqueue_create(&wq, name, lagg_workq_work,
   2880 	    NULL, prio, ipl, flags);
   2881 
   2882 	if (error)
   2883 		return NULL;
   2884 
   2885 	return wq;
   2886 }
   2887 
   2888 void
   2889 lagg_workq_destroy(struct workqueue *wq)
   2890 {
   2891 
   2892 	workqueue_destroy(wq);
   2893 }
   2894 
   2895 void
   2896 lagg_workq_add(struct workqueue *wq, struct lagg_work *lw)
   2897 {
   2898 
   2899 	if (atomic_cas_uint(&lw->lw_state, LAGG_WORK_IDLE,
   2900 	    LAGG_WORK_ENQUEUED) != LAGG_WORK_IDLE)
   2901 		return;
   2902 
   2903 	KASSERT(lw->lw_func != NULL);
   2904 	kpreempt_disable();
   2905 	workqueue_enqueue(wq, &lw->lw_cookie, NULL);
   2906 	kpreempt_enable();
   2907 }
   2908 
   2909 void
   2910 lagg_workq_wait(struct workqueue *wq, struct lagg_work *lw)
   2911 {
   2912 
   2913 	atomic_swap_uint(&lw->lw_state, LAGG_WORK_STOPPING);
   2914 	workqueue_wait(wq, &lw->lw_cookie);
   2915 }
   2916 
   2917 static int
   2918 lagg_chg_sadl(struct ifnet *ifp, const uint8_t *lla, size_t lla_len)
   2919 {
   2920 	struct psref psref_cur, psref_next;
   2921 	struct ifaddr *ifa_cur, *ifa_next, *ifa_lla;
   2922 	const struct sockaddr_dl *sdl, *nsdl;
   2923 	int s, error;
   2924 
   2925 	KASSERT(!cpu_intr_p() && !cpu_softintr_p());
   2926 	KASSERT(IFNET_LOCKED(ifp));
   2927 	KASSERT(ifp->if_addrlen == lla_len);
   2928 
   2929 	error = 0;
   2930 	ifa_lla = NULL;
   2931 
   2932 	/* Renew all AF_LINK address to update sdl_type */
   2933 	while (1) {
   2934 		/* find a Link-Level address that has the previous sdl_type */
   2935 		s = pserialize_read_enter();
   2936 		IFADDR_READER_FOREACH(ifa_cur, ifp) {
   2937 			sdl = satocsdl(ifa_cur->ifa_addr);
   2938 			if (sdl->sdl_family != AF_LINK)
   2939 				continue;
   2940 
   2941 			if (sdl->sdl_type != ifp->if_type) {
   2942 				ifa_acquire(ifa_cur, &psref_cur);
   2943 				break;
   2944 			}
   2945 		}
   2946 		pserialize_read_exit(s);
   2947 
   2948 		if (ifa_cur == NULL)
   2949 			break;
   2950 		/*
   2951 		 * create a new address that has new sdl_type,
   2952 		 * and copy address from the previous.
   2953 		 */
   2954 		ifa_next = if_dl_create(ifp, &nsdl);
   2955 		if (ifa_next == NULL) {
   2956 			error = ENOMEM;
   2957 			ifa_release(ifa_cur, &psref_cur);
   2958 			goto done;
   2959 		}
   2960 		ifa_acquire(ifa_next, &psref_next);
   2961 		(void)sockaddr_dl_setaddr(__UNCONST(nsdl), nsdl->sdl_len,
   2962 		    CLLADDR(sdl), ifp->if_addrlen);
   2963 		ifa_insert(ifp, ifa_next);
   2964 
   2965 		/* the next Link-Level address is already set */
   2966 		if (ifa_lla == NULL &&
   2967 		    memcmp(CLLADDR(sdl), lla, lla_len) == 0) {
   2968 			ifa_lla = ifa_next;
   2969 			ifaref(ifa_lla);
   2970 		}
   2971 
   2972 		if (ifa_cur == ifp->if_dl)
   2973 			if_activate_sadl(ifp, ifa_next, nsdl);
   2974 
   2975 		if (ifa_cur == ifp->if_hwdl) {
   2976 			ifp->if_hwdl = ifa_next;
   2977 			ifaref(ifa_next);
   2978 			ifafree(ifa_cur);
   2979 		}
   2980 
   2981 		/* remove the old address */
   2982 		ifaref(ifa_cur);
   2983 		ifa_release(ifa_cur, &psref_cur);
   2984 		ifa_remove(ifp, ifa_cur);
   2985 		KASSERTMSG(ifa_cur->ifa_refcnt == 1,
   2986 		    "ifa_refcnt=%d", ifa_cur->ifa_refcnt);
   2987 		ifafree(ifa_cur);
   2988 		ifa_release(ifa_next, &psref_next);
   2989 	}
   2990 
   2991 	/* acquire or create the next Link-Level address */
   2992 	if (ifa_lla != NULL) {
   2993 		ifa_next = ifa_lla;
   2994 
   2995 		ifa_acquire(ifa_next, &psref_next);
   2996 		ifafree(ifa_lla);
   2997 
   2998 		nsdl = satocsdl(ifa_next->ifa_addr);
   2999 	} else {
   3000 		ifa_next = if_dl_create(ifp, &nsdl);
   3001 		if (ifa_next == NULL) {
   3002 			error = ENOMEM;
   3003 			goto done;
   3004 		}
   3005 		ifa_acquire(ifa_next, &psref_next);
   3006 		(void)sockaddr_dl_setaddr(__UNCONST(nsdl),
   3007 		    nsdl->sdl_len, lla, ifp->if_addrlen);
   3008 		ifa_insert(ifp, ifa_next);
   3009 	}
   3010 
   3011 	/* Activate the next Link-Level address */
   3012 	if (__predict_true(ifa_next != ifp->if_dl)) {
   3013 		/* save the current address */
   3014 		ifa_cur = ifp->if_dl;
   3015 		if (ifa_cur != NULL)
   3016 			ifa_acquire(ifa_cur, &psref_cur);
   3017 
   3018 		if_activate_sadl(ifp, ifa_next, nsdl);
   3019 
   3020 		/*
   3021 		 * free the saved address after switching,
   3022 		 * if the address is not if_hwdl.
   3023 		 */
   3024 		if (ifa_cur != NULL) {
   3025 			if (ifa_cur != ifp->if_hwdl) {
   3026 				ifaref(ifa_cur);
   3027 				ifa_release(ifa_cur, &psref_cur);
   3028 				ifa_remove(ifp, ifa_cur);
   3029 				KASSERTMSG(ifa_cur->ifa_refcnt == 1,
   3030 				    "ifa_refcnt=%d",
   3031 				    ifa_cur->ifa_refcnt);
   3032 				ifafree(ifa_cur);
   3033 			} else {
   3034 				ifa_release(ifa_cur, &psref_cur);
   3035 			}
   3036 		}
   3037 	}
   3038 
   3039 	ifa_release(ifa_next, &psref_next);
   3040 
   3041 done:
   3042 	return error;
   3043 }
   3044 
   3045 /*
   3046  * Module infrastructure
   3047  */
   3048 #include <net/if_module.h>
   3049 
   3050 IF_MODULE(MODULE_CLASS_DRIVER, lagg, NULL)
   3051