diff --git a/conf/cf-lex.l b/conf/cf-lex.l index c99bd714..2a25e629 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -78,10 +78,8 @@ pool *global_root_scope_pool; linpool *global_root_scope_linpool; static struct sym_scope global_root_scope = { - .active = 1, }, global_filter_scope = { - .active = 0, .next = &global_root_scope, }; @@ -634,7 +632,8 @@ cf_find_symbol_scope(const struct sym_scope *scope, const byte *c) /* Find the symbol here or anywhere below */ while (scope) - if (scope->active && scope->hash.data && (s = HASH_FIND(scope->hash, SYM, c))) + if (((scope != &global_filter_scope) || !new_config || new_config->allow_attributes) && + scope->hash.data && (s = HASH_FIND(scope->hash, SYM, c))) return s; else scope = scope->next; @@ -735,6 +734,8 @@ ea_lex_register(struct ea_class *def) def->sym->attribute = def; } +#if 0 +/* When we start to support complete protocol removal, we may need this function */ void ea_lex_unregister(struct ea_class *def) { @@ -743,19 +744,13 @@ ea_lex_unregister(struct ea_class *def) mb_free(sym); def->sym = NULL; } +#endif struct ea_class * ea_class_find_by_name(const char *name) { - if (!global_filter_scope.hash.data) - return NULL; - - struct symbol *sym = HASH_FIND(global_filter_scope.hash, SYM, name); - - if (!sym || (sym->class != SYM_ATTRIBUTE)) - return NULL; - else - return sym->attribute; + struct symbol *sym = cf_find_symbol_scope(config ? config->root_scope : &global_filter_scope, name); + return sym && (sym->class == SYM_ATTRIBUTE) ? sym->attribute : NULL; } void f_type_methods_register(void); @@ -803,7 +798,6 @@ cf_lex_init(int is_cli, struct config *c) BEGIN(INITIAL); c->root_scope = c->current_scope = cfg_allocz(sizeof(struct sym_scope)); - c->root_scope->active = 1; if (is_cli) c->current_scope->next = config->root_scope; @@ -828,7 +822,6 @@ cf_push_scope(struct config *conf, struct symbol *sym) s->next = conf->current_scope; conf->current_scope = s; - s->active = 1; s->name = sym; s->slots = 0; } @@ -844,10 +837,7 @@ void cf_pop_scope(struct config *conf) { ASSERT(!conf->current_scope->soft_scopes); - - conf->current_scope->active = 0; conf->current_scope = conf->current_scope->next; - ASSERT(conf->current_scope); } @@ -903,8 +893,8 @@ cf_swap_soft_scope(struct config *conf) void cf_enter_filters(void) { - ASSERT_DIE(!global_filter_scope.active); - global_filter_scope.active = 1; + ASSERT_DIE(!new_config->allow_attributes); + new_config->allow_attributes = 1; } /** @@ -913,8 +903,8 @@ cf_enter_filters(void) void cf_exit_filters(void) { - ASSERT_DIE(global_filter_scope.active); - global_filter_scope.active = 0; + ASSERT_DIE(new_config->allow_attributes); + new_config->allow_attributes = 0; } diff --git a/conf/conf.c b/conf/conf.c index d828b6df..c76046ee 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -60,7 +60,8 @@ static jmp_buf conf_jmpbuf; -struct config *config, *new_config; +struct config *config; +_Thread_local struct config *new_config; pool *config_pool; static struct config *old_config; /* Old configuration */ diff --git a/conf/conf.h b/conf/conf.h index b5168873..841d5c1f 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -58,6 +58,7 @@ struct config { struct sym_scope *root_scope; /* Scope for root symbols */ struct sym_scope *current_scope; /* Current scope where we are actually in while parsing */ + int allow_attributes; /* Allow attributes in the current state of configuration parsing */ _Atomic int obstacle_count; /* Number of items blocking freeing of this config */ event done_event; /* Called when obstacle_count reaches zero */ int shutdown; /* This is a pseudo-config for daemon shutdown */ @@ -67,7 +68,7 @@ struct config { /* Please don't use these variables in protocols. Use proto_config->global instead. */ extern struct config *config; /* Currently active configuration */ -extern struct config *new_config; /* Configuration being parsed */ +extern _Thread_local struct config *new_config; /* Configuration being parsed */ struct config *config_alloc(const char *name); int config_parse(struct config *); @@ -149,7 +150,6 @@ struct sym_scope { uint slots; /* Variable slots */ byte soft_scopes; /* Number of soft scopes above */ - byte active:1; /* Currently entered */ byte block:1; /* No independent stack frame */ byte readonly:1; /* Do not add new symbols */ }; diff --git a/doc/bird.sgml b/doc/bird.sgml index c8cebffe..6e5a596d 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -3313,6 +3313,13 @@ some of them (marked with ` is configured it set automatically. +

For attributes unknown by BIRD, the user can assign a name (on top level) +to an attribute by its number. This defined name can be used then to both set +(by a bytestring literal, transitive) or unset the given attribute even though +BIRD knows nothing about it: + +