xref: /minix3/minix/net/lwip/mibtree.c (revision e4dbab1e5368dc2124168836ba46a7d3ff6414b0)
1 /* LWIP service - mibtree.c - sysctl support for */
2 /*
3  * This file acts as a dispatcher for the net.inet, net.inet6, and minix.lwip
4  * sysctl trees.  It does not cover the other net.* trees; these are taken care
5  * of in other source files.
6  */
7 
8 #include "lwip.h"
9 
10 #include <minix/sysctl.h>
11 
12 #define MAX_PROTO	6	/* maximum # of INET protocols with subtrees */
13 
14 static struct rmib_indir net_inet_indir[MAX_PROTO];
15 static unsigned int net_inet_indir_count = 0;
16 static struct rmib_node net_inet_node =
17     RMIB_SNODE(RMIB_RO, net_inet_indir, "inet", "PF_INET related settings");
18 
19 #ifdef INET6
20 static struct rmib_indir net_inet6_indir[MAX_PROTO];
21 static unsigned int net_inet6_indir_count = 0;
22 static struct rmib_node net_inet6_node =
23     RMIB_SNODE(RMIB_RO, net_inet6_indir, "inet6", "PF_INET6 related settings");
24 #endif /* INET6 */
25 
26 #define MAX_LWIP	4	/* maximum # of miscellaneous LWIP subtrees */
27 
28 static struct rmib_indir minix_lwip_indir[MAX_LWIP];
29 static unsigned int minix_lwip_indir_count = 0;
30 static struct rmib_node minix_lwip_node =
31     RMIB_SNODE(RMIB_RO, minix_lwip_indir, "lwip",
32 	"LWIP service information and settings");
33 
34 /*
35  * Initialize the status module by registering the net.inet, net.inet6, and
36  * minix.lwip trees with the MIB service.  Other modules must have added all
37  * subtrees to those trees through mibtree_register_*() before this point.
38  */
39 void
40 mibtree_init(void)
41 {
42 	const int inet_mib[] = { CTL_NET, PF_INET };
43 #ifdef INET6
44 	const int inet6_mib[] = { CTL_NET, PF_INET6 };
45 #endif /* INET6 */
46 	const int lwip_mib[] = { CTL_MINIX, MINIX_LWIP };
47 	int r;
48 
49 	/*
50 	 * Register the "net.inet", "net.inet6", and "minix.lwip" subtrees with
51 	 * the MIB service.
52 	 *
53 	 * These calls only return local failures.  Remote failures (in the MIB
54 	 * service) are silently ignored.  So, we can safely panic on failure.
55 	 */
56 	if ((r = rmib_register(inet_mib, __arraycount(inet_mib),
57 	    &net_inet_node)) != OK)
58 		panic("unable to register net.inet RMIB tree: %d", r);
59 
60 #ifdef INET6
61 	if ((r = rmib_register(inet6_mib, __arraycount(inet6_mib),
62 	    &net_inet6_node)) != OK)
63 		panic("unable to register net.inet6 RMIB tree: %d", r);
64 #endif /* INET6 */
65 
66 	if ((r = rmib_register(lwip_mib, __arraycount(lwip_mib),
67 	    &minix_lwip_node)) != OK)
68 		panic("unable to register minix.lwip RMIB tree: %d", r);
69 }
70 
71 /*
72  * Add a subtree to the local net.inet or net.inet6 tree.  This function must
73  * only be called *before* mibtree_init(), as the latter will register the
74  * final tree with the MIB service.
75  */
76 void
77 mibtree_register_inet(int domain, int protocol, struct rmib_node * node)
78 {
79 	struct rmib_node *parent;
80 	struct rmib_indir *indir;
81 	unsigned int i, *count;
82 
83 	switch (domain) {
84 	case PF_INET:
85 		parent = &net_inet_node;
86 		indir = net_inet_indir;
87 		count = &net_inet_indir_count;
88 		break;
89 	case PF_INET6:
90 #ifdef INET6
91 		parent = &net_inet6_node;
92 		indir = net_inet6_indir;
93 		count = &net_inet6_indir_count;
94 		break;
95 #else /* !INET6 */
96 		return;
97 #endif /* !INET6 */
98 	default:
99 		panic("invalid domain %d", domain);
100 	}
101 
102 	assert(*count < MAX_PROTO);
103 
104 	/* Insertion sort. */
105 	for (i = 0; i < *count; i++) {
106 		assert(indir[i].rindir_id != (unsigned int)protocol);
107 
108 		if (indir[i].rindir_id > (unsigned int)protocol)
109 			break;
110 	}
111 
112 	if (i < *count)
113 		memmove(&indir[i + 1], &indir[i],
114 		    sizeof(indir[0]) * (*count - i));
115 
116 	indir[i].rindir_id = protocol;
117 	indir[i].rindir_node = node;
118 	parent->rnode_size = ++*count;
119 }
120 
121 /*
122  * Add a miscellaneous subtree to the local minix.lwip tree.  This function
123  * must only be called *before* mibtree_init(), as the latter will register the
124  * final tree with the MIB service.  Note that the given subtrees are numbered
125  * arbitrarily.  We use sparse trees here only to avoid having to declare
126  * external variables, which is a bit of a hack, but with the expected low
127  * number of miscellaneous subtrees there will be no performance penalty.
128  */
129 void
130 mibtree_register_lwip(struct rmib_node * node)
131 {
132 	unsigned int i;
133 
134 	i = minix_lwip_indir_count;
135 
136 	assert(i < __arraycount(minix_lwip_indir));
137 
138 	minix_lwip_indir[i].rindir_id = i;
139 	minix_lwip_indir[i].rindir_node = node;
140 	minix_lwip_node.rnode_size = ++minix_lwip_indir_count;
141 }
142