X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..d9a64523371fa019c4575bb400cbbc3a50ac9903:/bsd/net/if_bond.c diff --git a/bsd/net/if_bond.c b/bsd/net/if_bond.c index fd632b8a4..8682a9fe5 100644 --- a/bsd/net/if_bond.c +++ b/bsd/net/if_bond.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2004-2018 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -49,7 +49,6 @@ #include #include #include - #include #include #include @@ -68,6 +67,7 @@ #include #include +#include #include #include @@ -79,15 +79,18 @@ #include #include -extern void dlil_input_packet_list(struct ifnet *, struct mbuf *); - static struct ether_addr slow_proto_multicast = { IEEE8023AD_SLOW_PROTO_MULTICAST }; +typedef struct ifbond_s ifbond, * ifbond_ref; +typedef struct bondport_s bondport, * bondport_ref; + #define BOND_MAXUNIT 128 -#define BONDNAME "bond" -#define M_BOND M_DEVBUF +#define BOND_ZONE_MAX_ELEM MIN(IFNETS_MAX, BOND_MAXUNIT) +#define BONDNAME "bond" + +#define M_BOND M_DEVBUF #define EA_FORMAT "%x:%x:%x:%x:%x:%x" #define EA_CH(e, i) ((u_char)((u_char *)(e))[(i)]) @@ -136,14 +139,14 @@ bond_lock_init(void) static __inline__ void bond_assert_lock_held(void) { - lck_mtx_assert(bond_lck_mtx, LCK_MTX_ASSERT_OWNED); + 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); + LCK_MTX_ASSERT(bond_lck_mtx, LCK_MTX_ASSERT_NOTOWNED); return; } @@ -304,26 +307,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 +326,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 +483,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,27 +619,29 @@ 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); + 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); + bpf_packet_func func); static int bond_attach_protocol(struct ifnet *ifp); static int bond_detach_protocol(struct ifnet *ifp); 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_long 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) @@ -724,13 +699,14 @@ 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); } - FREE(ifb, M_BOND); + if_clone_softc_deallocate(&bond_cloner, ifb); break; default: break; @@ -832,6 +808,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 +853,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 +865,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 +877,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 +908,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 +915,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 +1052,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 +1079,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 +1087,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 = if_clone_softc_allocate(&bond_cloner); if (ifb == NULL) { return (ENOMEM); } - bzero(ifb, sizeof(*ifb)); ifbond_retain(ifb); TAILQ_INIT(&ifb->ifb_port_list); @@ -1165,13 +1110,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 +1131,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 +1208,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 +1225,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 +1284,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 +1317,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 +1367,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 +1408,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 +1452,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 +1462,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 +1501,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 +1721,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 +1827,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"); @@ -2005,6 +1964,10 @@ bond_add_interface(struct ifnet * ifp, struct ifnet * port_ifp) bondport_ref p; int progress = 0; + 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) { @@ -2089,7 +2052,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 +2067,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 +2120,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 +2288,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 +2331,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 +2517,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 +2558,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 +2674,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 +2696,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 +2722,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 +2781,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 +2915,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 +2941,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 +3004,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 +3075,7 @@ bond_attach_protocol(struct ifnet *ifp) bzero(®, sizeof(reg)); reg.input = bond_input; reg.event = bond_event; + reg.detached = bond_detached; error = ifnet_attach_protocol(ifp, PF_BOND, ®); if (error) { @@ -3166,15 +3136,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 +3402,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 +4349,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;