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