Deleted Added
full compact
if_lagg.c (169340) if_lagg.c (169569)
1/* $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $ */
2
3/*
4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/cdefs.h>
1/* $OpenBSD: if_trunk.c,v 1.30 2007/01/31 06:20:19 reyk Exp $ */
2
3/*
4 * Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/cdefs.h>
20__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 169340 2007-05-07 09:53:02Z thompsa $");
20__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 169569 2007-05-15 07:41:46Z thompsa $");
21
22#include "opt_inet.h"
23#include "opt_inet6.h"
24
25#include <sys/param.h>
26#include <sys/kernel.h>
27#include <sys/malloc.h>
28#include <sys/mbuf.h>
29#include <sys/queue.h>
30#include <sys/socket.h>
31#include <sys/sockio.h>
32#include <sys/sysctl.h>
33#include <sys/module.h>
34#include <sys/priv.h>
35#include <sys/systm.h>
36#include <sys/proc.h>
37#include <sys/hash.h>
21
22#include "opt_inet.h"
23#include "opt_inet6.h"
24
25#include <sys/param.h>
26#include <sys/kernel.h>
27#include <sys/malloc.h>
28#include <sys/mbuf.h>
29#include <sys/queue.h>
30#include <sys/socket.h>
31#include <sys/sockio.h>
32#include <sys/sysctl.h>
33#include <sys/module.h>
34#include <sys/priv.h>
35#include <sys/systm.h>
36#include <sys/proc.h>
37#include <sys/hash.h>
38#include <sys/lock.h>
39#include <sys/rwlock.h>
38#include <sys/taskqueue.h>
39
40#include <net/ethernet.h>
41#include <net/if.h>
42#include <net/if_clone.h>
43#include <net/if_arp.h>
44#include <net/if_dl.h>
45#include <net/if_llc.h>

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

257}
258
259static void
260lagg_clone_destroy(struct ifnet *ifp)
261{
262 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
263 struct lagg_port *lp;
264
40#include <sys/taskqueue.h>
41
42#include <net/ethernet.h>
43#include <net/if.h>
44#include <net/if_clone.h>
45#include <net/if_arp.h>
46#include <net/if_dl.h>
47#include <net/if_llc.h>

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

259}
260
261static void
262lagg_clone_destroy(struct ifnet *ifp)
263{
264 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
265 struct lagg_port *lp;
266
265 LAGG_LOCK(sc);
267 LAGG_WLOCK(sc);
266
267 lagg_stop(sc);
268 ifp->if_flags &= ~IFF_UP;
269
270 /* Shutdown and remove lagg ports */
271 while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL)
272 lagg_port_destroy(lp, 1);
273 /* Unhook the aggregation protocol */
274 if (sc->sc_detach != NULL)
275 (*sc->sc_detach)(sc);
276
268
269 lagg_stop(sc);
270 ifp->if_flags &= ~IFF_UP;
271
272 /* Shutdown and remove lagg ports */
273 while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL)
274 lagg_port_destroy(lp, 1);
275 /* Unhook the aggregation protocol */
276 if (sc->sc_detach != NULL)
277 (*sc->sc_detach)(sc);
278
277 LAGG_UNLOCK(sc);
279 LAGG_WUNLOCK(sc);
278
279 ifmedia_removeall(&sc->sc_media);
280 ether_ifdetach(ifp);
281 if_free_type(ifp, IFT_ETHER);
282
283 mtx_lock(&lagg_list_mtx);
284 SLIST_REMOVE(&lagg_list, sc, lagg_softc, sc_entries);
285 mtx_unlock(&lagg_list_mtx);

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

304}
305
306static int
307lagg_capabilities(struct lagg_softc *sc)
308{
309 struct lagg_port *lp;
310 int cap = ~0, priv;
311
280
281 ifmedia_removeall(&sc->sc_media);
282 ether_ifdetach(ifp);
283 if_free_type(ifp, IFT_ETHER);
284
285 mtx_lock(&lagg_list_mtx);
286 SLIST_REMOVE(&lagg_list, sc, lagg_softc, sc_entries);
287 mtx_unlock(&lagg_list_mtx);

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

306}
307
308static int
309lagg_capabilities(struct lagg_softc *sc)
310{
311 struct lagg_port *lp;
312 int cap = ~0, priv;
313
312 LAGG_LOCK_ASSERT(sc);
314 LAGG_WLOCK_ASSERT(sc);
313
314 /* Preserve private capabilities */
315 priv = sc->sc_capabilities & IFCAP_LAGG_MASK;
316
317 /* Get capabilities from the lagg ports */
318 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
319 cap &= lp->lp_capabilities;
320

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

329static void
330lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
331{
332 struct lagg_softc *sc = lp->lp_lagg;
333 struct ifnet *ifp = lp->lp_ifp;
334 struct lagg_llq *llq;
335 int pending = 0;
336
315
316 /* Preserve private capabilities */
317 priv = sc->sc_capabilities & IFCAP_LAGG_MASK;
318
319 /* Get capabilities from the lagg ports */
320 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
321 cap &= lp->lp_capabilities;
322

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

331static void
332lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
333{
334 struct lagg_softc *sc = lp->lp_lagg;
335 struct ifnet *ifp = lp->lp_ifp;
336 struct lagg_llq *llq;
337 int pending = 0;
338
337 LAGG_LOCK_ASSERT(sc);
339 LAGG_WLOCK_ASSERT(sc);
338
339 if (lp->lp_detaching ||
340 memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
341 return;
342
343 /* Check to make sure its not already queued to be changed */
344 SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
345 if (llq->llq_ifp == ifp) {

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

371lagg_port_setlladdr(void *arg, int pending)
372{
373 struct lagg_softc *sc = (struct lagg_softc *)arg;
374 struct lagg_llq *llq, *head;
375 struct ifnet *ifp;
376 int error;
377
378 /* Grab a local reference of the queue and remove it from the softc */
340
341 if (lp->lp_detaching ||
342 memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
343 return;
344
345 /* Check to make sure its not already queued to be changed */
346 SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
347 if (llq->llq_ifp == ifp) {

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

373lagg_port_setlladdr(void *arg, int pending)
374{
375 struct lagg_softc *sc = (struct lagg_softc *)arg;
376 struct lagg_llq *llq, *head;
377 struct ifnet *ifp;
378 int error;
379
380 /* Grab a local reference of the queue and remove it from the softc */
379 LAGG_LOCK(sc);
381 LAGG_WLOCK(sc);
380 head = SLIST_FIRST(&sc->sc_llq_head);
381 SLIST_FIRST(&sc->sc_llq_head) = NULL;
382 head = SLIST_FIRST(&sc->sc_llq_head);
383 SLIST_FIRST(&sc->sc_llq_head) = NULL;
382 LAGG_UNLOCK(sc);
384 LAGG_WUNLOCK(sc);
383
384 /*
385 * Traverse the queue and set the lladdr on each ifp. It is safe to do
386 * unlocked as we have the only reference to it.
387 */
388 for (llq = head; llq != NULL; llq = head) {
389 ifp = llq->llq_ifp;
390

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

401
402static int
403lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
404{
405 struct lagg_softc *sc_ptr;
406 struct lagg_port *lp;
407 int error = 0;
408
385
386 /*
387 * Traverse the queue and set the lladdr on each ifp. It is safe to do
388 * unlocked as we have the only reference to it.
389 */
390 for (llq = head; llq != NULL; llq = head) {
391 ifp = llq->llq_ifp;
392

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

403
404static int
405lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp)
406{
407 struct lagg_softc *sc_ptr;
408 struct lagg_port *lp;
409 int error = 0;
410
409 LAGG_LOCK_ASSERT(sc);
411 LAGG_WLOCK_ASSERT(sc);
410
411 /* Limit the maximal number of lagg ports */
412 if (sc->sc_count >= LAGG_MAX_PORTS)
413 return (ENOSPC);
414
415 /* New lagg port has to be in an idle state */
416 if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
417 return (EBUSY);

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

495
496static int
497lagg_port_checkstacking(struct lagg_softc *sc)
498{
499 struct lagg_softc *sc_ptr;
500 struct lagg_port *lp;
501 int m = 0;
502
412
413 /* Limit the maximal number of lagg ports */
414 if (sc->sc_count >= LAGG_MAX_PORTS)
415 return (ENOSPC);
416
417 /* New lagg port has to be in an idle state */
418 if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
419 return (EBUSY);

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

497
498static int
499lagg_port_checkstacking(struct lagg_softc *sc)
500{
501 struct lagg_softc *sc_ptr;
502 struct lagg_port *lp;
503 int m = 0;
504
503 LAGG_LOCK_ASSERT(sc);
505 LAGG_WLOCK_ASSERT(sc);
504
505 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
506 if (lp->lp_flags & LAGG_PORT_STACK) {
507 sc_ptr = (struct lagg_softc *)lp->lp_ifp->if_softc;
508 m = MAX(m, lagg_port_checkstacking(sc_ptr));
509 }
510 }
511
512 return (m + 1);
513}
514
515static int
516lagg_port_destroy(struct lagg_port *lp, int runpd)
517{
518 struct lagg_softc *sc = lp->lp_lagg;
519 struct lagg_port *lp_ptr;
520 struct lagg_llq *llq;
521 struct ifnet *ifp = lp->lp_ifp;
522
506
507 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
508 if (lp->lp_flags & LAGG_PORT_STACK) {
509 sc_ptr = (struct lagg_softc *)lp->lp_ifp->if_softc;
510 m = MAX(m, lagg_port_checkstacking(sc_ptr));
511 }
512 }
513
514 return (m + 1);
515}
516
517static int
518lagg_port_destroy(struct lagg_port *lp, int runpd)
519{
520 struct lagg_softc *sc = lp->lp_lagg;
521 struct lagg_port *lp_ptr;
522 struct lagg_llq *llq;
523 struct ifnet *ifp = lp->lp_ifp;
524
523 LAGG_LOCK_ASSERT(sc);
525 LAGG_WLOCK_ASSERT(sc);
524
525 if (runpd && sc->sc_port_destroy != NULL)
526 (*sc->sc_port_destroy)(lp);
527
528 /*
529 * Remove multicast addresses and interface flags from this port and
530 * reset the MAC address, skip if the interface is being detached.
531 */

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

596
597 /* Should be checked by the caller */
598 if (ifp->if_type != IFT_IEEE8023ADLAG ||
599 (lp = ifp->if_lagg) == NULL || (sc = lp->lp_lagg) == NULL)
600 goto fallback;
601
602 switch (cmd) {
603 case SIOCGLAGGPORT:
526
527 if (runpd && sc->sc_port_destroy != NULL)
528 (*sc->sc_port_destroy)(lp);
529
530 /*
531 * Remove multicast addresses and interface flags from this port and
532 * reset the MAC address, skip if the interface is being detached.
533 */

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

598
599 /* Should be checked by the caller */
600 if (ifp->if_type != IFT_IEEE8023ADLAG ||
601 (lp = ifp->if_lagg) == NULL || (sc = lp->lp_lagg) == NULL)
602 goto fallback;
603
604 switch (cmd) {
605 case SIOCGLAGGPORT:
604 LAGG_LOCK(sc);
606 LAGG_RLOCK(sc);
605 if (rp->rp_portname[0] == '\0' ||
606 ifunit(rp->rp_portname) != ifp) {
607 error = EINVAL;
608 break;
609 }
610
611 if (lp->lp_lagg != sc) {
612 error = ENOENT;
613 break;
614 }
615
616 lagg_port2req(lp, rp);
607 if (rp->rp_portname[0] == '\0' ||
608 ifunit(rp->rp_portname) != ifp) {
609 error = EINVAL;
610 break;
611 }
612
613 if (lp->lp_lagg != sc) {
614 error = ENOENT;
615 break;
616 }
617
618 lagg_port2req(lp, rp);
617 LAGG_UNLOCK(sc);
619 LAGG_RUNLOCK(sc);
618 break;
619 default:
620 goto fallback;
621 }
622
623 return (error);
624
625fallback:

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

665 struct lagg_port *lp;
666 struct lagg_softc *sc;
667
668 if ((lp = ifp->if_lagg) == NULL)
669 return;
670
671 sc = lp->lp_lagg;
672
620 break;
621 default:
622 goto fallback;
623 }
624
625 return (error);
626
627fallback:

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

667 struct lagg_port *lp;
668 struct lagg_softc *sc;
669
670 if ((lp = ifp->if_lagg) == NULL)
671 return;
672
673 sc = lp->lp_lagg;
674
673 LAGG_LOCK(sc);
675 LAGG_WLOCK(sc);
674 lp->lp_detaching = 1;
675 lagg_port_destroy(lp, 1);
676 lp->lp_detaching = 1;
677 lagg_port_destroy(lp, 1);
676 LAGG_UNLOCK(sc);
678 LAGG_WUNLOCK(sc);
677}
678
679static void
680lagg_port2req(struct lagg_port *lp, struct lagg_reqport *rp)
681{
682 struct lagg_softc *sc = lp->lp_lagg;
683 strlcpy(rp->rp_ifname, sc->sc_ifname, sizeof(rp->rp_ifname));
684 strlcpy(rp->rp_portname, lp->lp_ifp->if_xname, sizeof(rp->rp_portname));

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

712{
713 struct lagg_softc *sc = (struct lagg_softc *)xsc;
714 struct lagg_port *lp;
715 struct ifnet *ifp = sc->sc_ifp;
716
717 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
718 return;
719
679}
680
681static void
682lagg_port2req(struct lagg_port *lp, struct lagg_reqport *rp)
683{
684 struct lagg_softc *sc = lp->lp_lagg;
685 strlcpy(rp->rp_ifname, sc->sc_ifname, sizeof(rp->rp_ifname));
686 strlcpy(rp->rp_portname, lp->lp_ifp->if_xname, sizeof(rp->rp_portname));

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

714{
715 struct lagg_softc *sc = (struct lagg_softc *)xsc;
716 struct lagg_port *lp;
717 struct ifnet *ifp = sc->sc_ifp;
718
719 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
720 return;
721
720 LAGG_LOCK(sc);
722 LAGG_WLOCK(sc);
721
722 ifp->if_drv_flags |= IFF_DRV_RUNNING;
723 /* Update the port lladdrs */
724 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
725 lagg_port_lladdr(lp, IF_LLADDR(ifp));
726
727 if (sc->sc_init != NULL)
728 (*sc->sc_init)(sc);
729
723
724 ifp->if_drv_flags |= IFF_DRV_RUNNING;
725 /* Update the port lladdrs */
726 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
727 lagg_port_lladdr(lp, IF_LLADDR(ifp));
728
729 if (sc->sc_init != NULL)
730 (*sc->sc_init)(sc);
731
730 LAGG_UNLOCK(sc);
732 LAGG_WUNLOCK(sc);
731}
732
733static void
734lagg_stop(struct lagg_softc *sc)
735{
736 struct ifnet *ifp = sc->sc_ifp;
737
733}
734
735static void
736lagg_stop(struct lagg_softc *sc)
737{
738 struct ifnet *ifp = sc->sc_ifp;
739
738 LAGG_LOCK_ASSERT(sc);
740 LAGG_WLOCK_ASSERT(sc);
739
740 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
741 return;
742
743 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
744
745 if (sc->sc_stop != NULL)
746 (*sc->sc_stop)(sc);

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

753 struct lagg_reqall *ra = (struct lagg_reqall *)data;
754 struct lagg_reqport *rp = (struct lagg_reqport *)data, rpbuf;
755 struct ifreq *ifr = (struct ifreq *)data;
756 struct lagg_port *lp;
757 struct ifnet *tpif;
758 struct thread *td = curthread;
759 int i, error = 0, unlock = 1;
760
741
742 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
743 return;
744
745 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
746
747 if (sc->sc_stop != NULL)
748 (*sc->sc_stop)(sc);

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

755 struct lagg_reqall *ra = (struct lagg_reqall *)data;
756 struct lagg_reqport *rp = (struct lagg_reqport *)data, rpbuf;
757 struct ifreq *ifr = (struct ifreq *)data;
758 struct lagg_port *lp;
759 struct ifnet *tpif;
760 struct thread *td = curthread;
761 int i, error = 0, unlock = 1;
762
761 LAGG_LOCK(sc);
763 LAGG_WLOCK(sc);
762
763 bzero(&rpbuf, sizeof(rpbuf));
764
765 switch (cmd) {
766 case SIOCGLAGG:
767 ra->ra_proto = sc->sc_proto;
768 ra->ra_ports = i = 0;
769 lp = SLIST_FIRST(&sc->sc_ports);

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

876 */
877 lagg_stop(sc);
878 } else if ((ifp->if_flags & IFF_UP) &&
879 !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
880 /*
881 * If interface is marked up and it is stopped, then
882 * start it.
883 */
764
765 bzero(&rpbuf, sizeof(rpbuf));
766
767 switch (cmd) {
768 case SIOCGLAGG:
769 ra->ra_proto = sc->sc_proto;
770 ra->ra_ports = i = 0;
771 lp = SLIST_FIRST(&sc->sc_ports);

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

878 */
879 lagg_stop(sc);
880 } else if ((ifp->if_flags & IFF_UP) &&
881 !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
882 /*
883 * If interface is marked up and it is stopped, then
884 * start it.
885 */
884 LAGG_UNLOCK(sc);
886 LAGG_WUNLOCK(sc);
885 unlock = 0;
886 (*ifp->if_init)(sc);
887 }
888 break;
889 case SIOCADDMULTI:
890 case SIOCDELMULTI:
891 error = lagg_ether_setmulti(sc);
892 break;
893 case SIOCSIFMEDIA:
894 case SIOCGIFMEDIA:
887 unlock = 0;
888 (*ifp->if_init)(sc);
889 }
890 break;
891 case SIOCADDMULTI:
892 case SIOCDELMULTI:
893 error = lagg_ether_setmulti(sc);
894 break;
895 case SIOCSIFMEDIA:
896 case SIOCGIFMEDIA:
895 LAGG_UNLOCK(sc);
897 LAGG_WUNLOCK(sc);
896 unlock = 0;
897 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
898 break;
899 default:
898 unlock = 0;
899 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
900 break;
901 default:
900 LAGG_UNLOCK(sc);
902 LAGG_WUNLOCK(sc);
901 unlock = 0;
902 error = ether_ioctl(ifp, cmd, data);
903 break;
904 }
905
906out:
907 if (unlock)
903 unlock = 0;
904 error = ether_ioctl(ifp, cmd, data);
905 break;
906 }
907
908out:
909 if (unlock)
908 LAGG_UNLOCK(sc);
910 LAGG_WUNLOCK(sc);
909 return (error);
910}
911
912static int
913lagg_ether_setmulti(struct lagg_softc *sc)
914{
915 struct lagg_port *lp;
916
911 return (error);
912}
913
914static int
915lagg_ether_setmulti(struct lagg_softc *sc)
916{
917 struct lagg_port *lp;
918
917 LAGG_LOCK_ASSERT(sc);
919 LAGG_WLOCK_ASSERT(sc);
918
919 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
920 /* First, remove any existing filter entries. */
921 lagg_ether_cmdmulti(lp, 0);
922 /* copy all addresses from the lagg interface to the port */
923 lagg_ether_cmdmulti(lp, 1);
924 }
925 return (0);

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

931 struct lagg_softc *sc = lp->lp_lagg;
932 struct ifnet *ifp = lp->lp_ifp;
933 struct ifnet *trifp = sc->sc_ifp;
934 struct lagg_mc *mc;
935 struct ifmultiaddr *ifma, *rifma = NULL;
936 struct sockaddr_dl sdl;
937 int error;
938
920
921 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
922 /* First, remove any existing filter entries. */
923 lagg_ether_cmdmulti(lp, 0);
924 /* copy all addresses from the lagg interface to the port */
925 lagg_ether_cmdmulti(lp, 1);
926 }
927 return (0);

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

933 struct lagg_softc *sc = lp->lp_lagg;
934 struct ifnet *ifp = lp->lp_ifp;
935 struct ifnet *trifp = sc->sc_ifp;
936 struct lagg_mc *mc;
937 struct ifmultiaddr *ifma, *rifma = NULL;
938 struct sockaddr_dl sdl;
939 int error;
940
939 LAGG_LOCK_ASSERT(sc);
941 LAGG_WLOCK_ASSERT(sc);
940
941 bzero((char *)&sdl, sizeof(sdl));
942 sdl.sdl_len = sizeof(sdl);
943 sdl.sdl_family = AF_LINK;
944 sdl.sdl_type = IFT_ETHER;
945 sdl.sdl_alen = ETHER_ADDR_LEN;
946 sdl.sdl_index = ifp->if_index;
947

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

976lagg_setflag(struct lagg_port *lp, int flag, int status,
977 int (*func)(struct ifnet *, int))
978{
979 struct lagg_softc *sc = lp->lp_lagg;
980 struct ifnet *trifp = sc->sc_ifp;
981 struct ifnet *ifp = lp->lp_ifp;
982 int error;
983
942
943 bzero((char *)&sdl, sizeof(sdl));
944 sdl.sdl_len = sizeof(sdl);
945 sdl.sdl_family = AF_LINK;
946 sdl.sdl_type = IFT_ETHER;
947 sdl.sdl_alen = ETHER_ADDR_LEN;
948 sdl.sdl_index = ifp->if_index;
949

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

978lagg_setflag(struct lagg_port *lp, int flag, int status,
979 int (*func)(struct ifnet *, int))
980{
981 struct lagg_softc *sc = lp->lp_lagg;
982 struct ifnet *trifp = sc->sc_ifp;
983 struct ifnet *ifp = lp->lp_ifp;
984 int error;
985
984 LAGG_LOCK_ASSERT(sc);
986 LAGG_WLOCK_ASSERT(sc);
985
986 status = status ? (trifp->if_flags & flag) : 0;
987 /* Now "status" contains the flag value or 0 */
988
989 /*
990 * See if recorded ports status is different from what
991 * we want it to be. If it is, flip it. We record ports
992 * status in lp_ifflags so that we won't clear ports flag

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

1026
1027static void
1028lagg_start(struct ifnet *ifp)
1029{
1030 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
1031 struct mbuf *m;
1032 int error = 0;
1033
987
988 status = status ? (trifp->if_flags & flag) : 0;
989 /* Now "status" contains the flag value or 0 */
990
991 /*
992 * See if recorded ports status is different from what
993 * we want it to be. If it is, flip it. We record ports
994 * status in lp_ifflags so that we won't clear ports flag

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

1028
1029static void
1030lagg_start(struct ifnet *ifp)
1031{
1032 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
1033 struct mbuf *m;
1034 int error = 0;
1035
1036 LAGG_RLOCK(sc);
1034 for (;; error = 0) {
1035 IFQ_DEQUEUE(&ifp->if_snd, m);
1036 if (m == NULL)
1037 break;
1038
1039 BPF_MTAP(ifp, m);
1040
1037 for (;; error = 0) {
1038 IFQ_DEQUEUE(&ifp->if_snd, m);
1039 if (m == NULL)
1040 break;
1041
1042 BPF_MTAP(ifp, m);
1043
1041 if (sc->sc_proto != LAGG_PROTO_NONE) {
1042 LAGG_LOCK(sc);
1044 if (sc->sc_proto != LAGG_PROTO_NONE)
1043 error = (*sc->sc_start)(sc, m);
1045 error = (*sc->sc_start)(sc, m);
1044 LAGG_UNLOCK(sc);
1045 } else
1046 else
1046 m_free(m);
1047
1048 if (error == 0)
1049 ifp->if_opackets++;
1050 else
1051 ifp->if_oerrors++;
1052 }
1047 m_free(m);
1048
1049 if (error == 0)
1050 ifp->if_opackets++;
1051 else
1052 ifp->if_oerrors++;
1053 }
1054 LAGG_RUNLOCK(sc);
1053
1054 return;
1055}
1056
1057static struct mbuf *
1058lagg_input(struct ifnet *ifp, struct mbuf *m)
1059{
1060 struct lagg_port *lp = ifp->if_lagg;
1061 struct lagg_softc *sc = lp->lp_lagg;
1062 struct ifnet *trifp = sc->sc_ifp;
1063
1064 if ((trifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
1065 (lp->lp_flags & LAGG_PORT_DISABLED) ||
1066 sc->sc_proto == LAGG_PROTO_NONE) {
1067 m_freem(m);
1068 return (NULL);
1069 }
1070
1055
1056 return;
1057}
1058
1059static struct mbuf *
1060lagg_input(struct ifnet *ifp, struct mbuf *m)
1061{
1062 struct lagg_port *lp = ifp->if_lagg;
1063 struct lagg_softc *sc = lp->lp_lagg;
1064 struct ifnet *trifp = sc->sc_ifp;
1065
1066 if ((trifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
1067 (lp->lp_flags & LAGG_PORT_DISABLED) ||
1068 sc->sc_proto == LAGG_PROTO_NONE) {
1069 m_freem(m);
1070 return (NULL);
1071 }
1072
1071 LAGG_LOCK(sc);
1073 LAGG_RLOCK(sc);
1072 BPF_MTAP(trifp, m);
1073
1074 m = (*sc->sc_input)(sc, lp, m);
1075
1076 if (m != NULL) {
1077 ifp->if_ipackets++;
1078 ifp->if_ibytes += m->m_pkthdr.len;
1079 trifp->if_ipackets++;
1080 trifp->if_ibytes += m->m_pkthdr.len;
1081 }
1082
1074 BPF_MTAP(trifp, m);
1075
1076 m = (*sc->sc_input)(sc, lp, m);
1077
1078 if (m != NULL) {
1079 ifp->if_ipackets++;
1080 ifp->if_ibytes += m->m_pkthdr.len;
1081 trifp->if_ipackets++;
1082 trifp->if_ibytes += m->m_pkthdr.len;
1083 }
1084
1083 LAGG_UNLOCK(sc);
1085 LAGG_RUNLOCK(sc);
1084 return (m);
1085}
1086
1087static int
1088lagg_media_change(struct ifnet *ifp)
1089{
1090 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
1091

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

1100lagg_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1101{
1102 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
1103 struct lagg_port *lp;
1104
1105 imr->ifm_status = IFM_AVALID;
1106 imr->ifm_active = IFM_ETHER | IFM_AUTO;
1107
1086 return (m);
1087}
1088
1089static int
1090lagg_media_change(struct ifnet *ifp)
1091{
1092 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
1093

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

1102lagg_media_status(struct ifnet *ifp, struct ifmediareq *imr)
1103{
1104 struct lagg_softc *sc = (struct lagg_softc *)ifp->if_softc;
1105 struct lagg_port *lp;
1106
1107 imr->ifm_status = IFM_AVALID;
1108 imr->ifm_active = IFM_ETHER | IFM_AUTO;
1109
1108 LAGG_LOCK(sc);
1110 LAGG_RLOCK(sc);
1109 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
1110 if (LAGG_PORTACTIVE(lp))
1111 imr->ifm_status |= IFM_ACTIVE;
1112 }
1111 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
1112 if (LAGG_PORTACTIVE(lp))
1113 imr->ifm_status |= IFM_ACTIVE;
1114 }
1113 LAGG_UNLOCK(sc);
1115 LAGG_RUNLOCK(sc);
1114}
1115
1116static void
1117lagg_port_state(struct ifnet *ifp, int state)
1118{
1119 struct lagg_port *lp = (struct lagg_port *)ifp->if_lagg;
1120 struct lagg_softc *sc = NULL;
1121
1122 if (lp != NULL)
1123 sc = lp->lp_lagg;
1124 if (sc == NULL)
1125 return;
1126
1116}
1117
1118static void
1119lagg_port_state(struct ifnet *ifp, int state)
1120{
1121 struct lagg_port *lp = (struct lagg_port *)ifp->if_lagg;
1122 struct lagg_softc *sc = NULL;
1123
1124 if (lp != NULL)
1125 sc = lp->lp_lagg;
1126 if (sc == NULL)
1127 return;
1128
1127 LAGG_LOCK(sc);
1129 LAGG_WLOCK(sc);
1128 if (sc->sc_linkstate != NULL)
1129 (*sc->sc_linkstate)(lp);
1130 if (sc->sc_linkstate != NULL)
1131 (*sc->sc_linkstate)(lp);
1130 LAGG_UNLOCK(sc);
1132 LAGG_WUNLOCK(sc);
1131}
1132
1133struct lagg_port *
1134lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp)
1135{
1136 struct lagg_port *lp_next, *rval = NULL;
1137 // int new_link = LINK_STATE_DOWN;
1138
1133}
1134
1135struct lagg_port *
1136lagg_link_active(struct lagg_softc *sc, struct lagg_port *lp)
1137{
1138 struct lagg_port *lp_next, *rval = NULL;
1139 // int new_link = LINK_STATE_DOWN;
1140
1139 LAGG_LOCK_ASSERT(sc);
1141 LAGG_WLOCK_ASSERT(sc);
1140 /*
1141 * Search a port which reports an active link state.
1142 */
1143
1144 if (lp == NULL)
1145 goto search;
1146 if (LAGG_PORTACTIVE(lp)) {
1147 rval = lp;

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

1553{
1554 struct lagg_port *lp;
1555 int error;
1556
1557 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
1558 lacp_port_destroy(lp);
1559
1560 /* unlocking is safe here */
1142 /*
1143 * Search a port which reports an active link state.
1144 */
1145
1146 if (lp == NULL)
1147 goto search;
1148 if (LAGG_PORTACTIVE(lp)) {
1149 rval = lp;

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

1555{
1556 struct lagg_port *lp;
1557 int error;
1558
1559 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
1560 lacp_port_destroy(lp);
1561
1562 /* unlocking is safe here */
1561 LAGG_UNLOCK(sc);
1563 LAGG_WUNLOCK(sc);
1562 error = lacp_detach(sc);
1564 error = lacp_detach(sc);
1563 LAGG_LOCK(sc);
1565 LAGG_WLOCK(sc);
1564
1565 return (error);
1566}
1567
1568static void
1569lagg_lacp_lladdr(struct lagg_softc *sc)
1570{
1571 struct lagg_port *lp;

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

1593}
1594
1595static struct mbuf *
1596lagg_lacp_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m)
1597{
1598 struct ifnet *ifp = sc->sc_ifp;
1599 struct ether_header *eh;
1600 u_short etype;
1566
1567 return (error);
1568}
1569
1570static void
1571lagg_lacp_lladdr(struct lagg_softc *sc)
1572{
1573 struct lagg_port *lp;

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

1595}
1596
1597static struct mbuf *
1598lagg_lacp_input(struct lagg_softc *sc, struct lagg_port *lp, struct mbuf *m)
1599{
1600 struct ifnet *ifp = sc->sc_ifp;
1601 struct ether_header *eh;
1602 u_short etype;
1601 uint8_t subtype;
1602
1603 eh = mtod(m, struct ether_header *);
1604 etype = ntohs(eh->ether_type);
1605
1606 /* Tap off LACP control messages */
1607 if (etype == ETHERTYPE_SLOW) {
1603
1604 eh = mtod(m, struct ether_header *);
1605 etype = ntohs(eh->ether_type);
1606
1607 /* Tap off LACP control messages */
1608 if (etype == ETHERTYPE_SLOW) {
1608 if (m->m_pkthdr.len < sizeof(*eh) + sizeof(subtype)) {
1609 m_freem(m);
1610 return (NULL);
1611 }
1612
1613 m_copydata(m, sizeof(*eh), sizeof(subtype), &subtype);
1614 switch (subtype) {
1615 case SLOWPROTOCOLS_SUBTYPE_LACP:
1616 lacp_input(lp, m);
1617 break;
1618
1619 case SLOWPROTOCOLS_SUBTYPE_MARKER:
1620 lacp_marker_input(lp, m);
1621 break;
1622
1623 default:
1624 /* Unknown LACP packet type */
1625 m_freem(m);
1626 break;
1627 }
1609 lacp_input(lp, m);
1628 return (NULL);
1629 }
1630
1631 /*
1632 * If the port is not collecting or not in the active aggregator then
1633 * free and return.
1634 */
1635 if ((lp->lp_flags & LAGG_PORT_COLLECTING) == 0 ||
1636 lacp_port_isactive(lp) == 0) {
1637 m_freem(m);
1638 return (NULL);
1639 }
1640
1641 m->m_pkthdr.rcvif = ifp;
1642 return (m);
1643}
1610 return (NULL);
1611 }
1612
1613 /*
1614 * If the port is not collecting or not in the active aggregator then
1615 * free and return.
1616 */
1617 if ((lp->lp_flags & LAGG_PORT_COLLECTING) == 0 ||
1618 lacp_port_isactive(lp) == 0) {
1619 m_freem(m);
1620 return (NULL);
1621 }
1622
1623 m->m_pkthdr.rcvif = ifp;
1624 return (m);
1625}