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