diff --git a/conf/cf-lex.l b/conf/cf-lex.l index fb2ffb32..95237215 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -78,7 +78,6 @@ static uint cf_hash(const byte *c); HASH_DEFINE_REHASH_FN(SYM, struct symbol) -struct sym_scope *conf_this_scope; struct sym_scope *global_root_scope; static pool *global_root_scope_pool; @@ -555,10 +554,10 @@ check_eof(void) return 0; } -static inline void cf_swap_soft_scope(void); +static inline void cf_swap_soft_scope(struct config *conf); 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; @@ -566,32 +565,21 @@ cf_new_symbol(const byte *c) if (l > SYM_MAX_LEN) cf_error("Symbol too long"); - cf_swap_soft_scope(); - - pool *p = new_config->pool; - - if (conf_this_scope == global_root_scope) - s = mb_allocz(p = global_root_scope_pool, sizeof(struct symbol) + l + 1); - else - s = cfg_allocz(sizeof(struct symbol) + l + 1); - *s = (struct symbol) { .scope = conf_this_scope, .class = SYM_VOID, }; + s = lp_alloc(lp, sizeof(struct symbol) + l + 1); + *s = (struct symbol) { .scope = scope, .class = SYM_VOID, }; strcpy(s->name, c); - if (!conf_this_scope->hash.data) - HASH_INIT(conf_this_scope->hash, p, SYM_ORDER); + if (!scope->hash.data) + HASH_INIT(scope->hash, p, SYM_ORDER); - HASH_INSERT2(conf_this_scope->hash, SYM, p, 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)); return s; } -struct symbol * -cf_symbol_from_keyword(const struct keyword *kw) -{ return cf_new_symbol(kw->name); } - /** * cf_find_symbol_scope - find a symbol by name * @scope: config scope @@ -628,9 +616,12 @@ cf_find_symbol_scope(const struct sym_scope *scope, const byte *c) * existing symbol is found. */ 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) + ); } /** @@ -641,22 +632,23 @@ cf_get_symbol(const byte *c) * for purposes of cf_define_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 (!sym->class) return sym; /* 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); /* 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 * -cf_default_name(char *template, int *counter) +cf_default_name(struct config *conf, char *template, int *counter) { char buf[SYM_MAX_LEN]; struct symbol *s; @@ -665,7 +657,7 @@ cf_default_name(char *template, int *counter) for(;;) { bsprintf(buf, template, ++(*counter)); - s = cf_get_symbol(buf); + s = cf_get_symbol(conf, buf); if (s->class == SYM_VOID) return s; if (!perc) @@ -678,7 +670,7 @@ static enum yytokentype cf_lex_symbol(const char *data) { /* 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; switch (sym->class) @@ -711,10 +703,15 @@ cf_lex_init(int is_cli, struct config *c) if (!global_root_scope_pool) { global_root_scope_pool = rp_new(&root_pool, "Keywords pool"); - conf_this_scope = global_root_scope = mb_allocz(global_root_scope_pool, sizeof(*global_root_scope)); + linpool *kwlp = lp_new(global_root_scope_pool); + global_root_scope = lp_allocz(kwlp, sizeof(*global_root_scope)); for (const struct keyword *k = keyword_list; k->name; k++) - cf_define_symbol(cf_get_symbol(k->name), SYM_KEYWORD, keyword, k); + { + struct symbol *sym = cf_new_symbol(global_root_scope, global_root_scope_pool, kwlp, k->name); + sym->class = SYM_KEYWORD; + sym->keyword = k; + } } ifs_head = ifs = push_ifs(NULL); @@ -733,14 +730,12 @@ cf_lex_init(int is_cli, struct config *c) else BEGIN(INITIAL); - c->root_scope = cfg_allocz(sizeof(struct sym_scope)); - conf_this_scope = c->root_scope; - conf_this_scope->active = 1; + c->root_scope = c->current_scope = cfg_allocz(sizeof(struct sym_scope)); if (is_cli) - conf_this_scope->next = config->root_scope; + c->current_scope->next = config->root_scope; else - conf_this_scope->next = global_root_scope; + c->current_scope->next = global_root_scope; } /** @@ -754,12 +749,12 @@ cf_lex_init(int is_cli, struct config *c) * in all scopes stored on the stack. */ 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)); - s->next = conf_this_scope; - conf_this_scope = s; + s->next = conf->current_scope; + conf->current_scope = s; s->active = 1; s->name = sym; s->slots = 0; @@ -773,14 +768,14 @@ cf_push_scope(struct symbol *sym) * invisible to the rest of the config. */ 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_this_scope = conf_this_scope->next; + conf->current_scope->active = 0; + conf->current_scope = conf->current_scope->next; - ASSERT(conf_this_scope); + ASSERT(conf->current_scope); } /** @@ -791,12 +786,12 @@ cf_pop_scope(void) * Such scope will be converted to a regular scope on first use. */ void -cf_push_soft_scope(void) +cf_push_soft_scope(struct config *conf) { - if (conf_this_scope->soft_scopes < 0xfe) - conf_this_scope->soft_scopes++; + if (conf->current_scope->soft_scopes < 0xfe) + conf->current_scope->soft_scopes++; else - cf_push_block_scope(); + cf_push_block_scope(conf); } /** @@ -805,12 +800,12 @@ cf_push_soft_scope(void) * Leave a soft scope entered by cf_push_soft_scope(). */ void -cf_pop_soft_scope(void) +cf_pop_soft_scope(struct config *conf) { - if (conf_this_scope->soft_scopes) - conf_this_scope->soft_scopes--; + if (conf->current_scope->soft_scopes) + conf->current_scope->soft_scopes--; else - cf_pop_block_scope(); + cf_pop_block_scope(conf); } /** @@ -820,12 +815,12 @@ cf_pop_soft_scope(void) * on first use. It is done automatically by cf_new_symbol(). */ 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--; - cf_push_block_scope(); + conf->current_scope->soft_scopes--; + cf_push_block_scope(conf); } } diff --git a/conf/conf.h b/conf/conf.h index 12f1a6b3..ec8c97e8 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -54,6 +54,7 @@ struct config { int file_fd; /* File descriptor of main configuration file */ struct sym_scope *root_scope; /* Scope for root symbols */ + struct sym_scope *current_scope; /* Current scope where we are actually in while parsing */ int obstacle_count; /* Number of items blocking freeing of this config */ int shutdown; /* This is a pseudo-config for daemon shutdown */ int gr_down; /* This is a pseudo-config for graceful restart */ @@ -186,8 +187,6 @@ struct include_file_stack { extern struct include_file_stack *ifs; -extern struct sym_scope *conf_this_scope; - int cf_lex(void); void cf_lex_init(int is_cli, struct config *c); void cf_lex_unwind(void); @@ -201,12 +200,12 @@ static inline struct symbol *cf_find_symbol_cfg(const struct config *cfg, const struct sym_scope: cf_find_symbol_scope \ )((where), (what)) -struct symbol *cf_get_symbol(const byte *c); -struct symbol *cf_default_name(char *template, int *counter); -struct symbol *cf_localize_symbol(struct symbol *sym); +struct symbol *cf_get_symbol(struct config *conf, const byte *c); +struct symbol *cf_default_name(struct config *conf, char *template, int *counter); +struct symbol *cf_localize_symbol(struct config *conf, struct symbol *sym); -static inline int cf_symbol_is_local(struct symbol *sym) -{ return (sym->scope == conf_this_scope) && !conf_this_scope->soft_scopes; } +static inline int cf_symbol_is_local(struct config *conf, struct symbol *sym) +{ return (sym->scope == conf->current_scope) && !conf->current_scope->soft_scopes; } /** * cf_define_symbol - define meaning of a symbol @@ -223,22 +222,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 * scope, it's the same @sym as passed to the function. */ -#define cf_define_symbol(osym_, type_, var_, def_) ({ \ - struct symbol *sym_ = cf_localize_symbol(osym_); \ +#define cf_define_symbol(conf_, osym_, type_, var_, def_) ({ \ + struct symbol *sym_ = cf_localize_symbol(conf_, osym_); \ sym_->class = type_; \ sym_->var_ = def_; \ sym_; }) -void cf_push_scope(struct symbol *); -void cf_pop_scope(void); -void cf_push_soft_scope(void); -void cf_pop_soft_scope(void); +void cf_push_scope(struct config *, struct symbol *); +void cf_pop_scope(struct config *); +void cf_push_soft_scope(struct config *); +void cf_pop_soft_scope(struct config *); -static inline void cf_push_block_scope(void) -{ cf_push_scope(NULL); conf_this_scope->block = 1; } +static inline void cf_push_block_scope(struct config *conf) +{ cf_push_scope(conf, NULL); conf->current_scope->block = 1; } -static inline void cf_pop_block_scope(void) -{ ASSERT(conf_this_scope->block); cf_pop_scope(); } +static inline void cf_pop_block_scope(struct config *conf) +{ ASSERT(conf->current_scope->block); cf_pop_scope(conf); } char *cf_symbol_class_name(struct symbol *sym); diff --git a/conf/confbase.Y b/conf/confbase.Y index 0c2807dc..df1e038b 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -159,7 +159,7 @@ definition: DEFINE symbol '=' term ';' { struct f_val *val = cfg_allocz(sizeof(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); } ; diff --git a/filter/config.Y b/filter/config.Y index 58c0c16b..e1eca9a5 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -377,13 +377,13 @@ CF_GRAMMAR conf: filter_def ; filter_def: - FILTER symbol { $2 = cf_define_symbol($2, SYM_FILTER, filter, NULL); cf_push_scope( $2 ); } + FILTER symbol { $2 = cf_define_symbol(new_config, $2, SYM_FILTER, filter, NULL); cf_push_scope( new_config, $2 ); } filter_body { struct filter *f = cfg_alloc(sizeof(struct filter)); *f = (struct filter) { .sym = $2, .root = $4 }; $2->filter = f; - cf_pop_scope(); + cf_pop_scope(new_config); } ; @@ -394,7 +394,7 @@ filter_eval: conf: custom_attr ; custom_attr: ATTRIBUTE type symbol ';' { - cf_define_symbol($3, SYM_ATTRIBUTE, attribute, ca_lookup(new_config->pool, $3->name, $2)->fda); + cf_define_symbol(new_config, $3, SYM_ATTRIBUTE, attribute, ca_lookup(new_config->pool, $3->name, $2)->fda); }; conf: bt_test_suite ; @@ -469,7 +469,7 @@ function_argsn: | function_argsn type symbol ';' { if ($3->scope->slots >= 0xfe) cf_error("Too many declarations, at most 255 allowed"); $$ = 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; } ; @@ -478,7 +478,7 @@ function_args: '(' ')' { $$ = NULL; } | '(' function_argsn type symbol ')' { $$ = 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; } ; @@ -486,7 +486,7 @@ function_args: function_vars: /* EMPTY */ { $$ = 0; } | 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; } ; @@ -498,12 +498,12 @@ filter: cf_assert_symbol($1, SYM_FILTER); $$ = $1->filter; } - | { cf_push_scope(NULL); } filter_body { + | { cf_push_scope(new_config, NULL); } filter_body { struct filter *f = cfg_alloc(sizeof(struct filter)); *f = (struct filter) { .root = $2 }; $$ = f; - cf_pop_scope(); + cf_pop_scope(new_config); } ; @@ -525,8 +525,8 @@ conf: function_def ; function_def: FUNCTION symbol { DBG( "Beginning of function %s\n", $2->name ); - $2 = cf_define_symbol($2, SYM_FUNCTION, function, NULL); - cf_push_scope($2); + $2 = cf_define_symbol(new_config, $2, SYM_FUNCTION, function, NULL); + cf_push_scope(new_config, $2); } function_args { /* Make dummy f_line for storing function prototype */ struct f_line *dummy = cfg_allocz(sizeof(struct f_line)); @@ -545,7 +545,7 @@ function_def: $6->args = $2->function->args; $6->arg_list = $2->function->arg_list; $2->function = $6; - cf_pop_scope(); + cf_pop_scope(new_config); } ; @@ -555,7 +555,7 @@ cmds: /* EMPTY */ { $$ = NULL; } | 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 ; @@ -935,17 +935,17 @@ print_list: /* EMPTY */ { $$ = NULL; } var: 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); } | 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); } ; 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); } ; @@ -961,13 +961,13 @@ cmd: } | FOR { /* Reserve space for walk data on stack */ - cf_push_block_scope(); - conf_this_scope->slots += 2; + cf_push_block_scope(new_config); + new_config->current_scope->slots += 2; } for_var IN /* 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 { - cf_pop_block_scope(); + cf_pop_block_scope(new_config); $$ = f_new_inst(FI_FOR_INIT, $6, $3); $$->next = f_new_inst(FI_FOR_NEXT, $3, $9); } diff --git a/nest/config.Y b/nest/config.Y index 8aaf0128..82f63783 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -255,19 +255,19 @@ proto_start: proto_name: /* 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->proto = this_proto; this_proto->name = s->name; } | 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; } | FROM CF_SYM_KNOWN { 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->proto = this_proto; this_proto->name = s->name; @@ -277,7 +277,7 @@ proto_name: | symbol FROM CF_SYM_KNOWN { 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; proto_copy_config(this_proto, $3->proto); diff --git a/nest/proto.c b/nest/proto.c index a5325705..bc7b7cc8 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -1269,8 +1269,8 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty /* This is hack, we would like to share config, but we need to copy it now */ new_config = new; cfg_mem = new->mem; - conf_this_scope = new->root_scope; - sym = cf_get_symbol(oc->name); + new->current_scope = new->root_scope; + sym = cf_get_symbol(new, oc->name); proto_clone_config(sym, parsym->proto); new_config = NULL; cfg_mem = NULL; diff --git a/nest/rt-table.c b/nest/rt-table.c index 23c4bbb2..742e2f05 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -2409,8 +2409,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); + rt_new_table(cf_get_symbol(c, "master4"), NET_IP4); + rt_new_table(cf_get_symbol(c, "master6"), NET_IP6); } void @@ -2838,7 +2838,7 @@ rt_new_table(struct symbol *s, uint addr_type) struct rtable_config *c = cfg_allocz(sizeof(struct rtable_config)); - cf_define_symbol(s, SYM_TABLE, table, c); + cf_define_symbol(new_config, s, SYM_TABLE, table, c); c->name = s->name; c->addr_type = addr_type; c->gc_threshold = 1000; diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 0a2e8f5a..f668b371 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -507,8 +507,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 */ new_config = config; cfg_mem = config->mem; - conf_this_scope = config->root_scope; - sym = cf_default_name(fmt, &(pp->dynamic_name_counter)); + config->current_scope = config->root_scope; + sym = cf_default_name(config, fmt, &(pp->dynamic_name_counter)); proto_clone_config(sym, pp->p.cf); new_config = NULL; cfg_mem = NULL; diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 0d3ec0c0..23cadb14 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -111,21 +111,21 @@ get_hostname(linpool *lp) #ifdef PATH_IPROUTE_DIR 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)); *v = (struct f_val) { .type = T_INT, .val.i = val }; - struct symbol *sym = cf_get_symbol(name); - if (sym->class && cf_symbol_is_local(sym)) + struct symbol *sym = cf_get_symbol(conf, name); + 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_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 rtnl_tab_initialize() from iproute2 package */ 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 *name; @@ -162,7 +162,7 @@ read_iproute_table(char *file, char *prefix, uint max) if ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z') && (*p < '0' || *p > '9') && (*p != '_')) *p = '_'; - add_num_const(namebuf, val, file, line); + add_num_const(conf, namebuf, val, file, line); } fclose(fp); @@ -191,10 +191,10 @@ sysdep_preconfig(struct config *c) c->watchdog_warning = UNIX_DEFAULT_WATCHDOG_WARNING; #ifdef PATH_IPROUTE_DIR - read_iproute_table(PATH_IPROUTE_DIR "/rt_protos", "ipp_", 255); - read_iproute_table(PATH_IPROUTE_DIR "/rt_realms", "ipr_", 0xffffffff); - read_iproute_table(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_protos", "ipp_", 255); + read_iproute_table(c, PATH_IPROUTE_DIR "/rt_realms", "ipr_", 0xffffffff); + read_iproute_table(c, PATH_IPROUTE_DIR "/rt_scopes", "ips_", 255); + read_iproute_table(c, PATH_IPROUTE_DIR "/rt_tables", "ipt_", 0xffffffff); #endif }