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