mirror of
https://git.proxmox.com/git/mirror_iproute2
synced 2025-12-17 05:59:14 +00:00
Use hash for routing table name cache
[IPROUTE]: Use hash for routing table name cache Use a hash for routing table name cache instead of the fixed size array. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
This commit is contained in:
parent
bd4bcdad77
commit
9c47d877d8
@ -23,6 +23,51 @@
|
|||||||
|
|
||||||
#include "rt_names.h"
|
#include "rt_names.h"
|
||||||
|
|
||||||
|
struct rtnl_hash_entry {
|
||||||
|
struct rtnl_hash_entry *next;
|
||||||
|
char * name;
|
||||||
|
unsigned int id;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
rtnl_hash_initialize(char *file, struct rtnl_hash_entry **hash, int size)
|
||||||
|
{
|
||||||
|
struct rtnl_hash_entry *entry;
|
||||||
|
char buf[512];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
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)
|
||||||
|
continue;
|
||||||
|
entry = malloc(sizeof(*entry));
|
||||||
|
entry->id = id;
|
||||||
|
entry->name = strdup(namebuf);
|
||||||
|
entry->next = hash[id & (size - 1)];
|
||||||
|
hash[id & (size - 1)] = entry;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
static void rtnl_tab_initialize(char *file, char **tab, int size)
|
static void rtnl_tab_initialize(char *file, char **tab, int size)
|
||||||
{
|
{
|
||||||
char buf[512];
|
char buf[512];
|
||||||
@ -57,7 +102,6 @@ static void rtnl_tab_initialize(char *file, char **tab, int size)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char * rtnl_rtprot_tab[256] = {
|
static char * rtnl_rtprot_tab[256] = {
|
||||||
[RTPROT_UNSPEC] = "none",
|
[RTPROT_UNSPEC] = "none",
|
||||||
[RTPROT_REDIRECT] ="redirect",
|
[RTPROT_REDIRECT] ="redirect",
|
||||||
@ -266,9 +310,14 @@ int rtnl_rtrealm_a2n(__u32 *id, char *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct rtnl_hash_entry dflt_table_entry = { .id = 253, .name = "default" };
|
||||||
|
static struct rtnl_hash_entry main_table_entry = { .id = 254, .name = "main" };
|
||||||
|
static struct rtnl_hash_entry local_table_entry = { .id = 255, .name = "local" };
|
||||||
|
|
||||||
static char * rtnl_rttable_tab[256] = {
|
static struct rtnl_hash_entry * rtnl_rttable_hash[256] = {
|
||||||
"unspec",
|
[253] = &dflt_table_entry,
|
||||||
|
[254] = &main_table_entry,
|
||||||
|
[255] = &local_table_entry,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rtnl_rttable_init;
|
static int rtnl_rttable_init;
|
||||||
@ -276,26 +325,26 @@ static int rtnl_rttable_init;
|
|||||||
static void rtnl_rttable_initialize(void)
|
static void rtnl_rttable_initialize(void)
|
||||||
{
|
{
|
||||||
rtnl_rttable_init = 1;
|
rtnl_rttable_init = 1;
|
||||||
rtnl_rttable_tab[255] = "local";
|
rtnl_hash_initialize("/etc/iproute2/rt_tables",
|
||||||
rtnl_rttable_tab[254] = "main";
|
rtnl_rttable_hash, 256);
|
||||||
rtnl_rttable_tab[253] = "default";
|
|
||||||
rtnl_tab_initialize("/etc/iproute2/rt_tables",
|
|
||||||
rtnl_rttable_tab, 256);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char * rtnl_rttable_n2a(int id, char *buf, int len)
|
char * rtnl_rttable_n2a(int id, char *buf, int len)
|
||||||
{
|
{
|
||||||
if (id<0 || id>=256) {
|
struct rtnl_hash_entry *entry;
|
||||||
snprintf(buf, len, "%d", id);
|
|
||||||
|
if (id >= RT_TABLE_MAX) {
|
||||||
|
snprintf(buf, len, "%u", id);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
if (!rtnl_rttable_tab[id]) {
|
|
||||||
if (!rtnl_rttable_init)
|
if (!rtnl_rttable_init)
|
||||||
rtnl_rttable_initialize();
|
rtnl_rttable_initialize();
|
||||||
}
|
entry = rtnl_rttable_hash[id & 255];
|
||||||
if (rtnl_rttable_tab[id])
|
while (entry && entry->id != id)
|
||||||
return rtnl_rttable_tab[id];
|
entry = entry->next;
|
||||||
snprintf(buf, len, "%d", id);
|
if (entry)
|
||||||
|
return entry->name;
|
||||||
|
snprintf(buf, len, "%u", id);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,6 +352,7 @@ int rtnl_rttable_a2n(__u32 *id, char *arg)
|
|||||||
{
|
{
|
||||||
static char *cache = NULL;
|
static char *cache = NULL;
|
||||||
static unsigned long res;
|
static unsigned long res;
|
||||||
|
struct rtnl_hash_entry *entry;
|
||||||
char *end;
|
char *end;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -315,17 +365,19 @@ int rtnl_rttable_a2n(__u32 *id, char *arg)
|
|||||||
rtnl_rttable_initialize();
|
rtnl_rttable_initialize();
|
||||||
|
|
||||||
for (i=0; i<256; i++) {
|
for (i=0; i<256; i++) {
|
||||||
if (rtnl_rttable_tab[i] &&
|
entry = rtnl_rttable_hash[i];
|
||||||
strcmp(rtnl_rttable_tab[i], arg) == 0) {
|
while (entry && strcmp(entry->name, arg))
|
||||||
cache = rtnl_rttable_tab[i];
|
entry = entry->next;
|
||||||
res = i;
|
if (entry) {
|
||||||
|
cache = entry->name;
|
||||||
|
res = entry->id;
|
||||||
*id = res;
|
*id = res;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i = strtoul(arg, &end, 0);
|
i = strtoul(arg, &end, 0);
|
||||||
if (!end || end == arg || *end || i > 255)
|
if (!end || end == arg || *end || i > RT_TABLE_MAX)
|
||||||
return -1;
|
return -1;
|
||||||
*id = i;
|
*id = i;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user