]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/if_bond.c
xnu-3789.70.16.tar.gz
[apple/xnu.git] / bsd / net / if_bond.c
index fd632b8a493bae853b41e4a34e559247e0e7c485..34f6e03d4ffd025e8f2460e5dd2b38086536a506 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2014 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -79,8 +79,6 @@
 #include <net/if_media.h>
 #include <net/multicast_list.h>
 
-extern void dlil_input_packet_list(struct ifnet *, struct mbuf *);
-
 static struct ether_addr slow_proto_multicast = {
     IEEE8023AD_SLOW_PROTO_MULTICAST
 };
@@ -304,26 +302,6 @@ struct bondport_s {
 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;
-}
-
-static __inline__ void
-ifbond_flags_clear_promisc(ifbond_ref ifb)
-{
-    ifb->ifb_flags &= ~IFBF_PROMISC;
-    return;
-}
-
 static __inline__ int
 ifbond_flags_if_detaching(ifbond_ref ifb)
 {
@@ -343,20 +321,6 @@ 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;
-}
-
 static __inline__ int
 ifbond_flags_change_in_progress(ifbond_ref ifb)
 {
@@ -514,11 +478,15 @@ packet_buffer_allocate(int length)
     /* 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 %lu\n", size, MHLEN);
-       return (NULL);
+       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);
     }
-    m = m_gethdr(M_WAITOK, MT_DATA);
     if (m == NULL) {
        return (NULL);
     }
@@ -646,12 +614,12 @@ bondport_collecting(bondport_ref p)
 /**
  ** bond interface/dlil specific routines
  **/
-static int bond_clone_create(struct if_clone *, int);
-static void bond_clone_destroy(struct ifnet *);
+static int bond_clone_create(struct if_clone *, u_int32_t, void *);
+static int bond_clone_destroy(struct ifnet *);
 static int bond_input(ifnet_t ifp, protocol_family_t protocol, mbuf_t m,
                                          char *frame_header);
 static int bond_output(struct ifnet *ifp, struct mbuf *m);
-static int bond_ioctl(struct ifnet *ifp, u_int32_t cmd, void * addr);
+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);
 static int bond_attach_protocol(struct ifnet *ifp);
@@ -666,7 +634,7 @@ static struct if_clone bond_cloner = IF_CLONE_INITIALIZER(BONDNAME,
                                                          bond_clone_destroy, 
                                                          0,
                                                          BOND_MAXUNIT);
-static void interface_link_event(struct ifnet * ifp, u_long event_code);
+static void interface_link_event(struct ifnet * ifp, u_int32_t event_code);
 
 static int
 siocsifmtu(struct ifnet * ifp, int mtu)
@@ -724,8 +692,9 @@ ifbond_release(ifbond_ref ifb)
                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);
+           (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);
@@ -832,6 +801,10 @@ link_speed(int active)
     case IFM_10G_SR:
     case IFM_10G_LR:
        return (10000);
+    case IFM_2500_T:
+       return (2500);
+    case IFM_5000_T:
+       return (5000);
     }
 }
 
@@ -873,33 +846,6 @@ interface_media_info(struct ifnet * ifp)
     return (mi);
 }
 
-/**
- ** interface utility functions
- **/
-static __inline__ struct ifaddr * 
-ifindex_get_ifaddr(int i)
-{
-    if (i > if_index || i == 0) {
-       return (NULL);
-    }
-    return (ifnet_addrs[i - 1]);
-}
-
-static __inline__ struct ifaddr *
-ifp_get_ifaddr(struct ifnet * ifp)
-{
-    return (ifindex_get_ifaddr(ifnet_index(ifp)));
-}
-
-static __inline__ struct sockaddr_dl *
-ifp_get_sdl(struct ifnet * ifp)
-{
-    struct ifaddr *    ifa;
-
-    ifa = ifp_get_ifaddr(ifp);
-    return ((struct sockaddr_dl *)(ifa->ifa_addr));
-}
-
 static int
 if_siflladdr(struct ifnet * ifp, const struct ether_addr * ea_p)
 {
@@ -912,10 +858,6 @@ if_siflladdr(struct ifnet * ifp, const struct ether_addr * ea_p)
     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 0
     return (ifnet_ioctl(ifp, 0, SIOCSIFLLADDR, &ifr));
 }
 
@@ -928,17 +870,13 @@ bond_globals_create(lacp_system_priority sys_pri,
 {
     bond_globals_ref   b;
 
-    b = _MALLOC(sizeof(*b), M_BOND, M_WAITOK);
+    b = _MALLOC(sizeof(*b), M_BOND, M_WAITOK | M_ZERO);
     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 0
     return (b);
 }
 
@@ -963,7 +901,6 @@ bond_globals_init(void)
     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);
        if (ifp != NULL) {
            break;
@@ -971,7 +908,7 @@ bond_globals_init(void)
     }
     b = NULL;
     if (ifp != NULL) {
-       b = bond_globals_create(0x8000, (lacp_system_ref)ifnet_lladdr(ifp));
+       b = bond_globals_create(0x8000, (lacp_system_ref)IF_LLADDR(ifp));
     }
     bond_lock();
     if (g_bond != NULL) {
@@ -1108,12 +1045,15 @@ bond_setmulti(struct ifnet * ifp)
     return (result);
 }
 
-static void
+static int
 bond_clone_attach(void)
 {
-    if_clone_attach(&bond_cloner);
+    int error;
+
+    if ((error = if_clone_attach(&bond_cloner)) != 0)
+       return error;
     bond_lock_init();
-    return;
+    return 0;
 }
 
 static int
@@ -1132,8 +1072,7 @@ ifbond_add_slow_proto_multicast(ifbond_ref ifb)
     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);
+    error = if_addmulti_anon(ifb->ifb_ifp, (struct sockaddr *)&sdl, &ifma);
     if (error == 0) {
        ifb->ifb_ifma_slow_proto = ifma;
     }
@@ -1141,23 +1080,22 @@ ifbond_add_slow_proto_multicast(ifbond_ref ifb)
 }
 
 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;
+       struct ifnet_init_eparams       bond_init;
        
        error = bond_globals_init();
        if (error != 0) {
                return (error);
        }
        
-       ifb = _MALLOC(sizeof(ifbond), M_BOND, M_WAITOK);
+       ifb = _MALLOC(sizeof(ifbond), M_BOND, M_WAITOK | M_ZERO);
        if (ifb == NULL) {
                return (ENOMEM);
        }
-       bzero(ifb, sizeof(*ifb));
        
        ifbond_retain(ifb);
        TAILQ_INIT(&ifb->ifb_port_list);
@@ -1165,13 +1103,16 @@ bond_clone_create(struct if_clone * ifc, int unit)
        ifb->ifb_key = unit + 1;
        
        /* use the interface name as the unique id for ifp recycle */
-       if ((u_long)snprintf(ifb->ifb_name, sizeof(ifb->ifb_name), "%s%d",
+       if ((u_int32_t)snprintf(ifb->ifb_name, sizeof(ifb->ifb_name), "%s%d",
                                                 ifc->ifc_name, unit) >= sizeof(ifb->ifb_name)) {
                ifbond_release(ifb);
                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;
@@ -1183,14 +1124,14 @@ 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);
@@ -1260,15 +1201,15 @@ bond_if_detach(struct ifnet * ifp)
     int                error;
 
     error = ifnet_detach(ifp);
-       if (error) {
-           printf("bond_if_detach %s%d: ifnet_detach failed, %d\n",
-                  ifnet_name(ifp), ifnet_unit(ifp), error);
-       }
+    if (error) {
+       printf("bond_if_detach %s%d: ifnet_detach failed, %d\n",
+              ifnet_name(ifp), ifnet_unit(ifp), error);
+    }
        
     return;
 }
 
-static void
+static int
 bond_clone_destroy(struct ifnet * ifp)
 {
     ifbond_ref ifb;
@@ -1277,16 +1218,16 @@ bond_clone_destroy(struct ifnet * ifp)
     ifb = ifnet_softc(ifp);
     if (ifb == NULL || ifnet_type(ifp) != IFT_IEEE8023ADLAG) {
        bond_unlock();
-       return;
+       return 0;
     }
     if (ifbond_flags_if_detaching(ifb)) {
        bond_unlock();
-       return;
+       return 0;
     }
     bond_remove(ifb);
     bond_unlock();
     bond_if_detach(ifp);
-    return;
+    return 0;
 }
 
 static int 
@@ -1336,7 +1277,7 @@ ether_header_hash(struct ether_header * eh_p)
 }
 
 static struct mbuf *
-S_mbuf_skip_to_offset(struct mbuf * m, long * offset)
+S_mbuf_skip_to_offset(struct mbuf * m, int32_t * offset)
 {
     int                        len;
 
@@ -1369,7 +1310,7 @@ make_uint32(u_char c0, u_char c1, u_char c2, u_char c3)
 #endif /* BYTE_ORDER == LITTLE_ENDIAN */
 
 static int
-S_mbuf_copy_uint32(struct mbuf * m, long offset, uint32_t * val)
+S_mbuf_copy_uint32(struct mbuf * m, int32_t offset, uint32_t * val)
 {
     struct mbuf *      current;
     u_char *           current_data;
@@ -1419,7 +1360,7 @@ ip_header_hash(struct mbuf * m)
     struct in_addr     ip_dst;
     struct in_addr     ip_src;
     u_char             ip_p;
-    long               offset;
+    int32_t            offset;
     struct mbuf *      orig_m = m;
 
     /* find the IP protocol field relative to the start of the packet */
@@ -1460,7 +1401,7 @@ ipv6_header_hash(struct mbuf * m)
 {
     u_char *           data;
     int                        i;
-    long               offset;
+    int32_t            offset;
     struct mbuf *      orig_m = m;
     uint32_t *         scan;
     uint32_t           val;
@@ -1504,6 +1445,8 @@ bond_output(struct ifnet * ifp, struct mbuf * m)
     uint32_t                   h;
     ifbond_ref                 ifb;
     struct ifnet *             port_ifp = NULL;
+    int                                err;
+    struct flowadv             adv = { FADV_SUCCESS };
        
     if (m == 0) {
        return (0);
@@ -1512,8 +1455,8 @@ bond_output(struct ifnet * ifp, struct mbuf * m)
        m_freem(m);
        return (0);
     }
-    if (m->m_pkthdr.socket_id != 0) {
-       h = m->m_pkthdr.socket_id;
+    if (m->m_pkthdr.pkt_flowid != 0) {
+       h = m->m_pkthdr.pkt_flowid;
     }
     else {
        struct ether_header *   eh_p;
@@ -1551,7 +1494,17 @@ bond_output(struct ifnet * ifp, struct mbuf * m)
     }
     bond_bpf_output(ifp, m, bpf_func);
 
-    return (ifnet_output_raw(port_ifp, PF_BOND, m));
+    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();
@@ -1761,7 +1714,7 @@ bond_input(ifnet_t port_ifp, __unused protocol_family_t protocol, mbuf_t m,
     }
     m->m_pkthdr.rcvif = ifp;
     bond_bpf_input(ifp, m, eh_p, bpf_func);
-    m->m_pkthdr.header = frame_header;
+    m->m_pkthdr.pkt_hdr = frame_header;
     dlil_input_packet_list(ifp, m);
     return 0;
 
@@ -1867,14 +1820,13 @@ bondport_create(struct ifnet * port_ifp, lacp_port_priority priority,
     lacp_actor_partner_state   s;
 
     *ret_error = 0;
-    p = _MALLOC(sizeof(*p), M_BOND, M_WAITOK);
+    p = _MALLOC(sizeof(*p), M_BOND, M_WAITOK | M_ZERO);
     if (p == NULL) {
        *ret_error = ENOMEM;
        return (NULL);
     }
-    bzero(p, sizeof(*p));
     multicast_list_init(&p->po_multicast);
-    if ((u_long)snprintf(p->po_name, sizeof(p->po_name), "%s%d",
+    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");
@@ -2089,7 +2041,7 @@ bond_add_interface(struct ifnet * ifp, struct ifnet * port_ifp)
     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));
+    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);
@@ -2104,7 +2056,7 @@ bond_add_interface(struct ifnet * ifp, struct ifnet * port_ifp)
 
     /* 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,
+       ifnet_set_lladdr_and_type(ifp, IF_LLADDR(port_ifp), ETHER_ADDR_LEN,
                                  IFT_ETHER);
     }
 
@@ -2157,7 +2109,7 @@ bond_add_interface(struct ifnet * ifp, struct ifnet * port_ifp)
 
     /* re-program the port's ethernet address */
     error = if_siflladdr(port_ifp, 
-                        (const struct ether_addr *)ifnet_lladdr(ifp));
+                        (const struct ether_addr *)IF_LLADDR(ifp));
     if (error != 0) {
        /* port doesn't support setting the link address */
        printf("bond_add_interface(%s, %s): if_siflladdr failed %d\n", 
@@ -2325,7 +2277,7 @@ bond_remove_interface(ifbond_ref ifb, struct ifnet * port_ifp)
        ifnet_set_mtu(ifp, 0);
        ifb->ifb_altmtu = 0;
     } else if (ifbond_flags_lladdr(ifb) == FALSE
-              && bcmp(&p->po_saved_addr, ifnet_lladdr(ifp), 
+              && bcmp(&p->po_saved_addr, IF_LLADDR(ifp), 
                       ETHER_ADDR_LEN) == 0) {
        new_link_address = TRUE;
     }
@@ -2368,7 +2320,7 @@ bond_remove_interface(ifbond_ref ifb, struct ifnet * port_ifp)
            scan_ifp = scan_port->po_ifp;
 
            error = if_siflladdr(scan_ifp,
-                                (const struct ether_addr *) ifnet_lladdr(ifp));
+                                (const struct ether_addr *) IF_LLADDR(ifp));
            if (error != 0) {
                printf("bond_remove_interface(%s, %s): "
                       "if_siflladdr (%s) failed %d\n", 
@@ -2554,7 +2506,7 @@ bond_get_status(ifbond_ref ifb, struct if_bond_req * ibr_p, user_addr_t datap)
            break;
        }
        bzero(&ibs, sizeof(ibs));
-       strncpy(ibs.ibs_if_name, port->po_name, sizeof(ibs.ibs_if_name));
+       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;
@@ -2595,24 +2547,6 @@ 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 0
     return (error);
 }
 
@@ -2729,14 +2663,14 @@ bond_set_mtu(struct ifnet * ifp, int mtu, int isdevmtu)
 }
 
 static int
-bond_ioctl(struct ifnet *ifp, u_int32_t cmd, void * data)
+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 ifmediareq64 *ifmr;
+    struct ifmediareq  *ifmr;
     struct ifnet *     port_ifp = NULL;
     user_addr_t                user_addr;
 
@@ -2751,15 +2685,15 @@ bond_ioctl(struct ifnet *ifp, u_int32_t cmd, void * data)
        ifnet_set_flags(ifp, IFF_UP, IFF_UP);
        break;
 
+    case SIOCGIFMEDIA32:
     case SIOCGIFMEDIA64:
-    case SIOCGIFMEDIA:
        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 ifmediareq64 *)data;
+       ifmr = (struct ifmediareq *)data;
        ifmr->ifm_current = IFM_ETHER;
        ifmr->ifm_mask = 0;
        ifmr->ifm_status = IFM_AVALID;
@@ -2777,9 +2711,9 @@ bond_ioctl(struct ifnet *ifp, u_int32_t cmd, void * data)
            ifmr->ifm_status |= IFM_ACTIVE;
        }
        bond_unlock();
-       user_addr = proc_is64bit(current_proc())
-           ? ifmr->ifm_ifmu.ifmu_ulist64
-           : CAST_USER_ADDR_T(ifmr->ifm_ifmu.ifmu_ulist32);
+       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,
@@ -2836,7 +2770,6 @@ bond_ioctl(struct ifnet *ifp, u_int32_t cmd, void * data)
        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;
@@ -2971,23 +2904,16 @@ bond_if_free(struct ifnet * ifp)
 }
 
 static void
-bond_event(struct ifnet * port_ifp, __unused protocol_family_t protocol,
-                  const struct kev_msg * event)
+bond_handle_event(struct ifnet * port_ifp, int event_code)
 {
     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:
+    switch (event_code) {
+    case KEV_DL_IF_DETACHED:
        break;
     case KEV_DL_LINK_OFF:
     case KEV_DL_LINK_ON:
@@ -3004,8 +2930,8 @@ bond_event(struct ifnet * port_ifp, __unused protocol_family_t protocol,
     }
     ifb = p->po_bond;
     old_distributing_count = ifb->ifb_distributing_count;
-    switch (event->event_code) {
-    case KEV_DL_IF_DETACHING:
+    switch (event_code) {
+    case KEV_DL_IF_DETACHED:
        bond_remove_interface(ifb, p->po_ifp);
        break;
     case KEV_DL_LINK_OFF:
@@ -3067,22 +2993,54 @@ bond_event(struct ifnet * port_ifp, __unused protocol_family_t protocol,
 }
 
 static void
-interface_link_event(struct ifnet * ifp, u_long event_code)
+bond_event(struct ifnet * 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:
+       /* we only care about link status changes */
+       bond_handle_event(port_ifp, event_code);
+       break;
+    default:
+       break;
+    }
+    return;
+}
+
+static errno_t
+bond_detached(ifnet_t port_ifp, __unused protocol_family_t protocol)
+{
+    bond_handle_event(port_ifp, KEV_DL_IF_DETACHED);
+    return (0);
+}
+
+static void
+interface_link_event(struct ifnet * ifp, u_int32_t event_code)
 {
     struct {
        struct kern_event_msg   header;
-       u_long                  unit;
+       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_long) ifnet_unit(ifp);
-    strncpy(event.if_name, ifnet_name(ifp), IFNAMSIZ);
+    event.unit                 = (u_int32_t) ifnet_unit(ifp);
+    strlcpy(event.if_name, ifnet_name(ifp), IFNAMSIZ);
     ifnet_event(ifp, &event.header);
     return;
 }
@@ -3106,6 +3064,7 @@ bond_attach_protocol(struct ifnet *ifp)
     bzero(&reg, sizeof(reg));
     reg.input = bond_input;
     reg.event = bond_event;
+    reg.detached = bond_detached;
        
     error = ifnet_attach_protocol(ifp, PF_BOND, &reg);
     if (error) {
@@ -3166,15 +3125,12 @@ bond_family_init(void)
        goto done;
     }
 #endif
-    error = proto_register_plumber(PF_APPLETALK, APPLE_IF_FAM_BOND, 
-                                 ether_attach_at, 
-                                 ether_detach_at);
+    error = bond_clone_attach();
     if (error != 0) {
-       printf("bond: proto_register_plumber failed for AppleTalk error=%d\n",
-              error);
-       goto done;
+        printf("bond: proto_register_plumber failed bond_clone_attach error=%d\n",
+               error);
+        goto done;
     }
-    bond_clone_attach();
 
  done:
     return (error);
@@ -3435,7 +3391,7 @@ ifbond_set_max_active(ifbond_ref bond, int max_active)
     }
     return;
 }
-#endif 0
+#endif
 
 static int
 ifbond_all_ports_ready(ifbond_ref bond)
@@ -4382,7 +4338,7 @@ bondport_periodic_transmit_machine(bondport_ref p, LAEvent event,
  **/
 static int
 bondport_can_transmit(bondport_ref p, int32_t current_secs,
-                     long * next_secs)
+                     __darwin_time_t * next_secs)
 {
     if (p->po_last_transmit_secs != current_secs) {
        p->po_last_transmit_secs = current_secs;