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