xref: /openbsd/usr.sbin/ripd/ripd.c (revision 5dea098c)
1 /*	$OpenBSD: ripd.c,v 1.37 2023/03/08 04:43:15 guenther Exp $ */
2 
3 /*
4  * Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it>
5  * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
6  * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
7  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
8  *
9  * Permission to use, copy, modify, and distribute this software for any
10  * purpose with or without fee is hereby granted, provided that the above
11  * copyright notice and this permission notice appear in all copies.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/queue.h>
25 #include <sys/time.h>
26 #include <sys/stat.h>
27 #include <sys/wait.h>
28 #include <sys/sysctl.h>
29 
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
32 
33 #include <event.h>
34 #include <err.h>
35 #include <errno.h>
36 #include <pwd.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <signal.h>
41 #include <unistd.h>
42 
43 #include "rip.h"
44 #include "ripd.h"
45 #include "ripe.h"
46 #include "log.h"
47 #include "control.h"
48 #include "rde.h"
49 
50 __dead void		 usage(void);
51 void			 main_sig_handler(int, short, void *);
52 __dead void		 ripd_shutdown(void);
53 void			 main_dispatch_ripe(int, short, void *);
54 void			 main_dispatch_rde(int, short, void *);
55 
56 int			 pipe_parent2ripe[2];
57 int			 pipe_parent2rde[2];
58 int			 pipe_ripe2rde[2];
59 
60 struct ripd_conf	*conf = NULL;
61 static struct imsgev	*iev_ripe;
62 static struct imsgev	*iev_rde;
63 
64 pid_t			 ripe_pid = 0;
65 pid_t			 rde_pid = 0;
66 
67 __dead void
68 usage(void)
69 {
70 	extern char *__progname;
71 
72 	fprintf(stderr,
73 	    "usage: %s [-dnv] [-D macro=value] [-f file] [-s socket]\n",
74 	    __progname);
75 	exit(1);
76 }
77 
78 void
79 main_sig_handler(int sig, short event, void *arg)
80 {
81 	/* signal handler rules don't apply, libevent decouples for us */
82 	switch (sig) {
83 	case SIGTERM:
84 	case SIGINT:
85 		ripd_shutdown();
86 		/* NOTREACHED */
87 	case SIGHUP:
88 		/* reconfigure */
89 		/* ... */
90 		break;
91 	default:
92 		fatalx("unexpected signal");
93 		/* NOTREACHED */
94 	}
95 }
96 
97 int
98 main(int argc, char *argv[])
99 {
100 	struct event	 ev_sigint, ev_sigterm, ev_sighup;
101 	int		 mib[4];
102 	int		 debug = 0;
103 	int		 ipforwarding;
104 	int		 ch;
105 	int		 opts = 0;
106 	char		*conffile;
107 	char 		*sockname;
108 	size_t		 len;
109 
110 	conffile = CONF_FILE;
111 	log_procname = "parent";
112 	sockname = RIPD_SOCKET;
113 
114 	log_init(1);	/* log to stderr until daemonized */
115 	log_verbose(1);
116 
117 	while ((ch = getopt(argc, argv, "cdD:f:ns:v")) != -1) {
118 		switch (ch) {
119 		case 'c':
120 			opts |= RIPD_OPT_FORCE_DEMOTE;
121 			break;
122 		case 'd':
123 			debug = 1;
124 			break;
125 		case 'D':
126 			if (cmdline_symset(optarg) < 0)
127 				log_warnx("could not parse macro definition %s",
128 				    optarg);
129 			break;
130 		case 'f':
131 			conffile = optarg;
132 			break;
133 		case 'n':
134 			opts |= RIPD_OPT_NOACTION;
135 			break;
136 		case 's':
137 			sockname = optarg;
138 			break;
139 		case 'v':
140 			if (opts & RIPD_OPT_VERBOSE)
141 				opts |= RIPD_OPT_VERBOSE2;
142 			opts |= RIPD_OPT_VERBOSE;
143 			break;
144 		default:
145 			usage();
146 			/* NOTREACHED */
147 		}
148 	}
149 
150 	argc -= optind;
151 	argv += optind;
152 	if (argc > 0)
153 		usage();
154 
155 	mib[0] = CTL_NET;
156 	mib[1] = PF_INET;
157 	mib[2] = IPPROTO_IP;
158 	mib[3] = IPCTL_FORWARDING;
159 	len = sizeof(ipforwarding);
160 	if (sysctl(mib, 4, &ipforwarding, &len, NULL, 0) == -1)
161 		err(1, "sysctl");
162 
163 	if (!ipforwarding)
164 		log_warnx("WARNING: IP forwarding NOT enabled");
165 
166 	/* fetch interfaces early */
167 	kif_init();
168 
169 	/* parse config file */
170 	if ((conf = parse_config(conffile, opts)) == NULL )
171 		exit(1);
172 	conf->csock = sockname;
173 
174 	if (conf->opts & RIPD_OPT_NOACTION) {
175 		if (conf->opts & RIPD_OPT_VERBOSE)
176 			print_config(conf);
177 		else
178 			fprintf(stderr, "configuration OK\n");
179 		exit(0);
180 	}
181 
182 	/* check for root privileges */
183 	if (geteuid())
184 		errx(1, "need root privileges");
185 
186 	/* check for ripd user */
187 	if (getpwnam(RIPD_USER) == NULL)
188 		errx(1, "unknown user %s", RIPD_USER);
189 
190 	log_init(debug);
191 	log_verbose(conf->opts & RIPD_OPT_VERBOSE);
192 
193 	if (!debug)
194 		daemon(1, 0);
195 
196 	log_info("startup");
197 
198 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
199 	    PF_UNSPEC, pipe_parent2ripe) == -1)
200 		fatal("socketpair");
201 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
202 	    PF_UNSPEC, pipe_parent2rde) == -1)
203 		fatal("socketpair");
204 	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
205 	    PF_UNSPEC, pipe_ripe2rde) == -1)
206 		fatal("socketpair");
207 
208 	/* start children */
209 	rde_pid = rde(conf, pipe_parent2rde, pipe_ripe2rde, pipe_parent2ripe);
210 	ripe_pid = ripe(conf, pipe_parent2ripe, pipe_ripe2rde, pipe_parent2rde);
211 
212 	/* no filesystem visibility */
213 	if (unveil("/", "") == -1)
214 		fatal("unveil /");
215 	if (unveil(NULL, NULL) == -1)
216 		fatal("unveil");
217 
218 	event_init();
219 
220 	/* setup signal handler */
221 	signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL);
222 	signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL);
223 	signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL);
224 	signal_add(&ev_sigint, NULL);
225 	signal_add(&ev_sigterm, NULL);
226 	signal_add(&ev_sighup, NULL);
227 	signal(SIGPIPE, SIG_IGN);
228 
229 	/* setup pipes to children */
230 	close(pipe_parent2ripe[1]);
231 	close(pipe_parent2rde[1]);
232 	close(pipe_ripe2rde[0]);
233 	close(pipe_ripe2rde[1]);
234 
235 	if ((iev_ripe = malloc(sizeof(struct imsgev))) == NULL ||
236 	    (iev_rde = malloc(sizeof(struct imsgev))) == NULL)
237 		fatal(NULL);
238 	imsg_init(&iev_ripe->ibuf, pipe_parent2ripe[0]);
239 	iev_ripe->handler = main_dispatch_ripe;
240 	imsg_init(&iev_rde->ibuf, pipe_parent2rde[0]);
241 	iev_rde->handler = main_dispatch_rde;
242 
243 	/* setup event handler */
244 	iev_ripe->events = EV_READ;
245 	event_set(&iev_ripe->ev, iev_ripe->ibuf.fd, iev_ripe->events,
246 	    iev_ripe->handler, iev_ripe);
247 	event_add(&iev_ripe->ev, NULL);
248 
249 	iev_rde->events = EV_READ;
250 	event_set(&iev_rde->ev, iev_rde->ibuf.fd, iev_rde->events,
251 	    iev_rde->handler, iev_rde);
252 	event_add(&iev_rde->ev, NULL);
253 
254 	if (kr_init(!(conf->flags & RIPD_FLAG_NO_FIB_UPDATE),
255 	    conf->rdomain, conf->fib_priority) == -1)
256 		fatalx("kr_init failed");
257 
258 	event_dispatch();
259 
260 	ripd_shutdown();
261 	/* NOTREACHED */
262 	return (0);
263 }
264 
265 __dead void
266 ripd_shutdown(void)
267 {
268 	struct iface	*i;
269 	pid_t		 pid;
270 	int		 status;
271 
272 	/* close pipes */
273 	msgbuf_clear(&iev_ripe->ibuf.w);
274 	close(iev_ripe->ibuf.fd);
275 	msgbuf_clear(&iev_rde->ibuf.w);
276 	close(iev_rde->ibuf.fd);
277 
278 	while ((i = LIST_FIRST(&conf->iface_list)) != NULL) {
279 		LIST_REMOVE(i, entry);
280 		if_del(i);
281 	}
282 
283 	kr_shutdown();
284 
285 	log_debug("waiting for children to terminate");
286 	do {
287 		pid = wait(&status);
288 		if (pid == -1) {
289 			if (errno != EINTR && errno != ECHILD)
290 				fatal("wait");
291 		} else if (WIFSIGNALED(status))
292 			log_warnx("%s terminated; signal %d",
293 			    (pid == rde_pid) ? "route decision engine" :
294 			    "rip engine", WTERMSIG(status));
295 	} while (pid != -1 || (pid == -1 && errno == EINTR));
296 
297 	free(iev_ripe);
298 	free(iev_rde);
299 	free(conf);
300 
301 	log_info("terminating");
302 	exit(0);
303 }
304 
305 /* imsg handling */
306 void
307 main_dispatch_ripe(int fd, short event, void *bula)
308 {
309 	struct imsgev		*iev = bula;
310 	struct imsgbuf		*ibuf = &iev->ibuf;
311 	struct imsg		 imsg;
312 	struct demote_msg	 dmsg;
313 	ssize_t			 n;
314 	int			 shut = 0, verbose;
315 
316 	if (event & EV_READ) {
317 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
318 			fatal("imsg_read error");
319 		if (n == 0)	/* connection closed */
320 			shut = 1;
321 	}
322 	if (event & EV_WRITE) {
323 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
324 			fatal("msgbuf_write");
325 		if (n == 0)	/* connection closed */
326 			shut = 1;
327 	}
328 
329 	for (;;) {
330 		if ((n = imsg_get(ibuf, &imsg)) == -1)
331 			fatal("imsg_get");
332 
333 		if (n == 0)
334 			break;
335 
336 		switch (imsg.hdr.type) {
337 		case IMSG_CTL_RELOAD:
338 			/* XXX reconfig */
339 			break;
340 		case IMSG_CTL_FIB_COUPLE:
341 			kr_fib_couple();
342 			break;
343 		case IMSG_CTL_FIB_DECOUPLE:
344 			kr_fib_decouple();
345 			break;
346 		case IMSG_CTL_KROUTE:
347 		case IMSG_CTL_KROUTE_ADDR:
348 			kr_show_route(&imsg);
349 			break;
350 		case IMSG_CTL_IFINFO:
351 			if (imsg.hdr.len == IMSG_HEADER_SIZE)
352 				kr_ifinfo(NULL, imsg.hdr.pid);
353 			else if (imsg.hdr.len == IMSG_HEADER_SIZE + IFNAMSIZ)
354 				kr_ifinfo(imsg.data, imsg.hdr.pid);
355 			else
356 				log_warnx("IFINFO request with wrong len");
357 			break;
358 		case IMSG_DEMOTE:
359 			if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(dmsg))
360 				fatalx("invalid size of OE request");
361 			memcpy(&dmsg, imsg.data, sizeof(dmsg));
362 			carp_demote_set(dmsg.demote_group, dmsg.level);
363 			break;
364 		case IMSG_CTL_LOG_VERBOSE:
365 			/* already checked by ripe */
366 			memcpy(&verbose, imsg.data, sizeof(verbose));
367 			log_verbose(verbose);
368 			break;
369 		default:
370 			log_debug("main_dispatch_ripe: error handling imsg %d",
371 			    imsg.hdr.type);
372 			break;
373 		}
374 		imsg_free(&imsg);
375 	}
376 	if (!shut)
377 		imsg_event_add(iev);
378 	else {
379 		/* this pipe is dead, so remove the event handler */
380 		event_del(&iev->ev);
381 		event_loopexit(NULL);
382 	}
383 }
384 
385 void
386 main_dispatch_rde(int fd, short event, void *bula)
387 {
388 	struct imsgev	*iev = bula;
389 	struct imsgbuf	*ibuf = &iev->ibuf;
390 	struct imsg	 imsg;
391 	ssize_t		 n;
392 	int		 shut = 0;
393 
394 	if (event & EV_READ) {
395 		if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN)
396 			fatal("imsg_read error");
397 		if (n == 0)	/* connection closed */
398 			shut = 1;
399 	}
400 	if (event & EV_WRITE) {
401 		if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN)
402 			fatal("msgbuf_write");
403 		if (n == 0)	/* connection closed */
404 			shut = 1;
405 	}
406 
407 	for (;;) {
408 		if ((n = imsg_get(ibuf, &imsg)) == -1)
409 			fatal("imsg_get");
410 
411 		if (n == 0)
412 			break;
413 
414 		switch (imsg.hdr.type) {
415 		case IMSG_KROUTE_CHANGE:
416 			if (kr_change(imsg.data))
417 				log_warn("main_dispatch_rde: error changing "
418 				    "route");
419 			break;
420 		case IMSG_KROUTE_DELETE:
421 			if (kr_delete(imsg.data))
422 				log_warn("main_dispatch_rde: error deleting "
423 				    "route");
424 			break;
425 		default:
426 			log_debug("main_dispatch_rde: error handling imsg %d",
427 			    imsg.hdr.type);
428 			break;
429 		}
430 		imsg_free(&imsg);
431 	}
432 	if (!shut)
433 		imsg_event_add(iev);
434 	else {
435 		/* this pipe is dead, so remove the event handler */
436 		event_del(&iev->ev);
437 		event_loopexit(NULL);
438 	}
439 }
440 
441 void
442 main_imsg_compose_ripe(int type, pid_t pid, void *data, u_int16_t datalen)
443 {
444 	imsg_compose_event(iev_ripe, type, 0, pid, -1, data, datalen);
445 }
446 
447 void
448 main_imsg_compose_rde(int type, pid_t pid, void *data, u_int16_t datalen)
449 {
450 	imsg_compose_event(iev_rde, type, 0, pid, -1, data, datalen);
451 }
452 
453 int
454 rip_redistribute(struct kroute *kr)
455 {
456 	struct redistribute	*r;
457 	u_int8_t		 is_default = 0;
458 
459 	if (kr->flags & F_RIPD_INSERTED)
460 		return (1);
461 
462 	/* only allow 0.0.0.0/0 via REDIST_DEFAULT */
463 	if (kr->prefix.s_addr == INADDR_ANY && kr->netmask.s_addr == INADDR_ANY)
464 		is_default = 1;
465 
466 	SIMPLEQ_FOREACH(r, &conf->redist_list, entry) {
467 		switch (r->type & ~REDIST_NO) {
468 		case REDIST_LABEL:
469 			if (kr->rtlabel == r->label)
470 				return (r->type & REDIST_NO ? 0 : 1);
471 			break;
472 		case REDIST_STATIC:
473 			/*
474 			 * Dynamic routes are not redistributable. Placed here
475 			 * so that link local addresses can be redistributed
476 			 * via a rtlabel.
477 			 */
478 			if (is_default)
479 				continue;
480 			if (kr->flags & F_DYNAMIC)
481 				continue;
482 			if (kr->flags & F_STATIC)
483 				return (r->type & REDIST_NO ? 0 : 1);
484 			break;
485 		case REDIST_CONNECTED:
486 			if (is_default)
487 				continue;
488 			if (kr->flags & F_DYNAMIC)
489 				continue;
490 			if (kr->flags & F_CONNECTED)
491 				return (r->type & REDIST_NO ? 0 : 1);
492 			break;
493 		case REDIST_ADDR:
494 			if (kr->flags & F_DYNAMIC)
495 				continue;
496 
497 			if (r->addr.s_addr == INADDR_ANY &&
498 			    r->mask.s_addr == INADDR_ANY) {
499 				if (is_default)
500 					return (r->type & REDIST_NO? 0 : 1);
501 				else
502 					return (0);
503 			}
504 
505 			if ((kr->prefix.s_addr & r->mask.s_addr) ==
506 			    (r->addr.s_addr & r->mask.s_addr) &&
507 			    (kr->netmask.s_addr & r->mask.s_addr) ==
508 			    r->mask.s_addr)
509 				return (r->type & REDIST_NO? 0 : 1);
510 			break;
511 		case REDIST_DEFAULT:
512 			if (is_default)
513 				return (r->type & REDIST_NO? 0 : 1);
514 			break;
515 		}
516 	}
517 
518 	return (0);
519 }
520 
521 void
522 imsg_event_add(struct imsgev *iev)
523 {
524 	if (iev->handler == NULL) {
525 		imsg_flush(&iev->ibuf);
526 		return;
527 	}
528 
529 	iev->events = EV_READ;
530 	if (iev->ibuf.w.queued)
531 		iev->events |= EV_WRITE;
532 
533 	event_del(&iev->ev);
534 	event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
535 	event_add(&iev->ev, NULL);
536 }
537 
538 int
539 imsg_compose_event(struct imsgev *iev, u_int16_t type,
540     u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen)
541 {
542 	int	ret;
543 
544 	if ((ret = imsg_compose(&iev->ibuf, type, peerid,
545 	    pid, fd, data, datalen)) != -1)
546 		imsg_event_add(iev);
547 	return (ret);
548 }
549