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
mibtree_init(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
mibtree_register_inet(int domain,int protocol,struct rmib_node * node)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
mibtree_register_lwip(struct rmib_node * node)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