]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/uipc_domain.c
xnu-4903.221.2.tar.gz
[apple/xnu.git] / bsd / kern / uipc_domain.c
index 5a1c62a79d5a662e05b167bf5b0dda82495edee6..4433e81bd4e5ec9275c9a766bb663ee8baf46daa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998-2013 Apple Inc. All rights reserved.
+ * Copyright (c) 1998-2018 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
 #include <sys/queue.h>
 
 #include <net/dlil.h>
+#include <net/nwk_wq.h>
 
 #include <mach/boolean.h>
 #include <pexpert/pexpert.h>
 
+/* Eventhandler context for protocol events */
+struct eventhandler_lists_ctxt protoctl_evhdlr_ctxt;
+
 static void pr_init_old(struct protosw *, struct domain *);
 static void init_proto(struct protosw *, struct domain *);
 static void attach_proto(struct protosw *, struct domain *);
@@ -102,9 +106,20 @@ static lck_grp_attr_t      *domain_proto_mtx_grp_attr;
 decl_lck_mtx_data(static, domain_proto_mtx);
 decl_lck_mtx_data(static, domain_timeout_mtx);
 
-extern sysctlfn net_sysctl;
+u_int64_t _net_uptime;
+
+#if (DEVELOPMENT || DEBUG)
+
+SYSCTL_DECL(_kern_ipc);
+
+static int sysctl_do_drain_domains SYSCTL_HANDLER_ARGS;
 
-static u_int64_t _net_uptime;
+SYSCTL_PROC(_kern_ipc, OID_AUTO, do_drain_domains,
+       CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_LOCKED,
+       0, 0,
+       sysctl_do_drain_domains, "I", "force manual drain domains");
+
+#endif /* DEVELOPMENT || DEBUG */
 
 static void
 pr_init_old(struct protosw *pp, struct domain *dp)
@@ -626,7 +641,7 @@ done:
 static void
 domain_sched_timeout(void)
 {
-       lck_mtx_assert(&domain_timeout_mtx, LCK_MTX_ASSERT_OWNED);
+       LCK_MTX_ASSERT(&domain_timeout_mtx, LCK_MTX_ASSERT_OWNED);
 
        if (!domain_timeout_run && domain_draining) {
                domain_timeout_run = TRUE;
@@ -694,6 +709,7 @@ domaininit(void)
        struct domain *dp;
        domain_guard_t guard;
 
+       eventhandler_lists_ctxt_init(&protoctl_evhdlr_ctxt);
        /*
         * allocate lock group attribute and group for domain mutexes
         */
@@ -909,53 +925,6 @@ pffindprotonotype(int family, int protocol)
        return (pp);
 }
 
-int
-net_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
-    user_addr_t newp, size_t newlen, struct proc *p)
-{
-#pragma unused(p)
-       int family, protocol, error = 0;
-       struct domain *dp;
-       struct protosw *pp;
-       domain_guard_t guard;
-
-       /*
-        * All sysctl names at this level are nonterminal;
-        * next two components are protocol family and protocol number,
-        * then at least one addition component.
-        */
-       if (namelen < 3)
-               return (EISDIR);                /* overloaded */
-       family = name[0];
-       protocol = name[1];
-
-       if (family == 0)
-               return (0);
-
-       guard = domain_guard_deploy();
-       TAILQ_FOREACH(dp, &domains, dom_entry) {
-               if (dp->dom_family == family)
-                       break;
-       }
-       if (dp == NULL) {
-               error = ENOPROTOOPT;
-               goto done;
-       }
-
-       TAILQ_FOREACH(pp, &dp->dom_protosw, pr_entry) {
-               if (pp->pr_protocol == protocol && pp->pr_sysctl != NULL) {
-                       error = (*pp->pr_sysctl)(name + 2, namelen - 2,
-                           (void *)(uintptr_t)oldp, oldlenp,
-                           (void *)(uintptr_t)newp, newlen);
-                       goto done;
-               }
-       }
-       error = ENOPROTOOPT;
-done:
-       domain_guard_release(guard);
-       return (error);
-}
-
 void
 pfctlinput(int cmd, struct sockaddr *sa)
 {
@@ -976,31 +945,32 @@ pfctlinput2(int cmd, struct sockaddr *sa, void *ctlparam)
        TAILQ_FOREACH(dp, &domains, dom_entry) {
                TAILQ_FOREACH(pp, &dp->dom_protosw, pr_entry) {
                        if (pp->pr_ctlinput != NULL)
-                               (*pp->pr_ctlinput)(cmd, sa, ctlparam);
+                               (*pp->pr_ctlinput)(cmd, sa, ctlparam, NULL);
                }
        }
        domain_guard_release(guard);
 }
 
 void
-net_update_uptime(void)
+net_update_uptime_with_time(const struct timeval *tvp)
 {
-       struct timeval tv;
-
-       microuptime(&tv);
-       _net_uptime = tv.tv_sec;
+       _net_uptime = tvp->tv_sec;
        /*
         * Round up the timer to the nearest integer value because otherwise
         * we might setup networking timers that are off by almost 1 second.
         */
-       if (tv.tv_usec > 500000)
+       if (tvp->tv_usec > 500000)
                _net_uptime++;
 }
 
 void
-net_update_uptime_secs(uint64_t secs)
+net_update_uptime(void)
 {
-       _net_uptime = secs;
+       struct timeval tv;
+
+       microuptime(&tv);
+
+       net_update_uptime_with_time(&tv);
 }
 
 /*
@@ -1033,13 +1003,13 @@ net_uptime(void)
 void
 domain_proto_mtx_lock_assert_held(void)
 {
-       lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
+       LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
 }
 
 void
 domain_proto_mtx_lock_assert_notheld(void)
 {
-       lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
+       LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
 }
 
 domain_guard_t
@@ -1049,11 +1019,11 @@ domain_guard_deploy(void)
 
        marks = net_thread_marks_push(NET_THREAD_HELD_DOMAIN);
        if (marks != net_thread_marks_none) {
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
                lck_mtx_lock(&domain_proto_mtx);
        }
        else
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
 
        return ((domain_guard_t)(const void*)marks);
 }
@@ -1064,12 +1034,12 @@ domain_guard_release(domain_guard_t guard)
        net_thread_marks_t marks = (net_thread_marks_t)(const void*)guard;
 
        if (marks != net_thread_marks_none) {
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
                lck_mtx_unlock(&domain_proto_mtx);
                net_thread_marks_pop(marks);
        }
        else
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
 }
 
 domain_unguard_t
@@ -1079,11 +1049,11 @@ domain_unguard_deploy(void)
 
        marks = net_thread_unmarks_push(NET_THREAD_HELD_DOMAIN);
        if (marks != net_thread_marks_none) {
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
                lck_mtx_unlock(&domain_proto_mtx);
        }
        else
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
 
        return ((domain_unguard_t)(const void*)marks);
 }
@@ -1094,10 +1064,31 @@ domain_unguard_release(domain_unguard_t unguard)
        net_thread_marks_t marks = (net_thread_marks_t)(const void*)unguard;
 
        if (marks != net_thread_marks_none) {
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_NOTOWNED);
                lck_mtx_lock(&domain_proto_mtx);
                net_thread_unmarks_pop(marks);
        }
        else
-               lck_mtx_assert(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
+               LCK_MTX_ASSERT(&domain_proto_mtx, LCK_MTX_ASSERT_OWNED);
 }
+
+
+#if (DEVELOPMENT || DEBUG)
+static int
+sysctl_do_drain_domains SYSCTL_HANDLER_ARGS
+{
+#pragma unused(arg1, arg2)
+       int error;
+       int dummy = 0;
+
+       error = sysctl_handle_int(oidp, &dummy, 0, req);        
+       if (error || req->newptr == USER_ADDR_NULL)
+               return (error);
+
+       net_drain_domains();
+
+       return (0);
+}
+
+#endif /* DEVELOPMENT || DEBUG */