xref: /openbsd-src/usr.sbin/bgpd/config.c (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /*	$OpenBSD: config.c,v 1.97 2020/12/29 15:30:34 claudio Exp $ */
2 
3 /*
4  * Copyright (c) 2003, 2004, 2005 Henning Brauer <henning@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 
22 #include <errno.h>
23 #include <ifaddrs.h>
24 #include <netdb.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <unistd.h>
29 
30 #include "bgpd.h"
31 #include "session.h"
32 #include "log.h"
33 
34 int		host_ip(const char *, struct bgpd_addr *, u_int8_t *);
35 void		free_networks(struct network_head *);
36 
37 struct bgpd_config *
38 new_config(void)
39 {
40 	struct bgpd_config	*conf;
41 
42 	if ((conf = calloc(1, sizeof(struct bgpd_config))) == NULL)
43 		fatal(NULL);
44 
45 	if ((conf->filters = calloc(1, sizeof(struct filter_head))) == NULL)
46 		fatal(NULL);
47 	if ((conf->listen_addrs = calloc(1, sizeof(struct listen_addrs))) ==
48 	    NULL)
49 		fatal(NULL);
50 	if ((conf->mrt = calloc(1, sizeof(struct mrt_head))) == NULL)
51 		fatal(NULL);
52 
53 	/* init the various list for later */
54 	RB_INIT(&conf->peers);
55 	TAILQ_INIT(&conf->networks);
56 	SIMPLEQ_INIT(&conf->l3vpns);
57 	SIMPLEQ_INIT(&conf->prefixsets);
58 	SIMPLEQ_INIT(&conf->originsets);
59 	SIMPLEQ_INIT(&conf->rde_prefixsets);
60 	SIMPLEQ_INIT(&conf->rde_originsets);
61 	RB_INIT(&conf->roa);
62 	SIMPLEQ_INIT(&conf->as_sets);
63 
64 	TAILQ_INIT(conf->filters);
65 	TAILQ_INIT(conf->listen_addrs);
66 	LIST_INIT(conf->mrt);
67 
68 	return (conf);
69 }
70 
71 void
72 copy_config(struct bgpd_config *to, struct bgpd_config *from)
73 {
74 	to->flags = from->flags;
75 	to->log = from->log;
76 	to->default_tableid = from->default_tableid;
77 	to->bgpid = from->bgpid;
78 	to->clusterid = from->clusterid;
79 	to->as = from->as;
80 	to->short_as = from->short_as;
81 	to->holdtime = from->holdtime;
82 	to->min_holdtime = from->min_holdtime;
83 	to->connectretry = from->connectretry;
84 	to->fib_priority = from->fib_priority;
85 }
86 
87 void
88 free_networks(struct network_head *networks)
89 {
90 	struct network		*n;
91 
92 	while ((n = TAILQ_FIRST(networks)) != NULL) {
93 		TAILQ_REMOVE(networks, n, entry);
94 		filterset_free(&n->net.attrset);
95 		free(n);
96 	}
97 }
98 
99 void
100 free_l3vpns(struct l3vpn_head *l3vpns)
101 {
102 	struct l3vpn		*vpn;
103 
104 	while ((vpn = SIMPLEQ_FIRST(l3vpns)) != NULL) {
105 		SIMPLEQ_REMOVE_HEAD(l3vpns, entry);
106 		filterset_free(&vpn->export);
107 		filterset_free(&vpn->import);
108 		free_networks(&vpn->net_l);
109 		free(vpn);
110 	}
111 }
112 
113 void
114 free_prefixsets(struct prefixset_head *psh)
115 {
116 	struct prefixset	*ps;
117 
118 	while (!SIMPLEQ_EMPTY(psh)) {
119 		ps = SIMPLEQ_FIRST(psh);
120 		free_roatree(&ps->roaitems);
121 		free_prefixtree(&ps->psitems);
122 		SIMPLEQ_REMOVE_HEAD(psh, entry);
123 		free(ps);
124 	}
125 }
126 
127 void
128 free_rde_prefixsets(struct rde_prefixset_head *psh)
129 {
130 	struct rde_prefixset	*ps;
131 
132 	if (psh == NULL)
133 		return;
134 
135 	while (!SIMPLEQ_EMPTY(psh)) {
136 		ps = SIMPLEQ_FIRST(psh);
137 		trie_free(&ps->th);
138 		SIMPLEQ_REMOVE_HEAD(psh, entry);
139 		free(ps);
140 	}
141 }
142 
143 void
144 free_prefixtree(struct prefixset_tree *p)
145 {
146 	struct prefixset_item	*psi, *npsi;
147 
148 	RB_FOREACH_SAFE(psi, prefixset_tree, p, npsi) {
149 		RB_REMOVE(prefixset_tree, p, psi);
150 		free(psi);
151 	}
152 }
153 
154 void
155 free_roatree(struct roa_tree *r)
156 {
157 	struct roa	*roa, *nroa;
158 
159 	RB_FOREACH_SAFE(roa, roa_tree, r, nroa) {
160 		RB_REMOVE(roa_tree, r, roa);
161 		free(roa);
162 	}
163 }
164 
165 void
166 free_config(struct bgpd_config *conf)
167 {
168 	struct peer		*p, *next;
169 	struct listen_addr	*la;
170 	struct mrt		*m;
171 
172 	free_l3vpns(&conf->l3vpns);
173 	free_networks(&conf->networks);
174 	filterlist_free(conf->filters);
175 	free_prefixsets(&conf->prefixsets);
176 	free_prefixsets(&conf->originsets);
177 	free_rde_prefixsets(&conf->rde_prefixsets);
178 	free_rde_prefixsets(&conf->rde_originsets);
179 	as_sets_free(&conf->as_sets);
180 	free_roatree(&conf->roa);
181 
182 	while ((la = TAILQ_FIRST(conf->listen_addrs)) != NULL) {
183 		TAILQ_REMOVE(conf->listen_addrs, la, entry);
184 		free(la);
185 	}
186 	free(conf->listen_addrs);
187 
188 	while ((m = LIST_FIRST(conf->mrt)) != NULL) {
189 		LIST_REMOVE(m, entry);
190 		free(m);
191 	}
192 	free(conf->mrt);
193 
194 	RB_FOREACH_SAFE(p, peer_head, &conf->peers, next) {
195 		RB_REMOVE(peer_head, &conf->peers, p);
196 		free(p);
197 	}
198 
199 	free(conf->csock);
200 	free(conf->rcsock);
201 
202 	free(conf);
203 }
204 
205 void
206 merge_config(struct bgpd_config *xconf, struct bgpd_config *conf)
207 {
208 	struct listen_addr	*nla, *ola, *next;
209 	struct peer		*p, *np, *nextp;
210 
211 	/*
212 	 * merge the freshly parsed conf into the running xconf
213 	 */
214 
215 	/* adjust FIB priority if changed */
216 	/* if xconf is uninitialized we get RTP_NONE */
217 	if (xconf->fib_priority != conf->fib_priority) {
218 		kr_fib_decouple_all(xconf->fib_priority);
219 		kr_fib_update_prio_all(conf->fib_priority);
220 		kr_fib_couple_all(conf->fib_priority);
221 	}
222 
223 	/* take over the easy config changes */
224 	copy_config(xconf, conf);
225 
226 	/* clear old control sockets and use new */
227 	free(xconf->csock);
228 	free(xconf->rcsock);
229 	xconf->csock = conf->csock;
230 	xconf->rcsock = conf->rcsock;
231 	/* set old one to NULL so we don't double free */
232 	conf->csock = NULL;
233 	conf->rcsock = NULL;
234 
235 	/* clear all current filters and take over the new ones */
236 	filterlist_free(xconf->filters);
237 	xconf->filters = conf->filters;
238 	conf->filters = NULL;
239 
240 	/* merge mrt config */
241 	mrt_mergeconfig(xconf->mrt, conf->mrt);
242 
243 	/* switch the roa, first remove the old one */
244 	free_roatree(&xconf->roa);
245 	/* then move the RB tree root */
246 	RB_ROOT(&xconf->roa) = RB_ROOT(&conf->roa);
247 	RB_ROOT(&conf->roa) = NULL;
248 
249 	/* switch the prefixsets, first remove the old ones */
250 	free_prefixsets(&xconf->prefixsets);
251 	SIMPLEQ_CONCAT(&xconf->prefixsets, &conf->prefixsets);
252 
253 	/* switch the originsets, first remove the old ones */
254 	free_prefixsets(&xconf->originsets);
255 	SIMPLEQ_CONCAT(&xconf->originsets, &conf->originsets);
256 
257 	/* switch the as_sets, first remove the old ones */
258 	as_sets_free(&xconf->as_sets);
259 	SIMPLEQ_CONCAT(&xconf->as_sets, &conf->as_sets);
260 
261 	/* switch the network statements, but first remove the old ones */
262 	free_networks(&xconf->networks);
263 	TAILQ_CONCAT(&xconf->networks, &conf->networks, entry);
264 
265 	/* switch the l3vpn configs, first remove the old ones */
266 	free_l3vpns(&xconf->l3vpns);
267 	SIMPLEQ_CONCAT(&xconf->l3vpns, &conf->l3vpns);
268 
269 	/*
270 	 * merge new listeners:
271 	 * -flag all existing ones as to be deleted
272 	 * -those that are in both new and old: flag to keep
273 	 * -new ones get inserted and flagged as to reinit
274 	 * -remove all that are still flagged for deletion
275 	 */
276 
277 	TAILQ_FOREACH(nla, xconf->listen_addrs, entry)
278 		nla->reconf = RECONF_DELETE;
279 
280 	/* no new listeners? preserve default ones */
281 	if (TAILQ_EMPTY(conf->listen_addrs))
282 		TAILQ_FOREACH(ola, xconf->listen_addrs, entry)
283 			if (ola->flags & DEFAULT_LISTENER)
284 				ola->reconf = RECONF_KEEP;
285 	/* else loop over listeners and merge configs */
286 	for (nla = TAILQ_FIRST(conf->listen_addrs); nla != NULL; nla = next) {
287 		next = TAILQ_NEXT(nla, entry);
288 
289 		TAILQ_FOREACH(ola, xconf->listen_addrs, entry)
290 			if (!memcmp(&nla->sa, &ola->sa, sizeof(nla->sa)))
291 				break;
292 
293 		if (ola == NULL) {
294 			/* new listener, copy over */
295 			TAILQ_REMOVE(conf->listen_addrs, nla, entry);
296 			TAILQ_INSERT_TAIL(xconf->listen_addrs, nla, entry);
297 			nla->reconf = RECONF_REINIT;
298 		} else		/* exists, just flag */
299 			ola->reconf = RECONF_KEEP;
300 	}
301 	/* finally clean up the original list and remove all stale entires */
302 	for (nla = TAILQ_FIRST(xconf->listen_addrs); nla != NULL; nla = next) {
303 		next = TAILQ_NEXT(nla, entry);
304 		if (nla->reconf == RECONF_DELETE) {
305 			TAILQ_REMOVE(xconf->listen_addrs, nla, entry);
306 			free(nla);
307 		}
308 	}
309 
310 	/*
311 	 * merge peers:
312 	 * - need to know which peers are new, replaced and removed
313 	 * - walk over old peers and check if there is a corresponding new
314 	 *   peer if so mark it RECONF_KEEP. Remove all old peers.
315 	 * - swap lists (old peer list is actually empty).
316 	 */
317 	RB_FOREACH_SAFE(p, peer_head, &xconf->peers, nextp) {
318 		np = getpeerbyid(conf, p->conf.id);
319 		if (np != NULL) {
320 			np->reconf_action = RECONF_KEEP;
321 			/* copy the auth state since parent uses it */
322 			np->auth = p->auth;
323 		} else {
324 			/* peer no longer exists, clear pfkey state */
325 			pfkey_remove(p);
326 		}
327 
328 		RB_REMOVE(peer_head, &xconf->peers, p);
329 		free(p);
330 	}
331 	RB_FOREACH_SAFE(np, peer_head, &conf->peers, nextp) {
332 		RB_REMOVE(peer_head, &conf->peers, np);
333 		if (RB_INSERT(peer_head, &xconf->peers, np) != NULL)
334 			fatalx("%s: peer tree is corrupt", __func__);
335 	}
336 
337 	/* conf is merged so free it */
338 	free_config(conf);
339 }
340 
341 u_int32_t
342 get_bgpid(void)
343 {
344 	struct ifaddrs		*ifap, *ifa;
345 	u_int32_t		 ip = 0, cur, localnet;
346 
347 	localnet = htonl(INADDR_LOOPBACK & IN_CLASSA_NET);
348 
349 	if (getifaddrs(&ifap) == -1)
350 		fatal("getifaddrs");
351 
352 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
353 		if (ifa->ifa_addr == NULL ||
354 		    ifa->ifa_addr->sa_family != AF_INET)
355 			continue;
356 		cur = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
357 		if ((cur & localnet) == localnet)	/* skip 127/8 */
358 			continue;
359 		if (ntohl(cur) > ntohl(ip))
360 			ip = cur;
361 	}
362 	freeifaddrs(ifap);
363 
364 	return (ip);
365 }
366 
367 int
368 host(const char *s, struct bgpd_addr *h, u_int8_t *len)
369 {
370 	int			 mask = 128;
371 	char			*p, *ps;
372 	const char		*errstr;
373 
374 	if ((ps = strdup(s)) == NULL)
375 		fatal("%s: strdup", __func__);
376 
377 	if ((p = strrchr(ps, '/')) != NULL) {
378 		mask = strtonum(p+1, 0, 128, &errstr);
379 		if (errstr) {
380 			log_warnx("prefixlen is %s: %s", errstr, p);
381 			free(ps);
382 			return (0);
383 		}
384 		p[0] = '\0';
385 	}
386 
387 	bzero(h, sizeof(*h));
388 
389 	if (host_ip(ps, h, len) == 0) {
390 		free(ps);
391 		return (0);
392 	}
393 
394 	if (p != NULL)
395 		*len = mask;
396 
397 	free(ps);
398 	return (1);
399 }
400 
401 int
402 host_ip(const char *s, struct bgpd_addr *h, u_int8_t *len)
403 {
404 	struct addrinfo		 hints, *res;
405 	int			 bits;
406 
407 	bzero(&hints, sizeof(hints));
408 	hints.ai_family = AF_UNSPEC;
409 	hints.ai_socktype = SOCK_DGRAM; /*dummy*/
410 	hints.ai_flags = AI_NUMERICHOST;
411 	if (getaddrinfo(s, NULL, &hints, &res) == 0) {
412 		*len = res->ai_family == AF_INET6 ? 128 : 32;
413 		sa2addr(res->ai_addr, h, NULL);
414 		freeaddrinfo(res);
415 	} else {	/* ie. for 10/8 parsing */
416 		if ((bits = inet_net_pton(AF_INET, s, &h->v4, sizeof(h->v4))) == -1)
417 			return (0);
418 		*len = bits;
419 		h->aid = AID_INET;
420 	}
421 
422 	return (1);
423 }
424 
425 int
426 prepare_listeners(struct bgpd_config *conf)
427 {
428 	struct listen_addr	*la, *next;
429 	int			 opt = 1;
430 	int			 r = 0;
431 
432 	if (TAILQ_EMPTY(conf->listen_addrs)) {
433 		if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
434 			fatal("setup_listeners calloc");
435 		la->fd = -1;
436 		la->flags = DEFAULT_LISTENER;
437 		la->reconf = RECONF_REINIT;
438 		la->sa_len = sizeof(struct sockaddr_in);
439 		((struct sockaddr_in *)&la->sa)->sin_family = AF_INET;
440 		((struct sockaddr_in *)&la->sa)->sin_addr.s_addr =
441 		    htonl(INADDR_ANY);
442 		((struct sockaddr_in *)&la->sa)->sin_port = htons(BGP_PORT);
443 		TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
444 
445 		if ((la = calloc(1, sizeof(struct listen_addr))) == NULL)
446 			fatal("setup_listeners calloc");
447 		la->fd = -1;
448 		la->flags = DEFAULT_LISTENER;
449 		la->reconf = RECONF_REINIT;
450 		la->sa_len = sizeof(struct sockaddr_in6);
451 		((struct sockaddr_in6 *)&la->sa)->sin6_family = AF_INET6;
452 		((struct sockaddr_in6 *)&la->sa)->sin6_port = htons(BGP_PORT);
453 		TAILQ_INSERT_TAIL(conf->listen_addrs, la, entry);
454 	}
455 
456 	for (la = TAILQ_FIRST(conf->listen_addrs); la != NULL; la = next) {
457 		next = TAILQ_NEXT(la, entry);
458 		if (la->reconf != RECONF_REINIT)
459 			continue;
460 
461 		if ((la->fd = socket(la->sa.ss_family,
462 		    SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
463 		    IPPROTO_TCP)) == -1) {
464 			if (la->flags & DEFAULT_LISTENER && (errno ==
465 			    EAFNOSUPPORT || errno == EPROTONOSUPPORT)) {
466 				TAILQ_REMOVE(conf->listen_addrs, la, entry);
467 				free(la);
468 				continue;
469 			} else
470 				fatal("socket");
471 		}
472 
473 		opt = 1;
474 		if (setsockopt(la->fd, SOL_SOCKET, SO_REUSEADDR,
475 		    &opt, sizeof(opt)) == -1)
476 			fatal("setsockopt SO_REUSEADDR");
477 
478 		if (bind(la->fd, (struct sockaddr *)&la->sa, la->sa_len) ==
479 		    -1) {
480 			switch (la->sa.ss_family) {
481 			case AF_INET:
482 				log_warn("cannot bind to %s:%u",
483 				    log_sockaddr((struct sockaddr *)&la->sa,
484 				    la->sa_len), ntohs(((struct sockaddr_in *)
485 				    &la->sa)->sin_port));
486 				break;
487 			case AF_INET6:
488 				log_warn("cannot bind to [%s]:%u",
489 				    log_sockaddr((struct sockaddr *)&la->sa,
490 				    la->sa_len), ntohs(((struct sockaddr_in6 *)
491 				    &la->sa)->sin6_port));
492 				break;
493 			default:
494 				log_warn("cannot bind to %s",
495 				    log_sockaddr((struct sockaddr *)&la->sa,
496 				    la->sa_len));
497 				break;
498 			}
499 			close(la->fd);
500 			TAILQ_REMOVE(conf->listen_addrs, la, entry);
501 			free(la);
502 			r = -1;
503 			continue;
504 		}
505 	}
506 
507 	return (r);
508 }
509 
510 void
511 expand_networks(struct bgpd_config *c)
512 {
513 	struct network		*n, *m, *tmp;
514 	struct network_head	*nw = &c->networks;
515 	struct prefixset	*ps;
516 	struct prefixset_item	*psi;
517 
518 	TAILQ_FOREACH_SAFE(n, nw, entry, tmp) {
519 		if (n->net.type == NETWORK_PREFIXSET) {
520 			TAILQ_REMOVE(nw, n, entry);
521 			if ((ps = find_prefixset(n->net.psname, &c->prefixsets))
522 			    == NULL)
523 				fatal("%s: prefixset %s not found", __func__,
524 				    n->net.psname);
525 			RB_FOREACH(psi, prefixset_tree, &ps->psitems) {
526 				if ((m = calloc(1, sizeof(struct network)))
527 				    == NULL)
528 					fatal(NULL);
529 				memcpy(&m->net.prefix, &psi->p.addr,
530 				    sizeof(m->net.prefix));
531 				m->net.prefixlen = psi->p.len;
532 				filterset_copy(&n->net.attrset,
533 				    &m->net.attrset);
534 				TAILQ_INSERT_TAIL(nw, m, entry);
535 			}
536 			filterset_free(&n->net.attrset);
537 			free(n);
538 		}
539 	}
540 }
541 
542 static inline int
543 prefixset_cmp(struct prefixset_item *a, struct prefixset_item *b)
544 {
545 	int i;
546 
547 	if (a->p.addr.aid < b->p.addr.aid)
548 		return (-1);
549 	if (a->p.addr.aid > b->p.addr.aid)
550 		return (1);
551 
552 	switch (a->p.addr.aid) {
553 	case AID_INET:
554 		if (ntohl(a->p.addr.v4.s_addr) < ntohl(b->p.addr.v4.s_addr))
555 			return (-1);
556 		if (ntohl(a->p.addr.v4.s_addr) > ntohl(b->p.addr.v4.s_addr))
557 			return (1);
558 		break;
559 	case AID_INET6:
560 		i = memcmp(&a->p.addr.v6, &b->p.addr.v6,
561 		    sizeof(struct in6_addr));
562 		if (i > 0)
563 			return (1);
564 		if (i < 0)
565 			return (-1);
566 		break;
567 	default:
568 		fatalx("%s: unknown af", __func__);
569 	}
570 	if (a->p.len < b->p.len)
571 		return (-1);
572 	if (a->p.len > b->p.len)
573 		return (1);
574 	if (a->p.len_min < b->p.len_min)
575 		return (-1);
576 	if (a->p.len_min > b->p.len_min)
577 		return (1);
578 	if (a->p.len_max < b->p.len_max)
579 		return (-1);
580 	if (a->p.len_max > b->p.len_max)
581 		return (1);
582 	return (0);
583 }
584 
585 RB_GENERATE(prefixset_tree, prefixset_item, entry, prefixset_cmp);
586 
587 static inline int
588 roa_cmp(struct roa *a, struct roa *b)
589 {
590 	size_t len = 4 + sizeof(a->asnum);
591 
592 	if (a->aid == b->aid) {
593 		if (a->aid == AID_INET)
594 			len += sizeof(a->prefix.inet);
595 		else
596 			len += sizeof(a->prefix.inet6);
597 	}
598 
599 	return memcmp(&a->aid, &b->aid, len);
600 }
601 
602 RB_GENERATE(roa_tree, roa, entry, roa_cmp);
603