xref: /freebsd/sys/kern/kern_sysctl.c (revision bdcbfde31e8e9b343f113a1956384bdf30d1ed62)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1982, 1986, 1989, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Mike Karels at Berkeley Software Design, Inc.
9  *
10  * Quite extensively rewritten by Poul-Henning Kamp of the FreeBSD
11  * project, to make these variables more userfriendly.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #include <sys/cdefs.h>
39 #include "opt_capsicum.h"
40 #include "opt_ddb.h"
41 #include "opt_ktrace.h"
42 #include "opt_sysctl.h"
43 
44 #include <sys/param.h>
45 #include <sys/fail.h>
46 #include <sys/systm.h>
47 #include <sys/capsicum.h>
48 #include <sys/kernel.h>
49 #include <sys/limits.h>
50 #include <sys/sysctl.h>
51 #include <sys/malloc.h>
52 #include <sys/priv.h>
53 #include <sys/proc.h>
54 #include <sys/jail.h>
55 #include <sys/kdb.h>
56 #include <sys/lock.h>
57 #include <sys/mutex.h>
58 #include <sys/rmlock.h>
59 #include <sys/sbuf.h>
60 #include <sys/sx.h>
61 #include <sys/sysproto.h>
62 #include <sys/uio.h>
63 #ifdef KTRACE
64 #include <sys/ktrace.h>
65 #endif
66 
67 #ifdef DDB
68 #include <ddb/ddb.h>
69 #include <ddb/db_lex.h>
70 #endif
71 
72 #include <net/vnet.h>
73 
74 #include <security/mac/mac_framework.h>
75 
76 #include <vm/vm.h>
77 #include <vm/vm_extern.h>
78 
79 static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic");
80 static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
81 static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
82 
83 RB_GENERATE(sysctl_oid_list, sysctl_oid, oid_link, cmp_sysctl_oid);
84 
85 /*
86  * The sysctllock protects the MIB tree.  It also protects sysctl
87  * contexts used with dynamic sysctls.  The sysctl_register_oid() and
88  * sysctl_unregister_oid() routines require the sysctllock to already
89  * be held, so the sysctl_wlock() and sysctl_wunlock() routines are
90  * provided for the few places in the kernel which need to use that
91  * API rather than using the dynamic API.  Use of the dynamic API is
92  * strongly encouraged for most code.
93  *
94  * The sysctlmemlock is used to limit the amount of user memory wired for
95  * sysctl requests.  This is implemented by serializing any userland
96  * sysctl requests larger than a single page via an exclusive lock.
97  *
98  * The sysctlstringlock is used to protect concurrent access to writable
99  * string nodes in sysctl_handle_string().
100  */
101 static struct rmlock sysctllock;
102 static struct sx __exclusive_cache_line sysctlmemlock;
103 static struct sx sysctlstringlock;
104 
105 #define	SYSCTL_WLOCK()		rm_wlock(&sysctllock)
106 #define	SYSCTL_WUNLOCK()	rm_wunlock(&sysctllock)
107 #define	SYSCTL_RLOCK(tracker)	rm_rlock(&sysctllock, (tracker))
108 #define	SYSCTL_RUNLOCK(tracker)	rm_runlock(&sysctllock, (tracker))
109 #define	SYSCTL_WLOCKED()	rm_wowned(&sysctllock)
110 #define	SYSCTL_ASSERT_LOCKED()	rm_assert(&sysctllock, RA_LOCKED)
111 #define	SYSCTL_ASSERT_WLOCKED()	rm_assert(&sysctllock, RA_WLOCKED)
112 #define	SYSCTL_ASSERT_RLOCKED()	rm_assert(&sysctllock, RA_RLOCKED)
113 #define	SYSCTL_INIT()		rm_init_flags(&sysctllock, "sysctl lock", \
114 				    RM_SLEEPABLE)
115 #define	SYSCTL_SLEEP(ch, wmesg, timo)					\
116 				rm_sleep(ch, &sysctllock, 0, wmesg, timo)
117 
118 static int sysctl_root(SYSCTL_HANDLER_ARGS);
119 
120 /* Root list */
121 struct sysctl_oid_list sysctl__children = RB_INITIALIZER(&sysctl__children);
122 
123 static char*	sysctl_escape_name(const char*);
124 static int	sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del,
125 		    int recurse);
126 static int	sysctl_old_kernel(struct sysctl_req *, const void *, size_t);
127 static int	sysctl_new_kernel(struct sysctl_req *, void *, size_t);
128 static int	name2oid(const char *, int *, int *, struct sysctl_oid **);
129 
130 static struct sysctl_oid *
131 sysctl_find_oidname(const char *name, struct sysctl_oid_list *list)
132 {
133 	struct sysctl_oid *oidp;
134 
135 	SYSCTL_ASSERT_LOCKED();
136 	SYSCTL_FOREACH(oidp, list) {
137 		if (strcmp(oidp->oid_name, name) == 0) {
138 			return (oidp);
139 		}
140 	}
141 	return (NULL);
142 }
143 
144 static struct sysctl_oid *
145 sysctl_find_oidnamelen(const char *name, size_t len,
146     struct sysctl_oid_list *list)
147 {
148 	struct sysctl_oid *oidp;
149 
150 	SYSCTL_ASSERT_LOCKED();
151 	SYSCTL_FOREACH(oidp, list) {
152 		if (strncmp(oidp->oid_name, name, len) == 0 &&
153 		    oidp->oid_name[len] == '\0')
154 			return (oidp);
155 	}
156 	return (NULL);
157 }
158 
159 /*
160  * Initialization of the MIB tree.
161  *
162  * Order by number in each list.
163  */
164 void
165 sysctl_wlock(void)
166 {
167 
168 	SYSCTL_WLOCK();
169 }
170 
171 void
172 sysctl_wunlock(void)
173 {
174 
175 	SYSCTL_WUNLOCK();
176 }
177 
178 static int
179 sysctl_root_handler_locked(struct sysctl_oid *oid, void *arg1, intmax_t arg2,
180     struct sysctl_req *req, struct rm_priotracker *tracker)
181 {
182 	int error;
183 
184 	if (oid->oid_kind & CTLFLAG_DYN)
185 		atomic_add_int(&oid->oid_running, 1);
186 
187 	if (tracker != NULL)
188 		SYSCTL_RUNLOCK(tracker);
189 	else
190 		SYSCTL_WUNLOCK();
191 
192 	/*
193 	 * Treat set CTLFLAG_NEEDGIANT and unset CTLFLAG_MPSAFE flags the same,
194 	 * untill we're ready to remove all traces of Giant from sysctl(9).
195 	 */
196 	if ((oid->oid_kind & CTLFLAG_NEEDGIANT) ||
197 	    (!(oid->oid_kind & CTLFLAG_MPSAFE)))
198 		mtx_lock(&Giant);
199 	error = oid->oid_handler(oid, arg1, arg2, req);
200 	if ((oid->oid_kind & CTLFLAG_NEEDGIANT) ||
201 	    (!(oid->oid_kind & CTLFLAG_MPSAFE)))
202 		mtx_unlock(&Giant);
203 
204 	KFAIL_POINT_ERROR(_debug_fail_point, sysctl_running, error);
205 
206 	if (tracker != NULL)
207 		SYSCTL_RLOCK(tracker);
208 	else
209 		SYSCTL_WLOCK();
210 
211 	if (oid->oid_kind & CTLFLAG_DYN) {
212 		if (atomic_fetchadd_int(&oid->oid_running, -1) == 1 &&
213 		    (oid->oid_kind & CTLFLAG_DYING) != 0)
214 			wakeup(&oid->oid_running);
215 	}
216 
217 	return (error);
218 }
219 
220 static void
221 sysctl_load_tunable_by_oid_locked(struct sysctl_oid *oidp)
222 {
223 	struct sysctl_req req;
224 	struct sysctl_oid *curr;
225 	char *penv = NULL;
226 	char path[96];
227 	ssize_t rem = sizeof(path);
228 	ssize_t len;
229 	uint8_t data[512] __aligned(sizeof(uint64_t));
230 	int size;
231 	int error;
232 
233 	path[--rem] = 0;
234 
235 	for (curr = oidp; curr != NULL; curr = SYSCTL_PARENT(curr)) {
236 		len = strlen(curr->oid_name);
237 		rem -= len;
238 		if (curr != oidp)
239 			rem -= 1;
240 		if (rem < 0) {
241 			printf("OID path exceeds %d bytes\n", (int)sizeof(path));
242 			return;
243 		}
244 		memcpy(path + rem, curr->oid_name, len);
245 		if (curr != oidp)
246 			path[rem + len] = '.';
247 	}
248 
249 	memset(&req, 0, sizeof(req));
250 
251 	req.td = curthread;
252 	req.oldfunc = sysctl_old_kernel;
253 	req.newfunc = sysctl_new_kernel;
254 	req.lock = REQ_UNWIRED;
255 
256 	switch (oidp->oid_kind & CTLTYPE) {
257 	case CTLTYPE_INT:
258 		if (getenv_array(path + rem, data, sizeof(data), &size,
259 		    sizeof(int), GETENV_SIGNED) == 0)
260 			return;
261 		req.newlen = size;
262 		req.newptr = data;
263 		break;
264 	case CTLTYPE_UINT:
265 		if (getenv_array(path + rem, data, sizeof(data), &size,
266 		    sizeof(int), GETENV_UNSIGNED) == 0)
267 			return;
268 		req.newlen = size;
269 		req.newptr = data;
270 		break;
271 	case CTLTYPE_LONG:
272 		if (getenv_array(path + rem, data, sizeof(data), &size,
273 		    sizeof(long), GETENV_SIGNED) == 0)
274 			return;
275 		req.newlen = size;
276 		req.newptr = data;
277 		break;
278 	case CTLTYPE_ULONG:
279 		if (getenv_array(path + rem, data, sizeof(data), &size,
280 		    sizeof(long), GETENV_UNSIGNED) == 0)
281 			return;
282 		req.newlen = size;
283 		req.newptr = data;
284 		break;
285 	case CTLTYPE_S8:
286 		if (getenv_array(path + rem, data, sizeof(data), &size,
287 		    sizeof(int8_t), GETENV_SIGNED) == 0)
288 			return;
289 		req.newlen = size;
290 		req.newptr = data;
291 		break;
292 	case CTLTYPE_S16:
293 		if (getenv_array(path + rem, data, sizeof(data), &size,
294 		    sizeof(int16_t), GETENV_SIGNED) == 0)
295 			return;
296 		req.newlen = size;
297 		req.newptr = data;
298 		break;
299 	case CTLTYPE_S32:
300 		if (getenv_array(path + rem, data, sizeof(data), &size,
301 		    sizeof(int32_t), GETENV_SIGNED) == 0)
302 			return;
303 		req.newlen = size;
304 		req.newptr = data;
305 		break;
306 	case CTLTYPE_S64:
307 		if (getenv_array(path + rem, data, sizeof(data), &size,
308 		    sizeof(int64_t), GETENV_SIGNED) == 0)
309 			return;
310 		req.newlen = size;
311 		req.newptr = data;
312 		break;
313 	case CTLTYPE_U8:
314 		if (getenv_array(path + rem, data, sizeof(data), &size,
315 		    sizeof(uint8_t), GETENV_UNSIGNED) == 0)
316 			return;
317 		req.newlen = size;
318 		req.newptr = data;
319 		break;
320 	case CTLTYPE_U16:
321 		if (getenv_array(path + rem, data, sizeof(data), &size,
322 		    sizeof(uint16_t), GETENV_UNSIGNED) == 0)
323 			return;
324 		req.newlen = size;
325 		req.newptr = data;
326 		break;
327 	case CTLTYPE_U32:
328 		if (getenv_array(path + rem, data, sizeof(data), &size,
329 		    sizeof(uint32_t), GETENV_UNSIGNED) == 0)
330 			return;
331 		req.newlen = size;
332 		req.newptr = data;
333 		break;
334 	case CTLTYPE_U64:
335 		if (getenv_array(path + rem, data, sizeof(data), &size,
336 		    sizeof(uint64_t), GETENV_UNSIGNED) == 0)
337 			return;
338 		req.newlen = size;
339 		req.newptr = data;
340 		break;
341 	case CTLTYPE_STRING:
342 		penv = kern_getenv(path + rem);
343 		if (penv == NULL)
344 			return;
345 		req.newlen = strlen(penv);
346 		req.newptr = penv;
347 		break;
348 	default:
349 		return;
350 	}
351 	error = sysctl_root_handler_locked(oidp, oidp->oid_arg1,
352 	    oidp->oid_arg2, &req, NULL);
353 	if (error != 0)
354 		printf("Setting sysctl %s failed: %d\n", path + rem, error);
355 	if (penv != NULL)
356 		freeenv(penv);
357 }
358 
359 /*
360  * Locate the path to a given oid.  Returns the length of the resulting path,
361  * or -1 if the oid was not found.  nodes must have room for CTL_MAXNAME
362  * elements.
363  */
364 static int
365 sysctl_search_oid(struct sysctl_oid **nodes, struct sysctl_oid *needle)
366 {
367 	int indx;
368 
369 	SYSCTL_ASSERT_LOCKED();
370 	indx = 0;
371 	/*
372 	 * Do a depth-first search of the oid tree, looking for 'needle'. Start
373 	 * with the first child of the root.
374 	 */
375 	nodes[indx] = RB_MIN(sysctl_oid_list, &sysctl__children);
376 	for (;;) {
377 		if (nodes[indx] == needle)
378 			return (indx + 1);
379 
380 		if (nodes[indx] == NULL) {
381 			/* Node has no more siblings, so back up to parent. */
382 			if (indx-- == 0) {
383 				/* Retreat to root, so give up. */
384 				break;
385 			}
386 		} else if ((nodes[indx]->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
387 			/* Node has children. */
388 			if (++indx == CTL_MAXNAME) {
389 				/* Max search depth reached, so give up. */
390 				break;
391 			}
392 			/* Start with the first child. */
393 			nodes[indx] = RB_MIN(sysctl_oid_list,
394 			    &nodes[indx - 1]->oid_children);
395 			continue;
396 		}
397 		/* Consider next sibling. */
398 		nodes[indx] = RB_NEXT(sysctl_oid_list, NULL, nodes[indx]);
399 	}
400 	return (-1);
401 }
402 
403 static void
404 sysctl_warn_reuse(const char *func, struct sysctl_oid *leaf)
405 {
406 	struct sysctl_oid *nodes[CTL_MAXNAME];
407 	char buf[128];
408 	struct sbuf sb;
409 	int rc, i;
410 
411 	(void)sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN | SBUF_INCLUDENUL);
412 	sbuf_set_drain(&sb, sbuf_printf_drain, NULL);
413 
414 	sbuf_printf(&sb, "%s: can't re-use a leaf (", __func__);
415 
416 	rc = sysctl_search_oid(nodes, leaf);
417 	if (rc > 0) {
418 		for (i = 0; i < rc; i++)
419 			sbuf_printf(&sb, "%s%.*s", nodes[i]->oid_name,
420 			    i != (rc - 1), ".");
421 	} else {
422 		sbuf_cat(&sb, leaf->oid_name);
423 	}
424 	sbuf_cat(&sb, ")!\n");
425 
426 	(void)sbuf_finish(&sb);
427 }
428 
429 #ifdef SYSCTL_DEBUG
430 static int
431 sysctl_reuse_test(SYSCTL_HANDLER_ARGS)
432 {
433 	struct rm_priotracker tracker;
434 
435 	SYSCTL_RLOCK(&tracker);
436 	sysctl_warn_reuse(__func__, oidp);
437 	SYSCTL_RUNLOCK(&tracker);
438 	return (0);
439 }
440 SYSCTL_PROC(_sysctl, OID_AUTO, reuse_test,
441     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 0, sysctl_reuse_test, "-",
442     "");
443 #endif
444 
445 void
446 sysctl_register_oid(struct sysctl_oid *oidp)
447 {
448 	struct sysctl_oid_list *parent = oidp->oid_parent;
449 	struct sysctl_oid *p, key;
450 	int oid_number;
451 	int timeout = 2;
452 
453 	/*
454 	 * First check if another oid with the same name already
455 	 * exists in the parent's list.
456 	 */
457 	SYSCTL_ASSERT_WLOCKED();
458 	p = sysctl_find_oidname(oidp->oid_name, parent);
459 	if (p != NULL) {
460 		if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
461 			p->oid_refcnt++;
462 			return;
463 		} else {
464 			sysctl_warn_reuse(__func__, p);
465 			return;
466 		}
467 	}
468 	/* get current OID number */
469 	oid_number = oidp->oid_number;
470 
471 #if (OID_AUTO >= 0)
472 #error "OID_AUTO is expected to be a negative value"
473 #endif
474 	/*
475 	 * Any negative OID number qualifies as OID_AUTO. Valid OID
476 	 * numbers should always be positive.
477 	 *
478 	 * NOTE: DO NOT change the starting value here, change it in
479 	 * <sys/sysctl.h>, and make sure it is at least 256 to
480 	 * accommodate e.g. net.inet.raw as a static sysctl node.
481 	 */
482 	if (oid_number < 0) {
483 		static int newoid;
484 
485 		/*
486 		 * By decrementing the next OID number we spend less
487 		 * time inserting the OIDs into a sorted list.
488 		 */
489 		if (--newoid < CTL_AUTO_START)
490 			newoid = 0x7fffffff;
491 
492 		oid_number = newoid;
493 	}
494 
495 	/*
496 	 * Insert the OID into the parent's list sorted by OID number.
497 	 */
498 	key.oid_number = oid_number;
499 	p = RB_NFIND(sysctl_oid_list, parent, &key);
500 	while (p != NULL && oid_number == p->oid_number) {
501 		/* get the next valid OID number */
502 		if (oid_number < CTL_AUTO_START ||
503 		    oid_number == 0x7fffffff) {
504 			/* wraparound - restart */
505 			oid_number = CTL_AUTO_START;
506 			/* don't loop forever */
507 			if (!timeout--)
508 				panic("sysctl: Out of OID numbers\n");
509 			key.oid_number = oid_number;
510 			p = RB_NFIND(sysctl_oid_list, parent, &key);
511 			continue;
512 		}
513 		p = RB_NEXT(sysctl_oid_list, NULL, p);
514 		oid_number++;
515 	}
516 	/* check for non-auto OID number collision */
517 	if (oidp->oid_number >= 0 && oidp->oid_number < CTL_AUTO_START &&
518 	    oid_number >= CTL_AUTO_START) {
519 		printf("sysctl: OID number(%d) is already in use for '%s'\n",
520 		    oidp->oid_number, oidp->oid_name);
521 	}
522 	/* update the OID number, if any */
523 	oidp->oid_number = oid_number;
524 	RB_INSERT(sysctl_oid_list, parent, oidp);
525 
526 	if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE &&
527 	    (oidp->oid_kind & CTLFLAG_TUN) != 0 &&
528 	    (oidp->oid_kind & CTLFLAG_NOFETCH) == 0) {
529 #ifdef VIMAGE
530 		/*
531 		 * Can fetch value multiple times for VNET loader tunables.
532 		 * Only fetch once for non-VNET loader tunables.
533 		 */
534 		if ((oidp->oid_kind & CTLFLAG_VNET) == 0)
535 #endif
536 			oidp->oid_kind |= CTLFLAG_NOFETCH;
537 		/* try to fetch value from kernel environment */
538 		sysctl_load_tunable_by_oid_locked(oidp);
539 	}
540 }
541 
542 void
543 sysctl_register_disabled_oid(struct sysctl_oid *oidp)
544 {
545 
546 	/*
547 	 * Mark the leaf as dormant if it's not to be immediately enabled.
548 	 * We do not disable nodes as they can be shared between modules
549 	 * and it is always safe to access a node.
550 	 */
551 	KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0,
552 	    ("internal flag is set in oid_kind"));
553 	if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
554 		oidp->oid_kind |= CTLFLAG_DORMANT;
555 	sysctl_register_oid(oidp);
556 }
557 
558 void
559 sysctl_enable_oid(struct sysctl_oid *oidp)
560 {
561 
562 	SYSCTL_ASSERT_WLOCKED();
563 	if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
564 		KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0,
565 		    ("sysctl node is marked as dormant"));
566 		return;
567 	}
568 	KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) != 0,
569 	    ("enabling already enabled sysctl oid"));
570 	oidp->oid_kind &= ~CTLFLAG_DORMANT;
571 }
572 
573 void
574 sysctl_unregister_oid(struct sysctl_oid *oidp)
575 {
576 	int error;
577 
578 	SYSCTL_ASSERT_WLOCKED();
579 	if (oidp->oid_number == OID_AUTO) {
580 		error = EINVAL;
581 	} else {
582 		error = ENOENT;
583 		if (RB_REMOVE(sysctl_oid_list, oidp->oid_parent, oidp))
584 			error = 0;
585 	}
586 
587 	/*
588 	 * This can happen when a module fails to register and is
589 	 * being unloaded afterwards.  It should not be a panic()
590 	 * for normal use.
591 	 */
592 	if (error) {
593 		printf("%s: failed(%d) to unregister sysctl(%s)\n",
594 		    __func__, error, oidp->oid_name);
595 	}
596 }
597 
598 /* Initialize a new context to keep track of dynamically added sysctls. */
599 int
600 sysctl_ctx_init(struct sysctl_ctx_list *c)
601 {
602 
603 	if (c == NULL) {
604 		return (EINVAL);
605 	}
606 
607 	/*
608 	 * No locking here, the caller is responsible for not adding
609 	 * new nodes to a context until after this function has
610 	 * returned.
611 	 */
612 	TAILQ_INIT(c);
613 	return (0);
614 }
615 
616 /* Free the context, and destroy all dynamic oids registered in this context */
617 int
618 sysctl_ctx_free(struct sysctl_ctx_list *clist)
619 {
620 	struct sysctl_ctx_entry *e, *e1;
621 	int error;
622 
623 	error = 0;
624 	/*
625 	 * First perform a "dry run" to check if it's ok to remove oids.
626 	 * XXX FIXME
627 	 * XXX This algorithm is a hack. But I don't know any
628 	 * XXX better solution for now...
629 	 */
630 	SYSCTL_WLOCK();
631 	TAILQ_FOREACH(e, clist, link) {
632 		error = sysctl_remove_oid_locked(e->entry, 0, 0);
633 		if (error)
634 			break;
635 	}
636 	/*
637 	 * Restore deregistered entries, either from the end,
638 	 * or from the place where error occurred.
639 	 * e contains the entry that was not unregistered
640 	 */
641 	if (error)
642 		e1 = TAILQ_PREV(e, sysctl_ctx_list, link);
643 	else
644 		e1 = TAILQ_LAST(clist, sysctl_ctx_list);
645 	while (e1 != NULL) {
646 		sysctl_register_oid(e1->entry);
647 		e1 = TAILQ_PREV(e1, sysctl_ctx_list, link);
648 	}
649 	if (error) {
650 		SYSCTL_WUNLOCK();
651 		return(EBUSY);
652 	}
653 	/* Now really delete the entries */
654 	e = TAILQ_FIRST(clist);
655 	while (e != NULL) {
656 		e1 = TAILQ_NEXT(e, link);
657 		error = sysctl_remove_oid_locked(e->entry, 1, 0);
658 		if (error)
659 			panic("sysctl_remove_oid: corrupt tree, entry: %s",
660 			    e->entry->oid_name);
661 		free(e, M_SYSCTLOID);
662 		e = e1;
663 	}
664 	SYSCTL_WUNLOCK();
665 	return (error);
666 }
667 
668 /* Add an entry to the context */
669 struct sysctl_ctx_entry *
670 sysctl_ctx_entry_add(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
671 {
672 	struct sysctl_ctx_entry *e;
673 
674 	SYSCTL_ASSERT_WLOCKED();
675 	if (clist == NULL || oidp == NULL)
676 		return(NULL);
677 	e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK);
678 	e->entry = oidp;
679 	TAILQ_INSERT_HEAD(clist, e, link);
680 	return (e);
681 }
682 
683 /* Find an entry in the context */
684 struct sysctl_ctx_entry *
685 sysctl_ctx_entry_find(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
686 {
687 	struct sysctl_ctx_entry *e;
688 
689 	SYSCTL_ASSERT_WLOCKED();
690 	if (clist == NULL || oidp == NULL)
691 		return(NULL);
692 	TAILQ_FOREACH(e, clist, link) {
693 		if (e->entry == oidp)
694 			return(e);
695 	}
696 	return (e);
697 }
698 
699 /*
700  * Delete an entry from the context.
701  * NOTE: this function doesn't free oidp! You have to remove it
702  * with sysctl_remove_oid().
703  */
704 int
705 sysctl_ctx_entry_del(struct sysctl_ctx_list *clist, struct sysctl_oid *oidp)
706 {
707 	struct sysctl_ctx_entry *e;
708 
709 	if (clist == NULL || oidp == NULL)
710 		return (EINVAL);
711 	SYSCTL_WLOCK();
712 	e = sysctl_ctx_entry_find(clist, oidp);
713 	if (e != NULL) {
714 		TAILQ_REMOVE(clist, e, link);
715 		SYSCTL_WUNLOCK();
716 		free(e, M_SYSCTLOID);
717 		return (0);
718 	} else {
719 		SYSCTL_WUNLOCK();
720 		return (ENOENT);
721 	}
722 }
723 
724 /*
725  * Remove dynamically created sysctl trees.
726  * oidp - top of the tree to be removed
727  * del - if 0 - just deregister, otherwise free up entries as well
728  * recurse - if != 0 traverse the subtree to be deleted
729  */
730 int
731 sysctl_remove_oid(struct sysctl_oid *oidp, int del, int recurse)
732 {
733 	int error;
734 
735 	SYSCTL_WLOCK();
736 	error = sysctl_remove_oid_locked(oidp, del, recurse);
737 	SYSCTL_WUNLOCK();
738 	return (error);
739 }
740 
741 int
742 sysctl_remove_name(struct sysctl_oid *parent, const char *name,
743     int del, int recurse)
744 {
745 	struct sysctl_oid *p;
746 	int error;
747 
748 	error = ENOENT;
749 	SYSCTL_WLOCK();
750 	p = sysctl_find_oidname(name, &parent->oid_children);
751 	if (p)
752 		error = sysctl_remove_oid_locked(p, del, recurse);
753 	SYSCTL_WUNLOCK();
754 
755 	return (error);
756 }
757 
758 /*
759  * Duplicate the provided string, escaping any illegal characters.  The result
760  * must be freed when no longer in use.
761  *
762  * The list of illegal characters is ".".
763  */
764 static char*
765 sysctl_escape_name(const char* orig)
766 {
767 	int i, s = 0, d = 0, nillegals = 0;
768 	char *new;
769 
770 	/* First count the number of illegal characters */
771 	for (i = 0; orig[i] != '\0'; i++) {
772 		if (orig[i] == '.')
773 			nillegals++;
774 	}
775 
776 	/* Allocate storage for new string */
777 	new = malloc(i + 2 * nillegals + 1, M_SYSCTLOID, M_WAITOK);
778 
779 	/* Copy the name, escaping characters as we go */
780 	while (orig[s] != '\0') {
781 		if (orig[s] == '.') {
782 			/* %25 is the hexadecimal representation of '.' */
783 			new[d++] = '%';
784 			new[d++] = '2';
785 			new[d++] = '5';
786 			s++;
787 		} else {
788 			new[d++] = orig[s++];
789 		}
790 	}
791 
792 	/* Finally, nul-terminate */
793 	new[d] = '\0';
794 
795 	return (new);
796 }
797 
798 static int
799 sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse)
800 {
801 	struct sysctl_oid *p, *tmp;
802 	int error;
803 
804 	SYSCTL_ASSERT_WLOCKED();
805 	if (oidp == NULL)
806 		return(EINVAL);
807 	if ((oidp->oid_kind & CTLFLAG_DYN) == 0) {
808 		printf("Warning: can't remove non-dynamic nodes (%s)!\n",
809 		    oidp->oid_name);
810 		return (EINVAL);
811 	}
812 	/*
813 	 * WARNING: normal method to do this should be through
814 	 * sysctl_ctx_free(). Use recursing as the last resort
815 	 * method to purge your sysctl tree of leftovers...
816 	 * However, if some other code still references these nodes,
817 	 * it will panic.
818 	 */
819 	if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
820 		if (oidp->oid_refcnt == 1) {
821 			for(p = RB_MIN(sysctl_oid_list, &oidp->oid_children);
822 			    p != NULL; p = tmp) {
823 				if (!recurse) {
824 					printf("Warning: failed attempt to "
825 					    "remove oid %s with child %s\n",
826 					    oidp->oid_name, p->oid_name);
827 					return (ENOTEMPTY);
828 				}
829 				tmp = RB_NEXT(sysctl_oid_list,
830 				    &oidp->oid_children, p);
831 				error = sysctl_remove_oid_locked(p, del,
832 				    recurse);
833 				if (error)
834 					return (error);
835 			}
836 		}
837 	}
838 	if (oidp->oid_refcnt > 1 ) {
839 		oidp->oid_refcnt--;
840 	} else {
841 		if (oidp->oid_refcnt == 0) {
842 			printf("Warning: bad oid_refcnt=%u (%s)!\n",
843 				oidp->oid_refcnt, oidp->oid_name);
844 			return (EINVAL);
845 		}
846 		sysctl_unregister_oid(oidp);
847 		if (del) {
848 			/*
849 			 * Wait for all threads running the handler to drain.
850 			 * This preserves the previous behavior when the
851 			 * sysctl lock was held across a handler invocation,
852 			 * and is necessary for module unload correctness.
853 			 */
854 			while (oidp->oid_running > 0) {
855 				oidp->oid_kind |= CTLFLAG_DYING;
856 				SYSCTL_SLEEP(&oidp->oid_running, "oidrm", 0);
857 			}
858 			if (oidp->oid_descr)
859 				free(__DECONST(char *, oidp->oid_descr),
860 				    M_SYSCTLOID);
861 			if (oidp->oid_label)
862 				free(__DECONST(char *, oidp->oid_label),
863 				    M_SYSCTLOID);
864 			free(__DECONST(char *, oidp->oid_name), M_SYSCTLOID);
865 			free(oidp, M_SYSCTLOID);
866 		}
867 	}
868 	return (0);
869 }
870 /*
871  * Create new sysctls at run time.
872  * clist may point to a valid context initialized with sysctl_ctx_init().
873  */
874 struct sysctl_oid *
875 sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent,
876 	int number, const char *name, int kind, void *arg1, intmax_t arg2,
877 	int (*handler)(SYSCTL_HANDLER_ARGS), const char *fmt, const char *descr,
878 	const char *label)
879 {
880 	struct sysctl_oid *oidp;
881 	char *escaped;
882 
883 	/* You have to hook up somewhere.. */
884 	if (parent == NULL)
885 		return(NULL);
886 	escaped = sysctl_escape_name(name);
887 	/* Check if the node already exists, otherwise create it */
888 	SYSCTL_WLOCK();
889 	oidp = sysctl_find_oidname(escaped, parent);
890 	if (oidp != NULL) {
891 		free(escaped, M_SYSCTLOID);
892 		if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
893 			oidp->oid_refcnt++;
894 			/* Update the context */
895 			if (clist != NULL)
896 				sysctl_ctx_entry_add(clist, oidp);
897 			SYSCTL_WUNLOCK();
898 			return (oidp);
899 		} else {
900 			sysctl_warn_reuse(__func__, oidp);
901 			SYSCTL_WUNLOCK();
902 			return (NULL);
903 		}
904 	}
905 	oidp = malloc(sizeof(struct sysctl_oid), M_SYSCTLOID, M_WAITOK|M_ZERO);
906 	oidp->oid_parent = parent;
907 	RB_INIT(&oidp->oid_children);
908 	oidp->oid_number = number;
909 	oidp->oid_refcnt = 1;
910 	oidp->oid_name = escaped;
911 	oidp->oid_handler = handler;
912 	oidp->oid_kind = CTLFLAG_DYN | kind;
913 	oidp->oid_arg1 = arg1;
914 	oidp->oid_arg2 = arg2;
915 	oidp->oid_fmt = fmt;
916 	if (descr != NULL)
917 		oidp->oid_descr = strdup(descr, M_SYSCTLOID);
918 	if (label != NULL)
919 		oidp->oid_label = strdup(label, M_SYSCTLOID);
920 	/* Update the context, if used */
921 	if (clist != NULL)
922 		sysctl_ctx_entry_add(clist, oidp);
923 	/* Register this oid */
924 	sysctl_register_oid(oidp);
925 	SYSCTL_WUNLOCK();
926 	return (oidp);
927 }
928 
929 /*
930  * Rename an existing oid.
931  */
932 void
933 sysctl_rename_oid(struct sysctl_oid *oidp, const char *name)
934 {
935 	char *newname;
936 	char *oldname;
937 
938 	newname = strdup(name, M_SYSCTLOID);
939 	SYSCTL_WLOCK();
940 	oldname = __DECONST(char *, oidp->oid_name);
941 	oidp->oid_name = newname;
942 	SYSCTL_WUNLOCK();
943 	free(oldname, M_SYSCTLOID);
944 }
945 
946 /*
947  * Reparent an existing oid.
948  */
949 int
950 sysctl_move_oid(struct sysctl_oid *oid, struct sysctl_oid_list *parent)
951 {
952 	struct sysctl_oid *oidp;
953 
954 	SYSCTL_WLOCK();
955 	if (oid->oid_parent == parent) {
956 		SYSCTL_WUNLOCK();
957 		return (0);
958 	}
959 	oidp = sysctl_find_oidname(oid->oid_name, parent);
960 	if (oidp != NULL) {
961 		SYSCTL_WUNLOCK();
962 		return (EEXIST);
963 	}
964 	sysctl_unregister_oid(oid);
965 	oid->oid_parent = parent;
966 	oid->oid_number = OID_AUTO;
967 	sysctl_register_oid(oid);
968 	SYSCTL_WUNLOCK();
969 	return (0);
970 }
971 
972 /*
973  * Register the kernel's oids on startup.
974  */
975 SET_DECLARE(sysctl_set, struct sysctl_oid);
976 
977 static void
978 sysctl_register_all(void *arg)
979 {
980 	struct sysctl_oid **oidp;
981 
982 	sx_init(&sysctlmemlock, "sysctl mem");
983 	sx_init(&sysctlstringlock, "sysctl string handler");
984 	SYSCTL_INIT();
985 	SYSCTL_WLOCK();
986 	SET_FOREACH(oidp, sysctl_set)
987 		sysctl_register_oid(*oidp);
988 	SYSCTL_WUNLOCK();
989 }
990 SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_register_all, NULL);
991 
992 #ifdef VIMAGE
993 static void
994 sysctl_setenv_vnet(void *arg __unused, const char *name)
995 {
996 	struct sysctl_oid *oidp;
997 	int oid[CTL_MAXNAME];
998 	int error, nlen;
999 
1000 	SYSCTL_WLOCK();
1001 	error = name2oid(name, oid, &nlen, &oidp);
1002 	if (error)
1003 		goto out;
1004 
1005 	if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE &&
1006 	    (oidp->oid_kind & CTLFLAG_VNET) != 0 &&
1007 	    (oidp->oid_kind & CTLFLAG_TUN) != 0 &&
1008 	    (oidp->oid_kind & CTLFLAG_NOFETCH) == 0) {
1009 		/* Update value from kernel environment */
1010 		sysctl_load_tunable_by_oid_locked(oidp);
1011 	}
1012 out:
1013 	SYSCTL_WUNLOCK();
1014 }
1015 
1016 static void
1017 sysctl_unsetenv_vnet(void *arg __unused, const char *name)
1018 {
1019 	struct sysctl_oid *oidp;
1020 	int oid[CTL_MAXNAME];
1021 	int error, nlen;
1022 
1023 	SYSCTL_WLOCK();
1024 	/*
1025 	 * The setenv / unsetenv event handlers are invoked by kern_setenv() /
1026 	 * kern_unsetenv() without exclusive locks. It is rare but still possible
1027 	 * that the invoke order of event handlers is different from that of
1028 	 * kern_setenv() and kern_unsetenv().
1029 	 * Re-check environment variable string to make sure it is unset.
1030 	 */
1031 	if (testenv(name))
1032 		goto out;
1033 	error = name2oid(name, oid, &nlen, &oidp);
1034 	if (error)
1035 		goto out;
1036 
1037 	if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE &&
1038 	    (oidp->oid_kind & CTLFLAG_VNET) != 0 &&
1039 	    (oidp->oid_kind & CTLFLAG_TUN) != 0 &&
1040 	    (oidp->oid_kind & CTLFLAG_NOFETCH) == 0) {
1041 		size_t size;
1042 
1043 		switch (oidp->oid_kind & CTLTYPE) {
1044 		case CTLTYPE_INT:
1045 		case CTLTYPE_UINT:
1046 			size = sizeof(int);
1047 			break;
1048 		case CTLTYPE_LONG:
1049 		case CTLTYPE_ULONG:
1050 			size = sizeof(long);
1051 			break;
1052 		case CTLTYPE_S8:
1053 		case CTLTYPE_U8:
1054 			size = sizeof(int8_t);
1055 			break;
1056 		case CTLTYPE_S16:
1057 		case CTLTYPE_U16:
1058 			size = sizeof(int16_t);
1059 			break;
1060 		case CTLTYPE_S32:
1061 		case CTLTYPE_U32:
1062 			size = sizeof(int32_t);
1063 			break;
1064 		case CTLTYPE_S64:
1065 		case CTLTYPE_U64:
1066 			size = sizeof(int64_t);
1067 			break;
1068 		case CTLTYPE_STRING:
1069 			MPASS(oidp->oid_arg2 > 0);
1070 			size = oidp->oid_arg2;
1071 			break;
1072 		default:
1073 			goto out;
1074 		}
1075 		vnet_restore_init(oidp->oid_arg1, size);
1076 	}
1077 out:
1078 	SYSCTL_WUNLOCK();
1079 }
1080 
1081 /*
1082  * Register the kernel's setenv / unsetenv events.
1083  */
1084 EVENTHANDLER_DEFINE(setenv, sysctl_setenv_vnet, NULL, EVENTHANDLER_PRI_ANY);
1085 EVENTHANDLER_DEFINE(unsetenv, sysctl_unsetenv_vnet, NULL, EVENTHANDLER_PRI_ANY);
1086 #endif
1087 
1088 /*
1089  * "Staff-functions"
1090  *
1091  * These functions implement a presently undocumented interface
1092  * used by the sysctl program to walk the tree, and get the type
1093  * so it can print the value.
1094  * This interface is under work and consideration, and should probably
1095  * be killed with a big axe by the first person who can find the time.
1096  * (be aware though, that the proper interface isn't as obvious as it
1097  * may seem, there are various conflicting requirements.
1098  *
1099  * {CTL_SYSCTL, CTL_SYSCTL_DEBUG}		printf the entire MIB-tree.
1100  * {CTL_SYSCTL, CTL_SYSCTL_NAME, ...}		return the name of the "..."
1101  *						OID.
1102  * {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...}		return the next OID, honoring
1103  *						CTLFLAG_SKIP.
1104  * {CTL_SYSCTL, CTL_SYSCTL_NAME2OID}		return the OID of the name in
1105  *						"new"
1106  * {CTL_SYSCTL, CTL_SYSCTL_OIDFMT, ...}		return the kind & format info
1107  *						for the "..." OID.
1108  * {CTL_SYSCTL, CTL_SYSCTL_OIDDESCR, ...}	return the description of the
1109  *						"..." OID.
1110  * {CTL_SYSCTL, CTL_SYSCTL_OIDLABEL, ...}	return the aggregation label of
1111  *						the "..." OID.
1112  * {CTL_SYSCTL, CTL_SYSCTL_NEXTNOSKIP, ...}	return the next OID, ignoring
1113  *						CTLFLAG_SKIP.
1114  */
1115 
1116 #ifdef SYSCTL_DEBUG
1117 static void
1118 sysctl_sysctl_debug_dump_node(struct sysctl_oid_list *l, int i)
1119 {
1120 	int k;
1121 	struct sysctl_oid *oidp;
1122 
1123 	SYSCTL_ASSERT_LOCKED();
1124 	SYSCTL_FOREACH(oidp, l) {
1125 		for (k=0; k<i; k++)
1126 			printf(" ");
1127 
1128 		printf("%d %s ", oidp->oid_number, oidp->oid_name);
1129 
1130 		printf("%c%c",
1131 			oidp->oid_kind & CTLFLAG_RD ? 'R':' ',
1132 			oidp->oid_kind & CTLFLAG_WR ? 'W':' ');
1133 
1134 		if (oidp->oid_handler)
1135 			printf(" *Handler");
1136 
1137 		switch (oidp->oid_kind & CTLTYPE) {
1138 			case CTLTYPE_NODE:
1139 				printf(" Node\n");
1140 				if (!oidp->oid_handler) {
1141 					sysctl_sysctl_debug_dump_node(
1142 					    SYSCTL_CHILDREN(oidp), i + 2);
1143 				}
1144 				break;
1145 			case CTLTYPE_INT:    printf(" Int\n"); break;
1146 			case CTLTYPE_UINT:   printf(" u_int\n"); break;
1147 			case CTLTYPE_LONG:   printf(" Long\n"); break;
1148 			case CTLTYPE_ULONG:  printf(" u_long\n"); break;
1149 			case CTLTYPE_STRING: printf(" String\n"); break;
1150 			case CTLTYPE_S8:     printf(" int8_t\n"); break;
1151 			case CTLTYPE_S16:    printf(" int16_t\n"); break;
1152 			case CTLTYPE_S32:    printf(" int32_t\n"); break;
1153 			case CTLTYPE_S64:    printf(" int64_t\n"); break;
1154 			case CTLTYPE_U8:     printf(" uint8_t\n"); break;
1155 			case CTLTYPE_U16:    printf(" uint16_t\n"); break;
1156 			case CTLTYPE_U32:    printf(" uint32_t\n"); break;
1157 			case CTLTYPE_U64:    printf(" uint64_t\n"); break;
1158 			case CTLTYPE_OPAQUE: printf(" Opaque/struct\n"); break;
1159 			default:	     printf("\n");
1160 		}
1161 	}
1162 }
1163 
1164 static int
1165 sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
1166 {
1167 	struct rm_priotracker tracker;
1168 	int error;
1169 
1170 	error = priv_check(req->td, PRIV_SYSCTL_DEBUG);
1171 	if (error)
1172 		return (error);
1173 	SYSCTL_RLOCK(&tracker);
1174 	sysctl_sysctl_debug_dump_node(&sysctl__children, 0);
1175 	SYSCTL_RUNLOCK(&tracker);
1176 	return (ENOENT);
1177 }
1178 
1179 SYSCTL_PROC(_sysctl, CTL_SYSCTL_DEBUG, debug, CTLTYPE_STRING | CTLFLAG_RD |
1180     CTLFLAG_MPSAFE, 0, 0, sysctl_sysctl_debug, "-", "");
1181 #endif
1182 
1183 static int
1184 sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
1185 {
1186 	int *name = (int *) arg1;
1187 	u_int namelen = arg2;
1188 	int error;
1189 	struct sysctl_oid *oid, key;
1190 	struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
1191 	struct rm_priotracker tracker;
1192 	char buf[10];
1193 
1194 	error = sysctl_wire_old_buffer(req, 0);
1195 	if (error)
1196 		return (error);
1197 
1198 	SYSCTL_RLOCK(&tracker);
1199 	while (namelen) {
1200 		if (!lsp) {
1201 			snprintf(buf,sizeof(buf),"%d",*name);
1202 			if (req->oldidx)
1203 				error = SYSCTL_OUT(req, ".", 1);
1204 			if (!error)
1205 				error = SYSCTL_OUT(req, buf, strlen(buf));
1206 			if (error)
1207 				goto out;
1208 			namelen--;
1209 			name++;
1210 			continue;
1211 		}
1212 		lsp2 = NULL;
1213 		key.oid_number = *name;
1214 		oid = RB_FIND(sysctl_oid_list, lsp, &key);
1215 		if (oid) {
1216 			if (req->oldidx)
1217 				error = SYSCTL_OUT(req, ".", 1);
1218 			if (!error)
1219 				error = SYSCTL_OUT(req, oid->oid_name,
1220 					strlen(oid->oid_name));
1221 			if (error)
1222 				goto out;
1223 
1224 			namelen--;
1225 			name++;
1226 
1227 			if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE &&
1228 				!oid->oid_handler)
1229 				lsp2 = SYSCTL_CHILDREN(oid);
1230 		}
1231 		lsp = lsp2;
1232 	}
1233 	error = SYSCTL_OUT(req, "", 1);
1234  out:
1235 	SYSCTL_RUNLOCK(&tracker);
1236 	return (error);
1237 }
1238 
1239 /*
1240  * XXXRW/JA: Shouldn't return name data for nodes that we don't permit in
1241  * capability mode.
1242  */
1243 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTLFLAG_RD |
1244     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, "");
1245 
1246 enum sysctl_iter_action {
1247 	ITER_SIBLINGS,	/* Not matched, continue iterating siblings */
1248 	ITER_CHILDREN,	/* Node has children we need to iterate over them */
1249 	ITER_FOUND,	/* Matching node was found */
1250 };
1251 
1252 /*
1253  * Tries to find the next node for @name and @namelen.
1254  *
1255  * Returns next action to take.
1256  */
1257 static enum sysctl_iter_action
1258 sysctl_sysctl_next_node(struct sysctl_oid *oidp, int *name, unsigned int namelen,
1259     bool honor_skip)
1260 {
1261 
1262 	if ((oidp->oid_kind & CTLFLAG_DORMANT) != 0)
1263 		return (ITER_SIBLINGS);
1264 
1265 	if (honor_skip && (oidp->oid_kind & CTLFLAG_SKIP) != 0)
1266 		return (ITER_SIBLINGS);
1267 
1268 	if (namelen == 0) {
1269 		/*
1270 		 * We have reached a node with a full name match and are
1271 		 * looking for the next oid in its children.
1272 		 *
1273 		 * For CTL_SYSCTL_NEXTNOSKIP we are done.
1274 		 *
1275 		 * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
1276 		 * has a handler) and move on to the children.
1277 		 */
1278 		if (!honor_skip)
1279 			return (ITER_FOUND);
1280 		if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
1281 			return (ITER_FOUND);
1282 		/* If node does not have an iterator, treat it as leaf */
1283 		if (oidp->oid_handler)
1284 			return (ITER_FOUND);
1285 
1286 		/* Report oid as a node to iterate */
1287 		return (ITER_CHILDREN);
1288 	}
1289 
1290 	/*
1291 	 * No match yet. Continue seeking the given name.
1292 	 *
1293 	 * We are iterating in order by oid_number, so skip oids lower
1294 	 * than the one we are looking for.
1295 	 *
1296 	 * When the current oid_number is higher than the one we seek,
1297 	 * that means we have reached the next oid in the sequence and
1298 	 * should return it.
1299 	 *
1300 	 * If the oid_number matches the name at this level then we
1301 	 * have to find a node to continue searching at the next level.
1302 	 */
1303 	if (oidp->oid_number < *name)
1304 		return (ITER_SIBLINGS);
1305 	if (oidp->oid_number > *name) {
1306 		/*
1307 		 * We have reached the next oid.
1308 		 *
1309 		 * For CTL_SYSCTL_NEXTNOSKIP we are done.
1310 		 *
1311 		 * For CTL_SYSCTL_NEXT we skip CTLTYPE_NODE (unless it
1312 		 * has a handler) and move on to the children.
1313 		 */
1314 		if (!honor_skip)
1315 			return (ITER_FOUND);
1316 		if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
1317 			return (ITER_FOUND);
1318 		/* If node does not have an iterator, treat it as leaf */
1319 		if (oidp->oid_handler)
1320 			return (ITER_FOUND);
1321 		return (ITER_CHILDREN);
1322 	}
1323 
1324 	/* match at a current level */
1325 	if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
1326 		return (ITER_SIBLINGS);
1327 	if (oidp->oid_handler)
1328 		return (ITER_SIBLINGS);
1329 
1330 	return (ITER_CHILDREN);
1331 }
1332 
1333 /*
1334  * Recursively walk the sysctl subtree at lsp until we find the given name.
1335  * Returns true and fills in next oid data in @next and @len if oid is found.
1336  */
1337 static bool
1338 sysctl_sysctl_next_action(struct sysctl_oid_list *lsp, int *name, u_int namelen,
1339     int *next, int *len, int level, bool honor_skip)
1340 {
1341 	struct sysctl_oid_list *next_lsp;
1342 	struct sysctl_oid *oidp = NULL, key;
1343 	bool success = false;
1344 	enum sysctl_iter_action action;
1345 
1346 	SYSCTL_ASSERT_LOCKED();
1347 	/*
1348 	 * Start the search at the requested oid.  But if not found, then scan
1349 	 * through all children.
1350 	 */
1351 	if (namelen > 0) {
1352 		key.oid_number = *name;
1353 		oidp = RB_FIND(sysctl_oid_list, lsp, &key);
1354 	}
1355 	if (!oidp)
1356 		oidp = RB_MIN(sysctl_oid_list, lsp);
1357 	for(; oidp != NULL; oidp = RB_NEXT(sysctl_oid_list, lsp, oidp)) {
1358 		action = sysctl_sysctl_next_node(oidp, name, namelen,
1359 		    honor_skip);
1360 		if (action == ITER_SIBLINGS)
1361 			continue;
1362 		if (action == ITER_FOUND) {
1363 			success = true;
1364 			break;
1365 		}
1366 		KASSERT((action== ITER_CHILDREN), ("ret(%d)!=ITER_CHILDREN", action));
1367 
1368 		next_lsp = SYSCTL_CHILDREN(oidp);
1369 		if (namelen == 0) {
1370 			success = sysctl_sysctl_next_action(next_lsp, NULL, 0,
1371 			    next + 1, len, level + 1, honor_skip);
1372 		} else {
1373 			success = sysctl_sysctl_next_action(next_lsp, name + 1,
1374 			    namelen - 1, next + 1, len, level + 1, honor_skip);
1375 			if (!success) {
1376 
1377 				/*
1378 				 * We maintain the invariant that current node oid
1379 				 * is >= the oid provided in @name.
1380 				 * As there are no usable children at this node,
1381 				 *  current node oid is strictly > than the requested
1382 				 *  oid.
1383 				 * Hence, reduce namelen to 0 to allow for picking first
1384 				 *  nodes/leafs in the next node in list.
1385 				 */
1386 				namelen = 0;
1387 			}
1388 		}
1389 		if (success)
1390 			break;
1391 	}
1392 
1393 	if (success) {
1394 		*next = oidp->oid_number;
1395 		if (level > *len)
1396 			*len = level;
1397 	}
1398 
1399 	return (success);
1400 }
1401 
1402 static int
1403 sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
1404 {
1405 	int *name = (int *) arg1;
1406 	u_int namelen = arg2;
1407 	int len, error;
1408 	bool success;
1409 	struct sysctl_oid_list *lsp = &sysctl__children;
1410 	struct rm_priotracker tracker;
1411 	int next[CTL_MAXNAME];
1412 
1413 	len = 0;
1414 	SYSCTL_RLOCK(&tracker);
1415 	success = sysctl_sysctl_next_action(lsp, name, namelen, next, &len, 1,
1416 	    oidp->oid_number == CTL_SYSCTL_NEXT);
1417 	SYSCTL_RUNLOCK(&tracker);
1418 	if (!success)
1419 		return (ENOENT);
1420 	error = SYSCTL_OUT(req, next, len * sizeof (int));
1421 	return (error);
1422 }
1423 
1424 /*
1425  * XXXRW/JA: Shouldn't return next data for nodes that we don't permit in
1426  * capability mode.
1427  */
1428 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXT, next, CTLFLAG_RD |
1429     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
1430 
1431 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXTNOSKIP, nextnoskip, CTLFLAG_RD |
1432     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
1433 
1434 static int
1435 name2oid(const char *name, int *oid, int *len, struct sysctl_oid **oidpp)
1436 {
1437 	struct sysctl_oid *oidp;
1438 	struct sysctl_oid_list *lsp = &sysctl__children;
1439 	const char *n;
1440 
1441 	SYSCTL_ASSERT_LOCKED();
1442 
1443 	for (*len = 0; *len < CTL_MAXNAME;) {
1444 		n = strchrnul(name, '.');
1445 		oidp = sysctl_find_oidnamelen(name, n - name, lsp);
1446 		if (oidp == NULL)
1447 			return (ENOENT);
1448 		*oid++ = oidp->oid_number;
1449 		(*len)++;
1450 
1451 		name = n;
1452 		if (*name == '.')
1453 			name++;
1454 		if (*name == '\0') {
1455 			if (oidpp)
1456 				*oidpp = oidp;
1457 			return (0);
1458 		}
1459 
1460 		if ((oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE)
1461 			break;
1462 
1463 		if (oidp->oid_handler)
1464 			break;
1465 
1466 		lsp = SYSCTL_CHILDREN(oidp);
1467 	}
1468 	return (ENOENT);
1469 }
1470 
1471 static int
1472 sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
1473 {
1474 	char *p;
1475 	int error, oid[CTL_MAXNAME], len = 0;
1476 	struct sysctl_oid *op = NULL;
1477 	struct rm_priotracker tracker;
1478 	char buf[32];
1479 
1480 	if (!req->newlen)
1481 		return (ENOENT);
1482 	if (req->newlen >= MAXPATHLEN)	/* XXX arbitrary, undocumented */
1483 		return (ENAMETOOLONG);
1484 
1485 	p = buf;
1486 	if (req->newlen >= sizeof(buf))
1487 		p = malloc(req->newlen+1, M_SYSCTL, M_WAITOK);
1488 
1489 	error = SYSCTL_IN(req, p, req->newlen);
1490 	if (error) {
1491 		if (p != buf)
1492 			free(p, M_SYSCTL);
1493 		return (error);
1494 	}
1495 
1496 	p [req->newlen] = '\0';
1497 
1498 	SYSCTL_RLOCK(&tracker);
1499 	error = name2oid(p, oid, &len, &op);
1500 	SYSCTL_RUNLOCK(&tracker);
1501 
1502 	if (p != buf)
1503 		free(p, M_SYSCTL);
1504 
1505 	if (error)
1506 		return (error);
1507 
1508 	error = SYSCTL_OUT(req, oid, len * sizeof *oid);
1509 	return (error);
1510 }
1511 
1512 /*
1513  * XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in
1514  * capability mode.
1515  */
1516 SYSCTL_PROC(_sysctl, CTL_SYSCTL_NAME2OID, name2oid, CTLTYPE_INT | CTLFLAG_RW |
1517     CTLFLAG_ANYBODY | CTLFLAG_MPSAFE | CTLFLAG_CAPRW, 0, 0,
1518     sysctl_sysctl_name2oid, "I", "");
1519 
1520 static int
1521 sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
1522 {
1523 	struct sysctl_oid *oid;
1524 	struct rm_priotracker tracker;
1525 	int error;
1526 
1527 	error = sysctl_wire_old_buffer(req, 0);
1528 	if (error)
1529 		return (error);
1530 
1531 	SYSCTL_RLOCK(&tracker);
1532 	error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
1533 	if (error)
1534 		goto out;
1535 
1536 	if (oid->oid_fmt == NULL) {
1537 		error = ENOENT;
1538 		goto out;
1539 	}
1540 	error = SYSCTL_OUT(req, &oid->oid_kind, sizeof(oid->oid_kind));
1541 	if (error)
1542 		goto out;
1543 	error = SYSCTL_OUT(req, oid->oid_fmt, strlen(oid->oid_fmt) + 1);
1544  out:
1545 	SYSCTL_RUNLOCK(&tracker);
1546 	return (error);
1547 }
1548 
1549 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDFMT, oidfmt, CTLFLAG_RD |
1550     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidfmt, "");
1551 
1552 static int
1553 sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
1554 {
1555 	struct sysctl_oid *oid;
1556 	struct rm_priotracker tracker;
1557 	int error;
1558 
1559 	error = sysctl_wire_old_buffer(req, 0);
1560 	if (error)
1561 		return (error);
1562 
1563 	SYSCTL_RLOCK(&tracker);
1564 	error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
1565 	if (error)
1566 		goto out;
1567 
1568 	if (oid->oid_descr == NULL) {
1569 		error = ENOENT;
1570 		goto out;
1571 	}
1572 	error = SYSCTL_OUT(req, oid->oid_descr, strlen(oid->oid_descr) + 1);
1573  out:
1574 	SYSCTL_RUNLOCK(&tracker);
1575 	return (error);
1576 }
1577 
1578 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDDESCR, oiddescr, CTLFLAG_RD |
1579     CTLFLAG_MPSAFE|CTLFLAG_CAPRD, sysctl_sysctl_oiddescr, "");
1580 
1581 static int
1582 sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
1583 {
1584 	struct sysctl_oid *oid;
1585 	struct rm_priotracker tracker;
1586 	int error;
1587 
1588 	error = sysctl_wire_old_buffer(req, 0);
1589 	if (error)
1590 		return (error);
1591 
1592 	SYSCTL_RLOCK(&tracker);
1593 	error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
1594 	if (error)
1595 		goto out;
1596 
1597 	if (oid->oid_label == NULL) {
1598 		error = ENOENT;
1599 		goto out;
1600 	}
1601 	error = SYSCTL_OUT(req, oid->oid_label, strlen(oid->oid_label) + 1);
1602  out:
1603 	SYSCTL_RUNLOCK(&tracker);
1604 	return (error);
1605 }
1606 
1607 static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDLABEL, oidlabel, CTLFLAG_RD |
1608     CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, "");
1609 
1610 /*
1611  * Default "handler" functions.
1612  */
1613 
1614 /*
1615  * Handle a bool.
1616  * Two cases:
1617  *     a variable:  point arg1 at it.
1618  *     a constant:  pass it in arg2.
1619  */
1620 
1621 int
1622 sysctl_handle_bool(SYSCTL_HANDLER_ARGS)
1623 {
1624 	uint8_t temp;
1625 	int error;
1626 
1627 	/*
1628 	 * Attempt to get a coherent snapshot by making a copy of the data.
1629 	 */
1630 	if (arg1)
1631 		temp = *(bool *)arg1 ? 1 : 0;
1632 	else
1633 		temp = arg2 ? 1 : 0;
1634 
1635 	error = SYSCTL_OUT(req, &temp, sizeof(temp));
1636 	if (error || !req->newptr)
1637 		return (error);
1638 
1639 	if (!arg1)
1640 		error = EPERM;
1641 	else {
1642 		error = SYSCTL_IN(req, &temp, sizeof(temp));
1643 		if (!error)
1644 			*(bool *)arg1 = temp ? 1 : 0;
1645 	}
1646 	return (error);
1647 }
1648 
1649 /*
1650  * Handle an int8_t, signed or unsigned.
1651  * Two cases:
1652  *     a variable:  point arg1 at it.
1653  *     a constant:  pass it in arg2.
1654  */
1655 
1656 int
1657 sysctl_handle_8(SYSCTL_HANDLER_ARGS)
1658 {
1659 	int8_t tmpout;
1660 	int error = 0;
1661 
1662 	/*
1663 	 * Attempt to get a coherent snapshot by making a copy of the data.
1664 	 */
1665 	if (arg1)
1666 		tmpout = *(int8_t *)arg1;
1667 	else
1668 		tmpout = arg2;
1669 	error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
1670 
1671 	if (error || !req->newptr)
1672 		return (error);
1673 
1674 	if (!arg1)
1675 		error = EPERM;
1676 	else
1677 		error = SYSCTL_IN(req, arg1, sizeof(tmpout));
1678 	return (error);
1679 }
1680 
1681 /*
1682  * Handle an int16_t, signed or unsigned.
1683  * Two cases:
1684  *     a variable:  point arg1 at it.
1685  *     a constant:  pass it in arg2.
1686  */
1687 
1688 int
1689 sysctl_handle_16(SYSCTL_HANDLER_ARGS)
1690 {
1691 	int16_t tmpout;
1692 	int error = 0;
1693 
1694 	/*
1695 	 * Attempt to get a coherent snapshot by making a copy of the data.
1696 	 */
1697 	if (arg1)
1698 		tmpout = *(int16_t *)arg1;
1699 	else
1700 		tmpout = arg2;
1701 	error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
1702 
1703 	if (error || !req->newptr)
1704 		return (error);
1705 
1706 	if (!arg1)
1707 		error = EPERM;
1708 	else
1709 		error = SYSCTL_IN(req, arg1, sizeof(tmpout));
1710 	return (error);
1711 }
1712 
1713 /*
1714  * Handle an int32_t, signed or unsigned.
1715  * Two cases:
1716  *     a variable:  point arg1 at it.
1717  *     a constant:  pass it in arg2.
1718  */
1719 
1720 int
1721 sysctl_handle_32(SYSCTL_HANDLER_ARGS)
1722 {
1723 	int32_t tmpout;
1724 	int error = 0;
1725 
1726 	/*
1727 	 * Attempt to get a coherent snapshot by making a copy of the data.
1728 	 */
1729 	if (arg1)
1730 		tmpout = *(int32_t *)arg1;
1731 	else
1732 		tmpout = arg2;
1733 	error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
1734 
1735 	if (error || !req->newptr)
1736 		return (error);
1737 
1738 	if (!arg1)
1739 		error = EPERM;
1740 	else
1741 		error = SYSCTL_IN(req, arg1, sizeof(tmpout));
1742 	return (error);
1743 }
1744 
1745 /*
1746  * Handle an int, signed or unsigned.
1747  * Two cases:
1748  *     a variable:  point arg1 at it.
1749  *     a constant:  pass it in arg2.
1750  */
1751 
1752 int
1753 sysctl_handle_int(SYSCTL_HANDLER_ARGS)
1754 {
1755 	int tmpout, error = 0;
1756 
1757 	/*
1758 	 * Attempt to get a coherent snapshot by making a copy of the data.
1759 	 */
1760 	if (arg1)
1761 		tmpout = *(int *)arg1;
1762 	else
1763 		tmpout = arg2;
1764 	error = SYSCTL_OUT(req, &tmpout, sizeof(int));
1765 
1766 	if (error || !req->newptr)
1767 		return (error);
1768 
1769 	if (!arg1)
1770 		error = EPERM;
1771 	else
1772 		error = SYSCTL_IN(req, arg1, sizeof(int));
1773 	return (error);
1774 }
1775 
1776 /*
1777  * Based on sysctl_handle_int() convert milliseconds into ticks.
1778  * Note: this is used by TCP.
1779  */
1780 
1781 int
1782 sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS)
1783 {
1784 	int error, s, tt;
1785 
1786 	tt = *(int *)arg1;
1787 	s = (int)((int64_t)tt * 1000 / hz);
1788 
1789 	error = sysctl_handle_int(oidp, &s, 0, req);
1790 	if (error || !req->newptr)
1791 		return (error);
1792 
1793 	tt = (int)((int64_t)s * hz / 1000);
1794 	if (tt < 1)
1795 		return (EINVAL);
1796 
1797 	*(int *)arg1 = tt;
1798 	return (0);
1799 }
1800 
1801 /*
1802  * Handle a long, signed or unsigned.
1803  * Two cases:
1804  *     a variable:  point arg1 at it.
1805  *     a constant:  pass it in arg2.
1806  */
1807 
1808 int
1809 sysctl_handle_long(SYSCTL_HANDLER_ARGS)
1810 {
1811 	int error = 0;
1812 	long tmplong;
1813 #ifdef SCTL_MASK32
1814 	int tmpint;
1815 #endif
1816 
1817 	/*
1818 	 * Attempt to get a coherent snapshot by making a copy of the data.
1819 	 */
1820 	if (arg1)
1821 		tmplong = *(long *)arg1;
1822 	else
1823 		tmplong = arg2;
1824 #ifdef SCTL_MASK32
1825 	if (req->flags & SCTL_MASK32) {
1826 		tmpint = tmplong;
1827 		error = SYSCTL_OUT(req, &tmpint, sizeof(int));
1828 	} else
1829 #endif
1830 		error = SYSCTL_OUT(req, &tmplong, sizeof(long));
1831 
1832 	if (error || !req->newptr)
1833 		return (error);
1834 
1835 	if (!arg1)
1836 		error = EPERM;
1837 #ifdef SCTL_MASK32
1838 	else if (req->flags & SCTL_MASK32) {
1839 		error = SYSCTL_IN(req, &tmpint, sizeof(int));
1840 		*(long *)arg1 = (long)tmpint;
1841 	}
1842 #endif
1843 	else
1844 		error = SYSCTL_IN(req, arg1, sizeof(long));
1845 	return (error);
1846 }
1847 
1848 /*
1849  * Handle a 64 bit int, signed or unsigned.
1850  * Two cases:
1851  *     a variable:  point arg1 at it.
1852  *     a constant:  pass it in arg2.
1853  */
1854 int
1855 sysctl_handle_64(SYSCTL_HANDLER_ARGS)
1856 {
1857 	int error = 0;
1858 	uint64_t tmpout;
1859 
1860 	/*
1861 	 * Attempt to get a coherent snapshot by making a copy of the data.
1862 	 */
1863 	if (arg1)
1864 		tmpout = *(uint64_t *)arg1;
1865 	else
1866 		tmpout = arg2;
1867 	error = SYSCTL_OUT(req, &tmpout, sizeof(uint64_t));
1868 
1869 	if (error || !req->newptr)
1870 		return (error);
1871 
1872 	if (!arg1)
1873 		error = EPERM;
1874 	else
1875 		error = SYSCTL_IN(req, arg1, sizeof(uint64_t));
1876 	return (error);
1877 }
1878 
1879 /*
1880  * Handle our generic '\0' terminated 'C' string.
1881  * Two cases:
1882  * 	a variable string:  point arg1 at it, arg2 is max length.
1883  * 	a constant string:  point arg1 at it, arg2 is zero.
1884  */
1885 
1886 int
1887 sysctl_handle_string(SYSCTL_HANDLER_ARGS)
1888 {
1889 	char *tmparg;
1890 	size_t outlen;
1891 	int error = 0, ro_string = 0;
1892 
1893 	/*
1894 	 * If the sysctl isn't writable and isn't a preallocated tunable that
1895 	 * can be modified by kenv(2), microoptimise and treat it as a
1896 	 * read-only string.
1897 	 * A zero-length buffer indicates a fixed size read-only
1898 	 * string.  In ddb, don't worry about trying to make a malloced
1899 	 * snapshot.
1900 	 */
1901 	if ((oidp->oid_kind & (CTLFLAG_WR | CTLFLAG_TUN)) == 0 ||
1902 	    arg2 == 0 || kdb_active) {
1903 		arg2 = strlen((char *)arg1) + 1;
1904 		ro_string = 1;
1905 	}
1906 
1907 	if (req->oldptr != NULL) {
1908 		if (ro_string) {
1909 			tmparg = arg1;
1910 			outlen = strlen(tmparg) + 1;
1911 		} else {
1912 			tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK);
1913 			sx_slock(&sysctlstringlock);
1914 			memcpy(tmparg, arg1, arg2);
1915 			sx_sunlock(&sysctlstringlock);
1916 			outlen = strlen(tmparg) + 1;
1917 		}
1918 
1919 		error = SYSCTL_OUT(req, tmparg, outlen);
1920 
1921 		if (!ro_string)
1922 			free(tmparg, M_SYSCTLTMP);
1923 	} else {
1924 		if (!ro_string)
1925 			sx_slock(&sysctlstringlock);
1926 		outlen = strlen((char *)arg1) + 1;
1927 		if (!ro_string)
1928 			sx_sunlock(&sysctlstringlock);
1929 		error = SYSCTL_OUT(req, NULL, outlen);
1930 	}
1931 	if (error || !req->newptr)
1932 		return (error);
1933 
1934 	if (req->newlen - req->newidx >= arg2 ||
1935 	    req->newlen - req->newidx < 0) {
1936 		error = EINVAL;
1937 	} else if (req->newlen - req->newidx == 0) {
1938 		sx_xlock(&sysctlstringlock);
1939 		((char *)arg1)[0] = '\0';
1940 		sx_xunlock(&sysctlstringlock);
1941 	} else if (req->newfunc == sysctl_new_kernel) {
1942 		arg2 = req->newlen - req->newidx;
1943 		sx_xlock(&sysctlstringlock);
1944 		error = SYSCTL_IN(req, arg1, arg2);
1945 		if (error == 0) {
1946 			((char *)arg1)[arg2] = '\0';
1947 			req->newidx += arg2;
1948 		}
1949 		sx_xunlock(&sysctlstringlock);
1950 	} else {
1951 		arg2 = req->newlen - req->newidx;
1952 		tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK);
1953 
1954 		error = SYSCTL_IN(req, tmparg, arg2);
1955 		if (error) {
1956 			free(tmparg, M_SYSCTLTMP);
1957 			return (error);
1958 		}
1959 
1960 		sx_xlock(&sysctlstringlock);
1961 		memcpy(arg1, tmparg, arg2);
1962 		((char *)arg1)[arg2] = '\0';
1963 		sx_xunlock(&sysctlstringlock);
1964 		free(tmparg, M_SYSCTLTMP);
1965 		req->newidx += arg2;
1966 	}
1967 	return (error);
1968 }
1969 
1970 /*
1971  * Handle any kind of opaque data.
1972  * arg1 points to it, arg2 is the size.
1973  */
1974 
1975 int
1976 sysctl_handle_opaque(SYSCTL_HANDLER_ARGS)
1977 {
1978 	int error, tries;
1979 	u_int generation;
1980 	struct sysctl_req req2;
1981 
1982 	/*
1983 	 * Attempt to get a coherent snapshot, by using the thread
1984 	 * pre-emption counter updated from within mi_switch() to
1985 	 * determine if we were pre-empted during a bcopy() or
1986 	 * copyout(). Make 3 attempts at doing this before giving up.
1987 	 * If we encounter an error, stop immediately.
1988 	 */
1989 	tries = 0;
1990 	req2 = *req;
1991 retry:
1992 	generation = curthread->td_generation;
1993 	error = SYSCTL_OUT(req, arg1, arg2);
1994 	if (error)
1995 		return (error);
1996 	tries++;
1997 	if (generation != curthread->td_generation && tries < 3) {
1998 		*req = req2;
1999 		goto retry;
2000 	}
2001 
2002 	error = SYSCTL_IN(req, arg1, arg2);
2003 
2004 	return (error);
2005 }
2006 
2007 /*
2008  * Based on sysctl_handle_64() convert microseconds to a sbintime.
2009  */
2010 int
2011 sysctl_usec_to_sbintime(SYSCTL_HANDLER_ARGS)
2012 {
2013 	int error;
2014 	int64_t usec;
2015 
2016 	usec = sbttous(*(sbintime_t *)arg1);
2017 
2018 	error = sysctl_handle_64(oidp, &usec, 0, req);
2019 	if (error || !req->newptr)
2020 		return (error);
2021 
2022 	*(sbintime_t *)arg1 = ustosbt(usec);
2023 
2024 	return (0);
2025 }
2026 
2027 /*
2028  * Based on sysctl_handle_64() convert milliseconds to a sbintime.
2029  */
2030 int
2031 sysctl_msec_to_sbintime(SYSCTL_HANDLER_ARGS)
2032 {
2033 	int error;
2034 	int64_t msec;
2035 
2036 	msec = sbttoms(*(sbintime_t *)arg1);
2037 
2038 	error = sysctl_handle_64(oidp, &msec, 0, req);
2039 	if (error || !req->newptr)
2040 		return (error);
2041 
2042 	*(sbintime_t *)arg1 = mstosbt(msec);
2043 
2044 	return (0);
2045 }
2046 
2047 /*
2048  * Convert seconds to a struct timeval.  Intended for use with
2049  * intervals and thus does not permit negative seconds.
2050  */
2051 int
2052 sysctl_sec_to_timeval(SYSCTL_HANDLER_ARGS)
2053 {
2054 	struct timeval *tv;
2055 	int error, secs;
2056 
2057 	tv = arg1;
2058 	secs = tv->tv_sec;
2059 
2060 	error = sysctl_handle_int(oidp, &secs, 0, req);
2061 	if (error || req->newptr == NULL)
2062 		return (error);
2063 
2064 	if (secs < 0)
2065 		return (EINVAL);
2066 	tv->tv_sec = secs;
2067 
2068 	return (0);
2069 }
2070 
2071 /*
2072  * Transfer functions to/from kernel space.
2073  * XXX: rather untested at this point
2074  */
2075 static int
2076 sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l)
2077 {
2078 	size_t i = 0;
2079 
2080 	if (req->oldptr) {
2081 		i = l;
2082 		if (req->oldlen <= req->oldidx)
2083 			i = 0;
2084 		else
2085 			if (i > req->oldlen - req->oldidx)
2086 				i = req->oldlen - req->oldidx;
2087 		if (i > 0)
2088 			bcopy(p, (char *)req->oldptr + req->oldidx, i);
2089 	}
2090 	req->oldidx += l;
2091 	if (req->oldptr && i != l)
2092 		return (ENOMEM);
2093 	return (0);
2094 }
2095 
2096 static int
2097 sysctl_new_kernel(struct sysctl_req *req, void *p, size_t l)
2098 {
2099 	if (!req->newptr)
2100 		return (0);
2101 	if (req->newlen - req->newidx < l)
2102 		return (EINVAL);
2103 	bcopy((const char *)req->newptr + req->newidx, p, l);
2104 	req->newidx += l;
2105 	return (0);
2106 }
2107 
2108 int
2109 kernel_sysctl(struct thread *td, int *name, u_int namelen, void *old,
2110     size_t *oldlenp, void *new, size_t newlen, size_t *retval, int flags)
2111 {
2112 	int error = 0;
2113 	struct sysctl_req req;
2114 
2115 	bzero(&req, sizeof req);
2116 
2117 	req.td = td;
2118 	req.flags = flags;
2119 
2120 	if (oldlenp) {
2121 		req.oldlen = *oldlenp;
2122 	}
2123 	req.validlen = req.oldlen;
2124 
2125 	if (old) {
2126 		req.oldptr= old;
2127 	}
2128 
2129 	if (new != NULL) {
2130 		req.newlen = newlen;
2131 		req.newptr = new;
2132 	}
2133 
2134 	req.oldfunc = sysctl_old_kernel;
2135 	req.newfunc = sysctl_new_kernel;
2136 	req.lock = REQ_UNWIRED;
2137 
2138 	error = sysctl_root(0, name, namelen, &req);
2139 
2140 	if (req.lock == REQ_WIRED && req.validlen > 0)
2141 		vsunlock(req.oldptr, req.validlen);
2142 
2143 	if (error && error != ENOMEM)
2144 		return (error);
2145 
2146 	if (retval) {
2147 		if (req.oldptr && req.oldidx > req.validlen)
2148 			*retval = req.validlen;
2149 		else
2150 			*retval = req.oldidx;
2151 	}
2152 	return (error);
2153 }
2154 
2155 int
2156 kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
2157     void *new, size_t newlen, size_t *retval, int flags)
2158 {
2159         int oid[CTL_MAXNAME];
2160         size_t oidlen, plen;
2161 	int error;
2162 
2163 	oid[0] = CTL_SYSCTL;
2164 	oid[1] = CTL_SYSCTL_NAME2OID;
2165 	oidlen = sizeof(oid);
2166 
2167 	error = kernel_sysctl(td, oid, 2, oid, &oidlen,
2168 	    (void *)name, strlen(name), &plen, flags);
2169 	if (error)
2170 		return (error);
2171 
2172 	error = kernel_sysctl(td, oid, plen / sizeof(int), old, oldlenp,
2173 	    new, newlen, retval, flags);
2174 	return (error);
2175 }
2176 
2177 /*
2178  * Transfer function to/from user space.
2179  */
2180 static int
2181 sysctl_old_user(struct sysctl_req *req, const void *p, size_t l)
2182 {
2183 	size_t i, len, origidx;
2184 	int error;
2185 
2186 	origidx = req->oldidx;
2187 	req->oldidx += l;
2188 	if (req->oldptr == NULL)
2189 		return (0);
2190 	/*
2191 	 * If we have not wired the user supplied buffer and we are currently
2192 	 * holding locks, drop a witness warning, as it's possible that
2193 	 * write operations to the user page can sleep.
2194 	 */
2195 	if (req->lock != REQ_WIRED)
2196 		WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
2197 		    "sysctl_old_user()");
2198 	i = l;
2199 	len = req->validlen;
2200 	if (len <= origidx)
2201 		i = 0;
2202 	else {
2203 		if (i > len - origidx)
2204 			i = len - origidx;
2205 		if (req->lock == REQ_WIRED) {
2206 			error = copyout_nofault(p, (char *)req->oldptr +
2207 			    origidx, i);
2208 		} else
2209 			error = copyout(p, (char *)req->oldptr + origidx, i);
2210 		if (error != 0)
2211 			return (error);
2212 	}
2213 	if (i < l)
2214 		return (ENOMEM);
2215 	return (0);
2216 }
2217 
2218 static int
2219 sysctl_new_user(struct sysctl_req *req, void *p, size_t l)
2220 {
2221 	int error;
2222 
2223 	if (!req->newptr)
2224 		return (0);
2225 	if (req->newlen - req->newidx < l)
2226 		return (EINVAL);
2227 	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
2228 	    "sysctl_new_user()");
2229 	error = copyin((const char *)req->newptr + req->newidx, p, l);
2230 	req->newidx += l;
2231 	return (error);
2232 }
2233 
2234 /*
2235  * Wire the user space destination buffer.  If set to a value greater than
2236  * zero, the len parameter limits the maximum amount of wired memory.
2237  */
2238 int
2239 sysctl_wire_old_buffer(struct sysctl_req *req, size_t len)
2240 {
2241 	int ret;
2242 	size_t wiredlen;
2243 
2244 	wiredlen = (len > 0 && len < req->oldlen) ? len : req->oldlen;
2245 	ret = 0;
2246 	if (req->lock != REQ_WIRED && req->oldptr &&
2247 	    req->oldfunc == sysctl_old_user) {
2248 		if (wiredlen != 0) {
2249 			ret = vslock(req->oldptr, wiredlen);
2250 			if (ret != 0) {
2251 				if (ret != ENOMEM)
2252 					return (ret);
2253 				wiredlen = 0;
2254 			}
2255 		}
2256 		req->lock = REQ_WIRED;
2257 		req->validlen = wiredlen;
2258 	}
2259 	return (0);
2260 }
2261 
2262 int
2263 sysctl_find_oid(int *name, u_int namelen, struct sysctl_oid **noid,
2264     int *nindx, struct sysctl_req *req)
2265 {
2266 	struct sysctl_oid_list *lsp;
2267 	struct sysctl_oid *oid;
2268 	struct sysctl_oid key;
2269 	int indx;
2270 
2271 	SYSCTL_ASSERT_LOCKED();
2272 	lsp = &sysctl__children;
2273 	indx = 0;
2274 	while (indx < CTL_MAXNAME) {
2275 		key.oid_number = name[indx];
2276 		oid = RB_FIND(sysctl_oid_list, lsp, &key);
2277 		if (oid == NULL)
2278 			return (ENOENT);
2279 
2280 		indx++;
2281 		if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
2282 			if (oid->oid_handler != NULL || indx == namelen) {
2283 				*noid = oid;
2284 				if (nindx != NULL)
2285 					*nindx = indx;
2286 				KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0,
2287 				    ("%s found DYING node %p", __func__, oid));
2288 				return (0);
2289 			}
2290 			lsp = SYSCTL_CHILDREN(oid);
2291 		} else if (indx == namelen) {
2292 			if ((oid->oid_kind & CTLFLAG_DORMANT) != 0)
2293 				return (ENOENT);
2294 			*noid = oid;
2295 			if (nindx != NULL)
2296 				*nindx = indx;
2297 			KASSERT((oid->oid_kind & CTLFLAG_DYING) == 0,
2298 			    ("%s found DYING node %p", __func__, oid));
2299 			return (0);
2300 		} else {
2301 			return (ENOTDIR);
2302 		}
2303 	}
2304 	return (ENOENT);
2305 }
2306 
2307 /*
2308  * Traverse our tree, and find the right node, execute whatever it points
2309  * to, and return the resulting error code.
2310  */
2311 
2312 static int
2313 sysctl_root(SYSCTL_HANDLER_ARGS)
2314 {
2315 	struct sysctl_oid *oid;
2316 	struct rm_priotracker tracker;
2317 	int error, indx, lvl;
2318 
2319 	SYSCTL_RLOCK(&tracker);
2320 
2321 	error = sysctl_find_oid(arg1, arg2, &oid, &indx, req);
2322 	if (error)
2323 		goto out;
2324 
2325 	if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
2326 		/*
2327 		 * You can't call a sysctl when it's a node, but has
2328 		 * no handler.  Inform the user that it's a node.
2329 		 * The indx may or may not be the same as namelen.
2330 		 */
2331 		if (oid->oid_handler == NULL) {
2332 			error = EISDIR;
2333 			goto out;
2334 		}
2335 	}
2336 
2337 	/* Is this sysctl writable? */
2338 	if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) {
2339 		error = EPERM;
2340 		goto out;
2341 	}
2342 
2343 	KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL"));
2344 
2345 #ifdef CAPABILITY_MODE
2346 	/*
2347 	 * If the process is in capability mode, then don't permit reading or
2348 	 * writing unless specifically granted for the node.
2349 	 */
2350 	if (IN_CAPABILITY_MODE(req->td)) {
2351 		if ((req->oldptr && !(oid->oid_kind & CTLFLAG_CAPRD)) ||
2352 		    (req->newptr && !(oid->oid_kind & CTLFLAG_CAPWR))) {
2353 			error = EPERM;
2354 			goto out;
2355 		}
2356 	}
2357 #endif
2358 
2359 	/* Is this sysctl sensitive to securelevels? */
2360 	if (req->newptr && (oid->oid_kind & CTLFLAG_SECURE)) {
2361 		lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE;
2362 		error = securelevel_gt(req->td->td_ucred, lvl);
2363 		if (error)
2364 			goto out;
2365 	}
2366 
2367 	/* Is this sysctl writable by only privileged users? */
2368 	if (req->newptr && !(oid->oid_kind & CTLFLAG_ANYBODY)) {
2369 		int priv;
2370 
2371 		if (oid->oid_kind & CTLFLAG_PRISON)
2372 			priv = PRIV_SYSCTL_WRITEJAIL;
2373 #ifdef VIMAGE
2374 		else if ((oid->oid_kind & CTLFLAG_VNET) &&
2375 		     prison_owns_vnet(req->td->td_ucred))
2376 			priv = PRIV_SYSCTL_WRITEJAIL;
2377 #endif
2378 		else
2379 			priv = PRIV_SYSCTL_WRITE;
2380 		error = priv_check(req->td, priv);
2381 		if (error)
2382 			goto out;
2383 	}
2384 
2385 	if (!oid->oid_handler) {
2386 		error = EINVAL;
2387 		goto out;
2388 	}
2389 
2390 	if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
2391 		arg1 = (int *)arg1 + indx;
2392 		arg2 -= indx;
2393 	} else {
2394 		arg1 = oid->oid_arg1;
2395 		arg2 = oid->oid_arg2;
2396 	}
2397 #ifdef MAC
2398 	error = mac_system_check_sysctl(req->td->td_ucred, oid, arg1, arg2,
2399 	    req);
2400 	if (error != 0)
2401 		goto out;
2402 #endif
2403 #ifdef VIMAGE
2404 	if ((oid->oid_kind & CTLFLAG_VNET) && arg1 != NULL)
2405 		arg1 = (void *)(curvnet->vnet_data_base + (uintptr_t)arg1);
2406 #endif
2407 	error = sysctl_root_handler_locked(oid, arg1, arg2, req, &tracker);
2408 
2409 out:
2410 	SYSCTL_RUNLOCK(&tracker);
2411 	return (error);
2412 }
2413 
2414 #ifndef _SYS_SYSPROTO_H_
2415 struct __sysctl_args {
2416 	int	*name;
2417 	u_int	namelen;
2418 	void	*old;
2419 	size_t	*oldlenp;
2420 	void	*new;
2421 	size_t	newlen;
2422 };
2423 #endif
2424 int
2425 sys___sysctl(struct thread *td, struct __sysctl_args *uap)
2426 {
2427 	int error, i, name[CTL_MAXNAME];
2428 	size_t j;
2429 
2430 	if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
2431 		return (EINVAL);
2432 
2433  	error = copyin(uap->name, &name, uap->namelen * sizeof(int));
2434  	if (error)
2435 		return (error);
2436 
2437 	error = userland_sysctl(td, name, uap->namelen,
2438 		uap->old, uap->oldlenp, 0,
2439 		uap->new, uap->newlen, &j, 0);
2440 	if (error && error != ENOMEM)
2441 		return (error);
2442 	if (uap->oldlenp) {
2443 		i = copyout(&j, uap->oldlenp, sizeof(j));
2444 		if (i)
2445 			return (i);
2446 	}
2447 	return (error);
2448 }
2449 
2450 int
2451 kern___sysctlbyname(struct thread *td, const char *oname, size_t namelen,
2452     void *old, size_t *oldlenp, void *new, size_t newlen, size_t *retval,
2453     int flags, bool inkernel)
2454 {
2455 	int oid[CTL_MAXNAME];
2456 	char namebuf[16];
2457 	char *name;
2458 	size_t oidlen;
2459 	int error;
2460 
2461 	if (namelen > MAXPATHLEN || namelen == 0)
2462 		return (EINVAL);
2463 	name = namebuf;
2464 	if (namelen > sizeof(namebuf))
2465 		name = malloc(namelen, M_SYSCTL, M_WAITOK);
2466 	error = copyin(oname, name, namelen);
2467 	if (error != 0)
2468 		goto out;
2469 
2470 	oid[0] = CTL_SYSCTL;
2471 	oid[1] = CTL_SYSCTL_NAME2OID;
2472 	oidlen = sizeof(oid);
2473 	error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen,
2474 	    retval, flags);
2475 	if (error != 0)
2476 		goto out;
2477 	error = userland_sysctl(td, oid, *retval / sizeof(int), old, oldlenp,
2478 	    inkernel, new, newlen, retval, flags);
2479 
2480 out:
2481 	if (namelen > sizeof(namebuf))
2482 		free(name, M_SYSCTL);
2483 	return (error);
2484 }
2485 
2486 #ifndef	_SYS_SYSPROTO_H_
2487 struct __sysctlbyname_args {
2488 	const char	*name;
2489 	size_t	namelen;
2490 	void	*old;
2491 	size_t	*oldlenp;
2492 	void	*new;
2493 	size_t	newlen;
2494 };
2495 #endif
2496 int
2497 sys___sysctlbyname(struct thread *td, struct __sysctlbyname_args *uap)
2498 {
2499 	size_t rv;
2500 	int error;
2501 
2502 	error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
2503 	    uap->oldlenp, uap->new, uap->newlen, &rv, 0, 0);
2504 	if (error != 0)
2505 		return (error);
2506 	if (uap->oldlenp != NULL)
2507 		error = copyout(&rv, uap->oldlenp, sizeof(rv));
2508 
2509 	return (error);
2510 }
2511 
2512 /*
2513  * This is used from various compatibility syscalls too.  That's why name
2514  * must be in kernel space.
2515  */
2516 int
2517 userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
2518     size_t *oldlenp, int inkernel, const void *new, size_t newlen,
2519     size_t *retval, int flags)
2520 {
2521 	int error = 0, memlocked;
2522 	struct sysctl_req req;
2523 
2524 	bzero(&req, sizeof req);
2525 
2526 	req.td = td;
2527 	req.flags = flags;
2528 
2529 	if (oldlenp) {
2530 		if (inkernel) {
2531 			req.oldlen = *oldlenp;
2532 		} else {
2533 			error = copyin(oldlenp, &req.oldlen, sizeof(*oldlenp));
2534 			if (error)
2535 				return (error);
2536 		}
2537 	}
2538 	req.validlen = req.oldlen;
2539 	req.oldptr = old;
2540 
2541 	if (new != NULL) {
2542 		req.newlen = newlen;
2543 		req.newptr = new;
2544 	}
2545 
2546 	req.oldfunc = sysctl_old_user;
2547 	req.newfunc = sysctl_new_user;
2548 	req.lock = REQ_UNWIRED;
2549 
2550 #ifdef KTRACE
2551 	if (KTRPOINT(curthread, KTR_SYSCTL))
2552 		ktrsysctl(name, namelen);
2553 #endif
2554 	memlocked = 0;
2555 	if (req.oldptr && req.oldlen > 4 * PAGE_SIZE) {
2556 		memlocked = 1;
2557 		sx_xlock(&sysctlmemlock);
2558 	}
2559 	CURVNET_SET(TD_TO_VNET(td));
2560 
2561 	for (;;) {
2562 		req.oldidx = 0;
2563 		req.newidx = 0;
2564 		error = sysctl_root(0, name, namelen, &req);
2565 		if (error != EAGAIN)
2566 			break;
2567 		kern_yield(PRI_USER);
2568 	}
2569 
2570 	CURVNET_RESTORE();
2571 
2572 	if (req.lock == REQ_WIRED && req.validlen > 0)
2573 		vsunlock(req.oldptr, req.validlen);
2574 	if (memlocked)
2575 		sx_xunlock(&sysctlmemlock);
2576 
2577 	if (error && error != ENOMEM)
2578 		return (error);
2579 
2580 	if (retval) {
2581 		if (req.oldptr && req.oldidx > req.validlen)
2582 			*retval = req.validlen;
2583 		else
2584 			*retval = req.oldidx;
2585 	}
2586 	return (error);
2587 }
2588 
2589 /*
2590  * Drain into a sysctl struct.  The user buffer should be wired if a page
2591  * fault would cause issue.
2592  */
2593 static int
2594 sbuf_sysctl_drain(void *arg, const char *data, int len)
2595 {
2596 	struct sysctl_req *req = arg;
2597 	int error;
2598 
2599 	error = SYSCTL_OUT(req, data, len);
2600 	KASSERT(error >= 0, ("Got unexpected negative value %d", error));
2601 	return (error == 0 ? len : -error);
2602 }
2603 
2604 struct sbuf *
2605 sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length,
2606     struct sysctl_req *req)
2607 {
2608 
2609 	/* Supply a default buffer size if none given. */
2610 	if (buf == NULL && length == 0)
2611 		length = 64;
2612 	s = sbuf_new(s, buf, length, SBUF_FIXEDLEN | SBUF_INCLUDENUL);
2613 	sbuf_set_drain(s, sbuf_sysctl_drain, req);
2614 	return (s);
2615 }
2616 
2617 #ifdef DDB
2618 
2619 /* The current OID the debugger is working with */
2620 static struct sysctl_oid *g_ddb_oid;
2621 
2622 /* The current flags specified by the user */
2623 static int g_ddb_sysctl_flags;
2624 
2625 /* Check to see if the last sysctl printed */
2626 static int g_ddb_sysctl_printed;
2627 
2628 static const int ctl_sign[CTLTYPE+1] = {
2629 	[CTLTYPE_INT] = 1,
2630 	[CTLTYPE_LONG] = 1,
2631 	[CTLTYPE_S8] = 1,
2632 	[CTLTYPE_S16] = 1,
2633 	[CTLTYPE_S32] = 1,
2634 	[CTLTYPE_S64] = 1,
2635 };
2636 
2637 static const int ctl_size[CTLTYPE+1] = {
2638 	[CTLTYPE_INT] = sizeof(int),
2639 	[CTLTYPE_UINT] = sizeof(u_int),
2640 	[CTLTYPE_LONG] = sizeof(long),
2641 	[CTLTYPE_ULONG] = sizeof(u_long),
2642 	[CTLTYPE_S8] = sizeof(int8_t),
2643 	[CTLTYPE_S16] = sizeof(int16_t),
2644 	[CTLTYPE_S32] = sizeof(int32_t),
2645 	[CTLTYPE_S64] = sizeof(int64_t),
2646 	[CTLTYPE_U8] = sizeof(uint8_t),
2647 	[CTLTYPE_U16] = sizeof(uint16_t),
2648 	[CTLTYPE_U32] = sizeof(uint32_t),
2649 	[CTLTYPE_U64] = sizeof(uint64_t),
2650 };
2651 
2652 #define DB_SYSCTL_NAME_ONLY	0x001	/* Compare with -N */
2653 #define DB_SYSCTL_VALUE_ONLY	0x002	/* Compare with -n */
2654 #define DB_SYSCTL_OPAQUE	0x004	/* Compare with -o */
2655 #define DB_SYSCTL_HEX		0x008	/* Compare with -x */
2656 
2657 #define DB_SYSCTL_SAFE_ONLY	0x100	/* Only simple types */
2658 
2659 static const char db_sysctl_modifs[] = {
2660 	'N', 'n', 'o', 'x',
2661 };
2662 
2663 static const int db_sysctl_modif_values[] = {
2664 	DB_SYSCTL_NAME_ONLY, DB_SYSCTL_VALUE_ONLY,
2665 	DB_SYSCTL_OPAQUE, DB_SYSCTL_HEX,
2666 };
2667 
2668 /* Handlers considered safe to print while recursing */
2669 static int (* const db_safe_handlers[])(SYSCTL_HANDLER_ARGS) = {
2670 	sysctl_handle_bool,
2671 	sysctl_handle_8,
2672 	sysctl_handle_16,
2673 	sysctl_handle_32,
2674 	sysctl_handle_64,
2675 	sysctl_handle_int,
2676 	sysctl_handle_long,
2677 	sysctl_handle_string,
2678 	sysctl_handle_opaque,
2679 };
2680 
2681 /*
2682  * Use in place of sysctl_old_kernel to print sysctl values.
2683  *
2684  * Compare to the output handling in show_var from sbin/sysctl/sysctl.c
2685  */
2686 static int
2687 sysctl_old_ddb(struct sysctl_req *req, const void *ptr, size_t len)
2688 {
2689 	const u_char *val, *p;
2690 	const char *sep1;
2691 	size_t intlen, slen;
2692 	uintmax_t umv;
2693 	intmax_t mv;
2694 	int sign, ctltype, hexlen, xflag, error;
2695 
2696 	/* Suppress false-positive GCC uninitialized variable warnings */
2697 	mv = 0;
2698 	umv = 0;
2699 
2700 	slen = len;
2701 	val = p = ptr;
2702 
2703 	if (ptr == NULL) {
2704 		error = 0;
2705 		goto out;
2706 	}
2707 
2708 	/* We are going to print */
2709 	g_ddb_sysctl_printed = 1;
2710 
2711 	xflag = g_ddb_sysctl_flags & DB_SYSCTL_HEX;
2712 
2713 	ctltype = (g_ddb_oid->oid_kind & CTLTYPE);
2714 	sign = ctl_sign[ctltype];
2715 	intlen = ctl_size[ctltype];
2716 
2717 	switch (ctltype) {
2718 	case CTLTYPE_NODE:
2719 	case CTLTYPE_STRING:
2720 		db_printf("%.*s", (int) len, (const char *) p);
2721 		error = 0;
2722 		goto out;
2723 
2724 	case CTLTYPE_INT:
2725 	case CTLTYPE_UINT:
2726 	case CTLTYPE_LONG:
2727 	case CTLTYPE_ULONG:
2728 	case CTLTYPE_S8:
2729 	case CTLTYPE_S16:
2730 	case CTLTYPE_S32:
2731 	case CTLTYPE_S64:
2732 	case CTLTYPE_U8:
2733 	case CTLTYPE_U16:
2734 	case CTLTYPE_U32:
2735 	case CTLTYPE_U64:
2736 		hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
2737 		sep1 = "";
2738 		while (len >= intlen) {
2739 			switch (ctltype) {
2740 			case CTLTYPE_INT:
2741 			case CTLTYPE_UINT:
2742 				umv = *(const u_int *)p;
2743 				mv = *(const int *)p;
2744 				break;
2745 			case CTLTYPE_LONG:
2746 			case CTLTYPE_ULONG:
2747 				umv = *(const u_long *)p;
2748 				mv = *(const long *)p;
2749 				break;
2750 			case CTLTYPE_S8:
2751 			case CTLTYPE_U8:
2752 				umv = *(const uint8_t *)p;
2753 				mv = *(const int8_t *)p;
2754 				break;
2755 			case CTLTYPE_S16:
2756 			case CTLTYPE_U16:
2757 				umv = *(const uint16_t *)p;
2758 				mv = *(const int16_t *)p;
2759 				break;
2760 			case CTLTYPE_S32:
2761 			case CTLTYPE_U32:
2762 				umv = *(const uint32_t *)p;
2763 				mv = *(const int32_t *)p;
2764 				break;
2765 			case CTLTYPE_S64:
2766 			case CTLTYPE_U64:
2767 				umv = *(const uint64_t *)p;
2768 				mv = *(const int64_t *)p;
2769 				break;
2770 			}
2771 
2772 			db_printf("%s", sep1);
2773 			if (xflag)
2774 				db_printf("%#0*jx", hexlen, umv);
2775 			else if (!sign)
2776 				db_printf("%ju", umv);
2777 			else if (g_ddb_oid->oid_fmt[1] == 'K') {
2778 				/* Kelvins are currently unsupported. */
2779 				error = EOPNOTSUPP;
2780 				goto out;
2781 			} else
2782 				db_printf("%jd", mv);
2783 
2784 			sep1 = " ";
2785 			len -= intlen;
2786 			p += intlen;
2787 		}
2788 		error = 0;
2789 		goto out;
2790 
2791 	case CTLTYPE_OPAQUE:
2792 		/* TODO: Support struct functions. */
2793 
2794 		/* FALLTHROUGH */
2795 	default:
2796 		db_printf("Format:%s Length:%zu Dump:0x",
2797 		    g_ddb_oid->oid_fmt, len);
2798 		while (len-- && (xflag || p < val + 16))
2799 			db_printf("%02x", *p++);
2800 		if (!xflag && len > 16)
2801 			db_printf("...");
2802 		error = 0;
2803 		goto out;
2804 	}
2805 
2806 out:
2807 	req->oldidx += slen;
2808 	return (error);
2809 }
2810 
2811 /*
2812  * Avoid setting new sysctl values from the debugger
2813  */
2814 static int
2815 sysctl_new_ddb(struct sysctl_req *req, void *p, size_t l)
2816 {
2817 
2818 	if (!req->newptr)
2819 		return (0);
2820 
2821 	/* Changing sysctls from the debugger is currently unsupported */
2822 	return (EPERM);
2823 }
2824 
2825 /*
2826  * Run a sysctl handler with the DDB oldfunc and newfunc attached.
2827  * Instead of copying any output to a buffer we'll dump it right to
2828  * the console.
2829  */
2830 static int
2831 db_sysctl(struct sysctl_oid *oidp, int *name, u_int namelen,
2832     void *old, size_t *oldlenp, size_t *retval, int flags)
2833 {
2834 	struct sysctl_req req;
2835 	int error;
2836 
2837 	/* Setup the request */
2838 	bzero(&req, sizeof req);
2839 	req.td = kdb_thread;
2840 	req.oldfunc = sysctl_old_ddb;
2841 	req.newfunc = sysctl_new_ddb;
2842 	req.lock = REQ_UNWIRED;
2843 	if (oldlenp) {
2844 		req.oldlen = *oldlenp;
2845 	}
2846 	req.validlen = req.oldlen;
2847 	if (old) {
2848 		req.oldptr = old;
2849 	}
2850 
2851 	/* Setup our globals for sysctl_old_ddb */
2852 	g_ddb_oid = oidp;
2853 	g_ddb_sysctl_flags = flags;
2854 	g_ddb_sysctl_printed = 0;
2855 
2856 	error = sysctl_root(0, name, namelen, &req);
2857 
2858 	/* Reset globals */
2859 	g_ddb_oid = NULL;
2860 	g_ddb_sysctl_flags = 0;
2861 
2862 	if (retval) {
2863 		if (req.oldptr && req.oldidx > req.validlen)
2864 			*retval = req.validlen;
2865 		else
2866 			*retval = req.oldidx;
2867 	}
2868 	return (error);
2869 }
2870 
2871 /*
2872  * Show a sysctl's name
2873  */
2874 static void
2875 db_show_oid_name(int *oid, size_t nlen)
2876 {
2877 	struct sysctl_oid *oidp;
2878 	int qoid[CTL_MAXNAME + 2];
2879 	int error;
2880 
2881 	qoid[0] = CTL_SYSCTL;
2882 	qoid[1] = CTL_SYSCTL_NAME;
2883 	memcpy(qoid + 2, oid, nlen * sizeof(int));
2884 
2885 	error = sysctl_find_oid(qoid, nlen + 2, &oidp, NULL, NULL);
2886 	if (error)
2887 		db_error("sysctl name oid");
2888 
2889 	error = db_sysctl(oidp, qoid, nlen + 2, NULL, NULL, NULL, 0);
2890 	if (error)
2891 		db_error("sysctl name");
2892 }
2893 
2894 /*
2895  * Check to see if an OID is safe to print from ddb.
2896  */
2897 static bool
2898 db_oid_safe(const struct sysctl_oid *oidp)
2899 {
2900 	for (unsigned int i = 0; i < nitems(db_safe_handlers); ++i) {
2901 		if (oidp->oid_handler == db_safe_handlers[i])
2902 			return (true);
2903 	}
2904 
2905 	return (false);
2906 }
2907 
2908 /*
2909  * Show a sysctl at a specific OID
2910  * Compare to the input handling in show_var from sbin/sysctl/sysctl.c
2911  */
2912 static int
2913 db_show_oid(struct sysctl_oid *oidp, int *oid, size_t nlen, int flags)
2914 {
2915 	int error, xflag, oflag, Nflag, nflag;
2916 	size_t len;
2917 
2918 	xflag = flags & DB_SYSCTL_HEX;
2919 	oflag = flags & DB_SYSCTL_OPAQUE;
2920 	nflag = flags & DB_SYSCTL_VALUE_ONLY;
2921 	Nflag = flags & DB_SYSCTL_NAME_ONLY;
2922 
2923 	if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_OPAQUE &&
2924 	    (!xflag && !oflag))
2925 		return (0);
2926 
2927 	if (Nflag) {
2928 		db_show_oid_name(oid, nlen);
2929 		error = 0;
2930 		goto out;
2931 	}
2932 
2933 	if (!nflag) {
2934 		db_show_oid_name(oid, nlen);
2935 		db_printf(": ");
2936 	}
2937 
2938 	if ((flags & DB_SYSCTL_SAFE_ONLY) && !db_oid_safe(oidp)) {
2939 		db_printf("Skipping, unsafe to print while recursing.");
2940 		error = 0;
2941 		goto out;
2942 	}
2943 
2944 	/* Try once, and ask about the size */
2945 	len = 0;
2946 	error = db_sysctl(oidp, oid, nlen,
2947 	    NULL, NULL, &len, flags);
2948 	if (error)
2949 		goto out;
2950 
2951 	if (!g_ddb_sysctl_printed)
2952 		/* Lie about the size */
2953 		error = db_sysctl(oidp, oid, nlen,
2954 		    (void *) 1, &len, NULL, flags);
2955 
2956 out:
2957 	db_printf("\n");
2958 	return (error);
2959 }
2960 
2961 /*
2962  * Show all sysctls under a specific OID
2963  * Compare to sysctl_all from sbin/sysctl/sysctl.c
2964  */
2965 static int
2966 db_show_sysctl_all(int *oid, size_t len, int flags)
2967 {
2968 	struct sysctl_oid *oidp;
2969 	int qoid[CTL_MAXNAME + 2], next[CTL_MAXNAME];
2970 	size_t nlen;
2971 
2972 	qoid[0] = CTL_SYSCTL;
2973 	qoid[1] = CTL_SYSCTL_NEXT;
2974 	if (len) {
2975 		nlen = len;
2976 		memcpy(&qoid[2], oid, nlen * sizeof(int));
2977 	} else {
2978 		nlen = 1;
2979 		qoid[2] = CTL_KERN;
2980 	}
2981 	for (;;) {
2982 		int error;
2983 		size_t nextsize = sizeof(next);
2984 
2985 		error = kernel_sysctl(kdb_thread, qoid, nlen + 2,
2986 		    next, &nextsize, NULL, 0, &nlen, 0);
2987 		if (error != 0) {
2988 			if (error == ENOENT)
2989 				return (0);
2990 			else
2991 				db_error("sysctl(next)");
2992 		}
2993 
2994 		nlen /= sizeof(int);
2995 
2996 		if (nlen < (unsigned int)len)
2997 			return (0);
2998 
2999 		if (memcmp(&oid[0], &next[0], len * sizeof(int)) != 0)
3000 			return (0);
3001 
3002 		/* Find the OID in question */
3003 		error = sysctl_find_oid(next, nlen, &oidp, NULL, NULL);
3004 		if (error)
3005 			return (error);
3006 
3007 		(void)db_show_oid(oidp, next, nlen, flags | DB_SYSCTL_SAFE_ONLY);
3008 
3009 		if (db_pager_quit)
3010 			return (0);
3011 
3012 		memcpy(&qoid[2 + len], &next[len], (nlen - len) * sizeof(int));
3013 	}
3014 }
3015 
3016 /*
3017  * Show a sysctl by its user facing string
3018  */
3019 static int
3020 db_sysctlbyname(const char *name, int flags)
3021 {
3022 	struct sysctl_oid *oidp;
3023 	int oid[CTL_MAXNAME];
3024 	int error, nlen;
3025 
3026 	error = name2oid(name, oid, &nlen, &oidp);
3027 	if (error) {
3028 		return (error);
3029 	}
3030 
3031 	if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
3032 		db_show_sysctl_all(oid, nlen, flags);
3033 	} else {
3034 		error = db_show_oid(oidp, oid, nlen, flags);
3035 	}
3036 
3037 	return (error);
3038 }
3039 
3040 static void
3041 db_sysctl_cmd_usage(void)
3042 {
3043 	db_printf(
3044 	    " sysctl [/Nnox] <sysctl>					    \n"
3045 	    "								    \n"
3046 	    " <sysctl> The name of the sysctl to show.			    \n"
3047 	    "								    \n"
3048 	    " Show a sysctl by hooking into SYSCTL_IN and SYSCTL_OUT.	    \n"
3049 	    " This will work for most sysctls, but should not be used	    \n"
3050 	    " with sysctls that are known to malloc.			    \n"
3051 	    "								    \n"
3052 	    " While recursing any \"unsafe\" sysctls will be skipped.	    \n"
3053 	    " Call sysctl directly on the sysctl to try printing the	    \n"
3054 	    " skipped sysctl. This is unsafe and may make the ddb	    \n"
3055 	    " session unusable.						    \n"
3056 	    "								    \n"
3057 	    " Arguments:						    \n"
3058 	    "	/N	Display only the name of the sysctl.		    \n"
3059 	    "	/n	Display only the value of the sysctl.		    \n"
3060 	    "	/o	Display opaque values.				    \n"
3061 	    "	/x	Display the sysctl in hex.			    \n"
3062 	    "								    \n"
3063 	    "For example:						    \n"
3064 	    "sysctl vm.v_free_min					    \n"
3065 	    "vn.v_free_min: 12669					    \n"
3066 	    );
3067 }
3068 
3069 /*
3070  * Show a specific sysctl similar to sysctl (8).
3071  */
3072 DB_COMMAND_FLAGS(sysctl, db_sysctl_cmd, CS_OWN)
3073 {
3074 	char name[TOK_STRING_SIZE];
3075 	int error, i, t, flags;
3076 
3077 	/* Parse the modifiers */
3078 	t = db_read_token();
3079 	if (t == tSLASH || t == tMINUS) {
3080 		t = db_read_token();
3081 		if (t != tIDENT) {
3082 			db_printf("Bad modifier\n");
3083 			error = EINVAL;
3084 			goto out;
3085 		}
3086 		db_strcpy(modif, db_tok_string);
3087 	}
3088 	else {
3089 		db_unread_token(t);
3090 		modif[0] = '\0';
3091 	}
3092 
3093 	flags = 0;
3094 	for (i = 0; i < nitems(db_sysctl_modifs); i++) {
3095 		if (strchr(modif, db_sysctl_modifs[i])) {
3096 			flags |= db_sysctl_modif_values[i];
3097 		}
3098 	}
3099 
3100 	/* Parse the sysctl names */
3101 	t = db_read_token();
3102 	if (t != tIDENT) {
3103 		db_printf("Need sysctl name\n");
3104 		error = EINVAL;
3105 		goto out;
3106 	}
3107 
3108 	/* Copy the name into a temporary buffer */
3109 	db_strcpy(name, db_tok_string);
3110 
3111 	/* Ensure there is no trailing cruft */
3112 	t = db_read_token();
3113 	if (t != tEOL) {
3114 		db_printf("Unexpected sysctl argument\n");
3115 		error = EINVAL;
3116 		goto out;
3117 	}
3118 
3119 	error = db_sysctlbyname(name, flags);
3120 	if (error == ENOENT) {
3121 		db_printf("unknown oid: '%s'\n", db_tok_string);
3122 		goto out;
3123 	} else if (error) {
3124 		db_printf("%s: error: %d\n", db_tok_string, error);
3125 		goto out;
3126 	}
3127 
3128 out:
3129 	/* Ensure we eat all of our text */
3130 	db_flush_lex();
3131 
3132 	if (error == EINVAL) {
3133 		db_sysctl_cmd_usage();
3134 	}
3135 }
3136 
3137 #endif /* DDB */
3138