Deleted Added
full compact
if_lagg.c (289400) if_lagg.c (290239)
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 * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org>
6 * Copyright (c) 2014 Marcelo Araujo <araujo@FreeBSD.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any

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

14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#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 * Copyright (c) 2007 Andrew Thompson <thompsa@FreeBSD.org>
6 * Copyright (c) 2014 Marcelo Araujo <araujo@FreeBSD.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any

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

14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/cdefs.h>
22__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 289400 2015-10-16 01:16:01Z hrs $");
22__FBSDID("$FreeBSD: head/sys/net/if_lagg.c 290239 2015-11-01 19:59:04Z melifaro $");
23
24#include "opt_inet.h"
25#include "opt_inet6.h"
26
27#include <sys/param.h>
28#include <sys/kernel.h>
29#include <sys/malloc.h>
30#include <sys/mbuf.h>

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

95static int lagg_clone_create(struct if_clone *, int, caddr_t);
96static void lagg_clone_destroy(struct ifnet *);
97static VNET_DEFINE(struct if_clone *, lagg_cloner);
98#define V_lagg_cloner VNET(lagg_cloner)
99static const char laggname[] = "lagg";
100
101static void lagg_lladdr(struct lagg_softc *, uint8_t *);
102static void lagg_capabilities(struct lagg_softc *);
23
24#include "opt_inet.h"
25#include "opt_inet6.h"
26
27#include <sys/param.h>
28#include <sys/kernel.h>
29#include <sys/malloc.h>
30#include <sys/mbuf.h>

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

95static int lagg_clone_create(struct if_clone *, int, caddr_t);
96static void lagg_clone_destroy(struct ifnet *);
97static VNET_DEFINE(struct if_clone *, lagg_cloner);
98#define V_lagg_cloner VNET(lagg_cloner)
99static const char laggname[] = "lagg";
100
101static void lagg_lladdr(struct lagg_softc *, uint8_t *);
102static void lagg_capabilities(struct lagg_softc *);
103static void lagg_port_lladdr(struct lagg_port *, uint8_t *);
103static void lagg_port_lladdr(struct lagg_port *, uint8_t *, lagg_llqtype);
104static void lagg_port_setlladdr(void *, int);
105static int lagg_port_create(struct lagg_softc *, struct ifnet *);
106static int lagg_port_destroy(struct lagg_port *, int);
107static struct mbuf *lagg_input(struct ifnet *, struct mbuf *);
108static void lagg_linkstate(struct lagg_softc *);
109static void lagg_port_state(struct ifnet *, int);
110static int lagg_port_ioctl(struct ifnet *, u_long, caddr_t);
111static int lagg_port_output(struct ifnet *, struct mbuf *,

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

538 EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
539 EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
540
541 /* Shutdown and remove lagg ports */
542 while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL)
543 lagg_port_destroy(lp, 1);
544 /* Unhook the aggregation protocol */
545 lagg_proto_detach(sc);
104static void lagg_port_setlladdr(void *, int);
105static int lagg_port_create(struct lagg_softc *, struct ifnet *);
106static int lagg_port_destroy(struct lagg_port *, int);
107static struct mbuf *lagg_input(struct ifnet *, struct mbuf *);
108static void lagg_linkstate(struct lagg_softc *);
109static void lagg_port_state(struct ifnet *, int);
110static int lagg_port_ioctl(struct ifnet *, u_long, caddr_t);
111static int lagg_port_output(struct ifnet *, struct mbuf *,

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

538 EVENTHANDLER_DEREGISTER(vlan_config, sc->vlan_attach);
539 EVENTHANDLER_DEREGISTER(vlan_unconfig, sc->vlan_detach);
540
541 /* Shutdown and remove lagg ports */
542 while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL)
543 lagg_port_destroy(lp, 1);
544 /* Unhook the aggregation protocol */
545 lagg_proto_detach(sc);
546 LAGG_UNLOCK_ASSERT(sc);
546
547 ifmedia_removeall(&sc->sc_media);
548 ether_ifdetach(ifp);
549 if_free(ifp);
550
551 LAGG_LIST_LOCK();
552 SLIST_REMOVE(&V_lagg_list, sc, lagg_softc, sc_entries);
553 LAGG_LIST_UNLOCK();
554
555 taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task);
556 LAGG_LOCK_DESTROY(sc);
557 free(sc, M_DEVBUF);
558}
559
547
548 ifmedia_removeall(&sc->sc_media);
549 ether_ifdetach(ifp);
550 if_free(ifp);
551
552 LAGG_LIST_LOCK();
553 SLIST_REMOVE(&V_lagg_list, sc, lagg_softc, sc_entries);
554 LAGG_LIST_UNLOCK();
555
556 taskqueue_drain(taskqueue_swi, &sc->sc_lladdr_task);
557 LAGG_LOCK_DESTROY(sc);
558 free(sc, M_DEVBUF);
559}
560
560static void
561/*
562 * Set link-layer address on the lagg interface itself.
563 *
564 * Set noinline to be dtrace-friendly
565 */
566static __noinline void
561lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr)
562{
563 struct ifnet *ifp = sc->sc_ifp;
564 struct lagg_port lp;
565
566 if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
567 return;
568
569 LAGG_WLOCK_ASSERT(sc);
570 /*
571 * Set the link layer address on the lagg interface.
572 * lagg_proto_lladdr() notifies the MAC change to
573 * the aggregation protocol. iflladdr_event handler which
574 * may trigger gratuitous ARPs for INET will be handled in
575 * a taskqueue.
576 */
577 bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN);
578 lagg_proto_lladdr(sc);
579
567lagg_lladdr(struct lagg_softc *sc, uint8_t *lladdr)
568{
569 struct ifnet *ifp = sc->sc_ifp;
570 struct lagg_port lp;
571
572 if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
573 return;
574
575 LAGG_WLOCK_ASSERT(sc);
576 /*
577 * Set the link layer address on the lagg interface.
578 * lagg_proto_lladdr() notifies the MAC change to
579 * the aggregation protocol. iflladdr_event handler which
580 * may trigger gratuitous ARPs for INET will be handled in
581 * a taskqueue.
582 */
583 bcopy(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN);
584 lagg_proto_lladdr(sc);
585
586 /*
587 * Send notification request for lagg interface
588 * itself. Note that new lladdr is already set.
589 */
580 bzero(&lp, sizeof(lp));
581 lp.lp_ifp = sc->sc_ifp;
582 lp.lp_softc = sc;
583
590 bzero(&lp, sizeof(lp));
591 lp.lp_ifp = sc->sc_ifp;
592 lp.lp_softc = sc;
593
584 lagg_port_lladdr(&lp, lladdr);
594 /* Do not request lladdr change */
595 lagg_port_lladdr(&lp, lladdr, LAGG_LLQTYPE_VIRT);
585}
586
587static void
588lagg_capabilities(struct lagg_softc *sc)
589{
590 struct lagg_port *lp;
591 int cap = ~0, ena = ~0;
592 u_long hwa = ~0UL;

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

617 getmicrotime(&sc->sc_ifp->if_lastchange);
618
619 if (sc->sc_ifflags & IFF_DEBUG)
620 if_printf(sc->sc_ifp,
621 "capabilities 0x%08x enabled 0x%08x\n", cap, ena);
622 }
623}
624
596}
597
598static void
599lagg_capabilities(struct lagg_softc *sc)
600{
601 struct lagg_port *lp;
602 int cap = ~0, ena = ~0;
603 u_long hwa = ~0UL;

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

628 getmicrotime(&sc->sc_ifp->if_lastchange);
629
630 if (sc->sc_ifflags & IFF_DEBUG)
631 if_printf(sc->sc_ifp,
632 "capabilities 0x%08x enabled 0x%08x\n", cap, ena);
633 }
634}
635
625static void
626lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
636/*
637 * Enqueue interface lladdr notification.
638 * If request is already queued, it is updated.
639 * If setting lladdr is also desired, @do_change has to be set to 1.
640 *
641 * Set noinline to be dtrace-friendly
642 */
643static __noinline void
644lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr, lagg_llqtype llq_type)
627{
628 struct lagg_softc *sc = lp->lp_softc;
629 struct ifnet *ifp = lp->lp_ifp;
630 struct lagg_llq *llq;
645{
646 struct lagg_softc *sc = lp->lp_softc;
647 struct ifnet *ifp = lp->lp_ifp;
648 struct lagg_llq *llq;
631 int pending = 0;
632 int primary;
633
634 LAGG_WLOCK_ASSERT(sc);
635
649
650 LAGG_WLOCK_ASSERT(sc);
651
636 primary = (sc->sc_primary->lp_ifp == ifp) ? 1 : 0;
637 if (primary == 0 && (lp->lp_detaching ||
638 memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0))
652 /*
653 * Do not enqueue requests where lladdr is the same for
654 * "physical" interfaces (e.g. ports in lagg)
655 */
656 if (llq_type == LAGG_LLQTYPE_PHYS &&
657 memcmp(IF_LLADDR(ifp), lladdr, ETHER_ADDR_LEN) == 0)
639 return;
640
641 /* Check to make sure its not already queued to be changed */
642 SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
658 return;
659
660 /* Check to make sure its not already queued to be changed */
661 SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
643 if (llq->llq_ifp == ifp && llq->llq_primary == primary) {
644 pending = 1;
645 break;
662 if (llq->llq_ifp == ifp) {
663 /* Update lladdr, it may have changed */
664 bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
665 return;
646 }
647 }
648
666 }
667 }
668
649 if (!pending) {
650 llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT);
651 if (llq == NULL) /* XXX what to do */
652 return;
653 }
669 llq = malloc(sizeof(struct lagg_llq), M_DEVBUF, M_NOWAIT | M_ZERO);
670 if (llq == NULL) /* XXX what to do */
671 return;
654
672
655 /* Update the lladdr even if pending, it may have changed */
656 llq->llq_ifp = ifp;
673 llq->llq_ifp = ifp;
657 llq->llq_primary = primary;
674 llq->llq_type = llq_type;
658 bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
675 bcopy(lladdr, llq->llq_lladdr, ETHER_ADDR_LEN);
676 /* XXX: We should insert to tail */
677 SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries);
659
678
660 if (!pending)
661 SLIST_INSERT_HEAD(&sc->sc_llq_head, llq, llq_entries);
662
663 taskqueue_enqueue(taskqueue_swi, &sc->sc_lladdr_task);
664}
665
666/*
667 * Set the interface MAC address from a taskqueue to avoid a LOR.
679 taskqueue_enqueue(taskqueue_swi, &sc->sc_lladdr_task);
680}
681
682/*
683 * Set the interface MAC address from a taskqueue to avoid a LOR.
684 *
685 * Set noinline to be dtrace-friendly
668 */
686 */
669static void
687static __noinline void
670lagg_port_setlladdr(void *arg, int pending)
671{
672 struct lagg_softc *sc = (struct lagg_softc *)arg;
673 struct lagg_llq *llq, *head;
674 struct ifnet *ifp;
675 int error;
676
677 /* Grab a local reference of the queue and remove it from the softc */

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

683 /*
684 * Traverse the queue and set the lladdr on each ifp. It is safe to do
685 * unlocked as we have the only reference to it.
686 */
687 for (llq = head; llq != NULL; llq = head) {
688 ifp = llq->llq_ifp;
689
690 CURVNET_SET(ifp->if_vnet);
688lagg_port_setlladdr(void *arg, int pending)
689{
690 struct lagg_softc *sc = (struct lagg_softc *)arg;
691 struct lagg_llq *llq, *head;
692 struct ifnet *ifp;
693 int error;
694
695 /* Grab a local reference of the queue and remove it from the softc */

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

701 /*
702 * Traverse the queue and set the lladdr on each ifp. It is safe to do
703 * unlocked as we have the only reference to it.
704 */
705 for (llq = head; llq != NULL; llq = head) {
706 ifp = llq->llq_ifp;
707
708 CURVNET_SET(ifp->if_vnet);
691 if (llq->llq_primary == 0) {
692 /*
693 * Set the link layer address on the laggport interface.
694 * if_setlladdr() triggers gratuitous ARPs for INET.
695 */
709 error = 0;
710
711 /*
712 * Set the link layer address on the laggport interface.
713 * Note that if_setlladdr() or iflladdr_event handler
714 * may result in arp transmission / lltable updates.
715 */
716 if (llq->llq_type == LAGG_LLQTYPE_PHYS)
696 error = if_setlladdr(ifp, llq->llq_lladdr,
697 ETHER_ADDR_LEN);
717 error = if_setlladdr(ifp, llq->llq_lladdr,
718 ETHER_ADDR_LEN);
698 if (error)
699 printf("%s: setlladdr failed on %s\n", __func__,
700 ifp->if_xname);
701 } else
719 if (error)
720 printf("%s: setlladdr failed on %s\n", __func__,
721 ifp->if_xname);
722 else
702 EVENTHANDLER_INVOKE(iflladdr_event, ifp);
703 CURVNET_RESTORE();
704 head = SLIST_NEXT(llq, llq_entries);
705 free(llq, M_DEVBUF);
706 }
707}
708
709static int

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

725 /* Port is already in the current lagg? */
726 lp = (struct lagg_port *)ifp->if_lagg;
727 if (lp->lp_softc == sc)
728 return (EEXIST);
729 return (EBUSY);
730 }
731
732 /* XXX Disallow non-ethernet interfaces (this should be any of 802) */
723 EVENTHANDLER_INVOKE(iflladdr_event, ifp);
724 CURVNET_RESTORE();
725 head = SLIST_NEXT(llq, llq_entries);
726 free(llq, M_DEVBUF);
727 }
728}
729
730static int

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

746 /* Port is already in the current lagg? */
747 lp = (struct lagg_port *)ifp->if_lagg;
748 if (lp->lp_softc == sc)
749 return (EEXIST);
750 return (EBUSY);
751 }
752
753 /* XXX Disallow non-ethernet interfaces (this should be any of 802) */
733 if (ifp->if_type != IFT_ETHER)
754 if (ifp->if_type != IFT_ETHER && ifp->if_type != IFT_L2VLAN)
734 return (EPROTONOSUPPORT);
735
736 /* Allow the first Ethernet member to define the MTU */
737 if (SLIST_EMPTY(&sc->sc_ports))
738 sc->sc_ifp->if_mtu = ifp->if_mtu;
739 else if (sc->sc_ifp->if_mtu != ifp->if_mtu) {
740 if_printf(sc->sc_ifp, "invalid MTU for %s\n",
741 ifp->if_xname);

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

779 lp->lp_ifp = ifp;
780 lp->lp_softc = sc;
781
782 /* Save port link layer address */
783 bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN);
784
785 if (SLIST_EMPTY(&sc->sc_ports)) {
786 sc->sc_primary = lp;
755 return (EPROTONOSUPPORT);
756
757 /* Allow the first Ethernet member to define the MTU */
758 if (SLIST_EMPTY(&sc->sc_ports))
759 sc->sc_ifp->if_mtu = ifp->if_mtu;
760 else if (sc->sc_ifp->if_mtu != ifp->if_mtu) {
761 if_printf(sc->sc_ifp, "invalid MTU for %s\n",
762 ifp->if_xname);

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

800 lp->lp_ifp = ifp;
801 lp->lp_softc = sc;
802
803 /* Save port link layer address */
804 bcopy(IF_LLADDR(ifp), lp->lp_lladdr, ETHER_ADDR_LEN);
805
806 if (SLIST_EMPTY(&sc->sc_ports)) {
807 sc->sc_primary = lp;
808 /* First port in lagg. Update/notify lagg lladdress */
787 lagg_lladdr(sc, IF_LLADDR(ifp));
788 } else {
809 lagg_lladdr(sc, IF_LLADDR(ifp));
810 } else {
789 /* Update link layer address for this port */
790 lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp));
811
812 /*
813 * Update link layer address for this port and
814 * send notifications to other subsystems.
815 */
816 lagg_port_lladdr(lp, IF_LLADDR(sc->sc_ifp), LAGG_LLQTYPE_PHYS);
791 }
792
793 /*
794 * Insert into the list of ports.
795 * Keep ports sorted by if_index. It is handy, when configuration
796 * is predictable and `ifconfig laggN create ...` command
797 * will lead to the same result each time.
798 */

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

868
869 /*
870 * Remove multicast addresses and interface flags from this port and
871 * reset the MAC address, skip if the interface is being detached.
872 */
873 if (!lp->lp_detaching) {
874 lagg_ether_cmdmulti(lp, 0);
875 lagg_setflags(lp, 0);
817 }
818
819 /*
820 * Insert into the list of ports.
821 * Keep ports sorted by if_index. It is handy, when configuration
822 * is predictable and `ifconfig laggN create ...` command
823 * will lead to the same result each time.
824 */

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

894
895 /*
896 * Remove multicast addresses and interface flags from this port and
897 * reset the MAC address, skip if the interface is being detached.
898 */
899 if (!lp->lp_detaching) {
900 lagg_ether_cmdmulti(lp, 0);
901 lagg_setflags(lp, 0);
876 lagg_port_lladdr(lp, lp->lp_lladdr);
902 lagg_port_lladdr(lp, lp->lp_lladdr, LAGG_LLQTYPE_PHYS);
877 }
878
879 /* Restore interface */
880 ifp->if_type = lp->lp_iftype;
881 ifp->if_ioctl = lp->lp_ioctl;
882 ifp->if_output = lp->lp_output;
883 ifp->if_lagg = NULL;
884

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

900 if ((lp0 = SLIST_FIRST(&sc->sc_ports)) == NULL) {
901 bzero(&lladdr, ETHER_ADDR_LEN);
902 } else {
903 bcopy(lp0->lp_lladdr,
904 lladdr, ETHER_ADDR_LEN);
905 }
906 lagg_lladdr(sc, lladdr);
907
903 }
904
905 /* Restore interface */
906 ifp->if_type = lp->lp_iftype;
907 ifp->if_ioctl = lp->lp_ioctl;
908 ifp->if_output = lp->lp_output;
909 ifp->if_lagg = NULL;
910

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

926 if ((lp0 = SLIST_FIRST(&sc->sc_ports)) == NULL) {
927 bzero(&lladdr, ETHER_ADDR_LEN);
928 } else {
929 bcopy(lp0->lp_lladdr,
930 lladdr, ETHER_ADDR_LEN);
931 }
932 lagg_lladdr(sc, lladdr);
933
934 /* Mark lp0 as new primary */
935 sc->sc_primary = lp0;
936
908 /*
937 /*
909 * Update link layer address for each port. No port is
910 * marked as primary at this moment.
938 * Enqueue lladdr update/notification for each port
939 * (new primary needs update as well, to switch from
940 * old lladdr to its 'real' one).
911 */
912 SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries)
941 */
942 SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries)
913 lagg_port_lladdr(lp_ptr, lladdr);
914 /*
915 * Mark lp0 as the new primary. This invokes an
916 * iflladdr_event.
917 */
918 sc->sc_primary = lp0;
919 if (lp0 != NULL)
920 lagg_port_lladdr(lp0, lladdr);
943 lagg_port_lladdr(lp_ptr, lladdr, LAGG_LLQTYPE_PHYS);
921 }
922
923 /* Remove any pending lladdr changes from the queue */
924 if (lp->lp_detaching) {
925 SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
926 if (llq->llq_ifp == ifp) {
927 SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq,
928 llq_entries);

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

1144 }
1145
1146}
1147
1148static void
1149lagg_init(void *xsc)
1150{
1151 struct lagg_softc *sc = (struct lagg_softc *)xsc;
944 }
945
946 /* Remove any pending lladdr changes from the queue */
947 if (lp->lp_detaching) {
948 SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) {
949 if (llq->llq_ifp == ifp) {
950 SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq,
951 llq_entries);

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

1167 }
1168
1169}
1170
1171static void
1172lagg_init(void *xsc)
1173{
1174 struct lagg_softc *sc = (struct lagg_softc *)xsc;
1152 struct lagg_port *lp;
1153 struct ifnet *ifp = sc->sc_ifp;
1175 struct ifnet *ifp = sc->sc_ifp;
1176 struct lagg_port *lp;
1154
1155 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1156 return;
1157
1158 LAGG_WLOCK(sc);
1159
1160 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1177
1178 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1179 return;
1180
1181 LAGG_WLOCK(sc);
1182
1183 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1161 /* Update the port lladdrs */
1184
1185 /*
1186 * Update the port lladdrs if needed.
1187 * This might be if_setlladdr() notification
1188 * that lladdr has been changed.
1189 */
1162 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
1190 SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
1163 lagg_port_lladdr(lp, IF_LLADDR(ifp));
1191 lagg_port_lladdr(lp, IF_LLADDR(ifp), LAGG_LLQTYPE_PHYS);
1164
1165 lagg_proto_init(sc);
1166
1167 LAGG_WUNLOCK(sc);
1168}
1169
1170static void
1171lagg_stop(struct lagg_softc *sc)

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

1239 break;
1240 if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) {
1241 error = EPROTONOSUPPORT;
1242 break;
1243 }
1244
1245 LAGG_WLOCK(sc);
1246 lagg_proto_detach(sc);
1192
1193 lagg_proto_init(sc);
1194
1195 LAGG_WUNLOCK(sc);
1196}
1197
1198static void
1199lagg_stop(struct lagg_softc *sc)

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

1267 break;
1268 if (ra->ra_proto < 1 || ra->ra_proto >= LAGG_PROTO_MAX) {
1269 error = EPROTONOSUPPORT;
1270 break;
1271 }
1272
1273 LAGG_WLOCK(sc);
1274 lagg_proto_detach(sc);
1275 LAGG_UNLOCK_ASSERT(sc);
1247 lagg_proto_attach(sc, ra->ra_proto);
1248 break;
1249 case SIOCGLAGGOPTS:
1250 ro->ro_opts = sc->sc_opts;
1251 if (sc->sc_proto == LAGG_PROTO_LACP) {
1252 struct lacp_softc *lsc;
1253
1254 lsc = (struct lacp_softc *)sc->sc_psc;

--- 941 unchanged lines hidden ---
1276 lagg_proto_attach(sc, ra->ra_proto);
1277 break;
1278 case SIOCGLAGGOPTS:
1279 ro->ro_opts = sc->sc_opts;
1280 if (sc->sc_proto == LAGG_PROTO_LACP) {
1281 struct lacp_softc *lsc;
1282
1283 lsc = (struct lacp_softc *)sc->sc_psc;

--- 941 unchanged lines hidden ---