xref: /openbsd-src/usr.sbin/ospfd/ospfe.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: ospfe.c,v 1.88 2014/07/12 20:16:38 krw Exp $ */
2 
3 /*
4  * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
5  * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
6  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/queue.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26 #include <net/if_types.h>
27 #include <stdlib.h>
28 #include <signal.h>
29 #include <string.h>
30 #include <fcntl.h>
31 #include <pwd.h>
32 #include <unistd.h>
33 #include <event.h>
34 #include <err.h>
35 #include <errno.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 
39 #include "ospf.h"
40 #include "ospfd.h"
41 #include "ospfe.h"
42 #include "rde.h"
43 #include "control.h"
44 #include "log.h"
45 
46 void		 ospfe_sig_handler(int, short, void *);
47 void		 ospfe_shutdown(void);
48 void		 orig_rtr_lsa_all(struct area *);
49 struct iface	*find_vlink(struct abr_rtr *);
50 
51 struct ospfd_conf	*oeconf = NULL, *nconf;
52 struct imsgev		*iev_main;
53 struct imsgev		*iev_rde;
54 int			 oe_nofib;
55 
56 /* ARGSUSED */
57 void
58 ospfe_sig_handler(int sig, short event, void *bula)
59 {
60 	switch (sig) {
61 	case SIGINT:
62 	case SIGTERM:
63 		ospfe_shutdown();
64 		/* NOTREACHED */
65 	default:
66 		fatalx("unexpected signal");
67 	}
68 }
69 
70 /* ospf engine */
71 pid_t
72 ospfe(struct ospfd_conf *xconf, int pipe_parent2ospfe[2], int pipe_ospfe2rde[2],
73     int pipe_parent2rde[2])
74 {
75 	struct area	*area;
76 	struct iface	*iface;
77 	struct redistribute *r;
78 	struct passwd	*pw;
79 	struct event	 ev_sigint, ev_sigterm;
80 	pid_t		 pid;
81 
82 	switch (pid = fork()) {
83 	case -1:
84 		fatal("cannot fork");
85 	case 0:
86 		break;
87 	default:
88 		return (pid);
89 	}
90 
91 	/* create ospfd control socket outside chroot */
92 	if (control_init(xconf->csock) == -1)
93 		fatalx("control socket setup failed");
94 
95 	/* create the raw ip socket */
96 	if ((xconf->ospf_socket = socket(AF_INET, SOCK_RAW,
97 	    IPPROTO_OSPF)) == -1)
98 		fatal("error creating raw socket");
99 
100 	/* set some defaults */
101 	if (if_set_mcast_loop(xconf->ospf_socket) == -1)
102 		fatal("if_set_mcast_loop");
103 	if (if_set_ip_hdrincl(xconf->ospf_socket) == -1)
104 		fatal("if_set_ip_hdrincl");
105 	if (if_set_recvif(xconf->ospf_socket, 1) == -1)
106 		fatal("if_set_recvif");
107 	if_set_sockbuf(xconf->ospf_socket);
108 
109 	oeconf = xconf;
110 	if (oeconf->flags & OSPFD_FLAG_NO_FIB_UPDATE)
111 		oe_nofib = 1;
112 
113 	if ((pw = getpwnam(OSPFD_USER)) == NULL)
114 		fatal("getpwnam");
115 
116 	if (chroot(pw->pw_dir) == -1)
117 		fatal("chroot");
118 	if (chdir("/") == -1)
119 		fatal("chdir(\"/\")");
120 
121 	setproctitle("ospf engine");
122 	ospfd_process = PROC_OSPF_ENGINE;
123 
124 	if (setgroups(1, &pw->pw_gid) ||
125 	    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
126 	    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
127 		fatal("can't drop privileges");
128 
129 	event_init();
130 	nbr_init(NBR_HASHSIZE);
131 	lsa_cache_init(LSA_HASHSIZE);
132 
133 	/* setup signal handler */
134 	signal_set(&ev_sigint, SIGINT, ospfe_sig_handler, NULL);
135 	signal_set(&ev_sigterm, SIGTERM, ospfe_sig_handler, NULL);
136 	signal_add(&ev_sigint, NULL);
137 	signal_add(&ev_sigterm, NULL);
138 	signal(SIGPIPE, SIG_IGN);
139 	signal(SIGHUP, SIG_IGN);
140 
141 	/* setup pipes */
142 	close(pipe_parent2ospfe[0]);
143 	close(pipe_ospfe2rde[1]);
144 	close(pipe_parent2rde[0]);
145 	close(pipe_parent2rde[1]);
146 
147 	if ((iev_rde = malloc(sizeof(struct imsgev))) == NULL ||
148 	    (iev_main = malloc(sizeof(struct imsgev))) == NULL)
149 		fatal(NULL);
150 	imsg_init(&iev_rde->ibuf, pipe_ospfe2rde[0]);
151 	iev_rde->handler = ospfe_dispatch_rde;
152 	imsg_init(&iev_main->ibuf, pipe_parent2ospfe[1]);
153 	iev_main->handler = ospfe_dispatch_main;
154 
155 	/* setup event handler */
156 	iev_rde->events = EV_READ;
157 	event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events,
158 	    iev_rde->handler, iev_rde);
159 	event_add(&iev_rde->ev, NULL);
160 
161 	iev_main->events = EV_READ;
162 	event_set(&iev_main->ev, iev_main->ibuf.fd, iev_main->events,
163 	    iev_main->handler, iev_main);
164 	event_add(&iev_main->ev, NULL);
165 
166 	event_set(&oeconf->ev, oeconf->ospf_socket, EV_READ|EV_PERSIST,
167 	    recv_packet, oeconf);
168 	event_add(&oeconf->ev, NULL);
169 
170 	/* remove unneeded config stuff */
171 	while ((r = SIMPLEQ_FIRST(&oeconf->redist_list)) != NULL) {
172 		SIMPLEQ_REMOVE_HEAD(&oeconf->redist_list, entry);
173 		free(r);
174 	}
175 	LIST_FOREACH(area, &oeconf->area_list, entry) {
176 		while ((r = SIMPLEQ_FIRST(&area->redist_list)) != NULL) {
177 			SIMPLEQ_REMOVE_HEAD(&area->redist_list, entry);
178 			free(r);
179 		}
180 	}
181 
182 	/* listen on ospfd control socket */
183 	TAILQ_INIT(&ctl_conns);
184 	control_listen();
185 
186 	if ((pkt_ptr = calloc(1, READ_BUF_SIZE)) == NULL)
187 		fatal("ospfe");
188 
189 	/* start interfaces */
190 	LIST_FOREACH(area, &oeconf->area_list, entry) {
191 		ospfe_demote_area(area, 0);
192 		LIST_FOREACH(iface, &area->iface_list, entry) {
193 			if_init(xconf, iface);
194 			if (if_fsm(iface, IF_EVT_UP)) {
195 				log_debug("error starting interface %s",
196 				    iface->name);
197 			}
198 		}
199 	}
200 
201 	event_dispatch();
202 
203 	ospfe_shutdown();
204 	/* NOTREACHED */
205 	return (0);
206 }
207 
208 void
209 ospfe_shutdown(void)
210 {
211 	struct area	*area;
212 	struct iface	*iface;
213 
214 	/* stop all interfaces and remove all areas */
215 	while ((area = LIST_FIRST(&oeconf->area_list)) != NULL) {
216 		LIST_FOREACH(iface, &area->iface_list, entry) {
217 			if (if_fsm(iface, IF_EVT_DOWN)) {
218 				log_debug("error stopping interface %s",
219 				    iface->name);
220 			}
221 		}
222 		LIST_REMOVE(area, entry);
223 		area_del(area);
224 	}
225 
226 	nbr_del(nbr_find_peerid(NBR_IDSELF));
227 	kr_shutdown();
228 	close(oeconf->ospf_socket);
229 
230 	/* clean up */
231 	msgbuf_write(&iev_rde->ibuf.w);
232 	msgbuf_clear(&iev_rde->ibuf.w);
233 	free(iev_rde);
234 	msgbuf_write(&iev_main->ibuf.w);
235 	msgbuf_clear(&iev_main->ibuf.w);
236 	free(iev_main);
237 	free(oeconf);
238 	free(pkt_ptr);
239 
240 	log_info("ospf engine exiting");
241 	_exit(0);
242 }
243 
244 /* imesg */
245 int
246 ospfe_imsg_compose_parent(int type, pid_t pid, void *data, u_int16_t datalen)
247 {
248 	return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
249 }
250 
251 int
252 ospfe_imsg_compose_rde(int type, u_int32_t peerid, pid_t pid,
253     void *data, u_int16_t datalen)
254 {
255 	return (imsg_compose_event(iev_rde, type, peerid, pid, -1,
256 	    data, datalen));
257 }
258 
259 /* ARGSUSED */
260 void
261 ospfe_dispatch_main(int fd, short event, void *bula)
262 {
263 	static struct area	*narea;
264 	static struct iface	*niface;
265 	struct ifaddrdel	*ifc;
266 	struct imsg	 imsg;
267 	struct imsgev	*iev = bula;
268 	struct imsgbuf	*ibuf = &iev->ibuf;
269 	struct area	*area = NULL;
270 	struct iface	*iface = NULL;
271 	struct kif	*kif;
272 	struct auth_md	 md;
273 	int		 n, link_ok, stub_changed, shut = 0;
274 
275 	if (event & EV_READ) {
276 		if ((n = imsg_read(ibuf)) == -1)
277 			fatal("imsg_read error");
278 		if (n == 0)	/* connection closed */
279 			shut = 1;
280 	}
281 	if (event & EV_WRITE) {
282 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
283 			fatal("msgbuf_write");
284 		if (n == 0)	/* connection closed */
285 			shut = 1;
286 	}
287 
288 	for (;;) {
289 		if ((n = imsg_get(ibuf, &imsg)) == -1)
290 			fatal("ospfe_dispatch_main: imsg_read error");
291 		if (n == 0)
292 			break;
293 
294 		switch (imsg.hdr.type) {
295 		case IMSG_IFINFO:
296 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
297 			    sizeof(struct kif))
298 				fatalx("IFINFO imsg with wrong len");
299 			kif = imsg.data;
300 			link_ok = (kif->flags & IFF_UP) &&
301 			    LINK_STATE_IS_UP(kif->link_state);
302 
303 			LIST_FOREACH(area, &oeconf->area_list, entry) {
304 				LIST_FOREACH(iface, &area->iface_list, entry) {
305 					if (kif->ifindex == iface->ifindex &&
306 					    iface->type !=
307 					    IF_TYPE_VIRTUALLINK) {
308 						iface->flags = kif->flags;
309 						iface->linkstate =
310 						    kif->link_state;
311 
312 						if (link_ok) {
313 							if_fsm(iface,
314 							    IF_EVT_UP);
315 							log_warnx("interface %s"
316 							    " up", iface->name);
317 						} else {
318 							if_fsm(iface,
319 							    IF_EVT_DOWN);
320 							log_warnx("interface %s"
321 							    " down",
322 							    iface->name);
323 						}
324 					}
325 				}
326 			}
327 			break;
328 		case IMSG_IFADDRDEL:
329 			if (imsg.hdr.len != IMSG_HEADER_SIZE +
330 			    sizeof(struct ifaddrdel))
331 				fatalx("IFADDRDEL imsg with wrong len");
332 			ifc = imsg.data;
333 
334 			LIST_FOREACH(area, &oeconf->area_list, entry) {
335 				LIST_FOREACH(iface, &area->iface_list, entry) {
336 					if (ifc->ifindex == iface->ifindex &&
337 					    ifc->addr.s_addr ==
338 					    iface->addr.s_addr) {
339 						if_fsm(iface, IF_EVT_DOWN);
340 						log_warnx("interface %s:%s "
341 						    "gone", iface->name,
342 						    inet_ntoa(iface->addr));
343 						break;
344 					}
345 				}
346 			}
347 			break;
348 		case IMSG_RECONF_CONF:
349 			if ((nconf = malloc(sizeof(struct ospfd_conf))) ==
350 			    NULL)
351 				fatal(NULL);
352 			memcpy(nconf, imsg.data, sizeof(struct ospfd_conf));
353 
354 			LIST_INIT(&nconf->area_list);
355 			LIST_INIT(&nconf->cand_list);
356 			break;
357 		case IMSG_RECONF_AREA:
358 			if ((narea = area_new()) == NULL)
359 				fatal(NULL);
360 			memcpy(narea, imsg.data, sizeof(struct area));
361 
362 			LIST_INIT(&narea->iface_list);
363 			LIST_INIT(&narea->nbr_list);
364 			RB_INIT(&narea->lsa_tree);
365 			SIMPLEQ_INIT(&narea->redist_list);
366 
367 			LIST_INSERT_HEAD(&nconf->area_list, narea, entry);
368 			break;
369 		case IMSG_RECONF_IFACE:
370 			if ((niface = malloc(sizeof(struct iface))) == NULL)
371 				fatal(NULL);
372 			memcpy(niface, imsg.data, sizeof(struct iface));
373 
374 			LIST_INIT(&niface->nbr_list);
375 			TAILQ_INIT(&niface->ls_ack_list);
376 			TAILQ_INIT(&niface->auth_md_list);
377 			RB_INIT(&niface->lsa_tree);
378 
379 			niface->area = narea;
380 			LIST_INSERT_HEAD(&narea->iface_list, niface, entry);
381 			break;
382 		case IMSG_RECONF_AUTHMD:
383 			memcpy(&md, imsg.data, sizeof(struct auth_md));
384 			md_list_add(&niface->auth_md_list, md.keyid, md.key);
385 			break;
386 		case IMSG_RECONF_END:
387 			if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER) !=
388 			    (nconf->flags & OSPFD_FLAG_STUB_ROUTER))
389 				stub_changed = 1;
390 			else
391 				stub_changed = 0;
392 			merge_config(oeconf, nconf);
393 			nconf = NULL;
394 			if (stub_changed)
395 				orig_rtr_lsa_all(NULL);
396 			break;
397 		case IMSG_CTL_KROUTE:
398 		case IMSG_CTL_KROUTE_ADDR:
399 		case IMSG_CTL_IFINFO:
400 		case IMSG_CTL_END:
401 			control_imsg_relay(&imsg);
402 			break;
403 		default:
404 			log_debug("ospfe_dispatch_main: error handling imsg %d",
405 			    imsg.hdr.type);
406 			break;
407 		}
408 		imsg_free(&imsg);
409 	}
410 	if (!shut)
411 		imsg_event_add(iev);
412 	else {
413 		/* this pipe is dead, so remove the event handler */
414 		event_del(&iev->ev);
415 		event_loopexit(NULL);
416 	}
417 }
418 
419 /* ARGSUSED */
420 void
421 ospfe_dispatch_rde(int fd, short event, void *bula)
422 {
423 	struct lsa_hdr		 lsa_hdr;
424 	struct imsgev		*iev = bula;
425 	struct imsgbuf		*ibuf = &iev->ibuf;
426 	struct nbr		*nbr;
427 	struct lsa_hdr		*lhp;
428 	struct lsa_ref		*ref;
429 	struct area		*area;
430 	struct iface		*iface;
431 	struct lsa_entry	*le;
432 	struct imsg		 imsg;
433 	struct abr_rtr		 ar;
434 	int			 n, noack = 0, shut = 0;
435 	u_int16_t		 l, age;
436 
437 	if (event & EV_READ) {
438 		if ((n = imsg_read(ibuf)) == -1)
439 			fatal("imsg_read error");
440 		if (n == 0)	/* connection closed */
441 			shut = 1;
442 	}
443 	if (event & EV_WRITE) {
444 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
445 			fatal("msgbuf_write");
446 		if (n == 0)	/* connection closed */
447 			shut = 1;
448 	}
449 
450 	for (;;) {
451 		if ((n = imsg_get(ibuf, &imsg)) == -1)
452 			fatal("ospfe_dispatch_rde: imsg_read error");
453 		if (n == 0)
454 			break;
455 
456 		switch (imsg.hdr.type) {
457 		case IMSG_DD:
458 			nbr = nbr_find_peerid(imsg.hdr.peerid);
459 			if (nbr == NULL)
460 				break;
461 
462 			/*
463 			 * Ignore imsg when in the wrong state because a
464 			 * NBR_EVT_SEQ_NUM_MIS may have been issued in between.
465 			 * Luckily regetting the DB snapshot acts as a barrier
466 			 * for both state and process synchronisation.
467 			 */
468 			if ((nbr->state & NBR_STA_FLOOD) == 0)
469 				break;
470 
471 			/* put these on my ls_req_list for retrieval */
472 			lhp = lsa_hdr_new();
473 			memcpy(lhp, imsg.data, sizeof(*lhp));
474 			ls_req_list_add(nbr, lhp);
475 			break;
476 		case IMSG_DD_END:
477 			nbr = nbr_find_peerid(imsg.hdr.peerid);
478 			if (nbr == NULL)
479 				break;
480 
481 			/* see above */
482 			if ((nbr->state & NBR_STA_FLOOD) == 0)
483 				break;
484 
485 			nbr->dd_pending--;
486 			if (nbr->dd_pending == 0 && nbr->state & NBR_STA_LOAD) {
487 				if (ls_req_list_empty(nbr))
488 					nbr_fsm(nbr, NBR_EVT_LOAD_DONE);
489 				else
490 					start_ls_req_tx_timer(nbr);
491 			}
492 			break;
493 		case IMSG_DD_BADLSA:
494 			nbr = nbr_find_peerid(imsg.hdr.peerid);
495 			if (nbr == NULL)
496 				break;
497 
498 			if (nbr->iface->self == nbr)
499 				fatalx("ospfe_dispatch_rde: "
500 				    "dummy neighbor got BADREQ");
501 
502 			nbr_fsm(nbr, NBR_EVT_SEQ_NUM_MIS);
503 			break;
504 		case IMSG_DB_SNAPSHOT:
505 			nbr = nbr_find_peerid(imsg.hdr.peerid);
506 			if (nbr == NULL)
507 				break;
508 			if (nbr->state != NBR_STA_SNAP)	/* discard */
509 				break;
510 
511 			/* add LSA header to the neighbor db_sum_list */
512 			lhp = lsa_hdr_new();
513 			memcpy(lhp, imsg.data, sizeof(*lhp));
514 			db_sum_list_add(nbr, lhp);
515 			break;
516 		case IMSG_DB_END:
517 			nbr = nbr_find_peerid(imsg.hdr.peerid);
518 			if (nbr == NULL)
519 				break;
520 
521 			nbr->dd_snapshot = 0;
522 			if (nbr->state != NBR_STA_SNAP)
523 				break;
524 
525 			/* snapshot done, start tx of dd packets */
526 			nbr_fsm(nbr, NBR_EVT_SNAP_DONE);
527 			break;
528 		case IMSG_LS_FLOOD:
529 			nbr = nbr_find_peerid(imsg.hdr.peerid);
530 			if (nbr == NULL)
531 				break;
532 
533 			l = imsg.hdr.len - IMSG_HEADER_SIZE;
534 			if (l < sizeof(lsa_hdr))
535 				fatalx("ospfe_dispatch_rde: "
536 				    "bad imsg size");
537 			memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr));
538 
539 			ref = lsa_cache_add(imsg.data, l);
540 
541 			if (lsa_hdr.type == LSA_TYPE_EXTERNAL) {
542 				/*
543 				 * flood on all areas but stub areas and
544 				 * virtual links
545 				 */
546 				LIST_FOREACH(area, &oeconf->area_list, entry) {
547 				    if (area->stub)
548 					    continue;
549 				    LIST_FOREACH(iface, &area->iface_list,
550 					entry) {
551 					    noack += lsa_flood(iface, nbr,
552 						&lsa_hdr, imsg.data);
553 				    }
554 				}
555 			} else if (lsa_hdr.type == LSA_TYPE_LINK_OPAQ) {
556 				/*
557 				 * Flood on interface only
558 				 */
559 				noack += lsa_flood(nbr->iface, nbr,
560 				    &lsa_hdr, imsg.data);
561 			} else {
562 				/*
563 				 * Flood on all area interfaces. For
564 				 * area 0.0.0.0 include the virtual links.
565 				 */
566 				area = nbr->iface->area;
567 				LIST_FOREACH(iface, &area->iface_list, entry) {
568 					noack += lsa_flood(iface, nbr,
569 					    &lsa_hdr, imsg.data);
570 				}
571 				/* XXX virtual links */
572 			}
573 
574 			/* remove from ls_req_list */
575 			le = ls_req_list_get(nbr, &lsa_hdr);
576 			if (!(nbr->state & NBR_STA_FULL) && le != NULL) {
577 				ls_req_list_free(nbr, le);
578 				/*
579 				 * XXX no need to ack requested lsa
580 				 * the problem is that the RFC is very
581 				 * unclear about this.
582 				 */
583 				noack = 1;
584 			}
585 
586 			if (!noack && nbr->iface != NULL &&
587 			    nbr->iface->self != nbr) {
588 				if (!(nbr->iface->state & IF_STA_BACKUP) ||
589 				    nbr->iface->dr == nbr) {
590 					/* delayed ack */
591 					lhp = lsa_hdr_new();
592 					memcpy(lhp, &lsa_hdr, sizeof(*lhp));
593 					ls_ack_list_add(nbr->iface, lhp);
594 				}
595 			}
596 
597 			lsa_cache_put(ref, nbr);
598 			break;
599 		case IMSG_LS_UPD:
600 		case IMSG_LS_SNAP:
601 			/*
602 			 * IMSG_LS_UPD is used in two cases:
603 			 * 1. as response to ls requests
604 			 * 2. as response to ls updates where the DB
605 			 *    is newer then the sent LSA
606 			 * IMSG_LS_SNAP is used in one case:
607 			 *    in EXSTART when the LSA has age MaxAge
608 			 */
609 			l = imsg.hdr.len - IMSG_HEADER_SIZE;
610 			if (l < sizeof(lsa_hdr))
611 				fatalx("ospfe_dispatch_rde: "
612 				    "bad imsg size");
613 
614 			nbr = nbr_find_peerid(imsg.hdr.peerid);
615 			if (nbr == NULL)
616 				break;
617 
618 			if (nbr->iface->self == nbr)
619 				break;
620 
621 			if (imsg.hdr.type == IMSG_LS_SNAP &&
622 			    nbr->state != NBR_STA_SNAP)
623 				break;
624 
625 			memcpy(&age, imsg.data, sizeof(age));
626 			ref = lsa_cache_add(imsg.data, l);
627 			if (ntohs(age) >= MAX_AGE)
628 				/* add to retransmit list */
629 				ls_retrans_list_add(nbr, imsg.data, 0, 0);
630 			else
631 				ls_retrans_list_add(nbr, imsg.data, 0, 1);
632 
633 			lsa_cache_put(ref, nbr);
634 			break;
635 		case IMSG_LS_ACK:
636 			/*
637 			 * IMSG_LS_ACK is used in two cases:
638 			 * 1. LSA was a duplicate
639 			 * 2. LS age is MaxAge and there is no current
640 			 *    instance in the DB plus no neighbor in state
641 			 *    Exchange or Loading
642 			 */
643 			nbr = nbr_find_peerid(imsg.hdr.peerid);
644 			if (nbr == NULL)
645 				break;
646 
647 			if (nbr->iface->self == nbr)
648 				break;
649 
650 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(lsa_hdr))
651 				fatalx("ospfe_dispatch_rde: bad imsg size");
652 			memcpy(&lsa_hdr, imsg.data, sizeof(lsa_hdr));
653 
654 			/* for case one check for implied acks */
655 			if (nbr->iface->state & IF_STA_DROTHER)
656 				if (ls_retrans_list_del(nbr->iface->self,
657 				    &lsa_hdr) == 0)
658 					break;
659 			if (ls_retrans_list_del(nbr, &lsa_hdr) == 0)
660 				break;
661 
662 			/* send a direct acknowledgement */
663 			send_direct_ack(nbr->iface, nbr->addr, imsg.data,
664 			    imsg.hdr.len - IMSG_HEADER_SIZE);
665 
666 			break;
667 		case IMSG_LS_BADREQ:
668 			nbr = nbr_find_peerid(imsg.hdr.peerid);
669 			if (nbr == NULL)
670 				break;
671 
672 			if (nbr->iface->self == nbr)
673 				fatalx("ospfe_dispatch_rde: "
674 				    "dummy neighbor got BADREQ");
675 
676 			nbr_fsm(nbr, NBR_EVT_BAD_LS_REQ);
677 			break;
678 		case IMSG_ABR_UP:
679 			memcpy(&ar, imsg.data, sizeof(ar));
680 
681 			if ((iface = find_vlink(&ar)) != NULL &&
682 			    iface->state == IF_STA_DOWN)
683 				if (if_fsm(iface, IF_EVT_UP)) {
684 					log_debug("error starting interface %s",
685 					    iface->name);
686 				}
687 			break;
688 		case IMSG_ABR_DOWN:
689 			memcpy(&ar, imsg.data, sizeof(ar));
690 
691 			if ((iface = find_vlink(&ar)) != NULL &&
692 			    iface->state == IF_STA_POINTTOPOINT)
693 				if (if_fsm(iface, IF_EVT_DOWN)) {
694 					log_debug("error stopping interface %s",
695 					    iface->name);
696 				}
697 			break;
698 		case IMSG_CTL_AREA:
699 		case IMSG_CTL_IFACE:
700 		case IMSG_CTL_END:
701 		case IMSG_CTL_SHOW_DATABASE:
702 		case IMSG_CTL_SHOW_DB_EXT:
703 		case IMSG_CTL_SHOW_DB_NET:
704 		case IMSG_CTL_SHOW_DB_RTR:
705 		case IMSG_CTL_SHOW_DB_SELF:
706 		case IMSG_CTL_SHOW_DB_SUM:
707 		case IMSG_CTL_SHOW_DB_ASBR:
708 		case IMSG_CTL_SHOW_DB_OPAQ:
709 		case IMSG_CTL_SHOW_RIB:
710 		case IMSG_CTL_SHOW_SUM:
711 		case IMSG_CTL_SHOW_SUM_AREA:
712 			control_imsg_relay(&imsg);
713 			break;
714 		default:
715 			log_debug("ospfe_dispatch_rde: error handling imsg %d",
716 			    imsg.hdr.type);
717 			break;
718 		}
719 		imsg_free(&imsg);
720 	}
721 	if (!shut)
722 		imsg_event_add(iev);
723 	else {
724 		/* this pipe is dead, so remove the event handler */
725 		event_del(&iev->ev);
726 		event_loopexit(NULL);
727 	}
728 }
729 
730 struct iface *
731 find_vlink(struct abr_rtr *ar)
732 {
733 	struct area	*area;
734 	struct iface	*iface = NULL;
735 
736 	LIST_FOREACH(area, &oeconf->area_list, entry)
737 		LIST_FOREACH(iface, &area->iface_list, entry)
738 			if (iface->abr_id.s_addr == ar->abr_id.s_addr &&
739 			    iface->type == IF_TYPE_VIRTUALLINK &&
740 			    iface->area->id.s_addr == ar->area.s_addr) {
741 				iface->dst.s_addr = ar->dst_ip.s_addr;
742 				iface->addr.s_addr = ar->addr.s_addr;
743 				iface->metric = ar->metric;
744 
745 				return (iface);
746 			}
747 
748 	return (iface);
749 }
750 
751 void
752 orig_rtr_lsa_all(struct area *area)
753 {
754 	struct area	*a;
755 
756 	/*
757 	 * update all router LSA in all areas except area itself,
758 	 * as this update is already running.
759 	 */
760 	LIST_FOREACH(a, &oeconf->area_list, entry)
761 		if (a != area)
762 			orig_rtr_lsa(a);
763 }
764 
765 void
766 orig_rtr_lsa(struct area *area)
767 {
768 	struct lsa_hdr		 lsa_hdr;
769 	struct lsa_rtr		 lsa_rtr;
770 	struct lsa_rtr_link	 rtr_link;
771 	struct iface		*iface;
772 	struct ibuf		*buf;
773 	struct nbr		*nbr, *self = NULL;
774 	u_int16_t		 num_links = 0;
775 	u_int16_t		 chksum;
776 	u_int8_t		 border, virtual = 0;
777 
778 	log_debug("orig_rtr_lsa: area %s", inet_ntoa(area->id));
779 
780 	if ((buf = ibuf_dynamic(sizeof(lsa_hdr),
781 	    IP_MAXPACKET - sizeof(struct ip) - sizeof(struct ospf_hdr) -
782 	    sizeof(u_int32_t) - MD5_DIGEST_LENGTH)) == NULL)
783 		fatal("orig_rtr_lsa");
784 
785 	/* reserve space for LSA header and LSA Router header */
786 	if (ibuf_reserve(buf, sizeof(lsa_hdr)) == NULL)
787 		fatal("orig_rtr_lsa: ibuf_reserve failed");
788 
789 	if (ibuf_reserve(buf, sizeof(lsa_rtr)) == NULL)
790 		fatal("orig_rtr_lsa: ibuf_reserve failed");
791 
792 	/* links */
793 	LIST_FOREACH(iface, &area->iface_list, entry) {
794 		if (self == NULL && iface->self != NULL)
795 			self = iface->self;
796 
797 		bzero(&rtr_link, sizeof(rtr_link));
798 
799 		if (iface->state & IF_STA_LOOPBACK) {
800 			rtr_link.id = iface->addr.s_addr;
801 			rtr_link.data = 0xffffffff;
802 			rtr_link.type = LINK_TYPE_STUB_NET;
803 			rtr_link.metric = htons(iface->metric);
804 			num_links++;
805 			if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
806 				fatalx("orig_rtr_lsa: ibuf_add failed");
807 			continue;
808 		}
809 
810 		switch (iface->type) {
811 		case IF_TYPE_POINTOPOINT:
812 			LIST_FOREACH(nbr, &iface->nbr_list, entry)
813 				if (nbr != iface->self &&
814 				    nbr->state & NBR_STA_FULL)
815 					break;
816 			if (nbr) {
817 				log_debug("orig_rtr_lsa: point-to-point, "
818 				    "interface %s", iface->name);
819 				rtr_link.id = nbr->id.s_addr;
820 				rtr_link.data = iface->addr.s_addr;
821 				rtr_link.type = LINK_TYPE_POINTTOPOINT;
822 				/* RFC 3137: stub router support */
823 				if (oeconf->flags & OSPFD_FLAG_STUB_ROUTER ||
824 				    oe_nofib)
825 					rtr_link.metric = MAX_METRIC;
826 				else
827 					rtr_link.metric = htons(iface->metric);
828 				num_links++;
829 				if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
830 					fatalx("orig_rtr_lsa: ibuf_add failed");
831 			}
832 			if (iface->state & IF_STA_POINTTOPOINT) {
833 				log_debug("orig_rtr_lsa: stub net, "
834 				    "interface %s", iface->name);
835 				bzero(&rtr_link, sizeof(rtr_link));
836 				if (nbr) {
837 					rtr_link.id = nbr->addr.s_addr;
838 					rtr_link.data = 0xffffffff;
839 				} else {
840 					rtr_link.id = iface->addr.s_addr;
841 					rtr_link.data = iface->mask.s_addr;
842 				}
843 				rtr_link.type = LINK_TYPE_STUB_NET;
844 				rtr_link.metric = htons(iface->metric);
845 				num_links++;
846 				if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
847 					fatalx("orig_rtr_lsa: ibuf_add failed");
848 			}
849 			continue;
850 		case IF_TYPE_BROADCAST:
851 		case IF_TYPE_NBMA:
852 			if ((iface->state & IF_STA_MULTI)) {
853 				if (iface->dr == iface->self) {
854 					LIST_FOREACH(nbr, &iface->nbr_list,
855 					    entry)
856 						if (nbr != iface->self &&
857 						    nbr->state & NBR_STA_FULL)
858 							break;
859 				} else
860 					nbr = iface->dr;
861 
862 				if (nbr && nbr->state & NBR_STA_FULL) {
863 					log_debug("orig_rtr_lsa: transit net, "
864 					    "interface %s", iface->name);
865 
866 					rtr_link.id = iface->dr->addr.s_addr;
867 					rtr_link.data = iface->addr.s_addr;
868 					rtr_link.type = LINK_TYPE_TRANSIT_NET;
869 					break;
870 				}
871 			}
872 
873 			/*
874 			 * do not add a stub net LSA for interfaces that are:
875 			 *  - down
876 			 *  - have a linkstate which is down, apart from carp:
877 			 *    backup carp interfaces have linkstate down, but
878 			 *    we still announce them.
879 			 */
880 			if (!(iface->flags & IFF_UP) ||
881 			    (!LINK_STATE_IS_UP(iface->linkstate) &&
882 			    !(iface->media_type == IFT_CARP &&
883 			    iface->linkstate == LINK_STATE_DOWN)))
884 				continue;
885 			log_debug("orig_rtr_lsa: stub net, "
886 			    "interface %s", iface->name);
887 
888 			rtr_link.id =
889 			    iface->addr.s_addr & iface->mask.s_addr;
890 			rtr_link.data = iface->mask.s_addr;
891 			rtr_link.type = LINK_TYPE_STUB_NET;
892 
893 			rtr_link.num_tos = 0;
894 			/*
895 			 * backup carp interfaces are anounced with high metric
896 			 * for faster failover.
897 			 */
898 			if (iface->media_type == IFT_CARP &&
899 			    iface->linkstate == LINK_STATE_DOWN)
900 				rtr_link.metric = MAX_METRIC;
901 			else
902 				rtr_link.metric = htons(iface->metric);
903 			num_links++;
904 			if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
905 				fatalx("orig_rtr_lsa: ibuf_add failed");
906 			continue;
907 		case IF_TYPE_VIRTUALLINK:
908 			LIST_FOREACH(nbr, &iface->nbr_list, entry) {
909 				if (nbr != iface->self &&
910 				    nbr->state & NBR_STA_FULL)
911 					break;
912 			}
913 			if (nbr) {
914 				rtr_link.id = nbr->id.s_addr;
915 				rtr_link.data = iface->addr.s_addr;
916 				rtr_link.type = LINK_TYPE_VIRTUAL;
917 				/* RFC 3137: stub router support */
918 				if (oeconf->flags & OSPFD_FLAG_STUB_ROUTER ||
919 				    oe_nofib)
920 					rtr_link.metric = MAX_METRIC;
921 				else
922 					rtr_link.metric = htons(iface->metric);
923 				num_links++;
924 				virtual = 1;
925 				if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
926 					fatalx("orig_rtr_lsa: ibuf_add failed");
927 
928 				log_debug("orig_rtr_lsa: virtual link, "
929 				    "interface %s", iface->name);
930 			}
931 			continue;
932 		case IF_TYPE_POINTOMULTIPOINT:
933 			log_debug("orig_rtr_lsa: stub net, "
934 			    "interface %s", iface->name);
935 			rtr_link.id = iface->addr.s_addr;
936 			rtr_link.data = 0xffffffff;
937 			rtr_link.type = LINK_TYPE_STUB_NET;
938 			rtr_link.metric = htons(iface->metric);
939 			num_links++;
940 			if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
941 				fatalx("orig_rtr_lsa: ibuf_add failed");
942 
943 			LIST_FOREACH(nbr, &iface->nbr_list, entry) {
944 				if (nbr != iface->self &&
945 				    nbr->state & NBR_STA_FULL) {
946 					bzero(&rtr_link, sizeof(rtr_link));
947 					log_debug("orig_rtr_lsa: "
948 					    "point-to-multipoint, interface %s",
949 					    iface->name);
950 					rtr_link.id = nbr->addr.s_addr;
951 					rtr_link.data = iface->addr.s_addr;
952 					rtr_link.type = LINK_TYPE_POINTTOPOINT;
953 					/* RFC 3137: stub router support */
954 					if (oe_nofib || oeconf->flags &
955 					    OSPFD_FLAG_STUB_ROUTER)
956 						rtr_link.metric = MAX_METRIC;
957 					else
958 						rtr_link.metric =
959 						    htons(iface->metric);
960 					num_links++;
961 					if (ibuf_add(buf, &rtr_link,
962 					    sizeof(rtr_link)))
963 						fatalx("orig_rtr_lsa: "
964 						    "ibuf_add failed");
965 				}
966 			}
967 			continue;
968 		default:
969 			fatalx("orig_rtr_lsa: unknown interface type");
970 		}
971 
972 		rtr_link.num_tos = 0;
973 		/* RFC 3137: stub router support */
974 		if ((oeconf->flags & OSPFD_FLAG_STUB_ROUTER || oe_nofib) &&
975 		    rtr_link.type != LINK_TYPE_STUB_NET)
976 			rtr_link.metric = MAX_METRIC;
977 		else
978 			rtr_link.metric = htons(iface->metric);
979 		num_links++;
980 		if (ibuf_add(buf, &rtr_link, sizeof(rtr_link)))
981 			fatalx("orig_rtr_lsa: ibuf_add failed");
982 	}
983 
984 	/* LSA router header */
985 	lsa_rtr.flags = 0;
986 	/*
987 	 * Set the E bit as soon as an as-ext lsa may be redistributed, only
988 	 * setting it in case we redistribute something is not worth the fuss.
989 	 * Do not set the E bit in case of a stub area.
990 	 */
991 	if (oeconf->redistribute && !area->stub)
992 		lsa_rtr.flags |= OSPF_RTR_E;
993 
994 	border = (area_border_router(oeconf) != 0);
995 	if (border != oeconf->border) {
996 		oeconf->border = border;
997 		orig_rtr_lsa_all(area);
998 	}
999 
1000 	if (oeconf->border)
1001 		lsa_rtr.flags |= OSPF_RTR_B;
1002 	/* TODO set V flag if a active virtual link ends here and the
1003 	 * area is the transit area for this link. */
1004 	if (virtual)
1005 		lsa_rtr.flags |= OSPF_RTR_V;
1006 
1007 	lsa_rtr.dummy = 0;
1008 	lsa_rtr.nlinks = htons(num_links);
1009 	memcpy(ibuf_seek(buf, sizeof(lsa_hdr), sizeof(lsa_rtr)),
1010 	    &lsa_rtr, sizeof(lsa_rtr));
1011 
1012 	/* LSA header */
1013 	lsa_hdr.age = htons(DEFAULT_AGE);
1014 	lsa_hdr.opts = area_ospf_options(area);
1015 	lsa_hdr.type = LSA_TYPE_ROUTER;
1016 	lsa_hdr.ls_id = oeconf->rtr_id.s_addr;
1017 	lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr;
1018 	lsa_hdr.seq_num = htonl(INIT_SEQ_NUM);
1019 	lsa_hdr.len = htons(ibuf_size(buf));
1020 	lsa_hdr.ls_chksum = 0;		/* updated later */
1021 	memcpy(ibuf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr));
1022 
1023 	chksum = htons(iso_cksum(buf->buf, ibuf_size(buf), LS_CKSUM_OFFSET));
1024 	memcpy(ibuf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)),
1025 	    &chksum, sizeof(chksum));
1026 
1027 	if (self && num_links)
1028 		imsg_compose_event(iev_rde, IMSG_LS_UPD, self->peerid, 0,
1029 		    -1, buf->buf, ibuf_size(buf));
1030 	else
1031 		log_warnx("orig_rtr_lsa: empty area %s",
1032 		    inet_ntoa(area->id));
1033 
1034 	ibuf_free(buf);
1035 }
1036 
1037 void
1038 orig_net_lsa(struct iface *iface)
1039 {
1040 	struct lsa_hdr		 lsa_hdr;
1041 	struct nbr		*nbr;
1042 	struct ibuf		*buf;
1043 	int			 num_rtr = 0;
1044 	u_int16_t		 chksum;
1045 
1046 	if ((buf = ibuf_dynamic(sizeof(lsa_hdr),
1047 	    IP_MAXPACKET - sizeof(struct ip) - sizeof(struct ospf_hdr) -
1048 	    sizeof(u_int32_t) - MD5_DIGEST_LENGTH)) == NULL)
1049 		fatal("orig_net_lsa");
1050 
1051 	/* reserve space for LSA header and LSA Router header */
1052 	if (ibuf_reserve(buf, sizeof(lsa_hdr)) == NULL)
1053 		fatal("orig_net_lsa: ibuf_reserve failed");
1054 
1055 	/* LSA net mask and then all fully adjacent routers */
1056 	if (ibuf_add(buf, &iface->mask, sizeof(iface->mask)))
1057 		fatal("orig_net_lsa: ibuf_add failed");
1058 
1059 	/* fully adjacent neighbors + self */
1060 	LIST_FOREACH(nbr, &iface->nbr_list, entry)
1061 		if (nbr->state & NBR_STA_FULL) {
1062 			if (ibuf_add(buf, &nbr->id, sizeof(nbr->id)))
1063 				fatal("orig_net_lsa: ibuf_add failed");
1064 			num_rtr++;
1065 		}
1066 
1067 	if (num_rtr == 1) {
1068 		/* non transit net therefore no need to generate a net lsa */
1069 		ibuf_free(buf);
1070 		return;
1071 	}
1072 
1073 	/* LSA header */
1074 	if (iface->state & IF_STA_DR)
1075 		lsa_hdr.age = htons(DEFAULT_AGE);
1076 	else
1077 		lsa_hdr.age = htons(MAX_AGE);
1078 
1079 	lsa_hdr.opts = area_ospf_options(iface->area);
1080 	lsa_hdr.type = LSA_TYPE_NETWORK;
1081 	lsa_hdr.ls_id = iface->addr.s_addr;
1082 	lsa_hdr.adv_rtr = oeconf->rtr_id.s_addr;
1083 	lsa_hdr.seq_num = htonl(INIT_SEQ_NUM);
1084 	lsa_hdr.len = htons(ibuf_size(buf));
1085 	lsa_hdr.ls_chksum = 0;		/* updated later */
1086 	memcpy(ibuf_seek(buf, 0, sizeof(lsa_hdr)), &lsa_hdr, sizeof(lsa_hdr));
1087 
1088 	chksum = htons(iso_cksum(buf->buf, ibuf_size(buf), LS_CKSUM_OFFSET));
1089 	memcpy(ibuf_seek(buf, LS_CKSUM_OFFSET, sizeof(chksum)),
1090 	    &chksum, sizeof(chksum));
1091 
1092 	imsg_compose_event(iev_rde, IMSG_LS_UPD, iface->self->peerid, 0,
1093 	    -1, buf->buf, ibuf_size(buf));
1094 
1095 	ibuf_free(buf);
1096 }
1097 
1098 u_int32_t
1099 ospfe_router_id(void)
1100 {
1101 	return (oeconf->rtr_id.s_addr);
1102 }
1103 
1104 void
1105 ospfe_fib_update(int type)
1106 {
1107 	int	old = oe_nofib;
1108 
1109 	if (type == IMSG_CTL_FIB_COUPLE)
1110 		oe_nofib = 0;
1111 	if (type == IMSG_CTL_FIB_DECOUPLE)
1112 		oe_nofib = 1;
1113 	if (old != oe_nofib)
1114 		orig_rtr_lsa_all(NULL);
1115 }
1116 
1117 void
1118 ospfe_iface_ctl(struct ctl_conn *c, unsigned int idx)
1119 {
1120 	struct area		*area;
1121 	struct iface		*iface;
1122 	struct ctl_iface	*ictl;
1123 
1124 	LIST_FOREACH(area, &oeconf->area_list, entry)
1125 		LIST_FOREACH(iface, &area->iface_list, entry)
1126 			if (idx == 0 || idx == iface->ifindex) {
1127 				ictl = if_to_ctl(iface);
1128 				imsg_compose_event(&c->iev,
1129 				    IMSG_CTL_SHOW_INTERFACE, 0, 0, -1,
1130 				    ictl, sizeof(struct ctl_iface));
1131 			}
1132 }
1133 
1134 void
1135 ospfe_nbr_ctl(struct ctl_conn *c)
1136 {
1137 	struct area	*area;
1138 	struct iface	*iface;
1139 	struct nbr	*nbr;
1140 	struct ctl_nbr	*nctl;
1141 
1142 	LIST_FOREACH(area, &oeconf->area_list, entry)
1143 		LIST_FOREACH(iface, &area->iface_list, entry)
1144 			LIST_FOREACH(nbr, &iface->nbr_list, entry) {
1145 				if (iface->self != nbr) {
1146 					nctl = nbr_to_ctl(nbr);
1147 					imsg_compose_event(&c->iev,
1148 					    IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl,
1149 					    sizeof(struct ctl_nbr));
1150 				}
1151 			}
1152 
1153 	imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0);
1154 }
1155 
1156 void
1157 ospfe_demote_area(struct area *area, int active)
1158 {
1159 	struct demote_msg	dmsg;
1160 
1161 	if (ospfd_process != PROC_OSPF_ENGINE ||
1162 	    area->demote_group[0] == '\0')
1163 		return;
1164 
1165 	bzero(&dmsg, sizeof(dmsg));
1166 	strlcpy(dmsg.demote_group, area->demote_group,
1167 	    sizeof(dmsg.demote_group));
1168 	dmsg.level = area->demote_level;
1169 	if (active)
1170 		dmsg.level = -dmsg.level;
1171 
1172 	ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg));
1173 }
1174 
1175 void
1176 ospfe_demote_iface(struct iface *iface, int active)
1177 {
1178 	struct demote_msg	dmsg;
1179 
1180 	if (ospfd_process != PROC_OSPF_ENGINE ||
1181 	    iface->demote_group[0] == '\0')
1182 		return;
1183 
1184 	bzero(&dmsg, sizeof(dmsg));
1185 	strlcpy(dmsg.demote_group, iface->demote_group,
1186 	sizeof(dmsg.demote_group));
1187 	if (active)
1188 		dmsg.level = -1;
1189 	else
1190 		dmsg.level = 1;
1191 
1192 	log_warnx("ospfe_demote_iface: group %s level %d", dmsg.demote_group,
1193 	    dmsg.level);
1194 
1195 	ospfe_imsg_compose_parent(IMSG_DEMOTE, 0, &dmsg, sizeof(dmsg));
1196 }
1197