]> git.ipfire.org Git - thirdparty/bird.git/blame - conf/conf.c
The MRT protocol
[thirdparty/bird.git] / conf / conf.c
CommitLineData
31b3e1bb
MM
1/*
2 * BIRD Internet Routing Daemon -- Configuration File Handling
3 *
50fe90ed 4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
31b3e1bb
MM
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
06607335
MM
9/**
10 * DOC: Configuration manager
11 *
725270cb 12 * Configuration of BIRD is complex, yet straightforward. There are three
06607335 13 * modules taking care of the configuration: config manager (which takes care
58f7d004 14 * of storage of the config information and controls switching between configs),
2e9b2421 15 * lexical analyzer and parser.
06607335
MM
16 *
17 * The configuration manager stores each config as a &config structure
18 * accompanied by a linear pool from which all information associated
19 * with the config and pointed to by the &config structure is allocated.
20 *
725270cb 21 * There can exist up to four different configurations at one time: an active
06607335 22 * one (pointed to by @config), configuration we are just switching from
9b9a7143
OZ
23 * (@old_config), one queued for the next reconfiguration (@future_config; if
24 * there is one and the user wants to reconfigure once again, we just free the
25 * previous queued config and replace it with the new one) and finally a config
26 * being parsed (@new_config). The stored @old_config is also used for undo
27 * reconfiguration, which works in a similar way. Reconfiguration could also
28 * have timeout (using @config_timer) and undo is automatically called if the
29 * new configuration is not confirmed later. The new config (@new_config) and
30 * associated linear pool (@cfg_mem) is non-NULL only during parsing.
06607335 31 *
9b9a7143
OZ
32 * Loading of new configuration is very simple: just call config_alloc() to get
33 * a new &config structure, then use config_parse() to parse a configuration
34 * file and fill all fields of the structure and finally ask the config manager
35 * to switch to the new config by calling config_commit().
06607335
MM
36 *
37 * CLI commands are parsed in a very similar way -- there is also a stripped-down
2e9b2421 38 * &config structure associated with them and they are lex-ed and parsed by the
06607335
MM
39 * same functions, only a special fake token is prepended before the command
40 * text to make the parser recognize only the rules corresponding to CLI commands.
41 */
42
31b3e1bb
MM
43#include <setjmp.h>
44#include <stdarg.h>
45
6b9fa320 46#undef LOCAL_DEBUG
50fe90ed 47
31b3e1bb 48#include "nest/bird.h"
0e02abfd 49#include "nest/route.h"
31b3e1bb
MM
50#include "nest/protocol.h"
51#include "nest/iface.h"
1b7ddb0e
PT
52#include "lib/resource.h"
53#include "lib/string.h"
50fe90ed 54#include "lib/event.h"
a6f79ca5 55#include "lib/timer.h"
31b3e1bb 56#include "conf/conf.h"
1b7ddb0e 57#include "filter/filter.h"
9b0a0ba9 58
31b3e1bb
MM
59
60static jmp_buf conf_jmpbuf;
61
a92cf57d
OZ
62struct config *config, *new_config;
63
64static struct config *old_config; /* Old configuration */
65static struct config *future_config; /* New config held here if recon requested during recon */
66static int old_cftype; /* Type of transition old_config -> config (RECONFIG_SOFT/HARD) */
67static int future_cftype; /* Type of scheduled transition, may also be RECONFIG_UNDO */
68/* Note that when future_cftype is RECONFIG_UNDO, then future_config is NULL,
69 therefore proper check for future scheduled config checks future_cftype */
70
71static event *config_event; /* Event for finalizing reconfiguration */
72static timer *config_timer; /* Timer for scheduled configuration rollback */
73
74/* These are public just for cmd_show_status(), should not be accessed elsewhere */
75int shutting_down; /* Shutdown requested, do not accept new config changes */
76int configuring; /* Reconfiguration is running */
77int undo_available; /* Undo was not requested from last reconfiguration */
78/* Note that both shutting_down and undo_available are related to requests, not processing */
31b3e1bb 79
06607335
MM
80/**
81 * config_alloc - allocate a new configuration
82 * @name: name of the config
83 *
84 * This function creates new &config structure, attaches a resource
85 * pool and a linear memory pool to it and makes it available for
86 * further use. Returns a pointer to the structure.
87 */
31b3e1bb 88struct config *
9b0a0ba9 89config_alloc(const char *name)
31b3e1bb
MM
90{
91 pool *p = rp_new(&root_pool, "Config");
05d47bd5 92 linpool *l = lp_new_default(p);
31b3e1bb
MM
93 struct config *c = lp_allocz(l, sizeof(struct config));
94
9b9a7143
OZ
95 /* Duplication of name string in local linear pool */
96 uint nlen = strlen(name) + 1;
97 char *ndup = lp_allocu(l, nlen);
98 memcpy(ndup, name, nlen);
99
9b0a0ba9 100 init_list(&c->tests);
cf31112f 101 c->mrtdump_file = -1; /* Hack, this should be sysdep-specific */
31b3e1bb 102 c->pool = p;
9b9a7143
OZ
103 c->mem = l;
104 c->file_name = ndup;
f047271c
OZ
105 c->load_time = current_time();
106 c->tf_route = c->tf_proto = TM_ISO_SHORT_MS;
107 c->tf_base = c->tf_log = TM_ISO_LONG_MS;
0c791f87 108 c->gr_wait = DEFAULT_GR_WAIT;
c37e7851 109
31b3e1bb
MM
110 return c;
111}
112
06607335
MM
113/**
114 * config_parse - parse a configuration
115 * @c: configuration
116 *
117 * config_parse() reads input by calling a hook function pointed to
118 * by @cf_read_hook and parses it according to the configuration
119 * grammar. It also calls all the preconfig and postconfig hooks
2e9b2421 120 * before, resp. after parsing.
06607335
MM
121 *
122 * Result: 1 if the config has been parsed successfully, 0 if any
2e9b2421 123 * error has occurred (such as anybody calling cf_error()) and
06607335
MM
124 * the @err_msg field has been set to the error message.
125 */
31b3e1bb
MM
126int
127config_parse(struct config *c)
128{
9b9a7143 129 int done = 0;
f30b86f9 130 DBG("Parsing configuration file `%s'\n", c->file_name);
31b3e1bb 131 new_config = c;
31b3e1bb
MM
132 cfg_mem = c->mem;
133 if (setjmp(conf_jmpbuf))
9b9a7143
OZ
134 goto cleanup;
135
48ec367a 136 cf_lex_init(0, c);
7c0cc76e 137 sysdep_preconfig(c);
31b3e1bb 138 protos_preconfig(c);
0e02abfd 139 rt_preconfig(c);
31b3e1bb 140 cf_parse();
f4a60a9b 141
97e46d28
OZ
142 if (EMPTY_LIST(c->protos))
143 cf_error("No protocol is specified in the config file");
f4a60a9b
OZ
144
145 /*
dce26783 146 if (!c->router_id)
fe9f1a6d 147 cf_error("Router ID must be configured manually");
f4a60a9b 148 */
fe9f1a6d 149
9b9a7143
OZ
150 done = 1;
151
152cleanup:
153 new_config = NULL;
154 cfg_mem = NULL;
155 return done;
31b3e1bb
MM
156}
157
06607335
MM
158/**
159 * cli_parse - parse a CLI command
160 * @c: temporary config structure
161 *
162 * cli_parse() is similar to config_parse(), but instead of a configuration,
163 * it parses a CLI command. See the CLI module for more information.
164 */
bc2fb680
MM
165int
166cli_parse(struct config *c)
167{
9b9a7143 168 int done = 0;
b7761af3 169 c->fallback = config;
9b9a7143 170 new_config = c;
bc2fb680
MM
171 cfg_mem = c->mem;
172 if (setjmp(conf_jmpbuf))
9b9a7143
OZ
173 goto cleanup;
174
48ec367a 175 cf_lex_init(1, c);
bc2fb680 176 cf_parse();
9b9a7143
OZ
177 done = 1;
178
179cleanup:
b7761af3 180 c->fallback = NULL;
9b9a7143
OZ
181 new_config = NULL;
182 cfg_mem = NULL;
183 return done;
bc2fb680
MM
184}
185
06607335
MM
186/**
187 * config_free - free a configuration
188 * @c: configuration to be freed
189 *
190 * This function takes a &config structure and frees all resources
191 * associated with it.
192 */
31b3e1bb
MM
193void
194config_free(struct config *c)
195{
a92cf57d
OZ
196 if (c)
197 rfree(c->pool);
31b3e1bb
MM
198}
199
200void
50fe90ed
MM
201config_add_obstacle(struct config *c)
202{
203 DBG("+++ adding obstacle %d\n", c->obstacle_count);
204 c->obstacle_count++;
205}
206
207void
208config_del_obstacle(struct config *c)
31b3e1bb 209{
50fe90ed
MM
210 DBG("+++ deleting obstacle %d\n", c->obstacle_count);
211 c->obstacle_count--;
863ecfc7 212 if (!c->obstacle_count && (c != config))
a92cf57d 213 ev_schedule(config_event);
50fe90ed
MM
214}
215
216static int
bf8558bc 217global_commit(struct config *new, struct config *old)
50fe90ed
MM
218{
219 if (!old)
220 return 0;
789772ed 221
bf8558bc 222 if (!new->router_id)
79b4e12e
OZ
223 {
224 new->router_id = old->router_id;
225
226 if (new->router_id_from)
227 {
228 u32 id = if_choose_router_id(new->router_id_from, old->router_id);
229 if (!id)
230 log(L_WARN "Cannot determine router ID, using old one");
231 else
232 new->router_id = id;
233 }
234 }
235
50fe90ed
MM
236 return 0;
237}
238
239static int
bf1aec97 240config_do_commit(struct config *c, int type)
50fe90ed 241{
a92cf57d
OZ
242 if (type == RECONFIG_UNDO)
243 {
244 c = old_config;
245 type = old_cftype;
246 }
247 else
248 config_free(old_config);
50fe90ed 249
50fe90ed 250 old_config = config;
a92cf57d
OZ
251 old_cftype = type;
252 config = c;
253
254 configuring = 1;
255 if (old_config && !config->shutdown)
256 log(L_INFO "Reconfiguring");
257
50fe90ed
MM
258 if (old_config)
259 old_config->obstacle_count++;
76b53a4e 260
50fe90ed 261 DBG("sysdep_commit\n");
a92cf57d 262 int force_restart = sysdep_commit(c, old_config);
50fe90ed
MM
263 DBG("global_commit\n");
264 force_restart |= global_commit(c, old_config);
265 DBG("rt_commit\n");
266 rt_commit(c, old_config);
267 DBG("protos_commit\n");
bf1aec97 268 protos_commit(c, old_config, force_restart, type);
a92cf57d 269
a92cf57d 270 int obs = 0;
50fe90ed 271 if (old_config)
a92cf57d
OZ
272 obs = --old_config->obstacle_count;
273
274 DBG("do_commit finished with %d obstacles remaining\n", obs);
275 return !obs;
50fe90ed
MM
276}
277
8f6accb5 278static void
7c103b1e 279config_done(void *unused UNUSED)
50fe90ed 280{
a92cf57d
OZ
281 if (config->shutdown)
282 sysdep_shutdown_done();
283
284 configuring = 0;
285 if (old_config)
286 log(L_INFO "Reconfigured");
50fe90ed 287
a92cf57d 288 if (future_cftype)
50fe90ed 289 {
a92cf57d
OZ
290 int type = future_cftype;
291 struct config *conf = future_config;
292 future_cftype = RECONFIG_NONE;
50fe90ed 293 future_config = NULL;
a92cf57d 294
76b53a4e 295 log(L_INFO "Reconfiguring to queued configuration");
a92cf57d
OZ
296 if (config_do_commit(conf, type))
297 config_done(NULL);
50fe90ed 298 }
50fe90ed
MM
299}
300
06607335
MM
301/**
302 * config_commit - commit a configuration
303 * @c: new configuration
bf1aec97 304 * @type: type of reconfiguration (RECONFIG_SOFT or RECONFIG_HARD)
3e405fb1 305 * @timeout: timeout for undo (in seconds; or 0 for no timeout)
06607335
MM
306 *
307 * When a configuration is parsed and prepared for use, the
308 * config_commit() function starts the process of reconfiguration.
309 * It checks whether there is already a reconfiguration in progress
310 * in which case it just queues the new config for later processing.
311 * Else it notifies all modules about the new configuration by calling
312 * their commit() functions which can either accept it immediately
313 * or call config_add_obstacle() to report that they need some time
314 * to complete the reconfiguration. After all such obstacles are removed
315 * using config_del_obstacle(), the old configuration is freed and
316 * everything runs according to the new one.
317 *
a92cf57d
OZ
318 * When @timeout is nonzero, the undo timer is activated with given
319 * timeout. The timer is deactivated when config_commit(),
320 * config_confirm() or config_undo() is called.
321 *
06607335
MM
322 * Result: %CONF_DONE if the configuration has been accepted immediately,
323 * %CONF_PROGRESS if it will take some time to switch to it, %CONF_QUEUED
324 * if it's been queued due to another reconfiguration being in progress now
325 * or %CONF_SHUTDOWN if BIRD is in shutdown mode and no new configurations
326 * are accepted.
327 */
50fe90ed 328int
3e405fb1 329config_commit(struct config *c, int type, uint timeout)
50fe90ed 330{
a92cf57d 331 if (shutting_down)
50fe90ed 332 {
a92cf57d
OZ
333 config_free(c);
334 return CONF_SHUTDOWN;
50fe90ed 335 }
a92cf57d
OZ
336
337 undo_available = 1;
3e405fb1 338 if (timeout)
a6f79ca5 339 tm_start(config_timer, timeout S);
a92cf57d 340 else
a6f79ca5 341 tm_stop(config_timer);
a92cf57d
OZ
342
343 if (configuring)
50fe90ed 344 {
a92cf57d 345 if (future_cftype)
50fe90ed
MM
346 {
347 log(L_INFO "Queueing new configuration, ignoring the one already queued");
348 config_free(future_config);
349 }
350 else
a92cf57d
OZ
351 log(L_INFO "Queueing new configuration");
352
353 future_cftype = type;
50fe90ed
MM
354 future_config = c;
355 return CONF_QUEUED;
356 }
76b53a4e 357
bf1aec97 358 if (config_do_commit(c, type))
50fe90ed
MM
359 {
360 config_done(NULL);
361 return CONF_DONE;
362 }
a92cf57d
OZ
363 return CONF_PROGRESS;
364}
365
366/**
367 * config_confirm - confirm a commited configuration
368 *
369 * When the undo timer is activated by config_commit() with nonzero timeout,
370 * this function can be used to deactivate it and therefore confirm
371 * the current configuration.
372 *
373 * Result: %CONF_CONFIRM when the current configuration is confirmed,
374 * %CONF_NONE when there is nothing to confirm (i.e. undo timer is not active).
375 */
376int
377config_confirm(void)
378{
379 if (config_timer->expires == 0)
380 return CONF_NOTHING;
381
a6f79ca5 382 tm_stop(config_timer);
a92cf57d
OZ
383
384 return CONF_CONFIRM;
385}
386
387/**
388 * config_undo - undo a configuration
389 *
390 * Function config_undo() can be used to change the current
391 * configuration back to stored %old_config. If no reconfiguration is
392 * running, this stored configuration is commited in the same way as a
393 * new configuration in config_commit(). If there is already a
394 * reconfiguration in progress and no next reconfiguration is
395 * scheduled, then the undo is scheduled for later processing as
396 * usual, but if another reconfiguration is already scheduled, then
397 * such reconfiguration is removed instead (i.e. undo is applied on
398 * the last commit that scheduled it).
399 *
400 * Result: %CONF_DONE if the configuration has been accepted immediately,
401 * %CONF_PROGRESS if it will take some time to switch to it, %CONF_QUEUED
402 * if it's been queued due to another reconfiguration being in progress now,
403 * %CONF_UNQUEUED if a scheduled reconfiguration is removed, %CONF_NOTHING
404 * if there is no relevant configuration to undo (the previous config request
c8cafc8e 405 * was config_undo() too) or %CONF_SHUTDOWN if BIRD is in shutdown mode and
a92cf57d
OZ
406 * no new configuration changes are accepted.
407 */
408int
409config_undo(void)
410{
411 if (shutting_down)
412 return CONF_SHUTDOWN;
413
414 if (!undo_available || !old_config)
415 return CONF_NOTHING;
416
417 undo_available = 0;
a6f79ca5 418 tm_stop(config_timer);
a92cf57d
OZ
419
420 if (configuring)
50fe90ed 421 {
a92cf57d
OZ
422 if (future_cftype)
423 {
424 config_free(future_config);
425 future_config = NULL;
426
427 log(L_INFO "Removing queued configuration");
428 future_cftype = RECONFIG_NONE;
429 return CONF_UNQUEUED;
430 }
431 else
432 {
433 log(L_INFO "Queueing undo configuration");
434 future_cftype = RECONFIG_UNDO;
435 return CONF_QUEUED;
436 }
437 }
438
439 if (config_do_commit(NULL, RECONFIG_UNDO))
440 {
441 config_done(NULL);
442 return CONF_DONE;
50fe90ed
MM
443 }
444 return CONF_PROGRESS;
31b3e1bb
MM
445}
446
a92cf57d
OZ
447extern void cmd_reconfig_undo_notify(void);
448
449static void
02552526 450config_timeout(timer *t UNUSED)
a92cf57d
OZ
451{
452 log(L_INFO "Config timeout expired, starting undo");
453 cmd_reconfig_undo_notify();
454
455 int r = config_undo();
456 if (r < 0)
457 log(L_ERR "Undo request failed");
458}
459
460void
461config_init(void)
462{
463 config_event = ev_new(&root_pool);
464 config_event->hook = config_done;
465
a6f79ca5 466 config_timer = tm_new(&root_pool);
a92cf57d
OZ
467 config_timer->hook = config_timeout;
468}
469
06607335
MM
470/**
471 * order_shutdown - order BIRD shutdown
472 *
473 * This function initiates shutdown of BIRD. It's accomplished by asking
474 * for switching to an empty configuration.
475 */
bf8558bc
MM
476void
477order_shutdown(void)
478{
479 struct config *c;
480
481 if (shutting_down)
482 return;
a92cf57d 483
bf8558bc
MM
484 log(L_INFO "Shutting down");
485 c = lp_alloc(config->mem, sizeof(struct config));
486 memcpy(c, config, sizeof(struct config));
487 init_list(&c->protos);
488 init_list(&c->tables);
489 c->shutdown = 1;
a92cf57d
OZ
490
491 config_commit(c, RECONFIG_HARD, 0);
bf8558bc
MM
492 shutting_down = 1;
493}
494
06607335
MM
495/**
496 * cf_error - report a configuration error
497 * @msg: printf-like format string
498 *
499 * cf_error() can be called during execution of config_parse(), that is
500 * from the parser, a preconfig hook or a postconfig hook, to report an
501 * error in the configuration.
502 */
31b3e1bb 503void
1a7daab1 504cf_error(const char *msg, ...)
31b3e1bb
MM
505{
506 char buf[1024];
507 va_list args;
508
509 va_start(args, msg);
510 if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
511 strcpy(buf, "<bug: error message too long>");
8f01879c 512 va_end(args);
31b3e1bb 513 new_config->err_msg = cfg_strdup(buf);
4be266a9 514 new_config->err_lino = ifs->lino;
d50b0bc4 515 new_config->err_chno = ifs->chno - ifs->toklen + 1;
4be266a9 516 new_config->err_file_name = ifs->file_name;
0c3d9dac 517 cf_lex_unwind();
31b3e1bb
MM
518 longjmp(conf_jmpbuf, 1);
519}
520
06607335
MM
521/**
522 * cfg_strdup - copy a string to config memory
523 * @c: string to copy
524 *
525 * cfg_strdup() creates a new copy of the string in the memory
526 * pool associated with the configuration being currently parsed.
527 * It's often used when a string literal occurs in the configuration
528 * and we want to preserve it for further use.
529 */
31b3e1bb 530char *
c8cafc8e 531cfg_strdup(const char *c)
31b3e1bb
MM
532{
533 int l = strlen(c) + 1;
534 char *z = cfg_allocu(l);
535 memcpy(z, c, l);
536 return z;
537}
a7f23f58
OZ
538
539
540void
541cfg_copy_list(list *dest, list *src, unsigned node_size)
542{
543 node *dn, *sn;
544
545 init_list(dest);
546 WALK_LIST(sn, *src)
547 {
548 dn = cfg_alloc(node_size);
549 memcpy(dn, sn, node_size);
550 add_tail(dest, dn);
551 }
552}