summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/conf.h2
-rw-r--r--nest/config.Y7
-rw-r--r--nest/proto.c2
-rw-r--r--nest/rt-show.c4
-rw-r--r--nest/rt-table.c50
-rw-r--r--nest/rt.h2
-rw-r--r--proto/bgp/bgp.c4
-rw-r--r--proto/static/static.c4
8 files changed, 56 insertions, 19 deletions
diff --git a/conf/conf.h b/conf/conf.h
index 50e01bf5..ffefa519 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -27,7 +27,7 @@ struct config {
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
const char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
- struct rtable_config *def_tables[NET_MAX]; /* Default routing tables for each network */
+ struct symbol *def_tables[NET_MAX]; /* Default routing tables for each network */
struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */
u32 router_id; /* Our Router ID */
diff --git a/nest/config.Y b/nest/config.Y
index 91147a29..4bf0fefe 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -361,7 +361,11 @@ channel_end:
proto_channel: channel_start channel_opt_list channel_end;
-rtable: CF_SYM_KNOWN { cf_assert_symbol($1, SYM_TABLE); $$ = $1->table; } ;
+rtable: CF_SYM_KNOWN {
+ cf_assert_symbol($1, SYM_TABLE);
+ if (!$1->table) rt_new_default_table($1);
+ $$ = $1->table;
+} ;
imexport:
FILTER filter { $$ = $2; }
@@ -683,6 +687,7 @@ r_args:
}
| r_args TABLE symbol_known {
cf_assert_symbol($3, SYM_TABLE);
+ if (!$3->table) cf_error("Table %s not configured", $3->name);
$$ = $1;
rt_show_add_table($$, $3->table->table);
$$->tables_defined_by = RSD_TDB_DIRECT;
diff --git a/nest/proto.c b/nest/proto.c
index 853b1cf9..ef3e3f4d 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -864,7 +864,7 @@ channel_config_new(const struct channel_class *cc, const char *name, uint net_ty
if (proto->net_type && (net_type != proto->net_type))
cf_error("Different channel type");
- tab = new_config->def_tables[net_type];
+ tab = rt_get_default_table(new_config, net_type);
}
if (!cc)
diff --git a/nest/rt-show.c b/nest/rt-show.c
index 17400029..5d7723cf 100644
--- a/nest/rt-show.c
+++ b/nest/rt-show.c
@@ -400,8 +400,8 @@ rt_show_get_default_tables(struct rt_show_data *d)
}
for (int i=1; i<NET_MAX; i++)
- if (config->def_tables[i] && config->def_tables[i]->table)
- rt_show_add_table(d, config->def_tables[i]->table);
+ if (config->def_tables[i] && config->def_tables[i]->table && config->def_tables[i]->table->table)
+ rt_show_add_table(d, config->def_tables[i]->table->table);
}
static inline void
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 8e1e03fb..f0552965 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -3094,8 +3094,8 @@ rt_preconfig(struct config *c)
{
init_list(&c->tables);
- rt_new_table(cf_get_symbol("master4"), NET_IP4);
- rt_new_table(cf_get_symbol("master6"), NET_IP6);
+ c->def_tables[NET_IP4] = cf_define_symbol(cf_get_symbol("master4"), SYM_TABLE, table, NULL);
+ c->def_tables[NET_IP6] = cf_define_symbol(cf_get_symbol("master6"), SYM_TABLE, table, NULL);
}
void
@@ -3110,6 +3110,13 @@ rt_postconfig(struct config *c)
WALK_LIST(rc, c->tables)
if (rc->gc_period == (uint) -1)
rc->gc_period = (uint) def_gc_period;
+
+ for (uint net_type = 0; net_type < NET_MAX; net_type++)
+ if (c->def_tables[net_type] && !c->def_tables[net_type]->table)
+ {
+ c->def_tables[net_type]->class = SYM_VOID;
+ c->def_tables[net_type] = NULL;
+ }
}
@@ -3584,19 +3591,42 @@ rt_next_hop_update(rtable *tab)
ev_schedule(tab->rt_event);
}
+void
+rt_new_default_table(struct symbol *s)
+{
+ for (uint addr_type = 0; addr_type < NET_MAX; addr_type++)
+ if (s == new_config->def_tables[addr_type])
+ {
+ s->table = rt_new_table(s, addr_type);
+ return;
+ }
+
+ bug("Requested an unknown new default table: %s", s->name);
+}
+
+struct rtable_config *
+rt_get_default_table(struct config *cf, uint addr_type)
+{
+ struct symbol *ts = cf->def_tables[addr_type];
+ if (!ts)
+ return NULL;
+
+ if (!ts->table)
+ rt_new_default_table(ts);
+
+ return ts->table;
+}
struct rtable_config *
rt_new_table(struct symbol *s, uint addr_type)
{
- /* Hack that allows to 'redefine' the master table */
- if ((s->class == SYM_TABLE) &&
- (s->table == new_config->def_tables[addr_type]) &&
- ((addr_type == NET_IP4) || (addr_type == NET_IP6)))
- return s->table;
-
struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config));
- cf_define_symbol(s, SYM_TABLE, table, c);
+ if (s == new_config->def_tables[addr_type])
+ s->table = c;
+ else
+ cf_define_symbol(s, SYM_TABLE, table, c);
+
c->name = s->name;
c->addr_type = addr_type;
c->gc_threshold = 1000;
@@ -3610,7 +3640,7 @@ rt_new_table(struct symbol *s, uint addr_type)
/* First table of each type is kept as default */
if (! new_config->def_tables[addr_type])
- new_config->def_tables[addr_type] = c;
+ new_config->def_tables[addr_type] = s;
return c;
}
diff --git a/nest/rt.h b/nest/rt.h
index 1a6b7a93..f5cf9457 100644
--- a/nest/rt.h
+++ b/nest/rt.h
@@ -481,6 +481,8 @@ void rt_reload_channel_abort(struct channel *c);
void rt_refeed_channel(struct channel *c);
void rt_prune_sync(rtable *t, int all);
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
+void rt_new_default_table(struct symbol *s);
+struct rtable_config *rt_get_default_table(struct config *cf, uint addr_type);
static inline int rt_is_ip(rtable *tab)
{ return (tab->addr_type == NET_IP4) || (tab->addr_type == NET_IP6); }
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 68c788ea..97b18fcf 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -1934,7 +1934,7 @@ bgp_default_igp_table(struct bgp_config *cf, struct bgp_channel_config *cc, u32
return cc2->c.table;
/* Last, try default table of given type */
- if (tab = cf->c.global->def_tables[type])
+ if (tab = rt_get_default_table(cf->c.global, type))
return tab;
cf_error("Undefined IGP table");
@@ -1953,7 +1953,7 @@ bgp_default_base_table(struct bgp_config *cf, struct bgp_channel_config *cc)
return cc2->c.table;
/* Last, try default table of given type */
- struct rtable_config *tab = cf->c.global->def_tables[type];
+ struct rtable_config *tab = rt_get_default_table(cf->c.global, type);
if (tab)
return tab;
diff --git a/proto/static/static.c b/proto/static/static.c
index 65f3eccc..cb764a1c 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -436,11 +436,11 @@ static_postconfig(struct proto_config *CF)
if (!cf->igp_table_ip4)
cf->igp_table_ip4 = (cc->table->addr_type == NET_IP4) ?
- cc->table : cf->c.global->def_tables[NET_IP4];
+ cc->table : rt_get_default_table(cf->c.global, NET_IP4);
if (!cf->igp_table_ip6)
cf->igp_table_ip6 = (cc->table->addr_type == NET_IP6) ?
- cc->table : cf->c.global->def_tables[NET_IP6];
+ cc->table : rt_get_default_table(cf->c.global, NET_IP6);
WALK_LIST(r, cf->routes)
if (r->net && (r->net->type != CF->net_type))