mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-03-21 22:07:03 +00:00
Merge commit '51f2e7af' into thread-next
Conflicts: conf/cf-lex.l conf/conf.h conf/confbase.Y filter/config.Y nest/config.Y nest/proto.c nest/rt-table.c proto/bgp/bgp.c sysdep/unix/main.c
This commit is contained in:
commit
0ba22509a8
110
conf/cf-lex.l
110
conf/cf-lex.l
@ -565,10 +565,10 @@ check_eof(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void cf_swap_soft_scope(void);
|
static inline void cf_swap_soft_scope(struct config *conf);
|
||||||
|
|
||||||
static struct symbol *
|
static struct symbol *
|
||||||
cf_new_symbol(const byte *c)
|
cf_new_symbol(struct sym_scope *scope, pool *p, struct linpool *lp, const byte *c)
|
||||||
{
|
{
|
||||||
struct symbol *s;
|
struct symbol *s;
|
||||||
|
|
||||||
@ -576,18 +576,16 @@ cf_new_symbol(const byte *c)
|
|||||||
if (l > SYM_MAX_LEN)
|
if (l > SYM_MAX_LEN)
|
||||||
cf_error("Symbol too long");
|
cf_error("Symbol too long");
|
||||||
|
|
||||||
cf_swap_soft_scope();
|
s = lp_alloc(lp, sizeof(struct symbol) + l + 1);
|
||||||
|
*s = (struct symbol) { .scope = scope, .class = SYM_VOID, };
|
||||||
s = cfg_allocz(sizeof(struct symbol) + l + 1);
|
|
||||||
*s = (struct symbol) { .scope = conf_this_scope, .class = SYM_VOID, };
|
|
||||||
memcpy(s->name, c, l+1);
|
memcpy(s->name, c, l+1);
|
||||||
|
|
||||||
if (!conf_this_scope->hash.data)
|
if (!scope->hash.data)
|
||||||
HASH_INIT(conf_this_scope->hash, new_config->pool, SYM_ORDER);
|
HASH_INIT(scope->hash, p, SYM_ORDER);
|
||||||
|
|
||||||
HASH_INSERT2(conf_this_scope->hash, SYM, new_config->pool, s);
|
HASH_INSERT2(scope->hash, SYM, p, s);
|
||||||
|
|
||||||
if (conf_this_scope == new_config->root_scope)
|
if (new_config && (scope == new_config->root_scope))
|
||||||
add_tail(&(new_config->symbols), &(s->n));
|
add_tail(&(new_config->symbols), &(s->n));
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
@ -648,9 +646,12 @@ cf_find_symbol_scope(const struct sym_scope *scope, const byte *c)
|
|||||||
* existing symbol is found.
|
* existing symbol is found.
|
||||||
*/
|
*/
|
||||||
struct symbol *
|
struct symbol *
|
||||||
cf_get_symbol(const byte *c)
|
cf_get_symbol(struct config *conf, const byte *c)
|
||||||
{
|
{
|
||||||
return cf_find_symbol_scope(conf_this_scope, c) ?: cf_new_symbol(c);
|
return cf_find_symbol_scope(conf->current_scope, c) ?: (
|
||||||
|
cf_swap_soft_scope(conf),
|
||||||
|
cf_new_symbol(conf->current_scope, conf->pool, conf->mem, c)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -661,22 +662,23 @@ cf_get_symbol(const byte *c)
|
|||||||
* for purposes of cf_define_symbol().
|
* for purposes of cf_define_symbol().
|
||||||
*/
|
*/
|
||||||
struct symbol *
|
struct symbol *
|
||||||
cf_localize_symbol(struct symbol *sym)
|
cf_localize_symbol(struct config *conf, struct symbol *sym)
|
||||||
{
|
{
|
||||||
/* If the symbol type is void, it has been recently allocated just in this scope. */
|
/* If the symbol type is void, it has been recently allocated just in this scope. */
|
||||||
if (!sym->class)
|
if (!sym->class)
|
||||||
return sym;
|
return sym;
|
||||||
|
|
||||||
/* If the scope is the current, it is already defined in this scope. */
|
/* If the scope is the current, it is already defined in this scope. */
|
||||||
if (cf_symbol_is_local(sym))
|
if (cf_symbol_is_local(conf, sym))
|
||||||
cf_error("Symbol '%s' already defined", sym->name);
|
cf_error("Symbol '%s' already defined", sym->name);
|
||||||
|
|
||||||
/* Not allocated here yet, doing it now. */
|
/* Not allocated here yet, doing it now. */
|
||||||
return cf_new_symbol(sym->name);
|
cf_swap_soft_scope(conf);
|
||||||
|
return cf_new_symbol(conf->current_scope, conf->pool, conf->mem, sym->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct symbol *
|
struct symbol *
|
||||||
cf_default_name(char *template, int *counter)
|
cf_default_name(struct config *conf, char *template, int *counter)
|
||||||
{
|
{
|
||||||
char buf[SYM_MAX_LEN];
|
char buf[SYM_MAX_LEN];
|
||||||
struct symbol *s;
|
struct symbol *s;
|
||||||
@ -685,7 +687,7 @@ cf_default_name(char *template, int *counter)
|
|||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
bsprintf(buf, template, ++(*counter));
|
bsprintf(buf, template, ++(*counter));
|
||||||
s = cf_get_symbol(buf);
|
s = cf_get_symbol(conf, buf);
|
||||||
if (s->class == SYM_VOID)
|
if (s->class == SYM_VOID)
|
||||||
return s;
|
return s;
|
||||||
if (!perc)
|
if (!perc)
|
||||||
@ -698,19 +700,18 @@ static enum yytokentype
|
|||||||
cf_lex_symbol(const char *data)
|
cf_lex_symbol(const char *data)
|
||||||
{
|
{
|
||||||
/* Have we defined such a symbol? */
|
/* Have we defined such a symbol? */
|
||||||
struct symbol *sym = cf_get_symbol(data);
|
struct symbol *sym = cf_get_symbol(new_config, data);
|
||||||
cf_lval.s = sym;
|
cf_lval.s = sym;
|
||||||
|
|
||||||
switch (sym->class)
|
switch (sym->class)
|
||||||
{
|
{
|
||||||
case SYM_KEYWORD:
|
case SYM_KEYWORD:
|
||||||
if (sym->keyword->value > 0)
|
{
|
||||||
return sym->keyword->value;
|
int val = sym->keyword->value;
|
||||||
else
|
if (val > 0) return val;
|
||||||
{
|
cf_lval.i = -val;
|
||||||
cf_lval.i = -sym->keyword->value;
|
return ENUM;
|
||||||
return ENUM;
|
}
|
||||||
}
|
|
||||||
case SYM_VOID:
|
case SYM_VOID:
|
||||||
return CF_SYM_UNDEFINED;
|
return CF_SYM_UNDEFINED;
|
||||||
default:
|
default:
|
||||||
@ -721,7 +722,9 @@ cf_lex_symbol(const char *data)
|
|||||||
void
|
void
|
||||||
ea_lex_register(struct ea_class *def)
|
ea_lex_register(struct ea_class *def)
|
||||||
{
|
{
|
||||||
def->sym = cf_define_symbol(cf_root_symbol(def->name, &global_filter_scope), SYM_ATTRIBUTE, attribute, def);
|
def->sym = cf_root_symbol(def->name, &global_filter_scope);
|
||||||
|
def->sym->class = SYM_ATTRIBUTE;
|
||||||
|
def->sym->attribute = def;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -763,7 +766,11 @@ cf_lex_init(int is_cli, struct config *c)
|
|||||||
global_root_scope_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Keywords pool");
|
global_root_scope_pool = rp_new(&root_pool, the_bird_domain.the_bird, "Keywords pool");
|
||||||
|
|
||||||
for (const struct keyword *k = keyword_list; k->name; k++)
|
for (const struct keyword *k = keyword_list; k->name; k++)
|
||||||
cf_define_symbol(cf_root_symbol(k->name, &global_root_scope), SYM_KEYWORD, keyword, k);
|
{
|
||||||
|
struct symbol *s = cf_root_symbol(k->name, &global_root_scope);
|
||||||
|
s->class = SYM_KEYWORD;
|
||||||
|
s->keyword = k;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ifs_head = ifs = push_ifs(NULL);
|
ifs_head = ifs = push_ifs(NULL);
|
||||||
@ -782,14 +789,13 @@ cf_lex_init(int is_cli, struct config *c)
|
|||||||
else
|
else
|
||||||
BEGIN(INITIAL);
|
BEGIN(INITIAL);
|
||||||
|
|
||||||
c->root_scope = cfg_allocz(sizeof(struct sym_scope));
|
c->root_scope = c->current_scope = cfg_allocz(sizeof(struct sym_scope));
|
||||||
conf_this_scope = c->root_scope;
|
c->root_scope->active = 1;
|
||||||
conf_this_scope->active = 1;
|
|
||||||
|
|
||||||
if (is_cli)
|
if (is_cli)
|
||||||
conf_this_scope->next = config->root_scope;
|
c->current_scope->next = config->root_scope;
|
||||||
else
|
else
|
||||||
conf_this_scope->next = &global_filter_scope;
|
c->current_scope->next = &global_filter_scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -803,12 +809,12 @@ cf_lex_init(int is_cli, struct config *c)
|
|||||||
* in all scopes stored on the stack.
|
* in all scopes stored on the stack.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cf_push_scope(struct symbol *sym)
|
cf_push_scope(struct config *conf, struct symbol *sym)
|
||||||
{
|
{
|
||||||
struct sym_scope *s = cfg_allocz(sizeof(struct sym_scope));
|
struct sym_scope *s = cfg_allocz(sizeof(struct sym_scope));
|
||||||
|
|
||||||
s->next = conf_this_scope;
|
s->next = conf->current_scope;
|
||||||
conf_this_scope = s;
|
conf->current_scope = s;
|
||||||
s->active = 1;
|
s->active = 1;
|
||||||
s->name = sym;
|
s->name = sym;
|
||||||
s->slots = 0;
|
s->slots = 0;
|
||||||
@ -822,14 +828,14 @@ cf_push_scope(struct symbol *sym)
|
|||||||
* invisible to the rest of the config.
|
* invisible to the rest of the config.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cf_pop_scope(void)
|
cf_pop_scope(struct config *conf)
|
||||||
{
|
{
|
||||||
ASSERT(!conf_this_scope->soft_scopes);
|
ASSERT(!conf->current_scope->soft_scopes);
|
||||||
|
|
||||||
conf_this_scope->active = 0;
|
conf->current_scope->active = 0;
|
||||||
conf_this_scope = conf_this_scope->next;
|
conf->current_scope = conf->current_scope->next;
|
||||||
|
|
||||||
ASSERT(conf_this_scope);
|
ASSERT(conf->current_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -840,12 +846,12 @@ cf_pop_scope(void)
|
|||||||
* Such scope will be converted to a regular scope on first use.
|
* Such scope will be converted to a regular scope on first use.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cf_push_soft_scope(void)
|
cf_push_soft_scope(struct config *conf)
|
||||||
{
|
{
|
||||||
if (conf_this_scope->soft_scopes < 0xfe)
|
if (conf->current_scope->soft_scopes < 0xfe)
|
||||||
conf_this_scope->soft_scopes++;
|
conf->current_scope->soft_scopes++;
|
||||||
else
|
else
|
||||||
cf_push_block_scope();
|
cf_push_block_scope(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -854,12 +860,12 @@ cf_push_soft_scope(void)
|
|||||||
* Leave a soft scope entered by cf_push_soft_scope().
|
* Leave a soft scope entered by cf_push_soft_scope().
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cf_pop_soft_scope(void)
|
cf_pop_soft_scope(struct config *conf)
|
||||||
{
|
{
|
||||||
if (conf_this_scope->soft_scopes)
|
if (conf->current_scope->soft_scopes)
|
||||||
conf_this_scope->soft_scopes--;
|
conf->current_scope->soft_scopes--;
|
||||||
else
|
else
|
||||||
cf_pop_block_scope();
|
cf_pop_block_scope(conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -869,12 +875,12 @@ cf_pop_soft_scope(void)
|
|||||||
* on first use. It is done automatically by cf_new_symbol().
|
* on first use. It is done automatically by cf_new_symbol().
|
||||||
*/
|
*/
|
||||||
static inline void
|
static inline void
|
||||||
cf_swap_soft_scope(void)
|
cf_swap_soft_scope(struct config *conf)
|
||||||
{
|
{
|
||||||
if (conf_this_scope->soft_scopes)
|
if (conf->current_scope->soft_scopes)
|
||||||
{
|
{
|
||||||
conf_this_scope->soft_scopes--;
|
conf->current_scope->soft_scopes--;
|
||||||
cf_push_block_scope();
|
cf_push_block_scope(conf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
33
conf/conf.h
33
conf/conf.h
@ -57,6 +57,7 @@ struct config {
|
|||||||
int thread_count; /* How many worker threads to prefork */
|
int thread_count; /* How many worker threads to prefork */
|
||||||
|
|
||||||
struct sym_scope *root_scope; /* Scope for root symbols */
|
struct sym_scope *root_scope; /* Scope for root symbols */
|
||||||
|
struct sym_scope *current_scope; /* Current scope where we are actually in while parsing */
|
||||||
_Atomic int obstacle_count; /* Number of items blocking freeing of this config */
|
_Atomic int obstacle_count; /* Number of items blocking freeing of this config */
|
||||||
event done_event; /* Called when obstacle_count reaches zero */
|
event done_event; /* Called when obstacle_count reaches zero */
|
||||||
int shutdown; /* This is a pseudo-config for daemon shutdown */
|
int shutdown; /* This is a pseudo-config for daemon shutdown */
|
||||||
@ -191,8 +192,6 @@ struct include_file_stack {
|
|||||||
|
|
||||||
extern struct include_file_stack *ifs;
|
extern struct include_file_stack *ifs;
|
||||||
|
|
||||||
extern struct sym_scope *conf_this_scope;
|
|
||||||
|
|
||||||
int cf_lex(void);
|
int cf_lex(void);
|
||||||
void cf_lex_init(int is_cli, struct config *c);
|
void cf_lex_init(int is_cli, struct config *c);
|
||||||
void cf_lex_unwind(void);
|
void cf_lex_unwind(void);
|
||||||
@ -206,12 +205,12 @@ static inline struct symbol *cf_find_symbol_cfg(const struct config *cfg, const
|
|||||||
struct sym_scope: cf_find_symbol_scope \
|
struct sym_scope: cf_find_symbol_scope \
|
||||||
)((where), (what))
|
)((where), (what))
|
||||||
|
|
||||||
struct symbol *cf_get_symbol(const byte *c);
|
struct symbol *cf_get_symbol(struct config *conf, const byte *c);
|
||||||
struct symbol *cf_default_name(char *template, int *counter);
|
struct symbol *cf_default_name(struct config *conf, char *template, int *counter);
|
||||||
struct symbol *cf_localize_symbol(struct symbol *sym);
|
struct symbol *cf_localize_symbol(struct config *conf, struct symbol *sym);
|
||||||
|
|
||||||
static inline int cf_symbol_is_local(struct symbol *sym)
|
static inline int cf_symbol_is_local(struct config *conf, struct symbol *sym)
|
||||||
{ return (sym->scope == conf_this_scope) && !conf_this_scope->soft_scopes; }
|
{ return (sym->scope == conf->current_scope) && !conf->current_scope->soft_scopes; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cf_define_symbol - define meaning of a symbol
|
* cf_define_symbol - define meaning of a symbol
|
||||||
@ -228,22 +227,22 @@ static inline int cf_symbol_is_local(struct symbol *sym)
|
|||||||
* Result: Pointer to the newly defined symbol. If we are in the top-level
|
* Result: Pointer to the newly defined symbol. If we are in the top-level
|
||||||
* scope, it's the same @sym as passed to the function.
|
* scope, it's the same @sym as passed to the function.
|
||||||
*/
|
*/
|
||||||
#define cf_define_symbol(osym_, type_, var_, def_) ({ \
|
#define cf_define_symbol(conf_, osym_, type_, var_, def_) ({ \
|
||||||
struct symbol *sym_ = cf_localize_symbol(osym_); \
|
struct symbol *sym_ = cf_localize_symbol(conf_, osym_); \
|
||||||
sym_->class = type_; \
|
sym_->class = type_; \
|
||||||
sym_->var_ = def_; \
|
sym_->var_ = def_; \
|
||||||
sym_; })
|
sym_; })
|
||||||
|
|
||||||
void cf_push_scope(struct symbol *);
|
void cf_push_scope(struct config *, struct symbol *);
|
||||||
void cf_pop_scope(void);
|
void cf_pop_scope(struct config *);
|
||||||
void cf_push_soft_scope(void);
|
void cf_push_soft_scope(struct config *);
|
||||||
void cf_pop_soft_scope(void);
|
void cf_pop_soft_scope(struct config *);
|
||||||
|
|
||||||
static inline void cf_push_block_scope(void)
|
static inline void cf_push_block_scope(struct config *conf)
|
||||||
{ cf_push_scope(NULL); conf_this_scope->block = 1; }
|
{ cf_push_scope(conf, NULL); conf->current_scope->block = 1; }
|
||||||
|
|
||||||
static inline void cf_pop_block_scope(void)
|
static inline void cf_pop_block_scope(struct config *conf)
|
||||||
{ ASSERT(conf_this_scope->block); cf_pop_scope(); }
|
{ ASSERT(conf->current_scope->block); cf_pop_scope(conf); }
|
||||||
|
|
||||||
char *cf_symbol_class_name(struct symbol *sym);
|
char *cf_symbol_class_name(struct symbol *sym);
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ conf: definition ;
|
|||||||
definition:
|
definition:
|
||||||
DEFINE symbol '=' term ';' {
|
DEFINE symbol '=' term ';' {
|
||||||
struct f_val *val = cf_eval($4, T_VOID);
|
struct f_val *val = cf_eval($4, T_VOID);
|
||||||
cf_define_symbol($2, SYM_CONSTANT | val->type, val, val);
|
cf_define_symbol(new_config, $2, SYM_CONSTANT | val->type, val, val);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -400,15 +400,15 @@ conf: FILTER STACKS expr expr ';' {
|
|||||||
conf: filter_def ;
|
conf: filter_def ;
|
||||||
filter_def:
|
filter_def:
|
||||||
FILTER symbol {
|
FILTER symbol {
|
||||||
$2 = cf_define_symbol($2, SYM_FILTER, filter, NULL);
|
$2 = cf_define_symbol(new_config, $2, SYM_FILTER, filter, NULL);
|
||||||
cf_enter_filters();
|
cf_enter_filters();
|
||||||
cf_push_scope( $2 );
|
cf_push_scope( new_config, $2 );
|
||||||
} filter_body {
|
} filter_body {
|
||||||
struct filter *f = cfg_alloc(sizeof(struct filter));
|
struct filter *f = cfg_alloc(sizeof(struct filter));
|
||||||
*f = (struct filter) { .sym = $2, .root = $4 };
|
*f = (struct filter) { .sym = $2, .root = $4 };
|
||||||
$2->filter = f;
|
$2->filter = f;
|
||||||
|
|
||||||
cf_pop_scope();
|
cf_pop_scope(new_config);
|
||||||
cf_exit_filters();
|
cf_exit_filters();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -423,7 +423,7 @@ custom_attr: ATTRIBUTE type symbol ';' {
|
|||||||
if (($3->class == SYM_ATTRIBUTE) && ($3->scope == new_config->root_scope))
|
if (($3->class == SYM_ATTRIBUTE) && ($3->scope == new_config->root_scope))
|
||||||
cf_error("Duplicate attribute %s definition", $3->name);
|
cf_error("Duplicate attribute %s definition", $3->name);
|
||||||
|
|
||||||
cf_define_symbol($3, SYM_ATTRIBUTE, attribute,
|
cf_define_symbol(new_config, $3, SYM_ATTRIBUTE, attribute,
|
||||||
ea_register_alloc(new_config->pool, (struct ea_class) {
|
ea_register_alloc(new_config->pool, (struct ea_class) {
|
||||||
.name = $3->name,
|
.name = $3->name,
|
||||||
.type = $2,
|
.type = $2,
|
||||||
@ -502,7 +502,7 @@ function_argsn:
|
|||||||
| function_argsn type symbol ';' {
|
| function_argsn type symbol ';' {
|
||||||
if ($3->scope->slots >= 0xfe) cf_error("Too many declarations, at most 255 allowed");
|
if ($3->scope->slots >= 0xfe) cf_error("Too many declarations, at most 255 allowed");
|
||||||
$$ = cfg_alloc(sizeof(struct f_arg));
|
$$ = cfg_alloc(sizeof(struct f_arg));
|
||||||
$$->arg = cf_define_symbol($3, SYM_VARIABLE | $2, offset, sym_->scope->slots++);
|
$$->arg = cf_define_symbol(new_config, $3, SYM_VARIABLE | $2, offset, sym_->scope->slots++);
|
||||||
$$->next = $1;
|
$$->next = $1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -511,7 +511,7 @@ function_args:
|
|||||||
'(' ')' { $$ = NULL; }
|
'(' ')' { $$ = NULL; }
|
||||||
| '(' function_argsn type symbol ')' {
|
| '(' function_argsn type symbol ')' {
|
||||||
$$ = cfg_alloc(sizeof(struct f_arg));
|
$$ = cfg_alloc(sizeof(struct f_arg));
|
||||||
$$->arg = cf_define_symbol($4, SYM_VARIABLE | $3, offset, sym_->scope->slots++);
|
$$->arg = cf_define_symbol(new_config, $4, SYM_VARIABLE | $3, offset, sym_->scope->slots++);
|
||||||
$$->next = $2;
|
$$->next = $2;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -519,7 +519,7 @@ function_args:
|
|||||||
function_vars:
|
function_vars:
|
||||||
/* EMPTY */ { $$ = 0; }
|
/* EMPTY */ { $$ = 0; }
|
||||||
| function_vars type symbol ';' {
|
| function_vars type symbol ';' {
|
||||||
cf_define_symbol($3, SYM_VARIABLE | $2, offset, f_new_var(sym_->scope));
|
cf_define_symbol(new_config, $3, SYM_VARIABLE | $2, offset, f_new_var(sym_->scope));
|
||||||
$$ = $1 + 1;
|
$$ = $1 + 1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -533,13 +533,13 @@ filter:
|
|||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
cf_enter_filters();
|
cf_enter_filters();
|
||||||
cf_push_scope(NULL);
|
cf_push_scope(new_config, NULL);
|
||||||
} filter_body {
|
} filter_body {
|
||||||
struct filter *f = cfg_alloc(sizeof(struct filter));
|
struct filter *f = cfg_alloc(sizeof(struct filter));
|
||||||
*f = (struct filter) { .root = $2 };
|
*f = (struct filter) { .root = $2 };
|
||||||
$$ = f;
|
$$ = f;
|
||||||
|
|
||||||
cf_pop_scope();
|
cf_pop_scope(new_config);
|
||||||
cf_exit_filters();
|
cf_exit_filters();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -565,9 +565,9 @@ conf: function_def ;
|
|||||||
function_def:
|
function_def:
|
||||||
FUNCTION symbol {
|
FUNCTION symbol {
|
||||||
DBG( "Beginning of function %s\n", $2->name );
|
DBG( "Beginning of function %s\n", $2->name );
|
||||||
$2 = cf_define_symbol($2, SYM_FUNCTION, function, NULL);
|
$2 = cf_define_symbol(new_config, $2, SYM_FUNCTION, function, NULL);
|
||||||
cf_enter_filters();
|
cf_enter_filters();
|
||||||
cf_push_scope($2);
|
cf_push_scope(new_config, $2);
|
||||||
} function_args {
|
} function_args {
|
||||||
/* Make dummy f_line for storing function prototype */
|
/* Make dummy f_line for storing function prototype */
|
||||||
struct f_line *dummy = cfg_allocz(sizeof(struct f_line));
|
struct f_line *dummy = cfg_allocz(sizeof(struct f_line));
|
||||||
@ -586,7 +586,7 @@ function_def:
|
|||||||
$6->args = $2->function->args;
|
$6->args = $2->function->args;
|
||||||
$6->arg_list = $2->function->arg_list;
|
$6->arg_list = $2->function->arg_list;
|
||||||
$2->function = $6;
|
$2->function = $6;
|
||||||
cf_pop_scope();
|
cf_pop_scope(new_config);
|
||||||
cf_exit_filters();
|
cf_exit_filters();
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -597,7 +597,7 @@ cmds: /* EMPTY */ { $$ = NULL; }
|
|||||||
| cmds_int { $$ = $1.begin; }
|
| cmds_int { $$ = $1.begin; }
|
||||||
;
|
;
|
||||||
|
|
||||||
cmds_scoped: { cf_push_soft_scope(); } cmds { cf_pop_soft_scope(); $$ = $2; } ;
|
cmds_scoped: { cf_push_soft_scope(new_config); } cmds { cf_pop_soft_scope(new_config); $$ = $2; } ;
|
||||||
|
|
||||||
cmd_var: var | cmd ;
|
cmd_var: var | cmd ;
|
||||||
|
|
||||||
@ -972,17 +972,17 @@ print_list: /* EMPTY */ { $$ = NULL; }
|
|||||||
|
|
||||||
var:
|
var:
|
||||||
type symbol '=' term ';' {
|
type symbol '=' term ';' {
|
||||||
struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
|
struct symbol *sym = cf_define_symbol(new_config, $2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
|
||||||
$$ = f_new_inst(FI_VAR_INIT, $4, sym);
|
$$ = f_new_inst(FI_VAR_INIT, $4, sym);
|
||||||
}
|
}
|
||||||
| type symbol ';' {
|
| type symbol ';' {
|
||||||
struct symbol *sym = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
|
struct symbol *sym = cf_define_symbol(new_config, $2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope));
|
||||||
$$ = f_new_inst(FI_VAR_INIT0, sym);
|
$$ = f_new_inst(FI_VAR_INIT0, sym);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
for_var:
|
for_var:
|
||||||
type symbol { $$ = cf_define_symbol($2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); }
|
type symbol { $$ = cf_define_symbol(new_config, $2, SYM_VARIABLE | $1, offset, f_new_var(sym_->scope)); }
|
||||||
| CF_SYM_KNOWN { $$ = $1; cf_assert_symbol($1, SYM_VARIABLE); }
|
| CF_SYM_KNOWN { $$ = $1; cf_assert_symbol($1, SYM_VARIABLE); }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -998,13 +998,13 @@ cmd:
|
|||||||
}
|
}
|
||||||
| FOR {
|
| FOR {
|
||||||
/* Reserve space for walk data on stack */
|
/* Reserve space for walk data on stack */
|
||||||
cf_push_block_scope();
|
cf_push_block_scope(new_config);
|
||||||
conf_this_scope->slots += 2;
|
new_config->current_scope->slots += 2;
|
||||||
} for_var IN
|
} for_var IN
|
||||||
/* Parse term in the parent scope */
|
/* Parse term in the parent scope */
|
||||||
{ conf_this_scope->active = 0; } term { conf_this_scope->active = 1; }
|
{ new_config->current_scope->active = 0; } term { new_config->current_scope->active = 1; }
|
||||||
DO cmd {
|
DO cmd {
|
||||||
cf_pop_block_scope();
|
cf_pop_block_scope(new_config);
|
||||||
$$ = f_new_inst(FI_FOR_INIT, $6, $3);
|
$$ = f_new_inst(FI_FOR_INIT, $6, $3);
|
||||||
$$->next = f_new_inst(FI_FOR_NEXT, $3, $9);
|
$$->next = f_new_inst(FI_FOR_NEXT, $3, $9);
|
||||||
}
|
}
|
||||||
|
@ -260,19 +260,19 @@ proto_start:
|
|||||||
|
|
||||||
proto_name:
|
proto_name:
|
||||||
/* EMPTY */ {
|
/* EMPTY */ {
|
||||||
struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
|
struct symbol *s = cf_default_name(new_config, this_proto->protocol->template, &this_proto->protocol->name_counter);
|
||||||
s->class = this_proto->class;
|
s->class = this_proto->class;
|
||||||
s->proto = this_proto;
|
s->proto = this_proto;
|
||||||
this_proto->name = s->name;
|
this_proto->name = s->name;
|
||||||
}
|
}
|
||||||
| symbol {
|
| symbol {
|
||||||
cf_define_symbol($1, this_proto->class, proto, this_proto);
|
cf_define_symbol(new_config, $1, this_proto->class, proto, this_proto);
|
||||||
this_proto->name = $1->name;
|
this_proto->name = $1->name;
|
||||||
}
|
}
|
||||||
| FROM CF_SYM_KNOWN {
|
| FROM CF_SYM_KNOWN {
|
||||||
if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
if (($2->class != SYM_TEMPLATE) && ($2->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
||||||
|
|
||||||
struct symbol *s = cf_default_name(this_proto->protocol->template, &this_proto->protocol->name_counter);
|
struct symbol *s = cf_default_name(new_config, this_proto->protocol->template, &this_proto->protocol->name_counter);
|
||||||
s->class = this_proto->class;
|
s->class = this_proto->class;
|
||||||
s->proto = this_proto;
|
s->proto = this_proto;
|
||||||
this_proto->name = s->name;
|
this_proto->name = s->name;
|
||||||
@ -282,7 +282,7 @@ proto_name:
|
|||||||
| symbol FROM CF_SYM_KNOWN {
|
| symbol FROM CF_SYM_KNOWN {
|
||||||
if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
if (($3->class != SYM_TEMPLATE) && ($3->class != SYM_PROTO)) cf_error("Template or protocol name expected");
|
||||||
|
|
||||||
cf_define_symbol($1, this_proto->class, proto, this_proto);
|
cf_define_symbol(new_config, $1, this_proto->class, proto, this_proto);
|
||||||
this_proto->name = $1->name;
|
this_proto->name = $1->name;
|
||||||
|
|
||||||
proto_copy_config(this_proto, $3->proto);
|
proto_copy_config(this_proto, $3->proto);
|
||||||
|
@ -1655,8 +1655,8 @@ protos_do_commit(struct config *new, struct config *old, int force_reconfig, int
|
|||||||
/* This is hack, we would like to share config, but we need to copy it now */
|
/* This is hack, we would like to share config, but we need to copy it now */
|
||||||
new_config = new;
|
new_config = new;
|
||||||
cfg_mem = new->mem;
|
cfg_mem = new->mem;
|
||||||
conf_this_scope = new->root_scope;
|
new->current_scope = new->root_scope;
|
||||||
sym = cf_get_symbol(oc->name);
|
sym = cf_get_symbol(new, oc->name);
|
||||||
proto_clone_config(sym, parsym->proto);
|
proto_clone_config(sym, parsym->proto);
|
||||||
new_config = NULL;
|
new_config = NULL;
|
||||||
cfg_mem = NULL;
|
cfg_mem = NULL;
|
||||||
|
@ -3442,8 +3442,8 @@ rt_preconfig(struct config *c)
|
|||||||
{
|
{
|
||||||
init_list(&c->tables);
|
init_list(&c->tables);
|
||||||
|
|
||||||
c->def_tables[NET_IP4] = cf_define_symbol(cf_get_symbol("master4"), SYM_TABLE, table, NULL);
|
c->def_tables[NET_IP4] = cf_define_symbol(c, cf_get_symbol(c, "master4"), SYM_TABLE, table, NULL);
|
||||||
c->def_tables[NET_IP6] = cf_define_symbol(cf_get_symbol("master6"), SYM_TABLE, table, NULL);
|
c->def_tables[NET_IP6] = cf_define_symbol(c, cf_get_symbol(c, "master6"), SYM_TABLE, table, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -4080,7 +4080,7 @@ rt_new_table(struct symbol *s, uint addr_type)
|
|||||||
if (s == new_config->def_tables[addr_type])
|
if (s == new_config->def_tables[addr_type])
|
||||||
s->table = c;
|
s->table = c;
|
||||||
else
|
else
|
||||||
cf_define_symbol(s, SYM_TABLE, table, c);
|
cf_define_symbol(new_config, s, SYM_TABLE, table, c);
|
||||||
|
|
||||||
c->name = s->name;
|
c->name = s->name;
|
||||||
c->addr_type = addr_type;
|
c->addr_type = addr_type;
|
||||||
|
@ -606,8 +606,8 @@ bgp_spawn(struct bgp_proto *pp, ip_addr remote_ip)
|
|||||||
/* This is hack, we would like to share config, but we need to copy it now */
|
/* This is hack, we would like to share config, but we need to copy it now */
|
||||||
new_config = config;
|
new_config = config;
|
||||||
cfg_mem = config->mem;
|
cfg_mem = config->mem;
|
||||||
conf_this_scope = config->root_scope;
|
config->current_scope = config->root_scope;
|
||||||
sym = cf_default_name(fmt, &(pp->dynamic_name_counter));
|
sym = cf_default_name(config, fmt, &(pp->dynamic_name_counter));
|
||||||
proto_clone_config(sym, pp->p.cf);
|
proto_clone_config(sym, pp->p.cf);
|
||||||
new_config = NULL;
|
new_config = NULL;
|
||||||
cfg_mem = NULL;
|
cfg_mem = NULL;
|
||||||
|
@ -112,21 +112,21 @@ get_hostname(linpool *lp)
|
|||||||
#ifdef PATH_IPROUTE_DIR
|
#ifdef PATH_IPROUTE_DIR
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
add_num_const(char *name, int val, const char *file, const uint line)
|
add_num_const(struct config *conf, char *name, int val, const char *file, const uint line)
|
||||||
{
|
{
|
||||||
struct f_val *v = cfg_alloc(sizeof(struct f_val));
|
struct f_val *v = cfg_alloc(sizeof(struct f_val));
|
||||||
*v = (struct f_val) { .type = T_INT, .val.i = val };
|
*v = (struct f_val) { .type = T_INT, .val.i = val };
|
||||||
struct symbol *sym = cf_get_symbol(name);
|
struct symbol *sym = cf_get_symbol(conf, name);
|
||||||
if (sym->class && cf_symbol_is_local(sym))
|
if (sym->class && cf_symbol_is_local(conf, sym))
|
||||||
cf_error("Error reading value for %s from %s:%d: already defined", name, file, line);
|
cf_error("Error reading value for %s from %s:%d: already defined", name, file, line);
|
||||||
|
|
||||||
cf_define_symbol(sym, SYM_CONSTANT | T_INT, val, v);
|
cf_define_symbol(conf, sym, SYM_CONSTANT | T_INT, val, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the code of read_iproute_table() is based on
|
/* the code of read_iproute_table() is based on
|
||||||
rtnl_tab_initialize() from iproute2 package */
|
rtnl_tab_initialize() from iproute2 package */
|
||||||
static void
|
static void
|
||||||
read_iproute_table(char *file, char *prefix, uint max)
|
read_iproute_table(struct config *conf, char *file, char *prefix, uint max)
|
||||||
{
|
{
|
||||||
char buf[512], namebuf[512];
|
char buf[512], namebuf[512];
|
||||||
char *name;
|
char *name;
|
||||||
@ -163,7 +163,7 @@ read_iproute_table(char *file, char *prefix, uint max)
|
|||||||
if ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9') && (*p != '_'))
|
if ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9') && (*p != '_'))
|
||||||
*p = '_';
|
*p = '_';
|
||||||
|
|
||||||
add_num_const(namebuf, val, file, line);
|
add_num_const(conf, namebuf, val, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@ -192,10 +192,10 @@ sysdep_preconfig(struct config *c)
|
|||||||
c->watchdog_warning = UNIX_DEFAULT_WATCHDOG_WARNING;
|
c->watchdog_warning = UNIX_DEFAULT_WATCHDOG_WARNING;
|
||||||
|
|
||||||
#ifdef PATH_IPROUTE_DIR
|
#ifdef PATH_IPROUTE_DIR
|
||||||
read_iproute_table(PATH_IPROUTE_DIR "/rt_protos", "ipp_", 255);
|
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_protos", "ipp_", 255);
|
||||||
read_iproute_table(PATH_IPROUTE_DIR "/rt_realms", "ipr_", 0xffffffff);
|
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_realms", "ipr_", 0xffffffff);
|
||||||
read_iproute_table(PATH_IPROUTE_DIR "/rt_scopes", "ips_", 255);
|
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_scopes", "ips_", 255);
|
||||||
read_iproute_table(PATH_IPROUTE_DIR "/rt_tables", "ipt_", 0xffffffff);
|
read_iproute_table(c, PATH_IPROUTE_DIR "/rt_tables", "ipt_", 0xffffffff);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user