ip: increased max ID for /etc/iproute2/rt_tables to 1023
[oweals/busybox.git] / networking / libiproute / rt_names.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * This program is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU General Public License
5  * as published by the Free Software Foundation; either version
6  * 2 of the License, or (at your option) any later version.
7  *
8  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
9  */
10 #include "libbb.h"
11 #include "rt_names.h"
12
13 typedef struct rtnl_tab_t {
14         const char *cached_str;
15         unsigned cached_result;
16         /* upstream version switched to a hash table and removed
17          * id < 256 limit. For now bbox bumps this array size from 256
18          * to 1024. If you plan to change this to a hash table,
19          * consider merging several hash tables we have (for example,
20          * awk has resizable one!
21          */
22 #define RT_TABLE_MAX 1023
23         const char *tab[RT_TABLE_MAX+1];
24 } rtnl_tab_t;
25
26 static void rtnl_tab_initialize(const char *file, const char **tab)
27 {
28         char *token[2];
29         parser_t *parser = config_open2(file, fopen_for_read);
30
31         while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) {
32                 unsigned id = bb_strtou(token[0], NULL, 0);
33                 if (id > RT_TABLE_MAX) {
34                         bb_error_msg("database %s is corrupted at line %d",
35                                 file, parser->lineno);
36                         break;
37                 }
38                 tab[id] = xstrdup(token[1]);
39         }
40         config_close(parser);
41 }
42
43 static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base)
44 {
45         unsigned i;
46
47         if (tab->cached_str && strcmp(tab->cached_str, arg) == 0) {
48                 *id = tab->cached_result;
49                 return 0;
50         }
51
52         for (i = 0; i <= RT_TABLE_MAX; i++) {
53                 if (tab->tab[i]
54                  && strcmp(tab->tab[i], arg) == 0
55                 ) {
56                         tab->cached_str = tab->tab[i];
57                         tab->cached_result = i;
58                         *id = i;
59                         return 0;
60                 }
61         }
62
63         i = bb_strtou(arg, NULL, base);
64         if (i > RT_TABLE_MAX)
65                 return -1;
66         *id = i;
67         return 0;
68 }
69
70
71 static rtnl_tab_t *rtnl_rtprot_tab;
72
73 static void rtnl_rtprot_initialize(void)
74 {
75         static const char *const init_tab[] = {
76                 "none",
77                 "redirect",
78                 "kernel",
79                 "boot",
80                 "static",
81                 NULL,
82                 NULL,
83                 NULL,
84                 "gated",
85                 "ra",
86                 "mrt",
87                 "zebra",
88                 "bird",
89         };
90
91         if (rtnl_rtprot_tab)
92                 return;
93         rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab));
94         memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab));
95         rtnl_tab_initialize("/etc/iproute2/rt_protos", rtnl_rtprot_tab->tab);
96 }
97
98 #if 0 /* UNUSED */
99 const char* FAST_FUNC rtnl_rtprot_n2a(int id)
100 {
101         if (id < 0 || id > RT_TABLE_MAX) {
102                 return itoa(id);
103         }
104
105         rtnl_rtprot_initialize();
106
107         if (rtnl_rtprot_tab->tab[id])
108                 return rtnl_rtprot_tab->tab[id];
109         return itoa(id);
110 }
111 #endif
112
113 int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg)
114 {
115         rtnl_rtprot_initialize();
116         return rtnl_a2n(rtnl_rtprot_tab, id, arg, 0);
117 }
118
119
120 static rtnl_tab_t *rtnl_rtscope_tab;
121
122 static void rtnl_rtscope_initialize(void)
123 {
124         if (rtnl_rtscope_tab)
125                 return;
126         rtnl_rtscope_tab = xzalloc(sizeof(*rtnl_rtscope_tab));
127         rtnl_rtscope_tab->tab[0] = "global";
128         rtnl_rtscope_tab->tab[255] = "nowhere";
129         rtnl_rtscope_tab->tab[254] = "host";
130         rtnl_rtscope_tab->tab[253] = "link";
131         rtnl_rtscope_tab->tab[200] = "site";
132         rtnl_tab_initialize("/etc/iproute2/rt_scopes", rtnl_rtscope_tab->tab);
133 }
134
135 const char* FAST_FUNC rtnl_rtscope_n2a(int id)
136 {
137         if (id < 0 || id > RT_TABLE_MAX) {
138                 return itoa(id);
139         }
140
141         rtnl_rtscope_initialize();
142
143         if (rtnl_rtscope_tab->tab[id])
144                 return rtnl_rtscope_tab->tab[id];
145         return itoa(id);
146 }
147
148 int FAST_FUNC rtnl_rtscope_a2n(uint32_t *id, char *arg)
149 {
150         rtnl_rtscope_initialize();
151         return rtnl_a2n(rtnl_rtscope_tab, id, arg, 0);
152 }
153
154
155 static rtnl_tab_t *rtnl_rtrealm_tab;
156
157 static void rtnl_rtrealm_initialize(void)
158 {
159         if (rtnl_rtrealm_tab) return;
160         rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab));
161         rtnl_rtrealm_tab->tab[0] = "unknown";
162         rtnl_tab_initialize("/etc/iproute2/rt_realms", rtnl_rtrealm_tab->tab);
163 }
164
165 int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg)
166 {
167         rtnl_rtrealm_initialize();
168         return rtnl_a2n(rtnl_rtrealm_tab, id, arg, 0);
169 }
170
171 #if ENABLE_FEATURE_IP_RULE
172 const char* FAST_FUNC rtnl_rtrealm_n2a(int id)
173 {
174         if (id < 0 || id > RT_TABLE_MAX) {
175                 return itoa(id);
176         }
177
178         rtnl_rtrealm_initialize();
179
180         if (rtnl_rtrealm_tab->tab[id])
181                 return rtnl_rtrealm_tab->tab[id];
182         return itoa(id);
183 }
184 #endif
185
186
187 static rtnl_tab_t *rtnl_rtdsfield_tab;
188
189 static void rtnl_rtdsfield_initialize(void)
190 {
191         if (rtnl_rtdsfield_tab) return;
192         rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab));
193         rtnl_rtdsfield_tab->tab[0] = "0";
194         rtnl_tab_initialize("/etc/iproute2/rt_dsfield", rtnl_rtdsfield_tab->tab);
195 }
196
197 const char* FAST_FUNC rtnl_dsfield_n2a(int id)
198 {
199         if (id < 0 || id > RT_TABLE_MAX) {
200                 return itoa(id);
201         }
202
203         rtnl_rtdsfield_initialize();
204
205         if (rtnl_rtdsfield_tab->tab[id])
206                 return rtnl_rtdsfield_tab->tab[id];
207         return itoa(id);
208 }
209
210 int FAST_FUNC rtnl_dsfield_a2n(uint32_t *id, char *arg)
211 {
212         rtnl_rtdsfield_initialize();
213         return rtnl_a2n(rtnl_rtdsfield_tab, id, arg, 16);
214 }
215
216
217 #if ENABLE_FEATURE_IP_RULE
218 static rtnl_tab_t *rtnl_rttable_tab;
219
220 static void rtnl_rttable_initialize(void)
221 {
222         if (rtnl_rttable_tab)
223                 return;
224
225         rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab));
226         rtnl_rttable_tab->tab[0] = "unspec";
227         rtnl_rttable_tab->tab[255] = "local";
228         rtnl_rttable_tab->tab[254] = "main";
229         rtnl_rttable_tab->tab[253] = "default";
230         rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab->tab);
231 }
232
233 const char* FAST_FUNC rtnl_rttable_n2a(int id)
234 {
235         if (id < 0 || id > RT_TABLE_MAX) {
236                 return itoa(id);
237         }
238
239         rtnl_rttable_initialize();
240
241         if (rtnl_rttable_tab->tab[id])
242                 return rtnl_rttable_tab->tab[id];
243         return itoa(id);
244 }
245
246 int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg)
247 {
248         rtnl_rttable_initialize();
249         return rtnl_a2n(rtnl_rttable_tab, id, arg, 0);
250 }
251
252 #endif