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