mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-18 17:18:42 +00:00
Default tables are not created unless actually used.
This allows for setting default table values at the beginning of config file before "master4" and "master6" tables are initialized.
This commit is contained in:
parent
34912b029b
commit
397fec4741
@ -27,7 +27,7 @@ struct config {
|
|||||||
|
|
||||||
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
|
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
|
||||||
const char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
|
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 */
|
struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */
|
||||||
|
|
||||||
u32 router_id; /* Our Router ID */
|
u32 router_id; /* Our Router ID */
|
||||||
|
@ -361,7 +361,11 @@ channel_end:
|
|||||||
proto_channel: channel_start channel_opt_list 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:
|
imexport:
|
||||||
FILTER filter { $$ = $2; }
|
FILTER filter { $$ = $2; }
|
||||||
@ -683,6 +687,7 @@ r_args:
|
|||||||
}
|
}
|
||||||
| r_args TABLE symbol_known {
|
| r_args TABLE symbol_known {
|
||||||
cf_assert_symbol($3, SYM_TABLE);
|
cf_assert_symbol($3, SYM_TABLE);
|
||||||
|
if (!$3->table) cf_error("Table %s not configured", $3->name);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
rt_show_add_table($$, $3->table->table);
|
rt_show_add_table($$, $3->table->table);
|
||||||
$$->tables_defined_by = RSD_TDB_DIRECT;
|
$$->tables_defined_by = RSD_TDB_DIRECT;
|
||||||
|
@ -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))
|
if (proto->net_type && (net_type != proto->net_type))
|
||||||
cf_error("Different channel type");
|
cf_error("Different channel type");
|
||||||
|
|
||||||
tab = new_config->def_tables[net_type];
|
tab = rt_get_default_table(new_config, net_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cc)
|
if (!cc)
|
||||||
|
@ -400,8 +400,8 @@ rt_show_get_default_tables(struct rt_show_data *d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i=1; i<NET_MAX; i++)
|
for (int i=1; i<NET_MAX; i++)
|
||||||
if (config->def_tables[i] && 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);
|
rt_show_add_table(d, config->def_tables[i]->table->table);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -3094,8 +3094,8 @@ rt_preconfig(struct config *c)
|
|||||||
{
|
{
|
||||||
init_list(&c->tables);
|
init_list(&c->tables);
|
||||||
|
|
||||||
rt_new_table(cf_get_symbol("master4"), NET_IP4);
|
c->def_tables[NET_IP4] = cf_define_symbol(cf_get_symbol("master4"), SYM_TABLE, table, NULL);
|
||||||
rt_new_table(cf_get_symbol("master6"), NET_IP6);
|
c->def_tables[NET_IP6] = cf_define_symbol(cf_get_symbol("master6"), SYM_TABLE, table, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3110,6 +3110,13 @@ rt_postconfig(struct config *c)
|
|||||||
WALK_LIST(rc, c->tables)
|
WALK_LIST(rc, c->tables)
|
||||||
if (rc->gc_period == (uint) -1)
|
if (rc->gc_period == (uint) -1)
|
||||||
rc->gc_period = (uint) def_gc_period;
|
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);
|
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 *
|
struct rtable_config *
|
||||||
rt_new_table(struct symbol *s, uint addr_type)
|
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));
|
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->name = s->name;
|
||||||
c->addr_type = addr_type;
|
c->addr_type = addr_type;
|
||||||
c->gc_threshold = 1000;
|
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 */
|
/* First table of each type is kept as default */
|
||||||
if (! new_config->def_tables[addr_type])
|
if (! new_config->def_tables[addr_type])
|
||||||
new_config->def_tables[addr_type] = c;
|
new_config->def_tables[addr_type] = s;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
@ -481,6 +481,8 @@ void rt_reload_channel_abort(struct channel *c);
|
|||||||
void rt_refeed_channel(struct channel *c);
|
void rt_refeed_channel(struct channel *c);
|
||||||
void rt_prune_sync(rtable *t, int all);
|
void rt_prune_sync(rtable *t, int all);
|
||||||
struct rtable_config *rt_new_table(struct symbol *s, uint addr_type);
|
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)
|
static inline int rt_is_ip(rtable *tab)
|
||||||
{ return (tab->addr_type == NET_IP4) || (tab->addr_type == NET_IP6); }
|
{ return (tab->addr_type == NET_IP4) || (tab->addr_type == NET_IP6); }
|
||||||
|
@ -1934,7 +1934,7 @@ bgp_default_igp_table(struct bgp_config *cf, struct bgp_channel_config *cc, u32
|
|||||||
return cc2->c.table;
|
return cc2->c.table;
|
||||||
|
|
||||||
/* Last, try default table of given type */
|
/* 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;
|
return tab;
|
||||||
|
|
||||||
cf_error("Undefined IGP table");
|
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;
|
return cc2->c.table;
|
||||||
|
|
||||||
/* Last, try default table of given type */
|
/* 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)
|
if (tab)
|
||||||
return tab;
|
return tab;
|
||||||
|
|
||||||
|
@ -436,11 +436,11 @@ static_postconfig(struct proto_config *CF)
|
|||||||
|
|
||||||
if (!cf->igp_table_ip4)
|
if (!cf->igp_table_ip4)
|
||||||
cf->igp_table_ip4 = (cc->table->addr_type == NET_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)
|
if (!cf->igp_table_ip6)
|
||||||
cf->igp_table_ip6 = (cc->table->addr_type == NET_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)
|
WALK_LIST(r, cf->routes)
|
||||||
if (r->net && (r->net->type != CF->net_type))
|
if (r->net && (r->net->type != CF->net_type))
|
||||||
|
Loading…
Reference in New Issue
Block a user