blob: b665d3e92fa52b4367b6b05ad3d1e27a06a6221f [file] [log] [blame]
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +00001/*
2 * rt_names.c rtnetlink names DB.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <syslog.h>
16#include <fcntl.h>
17#include <string.h>
18#include <sys/time.h>
osdl.org!shemmingerb88fd9f2004-06-08 23:50:43 +000019#include <sys/socket.h>
David Ahern13ada952015-11-24 13:20:01 -080020#include <dirent.h>
Gustavo Zacarias4a36b4c2016-01-21 15:19:48 -030021#include <limits.h>
osdl.org!shemmingerb88fd9f2004-06-08 23:50:43 +000022
23#include <asm/types.h>
24#include <linux/rtnetlink.h>
25
26#include "rt_names.h"
Daniel Borkmannf6793ee2015-11-26 15:38:44 +010027#include "utils.h"
Christoph J. Thompsonfb721292012-03-01 06:44:43 +000028
vadimkf00073e2014-12-06 04:05:12 +020029#define NAME_MAX_LEN 512
30
Patrick McHardy9c47d872006-08-11 00:14:50 +020031struct rtnl_hash_entry {
Stephen Hemminger68ef5072015-11-29 11:41:23 -080032 struct rtnl_hash_entry *next;
33 const char *name;
Patrick McHardy9c47d872006-08-11 00:14:50 +020034 unsigned int id;
35};
36
vadimkf00073e2014-12-06 04:05:12 +020037static int fread_id_name(FILE *fp, int *id, char *namebuf)
38{
39 char buf[NAME_MAX_LEN];
40
41 while (fgets(buf, sizeof(buf), fp)) {
42 char *p = buf;
43
44 while (*p == ' ' || *p == '\t')
45 p++;
46
47 if (*p == '#' || *p == '\n' || *p == 0)
48 continue;
49
50 if (sscanf(p, "0x%x %s\n", id, namebuf) != 2 &&
51 sscanf(p, "0x%x %s #", id, namebuf) != 2 &&
52 sscanf(p, "%d %s\n", id, namebuf) != 2 &&
53 sscanf(p, "%d %s #", id, namebuf) != 2) {
54 strcpy(namebuf, p);
55 return -1;
56 }
57 return 1;
58 }
59 return 0;
60}
61
Patrick McHardy9c47d872006-08-11 00:14:50 +020062static void
Stephen Hemminger46ac8a52013-02-12 11:39:07 -080063rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
Patrick McHardy9c47d872006-08-11 00:14:50 +020064{
65 struct rtnl_hash_entry *entry;
Patrick McHardy9c47d872006-08-11 00:14:50 +020066 FILE *fp;
vadimkf00073e2014-12-06 04:05:12 +020067 int id;
68 char namebuf[NAME_MAX_LEN] = {0};
69 int ret;
Patrick McHardy9c47d872006-08-11 00:14:50 +020070
71 fp = fopen(file, "r");
72 if (!fp)
73 return;
Patrick McHardy9c47d872006-08-11 00:14:50 +020074
vadimkf00073e2014-12-06 04:05:12 +020075 while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
76 if (ret == -1) {
Patrick McHardy9c47d872006-08-11 00:14:50 +020077 fprintf(stderr, "Database %s is corrupted at %s\n",
vadimkf00073e2014-12-06 04:05:12 +020078 file, namebuf);
Thomas Jarosch97c13582011-10-03 05:22:42 +000079 fclose(fp);
Patrick McHardy9c47d872006-08-11 00:14:50 +020080 return;
81 }
82
Stephen Hemminger68ef5072015-11-29 11:41:23 -080083 if (id < 0)
Patrick McHardy9c47d872006-08-11 00:14:50 +020084 continue;
vadimkf00073e2014-12-06 04:05:12 +020085
Patrick McHardy9c47d872006-08-11 00:14:50 +020086 entry = malloc(sizeof(*entry));
87 entry->id = id;
88 entry->name = strdup(namebuf);
89 entry->next = hash[id & (size - 1)];
90 hash[id & (size - 1)] = entry;
91 }
92 fclose(fp);
93}
94
Stephen Hemminger46ac8a52013-02-12 11:39:07 -080095static void rtnl_tab_initialize(const char *file, char **tab, int size)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +000096{
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +000097 FILE *fp;
vadimkf00073e2014-12-06 04:05:12 +020098 int id;
99 char namebuf[NAME_MAX_LEN] = {0};
100 int ret;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000101
102 fp = fopen(file, "r");
103 if (!fp)
104 return;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000105
vadimkf00073e2014-12-06 04:05:12 +0200106 while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
107 if (ret == -1) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000108 fprintf(stderr, "Database %s is corrupted at %s\n",
vadimkf00073e2014-12-06 04:05:12 +0200109 file, namebuf);
Thomas Jarosch97c13582011-10-03 05:22:42 +0000110 fclose(fp);
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000111 return;
112 }
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800113 if (id < 0 || id > size)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000114 continue;
115
116 tab[id] = strdup(namebuf);
117 }
118 fclose(fp);
119}
120
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800121static char *rtnl_rtprot_tab[256] = {
122 [RTPROT_UNSPEC] = "none",
123 [RTPROT_REDIRECT] = "redirect",
124 [RTPROT_KERNEL] = "kernel",
125 [RTPROT_BOOT] = "boot",
126 [RTPROT_STATIC] = "static",
osdl.org!shemmingerb88fd9f2004-06-08 23:50:43 +0000127
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800128 [RTPROT_GATED] = "gated",
129 [RTPROT_RA] = "ra",
130 [RTPROT_MRT] = "mrt",
131 [RTPROT_ZEBRA] = "zebra",
132 [RTPROT_BIRD] = "bird",
133 [RTPROT_BABEL] = "babel",
osdl.org!shemmingerb88fd9f2004-06-08 23:50:43 +0000134 [RTPROT_DNROUTED] = "dnrouted",
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800135 [RTPROT_XORP] = "xorp",
136 [RTPROT_NTK] = "ntk",
137 [RTPROT_DHCP] = "dhcp",
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000138};
139
140
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000141static int rtnl_rtprot_init;
142
143static void rtnl_rtprot_initialize(void)
144{
145 rtnl_rtprot_init = 1;
Christoph J. Thompsonfb721292012-03-01 06:44:43 +0000146 rtnl_tab_initialize(CONFDIR "/rt_protos",
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000147 rtnl_rtprot_tab, 256);
148}
149
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800150const char *rtnl_rtprot_n2a(int id, char *buf, int len)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000151{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800152 if (id < 0 || id >= 256) {
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800153 snprintf(buf, len, "%u", id);
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000154 return buf;
155 }
156 if (!rtnl_rtprot_tab[id]) {
157 if (!rtnl_rtprot_init)
158 rtnl_rtprot_initialize();
159 }
160 if (rtnl_rtprot_tab[id])
161 return rtnl_rtprot_tab[id];
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800162 snprintf(buf, len, "%u", id);
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000163 return buf;
164}
165
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800166int rtnl_rtprot_a2n(__u32 *id, const char *arg)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000167{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800168 static char *cache;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000169 static unsigned long res;
170 char *end;
171 int i;
172
173 if (cache && strcmp(cache, arg) == 0) {
174 *id = res;
175 return 0;
176 }
177
178 if (!rtnl_rtprot_init)
179 rtnl_rtprot_initialize();
180
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800181 for (i = 0; i < 256; i++) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000182 if (rtnl_rtprot_tab[i] &&
183 strcmp(rtnl_rtprot_tab[i], arg) == 0) {
184 cache = rtnl_rtprot_tab[i];
185 res = i;
186 *id = res;
187 return 0;
188 }
189 }
190
191 res = strtoul(arg, &end, 0);
192 if (!end || end == arg || *end || res > 255)
193 return -1;
194 *id = res;
195 return 0;
196}
197
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800198
199static char *rtnl_rtscope_tab[256] = {
200 [RT_SCOPE_UNIVERSE] = "global",
201 [RT_SCOPE_NOWHERE] = "nowhere",
202 [RT_SCOPE_HOST] = "host",
203 [RT_SCOPE_LINK] = "link",
204 [RT_SCOPE_SITE] = "site",
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000205};
206
207static int rtnl_rtscope_init;
208
209static void rtnl_rtscope_initialize(void)
210{
211 rtnl_rtscope_init = 1;
Christoph J. Thompsonfb721292012-03-01 06:44:43 +0000212 rtnl_tab_initialize(CONFDIR "/rt_scopes",
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000213 rtnl_rtscope_tab, 256);
214}
215
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800216const char *rtnl_rtscope_n2a(int id, char *buf, int len)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000217{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800218 if (id < 0 || id >= 256) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000219 snprintf(buf, len, "%d", id);
220 return buf;
221 }
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800222
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000223 if (!rtnl_rtscope_tab[id]) {
224 if (!rtnl_rtscope_init)
225 rtnl_rtscope_initialize();
226 }
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800227
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000228 if (rtnl_rtscope_tab[id])
229 return rtnl_rtscope_tab[id];
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800230
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000231 snprintf(buf, len, "%d", id);
232 return buf;
233}
234
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800235int rtnl_rtscope_a2n(__u32 *id, const char *arg)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000236{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800237 static const char *cache;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000238 static unsigned long res;
239 char *end;
240 int i;
241
242 if (cache && strcmp(cache, arg) == 0) {
243 *id = res;
244 return 0;
245 }
246
247 if (!rtnl_rtscope_init)
248 rtnl_rtscope_initialize();
249
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800250 for (i = 0; i < 256; i++) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000251 if (rtnl_rtscope_tab[i] &&
252 strcmp(rtnl_rtscope_tab[i], arg) == 0) {
253 cache = rtnl_rtscope_tab[i];
254 res = i;
255 *id = res;
256 return 0;
257 }
258 }
259
260 res = strtoul(arg, &end, 0);
261 if (!end || end == arg || *end || res > 255)
262 return -1;
263 *id = res;
264 return 0;
265}
266
267
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800268static char *rtnl_rtrealm_tab[256] = {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000269 "unknown",
270};
271
272static int rtnl_rtrealm_init;
273
274static void rtnl_rtrealm_initialize(void)
275{
276 rtnl_rtrealm_init = 1;
Christoph J. Thompsonfb721292012-03-01 06:44:43 +0000277 rtnl_tab_initialize(CONFDIR "/rt_realms",
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000278 rtnl_rtrealm_tab, 256);
279}
280
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800281const char *rtnl_rtrealm_n2a(int id, char *buf, int len)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000282{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800283 if (id < 0 || id >= 256) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000284 snprintf(buf, len, "%d", id);
285 return buf;
286 }
287 if (!rtnl_rtrealm_tab[id]) {
288 if (!rtnl_rtrealm_init)
289 rtnl_rtrealm_initialize();
290 }
291 if (rtnl_rtrealm_tab[id])
292 return rtnl_rtrealm_tab[id];
293 snprintf(buf, len, "%d", id);
294 return buf;
295}
296
297
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800298int rtnl_rtrealm_a2n(__u32 *id, const char *arg)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000299{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800300 static char *cache;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000301 static unsigned long res;
302 char *end;
303 int i;
304
305 if (cache && strcmp(cache, arg) == 0) {
306 *id = res;
307 return 0;
308 }
309
310 if (!rtnl_rtrealm_init)
311 rtnl_rtrealm_initialize();
312
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800313 for (i = 0; i < 256; i++) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000314 if (rtnl_rtrealm_tab[i] &&
315 strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
316 cache = rtnl_rtrealm_tab[i];
317 res = i;
318 *id = res;
319 return 0;
320 }
321 }
322
323 res = strtoul(arg, &end, 0);
324 if (!end || end == arg || *end || res > 255)
325 return -1;
326 *id = res;
327 return 0;
328}
329
330
Masatake YAMATO81ebcb22014-03-07 19:21:37 +0900331static struct rtnl_hash_entry dflt_table_entry = { .name = "default" };
332static struct rtnl_hash_entry main_table_entry = { .name = "main" };
333static struct rtnl_hash_entry local_table_entry = { .name = "local" };
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000334
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800335static struct rtnl_hash_entry *rtnl_rttable_hash[256] = {
Masatake YAMATO81ebcb22014-03-07 19:21:37 +0900336 [RT_TABLE_DEFAULT] = &dflt_table_entry,
337 [RT_TABLE_MAIN] = &main_table_entry,
338 [RT_TABLE_LOCAL] = &local_table_entry,
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000339};
340
341static int rtnl_rttable_init;
342
343static void rtnl_rttable_initialize(void)
344{
David Ahern13ada952015-11-24 13:20:01 -0800345 struct dirent *de;
346 DIR *d;
Masatake YAMATO81ebcb22014-03-07 19:21:37 +0900347 int i;
348
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000349 rtnl_rttable_init = 1;
Masatake YAMATO81ebcb22014-03-07 19:21:37 +0900350 for (i = 0; i < 256; i++) {
351 if (rtnl_rttable_hash[i])
352 rtnl_rttable_hash[i]->id = i;
353 }
Christoph J. Thompsonfb721292012-03-01 06:44:43 +0000354 rtnl_hash_initialize(CONFDIR "/rt_tables",
Patrick McHardy9c47d872006-08-11 00:14:50 +0200355 rtnl_rttable_hash, 256);
David Ahern13ada952015-11-24 13:20:01 -0800356
357 d = opendir(CONFDIR "/rt_tables.d");
358 if (!d)
359 return;
360
361 while ((de = readdir(d)) != NULL) {
362 char path[PATH_MAX];
363 size_t len;
364
365 if (*de->d_name == '.')
366 continue;
367
368 /* only consider filenames ending in '.conf' */
369 len = strlen(de->d_name);
370 if (len <= 5)
371 continue;
372 if (strcmp(de->d_name + len - 5, ".conf"))
373 continue;
374
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800375 snprintf(path, sizeof(path),
376 CONFDIR "/rt_tables.d/%s", de->d_name);
David Ahern13ada952015-11-24 13:20:01 -0800377 rtnl_hash_initialize(path, rtnl_rttable_hash, 256);
378 }
379 closedir(d);
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000380}
381
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800382const char *rtnl_rttable_n2a(__u32 id, char *buf, int len)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000383{
Patrick McHardy9c47d872006-08-11 00:14:50 +0200384 struct rtnl_hash_entry *entry;
385
Boian Bonev887a5d02006-11-27 14:12:31 -0800386 if (id > RT_TABLE_MAX) {
Patrick McHardy9c47d872006-08-11 00:14:50 +0200387 snprintf(buf, len, "%u", id);
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000388 return buf;
389 }
Patrick McHardy9c47d872006-08-11 00:14:50 +0200390 if (!rtnl_rttable_init)
391 rtnl_rttable_initialize();
392 entry = rtnl_rttable_hash[id & 255];
393 while (entry && entry->id != id)
394 entry = entry->next;
395 if (entry)
396 return entry->name;
397 snprintf(buf, len, "%u", id);
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000398 return buf;
399}
400
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800401int rtnl_rttable_a2n(__u32 *id, const char *arg)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000402{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800403 static const char *cache;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000404 static unsigned long res;
Patrick McHardy9c47d872006-08-11 00:14:50 +0200405 struct rtnl_hash_entry *entry;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000406 char *end;
Patrick McHardy34e95642006-08-11 00:14:51 +0200407 __u32 i;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000408
409 if (cache && strcmp(cache, arg) == 0) {
410 *id = res;
411 return 0;
412 }
413
414 if (!rtnl_rttable_init)
415 rtnl_rttable_initialize();
416
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800417 for (i = 0; i < 256; i++) {
Patrick McHardy9c47d872006-08-11 00:14:50 +0200418 entry = rtnl_rttable_hash[i];
419 while (entry && strcmp(entry->name, arg))
420 entry = entry->next;
421 if (entry) {
422 cache = entry->name;
423 res = entry->id;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000424 *id = res;
425 return 0;
426 }
427 }
428
429 i = strtoul(arg, &end, 0);
Patrick McHardy9c47d872006-08-11 00:14:50 +0200430 if (!end || end == arg || *end || i > RT_TABLE_MAX)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000431 return -1;
432 *id = i;
433 return 0;
434}
435
436
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800437static char *rtnl_rtdsfield_tab[256] = {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000438 "0",
439};
440
441static int rtnl_rtdsfield_init;
442
443static void rtnl_rtdsfield_initialize(void)
444{
445 rtnl_rtdsfield_init = 1;
Christoph J. Thompsonfb721292012-03-01 06:44:43 +0000446 rtnl_tab_initialize(CONFDIR "/rt_dsfield",
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000447 rtnl_rtdsfield_tab, 256);
448}
449
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800450const char *rtnl_dsfield_n2a(int id, char *buf, int len)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000451{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800452 if (id < 0 || id >= 256) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000453 snprintf(buf, len, "%d", id);
454 return buf;
455 }
456 if (!rtnl_rtdsfield_tab[id]) {
457 if (!rtnl_rtdsfield_init)
458 rtnl_rtdsfield_initialize();
459 }
460 if (rtnl_rtdsfield_tab[id])
461 return rtnl_rtdsfield_tab[id];
462 snprintf(buf, len, "0x%02x", id);
463 return buf;
464}
465
466
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800467int rtnl_dsfield_a2n(__u32 *id, const char *arg)
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000468{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800469 static char *cache;
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000470 static unsigned long res;
471 char *end;
472 int i;
473
474 if (cache && strcmp(cache, arg) == 0) {
475 *id = res;
476 return 0;
477 }
478
479 if (!rtnl_rtdsfield_init)
480 rtnl_rtdsfield_initialize();
481
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800482 for (i = 0; i < 256; i++) {
osdl.org!shemmingeraba5acd2004-04-15 20:56:59 +0000483 if (rtnl_rtdsfield_tab[i] &&
484 strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
485 cache = rtnl_rtdsfield_tab[i];
486 res = i;
487 *id = res;
488 return 0;
489 }
490 }
491
492 res = strtoul(arg, &end, 16);
493 if (!end || end == arg || *end || res > 255)
494 return -1;
495 *id = res;
496 return 0;
497}
498
Vlad Dogaruac694c32011-02-02 20:23:40 +0200499
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800500static struct rtnl_hash_entry dflt_group_entry = {
501 .id = 0, .name = "default"
502};
Vlad Dogaruac694c32011-02-02 20:23:40 +0200503
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800504static struct rtnl_hash_entry *rtnl_group_hash[256] = {
Vlad Dogaruac694c32011-02-02 20:23:40 +0200505 [0] = &dflt_group_entry,
506};
507
508static int rtnl_group_init;
509
510static void rtnl_group_initialize(void)
511{
512 rtnl_group_init = 1;
vadimk4e5615b2014-12-06 04:05:11 +0200513 rtnl_hash_initialize(CONFDIR "/group",
Vlad Dogaruac694c32011-02-02 20:23:40 +0200514 rtnl_group_hash, 256);
515}
516
Stephen Hemminger46ac8a52013-02-12 11:39:07 -0800517int rtnl_group_a2n(int *id, const char *arg)
Vlad Dogaruac694c32011-02-02 20:23:40 +0200518{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800519 static const char *cache;
Vlad Dogaruac694c32011-02-02 20:23:40 +0200520 static unsigned long res;
521 struct rtnl_hash_entry *entry;
522 char *end;
523 int i;
524
525 if (cache && strcmp(cache, arg) == 0) {
526 *id = res;
527 return 0;
528 }
529
530 if (!rtnl_group_init)
531 rtnl_group_initialize();
532
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800533 for (i = 0; i < 256; i++) {
Vlad Dogaruac694c32011-02-02 20:23:40 +0200534 entry = rtnl_group_hash[i];
535 while (entry && strcmp(entry->name, arg))
536 entry = entry->next;
537 if (entry) {
538 cache = entry->name;
539 res = entry->id;
540 *id = res;
541 return 0;
542 }
543 }
544
545 i = strtol(arg, &end, 0);
546 if (!end || end == arg || *end || i < 0)
547 return -1;
548 *id = i;
549 return 0;
550}
Stefan Tomanekc4fdf752013-08-03 14:20:53 +0200551
552const char *rtnl_group_n2a(int id, char *buf, int len)
553{
554 struct rtnl_hash_entry *entry;
555 int i;
556
557 if (!rtnl_group_init)
558 rtnl_group_initialize();
559
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800560 for (i = 0; i < 256; i++) {
Stefan Tomanekc4fdf752013-08-03 14:20:53 +0200561 entry = rtnl_group_hash[i];
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800562 if (entry && entry->id == id)
Stefan Tomanekc4fdf752013-08-03 14:20:53 +0200563 return entry->name;
Stefan Tomanekc4fdf752013-08-03 14:20:53 +0200564 }
565
566 snprintf(buf, len, "%d", id);
567 return buf;
568}
vadimkeef43b52014-10-30 17:33:36 +0200569
570static char *nl_proto_tab[256] = {
571 [NETLINK_ROUTE] = "rtnl",
572 [NETLINK_UNUSED] = "unused",
573 [NETLINK_USERSOCK] = "usersock",
574 [NETLINK_FIREWALL] = "fw",
575 [NETLINK_SOCK_DIAG] = "tcpdiag",
576 [NETLINK_NFLOG] = "nflog",
577 [NETLINK_XFRM] = "xfrm",
578 [NETLINK_SELINUX] = "selinux",
579 [NETLINK_ISCSI] = "iscsi",
580 [NETLINK_AUDIT] = "audit",
581 [NETLINK_FIB_LOOKUP] = "fiblookup",
582 [NETLINK_CONNECTOR] = "connector",
583 [NETLINK_NETFILTER] = "nft",
584 [NETLINK_IP6_FW] = "ip6fw",
585 [NETLINK_DNRTMSG] = "dec-rt",
586 [NETLINK_KOBJECT_UEVENT] = "uevent",
587 [NETLINK_GENERIC] = "genl",
588 [NETLINK_SCSITRANSPORT] = "scsi-trans",
589 [NETLINK_ECRYPTFS] = "ecryptfs",
590 [NETLINK_RDMA] = "rdma",
591 [NETLINK_CRYPTO] = "crypto",
592};
593
594static int nl_proto_init;
595
596static void nl_proto_initialize(void)
597{
598 nl_proto_init = 1;
599 rtnl_tab_initialize(CONFDIR "/nl_protos",
600 nl_proto_tab, 256);
601}
602
603const char *nl_proto_n2a(int id, char *buf, int len)
604{
605 if (id < 0 || id >= 256) {
606 snprintf(buf, len, "%u", id);
607 return buf;
608 }
609
610 if (!nl_proto_init)
611 nl_proto_initialize();
612
613 if (nl_proto_tab[id])
614 return nl_proto_tab[id];
615
616 snprintf(buf, len, "%u", id);
617 return buf;
618}
619
620int nl_proto_a2n(__u32 *id, const char *arg)
621{
Stephen Hemminger68ef5072015-11-29 11:41:23 -0800622 static char *cache;
vadimkeef43b52014-10-30 17:33:36 +0200623 static unsigned long res;
624 char *end;
625 int i;
626
627 if (cache && strcmp(cache, arg) == 0) {
628 *id = res;
629 return 0;
630 }
631
632 if (!nl_proto_init)
633 nl_proto_initialize();
634
635 for (i = 0; i < 256; i++) {
636 if (nl_proto_tab[i] &&
637 strcmp(nl_proto_tab[i], arg) == 0) {
638 cache = nl_proto_tab[i];
639 res = i;
640 *id = res;
641 return 0;
642 }
643 }
644
645 res = strtoul(arg, &end, 0);
646 if (!end || end == arg || *end || res > 255)
647 return -1;
648 *id = res;
649 return 0;
650}