xref: /netbsd-src/sys/kern/kern_sysctl.c (revision d20841bb642898112fe68f0ad3f7b26dddf56f07)
1 /*	$NetBSD: kern_sysctl.c,v 1.158 2004/01/17 04:01:14 atatat Exp $	*/
2 
3 /*-
4  * Copyright (c) 2003 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Andrew Brown.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the NetBSD
21  *      Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*-
40  * Copyright (c) 1982, 1986, 1989, 1993
41  *	The Regents of the University of California.  All rights reserved.
42  *
43  * This code is derived from software contributed to Berkeley by
44  * Mike Karels at Berkeley Software Design, Inc.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  * 1. Redistributions of source code must retain the above copyright
50  *    notice, this list of conditions and the following disclaimer.
51  * 2. Redistributions in binary form must reproduce the above copyright
52  *    notice, this list of conditions and the following disclaimer in the
53  *    documentation and/or other materials provided with the distribution.
54  * 3. Neither the name of the University nor the names of its contributors
55  *    may be used to endorse or promote products derived from this software
56  *    without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68  * SUCH DAMAGE.
69  *
70  *	@(#)kern_sysctl.c	8.9 (Berkeley) 5/20/95
71  */
72 
73 /*
74  * sysctl system call.
75  */
76 
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: kern_sysctl.c,v 1.158 2004/01/17 04:01:14 atatat Exp $");
79 
80 #include "opt_defcorename.h"
81 #include "opt_insecure.h"
82 #include "ksyms.h"
83 
84 #include <sys/param.h>
85 #include <sys/sysctl.h>
86 #include <sys/systm.h>
87 #include <sys/buf.h>
88 #include <sys/ksyms.h>
89 #include <sys/malloc.h>
90 #include <sys/mount.h>
91 #include <sys/sa.h>
92 #include <sys/syscallargs.h>
93 #include <machine/stdarg.h>
94 
95 MALLOC_DEFINE(M_SYSCTLNODE, "sysctlnode", "sysctl node structures");
96 MALLOC_DEFINE(M_SYSCTLDATA, "sysctldata", "misc sysctl data");
97 
98 static int sysctl_mmap(SYSCTLFN_RWPROTO);
99 static int sysctl_alloc(struct sysctlnode *, int);
100 static int sysctl_realloc(struct sysctlnode *);
101 
102 /*
103  * the "root" of the new sysctl tree
104  */
105 static struct sysctlnode sysctl_root = {
106 	.sysctl_flags = SYSCTL_ROOT|
107 	    SYSCTL_READWRITE|
108 	    CTLTYPE_NODE,
109 	.sysctl_num = 0,
110 	.sysctl_size = sizeof(struct sysctlnode),
111 	.sysctl_name = "(root)",
112 };
113 
114 /*
115  * link set of functions that add nodes at boot time (see also
116  * sysctl_buildtree())
117  */
118 __link_set_decl(sysctl_funcs, sysctl_setup_func);
119 
120 /*
121  * The `sysctl_lock' is intended to serialize access to the sysctl
122  * tree.  Given that it is now (a) dynamic, and (b) most consumers of
123  * sysctl are going to be copying data out, the old `sysctl_memlock'
124  * has been `upgraded' to simply guard the whole tree.
125  *
126  * The two new data here are to keep track of the locked chunk of
127  * memory, if there is one, so that it can be released more easily
128  * from anywhere.
129  */
130 struct lock sysctl_treelock;
131 caddr_t sysctl_memaddr;
132 size_t sysctl_memsize;
133 
134 /*
135  * Attributes stored in the kernel.
136  */
137 char hostname[MAXHOSTNAMELEN];
138 int hostnamelen;
139 
140 char domainname[MAXHOSTNAMELEN];
141 int domainnamelen;
142 
143 long hostid;
144 
145 #ifdef INSECURE
146 int securelevel = -1;
147 #else
148 int securelevel = 0;
149 #endif
150 
151 #ifndef DEFCORENAME
152 #define	DEFCORENAME	"%n.core"
153 #endif
154 char defcorename[MAXPATHLEN] = DEFCORENAME;
155 
156 /*
157  * ********************************************************************
158  * Section 0: Some simple glue
159  * ********************************************************************
160  * By wrapping copyin(), copyout(), and copyinstr() like this, we can
161  * stop caring about who's calling us and simplify some code a bunch.
162  * ********************************************************************
163  */
164 static inline int
165 sysctl_copyin(const struct lwp *l, const void *uaddr, void *kaddr, size_t len)
166 {
167 
168 	if (l != NULL)
169 		return (copyin(uaddr, kaddr, len));
170 	else
171 		return (kcopy(uaddr, kaddr, len));
172 }
173 
174 static inline int
175 sysctl_copyout(const struct lwp *l, const void *kaddr, void *uaddr, size_t len)
176 {
177 
178 	if (l != NULL)
179 		return (copyout(kaddr, uaddr, len));
180 	else
181 		return (kcopy(kaddr, uaddr, len));
182 }
183 
184 static inline int
185 sysctl_copyinstr(const struct lwp *l, const void *uaddr, void *kaddr,
186 		 size_t len, size_t *done)
187 {
188 
189 	if (l != NULL)
190 		return (copyinstr(uaddr, kaddr, len, done));
191 	else
192 		return (copystr(uaddr, kaddr, len, done));
193 }
194 
195 /*
196  * ********************************************************************
197  * Initialize sysctl subsystem.
198  * ********************************************************************
199  */
200 void
201 sysctl_init(void)
202 {
203 	sysctl_setup_func **sysctl_setup, f;
204 
205 	lockinit(&sysctl_treelock, PRIBIO|PCATCH, "sysctl", 0, 0);
206 
207 	/*
208 	 * dynamic mib numbers start here
209 	 */
210 	sysctl_root.sysctl_num = CREATE_BASE;
211 
212         __link_set_foreach(sysctl_setup, sysctl_funcs) {
213 		/*
214 		 * XXX - why do i have to coerce the pointers like this?
215 		 */
216 		f = (void*)*sysctl_setup;
217 		(*f)();
218 	}
219 
220 	/*
221 	 * setting this means no more permanent nodes can be added,
222 	 * trees that claim to be readonly at the root now are, and if
223 	 * the main tree is readonly, *everything* is.
224 	 */
225 	sysctl_root.sysctl_flags |= SYSCTL_PERMANENT;
226 
227 }
228 
229 /*
230  * ********************************************************************
231  * The main native sysctl system call itself.
232  * ********************************************************************
233  */
234 int
235 sys___sysctl(struct lwp *l, void *v, register_t *retval)
236 {
237 	struct sys___sysctl_args /* {
238 		syscallarg(int *) name;
239 		syscallarg(u_int) namelen;
240 		syscallarg(void *) old;
241 		syscallarg(size_t *) oldlenp;
242 		syscallarg(void *) new;
243 		syscallarg(size_t) newlen;
244 	} */ *uap = v;
245 	int error, nerror, name[CTL_MAXNAME];
246 	size_t oldlen, savelen, *oldlenp;
247 
248 	/*
249 	 * get oldlen
250 	 */
251 	oldlen = 0;
252 	oldlenp = SCARG(uap, oldlenp);
253 	if (oldlenp != NULL) {
254 		error = copyin(oldlenp, &oldlen, sizeof(oldlen));
255 		if (error)
256 			return (error);
257 	}
258 	savelen = oldlen;
259 
260 	/*
261 	 * top-level sysctl names may or may not be non-terminal, but
262 	 * we don't care
263 	 */
264 	if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 1)
265 		return (EINVAL);
266 	error = copyin(SCARG(uap, name), &name,
267 		       SCARG(uap, namelen) * sizeof(int));
268 	if (error)
269 		return (error);
270 
271 	/*
272 	 * wire old so that copyout() is less likely to fail?
273 	 */
274 	error = sysctl_lock(l, SCARG(uap, old), savelen);
275 	if (error)
276 		return (error);
277 
278 	/*
279 	 * do sysctl work (NULL means main built-in default tree)
280 	 */
281 	error = sysctl_dispatch(&name[0], SCARG(uap, namelen),
282 				SCARG(uap, old), &oldlen,
283 				SCARG(uap, new), SCARG(uap, newlen),
284 				&name[0], l, NULL);
285 
286 	/*
287 	 * release the sysctl lock
288 	 */
289 	sysctl_unlock(l);
290 
291 	/*
292 	 * set caller's oldlen to new value even in the face of an
293 	 * error (if this gets an error and they didn't have one, they
294 	 * get this one)
295 	 */
296 	if (oldlenp) {
297 		nerror = copyout(&oldlen, oldlenp, sizeof(oldlen));
298 		if (error == 0)
299 			error = nerror;
300 	}
301 
302 	/*
303 	 * if the only problem is that we weren't given enough space,
304 	 * that's an ENOMEM error
305 	 */
306 	if (error == 0 && SCARG(uap, old) != NULL && savelen < oldlen)
307 		error = ENOMEM;
308 
309 	return (error);
310 }
311 
312 /*
313  * ********************************************************************
314  * Section 1: How the tree is used
315  * ********************************************************************
316  * Implementations of sysctl for emulations should typically need only
317  * these three functions in this order: lock the tree, dispatch
318  * request into it, unlock the tree.
319  * ********************************************************************
320  */
321 int
322 sysctl_lock(struct lwp *l, void *oldp, size_t savelen)
323 {
324 	int error = 0;
325 
326 	error = lockmgr(&sysctl_treelock, LK_EXCLUSIVE, NULL);
327 	if (error)
328 		return (error);
329 
330 	if (l != NULL && oldp != NULL && savelen) {
331 		error = uvm_vslock(l->l_proc, oldp, savelen, VM_PROT_WRITE);
332 		if (error) {
333 			(void) lockmgr(&sysctl_treelock, LK_RELEASE, NULL);
334 			return (error);
335 		}
336 		sysctl_memaddr = oldp;
337 		sysctl_memsize = savelen;
338 	}
339 
340 	return (0);
341 }
342 
343 /*
344  * ********************************************************************
345  * the main sysctl dispatch routine.  scans the given tree and picks a
346  * function to call based on what it finds.
347  * ********************************************************************
348  */
349 int
350 sysctl_dispatch(SYSCTLFN_RWARGS)
351 {
352 	int error;
353 	sysctlfn fn;
354 	int ni;
355 
356 	fn = NULL;
357 	error = sysctl_locate(l, name, namelen, &rnode, &ni);
358 
359 	/*
360 	 * the node we ended up at has a function, so call it.  it can
361 	 * hand off to query or create if it wants to.
362 	 */
363 	if (rnode->sysctl_func != NULL)
364 		fn = rnode->sysctl_func;
365 
366 	/*
367 	 * we found the node they were looking for, so do a lookup.
368 	 */
369 	else if (error == 0)
370 		fn = (sysctlfn)sysctl_lookup; /* XXX may write to rnode */
371 
372 	/*
373 	 * prospective parent node found, but the terminal node was
374 	 * not.  generic operations associate with the parent.
375 	 */
376 	else if (error == ENOENT && (ni + 1) == namelen && name[ni] < 0) {
377 		switch (name[ni]) {
378 		case CTL_QUERY:
379 			fn = sysctl_query;
380 			break;
381 		case CTL_CREATE:
382 #if NKSYMS > 0
383 		case CTL_CREATESYM:
384 #endif /* NKSYMS > 0 */
385 			fn = (sysctlfn)sysctl_create; /* we own the rnode */
386 			break;
387 		case CTL_DESTROY:
388 			fn = (sysctlfn)sysctl_destroy; /* we own the rnode */
389 			break;
390 		case CTL_MMAP:
391 			fn = (sysctlfn)sysctl_mmap; /* we own the rnode */
392 			break;
393 		default:
394 			error = EOPNOTSUPP;
395 			break;
396 		}
397 	}
398 
399 	/*
400 	 * after all of that, maybe we found someone who knows how to
401 	 * get us what we want?
402 	 */
403 	if (fn != NULL)
404 		error = (*fn)(name + ni, namelen - ni, oldp, oldlenp,
405 			      newp, newlen, name, l, rnode);
406 
407 	else if (error == 0)
408 		error = EOPNOTSUPP;
409 
410 	return (error);
411 }
412 
413 /*
414  * ********************************************************************
415  * Releases the tree lock.  Note that if uvm_vslock() was called when
416  * the lock was taken, we release that memory now.  By keeping track
417  * of where and how much by ourselves, the lock can be released much
418  * more easily from anywhere.
419  * ********************************************************************
420  */
421 void
422 sysctl_unlock(struct lwp *l)
423 {
424 
425 	if (l != NULL && sysctl_memsize != 0) {
426 		uvm_vsunlock(l->l_proc, sysctl_memaddr, sysctl_memsize);
427 		sysctl_memsize = 0;
428 	}
429 
430 	(void) lockmgr(&sysctl_treelock, LK_RELEASE, NULL);
431 }
432 
433 /*
434  * ********************************************************************
435  * Section 2: The main tree interfaces
436  * ********************************************************************
437  * This is how sysctl_dispatch() does its work, and you can too, by
438  * calling these routines from helpers (though typically only
439  * sysctl_lookup() will be used).  The tree MUST BE LOCKED when these
440  * are called.
441  * ********************************************************************
442  */
443 
444 /*
445  * sysctl_locate -- Finds the node matching the given mib under the
446  * given tree (via rv).  If no tree is given, we fall back to the
447  * native tree.  The current process (via l) is used for access
448  * control on the tree (some nodes may be traversable only by root) and
449  * on return, nip will show how many numbers in the mib were consumed.
450  */
451 int
452 sysctl_locate(struct lwp *l, const int *name, u_int namelen,
453 	      struct sysctlnode **rnode, int *nip)
454 {
455 	struct sysctlnode *node, *pnode;
456 	int tn, si, ni, error, alias;
457 
458 	/*
459 	 * basic checks and setup
460 	 */
461 	if (*rnode == NULL)
462 		*rnode = &sysctl_root;
463 	if (nip)
464 		*nip = 0;
465 	if (namelen < 0)
466 		return (EINVAL);
467 	if (namelen == 0)
468 		return (0);
469 
470 	/*
471 	 * search starts from "root"
472 	 */
473 	pnode = *rnode;
474 	node = pnode->sysctl_child;
475 	error = 0;
476 
477 	/*
478 	 * scan for node to which new node should be attached
479 	 */
480 	for (ni = 0; ni < namelen; ni++) {
481 		/*
482 		 * walked off bottom of tree
483 		 */
484 		if (node == NULL) {
485 			if (SYSCTL_TYPE(pnode->sysctl_flags) == CTLTYPE_NODE)
486 				error = ENOENT;
487 			else
488 				error = ENOTDIR;
489 			break;
490 		}
491 		/*
492 		 * can anyone traverse this node or only root?
493 		 */
494 		if (l != NULL && (pnode->sysctl_flags & SYSCTL_PRIVATE) &&
495 		    (error = suser(l->l_proc->p_ucred, &l->l_proc->p_acflag))
496 		    != 0)
497 			return (error);
498 		/*
499 		 * find a child node with the right number
500 		 */
501 		tn = name[ni];
502 		alias = 0;
503 		for (si = 0; si < pnode->sysctl_clen; si++) {
504 			if (node[si].sysctl_num == tn ||
505 			    (tn >= 0 &&
506 			     node[si].sysctl_flags & SYSCTL_ANYNUMBER)) {
507 				if (node[si].sysctl_flags & SYSCTL_ALIAS) {
508 					if (alias++ == 4)
509 						si = pnode->sysctl_clen - 1;
510 					else {
511 						tn = node[si].sysctl_alias;
512 						si = -1;
513 					}
514 				}
515 				else
516 					break;
517 			}
518 		}
519 		/*
520 		 * if we ran off the end, it obviously doesn't exist
521 		 */
522 		if (si == pnode->sysctl_clen) {
523 			error = ENOENT;
524 			break;
525 		}
526 		/*
527 		 * so far so good, move on down the line
528 		 */
529 		pnode = &node[si];
530 		if (SYSCTL_TYPE(pnode->sysctl_flags) == CTLTYPE_NODE)
531 			node = node[si].sysctl_child;
532 		else
533 			node = NULL;
534 	}
535 
536 	*rnode = pnode;
537 	if (nip)
538 		*nip = ni;
539 
540 	return (error);
541 }
542 
543 /*
544  * sysctl_query -- The auto-discovery engine.  Copies out the
545  * descriptions on nodes under the given node and handles overlay
546  * trees.
547  */
548 int
549 sysctl_query(SYSCTLFN_ARGS)
550 {
551 	int error, ni, elim;
552 	size_t out, left, t;
553 	struct sysctlnode *enode, *onode;
554 
555 	if (newp != NULL)
556 		return (EPERM);
557 	if (SYSCTL_TYPE(rnode->sysctl_flags) != CTLTYPE_NODE)
558 		return (ENOTDIR);
559 	if (namelen != 1 || name[0] != CTL_QUERY)
560 		return (EINVAL);
561 
562 	error = 0;
563 	out = 0;
564 	left = *oldlenp;
565 	elim = 0;
566 	enode = NULL;
567 
568 	/*
569 	 * process has overlay tree
570 	 */
571 	if (l && l->l_proc->p_emul->e_sysctlovly) {
572 		enode = (void*)l->l_proc->p_emul->e_sysctlovly;
573 		elim = (name - oname);
574 		error = sysctl_locate(l, oname, elim, &enode, NULL);
575 		if (error == 0) {
576 			/* ah, found parent in overlay */
577 			elim = enode->sysctl_clen;
578 			enode = enode->sysctl_child;
579 		}
580 		else {
581 			error = 0;
582 			elim = 0;
583 			enode = NULL;
584 		}
585 	}
586 
587 	for (ni = 0; ni < rnode->sysctl_clen; ni++) {
588 		t = MIN(left, sizeof(struct sysctlnode));
589 		onode = &rnode->sysctl_child[ni];
590 		if (enode && enode->sysctl_num == onode->sysctl_num) {
591 			if (SYSCTL_TYPE(enode->sysctl_flags) !=
592 			    CTLTYPE_NODE)
593 				onode = enode;
594 			if (--elim > 0)
595 				enode++;
596 			else
597 				enode = NULL;
598 		}
599 		if (oldp != NULL && t > 0)
600 			error = sysctl_copyout(l, onode, (char*)oldp + out, t);
601 		if (error)
602 			return (error);
603 		out += sizeof(struct sysctlnode);
604 		left -= t;
605 	}
606 
607 	/*
608 	 * overlay trees *MUST* be entirely consumed
609 	 */
610 	KASSERT(enode == NULL);
611 
612 	*oldlenp = out;
613 
614 	return (error);
615 }
616 
617 #ifdef SYSCTL_DEBUG_CREATE
618 #undef sysctl_create
619 #endif /* SYSCTL_DEBUG_CREATE */
620 
621 /*
622  * sysctl_create -- Adds a node (the description of which is taken
623  * from newp) to the tree, returning a copy of it in the space pointed
624  * to by oldp.  In the event that the requested slot is already taken
625  * (either by name or by number), the offending node is returned
626  * instead.  Yes, this is complex, but we want to make sure everything
627  * is proper.
628  */
629 int
630 sysctl_create(SYSCTLFN_RWARGS)
631 {
632 	struct sysctlnode nnode, *node, *pnode;
633 	int error, ni, at, nm, type, sz, flags, rw, anum;
634 	void *own;
635 
636 	error = 0;
637 	own = NULL;
638 	anum = -1;
639 
640 	if (namelen != 1 || (name[namelen - 1] != CTL_CREATE
641 #if NKSYMS > 0
642 			     && name[namelen - 1] != CTL_CREATESYM
643 #endif /* NKSYMS > 0 */
644 			     ))
645 		return (EINVAL);
646 
647 	/*
648 	 * processes can only add nodes at securelevel 0, must be
649 	 * root, and can't add nodes to a parent that's not writeable
650 	 */
651 	if (l != NULL) {
652 #ifndef SYSCTL_DISALLOW_CREATE
653 		if (securelevel > 0)
654 			return (EPERM);
655 		error = suser(l->l_proc->p_ucred, &l->l_proc->p_acflag);
656 		if (error)
657 			return (error);
658 		if (!(rnode->sysctl_flags & SYSCTL_READWRITE))
659 #endif /* SYSCTL_DISALLOW_CREATE */
660 			return (EPERM);
661 	}
662 
663 	/*
664 	 * nothing can add a node if:
665 	 * we've finished initial set up and
666 	 * the tree itself is not writeable or
667 	 * the entire sysctl system is not writeable
668 	 */
669 	if ((sysctl_root.sysctl_flags & SYSCTL_PERMANENT) &&
670 	    (!(sysctl_rootof(rnode)->sysctl_flags & SYSCTL_READWRITE) ||
671 	     !(sysctl_root.sysctl_flags & SYSCTL_READWRITE)))
672 		return (EPERM);
673 
674 	/*
675 	 * it must be a "node", not a "int" or something
676 	 */
677 	if (SYSCTL_TYPE(rnode->sysctl_flags) != CTLTYPE_NODE)
678 		return (ENOTDIR);
679 	pnode = rnode;
680 
681 	if (newp == NULL || newlen != sizeof(struct sysctlnode))
682 		return (EINVAL);
683 	error = sysctl_copyin(l, newp, &nnode, sizeof(struct sysctlnode));
684 	if (error)
685 		return (error);
686 
687 	/*
688 	 * nodes passed in don't *have* parents
689 	 */
690 	if (nnode.sysctl_parent != NULL)
691 		return (EINVAL);
692 
693 	/*
694 	 * if we are indeed adding it, it should be a "good" name and
695 	 * number
696 	 */
697 	nm = nnode.sysctl_num;
698 #if NKSYMS > 0
699 	if (nm == CTL_CREATESYM)
700 		nm = CTL_CREATE;
701 #endif /* NKSYMS > 0 */
702 	if (nm < 0 && nm != CTL_CREATE)
703 		return (EINVAL);
704 	sz = 0;
705 
706 	/*
707 	 * the name can't start with a digit
708 	 */
709 	if (nnode.sysctl_name[sz] >= '0' &&
710 	    nnode.sysctl_name[sz] <= '9')
711 		return (EINVAL);
712 
713 	/*
714 	 * the name must be only alphanumerics or - or _, longer than
715 	 * 0 bytes and less that SYSCTL_NAMELEN
716 	 */
717 	while (sz < SYSCTL_NAMELEN && nnode.sysctl_name[sz] != '\0') {
718 		if ((nnode.sysctl_name[sz] >= '0' &&
719 		     nnode.sysctl_name[sz] <= '9') ||
720 		    (nnode.sysctl_name[sz] >= 'A' &&
721 		     nnode.sysctl_name[sz] <= 'Z') ||
722 		    (nnode.sysctl_name[sz] >= 'a' &&
723 		     nnode.sysctl_name[sz] <= 'z') ||
724 		    nnode.sysctl_name[sz] == '-' ||
725 		    nnode.sysctl_name[sz] == '_')
726 			sz++;
727 		else
728 			return (EINVAL);
729 	}
730 	if (sz == 0 || sz == SYSCTL_NAMELEN)
731 		return (EINVAL);
732 
733 	/*
734 	 * various checks revolve around size vs type, etc
735 	 */
736 	type = SYSCTL_TYPE(nnode.sysctl_flags);
737 	flags = SYSCTL_FLAGS(nnode.sysctl_flags);
738 	rw = (flags & SYSCTL_READWRITE) ? B_WRITE : B_READ;
739 	sz = nnode.sysctl_size;
740 
741 	/*
742 	 * find out if there's a collision, and if so, let the caller
743 	 * know what they collided with
744 	 */
745 	node = pnode->sysctl_child;
746 	if (((flags & SYSCTL_ANYNUMBER) && node) ||
747 	    (node && node->sysctl_flags & SYSCTL_ANYNUMBER))
748 		return (EINVAL);
749 	for (ni = at = 0; ni < pnode->sysctl_clen; ni++) {
750 		if (nm == node[ni].sysctl_num ||
751 		    strcmp(nnode.sysctl_name, node[ni].sysctl_name) == 0) {
752 			if (oldp != NULL) {
753 				/*
754 				 * ignore error here, since we
755 				 * are already fixed on EEXIST
756 				 */
757 				(void)sysctl_copyout(l, &node[ni], oldp,
758 				     MIN(*oldlenp, sizeof(struct sysctlnode)));
759 			}
760 			*oldlenp = sizeof(struct sysctlnode);
761 			return (EEXIST);
762 		}
763 		if (nm > node[ni].sysctl_num)
764 			at++;
765 	}
766 
767 	/*
768 	 * use sysctl_ver to add to the tree iff it hasn't changed
769 	 */
770 	if (nnode.sysctl_ver != 0) {
771 		/*
772 		 * a specified value must match either the parent
773 		 * node's version or the root node's version
774 		 */
775 		if (nnode.sysctl_ver != sysctl_rootof(rnode)->sysctl_ver &&
776 		    nnode.sysctl_ver != rnode->sysctl_ver) {
777 			return (EINVAL);
778 		}
779 	}
780 
781 	/*
782 	 * only the kernel can assign functions to entries
783 	 */
784 	if (l != NULL && nnode.sysctl_func != NULL)
785 		return (EPERM);
786 
787 	/*
788 	 * only the kernel can create permanent entries, and only then
789 	 * before the kernel is finished setting itself up
790 	 */
791 	if (l != NULL && (flags & ~SYSCTL_USERFLAGS))
792 		return (EPERM);
793 	if ((flags & SYSCTL_PERMANENT) &
794 	    (sysctl_root.sysctl_flags & SYSCTL_PERMANENT))
795 		return (EPERM);
796 	if ((flags & (SYSCTL_OWNDATA | SYSCTL_IMMEDIATE)) ==
797 	    (SYSCTL_OWNDATA | SYSCTL_IMMEDIATE))
798 		return (EINVAL);
799 	if ((flags & SYSCTL_IMMEDIATE) &&
800 	    type != CTLTYPE_INT && type != CTLTYPE_QUAD)
801 		return (EINVAL);
802 
803 	/*
804 	 * check size, or set it if unset and we can figure it out.
805 	 * kernel created nodes are allowed to have a function instead
806 	 * of a size (or a data pointer).
807 	 */
808 	switch (type) {
809 	case CTLTYPE_NODE:
810 		/*
811 		 * only *i* can assert the size of a node
812 		 */
813 		if (flags & SYSCTL_ALIAS) {
814 			anum = nnode.sysctl_alias;
815 			if (anum < 0)
816 				return (EINVAL);
817 			nnode.sysctl_alias = 0;
818 		}
819 		if (sz != 0 || nnode.sysctl_data != NULL)
820 			return (EINVAL);
821 		if (nnode.sysctl_csize != 0 ||
822 		    nnode.sysctl_clen != 0 ||
823 		    nnode.sysctl_child != 0)
824 			return (EINVAL);
825 		if (flags & SYSCTL_OWNDATA)
826 			return (EINVAL);
827 		sz = sizeof(struct sysctlnode);
828 		break;
829 	case CTLTYPE_INT:
830 		/*
831 		 * since an int is an int, if the size is not given or
832 		 * is wrong, we can "int-uit" it.
833 		 */
834 		if (sz != 0 && sz != sizeof(int))
835 			return (EINVAL);
836 		sz = sizeof(int);
837 		break;
838 	case CTLTYPE_STRING:
839 		/*
840 		 * strings are a little more tricky
841 		 */
842 		if (sz == 0) {
843 			if (l == NULL) {
844 				if (nnode.sysctl_func == NULL) {
845 					if (nnode.sysctl_data == NULL)
846 						return (EINVAL);
847 					else
848 						sz = strlen(nnode.sysctl_data) +
849 						    1;
850 				}
851 			}
852 			else if (nnode.sysctl_data == NULL &&
853 				 flags & SYSCTL_OWNDATA) {
854 				return (EINVAL);
855 			}
856 			else {
857 				char v[PAGE_SIZE], *e;
858 				size_t s;
859 
860 				/*
861 				 * we want a rough idea of what the
862 				 * size is now
863 				 */
864 				e = nnode.sysctl_data;
865 				do {
866 					error = copystr(e, &v[0], sizeof(v),
867 							&s);
868 					if (error) {
869 						if (error != ENAMETOOLONG)
870 							return (error);
871 						e += PAGE_SIZE;
872 						if ((e - 32 * PAGE_SIZE) >
873 						    (char*)nnode.sysctl_data)
874 							return (ERANGE);
875 					}
876 				} while (error != 0);
877 				sz = s + (e - (char*)nnode.sysctl_data);
878 			}
879 		}
880 		break;
881 	case CTLTYPE_QUAD:
882 		if (sz != 0 && sz != sizeof(u_quad_t))
883 			return (EINVAL);
884 		sz = sizeof(u_quad_t);
885 		break;
886 	case CTLTYPE_STRUCT:
887 		if (sz == 0) {
888 			if (l != NULL || nnode.sysctl_func == NULL)
889 				return (EINVAL);
890 			if (flags & SYSCTL_OWNDATA)
891 				return (EINVAL);
892 		}
893 		break;
894 	default:
895 		return (EINVAL);
896 	}
897 
898 	/*
899 	 * at this point, if sz is zero, we *must* have a
900 	 * function to go with it and we can't own it.
901 	 */
902 
903 	/*
904 	 *  l  ptr own
905 	 *  0   0   0  -> EINVAL (if no func)
906 	 *  0   0   1  -> own
907 	 *  0   1   0  -> kptr
908 	 *  0   1   1  -> kptr
909 	 *  1   0   0  -> EINVAL
910 	 *  1   0   1  -> own
911 	 *  1   1   0  -> kptr, no own (fault on lookup)
912 	 *  1   1   1  -> uptr, own
913 	 */
914 	if (type != CTLTYPE_NODE) {
915 		if (sz != 0) {
916 			if (flags & SYSCTL_OWNDATA) {
917 				own = malloc(sz, M_SYSCTLDATA,
918 					     M_WAITOK|M_CANFAIL);
919 				if (nnode.sysctl_data == NULL)
920 					memset(own, 0, sz);
921 				else {
922 					error = sysctl_copyin(l,
923 					    nnode.sysctl_data, own, sz);
924 					if (error != 0) {
925 						FREE(own, M_SYSCTLDATA);
926 						return (error);
927 					}
928 				}
929 			}
930 			else if ((nnode.sysctl_data != NULL) &&
931 				 !(flags & SYSCTL_IMMEDIATE)) {
932 #if NKSYMS > 0
933 				if (name[namelen - 1] == CTL_CREATESYM) {
934 					char symname[128]; /* XXX enough? */
935 					u_long symaddr;
936 					size_t symlen;
937 
938 					error = sysctl_copyinstr(l,
939 					    nnode.sysctl_data, symname,
940 					    sizeof(symname), &symlen);
941 					if (error)
942 						return (error);
943 					error = ksyms_getval_from_kernel(NULL,
944 					    symname, &symaddr, KSYMS_EXTERN);
945 					if (error)
946 						return (error); /* EINVAL? */
947 					nnode.sysctl_data = (void*)symaddr;
948 				}
949 #endif /* NKSYMS > 0 */
950 				/*
951 				 * Ideally, we'd like to verify here
952 				 * that this address is acceptable,
953 				 * but...
954 				 *
955 				 * - it might be valid now, only to
956 				 *   become invalid later
957 				 *
958 				 * - it might be invalid only for the
959 				 *   moment and valid later
960 				 *
961 				 * - or something else.
962 				 *
963 				 * Since we can't get a good answer,
964 				 * we'll just accept the address as
965 				 * given, and fault on individual
966 				 * lookups.
967 				 */
968 			}
969 		}
970 		else if (nnode.sysctl_func == NULL)
971 			return (EINVAL);
972 	}
973 
974 	/*
975 	 * a process can't assign a function to a node, and the kernel
976 	 * can't create a node that has no function or data.
977 	 * (XXX somewhat redundant check)
978 	 */
979 	if (l != NULL || nnode.sysctl_func == NULL) {
980 		if (type != CTLTYPE_NODE &&
981 		    nnode.sysctl_data == NULL &&
982 		    !(flags & SYSCTL_IMMEDIATE) &&
983 		    own == NULL)
984 			return (EINVAL);
985 	}
986 
987 #ifdef SYSCTL_DISALLOW_KWRITE
988 	/*
989 	 * a process can't create a writable node unless it refers to
990 	 * new data.
991 	 */
992 	if (l != NULL && own == NULL && type != CTLTYPE_NODE &&
993 	    (flags & SYSCTL_READWRITE) != SYSCTL_READONLY &&
994 	    !(flags & SYSCTL_IMMEDIATE))
995 		return (EPERM);
996 #endif /* SYSCTL_DISALLOW_KWRITE */
997 
998 	/*
999 	 * make sure there's somewhere to put the new stuff.
1000 	 */
1001 	if (pnode->sysctl_child == NULL) {
1002 		if (flags & SYSCTL_ANYNUMBER)
1003 			error = sysctl_alloc(pnode, 1);
1004 		else
1005 			error = sysctl_alloc(pnode, 0);
1006 		if (error)
1007 			return (error);
1008 	}
1009 	node = pnode->sysctl_child;
1010 
1011 	/*
1012 	 * no collisions, so pick a good dynamic number if we need to.
1013 	 */
1014 	if (nm == CTL_CREATE) {
1015 		nm = ++sysctl_root.sysctl_num;
1016 		for (ni = 0; ni < pnode->sysctl_clen; ni++) {
1017 			if (nm == node[ni].sysctl_num) {
1018 				nm++;
1019 				ni = -1;
1020 			}
1021 			else if (nm > node[ni].sysctl_num)
1022 				at = ni + 1;
1023 		}
1024 	}
1025 
1026 	/*
1027 	 * oops...ran out of space
1028 	 */
1029 	if (pnode->sysctl_clen == pnode->sysctl_csize) {
1030 		error = sysctl_realloc(pnode);
1031 		if (error)
1032 			return (error);
1033 		node = pnode->sysctl_child;
1034 	}
1035 
1036 	/*
1037 	 * insert new node data
1038 	 */
1039 	if (at < pnode->sysctl_clen) {
1040 		int t;
1041 
1042 		/*
1043 		 * move the nodes that should come after the new one
1044 		 */
1045 		memmove(&node[at + 1], &node[at],
1046 			(pnode->sysctl_clen - at) * sizeof(struct sysctlnode));
1047 		memset(&node[at], 0, sizeof(struct sysctlnode));
1048 		node[at].sysctl_parent = pnode;
1049 		/*
1050 		 * and...reparent any children of any moved nodes
1051 		 */
1052 		for (ni = at; ni <= pnode->sysctl_clen; ni++)
1053 			if (SYSCTL_TYPE(node[ni].sysctl_flags) == CTLTYPE_NODE)
1054 				for (t = 0; t < node[ni].sysctl_clen; t++)
1055 					node[ni].sysctl_child[t].sysctl_parent =
1056 						&node[ni];
1057 	}
1058 	node = &node[at];
1059 	pnode->sysctl_clen++;
1060 
1061 	strlcpy(node->sysctl_name, nnode.sysctl_name,
1062 		sizeof(node->sysctl_name));
1063 	node->sysctl_num = nm;
1064 	node->sysctl_size = sz;
1065 	node->sysctl_flags = type|flags;
1066 	node->sysctl_csize = 0;
1067 	node->sysctl_clen = 0;
1068 	if (own) {
1069 		node->sysctl_data = own;
1070 		node->sysctl_flags |= SYSCTL_OWNDATA;
1071 	}
1072 	else if (flags & SYSCTL_ALIAS) {
1073 		node->sysctl_alias = anum;
1074 	}
1075 	else if (flags & SYSCTL_IMMEDIATE) {
1076 		switch (type) {
1077 		case CTLTYPE_INT:
1078 			node->sysctl_idata = nnode.sysctl_idata;
1079 			break;
1080 		case CTLTYPE_QUAD:
1081 			node->sysctl_qdata = nnode.sysctl_qdata;
1082 			break;
1083 		}
1084 	}
1085 	else {
1086 		node->sysctl_data = nnode.sysctl_data;
1087 		node->sysctl_flags &= ~SYSCTL_OWNDATA;
1088 	}
1089         node->sysctl_func = nnode.sysctl_func;
1090         node->sysctl_child = NULL;
1091 	/* node->sysctl_parent should already be done */
1092 
1093 	/*
1094 	 * update "version" on path to "root"
1095 	 */
1096 	for (; rnode->sysctl_parent != NULL; rnode = rnode->sysctl_parent)
1097 		;
1098 	pnode = node;
1099 	for (nm = rnode->sysctl_ver + 1; pnode != NULL;
1100 	     pnode = pnode->sysctl_parent)
1101 		pnode->sysctl_ver = nm;
1102 
1103 	if (oldp != NULL)
1104 		error = sysctl_copyout(l, node, oldp,
1105 		    MIN(*oldlenp, sizeof(struct sysctlnode)));
1106 	*oldlenp = sizeof(struct sysctlnode);
1107 
1108 	return (error);
1109 }
1110 
1111 /*
1112  * ********************************************************************
1113  * A wrapper around sysctl_create() that prints the thing we're trying
1114  * to add.
1115  * ********************************************************************
1116  */
1117 #ifdef SYSCTL_DEBUG_CREATE
1118 int _sysctl_create(SYSCTLFN_RWPROTO);
1119 int
1120 _sysctl_create(SYSCTLFN_RWARGS)
1121 {
1122 	const struct sysctlnode *node;
1123 	int k, rc, ni, nl = namelen + (name - oname);
1124 
1125 	node = newp;
1126 
1127 	printf("namelen %d (", nl);
1128 	for (ni = 0; ni < nl - 1; ni++)
1129 		printf(" %d", oname[ni]);
1130 	printf(" %d )\t[%s]\tflags %08x (%08x %d %zu)\n",
1131 	       k = node->sysctl_num,
1132 	       node->sysctl_name,
1133 	       node->sysctl_flags,
1134 	       SYSCTL_FLAGS(node->sysctl_flags),
1135 	       SYSCTL_TYPE(node->sysctl_flags),
1136 	       node->sysctl_size);
1137 
1138 	node = rnode;
1139 	rc = sysctl_create(SYSCTLFN_CALL(rnode));
1140 
1141 	printf("sysctl_create(");
1142 	for (ni = 0; ni < nl - 1; ni++)
1143 		printf(" %d", oname[ni]);
1144 	printf(" %d ) returned %d\n", k, rc);
1145 
1146 	return (rc);
1147 }
1148 #define sysctl_create _sysctl_create
1149 #endif /* SYSCTL_DEBUG_CREATE */
1150 
1151 /*
1152  * sysctl_destroy -- Removes a node (as described by newp) from the
1153  * given tree, returning (if successful) a copy of the dead node in
1154  * oldp.  Since we're removing stuff, there's not much to check.
1155  */
1156 int
1157 sysctl_destroy(SYSCTLFN_RWARGS)
1158 {
1159 	struct sysctlnode *node, *pnode, onode, nnode;
1160 	int ni, error;
1161 
1162 	error = 0;
1163 
1164 	if (namelen != 1 || name[namelen - 1] != CTL_DESTROY)
1165 		return (EINVAL);
1166 
1167 	/*
1168 	 * processes can only destroy nodes at securelevel 0, must be
1169 	 * root, and can't remove nodes from a parent that's not
1170 	 * writeable
1171 	 */
1172 	if (l != NULL) {
1173 #ifndef SYSCTL_DISALLOW_CREATE
1174 		if (securelevel > 0)
1175 			return (EPERM);
1176 		error = suser(l->l_proc->p_ucred, &l->l_proc->p_acflag);
1177 		if (error)
1178 			return (error);
1179 		if (!(rnode->sysctl_flags & SYSCTL_READWRITE))
1180 #endif /* SYSCTL_DISALLOW_CREATE */
1181 			return (EPERM);
1182 	}
1183 
1184 	/*
1185 	 * nothing can remove a node if:
1186 	 * the node is permanent (checked later) or
1187 	 * the tree itself is not writeable or
1188 	 * the entire sysctl system is not writeable
1189 	 */
1190 	if (!(sysctl_rootof(rnode)->sysctl_flags & SYSCTL_READWRITE) ||
1191 	    !(sysctl_root.sysctl_flags & SYSCTL_READWRITE))
1192 		return (EPERM);
1193 
1194 	if (newp == NULL || newlen != sizeof(struct sysctlnode))
1195 		return (EINVAL);
1196 	error = sysctl_copyin(l, newp, &nnode, sizeof(struct sysctlnode));
1197 	if (error)
1198 		return (error);
1199 	memset(&onode, 0, sizeof(struct sysctlnode));
1200 
1201 	node = rnode->sysctl_child;
1202 	for (ni = 0; ni < rnode->sysctl_clen; ni++) {
1203 		if (nnode.sysctl_num == node[ni].sysctl_num) {
1204 			/*
1205 			 * if name specified, must match
1206 			 */
1207 			if (nnode.sysctl_name[0] != '\0' &&
1208 			    strcmp(nnode.sysctl_name, node[ni].sysctl_name))
1209 				continue;
1210 			/*
1211 			 * if version specified, must match
1212 			 */
1213 			if (nnode.sysctl_ver != 0 &&
1214 			    nnode.sysctl_ver != node[ni].sysctl_ver)
1215 				continue;
1216 			/*
1217 			 * this must be the one
1218 			 */
1219 			break;
1220 		}
1221 	}
1222 	if (ni == rnode->sysctl_clen)
1223 		return (ENOENT);
1224 	node = &node[ni];
1225 	pnode = node->sysctl_parent;
1226 
1227 	/*
1228 	 * if the kernel says permanent, it is, so there.  nyah.
1229 	 */
1230 	if (SYSCTL_FLAGS(node->sysctl_flags) & SYSCTL_PERMANENT)
1231 		return (EPERM);
1232 
1233 	/*
1234 	 * can't delete non-empty nodes
1235 	 */
1236 	if (SYSCTL_TYPE(node->sysctl_flags) == CTLTYPE_NODE &&
1237 	    node->sysctl_clen != 0)
1238 		return (ENOTEMPTY);
1239 
1240 	/*
1241 	 * if the node "owns" data, release it now
1242 	 */
1243 	if (node->sysctl_flags & SYSCTL_OWNDATA) {
1244 		if (node->sysctl_data != NULL)
1245 			FREE(node->sysctl_data, M_SYSCTLDATA);
1246 		node->sysctl_data = NULL;
1247 	}
1248 
1249 	/*
1250 	 * if the node to be removed is not the last one on the list,
1251 	 * move the remaining nodes up, and reparent any grandchildren
1252 	 */
1253 	onode = *node;
1254 	if (ni < pnode->sysctl_clen - 1) {
1255 		int t;
1256 
1257 		memmove(&pnode->sysctl_child[ni], &pnode->sysctl_child[ni + 1],
1258 			(pnode->sysctl_clen - ni - 1) *
1259 			sizeof(struct sysctlnode));
1260 		for (; ni < pnode->sysctl_clen - 1; ni++)
1261 			if (SYSCTL_TYPE(pnode->sysctl_child[ni].sysctl_flags) ==
1262 			    CTLTYPE_NODE)
1263 				for (t = 0; t < pnode->sysctl_child[ni].sysctl_clen;
1264 				     t++)
1265 					pnode->sysctl_child[ni].sysctl_child[t].
1266 						sysctl_parent =
1267 						&pnode->sysctl_child[ni];
1268 		ni = pnode->sysctl_clen - 1;
1269 		node = &pnode->sysctl_child[ni];
1270 	}
1271 
1272 	/*
1273 	 * reset the space we just vacated
1274 	 */
1275 	memset(node, 0, sizeof(struct sysctlnode));
1276 	node->sysctl_parent = pnode;
1277 	pnode->sysctl_clen--;
1278 
1279 	/*
1280 	 * if this parent just lost its last child, nuke the creche
1281 	 */
1282 	if (pnode->sysctl_clen == 0) {
1283 		FREE(pnode->sysctl_child, M_SYSCTLNODE);
1284 		pnode->sysctl_csize = 0;
1285 		pnode->sysctl_child = NULL;
1286 	}
1287 
1288 	/*
1289 	 * update "version" on path to "root"
1290 	 */
1291         for (; rnode->sysctl_parent != NULL; rnode = rnode->sysctl_parent)
1292                 ;
1293 	for (ni = rnode->sysctl_ver + 1; pnode != NULL;
1294 	     pnode = pnode->sysctl_parent)
1295 		pnode->sysctl_ver = ni;
1296 
1297 	if (oldp != NULL)
1298 		error = sysctl_copyout(l, &onode, oldp,
1299 		    MIN(*oldlenp, sizeof(struct sysctlnode)));
1300 	*oldlenp = sizeof(struct sysctlnode);
1301 
1302 	return (error);
1303 }
1304 
1305 /*
1306  * sysctl_lookup -- Handles copyin/copyout of new and old values.
1307  * Partial reads are globally allowed.  Only root can write to things
1308  * unless the node says otherwise.
1309  */
1310 int
1311 sysctl_lookup(SYSCTLFN_RWARGS)
1312 {
1313 	int error, rw;
1314 	size_t sz, len;
1315 	void *d;
1316 
1317 	error = 0;
1318 
1319 	/*
1320 	 * you can't "look up" a node.  you can "query" it, but you
1321 	 * can't "look it up".
1322 	 */
1323 	if (SYSCTL_TYPE(rnode->sysctl_flags) == CTLTYPE_NODE || namelen != 0)
1324 		return (EINVAL);
1325 
1326 	/*
1327 	 * some nodes are private, so only root can look into them.
1328 	 */
1329 	if (l != NULL && (rnode->sysctl_flags & SYSCTL_PRIVATE) &&
1330 	    (error = suser(l->l_proc->p_ucred, &l->l_proc->p_acflag)) != 0)
1331 		return (error);
1332 
1333 	/*
1334 	 * if a node wants to be writable according to different rules
1335 	 * other than "only root can write to stuff unless a flag is
1336 	 * set", then it needs its own function which should have been
1337 	 * called and not us.
1338 	 */
1339 	if (l != NULL && newp != NULL &&
1340 	    !(rnode->sysctl_flags & SYSCTL_ANYWRITE) &&
1341 	    (error = suser(l->l_proc->p_ucred, &l->l_proc->p_acflag)) != 0)
1342 		return (error);
1343 
1344 	/*
1345 	 * is this node supposedly writable?
1346 	 */
1347 	rw = 0;
1348 	switch (rnode->sysctl_flags & SYSCTL_READWRITE) {
1349 	    case SYSCTL_READONLY1:
1350 		rw = (securelevel < 1) ? 1 : 0;
1351 		break;
1352 	    case SYSCTL_READONLY2:
1353 		rw = (securelevel < 2) ? 1 : 0;
1354 		break;
1355 	    case SYSCTL_READWRITE:
1356 		rw = 1;
1357 		break;
1358 	}
1359 
1360 	/*
1361 	 * it appears not to be writable at this time, so if someone
1362 	 * tried to write to it, we must tell them to go away
1363 	 */
1364 	if (!rw && newp != NULL)
1365 		return (EPERM);
1366 
1367 	/*
1368 	 * step one, copy out the stuff we have presently
1369 	 */
1370 	if (rnode->sysctl_flags & SYSCTL_IMMEDIATE) {
1371 		switch (SYSCTL_TYPE(rnode->sysctl_flags)) {
1372 		case CTLTYPE_INT:
1373 			d = &rnode->sysctl_idata;
1374 			break;
1375 		case CTLTYPE_QUAD:
1376 			d = &rnode->sysctl_qdata;
1377 			break;
1378 		default:
1379 			return (EINVAL);
1380 		}
1381 	}
1382 	else
1383 		d = rnode->sysctl_data;
1384 	if (SYSCTL_TYPE(rnode->sysctl_flags) == CTLTYPE_STRING)
1385 		sz = strlen(d) + 1; /* XXX@@@ possible fault here */
1386 	else
1387 		sz = rnode->sysctl_size;
1388 	if (oldp != NULL)
1389 		error = sysctl_copyout(l, d, oldp, MIN(sz, *oldlenp));
1390 	if (error)
1391 		return (error);
1392 	*oldlenp = sz;
1393 
1394 	/*
1395 	 * are we done?
1396 	 */
1397 	if (newp == NULL || newlen == 0)
1398 		return (0);
1399 
1400 	/*
1401 	 * hmm...not done.  must now "copy in" new value.  re-adjust
1402 	 * sz to maximum value (strings are "weird").
1403 	 */
1404 	sz = rnode->sysctl_size;
1405 	switch (SYSCTL_TYPE(rnode->sysctl_flags)) {
1406 	case CTLTYPE_INT:
1407 	case CTLTYPE_QUAD:
1408 	case CTLTYPE_STRUCT:
1409 		/*
1410 		 * these data must be *exactly* the same size coming
1411 		 * in.
1412 		 */
1413 		if (newlen != sz)
1414 			return (EINVAL);
1415 		error = sysctl_copyin(l, newp, d, sz);
1416 		break;
1417 	case CTLTYPE_STRING: {
1418 		/*
1419 		 * strings, on the other hand, can be shorter, and we
1420 		 * let userland be sloppy about the trailing nul.
1421 		 */
1422 		char *newbuf;
1423 
1424 		/*
1425 		 * too much new string?
1426 		 */
1427 		if (newlen > sz)
1428 			return (EINVAL);
1429 
1430 		/*
1431 		 * temporary copy of new inbound string
1432 		 */
1433 		len = MIN(sz, newlen);
1434 		newbuf = malloc(len, M_SYSCTLDATA, M_WAITOK|M_CANFAIL);
1435 		if (newbuf == NULL)
1436 			return (ENOMEM);
1437 		error = sysctl_copyin(l, newp, newbuf, len);
1438 		if (error) {
1439 			FREE(newbuf, M_SYSCTLDATA);
1440 			return (error);
1441 		}
1442 
1443 		/*
1444 		 * did they null terminate it, or do we have space
1445 		 * left to do it ourselves?
1446 		 */
1447 		if (newbuf[len - 1] != '\0' && len == sz) {
1448 			FREE(newbuf, M_SYSCTLDATA);
1449 			return (EINVAL);
1450 		}
1451 
1452 		/*
1453 		 * looks good, so pop it into place and zero the rest.
1454 		 */
1455 		if (len > 0)
1456 			memcpy(rnode->sysctl_data, newbuf, len);
1457 		if (sz != len)
1458 			memset((char*)rnode->sysctl_data + len, 0, sz - len);
1459 		FREE(newbuf, M_SYSCTLDATA);
1460 		break;
1461 	}
1462 	default:
1463 		return (EINVAL);
1464 	}
1465 
1466 	return (error);
1467 }
1468 
1469 /*
1470  * sysctl_mmap -- Dispatches sysctl mmap requests to those nodes that
1471  * purport to handle it.  This interface isn't fully fleshed out yet,
1472  * unfortunately.
1473  */
1474 static int
1475 sysctl_mmap(SYSCTLFN_RWARGS)
1476 {
1477 	struct sysctlnode nnode, *node;
1478 	int error;
1479 
1480 	/*
1481 	 * let's just pretend that didn't happen, m'kay?
1482 	 */
1483 	if (l == NULL)
1484 		return (EPERM);
1485 
1486 	/*
1487 	 * is this a sysctlnode description of an mmap request?
1488 	 */
1489 	if (newp == NULL || newlen != sizeof(struct sysctlnode))
1490 		return (EINVAL);
1491 	error = sysctl_copyin(l, newp, &nnode, sizeof(struct sysctlnode));
1492 	if (error)
1493 		return (error);
1494 
1495 	/*
1496 	 * does the node they asked for exist?
1497 	 */
1498 	if (namelen != 1)
1499 		return (EOPNOTSUPP);
1500 	node = rnode;
1501         error = sysctl_locate(l, &nnode.sysctl_num, 1, &node, NULL);
1502 	if (error)
1503 		return (error);
1504 
1505 	/*
1506 	 * does this node that we have found purport to handle mmap?
1507 	 */
1508 	if (node->sysctl_func == NULL ||
1509 	    !(node->sysctl_flags & SYSCTL_MMAP))
1510 		return (EOPNOTSUPP);
1511 
1512 	/*
1513 	 * well...okay, they asked for it.
1514 	 */
1515 	return ((*node->sysctl_func)(SYSCTLFN_CALL(node)));
1516 }
1517 
1518 /*
1519  * ********************************************************************
1520  * Section 3: Create and destroy from inside the kernel
1521  * ********************************************************************
1522  * sysctl_createv() and sysctl_destroyv() are simpler-to-use
1523  * interfaces for the kernel to fling new entries into the mib and rip
1524  * them out later.  In the case of sysctl_createv(), the returned copy
1525  * of the node (see sysctl_create()) will be translated back into a
1526  * pointer to the actual node.
1527  *
1528  * Note that sysctl_createv() will return 0 if the create request
1529  * matches an existing node (ala mkdir -p), and that sysctl_destroyv()
1530  * will return 0 if the node to be destroyed already does not exist
1531  * (aka rm -f) or if it is a parent of other nodes.
1532  *
1533  * This allows two (or more) different subsystems to assert sub-tree
1534  * existence before populating their own nodes, and to remove their
1535  * own nodes without orphaning the others when they are done.
1536  * ********************************************************************
1537  */
1538 int
1539 sysctl_createv(int flags, int type,
1540 	       const char *namep, struct sysctlnode **rnode,
1541 	       sysctlfn func, u_quad_t qv, void *newp, size_t newlen,
1542 	       ...)
1543 {
1544 	va_list ap;
1545 	int error, ni, namelen, name[CTL_MAXNAME];
1546 	struct sysctlnode *pnode, nnode, onode;
1547 	size_t sz;
1548 
1549 	/*
1550 	 * what is it?
1551 	 */
1552 	flags = SYSCTL_TYPE(type)|SYSCTL_FLAGS(flags);
1553 
1554 	/*
1555 	 * where do we put it?
1556 	 */
1557 	va_start(ap, newlen);
1558 	namelen = 0;
1559 	ni = -1;
1560 	do {
1561 		if (++ni == CTL_MAXNAME)
1562 			return (ENAMETOOLONG);
1563 		name[ni] = va_arg(ap, int);
1564 		/*
1565 		 * sorry, this is not supported from here
1566 		 */
1567 		if (name[ni] == CTL_CREATESYM)
1568 			return (EINVAL);
1569 	} while (name[ni] != CTL_EOL && name[ni] != CTL_CREATE);
1570 	namelen = ni + (name[ni] == CTL_CREATE ? 1 : 0);
1571 	va_end(ap);
1572 
1573 	/*
1574 	 * what's it called
1575 	 */
1576 	if (strlcpy(nnode.sysctl_name, namep, sizeof(nnode.sysctl_name)) >
1577 	    sizeof(nnode.sysctl_name))
1578 		return (ENAMETOOLONG);
1579 
1580 	/*
1581 	 * cons up the description of the new node
1582 	 */
1583 	nnode.sysctl_num = name[namelen - 1];
1584 	name[namelen - 1] = CTL_CREATE;
1585 	nnode.sysctl_size = newlen;
1586 	nnode.sysctl_flags = flags;
1587 	if (type == CTLTYPE_NODE) {
1588 		nnode.sysctl_csize = 0;
1589 		nnode.sysctl_clen = 0;
1590 		nnode.sysctl_child = NULL;
1591 		if (flags & SYSCTL_ALIAS)
1592 			nnode.sysctl_alias = qv;
1593 	}
1594 	else if (flags & SYSCTL_IMMEDIATE) {
1595 		switch (type) {
1596 		case CTLTYPE_INT:
1597 			nnode.sysctl_idata = qv;
1598 			break;
1599 		case CTLTYPE_QUAD:
1600 			nnode.sysctl_qdata = qv;
1601 			break;
1602 		default:
1603 			return (EINVAL);
1604 		}
1605 	}
1606 	else {
1607 		nnode.sysctl_data = newp;
1608 	}
1609 	nnode.sysctl_func = func;
1610 	nnode.sysctl_parent = NULL;
1611 	nnode.sysctl_ver = 0;
1612 
1613 	/*
1614 	 * initialize lock state -- we need locks if the main tree has
1615 	 * been marked as complete, but since we could be called from
1616 	 * either there, or from a device driver (say, at device
1617 	 * insertion), or from an lkm (at lkm load time, say), we
1618 	 * don't really want to "wait"...
1619 	 */
1620 	error = sysctl_lock(NULL, NULL, 0);
1621 	if (error)
1622 		return (error);
1623 
1624 	/*
1625 	 * locate the prospective parent of the new node, and if we
1626 	 * find it, add the new node.
1627 	 */
1628 	sz = sizeof(onode);
1629 	pnode = (rnode != NULL) ? *rnode : NULL;
1630 	error = sysctl_locate(NULL, &name[0], namelen - 1, &pnode, &ni);
1631 	if (error == 0)
1632 		error = sysctl_create(&name[ni], namelen - ni, &onode, &sz,
1633 				      &nnode, sizeof(nnode), &name[0], NULL,
1634 				      pnode);
1635 
1636 	/*
1637 	 * unfortunately the node we wanted to create is already
1638 	 * there.  if the node that's already there is a reasonable
1639 	 * facsimile of the node we wanted to create, just pretend
1640 	 * (for the caller's benefit) that we managed to create the
1641 	 * node they wanted.
1642 	 */
1643 	if (error == EEXIST) {
1644 		/* name is the same as requested... */
1645 		if (strcmp(nnode.sysctl_name, onode.sysctl_name) == 0 &&
1646 		    /* they want the same function... */
1647 		    nnode.sysctl_func == onode.sysctl_func &&
1648 		    /* number is the same as requested, or... */
1649 		    (nnode.sysctl_num == onode.sysctl_num ||
1650 		     /* they didn't pick a number... */
1651 		     nnode.sysctl_num == CTL_CREATE)) {
1652 			/*
1653 			 * collision here from trying to create
1654 			 * something that already existed; let's give
1655 			 * our customers a hand and tell them they got
1656 			 * what they wanted.
1657 			 */
1658 #ifdef SYSCTL_DEBUG_CREATE
1659 			printf("cleared\n");
1660 #endif /* SYSCTL_DEBUG_CREATE */
1661 			error = 0;
1662 		}
1663 	}
1664 
1665 	/*
1666 	 * if they want to know where the new node is, go find the
1667 	 * address of the actual node, not the copy that
1668 	 * sysctl_create() gave us.
1669 	 */
1670 	if (rnode != NULL && error == 0) {
1671 		/*
1672 		 * sysctl_create() gave us back a copy of the node,
1673 		 * but we need to know where it actually is...
1674 		 */
1675 		name[namelen - 1] = onode.sysctl_num;
1676 		pnode = *rnode;
1677 		error = sysctl_locate(NULL, &name[0], namelen, &pnode, &ni);
1678 		/*
1679 		 * not expecting an error here, but...
1680 		 */
1681 		if (error == 0)
1682 			*rnode = pnode;
1683 	}
1684 
1685 	/*
1686 	 * now it should be safe to release the lock state.
1687 	 */
1688 	sysctl_unlock(NULL);
1689 
1690 	if (error != 0) {
1691 		printf("sysctl_createv: sysctl_create(%s) returned %d\n",
1692 		       nnode.sysctl_name, error);
1693 #if 0
1694 		if (error != ENOENT)
1695 			sysctl_dump(&onode);
1696 #endif
1697 	}
1698 
1699 	return (error);
1700 }
1701 
1702 int
1703 sysctl_destroyv(struct sysctlnode *rnode, ...)
1704 {
1705 	va_list ap;
1706 	int error, name[CTL_MAXNAME], namelen, ni;
1707 	struct sysctlnode *pnode, *node, dnode;
1708 	size_t sz;
1709 
1710 	va_start(ap, rnode);
1711 	namelen = 0;
1712 	ni = 0;
1713 	do {
1714 		if (ni == CTL_MAXNAME)
1715 			return (ENAMETOOLONG);
1716 		name[ni] = va_arg(ap, int);
1717 	} while (name[ni++] != CTL_EOL);
1718 	namelen = ni - 1;
1719 	va_end(ap);
1720 
1721 	/*
1722 	 * i can't imagine why we'd be destroying a node when the tree
1723 	 * wasn't complete, but who knows?
1724 	 */
1725 	error = sysctl_lock(NULL, NULL, 0);
1726 	if (error)
1727 		return (error);
1728 
1729 	/*
1730 	 * where is it?
1731 	 */
1732 	node = rnode;
1733         error = sysctl_locate(NULL, &name[0], namelen, &node, &ni);
1734 	if (error) {
1735 		/* they want it gone and it's not there, so... */
1736 		sysctl_unlock(NULL);
1737 		return (error == ENOENT ? 0 : error);
1738 	}
1739 
1740 	/*
1741 	 * check to see if we crossed an aliased node
1742 	 */
1743 	if (node->sysctl_num != name[namelen - 1]) {
1744 		memset(&dnode, 0, sizeof(dnode));
1745 		dnode.sysctl_num = name[namelen - 1];
1746 		node = &dnode;
1747 	}
1748 
1749 	/*
1750 	 * we found it, now let's nuke it
1751 	 */
1752 	name[namelen - 1] = CTL_DESTROY;
1753 	pnode = node->sysctl_parent;
1754 	sz = 0;
1755 	error = sysctl_destroy(&name[namelen - 1], 1, NULL, &sz,
1756 			       node, sizeof(*node), &name[0], NULL,
1757 			       pnode);
1758 	if (error == ENOTEMPTY)
1759 		/*
1760 		 * think of trying to delete "foo" when "foo.bar"
1761 		 * (which someone else put there) is still in
1762 		 * existence
1763 		 */
1764 		error = 0;
1765 
1766         sysctl_unlock(NULL);
1767 
1768 	return (error);
1769 }
1770 
1771 #if 0
1772 /*
1773  * ********************************************************************
1774  * the dump routine.  i haven't yet decided how (if at all) i'll call
1775  * this from userland when it's in the kernel.
1776  * ********************************************************************
1777  */
1778 static const char *
1779 sf(int f)
1780 {
1781 	static char s[256];
1782 	char *c;
1783 
1784 	s[0] = '\0';
1785 	c = "";
1786 
1787 #define print_flag(_f, _s, _c, _q, _x) \
1788 	if (((_x) && (((_f) & (_x)) == (__CONCAT(SYSCTL_,_q)))) || \
1789 	    (!(_x) && ((_f) & (__CONCAT(SYSCTL_,_q))))) { \
1790 		strlcat((_s), (_c), sizeof(_s)); \
1791 		strlcat((_s), __STRING(_q), sizeof(_s)); \
1792 		(_c) = ","; \
1793 		(_f) &= ~(__CONCAT(SYSCTL_,_q)|(_x)); \
1794 	}
1795 	print_flag(f, s, c, READONLY, SYSCTL_READWRITE);
1796 	print_flag(f, s, c, READONLY1, SYSCTL_READWRITE);
1797 	print_flag(f, s, c, READONLY2, SYSCTL_READWRITE);
1798 	print_flag(f, s, c, READWRITE, SYSCTL_READWRITE);
1799 	print_flag(f, s, c, ANYWRITE, 0);
1800 	print_flag(f, s, c, PRIVATE, 0);
1801 	print_flag(f, s, c, PERMANENT, 0);
1802 	print_flag(f, s, c, OWNDATA, 0);
1803 	print_flag(f, s, c, IMMEDIATE, 0);
1804 	print_flag(f, s, c, HEX, 0);
1805 	print_flag(f, s, c, ROOT, 0);
1806 	print_flag(f, s, c, ANYNUMBER, 0);
1807 	print_flag(f, s, c, HIDDEN, 0);
1808 	print_flag(f, s, c, ALIAS, 0);
1809 #undef print_flag
1810 
1811 	if (f) {
1812 		char foo[9];
1813 		snprintf(foo, sizeof(foo), "%x", f);
1814 		strlcat(s, c, sizeof(s));
1815 		strlcat(s, foo, sizeof(s));
1816 	}
1817 
1818 	return (s);
1819 }
1820 
1821 static const char *
1822 st(int t)
1823 {
1824 
1825 	switch (t) {
1826 	case CTLTYPE_NODE:
1827 		return "NODE";
1828 	case CTLTYPE_INT:
1829 		return "INT";
1830 	case CTLTYPE_STRING:
1831 		return "STRING";
1832 	case CTLTYPE_QUAD:
1833 		return "QUAD";
1834 	case CTLTYPE_STRUCT:
1835 		return "STRUCT";
1836 	}
1837 
1838 	return "???";
1839 }
1840 
1841 void
1842 sysctl_dump(const struct sysctlnode *d)
1843 {
1844 	static char nmib[64], smib[256];
1845 	static int indent;
1846 	struct sysctlnode *n;
1847 	char *np, *sp, tmp[20];
1848 	int i;
1849 
1850 	if (d == NULL)
1851 		return;
1852 
1853 	np = &nmib[strlen(nmib)];
1854 	sp = &smib[strlen(smib)];
1855 
1856 	if (!(d->sysctl_flags & SYSCTL_ROOT)) {
1857 		snprintf(tmp, sizeof(tmp), "%d", d->sysctl_num);
1858 		strcat(nmib, ".");
1859 		strcat(smib, ".");
1860 		strcat(nmib, tmp);
1861 		strcat(smib, d->sysctl_name);
1862 		printf("%s -> %s (%d)\n", &nmib[1], &smib[1],
1863 		       SYSCTL_TYPE(d->sysctl_flags));
1864 	}
1865 
1866 	if (1) {
1867 		printf("%*s%p:\tsysctl_name  [%s]\n", indent, "",
1868 		       d, d->sysctl_name);
1869 		printf("%*s\t\tsysctl_num    %d\n",   indent, "",
1870 		       d->sysctl_num);
1871 		printf("%*s\t\tsysctl_flags  %x (flags=%x<%s> type=%d<%s> "
1872 		       "size=%zu)\n",
1873 		       indent, "", d->sysctl_flags,
1874 		       SYSCTL_FLAGS(d->sysctl_flags),
1875 		       sf(SYSCTL_FLAGS(d->sysctl_flags)),
1876 		       SYSCTL_TYPE(d->sysctl_flags),
1877 		       st(SYSCTL_TYPE(d->sysctl_flags)),
1878 		       d->sysctl_size);
1879 		if (SYSCTL_TYPE(d->sysctl_flags) == CTLTYPE_NODE) {
1880 			printf("%*s\t\tsysctl_csize  %d\n",   indent, "",
1881 			       d->sysctl_csize);
1882 			printf("%*s\t\tsysctl_clen   %d\n",   indent, "",
1883 			       d->sysctl_clen);
1884 			printf("%*s\t\tsysctl_child  %p\n",   indent, "",
1885 			       d->sysctl_child);
1886 		}
1887 		else
1888 			printf("%*s\t\tsysctl_data   %p\n",   indent, "",
1889 			       d->sysctl_data);
1890 		printf("%*s\t\tsysctl_func   %p\n",   indent, "",
1891 		       d->sysctl_func);
1892 		printf("%*s\t\tsysctl_parent %p\n",   indent, "",
1893 		       d->sysctl_parent);
1894 		printf("%*s\t\tsysctl_ver    %d\n",   indent, "",
1895 		       d->sysctl_ver);
1896 	}
1897 
1898 	if (SYSCTL_TYPE(d->sysctl_flags) == CTLTYPE_NODE) {
1899 		indent += 8;
1900 		n = d->sysctl_child;
1901 		for (i = 0; i < d->sysctl_clen; i++) {
1902 			sysctl_dump(&n[i]);
1903 		}
1904 		indent -= 8;
1905 	}
1906 
1907 	np[0] = '\0';
1908 	sp[0] = '\0';
1909 }
1910 #endif /* 0 */
1911 
1912 /*
1913  * ********************************************************************
1914  * Deletes an entire n-ary tree.  Not recommended unless you know why
1915  * you're doing it.  Personally, I don't know why you'd even think
1916  * about it.
1917  * ********************************************************************
1918  */
1919 void
1920 sysctl_free(struct sysctlnode *rnode)
1921 {
1922 	struct sysctlnode *node, *pnode;
1923 
1924 	if (rnode == NULL)
1925 		rnode = &sysctl_root;
1926 	pnode = rnode;
1927 
1928 	node = pnode->sysctl_child;
1929 	do {
1930 		while (node != NULL && pnode->sysctl_csize > 0) {
1931 			while (node <
1932 			       &pnode->sysctl_child[pnode->sysctl_clen] &&
1933 			       (SYSCTL_TYPE(node->sysctl_flags) !=
1934 				CTLTYPE_NODE ||
1935 				node->sysctl_csize == 0)) {
1936 				if (SYSCTL_FLAGS(node->sysctl_flags) &
1937 				    SYSCTL_OWNDATA) {
1938 					if (node->sysctl_data != NULL) {
1939 						FREE(node->sysctl_data,
1940 						     M_SYSCTLDATA);
1941 						node->sysctl_data = NULL;
1942 					}
1943 				}
1944 				node++;
1945 			}
1946 			if (node < &pnode->sysctl_child[pnode->sysctl_clen]) {
1947 				pnode = node;
1948 				node = node->sysctl_child;
1949 			}
1950 			else
1951 				break;
1952 		}
1953 		if (pnode->sysctl_child != NULL)
1954 			FREE(pnode->sysctl_child, M_SYSCTLNODE);
1955 		pnode->sysctl_clen = 0;
1956 		pnode->sysctl_csize = 0;
1957 		pnode->sysctl_child = NULL;
1958 		node = pnode;
1959 		pnode = node->sysctl_parent;
1960 	} while (pnode != NULL && node != rnode);
1961 }
1962 
1963 /*
1964  * ********************************************************************
1965  * old_sysctl -- A routine to bridge old-style internal calls to the
1966  * new infrastructure.
1967  * ********************************************************************
1968  */
1969 int
1970 old_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1971 	   void *newp, size_t newlen, struct lwp *l)
1972 {
1973 	int error;
1974 	size_t savelen = *oldlenp;
1975 
1976 	error = sysctl_lock(l, oldp, savelen);
1977 	if (error)
1978 		return (error);
1979 	error = sysctl_dispatch(name, namelen, oldp, oldlenp,
1980 				newp, newlen, name, l, NULL);
1981 	sysctl_unlock(l);
1982 	if (error == 0 && oldp != NULL && savelen < *oldlenp)
1983 		error = ENOMEM;
1984 
1985 	return (error);
1986 }
1987 
1988 /*
1989  * ********************************************************************
1990  * Section 4: Generic helper routines
1991  * ********************************************************************
1992  * "helper" routines that can do more finely grained access control,
1993  * construct structures from disparate information, create the
1994  * appearance of more nodes and sub-trees, etc.  for example, if
1995  * CTL_PROC wanted a helper function, it could respond to a CTL_QUERY
1996  * with a dynamically created list of nodes that represented the
1997  * currently running processes at that instant.
1998  * ********************************************************************
1999  */
2000 
2001 /*
2002  * first, a few generic helpers that provide:
2003  *
2004  * sysctl_needfunc()		a readonly interface that emits a warning
2005  * sysctl_notavail()		returns EOPNOTSUPP (generic error)
2006  * sysctl_null()		an empty return buffer with no error
2007  */
2008 int
2009 sysctl_needfunc(SYSCTLFN_ARGS)
2010 {
2011 	int error;
2012 
2013 	printf("!!SYSCTL_NEEDFUNC!!\n");
2014 
2015 	if (newp != NULL || namelen != 0)
2016 		return (EOPNOTSUPP);
2017 
2018 	error = 0;
2019 	if (oldp != NULL)
2020 		error = sysctl_copyout(l, rnode->sysctl_data, oldp,
2021 				       MIN(rnode->sysctl_size, *oldlenp));
2022 	*oldlenp = rnode->sysctl_size;
2023 
2024 	return (error);
2025 }
2026 
2027 int
2028 sysctl_notavail(SYSCTLFN_ARGS)
2029 {
2030 
2031 	if (namelen == 1 && name[0] == CTL_QUERY)
2032 		return (sysctl_query(SYSCTLFN_CALL(rnode)));
2033 
2034 	return (EOPNOTSUPP);
2035 }
2036 
2037 int
2038 sysctl_null(SYSCTLFN_ARGS)
2039 {
2040 
2041 	*oldlenp = 0;
2042 
2043 	return (0);
2044 }
2045 
2046 /*
2047  * ********************************************************************
2048  * Section 5: The machinery that makes it all go
2049  * ********************************************************************
2050  * Memory "manglement" routines.  Not much to this, eh?
2051  * ********************************************************************
2052  */
2053 static int
2054 sysctl_alloc(struct sysctlnode *p, int x)
2055 {
2056 	int i;
2057 	struct sysctlnode *n;
2058 
2059 	assert(p->sysctl_child == NULL);
2060 
2061 	if (x == 1)
2062 		MALLOC(n, struct sysctlnode *,
2063 		       sizeof(struct sysctlnode),
2064 		       M_SYSCTLNODE, M_WAITOK|M_CANFAIL);
2065 	else
2066 		MALLOC(n, struct sysctlnode *,
2067 		       SYSCTL_DEFSIZE * sizeof(struct sysctlnode),
2068 		       M_SYSCTLNODE, M_WAITOK|M_CANFAIL);
2069 	if (n == NULL)
2070 		return (ENOMEM);
2071 
2072 	if (x == 1) {
2073 		memset(n, 0, sizeof(struct sysctlnode));
2074 		p->sysctl_csize = 1;
2075 	}
2076 	else {
2077 		memset(n, 0, SYSCTL_DEFSIZE * sizeof(struct sysctlnode));
2078 		p->sysctl_csize = SYSCTL_DEFSIZE;
2079 	}
2080 	p->sysctl_clen = 0;
2081 
2082 	for (i = 0; i < p->sysctl_csize; i++)
2083 		n[i].sysctl_parent = p;
2084 
2085 	p->sysctl_child = n;
2086 	return (0);
2087 }
2088 
2089 static int
2090 sysctl_realloc(struct sysctlnode *p)
2091 {
2092 	int i, j;
2093 	struct sysctlnode *n;
2094 
2095 	assert(p->sysctl_csize == p->sysctl_clen);
2096 
2097 	/*
2098 	 * how many do we have...how many should we make?
2099 	 */
2100 	i = p->sysctl_clen;
2101 	n = malloc(2 * i * sizeof(struct sysctlnode), M_SYSCTLNODE,
2102 		   M_WAITOK|M_CANFAIL);
2103 	if (n == NULL)
2104 		return (ENOMEM);
2105 
2106 	/*
2107 	 * move old children over...initialize new children
2108 	 */
2109 	memcpy(n, p->sysctl_child, i * sizeof(struct sysctlnode));
2110 	memset(&n[i], 0, i * sizeof(struct sysctlnode));
2111 	p->sysctl_csize = 2 * i;
2112 
2113 	/*
2114 	 * reattach moved (and new) children to parent; if a moved
2115 	 * child node has children, reattach the parent pointers of
2116 	 * grandchildren
2117 	 */
2118         for (i = 0; i < p->sysctl_csize; i++) {
2119                 n[i].sysctl_parent = p;
2120 		if (n[i].sysctl_child != NULL) {
2121 			for (j = 0; j < n[i].sysctl_csize; j++)
2122 				n[i].sysctl_child[j].sysctl_parent = &n[i];
2123 		}
2124 	}
2125 
2126 	/*
2127 	 * get out with the old and in with the new
2128 	 */
2129 	FREE(p->sysctl_child, M_SYSCTLNODE);
2130 	p->sysctl_child = n;
2131 
2132 	return (0);
2133 }
2134