]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/if_bond.c
xnu-6153.61.1.tar.gz
[apple/xnu.git] / bsd / net / if_bond.c
index bdf0b42cd2ad229cb312fa68a75c9a53052084d3..75492392758d15c94629753b60b5629190721155 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2004-2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 /*
- * if_bond.c 
+ * if_bond.c
  * - bond/failover interface
  * - implements IEEE 802.3ad Link Aggregation
  */
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 #include <sys/kern_event.h>
-
 #include <net/bpf.h>
 #include <net/ethernet.h>
 #include <net/if.h>
 #include <net/kpi_interface.h>
+#include <net/kpi_interfacefilter.h>
 #include <net/if_arp.h>
 #include <net/if_dl.h>
 #include <net/if_ether.h>
 #include <net/devtimer.h>
 #include <net/if_vlan_var.h>
 #include <net/kpi_protocol.h>
-
+#include <sys/protosw.h>
 #include <kern/locks.h>
-#include <libkern/OSAtomic.h>
+#include <kern/zalloc.h>
+#include <os/refcnt.h>
 
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 #include <net/if_media.h>
 #include <net/multicast_list.h>
 
-extern void dlil_input_packet_list(struct ifnet *, struct mbuf *);
+SYSCTL_DECL(_net_link);
+SYSCTL_NODE(_net_link, OID_AUTO, bond, CTLFLAG_RW | CTLFLAG_LOCKED, 0,
+    "Bond interface");
+
+static int if_bond_debug = 0;
+SYSCTL_INT(_net_link_bond, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_LOCKED,
+    &if_bond_debug, 0, "Bond interface debug logs");
 
 static struct ether_addr slow_proto_multicast = {
-    IEEE8023AD_SLOW_PROTO_MULTICAST
+       .octet = IEEE8023AD_SLOW_PROTO_MULTICAST
 };
 
-#define        BOND_MAXUNIT            128
-#define BONDNAME               "bond"
-#define M_BOND                 M_DEVBUF
+typedef struct ifbond_s ifbond, * ifbond_ref;
+typedef struct bondport_s bondport, * bondport_ref;
+
+#define BOND_MAXUNIT            128
+#define BOND_ZONE_MAX_ELEM      MIN(IFNETS_MAX, BOND_MAXUNIT)
+#define BONDNAME                "bond"
 
-#define EA_FORMAT      "%x:%x:%x:%x:%x:%x"
-#define EA_CH(e, i)    ((u_char)((u_char *)(e))[(i)])
-#define EA_LIST(ea)    EA_CH(ea,0),EA_CH(ea,1),EA_CH(ea,2),EA_CH(ea,3),EA_CH(ea,4),EA_CH(ea,5)
+#define M_BOND                  M_DEVBUF
 
-#define timestamp_printf       printf
+#define EA_FORMAT       "%x:%x:%x:%x:%x:%x"
+#define EA_CH(e, i)     ((u_char)((u_char *)(e))[(i)])
+#define EA_LIST(ea)     EA_CH(ea,0),EA_CH(ea,1),EA_CH(ea,2),EA_CH(ea,3),EA_CH(ea,4),EA_CH(ea,5)
+
+#define timestamp_printf        printf
 
 /**
- ** bond locks
- **/
+** bond locks
+**/
 static __inline__ lck_grp_t *
 my_lck_grp_alloc_init(const char * grp_name)
 {
-    lck_grp_t *                grp;
-    lck_grp_attr_t *   grp_attrs;
-    
-    grp_attrs = lck_grp_attr_alloc_init();
-    grp = lck_grp_alloc_init(grp_name, grp_attrs);
-    lck_grp_attr_free(grp_attrs);
-    return (grp);
+       lck_grp_t *         grp;
+       lck_grp_attr_t *    grp_attrs;
+
+       grp_attrs = lck_grp_attr_alloc_init();
+       grp = lck_grp_alloc_init(grp_name, grp_attrs);
+       lck_grp_attr_free(grp_attrs);
+       return grp;
 }
 
 static __inline__ lck_mtx_t *
 my_lck_mtx_alloc_init(lck_grp_t * lck_grp)
 {
-    lck_attr_t *       lck_attrs;
-    lck_mtx_t *                lck_mtx;
+       lck_attr_t *        lck_attrs;
+       lck_mtx_t *         lck_mtx;
 
-    lck_attrs = lck_attr_alloc_init();
-    lck_mtx = lck_mtx_alloc_init(lck_grp, lck_attrs);
-    lck_attr_free(lck_attrs);
-    return (lck_mtx);
+       lck_attrs = lck_attr_alloc_init();
+       lck_mtx = lck_mtx_alloc_init(lck_grp, lck_attrs);
+       lck_attr_free(lck_attrs);
+       return lck_mtx;
 }
 
-static lck_mtx_t *     bond_lck_mtx;
+static lck_mtx_t *      bond_lck_mtx;
 
 static __inline__ void
 bond_lock_init(void)
 {
-    lck_grp_t *                bond_lck_grp;
+       lck_grp_t *         bond_lck_grp;
 
-    bond_lck_grp = my_lck_grp_alloc_init("if_bond");
-    bond_lck_mtx = my_lck_mtx_alloc_init(bond_lck_grp);
+       bond_lck_grp = my_lck_grp_alloc_init("if_bond");
+       bond_lck_mtx = my_lck_mtx_alloc_init(bond_lck_grp);
 }
 
 static __inline__ void
 bond_assert_lock_held(void)
 {
-    lck_mtx_assert(bond_lck_mtx, LCK_MTX_ASSERT_OWNED);
-    return;
+       LCK_MTX_ASSERT(bond_lck_mtx, LCK_MTX_ASSERT_OWNED);
+       return;
 }
 
 static __inline__ void
 bond_assert_lock_not_held(void)
 {
-    lck_mtx_assert(bond_lck_mtx, LCK_MTX_ASSERT_NOTOWNED);
-    return;
+       LCK_MTX_ASSERT(bond_lck_mtx, LCK_MTX_ASSERT_NOTOWNED);
+       return;
 }
 
 static __inline__ void
 bond_lock(void)
 {
-    lck_mtx_lock(bond_lck_mtx);
-    return;
+       lck_mtx_lock(bond_lck_mtx);
+       return;
 }
 
 static __inline__ void
 bond_unlock(void)
 {
-    lck_mtx_unlock(bond_lck_mtx);
-    return;
+       lck_mtx_unlock(bond_lck_mtx);
+       return;
 }
 
 /**
- ** bond structures, types
- **/
+** bond structures, types
+**/
 
 struct LAG_info_s {
-    lacp_system                        li_system;
-    lacp_system_priority       li_system_priority;
-    lacp_key                   li_key;
+       lacp_system                 li_system;
+       lacp_system_priority        li_system_priority;
+       lacp_key                    li_key;
 };
 typedef struct LAG_info_s LAG_info, * LAG_info_ref;
 
@@ -183,398 +195,377 @@ typedef struct ifbond_s ifbond, * ifbond_ref;
 typedef struct bondport_s bondport, * bondport_ref;
 
 struct LAG_s {
-    TAILQ_ENTRY(LAG_s)         lag_list;
-    struct port_list           lag_port_list;
-    short                      lag_port_count;
-    short                      lag_selected_port_count;
-    int                                lag_active_media;
-    LAG_info                   lag_info;
+       TAILQ_ENTRY(LAG_s)          lag_list;
+       struct port_list            lag_port_list;
+       short                       lag_port_count;
+       short                       lag_selected_port_count;
+       int                         lag_active_media;
+       LAG_info                    lag_info;
 };
 typedef struct LAG_s LAG, * LAG_ref;
 
 typedef struct partner_state_s {
-    LAG_info                   ps_lag_info;
-    lacp_port                  ps_port;
-    lacp_port_priority         ps_port_priority;
-    lacp_actor_partner_state   ps_state;
+       LAG_info                    ps_lag_info;
+       lacp_port                   ps_port;
+       lacp_port_priority          ps_port_priority;
+       lacp_actor_partner_state    ps_state;
 } partner_state, * partner_state_ref;
 
 struct ifbond_s {
-    TAILQ_ENTRY(ifbond_s)      ifb_bond_list;
-    int                                ifb_flags;
-    SInt32                     ifb_retain_count;
-    char                       ifb_name[IFNAMSIZ];
-    struct ifnet *             ifb_ifp;
-    bpf_packet_func            ifb_bpf_input;
-    bpf_packet_func            ifb_bpf_output;
-    int                                ifb_altmtu;
-    struct port_list           ifb_port_list;
-    short                      ifb_port_count;
-    struct lag_list            ifb_lag_list;
-    lacp_key                   ifb_key;
-    short                      ifb_max_active; /* 0 == unlimited */
-    LAG_ref                    ifb_active_lag;
-    struct ifmultiaddr *       ifb_ifma_slow_proto;
-    bondport_ref *             ifb_distributing_array;
-    int                                ifb_distributing_count;
-    int                                ifb_last_link_event;
-    int                                ifb_mode; /* LACP, STATIC */
+       TAILQ_ENTRY(ifbond_s)       ifb_bond_list;
+       int                         ifb_flags;
+       struct os_refcnt            ifb_retain_count;
+       char                        ifb_name[IFNAMSIZ];
+       struct ifnet *              ifb_ifp;
+       bpf_packet_func             ifb_bpf_input;
+       bpf_packet_func             ifb_bpf_output;
+       int                         ifb_altmtu;
+       struct port_list            ifb_port_list;
+       short                       ifb_port_count;
+       struct lag_list             ifb_lag_list;
+       lacp_key                    ifb_key;
+       short                       ifb_max_active;/* 0 == unlimited */
+       LAG_ref                     ifb_active_lag;
+       struct ifmultiaddr *        ifb_ifma_slow_proto;
+       bondport_ref *              ifb_distributing_array;
+       int                         ifb_distributing_count;
+       int                         ifb_last_link_event;
+       int                         ifb_mode;/* LACP, STATIC */
 };
 
 struct media_info {
-    int                mi_active;
-    int                mi_status;
+       int         mi_active;
+       int         mi_status;
 };
 
 enum {
-    ReceiveState_none = 0,
-    ReceiveState_INITIALIZE = 1,
-    ReceiveState_PORT_DISABLED = 2,
-    ReceiveState_EXPIRED = 3,
-    ReceiveState_LACP_DISABLED = 4,
-    ReceiveState_DEFAULTED = 5,
-    ReceiveState_CURRENT = 6,
+       ReceiveState_none = 0,
+       ReceiveState_INITIALIZE = 1,
+       ReceiveState_PORT_DISABLED = 2,
+       ReceiveState_EXPIRED = 3,
+       ReceiveState_LACP_DISABLED = 4,
+       ReceiveState_DEFAULTED = 5,
+       ReceiveState_CURRENT = 6,
 };
 
 typedef u_char ReceiveState;
 
 enum {
-    SelectedState_UNSELECTED = IF_BOND_STATUS_SELECTED_STATE_UNSELECTED,
-    SelectedState_SELECTED = IF_BOND_STATUS_SELECTED_STATE_SELECTED,
-    SelectedState_STANDBY = IF_BOND_STATUS_SELECTED_STATE_STANDBY
+       SelectedState_UNSELECTED = IF_BOND_STATUS_SELECTED_STATE_UNSELECTED,
+       SelectedState_SELECTED = IF_BOND_STATUS_SELECTED_STATE_SELECTED,
+       SelectedState_STANDBY = IF_BOND_STATUS_SELECTED_STATE_STANDBY
 };
 typedef u_char SelectedState;
 
 static __inline__ const char *
 SelectedStateString(SelectedState s)
 {
-    static const char * names[] = { "UNSELECTED", "SELECTED", "STANDBY" };
+       static const char * names[] = { "UNSELECTED", "SELECTED", "STANDBY" };
 
-    if (s <= SelectedState_STANDBY) {
-       return (names[s]);
-    }
-    return ("<unknown>");
+       if (s <= SelectedState_STANDBY) {
+               return names[s];
+       }
+       return "<unknown>";
 }
 
 enum {
-    MuxState_none = 0,
-    MuxState_DETACHED = 1,
-    MuxState_WAITING = 2,
-    MuxState_ATTACHED = 3,
-    MuxState_COLLECTING_DISTRIBUTING = 4,
+       MuxState_none = 0,
+       MuxState_DETACHED = 1,
+       MuxState_WAITING = 2,
+       MuxState_ATTACHED = 3,
+       MuxState_COLLECTING_DISTRIBUTING = 4,
 };
 
 typedef u_char MuxState;
 
+#define PORT_CONTROL_FLAGS_IN_LIST               0x01
+#define PORT_CONTROL_FLAGS_PROTO_ATTACHED        0x02
+#define PORT_CONTROL_FLAGS_FILTER_ATTACHED       0x04
+#define PORT_CONTROL_FLAGS_LLADDR_SET            0x08
+#define PORT_CONTROL_FLAGS_MTU_SET               0x10
+#define PORT_CONTROL_FLAGS_PROMISCUOUS_SET       0x20
+
 struct bondport_s {
-    TAILQ_ENTRY(bondport_s)    po_port_list;
-    ifbond_ref                 po_bond;
-    struct multicast_list      po_multicast;
-    struct ifnet *             po_ifp;
-    struct ether_addr          po_saved_addr;
-    int                                po_enabled;
-    char                       po_name[IFNAMSIZ];
-    struct ifdevmtu            po_devmtu;
-
-    /* LACP */
-    TAILQ_ENTRY(bondport_s)    po_lag_port_list;
-    devtimer_ref               po_current_while_timer;
-    devtimer_ref               po_periodic_timer;
-    devtimer_ref               po_wait_while_timer;
-    devtimer_ref               po_transmit_timer;
-    partner_state              po_partner_state;
-    lacp_port_priority         po_priority;
-    lacp_actor_partner_state   po_actor_state;
-    u_char                     po_flags;
-    u_char                     po_periodic_interval;
-    u_char                     po_n_transmit;
-    ReceiveState               po_receive_state;
-    MuxState                   po_mux_state;
-    SelectedState              po_selected;
-    int32_t                    po_last_transmit_secs;
-    struct media_info          po_media_info;
-    LAG_ref                    po_lag;
+       TAILQ_ENTRY(bondport_s)     po_port_list;
+       ifbond_ref                  po_bond;
+       struct multicast_list       po_multicast;
+       struct ifnet *              po_ifp;
+       struct ether_addr           po_saved_addr;
+       int                         po_enabled;
+       char                        po_name[IFNAMSIZ];
+       struct ifdevmtu             po_devmtu;
+       uint32_t                    po_control_flags;
+       interface_filter_t          po_filter;
+
+       /* LACP */
+       TAILQ_ENTRY(bondport_s)     po_lag_port_list;
+       devtimer_ref                po_current_while_timer;
+       devtimer_ref                po_periodic_timer;
+       devtimer_ref                po_wait_while_timer;
+       devtimer_ref                po_transmit_timer;
+       partner_state               po_partner_state;
+       lacp_port_priority          po_priority;
+       lacp_actor_partner_state    po_actor_state;
+       u_char                      po_flags;
+       u_char                      po_periodic_interval;
+       u_char                      po_n_transmit;
+       ReceiveState                po_receive_state;
+       MuxState                    po_mux_state;
+       SelectedState               po_selected;
+       int32_t                     po_last_transmit_secs;
+       struct media_info           po_media_info;
+       uint64_t                    po_force_link_event_time;
+       LAG_ref                     po_lag;
 };
 
-#define        IFBF_PROMISC            0x1     /* promiscuous mode */
-#define IFBF_IF_DETACHING      0x2     /* interface is detaching */
-#define IFBF_LLADDR            0x4     /* specific link address requested */
-#define IFBF_CHANGE_IN_PROGRESS        0x8     /* interface add/remove in progress */
-
-static int bond_get_status(ifbond_ref ifb, struct if_bond_req * ibr_p, 
-                          user_addr_t datap);
-
-static __inline__ int
-ifbond_flags_promisc(ifbond_ref ifb)
-{
-    return ((ifb->ifb_flags & IFBF_PROMISC) != 0);
-}
-
-static __inline__ void
-ifbond_flags_set_promisc(ifbond_ref ifb)
-{
-    ifb->ifb_flags |= IFBF_PROMISC;
-    return;
-}
+#define IFBF_PROMISC            0x1     /* promiscuous mode */
+#define IFBF_IF_DETACHING       0x2     /* interface is detaching */
+#define IFBF_LLADDR             0x4     /* specific link address requested */
+#define IFBF_CHANGE_IN_PROGRESS 0x8     /* interface add/remove in progress */
 
-static __inline__ void
-ifbond_flags_clear_promisc(ifbond_ref ifb)
-{
-    ifb->ifb_flags &= ~IFBF_PROMISC;
-    return;
-}
+static int bond_get_status(ifbond_ref ifb, struct if_bond_req * ibr_p,
+    user_addr_t datap);
 
 static __inline__ int
 ifbond_flags_if_detaching(ifbond_ref ifb)
 {
-    return ((ifb->ifb_flags & IFBF_IF_DETACHING) != 0);
+       return (ifb->ifb_flags & IFBF_IF_DETACHING) != 0;
 }
 
 static __inline__ void
 ifbond_flags_set_if_detaching(ifbond_ref ifb)
 {
-    ifb->ifb_flags |= IFBF_IF_DETACHING;
-    return;
+       ifb->ifb_flags |= IFBF_IF_DETACHING;
+       return;
 }
 
 static __inline__ int
 ifbond_flags_lladdr(ifbond_ref ifb)
 {
-    return ((ifb->ifb_flags & IFBF_LLADDR) != 0);
-}
-
-static __inline__ void
-ifbond_flags_set_lladdr(ifbond_ref ifb)
-{
-    ifb->ifb_flags |= IFBF_LLADDR;
-    return;
-}
-
-static __inline__ void
-ifbond_flags_clear_lladdr(ifbond_ref ifb)
-{
-    ifb->ifb_flags &= ~IFBF_LLADDR;
-    return;
+       return (ifb->ifb_flags & IFBF_LLADDR) != 0;
 }
 
 static __inline__ int
 ifbond_flags_change_in_progress(ifbond_ref ifb)
 {
-    return ((ifb->ifb_flags & IFBF_CHANGE_IN_PROGRESS) != 0);
+       return (ifb->ifb_flags & IFBF_CHANGE_IN_PROGRESS) != 0;
 }
 
 static __inline__ void
 ifbond_flags_set_change_in_progress(ifbond_ref ifb)
 {
-    ifb->ifb_flags |= IFBF_CHANGE_IN_PROGRESS;
-    return;
+       ifb->ifb_flags |= IFBF_CHANGE_IN_PROGRESS;
+       return;
 }
 
 static __inline__ void
 ifbond_flags_clear_change_in_progress(ifbond_ref ifb)
 {
-    ifb->ifb_flags &= ~IFBF_CHANGE_IN_PROGRESS;
-    return;
+       ifb->ifb_flags &= ~IFBF_CHANGE_IN_PROGRESS;
+       return;
 }
 
 /*
  * bondport_ref->po_flags bits
  */
-#define BONDPORT_FLAGS_NTT             0x01
-#define BONDPORT_FLAGS_READY           0x02
-#define BONDPORT_FLAGS_SELECTED_CHANGED        0x04
-#define BONDPORT_FLAGS_MUX_ATTACHED    0x08
-#define BONDPORT_FLAGS_DISTRIBUTING    0x10
-#define BONDPORT_FLAGS_UNUSED2         0x20
-#define BONDPORT_FLAGS_UNUSED3         0x40
-#define BONDPORT_FLAGS_UNUSED4         0x80
+#define BONDPORT_FLAGS_NTT              0x01
+#define BONDPORT_FLAGS_READY            0x02
+#define BONDPORT_FLAGS_SELECTED_CHANGED 0x04
+#define BONDPORT_FLAGS_MUX_ATTACHED     0x08
+#define BONDPORT_FLAGS_DISTRIBUTING     0x10
+#define BONDPORT_FLAGS_UNUSED2          0x20
+#define BONDPORT_FLAGS_UNUSED3          0x40
+#define BONDPORT_FLAGS_UNUSED4          0x80
 
 static __inline__ void
 bondport_flags_set_ntt(bondport_ref p)
 {
-    p->po_flags |= BONDPORT_FLAGS_NTT;
-    return;
+       p->po_flags |= BONDPORT_FLAGS_NTT;
+       return;
 }
 
 static __inline__ void
 bondport_flags_clear_ntt(bondport_ref p)
 {
-    p->po_flags &= ~BONDPORT_FLAGS_NTT;
-    return;
+       p->po_flags &= ~BONDPORT_FLAGS_NTT;
+       return;
 }
 
 static __inline__ int
 bondport_flags_ntt(bondport_ref p)
 {
-    return ((p->po_flags & BONDPORT_FLAGS_NTT) != 0);
+       return (p->po_flags & BONDPORT_FLAGS_NTT) != 0;
 }
 
 static __inline__ void
 bondport_flags_set_ready(bondport_ref p)
 {
-    p->po_flags |= BONDPORT_FLAGS_READY;
-    return;
+       p->po_flags |= BONDPORT_FLAGS_READY;
+       return;
 }
 
 static __inline__ void
 bondport_flags_clear_ready(bondport_ref p)
 {
-    p->po_flags &= ~BONDPORT_FLAGS_READY;
-    return;
+       p->po_flags &= ~BONDPORT_FLAGS_READY;
+       return;
 }
 
 static __inline__ int
 bondport_flags_ready(bondport_ref p)
 {
-    return ((p->po_flags & BONDPORT_FLAGS_READY) != 0);
+       return (p->po_flags & BONDPORT_FLAGS_READY) != 0;
 }
 
 static __inline__ void
 bondport_flags_set_selected_changed(bondport_ref p)
 {
-    p->po_flags |= BONDPORT_FLAGS_SELECTED_CHANGED;
-    return;
+       p->po_flags |= BONDPORT_FLAGS_SELECTED_CHANGED;
+       return;
 }
 
 static __inline__ void
 bondport_flags_clear_selected_changed(bondport_ref p)
 {
-    p->po_flags &= ~BONDPORT_FLAGS_SELECTED_CHANGED;
-    return;
+       p->po_flags &= ~BONDPORT_FLAGS_SELECTED_CHANGED;
+       return;
 }
 
 static __inline__ int
 bondport_flags_selected_changed(bondport_ref p)
 {
-    return ((p->po_flags & BONDPORT_FLAGS_SELECTED_CHANGED) != 0);
+       return (p->po_flags & BONDPORT_FLAGS_SELECTED_CHANGED) != 0;
 }
 
 static __inline__ void
 bondport_flags_set_mux_attached(bondport_ref p)
 {
-    p->po_flags |= BONDPORT_FLAGS_MUX_ATTACHED;
-    return;
+       p->po_flags |= BONDPORT_FLAGS_MUX_ATTACHED;
+       return;
 }
 
 static __inline__ void
 bondport_flags_clear_mux_attached(bondport_ref p)
 {
-    p->po_flags &= ~BONDPORT_FLAGS_MUX_ATTACHED;
-    return;
+       p->po_flags &= ~BONDPORT_FLAGS_MUX_ATTACHED;
+       return;
 }
 
 static __inline__ int
 bondport_flags_mux_attached(bondport_ref p)
 {
-    return ((p->po_flags & BONDPORT_FLAGS_MUX_ATTACHED) != 0);
+       return (p->po_flags & BONDPORT_FLAGS_MUX_ATTACHED) != 0;
 }
 
 static __inline__ void
 bondport_flags_set_distributing(bondport_ref p)
 {
-    p->po_flags |= BONDPORT_FLAGS_DISTRIBUTING;
-    return;
+       p->po_flags |= BONDPORT_FLAGS_DISTRIBUTING;
+       return;
 }
 
 static __inline__ void
 bondport_flags_clear_distributing(bondport_ref p)
 {
-    p->po_flags &= ~BONDPORT_FLAGS_DISTRIBUTING;
-    return;
+       p->po_flags &= ~BONDPORT_FLAGS_DISTRIBUTING;
+       return;
 }
 
 static __inline__ int
 bondport_flags_distributing(bondport_ref p)
 {
-    return ((p->po_flags & BONDPORT_FLAGS_DISTRIBUTING) != 0);
+       return (p->po_flags & BONDPORT_FLAGS_DISTRIBUTING) != 0;
 }
 
 typedef struct bond_globals_s {
-    struct ifbond_list         ifbond_list;
-    lacp_system                        system;
-    lacp_system_priority       system_priority;
-    int                                verbose;
+       struct ifbond_list          ifbond_list;
+       lacp_system                 system;
+       lacp_system_priority        system_priority;
 } * bond_globals_ref;
 
-static bond_globals_ref        g_bond;
+static bond_globals_ref g_bond;
 
 /**
- ** packet_buffer routines
- ** - thin wrapper for mbuf
- **/
+** packet_buffer routines
+** - thin wrapper for mbuf
+**/
 
 typedef struct mbuf * packet_buffer_ref;
 
 static packet_buffer_ref
 packet_buffer_allocate(int length)
 {
-    packet_buffer_ref  m;
-    int                        size;
-
-    /* leave room for ethernet header */
-    size = length + sizeof(struct ether_header);
-    if (size > (int)MHLEN) {
-       /* XXX doesn't handle large payloads */
-       printf("bond: packet_buffer_allocate size %d > max %u\n", size, MHLEN);
-       return (NULL);
-    }
-    m = m_gethdr(M_WAITOK, MT_DATA);
-    if (m == NULL) {
-       return (NULL);
-    }
-    m->m_len = size;
-    m->m_pkthdr.len = size;
-    return (m);
+       packet_buffer_ref   m;
+       int                 size;
+
+       /* leave room for ethernet header */
+       size = length + sizeof(struct ether_header);
+       if (size > (int)MHLEN) {
+               if (size > (int)MCLBYTES) {
+                       printf("bond: packet_buffer_allocate size %d > max %u\n",
+                           size, MCLBYTES);
+                       return NULL;
+               }
+               m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
+       } else {
+               m = m_gethdr(M_WAITOK, MT_DATA);
+       }
+       if (m == NULL) {
+               return NULL;
+       }
+       m->m_len = size;
+       m->m_pkthdr.len = size;
+       return m;
 }
 
 static void *
 packet_buffer_byteptr(packet_buffer_ref buf)
 {
-    return (buf->m_data + sizeof(struct ether_header));
+       return buf->m_data + sizeof(struct ether_header);
 }
 
 typedef enum {
-    LAEventStart,
-    LAEventTimeout,
-    LAEventPacket,
-    LAEventMediaChange,
-    LAEventSelectedChange,
-    LAEventPortMoved,
-    LAEventReady
+       LAEventStart,
+       LAEventTimeout,
+       LAEventPacket,
+       LAEventMediaChange,
+       LAEventSelectedChange,
+       LAEventPortMoved,
+       LAEventReady
 } LAEvent;
 
 /**
- ** Receive machine
- **/
+** Receive machine
+**/
 static void
 bondport_receive_machine(bondport_ref p, LAEvent event,
-                        void * event_data);
+    void * event_data);
 /**
- ** Periodic Transmission machine
- **/
+** Periodic Transmission machine
+**/
 static void
 bondport_periodic_transmit_machine(bondport_ref p, LAEvent event,
-                                  void * event_data);
+    void * event_data);
 
 /**
- ** Transmit machine
- **/
-#define TRANSMIT_MACHINE_TX_IMMEDIATE  ((void *)1)
+** Transmit machine
+**/
+#define TRANSMIT_MACHINE_TX_IMMEDIATE   ((void *)1)
 
 static void
 bondport_transmit_machine(bondport_ref p, LAEvent event,
-                         void * event_data);
+    void * event_data);
 
 /**
- ** Mux machine
- **/
+** Mux machine
+**/
 static void
 bondport_mux_machine(bondport_ref p, LAEvent event,
-                    void * event_data);
+    void * event_data);
 
 /**
- ** bond, LAG
- **/
+** bond, LAG
+**/
 static void
 ifbond_activate_LAG(ifbond_ref bond, LAG_ref lag, int active_media);
 
@@ -593,10 +584,12 @@ LAG_get_aggregatable_port_count(LAG_ref lag, int * active_media);
 static int
 ifbond_selection(ifbond_ref bond);
 
+static void
+bond_handle_event(struct ifnet * port_ifp, int event_code);
 
 /**
- ** bondport
- **/
+** bondport
+**/
 
 static void
 bondport_receive_lacpdu(bondport_ref p, lacpdu_ref in_lacpdu_p);
@@ -606,7 +599,7 @@ bondport_slow_proto_transmit(bondport_ref p, packet_buffer_ref buf);
 
 static bondport_ref
 bondport_create(struct ifnet * port_ifp, lacp_port_priority priority,
-               int active, int short_timeout, int * error);
+    int active, int short_timeout, int * error);
 static void
 bondport_start(bondport_ref p);
 
@@ -619,7 +612,7 @@ bondport_aggregatable(bondport_ref p);
 static int
 bondport_remove_from_LAG(bondport_ref p);
 
-static void 
+static void
 bondport_set_selected(bondport_ref p, SelectedState s);
 
 static int
@@ -637,117 +630,112 @@ bondport_disable_distributing(bondport_ref p);
 static __inline__ int
 bondport_collecting(bondport_ref p)
 {
-    if (p->po_bond->ifb_mode == IF_BOND_MODE_LACP) {
-       return (lacp_actor_partner_state_collecting(p->po_actor_state));
-    }
-    return (TRUE);
+       if (p->po_bond->ifb_mode == IF_BOND_MODE_LACP) {
+               return lacp_actor_partner_state_collecting(p->po_actor_state);
+       }
+       return TRUE;
 }
 
 /**
- ** bond interface/dlil specific routines
- **/
-static int bond_clone_create(struct if_clone *, int);
-static void bond_clone_destroy(struct ifnet *);
-static int bond_input(ifnet_t ifp, protocol_family_t protocol, mbuf_t m,
-                                         char *frame_header);
+** bond interface/dlil specific routines
+**/
+static int bond_clone_create(struct if_clone *, u_int32_t, void *);
+static int bond_clone_destroy(struct ifnet *);
 static int bond_output(struct ifnet *ifp, struct mbuf *m);
 static int bond_ioctl(struct ifnet *ifp, u_long cmd, void * addr);
 static int bond_set_bpf_tap(struct ifnet * ifp, bpf_tap_mode mode,
-                           bpf_packet_func func);
+    bpf_packet_func func);
 static int bond_attach_protocol(struct ifnet *ifp);
 static int bond_detach_protocol(struct ifnet *ifp);
+static errno_t bond_iff_input(void *cookie, ifnet_t ifp,
+    protocol_family_t protocol, mbuf_t *data, char **frame_ptr);
+static int bond_attach_filter(struct ifnet *ifp, interface_filter_t * filter_p);
 static int bond_setmulti(struct ifnet *ifp);
 static int bond_add_interface(struct ifnet * ifp, struct ifnet * port_ifp);
 static int bond_remove_interface(ifbond_ref ifb, struct ifnet * port_ifp);
 static void bond_if_free(struct ifnet * ifp);
+static void interface_link_event(struct ifnet * ifp, u_int32_t event_code);
 
 static struct if_clone bond_cloner = IF_CLONE_INITIALIZER(BONDNAME,
-                                                         bond_clone_create, 
-                                                         bond_clone_destroy, 
-                                                         0,
-                                                         BOND_MAXUNIT);
-static void interface_link_event(struct ifnet * ifp, u_int32_t event_code);
+    bond_clone_create,
+    bond_clone_destroy,
+    0,
+    BOND_MAXUNIT,
+    BOND_ZONE_MAX_ELEM,
+    sizeof(ifbond));
 
 static int
 siocsifmtu(struct ifnet * ifp, int mtu)
 {
-    struct ifreq       ifr;
+       struct ifreq        ifr;
 
-    bzero(&ifr, sizeof(ifr));
-    ifr.ifr_mtu = mtu;
-    return (ifnet_ioctl(ifp, 0, SIOCSIFMTU, &ifr));
+       bzero(&ifr, sizeof(ifr));
+       ifr.ifr_mtu = mtu;
+       return ifnet_ioctl(ifp, 0, SIOCSIFMTU, &ifr);
 }
 
 static int
 siocgifdevmtu(struct ifnet * ifp, struct ifdevmtu * ifdm_p)
 {
-    struct ifreq       ifr;
-    int                error;
+       struct ifreq        ifr;
+       int                 error;
 
-    bzero(&ifr, sizeof(ifr));
-    error = ifnet_ioctl(ifp, 0, SIOCGIFDEVMTU, &ifr);
-    if (error == 0) {
-       *ifdm_p = ifr.ifr_devmtu;
-    }
-    return (error);
+       bzero(&ifr, sizeof(ifr));
+       error = ifnet_ioctl(ifp, 0, SIOCGIFDEVMTU, &ifr);
+       if (error == 0) {
+               *ifdm_p = ifr.ifr_devmtu;
+       }
+       return error;
 }
 
 static __inline__ void
 ether_addr_copy(void * dest, const void * source)
 {
-    bcopy(source, dest, ETHER_ADDR_LEN);
-    return;
+       bcopy(source, dest, ETHER_ADDR_LEN);
+       return;
 }
 
 static __inline__ void
 ifbond_retain(ifbond_ref ifb)
 {
-    OSIncrementAtomic(&ifb->ifb_retain_count);
+       os_ref_retain(&ifb->ifb_retain_count);
 }
 
 static __inline__ void
 ifbond_release(ifbond_ref ifb)
 {
-    UInt32             old_retain_count;
+       if (os_ref_release(&ifb->ifb_retain_count) != 0) {
+               return;
+       }
 
-    old_retain_count = OSDecrementAtomic(&ifb->ifb_retain_count);
-    switch (old_retain_count) {
-    case 0:
-       panic("ifbond_release: retain count is 0\n");
-       break;
-    case 1:
-       if (g_bond->verbose) {
-           printf("ifbond_release(%s)\n", ifb->ifb_name);
+       if (if_bond_debug) {
+               printf("ifbond_release(%s)\n", ifb->ifb_name);
        }
        if (ifb->ifb_ifma_slow_proto != NULL) {
-           if (g_bond->verbose) {
-               printf("ifbond_release(%s) removing multicast\n",
-                      ifb->ifb_name);
-           }
-           (void)if_delmultiaddr(ifb->ifb_ifma_slow_proto, 0);
-           ifma_release(ifb->ifb_ifma_slow_proto);
+               if (if_bond_debug) {
+                       printf("ifbond_release(%s) removing multicast\n",
+                           ifb->ifb_name);
+               }
+               (void) if_delmulti_anon(ifb->ifb_ifma_slow_proto->ifma_ifp,
+                   ifb->ifb_ifma_slow_proto->ifma_addr);
+               IFMA_REMREF(ifb->ifb_ifma_slow_proto);
        }
        if (ifb->ifb_distributing_array != NULL) {
-           FREE(ifb->ifb_distributing_array, M_BOND);
+               FREE(ifb->ifb_distributing_array, M_BOND);
        }
-       FREE(ifb, M_BOND);
-       break;
-    default:
-       break;
-    }
-    return;
+       if_clone_softc_deallocate(&bond_cloner, ifb);
 }
 
 /*
  * Function: ifbond_wait
  * Purpose:
  *   Allows a single thread to gain exclusive access to the ifbond
- *   data structure.  Some operations take a long time to complete, 
+ *   data structure.  Some operations take a long time to complete,
  *   and some have side-effects that we can't predict.  Holding the
  *   bond_lock() across such operations is not possible.
  *
  *   For example:
- *   1) The SIOCSIFLLADDR ioctl takes a long time (several seconds) to 
+ *   1) The SIOCSIFLLADDR ioctl takes a long time (several seconds) to
  *      complete.  Simply holding the bond_lock() would freeze all other
  *      data structure accesses during that time.
  *   2) When we attach our protocol to the interface, a dlil event is
@@ -761,28 +749,28 @@ ifbond_release(ifbond_ref ifb)
 static void
 ifbond_wait(ifbond_ref ifb, const char * msg)
 {
-    int                waited = 0;
+       int         waited = 0;
 
-    /* other add/remove in progress */
-    while (ifbond_flags_change_in_progress(ifb)) {
-       if (g_bond->verbose) {
-           printf("%s: %s msleep\n", ifb->ifb_name, msg);
+       /* other add/remove in progress */
+       while (ifbond_flags_change_in_progress(ifb)) {
+               if (if_bond_debug) {
+                       printf("%s: %s msleep\n", ifb->ifb_name, msg);
+               }
+               waited = 1;
+               (void)msleep(ifb, bond_lck_mtx, PZERO, msg, 0);
        }
-       waited = 1;
-       (void)msleep(ifb, bond_lck_mtx, PZERO, msg, 0);
-    }
-    /* prevent other bond list remove/add from taking place */
-    ifbond_flags_set_change_in_progress(ifb);
-    if (g_bond->verbose && waited) {
-       printf("%s: %s woke up\n", ifb->ifb_name, msg);
-    }
-    return;
+       /* prevent other bond list remove/add from taking place */
+       ifbond_flags_set_change_in_progress(ifb);
+       if (if_bond_debug && waited) {
+               printf("%s: %s woke up\n", ifb->ifb_name, msg);
+       }
+       return;
 }
 
 /*
  * Function: ifbond_signal
  * Purpose:
- *   Allows the thread that previously invoked ifbond_wait() to 
+ *   Allows the thread that previously invoked ifbond_wait() to
  *   give up exclusive access to the ifbond data structure, and wake up
  *   any other threads waiting to access
  * Notes:
@@ -792,240 +780,293 @@ ifbond_wait(ifbond_ref ifb, const char * msg)
 static void
 ifbond_signal(ifbond_ref ifb, const char * msg)
 {
-    ifbond_flags_clear_change_in_progress(ifb);
-    wakeup((caddr_t)ifb);
-    if (g_bond->verbose) {
-       printf("%s: %s wakeup\n", ifb->ifb_name, msg);
-    }
-    return;
+       ifbond_flags_clear_change_in_progress(ifb);
+       wakeup((caddr_t)ifb);
+       if (if_bond_debug) {
+               printf("%s: %s wakeup\n", ifb->ifb_name, msg);
+       }
+       return;
 }
 
 /**
- ** Media information
- **/
+** Media information
+**/
 
 static int
 link_speed(int active)
 {
-    switch (IFM_SUBTYPE(active)) {
-    case IFM_10_T:
-    case IFM_10_2:
-    case IFM_10_5:
-    case IFM_10_STP:
-    case IFM_10_FL:
-       return (10);
-    case IFM_100_TX:
-    case IFM_100_FX:
-    case IFM_100_T4:
-    case IFM_100_VG:
-    case IFM_100_T2:
-       return (100);
-    case IFM_1000_SX:
-    case IFM_1000_LX:
-    case IFM_1000_CX:
-    case IFM_1000_TX:
-       return (1000);
-    case IFM_HPNA_1:
-       return (0);
-    default:
+       switch (IFM_SUBTYPE(active)) {
+       case IFM_AUTO:
+       case IFM_MANUAL:
+       case IFM_NONE:
+               return 0;
+       case IFM_10_T:
+       case IFM_10_2:
+       case IFM_10_5:
+       case IFM_10_STP:
+       case IFM_10_FL:
+               return 10;
+       case IFM_100_TX:
+       case IFM_100_FX:
+       case IFM_100_T4:
+       case IFM_100_VG:
+       case IFM_100_T2:
+               return 100;
+       case IFM_1000_SX:
+       case IFM_1000_LX:
+       case IFM_1000_CX:
+       case IFM_1000_TX:
+       case IFM_1000_CX_SGMII:
+       case IFM_1000_KX:
+               return 1000;
+       case IFM_HPNA_1:
+               return 1;
+       default:
        /* assume that new defined types are going to be at least 10GigE */
-    case IFM_10G_SR:
-    case IFM_10G_LR:
-       return (10000);
-    }
+       case IFM_10G_SR:
+       case IFM_10G_LR:
+       case IFM_10G_KX4:
+       case IFM_10G_KR:
+       case IFM_10G_CR1:
+       case IFM_10G_ER:
+               return 10000;
+       case IFM_2500_T:
+               return 2500;
+       case IFM_5000_T:
+               return 5000;
+       case IFM_20G_KR2:
+               return 20000;
+       case IFM_25G_CR:
+       case IFM_25G_KR:
+       case IFM_25G_SR:
+       case IFM_25G_LR:
+               return 25000;
+       case IFM_40G_CR4:
+       case IFM_40G_SR4:
+       case IFM_40G_LR4:
+       case IFM_40G_KR4:
+               return 40000;
+       case IFM_50G_CR2:
+       case IFM_50G_KR2:
+       case IFM_50G_SR2:
+       case IFM_50G_LR2:
+               return 50000;
+       case IFM_56G_R4:
+               return 56000;
+       case IFM_100G_CR4:
+       case IFM_100G_SR4:
+       case IFM_100G_KR4:
+       case IFM_100G_LR4:
+               return 100000;
+       }
 }
 
 static __inline__ int
 media_active(const struct media_info * mi)
 {
-    if ((mi->mi_status & IFM_AVALID) == 0) {
-       return (1);
-    }
-    return ((mi->mi_status & IFM_ACTIVE) != 0);
+       if ((mi->mi_status & IFM_AVALID) == 0) {
+               return 1;
+       }
+       return (mi->mi_status & IFM_ACTIVE) != 0;
 }
 
 static __inline__ int
 media_full_duplex(const struct media_info * mi)
 {
-    return ((mi->mi_active & IFM_FDX) != 0);
+       return (mi->mi_active & IFM_FDX) != 0;
+}
+
+static __inline__ int
+media_type_unknown(const struct media_info * mi)
+{
+       int unknown;
+
+       switch (IFM_SUBTYPE(mi->mi_active)) {
+       case IFM_AUTO:
+       case IFM_MANUAL:
+       case IFM_NONE:
+               unknown = 1;
+               break;
+       default:
+               unknown = 0;
+               break;
+       }
+       return unknown;
+}
+
+static __inline__ int
+media_ok(const struct media_info * mi)
+{
+       return media_full_duplex(mi) || media_type_unknown(mi);
 }
 
 static __inline__ int
 media_speed(const struct media_info * mi)
 {
-    return (link_speed(mi->mi_active));
+       return link_speed(mi->mi_active);
 }
 
 static struct media_info
 interface_media_info(struct ifnet * ifp)
 {
-    struct ifmediareq  ifmr;
-    struct media_info  mi;
+       struct ifmediareq   ifmr;
+       struct media_info   mi;
 
-    bzero(&mi, sizeof(mi));
-    bzero(&ifmr, sizeof(ifmr));
-    if (ifnet_ioctl(ifp, 0, SIOCGIFMEDIA, &ifmr) == 0) {
-       if (ifmr.ifm_count != 0) {
-           mi.mi_status = ifmr.ifm_status;
-           mi.mi_active = ifmr.ifm_active;
+       bzero(&mi, sizeof(mi));
+       bzero(&ifmr, sizeof(ifmr));
+       if (ifnet_ioctl(ifp, 0, SIOCGIFMEDIA, &ifmr) == 0) {
+               if (ifmr.ifm_count != 0) {
+                       mi.mi_status = ifmr.ifm_status;
+                       mi.mi_active = ifmr.ifm_active;
+               }
        }
-    }
-    return (mi);
+       return mi;
 }
 
 static int
 if_siflladdr(struct ifnet * ifp, const struct ether_addr * ea_p)
 {
-    struct ifreq       ifr;
+       struct ifreq        ifr;
 
-    /*
-     * XXX setting the sa_len to ETHER_ADDR_LEN is wrong, but the driver
-     * currently expects it that way
-     */
-    ifr.ifr_addr.sa_family = AF_UNSPEC;
-    ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
-    ether_addr_copy(ifr.ifr_addr.sa_data, ea_p);
-#if 0
-    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", ifnet_name(ifp),
-            ifnet_unit(ifp));
-#endif
-    return (ifnet_ioctl(ifp, 0, SIOCSIFLLADDR, &ifr));
+       /*
+        * XXX setting the sa_len to ETHER_ADDR_LEN is wrong, but the driver
+        * currently expects it that way
+        */
+       ifr.ifr_addr.sa_family = AF_UNSPEC;
+       ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+       ether_addr_copy(ifr.ifr_addr.sa_data, ea_p);
+       return ifnet_ioctl(ifp, 0, SIOCSIFLLADDR, &ifr);
 }
 
 /**
- ** bond_globals
- **/
+** bond_globals
+**/
 static bond_globals_ref
 bond_globals_create(lacp_system_priority sys_pri,
-                   lacp_system_ref sys)
-{
-    bond_globals_ref   b;
-
-    b = _MALLOC(sizeof(*b), M_BOND, M_WAITOK);
-    if (b == NULL) {
-       return (NULL);
-    }
-    bzero(b, sizeof(*b));
-    TAILQ_INIT(&b->ifbond_list);
-    b->system = *sys;
-    b->system_priority = sys_pri;
-#if 0
-    b->verbose = 1;
-#endif
-    return (b);
+    lacp_system_ref sys)
+{
+       bond_globals_ref    b;
+
+       b = _MALLOC(sizeof(*b), M_BOND, M_WAITOK | M_ZERO);
+       if (b == NULL) {
+               return NULL;
+       }
+       TAILQ_INIT(&b->ifbond_list);
+       b->system = *sys;
+       b->system_priority = sys_pri;
+       return b;
 }
 
 static int
 bond_globals_init(void)
 {
-    bond_globals_ref   b;
-    int                        i;
-    struct ifnet *     ifp;
-
-    bond_assert_lock_not_held();
-
-    if (g_bond != NULL) {
-       return (0);
-    }
-
-    /*
-     * use en0's ethernet address as the system identifier, and if it's not
-     * there, use en1 .. en3
-     */
-    ifp = NULL;
-    for (i = 0; i < 4; i++) {
-       char            ifname[IFNAMSIZ+1];
-       snprintf(ifname, sizeof(ifname), "en%d", i);
-       /* XXX ifunit() needs to return a reference on the ifp */
-       ifp = ifunit(ifname);
+       bond_globals_ref    b;
+       int                 i;
+       struct ifnet *      ifp;
+
+       bond_assert_lock_not_held();
+
+       if (g_bond != NULL) {
+               return 0;
+       }
+
+       /*
+        * use en0's ethernet address as the system identifier, and if it's not
+        * there, use en1 .. en3
+        */
+       ifp = NULL;
+       for (i = 0; i < 4; i++) {
+               char            ifname[IFNAMSIZ + 1];
+               snprintf(ifname, sizeof(ifname), "en%d", i);
+               ifp = ifunit(ifname);
+               if (ifp != NULL) {
+                       break;
+               }
+       }
+       b = NULL;
        if (ifp != NULL) {
-           break;
-       }
-    }
-    b = NULL;
-    if (ifp != NULL) {
-       b = bond_globals_create(0x8000, (lacp_system_ref)ifnet_lladdr(ifp));
-    }
-    bond_lock();
-    if (g_bond != NULL) {
+               b = bond_globals_create(0x8000, (lacp_system_ref)IF_LLADDR(ifp));
+       }
+       bond_lock();
+       if (g_bond != NULL) {
+               bond_unlock();
+               _FREE(b, M_BOND);
+               return 0;
+       }
+       g_bond = b;
        bond_unlock();
-       _FREE(b, M_BOND);
-       return (0);
-    }
-    g_bond = b;
-    bond_unlock();
-    if (ifp == NULL) {
-       return (ENXIO);
-    }
-    if (b == NULL) {
-       return (ENOMEM);
-    }
-    return (0);
+       if (ifp == NULL) {
+               return ENXIO;
+       }
+       if (b == NULL) {
+               return ENOMEM;
+       }
+       return 0;
 }
 
 static void
 bond_bpf_vlan(struct ifnet * ifp, struct mbuf * m,
-             const struct ether_header * eh_p,
-             u_int16_t vlan_tag, bpf_packet_func func)
-{
-    struct ether_vlan_header * vlh_p;
-    struct mbuf *              vl_m;
-
-    vl_m = m_get(M_DONTWAIT, MT_DATA);
-    if (vl_m == NULL) {
+    const struct ether_header * eh_p,
+    u_int16_t vlan_tag, bpf_packet_func func)
+{
+       struct ether_vlan_header *  vlh_p;
+       struct mbuf *               vl_m;
+
+       vl_m = m_get(M_DONTWAIT, MT_DATA);
+       if (vl_m == NULL) {
+               return;
+       }
+       /* populate a new mbuf containing the vlan ethernet header */
+       vl_m->m_len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
+       vlh_p = mtod(vl_m, struct ether_vlan_header *);
+       bcopy(eh_p, vlh_p, offsetof(struct ether_header, ether_type));
+       vlh_p->evl_encap_proto = htons(ETHERTYPE_VLAN);
+       vlh_p->evl_tag = htons(vlan_tag);
+       vlh_p->evl_proto = eh_p->ether_type;
+       vl_m->m_next = m;
+       (*func)(ifp, vl_m);
+       vl_m->m_next = NULL;
+       m_free(vl_m);
        return;
-    }
-    /* populate a new mbuf containing the vlan ethernet header */
-    vl_m->m_len = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
-    vlh_p = mtod(vl_m, struct ether_vlan_header *);
-    bcopy(eh_p, vlh_p, offsetof(struct ether_header, ether_type));
-    vlh_p->evl_encap_proto = htons(ETHERTYPE_VLAN);
-    vlh_p->evl_tag = htons(vlan_tag);
-    vlh_p->evl_proto = eh_p->ether_type;
-    vl_m->m_next = m;
-    (*func)(ifp, vl_m);
-    vl_m->m_next = NULL;
-    m_free(vl_m);
-    return;
-}
-
-static __inline__ void 
-bond_bpf_output(struct ifnet * ifp, struct mbuf * m, 
-               bpf_packet_func func)
-{
-    if (func != NULL) {
-       if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
-           const struct ether_header * eh_p;
-           eh_p = mtod(m, const struct ether_header *);
-           m->m_data += ETHER_HDR_LEN;
-           m->m_len -= ETHER_HDR_LEN;
-           bond_bpf_vlan(ifp, m, eh_p, m->m_pkthdr.vlan_tag, func);
-           m->m_data -= ETHER_HDR_LEN;
-           m->m_len += ETHER_HDR_LEN;
-       } else {
-           (*func)(ifp, m);
+}
+
+static __inline__ void
+bond_bpf_output(struct ifnet * ifp, struct mbuf * m,
+    bpf_packet_func func)
+{
+       if (func != NULL) {
+               if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
+                       const struct ether_header * eh_p;
+                       eh_p = mtod(m, const struct ether_header *);
+                       m->m_data += ETHER_HDR_LEN;
+                       m->m_len -= ETHER_HDR_LEN;
+                       bond_bpf_vlan(ifp, m, eh_p, m->m_pkthdr.vlan_tag, func);
+                       m->m_data -= ETHER_HDR_LEN;
+                       m->m_len += ETHER_HDR_LEN;
+               } else {
+                       (*func)(ifp, m);
+               }
        }
-    }
-    return;
+       return;
 }
 
-static __inline__ void 
+static __inline__ void
 bond_bpf_input(ifnet_t ifp, mbuf_t m, const struct ether_header * eh_p,
-               bpf_packet_func func)
-{
-    if (func != NULL) {
-       if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
-           bond_bpf_vlan(ifp, m, eh_p, m->m_pkthdr.vlan_tag, func);
-       } else {
-           /* restore the header */
-           m->m_data -= ETHER_HDR_LEN;
-           m->m_len += ETHER_HDR_LEN;
-           (*func)(ifp, m);
-           m->m_data += ETHER_HDR_LEN;
-           m->m_len -= ETHER_HDR_LEN;
+    bpf_packet_func func)
+{
+       if (func != NULL) {
+               if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
+                       bond_bpf_vlan(ifp, m, eh_p, m->m_pkthdr.vlan_tag, func);
+               } else {
+                       /* restore the header */
+                       m->m_data -= ETHER_HDR_LEN;
+                       m->m_len += ETHER_HDR_LEN;
+                       (*func)(ifp, m);
+                       m->m_data += ETHER_HDR_LEN;
+                       m->m_len -= ETHER_HDR_LEN;
+               }
        }
-    }
-    return;
+       return;
 }
 
 /*
@@ -1037,117 +1078,119 @@ bond_bpf_input(ifnet_t ifp, mbuf_t m, const struct ether_header * eh_p,
 static int
 bond_setmulti(struct ifnet * ifp)
 {
-    ifbond_ref         ifb;
-    int                        error;
-    int                        result = 0;
-    bondport_ref       p;
+       ifbond_ref          ifb;
+       int                 error;
+       int                 result = 0;
+       bondport_ref        p;
+
+       bond_lock();
+       ifb = ifnet_softc(ifp);
+       if (ifb == NULL || ifbond_flags_if_detaching(ifb)
+           || TAILQ_EMPTY(&ifb->ifb_port_list)) {
+               bond_unlock();
+               return 0;
+       }
+       ifbond_retain(ifb);
+       ifbond_wait(ifb, "bond_setmulti");
 
-    bond_lock();
-    ifb = ifnet_softc(ifp);
-    if (ifb == NULL || ifbond_flags_if_detaching(ifb) 
-       || TAILQ_EMPTY(&ifb->ifb_port_list)) {
+       if (ifbond_flags_if_detaching(ifb)) {
+               /* someone destroyed the bond while we were waiting */
+               result = EBUSY;
+               goto signal_done;
+       }
        bond_unlock();
-       return (0);
-    }
-    ifbond_retain(ifb);
-    ifbond_wait(ifb, "bond_setmulti");
-
-    if (ifbond_flags_if_detaching(ifb)) {
-       /* someone destroyed the bond while we were waiting */
-       result = EBUSY;
-       goto signal_done;
-    }
-    bond_unlock();
-
-    /* ifbond_wait() let's us safely walk the list without holding the lock */
-    TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
-       struct ifnet *  port_ifp = p->po_ifp;
-
-       error = multicast_list_program(&p->po_multicast,
-                                      ifp, port_ifp);
-       if (error != 0) {
-           printf("bond_setmulti(%s): "
-                  "multicast_list_program(%s%d) failed, %d\n",
-                  ifb->ifb_name, ifnet_name(port_ifp),
-                  ifnet_unit(port_ifp), error);
-           result = error;
+
+       /* ifbond_wait() let's us safely walk the list without holding the lock */
+       TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
+               struct ifnet *  port_ifp = p->po_ifp;
+
+               error = multicast_list_program(&p->po_multicast,
+                   ifp, port_ifp);
+               if (error != 0) {
+                       printf("bond_setmulti(%s): "
+                           "multicast_list_program(%s%d) failed, %d\n",
+                           ifb->ifb_name, ifnet_name(port_ifp),
+                           ifnet_unit(port_ifp), error);
+                       result = error;
+               }
        }
-    }
-    bond_lock();
- signal_done:
-    ifbond_signal(ifb, "bond_setmulti");
-    bond_unlock();
-    ifbond_release(ifb);
-    return (result);
+       bond_lock();
+signal_done:
+       ifbond_signal(ifb, __func__);
+       bond_unlock();
+       ifbond_release(ifb);
+       return result;
 }
 
 static int
 bond_clone_attach(void)
 {
-    int error;
+       int error;
 
-    if ((error = if_clone_attach(&bond_cloner)) != 0)
-       return error;
-    bond_lock_init();
-    return 0;
+       if ((error = if_clone_attach(&bond_cloner)) != 0) {
+               return error;
+       }
+       bond_lock_init();
+       return 0;
 }
 
 static int
 ifbond_add_slow_proto_multicast(ifbond_ref ifb)
 {
-    int                                error;
-    struct ifmultiaddr *       ifma = NULL;
-    struct sockaddr_dl         sdl;
+       int                         error;
+       struct ifmultiaddr *        ifma = NULL;
+       struct sockaddr_dl          sdl;
 
-    bond_assert_lock_not_held();
+       bond_assert_lock_not_held();
 
-    bzero(&sdl, sizeof(sdl));
-    sdl.sdl_len = sizeof(sdl);
-    sdl.sdl_family = AF_LINK;
-    sdl.sdl_type = IFT_ETHER;
-    sdl.sdl_nlen = 0;
-    sdl.sdl_alen = sizeof(slow_proto_multicast);
-    bcopy(&slow_proto_multicast, sdl.sdl_data, sizeof(slow_proto_multicast));
-    error = if_addmulti(ifb->ifb_ifp, (struct sockaddr *)&sdl, 
-                       &ifma);
-    if (error == 0) {
-       ifb->ifb_ifma_slow_proto = ifma;
-    }
-    return (error);
+       bzero(&sdl, sizeof(sdl));
+       sdl.sdl_len = sizeof(sdl);
+       sdl.sdl_family = AF_LINK;
+       sdl.sdl_type = IFT_ETHER;
+       sdl.sdl_nlen = 0;
+       sdl.sdl_alen = sizeof(slow_proto_multicast);
+       bcopy(&slow_proto_multicast, sdl.sdl_data, sizeof(slow_proto_multicast));
+       error = if_addmulti_anon(ifb->ifb_ifp, (struct sockaddr *)&sdl, &ifma);
+       if (error == 0) {
+               ifb->ifb_ifma_slow_proto = ifma;
+       }
+       return error;
 }
 
 static int
-bond_clone_create(struct if_clone * ifc, int unit)
+bond_clone_create(struct if_clone * ifc, u_int32_t unit, __unused void *params)
 {
-       int                                             error;
-       ifbond_ref                                      ifb;
-       ifnet_t                                         ifp;
-       struct ifnet_init_params        bond_init;
-       
+       int                                             error;
+       ifbond_ref                                      ifb;
+       ifnet_t                                         ifp;
+       struct ifnet_init_eparams       bond_init;
+
        error = bond_globals_init();
        if (error != 0) {
-               return (error);
+               return error;
        }
-       
-       ifb = _MALLOC(sizeof(ifbond), M_BOND, M_WAITOK);
+
+       ifb = if_clone_softc_allocate(&bond_cloner);
        if (ifb == NULL) {
-               return (ENOMEM);
+               return ENOMEM;
        }
-       bzero(ifb, sizeof(*ifb));
-       
-       ifbond_retain(ifb);
+
+       os_ref_init(&ifb->ifb_retain_count, NULL);
        TAILQ_INIT(&ifb->ifb_port_list);
        TAILQ_INIT(&ifb->ifb_lag_list);
        ifb->ifb_key = unit + 1;
-       
+
        /* use the interface name as the unique id for ifp recycle */
        if ((u_int32_t)snprintf(ifb->ifb_name, sizeof(ifb->ifb_name), "%s%d",
-                                                ifc->ifc_name, unit) >= sizeof(ifb->ifb_name)) {
+           ifc->ifc_name, unit) >= sizeof(ifb->ifb_name)) {
                ifbond_release(ifb);
-               return (EINVAL);
+               return EINVAL;
        }
-       
+
        bzero(&bond_init, sizeof(bond_init));
+       bond_init.ver = IFNET_INIT_CURRENT_VERSION;
+       bond_init.len = sizeof(bond_init);
+       bond_init.flags = IFNET_INIT_LEGACY;
        bond_init.uniqueid = ifb->ifb_name;
        bond_init.uniqueid_len = strlen(ifb->ifb_name);
        bond_init.name = ifc->ifc_name;
@@ -1159,230 +1202,229 @@ bond_clone_create(struct if_clone * ifc, int unit)
        bond_init.add_proto = ether_add_proto;
        bond_init.del_proto = ether_del_proto;
        bond_init.check_multi = ether_check_multi;
-       bond_init.framer = ether_frameout;
+       bond_init.framer_extended = ether_frameout_extended;
        bond_init.ioctl = bond_ioctl;
        bond_init.set_bpf_tap = bond_set_bpf_tap;
        bond_init.detach = bond_if_free;
        bond_init.broadcast_addr = etherbroadcastaddr;
        bond_init.broadcast_len = ETHER_ADDR_LEN;
        bond_init.softc = ifb;
-       error = ifnet_allocate(&bond_init, &ifp);
-       
+       error = ifnet_allocate_extended(&bond_init, &ifp);
+
        if (error) {
                ifbond_release(ifb);
-               return (error);
+               return error;
        }
-       
+
        ifb->ifb_ifp = ifp;
        ifnet_set_offload(ifp, 0);
        ifnet_set_addrlen(ifp, ETHER_ADDR_LEN); /* XXX ethernet specific */
        ifnet_set_flags(ifp, IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX, 0xffff);
-       ifnet_set_baudrate(ifp, 0);
-       ifnet_set_mtu(ifp, 0);
-       
+       ifnet_set_mtu(ifp, ETHERMTU);
+
        error = ifnet_attach(ifp, NULL);
        if (error != 0) {
                ifnet_release(ifp);
                ifbond_release(ifb);
-               return (error);
+               return error;
        }
        error = ifbond_add_slow_proto_multicast(ifb);
        if (error != 0) {
                printf("bond_clone_create(%s): "
-                          "failed to add slow_proto multicast, %d\n",
-                          ifb->ifb_name, error);
+                   "failed to add slow_proto multicast, %d\n",
+                   ifb->ifb_name, error);
        }
-       
+
        /* attach as ethernet */
        bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
-       
+
        bond_lock();
        TAILQ_INSERT_HEAD(&g_bond->ifbond_list, ifb, ifb_bond_list);
        bond_unlock();
-       
-       return (0);
+
+       return 0;
 }
 
 static void
 bond_remove_all_interfaces(ifbond_ref ifb)
 {
-    bondport_ref       p;
+       bondport_ref        p;
 
-    bond_assert_lock_held();
+       bond_assert_lock_held();
 
-    /*
-     * do this in reverse order to avoid re-programming the mac address
-     * as each head interface is removed
-     */
-    while ((p = TAILQ_LAST(&ifb->ifb_port_list, port_list)) != NULL) {
-       bond_remove_interface(ifb, p->po_ifp);
-    }
-    return;
+       /*
+        * do this in reverse order to avoid re-programming the mac address
+        * as each head interface is removed
+        */
+       while ((p = TAILQ_LAST(&ifb->ifb_port_list, port_list)) != NULL) {
+               bond_remove_interface(ifb, p->po_ifp);
+       }
+       return;
 }
 
 static void
 bond_remove(ifbond_ref ifb)
 {
-    bond_assert_lock_held();
-    ifbond_flags_set_if_detaching(ifb);
-    TAILQ_REMOVE(&g_bond->ifbond_list, ifb, ifb_bond_list);
-    bond_remove_all_interfaces(ifb);
-    return;
+       bond_assert_lock_held();
+       ifbond_flags_set_if_detaching(ifb);
+       TAILQ_REMOVE(&g_bond->ifbond_list, ifb, ifb_bond_list);
+       bond_remove_all_interfaces(ifb);
+       return;
 }
 
 static void
 bond_if_detach(struct ifnet * ifp)
 {
-    int                error;
+       int         error;
 
-    error = ifnet_detach(ifp);
+       error = ifnet_detach(ifp);
        if (error) {
-           printf("bond_if_detach %s%d: ifnet_detach failed, %d\n",
-                  ifnet_name(ifp), ifnet_unit(ifp), error);
+               printf("bond_if_detach %s%d: ifnet_detach failed, %d\n",
+                   ifnet_name(ifp), ifnet_unit(ifp), error);
        }
-       
-    return;
+
+       return;
 }
 
-static void
+static int
 bond_clone_destroy(struct ifnet * ifp)
 {
-    ifbond_ref ifb;
+       ifbond_ref ifb;
 
-    bond_lock();
-    ifb = ifnet_softc(ifp);
-    if (ifb == NULL || ifnet_type(ifp) != IFT_IEEE8023ADLAG) {
-       bond_unlock();
-       return;
-    }
-    if (ifbond_flags_if_detaching(ifb)) {
+       bond_lock();
+       ifb = ifnet_softc(ifp);
+       if (ifb == NULL || ifnet_type(ifp) != IFT_IEEE8023ADLAG) {
+               bond_unlock();
+               return 0;
+       }
+       if (ifbond_flags_if_detaching(ifb)) {
+               bond_unlock();
+               return 0;
+       }
+       bond_remove(ifb);
        bond_unlock();
-       return;
-    }
-    bond_remove(ifb);
-    bond_unlock();
-    bond_if_detach(ifp);
-    return;
+       bond_if_detach(ifp);
+       return 0;
 }
 
-static int 
+static int
 bond_set_bpf_tap(struct ifnet * ifp, bpf_tap_mode mode, bpf_packet_func func)
 {
-    ifbond_ref ifb;
+       ifbond_ref  ifb;
+
+       bond_lock();
+       ifb = ifnet_softc(ifp);
+       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+               bond_unlock();
+               return ENODEV;
+       }
+       switch (mode) {
+       case BPF_TAP_DISABLE:
+               ifb->ifb_bpf_input = ifb->ifb_bpf_output = NULL;
+               break;
+
+       case BPF_TAP_INPUT:
+               ifb->ifb_bpf_input = func;
+               break;
+
+       case BPF_TAP_OUTPUT:
+               ifb->ifb_bpf_output = func;
+               break;
 
-    bond_lock();
-    ifb = ifnet_softc(ifp);
-    if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+       case BPF_TAP_INPUT_OUTPUT:
+               ifb->ifb_bpf_input = ifb->ifb_bpf_output = func;
+               break;
+       default:
+               break;
+       }
        bond_unlock();
-       return (ENODEV);
-    }
-    switch (mode) {
-    case BPF_TAP_DISABLE:
-       ifb->ifb_bpf_input = ifb->ifb_bpf_output = NULL;
-       break;
-
-    case BPF_TAP_INPUT:
-       ifb->ifb_bpf_input = func;
-       break;
-
-    case BPF_TAP_OUTPUT:
-       ifb->ifb_bpf_output = func;
-       break;
-        
-    case BPF_TAP_INPUT_OUTPUT:
-       ifb->ifb_bpf_input = ifb->ifb_bpf_output = func;
-       break;
-    default:
-       break;
-    }
-    bond_unlock();
-    return 0;
+       return 0;
 }
 
 static uint32_t
 ether_header_hash(struct ether_header * eh_p)
 {
-    uint32_t   h;
+       uint32_t    h;
 
-    /* get 32-bits from destination ether and ether type */
-    h = (*((uint16_t *)&eh_p->ether_dhost[4]) << 16)
-       | eh_p->ether_type;
-    h ^= *((uint32_t *)&eh_p->ether_dhost[0]);
-    return (h);
+       /* get 32-bits from destination ether and ether type */
+       h = (*((uint16_t *)&eh_p->ether_dhost[4]) << 16)
+           | eh_p->ether_type;
+       h ^= *((uint32_t *)&eh_p->ether_dhost[0]);
+       return h;
 }
 
 static struct mbuf *
 S_mbuf_skip_to_offset(struct mbuf * m, int32_t * offset)
 {
-    int                        len;
+       int                 len;
 
-    len = m->m_len;
-    while (*offset >= len) {
-       *offset -= len;
-       m = m->m_next;
-       if (m == NULL) {
-           break;
-       }
        len = m->m_len;
-    }
-    return (m);
+       while (*offset >= len) {
+               *offset -= len;
+               m = m->m_next;
+               if (m == NULL) {
+                       break;
+               }
+               len = m->m_len;
+       }
+       return m;
 }
 
 #if BYTE_ORDER == BIG_ENDIAN
 static __inline__ uint32_t
 make_uint32(u_char c0, u_char c1, u_char c2, u_char c3)
 {
-    return (((uint32_t)c0 << 24) | ((uint32_t)c1 << 16) 
-           | ((uint32_t)c2 << 8) | (uint32_t)c3);
+       return ((uint32_t)c0 << 24) | ((uint32_t)c1 << 16)
+              | ((uint32_t)c2 << 8) | (uint32_t)c3;
 }
 #else /* BYTE_ORDER == LITTLE_ENDIAN */
 static __inline__ uint32_t
 make_uint32(u_char c0, u_char c1, u_char c2, u_char c3)
 {
-    return (((uint32_t)c3 << 24) | ((uint32_t)c2 << 16) 
-           | ((uint32_t)c1 << 8) | (uint32_t)c0);
+       return ((uint32_t)c3 << 24) | ((uint32_t)c2 << 16)
+              | ((uint32_t)c1 << 8) | (uint32_t)c0;
 }
 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
 
 static int
 S_mbuf_copy_uint32(struct mbuf * m, int32_t offset, uint32_t * val)
 {
-    struct mbuf *      current;
-    u_char *           current_data;
-    struct mbuf *      next;
-    u_char *           next_data;
-    int                        space_current;
-
-    current = S_mbuf_skip_to_offset(m, &offset);
-    if (current == NULL) {
-       return (1);
-    }
-    current_data = mtod(current, u_char *) + offset;
-    space_current = current->m_len - offset;
-    if (space_current >= (int)sizeof(uint32_t)) {
-       *val = *((uint32_t *)current_data);
-       return (0);
-    }
-    next = current->m_next;
-    if (next == NULL || (next->m_len + space_current) < (int)sizeof(uint32_t)) {
-       return (1);
-    }
-    next_data = mtod(next, u_char *);
-    switch (space_current) {
-    case 1:
-       *val = make_uint32(current_data[0], next_data[0],
-                          next_data[1], next_data[2]);
-       break;
-    case 2:
-       *val = make_uint32(current_data[0], current_data[1],
-                          next_data[0], next_data[1]);
-       break;
-    default:
-       *val = make_uint32(current_data[0], current_data[1],
-                          current_data[2], next_data[0]);
-       break;
-    }
-    return (0);
+       struct mbuf *       current;
+       u_char *            current_data;
+       struct mbuf *       next;
+       u_char *            next_data;
+       int                 space_current;
+
+       current = S_mbuf_skip_to_offset(m, &offset);
+       if (current == NULL) {
+               return 1;
+       }
+       current_data = mtod(current, u_char *) + offset;
+       space_current = current->m_len - offset;
+       if (space_current >= (int)sizeof(uint32_t)) {
+               *val = *((uint32_t *)current_data);
+               return 0;
+       }
+       next = current->m_next;
+       if (next == NULL || (next->m_len + space_current) < (int)sizeof(uint32_t)) {
+               return 1;
+       }
+       next_data = mtod(next, u_char *);
+       switch (space_current) {
+       case 1:
+               *val = make_uint32(current_data[0], next_data[0],
+                   next_data[1], next_data[2]);
+               break;
+       case 2:
+               *val = make_uint32(current_data[0], current_data[1],
+                   next_data[0], next_data[1]);
+               break;
+       default:
+               *val = make_uint32(current_data[0], current_data[1],
+                   current_data[2], next_data[0]);
+               break;
+       }
+       return 0;
 }
 
 #define IP_SRC_OFFSET (offsetof(struct ip, ip_src) - offsetof(struct ip, ip_p))
@@ -1391,529 +1433,577 @@ S_mbuf_copy_uint32(struct mbuf * m, int32_t offset, uint32_t * val)
 static uint32_t
 ip_header_hash(struct mbuf * m)
 {
-    u_char *           data;
-    struct in_addr     ip_dst;
-    struct in_addr     ip_src;
-    u_char             ip_p;
-    int32_t            offset;
-    struct mbuf *      orig_m = m;
-
-    /* find the IP protocol field relative to the start of the packet */
-    offset = offsetof(struct ip, ip_p) + sizeof(struct ether_header);
-    m = S_mbuf_skip_to_offset(m, &offset);
-    if (m == NULL || m->m_len < 1) {
-       goto bad_ip_packet;
-    }
-    data = mtod(m, u_char *) + offset;
-    ip_p = *data;
-
-    /* find the IP src relative to the IP protocol */
-    if ((m->m_len - offset) 
-       >= (int)(IP_SRC_OFFSET + sizeof(struct in_addr) * 2)) {
-       /* this should be the normal case */
-       ip_src = *(struct in_addr *)(data + IP_SRC_OFFSET);
-       ip_dst = *(struct in_addr *)(data + IP_DST_OFFSET);
-    }
-    else {
-       if (S_mbuf_copy_uint32(m, offset + IP_SRC_OFFSET,
-                              (uint32_t *)&ip_src.s_addr)) {
-           goto bad_ip_packet;
-       }
-       if (S_mbuf_copy_uint32(m, offset + IP_DST_OFFSET,
-                              (uint32_t *)&ip_dst.s_addr)) {
-           goto bad_ip_packet;
-       }
-    }
-    return (ntohl(ip_dst.s_addr) ^ ntohl(ip_src.s_addr) ^ ((uint32_t)ip_p));
-
- bad_ip_packet:
-    return (ether_header_hash(mtod(orig_m, struct ether_header *)));
-}
-
-#define IP6_ADDRS_LEN  (sizeof(struct in6_addr) * 2)
+       u_char *            data;
+       struct in_addr      ip_dst;
+       struct in_addr      ip_src;
+       u_char              ip_p;
+       int32_t             offset;
+       struct mbuf *       orig_m = m;
+
+       /* find the IP protocol field relative to the start of the packet */
+       offset = offsetof(struct ip, ip_p) + sizeof(struct ether_header);
+       m = S_mbuf_skip_to_offset(m, &offset);
+       if (m == NULL || m->m_len < 1) {
+               goto bad_ip_packet;
+       }
+       data = mtod(m, u_char *) + offset;
+       ip_p = *data;
+
+       /* find the IP src relative to the IP protocol */
+       if ((m->m_len - offset)
+           >= (int)(IP_SRC_OFFSET + sizeof(struct in_addr) * 2)) {
+               /* this should be the normal case */
+               ip_src = *(struct in_addr *)(data + IP_SRC_OFFSET);
+               ip_dst = *(struct in_addr *)(data + IP_DST_OFFSET);
+       } else {
+               if (S_mbuf_copy_uint32(m, offset + IP_SRC_OFFSET,
+                   (uint32_t *)&ip_src.s_addr)) {
+                       goto bad_ip_packet;
+               }
+               if (S_mbuf_copy_uint32(m, offset + IP_DST_OFFSET,
+                   (uint32_t *)&ip_dst.s_addr)) {
+                       goto bad_ip_packet;
+               }
+       }
+       return ntohl(ip_dst.s_addr) ^ ntohl(ip_src.s_addr) ^ ((uint32_t)ip_p);
+
+bad_ip_packet:
+       return ether_header_hash(mtod(orig_m, struct ether_header *));
+}
+
+#define IP6_ADDRS_LEN   (sizeof(struct in6_addr) * 2)
 static uint32_t
 ipv6_header_hash(struct mbuf * m)
 {
-    u_char *           data;
-    int                        i;
-    int32_t            offset;
-    struct mbuf *      orig_m = m;
-    uint32_t *         scan;
-    uint32_t           val;
-
-    /* find the IP protocol field relative to the start of the packet */
-    offset = offsetof(struct ip6_hdr, ip6_src) + sizeof(struct ether_header);
-    m = S_mbuf_skip_to_offset(m, &offset);
-    if (m == NULL) {
-       goto bad_ipv6_packet;
-    }
-    data = mtod(m, u_char *) + offset;
-    val = 0;
-    if ((m->m_len - offset) >= (int)IP6_ADDRS_LEN) {
-       /* this should be the normal case */
-       for (i = 0, scan = (uint32_t *)data;
-            i < (int)(IP6_ADDRS_LEN / sizeof(uint32_t));
-            i++, scan++) {
-           val ^= *scan;
-       }
-    }
-    else {
-       for (i = 0; i < (int)(IP6_ADDRS_LEN / sizeof(uint32_t)); i++) {
-           uint32_t    tmp;
-           if (S_mbuf_copy_uint32(m, offset + i * sizeof(uint32_t),
-                                  (uint32_t *)&tmp)) {
+       u_char *            data;
+       int                 i;
+       int32_t             offset;
+       struct mbuf *       orig_m = m;
+       uint32_t *          scan;
+       uint32_t            val;
+
+       /* find the IP protocol field relative to the start of the packet */
+       offset = offsetof(struct ip6_hdr, ip6_src) + sizeof(struct ether_header);
+       m = S_mbuf_skip_to_offset(m, &offset);
+       if (m == NULL) {
                goto bad_ipv6_packet;
-           }
-           val ^= tmp;
        }
-    }
-    return (ntohl(val));
+       data = mtod(m, u_char *) + offset;
+       val = 0;
+       if ((m->m_len - offset) >= (int)IP6_ADDRS_LEN) {
+               /* this should be the normal case */
+               for (i = 0, scan = (uint32_t *)data;
+                   i < (int)(IP6_ADDRS_LEN / sizeof(uint32_t));
+                   i++, scan++) {
+                       val ^= *scan;
+               }
+       } else {
+               for (i = 0; i < (int)(IP6_ADDRS_LEN / sizeof(uint32_t)); i++) {
+                       uint32_t    tmp;
+                       if (S_mbuf_copy_uint32(m, offset + i * sizeof(uint32_t),
+                           (uint32_t *)&tmp)) {
+                               goto bad_ipv6_packet;
+                       }
+                       val ^= tmp;
+               }
+       }
+       return ntohl(val);
 
- bad_ipv6_packet:
-    return (ether_header_hash(mtod(orig_m, struct ether_header *)));
+bad_ipv6_packet:
+       return ether_header_hash(mtod(orig_m, struct ether_header *));
 }
 
 static int
 bond_output(struct ifnet * ifp, struct mbuf * m)
 {
-    bpf_packet_func            bpf_func;
-    uint32_t                   h;
-    ifbond_ref                 ifb;
-    struct ifnet *             port_ifp = NULL;
-       
-    if (m == 0) {
-       return (0);
-    }
-    if ((m->m_flags & M_PKTHDR) == 0) {
+       bpf_packet_func             bpf_func;
+       uint32_t                    h;
+       ifbond_ref                  ifb;
+       struct ifnet *              port_ifp = NULL;
+       int                         err;
+       struct flowadv              adv = { .code = FADV_SUCCESS };
+
+       if (m == 0) {
+               return 0;
+       }
+       if ((m->m_flags & M_PKTHDR) == 0) {
+               m_freem(m);
+               return 0;
+       }
+       if (m->m_pkthdr.pkt_flowid != 0) {
+               h = m->m_pkthdr.pkt_flowid;
+       } else {
+               struct ether_header *   eh_p;
+
+               eh_p = mtod(m, struct ether_header *);
+               switch (ntohs(eh_p->ether_type)) {
+               case ETHERTYPE_IP:
+                       h = ip_header_hash(m);
+                       break;
+               case ETHERTYPE_IPV6:
+                       h = ipv6_header_hash(m);
+                       break;
+               default:
+                       h = ether_header_hash(eh_p);
+                       break;
+               }
+       }
+       bond_lock();
+       ifb = ifnet_softc(ifp);
+       if (ifb == NULL || ifbond_flags_if_detaching(ifb)
+           || ifb->ifb_distributing_count == 0) {
+               goto done;
+       }
+       h %= ifb->ifb_distributing_count;
+       port_ifp = ifb->ifb_distributing_array[h]->po_ifp;
+       bpf_func = ifb->ifb_bpf_output;
+       bond_unlock();
+
+       if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
+               (void)ifnet_stat_increment_out(ifp, 1,
+                   m->m_pkthdr.len + ETHER_VLAN_ENCAP_LEN,
+                   0);
+       } else {
+               (void)ifnet_stat_increment_out(ifp, 1, m->m_pkthdr.len, 0);
+       }
+       bond_bpf_output(ifp, m, bpf_func);
+
+       err = dlil_output(port_ifp, PF_BOND, m, NULL, NULL, 1, &adv);
+
+       if (err == 0) {
+               if (adv.code == FADV_FLOW_CONTROLLED) {
+                       err = EQFULL;
+               } else if (adv.code == FADV_SUSPENDED) {
+                       err = EQSUSPENDED;
+               }
+       }
+
+       return err;
+
+done:
+       bond_unlock();
        m_freem(m);
-       return (0);
-    }
-    if (m->m_pkthdr.socket_id != 0) {
-       h = m->m_pkthdr.socket_id;
-    }
-    else {
-       struct ether_header *   eh_p;
-
-       eh_p = mtod(m, struct ether_header *);
-       switch (ntohs(eh_p->ether_type)) {
-       case ETHERTYPE_IP:
-           h = ip_header_hash(m);
-           break;
-       case ETHERTYPE_IPV6:
-           h = ipv6_header_hash(m);
-           break;
-       default:
-           h = ether_header_hash(eh_p);
-           break;
-       }
-    }
-    bond_lock();
-    ifb = ifnet_softc(ifp);
-    if (ifb == NULL || ifbond_flags_if_detaching(ifb)
-       || ifb->ifb_distributing_count == 0) {
-       goto done;
-    }
-    h %= ifb->ifb_distributing_count;
-    port_ifp = ifb->ifb_distributing_array[h]->po_ifp;
-    bpf_func = ifb->ifb_bpf_output;
-    bond_unlock();
-
-    if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
-       (void)ifnet_stat_increment_out(ifp, 1, 
-                                      m->m_pkthdr.len + ETHER_VLAN_ENCAP_LEN,
-                                      0);
-    } else {
-       (void)ifnet_stat_increment_out(ifp, 1, m->m_pkthdr.len, 0);
-    }
-    bond_bpf_output(ifp, m, bpf_func);
-
-    return (ifnet_output_raw(port_ifp, PF_BOND, m));
-
- done:
-    bond_unlock();
-    m_freem(m);
-    return (0);
+       return 0;
 }
 
 static bondport_ref
 ifbond_lookup_port(ifbond_ref ifb, struct ifnet * port_ifp)
 {
-    bondport_ref       p;
-    TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
-       if (p->po_ifp == port_ifp) {
-           return (p);
+       bondport_ref        p;
+       TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
+               if (p->po_ifp == port_ifp) {
+                       return p;
+               }
        }
-    }
-    return (NULL);
+       return NULL;
 }
 
 static bondport_ref
 bond_lookup_port(struct ifnet * port_ifp)
 {
-    ifbond_ref         ifb;
-    bondport_ref       port;
+       ifbond_ref          ifb;
+       bondport_ref        port;
 
-    TAILQ_FOREACH(ifb, &g_bond->ifbond_list, ifb_bond_list) {
-       port = ifbond_lookup_port(ifb, port_ifp);
-       if (port != NULL) {
-           return (port);
+       TAILQ_FOREACH(ifb, &g_bond->ifbond_list, ifb_bond_list) {
+               port = ifbond_lookup_port(ifb, port_ifp);
+               if (port != NULL) {
+                       return port;
+               }
        }
-    }
-    return (NULL);
+       return NULL;
 }
 
 static void
 bond_receive_lacpdu(struct mbuf * m, struct ifnet * port_ifp)
 {
-    struct ifnet *             bond_ifp = NULL;
-    ifbond_ref                 ifb;
-    int                                event_code = 0;
-    bondport_ref               p;
-
-    bond_lock();
-    if ((ifnet_eflags(port_ifp) & IFEF_BOND) == 0) {
-       goto done;
-    }
-    p = bond_lookup_port(port_ifp);
-    if (p == NULL) {
-       goto done;
-    }
-    if (p->po_enabled == 0) {
-       goto done;
-    }
-    ifb = p->po_bond;
-    if (ifb->ifb_mode != IF_BOND_MODE_LACP) {
-       goto done;
-    }
-    bondport_receive_lacpdu(p, (lacpdu_ref)m->m_data);
-    if (ifbond_selection(ifb)) {
-       event_code = (ifb->ifb_active_lag == NULL) 
-           ? KEV_DL_LINK_OFF 
-           : KEV_DL_LINK_ON;
-       /* XXX need to take a reference on bond_ifp */
-       bond_ifp = ifb->ifb_ifp;
-       ifb->ifb_last_link_event = event_code;
-    }
-    else {
-       event_code = (ifb->ifb_active_lag == NULL) 
-           ? KEV_DL_LINK_OFF 
-           : KEV_DL_LINK_ON;
-       if (event_code != ifb->ifb_last_link_event) {
-           if (g_bond->verbose) {
-               timestamp_printf("%s: (receive) generating LINK event\n",
-                                ifb->ifb_name);
-           }
-           bond_ifp = ifb->ifb_ifp;
-           ifb->ifb_last_link_event = event_code;
-       }
-    }
-
- done:
-    bond_unlock();
-    if (bond_ifp != NULL) {
-       interface_link_event(bond_ifp, event_code);
-    }
-    m_freem(m);
-    return;
-}
-
-static void
-bond_receive_la_marker_pdu(struct mbuf * m, struct ifnet * port_ifp)
-{
-    la_marker_pdu_ref          marker_p;
-    bondport_ref               p;
-
-    marker_p = (la_marker_pdu_ref)(m->m_data + ETHER_HDR_LEN);
-    if (marker_p->lm_marker_tlv_type != LA_MARKER_TLV_TYPE_MARKER) {
-       goto failed;
-    }
-    bond_lock();
-    if ((ifnet_eflags(port_ifp) & IFEF_BOND) == 0) {
-       bond_unlock();
-       goto failed;
-    }
-    p = bond_lookup_port(port_ifp);
-    if (p == NULL || p->po_enabled == 0
-       || p->po_bond->ifb_mode != IF_BOND_MODE_LACP) {
-       bond_unlock();
-       goto failed;
-    }
-    /* echo back the same packet as a marker response */
-    marker_p->lm_marker_tlv_type = LA_MARKER_TLV_TYPE_MARKER_RESPONSE;
-    bondport_slow_proto_transmit(p, (packet_buffer_ref)m);
-    bond_unlock();
-    return;
+       struct ifnet *              bond_ifp = NULL;
+       ifbond_ref                  ifb;
+       int                         event_code = 0;
+       bool                        need_link_update = false;
+       bondport_ref                p;
 
- failed:
-    m_freem(m);
-    return;
-}
-
-static int
-bond_input(ifnet_t port_ifp, __unused protocol_family_t protocol, mbuf_t m,
-                  char * frame_header)
-{
-    bpf_packet_func            bpf_func;
-    const struct ether_header *        eh_p;
-    ifbond_ref                 ifb;
-    struct ifnet *             ifp;    
-    bondport_ref               p;
-
-    eh_p = (const struct ether_header *)frame_header;
-    if ((m->m_flags & M_MCAST) != 0
-       && bcmp(eh_p->ether_dhost, &slow_proto_multicast,
-               sizeof(eh_p->ether_dhost)) == 0
-       && ntohs(eh_p->ether_type) == IEEE8023AD_SLOW_PROTO_ETHERTYPE) {
-       u_char  subtype = *mtod(m, u_char *);
-
-       if (subtype == IEEE8023AD_SLOW_PROTO_SUBTYPE_LACP) {
-           if (m->m_pkthdr.len < (int)offsetof(lacpdu, la_reserved)) {
-               m_freem(m);
-               return (0);
-           }
-           /* send to lacp */
-           if (m->m_len < (int)offsetof(lacpdu, la_reserved)) {
-               m = m_pullup(m, offsetof(lacpdu, la_reserved));
-               if (m == NULL) {
-                   return (0);
+       bond_lock();
+       if ((ifnet_eflags(port_ifp) & IFEF_BOND) == 0) {
+               goto done;
+       }
+       p = bond_lookup_port(port_ifp);
+       if (p == NULL) {
+               goto done;
+       }
+       if (p->po_enabled == 0) {
+               goto done;
+       }
+       ifb = p->po_bond;
+       if (ifb->ifb_mode != IF_BOND_MODE_LACP) {
+               goto done;
+       }
+       /*
+        * Work-around for rdar://problem/51372042
+        * Sometimes, the link comes up but the driver doesn't report the
+        * negotiated medium at that time. When we receive an LACPDU packet,
+        * and the medium is unknown, force a link status check. Don't force
+        * the link status check more often than _FORCE_LINK_EVENT_INTERVAL
+        * seconds.
+        */
+#define _FORCE_LINK_EVENT_INTERVAL      1
+       if (media_type_unknown(&p->po_media_info)) {
+               uint64_t        now = net_uptime();
+
+               if ((now - p->po_force_link_event_time) >=
+                   _FORCE_LINK_EVENT_INTERVAL) {
+                       need_link_update = true;
+                       p->po_force_link_event_time = now;
                }
-           }
-           bond_receive_lacpdu(m, port_ifp);
-           return (0);
        }
-       else if (subtype == IEEE8023AD_SLOW_PROTO_SUBTYPE_LA_MARKER_PROTOCOL) {
-           int         min_size;
-
-           /* restore the ethernet header pointer in the mbuf */
-           m->m_pkthdr.len += ETHER_HDR_LEN;
-           m->m_data -= ETHER_HDR_LEN;
-           m->m_len += ETHER_HDR_LEN;
-           min_size = ETHER_HDR_LEN + offsetof(la_marker_pdu, lm_reserved);
-           if (m->m_pkthdr.len < min_size) {
-               m_freem(m);
-               return (0);
-           }
-           /* send to lacp */
-           if (m->m_len < min_size) {
-               m = m_pullup(m, min_size);
-               if (m == NULL) {
-                   return (0);
-               }
-           }
-           /* send to marker responder */
-           bond_receive_la_marker_pdu(m, port_ifp);
-           return (0);
-       }
-       else if (subtype == 0 
-                || subtype > IEEE8023AD_SLOW_PROTO_SUBTYPE_RESERVED_END) {
-           /* invalid subtype, discard the frame */
-           m_freem(m);
-           return (0);
-       }
-    }
-    bond_lock();
-    if ((ifnet_eflags(port_ifp) & IFEF_BOND) == 0) {
-       goto done;
-    }
-    p = bond_lookup_port(port_ifp);
-    if (p == NULL || bondport_collecting(p) == 0) {
-       goto done;
-    }
-
-    /* make the packet appear as if it arrived on the bonded interface */
-    ifb = p->po_bond;
-    ifp = ifb->ifb_ifp;
-    bpf_func = ifb->ifb_bpf_input;
-    bond_unlock();
-
-    if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
-       (void)ifnet_stat_increment_in(ifp, 1, 
-                                     (m->m_pkthdr.len + ETHER_HDR_LEN 
-                                      + ETHER_VLAN_ENCAP_LEN), 0);
-    }
-    else {
-       (void)ifnet_stat_increment_in(ifp, 1, 
-                                     (m->m_pkthdr.len + ETHER_HDR_LEN), 0);
-    }
-    m->m_pkthdr.rcvif = ifp;
-    bond_bpf_input(ifp, m, eh_p, bpf_func);
-    m->m_pkthdr.header = frame_header;
-    dlil_input_packet_list(ifp, m);
-    return 0;
-
- done:
-    bond_unlock();
-    m_freem(m);
-    return (0);
-}
+       bondport_receive_lacpdu(p, (lacpdu_ref)m->m_data);
+       if (ifbond_selection(ifb)) {
+               event_code = (ifb->ifb_active_lag == NULL)
+                   ? KEV_DL_LINK_OFF
+                   : KEV_DL_LINK_ON;
+               /* XXX need to take a reference on bond_ifp */
+               bond_ifp = ifb->ifb_ifp;
+               ifb->ifb_last_link_event = event_code;
+       } else {
+               event_code = (ifb->ifb_active_lag == NULL)
+                   ? KEV_DL_LINK_OFF
+                   : KEV_DL_LINK_ON;
+               if (event_code != ifb->ifb_last_link_event) {
+                       if (if_bond_debug) {
+                               timestamp_printf("%s: (receive) generating LINK event\n",
+                                   ifb->ifb_name);
+                       }
+                       bond_ifp = ifb->ifb_ifp;
+                       ifb->ifb_last_link_event = event_code;
+               }
+       }
+
+done:
+       bond_unlock();
+       if (bond_ifp != NULL) {
+               interface_link_event(bond_ifp, event_code);
+       }
+       m_freem(m);
+       if (need_link_update) {
+               if (if_bond_debug != 0) {
+                       printf("bond: simulating link status changed event");
+               }
+               bond_handle_event(port_ifp, KEV_DL_LINK_ON);
+       }
+       return;
+}
+
+static void
+bond_receive_la_marker_pdu(struct mbuf * m, struct ifnet * port_ifp)
+{
+       la_marker_pdu_ref           marker_p;
+       bondport_ref                p;
+
+       marker_p = (la_marker_pdu_ref)(m->m_data + ETHER_HDR_LEN);
+       if (marker_p->lm_marker_tlv_type != LA_MARKER_TLV_TYPE_MARKER) {
+               goto failed;
+       }
+       bond_lock();
+       if ((ifnet_eflags(port_ifp) & IFEF_BOND) == 0) {
+               bond_unlock();
+               goto failed;
+       }
+       p = bond_lookup_port(port_ifp);
+       if (p == NULL || p->po_enabled == 0
+           || p->po_bond->ifb_mode != IF_BOND_MODE_LACP) {
+               bond_unlock();
+               goto failed;
+       }
+       /* echo back the same packet as a marker response */
+       marker_p->lm_marker_tlv_type = LA_MARKER_TLV_TYPE_MARKER_RESPONSE;
+       bondport_slow_proto_transmit(p, (packet_buffer_ref)m);
+       bond_unlock();
+       return;
+
+failed:
+       m_freem(m);
+       return;
+}
+
+static void
+bond_input(ifnet_t port_ifp, mbuf_t m, char *frame_header)
+{
+       bpf_packet_func             bpf_func;
+       const struct ether_header * eh_p;
+       ifbond_ref                  ifb;
+       struct ifnet *              ifp;
+       bondport_ref                p;
+
+       eh_p = (const struct ether_header *)frame_header;
+       if ((m->m_flags & M_MCAST) != 0
+           && bcmp(eh_p->ether_dhost, &slow_proto_multicast,
+           sizeof(eh_p->ether_dhost)) == 0
+           && ntohs(eh_p->ether_type) == IEEE8023AD_SLOW_PROTO_ETHERTYPE) {
+               u_char  subtype = *mtod(m, u_char *);
+
+               if (subtype == IEEE8023AD_SLOW_PROTO_SUBTYPE_LACP) {
+                       if (m->m_pkthdr.len < (int)offsetof(lacpdu, la_reserved)) {
+                               m_freem(m);
+                               return;
+                       }
+                       /* send to lacp */
+                       if (m->m_len < (int)offsetof(lacpdu, la_reserved)) {
+                               m = m_pullup(m, offsetof(lacpdu, la_reserved));
+                               if (m == NULL) {
+                                       return;
+                               }
+                       }
+                       bond_receive_lacpdu(m, port_ifp);
+                       return;
+               } else if (subtype == IEEE8023AD_SLOW_PROTO_SUBTYPE_LA_MARKER_PROTOCOL) {
+                       int         min_size;
+
+                       /* restore the ethernet header pointer in the mbuf */
+                       m->m_pkthdr.len += ETHER_HDR_LEN;
+                       m->m_data -= ETHER_HDR_LEN;
+                       m->m_len += ETHER_HDR_LEN;
+                       min_size = ETHER_HDR_LEN + offsetof(la_marker_pdu, lm_reserved);
+                       if (m->m_pkthdr.len < min_size) {
+                               m_freem(m);
+                               return;
+                       }
+                       /* send to lacp */
+                       if (m->m_len < min_size) {
+                               m = m_pullup(m, min_size);
+                               if (m == NULL) {
+                                       return;
+                               }
+                       }
+                       /* send to marker responder */
+                       bond_receive_la_marker_pdu(m, port_ifp);
+                       return;
+               } else if (subtype == 0
+                   || subtype > IEEE8023AD_SLOW_PROTO_SUBTYPE_RESERVED_END) {
+                       /* invalid subtype, discard the frame */
+                       m_freem(m);
+                       return;
+               }
+       }
+       bond_lock();
+       if ((ifnet_eflags(port_ifp) & IFEF_BOND) == 0) {
+               goto done;
+       }
+       p = bond_lookup_port(port_ifp);
+       if (p == NULL || bondport_collecting(p) == 0) {
+               goto done;
+       }
+
+       ifb = p->po_bond;
+       ifp = ifb->ifb_ifp;
+       bpf_func = ifb->ifb_bpf_input;
+       bond_unlock();
+
+       /*
+        * Need to clear the promiscous flags otherwise it will be
+        * dropped by DLIL after processing filters
+        */
+       if ((mbuf_flags(m) & MBUF_PROMISC)) {
+               mbuf_setflags_mask(m, 0, MBUF_PROMISC);
+       }
+
+       if (m->m_pkthdr.csum_flags & CSUM_VLAN_TAG_VALID) {
+               (void)ifnet_stat_increment_in(ifp, 1,
+                   (m->m_pkthdr.len + ETHER_HDR_LEN
+                   + ETHER_VLAN_ENCAP_LEN), 0);
+       } else {
+               (void)ifnet_stat_increment_in(ifp, 1,
+                   (m->m_pkthdr.len + ETHER_HDR_LEN), 0);
+       }
+
+       /* make the packet appear as if it arrived on the bonded interface */
+       m->m_pkthdr.rcvif = ifp;
+       bond_bpf_input(ifp, m, eh_p, bpf_func);
+       m->m_pkthdr.pkt_hdr = frame_header;
+       dlil_input_packet_list(ifp, m);
+       return;
+
+done:
+       bond_unlock();
+       m_freem(m);
+       return;
+}
+
+static errno_t
+bond_iff_input(void *cookie, ifnet_t port_ifp, protocol_family_t protocol,
+    mbuf_t *data, char **frame_header_ptr)
+{
+#pragma unused(cookie)
+#pragma unused(protocol)
+       mbuf_t                      m = *data;
+       char *                      frame_header = *frame_header_ptr;
+
+       bond_input(port_ifp, m, frame_header);
+       return EJUSTRETURN;
+}
 
 static __inline__ const char *
 bondport_get_name(bondport_ref p)
 {
-    return (p->po_name);
+       return p->po_name;
 }
 
 static __inline__ int
 bondport_get_index(bondport_ref p)
 {
-    return (ifnet_index(p->po_ifp));
+       return ifnet_index(p->po_ifp);
 }
 
 static void
 bondport_slow_proto_transmit(bondport_ref p, packet_buffer_ref buf)
 {
-    struct ether_header *      eh_p;
-    int                                error;
+       struct ether_header *       eh_p;
+       int                         error;
 
-    /* packet_buffer_allocate leaves room for ethernet header */
-    eh_p = mtod(buf, struct ether_header *);
-    bcopy(&slow_proto_multicast, &eh_p->ether_dhost, sizeof(eh_p->ether_dhost));
-    bcopy(&p->po_saved_addr, eh_p->ether_shost, sizeof(eh_p->ether_shost));
-    eh_p->ether_type = htons(IEEE8023AD_SLOW_PROTO_ETHERTYPE);
-    error = ifnet_output_raw(p->po_ifp, PF_BOND, buf);
-    if (error != 0) {
-       printf("bondport_slow_proto_transmit(%s) failed %d\n",
-              bondport_get_name(p), error);
-    }
-    return;
+       /* packet_buffer_allocate leaves room for ethernet header */
+       eh_p = mtod(buf, struct ether_header *);
+       bcopy(&slow_proto_multicast, &eh_p->ether_dhost, sizeof(eh_p->ether_dhost));
+       bcopy(&p->po_saved_addr, eh_p->ether_shost, sizeof(eh_p->ether_shost));
+       eh_p->ether_type = htons(IEEE8023AD_SLOW_PROTO_ETHERTYPE);
+       error = ifnet_output_raw(p->po_ifp, PF_BOND, buf);
+       if (error != 0) {
+               printf("bondport_slow_proto_transmit(%s) failed %d\n",
+                   bondport_get_name(p), error);
+       }
+       return;
 }
 
 static void
-bondport_timer_process_func(devtimer_ref timer, 
-                           devtimer_process_func_event event)
+bondport_timer_process_func(devtimer_ref timer,
+    devtimer_process_func_event event)
 {
-    bondport_ref       p;
+       bondport_ref        p;
 
-    switch (event) {
-    case devtimer_process_func_event_lock:
-       bond_lock();
-       devtimer_retain(timer);
-       break;
-    case devtimer_process_func_event_unlock:
-       if (devtimer_valid(timer)) {
-           /* as long as the devtimer is valid, we can look at arg0 */
-           int                 event_code = 0;
-           struct ifnet *      bond_ifp = NULL;
-
-           p = (bondport_ref)devtimer_arg0(timer);
-           if (ifbond_selection(p->po_bond)) {
-               event_code = (p->po_bond->ifb_active_lag == NULL) 
-                   ? KEV_DL_LINK_OFF 
-                   : KEV_DL_LINK_ON;
-               /* XXX need to take a reference on bond_ifp */
-               bond_ifp = p->po_bond->ifb_ifp;
-               p->po_bond->ifb_last_link_event = event_code;
-           }
-           else {
-               event_code = (p->po_bond->ifb_active_lag == NULL) 
-                   ? KEV_DL_LINK_OFF 
-                   : KEV_DL_LINK_ON;
-               if (event_code != p->po_bond->ifb_last_link_event) {
-                   if (g_bond->verbose) {
-                       timestamp_printf("%s: (timer) generating LINK event\n",
-                                        p->po_bond->ifb_name);
-                   }
-                   bond_ifp = p->po_bond->ifb_ifp;
-                   p->po_bond->ifb_last_link_event = event_code;
-               }
-           }
-           devtimer_release(timer);
-           bond_unlock();
-           if (bond_ifp != NULL) {
-               interface_link_event(bond_ifp, event_code);
-           }
-       }
-       else {
-           /* timer is going away */
-           devtimer_release(timer);
-           bond_unlock();
+       switch (event) {
+       case devtimer_process_func_event_lock:
+               bond_lock();
+               devtimer_retain(timer);
+               break;
+       case devtimer_process_func_event_unlock:
+               if (devtimer_valid(timer)) {
+                       /* as long as the devtimer is valid, we can look at arg0 */
+                       int                 event_code = 0;
+                       struct ifnet *      bond_ifp = NULL;
+
+                       p = (bondport_ref)devtimer_arg0(timer);
+                       if (ifbond_selection(p->po_bond)) {
+                               event_code = (p->po_bond->ifb_active_lag == NULL)
+                                   ? KEV_DL_LINK_OFF
+                                   : KEV_DL_LINK_ON;
+                               /* XXX need to take a reference on bond_ifp */
+                               bond_ifp = p->po_bond->ifb_ifp;
+                               p->po_bond->ifb_last_link_event = event_code;
+                       } else {
+                               event_code = (p->po_bond->ifb_active_lag == NULL)
+                                   ? KEV_DL_LINK_OFF
+                                   : KEV_DL_LINK_ON;
+                               if (event_code != p->po_bond->ifb_last_link_event) {
+                                       if (if_bond_debug) {
+                                               timestamp_printf("%s: (timer) generating LINK event\n",
+                                                   p->po_bond->ifb_name);
+                                       }
+                                       bond_ifp = p->po_bond->ifb_ifp;
+                                       p->po_bond->ifb_last_link_event = event_code;
+                               }
+                       }
+                       devtimer_release(timer);
+                       bond_unlock();
+                       if (bond_ifp != NULL) {
+                               interface_link_event(bond_ifp, event_code);
+                       }
+               } else {
+                       /* timer is going away */
+                       devtimer_release(timer);
+                       bond_unlock();
+               }
+               break;
+       default:
+               break;
        }
-       break;
-    default:
-       break;
-    }
 }
 
 static bondport_ref
 bondport_create(struct ifnet * port_ifp, lacp_port_priority priority,
-               int active, int short_timeout, int * ret_error)
-{
-    int                                error = 0;
-    bondport_ref               p = NULL;
-    lacp_actor_partner_state   s;
-
-    *ret_error = 0;
-    p = _MALLOC(sizeof(*p), M_BOND, M_WAITOK);
-    if (p == NULL) {
-       *ret_error = ENOMEM;
-       return (NULL);
-    }
-    bzero(p, sizeof(*p));
-    multicast_list_init(&p->po_multicast);
-    if ((u_int32_t)snprintf(p->po_name, sizeof(p->po_name), "%s%d",
-                        ifnet_name(port_ifp), ifnet_unit(port_ifp)) 
-       >= sizeof(p->po_name)) {
-       printf("if_bond: name too large\n");
-       *ret_error = EINVAL;
-       goto failed;
-    }
-    error = siocgifdevmtu(port_ifp, &p->po_devmtu);
-    if (error != 0) {
-       printf("if_bond: SIOCGIFDEVMTU %s failed, %d\n",
-              bondport_get_name(p), error);
-       goto failed;
-    }
-    /* remember the current interface MTU so it can be restored */
-    p->po_devmtu.ifdm_current = ifnet_mtu(port_ifp);
-    p->po_ifp = port_ifp;
-    p->po_media_info = interface_media_info(port_ifp);
-    p->po_current_while_timer = devtimer_create(bondport_timer_process_func, p);
-    if (p->po_current_while_timer == NULL) {
-       *ret_error = ENOMEM;
-       goto failed;
-    }
-    p->po_periodic_timer = devtimer_create(bondport_timer_process_func, p);
-    if (p->po_periodic_timer == NULL) {
-       *ret_error = ENOMEM;
-       goto failed;
-    }
-    p->po_wait_while_timer = devtimer_create(bondport_timer_process_func, p);
-    if (p->po_wait_while_timer == NULL) {
-       *ret_error = ENOMEM;
-       goto failed;
-    }
-    p->po_transmit_timer = devtimer_create(bondport_timer_process_func, p);
-    if (p->po_transmit_timer == NULL) {
-       *ret_error = ENOMEM;
-       goto failed;
-    }
-    p->po_receive_state = ReceiveState_none;
-    p->po_mux_state = MuxState_none;
-    p->po_priority = priority;
-    s = 0;
-    s = lacp_actor_partner_state_set_aggregatable(s);
-    if (short_timeout) {
-       s = lacp_actor_partner_state_set_short_timeout(s);
-    }
-    if (active) {
-       s = lacp_actor_partner_state_set_active_lacp(s);
-    }
-    p->po_actor_state = s;
-    return (p);
-
- failed:
-    bondport_free(p);
-    return (NULL);
+    int active, int short_timeout, int * ret_error)
+{
+       int                         error = 0;
+       bondport_ref                p = NULL;
+       lacp_actor_partner_state    s;
+
+       *ret_error = 0;
+       p = _MALLOC(sizeof(*p), M_BOND, M_WAITOK | M_ZERO);
+       if (p == NULL) {
+               *ret_error = ENOMEM;
+               return NULL;
+       }
+       multicast_list_init(&p->po_multicast);
+       if ((u_int32_t)snprintf(p->po_name, sizeof(p->po_name), "%s%d",
+           ifnet_name(port_ifp), ifnet_unit(port_ifp))
+           >= sizeof(p->po_name)) {
+               printf("if_bond: name too large\n");
+               *ret_error = EINVAL;
+               goto failed;
+       }
+       error = siocgifdevmtu(port_ifp, &p->po_devmtu);
+       if (error != 0) {
+               printf("if_bond: SIOCGIFDEVMTU %s failed, %d\n",
+                   bondport_get_name(p), error);
+               goto failed;
+       }
+       /* remember the current interface MTU so it can be restored */
+       p->po_devmtu.ifdm_current = ifnet_mtu(port_ifp);
+       p->po_ifp = port_ifp;
+       p->po_media_info = interface_media_info(port_ifp);
+       p->po_current_while_timer = devtimer_create(bondport_timer_process_func, p);
+       if (p->po_current_while_timer == NULL) {
+               *ret_error = ENOMEM;
+               goto failed;
+       }
+       p->po_periodic_timer = devtimer_create(bondport_timer_process_func, p);
+       if (p->po_periodic_timer == NULL) {
+               *ret_error = ENOMEM;
+               goto failed;
+       }
+       p->po_wait_while_timer = devtimer_create(bondport_timer_process_func, p);
+       if (p->po_wait_while_timer == NULL) {
+               *ret_error = ENOMEM;
+               goto failed;
+       }
+       p->po_transmit_timer = devtimer_create(bondport_timer_process_func, p);
+       if (p->po_transmit_timer == NULL) {
+               *ret_error = ENOMEM;
+               goto failed;
+       }
+       p->po_receive_state = ReceiveState_none;
+       p->po_mux_state = MuxState_none;
+       p->po_priority = priority;
+       s = 0;
+       s = lacp_actor_partner_state_set_aggregatable(s);
+       if (short_timeout) {
+               s = lacp_actor_partner_state_set_short_timeout(s);
+       }
+       if (active) {
+               s = lacp_actor_partner_state_set_active_lacp(s);
+       }
+       p->po_actor_state = s;
+       return p;
+
+failed:
+       bondport_free(p);
+       return NULL;
 }
 
 static void
 bondport_start(bondport_ref p)
 {
-    bondport_receive_machine(p, LAEventStart, NULL);
-    bondport_mux_machine(p, LAEventStart, NULL);
-    bondport_periodic_transmit_machine(p, LAEventStart, NULL);
-    bondport_transmit_machine(p, LAEventStart, NULL);
-    return;
+       bondport_receive_machine(p, LAEventStart, NULL);
+       bondport_mux_machine(p, LAEventStart, NULL);
+       bondport_periodic_transmit_machine(p, LAEventStart, NULL);
+       bondport_transmit_machine(p, LAEventStart, NULL);
+       return;
 }
 
 /*
@@ -1924,10 +2014,10 @@ bondport_start(bondport_ref p)
 static void
 bondport_invalidate_timers(bondport_ref p)
 {
-    devtimer_invalidate(p->po_current_while_timer);
-    devtimer_invalidate(p->po_periodic_timer);
-    devtimer_invalidate(p->po_wait_while_timer);
-    devtimer_invalidate(p->po_transmit_timer);
+       devtimer_invalidate(p->po_current_while_timer);
+       devtimer_invalidate(p->po_periodic_timer);
+       devtimer_invalidate(p->po_wait_while_timer);
+       devtimer_invalidate(p->po_transmit_timer);
 }
 
 /*
@@ -1938,1137 +2028,1209 @@ bondport_invalidate_timers(bondport_ref p)
 static void
 bondport_cancel_timers(bondport_ref p)
 {
-    devtimer_cancel(p->po_current_while_timer);
-    devtimer_cancel(p->po_periodic_timer);
-    devtimer_cancel(p->po_wait_while_timer);
-    devtimer_cancel(p->po_transmit_timer);
+       devtimer_cancel(p->po_current_while_timer);
+       devtimer_cancel(p->po_periodic_timer);
+       devtimer_cancel(p->po_wait_while_timer);
+       devtimer_cancel(p->po_transmit_timer);
 }
 
 static void
 bondport_free(bondport_ref p)
 {
-    multicast_list_remove(&p->po_multicast);
-    devtimer_release(p->po_current_while_timer);
-    devtimer_release(p->po_periodic_timer);
-    devtimer_release(p->po_wait_while_timer);
-    devtimer_release(p->po_transmit_timer);
-    FREE(p, M_BOND);
-    return;
+       multicast_list_remove(&p->po_multicast);
+       devtimer_release(p->po_current_while_timer);
+       devtimer_release(p->po_periodic_timer);
+       devtimer_release(p->po_wait_while_timer);
+       devtimer_release(p->po_transmit_timer);
+       FREE(p, M_BOND);
+       return;
 }
 
-#define BOND_ADD_PROGRESS_IN_LIST              0x1
-#define BOND_ADD_PROGRESS_PROTO_ATTACHED       0x2
-#define BOND_ADD_PROGRESS_LLADDR_SET           0x4
-#define BOND_ADD_PROGRESS_MTU_SET              0x8
-
 static __inline__ int
 bond_device_mtu(struct ifnet * ifp, ifbond_ref ifb)
 {
-    return (((int)ifnet_mtu(ifp) > ifb->ifb_altmtu) 
-           ? (int)ifnet_mtu(ifp) : ifb->ifb_altmtu);
+       return ((int)ifnet_mtu(ifp) > ifb->ifb_altmtu)
+              ? (int)ifnet_mtu(ifp) : ifb->ifb_altmtu;
 }
 
 static int
 bond_add_interface(struct ifnet * ifp, struct ifnet * port_ifp)
 {
-    int                                devmtu;
-    int                                error = 0;
-    int                                event_code = 0;
-    int                                first = FALSE;
-    ifbond_ref                 ifb;
-    bondport_ref *             new_array = NULL;
-    bondport_ref *             old_array = NULL;
-    bondport_ref               p;
-    int                                progress = 0;
-
-    /* pre-allocate space for new port */
-    p = bondport_create(port_ifp, 0x8000, 1, 0, &error);
-    if (p == NULL) {
-       return (error);
-    }
-    bond_lock();
-    ifb = (ifbond_ref)ifnet_softc(ifp);
-    if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+       uint32_t                    control_flags = 0;
+       int                         devmtu;
+       int                         error = 0;
+       int                         event_code = 0;
+       interface_filter_t          filter = NULL;
+       int                         first = FALSE;
+       ifbond_ref                  ifb;
+       bondport_ref *              new_array = NULL;
+       bondport_ref *              old_array = NULL;
+       bondport_ref                p;
+
+       if (IFNET_IS_INTCOPROC(port_ifp)) {
+               return EINVAL;
+       }
+
+       /* pre-allocate space for new port */
+       p = bondport_create(port_ifp, 0x8000, 1, 0, &error);
+       if (p == NULL) {
+               return error;
+       }
+       bond_lock();
+       ifb = (ifbond_ref)ifnet_softc(ifp);
+       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+               bond_unlock();
+               bondport_free(p);
+               return ifb == NULL ? EOPNOTSUPP : EBUSY;
+       }
+
+       /* make sure this interface can handle our current MTU */
+       devmtu = bond_device_mtu(ifp, ifb);
+       if (devmtu != 0
+           && (devmtu > p->po_devmtu.ifdm_max || devmtu < p->po_devmtu.ifdm_min)) {
+               bond_unlock();
+               printf("if_bond: interface %s doesn't support mtu %d",
+                   bondport_get_name(p), devmtu);
+               bondport_free(p);
+               return EINVAL;
+       }
+
+       /* make sure ifb doesn't get de-allocated while we wait */
+       ifbond_retain(ifb);
+
+       /* wait for other add or remove to complete */
+       ifbond_wait(ifb, __func__);
+
+       if (ifbond_flags_if_detaching(ifb)) {
+               /* someone destroyed the bond while we were waiting */
+               error = EBUSY;
+               goto signal_done;
+       }
+       if (bond_lookup_port(port_ifp) != NULL) {
+               /* port is already part of a bond */
+               error = EBUSY;
+               goto signal_done;
+       }
+       ifnet_lock_exclusive(port_ifp);
+       if ((ifnet_eflags(port_ifp) & (IFEF_VLAN | IFEF_BOND)) != 0) {
+               /* interface already has VLAN's, or is part of bond */
+               ifnet_lock_done(port_ifp);
+               error = EBUSY;
+               goto signal_done;
+       }
+
+       /* mark the interface busy */
+       /* can't use ifnet_set_eflags because that takes the lock */
+       port_ifp->if_eflags |= IFEF_BOND;
+       ifnet_lock_done(port_ifp);
+
+       if (TAILQ_EMPTY(&ifb->ifb_port_list)) {
+               ifnet_set_offload(ifp, ifnet_offload(port_ifp));
+               ifnet_set_flags(ifp, IFF_RUNNING, IFF_RUNNING);
+               if (ifbond_flags_lladdr(ifb) == FALSE) {
+                       first = TRUE;
+               }
+       } else {
+               ifnet_offload_t         ifp_offload;
+               ifnet_offload_t         port_ifp_offload;
+
+               ifp_offload = ifnet_offload(ifp);
+               port_ifp_offload = ifnet_offload(port_ifp);
+               if (ifp_offload != port_ifp_offload) {
+                       ifnet_offload_t     offload;
+
+                       offload = ifp_offload & port_ifp_offload;
+                       printf("%s(%s, %s)  "
+                           "hwassist values don't match 0x%x != 0x%x, using 0x%x instead\n",
+                           __func__,
+                           ifb->ifb_name, bondport_get_name(p),
+                           ifp_offload, port_ifp_offload, offload);
+                       /*
+                        * XXX
+                        * if the bond has VLAN's, we can't simply change the hwassist
+                        * field behind its back: this needs work
+                        */
+                       ifnet_set_offload(ifp, offload);
+               }
+       }
+       p->po_bond = ifb;
+
+       /* remember the port's ethernet address so it can be restored */
+       ether_addr_copy(&p->po_saved_addr, IF_LLADDR(port_ifp));
+
+       /* add it to the list of ports */
+       TAILQ_INSERT_TAIL(&ifb->ifb_port_list, p, po_port_list);
+       ifb->ifb_port_count++;
+
        bond_unlock();
-       bondport_free(p);
-       return ((ifb == NULL ? EOPNOTSUPP : EBUSY));
-    }
 
-    /* make sure this interface can handle our current MTU */
-    devmtu = bond_device_mtu(ifp, ifb);
-    if (devmtu != 0 
-       && (devmtu > p->po_devmtu.ifdm_max || devmtu < p->po_devmtu.ifdm_min)) {
+
+       /* first port added to bond determines bond's ethernet address */
+       if (first) {
+               ifnet_set_lladdr_and_type(ifp, IF_LLADDR(port_ifp), ETHER_ADDR_LEN,
+                   IFT_ETHER);
+       }
+
+       control_flags |= PORT_CONTROL_FLAGS_IN_LIST;
+
+       /* allocate a larger distributing array */
+       new_array = (bondport_ref *)
+           _MALLOC(sizeof(*new_array) * ifb->ifb_port_count, M_BOND, M_WAITOK);
+       if (new_array == NULL) {
+               error = ENOMEM;
+               goto failed;
+       }
+
+       /* attach our BOND "protocol" to the interface */
+       error = bond_attach_protocol(port_ifp);
+       if (error) {
+               goto failed;
+       }
+       control_flags |= PORT_CONTROL_FLAGS_PROTO_ATTACHED;
+
+       /* attach our BOND interface filter */
+       error = bond_attach_filter(port_ifp, &filter);
+       if (error != 0) {
+               goto failed;
+       }
+       control_flags |= PORT_CONTROL_FLAGS_FILTER_ATTACHED;
+
+       /* set the interface MTU */
+       devmtu = bond_device_mtu(ifp, ifb);
+       error = siocsifmtu(port_ifp, devmtu);
+       if (error != 0) {
+               printf("%s(%s, %s):"
+                   " SIOCSIFMTU %d failed %d\n",
+                   __func__,
+                   ifb->ifb_name, bondport_get_name(p), devmtu, error);
+               goto failed;
+       }
+       control_flags |= PORT_CONTROL_FLAGS_MTU_SET;
+
+       /* program the port with our multicast addresses */
+       error = multicast_list_program(&p->po_multicast, ifp, port_ifp);
+       if (error) {
+               printf("%s(%s, %s): multicast_list_program failed %d\n",
+                   __func__,
+                   ifb->ifb_name, bondport_get_name(p), error);
+               goto failed;
+       }
+
+       /* mark the interface up */
+       ifnet_set_flags(port_ifp, IFF_UP, IFF_UP);
+
+       error = ifnet_ioctl(port_ifp, 0, SIOCSIFFLAGS, NULL);
+       if (error != 0) {
+               printf("%s(%s, %s): SIOCSIFFLAGS failed %d\n",
+                   __func__,
+                   ifb->ifb_name, bondport_get_name(p), error);
+               goto failed;
+       }
+
+       /* re-program the port's ethernet address */
+       error = if_siflladdr(port_ifp,
+           (const struct ether_addr *)IF_LLADDR(ifp));
+       if (error == 0) {
+               if (memcmp(IF_LLADDR(ifp), IF_LLADDR(port_ifp), ETHER_ADDR_LEN)
+                   != 0) {
+                       /* it lied, it really doesn't support setting lladdr */
+                       error = EOPNOTSUPP;
+               }
+       }
+       if (error != 0) {
+               /* port doesn't support setting the link address */
+               printf("%s(%s, %s): if_siflladdr failed %d\n",
+                   __func__,
+                   ifb->ifb_name, bondport_get_name(p), error);
+               error = ifnet_set_promiscuous(port_ifp, 1);
+               if (error != 0) {
+                       /* port doesn't support setting promiscuous mode */
+                       printf("%s(%s, %s): set promiscuous failed %d\n",
+                           __func__,
+                           ifb->ifb_name, bondport_get_name(p), error);
+                       goto failed;
+               }
+               control_flags |= PORT_CONTROL_FLAGS_PROMISCUOUS_SET;
+       } else {
+               control_flags |= PORT_CONTROL_FLAGS_LLADDR_SET;
+       }
+
+       bond_lock();
+
+       /* no failures past this point */
+       p->po_enabled = 1;
+       p->po_control_flags = control_flags;
+
+       /* copy the contents of the existing distributing array */
+       if (ifb->ifb_distributing_count) {
+               bcopy(ifb->ifb_distributing_array, new_array,
+                   sizeof(*new_array) * ifb->ifb_distributing_count);
+       }
+       old_array = ifb->ifb_distributing_array;
+       ifb->ifb_distributing_array = new_array;
+
+       if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
+               bondport_start(p);
+
+               /* check if we need to generate a link status event */
+               if (ifbond_selection(ifb)) {
+                       event_code = (ifb->ifb_active_lag == NULL)
+                           ? KEV_DL_LINK_OFF
+                           : KEV_DL_LINK_ON;
+                       ifb->ifb_last_link_event = event_code;
+               }
+       } else {
+               /* are we adding the first distributing interface? */
+               if (media_active(&p->po_media_info)) {
+                       if (ifb->ifb_distributing_count == 0) {
+                               ifb->ifb_last_link_event = event_code = KEV_DL_LINK_ON;
+                       }
+                       bondport_enable_distributing(p);
+               } else {
+                       bondport_disable_distributing(p);
+               }
+       }
+       p->po_filter = filter;
+
+       /* clear the busy state, and wakeup anyone waiting */
+       ifbond_signal(ifb, __func__);
        bond_unlock();
-       printf("if_bond: interface %s doesn't support mtu %d",
-              bondport_get_name(p), devmtu);
-       bondport_free(p);
-       return (EINVAL);
-    }
-
-    /* make sure ifb doesn't get de-allocated while we wait */
-    ifbond_retain(ifb);
-
-    /* wait for other add or remove to complete */
-    ifbond_wait(ifb, "bond_add_interface");
-
-    if (ifbond_flags_if_detaching(ifb)) {
-       /* someone destroyed the bond while we were waiting */
-       error = EBUSY;
-       goto signal_done;
-    }
-    if (bond_lookup_port(port_ifp) != NULL) {
-       /* port is already part of a bond */
-       error = EBUSY;
-       goto signal_done;
-    }
-    ifnet_lock_exclusive(port_ifp);
-    if ((ifnet_eflags(port_ifp) & (IFEF_VLAN | IFEF_BOND)) != 0) {
-       /* interface already has VLAN's, or is part of bond */
-       ifnet_lock_done(port_ifp);
-       error = EBUSY;
-       goto signal_done;
-    }
-
-    /* mark the interface busy */
-    /* can't use ifnet_set_eflags because that takes the lock */
-    port_ifp->if_eflags |= IFEF_BOND;
-    ifnet_lock_done(port_ifp);
-
-    if (TAILQ_EMPTY(&ifb->ifb_port_list)) {
-       ifnet_set_offload(ifp, ifnet_offload(port_ifp));
-       ifnet_set_flags(ifp, IFF_RUNNING, IFF_RUNNING);
-       if (ifbond_flags_lladdr(ifb) == FALSE) {
-           first = TRUE;
-       }
-    } else {
-       ifnet_offload_t         ifp_offload;
-       ifnet_offload_t         port_ifp_offload;
-
-       ifp_offload = ifnet_offload(ifp);
-       port_ifp_offload = ifnet_offload(port_ifp);
-       if (ifp_offload != port_ifp_offload) {
-           ifnet_offload_t     offload;
-
-           offload = ifp_offload & port_ifp_offload;
-           printf("bond_add_interface(%s, %s)  "
-                  "hwassist values don't match 0x%x != 0x%x, using 0x%x instead\n",
-                  ifb->ifb_name, bondport_get_name(p),
-                  ifp_offload, port_ifp_offload, offload);
-           /*
-            * XXX
-            * if the bond has VLAN's, we can't simply change the hwassist
-            * field behind its back: this needs work
-            */
-           ifnet_set_offload(ifp, offload);
-       }
-    }
-    p->po_bond = ifb;
-
-    /* remember the port's ethernet address so it can be restored */
-    ether_addr_copy(&p->po_saved_addr, ifnet_lladdr(port_ifp));
-
-    /* add it to the list of ports */
-    TAILQ_INSERT_TAIL(&ifb->ifb_port_list, p, po_port_list);
-    ifb->ifb_port_count++;
-
-    /* set the default MTU */
-    if (ifnet_mtu(ifp) == 0) {
-       ifnet_set_mtu(ifp, ETHERMTU);
-    }
-    bond_unlock();
-
-
-    /* first port added to bond determines bond's ethernet address */
-    if (first) {
-       ifnet_set_lladdr_and_type(ifp, ifnet_lladdr(port_ifp), ETHER_ADDR_LEN,
-                                 IFT_ETHER);
-    }
-
-    progress |= BOND_ADD_PROGRESS_IN_LIST;
-
-    /* allocate a larger distributing array */
-    new_array = (bondport_ref *)
-       _MALLOC(sizeof(*new_array) * ifb->ifb_port_count, M_BOND, M_WAITOK);
-    if (new_array == NULL) {
-       error = ENOMEM;
-       goto failed;
-    }
-
-    /* attach our BOND "protocol" to the interface */
-    error = bond_attach_protocol(port_ifp);
-    if (error) {
-       goto failed;
-    }
-    progress |= BOND_ADD_PROGRESS_PROTO_ATTACHED;
-
-    /* set the interface MTU */
-    devmtu = bond_device_mtu(ifp, ifb);
-    error = siocsifmtu(port_ifp, devmtu);
-    if (error != 0) {
-       printf("bond_add_interface(%s, %s):"
-              " SIOCSIFMTU %d failed %d\n", 
-              ifb->ifb_name, bondport_get_name(p), devmtu, error);
-       goto failed;
-    }
-    progress |= BOND_ADD_PROGRESS_MTU_SET;
-
-    /* program the port with our multicast addresses */
-    error = multicast_list_program(&p->po_multicast, ifp, port_ifp);
-    if (error) {
-       printf("bond_add_interface(%s, %s):"
-              " multicast_list_program failed %d\n", 
-              ifb->ifb_name, bondport_get_name(p), error);
-       goto failed;
-    }
-
-    /* mark the interface up */
-    ifnet_set_flags(port_ifp, IFF_UP, IFF_UP);
-
-    error = ifnet_ioctl(port_ifp, 0, SIOCSIFFLAGS, NULL);
-    if (error != 0) {
-       printf("bond_add_interface(%s, %s): SIOCSIFFLAGS failed %d\n", 
-              ifb->ifb_name, bondport_get_name(p), error);
-       goto failed;
-    }
-
-    /* re-program the port's ethernet address */
-    error = if_siflladdr(port_ifp, 
-                        (const struct ether_addr *)ifnet_lladdr(ifp));
-    if (error != 0) {
-       /* port doesn't support setting the link address */
-       printf("bond_add_interface(%s, %s): if_siflladdr failed %d\n", 
-              ifb->ifb_name, bondport_get_name(p), error);
-       goto failed;
-    }
-    progress |= BOND_ADD_PROGRESS_LLADDR_SET;
-
-    bond_lock();
-
-    /* no failures past this point */
-    p->po_enabled = 1;
-
-    /* copy the contents of the existing distributing array */
-    if (ifb->ifb_distributing_count) {
-       bcopy(ifb->ifb_distributing_array, new_array, 
-             sizeof(*new_array) * ifb->ifb_distributing_count);
-    }
-    old_array = ifb->ifb_distributing_array;
-    ifb->ifb_distributing_array = new_array;
-
-    if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
-       bondport_start(p);
+       if (event_code != 0) {
+               interface_link_event(ifp, event_code);
+       }
+       if (old_array != NULL) {
+               FREE(old_array, M_BOND);
+       }
+       return 0;
 
-       /* check if we need to generate a link status event */
-       if (ifbond_selection(ifb)) {
-           event_code = (ifb->ifb_active_lag == NULL) 
-               ? KEV_DL_LINK_OFF 
-               : KEV_DL_LINK_ON;
-           ifb->ifb_last_link_event = event_code;
-       }
-    }
-    else {
-       /* are we adding the first distributing interface? */
-       if (media_active(&p->po_media_info)) {
-           if (ifb->ifb_distributing_count == 0) {
-               ifb->ifb_last_link_event = event_code = KEV_DL_LINK_ON;
-           }
-           bondport_enable_distributing(p);
-       }
-       else {
-           bondport_disable_distributing(p);
-       }
-    }
-    /* clear the busy state, and wakeup anyone waiting */
-    ifbond_signal(ifb, "bond_add_interface");
-    bond_unlock();
-    if (event_code != 0) {
-       interface_link_event(ifp, event_code);
-    }
-    if (old_array != NULL) {
-       FREE(old_array, M_BOND);
-    }
-    return 0;
-
- failed:
-    bond_assert_lock_not_held();
-
-    /* if this was the first port to be added, clear our address */
-    if (first) {
-       ifnet_set_lladdr_and_type(ifp, NULL, 0, IFT_IEEE8023ADLAG);
-    }
-
-    if (new_array != NULL) {
-       FREE(new_array, M_BOND);
-    }
-    if ((progress & BOND_ADD_PROGRESS_LLADDR_SET) != 0) {
-       int     error1;
-
-       error1 = if_siflladdr(port_ifp, &p->po_saved_addr);
-       if (error1 != 0) {
-           printf("bond_add_interface(%s, %s): if_siflladdr failed %d\n", 
-                  ifb->ifb_name, bondport_get_name(p), error1);
-       }
-    }
-    if ((progress & BOND_ADD_PROGRESS_PROTO_ATTACHED) != 0) {
-       (void)bond_detach_protocol(port_ifp);
-    }
-    if ((progress & BOND_ADD_PROGRESS_MTU_SET) != 0) {
-       int error1;
-
-       error1 = siocsifmtu(port_ifp, p->po_devmtu.ifdm_current);
-       if (error1 != 0) {
-           printf("bond_add_interface(%s, %s): SIOCSIFMTU %d failed %d\n", 
-                  ifb->ifb_name, bondport_get_name(p),
-                  p->po_devmtu.ifdm_current, error1);
-       }
-    }
-    bond_lock();
-    if ((progress & BOND_ADD_PROGRESS_IN_LIST) != 0) {
-       TAILQ_REMOVE(&ifb->ifb_port_list, p, po_port_list);
-       ifb->ifb_port_count--;
-    }
-    ifnet_set_eflags(ifp, 0, IFEF_BOND);
-    if (TAILQ_EMPTY(&ifb->ifb_port_list)) {
-       ifb->ifb_altmtu = 0;
-       ifnet_set_mtu(ifp, 0);
-       ifnet_set_offload(ifp, 0);
-    }
+failed:
+       bond_assert_lock_not_held();
+
+       /* if this was the first port to be added, clear our address */
+       if (first) {
+               ifnet_set_lladdr_and_type(ifp, NULL, 0, IFT_IEEE8023ADLAG);
+       }
+
+       if (new_array != NULL) {
+               FREE(new_array, M_BOND);
+       }
+       if ((control_flags & PORT_CONTROL_FLAGS_LLADDR_SET) != 0) {
+               int     error1;
+
+               error1 = if_siflladdr(port_ifp, &p->po_saved_addr);
+               if (error1 != 0) {
+                       printf("%s(%s, %s): if_siflladdr restore failed %d\n",
+                           __func__,
+                           ifb->ifb_name, bondport_get_name(p), error1);
+               }
+       }
+       if ((control_flags & PORT_CONTROL_FLAGS_PROMISCUOUS_SET) != 0) {
+               int     error1;
 
- signal_done:
-    ifbond_signal(ifb, "bond_add_interface");
-    bond_unlock();
-    ifbond_release(ifb);
-    bondport_free(p);
-    return (error);
+               error1 = ifnet_set_promiscuous(port_ifp, 0);
+               if (error1 != 0) {
+                       printf("%s(%s, %s): promiscous mode disable failed %d\n",
+                           __func__,
+                           ifb->ifb_name, bondport_get_name(p), error1);
+               }
+       }
+       if ((control_flags & PORT_CONTROL_FLAGS_PROTO_ATTACHED) != 0) {
+               (void)bond_detach_protocol(port_ifp);
+       }
+       if ((control_flags & PORT_CONTROL_FLAGS_FILTER_ATTACHED) != 0) {
+               iflt_detach(filter);
+       }
+       if ((control_flags & PORT_CONTROL_FLAGS_MTU_SET) != 0) {
+               int error1;
+
+               error1 = siocsifmtu(port_ifp, p->po_devmtu.ifdm_current);
+               if (error1 != 0) {
+                       printf("%s(%s, %s): SIOCSIFMTU %d failed %d\n",
+                           __func__,
+                           ifb->ifb_name, bondport_get_name(p),
+                           p->po_devmtu.ifdm_current, error1);
+               }
+       }
+       bond_lock();
+       if ((control_flags & PORT_CONTROL_FLAGS_IN_LIST) != 0) {
+               TAILQ_REMOVE(&ifb->ifb_port_list, p, po_port_list);
+               ifb->ifb_port_count--;
+       }
+       ifnet_set_eflags(ifp, 0, IFEF_BOND);
+       if (TAILQ_EMPTY(&ifb->ifb_port_list)) {
+               ifb->ifb_altmtu = 0;
+               ifnet_set_mtu(ifp, ETHERMTU);
+               ifnet_set_offload(ifp, 0);
+       }
+
+signal_done:
+       ifbond_signal(ifb, __func__);
+       bond_unlock();
+       ifbond_release(ifb);
+       bondport_free(p);
+       return error;
 }
 
 static int
 bond_remove_interface(ifbond_ref ifb, struct ifnet * port_ifp)
 {
-    int                                active_lag = 0;
-    int                        error = 0;
-    int                                event_code = 0;
-    bondport_ref               head_port;
-    struct ifnet *             ifp;
-    int                                last = FALSE;
-    int                                new_link_address = FALSE;
-    bondport_ref               p;
-    lacp_actor_partner_state   s;
-    int                                was_distributing;
-
-    bond_assert_lock_held();
-
-    ifbond_retain(ifb);
-    ifbond_wait(ifb, "bond_remove_interface");
-
-    p = ifbond_lookup_port(ifb, port_ifp);
-    if (p == NULL) {
-       error = ENXIO;
-       /* it got removed by another thread */
-       goto signal_done;
-    }
-
-    /* de-select it and remove it from the lists */
-    was_distributing = bondport_flags_distributing(p);
-    bondport_disable_distributing(p);
-    if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
-       bondport_set_selected(p, SelectedState_UNSELECTED);
-       active_lag = bondport_remove_from_LAG(p);
-       /* invalidate timers here while holding the bond_lock */
-       bondport_invalidate_timers(p);
-
-       /* announce that we're Individual now */
-       s = p->po_actor_state;
-       s = lacp_actor_partner_state_set_individual(s);
-       s = lacp_actor_partner_state_set_not_collecting(s);
-       s = lacp_actor_partner_state_set_not_distributing(s);
-       s = lacp_actor_partner_state_set_out_of_sync(s);
-       p->po_actor_state = s;
-       bondport_flags_set_ntt(p);
-    }
+       int                         active_lag = 0;
+       int                         error = 0;
+       int                         event_code = 0;
+       bondport_ref                head_port;
+       struct ifnet *              ifp;
+       interface_filter_t          filter;
+       int                         last = FALSE;
+       int                         new_link_address = FALSE;
+       bondport_ref                p;
+       lacp_actor_partner_state    s;
+       int                         was_distributing;
 
-    TAILQ_REMOVE(&ifb->ifb_port_list, p, po_port_list);
-    ifb->ifb_port_count--;
+       bond_assert_lock_held();
 
-    ifp = ifb->ifb_ifp;
-    head_port = TAILQ_FIRST(&ifb->ifb_port_list);
-    if (head_port == NULL) {
-       ifnet_set_flags(ifp, 0, IFF_RUNNING);
-       if (ifbond_flags_lladdr(ifb) == FALSE) {
-           last = TRUE;
+       ifbond_retain(ifb);
+       ifbond_wait(ifb, "bond_remove_interface");
+
+       p = ifbond_lookup_port(ifb, port_ifp);
+       if (p == NULL) {
+               error = ENXIO;
+               /* it got removed by another thread */
+               goto signal_done;
        }
-       ifnet_set_offload(ifp, 0);
-       ifnet_set_mtu(ifp, 0);
-       ifb->ifb_altmtu = 0;
-    } else if (ifbond_flags_lladdr(ifb) == FALSE
-              && bcmp(&p->po_saved_addr, ifnet_lladdr(ifp), 
-                      ETHER_ADDR_LEN) == 0) {
-       new_link_address = TRUE;
-    }
-    /* check if we need to generate a link status event */
-    if (ifb->ifb_mode == IF_BOND_MODE_LACP ) {
-       if (ifbond_selection(ifb) || active_lag) {
-           event_code = (ifb->ifb_active_lag == NULL) 
-               ? KEV_DL_LINK_OFF 
-               : KEV_DL_LINK_ON;
-           ifb->ifb_last_link_event = event_code;
-       }
-       bondport_transmit_machine(p, LAEventStart,
-                                 TRANSMIT_MACHINE_TX_IMMEDIATE);
-    }
-    else {
-       /* are we removing the last distributing interface? */
-       if (was_distributing && ifb->ifb_distributing_count == 0) {
-           ifb->ifb_last_link_event = event_code = KEV_DL_LINK_OFF;
-       }
-    }
-
-    bond_unlock();
-
-    if (last) {
-       ifnet_set_lladdr_and_type(ifp, NULL, 0, IFT_IEEE8023ADLAG);
-    }
-    else if (new_link_address) {
-       struct ifnet *  scan_ifp;
-       bondport_ref    scan_port;
-
-       /* ifbond_wait() allows port list traversal without holding the lock */
-
-       /* this port gave the bond its ethernet address, switch to new one */
-       ifnet_set_lladdr_and_type(ifp,
-                                 &head_port->po_saved_addr, ETHER_ADDR_LEN,
-                                 IFT_ETHER);
-
-       /* re-program each port with the new link address */
-       TAILQ_FOREACH(scan_port, &ifb->ifb_port_list, po_port_list) {
-           scan_ifp = scan_port->po_ifp;
-
-           error = if_siflladdr(scan_ifp,
-                                (const struct ether_addr *) ifnet_lladdr(ifp));
-           if (error != 0) {
-               printf("bond_remove_interface(%s, %s): "
-                      "if_siflladdr (%s) failed %d\n", 
-                      ifb->ifb_name, bondport_get_name(p),
-                      bondport_get_name(scan_port), error);
-           }
-       }
-    }
-
-    /* restore the port's ethernet address */
-    error = if_siflladdr(port_ifp, &p->po_saved_addr);
-    if (error != 0) {
-       printf("bond_remove_interface(%s, %s): if_siflladdr failed %d\n", 
-              ifb->ifb_name, bondport_get_name(p), error);
-    }
-
-    /* restore the port's MTU */
-    error = siocsifmtu(port_ifp, p->po_devmtu.ifdm_current);
-    if (error != 0) {
-       printf("bond_remove_interface(%s, %s): SIOCSIFMTU %d failed %d\n", 
-              ifb->ifb_name, bondport_get_name(p), 
-              p->po_devmtu.ifdm_current, error);
-    }
-
-    /* remove the bond "protocol" */
-    bond_detach_protocol(port_ifp);
-
-    /* generate link event */
-    if (event_code != 0) {
-       interface_link_event(ifp, event_code);
-    }
-
-    bond_lock();
-    bondport_free(p);
-    ifnet_set_eflags(port_ifp, 0, IFEF_BOND);
-    /* release this bondport's reference to the ifbond */
-    ifbond_release(ifb);
-
- signal_done:
-    ifbond_signal(ifb, "bond_remove_interface");
-    ifbond_release(ifb);
-    return (error);
+
+       /* de-select it and remove it from the lists */
+       was_distributing = bondport_flags_distributing(p);
+       bondport_disable_distributing(p);
+       if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
+               bondport_set_selected(p, SelectedState_UNSELECTED);
+               active_lag = bondport_remove_from_LAG(p);
+               /* invalidate timers here while holding the bond_lock */
+               bondport_invalidate_timers(p);
+
+               /* announce that we're Individual now */
+               s = p->po_actor_state;
+               s = lacp_actor_partner_state_set_individual(s);
+               s = lacp_actor_partner_state_set_not_collecting(s);
+               s = lacp_actor_partner_state_set_not_distributing(s);
+               s = lacp_actor_partner_state_set_out_of_sync(s);
+               p->po_actor_state = s;
+               bondport_flags_set_ntt(p);
+       }
+
+       TAILQ_REMOVE(&ifb->ifb_port_list, p, po_port_list);
+       ifb->ifb_port_count--;
+
+       ifp = ifb->ifb_ifp;
+       head_port = TAILQ_FIRST(&ifb->ifb_port_list);
+       if (head_port == NULL) {
+               ifnet_set_flags(ifp, 0, IFF_RUNNING);
+               if (ifbond_flags_lladdr(ifb) == FALSE) {
+                       last = TRUE;
+               }
+               ifnet_set_offload(ifp, 0);
+               ifnet_set_mtu(ifp, ETHERMTU);
+               ifb->ifb_altmtu = 0;
+       } else if (ifbond_flags_lladdr(ifb) == FALSE
+           && bcmp(&p->po_saved_addr, IF_LLADDR(ifp),
+           ETHER_ADDR_LEN) == 0) {
+               new_link_address = TRUE;
+       }
+       /* check if we need to generate a link status event */
+       if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
+               if (ifbond_selection(ifb) || active_lag) {
+                       event_code = (ifb->ifb_active_lag == NULL)
+                           ? KEV_DL_LINK_OFF
+                           : KEV_DL_LINK_ON;
+                       ifb->ifb_last_link_event = event_code;
+               }
+               bondport_transmit_machine(p, LAEventStart,
+                   TRANSMIT_MACHINE_TX_IMMEDIATE);
+       } else {
+               /* are we removing the last distributing interface? */
+               if (was_distributing && ifb->ifb_distributing_count == 0) {
+                       ifb->ifb_last_link_event = event_code = KEV_DL_LINK_OFF;
+               }
+       }
+       filter = p->po_filter;
+       bond_unlock();
+
+       if (last) {
+               ifnet_set_lladdr_and_type(ifp, NULL, 0, IFT_IEEE8023ADLAG);
+       } else if (new_link_address) {
+               struct ifnet *  scan_ifp;
+               bondport_ref    scan_port;
+
+               /* ifbond_wait() allows port list traversal without holding the lock */
+
+               /* this port gave the bond its ethernet address, switch to new one */
+               ifnet_set_lladdr_and_type(ifp,
+                   &head_port->po_saved_addr, ETHER_ADDR_LEN,
+                   IFT_ETHER);
+
+               /* re-program each port with the new link address */
+               TAILQ_FOREACH(scan_port, &ifb->ifb_port_list, po_port_list) {
+                       scan_ifp = scan_port->po_ifp;
+
+                       if ((scan_port->po_control_flags &
+                           PORT_CONTROL_FLAGS_LLADDR_SET) == 0) {
+                               /* port doesn't support setting lladdr */
+                               continue;
+                       }
+                       error = if_siflladdr(scan_ifp,
+                           (const struct ether_addr *) IF_LLADDR(ifp));
+                       if (error != 0) {
+                               printf("%s(%s, %s): "
+                                   "if_siflladdr (%s) failed %d\n",
+                                   __func__,
+                                   ifb->ifb_name, bondport_get_name(p),
+                                   bondport_get_name(scan_port), error);
+                       }
+               }
+       }
+
+       /* restore the port's ethernet address */
+       if ((p->po_control_flags & PORT_CONTROL_FLAGS_LLADDR_SET) != 0) {
+               error = if_siflladdr(port_ifp, &p->po_saved_addr);
+               if (error != 0) {
+                       printf("%s(%s, %s): if_siflladdr failed %d\n",
+                           __func__,
+                           ifb->ifb_name, bondport_get_name(p), error);
+               }
+       }
+
+       /* disable promiscous mode (if we enabled it) */
+       if ((p->po_control_flags & PORT_CONTROL_FLAGS_PROMISCUOUS_SET) != 0) {
+               error = ifnet_set_promiscuous(port_ifp, 0);
+               if (error != 0) {
+                       printf("%s(%s, %s): disable promiscuous failed %d\n",
+                           __func__,
+                           ifb->ifb_name, bondport_get_name(p), error);
+               }
+       }
+
+       /* restore the port's MTU */
+       error = siocsifmtu(port_ifp, p->po_devmtu.ifdm_current);
+       if (error != 0) {
+               printf("%s(%s, %s): SIOCSIFMTU %d failed %d\n",
+                   __func__,
+                   ifb->ifb_name, bondport_get_name(p),
+                   p->po_devmtu.ifdm_current, error);
+       }
+
+       /* remove the bond "protocol" */
+       bond_detach_protocol(port_ifp);
+
+       /* detach the filter */
+       if (filter != NULL) {
+               iflt_detach(filter);
+       }
+
+       /* generate link event */
+       if (event_code != 0) {
+               interface_link_event(ifp, event_code);
+       }
+
+       bond_lock();
+       bondport_free(p);
+       ifnet_set_eflags(port_ifp, 0, IFEF_BOND);
+       /* release this bondport's reference to the ifbond */
+       ifbond_release(ifb);
+
+signal_done:
+       ifbond_signal(ifb, __func__);
+       ifbond_release(ifb);
+       return error;
 }
 
 static void
 bond_set_lacp_mode(ifbond_ref ifb)
 {
-    bondport_ref               p;
+       bondport_ref                p;
 
-    TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
-       bondport_disable_distributing(p);
-       bondport_start(p);
-    }
-    return;
+       TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
+               bondport_disable_distributing(p);
+               bondport_start(p);
+       }
+       return;
 }
 
 static void
 bond_set_static_mode(ifbond_ref ifb)
 {
-    bondport_ref               p;
-    lacp_actor_partner_state   s;
+       bondport_ref                p;
+       lacp_actor_partner_state    s;
 
-    TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
-       bondport_disable_distributing(p);
-       bondport_set_selected(p, SelectedState_UNSELECTED);
-       (void)bondport_remove_from_LAG(p);
-       bondport_cancel_timers(p);
-
-       /* announce that we're Individual now */
-       s = p->po_actor_state;
-       s = lacp_actor_partner_state_set_individual(s);
-       s = lacp_actor_partner_state_set_not_collecting(s);
-       s = lacp_actor_partner_state_set_not_distributing(s);
-       s = lacp_actor_partner_state_set_out_of_sync(s);
-       p->po_actor_state = s;
-       bondport_flags_set_ntt(p);
-       bondport_transmit_machine(p, LAEventStart,
-                                 TRANSMIT_MACHINE_TX_IMMEDIATE);
-       /* clear state */
-       p->po_actor_state = 0;
-       bzero(&p->po_partner_state, sizeof(p->po_partner_state));
-
-       if (media_active(&p->po_media_info)) {
-           bondport_enable_distributing(p);
-       }
-       else {
-           bondport_disable_distributing(p);
+       TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
+               bondport_disable_distributing(p);
+               bondport_set_selected(p, SelectedState_UNSELECTED);
+               (void)bondport_remove_from_LAG(p);
+               bondport_cancel_timers(p);
+
+               /* announce that we're Individual now */
+               s = p->po_actor_state;
+               s = lacp_actor_partner_state_set_individual(s);
+               s = lacp_actor_partner_state_set_not_collecting(s);
+               s = lacp_actor_partner_state_set_not_distributing(s);
+               s = lacp_actor_partner_state_set_out_of_sync(s);
+               p->po_actor_state = s;
+               bondport_flags_set_ntt(p);
+               bondport_transmit_machine(p, LAEventStart,
+                   TRANSMIT_MACHINE_TX_IMMEDIATE);
+               /* clear state */
+               p->po_actor_state = 0;
+               bzero(&p->po_partner_state, sizeof(p->po_partner_state));
+
+               if (media_active(&p->po_media_info)) {
+                       bondport_enable_distributing(p);
+               } else {
+                       bondport_disable_distributing(p);
+               }
        }
-    }
-    return;
+       return;
 }
 
 static int
 bond_set_mode(struct ifnet * ifp, int mode)
 {
-    int                                error = 0;
-    int                                event_code = 0;
-    ifbond_ref                 ifb;
+       int                         error = 0;
+       int                         event_code = 0;
+       ifbond_ref                  ifb;
 
-    bond_lock();
-    ifb = (ifbond_ref)ifnet_softc(ifp);
-    if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
-       bond_unlock();
-       return ((ifb == NULL) ? EOPNOTSUPP : EBUSY);
-    }
-    if (ifb->ifb_mode == mode) {
-       bond_unlock();
-       return (0);
-    }
-
-    ifbond_retain(ifb);
-    ifbond_wait(ifb, "bond_set_mode");
-
-    /* verify (again) that the mode is actually different */
-    if (ifb->ifb_mode == mode) {
-       /* nothing to do */
-       goto signal_done;
-    }
-
-    ifb->ifb_mode = mode;
-    if (mode == IF_BOND_MODE_LACP) {
-       bond_set_lacp_mode(ifb);
-       
-       /* check if we need to generate a link status event */
-       if (ifbond_selection(ifb)) {
-           event_code = (ifb->ifb_active_lag == NULL) 
-               ? KEV_DL_LINK_OFF 
-               : KEV_DL_LINK_ON;
+       bond_lock();
+       ifb = (ifbond_ref)ifnet_softc(ifp);
+       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+               bond_unlock();
+               return (ifb == NULL) ? EOPNOTSUPP : EBUSY;
+       }
+       if (ifb->ifb_mode == mode) {
+               bond_unlock();
+               return 0;
+       }
+
+       ifbond_retain(ifb);
+       ifbond_wait(ifb, "bond_set_mode");
+
+       /* verify (again) that the mode is actually different */
+       if (ifb->ifb_mode == mode) {
+               /* nothing to do */
+               goto signal_done;
+       }
+
+       ifb->ifb_mode = mode;
+       if (mode == IF_BOND_MODE_LACP) {
+               bond_set_lacp_mode(ifb);
+
+               /* check if we need to generate a link status event */
+               if (ifbond_selection(ifb)) {
+                       event_code = (ifb->ifb_active_lag == NULL)
+                           ? KEV_DL_LINK_OFF
+                           : KEV_DL_LINK_ON;
+               }
+       } else {
+               bond_set_static_mode(ifb);
+               event_code = (ifb->ifb_distributing_count == 0)
+                   ? KEV_DL_LINK_OFF
+                   : KEV_DL_LINK_ON;
        }
-    } else {
-       bond_set_static_mode(ifb);
-       event_code = (ifb->ifb_distributing_count == 0) 
-           ? KEV_DL_LINK_OFF 
-           : KEV_DL_LINK_ON;
-    }
-    ifb->ifb_last_link_event = event_code;
+       ifb->ifb_last_link_event = event_code;
 
- signal_done:
-    ifbond_signal(ifb, "bond_set_mode");
-    bond_unlock();
-    ifbond_release(ifb);
+signal_done:
+       ifbond_signal(ifb, __func__);
+       bond_unlock();
+       ifbond_release(ifb);
 
-    if (event_code != 0) {
-       interface_link_event(ifp, event_code);
-    }
-    return (error);
+       if (event_code != 0) {
+               interface_link_event(ifp, event_code);
+       }
+       return error;
 }
 
 static int
 bond_get_status(ifbond_ref ifb, struct if_bond_req * ibr_p, user_addr_t datap)
 {
-    int                                count;
-    user_addr_t                        dst;
-    int                                error = 0;
-    struct if_bond_status_req *        ibsr;
-    struct if_bond_status      ibs;
-    bondport_ref               port;
-
-    ibsr = &(ibr_p->ibr_ibru.ibru_status);
-    if (ibsr->ibsr_version != IF_BOND_STATUS_REQ_VERSION) {
-       return (EINVAL);
-    }
-    ibsr->ibsr_key = ifb->ifb_key;
-    ibsr->ibsr_mode = ifb->ifb_mode;
-    ibsr->ibsr_total = ifb->ifb_port_count;
-    dst = proc_is64bit(current_proc())
-       ? ibsr->ibsr_ibsru.ibsru_buffer64
-       : CAST_USER_ADDR_T(ibsr->ibsr_ibsru.ibsru_buffer);
-    if (dst == USER_ADDR_NULL) {
-       /* just want to know how many there are */
-       goto done;
-    }
-    if (ibsr->ibsr_count < 0) {
-       return (EINVAL);
-    }
-    count = (ifb->ifb_port_count < ibsr->ibsr_count) 
-       ? ifb->ifb_port_count : ibsr->ibsr_count;
-    TAILQ_FOREACH(port, &ifb->ifb_port_list, po_port_list) {
-       struct if_bond_partner_state *  ibps_p;
-       partner_state_ref               ps;
-
-       if (count == 0) {
-           break;
-       }
-       bzero(&ibs, sizeof(ibs));
-       strncpy(ibs.ibs_if_name, port->po_name, sizeof(ibs.ibs_if_name));
-       ibs.ibs_port_priority = port->po_priority;
-       if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
-           ibs.ibs_state = port->po_actor_state;
-           ibs.ibs_selected_state = port->po_selected;
-           ps = &port->po_partner_state;
-           ibps_p = &ibs.ibs_partner_state;
-           ibps_p->ibps_system = ps->ps_lag_info.li_system;
-           ibps_p->ibps_system_priority = ps->ps_lag_info.li_system_priority;
-           ibps_p->ibps_key = ps->ps_lag_info.li_key;
-           ibps_p->ibps_port = ps->ps_port;
-           ibps_p->ibps_port_priority = ps->ps_port_priority;
-           ibps_p->ibps_state = ps->ps_state;
-       }
-       else {
-           /* fake the selected information */
-           ibs.ibs_selected_state = bondport_flags_distributing(port)
-               ? SelectedState_SELECTED : SelectedState_UNSELECTED;
-       }
-       error = copyout(&ibs, dst, sizeof(ibs));
-       if (error != 0) {
-           break;
+       int                         count;
+       user_addr_t                 dst;
+       int                         error = 0;
+       struct if_bond_status_req * ibsr;
+       struct if_bond_status       ibs;
+       bondport_ref                port;
+
+       ibsr = &(ibr_p->ibr_ibru.ibru_status);
+       if (ibsr->ibsr_version != IF_BOND_STATUS_REQ_VERSION) {
+               return EINVAL;
+       }
+       ibsr->ibsr_key = ifb->ifb_key;
+       ibsr->ibsr_mode = ifb->ifb_mode;
+       ibsr->ibsr_total = ifb->ifb_port_count;
+       dst = proc_is64bit(current_proc())
+           ? ibsr->ibsr_ibsru.ibsru_buffer64
+           : CAST_USER_ADDR_T(ibsr->ibsr_ibsru.ibsru_buffer);
+       if (dst == USER_ADDR_NULL) {
+               /* just want to know how many there are */
+               goto done;
+       }
+       if (ibsr->ibsr_count < 0) {
+               return EINVAL;
+       }
+       count = (ifb->ifb_port_count < ibsr->ibsr_count)
+           ? ifb->ifb_port_count : ibsr->ibsr_count;
+       TAILQ_FOREACH(port, &ifb->ifb_port_list, po_port_list) {
+               struct if_bond_partner_state *  ibps_p;
+               partner_state_ref               ps;
+
+               if (count == 0) {
+                       break;
+               }
+               bzero(&ibs, sizeof(ibs));
+               strlcpy(ibs.ibs_if_name, port->po_name, sizeof(ibs.ibs_if_name));
+               ibs.ibs_port_priority = port->po_priority;
+               if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
+                       ibs.ibs_state = port->po_actor_state;
+                       ibs.ibs_selected_state = port->po_selected;
+                       ps = &port->po_partner_state;
+                       ibps_p = &ibs.ibs_partner_state;
+                       ibps_p->ibps_system = ps->ps_lag_info.li_system;
+                       ibps_p->ibps_system_priority = ps->ps_lag_info.li_system_priority;
+                       ibps_p->ibps_key = ps->ps_lag_info.li_key;
+                       ibps_p->ibps_port = ps->ps_port;
+                       ibps_p->ibps_port_priority = ps->ps_port_priority;
+                       ibps_p->ibps_state = ps->ps_state;
+               } else {
+                       /* fake the selected information */
+                       ibs.ibs_selected_state = bondport_flags_distributing(port)
+                           ? SelectedState_SELECTED : SelectedState_UNSELECTED;
+               }
+               error = copyout(&ibs, dst, sizeof(ibs));
+               if (error != 0) {
+                       break;
+               }
+               dst += sizeof(ibs);
+               count--;
        }
-       dst += sizeof(ibs);
-       count--;
-    }
 
- done:
-    if (error == 0) {
-       error = copyout(ibr_p, datap, sizeof(*ibr_p));
-    }
-    else {
-       (void)copyout(ibr_p, datap, sizeof(*ibr_p));
-    }
-    return (error);
+done:
+       if (error == 0) {
+               error = copyout(ibr_p, datap, sizeof(*ibr_p));
+       } else {
+               (void)copyout(ibr_p, datap, sizeof(*ibr_p));
+       }
+       return error;
 }
 
 static int
 bond_set_promisc(__unused struct ifnet *ifp)
 {
-    int                error = 0;
-#if 0
-    ifbond_ref ifb = ifnet_softc(ifp);
-
-
-    if ((ifnet_flags(ifp) & IFF_PROMISC) != 0) {
-       if ((ifb->ifb_flags & IFBF_PROMISC) == 0) {
-           error = ifnet_set_promiscuous(ifb->ifb_p, 1);
-           if (error == 0)
-               ifb->ifb_flags |= IFBF_PROMISC;
-       }
-    } else {
-       if ((ifb->ifb_flags & IFBF_PROMISC) != 0) {
-           error = ifnet_set_promiscuous(ifb->ifb_p, 0);
-           if (error == 0)
-               ifb->ifb_flags &= ~IFBF_PROMISC;
-       }
-    }
-#endif
-    return (error);
+       int                 error = 0;
+       return error;
 }
 
 static void
 bond_get_mtu_values(ifbond_ref ifb, int * ret_min, int * ret_max)
 {
-    int                                mtu_min = 0;
-    int                                mtu_max = 0;
-    bondport_ref               p;
-
-    if (TAILQ_FIRST(&ifb->ifb_port_list) != NULL) {
-       mtu_min = IF_MINMTU;
-    }
-    TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
-       struct ifdevmtu *       devmtu_p = &p->po_devmtu;
+       int                         mtu_min = 0;
+       int                         mtu_max = 0;
+       bondport_ref                p;
 
-       if (devmtu_p->ifdm_min > mtu_min) {
-           mtu_min = devmtu_p->ifdm_min;
+       if (TAILQ_FIRST(&ifb->ifb_port_list) != NULL) {
+               mtu_min = IF_MINMTU;
        }
-       if (mtu_max == 0 || devmtu_p->ifdm_max < mtu_max) {
-           mtu_max = devmtu_p->ifdm_max;
+       TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
+               struct ifdevmtu *       devmtu_p = &p->po_devmtu;
+
+               if (devmtu_p->ifdm_min > mtu_min) {
+                       mtu_min = devmtu_p->ifdm_min;
+               }
+               if (mtu_max == 0 || devmtu_p->ifdm_max < mtu_max) {
+                       mtu_max = devmtu_p->ifdm_max;
+               }
        }
-    }
-    *ret_min = mtu_min;
-    *ret_max = mtu_max;
-    return;
+       *ret_min = mtu_min;
+       *ret_max = mtu_max;
+       return;
 }
 
 static int
 bond_set_mtu_on_ports(ifbond_ref ifb, int mtu)
 {
-    int                                error = 0;
-    bondport_ref               p;
+       int                         error = 0;
+       bondport_ref                p;
 
-    TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
-       error = siocsifmtu(p->po_ifp, mtu);
-       if (error != 0) {
-           printf("if_bond(%s): SIOCSIFMTU %s failed, %d\n",
-                  ifb->ifb_name, bondport_get_name(p), error);
-           break;
+       TAILQ_FOREACH(p, &ifb->ifb_port_list, po_port_list) {
+               error = siocsifmtu(p->po_ifp, mtu);
+               if (error != 0) {
+                       printf("if_bond(%s): SIOCSIFMTU %s failed, %d\n",
+                           ifb->ifb_name, bondport_get_name(p), error);
+                       break;
+               }
        }
-    }
-    return (error);
+       return error;
 }
 
 static int
 bond_set_mtu(struct ifnet * ifp, int mtu, int isdevmtu)
 {
-    int                        error = 0;
-    ifbond_ref         ifb;
-    int                        mtu_min;
-    int                        mtu_max;
-    int                        new_max;
-    int                        old_max;
-
-    bond_lock();
-    ifb = (ifbond_ref)ifnet_softc(ifp);
-    if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
-       error = (ifb == NULL) ? EOPNOTSUPP : EBUSY;
-       goto done;
-    }
-    ifbond_retain(ifb);
-    ifbond_wait(ifb, "bond_set_mtu");
-
-    /* check again */
-    if (ifnet_softc(ifp) == NULL || ifbond_flags_if_detaching(ifb)) {
-       error = EBUSY;
-       goto signal_done;
-    }
-    bond_get_mtu_values(ifb, &mtu_min, &mtu_max);
-    if (mtu > mtu_max) {
-       error = EINVAL;
-       goto signal_done;
-    }
-    if (mtu < mtu_min && (isdevmtu == 0 || mtu != 0)) {
-       /* allow SIOCSIFALTMTU to set the mtu to 0 */
-       error = EINVAL;
-       goto signal_done;
-    }
-    if (isdevmtu) {
-       new_max = (mtu > (int)ifnet_mtu(ifp)) ? mtu : (int)ifnet_mtu(ifp);
-    }
-    else {
-       new_max = (mtu > ifb->ifb_altmtu) ? mtu : ifb->ifb_altmtu;
-    }
-    old_max = ((int)ifnet_mtu(ifp) > ifb->ifb_altmtu) 
-       ? (int)ifnet_mtu(ifp) : ifb->ifb_altmtu;
-    if (new_max != old_max) {
-       /* we can safely walk the list of port without the lock held */
-       bond_unlock();
-       error = bond_set_mtu_on_ports(ifb, new_max);
-       if (error != 0) {
-           /* try our best to back out of it */
-           (void)bond_set_mtu_on_ports(ifb, old_max);
-       }
+       int                 error = 0;
+       ifbond_ref          ifb;
+       int                 mtu_min;
+       int                 mtu_max;
+       int                 new_max;
+       int                 old_max;
+
        bond_lock();
-    }
-    if (error == 0) {
+       ifb = (ifbond_ref)ifnet_softc(ifp);
+       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+               error = (ifb == NULL) ? EOPNOTSUPP : EBUSY;
+               goto done;
+       }
+       ifbond_retain(ifb);
+       ifbond_wait(ifb, "bond_set_mtu");
+
+       /* check again */
+       if (ifnet_softc(ifp) == NULL || ifbond_flags_if_detaching(ifb)) {
+               error = EBUSY;
+               goto signal_done;
+       }
+       bond_get_mtu_values(ifb, &mtu_min, &mtu_max);
+       if (mtu > mtu_max) {
+               error = EINVAL;
+               goto signal_done;
+       }
+       if (mtu < mtu_min && (isdevmtu == 0 || mtu != 0)) {
+               /* allow SIOCSIFALTMTU to set the mtu to 0 */
+               error = EINVAL;
+               goto signal_done;
+       }
        if (isdevmtu) {
-           ifb->ifb_altmtu = mtu;
+               new_max = (mtu > (int)ifnet_mtu(ifp)) ? mtu : (int)ifnet_mtu(ifp);
+       } else {
+               new_max = (mtu > ifb->ifb_altmtu) ? mtu : ifb->ifb_altmtu;
+       }
+       old_max = ((int)ifnet_mtu(ifp) > ifb->ifb_altmtu)
+           ? (int)ifnet_mtu(ifp) : ifb->ifb_altmtu;
+       if (new_max != old_max) {
+               /* we can safely walk the list of port without the lock held */
+               bond_unlock();
+               error = bond_set_mtu_on_ports(ifb, new_max);
+               if (error != 0) {
+                       /* try our best to back out of it */
+                       (void)bond_set_mtu_on_ports(ifb, old_max);
+               }
+               bond_lock();
        }
-       else {
-               ifnet_set_mtu(ifp, mtu);
+       if (error == 0) {
+               if (isdevmtu) {
+                       ifb->ifb_altmtu = mtu;
+               } else {
+                       ifnet_set_mtu(ifp, mtu);
+               }
        }
-    }
 
- signal_done:
-    ifbond_signal(ifb, "bond_set_mtu");
-    ifbond_release(ifb);
-    
- done:
-    bond_unlock();
-    return (error);
+signal_done:
+       ifbond_signal(ifb, __func__);
+       ifbond_release(ifb);
+
+done:
+       bond_unlock();
+       return error;
 }
 
 static int
 bond_ioctl(struct ifnet *ifp, u_long cmd, void * data)
 {
-    int                error = 0;
-    struct if_bond_req ibr;
-    struct ifaddr *    ifa;
-    ifbond_ref         ifb;
-    struct ifreq *     ifr;
-    struct ifmediareq  *ifmr;
-    struct ifnet *     port_ifp = NULL;
-    user_addr_t                user_addr;
-
-    if (ifnet_type(ifp) != IFT_IEEE8023ADLAG) {
-       return (EOPNOTSUPP);
-    }
-    ifr = (struct ifreq *)data;
-    ifa = (struct ifaddr *)data;
-
-    switch (cmd) {
-    case SIOCSIFADDR:
-       ifnet_set_flags(ifp, IFF_UP, IFF_UP);
-       break;
-
-    case SIOCGIFMEDIA32:
-    case SIOCGIFMEDIA64:
-       bond_lock();
-       ifb = (ifbond_ref)ifnet_softc(ifp);
-       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
-           bond_unlock();
-           return (ifb == NULL ? EOPNOTSUPP : EBUSY);
-       }
-       ifmr = (struct ifmediareq *)data;
-       ifmr->ifm_current = IFM_ETHER;
-       ifmr->ifm_mask = 0;
-       ifmr->ifm_status = IFM_AVALID;
-       ifmr->ifm_active = IFM_ETHER;
-       ifmr->ifm_count = 1;
-       if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
-           if (ifb->ifb_active_lag != NULL) {
-               ifmr->ifm_active = ifb->ifb_active_lag->lag_active_media;
-               ifmr->ifm_status |= IFM_ACTIVE;
-           }
-       }
-       else if (ifb->ifb_distributing_count > 0) {
-           ifmr->ifm_active
-               = ifb->ifb_distributing_array[0]->po_media_info.mi_active;
-           ifmr->ifm_status |= IFM_ACTIVE;
-       }
-       bond_unlock();
-       user_addr = (cmd == SIOCGIFMEDIA64) ?
-           ((struct ifmediareq64 *)ifmr)->ifmu_ulist :
-           CAST_USER_ADDR_T(((struct ifmediareq32 *)ifmr)->ifmu_ulist);
-       if (user_addr != USER_ADDR_NULL) {
-           error = copyout(&ifmr->ifm_current,
-                           user_addr,
-                           sizeof(int));
+       int                 error = 0;
+       struct if_bond_req  ibr;
+       struct ifaddr *     ifa;
+       ifbond_ref          ifb;
+       struct ifreq *      ifr;
+       struct ifmediareq   *ifmr;
+       struct ifnet *      port_ifp = NULL;
+       user_addr_t         user_addr;
+
+       if (ifnet_type(ifp) != IFT_IEEE8023ADLAG) {
+               return EOPNOTSUPP;
        }
-       break;
+       ifr = (struct ifreq *)data;
+       ifa = (struct ifaddr *)data;
 
-    case SIOCSIFMEDIA:
-       /* XXX send the SIFMEDIA to all children?  Or force autoselect? */
-       error = EINVAL;
-       break;
+       switch (cmd) {
+       case SIOCSIFADDR:
+               ifnet_set_flags(ifp, IFF_UP, IFF_UP);
+               break;
 
-    case SIOCGIFDEVMTU:
-       bond_lock();
-       ifb = (ifbond_ref)ifnet_softc(ifp);
-       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
-           bond_unlock();
-           error = (ifb == NULL) ? EOPNOTSUPP : EBUSY;
-           break;
-       }
-       ifr->ifr_devmtu.ifdm_current = bond_device_mtu(ifp, ifb);
-       bond_get_mtu_values(ifb, &ifr->ifr_devmtu.ifdm_min,
-                           &ifr->ifr_devmtu.ifdm_max);
-       bond_unlock();
-       break;
+       case SIOCGIFMEDIA32:
+       case SIOCGIFMEDIA64:
+               bond_lock();
+               ifb = (ifbond_ref)ifnet_softc(ifp);
+               if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+                       bond_unlock();
+                       return ifb == NULL ? EOPNOTSUPP : EBUSY;
+               }
+               ifmr = (struct ifmediareq *)data;
+               ifmr->ifm_current = IFM_ETHER;
+               ifmr->ifm_mask = 0;
+               ifmr->ifm_status = IFM_AVALID;
+               ifmr->ifm_active = IFM_ETHER;
+               ifmr->ifm_count = 1;
+               if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
+                       if (ifb->ifb_active_lag != NULL) {
+                               ifmr->ifm_active = ifb->ifb_active_lag->lag_active_media;
+                               ifmr->ifm_status |= IFM_ACTIVE;
+                       }
+               } else if (ifb->ifb_distributing_count > 0) {
+                       ifmr->ifm_active
+                               = ifb->ifb_distributing_array[0]->po_media_info.mi_active;
+                       ifmr->ifm_status |= IFM_ACTIVE;
+               }
+               bond_unlock();
+               user_addr = (cmd == SIOCGIFMEDIA64) ?
+                   ((struct ifmediareq64 *)ifmr)->ifmu_ulist :
+                   CAST_USER_ADDR_T(((struct ifmediareq32 *)ifmr)->ifmu_ulist);
+               if (user_addr != USER_ADDR_NULL) {
+                       error = copyout(&ifmr->ifm_current,
+                           user_addr,
+                           sizeof(int));
+               }
+               break;
 
-    case SIOCGIFALTMTU:
-       bond_lock();
-       ifb = (ifbond_ref)ifnet_softc(ifp);
-       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
-           bond_unlock();
-           error = (ifb == NULL) ? EOPNOTSUPP : EBUSY;
-           break;
-       }
-       ifr->ifr_mtu = ifb->ifb_altmtu;
-       bond_unlock();
-       break;
+       case SIOCSIFMEDIA:
+               /* XXX send the SIFMEDIA to all children?  Or force autoselect? */
+               error = EINVAL;
+               break;
 
-    case SIOCSIFALTMTU:
-       error = bond_set_mtu(ifp, ifr->ifr_mtu, 1);
-       break;
+       case SIOCGIFDEVMTU:
+               bond_lock();
+               ifb = (ifbond_ref)ifnet_softc(ifp);
+               if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+                       bond_unlock();
+                       error = (ifb == NULL) ? EOPNOTSUPP : EBUSY;
+                       break;
+               }
+               ifr->ifr_devmtu.ifdm_current = bond_device_mtu(ifp, ifb);
+               bond_get_mtu_values(ifb, &ifr->ifr_devmtu.ifdm_min,
+                   &ifr->ifr_devmtu.ifdm_max);
+               bond_unlock();
+               break;
 
-    case SIOCSIFMTU:
-       error = bond_set_mtu(ifp, ifr->ifr_mtu, 0);
-       break;
+       case SIOCGIFALTMTU:
+               bond_lock();
+               ifb = (ifbond_ref)ifnet_softc(ifp);
+               if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+                       bond_unlock();
+                       error = (ifb == NULL) ? EOPNOTSUPP : EBUSY;
+                       break;
+               }
+               ifr->ifr_mtu = ifb->ifb_altmtu;
+               bond_unlock();
+               break;
 
-    case SIOCSIFBOND:
-       user_addr = proc_is64bit(current_proc())
-           ? ifr->ifr_data64 : CAST_USER_ADDR_T(ifr->ifr_data);
-       error = copyin(user_addr, &ibr, sizeof(ibr));
-       if (error) {
-           break;
-       }
-       switch (ibr.ibr_op) {
-       case IF_BOND_OP_ADD_INTERFACE:
-       case IF_BOND_OP_REMOVE_INTERFACE:
-           /* XXX ifunit() needs to return a reference on the ifp */
-           port_ifp = ifunit(ibr.ibr_ibru.ibru_if_name);
-           if (port_ifp == NULL) {
-               error = ENXIO;
+       case SIOCSIFALTMTU:
+               error = bond_set_mtu(ifp, ifr->ifr_mtu, 1);
                break;
-           }
-           if (ifnet_type(port_ifp) != IFT_ETHER) {
-               error = EPROTONOSUPPORT;
+
+       case SIOCSIFMTU:
+               error = bond_set_mtu(ifp, ifr->ifr_mtu, 0);
                break;
-           }
-           break;
-       case IF_BOND_OP_SET_VERBOSE:
-       case IF_BOND_OP_SET_MODE:
-           break;
-       default:
-           error = EOPNOTSUPP;
-           break;
-       }
-       if (error != 0) {
-           break;
-       }
-       switch (ibr.ibr_op) {
-       case IF_BOND_OP_ADD_INTERFACE:
-           error = bond_add_interface(ifp, port_ifp);
-           break;
-       case IF_BOND_OP_REMOVE_INTERFACE:
-           bond_lock();
-           ifb = (ifbond_ref)ifnet_softc(ifp);
-           if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
-               bond_unlock();
-               return (ifb == NULL ? EOPNOTSUPP : EBUSY);
-           }
-           error = bond_remove_interface(ifb, port_ifp);
-           bond_unlock();
-           break;
-       case IF_BOND_OP_SET_VERBOSE:
-           bond_lock();
-           if (g_bond == NULL) {
+
+       case SIOCSIFBOND:
+               user_addr = proc_is64bit(current_proc())
+                   ? ifr->ifr_data64 : CAST_USER_ADDR_T(ifr->ifr_data);
+               error = copyin(user_addr, &ibr, sizeof(ibr));
+               if (error) {
+                       break;
+               }
+               switch (ibr.ibr_op) {
+               case IF_BOND_OP_ADD_INTERFACE:
+               case IF_BOND_OP_REMOVE_INTERFACE:
+                       port_ifp = ifunit(ibr.ibr_ibru.ibru_if_name);
+                       if (port_ifp == NULL) {
+                               error = ENXIO;
+                               break;
+                       }
+                       if (ifnet_type(port_ifp) != IFT_ETHER) {
+                               error = EPROTONOSUPPORT;
+                               break;
+                       }
+                       break;
+               case IF_BOND_OP_SET_VERBOSE:
+               case IF_BOND_OP_SET_MODE:
+                       break;
+               default:
+                       error = EOPNOTSUPP;
+                       break;
+               }
+               if (error != 0) {
+                       break;
+               }
+               switch (ibr.ibr_op) {
+               case IF_BOND_OP_ADD_INTERFACE:
+                       error = bond_add_interface(ifp, port_ifp);
+                       break;
+               case IF_BOND_OP_REMOVE_INTERFACE:
+                       bond_lock();
+                       ifb = (ifbond_ref)ifnet_softc(ifp);
+                       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+                               bond_unlock();
+                               return ifb == NULL ? EOPNOTSUPP : EBUSY;
+                       }
+                       error = bond_remove_interface(ifb, port_ifp);
+                       bond_unlock();
+                       break;
+               case IF_BOND_OP_SET_VERBOSE:
+                       bond_lock();
+                       if_bond_debug = ibr.ibr_ibru.ibru_int_val;
+                       bond_unlock();
+                       break;
+               case IF_BOND_OP_SET_MODE:
+                       switch (ibr.ibr_ibru.ibru_int_val) {
+                       case IF_BOND_MODE_LACP:
+                       case IF_BOND_MODE_STATIC:
+                               break;
+                       default:
+                               error = EINVAL;
+                               break;
+                       }
+                       if (error != 0) {
+                               break;
+                       }
+                       error = bond_set_mode(ifp, ibr.ibr_ibru.ibru_int_val);
+                       break;
+               }
+               break; /* SIOCSIFBOND */
+
+       case SIOCGIFBOND:
+               user_addr = proc_is64bit(current_proc())
+                   ? ifr->ifr_data64 : CAST_USER_ADDR_T(ifr->ifr_data);
+               error = copyin(user_addr, &ibr, sizeof(ibr));
+               if (error) {
+                       break;
+               }
+               switch (ibr.ibr_op) {
+               case IF_BOND_OP_GET_STATUS:
+                       break;
+               default:
+                       error = EOPNOTSUPP;
+                       break;
+               }
+               if (error != 0) {
+                       break;
+               }
+               bond_lock();
+               ifb = (ifbond_ref)ifnet_softc(ifp);
+               if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
+                       bond_unlock();
+                       return ifb == NULL ? EOPNOTSUPP : EBUSY;
+               }
+               switch (ibr.ibr_op) {
+               case IF_BOND_OP_GET_STATUS:
+                       error = bond_get_status(ifb, &ibr, user_addr);
+                       break;
+               }
                bond_unlock();
-               error = ENXIO;
-               break;
-           }
-           g_bond->verbose = ibr.ibr_ibru.ibru_int_val;
-           bond_unlock();
-           break;
-       case IF_BOND_OP_SET_MODE:
-           switch (ibr.ibr_ibru.ibru_int_val) {
-           case IF_BOND_MODE_LACP:
-           case IF_BOND_MODE_STATIC:
+               break; /* SIOCGIFBOND */
+
+       case SIOCSIFLLADDR:
+               error = EOPNOTSUPP;
                break;
-           default:
-               error = EINVAL;
+
+       case SIOCSIFFLAGS:
+               /* enable/disable promiscuous mode */
+               bond_lock();
+               error = bond_set_promisc(ifp);
+               bond_unlock();
                break;
-           }
-           if (error != 0) {
+
+       case SIOCADDMULTI:
+       case SIOCDELMULTI:
+               error = bond_setmulti(ifp);
                break;
-           }
-           error = bond_set_mode(ifp, ibr.ibr_ibru.ibru_int_val);
-           break;
-       }
-       break; /* SIOCSIFBOND */
-               
-    case SIOCGIFBOND:
-       user_addr = proc_is64bit(current_proc())
-           ? ifr->ifr_data64 : CAST_USER_ADDR_T(ifr->ifr_data);
-       error = copyin(user_addr, &ibr, sizeof(ibr));
-       if (error) {
-           break;
-       }
-       switch (ibr.ibr_op) {
-       case IF_BOND_OP_GET_STATUS:
-           break;
        default:
-           error = EOPNOTSUPP;
-           break;
-       }
-       if (error != 0) {
-           break;
-       }
-       bond_lock();
-       ifb = (ifbond_ref)ifnet_softc(ifp);
-       if (ifb == NULL || ifbond_flags_if_detaching(ifb)) {
-           bond_unlock();
-           return (ifb == NULL ? EOPNOTSUPP : EBUSY);
-       }
-       switch (ibr.ibr_op) {
-       case IF_BOND_OP_GET_STATUS:
-           error = bond_get_status(ifb, &ibr, user_addr);
-           break;
+               error = EOPNOTSUPP;
        }
-       bond_unlock();
-       break; /* SIOCGIFBOND */
-               
-    case SIOCSIFLLADDR:
-       error = EOPNOTSUPP;
-       break;
-
-    case SIOCSIFFLAGS:
-       /* enable/disable promiscuous mode */
-       bond_lock();
-       error = bond_set_promisc(ifp);
-       bond_unlock();
-       break;
-
-    case SIOCADDMULTI:
-    case SIOCDELMULTI:
-       error = bond_setmulti(ifp);
-       break;
-    default:
-       error = EOPNOTSUPP;
-    }
-    return error;
+       return error;
 }
 
-static void 
+static void
 bond_if_free(struct ifnet * ifp)
 {
-    ifbond_ref         ifb;
+       ifbond_ref  ifb;
 
-    if (ifp == NULL) {
-       return;
-    }
-    bond_lock();
-    ifb = (ifbond_ref)ifnet_softc(ifp);
-    if (ifb == NULL) {
+       if (ifp == NULL) {
+               return;
+       }
+       bond_lock();
+       ifb = (ifbond_ref)ifnet_softc(ifp);
+       if (ifb == NULL) {
+               bond_unlock();
+               return;
+       }
+       ifbond_release(ifb);
        bond_unlock();
+       ifnet_release(ifp);
        return;
-    }
-    ifbond_release(ifb);
-    bond_unlock();
-    ifnet_release(ifp);
-    return;
 }
 
 static void
-bond_event(struct ifnet * port_ifp, __unused protocol_family_t protocol,
-                  const struct kev_msg * event)
-{
-    struct ifnet *     bond_ifp = NULL;
-    int                        event_code = 0;
-    ifbond_ref         ifb;
-    int                        old_distributing_count;
-    bondport_ref       p;
-    struct media_info  media_info = { 0, 0};
-
-    if (event->vendor_code != KEV_VENDOR_APPLE 
-       || event->kev_class != KEV_NETWORK_CLASS 
-       || event->kev_subclass != KEV_DL_SUBCLASS) {
-       return;
-    }
-    switch (event->event_code) {
-    case KEV_DL_IF_DETACHING:
-       break;
-    case KEV_DL_LINK_OFF:
-    case KEV_DL_LINK_ON:
-       media_info = interface_media_info(port_ifp);
-       break;
-    default:
-       return;
-    }
-    bond_lock();
-    p = bond_lookup_port(port_ifp);
-    if (p == NULL) {
-       bond_unlock();
-       return;
-    }
-    ifb = p->po_bond;
-    old_distributing_count = ifb->ifb_distributing_count;
-    switch (event->event_code) {
-    case KEV_DL_IF_DETACHING:
-       bond_remove_interface(ifb, p->po_ifp);
-       break;
-    case KEV_DL_LINK_OFF:
-    case KEV_DL_LINK_ON:
-       p->po_media_info = media_info;
-       if (p->po_enabled) {
-           bondport_link_status_changed(p);
-       }
-       break;
-    }
-    /* generate a link-event */
-    if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
-       if (ifbond_selection(ifb)) {
-           event_code = (ifb->ifb_active_lag == NULL) 
-               ? KEV_DL_LINK_OFF 
-               : KEV_DL_LINK_ON;
-           /* XXX need to take a reference on bond_ifp */
-           bond_ifp = ifb->ifb_ifp;
-           ifb->ifb_last_link_event = event_code;
-       }
-       else {
-           event_code = (ifb->ifb_active_lag == NULL) 
-               ? KEV_DL_LINK_OFF 
-               : KEV_DL_LINK_ON;
-           if (event_code != ifb->ifb_last_link_event) {
-               if (g_bond->verbose) {
-                   timestamp_printf("%s: (event) generating LINK event\n",
-                                    ifb->ifb_name);
+bond_handle_event(struct ifnet * port_ifp, int event_code)
+{
+       struct ifnet *      bond_ifp = NULL;
+       ifbond_ref          ifb;
+       int                 old_distributing_count;
+       bondport_ref        p;
+       struct media_info   media_info = { .mi_active = 0, .mi_status = 0 };
+
+       switch (event_code) {
+       case KEV_DL_IF_DETACHED:
+       case KEV_DL_IF_DETACHING:
+               break;
+       case KEV_DL_LINK_OFF:
+       case KEV_DL_LINK_ON:
+               media_info = interface_media_info(port_ifp);
+               break;
+       default:
+               return;
+       }
+       bond_lock();
+       p = bond_lookup_port(port_ifp);
+       if (p == NULL) {
+               bond_unlock();
+               return;
+       }
+       ifb = p->po_bond;
+       old_distributing_count = ifb->ifb_distributing_count;
+       switch (event_code) {
+       case KEV_DL_IF_DETACHED:
+       case KEV_DL_IF_DETACHING:
+               bond_remove_interface(ifb, p->po_ifp);
+               break;
+       case KEV_DL_LINK_OFF:
+       case KEV_DL_LINK_ON:
+               p->po_media_info = media_info;
+               if (p->po_enabled) {
+                       bondport_link_status_changed(p);
                }
-               bond_ifp = ifb->ifb_ifp;
-               ifb->ifb_last_link_event = event_code;
-           }
+               break;
        }
-    }
-    else {
-       /*
-        * if the distributing array membership changed from 0 <-> !0
-        * generate a link event
-        */
-       if (old_distributing_count == 0 
-           && ifb->ifb_distributing_count != 0) {
-           event_code = KEV_DL_LINK_ON;
+       /* generate a link-event */
+       if (ifb->ifb_mode == IF_BOND_MODE_LACP) {
+               if (ifbond_selection(ifb)) {
+                       event_code = (ifb->ifb_active_lag == NULL)
+                           ? KEV_DL_LINK_OFF
+                           : KEV_DL_LINK_ON;
+                       /* XXX need to take a reference on bond_ifp */
+                       bond_ifp = ifb->ifb_ifp;
+                       ifb->ifb_last_link_event = event_code;
+               } else {
+                       event_code = (ifb->ifb_active_lag == NULL)
+                           ? KEV_DL_LINK_OFF
+                           : KEV_DL_LINK_ON;
+                       if (event_code != ifb->ifb_last_link_event) {
+                               if (if_bond_debug) {
+                                       timestamp_printf("%s: (event) generating LINK event\n",
+                                           ifb->ifb_name);
+                               }
+                               bond_ifp = ifb->ifb_ifp;
+                               ifb->ifb_last_link_event = event_code;
+                       }
+               }
+       } else {
+               /*
+                * if the distributing array membership changed from 0 <-> !0
+                * generate a link event
+                */
+               if (old_distributing_count == 0
+                   && ifb->ifb_distributing_count != 0) {
+                       event_code = KEV_DL_LINK_ON;
+               } else if (old_distributing_count != 0
+                   && ifb->ifb_distributing_count == 0) {
+                       event_code = KEV_DL_LINK_OFF;
+               }
+               if (event_code != 0 && event_code != ifb->ifb_last_link_event) {
+                       bond_ifp = ifb->ifb_ifp;
+                       ifb->ifb_last_link_event = event_code;
+               }
        }
-       else if (old_distributing_count != 0 
-                && ifb->ifb_distributing_count == 0) {
-           event_code = KEV_DL_LINK_OFF;
+
+       bond_unlock();
+       if (bond_ifp != NULL) {
+               interface_link_event(bond_ifp, event_code);
        }
-       if (event_code != 0 && event_code != ifb->ifb_last_link_event) {
-           bond_ifp = ifb->ifb_ifp;
-           ifb->ifb_last_link_event = event_code;
+       return;
+}
+
+static void
+bond_iff_event(__unused void *cookie, ifnet_t port_ifp,
+    __unused protocol_family_t protocol,
+    const struct kev_msg *event)
+{
+       int         event_code;
+
+       if (event->vendor_code != KEV_VENDOR_APPLE
+           || event->kev_class != KEV_NETWORK_CLASS
+           || event->kev_subclass != KEV_DL_SUBCLASS) {
+               return;
+       }
+       event_code = event->event_code;
+       switch (event_code) {
+       case KEV_DL_LINK_OFF:
+       case KEV_DL_LINK_ON:
+       case KEV_DL_IF_DETACHING:
+       case KEV_DL_IF_DETACHED:
+               bond_handle_event(port_ifp, event_code);
+               break;
+       default:
+               break;
        }
-    }
+       return;
+}
 
-    bond_unlock();
-    if (bond_ifp != NULL) {
-       interface_link_event(bond_ifp, event_code);
-    }
-    return;
+static void
+bond_iff_detached(__unused void *cookie, ifnet_t port_ifp)
+{
+       bond_handle_event(port_ifp, KEV_DL_IF_DETACHED);
+       return;
 }
 
 static void
 interface_link_event(struct ifnet * ifp, u_int32_t event_code)
 {
-    struct {
-       struct kern_event_msg   header;
-       u_int32_t                       unit;
-       char                    if_name[IFNAMSIZ];
-    } event;
+       struct {
+               struct kern_event_msg   header;
+               u_int32_t                       unit;
+               char                    if_name[IFNAMSIZ];
+       } event;
+
+       bzero(&event, sizeof(event));
+       event.header.total_size    = sizeof(event);
+       event.header.vendor_code   = KEV_VENDOR_APPLE;
+       event.header.kev_class     = KEV_NETWORK_CLASS;
+       event.header.kev_subclass  = KEV_DL_SUBCLASS;
+       event.header.event_code    = event_code;
+       event.header.event_data[0] = ifnet_family(ifp);
+       event.unit                 = (u_int32_t) ifnet_unit(ifp);
+       strlcpy(event.if_name, ifnet_name(ifp), IFNAMSIZ);
+       ifnet_event(ifp, &event.header);
+       return;
+}
 
-    event.header.total_size    = sizeof(event);
-    event.header.vendor_code   = KEV_VENDOR_APPLE;
-    event.header.kev_class     = KEV_NETWORK_CLASS;
-    event.header.kev_subclass  = KEV_DL_SUBCLASS;
-    event.header.event_code    = event_code;
-    event.header.event_data[0] = ifnet_family(ifp);
-    event.unit                 = (u_int32_t) ifnet_unit(ifp);
-    strncpy(event.if_name, ifnet_name(ifp), IFNAMSIZ);
-    ifnet_event(ifp, &event.header);
-    return;
+static errno_t
+bond_proto_input(ifnet_t ifp, protocol_family_t protocol, mbuf_t packet,
+    char *header)
+{
+#pragma unused(protocol, packet, header)
+       if (if_bond_debug != 0) {
+               printf("%s: unexpected packet from %s\n", __func__,
+                   ifp->if_xname);
+       }
+       return 0;
 }
 
+
 /*
  * Function: bond_attach_protocol
  * Purpose:
  *   Attach a DLIL protocol to the interface.
  *
- *   The ethernet demux special cases to always return PF_BOND if the 
+ *   The ethernet demux special cases to always return PF_BOND if the
  *   interface is bonded.  That means we receive all traffic from that
  *   interface without passing any of the traffic to any other attached
  *   protocol.
@@ -3076,19 +3238,18 @@ interface_link_event(struct ifnet * ifp, u_int32_t event_code)
 static int
 bond_attach_protocol(struct ifnet *ifp)
 {
-    int                                                                error;
-    struct ifnet_attach_proto_param    reg;
-       
-    bzero(&reg, sizeof(reg));
-    reg.input = bond_input;
-    reg.event = bond_event;
-       
-    error = ifnet_attach_protocol(ifp, PF_BOND, &reg);
-    if (error) {
-       printf("bond over %s%d: ifnet_attach_protocol failed, %d\n",
-              ifnet_name(ifp), ifnet_unit(ifp), error);
-    }
-    return (error);
+       int                                                         error;
+       struct ifnet_attach_proto_param     reg;
+
+       bzero(&reg, sizeof(reg));
+       reg.input = bond_proto_input;
+
+       error = ifnet_attach_protocol(ifp, PF_BOND, &reg);
+       if (error) {
+               printf("bond over %s%d: ifnet_attach_protocol failed, %d\n",
+                   ifnet_name(ifp), ifnet_unit(ifp), error);
+       }
+       return error;
 }
 
 /*
@@ -3099,16 +3260,43 @@ bond_attach_protocol(struct ifnet *ifp)
 static int
 bond_detach_protocol(struct ifnet *ifp)
 {
-    int         error;
+       int         error;
+
+       error = ifnet_detach_protocol(ifp, PF_BOND);
+       if (error) {
+               printf("bond over %s%d: ifnet_detach_protocol failed, %d\n",
+                   ifnet_name(ifp), ifnet_unit(ifp), error);
+       }
+       return error;
+}
+
+/*
+ * Function: bond_attach_filter
+ * Purpose:
+ *   Attach our DLIL interface filter.
+ */
+static int
+bond_attach_filter(struct ifnet *ifp, interface_filter_t * filter_p)
+{
+       int                     error;
+       struct iff_filter       iff;
 
-    error = ifnet_detach_protocol(ifp, PF_BOND);
-    if (error) {
-       printf("bond over %s%d: ifnet_detach_protocol failed, %d\n",
-              ifnet_name(ifp), ifnet_unit(ifp), error);
-    }
-    return (error);
+       /*
+        * install an interface filter
+        */
+       memset(&iff, 0, sizeof(struct iff_filter));
+       iff.iff_name = "com.apple.kernel.bsd.net.if_bond";
+       iff.iff_input = bond_iff_input;
+       iff.iff_event = bond_iff_event;
+       iff.iff_detached = bond_iff_detached;
+       error = iflt_attach_internal(ifp, &iff, filter_p);
+       if (error != 0) {
+               printf("%s: iflt_attach_internal failed %d\n", __func__, error);
+       }
+       return error;
 }
 
+
 /*
  * DLIL interface family functions
  */
@@ -3122,1613 +3310,1589 @@ extern void ether_detach_at(ifnet_t ifp, protocol_family_t protocol_family);
 __private_extern__ int
 bond_family_init(void)
 {
-    int error=0;
+       int error = 0;
 
-    error = proto_register_plumber(PF_INET, APPLE_IF_FAM_BOND, 
-                                 ether_attach_inet, 
-                                 ether_detach_inet);
-    if (error != 0) {
-       printf("bond: proto_register_plumber failed for AF_INET error=%d\n",
-              error);
-       goto done;
-    }
+       error = proto_register_plumber(PF_INET, APPLE_IF_FAM_BOND,
+           ether_attach_inet,
+           ether_detach_inet);
+       if (error != 0) {
+               printf("bond: proto_register_plumber failed for AF_INET error=%d\n",
+                   error);
+               goto done;
+       }
 #if INET6
-    error = proto_register_plumber(PF_INET6, APPLE_IF_FAM_BOND, 
-                                 ether_attach_inet6, 
-                                 ether_detach_inet6);
-    if (error != 0) {
-       printf("bond: proto_register_plumber failed for AF_INET6 error=%d\n",
-              error);
-       goto done;
-    }
-#endif
-#if NETAT
-    error = proto_register_plumber(PF_APPLETALK, APPLE_IF_FAM_BOND, 
-                                 ether_attach_at, 
-                                 ether_detach_at);
-    if (error != 0) {
-       printf("bond: proto_register_plumber failed for AppleTalk error=%d\n",
-              error);
-       goto done;
-    }
+       error = proto_register_plumber(PF_INET6, APPLE_IF_FAM_BOND,
+           ether_attach_inet6,
+           ether_detach_inet6);
+       if (error != 0) {
+               printf("bond: proto_register_plumber failed for AF_INET6 error=%d\n",
+                   error);
+               goto done;
+       }
 #endif
-    error = bond_clone_attach();
-    if (error != 0) {
-        printf("bond: proto_register_plumber failed bond_clone_attach error=%d\n",
-               error);
-        goto done;
-    }
+       error = bond_clone_attach();
+       if (error != 0) {
+               printf("bond: proto_register_plumber failed bond_clone_attach error=%d\n",
+                   error);
+               goto done;
+       }
 
- done:
-    return (error);
+done:
+       return error;
 }
 /**
- **
- ** LACP routines:
- **
- **/
+**
+** LACP routines:
+**
+**/
 
 /**
- ** LACP ifbond_list routines
- **/
+** LACP ifbond_list routines
+**/
 static bondport_ref
-ifbond_list_find_moved_port(bondport_ref rx_port, 
-                           const lacp_actor_partner_tlv_ref atlv)
-{
-    ifbond_ref         bond;
-    bondport_ref       p;
-    partner_state_ref  ps;
-    LAG_info_ref       ps_li;
-
-    TAILQ_FOREACH(bond, &g_bond->ifbond_list, ifb_bond_list) {
-       TAILQ_FOREACH(p, &bond->ifb_port_list, po_port_list) {
-
-           if (rx_port == p) {
-               /* no point in comparing against ourselves */
-               continue;
-           }
-           if (p->po_receive_state != ReceiveState_PORT_DISABLED) {
-               /* it's not clear that we should be checking this */
-               continue;
-           }
-           ps = &p->po_partner_state;
-           if (lacp_actor_partner_state_defaulted(ps->ps_state)) {
-               continue;
-           }
-           ps_li = &ps->ps_lag_info;
-           if (ps->ps_port == lacp_actor_partner_tlv_get_port(atlv)
-               && bcmp(&ps_li->li_system, atlv->lap_system,
-                       sizeof(ps_li->li_system)) == 0) {
-               if (g_bond->verbose) {
-                   timestamp_printf("System " EA_FORMAT 
-                                    " Port 0x%x moved from %s to %s\n",
-                                    EA_LIST(&ps_li->li_system), ps->ps_port, 
-                                    bondport_get_name(p), 
-                                    bondport_get_name(rx_port));
-               }
-               return (p);
-           }
-       }
-    }
-    return (NULL);
+ifbond_list_find_moved_port(bondport_ref rx_port,
+    const lacp_actor_partner_tlv_ref atlv)
+{
+       ifbond_ref          bond;
+       bondport_ref        p;
+       partner_state_ref   ps;
+       LAG_info_ref        ps_li;
+
+       TAILQ_FOREACH(bond, &g_bond->ifbond_list, ifb_bond_list) {
+               TAILQ_FOREACH(p, &bond->ifb_port_list, po_port_list) {
+                       if (rx_port == p) {
+                               /* no point in comparing against ourselves */
+                               continue;
+                       }
+                       if (p->po_receive_state != ReceiveState_PORT_DISABLED) {
+                               /* it's not clear that we should be checking this */
+                               continue;
+                       }
+                       ps = &p->po_partner_state;
+                       if (lacp_actor_partner_state_defaulted(ps->ps_state)) {
+                               continue;
+                       }
+                       ps_li = &ps->ps_lag_info;
+                       if (ps->ps_port == lacp_actor_partner_tlv_get_port(atlv)
+                           && bcmp(&ps_li->li_system, atlv->lap_system,
+                           sizeof(ps_li->li_system)) == 0) {
+                               if (if_bond_debug) {
+                                       timestamp_printf("System " EA_FORMAT
+                                           " Port 0x%x moved from %s to %s\n",
+                                           EA_LIST(&ps_li->li_system), ps->ps_port,
+                                           bondport_get_name(p),
+                                           bondport_get_name(rx_port));
+                               }
+                               return p;
+                       }
+               }
+       }
+       return NULL;
 }
 
 /**
- ** LACP ifbond, LAG routines
- **/
+** LACP ifbond, LAG routines
+**/
 
 static int
 ifbond_selection(ifbond_ref bond)
 {
-    int                        all_ports_ready = 0;
-    int                        active_media = 0;
-    LAG_ref            lag = NULL;
-    int                        lag_changed = 0;
-    bondport_ref       p;
-    int                        port_speed = 0;
-    
-    lag = ifbond_find_best_LAG(bond, &active_media);
-    if (lag != bond->ifb_active_lag) {
-       if (bond->ifb_active_lag != NULL) {
-           ifbond_deactivate_LAG(bond, bond->ifb_active_lag);
-           bond->ifb_active_lag = NULL;
+       int                 all_ports_ready = 0;
+       int                 active_media = 0;
+       LAG_ref             lag = NULL;
+       int                 lag_changed = 0;
+       bondport_ref        p;
+       int                 port_speed = 0;
+
+       lag = ifbond_find_best_LAG(bond, &active_media);
+       if (lag != bond->ifb_active_lag) {
+               if (bond->ifb_active_lag != NULL) {
+                       ifbond_deactivate_LAG(bond, bond->ifb_active_lag);
+                       bond->ifb_active_lag = NULL;
+               }
+               bond->ifb_active_lag = lag;
+               if (lag != NULL) {
+                       ifbond_activate_LAG(bond, lag, active_media);
+               }
+               lag_changed = 1;
+       } else if (lag != NULL) {
+               if (lag->lag_active_media != active_media) {
+                       if (if_bond_debug) {
+                               timestamp_printf("LAG PORT SPEED CHANGED from %d to %d\n",
+                                   link_speed(lag->lag_active_media),
+                                   link_speed(active_media));
+                       }
+                       ifbond_deactivate_LAG(bond, lag);
+                       ifbond_activate_LAG(bond, lag, active_media);
+                       lag_changed = 1;
+               }
        }
-       bond->ifb_active_lag = lag;
        if (lag != NULL) {
-           ifbond_activate_LAG(bond, lag, active_media);
-       }
-       lag_changed = 1;
-    }
-    else if (lag != NULL) {
-       if (lag->lag_active_media != active_media) {
-           if (g_bond->verbose) {
-               timestamp_printf("LAG PORT SPEED CHANGED from %d to %d\n",
-                                link_speed(lag->lag_active_media), 
-                                link_speed(active_media));
-           }
-           ifbond_deactivate_LAG(bond, lag);
-           ifbond_activate_LAG(bond, lag, active_media);
-           lag_changed = 1;
-       }
-    }
-    if (lag != NULL) {
-       port_speed = link_speed(active_media);
-       all_ports_ready = ifbond_all_ports_ready(bond);
-    }
-    TAILQ_FOREACH(p, &bond->ifb_port_list, po_port_list) {
-       if (lag != NULL && p->po_lag == lag
-           && media_speed(&p->po_media_info) == port_speed
-           && (p->po_mux_state == MuxState_DETACHED
-               || p->po_selected == SelectedState_SELECTED
-               || p->po_selected == SelectedState_STANDBY)
-           && bondport_aggregatable(p)) {
-           if (bond->ifb_max_active > 0) {
-               if (lag->lag_selected_port_count < bond->ifb_max_active) {
-                   if (p->po_selected == SelectedState_STANDBY
-                       || p->po_selected == SelectedState_UNSELECTED) {
-                       bondport_set_selected(p, SelectedState_SELECTED);
-                   }
-               }
-               else if (p->po_selected == SelectedState_UNSELECTED) {
-                   bondport_set_selected(p, SelectedState_STANDBY);
-               }
-           }
-           else {
-               bondport_set_selected(p, SelectedState_SELECTED);
-           }
-       }
-       if (bondport_flags_selected_changed(p)) {
-           bondport_flags_clear_selected_changed(p);
-           bondport_mux_machine(p, LAEventSelectedChange, NULL);
-       }
-       if (all_ports_ready
-           && bondport_flags_ready(p)
-           && p->po_mux_state == MuxState_WAITING) {
-           bondport_mux_machine(p, LAEventReady, NULL);
+               port_speed = link_speed(active_media);
+               all_ports_ready = ifbond_all_ports_ready(bond);
        }
-       bondport_transmit_machine(p, LAEventStart, NULL);
-    }
-    return (lag_changed);
+       TAILQ_FOREACH(p, &bond->ifb_port_list, po_port_list) {
+               if (lag != NULL && p->po_lag == lag
+                   && media_speed(&p->po_media_info) == port_speed
+                   && (p->po_mux_state == MuxState_DETACHED
+                   || p->po_selected == SelectedState_SELECTED
+                   || p->po_selected == SelectedState_STANDBY)
+                   && bondport_aggregatable(p)) {
+                       if (bond->ifb_max_active > 0) {
+                               if (lag->lag_selected_port_count < bond->ifb_max_active) {
+                                       if (p->po_selected == SelectedState_STANDBY
+                                           || p->po_selected == SelectedState_UNSELECTED) {
+                                               bondport_set_selected(p, SelectedState_SELECTED);
+                                       }
+                               } else if (p->po_selected == SelectedState_UNSELECTED) {
+                                       bondport_set_selected(p, SelectedState_STANDBY);
+                               }
+                       } else {
+                               bondport_set_selected(p, SelectedState_SELECTED);
+                       }
+               }
+               if (bondport_flags_selected_changed(p)) {
+                       bondport_flags_clear_selected_changed(p);
+                       bondport_mux_machine(p, LAEventSelectedChange, NULL);
+               }
+               if (all_ports_ready
+                   && bondport_flags_ready(p)
+                   && p->po_mux_state == MuxState_WAITING) {
+                       bondport_mux_machine(p, LAEventReady, NULL);
+               }
+               bondport_transmit_machine(p, LAEventStart, NULL);
+       }
+       return lag_changed;
 }
 
 static LAG_ref
 ifbond_find_best_LAG(ifbond_ref bond, int * active_media)
 {
-    int                        best_active = 0;
-    LAG_ref            best_lag = NULL;
-    int                        best_count = 0;
-    int                        best_speed = 0;
-    LAG_ref            lag;
-
-    if (bond->ifb_active_lag != NULL) {
-       best_lag = bond->ifb_active_lag;
-       best_count = LAG_get_aggregatable_port_count(best_lag, &best_active);
-       if (bond->ifb_max_active > 0
-           && best_count > bond->ifb_max_active) {
-           best_count = bond->ifb_max_active;
-       }
-       best_speed = link_speed(best_active);
-    }
-    TAILQ_FOREACH(lag, &bond->ifb_lag_list, lag_list) {
-       int     active;
-       int     count;
-       int     speed;
-
-       if (lag == bond->ifb_active_lag) {
-           /* we've already computed it */
-           continue;
-       }
-       count = LAG_get_aggregatable_port_count(lag, &active);
-       if (count == 0) {
-           continue;
-       }
-       if (bond->ifb_max_active > 0
-           && count > bond->ifb_max_active) {
-           /* if there's a limit, don't count extra links */
-           count = bond->ifb_max_active;
-       }
-       speed = link_speed(active);
-       if ((count * speed) > (best_count * best_speed)) {
-           best_count = count;
-           best_speed = speed;
-           best_active = active;
-           best_lag = lag;
-       }
-    }
-    if (best_count == 0) {
-       return (NULL);
-    }
-    *active_media = best_active;
-    return (best_lag);
+       int                 best_active = 0;
+       LAG_ref             best_lag = NULL;
+       int                 best_count = 0;
+       int                 best_speed = 0;
+       LAG_ref             lag;
+
+       if (bond->ifb_active_lag != NULL) {
+               best_lag = bond->ifb_active_lag;
+               best_count = LAG_get_aggregatable_port_count(best_lag, &best_active);
+               if (bond->ifb_max_active > 0
+                   && best_count > bond->ifb_max_active) {
+                       best_count = bond->ifb_max_active;
+               }
+               best_speed = link_speed(best_active);
+       }
+       TAILQ_FOREACH(lag, &bond->ifb_lag_list, lag_list) {
+               int     active;
+               int     count;
+               int     speed;
+
+               if (lag == bond->ifb_active_lag) {
+                       /* we've already computed it */
+                       continue;
+               }
+               count = LAG_get_aggregatable_port_count(lag, &active);
+               if (count == 0) {
+                       continue;
+               }
+               if (bond->ifb_max_active > 0
+                   && count > bond->ifb_max_active) {
+                       /* if there's a limit, don't count extra links */
+                       count = bond->ifb_max_active;
+               }
+               speed = link_speed(active);
+               if ((count * speed) > (best_count * best_speed)) {
+                       best_count = count;
+                       best_speed = speed;
+                       best_active = active;
+                       best_lag = lag;
+               }
+       }
+       if (best_count == 0) {
+               return NULL;
+       }
+       *active_media = best_active;
+       return best_lag;
 }
 
 static void
 ifbond_deactivate_LAG(__unused ifbond_ref bond, LAG_ref lag)
 {
-    bondport_ref       p;
+       bondport_ref        p;
 
-    TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
-       bondport_set_selected(p, SelectedState_UNSELECTED);
-    }
-    return;
+       TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
+               bondport_set_selected(p, SelectedState_UNSELECTED);
+       }
+       return;
 }
 
 static void
 ifbond_activate_LAG(ifbond_ref bond, LAG_ref lag, int active_media)
 {
-    int                        need = 0;
-    bondport_ref       p;
+       int                 need = 0;
+       bondport_ref        p;
 
-    if (bond->ifb_max_active > 0) {
-       need = bond->ifb_max_active;
-    }
-    lag->lag_active_media = active_media;
-    TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
-       if (bondport_aggregatable(p) == 0) {
-           bondport_set_selected(p, SelectedState_UNSELECTED);
-       }
-       else if (media_speed(&p->po_media_info) != link_speed(active_media)) {
-           bondport_set_selected(p, SelectedState_UNSELECTED);
+       if (bond->ifb_max_active > 0) {
+               need = bond->ifb_max_active;
        }
-       else if (p->po_mux_state == MuxState_DETACHED) {
-           if (bond->ifb_max_active > 0) {
-               if (need > 0) {
-                   bondport_set_selected(p, SelectedState_SELECTED);
-                   need--;
-               }
-               else {
-                   bondport_set_selected(p, SelectedState_STANDBY);
+       lag->lag_active_media = active_media;
+       TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
+               if (bondport_aggregatable(p) == 0) {
+                       bondport_set_selected(p, SelectedState_UNSELECTED);
+               } else if (media_speed(&p->po_media_info) != link_speed(active_media)) {
+                       bondport_set_selected(p, SelectedState_UNSELECTED);
+               } else if (p->po_mux_state == MuxState_DETACHED) {
+                       if (bond->ifb_max_active > 0) {
+                               if (need > 0) {
+                                       bondport_set_selected(p, SelectedState_SELECTED);
+                                       need--;
+                               } else {
+                                       bondport_set_selected(p, SelectedState_STANDBY);
+                               }
+                       } else {
+                               bondport_set_selected(p, SelectedState_SELECTED);
+                       }
+               } else {
+                       bondport_set_selected(p, SelectedState_UNSELECTED);
                }
-           }
-           else {
-               bondport_set_selected(p, SelectedState_SELECTED);
-           }
        }
-       else {
-           bondport_set_selected(p, SelectedState_UNSELECTED);
-       }
-    }
-    return;
+       return;
 }
 
 #if 0
 static void
 ifbond_set_max_active(ifbond_ref bond, int max_active)
 {
-    LAG_ref    lag = bond->ifb_active_lag;
-
-    bond->ifb_max_active = max_active;
-    if (bond->ifb_max_active <= 0 || lag == NULL) {
-       return;
-    }
-    if (lag->lag_selected_port_count > bond->ifb_max_active) {
-       bondport_ref    p;
-       int                     remove_count;
-
-       remove_count = lag->lag_selected_port_count - bond->ifb_max_active;
-       TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
-           if (p->po_selected == SelectedState_SELECTED) {
-               bondport_set_selected(p, SelectedState_UNSELECTED);
-               remove_count--;
-               if (remove_count == 0) {
-                   break;
+       LAG_ref     lag = bond->ifb_active_lag;
+
+       bond->ifb_max_active = max_active;
+       if (bond->ifb_max_active <= 0 || lag == NULL) {
+               return;
+       }
+       if (lag->lag_selected_port_count > bond->ifb_max_active) {
+               bondport_ref    p;
+               int                     remove_count;
+
+               remove_count = lag->lag_selected_port_count - bond->ifb_max_active;
+               TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
+                       if (p->po_selected == SelectedState_SELECTED) {
+                               bondport_set_selected(p, SelectedState_UNSELECTED);
+                               remove_count--;
+                               if (remove_count == 0) {
+                                       break;
+                               }
+                       }
                }
-           }
        }
-    }
-    return;
+       return;
 }
 #endif
 
 static int
 ifbond_all_ports_ready(ifbond_ref bond)
 {
-    int                        ready = 0;
-    bondport_ref       p;
+       int                 ready = 0;
+       bondport_ref        p;
 
-    if (bond->ifb_active_lag == NULL) {
-       return (0);
-    }
-    TAILQ_FOREACH(p, &bond->ifb_active_lag->lag_port_list, po_lag_port_list) {
-       if (p->po_mux_state == MuxState_WAITING
-           && p->po_selected == SelectedState_SELECTED) {
-           if (bondport_flags_ready(p) == 0) {
-               return (0);
-           }
+       if (bond->ifb_active_lag == NULL) {
+               return 0;
        }
-       /* note that there was at least one ready port */
-       ready = 1;
-    }
-    return (ready);
+       TAILQ_FOREACH(p, &bond->ifb_active_lag->lag_port_list, po_lag_port_list) {
+               if (p->po_mux_state == MuxState_WAITING
+                   && p->po_selected == SelectedState_SELECTED) {
+                       if (bondport_flags_ready(p) == 0) {
+                               return 0;
+                       }
+               }
+               /* note that there was at least one ready port */
+               ready = 1;
+       }
+       return ready;
 }
 
 static int
 ifbond_all_ports_attached(ifbond_ref bond, bondport_ref this_port)
 {
-    bondport_ref       p;
+       bondport_ref        p;
 
-    TAILQ_FOREACH(p, &bond->ifb_port_list, po_port_list) {
-       if (this_port == p) {
-           continue;
-       }
-       if (bondport_flags_mux_attached(p) == 0) {
-           return (0);
+       TAILQ_FOREACH(p, &bond->ifb_port_list, po_port_list) {
+               if (this_port == p) {
+                       continue;
+               }
+               if (bondport_flags_mux_attached(p) == 0) {
+                       return 0;
+               }
        }
-    }
-    return (1);
+       return 1;
 }
 
 static LAG_ref
 ifbond_get_LAG_matching_port(ifbond_ref bond, bondport_ref p)
 {
-    LAG_ref    lag;
+       LAG_ref     lag;
 
-    TAILQ_FOREACH(lag, &bond->ifb_lag_list, lag_list) {
-       if (bcmp(&lag->lag_info, &p->po_partner_state.ps_lag_info,
-                sizeof(lag->lag_info)) == 0) {
-           return (lag);
+       TAILQ_FOREACH(lag, &bond->ifb_lag_list, lag_list) {
+               if (bcmp(&lag->lag_info, &p->po_partner_state.ps_lag_info,
+                   sizeof(lag->lag_info)) == 0) {
+                       return lag;
+               }
        }
-    }
-    return (NULL);
+       return NULL;
 }
 
 static int
 LAG_get_aggregatable_port_count(LAG_ref lag, int * active_media)
 {
-    int                        active;
-    int                count;
-    bondport_ref       p;
-    int                        speed;
-
-    active = 0;
-    count = 0;
-    speed = 0;
-    TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
-       if (bondport_aggregatable(p)) {
-           int this_speed;
-
-           this_speed = media_speed(&p->po_media_info);
-           if (this_speed == 0) {
-               continue;
-           }
-           if (this_speed > speed) {
-               active = p->po_media_info.mi_active;
-               speed = this_speed;
-               count = 1;
-           }
-           else if (this_speed == speed) {
-               count++;
-           }
-       }
-    }
-    *active_media = active;
-    return (count);
+       int                 active;
+       int                 count;
+       bondport_ref        p;
+       int                 speed;
+
+       active = 0;
+       count = 0;
+       speed = 0;
+       TAILQ_FOREACH(p, &lag->lag_port_list, po_lag_port_list) {
+               if (bondport_aggregatable(p)) {
+                       int this_speed;
+
+                       this_speed = media_speed(&p->po_media_info);
+                       if (this_speed == 0) {
+                               continue;
+                       }
+                       if (this_speed > speed) {
+                               active = p->po_media_info.mi_active;
+                               speed = this_speed;
+                               count = 1;
+                       } else if (this_speed == speed) {
+                               count++;
+                       }
+               }
+       }
+       *active_media = active;
+       return count;
 }
 
 
 /**
- ** LACP bondport routines
- **/
+** LACP bondport routines
+**/
 static void
 bondport_link_status_changed(bondport_ref p)
 {
-    ifbond_ref bond = p->po_bond;
-
-    if (g_bond->verbose) {
-       if (media_active(&p->po_media_info)) {
-           timestamp_printf("[%s] Link UP %d Mbit/s %s duplex\n", 
-                            bondport_get_name(p),
-                            media_speed(&p->po_media_info),
-                            media_full_duplex(&p->po_media_info) 
-                            ? "full" : "half");
-       }
-       else {
-           timestamp_printf("[%s] Link DOWN\n", bondport_get_name(p));
-       }
-    }
-    if (bond->ifb_mode == IF_BOND_MODE_LACP) {
-       if (media_active(&p->po_media_info)
-           && bond->ifb_active_lag != NULL
-           && p->po_lag == bond->ifb_active_lag
-           && p->po_selected != SelectedState_UNSELECTED) {
-           if (media_speed(&p->po_media_info) != p->po_lag->lag_active_media) {
-               if (g_bond->verbose) {
-                   timestamp_printf("[%s] Port speed %d differs from LAG %d\n",
-                                    bondport_get_name(p),
-                                    media_speed(&p->po_media_info),
-                                    link_speed(p->po_lag->lag_active_media));
+       ifbond_ref  bond = p->po_bond;
+
+       if (if_bond_debug) {
+               if (media_active(&p->po_media_info)) {
+                       const char * duplex_string;
+
+                       if (media_full_duplex(&p->po_media_info)) {
+                               duplex_string = "full";
+                       } else if (media_type_unknown(&p->po_media_info)) {
+                               duplex_string = "unknown";
+                       } else {
+                               duplex_string = "half";
+                       }
+                       timestamp_printf("[%s] Link UP %d Mbit/s %s duplex\n",
+                           bondport_get_name(p),
+                           media_speed(&p->po_media_info),
+                           duplex_string);
+               } else {
+                       timestamp_printf("[%s] Link DOWN\n",
+                           bondport_get_name(p));
                }
-               bondport_set_selected(p, SelectedState_UNSELECTED);
-           }
-       }
-       bondport_receive_machine(p, LAEventMediaChange, NULL);
-       bondport_mux_machine(p, LAEventMediaChange, NULL);
-       bondport_periodic_transmit_machine(p, LAEventMediaChange, NULL);
-    }
-    else {
-       if (media_active(&p->po_media_info)) {
-           bondport_enable_distributing(p);
        }
-       else {
-           bondport_disable_distributing(p);
+       if (bond->ifb_mode == IF_BOND_MODE_LACP) {
+               if (media_active(&p->po_media_info)
+                   && bond->ifb_active_lag != NULL
+                   && p->po_lag == bond->ifb_active_lag
+                   && p->po_selected != SelectedState_UNSELECTED) {
+                       if (media_speed(&p->po_media_info) != p->po_lag->lag_active_media) {
+                               if (if_bond_debug) {
+                                       timestamp_printf("[%s] Port speed %d differs from LAG %d\n",
+                                           bondport_get_name(p),
+                                           media_speed(&p->po_media_info),
+                                           link_speed(p->po_lag->lag_active_media));
+                               }
+                               bondport_set_selected(p, SelectedState_UNSELECTED);
+                       }
+               }
+               bondport_receive_machine(p, LAEventMediaChange, NULL);
+               bondport_mux_machine(p, LAEventMediaChange, NULL);
+               bondport_periodic_transmit_machine(p, LAEventMediaChange, NULL);
+       } else {
+               if (media_active(&p->po_media_info)) {
+                       bondport_enable_distributing(p);
+               } else {
+                       bondport_disable_distributing(p);
+               }
        }
-    }
-    return;
+       return;
 }
 
 static int
 bondport_aggregatable(bondport_ref p)
 {
-    partner_state_ref  ps = &p->po_partner_state;
-
-    if (lacp_actor_partner_state_aggregatable(p->po_actor_state) == 0
-       || lacp_actor_partner_state_aggregatable(ps->ps_state) == 0) {
-       /* we and/or our partner are individual */
-       return (0);
-    }
-    if (p->po_lag == NULL) {
-       return (0);
-    }
-    switch (p->po_receive_state) {
-    default:
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Port is not selectable\n", 
-                            bondport_get_name(p));
-       }
-       return (0);
-    case ReceiveState_CURRENT:
-    case ReceiveState_EXPIRED:
-       break;
-    }
-    return (1);
+       partner_state_ref   ps = &p->po_partner_state;
+
+       if (lacp_actor_partner_state_aggregatable(p->po_actor_state) == 0
+           || lacp_actor_partner_state_aggregatable(ps->ps_state) == 0) {
+               /* we and/or our partner are individual */
+               return 0;
+       }
+       if (p->po_lag == NULL) {
+               return 0;
+       }
+       switch (p->po_receive_state) {
+       default:
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Port is not selectable\n",
+                           bondport_get_name(p));
+               }
+               return 0;
+       case ReceiveState_CURRENT:
+       case ReceiveState_EXPIRED:
+               break;
+       }
+       return 1;
 }
 
 static int
 bondport_matches_LAG(bondport_ref p, LAG_ref lag)
 {
-    LAG_info_ref       lag_li;
-    partner_state_ref  ps;
-    LAG_info_ref       ps_li;
-
-    ps = &p->po_partner_state;
-    ps_li = &ps->ps_lag_info;
-    lag_li = &lag->lag_info;
-    if (ps_li->li_system_priority == lag_li->li_system_priority
-       && ps_li->li_key == lag_li->li_key
-       && (bcmp(&ps_li->li_system, &lag_li->li_system, 
-                sizeof(lag_li->li_system))
+       LAG_info_ref        lag_li;
+       partner_state_ref   ps;
+       LAG_info_ref        ps_li;
+
+       ps = &p->po_partner_state;
+       ps_li = &ps->ps_lag_info;
+       lag_li = &lag->lag_info;
+       if (ps_li->li_system_priority == lag_li->li_system_priority
+           && ps_li->li_key == lag_li->li_key
+           && (bcmp(&ps_li->li_system, &lag_li->li_system,
+           sizeof(lag_li->li_system))
            == 0)) {
-       return (1);
-    }
-    return (0);
+               return 1;
+       }
+       return 0;
 }
 
 static int
 bondport_remove_from_LAG(bondport_ref p)
 {
-    int                active_lag = 0;
-    ifbond_ref bond = p->po_bond;
-    LAG_ref    lag = p->po_lag;
-
-    if (lag == NULL) {
-       return (0);
-    }
-    TAILQ_REMOVE(&lag->lag_port_list, p, po_lag_port_list);
-    if (g_bond->verbose) {
-       timestamp_printf("[%s] Removed from LAG (0x%04x," EA_FORMAT 
-                        ",0x%04x)\n",
-                        bondport_get_name(p),
-                        lag->lag_info.li_system_priority,
-                        EA_LIST(&lag->lag_info.li_system),
-                        lag->lag_info.li_key);
-    }
-    p->po_lag = NULL;
-    lag->lag_port_count--;
-    if (lag->lag_port_count > 0) {
-       return (bond->ifb_active_lag == lag);
-    }
-    if (g_bond->verbose) {
-       timestamp_printf("Key 0x%04x: LAG Released (%04x," EA_FORMAT 
-                        ",0x%04x)\n",
-                        bond->ifb_key,
-                        lag->lag_info.li_system_priority,
-                        EA_LIST(&lag->lag_info.li_system),
-                        lag->lag_info.li_key);
-    }
-    TAILQ_REMOVE(&bond->ifb_lag_list, lag, lag_list);
-    if (bond->ifb_active_lag == lag) {
-       bond->ifb_active_lag = NULL;
-       active_lag = 1;
-    }
-    FREE(lag, M_BOND);
-    return (active_lag);
+       int         active_lag = 0;
+       ifbond_ref  bond = p->po_bond;
+       LAG_ref     lag = p->po_lag;
+
+       if (lag == NULL) {
+               return 0;
+       }
+       TAILQ_REMOVE(&lag->lag_port_list, p, po_lag_port_list);
+       if (if_bond_debug) {
+               timestamp_printf("[%s] Removed from LAG (0x%04x," EA_FORMAT
+                   ",0x%04x)\n",
+                   bondport_get_name(p),
+                   lag->lag_info.li_system_priority,
+                   EA_LIST(&lag->lag_info.li_system),
+                   lag->lag_info.li_key);
+       }
+       p->po_lag = NULL;
+       lag->lag_port_count--;
+       if (lag->lag_port_count > 0) {
+               return bond->ifb_active_lag == lag;
+       }
+       if (if_bond_debug) {
+               timestamp_printf("Key 0x%04x: LAG Released (%04x," EA_FORMAT
+                   ",0x%04x)\n",
+                   bond->ifb_key,
+                   lag->lag_info.li_system_priority,
+                   EA_LIST(&lag->lag_info.li_system),
+                   lag->lag_info.li_key);
+       }
+       TAILQ_REMOVE(&bond->ifb_lag_list, lag, lag_list);
+       if (bond->ifb_active_lag == lag) {
+               bond->ifb_active_lag = NULL;
+               active_lag = 1;
+       }
+       FREE(lag, M_BOND);
+       return active_lag;
 }
 
 static void
 bondport_add_to_LAG(bondport_ref p, LAG_ref lag)
 {
-    TAILQ_INSERT_TAIL(&lag->lag_port_list, p, po_lag_port_list);
-    p->po_lag = lag;
-    lag->lag_port_count++;
-    if (g_bond->verbose) {
-       timestamp_printf("[%s] Added to LAG (0x%04x," EA_FORMAT "0x%04x)\n",
-                        bondport_get_name(p),
-                        lag->lag_info.li_system_priority,
-                        EA_LIST(&lag->lag_info.li_system),
-                        lag->lag_info.li_key);
-    }
-    return;
+       TAILQ_INSERT_TAIL(&lag->lag_port_list, p, po_lag_port_list);
+       p->po_lag = lag;
+       lag->lag_port_count++;
+       if (if_bond_debug) {
+               timestamp_printf("[%s] Added to LAG (0x%04x," EA_FORMAT "0x%04x)\n",
+                   bondport_get_name(p),
+                   lag->lag_info.li_system_priority,
+                   EA_LIST(&lag->lag_info.li_system),
+                   lag->lag_info.li_key);
+       }
+       return;
 }
 
 static void
 bondport_assign_to_LAG(bondport_ref p)
 {
-    ifbond_ref bond = p->po_bond;
-    LAG_ref    lag;
+       ifbond_ref  bond = p->po_bond;
+       LAG_ref     lag;
 
-    if (lacp_actor_partner_state_defaulted(p->po_actor_state)) {
-       bondport_remove_from_LAG(p);
-       return;
-    }
-    lag = p->po_lag;
-    if (lag != NULL) {
-       if (bondport_matches_LAG(p, lag)) {
-           /* still OK */
-           return;
-       }
-       bondport_remove_from_LAG(p);
-    }
-    lag = ifbond_get_LAG_matching_port(bond, p);
-    if (lag != NULL) {
+       if (lacp_actor_partner_state_defaulted(p->po_actor_state)) {
+               bondport_remove_from_LAG(p);
+               return;
+       }
+       lag = p->po_lag;
+       if (lag != NULL) {
+               if (bondport_matches_LAG(p, lag)) {
+                       /* still OK */
+                       return;
+               }
+               bondport_remove_from_LAG(p);
+       }
+       lag = ifbond_get_LAG_matching_port(bond, p);
+       if (lag != NULL) {
+               bondport_add_to_LAG(p, lag);
+               return;
+       }
+       lag = (LAG_ref)_MALLOC(sizeof(*lag), M_BOND, M_WAITOK);
+       TAILQ_INIT(&lag->lag_port_list);
+       lag->lag_port_count = 0;
+       lag->lag_selected_port_count = 0;
+       lag->lag_info = p->po_partner_state.ps_lag_info;
+       TAILQ_INSERT_TAIL(&bond->ifb_lag_list, lag, lag_list);
+       if (if_bond_debug) {
+               timestamp_printf("Key 0x%04x: LAG Created (0x%04x," EA_FORMAT
+                   ",0x%04x)\n",
+                   bond->ifb_key,
+                   lag->lag_info.li_system_priority,
+                   EA_LIST(&lag->lag_info.li_system),
+                   lag->lag_info.li_key);
+       }
        bondport_add_to_LAG(p, lag);
        return;
-    }
-    lag = (LAG_ref)_MALLOC(sizeof(*lag), M_BOND, M_WAITOK);
-    TAILQ_INIT(&lag->lag_port_list);
-    lag->lag_port_count = 0;
-    lag->lag_selected_port_count = 0;
-    lag->lag_info = p->po_partner_state.ps_lag_info;
-    TAILQ_INSERT_TAIL(&bond->ifb_lag_list, lag, lag_list);
-    if (g_bond->verbose) {
-       timestamp_printf("Key 0x%04x: LAG Created (0x%04x," EA_FORMAT 
-                        ",0x%04x)\n",
-                        bond->ifb_key,
-                        lag->lag_info.li_system_priority,
-                        EA_LIST(&lag->lag_info.li_system),
-                        lag->lag_info.li_key);
-    }
-    bondport_add_to_LAG(p, lag);
-    return;
 }
 
 static void
 bondport_receive_lacpdu(bondport_ref p, lacpdu_ref in_lacpdu_p)
 {
-    bondport_ref               moved_port;
+       bondport_ref                moved_port;
 
-    moved_port
-       = ifbond_list_find_moved_port(p, (const lacp_actor_partner_tlv_ref)
-                                     &in_lacpdu_p->la_actor_tlv);
-    if (moved_port != NULL) {
-       bondport_receive_machine(moved_port, LAEventPortMoved, NULL);
-    }
-    bondport_receive_machine(p, LAEventPacket, in_lacpdu_p);
-    bondport_mux_machine(p, LAEventPacket, in_lacpdu_p);
-    bondport_periodic_transmit_machine(p, LAEventPacket, in_lacpdu_p);
-    return;
+       moved_port
+               = ifbond_list_find_moved_port(p, (const lacp_actor_partner_tlv_ref)
+           &in_lacpdu_p->la_actor_tlv);
+       if (moved_port != NULL) {
+               bondport_receive_machine(moved_port, LAEventPortMoved, NULL);
+       }
+       bondport_receive_machine(p, LAEventPacket, in_lacpdu_p);
+       bondport_mux_machine(p, LAEventPacket, in_lacpdu_p);
+       bondport_periodic_transmit_machine(p, LAEventPacket, in_lacpdu_p);
+       return;
 }
 
-static void 
+static void
 bondport_set_selected(bondport_ref p, SelectedState s)
 {
-    if (s != p->po_selected) {
-       ifbond_ref      bond = p->po_bond;
-       LAG_ref         lag = p->po_lag;
-
-       bondport_flags_set_selected_changed(p);
-       if (lag != NULL && bond->ifb_active_lag == lag) {
-           if (p->po_selected == SelectedState_SELECTED) {
-               lag->lag_selected_port_count--;
-           }
-           else if (s == SelectedState_SELECTED) {
-               lag->lag_selected_port_count++;
-           }
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] SetSelected: %s (was %s)\n",
-                                bondport_get_name(p), 
-                                SelectedStateString(s),
-                                SelectedStateString(p->po_selected));
-           }
-       }
-    }
-    p->po_selected = s;
-    return;
+       if (s != p->po_selected) {
+               ifbond_ref      bond = p->po_bond;
+               LAG_ref         lag = p->po_lag;
+
+               bondport_flags_set_selected_changed(p);
+               if (lag != NULL && bond->ifb_active_lag == lag) {
+                       if (p->po_selected == SelectedState_SELECTED) {
+                               lag->lag_selected_port_count--;
+                       } else if (s == SelectedState_SELECTED) {
+                               lag->lag_selected_port_count++;
+                       }
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] SetSelected: %s (was %s)\n",
+                                   bondport_get_name(p),
+                                   SelectedStateString(s),
+                                   SelectedStateString(p->po_selected));
+                       }
+               }
+       }
+       p->po_selected = s;
+       return;
 }
 
 /**
- ** Receive machine
- **/
+** Receive machine
+**/
 
 static void
 bondport_UpdateDefaultSelected(bondport_ref p)
 {
-    bondport_set_selected(p, SelectedState_UNSELECTED);
-    return;
+       bondport_set_selected(p, SelectedState_UNSELECTED);
+       return;
 }
 
 static void
 bondport_RecordDefault(bondport_ref p)
 {
-    bzero(&p->po_partner_state, sizeof(p->po_partner_state));
-    p->po_actor_state 
-       = lacp_actor_partner_state_set_defaulted(p->po_actor_state);
-    bondport_assign_to_LAG(p);
-    return;
+       bzero(&p->po_partner_state, sizeof(p->po_partner_state));
+       p->po_actor_state
+               = lacp_actor_partner_state_set_defaulted(p->po_actor_state);
+       bondport_assign_to_LAG(p);
+       return;
 }
 
 static void
 bondport_UpdateSelected(bondport_ref p, lacpdu_ref lacpdu_p)
 {
-    lacp_actor_partner_tlv_ref actor;
-    partner_state_ref          ps;
-    LAG_info_ref               ps_li;
+       lacp_actor_partner_tlv_ref  actor;
+       partner_state_ref           ps;
+       LAG_info_ref                ps_li;
 
-    /* compare the PDU's Actor information to our Partner state */
-    actor = (lacp_actor_partner_tlv_ref)lacpdu_p->la_actor_tlv;
-    ps = &p->po_partner_state;
-    ps_li = &ps->ps_lag_info;
-    if (lacp_actor_partner_tlv_get_port(actor) != ps->ps_port
-       || (lacp_actor_partner_tlv_get_port_priority(actor)
+       /* compare the PDU's Actor information to our Partner state */
+       actor = (lacp_actor_partner_tlv_ref)lacpdu_p->la_actor_tlv;
+       ps = &p->po_partner_state;
+       ps_li = &ps->ps_lag_info;
+       if (lacp_actor_partner_tlv_get_port(actor) != ps->ps_port
+           || (lacp_actor_partner_tlv_get_port_priority(actor)
            != ps->ps_port_priority)
-       || bcmp(actor->lap_system, &ps_li->li_system, sizeof(ps_li->li_system))
-       || (lacp_actor_partner_tlv_get_system_priority(actor) 
+           || bcmp(actor->lap_system, &ps_li->li_system, sizeof(ps_li->li_system))
+           || (lacp_actor_partner_tlv_get_system_priority(actor)
            != ps_li->li_system_priority)
-       || (lacp_actor_partner_tlv_get_key(actor) != ps_li->li_key)
-       || (lacp_actor_partner_state_aggregatable(actor->lap_state)
+           || (lacp_actor_partner_tlv_get_key(actor) != ps_li->li_key)
+           || (lacp_actor_partner_state_aggregatable(actor->lap_state)
            != lacp_actor_partner_state_aggregatable(ps->ps_state))) {
-       bondport_set_selected(p, SelectedState_UNSELECTED);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] updateSelected UNSELECTED\n",
-                            bondport_get_name(p));
+               bondport_set_selected(p, SelectedState_UNSELECTED);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] updateSelected UNSELECTED\n",
+                           bondport_get_name(p));
+               }
        }
-    }
-    return;
+       return;
 }
 
 static void
 bondport_RecordPDU(bondport_ref p, lacpdu_ref lacpdu_p)
 {
-    lacp_actor_partner_tlv_ref actor;
-    ifbond_ref                 bond = p->po_bond;
-    int                                lacp_maintain = 0;
-    partner_state_ref          ps;
-    lacp_actor_partner_tlv_ref partner;
-    LAG_info_ref               ps_li;
-
-    /* copy the PDU's Actor information into our Partner state */
-    actor = (lacp_actor_partner_tlv_ref)lacpdu_p->la_actor_tlv;
-    ps = &p->po_partner_state;
-    ps_li = &ps->ps_lag_info;
-    ps->ps_port = lacp_actor_partner_tlv_get_port(actor);
-    ps->ps_port_priority = lacp_actor_partner_tlv_get_port_priority(actor);
-    ps_li->li_system = *((lacp_system_ref)actor->lap_system);
-    ps_li->li_system_priority 
-       = lacp_actor_partner_tlv_get_system_priority(actor);
-    ps_li->li_key = lacp_actor_partner_tlv_get_key(actor);
-    ps->ps_state = lacp_actor_partner_state_set_out_of_sync(actor->lap_state);
-    p->po_actor_state 
-       = lacp_actor_partner_state_set_not_defaulted(p->po_actor_state);
-
-    /* compare the PDU's Partner information to our own information */
-    partner = (lacp_actor_partner_tlv_ref)lacpdu_p->la_partner_tlv;
-
-    if (lacp_actor_partner_state_active_lacp(ps->ps_state)
-       || (lacp_actor_partner_state_active_lacp(p->po_actor_state)
+       lacp_actor_partner_tlv_ref  actor;
+       ifbond_ref                  bond = p->po_bond;
+       int                         lacp_maintain = 0;
+       partner_state_ref           ps;
+       lacp_actor_partner_tlv_ref  partner;
+       LAG_info_ref                ps_li;
+
+       /* copy the PDU's Actor information into our Partner state */
+       actor = (lacp_actor_partner_tlv_ref)lacpdu_p->la_actor_tlv;
+       ps = &p->po_partner_state;
+       ps_li = &ps->ps_lag_info;
+       ps->ps_port = lacp_actor_partner_tlv_get_port(actor);
+       ps->ps_port_priority = lacp_actor_partner_tlv_get_port_priority(actor);
+       ps_li->li_system = *((lacp_system_ref)actor->lap_system);
+       ps_li->li_system_priority
+               = lacp_actor_partner_tlv_get_system_priority(actor);
+       ps_li->li_key = lacp_actor_partner_tlv_get_key(actor);
+       ps->ps_state = lacp_actor_partner_state_set_out_of_sync(actor->lap_state);
+       p->po_actor_state
+               = lacp_actor_partner_state_set_not_defaulted(p->po_actor_state);
+
+       /* compare the PDU's Partner information to our own information */
+       partner = (lacp_actor_partner_tlv_ref)lacpdu_p->la_partner_tlv;
+
+       if (lacp_actor_partner_state_active_lacp(ps->ps_state)
+           || (lacp_actor_partner_state_active_lacp(p->po_actor_state)
            && lacp_actor_partner_state_active_lacp(partner->lap_state))) {
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] recordPDU: LACP will maintain\n",
-                            bondport_get_name(p));
-       }
-       lacp_maintain = 1;
-    }
-    if ((lacp_actor_partner_tlv_get_port(partner) 
-        == bondport_get_index(p))
-       && lacp_actor_partner_tlv_get_port_priority(partner) == p->po_priority
-       && bcmp(partner->lap_system, &g_bond->system, 
-               sizeof(g_bond->system)) == 0
-       && (lacp_actor_partner_tlv_get_system_priority(partner) 
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] recordPDU: LACP will maintain\n",
+                           bondport_get_name(p));
+               }
+               lacp_maintain = 1;
+       }
+       if ((lacp_actor_partner_tlv_get_port(partner)
+           == bondport_get_index(p))
+           && lacp_actor_partner_tlv_get_port_priority(partner) == p->po_priority
+           && bcmp(partner->lap_system, &g_bond->system,
+           sizeof(g_bond->system)) == 0
+           && (lacp_actor_partner_tlv_get_system_priority(partner)
            == g_bond->system_priority)
-       && lacp_actor_partner_tlv_get_key(partner) == bond->ifb_key
-       && (lacp_actor_partner_state_aggregatable(partner->lap_state)
+           && lacp_actor_partner_tlv_get_key(partner) == bond->ifb_key
+           && (lacp_actor_partner_state_aggregatable(partner->lap_state)
            == lacp_actor_partner_state_aggregatable(p->po_actor_state))
-       && lacp_actor_partner_state_in_sync(actor->lap_state)
-       && lacp_maintain) {
-       ps->ps_state = lacp_actor_partner_state_set_in_sync(ps->ps_state);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] recordPDU: LACP partner in sync\n",
-                            bondport_get_name(p));
-       }
-    }
-    else if (lacp_actor_partner_state_aggregatable(actor->lap_state) == 0
-            && lacp_actor_partner_state_in_sync(actor->lap_state)
-            && lacp_maintain) {
-       ps->ps_state = lacp_actor_partner_state_set_in_sync(ps->ps_state);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] recordPDU: LACP partner in sync (ind)\n",
-                            bondport_get_name(p));
-       }
-    }
-    bondport_assign_to_LAG(p);
-    return;
+           && lacp_actor_partner_state_in_sync(actor->lap_state)
+           && lacp_maintain) {
+               ps->ps_state = lacp_actor_partner_state_set_in_sync(ps->ps_state);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] recordPDU: LACP partner in sync\n",
+                           bondport_get_name(p));
+               }
+       } else if (lacp_actor_partner_state_aggregatable(actor->lap_state) == 0
+           && lacp_actor_partner_state_in_sync(actor->lap_state)
+           && lacp_maintain) {
+               ps->ps_state = lacp_actor_partner_state_set_in_sync(ps->ps_state);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] recordPDU: LACP partner in sync (ind)\n",
+                           bondport_get_name(p));
+               }
+       }
+       bondport_assign_to_LAG(p);
+       return;
 }
 
 static __inline__ lacp_actor_partner_state
 updateNTTBits(lacp_actor_partner_state s)
 {
-    return (s & (LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY
-                | LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT
-                | LACP_ACTOR_PARTNER_STATE_AGGREGATION
-                | LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION));
+       return s & (LACP_ACTOR_PARTNER_STATE_LACP_ACTIVITY
+              | LACP_ACTOR_PARTNER_STATE_LACP_TIMEOUT
+              | LACP_ACTOR_PARTNER_STATE_AGGREGATION
+              | LACP_ACTOR_PARTNER_STATE_SYNCHRONIZATION);
 }
 
 static void
 bondport_UpdateNTT(bondport_ref p, lacpdu_ref lacpdu_p)
 {
-    ifbond_ref                 bond = p->po_bond;
-    lacp_actor_partner_tlv_ref partner;
+       ifbond_ref                  bond = p->po_bond;
+       lacp_actor_partner_tlv_ref  partner;
 
-    /* compare the PDU's Actor information to our Partner state */
-    partner = (lacp_actor_partner_tlv_ref)lacpdu_p->la_partner_tlv;
-    if ((lacp_actor_partner_tlv_get_port(partner) != bondport_get_index(p))
-       || lacp_actor_partner_tlv_get_port_priority(partner) != p->po_priority
-       || bcmp(partner->lap_system, &g_bond->system, sizeof(g_bond->system))
-       || (lacp_actor_partner_tlv_get_system_priority(partner) 
+       /* compare the PDU's Actor information to our Partner state */
+       partner = (lacp_actor_partner_tlv_ref)lacpdu_p->la_partner_tlv;
+       if ((lacp_actor_partner_tlv_get_port(partner) != bondport_get_index(p))
+           || lacp_actor_partner_tlv_get_port_priority(partner) != p->po_priority
+           || bcmp(partner->lap_system, &g_bond->system, sizeof(g_bond->system))
+           || (lacp_actor_partner_tlv_get_system_priority(partner)
            != g_bond->system_priority)
-       || lacp_actor_partner_tlv_get_key(partner) != bond->ifb_key
-       || (updateNTTBits(partner->lap_state) 
+           || lacp_actor_partner_tlv_get_key(partner) != bond->ifb_key
+           || (updateNTTBits(partner->lap_state)
            != updateNTTBits(p->po_actor_state))) {
-       bondport_flags_set_ntt(p);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] updateNTT: Need To Transmit\n",
-                            bondport_get_name(p));
+               bondport_flags_set_ntt(p);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] updateNTT: Need To Transmit\n",
+                           bondport_get_name(p));
+               }
        }
-    }
-    return;
+       return;
 }
 
 static void
 bondport_AttachMuxToAggregator(bondport_ref p)
 {
-    if (bondport_flags_mux_attached(p) == 0) {
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Attached Mux To Aggregator\n",
-                            bondport_get_name(p));
+       if (bondport_flags_mux_attached(p) == 0) {
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Attached Mux To Aggregator\n",
+                           bondport_get_name(p));
+               }
+               bondport_flags_set_mux_attached(p);
        }
-       bondport_flags_set_mux_attached(p);
-    }
-    return;
+       return;
 }
 
 static void
 bondport_DetachMuxFromAggregator(bondport_ref p)
 {
-    if (bondport_flags_mux_attached(p)) {
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Detached Mux From Aggregator\n",
-                            bondport_get_name(p));
+       if (bondport_flags_mux_attached(p)) {
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Detached Mux From Aggregator\n",
+                           bondport_get_name(p));
+               }
+               bondport_flags_clear_mux_attached(p);
        }
-       bondport_flags_clear_mux_attached(p);
-    }
-    return;
+       return;
 }
 
 static void
 bondport_enable_distributing(bondport_ref p)
 {
-    if (bondport_flags_distributing(p) == 0) {
-       ifbond_ref      bond = p->po_bond;
+       if (bondport_flags_distributing(p) == 0) {
+               ifbond_ref      bond = p->po_bond;
 
-       bond->ifb_distributing_array[bond->ifb_distributing_count++] = p;
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Distribution Enabled\n",
-                            bondport_get_name(p));
+               bond->ifb_distributing_array[bond->ifb_distributing_count++] = p;
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Distribution Enabled\n",
+                           bondport_get_name(p));
+               }
+               bondport_flags_set_distributing(p);
        }
-       bondport_flags_set_distributing(p);
-    }
-    return;
+       return;
 }
 
 static void
 bondport_disable_distributing(bondport_ref p)
 {
-    if (bondport_flags_distributing(p)) {
-       bondport_ref *  array;
-       ifbond_ref      bond;
-       int             count;
-       int             i;
-
-       bond = p->po_bond;
-       array = bond->ifb_distributing_array;
-       count = bond->ifb_distributing_count;
-       for (i = 0; i < count; i++) {
-           if (array[i] == p) {
-               int     j;
-
-               for (j = i; j < (count - 1); j++) {
-                   array[j] = array[j + 1];
+       if (bondport_flags_distributing(p)) {
+               bondport_ref *  array;
+               ifbond_ref      bond;
+               int             count;
+               int             i;
+
+               bond = p->po_bond;
+               array = bond->ifb_distributing_array;
+               count = bond->ifb_distributing_count;
+               for (i = 0; i < count; i++) {
+                       if (array[i] == p) {
+                               int     j;
+
+                               for (j = i; j < (count - 1); j++) {
+                                       array[j] = array[j + 1];
+                               }
+                               break;
+                       }
                }
-               break;
-           }
-       }
-       bond->ifb_distributing_count--;
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Distribution Disabled\n",
-                            bondport_get_name(p));
+               bond->ifb_distributing_count--;
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Distribution Disabled\n",
+                           bondport_get_name(p));
+               }
+               bondport_flags_clear_distributing(p);
        }
-       bondport_flags_clear_distributing(p);
-    }
-    return;
+       return;
 }
 
 /**
- ** Receive machine functions
- **/
+** Receive machine functions
+**/
 static void
 bondport_receive_machine_initialize(bondport_ref p, LAEvent event,
-                                   void * event_data);
+    void * event_data);
 static void
 bondport_receive_machine_port_disabled(bondport_ref p, LAEvent event,
-                                      void * event_data);
+    void * event_data);
 static void
 bondport_receive_machine_expired(bondport_ref p, LAEvent event,
-                                void * event_data);
+    void * event_data);
 static void
 bondport_receive_machine_lacp_disabled(bondport_ref p, LAEvent event,
-                                      void * event_data);
+    void * event_data);
 static void
 bondport_receive_machine_defaulted(bondport_ref p, LAEvent event,
-                                  void * event_data);
+    void * event_data);
 static void
 bondport_receive_machine_current(bondport_ref p, LAEvent event,
-                                void * event_data);
+    void * event_data);
 
 static void
-bondport_receive_machine_event(bondport_ref p, LAEvent event, 
-                              void * event_data)
-{
-    switch (p->po_receive_state) {
-    case ReceiveState_none:
-       bondport_receive_machine_initialize(p, LAEventStart, NULL);
-       break;
-    case ReceiveState_INITIALIZE:
-       bondport_receive_machine_initialize(p, event, event_data);
-       break;
-    case ReceiveState_PORT_DISABLED:
-       bondport_receive_machine_port_disabled(p, event, event_data);
-       break;
-    case ReceiveState_EXPIRED:
-       bondport_receive_machine_expired(p, event, event_data);
-       break;
-    case ReceiveState_LACP_DISABLED:
-       bondport_receive_machine_lacp_disabled(p, event, event_data);
-       break;
-    case ReceiveState_DEFAULTED:
-       bondport_receive_machine_defaulted(p, event, event_data);
-       break;
-    case ReceiveState_CURRENT:
-       bondport_receive_machine_current(p, event, event_data);
-       break;
-    default:
-       break;
-    }
-    return;
+bondport_receive_machine_event(bondport_ref p, LAEvent event,
+    void * event_data)
+{
+       switch (p->po_receive_state) {
+       case ReceiveState_none:
+               bondport_receive_machine_initialize(p, LAEventStart, NULL);
+               break;
+       case ReceiveState_INITIALIZE:
+               bondport_receive_machine_initialize(p, event, event_data);
+               break;
+       case ReceiveState_PORT_DISABLED:
+               bondport_receive_machine_port_disabled(p, event, event_data);
+               break;
+       case ReceiveState_EXPIRED:
+               bondport_receive_machine_expired(p, event, event_data);
+               break;
+       case ReceiveState_LACP_DISABLED:
+               bondport_receive_machine_lacp_disabled(p, event, event_data);
+               break;
+       case ReceiveState_DEFAULTED:
+               bondport_receive_machine_defaulted(p, event, event_data);
+               break;
+       case ReceiveState_CURRENT:
+               bondport_receive_machine_current(p, event, event_data);
+               break;
+       default:
+               break;
+       }
+       return;
 }
 
 static void
 bondport_receive_machine(bondport_ref p, LAEvent event,
-                        void * event_data)
-{
-    switch (event) {
-    case LAEventPacket:
-       if (p->po_receive_state != ReceiveState_LACP_DISABLED) {
-           bondport_receive_machine_current(p, event, event_data);
-       }
-       break;
-    case LAEventMediaChange:
-       if (media_active(&p->po_media_info)) {
-           switch (p->po_receive_state) {
-           case ReceiveState_PORT_DISABLED:
-           case ReceiveState_LACP_DISABLED:
-               bondport_receive_machine_port_disabled(p, LAEventMediaChange, NULL);
+    void * event_data)
+{
+       switch (event) {
+       case LAEventPacket:
+               if (p->po_receive_state != ReceiveState_LACP_DISABLED) {
+                       bondport_receive_machine_current(p, event, event_data);
+               }
                break;
-           default:
+       case LAEventMediaChange:
+               if (media_active(&p->po_media_info)) {
+                       switch (p->po_receive_state) {
+                       case ReceiveState_PORT_DISABLED:
+                       case ReceiveState_LACP_DISABLED:
+                               bondport_receive_machine_port_disabled(p, LAEventMediaChange, NULL);
+                               break;
+                       default:
+                               break;
+                       }
+               } else {
+                       bondport_receive_machine_port_disabled(p, LAEventStart, NULL);
+               }
+               break;
+       default:
+               bondport_receive_machine_event(p, event, event_data);
                break;
-           }
-       }
-       else {
-           bondport_receive_machine_port_disabled(p, LAEventStart, NULL);
        }
-       break;
-    default:
-       bondport_receive_machine_event(p, event, event_data);
-       break;
-    }
-    return;
+       return;
 }
 
 static void
 bondport_receive_machine_initialize(bondport_ref p, LAEvent event,
-                                   __unused void * event_data)
-{
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_current_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Receive INITIALIZE\n",
-                            bondport_get_name(p));
+    __unused void * event_data)
+{
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_current_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Receive INITIALIZE\n",
+                           bondport_get_name(p));
+               }
+               p->po_receive_state = ReceiveState_INITIALIZE;
+               bondport_set_selected(p, SelectedState_UNSELECTED);
+               bondport_RecordDefault(p);
+               p->po_actor_state
+                       = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
+               bondport_receive_machine_port_disabled(p, LAEventStart, NULL);
+               break;
+       default:
+               break;
        }
-       p->po_receive_state = ReceiveState_INITIALIZE;
-       bondport_set_selected(p, SelectedState_UNSELECTED);
-       bondport_RecordDefault(p);
-       p->po_actor_state
-           = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
-       bondport_receive_machine_port_disabled(p, LAEventStart, NULL);
-       break;
-    default:
-       break;
-    }
-    return;
+       return;
 }
 
 static void
 bondport_receive_machine_port_disabled(bondport_ref p, LAEvent event,
-                                      __unused void * event_data)
+    __unused void * event_data)
 {
-    partner_state_ref  ps;
+       partner_state_ref   ps;
 
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_current_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Receive PORT_DISABLED\n",
-                            bondport_get_name(p));
-       }
-       p->po_receive_state = ReceiveState_PORT_DISABLED;
-       ps = &p->po_partner_state;
-       ps->ps_state = lacp_actor_partner_state_set_out_of_sync(ps->ps_state);
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_current_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Receive PORT_DISABLED\n",
+                           bondport_get_name(p));
+               }
+               p->po_receive_state = ReceiveState_PORT_DISABLED;
+               ps = &p->po_partner_state;
+               ps->ps_state = lacp_actor_partner_state_set_out_of_sync(ps->ps_state);
        /* FALL THROUGH */
-    case LAEventMediaChange:
-       if (media_active(&p->po_media_info)) {
-           if (media_full_duplex(&p->po_media_info)) {
-               bondport_receive_machine_expired(p, LAEventStart, NULL);
-           }
-           else {
-               bondport_receive_machine_lacp_disabled(p, LAEventStart, NULL);
-           }
-       }
-       else if (p->po_selected == SelectedState_SELECTED) {
-           struct timeval      tv;
-
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Receive PORT_DISABLED: "
-                                "link timer started\n",
-                                bondport_get_name(p));
-           }
-           tv.tv_sec = 1;
-           tv.tv_usec = 0;
-           devtimer_set_relative(p->po_current_while_timer, tv, 
-                                 (devtimer_timeout_func)
-                                 bondport_receive_machine_port_disabled,
-                                 (void *)LAEventTimeout, NULL);
-       }
-       else if (p->po_selected == SelectedState_STANDBY) {
-           bondport_set_selected(p, SelectedState_UNSELECTED);
-       }
-       break;
-    case LAEventTimeout:
-       if (p->po_selected == SelectedState_SELECTED) {
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Receive PORT_DISABLED: "
-                                "link timer completed, marking UNSELECTED\n",
-                                bondport_get_name(p));
-           }
-           bondport_set_selected(p, SelectedState_UNSELECTED);
-       }
-       break;
-    case LAEventPortMoved:
-       bondport_receive_machine_initialize(p, LAEventStart, NULL);
-       break;
-    default:
-       break;
-    }
-    return;
+       case LAEventMediaChange:
+               if (media_active(&p->po_media_info)) {
+                       if (media_ok(&p->po_media_info)) {
+                               bondport_receive_machine_expired(p, LAEventStart, NULL);
+                       } else {
+                               bondport_receive_machine_lacp_disabled(p, LAEventStart, NULL);
+                       }
+               } else if (p->po_selected == SelectedState_SELECTED) {
+                       struct timeval      tv;
+
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Receive PORT_DISABLED: "
+                                   "link timer started\n",
+                                   bondport_get_name(p));
+                       }
+                       tv.tv_sec = 1;
+                       tv.tv_usec = 0;
+                       devtimer_set_relative(p->po_current_while_timer, tv,
+                           (devtimer_timeout_func)
+                           bondport_receive_machine_port_disabled,
+                           (void *)LAEventTimeout, NULL);
+               } else if (p->po_selected == SelectedState_STANDBY) {
+                       bondport_set_selected(p, SelectedState_UNSELECTED);
+               }
+               break;
+       case LAEventTimeout:
+               if (p->po_selected == SelectedState_SELECTED) {
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Receive PORT_DISABLED: "
+                                   "link timer completed, marking UNSELECTED\n",
+                                   bondport_get_name(p));
+                       }
+                       bondport_set_selected(p, SelectedState_UNSELECTED);
+               }
+               break;
+       case LAEventPortMoved:
+               bondport_receive_machine_initialize(p, LAEventStart, NULL);
+               break;
+       default:
+               break;
+       }
+       return;
 }
 
 static void
 bondport_receive_machine_expired(bondport_ref p, LAEvent event,
-                                __unused void * event_data)
+    __unused void * event_data)
 {
-    lacp_actor_partner_state   s;
-    struct timeval             tv;
+       lacp_actor_partner_state    s;
+       struct timeval              tv;
 
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_current_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Receive EXPIRED\n",
-                            bondport_get_name(p));
-       }
-       p->po_receive_state = ReceiveState_EXPIRED;
-       s = p->po_partner_state.ps_state;
-       s = lacp_actor_partner_state_set_out_of_sync(s);
-       s = lacp_actor_partner_state_set_short_timeout(s);
-       p->po_partner_state.ps_state = s;
-       p->po_actor_state 
-           = lacp_actor_partner_state_set_expired(p->po_actor_state);
-       /* start current_while timer */
-       tv.tv_sec = LACP_SHORT_TIMEOUT_TIME;
-       tv.tv_usec = 0;
-       devtimer_set_relative(p->po_current_while_timer, tv, 
-                             (devtimer_timeout_func)
-                             bondport_receive_machine_expired,
-                             (void *)LAEventTimeout, NULL);
-
-       break;
-    case LAEventTimeout:
-       bondport_receive_machine_defaulted(p, LAEventStart, NULL);
-       break;
-    default:
-       break;
-    }
-    return;
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_current_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Receive EXPIRED\n",
+                           bondport_get_name(p));
+               }
+               p->po_receive_state = ReceiveState_EXPIRED;
+               s = p->po_partner_state.ps_state;
+               s = lacp_actor_partner_state_set_out_of_sync(s);
+               s = lacp_actor_partner_state_set_short_timeout(s);
+               p->po_partner_state.ps_state = s;
+               p->po_actor_state
+                       = lacp_actor_partner_state_set_expired(p->po_actor_state);
+               /* start current_while timer */
+               tv.tv_sec = LACP_SHORT_TIMEOUT_TIME;
+               tv.tv_usec = 0;
+               devtimer_set_relative(p->po_current_while_timer, tv,
+                   (devtimer_timeout_func)
+                   bondport_receive_machine_expired,
+                   (void *)LAEventTimeout, NULL);
+
+               break;
+       case LAEventTimeout:
+               bondport_receive_machine_defaulted(p, LAEventStart, NULL);
+               break;
+       default:
+               break;
+       }
+       return;
 }
 
 static void
 bondport_receive_machine_lacp_disabled(bondport_ref p, LAEvent event,
-                                      __unused void * event_data)
-{
-    partner_state_ref  ps;
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_current_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Receive LACP_DISABLED\n",
-                            bondport_get_name(p));
+    __unused void * event_data)
+{
+       partner_state_ref   ps;
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_current_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Receive LACP_DISABLED\n",
+                           bondport_get_name(p));
+               }
+               p->po_receive_state = ReceiveState_LACP_DISABLED;
+               bondport_set_selected(p, SelectedState_UNSELECTED);
+               bondport_RecordDefault(p);
+               ps = &p->po_partner_state;
+               ps->ps_state = lacp_actor_partner_state_set_individual(ps->ps_state);
+               p->po_actor_state
+                       = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
+               break;
+       default:
+               break;
        }
-       p->po_receive_state = ReceiveState_LACP_DISABLED;
-       bondport_set_selected(p, SelectedState_UNSELECTED);
-       bondport_RecordDefault(p);
-       ps = &p->po_partner_state;
-       ps->ps_state = lacp_actor_partner_state_set_individual(ps->ps_state);
-       p->po_actor_state
-           = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
-       break;
-    default:
-       break;
-    }
-    return;
+       return;
 }
 
 static void
 bondport_receive_machine_defaulted(bondport_ref p, LAEvent event,
-                                  __unused void * event_data)
-{
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_current_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Receive DEFAULTED\n",
-                            bondport_get_name(p));
+    __unused void * event_data)
+{
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_current_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Receive DEFAULTED\n",
+                           bondport_get_name(p));
+               }
+               p->po_receive_state = ReceiveState_DEFAULTED;
+               bondport_UpdateDefaultSelected(p);
+               bondport_RecordDefault(p);
+               p->po_actor_state
+                       = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
+               break;
+       default:
+               break;
        }
-       p->po_receive_state = ReceiveState_DEFAULTED;
-       bondport_UpdateDefaultSelected(p);
-       bondport_RecordDefault(p);
-       p->po_actor_state
-           = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
-       break;
-    default:
-       break;
-    }
-    return;
+       return;
 }
 
 static void
 bondport_receive_machine_current(bondport_ref p, LAEvent event,
-                                void * event_data)
+    void * event_data)
 {
-    partner_state_ref  ps;
-    struct timeval     tv;
+       partner_state_ref   ps;
+       struct timeval      tv;
 
-    switch (event) {
-    case LAEventPacket:
-       devtimer_cancel(p->po_current_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Receive CURRENT\n",
-                            bondport_get_name(p));
-       }
-       p->po_receive_state = ReceiveState_CURRENT;
-       bondport_UpdateSelected(p, event_data);
-       bondport_UpdateNTT(p, event_data);
-       bondport_RecordPDU(p, event_data);
-       p->po_actor_state
-           = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
-       bondport_assign_to_LAG(p);
-       /* start current_while timer */
-       ps = &p->po_partner_state;
-       if (lacp_actor_partner_state_short_timeout(ps->ps_state)) {
-           tv.tv_sec = LACP_SHORT_TIMEOUT_TIME;
-       }
-       else {
-           tv.tv_sec = LACP_LONG_TIMEOUT_TIME;
-       }
-       tv.tv_usec = 0;
-       devtimer_set_relative(p->po_current_while_timer, tv,
-                             (devtimer_timeout_func)
-                             bondport_receive_machine_current,
-                             (void *)LAEventTimeout, NULL);
-       break;
-    case LAEventTimeout:
-       bondport_receive_machine_expired(p, LAEventStart, NULL);
-       break;
-    default:
-       break;
-    }
-    return;
+       switch (event) {
+       case LAEventPacket:
+               devtimer_cancel(p->po_current_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Receive CURRENT\n",
+                           bondport_get_name(p));
+               }
+               p->po_receive_state = ReceiveState_CURRENT;
+               bondport_UpdateSelected(p, event_data);
+               bondport_UpdateNTT(p, event_data);
+               bondport_RecordPDU(p, event_data);
+               p->po_actor_state
+                       = lacp_actor_partner_state_set_not_expired(p->po_actor_state);
+               bondport_assign_to_LAG(p);
+               /* start current_while timer */
+               ps = &p->po_partner_state;
+               if (lacp_actor_partner_state_short_timeout(ps->ps_state)) {
+                       tv.tv_sec = LACP_SHORT_TIMEOUT_TIME;
+               } else {
+                       tv.tv_sec = LACP_LONG_TIMEOUT_TIME;
+               }
+               tv.tv_usec = 0;
+               devtimer_set_relative(p->po_current_while_timer, tv,
+                   (devtimer_timeout_func)
+                   bondport_receive_machine_current,
+                   (void *)LAEventTimeout, NULL);
+               break;
+       case LAEventTimeout:
+               bondport_receive_machine_expired(p, LAEventStart, NULL);
+               break;
+       default:
+               break;
+       }
+       return;
 }
 
 /**
- ** Periodic Transmission machine
- **/
+** Periodic Transmission machine
+**/
 
 static void
 bondport_periodic_transmit_machine(bondport_ref p, LAEvent event,
-                                  __unused void * event_data)
+    __unused void * event_data)
 {
-    int                        interval;
-    partner_state_ref  ps;
-    struct timeval     tv;
+       int                 interval;
+       partner_state_ref   ps;
+       struct timeval      tv;
 
-    switch (event) {
-    case LAEventStart:
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] periodic_transmit Start\n",
-                            bondport_get_name(p));
-       }
+       switch (event) {
+       case LAEventStart:
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] periodic_transmit Start\n",
+                           bondport_get_name(p));
+               }
        /* FALL THROUGH */
-    case LAEventMediaChange:
-       devtimer_cancel(p->po_periodic_timer);
-       p->po_periodic_interval = 0;
-       if (media_active(&p->po_media_info) == 0
-           || media_full_duplex(&p->po_media_info) == 0) {
-           break;
-       }
-    case LAEventPacket:
-       /* Neither Partner nor Actor are LACP Active, no periodic tx */
-       ps = &p->po_partner_state;
-       if (lacp_actor_partner_state_active_lacp(p->po_actor_state) == 0
-           && (lacp_actor_partner_state_active_lacp(ps->ps_state) 
-               == 0)) {
-           devtimer_cancel(p->po_periodic_timer);
-           p->po_periodic_interval = 0;
-           break;
-       }
-       if (lacp_actor_partner_state_short_timeout(ps->ps_state)) {
-           interval = LACP_FAST_PERIODIC_TIME;
-       }
-       else {
-           interval = LACP_SLOW_PERIODIC_TIME;
-       }
-       if (p->po_periodic_interval != interval) {
-           if (interval == LACP_FAST_PERIODIC_TIME
-               && p->po_periodic_interval == LACP_SLOW_PERIODIC_TIME) {
-               if (g_bond->verbose) {
-                   timestamp_printf("[%s] periodic_transmit:"
-                                    " Need To Transmit\n",
-                                    bondport_get_name(p));
+       case LAEventMediaChange:
+               devtimer_cancel(p->po_periodic_timer);
+               p->po_periodic_interval = 0;
+               if (media_active(&p->po_media_info) == 0
+                   || media_ok(&p->po_media_info) == 0) {
+                       break;
+               }
+       case LAEventPacket:
+               /* Neither Partner nor Actor are LACP Active, no periodic tx */
+               ps = &p->po_partner_state;
+               if (lacp_actor_partner_state_active_lacp(p->po_actor_state) == 0
+                   && (lacp_actor_partner_state_active_lacp(ps->ps_state)
+                   == 0)) {
+                       devtimer_cancel(p->po_periodic_timer);
+                       p->po_periodic_interval = 0;
+                       break;
                }
+               if (lacp_actor_partner_state_short_timeout(ps->ps_state)) {
+                       interval = LACP_FAST_PERIODIC_TIME;
+               } else {
+                       interval = LACP_SLOW_PERIODIC_TIME;
+               }
+               if (p->po_periodic_interval != interval) {
+                       if (interval == LACP_FAST_PERIODIC_TIME
+                           && p->po_periodic_interval == LACP_SLOW_PERIODIC_TIME) {
+                               if (if_bond_debug) {
+                                       timestamp_printf("[%s] periodic_transmit:"
+                                           " Need To Transmit\n",
+                                           bondport_get_name(p));
+                               }
+                               bondport_flags_set_ntt(p);
+                       }
+                       p->po_periodic_interval = interval;
+                       tv.tv_usec = 0;
+                       tv.tv_sec = interval;
+                       devtimer_set_relative(p->po_periodic_timer, tv,
+                           (devtimer_timeout_func)
+                           bondport_periodic_transmit_machine,
+                           (void *)LAEventTimeout, NULL);
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Periodic Transmission Timer: %d secs\n",
+                                   bondport_get_name(p),
+                                   p->po_periodic_interval);
+                       }
+               }
+               break;
+       case LAEventTimeout:
                bondport_flags_set_ntt(p);
-           }
-           p->po_periodic_interval = interval;
-           tv.tv_usec = 0;
-           tv.tv_sec = interval;
-           devtimer_set_relative(p->po_periodic_timer, tv, 
-                                 (devtimer_timeout_func)
-                                 bondport_periodic_transmit_machine,
-                                 (void *)LAEventTimeout, NULL);
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Periodic Transmission Timer: %d secs\n",
-                                bondport_get_name(p), 
-                                p->po_periodic_interval);
-           }
-       }
-       break;
-    case LAEventTimeout:
-       bondport_flags_set_ntt(p);
-       tv.tv_sec = p->po_periodic_interval;
-       tv.tv_usec = 0;
-       devtimer_set_relative(p->po_periodic_timer, tv, (devtimer_timeout_func)
-                             bondport_periodic_transmit_machine,
-                             (void *)LAEventTimeout, NULL);
-       if (g_bond->verbose > 1) {
-           timestamp_printf("[%s] Periodic Transmission Timer: %d secs\n",
-                            bondport_get_name(p), p->po_periodic_interval);
-       }
-       break;
-    default:
-       break;
-    }
-    return;
+               tv.tv_sec = p->po_periodic_interval;
+               tv.tv_usec = 0;
+               devtimer_set_relative(p->po_periodic_timer, tv, (devtimer_timeout_func)
+                   bondport_periodic_transmit_machine,
+                   (void *)LAEventTimeout, NULL);
+               if (if_bond_debug > 1) {
+                       timestamp_printf("[%s] Periodic Transmission Timer: %d secs\n",
+                           bondport_get_name(p), p->po_periodic_interval);
+               }
+               break;
+       default:
+               break;
+       }
+       return;
 }
 
 /**
- ** Transmit machine
- **/
+** Transmit machine
+**/
 static int
 bondport_can_transmit(bondport_ref p, int32_t current_secs,
-                     __darwin_time_t * next_secs)
-{
-    if (p->po_last_transmit_secs != current_secs) {
-       p->po_last_transmit_secs = current_secs;
-       p->po_n_transmit = 0;
-    }
-    if (p->po_n_transmit < LACP_PACKET_RATE) {
-       p->po_n_transmit++;
-       return (1);
-    }
-    if (next_secs != NULL) {
-       *next_secs = current_secs + 1;
-    }
-    return (0);
+    __darwin_time_t * next_secs)
+{
+       if (p->po_last_transmit_secs != current_secs) {
+               p->po_last_transmit_secs = current_secs;
+               p->po_n_transmit = 0;
+       }
+       if (p->po_n_transmit < LACP_PACKET_RATE) {
+               p->po_n_transmit++;
+               return 1;
+       }
+       if (next_secs != NULL) {
+               *next_secs = current_secs + 1;
+       }
+       return 0;
 }
 
 static void
 bondport_transmit_machine(bondport_ref p, LAEvent event,
-                         void * event_data)
-{
-    lacp_actor_partner_tlv_ref aptlv;
-    lacp_collector_tlv_ref     ctlv;
-    struct timeval             next_tick_time = {0, 0};
-    lacpdu_ref         out_lacpdu_p;
-    packet_buffer_ref          pkt;
-    partner_state_ref          ps;
-    LAG_info_ref               ps_li;
-
-    switch (event) {
-    case LAEventTimeout:
-    case LAEventStart:
-       if (p->po_periodic_interval == 0 || bondport_flags_ntt(p) == 0) {
-           break;
-       }
-       if (event_data == TRANSMIT_MACHINE_TX_IMMEDIATE) {
-           /* we're going away, transmit the packet no matter what */
-       }
-       else if (bondport_can_transmit(p, devtimer_current_secs(),
-                                      &next_tick_time.tv_sec) == 0) {
-           if (devtimer_enabled(p->po_transmit_timer)) {
-               if (g_bond->verbose > 0) {
-                   timestamp_printf("[%s] Transmit Timer Already Set\n",
-                                    bondport_get_name(p));
-               }
-           }
-           else {
-               devtimer_set_absolute(p->po_transmit_timer, next_tick_time,
-                                     (devtimer_timeout_func)
-                                     bondport_transmit_machine,
-                                     (void *)LAEventTimeout, NULL);
-               if (g_bond->verbose > 0) {
-                   timestamp_printf("[%s] Transmit Timer Deadline %d secs\n",
-                                    bondport_get_name(p),
-                                    (int)next_tick_time.tv_sec);
-               }
-           }
-           break;
-       }
-       if (g_bond->verbose > 0) {
-           if (event == LAEventTimeout) {
-               timestamp_printf("[%s] Transmit Timer Complete\n",
-                                bondport_get_name(p));
-           }
-       }
-       pkt = packet_buffer_allocate(sizeof(*out_lacpdu_p));
-       if (pkt == NULL) {
-           printf("[%s] Transmit: failed to allocate packet buffer\n",
-                  bondport_get_name(p));
-           break;
-       }
-       out_lacpdu_p = (lacpdu_ref)packet_buffer_byteptr(pkt);
-       bzero(out_lacpdu_p, sizeof(*out_lacpdu_p));
-       out_lacpdu_p->la_subtype = IEEE8023AD_SLOW_PROTO_SUBTYPE_LACP;
-       out_lacpdu_p->la_version = LACPDU_VERSION_1;
-
-       /* Actor */
-       aptlv = (lacp_actor_partner_tlv_ref)out_lacpdu_p->la_actor_tlv;
-       aptlv->lap_tlv_type = LACPDU_TLV_TYPE_ACTOR;
-       aptlv->lap_length = LACPDU_ACTOR_TLV_LENGTH;
-       *((lacp_system_ref)aptlv->lap_system) = g_bond->system;
-       lacp_actor_partner_tlv_set_system_priority(aptlv, 
-                                                  g_bond->system_priority);
-       lacp_actor_partner_tlv_set_port_priority(aptlv, p->po_priority);
-       lacp_actor_partner_tlv_set_port(aptlv, bondport_get_index(p));
-       lacp_actor_partner_tlv_set_key(aptlv, p->po_bond->ifb_key);
-       aptlv->lap_state = p->po_actor_state;
-
-       /* Partner */
-       aptlv = (lacp_actor_partner_tlv_ref)out_lacpdu_p->la_partner_tlv;
-       aptlv->lap_tlv_type = LACPDU_TLV_TYPE_PARTNER;
-       aptlv->lap_length = LACPDU_PARTNER_TLV_LENGTH;
-       ps = &p->po_partner_state;
-       ps_li = &ps->ps_lag_info;
-       lacp_actor_partner_tlv_set_port(aptlv, ps->ps_port);
-       lacp_actor_partner_tlv_set_port_priority(aptlv, ps->ps_port_priority);
-       *((lacp_system_ref)aptlv->lap_system) = ps_li->li_system;
-       lacp_actor_partner_tlv_set_system_priority(aptlv, 
-                                                  ps_li->li_system_priority);
-       lacp_actor_partner_tlv_set_key(aptlv, ps_li->li_key);
-       aptlv->lap_state = ps->ps_state;
-
-       /* Collector */
-       ctlv = (lacp_collector_tlv_ref)out_lacpdu_p->la_collector_tlv;
-       ctlv->lac_tlv_type = LACPDU_TLV_TYPE_COLLECTOR;
-       ctlv->lac_length = LACPDU_COLLECTOR_TLV_LENGTH;
-
-       bondport_slow_proto_transmit(p, pkt);
-       bondport_flags_clear_ntt(p);
-       if (g_bond->verbose > 0) {
-           timestamp_printf("[%s] Transmit Packet %d\n",
-                            bondport_get_name(p), p->po_n_transmit);
-       }
-       break;
-    default:
-       break;
-    }
-    return;
+    void * event_data)
+{
+       lacp_actor_partner_tlv_ref  aptlv;
+       lacp_collector_tlv_ref      ctlv;
+       struct timeval              next_tick_time = {.tv_sec = 0, .tv_usec = 0};
+       lacpdu_ref          out_lacpdu_p;
+       packet_buffer_ref           pkt;
+       partner_state_ref           ps;
+       LAG_info_ref                ps_li;
+
+       switch (event) {
+       case LAEventTimeout:
+       case LAEventStart:
+               if (p->po_periodic_interval == 0 || bondport_flags_ntt(p) == 0) {
+                       break;
+               }
+               if (event_data == TRANSMIT_MACHINE_TX_IMMEDIATE) {
+                       /* we're going away, transmit the packet no matter what */
+               } else if (bondport_can_transmit(p, devtimer_current_secs(),
+                   &next_tick_time.tv_sec) == 0) {
+                       if (devtimer_enabled(p->po_transmit_timer)) {
+                               if (if_bond_debug > 0) {
+                                       timestamp_printf("[%s] Transmit Timer Already Set\n",
+                                           bondport_get_name(p));
+                               }
+                       } else {
+                               devtimer_set_absolute(p->po_transmit_timer, next_tick_time,
+                                   (devtimer_timeout_func)
+                                   bondport_transmit_machine,
+                                   (void *)LAEventTimeout, NULL);
+                               if (if_bond_debug > 0) {
+                                       timestamp_printf("[%s] Transmit Timer Deadline %d secs\n",
+                                           bondport_get_name(p),
+                                           (int)next_tick_time.tv_sec);
+                               }
+                       }
+                       break;
+               }
+               if (if_bond_debug > 0) {
+                       if (event == LAEventTimeout) {
+                               timestamp_printf("[%s] Transmit Timer Complete\n",
+                                   bondport_get_name(p));
+                       }
+               }
+               pkt = packet_buffer_allocate(sizeof(*out_lacpdu_p));
+               if (pkt == NULL) {
+                       printf("[%s] Transmit: failed to allocate packet buffer\n",
+                           bondport_get_name(p));
+                       break;
+               }
+               out_lacpdu_p = (lacpdu_ref)packet_buffer_byteptr(pkt);
+               bzero(out_lacpdu_p, sizeof(*out_lacpdu_p));
+               out_lacpdu_p->la_subtype = IEEE8023AD_SLOW_PROTO_SUBTYPE_LACP;
+               out_lacpdu_p->la_version = LACPDU_VERSION_1;
+
+               /* Actor */
+               aptlv = (lacp_actor_partner_tlv_ref)out_lacpdu_p->la_actor_tlv;
+               aptlv->lap_tlv_type = LACPDU_TLV_TYPE_ACTOR;
+               aptlv->lap_length = LACPDU_ACTOR_TLV_LENGTH;
+               *((lacp_system_ref)aptlv->lap_system) = g_bond->system;
+               lacp_actor_partner_tlv_set_system_priority(aptlv,
+                   g_bond->system_priority);
+               lacp_actor_partner_tlv_set_port_priority(aptlv, p->po_priority);
+               lacp_actor_partner_tlv_set_port(aptlv, bondport_get_index(p));
+               lacp_actor_partner_tlv_set_key(aptlv, p->po_bond->ifb_key);
+               aptlv->lap_state = p->po_actor_state;
+
+               /* Partner */
+               aptlv = (lacp_actor_partner_tlv_ref)out_lacpdu_p->la_partner_tlv;
+               aptlv->lap_tlv_type = LACPDU_TLV_TYPE_PARTNER;
+               aptlv->lap_length = LACPDU_PARTNER_TLV_LENGTH;
+               ps = &p->po_partner_state;
+               ps_li = &ps->ps_lag_info;
+               lacp_actor_partner_tlv_set_port(aptlv, ps->ps_port);
+               lacp_actor_partner_tlv_set_port_priority(aptlv, ps->ps_port_priority);
+               *((lacp_system_ref)aptlv->lap_system) = ps_li->li_system;
+               lacp_actor_partner_tlv_set_system_priority(aptlv,
+                   ps_li->li_system_priority);
+               lacp_actor_partner_tlv_set_key(aptlv, ps_li->li_key);
+               aptlv->lap_state = ps->ps_state;
+
+               /* Collector */
+               ctlv = (lacp_collector_tlv_ref)out_lacpdu_p->la_collector_tlv;
+               ctlv->lac_tlv_type = LACPDU_TLV_TYPE_COLLECTOR;
+               ctlv->lac_length = LACPDU_COLLECTOR_TLV_LENGTH;
+
+               bondport_slow_proto_transmit(p, pkt);
+               bondport_flags_clear_ntt(p);
+               if (if_bond_debug > 0) {
+                       timestamp_printf("[%s] Transmit Packet %d\n",
+                           bondport_get_name(p), p->po_n_transmit);
+               }
+               break;
+       default:
+               break;
+       }
+       return;
 }
 
 /**
- ** Mux machine functions
- **/
+** Mux machine functions
+**/
 
 static void
 bondport_mux_machine_detached(bondport_ref p, LAEvent event,
-                             void * event_data);
+    void * event_data);
 static void
 bondport_mux_machine_waiting(bondport_ref p, LAEvent event,
-                            void * event_data);
+    void * event_data);
 static void
 bondport_mux_machine_attached(bondport_ref p, LAEvent event,
-                             void * event_data);
+    void * event_data);
 
 static void
 bondport_mux_machine_collecting_distributing(bondport_ref p, LAEvent event,
-                                            void * event_data);
+    void * event_data);
 
 static void
 bondport_mux_machine(bondport_ref p, LAEvent event, void * event_data)
 {
-    switch (p->po_mux_state) {
-    case MuxState_none:
-       bondport_mux_machine_detached(p, LAEventStart, NULL);
-       break;
-    case MuxState_DETACHED:
-       bondport_mux_machine_detached(p, event, event_data);
-       break;
-    case MuxState_WAITING:
-       bondport_mux_machine_waiting(p, event, event_data);
-       break;
-    case MuxState_ATTACHED:
-       bondport_mux_machine_attached(p, event, event_data);
-       break;
-    case MuxState_COLLECTING_DISTRIBUTING:
-       bondport_mux_machine_collecting_distributing(p, event, event_data);
-       break;
-    default:
-       break;
-    }
-    return;
+       switch (p->po_mux_state) {
+       case MuxState_none:
+               bondport_mux_machine_detached(p, LAEventStart, NULL);
+               break;
+       case MuxState_DETACHED:
+               bondport_mux_machine_detached(p, event, event_data);
+               break;
+       case MuxState_WAITING:
+               bondport_mux_machine_waiting(p, event, event_data);
+               break;
+       case MuxState_ATTACHED:
+               bondport_mux_machine_attached(p, event, event_data);
+               break;
+       case MuxState_COLLECTING_DISTRIBUTING:
+               bondport_mux_machine_collecting_distributing(p, event, event_data);
+               break;
+       default:
+               break;
+       }
+       return;
 }
 
 static void
 bondport_mux_machine_detached(bondport_ref p, LAEvent event,
-                             __unused void * event_data)
+    __unused void * event_data)
 {
-    lacp_actor_partner_state   s;
+       lacp_actor_partner_state    s;
 
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_wait_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Mux DETACHED\n",
-                            bondport_get_name(p));
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_wait_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Mux DETACHED\n",
+                           bondport_get_name(p));
+               }
+               p->po_mux_state = MuxState_DETACHED;
+               bondport_flags_clear_ready(p);
+               bondport_DetachMuxFromAggregator(p);
+               bondport_disable_distributing(p);
+               s = p->po_actor_state;
+               s = lacp_actor_partner_state_set_out_of_sync(s);
+               s = lacp_actor_partner_state_set_not_collecting(s);
+               s = lacp_actor_partner_state_set_not_distributing(s);
+               p->po_actor_state = s;
+               bondport_flags_set_ntt(p);
+               break;
+       case LAEventSelectedChange:
+       case LAEventPacket:
+       case LAEventMediaChange:
+               if (p->po_selected == SelectedState_SELECTED
+                   || p->po_selected == SelectedState_STANDBY) {
+                       bondport_mux_machine_waiting(p, LAEventStart, NULL);
+               }
+               break;
+       default:
+               break;
        }
-       p->po_mux_state = MuxState_DETACHED;
-       bondport_flags_clear_ready(p);
-       bondport_DetachMuxFromAggregator(p);
-       bondport_disable_distributing(p);
-       s = p->po_actor_state;
-       s = lacp_actor_partner_state_set_out_of_sync(s);
-       s = lacp_actor_partner_state_set_not_collecting(s);
-       s = lacp_actor_partner_state_set_not_distributing(s);
-       p->po_actor_state = s;
-       bondport_flags_set_ntt(p);
-       break;
-    case LAEventSelectedChange:
-    case LAEventPacket:
-    case LAEventMediaChange:
-       if (p->po_selected == SelectedState_SELECTED
-           || p->po_selected == SelectedState_STANDBY) {
-           bondport_mux_machine_waiting(p, LAEventStart, NULL);
-       }
-       break;
-    default:
-       break;
-    }
-    return;
+       return;
 }
 
 static void
 bondport_mux_machine_waiting(bondport_ref p, LAEvent event,
-                            __unused void * event_data)
+    __unused void * event_data)
 {
-    struct timeval     tv;
+       struct timeval      tv;
 
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_wait_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Mux WAITING\n", 
-                            bondport_get_name(p));
-       }
-       p->po_mux_state = MuxState_WAITING;
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_wait_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Mux WAITING\n",
+                           bondport_get_name(p));
+               }
+               p->po_mux_state = MuxState_WAITING;
        /* FALL THROUGH */
-    default:
-    case LAEventSelectedChange:
-       if (p->po_selected == SelectedState_UNSELECTED) {
-           bondport_mux_machine_detached(p, LAEventStart, NULL);
-           break;
-       }
-       if (p->po_selected == SelectedState_STANDBY) {
-           devtimer_cancel(p->po_wait_while_timer);
-           /* wait until state changes to SELECTED */
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Mux WAITING: Standby\n",
-                                bondport_get_name(p));
-           }
-           break;
-       }
-       if (bondport_flags_ready(p)) {
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Mux WAITING: Port is already ready\n",
-                                bondport_get_name(p));
-           }
-           break;
-       }
-       if (devtimer_enabled(p->po_wait_while_timer)) {
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Mux WAITING: Timer already set\n",
-                                bondport_get_name(p));
-           }
-           break;
-       }
-       if (ifbond_all_ports_attached(p->po_bond, p)) {
-           devtimer_cancel(p->po_wait_while_timer);
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Mux WAITING: No waiting\n",
-                                bondport_get_name(p));
-           }
-           bondport_flags_set_ready(p);
-           goto no_waiting;
-       }
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Mux WAITING: 2 seconds\n", 
-                            bondport_get_name(p));
-       }
-       tv.tv_sec = LACP_AGGREGATE_WAIT_TIME;
-       tv.tv_usec = 0;
-       devtimer_set_relative(p->po_wait_while_timer, tv, 
-                             (devtimer_timeout_func)
-                             bondport_mux_machine_waiting,
-                             (void *)LAEventTimeout, NULL);
-       break;
-    case LAEventTimeout:
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Mux WAITING: Ready\n", 
-                            bondport_get_name(p));
-       }
-       bondport_flags_set_ready(p);
-       break;
-    case LAEventReady:
-    no_waiting:
-       if (bondport_flags_ready(p)){
-           if (g_bond->verbose) {
-               timestamp_printf("[%s] Mux WAITING: All Ports Ready\n", 
-                                bondport_get_name(p));
-           }
-           bondport_mux_machine_attached(p, LAEventStart, NULL);
-           break;
-       }
-       break;
-    }
-    return;
+       default:
+       case LAEventSelectedChange:
+               if (p->po_selected == SelectedState_UNSELECTED) {
+                       bondport_mux_machine_detached(p, LAEventStart, NULL);
+                       break;
+               }
+               if (p->po_selected == SelectedState_STANDBY) {
+                       devtimer_cancel(p->po_wait_while_timer);
+                       /* wait until state changes to SELECTED */
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Mux WAITING: Standby\n",
+                                   bondport_get_name(p));
+                       }
+                       break;
+               }
+               if (bondport_flags_ready(p)) {
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Mux WAITING: Port is already ready\n",
+                                   bondport_get_name(p));
+                       }
+                       break;
+               }
+               if (devtimer_enabled(p->po_wait_while_timer)) {
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Mux WAITING: Timer already set\n",
+                                   bondport_get_name(p));
+                       }
+                       break;
+               }
+               if (ifbond_all_ports_attached(p->po_bond, p)) {
+                       devtimer_cancel(p->po_wait_while_timer);
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Mux WAITING: No waiting\n",
+                                   bondport_get_name(p));
+                       }
+                       bondport_flags_set_ready(p);
+                       goto no_waiting;
+               }
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Mux WAITING: 2 seconds\n",
+                           bondport_get_name(p));
+               }
+               tv.tv_sec = LACP_AGGREGATE_WAIT_TIME;
+               tv.tv_usec = 0;
+               devtimer_set_relative(p->po_wait_while_timer, tv,
+                   (devtimer_timeout_func)
+                   bondport_mux_machine_waiting,
+                   (void *)LAEventTimeout, NULL);
+               break;
+       case LAEventTimeout:
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Mux WAITING: Ready\n",
+                           bondport_get_name(p));
+               }
+               bondport_flags_set_ready(p);
+               break;
+       case LAEventReady:
+no_waiting:
+               if (bondport_flags_ready(p)) {
+                       if (if_bond_debug) {
+                               timestamp_printf("[%s] Mux WAITING: All Ports Ready\n",
+                                   bondport_get_name(p));
+                       }
+                       bondport_mux_machine_attached(p, LAEventStart, NULL);
+                       break;
+               }
+               break;
+       }
+       return;
 }
 
 static void
 bondport_mux_machine_attached(bondport_ref p, LAEvent event,
-                             __unused void * event_data)
+    __unused void * event_data)
 {
-    lacp_actor_partner_state   s;
+       lacp_actor_partner_state    s;
 
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_wait_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Mux ATTACHED\n",
-                            bondport_get_name(p));
-       }
-       p->po_mux_state = MuxState_ATTACHED;
-       bondport_AttachMuxToAggregator(p);
-       s = p->po_actor_state;
-       s = lacp_actor_partner_state_set_in_sync(s);
-       s = lacp_actor_partner_state_set_not_collecting(s);
-       s = lacp_actor_partner_state_set_not_distributing(s);
-       bondport_disable_distributing(p);
-       p->po_actor_state = s;
-       bondport_flags_set_ntt(p);
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_wait_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Mux ATTACHED\n",
+                           bondport_get_name(p));
+               }
+               p->po_mux_state = MuxState_ATTACHED;
+               bondport_AttachMuxToAggregator(p);
+               s = p->po_actor_state;
+               s = lacp_actor_partner_state_set_in_sync(s);
+               s = lacp_actor_partner_state_set_not_collecting(s);
+               s = lacp_actor_partner_state_set_not_distributing(s);
+               bondport_disable_distributing(p);
+               p->po_actor_state = s;
+               bondport_flags_set_ntt(p);
        /* FALL THROUGH */
-    default:
-       switch (p->po_selected) {
-       case SelectedState_SELECTED:
-           s = p->po_partner_state.ps_state;
-           if (lacp_actor_partner_state_in_sync(s)) {
-               bondport_mux_machine_collecting_distributing(p, LAEventStart, 
-                                                            NULL);
-           }
-           break;
        default:
-           bondport_mux_machine_detached(p, LAEventStart, NULL);
-           break;
+               switch (p->po_selected) {
+               case SelectedState_SELECTED:
+                       s = p->po_partner_state.ps_state;
+                       if (lacp_actor_partner_state_in_sync(s)) {
+                               bondport_mux_machine_collecting_distributing(p, LAEventStart,
+                                   NULL);
+                       }
+                       break;
+               default:
+                       bondport_mux_machine_detached(p, LAEventStart, NULL);
+                       break;
+               }
+               break;
        }
-       break;
-    }
-    return;
+       return;
 }
 
 static void
-bondport_mux_machine_collecting_distributing(bondport_ref p, 
-                                            LAEvent event,
-                                            __unused void * event_data)
-{
-    lacp_actor_partner_state   s;
-
-    switch (event) {
-    case LAEventStart:
-       devtimer_cancel(p->po_wait_while_timer);
-       if (g_bond->verbose) {
-           timestamp_printf("[%s] Mux COLLECTING_DISTRIBUTING\n", 
-                            bondport_get_name(p));
-       }
-       p->po_mux_state = MuxState_COLLECTING_DISTRIBUTING;
-       bondport_enable_distributing(p);
-       s = p->po_actor_state;
-       s = lacp_actor_partner_state_set_collecting(s);
-       s = lacp_actor_partner_state_set_distributing(s);
-       p->po_actor_state = s;
-       bondport_flags_set_ntt(p);
+bondport_mux_machine_collecting_distributing(bondport_ref p,
+    LAEvent event,
+    __unused void * event_data)
+{
+       lacp_actor_partner_state    s;
+
+       switch (event) {
+       case LAEventStart:
+               devtimer_cancel(p->po_wait_while_timer);
+               if (if_bond_debug) {
+                       timestamp_printf("[%s] Mux COLLECTING_DISTRIBUTING\n",
+                           bondport_get_name(p));
+               }
+               p->po_mux_state = MuxState_COLLECTING_DISTRIBUTING;
+               bondport_enable_distributing(p);
+               s = p->po_actor_state;
+               s = lacp_actor_partner_state_set_collecting(s);
+               s = lacp_actor_partner_state_set_distributing(s);
+               p->po_actor_state = s;
+               bondport_flags_set_ntt(p);
        /* FALL THROUGH */
-    default:
-       s = p->po_partner_state.ps_state;
-       if (lacp_actor_partner_state_in_sync(s) == 0) {
-           bondport_mux_machine_attached(p, LAEventStart, NULL);
-           break;
-       }
-       switch (p->po_selected) {
-       case SelectedState_UNSELECTED:
-       case SelectedState_STANDBY:
-           bondport_mux_machine_attached(p, LAEventStart, NULL);
-           break;
        default:
-           break;
+               s = p->po_partner_state.ps_state;
+               if (lacp_actor_partner_state_in_sync(s) == 0) {
+                       bondport_mux_machine_attached(p, LAEventStart, NULL);
+                       break;
+               }
+               switch (p->po_selected) {
+               case SelectedState_UNSELECTED:
+               case SelectedState_STANDBY:
+                       bondport_mux_machine_attached(p, LAEventStart, NULL);
+                       break;
+               default:
+                       break;
+               }
+               break;
        }
-       break;
-    }
-    return;
+       return;
 }