/*
- * 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 *);
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)
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;
struct domain *dp;
domain_guard_t guard;
+ eventhandler_lists_ctxt_init(&protoctl_evhdlr_ctxt);
/*
* allocate lock group attribute and group for domain mutexes
*/
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)
{
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);
}
/*
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
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);
}
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
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);
}
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 */