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