]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldpd.c
doc: use config values from configure in manpages
[mirror_frr.git] / ldpd / ldpd.c
CommitLineData
8429abe0
RW
1/* $OpenBSD$ */
2
3/*
4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
5 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
6 * Copyright (c) 2004, 2008 Esben Norby <norby@openbsd.org>
7 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
eac6e3f0 22#include <zebra.h>
8429abe0 23#include <sys/wait.h>
8429abe0
RW
24
25#include "ldpd.h"
26#include "ldpe.h"
27#include "lde.h"
28#include "log.h"
eac6e3f0
RW
29#include "ldp_vty.h"
30#include "ldp_debug.h"
31
32#include <lib/version.h>
33#include <lib/log.h>
34#include "getopt.h"
35#include "vty.h"
36#include "command.h"
37#include "memory.h"
38#include "privs.h"
39#include "sigevent.h"
40#include "zclient.h"
41#include "vrf.h"
4af8997d 42#include "qobj.h"
eac6e3f0
RW
43
44static void ldpd_shutdown(void);
45static pid_t start_child(enum ldpd_process, char *, int,
46 const char *, const char *);
47static int main_dispatch_ldpe(struct thread *);
48static int main_dispatch_lde(struct thread *);
8429abe0
RW
49static int main_imsg_send_ipc_sockets(struct imsgbuf *,
50 struct imsgbuf *);
51static void main_imsg_send_net_sockets(int);
52static void main_imsg_send_net_socket(int, enum socket_type);
53static int main_imsg_send_config(struct ldpd_conf *);
b67c140b
RW
54static void ldp_config_normalize(struct ldpd_conf *, void **);
55static void ldp_config_reset_main(struct ldpd_conf *, void **);
56static void ldp_config_reset_af(struct ldpd_conf *, int, void **);
57static void merge_config_ref(struct ldpd_conf *, struct ldpd_conf *, void **);
8429abe0
RW
58static void merge_global(struct ldpd_conf *, struct ldpd_conf *);
59static void merge_af(int, struct ldpd_af_conf *,
60 struct ldpd_af_conf *);
b67c140b 61static void merge_ifaces(struct ldpd_conf *, struct ldpd_conf *, void **);
8429abe0 62static void merge_iface_af(struct iface_af *, struct iface_af *);
b67c140b
RW
63static void merge_tnbrs(struct ldpd_conf *, struct ldpd_conf *, void **);
64static void merge_nbrps(struct ldpd_conf *, struct ldpd_conf *, void **);
65static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *, void **);
8429abe0 66static void merge_l2vpn(struct ldpd_conf *, struct l2vpn *,
b67c140b 67 struct l2vpn *, void **);
8429abe0 68
4af8997d
RW
69DEFINE_QOBJ_TYPE(iface)
70DEFINE_QOBJ_TYPE(tnbr)
71DEFINE_QOBJ_TYPE(nbr_params)
72DEFINE_QOBJ_TYPE(l2vpn_if)
73DEFINE_QOBJ_TYPE(l2vpn_pw)
74DEFINE_QOBJ_TYPE(l2vpn)
75DEFINE_QOBJ_TYPE(ldpd_conf)
76
8429abe0
RW
77struct ldpd_global global;
78struct ldpd_conf *ldpd_conf;
79
8429abe0
RW
80static struct imsgev *iev_ldpe;
81static struct imsgev *iev_lde;
82static pid_t ldpe_pid;
83static pid_t lde_pid;
84
eac6e3f0
RW
85#define LDP_DEFAULT_CONFIG "ldpd.conf"
86#define LDP_VTY_PORT 2612
87
88/* Master of threads. */
89struct thread_master *master;
90
91/* Process ID saved for use by init system */
92static const char *pid_file = PATH_LDPD_PID;
93
94/* Configuration filename and directory. */
95static char config_default[] = SYSCONFDIR LDP_DEFAULT_CONFIG;
96
97/* ldpd privileges */
98static zebra_capabilities_t _caps_p [] =
8429abe0 99{
eac6e3f0
RW
100 ZCAP_BIND,
101 ZCAP_NET_ADMIN
102};
103
104struct zebra_privs_t ldpd_privs =
105{
106#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
107 .user = QUAGGA_USER,
108 .group = QUAGGA_GROUP,
109#endif
110#if defined(VTY_GROUP)
111 .vty_group = VTY_GROUP,
112#endif
113 .caps_p = _caps_p,
114 .cap_num_p = array_size(_caps_p),
115 .cap_num_i = 0
116};
117
118/* LDPd options. */
119static struct option longopts[] =
120{
121 { "daemon", no_argument, NULL, 'd'},
122 { "config_file", required_argument, NULL, 'f'},
123 { "pid_file", required_argument, NULL, 'i'},
124 { "socket", required_argument, NULL, 'z'},
125 { "dryrun", no_argument, NULL, 'C'},
126 { "help", no_argument, NULL, 'h'},
127 { "vty_addr", required_argument, NULL, 'A'},
128 { "vty_port", required_argument, NULL, 'P'},
129 { "user", required_argument, NULL, 'u'},
130 { "group", required_argument, NULL, 'g'},
131 { "version", no_argument, NULL, 'v'},
132 { 0 }
133};
134
135/* Help information display. */
136static void __attribute__ ((noreturn))
137usage(char *progname, int status)
138{
139 if (status != 0)
140 fprintf(stderr, "Try `%s --help' for more information.\n",
141 progname);
142 else {
143 printf("Usage : %s [OPTION...]\n\
144Daemon which manages LDP.\n\n\
145-d, --daemon Runs in daemon mode\n\
146-f, --config_file Set configuration file name\n\
147-i, --pid_file Set process identifier file name\n\
148-z, --socket Set path of zebra socket\n\
149-A, --vty_addr Set vty's bind address\n\
150-P, --vty_port Set vty's port number\n\
151-u, --user User to run as\n\
152-g, --group Group to run as\n\
153-v, --version Print program version\n\
154-C, --dryrun Check configuration for validity and exit\n\
155-h, --help Display this help and exit\n\
156\n\
157Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
8429abe0 158 }
eac6e3f0
RW
159
160 exit(status);
8429abe0
RW
161}
162
eac6e3f0
RW
163/* SIGHUP handler. */
164static void
165sighup(void)
166{
167 log_info("SIGHUP received");
168}
169
170/* SIGINT / SIGTERM handler. */
171static void
172sigint(void)
8429abe0 173{
eac6e3f0
RW
174 log_info("SIGINT received");
175 ldpd_shutdown();
176}
8429abe0 177
eac6e3f0
RW
178/* SIGUSR1 handler. */
179static void
180sigusr1(void)
181{
182 zlog_rotate(NULL);
8429abe0
RW
183}
184
eac6e3f0
RW
185static struct quagga_signal_t ldp_signals[] =
186{
187 {
188 .signal = SIGHUP,
189 .handler = &sighup,
190 },
191 {
192 .signal = SIGINT,
193 .handler = &sigint,
194 },
195 {
196 .signal = SIGTERM,
197 .handler = &sigint,
198 },
199 {
200 .signal = SIGUSR1,
201 .handler = &sigusr1,
202 }
203};
204
8429abe0
RW
205int
206main(int argc, char *argv[])
207{
8429abe0 208 char *saved_argv0;
eac6e3f0 209 int lflag = 0, eflag = 0;
8429abe0
RW
210 int pipe_parent2ldpe[2];
211 int pipe_parent2lde[2];
eac6e3f0
RW
212 char *p;
213 char *vty_addr = NULL;
214 int vty_port = LDP_VTY_PORT;
215 int daemon_mode = 0;
216 const char *user = NULL;
217 const char *group = NULL;
218 char *config_file = NULL;
219 char *progname;
220 struct thread thread;
221 int dryrun = 0;
8429abe0 222
8429abe0
RW
223 ldpd_process = PROC_MAIN;
224
eac6e3f0
RW
225 /* Set umask before anything for security */
226 umask(0027);
227
228 /* get program name */
229 progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
8429abe0
RW
230
231 saved_argv0 = argv[0];
232 if (saved_argv0 == NULL)
eac6e3f0 233 saved_argv0 = (char *)"ldpd";
8429abe0 234
eac6e3f0
RW
235 while (1) {
236 int opt;
237
238 opt = getopt_long(argc, argv, "df:i:z:hA:P:u:g:vCLE",
239 longopts, 0);
240
241 if (opt == EOF)
8429abe0 242 break;
eac6e3f0
RW
243
244 switch (opt) {
245 case 0:
246 break;
247 case 'd':
248 daemon_mode = 1;
8429abe0
RW
249 break;
250 case 'f':
eac6e3f0
RW
251 config_file = optarg;
252 break;
253 case 'A':
254 vty_addr = optarg;
255 break;
256 case 'i':
257 pid_file = optarg;
258 break;
259 case 'z':
260 zclient_serv_path_set(optarg);
261 break;
262 case 'P':
263 /*
264 * Deal with atoi() returning 0 on failure, and ldpd
265 * not listening on ldpd port.
266 */
267 if (strcmp(optarg, "0") == 0) {
268 vty_port = 0;
269 break;
270 }
271 vty_port = atoi(optarg);
272 if (vty_port <= 0 || vty_port > 0xffff)
273 vty_port = LDP_VTY_PORT;
274 break;
275 case 'u':
276 user = optarg;
8429abe0 277 break;
eac6e3f0
RW
278 case 'g':
279 group = optarg;
8429abe0
RW
280 break;
281 case 'v':
eac6e3f0
RW
282 print_version(progname);
283 exit(0);
284 break;
285 case 'C':
286 dryrun = 1;
287 break;
288 case 'h':
289 usage(progname, 0);
8429abe0
RW
290 break;
291 case 'L':
292 lflag = 1;
293 break;
294 case 'E':
295 eflag = 1;
296 break;
297 default:
eac6e3f0
RW
298 usage(progname, 1);
299 break;
8429abe0
RW
300 }
301 }
302
303 argc -= optind;
304 argv += optind;
305 if (argc > 0 || (lflag && eflag))
eac6e3f0 306 usage(progname, 1);
8429abe0 307
eac6e3f0
RW
308 /* check for root privileges */
309 if (geteuid() != 0) {
310 errno = EPERM;
311 perror(progname);
8429abe0
RW
312 exit(1);
313 }
314
eac6e3f0
RW
315 zlog_default = openzlog(progname, ZLOG_LDP, 0,
316 LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
8429abe0 317
eac6e3f0
RW
318 if (lflag)
319 lde(user, group);
320 else if (eflag)
321 ldpe(user, group);
8429abe0 322
eac6e3f0 323 master = thread_master_create();
8429abe0 324
eac6e3f0 325 cmd_init(1);
0b47280e 326 vty_config_lockless ();
eac6e3f0
RW
327 vty_init(master);
328 vrf_init();
329 ldp_vty_init();
330 ldp_vty_if_init();
8429abe0 331
eac6e3f0
RW
332 /* Get configuration file. */
333 ldpd_conf = config_new_empty();
b67c140b 334 ldp_config_reset_main(ldpd_conf, NULL);
eac6e3f0 335 vty_read_config(config_file, config_default);
8429abe0 336
eac6e3f0
RW
337 /* Start execution only if not in dry-run mode */
338 if (dryrun)
339 exit(0);
340
4af8997d
RW
341 QOBJ_REG (ldpd_conf, ldpd_conf);
342
eac6e3f0
RW
343 if (daemon_mode && daemon(0, 0) < 0) {
344 log_warn("LDPd daemon failed");
345 exit(1);
346 }
8429abe0 347
eac6e3f0 348 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
8429abe0 349 fatal("socketpair");
eac6e3f0 350 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2lde) == -1)
8429abe0 351 fatal("socketpair");
eac6e3f0
RW
352 sock_set_nonblock(pipe_parent2ldpe[0]);
353 sock_set_cloexec(pipe_parent2ldpe[0]);
354 sock_set_nonblock(pipe_parent2ldpe[1]);
355 sock_set_cloexec(pipe_parent2ldpe[1]);
356 sock_set_nonblock(pipe_parent2lde[0]);
357 sock_set_cloexec(pipe_parent2lde[0]);
358 sock_set_nonblock(pipe_parent2lde[1]);
359 sock_set_cloexec(pipe_parent2lde[1]);
8429abe0
RW
360
361 /* start children */
362 lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
eac6e3f0 363 pipe_parent2lde[1], user, group);
8429abe0 364 ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
eac6e3f0 365 pipe_parent2ldpe[1], user, group);
8429abe0 366
eac6e3f0
RW
367 /* drop privileges */
368 if (user)
369 ldpd_privs.user = user;
370 if (group)
371 ldpd_privs.group = group;
372 zprivs_init(&ldpd_privs);
8429abe0
RW
373
374 /* setup signal handler */
eac6e3f0
RW
375 signal_init(master, array_size(ldp_signals), ldp_signals);
376
377 /* library inits */
378 ldp_zebra_init(master);
8429abe0
RW
379
380 /* setup pipes to children */
381 if ((iev_ldpe = malloc(sizeof(struct imsgev))) == NULL ||
382 (iev_lde = malloc(sizeof(struct imsgev))) == NULL)
383 fatal(NULL);
384 imsg_init(&iev_ldpe->ibuf, pipe_parent2ldpe[0]);
eac6e3f0
RW
385 iev_ldpe->handler_read = main_dispatch_ldpe;
386 iev_ldpe->ev_read = thread_add_read(master, iev_ldpe->handler_read,
387 iev_ldpe, iev_ldpe->ibuf.fd);
388 iev_ldpe->handler_write = ldp_write_handler;
389 iev_ldpe->ev_write = NULL;
8429abe0 390
eac6e3f0
RW
391 imsg_init(&iev_lde->ibuf, pipe_parent2lde[0]);
392 iev_lde->handler_read = main_dispatch_lde;
393 iev_lde->ev_read = thread_add_read(master, iev_lde->handler_read,
394 iev_lde, iev_lde->ibuf.fd);
395 iev_lde->handler_write = ldp_write_handler;
396 iev_lde->ev_write = NULL;
8429abe0
RW
397
398 if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
399 fatal("could not establish imsg links");
eac6e3f0
RW
400 main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug,
401 sizeof(ldp_debug));
8429abe0
RW
402 main_imsg_send_config(ldpd_conf);
403
8429abe0
RW
404 if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED)
405 main_imsg_send_net_sockets(AF_INET);
406 if (ldpd_conf->ipv6.flags & F_LDPD_AF_ENABLED)
407 main_imsg_send_net_sockets(AF_INET6);
408
eac6e3f0
RW
409 /* Process id file create. */
410 pid_output(pid_file);
8429abe0 411
eac6e3f0
RW
412 /* Create VTY socket */
413 vty_serv_sock(vty_addr, vty_port, LDP_VTYSH_PATH);
414
415 /* Print banner. */
416 log_notice("LDPd %s starting: vty@%d", QUAGGA_VERSION, vty_port);
417
418 /* Fetch next active thread. */
419 while (thread_fetch(master, &thread))
420 thread_call(&thread);
8429abe0 421
8429abe0
RW
422 /* NOTREACHED */
423 return (0);
424}
425
eac6e3f0 426static void
8429abe0
RW
427ldpd_shutdown(void)
428{
429 pid_t pid;
430 int status;
431
432 /* close pipes */
433 msgbuf_clear(&iev_ldpe->ibuf.w);
434 close(iev_ldpe->ibuf.fd);
435 msgbuf_clear(&iev_lde->ibuf.w);
436 close(iev_lde->ibuf.fd);
437
8429abe0
RW
438 config_clear(ldpd_conf);
439
440 log_debug("waiting for children to terminate");
441 do {
442 pid = wait(&status);
443 if (pid == -1) {
444 if (errno != EINTR && errno != ECHILD)
445 fatal("wait");
446 } else if (WIFSIGNALED(status))
447 log_warnx("%s terminated; signal %d",
448 (pid == lde_pid) ? "label decision engine" :
449 "ldp engine", WTERMSIG(status));
450 } while (pid != -1 || (pid == -1 && errno == EINTR));
451
452 free(iev_ldpe);
453 free(iev_lde);
454
455 log_info("terminating");
456 exit(0);
457}
458
459static pid_t
eac6e3f0
RW
460start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
461 const char *group)
8429abe0 462{
eac6e3f0 463 char *argv[7];
8429abe0
RW
464 int argc = 0;
465 pid_t pid;
466
467 switch (pid = fork()) {
468 case -1:
469 fatal("cannot fork");
470 case 0:
471 break;
472 default:
473 close(fd);
474 return (pid);
475 }
476
477 if (dup2(fd, 3) == -1)
478 fatal("cannot setup imsg fd");
479
480 argv[argc++] = argv0;
481 switch (p) {
482 case PROC_MAIN:
483 fatalx("Can not start main process");
484 case PROC_LDE_ENGINE:
eac6e3f0 485 argv[argc++] = (char *)"-L";
8429abe0
RW
486 break;
487 case PROC_LDP_ENGINE:
eac6e3f0 488 argv[argc++] = (char *)"-E";
8429abe0
RW
489 break;
490 }
eac6e3f0
RW
491 if (user) {
492 argv[argc++] = (char *)"-u";
493 argv[argc++] = (char *)user;
494 }
495 if (group) {
496 argv[argc++] = (char *)"-g";
497 argv[argc++] = (char *)group;
498 }
8429abe0
RW
499 argv[argc++] = NULL;
500
501 execvp(argv0, argv);
502 fatal("execvp");
503}
504
505/* imsg handling */
506/* ARGSUSED */
eac6e3f0
RW
507static int
508main_dispatch_ldpe(struct thread *thread)
8429abe0 509{
eac6e3f0 510 struct imsgev *iev = THREAD_ARG(thread);
8429abe0
RW
511 struct imsgbuf *ibuf = &iev->ibuf;
512 struct imsg imsg;
513 int af;
514 ssize_t n;
eac6e3f0 515 int shut = 0;
8429abe0 516
eac6e3f0
RW
517 iev->ev_read = NULL;
518
519 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
520 fatal("imsg_read error");
521 if (n == 0) /* connection closed */
522 shut = 1;
8429abe0
RW
523
524 for (;;) {
525 if ((n = imsg_get(ibuf, &imsg)) == -1)
526 fatal("imsg_get");
527
528 if (n == 0)
529 break;
530
531 switch (imsg.hdr.type) {
eac6e3f0
RW
532 case IMSG_LOG:
533 logit(imsg.hdr.pid, "%s", (const char *)imsg.data);
534 break;
8429abe0
RW
535 case IMSG_REQUEST_SOCKETS:
536 af = imsg.hdr.pid;
537 main_imsg_send_net_sockets(af);
538 break;
8429abe0
RW
539 default:
540 log_debug("%s: error handling imsg %d", __func__,
541 imsg.hdr.type);
542 break;
543 }
544 imsg_free(&imsg);
545 }
546 if (!shut)
547 imsg_event_add(iev);
548 else {
eac6e3f0
RW
549 /* this pipe is dead, so remove the event handlers and exit */
550 THREAD_READ_OFF(iev->ev_read);
551 THREAD_WRITE_OFF(iev->ev_write);
552 ldpe_pid = 0;
553 if (lde_pid == 0)
554 ldpd_shutdown();
555 else
556 kill(lde_pid, SIGTERM);
8429abe0 557 }
eac6e3f0
RW
558
559 return (0);
8429abe0
RW
560}
561
562/* ARGSUSED */
eac6e3f0
RW
563static int
564main_dispatch_lde(struct thread *thread)
8429abe0 565{
eac6e3f0 566 struct imsgev *iev = THREAD_ARG(thread);
8429abe0
RW
567 struct imsgbuf *ibuf = &iev->ibuf;
568 struct imsg imsg;
569 ssize_t n;
570 int shut = 0;
571
eac6e3f0
RW
572 iev->ev_read = NULL;
573
574 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
575 fatal("imsg_read error");
576 if (n == 0) /* connection closed */
577 shut = 1;
8429abe0
RW
578
579 for (;;) {
580 if ((n = imsg_get(ibuf, &imsg)) == -1)
581 fatal("imsg_get");
582
583 if (n == 0)
584 break;
585
586 switch (imsg.hdr.type) {
eac6e3f0
RW
587 case IMSG_LOG:
588 logit(imsg.hdr.pid, "%s", (const char *)imsg.data);
589 break;
8429abe0
RW
590 case IMSG_KLABEL_CHANGE:
591 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
592 sizeof(struct kroute))
593 fatalx("invalid size of IMSG_KLABEL_CHANGE");
594 if (kr_change(imsg.data))
595 log_warnx("%s: error changing route", __func__);
596 break;
597 case IMSG_KLABEL_DELETE:
598 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
599 sizeof(struct kroute))
600 fatalx("invalid size of IMSG_KLABEL_DELETE");
601 if (kr_delete(imsg.data))
602 log_warnx("%s: error deleting route", __func__);
603 break;
604 case IMSG_KPWLABEL_CHANGE:
605 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
606 sizeof(struct kpw))
607 fatalx("invalid size of IMSG_KPWLABEL_CHANGE");
608 if (kmpw_set(imsg.data))
609 log_warnx("%s: error changing pseudowire",
610 __func__);
611 break;
612 case IMSG_KPWLABEL_DELETE:
613 if (imsg.hdr.len - IMSG_HEADER_SIZE !=
614 sizeof(struct kpw))
615 fatalx("invalid size of IMSG_KPWLABEL_DELETE");
616 if (kmpw_unset(imsg.data))
617 log_warnx("%s: error unsetting pseudowire",
618 __func__);
619 break;
620 default:
621 log_debug("%s: error handling imsg %d", __func__,
622 imsg.hdr.type);
623 break;
624 }
625 imsg_free(&imsg);
626 }
627 if (!shut)
628 imsg_event_add(iev);
629 else {
eac6e3f0
RW
630 /* this pipe is dead, so remove the event handlers and exit */
631 THREAD_READ_OFF(iev->ev_read);
632 THREAD_WRITE_OFF(iev->ev_write);
633 lde_pid = 0;
634 if (ldpe_pid == 0)
635 ldpd_shutdown();
636 else
637 kill(ldpe_pid, SIGTERM);
8429abe0 638 }
eac6e3f0
RW
639
640 return (0);
641}
642
643/* ARGSUSED */
644int
645ldp_write_handler(struct thread *thread)
646{
647 struct imsgev *iev = THREAD_ARG(thread);
648 struct imsgbuf *ibuf = &iev->ibuf;
649 ssize_t n;
650
651 iev->ev_write = NULL;
652
653 if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
654 fatal("msgbuf_write");
655 if (n == 0) {
656 /* this pipe is dead, so remove the event handlers */
657 THREAD_READ_OFF(iev->ev_read);
658 THREAD_WRITE_OFF(iev->ev_write);
659 return (0);
660 }
661
662 imsg_event_add(iev);
663
664 return (0);
8429abe0
RW
665}
666
667void
668main_imsg_compose_ldpe(int type, pid_t pid, void *data, uint16_t datalen)
669{
670 if (iev_ldpe == NULL)
671 return;
672 imsg_compose_event(iev_ldpe, type, 0, pid, -1, data, datalen);
673}
674
675void
676main_imsg_compose_lde(int type, pid_t pid, void *data, uint16_t datalen)
677{
678 imsg_compose_event(iev_lde, type, 0, pid, -1, data, datalen);
679}
680
eac6e3f0 681int
8429abe0
RW
682main_imsg_compose_both(enum imsg_type type, void *buf, uint16_t len)
683{
eac6e3f0
RW
684 if (iev_ldpe == NULL || iev_lde == NULL)
685 return (0);
8429abe0
RW
686 if (imsg_compose_event(iev_ldpe, type, 0, 0, -1, buf, len) == -1)
687 return (-1);
688 if (imsg_compose_event(iev_lde, type, 0, 0, -1, buf, len) == -1)
689 return (-1);
690 return (0);
691}
692
693void
694imsg_event_add(struct imsgev *iev)
695{
eac6e3f0
RW
696 THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
697 iev->ibuf.fd);
8429abe0 698
eac6e3f0
RW
699 if (iev->ibuf.w.queued)
700 THREAD_WRITE_ON(master, iev->ev_write, iev->handler_write, iev,
701 iev->ibuf.fd);
8429abe0
RW
702}
703
704int
705imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
706 pid_t pid, int fd, void *data, uint16_t datalen)
707{
708 int ret;
709
710 if ((ret = imsg_compose(&iev->ibuf, type, peerid,
711 pid, fd, data, datalen)) != -1)
712 imsg_event_add(iev);
713 return (ret);
714}
715
716void
717evbuf_enqueue(struct evbuf *eb, struct ibuf *buf)
718{
719 ibuf_close(&eb->wbuf, buf);
720 evbuf_event_add(eb);
721}
722
723void
724evbuf_event_add(struct evbuf *eb)
725{
726 if (eb->wbuf.queued)
eac6e3f0
RW
727 THREAD_WRITE_ON(master, eb->ev, eb->handler, eb->arg,
728 eb->wbuf.fd);
8429abe0
RW
729}
730
731void
eac6e3f0 732evbuf_init(struct evbuf *eb, int fd, int (*handler)(struct thread *),
8429abe0
RW
733 void *arg)
734{
735 msgbuf_init(&eb->wbuf);
736 eb->wbuf.fd = fd;
eac6e3f0
RW
737 eb->handler = handler;
738 eb->arg = arg;
8429abe0
RW
739}
740
741void
742evbuf_clear(struct evbuf *eb)
743{
eac6e3f0 744 THREAD_WRITE_OFF(eb->ev);
8429abe0
RW
745 msgbuf_clear(&eb->wbuf);
746 eb->wbuf.fd = -1;
747}
748
749static int
750main_imsg_send_ipc_sockets(struct imsgbuf *ldpe_buf, struct imsgbuf *lde_buf)
751{
752 int pipe_ldpe2lde[2];
753
eac6e3f0 754 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_ldpe2lde) == -1)
8429abe0 755 return (-1);
eac6e3f0
RW
756 sock_set_nonblock(pipe_ldpe2lde[0]);
757 sock_set_nonblock(pipe_ldpe2lde[1]);
8429abe0
RW
758
759 if (imsg_compose(ldpe_buf, IMSG_SOCKET_IPC, 0, 0, pipe_ldpe2lde[0],
760 NULL, 0) == -1)
761 return (-1);
762 if (imsg_compose(lde_buf, IMSG_SOCKET_IPC, 0, 0, pipe_ldpe2lde[1],
763 NULL, 0) == -1)
764 return (-1);
765
766 return (0);
767}
768
769static void
770main_imsg_send_net_sockets(int af)
771{
eac6e3f0
RW
772 if (!ldp_addrisset(af, &(ldp_af_conf_get(ldpd_conf, af))->trans_addr))
773 return;
774
8429abe0
RW
775 main_imsg_send_net_socket(af, LDP_SOCKET_DISC);
776 main_imsg_send_net_socket(af, LDP_SOCKET_EDISC);
777 main_imsg_send_net_socket(af, LDP_SOCKET_SESSION);
778 imsg_compose_event(iev_ldpe, IMSG_SETUP_SOCKETS, af, 0, -1, NULL, 0);
779}
780
781static void
782main_imsg_send_net_socket(int af, enum socket_type type)
783{
784 int fd;
785
786 fd = ldp_create_socket(af, type);
787 if (fd == -1) {
788 log_warnx("%s: failed to create %s socket for address-family "
789 "%s", __func__, socket_name(type), af_name(af));
790 return;
791 }
792
793 imsg_compose_event(iev_ldpe, IMSG_SOCKET_NET, af, 0, fd, &type,
794 sizeof(type));
795}
796
797struct ldpd_af_conf *
798ldp_af_conf_get(struct ldpd_conf *xconf, int af)
799{
800 switch (af) {
801 case AF_INET:
802 return (&xconf->ipv4);
803 case AF_INET6:
804 return (&xconf->ipv6);
805 default:
806 fatalx("ldp_af_conf_get: unknown af");
807 }
808}
809
810struct ldpd_af_global *
811ldp_af_global_get(struct ldpd_global *xglobal, int af)
812{
813 switch (af) {
814 case AF_INET:
815 return (&xglobal->ipv4);
816 case AF_INET6:
817 return (&xglobal->ipv6);
818 default:
819 fatalx("ldp_af_global_get: unknown af");
820 }
821}
822
823int
824ldp_is_dual_stack(struct ldpd_conf *xconf)
825{
826 return ((xconf->ipv4.flags & F_LDPD_AF_ENABLED) &&
827 (xconf->ipv6.flags & F_LDPD_AF_ENABLED));
828}
829
eac6e3f0
RW
830in_addr_t
831ldp_rtr_id_get(struct ldpd_conf *xconf)
832{
833 if (xconf->rtr_id.s_addr != INADDR_ANY)
834 return (xconf->rtr_id.s_addr);
835 else
836 return (global.rtr_id.s_addr);
837}
838
8429abe0
RW
839static int
840main_imsg_send_config(struct ldpd_conf *xconf)
841{
842 struct iface *iface;
843 struct tnbr *tnbr;
844 struct nbr_params *nbrp;
845 struct l2vpn *l2vpn;
846 struct l2vpn_if *lif;
847 struct l2vpn_pw *pw;
848
849 if (main_imsg_compose_both(IMSG_RECONF_CONF, xconf,
850 sizeof(*xconf)) == -1)
851 return (-1);
852
853 LIST_FOREACH(iface, &xconf->iface_list, entry) {
854 if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface,
855 sizeof(*iface)) == -1)
856 return (-1);
857 }
858
859 LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) {
860 if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr,
861 sizeof(*tnbr)) == -1)
862 return (-1);
863 }
864
865 LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) {
866 if (main_imsg_compose_both(IMSG_RECONF_NBRP, nbrp,
867 sizeof(*nbrp)) == -1)
868 return (-1);
869 }
870
871 LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
872 if (main_imsg_compose_both(IMSG_RECONF_L2VPN, l2vpn,
873 sizeof(*l2vpn)) == -1)
874 return (-1);
875
876 LIST_FOREACH(lif, &l2vpn->if_list, entry) {
877 if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IF, lif,
878 sizeof(*lif)) == -1)
879 return (-1);
880 }
881 LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
882 if (main_imsg_compose_both(IMSG_RECONF_L2VPN_PW, pw,
883 sizeof(*pw)) == -1)
884 return (-1);
885 }
eac6e3f0
RW
886 LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
887 if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IPW, pw,
888 sizeof(*pw)) == -1)
889 return (-1);
890 }
8429abe0
RW
891 }
892
893 if (main_imsg_compose_both(IMSG_RECONF_END, NULL, 0) == -1)
894 return (-1);
895
896 return (0);
897}
898
eac6e3f0 899int
b67c140b 900ldp_reload_ref(struct ldpd_conf *xconf, void **ref)
8429abe0 901{
b67c140b 902 ldp_config_normalize(xconf, ref);
8429abe0
RW
903
904 if (main_imsg_send_config(xconf) == -1)
905 return (-1);
906
b67c140b 907 merge_config_ref(ldpd_conf, xconf, ref);
8429abe0
RW
908
909 return (0);
910}
911
b67c140b
RW
912int
913ldp_reload(struct ldpd_conf *xconf)
914{
915 return ldp_reload_ref(xconf, NULL);
916}
917
eac6e3f0 918static void
b67c140b 919ldp_config_normalize(struct ldpd_conf *xconf, void **ref)
eac6e3f0
RW
920{
921 struct l2vpn *l2vpn;
922 struct l2vpn_pw *pw;
923
924 if (!(xconf->flags & F_LDPD_ENABLED))
b67c140b 925 ldp_config_reset_main(xconf, ref);
eac6e3f0
RW
926 else {
927 if (!(xconf->ipv4.flags & F_LDPD_AF_ENABLED))
b67c140b 928 ldp_config_reset_af(xconf, AF_INET, ref);
eac6e3f0 929 if (!(xconf->ipv6.flags & F_LDPD_AF_ENABLED))
b67c140b 930 ldp_config_reset_af(xconf, AF_INET6, ref);
eac6e3f0
RW
931 }
932
933 LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
934 LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
935 if (pw->flags & F_PW_STATIC_NBR_ADDR)
936 continue;
937
938 pw->af = AF_INET;
939 pw->addr.v4 = pw->lsr_id;
940 }
941 LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
942 if (pw->flags & F_PW_STATIC_NBR_ADDR)
943 continue;
944
945 pw->af = AF_INET;
946 pw->addr.v4 = pw->lsr_id;
947 }
948 }
949}
950
951static void
b67c140b 952ldp_config_reset_main(struct ldpd_conf *conf, void **ref)
eac6e3f0
RW
953{
954 struct iface *iface;
955 struct nbr_params *nbrp;
956
957 while ((iface = LIST_FIRST(&conf->iface_list)) != NULL) {
b67c140b
RW
958 if (ref && *ref == iface)
959 *ref = NULL;
eac6e3f0
RW
960 LIST_REMOVE(iface, entry);
961 free(iface);
962 }
963
964 while ((nbrp = LIST_FIRST(&conf->nbrp_list)) != NULL) {
b67c140b
RW
965 if (ref && *ref == nbrp)
966 *ref = NULL;
eac6e3f0
RW
967 LIST_REMOVE(nbrp, entry);
968 free(nbrp);
969 }
970
971 conf->rtr_id.s_addr = INADDR_ANY;
b67c140b
RW
972 ldp_config_reset_af(conf, AF_INET, ref);
973 ldp_config_reset_af(conf, AF_INET6, ref);
eac6e3f0
RW
974 conf->lhello_holdtime = LINK_DFLT_HOLDTIME;
975 conf->lhello_interval = DEFAULT_HELLO_INTERVAL;
976 conf->thello_holdtime = TARGETED_DFLT_HOLDTIME;
977 conf->thello_interval = DEFAULT_HELLO_INTERVAL;
978 conf->trans_pref = DUAL_STACK_LDPOV6;
979 conf->flags = 0;
980}
981
982static void
b67c140b 983ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref)
eac6e3f0
RW
984{
985 struct ldpd_af_conf *af_conf;
986 struct iface *iface;
987 struct iface_af *ia;
988 struct tnbr *tnbr, *ttmp;
989
990 LIST_FOREACH(iface, &conf->iface_list, entry) {
991 ia = iface_af_get(iface, af);
992 ia->enabled = 0;
993 }
994
995 LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
996 if (tnbr->af != af)
997 continue;
998
b67c140b
RW
999 if (ref && *ref == tnbr)
1000 *ref = NULL;
eac6e3f0
RW
1001 LIST_REMOVE(tnbr, entry);
1002 free(tnbr);
1003 }
1004
1005 af_conf = ldp_af_conf_get(conf, af);
1006 af_conf->keepalive = 180;
1007 af_conf->lhello_holdtime = 0;
1008 af_conf->lhello_interval = 0;
1009 af_conf->thello_holdtime = 0;
1010 af_conf->thello_interval = 0;
1011 memset(&af_conf->trans_addr, 0, sizeof(af_conf->trans_addr));
1012 af_conf->flags = 0;
1013}
1014
1015struct ldpd_conf *
b67c140b 1016ldp_dup_config_ref(struct ldpd_conf *conf, void **ref)
eac6e3f0
RW
1017{
1018 struct ldpd_conf *xconf;
1019 struct iface *iface, *xi;
1020 struct tnbr *tnbr, *xt;
1021 struct nbr_params *nbrp, *xn;
1022 struct l2vpn *l2vpn, *xl;
1023 struct l2vpn_if *lif, *xf;
1024 struct l2vpn_pw *pw, *xp;
1025
b67c140b
RW
1026#define COPY(a, b) do { \
1027 a = calloc(1, sizeof(*a)); \
1028 if (a == NULL) \
1029 fatal(__func__); \
1030 *a = *b; \
1031 if (ref && *ref == b) *ref = a; \
1032 } while (0)
1033
1034 COPY(xconf, conf);
eac6e3f0
RW
1035 LIST_INIT(&xconf->iface_list);
1036 LIST_INIT(&xconf->tnbr_list);
1037 LIST_INIT(&xconf->nbrp_list);
1038 LIST_INIT(&xconf->l2vpn_list);
1039
1040 LIST_FOREACH(iface, &conf->iface_list, entry) {
b67c140b 1041 COPY(xi, iface);
eac6e3f0
RW
1042 xi->ipv4.iface = xi;
1043 xi->ipv6.iface = xi;
1044 LIST_INSERT_HEAD(&xconf->iface_list, xi, entry);
1045 }
1046 LIST_FOREACH(tnbr, &conf->tnbr_list, entry) {
b67c140b 1047 COPY(xt, tnbr);
eac6e3f0
RW
1048 LIST_INSERT_HEAD(&xconf->tnbr_list, xt, entry);
1049 }
1050 LIST_FOREACH(nbrp, &conf->nbrp_list, entry) {
b67c140b 1051 COPY(xn, nbrp);
eac6e3f0
RW
1052 LIST_INSERT_HEAD(&xconf->nbrp_list, xn, entry);
1053 }
1054 LIST_FOREACH(l2vpn, &conf->l2vpn_list, entry) {
b67c140b 1055 COPY(xl, l2vpn);
eac6e3f0
RW
1056 LIST_INIT(&xl->if_list);
1057 LIST_INIT(&xl->pw_list);
1058 LIST_INIT(&xl->pw_inactive_list);
1059 LIST_INSERT_HEAD(&xconf->l2vpn_list, xl, entry);
1060
1061 LIST_FOREACH(lif, &l2vpn->if_list, entry) {
b67c140b 1062 COPY(xf, lif);
eac6e3f0
RW
1063 xf->l2vpn = xl;
1064 LIST_INSERT_HEAD(&xl->if_list, xf, entry);
1065 }
1066 LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
b67c140b 1067 COPY(xp, pw);
eac6e3f0
RW
1068 xp->l2vpn = xl;
1069 LIST_INSERT_HEAD(&xl->pw_list, xp, entry);
1070 }
1071 LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
b67c140b 1072 COPY(xp, pw);
eac6e3f0
RW
1073 xp->l2vpn = xl;
1074 LIST_INSERT_HEAD(&xl->pw_inactive_list, xp, entry);
1075 }
1076 }
b67c140b 1077#undef COPY
eac6e3f0
RW
1078
1079 return (xconf);
1080}
1081
b67c140b
RW
1082struct ldpd_conf *
1083ldp_dup_config(struct ldpd_conf *conf)
1084{
1085 return ldp_dup_config_ref(conf, NULL);
1086}
1087
eac6e3f0
RW
1088void
1089ldp_clear_config(struct ldpd_conf *xconf)
1090{
1091 struct iface *iface;
1092 struct tnbr *tnbr;
1093 struct nbr_params *nbrp;
1094 struct l2vpn *l2vpn;
1095
1096 while ((iface = LIST_FIRST(&xconf->iface_list)) != NULL) {
1097 LIST_REMOVE(iface, entry);
1098 free(iface);
1099 }
1100 while ((tnbr = LIST_FIRST(&xconf->tnbr_list)) != NULL) {
1101 LIST_REMOVE(tnbr, entry);
1102 free(tnbr);
1103 }
1104 while ((nbrp = LIST_FIRST(&xconf->nbrp_list)) != NULL) {
1105 LIST_REMOVE(nbrp, entry);
1106 free(nbrp);
1107 }
1108 while ((l2vpn = LIST_FIRST(&xconf->l2vpn_list)) != NULL) {
1109 LIST_REMOVE(l2vpn, entry);
1110 l2vpn_del(l2vpn);
1111 }
1112
1113 free(xconf);
1114}
1115
b67c140b
RW
1116static void
1117merge_config_ref(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
8429abe0
RW
1118{
1119 merge_global(conf, xconf);
1120 merge_af(AF_INET, &conf->ipv4, &xconf->ipv4);
1121 merge_af(AF_INET6, &conf->ipv6, &xconf->ipv6);
b67c140b
RW
1122 merge_ifaces(conf, xconf, ref);
1123 merge_tnbrs(conf, xconf, ref);
1124 merge_nbrps(conf, xconf, ref);
1125 merge_l2vpns(conf, xconf, ref);
1126 if (ref && *ref == xconf)
1127 *ref = conf;
8429abe0
RW
1128 free(xconf);
1129}
1130
b67c140b
RW
1131void
1132merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
1133{
1134 merge_config_ref(conf, xconf, NULL);
1135}
1136
8429abe0
RW
1137static void
1138merge_global(struct ldpd_conf *conf, struct ldpd_conf *xconf)
1139{
1140 /* change of router-id requires resetting all neighborships */
1141 if (conf->rtr_id.s_addr != xconf->rtr_id.s_addr) {
1142 if (ldpd_process == PROC_LDP_ENGINE) {
1143 ldpe_reset_nbrs(AF_INET);
1144 ldpe_reset_nbrs(AF_INET6);
1145 if (conf->rtr_id.s_addr == INADDR_ANY ||
1146 xconf->rtr_id.s_addr == INADDR_ANY) {
1147 if_update_all(AF_UNSPEC);
1148 tnbr_update_all(AF_UNSPEC);
1149 }
1150 }
1151 conf->rtr_id = xconf->rtr_id;
1152 }
1153
eac6e3f0
RW
1154 conf->lhello_holdtime = xconf->lhello_holdtime;
1155 conf->lhello_interval = xconf->lhello_interval;
1156 conf->thello_holdtime = xconf->thello_holdtime;
1157 conf->thello_interval = xconf->thello_interval;
1158
8429abe0
RW
1159 if (conf->trans_pref != xconf->trans_pref) {
1160 if (ldpd_process == PROC_LDP_ENGINE)
1161 ldpe_reset_ds_nbrs();
1162 conf->trans_pref = xconf->trans_pref;
1163 }
1164
1165 if ((conf->flags & F_LDPD_DS_CISCO_INTEROP) !=
1166 (xconf->flags & F_LDPD_DS_CISCO_INTEROP)) {
1167 if (ldpd_process == PROC_LDP_ENGINE)
1168 ldpe_reset_ds_nbrs();
1169 }
1170
1171 conf->flags = xconf->flags;
1172}
1173
1174static void
1175merge_af(int af, struct ldpd_af_conf *af_conf, struct ldpd_af_conf *xa)
1176{
1177 int egress_label_changed = 0;
1178 int update_sockets = 0;
1179
1180 if (af_conf->keepalive != xa->keepalive) {
1181 af_conf->keepalive = xa->keepalive;
1182 if (ldpd_process == PROC_LDP_ENGINE)
1183 ldpe_stop_init_backoff(af);
1184 }
eac6e3f0
RW
1185
1186 af_conf->lhello_holdtime = xa->lhello_holdtime;
1187 af_conf->lhello_interval = xa->lhello_interval;
8429abe0
RW
1188 af_conf->thello_holdtime = xa->thello_holdtime;
1189 af_conf->thello_interval = xa->thello_interval;
1190
1191 /* update flags */
1192 if (ldpd_process == PROC_LDP_ENGINE &&
1193 (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) &&
1194 !(xa->flags & F_LDPD_AF_THELLO_ACCEPT))
1195 ldpe_remove_dynamic_tnbrs(af);
1196
1197 if ((af_conf->flags & F_LDPD_AF_NO_GTSM) !=
1198 (xa->flags & F_LDPD_AF_NO_GTSM)) {
1199 if (af == AF_INET6)
1200 /* need to set/unset IPV6_MINHOPCOUNT */
1201 update_sockets = 1;
1202 else if (ldpd_process == PROC_LDP_ENGINE)
1203 /* for LDPv4 just resetting the neighbors is enough */
1204 ldpe_reset_nbrs(af);
1205 }
1206
1207 if ((af_conf->flags & F_LDPD_AF_EXPNULL) !=
1208 (xa->flags & F_LDPD_AF_EXPNULL))
1209 egress_label_changed = 1;
1210
1211 af_conf->flags = xa->flags;
1212
1213 if (egress_label_changed) {
1214 switch (ldpd_process) {
1215 case PROC_LDE_ENGINE:
1216 lde_change_egress_label(af, af_conf->flags &
1217 F_LDPD_AF_EXPNULL);
1218 break;
8429abe0
RW
1219 default:
1220 break;
1221 }
1222 }
1223
1224 if (ldp_addrcmp(af, &af_conf->trans_addr, &xa->trans_addr)) {
1225 af_conf->trans_addr = xa->trans_addr;
1226 update_sockets = 1;
1227 }
1228
eac6e3f0 1229 if (ldpd_process == PROC_MAIN && iev_ldpe && update_sockets)
8429abe0
RW
1230 imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af, 0, -1,
1231 NULL, 0);
1232}
1233
1234static void
b67c140b 1235merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
8429abe0
RW
1236{
1237 struct iface *iface, *itmp, *xi;
1238
1239 LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) {
1240 /* find deleted interfaces */
eac6e3f0 1241 if ((xi = if_lookup_name(xconf, iface->name)) == NULL) {
8429abe0 1242 LIST_REMOVE(iface, entry);
4af8997d
RW
1243
1244 switch (ldpd_process) {
1245 case PROC_LDE_ENGINE:
1246 break;
1247 case PROC_LDP_ENGINE:
8429abe0 1248 if_exit(iface);
4af8997d
RW
1249 break;
1250 case PROC_MAIN:
1251 QOBJ_UNREG (iface);
1252 break;
1253 }
8429abe0
RW
1254 free(iface);
1255 }
1256 }
1257 LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) {
1258 /* find new interfaces */
eac6e3f0 1259 if ((iface = if_lookup_name(conf, xi->name)) == NULL) {
8429abe0
RW
1260 LIST_REMOVE(xi, entry);
1261 LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
1262
4af8997d
RW
1263 if (ldpd_process == PROC_MAIN) {
1264 QOBJ_REG (xi, iface);
1265 /* resend addresses to activate new interfaces */
8429abe0 1266 kif_redistribute(xi->name);
4af8997d 1267 }
8429abe0
RW
1268 continue;
1269 }
1270
1271 /* update existing interfaces */
1272 merge_iface_af(&iface->ipv4, &xi->ipv4);
1273 merge_iface_af(&iface->ipv6, &xi->ipv6);
1274 LIST_REMOVE(xi, entry);
b67c140b
RW
1275 if (ref && *ref == xi)
1276 *ref = iface;
8429abe0
RW
1277 free(xi);
1278 }
1279}
1280
1281static void
1282merge_iface_af(struct iface_af *ia, struct iface_af *xi)
1283{
1284 if (ia->enabled != xi->enabled) {
1285 ia->enabled = xi->enabled;
1286 if (ldpd_process == PROC_LDP_ENGINE)
1287 if_update(ia->iface, ia->af);
1288 }
1289 ia->hello_holdtime = xi->hello_holdtime;
1290 ia->hello_interval = xi->hello_interval;
1291}
1292
1293static void
b67c140b 1294merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
8429abe0
RW
1295{
1296 struct tnbr *tnbr, *ttmp, *xt;
1297
1298 LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
1299 if (!(tnbr->flags & F_TNBR_CONFIGURED))
1300 continue;
1301
1302 /* find deleted tnbrs */
1303 if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) {
4af8997d
RW
1304 switch (ldpd_process) {
1305 case PROC_LDE_ENGINE:
1306 LIST_REMOVE(tnbr, entry);
1307 free(tnbr);
1308 break;
1309 case PROC_LDP_ENGINE:
8429abe0
RW
1310 tnbr->flags &= ~F_TNBR_CONFIGURED;
1311 tnbr_check(tnbr);
4af8997d
RW
1312 break;
1313 case PROC_MAIN:
8429abe0 1314 LIST_REMOVE(tnbr, entry);
4af8997d 1315 QOBJ_UNREG (tnbr);
8429abe0 1316 free(tnbr);
4af8997d 1317 break;
8429abe0
RW
1318 }
1319 }
1320 }
1321 LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) {
1322 /* find new tnbrs */
1323 if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) {
1324 LIST_REMOVE(xt, entry);
1325 LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry);
1326
4af8997d
RW
1327 switch (ldpd_process) {
1328 case PROC_LDE_ENGINE:
1329 break;
1330 case PROC_LDP_ENGINE:
8429abe0 1331 tnbr_update(xt);
4af8997d
RW
1332 break;
1333 case PROC_MAIN:
1334 QOBJ_REG (xt, tnbr);
1335 break;
1336 }
8429abe0
RW
1337 continue;
1338 }
1339
1340 /* update existing tnbrs */
1341 if (!(tnbr->flags & F_TNBR_CONFIGURED))
1342 tnbr->flags |= F_TNBR_CONFIGURED;
8429abe0 1343 LIST_REMOVE(xt, entry);
b67c140b
RW
1344 if (ref && *ref == xt)
1345 *ref = tnbr;
8429abe0
RW
1346 free(xt);
1347 }
1348}
1349
1350static void
b67c140b 1351merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
8429abe0
RW
1352{
1353 struct nbr_params *nbrp, *ntmp, *xn;
1354 struct nbr *nbr;
1355 int nbrp_changed;
1356
1357 LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) {
1358 /* find deleted nbrps */
1359 if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) {
4af8997d
RW
1360 switch (ldpd_process) {
1361 case PROC_LDE_ENGINE:
1362 break;
1363 case PROC_LDP_ENGINE:
8429abe0
RW
1364 nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
1365 if (nbr) {
1366 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
eac6e3f0 1367#ifdef __OpenBSD__
8429abe0 1368 pfkey_remove(nbr);
eac6e3f0
RW
1369#else
1370 sock_set_md5sig(
1371 (ldp_af_global_get(&global,
1372 nbr->af))->ldp_session_socket,
1373 nbr->af, &nbr->raddr, NULL);
1374#endif
8429abe0
RW
1375 if (nbr_session_active_role(nbr))
1376 nbr_establish_connection(nbr);
1377 }
4af8997d
RW
1378 break;
1379 case PROC_MAIN:
1380 QOBJ_UNREG (nbrp);
1381 break;
8429abe0
RW
1382 }
1383 LIST_REMOVE(nbrp, entry);
1384 free(nbrp);
1385 }
1386 }
1387 LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) {
1388 /* find new nbrps */
1389 if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) {
1390 LIST_REMOVE(xn, entry);
1391 LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry);
1392
4af8997d
RW
1393 switch (ldpd_process) {
1394 case PROC_LDE_ENGINE:
1395 break;
1396 case PROC_LDP_ENGINE:
8429abe0
RW
1397 nbr = nbr_find_ldpid(xn->lsr_id.s_addr);
1398 if (nbr) {
1399 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
eac6e3f0 1400#ifdef __OpenBSD__
8429abe0
RW
1401 if (pfkey_establish(nbr, xn) == -1)
1402 fatalx("pfkey setup failed");
eac6e3f0
RW
1403#else
1404 sock_set_md5sig(
1405 (ldp_af_global_get(&global,
1406 nbr->af))->ldp_session_socket,
1407 nbr->af, &nbr->raddr,
1408 xn->auth.md5key);
1409#endif
8429abe0
RW
1410 if (nbr_session_active_role(nbr))
1411 nbr_establish_connection(nbr);
1412 }
4af8997d
RW
1413 break;
1414 case PROC_MAIN:
1415 QOBJ_REG (xn, nbr_params);
1416 break;
8429abe0
RW
1417 }
1418 continue;
1419 }
1420
1421 /* update existing nbrps */
1422 if (nbrp->flags != xn->flags ||
1423 nbrp->keepalive != xn->keepalive ||
1424 nbrp->gtsm_enabled != xn->gtsm_enabled ||
1425 nbrp->gtsm_hops != xn->gtsm_hops ||
1426 nbrp->auth.method != xn->auth.method ||
1427 strcmp(nbrp->auth.md5key, xn->auth.md5key) != 0)
1428 nbrp_changed = 1;
1429 else
1430 nbrp_changed = 0;
1431
1432 nbrp->keepalive = xn->keepalive;
1433 nbrp->gtsm_enabled = xn->gtsm_enabled;
1434 nbrp->gtsm_hops = xn->gtsm_hops;
1435 nbrp->auth.method = xn->auth.method;
1436 strlcpy(nbrp->auth.md5key, xn->auth.md5key,
1437 sizeof(nbrp->auth.md5key));
1438 nbrp->auth.md5key_len = xn->auth.md5key_len;
1439 nbrp->flags = xn->flags;
1440
1441 if (ldpd_process == PROC_LDP_ENGINE) {
1442 nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
1443 if (nbr && nbrp_changed) {
1444 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
eac6e3f0 1445#ifdef __OpenBSD__
8429abe0
RW
1446 pfkey_remove(nbr);
1447 if (pfkey_establish(nbr, nbrp) == -1)
1448 fatalx("pfkey setup failed");
eac6e3f0
RW
1449#else
1450 sock_set_md5sig((ldp_af_global_get(&global,
1451 nbr->af))->ldp_session_socket, nbr->af,
1452 &nbr->raddr, nbrp->auth.md5key);
1453#endif
8429abe0
RW
1454 if (nbr_session_active_role(nbr))
1455 nbr_establish_connection(nbr);
1456 }
1457 }
1458 LIST_REMOVE(xn, entry);
b67c140b
RW
1459 if (ref && *ref == xn)
1460 *ref = nbrp;
8429abe0
RW
1461 free(xn);
1462 }
1463}
1464
1465static void
b67c140b 1466merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
8429abe0
RW
1467{
1468 struct l2vpn *l2vpn, *ltmp, *xl;
4af8997d
RW
1469 struct l2vpn_if *lif;
1470 struct l2vpn_pw *pw;
8429abe0
RW
1471
1472 LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) {
1473 /* find deleted l2vpns */
1474 if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
1475 LIST_REMOVE(l2vpn, entry);
1476
1477 switch (ldpd_process) {
1478 case PROC_LDE_ENGINE:
1479 l2vpn_exit(l2vpn);
1480 break;
1481 case PROC_LDP_ENGINE:
1482 ldpe_l2vpn_exit(l2vpn);
1483 break;
1484 case PROC_MAIN:
4af8997d
RW
1485 LIST_FOREACH(lif, &l2vpn->if_list, entry)
1486 QOBJ_UNREG (lif);
1487 LIST_FOREACH(pw, &l2vpn->pw_list, entry)
1488 QOBJ_UNREG (pw);
1489 LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
1490 QOBJ_UNREG (pw);
1491 QOBJ_UNREG (l2vpn);
8429abe0
RW
1492 break;
1493 }
1494 l2vpn_del(l2vpn);
1495 }
1496 }
1497 LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) {
1498 /* find new l2vpns */
1499 if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
1500 LIST_REMOVE(xl, entry);
1501 LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry);
1502
1503 switch (ldpd_process) {
1504 case PROC_LDE_ENGINE:
1505 l2vpn_init(xl);
1506 break;
1507 case PROC_LDP_ENGINE:
1508 ldpe_l2vpn_init(xl);
1509 break;
1510 case PROC_MAIN:
4af8997d 1511 QOBJ_REG (xl, l2vpn);
8429abe0
RW
1512 break;
1513 }
1514 continue;
1515 }
1516
1517 /* update existing l2vpns */
b67c140b 1518 merge_l2vpn(conf, l2vpn, xl, ref);
8429abe0 1519 LIST_REMOVE(xl, entry);
b67c140b
RW
1520 if (ref && *ref == xl)
1521 *ref = l2vpn;
8429abe0
RW
1522 free(xl);
1523 }
1524}
1525
1526static void
b67c140b 1527merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void **ref)
8429abe0
RW
1528{
1529 struct l2vpn_if *lif, *ftmp, *xf;
1530 struct l2vpn_pw *pw, *ptmp, *xp;
1531 struct nbr *nbr;
1532 int reset_nbr, reinstall_pwfec, reinstall_tnbr;
eac6e3f0 1533 LIST_HEAD(, l2vpn_pw) pw_aux_list;
8429abe0
RW
1534 int previous_pw_type, previous_mtu;
1535
1536 previous_pw_type = l2vpn->pw_type;
1537 previous_mtu = l2vpn->mtu;
1538
1539 /* merge intefaces */
1540 LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) {
1541 /* find deleted interfaces */
eac6e3f0 1542 if ((xf = l2vpn_if_find_name(xl, lif->ifname)) == NULL) {
4af8997d
RW
1543 if (ldpd_process == PROC_MAIN)
1544 QOBJ_UNREG (lif);
8429abe0
RW
1545 LIST_REMOVE(lif, entry);
1546 free(lif);
1547 }
1548 }
1549 LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) {
1550 /* find new interfaces */
eac6e3f0 1551 if ((lif = l2vpn_if_find_name(l2vpn, xf->ifname)) == NULL) {
8429abe0
RW
1552 LIST_REMOVE(xf, entry);
1553 LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
1554 xf->l2vpn = l2vpn;
4af8997d
RW
1555 if (ldpd_process == PROC_MAIN)
1556 QOBJ_REG (xf, l2vpn_if);
8429abe0
RW
1557 continue;
1558 }
1559
1560 LIST_REMOVE(xf, entry);
b67c140b
RW
1561 if (ref && *ref == xf)
1562 *ref = lif;
8429abe0
RW
1563 free(xf);
1564 }
1565
eac6e3f0
RW
1566 /* merge active pseudowires */
1567 LIST_INIT(&pw_aux_list);
8429abe0 1568 LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) {
eac6e3f0
RW
1569 /* find deleted active pseudowires */
1570 if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
8429abe0
RW
1571 switch (ldpd_process) {
1572 case PROC_LDE_ENGINE:
1573 l2vpn_pw_exit(pw);
1574 break;
1575 case PROC_LDP_ENGINE:
1576 ldpe_l2vpn_pw_exit(pw);
1577 break;
1578 case PROC_MAIN:
4af8997d 1579 QOBJ_UNREG (pw);
8429abe0
RW
1580 break;
1581 }
1582
1583 LIST_REMOVE(pw, entry);
1584 free(pw);
1585 }
1586 }
1587 LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) {
eac6e3f0
RW
1588 /* find new active pseudowires */
1589 if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
8429abe0
RW
1590 LIST_REMOVE(xp, entry);
1591 LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry);
1592 xp->l2vpn = l2vpn;
1593
1594 switch (ldpd_process) {
1595 case PROC_LDE_ENGINE:
1596 l2vpn_pw_init(xp);
1597 break;
1598 case PROC_LDP_ENGINE:
1599 ldpe_l2vpn_pw_init(xp);
1600 break;
1601 case PROC_MAIN:
4af8997d 1602 QOBJ_REG (xp, l2vpn_pw);
8429abe0
RW
1603 break;
1604 }
1605 continue;
1606 }
1607
eac6e3f0 1608 /* update existing active pseudowire */
8429abe0
RW
1609 if (pw->af != xp->af ||
1610 ldp_addrcmp(pw->af, &pw->addr, &xp->addr))
1611 reinstall_tnbr = 1;
1612 else
1613 reinstall_tnbr = 0;
1614
1615 /* changes that require a session restart */
1616 if ((pw->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)) !=
1617 (xp->flags & (F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF)))
1618 reset_nbr = 1;
1619 else
1620 reset_nbr = 0;
1621
1622 if (l2vpn->pw_type != xl->pw_type || l2vpn->mtu != xl->mtu ||
1623 pw->pwid != xp->pwid || reinstall_tnbr || reset_nbr ||
1624 pw->lsr_id.s_addr != xp->lsr_id.s_addr)
1625 reinstall_pwfec = 1;
1626 else
1627 reinstall_pwfec = 0;
1628
eac6e3f0
RW
1629 /* check if the pseudowire should be disabled */
1630 if (xp->lsr_id.s_addr == INADDR_ANY || xp->pwid == 0) {
1631 reinstall_tnbr = 0;
1632 reset_nbr = 0;
1633 reinstall_pwfec = 0;
1634
1635 switch (ldpd_process) {
1636 case PROC_LDE_ENGINE:
1637 l2vpn_pw_exit(pw);
1638 break;
1639 case PROC_LDP_ENGINE:
1640 ldpe_l2vpn_pw_exit(pw);
1641 break;
1642 case PROC_MAIN:
1643 break;
1644 }
1645
1646 /* remove from active list */
1647 LIST_REMOVE(pw, entry);
1648 LIST_INSERT_HEAD(&pw_aux_list, pw, entry);
1649 }
1650
8429abe0
RW
1651 if (ldpd_process == PROC_LDP_ENGINE) {
1652 if (reinstall_tnbr)
1653 ldpe_l2vpn_pw_exit(pw);
1654 if (reset_nbr) {
1655 nbr = nbr_find_ldpid(pw->lsr_id.s_addr);
1656 if (nbr && nbr->state == NBR_STA_OPER)
1657 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
1658 }
1659 }
1660 if (ldpd_process == PROC_LDE_ENGINE &&
1661 !reset_nbr && reinstall_pwfec)
1662 l2vpn_pw_exit(pw);
1663 pw->lsr_id = xp->lsr_id;
1664 pw->af = xp->af;
1665 pw->addr = xp->addr;
1666 pw->pwid = xp->pwid;
1667 strlcpy(pw->ifname, xp->ifname, sizeof(pw->ifname));
1668 pw->ifindex = xp->ifindex;
1669 if (xp->flags & F_PW_CWORD_CONF)
1670 pw->flags |= F_PW_CWORD_CONF;
1671 else
1672 pw->flags &= ~F_PW_CWORD_CONF;
1673 if (xp->flags & F_PW_STATUSTLV_CONF)
1674 pw->flags |= F_PW_STATUSTLV_CONF;
1675 else
1676 pw->flags &= ~F_PW_STATUSTLV_CONF;
eac6e3f0
RW
1677 if (xp->flags & F_PW_STATIC_NBR_ADDR)
1678 pw->flags |= F_PW_STATIC_NBR_ADDR;
1679 else
1680 pw->flags &= ~F_PW_STATIC_NBR_ADDR;
8429abe0
RW
1681 if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr)
1682 ldpe_l2vpn_pw_init(pw);
1683 if (ldpd_process == PROC_LDE_ENGINE &&
1684 !reset_nbr && reinstall_pwfec) {
1685 l2vpn->pw_type = xl->pw_type;
1686 l2vpn->mtu = xl->mtu;
1687 l2vpn_pw_init(pw);
1688 l2vpn->pw_type = previous_pw_type;
1689 l2vpn->mtu = previous_mtu;
1690 }
1691
1692 LIST_REMOVE(xp, entry);
b67c140b
RW
1693 if (ref && *ref == xp)
1694 *ref = pw;
8429abe0
RW
1695 free(xp);
1696 }
1697
eac6e3f0
RW
1698 /* merge inactive pseudowires */
1699 LIST_FOREACH_SAFE(pw, &l2vpn->pw_inactive_list, entry, ptmp) {
1700 /* find deleted inactive pseudowires */
1701 if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
1702 LIST_REMOVE(pw, entry);
4af8997d
RW
1703 if (ldpd_process == PROC_MAIN)
1704 QOBJ_UNREG (pw);
eac6e3f0
RW
1705 free(pw);
1706 }
1707 }
1708 LIST_FOREACH_SAFE(xp, &xl->pw_inactive_list, entry, ptmp) {
1709 /* find new inactive pseudowires */
1710 if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
1711 LIST_REMOVE(xp, entry);
1712 LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, xp, entry);
1713 xp->l2vpn = l2vpn;
4af8997d
RW
1714 if (ldpd_process == PROC_MAIN)
1715 QOBJ_REG (xp, l2vpn_pw);
eac6e3f0
RW
1716 continue;
1717 }
1718
1719 /* update existing inactive pseudowire */
1720 pw->lsr_id.s_addr = xp->lsr_id.s_addr;
1721 pw->af = xp->af;
1722 pw->addr = xp->addr;
1723 pw->pwid = xp->pwid;
1724 strlcpy(pw->ifname, xp->ifname, sizeof(pw->ifname));
1725 pw->ifindex = xp->ifindex;
1726 pw->flags = xp->flags;
1727
1728 /* check if the pseudowire should be activated */
1729 if (pw->lsr_id.s_addr != INADDR_ANY && pw->pwid != 0) {
1730 /* remove from inactive list */
1731 LIST_REMOVE(pw, entry);
1732 LIST_INSERT_HEAD(&l2vpn->pw_list, pw, entry);
1733
1734 switch (ldpd_process) {
1735 case PROC_LDE_ENGINE:
1736 l2vpn_pw_init(pw);
1737 break;
1738 case PROC_LDP_ENGINE:
1739 ldpe_l2vpn_pw_init(pw);
1740 break;
1741 case PROC_MAIN:
1742 break;
1743 }
1744 }
1745
1746 LIST_REMOVE(xp, entry);
b67c140b
RW
1747 if (ref && *ref == xp)
1748 *ref = pw;
eac6e3f0
RW
1749 free(xp);
1750 }
1751
1752 /* insert pseudowires that were disabled in the inactive list */
1753 LIST_FOREACH_SAFE(pw, &pw_aux_list, entry, ptmp) {
1754 LIST_REMOVE(pw, entry);
1755 LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
1756 }
1757
8429abe0
RW
1758 l2vpn->pw_type = xl->pw_type;
1759 l2vpn->mtu = xl->mtu;
1760 strlcpy(l2vpn->br_ifname, xl->br_ifname, sizeof(l2vpn->br_ifname));
1761 l2vpn->br_ifindex = xl->br_ifindex;
1762}
1763
1764struct ldpd_conf *
1765config_new_empty(void)
1766{
1767 struct ldpd_conf *xconf;
1768
1769 xconf = calloc(1, sizeof(*xconf));
1770 if (xconf == NULL)
1771 fatal(NULL);
1772
1773 LIST_INIT(&xconf->iface_list);
1774 LIST_INIT(&xconf->tnbr_list);
1775 LIST_INIT(&xconf->nbrp_list);
1776 LIST_INIT(&xconf->l2vpn_list);
1777
1778 return (xconf);
1779}
1780
1781void
1782config_clear(struct ldpd_conf *conf)
1783{
1784 struct ldpd_conf *xconf;
1785
1786 /*
1787 * Merge current config with an empty config, this will deactivate
1788 * and deallocate all the interfaces, pseudowires and so on. Before
1789 * merging, copy the router-id and other variables to avoid some
1790 * unnecessary operations, like trying to reset the neighborships.
1791 */
1792 xconf = config_new_empty();
1793 xconf->ipv4 = conf->ipv4;
1794 xconf->ipv6 = conf->ipv6;
1795 xconf->rtr_id = conf->rtr_id;
1796 xconf->trans_pref = conf->trans_pref;
1797 xconf->flags = conf->flags;
1798 merge_config(conf, xconf);
4af8997d
RW
1799 if (ldpd_process == PROC_MAIN)
1800 QOBJ_UNREG (conf);
8429abe0
RW
1801 free(conf);
1802}