Deleted Added
full compact
ieee8023ad_lacp.c (169741) ieee8023ad_lacp.c (170599)
1/* $NetBSD: ieee8023ad_lacp.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */
2
3/*-
4 * Copyright (c)2005 YAMAMOTO Takashi,
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
1/* $NetBSD: ieee8023ad_lacp.c,v 1.3 2005/12/11 12:24:54 christos Exp $ */
2
3/*-
4 * Copyright (c)2005 YAMAMOTO Takashi,
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

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

22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/net/ieee8023ad_lacp.c 169741 2007-05-19 09:37:04Z thompsa $");
30__FBSDID("$FreeBSD: head/sys/net/ieee8023ad_lacp.c 170599 2007-06-12 07:29:11Z thompsa $");
31
32#include <sys/param.h>
33#include <sys/callout.h>
34#include <sys/mbuf.h>
35#include <sys/systm.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h> /* hz */
38#include <sys/socket.h> /* for net/if.h */

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

211 [LACP_TIMER_CURRENT_WHILE] = lacp_sm_rx_timer,
212 [LACP_TIMER_PERIODIC] = lacp_sm_ptx_timer,
213 [LACP_TIMER_WAIT_WHILE] = lacp_sm_mux_timer,
214};
215
216void
217lacp_input(struct lagg_port *lgp, struct mbuf *m)
218{
31
32#include <sys/param.h>
33#include <sys/callout.h>
34#include <sys/mbuf.h>
35#include <sys/systm.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h> /* hz */
38#include <sys/socket.h> /* for net/if.h */

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

211 [LACP_TIMER_CURRENT_WHILE] = lacp_sm_rx_timer,
212 [LACP_TIMER_PERIODIC] = lacp_sm_ptx_timer,
213 [LACP_TIMER_WAIT_WHILE] = lacp_sm_mux_timer,
214};
215
216void
217lacp_input(struct lagg_port *lgp, struct mbuf *m)
218{
219 struct lagg_softc *lgs = lgp->lp_lagg;
220 struct lacp_softc *lsc = LACP_SOFTC(lgs);
219 struct lagg_softc *sc = lgp->lp_softc;
220 struct lacp_softc *lsc = LACP_SOFTC(sc);
221 uint8_t subtype;
222
223 if (m->m_pkthdr.len < sizeof(struct ether_header) + sizeof(subtype)) {
224 m_freem(m);
225 return;
226 }
227
228 m_copydata(m, sizeof(struct ether_header), sizeof(subtype), &subtype);

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

242 break;
243 }
244}
245
246static void
247lacp_dequeue(void *arg, int pending)
248{
249 struct lacp_softc *lsc = (struct lacp_softc *)arg;
221 uint8_t subtype;
222
223 if (m->m_pkthdr.len < sizeof(struct ether_header) + sizeof(subtype)) {
224 m_freem(m);
225 return;
226 }
227
228 m_copydata(m, sizeof(struct ether_header), sizeof(subtype), &subtype);

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

242 break;
243 }
244}
245
246static void
247lacp_dequeue(void *arg, int pending)
248{
249 struct lacp_softc *lsc = (struct lacp_softc *)arg;
250 struct lagg_softc *sc = lsc->lsc_lagg;
250 struct lagg_softc *sc = lsc->lsc_softc;
251 struct lagg_port *lgp;
252 struct mbuf *m;
253
254 LAGG_WLOCK(sc);
255 for (;;) {
256 IF_DEQUEUE(&lsc->lsc_queue, m);
257 if (m == NULL)
258 break;

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

267 */
268static int
269lacp_pdu_input(struct lagg_port *lgp, struct mbuf *m)
270{
271 struct lacp_port *lp = LACP_PORT(lgp);
272 struct lacpdu *du;
273 int error = 0;
274
251 struct lagg_port *lgp;
252 struct mbuf *m;
253
254 LAGG_WLOCK(sc);
255 for (;;) {
256 IF_DEQUEUE(&lsc->lsc_queue, m);
257 if (m == NULL)
258 break;

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

267 */
268static int
269lacp_pdu_input(struct lagg_port *lgp, struct mbuf *m)
270{
271 struct lacp_port *lp = LACP_PORT(lgp);
272 struct lacpdu *du;
273 int error = 0;
274
275 LAGG_WLOCK_ASSERT(lgp->lp_lagg);
275 LAGG_WLOCK_ASSERT(lgp->lp_softc);
276
276
277 if (__predict_false(lp->lp_flags & LACP_PORT_DETACHING)) {
278 goto bad;
279 }
280
281 if (m->m_pkthdr.len != sizeof(*du)) {
282 goto bad;
283 }
284
285 if ((m->m_flags & M_MCAST) == 0) {
286 goto bad;
287 }
288

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

295
296 du = mtod(m, struct lacpdu *);
297
298 if (memcmp(&du->ldu_eh.ether_dhost,
299 &ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) {
300 goto bad;
301 }
302
277 if (m->m_pkthdr.len != sizeof(*du)) {
278 goto bad;
279 }
280
281 if ((m->m_flags & M_MCAST) == 0) {
282 goto bad;
283 }
284

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

291
292 du = mtod(m, struct lacpdu *);
293
294 if (memcmp(&du->ldu_eh.ether_dhost,
295 &ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) {
296 goto bad;
297 }
298
303 /* XXX
304 KASSERT(du->ldu_sph.sph_subtype == SLOWPROTOCOLS_SUBTYPE_LACP,
305 ("a very bad kassert!"));
306 */
307
308 /*
309 * ignore the version for compatibility with
310 * the future protocol revisions.
311 */
299 /*
300 * ignore the version for compatibility with
301 * the future protocol revisions.
302 */
312
313#if 0
314 if (du->ldu_sph.sph_version != 1) {
315 goto bad;
316 }
317#endif
318
319 /*
320 * ignore tlv types for compatibility with
321 * the future protocol revisions.
322 */
303#if 0
304 if (du->ldu_sph.sph_version != 1) {
305 goto bad;
306 }
307#endif
308
309 /*
310 * ignore tlv types for compatibility with
311 * the future protocol revisions.
312 */
323
324 if (tlv_check(du, sizeof(*du), &du->ldu_tlv_actor,
325 lacp_info_tlv_template, FALSE)) {
326 goto bad;
327 }
328
329#if defined(LACP_DEBUG)
330 LACP_DPRINTF((lp, "lacpdu receive\n"));
331 lacp_dump_lacpdu(du);

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

340 m_freem(m);
341 return (EINVAL);
342}
343
344static void
345lacp_fill_actorinfo(struct lacp_port *lp, struct lacp_peerinfo *info)
346{
347 struct lagg_port *lgp = lp->lp_lagg;
313 if (tlv_check(du, sizeof(*du), &du->ldu_tlv_actor,
314 lacp_info_tlv_template, FALSE)) {
315 goto bad;
316 }
317
318#if defined(LACP_DEBUG)
319 LACP_DPRINTF((lp, "lacpdu receive\n"));
320 lacp_dump_lacpdu(du);

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

329 m_freem(m);
330 return (EINVAL);
331}
332
333static void
334lacp_fill_actorinfo(struct lacp_port *lp, struct lacp_peerinfo *info)
335{
336 struct lagg_port *lgp = lp->lp_lagg;
348 struct lagg_softc *lgs = lgp->lp_lagg;
337 struct lagg_softc *sc = lgp->lp_softc;
349
350 info->lip_systemid.lsi_prio = htons(LACP_SYSTEM_PRIO);
351 memcpy(&info->lip_systemid.lsi_mac,
338
339 info->lip_systemid.lsi_prio = htons(LACP_SYSTEM_PRIO);
340 memcpy(&info->lip_systemid.lsi_mac,
352 IF_LLADDR(lgs->sc_ifp), ETHER_ADDR_LEN);
341 IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
353 info->lip_portid.lpi_prio = htons(LACP_PORT_PRIO);
354 info->lip_portid.lpi_portno = htons(lp->lp_ifp->if_index);
355 info->lip_state = lp->lp_state;
356}
357
358static void
359lacp_fill_markerinfo(struct lacp_port *lp, struct lacp_markerinfo *info)
360{

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

369static int
370lacp_xmit_lacpdu(struct lacp_port *lp)
371{
372 struct lagg_port *lgp = lp->lp_lagg;
373 struct mbuf *m;
374 struct lacpdu *du;
375 int error;
376
342 info->lip_portid.lpi_prio = htons(LACP_PORT_PRIO);
343 info->lip_portid.lpi_portno = htons(lp->lp_ifp->if_index);
344 info->lip_state = lp->lp_state;
345}
346
347static void
348lacp_fill_markerinfo(struct lacp_port *lp, struct lacp_markerinfo *info)
349{

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

358static int
359lacp_xmit_lacpdu(struct lacp_port *lp)
360{
361 struct lagg_port *lgp = lp->lp_lagg;
362 struct mbuf *m;
363 struct lacpdu *du;
364 int error;
365
377 LAGG_WLOCK_ASSERT(lgp->lp_lagg);
366 LAGG_WLOCK_ASSERT(lgp->lp_softc);
378
379 m = m_gethdr(M_DONTWAIT, MT_DATA);
380 if (m == NULL) {
381 return (ENOMEM);
382 }
383 m->m_len = m->m_pkthdr.len = sizeof(*du);
384
385 du = mtod(m, struct lacpdu *);

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

423static int
424lacp_xmit_marker(struct lacp_port *lp)
425{
426 struct lagg_port *lgp = lp->lp_lagg;
427 struct mbuf *m;
428 struct markerdu *mdu;
429 int error;
430
367
368 m = m_gethdr(M_DONTWAIT, MT_DATA);
369 if (m == NULL) {
370 return (ENOMEM);
371 }
372 m->m_len = m->m_pkthdr.len = sizeof(*du);
373
374 du = mtod(m, struct lacpdu *);

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

412static int
413lacp_xmit_marker(struct lacp_port *lp)
414{
415 struct lagg_port *lgp = lp->lp_lagg;
416 struct mbuf *m;
417 struct markerdu *mdu;
418 int error;
419
431 LAGG_WLOCK_ASSERT(lgp->lp_lagg);
420 LAGG_WLOCK_ASSERT(lgp->lp_softc);
432
433 m = m_gethdr(M_DONTWAIT, MT_DATA);
434 if (m == NULL) {
435 return (ENOMEM);
436 }
437 m->m_len = m->m_pkthdr.len = sizeof(*mdu);
438
439 mdu = mtod(m, struct markerdu *);

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

466 struct lacp_port *lp = LACP_PORT(lgp);
467 struct ifnet *ifp = lgp->lp_ifp;
468 struct ifmediareq ifmr;
469 int error = 0;
470 u_int media;
471 uint8_t old_state;
472 uint16_t old_key;
473
421
422 m = m_gethdr(M_DONTWAIT, MT_DATA);
423 if (m == NULL) {
424 return (ENOMEM);
425 }
426 m->m_len = m->m_pkthdr.len = sizeof(*mdu);
427
428 mdu = mtod(m, struct markerdu *);

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

455 struct lacp_port *lp = LACP_PORT(lgp);
456 struct ifnet *ifp = lgp->lp_ifp;
457 struct ifmediareq ifmr;
458 int error = 0;
459 u_int media;
460 uint8_t old_state;
461 uint16_t old_key;
462
474 LAGG_WLOCK_ASSERT(lgp->lp_lagg);
463 LAGG_WLOCK_ASSERT(lgp->lp_softc);
475
476 bzero((char *)&ifmr, sizeof(ifmr));
477 error = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr);
478 if (error != 0)
479 return;
480
481 media = ifmr.ifm_active;
482 LACP_DPRINTF((lp, "media changed 0x%x -> 0x%x, ether = %d, fdx = %d, "
483 "link = %d\n", lp->lp_media, media, IFM_TYPE(media) == IFM_ETHER,
484 (media & IFM_FDX) != 0, ifp->if_link_state == LINK_STATE_UP));
485 old_state = lp->lp_state;
486 old_key = lp->lp_key;
487
488 lp->lp_media = media;
464
465 bzero((char *)&ifmr, sizeof(ifmr));
466 error = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr);
467 if (error != 0)
468 return;
469
470 media = ifmr.ifm_active;
471 LACP_DPRINTF((lp, "media changed 0x%x -> 0x%x, ether = %d, fdx = %d, "
472 "link = %d\n", lp->lp_media, media, IFM_TYPE(media) == IFM_ETHER,
473 (media & IFM_FDX) != 0, ifp->if_link_state == LINK_STATE_UP));
474 old_state = lp->lp_state;
475 old_key = lp->lp_key;
476
477 lp->lp_media = media;
489 /*
478 /*
490 * If the port is not an active full duplex Ethernet link then it can
491 * not be aggregated.
492 */
493 if (IFM_TYPE(media) != IFM_ETHER || (media & IFM_FDX) == 0 ||
494 ifp->if_link_state != LINK_STATE_UP) {
495 lacp_port_disable(lp);
496 } else {
497 lacp_port_enable(lp);

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

503 lp->lp_selected = LACP_UNSELECTED;
504 }
505}
506
507static void
508lacp_tick(void *arg)
509{
510 struct lacp_softc *lsc = arg;
479 * If the port is not an active full duplex Ethernet link then it can
480 * not be aggregated.
481 */
482 if (IFM_TYPE(media) != IFM_ETHER || (media & IFM_FDX) == 0 ||
483 ifp->if_link_state != LINK_STATE_UP) {
484 lacp_port_disable(lp);
485 } else {
486 lacp_port_enable(lp);

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

492 lp->lp_selected = LACP_UNSELECTED;
493 }
494}
495
496static void
497lacp_tick(void *arg)
498{
499 struct lacp_softc *lsc = arg;
511 struct lagg_softc *sc = lsc->lsc_lagg;
500 struct lagg_softc *sc = lsc->lsc_softc;
512 struct lacp_port *lp;
513
514 LAGG_WLOCK(sc);
515 LIST_FOREACH(lp, &lsc->lsc_ports, lp_next) {
516 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0)
517 continue;
518
519 lacp_run_timers(lp);

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

525 }
526 LAGG_WUNLOCK(sc);
527 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc);
528}
529
530int
531lacp_port_create(struct lagg_port *lgp)
532{
501 struct lacp_port *lp;
502
503 LAGG_WLOCK(sc);
504 LIST_FOREACH(lp, &lsc->lsc_ports, lp_next) {
505 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0)
506 continue;
507
508 lacp_run_timers(lp);

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

514 }
515 LAGG_WUNLOCK(sc);
516 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc);
517}
518
519int
520lacp_port_create(struct lagg_port *lgp)
521{
533 struct lagg_softc *lgs = lgp->lp_lagg;
534 struct lacp_softc *lsc = LACP_SOFTC(lgs);
522 struct lagg_softc *sc = lgp->lp_softc;
523 struct lacp_softc *lsc = LACP_SOFTC(sc);
535 struct lacp_port *lp;
536 struct ifnet *ifp = lgp->lp_ifp;
537 struct sockaddr_dl sdl;
538 struct ifmultiaddr *rifma = NULL;
539 int error;
540
541 boolean_t active = TRUE; /* XXX should be configurable */
542 boolean_t fast = FALSE; /* XXX should be configurable */
543
524 struct lacp_port *lp;
525 struct ifnet *ifp = lgp->lp_ifp;
526 struct sockaddr_dl sdl;
527 struct ifmultiaddr *rifma = NULL;
528 int error;
529
530 boolean_t active = TRUE; /* XXX should be configurable */
531 boolean_t fast = FALSE; /* XXX should be configurable */
532
544 LAGG_WLOCK_ASSERT(lgs);
533 LAGG_WLOCK_ASSERT(sc);
545
546 bzero((char *)&sdl, sizeof(sdl));
547 sdl.sdl_len = sizeof(sdl);
548 sdl.sdl_family = AF_LINK;
549 sdl.sdl_index = ifp->if_index;
550 sdl.sdl_type = IFT_ETHER;
551 sdl.sdl_alen = ETHER_ADDR_LEN;
552

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

584}
585
586void
587lacp_port_destroy(struct lagg_port *lgp)
588{
589 struct lacp_port *lp = LACP_PORT(lgp);
590 int i;
591
534
535 bzero((char *)&sdl, sizeof(sdl));
536 sdl.sdl_len = sizeof(sdl);
537 sdl.sdl_family = AF_LINK;
538 sdl.sdl_index = ifp->if_index;
539 sdl.sdl_type = IFT_ETHER;
540 sdl.sdl_alen = ETHER_ADDR_LEN;
541

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

573}
574
575void
576lacp_port_destroy(struct lagg_port *lgp)
577{
578 struct lacp_port *lp = LACP_PORT(lgp);
579 int i;
580
592 LAGG_WLOCK_ASSERT(lgp->lp_lagg);
581 LAGG_WLOCK_ASSERT(lgp->lp_softc);
593
594 for (i = 0; i < LACP_NTIMER; i++) {
595 LACP_TIMER_DISARM(lp, i);
596 }
597
598 lacp_disable_collecting(lp);
599 lacp_disable_distributing(lp);
600 lacp_unselect(lp);

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

649{
650 struct lacp_aggregator *la = lp->lp_aggregator;
651 struct lacp_softc *lsc = lp->lp_lsc;
652 struct lagg_port *lgp = lp->lp_lagg;
653#if defined(LACP_DEBUG)
654 char buf[LACP_LAGIDSTR_MAX+1];
655#endif /* defined(LACP_DEBUG) */
656
582
583 for (i = 0; i < LACP_NTIMER; i++) {
584 LACP_TIMER_DISARM(lp, i);
585 }
586
587 lacp_disable_collecting(lp);
588 lacp_disable_distributing(lp);
589 lacp_unselect(lp);

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

638{
639 struct lacp_aggregator *la = lp->lp_aggregator;
640 struct lacp_softc *lsc = lp->lp_lsc;
641 struct lagg_port *lgp = lp->lp_lagg;
642#if defined(LACP_DEBUG)
643 char buf[LACP_LAGIDSTR_MAX+1];
644#endif /* defined(LACP_DEBUG) */
645
657 LAGG_WLOCK_ASSERT(lgp->lp_lagg);
646 LAGG_WLOCK_ASSERT(lgp->lp_softc);
658
659 if (la == NULL || (lp->lp_state & LACP_STATE_DISTRIBUTING) == 0) {
660 return;
661 }
662
663 KASSERT(!TAILQ_EMPTY(&la->la_ports), ("no aggregator ports"));
664 KASSERT(la->la_nports > 0, ("nports invalid (%d)", la->la_nports));
665 KASSERT(la->la_refcnt >= la->la_nports, ("aggregator refcnt invalid"));

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

687{
688 struct lacp_aggregator *la = lp->lp_aggregator;
689 struct lacp_softc *lsc = lp->lp_lsc;
690 struct lagg_port *lgp = lp->lp_lagg;
691#if defined(LACP_DEBUG)
692 char buf[LACP_LAGIDSTR_MAX+1];
693#endif /* defined(LACP_DEBUG) */
694
647
648 if (la == NULL || (lp->lp_state & LACP_STATE_DISTRIBUTING) == 0) {
649 return;
650 }
651
652 KASSERT(!TAILQ_EMPTY(&la->la_ports), ("no aggregator ports"));
653 KASSERT(la->la_nports > 0, ("nports invalid (%d)", la->la_nports));
654 KASSERT(la->la_refcnt >= la->la_nports, ("aggregator refcnt invalid"));

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

676{
677 struct lacp_aggregator *la = lp->lp_aggregator;
678 struct lacp_softc *lsc = lp->lp_lsc;
679 struct lagg_port *lgp = lp->lp_lagg;
680#if defined(LACP_DEBUG)
681 char buf[LACP_LAGIDSTR_MAX+1];
682#endif /* defined(LACP_DEBUG) */
683
695 LAGG_WLOCK_ASSERT(lgp->lp_lagg);
684 LAGG_WLOCK_ASSERT(lgp->lp_softc);
696
697 if ((lp->lp_state & LACP_STATE_DISTRIBUTING) != 0) {
698 return;
699 }
700
701 LACP_DPRINTF((lp, "enable distributing on aggregator %s, "
702 "nports %d -> %d\n",
703 lacp_format_lagid_aggregator(la, buf, sizeof(buf)),

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

722{
723 struct lacp_softc *lsc = vp;
724
725 LACP_DPRINTF((NULL, "%s\n", __func__));
726 lsc->lsc_suppress_distributing = FALSE;
727}
728
729int
685
686 if ((lp->lp_state & LACP_STATE_DISTRIBUTING) != 0) {
687 return;
688 }
689
690 LACP_DPRINTF((lp, "enable distributing on aggregator %s, "
691 "nports %d -> %d\n",
692 lacp_format_lagid_aggregator(la, buf, sizeof(buf)),

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

711{
712 struct lacp_softc *lsc = vp;
713
714 LACP_DPRINTF((NULL, "%s\n", __func__));
715 lsc->lsc_suppress_distributing = FALSE;
716}
717
718int
730lacp_attach(struct lagg_softc *lgs)
719lacp_attach(struct lagg_softc *sc)
731{
732 struct lacp_softc *lsc;
733
720{
721 struct lacp_softc *lsc;
722
734 LAGG_WLOCK_ASSERT(lgs);
723 LAGG_WLOCK_ASSERT(sc);
735
736 lsc = malloc(sizeof(struct lacp_softc),
737 M_DEVBUF, M_NOWAIT|M_ZERO);
738 if (lsc == NULL)
739 return (ENOMEM);
740
724
725 lsc = malloc(sizeof(struct lacp_softc),
726 M_DEVBUF, M_NOWAIT|M_ZERO);
727 if (lsc == NULL)
728 return (ENOMEM);
729
741 lgs->sc_psc = (caddr_t)lsc;
742 lsc->lsc_lagg = lgs;
730 sc->sc_psc = (caddr_t)lsc;
731 lsc->lsc_softc = sc;
743
744 lsc->lsc_hashkey = arc4random();
745 lsc->lsc_active_aggregator = NULL;
746 TAILQ_INIT(&lsc->lsc_aggregators);
747 LIST_INIT(&lsc->lsc_ports);
748
749 TASK_INIT(&lsc->lsc_qtask, 0, lacp_dequeue, lsc);
750 mtx_init(&lsc->lsc_queue.ifq_mtx, "lacp queue", NULL, MTX_DEF);
751 lsc->lsc_queue.ifq_maxlen = ifqmaxlen;
752
753 callout_init(&lsc->lsc_transit_callout, CALLOUT_MPSAFE);
754 callout_init(&lsc->lsc_callout, CALLOUT_MPSAFE);
755
756 /* if the lagg is already up then do the same */
732
733 lsc->lsc_hashkey = arc4random();
734 lsc->lsc_active_aggregator = NULL;
735 TAILQ_INIT(&lsc->lsc_aggregators);
736 LIST_INIT(&lsc->lsc_ports);
737
738 TASK_INIT(&lsc->lsc_qtask, 0, lacp_dequeue, lsc);
739 mtx_init(&lsc->lsc_queue.ifq_mtx, "lacp queue", NULL, MTX_DEF);
740 lsc->lsc_queue.ifq_maxlen = ifqmaxlen;
741
742 callout_init(&lsc->lsc_transit_callout, CALLOUT_MPSAFE);
743 callout_init(&lsc->lsc_callout, CALLOUT_MPSAFE);
744
745 /* if the lagg is already up then do the same */
757 if (lgs->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
758 lacp_init(lgs);
746 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)
747 lacp_init(sc);
759
760 return (0);
761}
762
763int
748
749 return (0);
750}
751
752int
764lacp_detach(struct lagg_softc *lgs)
753lacp_detach(struct lagg_softc *sc)
765{
754{
766 struct lacp_softc *lsc = LACP_SOFTC(lgs);
755 struct lacp_softc *lsc = LACP_SOFTC(sc);
767
768 KASSERT(TAILQ_EMPTY(&lsc->lsc_aggregators),
769 ("aggregators still active"));
770 KASSERT(lsc->lsc_active_aggregator == NULL,
771 ("aggregator still attached"));
772
756
757 KASSERT(TAILQ_EMPTY(&lsc->lsc_aggregators),
758 ("aggregators still active"));
759 KASSERT(lsc->lsc_active_aggregator == NULL,
760 ("aggregator still attached"));
761
773 lgs->sc_psc = NULL;
762 sc->sc_psc = NULL;
774 callout_drain(&lsc->lsc_transit_callout);
775 callout_drain(&lsc->lsc_callout);
776 taskqueue_drain(taskqueue_swi, &lsc->lsc_qtask);
777 IF_DRAIN(&lsc->lsc_queue);
778 mtx_destroy(&lsc->lsc_queue.ifq_mtx);
779
780 free(lsc, M_DEVBUF);
781 return (0);
782}
783
784void
763 callout_drain(&lsc->lsc_transit_callout);
764 callout_drain(&lsc->lsc_callout);
765 taskqueue_drain(taskqueue_swi, &lsc->lsc_qtask);
766 IF_DRAIN(&lsc->lsc_queue);
767 mtx_destroy(&lsc->lsc_queue.ifq_mtx);
768
769 free(lsc, M_DEVBUF);
770 return (0);
771}
772
773void
785lacp_init(struct lagg_softc *lgs)
774lacp_init(struct lagg_softc *sc)
786{
775{
787 struct lacp_softc *lsc = LACP_SOFTC(lgs);
776 struct lacp_softc *lsc = LACP_SOFTC(sc);
788
789 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc);
790}
791
792void
777
778 callout_reset(&lsc->lsc_callout, hz, lacp_tick, lsc);
779}
780
781void
793lacp_stop(struct lagg_softc *lgs)
782lacp_stop(struct lagg_softc *sc)
794{
783{
795 struct lacp_softc *lsc = LACP_SOFTC(lgs);
784 struct lacp_softc *lsc = LACP_SOFTC(sc);
796
797 callout_stop(&lsc->lsc_transit_callout);
798 callout_stop(&lsc->lsc_callout);
799}
800
801struct lagg_port *
785
786 callout_stop(&lsc->lsc_transit_callout);
787 callout_stop(&lsc->lsc_callout);
788}
789
790struct lagg_port *
802lacp_select_tx_port(struct lagg_softc *lgs, struct mbuf *m)
791lacp_select_tx_port(struct lagg_softc *sc, struct mbuf *m)
803{
792{
804 struct lacp_softc *lsc = LACP_SOFTC(lgs);
793 struct lacp_softc *lsc = LACP_SOFTC(sc);
805 struct lacp_aggregator *la;
806 struct lacp_port *lp;
807 uint32_t hash;
808 int nports;
809
794 struct lacp_aggregator *la;
795 struct lacp_port *lp;
796 uint32_t hash;
797 int nports;
798
810 LAGG_RLOCK_ASSERT(lgs);
799 LAGG_RLOCK_ASSERT(sc);
811
812 if (__predict_false(lsc->lsc_suppress_distributing)) {
813 LACP_DPRINTF((NULL, "%s: waiting transit\n", __func__));
814 return (NULL);
815 }
816
817 la = lsc->lsc_active_aggregator;
818 if (__predict_false(la == NULL)) {

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

976 }
977 }
978}
979
980static uint16_t
981lacp_compose_key(struct lacp_port *lp)
982{
983 struct lagg_port *lgp = lp->lp_lagg;
800
801 if (__predict_false(lsc->lsc_suppress_distributing)) {
802 LACP_DPRINTF((NULL, "%s: waiting transit\n", __func__));
803 return (NULL);
804 }
805
806 la = lsc->lsc_active_aggregator;
807 if (__predict_false(la == NULL)) {

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

965 }
966 }
967}
968
969static uint16_t
970lacp_compose_key(struct lacp_port *lp)
971{
972 struct lagg_port *lgp = lp->lp_lagg;
984 struct lagg_softc *lgs = lgp->lp_lagg;
973 struct lagg_softc *sc = lgp->lp_softc;
985 u_int media = lp->lp_media;
986 uint16_t key;
987
988 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0) {
989
990 /*
991 * non-aggregatable links should have unique keys.
992 *

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

1001 u_int subtype = IFM_SUBTYPE(media);
1002
1003 KASSERT(IFM_TYPE(media) == IFM_ETHER, ("invalid media type"));
1004 KASSERT((media & IFM_FDX) != 0, ("aggregating HDX interface"));
1005
1006 /* bit 0..4: IFM_SUBTYPE */
1007 key = subtype;
1008 /* bit 5..14: (some bits of) if_index of lagg device */
974 u_int media = lp->lp_media;
975 uint16_t key;
976
977 if ((lp->lp_state & LACP_STATE_AGGREGATION) == 0) {
978
979 /*
980 * non-aggregatable links should have unique keys.
981 *

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

990 u_int subtype = IFM_SUBTYPE(media);
991
992 KASSERT(IFM_TYPE(media) == IFM_ETHER, ("invalid media type"));
993 KASSERT((media & IFM_FDX) != 0, ("aggregating HDX interface"));
994
995 /* bit 0..4: IFM_SUBTYPE */
996 key = subtype;
997 /* bit 5..14: (some bits of) if_index of lagg device */
1009 key |= 0x7fe0 & ((lgs->sc_ifp->if_index) << 5);
998 key |= 0x7fe0 & ((sc->sc_ifp->if_index) << 5);
1010 /* bit 15: 0 */
1011 }
1012 return (htons(key));
1013}
1014
1015static void
1016lacp_aggregator_addref(struct lacp_softc *lsc, struct lacp_aggregator *la)
1017{

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

1675{
1676 struct lacp_port *lp = LACP_PORT(lgp);
1677 struct lacp_port *lp2;
1678 struct lacp_softc *lsc = lp->lp_lsc;
1679 struct markerdu *mdu;
1680 int error = 0;
1681 int pending = 0;
1682
999 /* bit 15: 0 */
1000 }
1001 return (htons(key));
1002}
1003
1004static void
1005lacp_aggregator_addref(struct lacp_softc *lsc, struct lacp_aggregator *la)
1006{

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

1664{
1665 struct lacp_port *lp = LACP_PORT(lgp);
1666 struct lacp_port *lp2;
1667 struct lacp_softc *lsc = lp->lp_lsc;
1668 struct markerdu *mdu;
1669 int error = 0;
1670 int pending = 0;
1671
1683 LAGG_RLOCK_ASSERT(lgp->lp_lagg);
1672 LAGG_RLOCK_ASSERT(lgp->lp_softc);
1684
1673
1685 if (__predict_false(lp->lp_flags & LACP_PORT_DETACHING)) {
1686 goto bad;
1687 }
1688
1689 if (m->m_pkthdr.len != sizeof(*mdu)) {
1690 goto bad;
1691 }
1692
1693 if ((m->m_flags & M_MCAST) == 0) {
1694 goto bad;
1695 }
1696

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

1703
1704 mdu = mtod(m, struct markerdu *);
1705
1706 if (memcmp(&mdu->mdu_eh.ether_dhost,
1707 &ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) {
1708 goto bad;
1709 }
1710
1674 if (m->m_pkthdr.len != sizeof(*mdu)) {
1675 goto bad;
1676 }
1677
1678 if ((m->m_flags & M_MCAST) == 0) {
1679 goto bad;
1680 }
1681

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

1688
1689 mdu = mtod(m, struct markerdu *);
1690
1691 if (memcmp(&mdu->mdu_eh.ether_dhost,
1692 &ethermulticastaddr_slowprotocols, ETHER_ADDR_LEN)) {
1693 goto bad;
1694 }
1695
1711 /* XXX
1712 KASSERT(mdu->mdu_sph.sph_subtype == SLOWPROTOCOLS_SUBTYPE_MARKER,
1713 ("a very bad kassert!"));
1714 */
1715
1716 if (mdu->mdu_sph.sph_version != 1) {
1717 goto bad;
1718 }
1719
1720 switch (mdu->mdu_tlv.tlv_type) {
1721 case MARKER_TYPE_INFO:
1722 if (tlv_check(mdu, sizeof(*mdu), &mdu->mdu_tlv,
1723 marker_info_tlv_template, TRUE)) {

--- 211 unchanged lines hidden ---
1696 if (mdu->mdu_sph.sph_version != 1) {
1697 goto bad;
1698 }
1699
1700 switch (mdu->mdu_tlv.tlv_type) {
1701 case MARKER_TYPE_INFO:
1702 if (tlv_check(mdu, sizeof(*mdu), &mdu->mdu_tlv,
1703 marker_info_tlv_template, TRUE)) {

--- 211 unchanged lines hidden ---