diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ChangeLog | 8 | ||||
-rw-r--r-- | lib/Makefile.am | 4 | ||||
-rw-r--r-- | lib/rt_names.c | 412 | ||||
-rw-r--r-- | lib/rt_names.h | 28 | ||||
-rw-r--r-- | lib/zclient.c | 5 | ||||
-rw-r--r-- | lib/zclient.h | 7 | ||||
-rw-r--r-- | lib/zebra.h | 4 |
7 files changed, 466 insertions, 2 deletions
diff --git a/lib/ChangeLog b/lib/ChangeLog index 01f45ba5..e2c25ca6 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -483,6 +483,14 @@ * memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE +2005-04-24 Calin Velea <vcalinus@gemenii.ro> + + * rt_names.c, rt_names.h: Library for realm name support - original + iproute2 version modified to support name database reloading + * zclient.c, zclient.h: API realmto message + * zebra.h: Include rt_names.h + + 2005-05-24 Paul Jakma <paul@dishone.st> * memtypes.h: update this auto-built file. (maybe we should just diff --git a/lib/Makefile.am b/lib/Makefile.am index 315e919b..2bd25235 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -12,7 +12,7 @@ libzebra_la_SOURCES = \ sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \ filter.c routemap.c distribute.c stream.c str.c log.c plist.c \ zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c \ - sigevent.c pqueue.c jhash.c memtypes.c workqueue.c + sigevent.c pqueue.c jhash.c memtypes.c workqueue.c rt_names.c BUILT_SOURCES = memtypes.h route_types.h @@ -27,7 +27,7 @@ pkginclude_HEADERS = \ str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \ plist.h zclient.h sockopt.h smux.h md5.h if_rmap.h keychain.h \ privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \ - workqueue.h route_types.h + workqueue.h route_types.h rt_names.h EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.awk route_types.txt diff --git a/lib/rt_names.c b/lib/rt_names.c new file mode 100644 index 00000000..6ed2d7ab --- /dev/null +++ b/lib/rt_names.c @@ -0,0 +1,412 @@ +/* + * rt_names.c rtnetlink names DB. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> + * + * Fix: 23 Apr 2005 Calin Velea <vcalinus@gemenii.ro> + * + * bgpd-specific fixes + * + * - Modified rtnl_tab_initialize() function to free allocated entries + * before re-reading table; rtnl_rtrealm_initialize() to zero + * unused entries at first call + * - Modified rtnl_rtrealm_a2n() to read realm table each time; otherwise + * bgpd restart was necessary to be in sync with /etc/iproute2/rt_realms + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <syslog.h> +#include <fcntl.h> +#include <string.h> +#include <sys/time.h> + +static void rtnl_tab_initialize(char *file, char **tab, int size) +{ + int i; + char buf[512]; + FILE *fp; + + for(i = 1; i < 255; i++) + if(tab[i]) { + free(tab[i]); + tab[i] = NULL; + } + + + fp = fopen(file, "r"); + if (!fp) + return; + while (fgets(buf, sizeof(buf), fp)) { + char *p = buf; + int id; + char namebuf[512]; + + while (*p == ' ' || *p == '\t') + p++; + if (*p == '#' || *p == '\n' || *p == 0) + continue; + if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 && + sscanf(p, "0x%x %s #", &id, namebuf) != 2 && + sscanf(p, "%d %s\n", &id, namebuf) != 2 && + sscanf(p, "%d %s #", &id, namebuf) != 2) { + fprintf(stderr, "Database %s is corrupted at %s\n", + file, p); + return; + } + + if (id<0 || id>size) + continue; + + tab[id] = strdup(namebuf); + } + fclose(fp); +} + + +static char * rtnl_rtprot_tab[256] = { + "none", + "redirect", + "kernel", + "boot", + "static", + NULL, + NULL, + NULL, + "gated", + "ra", + "mrt", + "zebra", + "bird", +}; + + + +static int rtnl_rtprot_init; + +static void rtnl_rtprot_initialize(void) +{ + rtnl_rtprot_init = 1; + rtnl_tab_initialize("/etc/iproute2/rt_protos", + rtnl_rtprot_tab, 256); +} + +char * rtnl_rtprot_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtprot_tab[id]) { + if (!rtnl_rtprot_init) + rtnl_rtprot_initialize(); + } + if (rtnl_rtprot_tab[id]) + return rtnl_rtprot_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + +int rtnl_rtprot_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rtprot_init) + rtnl_rtprot_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtprot_tab[i] && + strcmp(rtnl_rtprot_tab[i], arg) == 0) { + cache = rtnl_rtprot_tab[i]; + res = i; + *id = res; + return 0; + } + } + + res = strtoul(arg, &end, 0); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + + + +static char * rtnl_rtscope_tab[256] = { + "global", +}; + +static int rtnl_rtscope_init; + +static void rtnl_rtscope_initialize(void) +{ + rtnl_rtscope_init = 1; + rtnl_rtscope_tab[255] = "nowhere"; + rtnl_rtscope_tab[254] = "host"; + rtnl_rtscope_tab[253] = "link"; + rtnl_rtscope_tab[200] = "site"; + rtnl_tab_initialize("/etc/iproute2/rt_scopes", + rtnl_rtscope_tab, 256); +} + +char * rtnl_rtscope_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtscope_tab[id]) { + if (!rtnl_rtscope_init) + rtnl_rtscope_initialize(); + } + if (rtnl_rtscope_tab[id]) + return rtnl_rtscope_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + +int rtnl_rtscope_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rtscope_init) + rtnl_rtscope_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtscope_tab[i] && + strcmp(rtnl_rtscope_tab[i], arg) == 0) { + cache = rtnl_rtscope_tab[i]; + res = i; + *id = res; + return 0; + } + } + + res = strtoul(arg, &end, 0); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + + + +static char * rtnl_rtrealm_tab[256] = { + "unknown", +}; + +static int rtnl_rtrealm_init = 0; + +static void rtnl_rtrealm_initialize(void) +{ + int i; + + if(!rtnl_rtrealm_init) + for(i = 1; i < 255; i++) + rtnl_rtrealm_tab[i] = NULL; + + rtnl_rtrealm_init = 1; + rtnl_tab_initialize("/etc/iproute2/rt_realms", + rtnl_rtrealm_tab, 256); +} + +char * rtnl_rtrealm_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtrealm_tab[id]) { + if (!rtnl_rtrealm_init) + rtnl_rtrealm_initialize(); + } + if (rtnl_rtrealm_tab[id]) + return rtnl_rtrealm_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + + +int rtnl_rtrealm_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long cache_res; + unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = cache_res; + return 0; + } + rtnl_rtrealm_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtrealm_tab[i] && + strcmp(rtnl_rtrealm_tab[i], arg) == 0) { + cache = rtnl_rtrealm_tab[i]; + cache_res = i; + *id = cache_res; + return 0; + } + } + + res = strtoul(arg, &end, 0); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + + + +static char * rtnl_rttable_tab[256] = { + "unspec", +}; + +static int rtnl_rttable_init; + +static void rtnl_rttable_initialize(void) +{ + rtnl_rttable_init = 1; + rtnl_rttable_tab[255] = "local"; + rtnl_rttable_tab[254] = "main"; + rtnl_tab_initialize("/etc/iproute2/rt_tables", + rtnl_rttable_tab, 256); +} + +char * rtnl_rttable_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rttable_tab[id]) { + if (!rtnl_rttable_init) + rtnl_rttable_initialize(); + } + if (rtnl_rttable_tab[id]) + return rtnl_rttable_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + +int rtnl_rttable_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rttable_init) + rtnl_rttable_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rttable_tab[i] && + strcmp(rtnl_rttable_tab[i], arg) == 0) { + cache = rtnl_rttable_tab[i]; + res = i; + *id = res; + return 0; + } + } + + i = strtoul(arg, &end, 0); + if (!end || end == arg || *end || i > 255) + return -1; + *id = i; + return 0; +} + + +static char * rtnl_rtdsfield_tab[256] = { + "0", +}; + +static int rtnl_rtdsfield_init; + +static void rtnl_rtdsfield_initialize(void) +{ + rtnl_rtdsfield_init = 1; + rtnl_tab_initialize("/etc/iproute2/rt_dsfield", + rtnl_rtdsfield_tab, 256); +} + +char * rtnl_dsfield_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtdsfield_tab[id]) { + if (!rtnl_rtdsfield_init) + rtnl_rtdsfield_initialize(); + } + if (rtnl_rtdsfield_tab[id]) + return rtnl_rtdsfield_tab[id]; + snprintf(buf, len, "0x%02x", id); + return buf; +} + + +int rtnl_dsfield_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rtdsfield_init) + rtnl_rtdsfield_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtdsfield_tab[i] && + strcmp(rtnl_rtdsfield_tab[i], arg) == 0) { + cache = rtnl_rtdsfield_tab[i]; + res = i; + *id = res; + return 0; + } + } + + res = strtoul(arg, &end, 16); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + diff --git a/lib/rt_names.h b/lib/rt_names.h new file mode 100644 index 00000000..6ac29204 --- /dev/null +++ b/lib/rt_names.h @@ -0,0 +1,28 @@ +#ifndef RT_NAMES_H_ +#define RT_NAMES_H_ 1 + +const char* rtnl_rtprot_n2a(int id, char *buf, int len); +const char* rtnl_rtscope_n2a(int id, char *buf, int len); +const char* rtnl_rttable_n2a(int id, char *buf, int len); +const char* rtnl_rtrealm_n2a(int id, char *buf, int len); +const char* rtnl_dsfield_n2a(int id, char *buf, int len); +int rtnl_rtprot_a2n(int *id, char *arg); +int rtnl_rtscope_a2n(int *id, char *arg); +int rtnl_rttable_a2n(int *id, char *arg); +int rtnl_rtrealm_a2n(__u32 *id, char *arg); +int rtnl_dsfield_a2n(__u32 *id, char *arg); + +const char *inet_proto_n2a(int proto, char *buf, int len); +int inet_proto_a2n(char *buf); + + +const char * ll_type_n2a(int type, char *buf, int len); + +const char *ll_addr_n2a(unsigned char *addr, int alen, int type, char *buf, int blen); +int ll_addr_a2n(unsigned char *lladdr, int len, char *arg); + +const char * ll_proto_n2a(unsigned short id, char *buf, int len); +int ll_proto_a2n(unsigned short *id, char *buf); + + +#endif diff --git a/lib/zclient.c b/lib/zclient.c index a253af61..b6858fab 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -475,6 +475,11 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) stream_putl (s, api->metric); +#ifdef SUPPORT_REALMS + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_REALMTO)) + stream_putw (s, api->realmto); +#endif + /* Put length at the first point of the stream. */ stream_putw_at (s, 0, stream_get_endp (s)); diff --git a/lib/zclient.h b/lib/zclient.h index 69ada144..749f1182 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -87,6 +87,10 @@ struct zclient #define ZAPI_MESSAGE_DISTANCE 0x04 #define ZAPI_MESSAGE_METRIC 0x08 +#ifdef SUPPORT_REALMS + #define ZAPI_MESSAGE_REALMTO 0x10 +#endif + /* Zserv protocol message header */ struct zserv_header { @@ -117,6 +121,9 @@ struct zapi_ipv4 u_char distance; u_int32_t metric; +#ifdef SUPPORT_REALMS + u_int16_t realmto; +#endif }; /* Prototypes of zebra client service functions. */ diff --git a/lib/zebra.h b/lib/zebra.h index 2e2f8cda..2b7ff442 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -232,6 +232,10 @@ typedef int socklen_t; #include <libutil.h> #endif /* HAVE_LIBUTIL_H */ +#ifdef SUPPORT_REALMS +#include <rt_names.h> +#endif + #ifdef HAVE_GLIBC_BACKTRACE #include <execinfo.h> #endif /* HAVE_GLIBC_BACKTRACE */ |