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