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