X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/143464d58d2bd6378e74eec636961ceb0d32fb91..fe8ab488e9161c46dd9885d58fc52996dc0249ff:/bsd/net/dlil.c?ds=sidebyside diff --git a/bsd/net/dlil.c b/bsd/net/dlil.c index ff2d31cf0..28d307d13 100644 --- a/bsd/net/dlil.c +++ b/bsd/net/dlil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2013 Apple Inc. All rights reserved. + * Copyright (c) 1999-2014 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -606,6 +606,11 @@ SYSCTL_UINT(_net_link_generic_system, OID_AUTO, flow_advisory, CTLFLAG_RW | CTLFLAG_LOCKED, &if_flowadv, 1, "enable flow-advisory mechanism"); +static u_int32_t if_delaybased_queue = 1; +SYSCTL_UINT(_net_link_generic_system, OID_AUTO, delaybased_queue, + CTLFLAG_RW | CTLFLAG_LOCKED, &if_delaybased_queue, 1, + "enable delay based dynamic queue sizing"); + static uint64_t hwcksum_in_invalidated = 0; SYSCTL_QUAD(_net_link_generic_system, OID_AUTO, hwcksum_in_invalidated, CTLFLAG_RD | CTLFLAG_LOCKED, @@ -973,7 +978,7 @@ dlil_post_msg(struct ifnet *ifp, u_int32_t event_subclass, event_data_len = sizeof(struct net_event_data); } - strncpy(&event_data->if_name[0], ifp->if_name, IFNAMSIZ); + strlcpy(&event_data->if_name[0], ifp->if_name, IFNAMSIZ); event_data->if_family = ifp->if_family; event_data->if_unit = (u_int32_t) ifp->if_unit; @@ -1332,6 +1337,7 @@ dlil_init(void) _CASSERT(IFRTYPE_SUBFAMILY_BLUETOOTH == IFNET_SUBFAMILY_BLUETOOTH); _CASSERT(IFRTYPE_SUBFAMILY_WIFI == IFNET_SUBFAMILY_WIFI); _CASSERT(IFRTYPE_SUBFAMILY_THUNDERBOLT == IFNET_SUBFAMILY_THUNDERBOLT); + _CASSERT(IFRTYPE_SUBFAMILY_RESERVED == IFNET_SUBFAMILY_RESERVED); _CASSERT(DLIL_MODIDLEN == IFNET_MODIDLEN); _CASSERT(DLIL_MODARGLEN == IFNET_MODARGLEN); @@ -2575,8 +2581,6 @@ ifnet_start_thread_fn(void *v, wait_result_t w) } /* NOTREACHED */ - lck_mtx_unlock(&ifp->if_start_lock); - VERIFY(0); /* we should never get here */ } void @@ -2738,8 +2742,6 @@ ifnet_poll_thread_fn(void *v, wait_result_t w) } /* NOTREACHED */ - lck_mtx_unlock(&ifp->if_poll_lock); - VERIFY(0); /* we should never get here */ } void @@ -2953,39 +2955,54 @@ ifnet_enqueue(struct ifnet *ifp, struct mbuf *m) errno_t ifnet_dequeue(struct ifnet *ifp, struct mbuf **mp) { + errno_t rc; if (ifp == NULL || mp == NULL) return (EINVAL); else if (!(ifp->if_eflags & IFEF_TXSTART) || (ifp->if_output_sched_model != IFNET_SCHED_MODEL_NORMAL)) return (ENXIO); + if (!ifnet_is_attached(ifp, 1)) + return (ENXIO); + rc = ifclassq_dequeue(&ifp->if_snd, 1, mp, NULL, NULL, NULL); + ifnet_decr_iorefcnt(ifp); - return (ifclassq_dequeue(&ifp->if_snd, 1, mp, NULL, NULL, NULL)); + return (rc); } errno_t ifnet_dequeue_service_class(struct ifnet *ifp, mbuf_svc_class_t sc, struct mbuf **mp) { + errno_t rc; if (ifp == NULL || mp == NULL || !MBUF_VALID_SC(sc)) return (EINVAL); else if (!(ifp->if_eflags & IFEF_TXSTART) || (ifp->if_output_sched_model != IFNET_SCHED_MODEL_DRIVER_MANAGED)) return (ENXIO); - - return (ifclassq_dequeue_sc(&ifp->if_snd, sc, 1, mp, NULL, NULL, NULL)); + if (!ifnet_is_attached(ifp, 1)) + return (ENXIO); + + rc = ifclassq_dequeue_sc(&ifp->if_snd, sc, 1, mp, NULL, NULL, NULL); + ifnet_decr_iorefcnt(ifp); + return (rc); } errno_t ifnet_dequeue_multi(struct ifnet *ifp, u_int32_t limit, struct mbuf **head, struct mbuf **tail, u_int32_t *cnt, u_int32_t *len) { + errno_t rc; if (ifp == NULL || head == NULL || limit < 1) return (EINVAL); else if (!(ifp->if_eflags & IFEF_TXSTART) || (ifp->if_output_sched_model != IFNET_SCHED_MODEL_NORMAL)) return (ENXIO); - - return (ifclassq_dequeue(&ifp->if_snd, limit, head, tail, cnt, len)); + if (!ifnet_is_attached(ifp, 1)) + return (ENXIO); + + rc = ifclassq_dequeue(&ifp->if_snd, limit, head, tail, cnt, len); + ifnet_decr_iorefcnt(ifp); + return (rc); } errno_t @@ -2993,15 +3010,18 @@ ifnet_dequeue_service_class_multi(struct ifnet *ifp, mbuf_svc_class_t sc, u_int32_t limit, struct mbuf **head, struct mbuf **tail, u_int32_t *cnt, u_int32_t *len) { - + errno_t rc; if (ifp == NULL || head == NULL || limit < 1 || !MBUF_VALID_SC(sc)) return (EINVAL); else if (!(ifp->if_eflags & IFEF_TXSTART) || (ifp->if_output_sched_model != IFNET_SCHED_MODEL_DRIVER_MANAGED)) return (ENXIO); - - return (ifclassq_dequeue_sc(&ifp->if_snd, sc, limit, head, - tail, cnt, len)); + if (!ifnet_is_attached(ifp, 1)) + return (ENXIO); + rc = ifclassq_dequeue_sc(&ifp->if_snd, sc, limit, head, + tail, cnt, len); + ifnet_decr_iorefcnt(ifp); + return (rc); } errno_t @@ -4982,6 +5002,9 @@ ifnet_attach(ifnet_t ifp, const struct sockaddr_dl *ll_addr) if (if_flowadv) sflags |= PKTSCHEDF_QALG_FLOWCTL; + if (if_delaybased_queue) + sflags |= PKTSCHEDF_QALG_DELAYBASED; + /* Initialize transmit queue(s) */ err = ifclassq_setup(ifp, sflags, (dl_if->dl_if_flags & DLIF_REUSE)); if (err != 0) { @@ -5112,6 +5135,7 @@ ifnet_attach(ifnet_t ifp, const struct sockaddr_dl *ll_addr) VERIFY(ifp->if_delegated.type == 0); VERIFY(ifp->if_delegated.family == 0); VERIFY(ifp->if_delegated.subfamily == 0); + VERIFY(ifp->if_delegated.expensive == 0); ifnet_lock_done(ifp); ifnet_head_done(); @@ -5413,9 +5437,6 @@ ifnet_detach(ifnet_t ifp) /* Mark the interface as DOWN */ if_down(ifp); - /* Drain send queue */ - ifclassq_teardown(ifp); - /* Disable forwarding cached route */ lck_mtx_lock(&ifp->if_cached_route_lock); ifp->if_fwd_cacheok = 0; @@ -5548,6 +5569,9 @@ ifnet_detach_final(struct ifnet *ifp) } lck_mtx_unlock(&ifp->if_ref_lock); + /* Drain and destroy send queue */ + ifclassq_teardown(ifp); + /* Detach interface filters */ lck_mtx_lock(&ifp->if_flt_lock); if_flt_monitor_enter(ifp); @@ -5719,6 +5743,7 @@ ifnet_detach_final(struct ifnet *ifp) VERIFY(ifp->if_delegated.type == 0); VERIFY(ifp->if_delegated.family == 0); VERIFY(ifp->if_delegated.subfamily == 0); + VERIFY(ifp->if_delegated.expensive == 0); ifnet_lock_done(ifp); @@ -6036,7 +6061,7 @@ dlil_if_release(ifnet_t ifp) ifnet_lock_exclusive(ifp); lck_mtx_lock(&dlifp->dl_if_lock); dlifp->dl_if_flags &= ~DLIF_INUSE; - strncpy(dlifp->dl_if_namestorage, ifp->if_name, IFNAMSIZ); + strlcpy(dlifp->dl_if_namestorage, ifp->if_name, IFNAMSIZ); ifp->if_name = dlifp->dl_if_namestorage; /* Reset external name (name + unit) */ ifp->if_xname = dlifp->dl_if_xnamestorage; @@ -6228,7 +6253,9 @@ if_lqm_update(struct ifnet *ifp, int lqm) VERIFY(lqm >= IFNET_LQM_MIN && lqm <= IFNET_LQM_MAX); /* Normalize to edge */ - if (lqm > IFNET_LQM_THRESH_UNKNOWN && lqm <= IFNET_LQM_THRESH_POOR) + if (lqm > IFNET_LQM_THRESH_UNKNOWN && lqm <= IFNET_LQM_THRESH_BAD) + lqm = IFNET_LQM_THRESH_BAD; + else if (lqm > IFNET_LQM_THRESH_BAD && lqm <= IFNET_LQM_THRESH_POOR) lqm = IFNET_LQM_THRESH_POOR; else if (lqm > IFNET_LQM_THRESH_POOR && lqm <= IFNET_LQM_THRESH_GOOD) lqm = IFNET_LQM_THRESH_GOOD; @@ -6497,10 +6524,7 @@ dlil_ifaddr_bytes(const struct sockaddr_dl *sdl, size_t *sizep, if (dlil_lladdr_ckreq) { switch (sdl->sdl_type) { case IFT_ETHER: - case IFT_BRIDGE: case IFT_IEEE1394: - case IFT_IEEE8023ADLAG: - case IFT_L2VLAN: break; default: credp = NULL; @@ -6514,9 +6538,6 @@ dlil_ifaddr_bytes(const struct sockaddr_dl *sdl, size_t *sizep, switch (sdl->sdl_type) { case IFT_ETHER: - case IFT_BRIDGE: - case IFT_IEEE8023ADLAG: - case IFT_L2VLAN: VERIFY(size == ETHER_ADDR_LEN); bytes = unspec; break;