]>
Commit | Line | Data |
---|---|---|
fe7cec12 MM |
1 | /* |
2 | * BIRD Internet Routing Daemon -- Configuration File Handling | |
3 | * | |
50fe90ed | 4 | * (c) 1998--2000 Martin Mares <mj@ucw.cz> |
fe7cec12 MM |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #ifndef _BIRD_CONF_H_ | |
10 | #define _BIRD_CONF_H_ | |
11 | ||
9b0a0ba9 OZ |
12 | #include "sysdep/config.h" |
13 | #include "lib/ip.h" | |
b7761af3 | 14 | #include "lib/hash.h" |
fe7cec12 | 15 | #include "lib/resource.h" |
a6f79ca5 | 16 | #include "lib/timer.h" |
fe7cec12 | 17 | |
31b3e1bb | 18 | /* Configuration structure */ |
31b3e1bb MM |
19 | struct config { |
20 | pool *pool; /* Pool the configuration is stored in */ | |
21 | linpool *mem; /* Linear pool containing configuration data */ | |
22 | list protos; /* Configured protocol instances (struct proto_config) */ | |
4107df1d | 23 | list tables; /* Configured routing tables (struct rtable_config) */ |
c8cafc8e | 24 | list logfiles; /* Configured log files (sysdep) */ |
bd795877 | 25 | list tests; /* Configured unit tests (f_bt_test_suite) */ |
f249d0b8 | 26 | list symbols; /* Configured symbols in config order */ |
af582c48 | 27 | |
cf31112f | 28 | int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */ |
fd9f0c06 | 29 | const char *syslog_name; /* Name used for syslog (NULL -> no syslog) */ |
f4a60a9b | 30 | struct rtable_config *def_tables[NET_MAX]; /* Default routing tables for each network */ |
79b4e12e | 31 | struct iface_patt *router_id_from; /* Configured list of router ID iface patterns */ |
cf31112f | 32 | |
31b3e1bb | 33 | u32 router_id; /* Our Router ID */ |
61dae32b OZ |
34 | u32 proto_default_debug; /* Default protocol debug mask */ |
35 | u32 proto_default_mrtdump; /* Default protocol mrtdump mask */ | |
36 | u32 channel_default_debug; /* Default channel debug mask */ | |
c37e7851 OZ |
37 | struct timeformat tf_route; /* Time format for 'show route' */ |
38 | struct timeformat tf_proto; /* Time format for 'show protocol' */ | |
39 | struct timeformat tf_log; /* Time format for the logfile */ | |
40 | struct timeformat tf_base; /* Time format for other purposes */ | |
3e405fb1 | 41 | u32 gr_wait; /* Graceful restart wait timeout (sec) */ |
71423871 | 42 | const char *hostname; /* Hostname */ |
c37e7851 | 43 | |
4761efdb | 44 | int cli_debug; /* Tracing of CLI connections and commands */ |
8bcb5fb1 OZ |
45 | int latency_debug; /* I/O loop tracks duration of each event */ |
46 | u32 latency_limit; /* Events with longer duration are logged (us) */ | |
47 | u32 watchdog_warning; /* I/O loop watchdog limit for warning (us) */ | |
48 | u32 watchdog_timeout; /* Watchdog timeout (in seconds, 0 = disabled) */ | |
31b3e1bb MM |
49 | char *err_msg; /* Parser error message */ |
50 | int err_lino; /* Line containing error */ | |
d50b0bc4 | 51 | int err_chno; /* Character where the parser stopped */ |
48ec367a OF |
52 | char *err_file_name; /* File name containing error */ |
53 | char *file_name; /* Name of main configuration file */ | |
54 | int file_fd; /* File descriptor of main configuration file */ | |
8e177cf3 | 55 | |
e0835db4 | 56 | struct sym_scope *root_scope; /* Scope for root symbols */ |
51f2e7af | 57 | struct sym_scope *current_scope; /* Current scope where we are actually in while parsing */ |
50fe90ed | 58 | int obstacle_count; /* Number of items blocking freeing of this config */ |
bf8558bc | 59 | int shutdown; /* This is a pseudo-config for daemon shutdown */ |
8a68316e | 60 | int gr_down; /* This is a pseudo-config for graceful restart */ |
f047271c | 61 | btime load_time; /* When we've got this configuration */ |
31b3e1bb MM |
62 | }; |
63 | ||
31b3e1bb | 64 | /* Please don't use these variables in protocols. Use proto_config->global instead. */ |
50fe90ed MM |
65 | extern struct config *config; /* Currently active configuration */ |
66 | extern struct config *new_config; /* Configuration being parsed */ | |
bf8558bc | 67 | |
9b0a0ba9 | 68 | struct config *config_alloc(const char *name); |
31b3e1bb | 69 | int config_parse(struct config *); |
bc2fb680 | 70 | int cli_parse(struct config *); |
31b3e1bb | 71 | void config_free(struct config *); |
371eb490 | 72 | void config_free_old(void); |
3e405fb1 | 73 | int config_commit(struct config *, int type, uint timeout); |
a92cf57d OZ |
74 | int config_confirm(void); |
75 | int config_undo(void); | |
9106a750 OZ |
76 | int config_status(void); |
77 | btime config_timer_status(void); | |
a92cf57d | 78 | void config_init(void); |
1a7daab1 | 79 | void cf_error(const char *msg, ...) NORET; |
50fe90ed MM |
80 | void config_add_obstacle(struct config *); |
81 | void config_del_obstacle(struct config *); | |
8a68316e | 82 | void order_shutdown(int gr); |
50fe90ed | 83 | |
a92cf57d OZ |
84 | #define RECONFIG_NONE 0 |
85 | #define RECONFIG_HARD 1 | |
86 | #define RECONFIG_SOFT 2 | |
87 | #define RECONFIG_UNDO 3 | |
88 | ||
89 | #define CONF_DONE 0 | |
90 | #define CONF_PROGRESS 1 | |
91 | #define CONF_QUEUED 2 | |
92 | #define CONF_UNQUEUED 3 | |
93 | #define CONF_CONFIRM 4 | |
94 | #define CONF_SHUTDOWN -1 | |
95 | #define CONF_NOTHING -2 | |
96 | ||
31b3e1bb | 97 | |
49e4a4d1 | 98 | /* Pools */ |
37b64441 | 99 | extern pool *config_pool; |
b35d72ac | 100 | extern linpool *cfg_mem; |
fe7cec12 | 101 | |
b35d72ac MM |
102 | #define cfg_alloc(size) lp_alloc(cfg_mem, size) |
103 | #define cfg_allocu(size) lp_allocu(cfg_mem, size) | |
104 | #define cfg_allocz(size) lp_allocz(cfg_mem, size) | |
c8cafc8e | 105 | char *cfg_strdup(const char *c); |
a7f23f58 | 106 | void cfg_copy_list(list *dest, list *src, unsigned node_size); |
49e4a4d1 | 107 | |
fe7cec12 MM |
108 | /* Lexer */ |
109 | ||
ae80a2de | 110 | extern int (*cf_read_hook)(byte *buf, uint max, int fd); |
fe7cec12 MM |
111 | |
112 | struct symbol { | |
f249d0b8 | 113 | node n; /* In list of symbols in config */ |
fe7cec12 | 114 | struct symbol *next; |
c8f61a01 | 115 | struct sym_scope *scope; |
0b39b1cb MM |
116 | int class; /* SYM_* */ |
117 | uint flags; /* SYM_FLAG_* */ | |
118 | ||
119 | union { | |
120 | struct proto_config *proto; /* For SYM_PROTO and SYM_TEMPLATE */ | |
121 | const struct f_line *function; /* For SYM_FUNCTION */ | |
122 | const struct filter *filter; /* For SYM_FILTER */ | |
123 | struct rtable_config *table; /* For SYM_TABLE */ | |
124 | struct f_dynamic_attr *attribute; /* For SYM_ATTRIBUTE */ | |
96d757c1 JMM |
125 | struct f_val *val; /* For SYM_CONSTANT */ |
126 | uint offset; /* For SYM_VARIABLE */ | |
58efa944 | 127 | const struct keyword *keyword; /* For SYM_KEYWORD */ |
0b39b1cb MM |
128 | }; |
129 | ||
130 | char name[0]; | |
fe7cec12 MM |
131 | }; |
132 | ||
b7761af3 OZ |
133 | struct sym_scope { |
134 | struct sym_scope *next; /* Next on scope stack */ | |
135 | struct symbol *name; /* Name of this scope */ | |
8e177cf3 MM |
136 | |
137 | HASH(struct symbol) hash; /* Local symbol hash */ | |
138 | ||
63e76204 | 139 | uint slots; /* Variable slots */ |
946cedfc | 140 | byte soft_scopes; /* Number of soft scopes above */ |
6b95353e MM |
141 | byte active:1; /* Currently entered */ |
142 | byte block:1; /* No independent stack frame */ | |
143 | byte readonly:1; /* Do not add new symbols */ | |
b7761af3 OZ |
144 | }; |
145 | ||
8e177cf3 MM |
146 | extern struct sym_scope *global_root_scope; |
147 | ||
35f88b30 THJ |
148 | struct bytestring { |
149 | size_t length; | |
150 | byte data[]; | |
151 | }; | |
152 | ||
bc7f4e0e OZ |
153 | #define SYM_MAX_LEN 64 |
154 | ||
c0b2f646 | 155 | /* Remember to update cf_symbol_class_name() */ |
fe7cec12 | 156 | #define SYM_VOID 0 |
8450be97 | 157 | #define SYM_PROTO 1 |
1103b32e | 158 | #define SYM_TEMPLATE 2 |
cbc31830 MM |
159 | #define SYM_FUNCTION 3 |
160 | #define SYM_FILTER 4 | |
161 | #define SYM_TABLE 5 | |
265419a3 | 162 | #define SYM_ATTRIBUTE 6 |
58efa944 | 163 | #define SYM_KEYWORD 7 |
fe7cec12 | 164 | |
cbc31830 | 165 | #define SYM_VARIABLE 0x100 /* 0x100-0x1ff are variable types */ |
265419a3 | 166 | #define SYM_VARIABLE_RANGE SYM_VARIABLE ... (SYM_VARIABLE | 0xff) |
1103b32e | 167 | #define SYM_CONSTANT 0x200 /* 0x200-0x2ff are variable types */ |
265419a3 | 168 | #define SYM_CONSTANT_RANGE SYM_CONSTANT ... (SYM_CONSTANT | 0xff) |
1103b32e | 169 | |
0b39b1cb MM |
170 | #define SYM_TYPE(s) ((s)->val->type) |
171 | #define SYM_VAL(s) ((s)->val->val) | |
172 | ||
173 | /* Symbol flags */ | |
174 | #define SYM_FLAG_SAME 0x1 /* For SYM_FUNCTION and SYM_FILTER */ | |
ba921648 | 175 | |
48ec367a | 176 | struct include_file_stack { |
4be266a9 OZ |
177 | void *buffer; /* Internal lexer state */ |
178 | char *file_name; /* File name */ | |
179 | int fd; /* File descriptor */ | |
180 | int lino; /* Current line num */ | |
d50b0bc4 JMM |
181 | int chno; /* Current char num (on current line) */ |
182 | int toklen; /* Current token length */ | |
4be266a9 OZ |
183 | int depth; /* Include depth, 0 = cannot include */ |
184 | ||
185 | struct include_file_stack *prev; /* Previous record in stack */ | |
186 | struct include_file_stack *up; /* Parent (who included this file) */ | |
48ec367a OF |
187 | }; |
188 | ||
9b7fdfc8 | 189 | extern struct include_file_stack *ifs; |
48ec367a | 190 | |
fe7cec12 | 191 | int cf_lex(void); |
48ec367a | 192 | void cf_lex_init(int is_cli, struct config *c); |
0c3d9dac OZ |
193 | void cf_lex_unwind(void); |
194 | ||
8e177cf3 MM |
195 | struct symbol *cf_find_symbol_scope(const struct sym_scope *scope, const byte *c); |
196 | static inline struct symbol *cf_find_symbol_cfg(const struct config *cfg, const byte *c) | |
197 | { return cf_find_symbol_scope(cfg->root_scope, c); } | |
9b9a7143 | 198 | |
8e177cf3 MM |
199 | #define cf_find_symbol(where, what) _Generic(*(where), \ |
200 | struct config: cf_find_symbol_cfg, \ | |
201 | struct sym_scope: cf_find_symbol_scope \ | |
202 | )((where), (what)) | |
a8a64ca0 | 203 | |
51f2e7af MM |
204 | struct symbol *cf_get_symbol(struct config *conf, const byte *c); |
205 | struct symbol *cf_default_name(struct config *conf, char *template, int *counter); | |
206 | struct symbol *cf_localize_symbol(struct config *conf, struct symbol *sym); | |
0b39b1cb | 207 | |
51f2e7af MM |
208 | static inline int cf_symbol_is_local(struct config *conf, struct symbol *sym) |
209 | { return (sym->scope == conf->current_scope) && !conf->current_scope->soft_scopes; } | |
946cedfc | 210 | |
0b39b1cb MM |
211 | /** |
212 | * cf_define_symbol - define meaning of a symbol | |
213 | * @sym: symbol to be defined | |
214 | * @type: symbol class to assign | |
215 | * @def: class dependent data | |
216 | * | |
217 | * Defines new meaning of a symbol. If the symbol is an undefined | |
218 | * one (%SYM_VOID), it's just re-defined to the new type. If it's defined | |
219 | * in different scope, a new symbol in current scope is created and the | |
220 | * meaning is assigned to it. If it's already defined in the current scope, | |
221 | * an error is reported via cf_error(). | |
222 | * | |
223 | * Result: Pointer to the newly defined symbol. If we are in the top-level | |
224 | * scope, it's the same @sym as passed to the function. | |
225 | */ | |
51f2e7af MM |
226 | #define cf_define_symbol(conf_, osym_, type_, var_, def_) ({ \ |
227 | struct symbol *sym_ = cf_localize_symbol(conf_, osym_); \ | |
ab089f4f MM |
228 | sym_->class = type_; \ |
229 | sym_->var_ = def_; \ | |
230 | sym_; }) | |
0b39b1cb | 231 | |
51f2e7af MM |
232 | void cf_push_scope(struct config *, struct symbol *); |
233 | void cf_pop_scope(struct config *); | |
234 | void cf_push_soft_scope(struct config *); | |
235 | void cf_pop_soft_scope(struct config *); | |
946cedfc | 236 | |
51f2e7af MM |
237 | static inline void cf_push_block_scope(struct config *conf) |
238 | { cf_push_scope(conf, NULL); conf->current_scope->block = 1; } | |
e471f9e0 | 239 | |
51f2e7af MM |
240 | static inline void cf_pop_block_scope(struct config *conf) |
241 | { ASSERT(conf->current_scope->block); cf_pop_scope(conf); } | |
e471f9e0 | 242 | |
4b87e256 | 243 | char *cf_symbol_class_name(struct symbol *sym); |
fe7cec12 MM |
244 | |
245 | /* Parser */ | |
246 | ||
9b0a0ba9 | 247 | extern char *cf_text; |
fe7cec12 MM |
248 | int cf_parse(void); |
249 | ||
7c0cc76e MM |
250 | /* Sysdep hooks */ |
251 | ||
252 | void sysdep_preconfig(struct config *); | |
50fe90ed | 253 | int sysdep_commit(struct config *, struct config *); |
bf8558bc | 254 | void sysdep_shutdown_done(void); |
7c0cc76e | 255 | |
fe7cec12 | 256 | #endif |