]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/ldpd.c
ldpd: use red-black trees to store 'iface' elements
[mirror_frr.git] / ldpd / ldpd.c
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
22 #include <zebra.h>
23 #include <sys/wait.h>
24
25 #include "ldpd.h"
26 #include "ldpe.h"
27 #include "lde.h"
28 #include "log.h"
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 #include "qobj.h"
43
44 static void ldpd_shutdown(void);
45 static pid_t start_child(enum ldpd_process, char *, int,
46 const char *, const char *);
47 static int main_dispatch_ldpe(struct thread *);
48 static int main_dispatch_lde(struct thread *);
49 static int main_imsg_send_ipc_sockets(struct imsgbuf *,
50 struct imsgbuf *);
51 static void main_imsg_send_net_sockets(int);
52 static void main_imsg_send_net_socket(int, enum socket_type);
53 static int main_imsg_send_config(struct ldpd_conf *);
54 static void ldp_config_normalize(struct ldpd_conf *, void **);
55 static void ldp_config_reset_main(struct ldpd_conf *, void **);
56 static void ldp_config_reset_af(struct ldpd_conf *, int, void **);
57 static void merge_config_ref(struct ldpd_conf *, struct ldpd_conf *, void **);
58 static void merge_global(struct ldpd_conf *, struct ldpd_conf *);
59 static void merge_af(int, struct ldpd_af_conf *,
60 struct ldpd_af_conf *);
61 static void merge_ifaces(struct ldpd_conf *, struct ldpd_conf *, void **);
62 static void merge_iface_af(struct iface_af *, struct iface_af *);
63 static void merge_tnbrs(struct ldpd_conf *, struct ldpd_conf *, void **);
64 static void merge_nbrps(struct ldpd_conf *, struct ldpd_conf *, void **);
65 static void merge_l2vpns(struct ldpd_conf *, struct ldpd_conf *, void **);
66 static void merge_l2vpn(struct ldpd_conf *, struct l2vpn *,
67 struct l2vpn *, void **);
68
69 DEFINE_QOBJ_TYPE(iface)
70 DEFINE_QOBJ_TYPE(tnbr)
71 DEFINE_QOBJ_TYPE(nbr_params)
72 DEFINE_QOBJ_TYPE(l2vpn_if)
73 DEFINE_QOBJ_TYPE(l2vpn_pw)
74 DEFINE_QOBJ_TYPE(l2vpn)
75 DEFINE_QOBJ_TYPE(ldpd_conf)
76
77 struct ldpd_global global;
78 struct ldpd_conf *ldpd_conf;
79
80 static struct imsgev *iev_ldpe;
81 static struct imsgev *iev_lde;
82 static pid_t ldpe_pid;
83 static pid_t lde_pid;
84
85 #define LDP_DEFAULT_CONFIG "ldpd.conf"
86 #define LDP_VTY_PORT 2612
87
88 /* Master of threads. */
89 struct thread_master *master;
90
91 /* Process ID saved for use by init system */
92 static const char *pid_file = PATH_LDPD_PID;
93
94 /* Configuration filename and directory. */
95 static char config_default[] = SYSCONFDIR LDP_DEFAULT_CONFIG;
96
97 /* ldpd privileges */
98 static zebra_capabilities_t _caps_p [] =
99 {
100 ZCAP_BIND,
101 ZCAP_NET_ADMIN
102 };
103
104 struct 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. */
119 static 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. */
136 static void __attribute__ ((noreturn))
137 usage(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\
144 Daemon 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\
157 Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS);
158 }
159
160 exit(status);
161 }
162
163 /* SIGHUP handler. */
164 static void
165 sighup(void)
166 {
167 log_info("SIGHUP received");
168 }
169
170 /* SIGINT / SIGTERM handler. */
171 static void
172 sigint(void)
173 {
174 log_info("SIGINT received");
175 ldpd_shutdown();
176 }
177
178 /* SIGUSR1 handler. */
179 static void
180 sigusr1(void)
181 {
182 zlog_rotate(NULL);
183 }
184
185 static 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
205 int
206 main(int argc, char *argv[])
207 {
208 char *saved_argv0;
209 int lflag = 0, eflag = 0;
210 int pipe_parent2ldpe[2];
211 int pipe_parent2lde[2];
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;
222
223 ldpd_process = PROC_MAIN;
224
225 /* Set umask before anything for security */
226 umask(0027);
227
228 /* get program name */
229 progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
230
231 saved_argv0 = argv[0];
232 if (saved_argv0 == NULL)
233 saved_argv0 = (char *)"ldpd";
234
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)
242 break;
243
244 switch (opt) {
245 case 0:
246 break;
247 case 'd':
248 daemon_mode = 1;
249 break;
250 case 'f':
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;
277 break;
278 case 'g':
279 group = optarg;
280 break;
281 case 'v':
282 print_version(progname);
283 exit(0);
284 break;
285 case 'C':
286 dryrun = 1;
287 break;
288 case 'h':
289 usage(progname, 0);
290 break;
291 case 'L':
292 lflag = 1;
293 break;
294 case 'E':
295 eflag = 1;
296 break;
297 default:
298 usage(progname, 1);
299 break;
300 }
301 }
302
303 argc -= optind;
304 argv += optind;
305 if (argc > 0 || (lflag && eflag))
306 usage(progname, 1);
307
308 /* check for root privileges */
309 if (geteuid() != 0) {
310 errno = EPERM;
311 perror(progname);
312 exit(1);
313 }
314
315 zlog_default = openzlog(progname, ZLOG_LDP, 0,
316 LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
317
318 if (lflag)
319 lde(user, group);
320 else if (eflag)
321 ldpe(user, group);
322
323 master = thread_master_create();
324
325 cmd_init(1);
326 vty_config_lockless ();
327 vty_init(master);
328 vrf_init();
329 ldp_vty_init();
330 ldp_vty_if_init();
331
332 /* Get configuration file. */
333 ldpd_conf = config_new_empty();
334 ldp_config_reset_main(ldpd_conf, NULL);
335 vty_read_config(config_file, config_default);
336
337 /* Start execution only if not in dry-run mode */
338 if (dryrun)
339 exit(0);
340
341 QOBJ_REG (ldpd_conf, ldpd_conf);
342
343 if (daemon_mode && daemon(0, 0) < 0) {
344 log_warn("LDPd daemon failed");
345 exit(1);
346 }
347
348 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
349 fatal("socketpair");
350 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2lde) == -1)
351 fatal("socketpair");
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]);
360
361 /* start children */
362 lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
363 pipe_parent2lde[1], user, group);
364 ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
365 pipe_parent2ldpe[1], user, group);
366
367 /* drop privileges */
368 if (user)
369 ldpd_privs.user = user;
370 if (group)
371 ldpd_privs.group = group;
372 zprivs_init(&ldpd_privs);
373
374 /* setup signal handler */
375 signal_init(master, array_size(ldp_signals), ldp_signals);
376
377 /* library inits */
378 ldp_zebra_init(master);
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]);
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;
390
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;
397
398 if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
399 fatal("could not establish imsg links");
400 main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug,
401 sizeof(ldp_debug));
402 main_imsg_send_config(ldpd_conf);
403
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
409 /* Process id file create. */
410 pid_output(pid_file);
411
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);
421
422 /* NOTREACHED */
423 return (0);
424 }
425
426 static void
427 ldpd_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
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
459 static pid_t
460 start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
461 const char *group)
462 {
463 char *argv[7];
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:
485 argv[argc++] = (char *)"-L";
486 break;
487 case PROC_LDP_ENGINE:
488 argv[argc++] = (char *)"-E";
489 break;
490 }
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 }
499 argv[argc++] = NULL;
500
501 execvp(argv0, argv);
502 fatal("execvp");
503 }
504
505 /* imsg handling */
506 /* ARGSUSED */
507 static int
508 main_dispatch_ldpe(struct thread *thread)
509 {
510 struct imsgev *iev = THREAD_ARG(thread);
511 struct imsgbuf *ibuf = &iev->ibuf;
512 struct imsg imsg;
513 int af;
514 ssize_t n;
515 int shut = 0;
516
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;
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) {
532 case IMSG_LOG:
533 logit(imsg.hdr.pid, "%s", (const char *)imsg.data);
534 break;
535 case IMSG_REQUEST_SOCKETS:
536 af = imsg.hdr.pid;
537 main_imsg_send_net_sockets(af);
538 break;
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 {
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);
557 }
558
559 return (0);
560 }
561
562 /* ARGSUSED */
563 static int
564 main_dispatch_lde(struct thread *thread)
565 {
566 struct imsgev *iev = THREAD_ARG(thread);
567 struct imsgbuf *ibuf = &iev->ibuf;
568 struct imsg imsg;
569 ssize_t n;
570 int shut = 0;
571
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;
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) {
587 case IMSG_LOG:
588 logit(imsg.hdr.pid, "%s", (const char *)imsg.data);
589 break;
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 {
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);
638 }
639
640 return (0);
641 }
642
643 /* ARGSUSED */
644 int
645 ldp_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);
665 }
666
667 void
668 main_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
675 void
676 main_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
681 int
682 main_imsg_compose_both(enum imsg_type type, void *buf, uint16_t len)
683 {
684 if (iev_ldpe == NULL || iev_lde == NULL)
685 return (0);
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
693 void
694 imsg_event_add(struct imsgev *iev)
695 {
696 THREAD_READ_ON(master, iev->ev_read, iev->handler_read, iev,
697 iev->ibuf.fd);
698
699 if (iev->ibuf.w.queued)
700 THREAD_WRITE_ON(master, iev->ev_write, iev->handler_write, iev,
701 iev->ibuf.fd);
702 }
703
704 int
705 imsg_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
716 void
717 evbuf_enqueue(struct evbuf *eb, struct ibuf *buf)
718 {
719 ibuf_close(&eb->wbuf, buf);
720 evbuf_event_add(eb);
721 }
722
723 void
724 evbuf_event_add(struct evbuf *eb)
725 {
726 if (eb->wbuf.queued)
727 THREAD_WRITE_ON(master, eb->ev, eb->handler, eb->arg,
728 eb->wbuf.fd);
729 }
730
731 void
732 evbuf_init(struct evbuf *eb, int fd, int (*handler)(struct thread *),
733 void *arg)
734 {
735 msgbuf_init(&eb->wbuf);
736 eb->wbuf.fd = fd;
737 eb->handler = handler;
738 eb->arg = arg;
739 }
740
741 void
742 evbuf_clear(struct evbuf *eb)
743 {
744 THREAD_WRITE_OFF(eb->ev);
745 msgbuf_clear(&eb->wbuf);
746 eb->wbuf.fd = -1;
747 }
748
749 static int
750 main_imsg_send_ipc_sockets(struct imsgbuf *ldpe_buf, struct imsgbuf *lde_buf)
751 {
752 int pipe_ldpe2lde[2];
753
754 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_ldpe2lde) == -1)
755 return (-1);
756 sock_set_nonblock(pipe_ldpe2lde[0]);
757 sock_set_nonblock(pipe_ldpe2lde[1]);
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
769 static void
770 main_imsg_send_net_sockets(int af)
771 {
772 if (!ldp_addrisset(af, &(ldp_af_conf_get(ldpd_conf, af))->trans_addr))
773 return;
774
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
781 static void
782 main_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
797 struct ldpd_af_conf *
798 ldp_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
810 struct ldpd_af_global *
811 ldp_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
823 int
824 ldp_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
830 in_addr_t
831 ldp_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
839 static int
840 main_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 RB_FOREACH(iface, iface_head, &xconf->iface_tree) {
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 }
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 }
891 }
892
893 if (main_imsg_compose_both(IMSG_RECONF_END, NULL, 0) == -1)
894 return (-1);
895
896 return (0);
897 }
898
899 int
900 ldp_reload_ref(struct ldpd_conf *xconf, void **ref)
901 {
902 ldp_config_normalize(xconf, ref);
903
904 if (main_imsg_send_config(xconf) == -1)
905 return (-1);
906
907 merge_config_ref(ldpd_conf, xconf, ref);
908
909 return (0);
910 }
911
912 int
913 ldp_reload(struct ldpd_conf *xconf)
914 {
915 return ldp_reload_ref(xconf, NULL);
916 }
917
918 static void
919 ldp_config_normalize(struct ldpd_conf *xconf, void **ref)
920 {
921 struct l2vpn *l2vpn;
922 struct l2vpn_pw *pw;
923
924 if (!(xconf->flags & F_LDPD_ENABLED))
925 ldp_config_reset_main(xconf, ref);
926 else {
927 if (!(xconf->ipv4.flags & F_LDPD_AF_ENABLED))
928 ldp_config_reset_af(xconf, AF_INET, ref);
929 if (!(xconf->ipv6.flags & F_LDPD_AF_ENABLED))
930 ldp_config_reset_af(xconf, AF_INET6, ref);
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
951 static void
952 ldp_config_reset_main(struct ldpd_conf *conf, void **ref)
953 {
954 struct iface *iface;
955 struct nbr_params *nbrp;
956
957 while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) {
958 if (ref && *ref == iface)
959 *ref = NULL;
960 RB_REMOVE(iface_head, &conf->iface_tree, iface);
961 free(iface);
962 }
963
964 while ((nbrp = LIST_FIRST(&conf->nbrp_list)) != NULL) {
965 if (ref && *ref == nbrp)
966 *ref = NULL;
967 LIST_REMOVE(nbrp, entry);
968 free(nbrp);
969 }
970
971 conf->rtr_id.s_addr = INADDR_ANY;
972 ldp_config_reset_af(conf, AF_INET, ref);
973 ldp_config_reset_af(conf, AF_INET6, ref);
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
982 static void
983 ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref)
984 {
985 struct ldpd_af_conf *af_conf;
986 struct iface *iface;
987 struct iface_af *ia;
988 struct tnbr *tnbr, *ttmp;
989
990 RB_FOREACH(iface, iface_head, &conf->iface_tree) {
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
999 if (ref && *ref == tnbr)
1000 *ref = NULL;
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
1015 struct ldpd_conf *
1016 ldp_dup_config_ref(struct ldpd_conf *conf, void **ref)
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
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);
1035 RB_INIT(&xconf->iface_tree);
1036 LIST_INIT(&xconf->tnbr_list);
1037 LIST_INIT(&xconf->nbrp_list);
1038 LIST_INIT(&xconf->l2vpn_list);
1039
1040 RB_FOREACH(iface, iface_head, &conf->iface_tree) {
1041 COPY(xi, iface);
1042 xi->ipv4.iface = xi;
1043 xi->ipv6.iface = xi;
1044 RB_INSERT(iface_head, &xconf->iface_tree, xi);
1045 }
1046 LIST_FOREACH(tnbr, &conf->tnbr_list, entry) {
1047 COPY(xt, tnbr);
1048 LIST_INSERT_HEAD(&xconf->tnbr_list, xt, entry);
1049 }
1050 LIST_FOREACH(nbrp, &conf->nbrp_list, entry) {
1051 COPY(xn, nbrp);
1052 LIST_INSERT_HEAD(&xconf->nbrp_list, xn, entry);
1053 }
1054 LIST_FOREACH(l2vpn, &conf->l2vpn_list, entry) {
1055 COPY(xl, l2vpn);
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) {
1062 COPY(xf, lif);
1063 xf->l2vpn = xl;
1064 LIST_INSERT_HEAD(&xl->if_list, xf, entry);
1065 }
1066 LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
1067 COPY(xp, pw);
1068 xp->l2vpn = xl;
1069 LIST_INSERT_HEAD(&xl->pw_list, xp, entry);
1070 }
1071 LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) {
1072 COPY(xp, pw);
1073 xp->l2vpn = xl;
1074 LIST_INSERT_HEAD(&xl->pw_inactive_list, xp, entry);
1075 }
1076 }
1077 #undef COPY
1078
1079 return (xconf);
1080 }
1081
1082 struct ldpd_conf *
1083 ldp_dup_config(struct ldpd_conf *conf)
1084 {
1085 return ldp_dup_config_ref(conf, NULL);
1086 }
1087
1088 void
1089 ldp_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 = RB_ROOT(&xconf->iface_tree)) != NULL) {
1097 RB_REMOVE(iface_head, &xconf->iface_tree, iface);
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
1116 static void
1117 merge_config_ref(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
1118 {
1119 merge_global(conf, xconf);
1120 merge_af(AF_INET, &conf->ipv4, &xconf->ipv4);
1121 merge_af(AF_INET6, &conf->ipv6, &xconf->ipv6);
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;
1128 free(xconf);
1129 }
1130
1131 void
1132 merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
1133 {
1134 merge_config_ref(conf, xconf, NULL);
1135 }
1136
1137 static void
1138 merge_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
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
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
1174 static void
1175 merge_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 }
1185
1186 af_conf->lhello_holdtime = xa->lhello_holdtime;
1187 af_conf->lhello_interval = xa->lhello_interval;
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;
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
1229 if (ldpd_process == PROC_MAIN && iev_ldpe && update_sockets)
1230 imsg_compose_event(iev_ldpe, IMSG_CLOSE_SOCKETS, af, 0, -1,
1231 NULL, 0);
1232 }
1233
1234 static void
1235 merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
1236 {
1237 struct iface *iface, *itmp, *xi;
1238
1239 RB_FOREACH_SAFE(iface, iface_head, &conf->iface_tree, itmp) {
1240 /* find deleted interfaces */
1241 if ((xi = if_lookup_name(xconf, iface->name)) == NULL) {
1242 RB_REMOVE(iface_head, &conf->iface_tree, iface);
1243
1244 switch (ldpd_process) {
1245 case PROC_LDE_ENGINE:
1246 break;
1247 case PROC_LDP_ENGINE:
1248 if_exit(iface);
1249 break;
1250 case PROC_MAIN:
1251 QOBJ_UNREG (iface);
1252 break;
1253 }
1254 free(iface);
1255 }
1256 }
1257 RB_FOREACH_SAFE(xi, iface_head, &xconf->iface_tree, itmp) {
1258 /* find new interfaces */
1259 if ((iface = if_lookup_name(conf, xi->name)) == NULL) {
1260 RB_REMOVE(iface_head, &xconf->iface_tree, xi);
1261 RB_INSERT(iface_head, &conf->iface_tree, xi);
1262
1263 if (ldpd_process == PROC_MAIN) {
1264 QOBJ_REG (xi, iface);
1265 /* resend addresses to activate new interfaces */
1266 kif_redistribute(xi->name);
1267 }
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 RB_REMOVE(iface_head, &xconf->iface_tree, xi);
1275 if (ref && *ref == xi)
1276 *ref = iface;
1277 free(xi);
1278 }
1279 }
1280
1281 static void
1282 merge_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
1293 static void
1294 merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
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) {
1304 switch (ldpd_process) {
1305 case PROC_LDE_ENGINE:
1306 LIST_REMOVE(tnbr, entry);
1307 free(tnbr);
1308 break;
1309 case PROC_LDP_ENGINE:
1310 tnbr->flags &= ~F_TNBR_CONFIGURED;
1311 tnbr_check(tnbr);
1312 break;
1313 case PROC_MAIN:
1314 LIST_REMOVE(tnbr, entry);
1315 QOBJ_UNREG (tnbr);
1316 free(tnbr);
1317 break;
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
1327 switch (ldpd_process) {
1328 case PROC_LDE_ENGINE:
1329 break;
1330 case PROC_LDP_ENGINE:
1331 tnbr_update(xt);
1332 break;
1333 case PROC_MAIN:
1334 QOBJ_REG (xt, tnbr);
1335 break;
1336 }
1337 continue;
1338 }
1339
1340 /* update existing tnbrs */
1341 if (!(tnbr->flags & F_TNBR_CONFIGURED))
1342 tnbr->flags |= F_TNBR_CONFIGURED;
1343 LIST_REMOVE(xt, entry);
1344 if (ref && *ref == xt)
1345 *ref = tnbr;
1346 free(xt);
1347 }
1348 }
1349
1350 static void
1351 merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
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) {
1360 switch (ldpd_process) {
1361 case PROC_LDE_ENGINE:
1362 break;
1363 case PROC_LDP_ENGINE:
1364 nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
1365 if (nbr) {
1366 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
1367 #ifdef __OpenBSD__
1368 pfkey_remove(nbr);
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
1375 if (nbr_session_active_role(nbr))
1376 nbr_establish_connection(nbr);
1377 }
1378 break;
1379 case PROC_MAIN:
1380 QOBJ_UNREG (nbrp);
1381 break;
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
1393 switch (ldpd_process) {
1394 case PROC_LDE_ENGINE:
1395 break;
1396 case PROC_LDP_ENGINE:
1397 nbr = nbr_find_ldpid(xn->lsr_id.s_addr);
1398 if (nbr) {
1399 session_shutdown(nbr, S_SHUTDOWN, 0, 0);
1400 #ifdef __OpenBSD__
1401 if (pfkey_establish(nbr, xn) == -1)
1402 fatalx("pfkey setup failed");
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
1410 if (nbr_session_active_role(nbr))
1411 nbr_establish_connection(nbr);
1412 }
1413 break;
1414 case PROC_MAIN:
1415 QOBJ_REG (xn, nbr_params);
1416 break;
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);
1445 #ifdef __OpenBSD__
1446 pfkey_remove(nbr);
1447 if (pfkey_establish(nbr, nbrp) == -1)
1448 fatalx("pfkey setup failed");
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
1454 if (nbr_session_active_role(nbr))
1455 nbr_establish_connection(nbr);
1456 }
1457 }
1458 LIST_REMOVE(xn, entry);
1459 if (ref && *ref == xn)
1460 *ref = nbrp;
1461 free(xn);
1462 }
1463 }
1464
1465 static void
1466 merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
1467 {
1468 struct l2vpn *l2vpn, *ltmp, *xl;
1469 struct l2vpn_if *lif;
1470 struct l2vpn_pw *pw;
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:
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);
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:
1511 QOBJ_REG (xl, l2vpn);
1512 break;
1513 }
1514 continue;
1515 }
1516
1517 /* update existing l2vpns */
1518 merge_l2vpn(conf, l2vpn, xl, ref);
1519 LIST_REMOVE(xl, entry);
1520 if (ref && *ref == xl)
1521 *ref = l2vpn;
1522 free(xl);
1523 }
1524 }
1525
1526 static void
1527 merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void **ref)
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;
1533 LIST_HEAD(, l2vpn_pw) pw_aux_list;
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 */
1542 if ((xf = l2vpn_if_find_name(xl, lif->ifname)) == NULL) {
1543 if (ldpd_process == PROC_MAIN)
1544 QOBJ_UNREG (lif);
1545 LIST_REMOVE(lif, entry);
1546 free(lif);
1547 }
1548 }
1549 LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) {
1550 /* find new interfaces */
1551 if ((lif = l2vpn_if_find_name(l2vpn, xf->ifname)) == NULL) {
1552 LIST_REMOVE(xf, entry);
1553 LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry);
1554 xf->l2vpn = l2vpn;
1555 if (ldpd_process == PROC_MAIN)
1556 QOBJ_REG (xf, l2vpn_if);
1557 continue;
1558 }
1559
1560 LIST_REMOVE(xf, entry);
1561 if (ref && *ref == xf)
1562 *ref = lif;
1563 free(xf);
1564 }
1565
1566 /* merge active pseudowires */
1567 LIST_INIT(&pw_aux_list);
1568 LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) {
1569 /* find deleted active pseudowires */
1570 if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
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:
1579 QOBJ_UNREG (pw);
1580 break;
1581 }
1582
1583 LIST_REMOVE(pw, entry);
1584 free(pw);
1585 }
1586 }
1587 LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) {
1588 /* find new active pseudowires */
1589 if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
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:
1602 QOBJ_REG (xp, l2vpn_pw);
1603 break;
1604 }
1605 continue;
1606 }
1607
1608 /* update existing active pseudowire */
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
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
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;
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;
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);
1693 if (ref && *ref == xp)
1694 *ref = pw;
1695 free(xp);
1696 }
1697
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);
1703 if (ldpd_process == PROC_MAIN)
1704 QOBJ_UNREG (pw);
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;
1714 if (ldpd_process == PROC_MAIN)
1715 QOBJ_REG (xp, l2vpn_pw);
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);
1747 if (ref && *ref == xp)
1748 *ref = pw;
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
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
1764 struct ldpd_conf *
1765 config_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 RB_INIT(&xconf->iface_tree);
1774 LIST_INIT(&xconf->tnbr_list);
1775 LIST_INIT(&xconf->nbrp_list);
1776 LIST_INIT(&xconf->l2vpn_list);
1777
1778 return (xconf);
1779 }
1780
1781 void
1782 config_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);
1799 if (ldpd_process == PROC_MAIN)
1800 QOBJ_UNREG (conf);
1801 free(conf);
1802 }