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