]> git.proxmox.com Git - mirror_iproute2.git/blame - lib/rt_names.c
geneve: add support for IPv6 link partners
[mirror_iproute2.git] / lib / rt_names.c
CommitLineData
aba5acdf
SH
1/*
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>
b88fd9f4
SH
19#include <sys/socket.h>
20
21#include <asm/types.h>
22#include <linux/rtnetlink.h>
23
24#include "rt_names.h"
aba5acdf 25
fb72129b
CT
26#ifndef CONFDIR
27#define CONFDIR "/etc/iproute2"
28#endif
29
f00073e8 30#define NAME_MAX_LEN 512
31
9c47d877
PM
32struct rtnl_hash_entry {
33 struct rtnl_hash_entry *next;
46ac8a55 34 const char * name;
9c47d877
PM
35 unsigned int id;
36};
37
f00073e8 38static int fread_id_name(FILE *fp, int *id, char *namebuf)
39{
40 char buf[NAME_MAX_LEN];
41
42 while (fgets(buf, sizeof(buf), fp)) {
43 char *p = buf;
44
45 while (*p == ' ' || *p == '\t')
46 p++;
47
48 if (*p == '#' || *p == '\n' || *p == 0)
49 continue;
50
51 if (sscanf(p, "0x%x %s\n", id, namebuf) != 2 &&
52 sscanf(p, "0x%x %s #", id, namebuf) != 2 &&
53 sscanf(p, "%d %s\n", id, namebuf) != 2 &&
54 sscanf(p, "%d %s #", id, namebuf) != 2) {
55 strcpy(namebuf, p);
56 return -1;
57 }
58 return 1;
59 }
60 return 0;
61}
62
9c47d877 63static void
46ac8a55 64rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
9c47d877
PM
65{
66 struct rtnl_hash_entry *entry;
9c47d877 67 FILE *fp;
f00073e8 68 int id;
69 char namebuf[NAME_MAX_LEN] = {0};
70 int ret;
9c47d877
PM
71
72 fp = fopen(file, "r");
73 if (!fp)
74 return;
9c47d877 75
f00073e8 76 while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
77 if (ret == -1) {
9c47d877 78 fprintf(stderr, "Database %s is corrupted at %s\n",
f00073e8 79 file, namebuf);
97c13582 80 fclose(fp);
9c47d877
PM
81 return;
82 }
83
84 if (id<0)
85 continue;
f00073e8 86
9c47d877
PM
87 entry = malloc(sizeof(*entry));
88 entry->id = id;
89 entry->name = strdup(namebuf);
90 entry->next = hash[id & (size - 1)];
91 hash[id & (size - 1)] = entry;
92 }
93 fclose(fp);
94}
95
46ac8a55 96static void rtnl_tab_initialize(const char *file, char **tab, int size)
aba5acdf 97{
aba5acdf 98 FILE *fp;
f00073e8 99 int id;
100 char namebuf[NAME_MAX_LEN] = {0};
101 int ret;
aba5acdf
SH
102
103 fp = fopen(file, "r");
104 if (!fp)
105 return;
aba5acdf 106
f00073e8 107 while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
108 if (ret == -1) {
aba5acdf 109 fprintf(stderr, "Database %s is corrupted at %s\n",
f00073e8 110 file, namebuf);
97c13582 111 fclose(fp);
aba5acdf
SH
112 return;
113 }
aba5acdf
SH
114 if (id<0 || id>size)
115 continue;
116
117 tab[id] = strdup(namebuf);
118 }
119 fclose(fp);
120}
121
aba5acdf 122static char * rtnl_rtprot_tab[256] = {
b88fd9f4
SH
123 [RTPROT_UNSPEC] = "none",
124 [RTPROT_REDIRECT] ="redirect",
125 [RTPROT_KERNEL] = "kernel",
126 [RTPROT_BOOT] = "boot",
127 [RTPROT_STATIC] = "static",
128
129 [RTPROT_GATED] = "gated",
130 [RTPROT_RA] = "ra",
131 [RTPROT_MRT] = "mrt",
132 [RTPROT_ZEBRA] ="zebra",
133 [RTPROT_BIRD] = "bird",
1fa804e0 134 [RTPROT_BABEL] = "babel",
b88fd9f4
SH
135 [RTPROT_DNROUTED] = "dnrouted",
136 [RTPROT_XORP] = "xorp",
40b6c62c 137 [RTPROT_NTK] = "ntk",
1e659af3 138 [RTPROT_DHCP] = "dhcp",
aba5acdf
SH
139};
140
141
aba5acdf
SH
142static int rtnl_rtprot_init;
143
144static void rtnl_rtprot_initialize(void)
145{
146 rtnl_rtprot_init = 1;
fb72129b 147 rtnl_tab_initialize(CONFDIR "/rt_protos",
aba5acdf
SH
148 rtnl_rtprot_tab, 256);
149}
150
46ac8a55 151const char * rtnl_rtprot_n2a(int id, char *buf, int len)
aba5acdf
SH
152{
153 if (id<0 || id>=256) {
46ac8a55 154 snprintf(buf, len, "%u", id);
aba5acdf
SH
155 return buf;
156 }
157 if (!rtnl_rtprot_tab[id]) {
158 if (!rtnl_rtprot_init)
159 rtnl_rtprot_initialize();
160 }
161 if (rtnl_rtprot_tab[id])
162 return rtnl_rtprot_tab[id];
46ac8a55 163 snprintf(buf, len, "%u", id);
aba5acdf
SH
164 return buf;
165}
166
46ac8a55 167int rtnl_rtprot_a2n(__u32 *id, const char *arg)
aba5acdf
SH
168{
169 static char *cache = NULL;
170 static unsigned long res;
171 char *end;
172 int i;
173
174 if (cache && strcmp(cache, arg) == 0) {
175 *id = res;
176 return 0;
177 }
178
179 if (!rtnl_rtprot_init)
180 rtnl_rtprot_initialize();
181
182 for (i=0; i<256; i++) {
183 if (rtnl_rtprot_tab[i] &&
184 strcmp(rtnl_rtprot_tab[i], arg) == 0) {
185 cache = rtnl_rtprot_tab[i];
186 res = i;
187 *id = res;
188 return 0;
189 }
190 }
191
192 res = strtoul(arg, &end, 0);
193 if (!end || end == arg || *end || res > 255)
194 return -1;
195 *id = res;
196 return 0;
197}
198
b0d30f7f 199static char * rtnl_rtscope_tab[256] = {
aba5acdf
SH
200 "global",
201};
202
203static int rtnl_rtscope_init;
204
205static void rtnl_rtscope_initialize(void)
206{
207 rtnl_rtscope_init = 1;
58ed50ee
MY
208 rtnl_rtscope_tab[RT_SCOPE_NOWHERE] = "nowhere";
209 rtnl_rtscope_tab[RT_SCOPE_HOST] = "host";
210 rtnl_rtscope_tab[RT_SCOPE_LINK] = "link";
211 rtnl_rtscope_tab[RT_SCOPE_SITE] = "site";
fb72129b 212 rtnl_tab_initialize(CONFDIR "/rt_scopes",
aba5acdf
SH
213 rtnl_rtscope_tab, 256);
214}
215
46ac8a55 216const char *rtnl_rtscope_n2a(int id, char *buf, int len)
aba5acdf
SH
217{
218 if (id<0 || id>=256) {
219 snprintf(buf, len, "%d", id);
220 return buf;
221 }
222 if (!rtnl_rtscope_tab[id]) {
223 if (!rtnl_rtscope_init)
224 rtnl_rtscope_initialize();
225 }
226 if (rtnl_rtscope_tab[id])
227 return rtnl_rtscope_tab[id];
228 snprintf(buf, len, "%d", id);
229 return buf;
230}
231
46ac8a55 232int rtnl_rtscope_a2n(__u32 *id, const char *arg)
aba5acdf 233{
46ac8a55 234 static const char *cache = NULL;
aba5acdf
SH
235 static unsigned long res;
236 char *end;
237 int i;
238
239 if (cache && strcmp(cache, arg) == 0) {
240 *id = res;
241 return 0;
242 }
243
244 if (!rtnl_rtscope_init)
245 rtnl_rtscope_initialize();
246
247 for (i=0; i<256; i++) {
248 if (rtnl_rtscope_tab[i] &&
249 strcmp(rtnl_rtscope_tab[i], arg) == 0) {
250 cache = rtnl_rtscope_tab[i];
251 res = i;
252 *id = res;
253 return 0;
254 }
255 }
256
257 res = strtoul(arg, &end, 0);
258 if (!end || end == arg || *end || res > 255)
259 return -1;
260 *id = res;
261 return 0;
262}
263
264
aba5acdf
SH
265static char * rtnl_rtrealm_tab[256] = {
266 "unknown",
267};
268
269static int rtnl_rtrealm_init;
270
271static void rtnl_rtrealm_initialize(void)
272{
273 rtnl_rtrealm_init = 1;
fb72129b 274 rtnl_tab_initialize(CONFDIR "/rt_realms",
aba5acdf
SH
275 rtnl_rtrealm_tab, 256);
276}
277
46ac8a55 278const char *rtnl_rtrealm_n2a(int id, char *buf, int len)
aba5acdf
SH
279{
280 if (id<0 || id>=256) {
281 snprintf(buf, len, "%d", id);
282 return buf;
283 }
284 if (!rtnl_rtrealm_tab[id]) {
285 if (!rtnl_rtrealm_init)
286 rtnl_rtrealm_initialize();
287 }
288 if (rtnl_rtrealm_tab[id])
289 return rtnl_rtrealm_tab[id];
290 snprintf(buf, len, "%d", id);
291 return buf;
292}
293
294
46ac8a55 295int rtnl_rtrealm_a2n(__u32 *id, const char *arg)
aba5acdf
SH
296{
297 static char *cache = NULL;
298 static unsigned long res;
299 char *end;
300 int i;
301
302 if (cache && strcmp(cache, arg) == 0) {
303 *id = res;
304 return 0;
305 }
306
307 if (!rtnl_rtrealm_init)
308 rtnl_rtrealm_initialize();
309
310 for (i=0; i<256; i++) {
311 if (rtnl_rtrealm_tab[i] &&
312 strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
313 cache = rtnl_rtrealm_tab[i];
314 res = i;
315 *id = res;
316 return 0;
317 }
318 }
319
320 res = strtoul(arg, &end, 0);
321 if (!end || end == arg || *end || res > 255)
322 return -1;
323 *id = res;
324 return 0;
325}
326
327
81ebcb2a
MY
328static struct rtnl_hash_entry dflt_table_entry = { .name = "default" };
329static struct rtnl_hash_entry main_table_entry = { .name = "main" };
330static struct rtnl_hash_entry local_table_entry = { .name = "local" };
aba5acdf 331
9c47d877 332static struct rtnl_hash_entry * rtnl_rttable_hash[256] = {
81ebcb2a
MY
333 [RT_TABLE_DEFAULT] = &dflt_table_entry,
334 [RT_TABLE_MAIN] = &main_table_entry,
335 [RT_TABLE_LOCAL] = &local_table_entry,
aba5acdf
SH
336};
337
338static int rtnl_rttable_init;
339
340static void rtnl_rttable_initialize(void)
341{
81ebcb2a
MY
342 int i;
343
aba5acdf 344 rtnl_rttable_init = 1;
81ebcb2a
MY
345 for (i = 0; i < 256; i++) {
346 if (rtnl_rttable_hash[i])
347 rtnl_rttable_hash[i]->id = i;
348 }
fb72129b 349 rtnl_hash_initialize(CONFDIR "/rt_tables",
9c47d877 350 rtnl_rttable_hash, 256);
aba5acdf
SH
351}
352
46ac8a55 353const char * rtnl_rttable_n2a(__u32 id, char *buf, int len)
aba5acdf 354{
9c47d877
PM
355 struct rtnl_hash_entry *entry;
356
887a5d00 357 if (id > RT_TABLE_MAX) {
9c47d877 358 snprintf(buf, len, "%u", id);
aba5acdf
SH
359 return buf;
360 }
9c47d877
PM
361 if (!rtnl_rttable_init)
362 rtnl_rttable_initialize();
363 entry = rtnl_rttable_hash[id & 255];
364 while (entry && entry->id != id)
365 entry = entry->next;
366 if (entry)
367 return entry->name;
368 snprintf(buf, len, "%u", id);
aba5acdf
SH
369 return buf;
370}
371
46ac8a55 372int rtnl_rttable_a2n(__u32 *id, const char *arg)
aba5acdf 373{
46ac8a55 374 static const char *cache = NULL;
aba5acdf 375 static unsigned long res;
9c47d877 376 struct rtnl_hash_entry *entry;
aba5acdf 377 char *end;
34e95647 378 __u32 i;
aba5acdf
SH
379
380 if (cache && strcmp(cache, arg) == 0) {
381 *id = res;
382 return 0;
383 }
384
385 if (!rtnl_rttable_init)
386 rtnl_rttable_initialize();
387
388 for (i=0; i<256; i++) {
9c47d877
PM
389 entry = rtnl_rttable_hash[i];
390 while (entry && strcmp(entry->name, arg))
391 entry = entry->next;
392 if (entry) {
393 cache = entry->name;
394 res = entry->id;
aba5acdf
SH
395 *id = res;
396 return 0;
397 }
398 }
399
400 i = strtoul(arg, &end, 0);
9c47d877 401 if (!end || end == arg || *end || i > RT_TABLE_MAX)
aba5acdf
SH
402 return -1;
403 *id = i;
404 return 0;
405}
406
407
408static char * rtnl_rtdsfield_tab[256] = {
409 "0",
410};
411
412static int rtnl_rtdsfield_init;
413
414static void rtnl_rtdsfield_initialize(void)
415{
416 rtnl_rtdsfield_init = 1;
fb72129b 417 rtnl_tab_initialize(CONFDIR "/rt_dsfield",
aba5acdf
SH
418 rtnl_rtdsfield_tab, 256);
419}
420
46ac8a55 421const char *rtnl_dsfield_n2a(int id, char *buf, int len)
aba5acdf
SH
422{
423 if (id<0 || id>=256) {
424 snprintf(buf, len, "%d", id);
425 return buf;
426 }
427 if (!rtnl_rtdsfield_tab[id]) {
428 if (!rtnl_rtdsfield_init)
429 rtnl_rtdsfield_initialize();
430 }
431 if (rtnl_rtdsfield_tab[id])
432 return rtnl_rtdsfield_tab[id];
433 snprintf(buf, len, "0x%02x", id);
434 return buf;
435}
436
437
46ac8a55 438int rtnl_dsfield_a2n(__u32 *id, const char *arg)
aba5acdf
SH
439{
440 static char *cache = NULL;
441 static unsigned long res;
442 char *end;
443 int i;
444
445 if (cache && strcmp(cache, arg) == 0) {
446 *id = res;
447 return 0;
448 }
449
450 if (!rtnl_rtdsfield_init)
451 rtnl_rtdsfield_initialize();
452
453 for (i=0; i<256; i++) {
454 if (rtnl_rtdsfield_tab[i] &&
455 strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
456 cache = rtnl_rtdsfield_tab[i];
457 res = i;
458 *id = res;
459 return 0;
460 }
461 }
462
463 res = strtoul(arg, &end, 16);
464 if (!end || end == arg || *end || res > 255)
465 return -1;
466 *id = res;
467 return 0;
468}
469
ac694c33
VD
470
471static struct rtnl_hash_entry dflt_group_entry = { .id = 0, .name = "default" };
472
473static struct rtnl_hash_entry * rtnl_group_hash[256] = {
474 [0] = &dflt_group_entry,
475};
476
477static int rtnl_group_init;
478
479static void rtnl_group_initialize(void)
480{
481 rtnl_group_init = 1;
4e5615b3 482 rtnl_hash_initialize(CONFDIR "/group",
ac694c33
VD
483 rtnl_group_hash, 256);
484}
485
46ac8a55 486int rtnl_group_a2n(int *id, const char *arg)
ac694c33 487{
46ac8a55 488 static const char *cache = NULL;
ac694c33
VD
489 static unsigned long res;
490 struct rtnl_hash_entry *entry;
491 char *end;
492 int i;
493
494 if (cache && strcmp(cache, arg) == 0) {
495 *id = res;
496 return 0;
497 }
498
499 if (!rtnl_group_init)
500 rtnl_group_initialize();
501
502 for (i=0; i<256; i++) {
503 entry = rtnl_group_hash[i];
504 while (entry && strcmp(entry->name, arg))
505 entry = entry->next;
506 if (entry) {
507 cache = entry->name;
508 res = entry->id;
509 *id = res;
510 return 0;
511 }
512 }
513
514 i = strtol(arg, &end, 0);
515 if (!end || end == arg || *end || i < 0)
516 return -1;
517 *id = i;
518 return 0;
519}
c4fdf75d
ST
520
521const char *rtnl_group_n2a(int id, char *buf, int len)
522{
523 struct rtnl_hash_entry *entry;
524 int i;
525
526 if (!rtnl_group_init)
527 rtnl_group_initialize();
528
529 for (i=0; i<256; i++) {
530 entry = rtnl_group_hash[i];
531 if (entry && entry->id == id) {
532 return entry->name;
533 }
534 }
535
536 snprintf(buf, len, "%d", id);
537 return buf;
538}
eef43b50 539
540static char *nl_proto_tab[256] = {
541 [NETLINK_ROUTE] = "rtnl",
542 [NETLINK_UNUSED] = "unused",
543 [NETLINK_USERSOCK] = "usersock",
544 [NETLINK_FIREWALL] = "fw",
545 [NETLINK_SOCK_DIAG] = "tcpdiag",
546 [NETLINK_NFLOG] = "nflog",
547 [NETLINK_XFRM] = "xfrm",
548 [NETLINK_SELINUX] = "selinux",
549 [NETLINK_ISCSI] = "iscsi",
550 [NETLINK_AUDIT] = "audit",
551 [NETLINK_FIB_LOOKUP] = "fiblookup",
552 [NETLINK_CONNECTOR] = "connector",
553 [NETLINK_NETFILTER] = "nft",
554 [NETLINK_IP6_FW] = "ip6fw",
555 [NETLINK_DNRTMSG] = "dec-rt",
556 [NETLINK_KOBJECT_UEVENT] = "uevent",
557 [NETLINK_GENERIC] = "genl",
558 [NETLINK_SCSITRANSPORT] = "scsi-trans",
559 [NETLINK_ECRYPTFS] = "ecryptfs",
560 [NETLINK_RDMA] = "rdma",
561 [NETLINK_CRYPTO] = "crypto",
562};
563
564static int nl_proto_init;
565
566static void nl_proto_initialize(void)
567{
568 nl_proto_init = 1;
569 rtnl_tab_initialize(CONFDIR "/nl_protos",
570 nl_proto_tab, 256);
571}
572
573const char *nl_proto_n2a(int id, char *buf, int len)
574{
575 if (id < 0 || id >= 256) {
576 snprintf(buf, len, "%u", id);
577 return buf;
578 }
579
580 if (!nl_proto_init)
581 nl_proto_initialize();
582
583 if (nl_proto_tab[id])
584 return nl_proto_tab[id];
585
586 snprintf(buf, len, "%u", id);
587 return buf;
588}
589
590int nl_proto_a2n(__u32 *id, const char *arg)
591{
592 static char *cache = NULL;
593 static unsigned long res;
594 char *end;
595 int i;
596
597 if (cache && strcmp(cache, arg) == 0) {
598 *id = res;
599 return 0;
600 }
601
602 if (!nl_proto_init)
603 nl_proto_initialize();
604
605 for (i = 0; i < 256; i++) {
606 if (nl_proto_tab[i] &&
607 strcmp(nl_proto_tab[i], arg) == 0) {
608 cache = nl_proto_tab[i];
609 res = i;
610 *id = res;
611 return 0;
612 }
613 }
614
615 res = strtoul(arg, &end, 0);
616 if (!end || end == arg || *end || res > 255)
617 return -1;
618 *id = res;
619 return 0;
620}