]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/dlil.c
xnu-2782.1.97.tar.gz
[apple/xnu.git] / bsd / net / dlil.c
index ff2d31cf0f949e3741f17323772b4d13961259a8..28d307d133e9b6fb1c1c24f3bede3f1e92d8d7e3 100644 (file)
@@ -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;