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