1 /* $OpenBSD: neighbor.c,v 1.81 2019/06/28 13:32:48 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org> 5 * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> 6 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 7 * Copyright (c) 2004, 2005, 2008 Esben Norby <norby@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/time.h> 24 #include <netinet/tcp.h> 25 #include <arpa/inet.h> 26 #include <errno.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <unistd.h> 30 31 #include "ldpd.h" 32 #include "ldpe.h" 33 #include "lde.h" 34 #include "log.h" 35 36 static __inline int nbr_id_compare(struct nbr *, struct nbr *); 37 static __inline int nbr_addr_compare(struct nbr *, struct nbr *); 38 static __inline int nbr_pid_compare(struct nbr *, struct nbr *); 39 static void nbr_update_peerid(struct nbr *); 40 static void nbr_ktimer(int, short, void *); 41 static void nbr_start_ktimer(struct nbr *); 42 static void nbr_ktimeout(int, short, void *); 43 static void nbr_start_ktimeout(struct nbr *); 44 static void nbr_itimeout(int, short, void *); 45 static void nbr_start_itimeout(struct nbr *); 46 static void nbr_idtimer(int, short, void *); 47 static int nbr_act_session_operational(struct nbr *); 48 static void nbr_send_labelmappings(struct nbr *); 49 50 RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare) 51 RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare) 52 RB_GENERATE(nbr_pid_head, nbr, pid_tree, nbr_pid_compare) 53 54 struct { 55 int state; 56 enum nbr_event event; 57 enum nbr_action action; 58 int new_state; 59 } nbr_fsm_tbl[] = { 60 /* current state event that happened action to take resulting state */ 61 /* Passive Role */ 62 {NBR_STA_PRESENT, NBR_EVT_MATCH_ADJ, NBR_ACT_NOTHING, NBR_STA_INITIAL}, 63 {NBR_STA_INITIAL, NBR_EVT_INIT_RCVD, NBR_ACT_PASSIVE_INIT, NBR_STA_OPENREC}, 64 {NBR_STA_OPENREC, NBR_EVT_KEEPALIVE_RCVD, NBR_ACT_SESSION_EST, NBR_STA_OPER}, 65 /* Active Role */ 66 {NBR_STA_PRESENT, NBR_EVT_CONNECT_UP, NBR_ACT_CONNECT_SETUP, NBR_STA_INITIAL}, 67 {NBR_STA_INITIAL, NBR_EVT_INIT_SENT, NBR_ACT_NOTHING, NBR_STA_OPENSENT}, 68 {NBR_STA_OPENSENT, NBR_EVT_INIT_RCVD, NBR_ACT_KEEPALIVE_SEND, NBR_STA_OPENREC}, 69 /* Session Maintenance */ 70 {NBR_STA_OPER, NBR_EVT_PDU_RCVD, NBR_ACT_RST_KTIMEOUT, 0}, 71 {NBR_STA_SESSION, NBR_EVT_PDU_RCVD, NBR_ACT_NOTHING, 0}, 72 {NBR_STA_OPER, NBR_EVT_PDU_SENT, NBR_ACT_RST_KTIMER, 0}, 73 {NBR_STA_SESSION, NBR_EVT_PDU_SENT, NBR_ACT_NOTHING, 0}, 74 /* Session Close */ 75 {NBR_STA_PRESENT, NBR_EVT_CLOSE_SESSION, NBR_ACT_NOTHING, 0}, 76 {NBR_STA_SESSION, NBR_EVT_CLOSE_SESSION, NBR_ACT_CLOSE_SESSION, NBR_STA_PRESENT}, 77 {-1, NBR_EVT_NOTHING, NBR_ACT_NOTHING, 0}, 78 }; 79 80 const char * const nbr_event_names[] = { 81 "NOTHING", 82 "ADJACENCY MATCHED", 83 "CONNECTION UP", 84 "SESSION CLOSE", 85 "INIT RECEIVED", 86 "KEEPALIVE RECEIVED", 87 "PDU RECEIVED", 88 "PDU SENT", 89 "INIT SENT" 90 }; 91 92 const char * const nbr_action_names[] = { 93 "NOTHING", 94 "RESET KEEPALIVE TIMEOUT", 95 "START NEIGHBOR SESSION", 96 "RESET KEEPALIVE TIMER", 97 "SETUP NEIGHBOR CONNECTION", 98 "SEND INIT AND KEEPALIVE", 99 "SEND KEEPALIVE", 100 "CLOSE SESSION" 101 }; 102 103 struct nbr_id_head nbrs_by_id = RB_INITIALIZER(&nbrs_by_id); 104 struct nbr_addr_head nbrs_by_addr = RB_INITIALIZER(&nbrs_by_addr); 105 struct nbr_pid_head nbrs_by_pid = RB_INITIALIZER(&nbrs_by_pid); 106 107 static __inline int 108 nbr_id_compare(struct nbr *a, struct nbr *b) 109 { 110 return (ntohl(a->id.s_addr) - ntohl(b->id.s_addr)); 111 } 112 113 static __inline int 114 nbr_addr_compare(struct nbr *a, struct nbr *b) 115 { 116 if (a->af < b->af) 117 return (-1); 118 if (a->af > b->af) 119 return (1); 120 121 return (ldp_addrcmp(a->af, &a->raddr, &b->raddr)); 122 } 123 124 static __inline int 125 nbr_pid_compare(struct nbr *a, struct nbr *b) 126 { 127 return (a->peerid - b->peerid); 128 } 129 130 int 131 nbr_fsm(struct nbr *nbr, enum nbr_event event) 132 { 133 struct timeval now; 134 int old_state; 135 int new_state = 0; 136 int i; 137 138 old_state = nbr->state; 139 for (i = 0; nbr_fsm_tbl[i].state != -1; i++) 140 if ((nbr_fsm_tbl[i].state & old_state) && 141 (nbr_fsm_tbl[i].event == event)) { 142 new_state = nbr_fsm_tbl[i].new_state; 143 break; 144 } 145 146 if (nbr_fsm_tbl[i].state == -1) { 147 /* event outside of the defined fsm, ignore it. */ 148 log_warnx("%s: lsr-id %s, event %s not expected in " 149 "state %s", __func__, inet_ntoa(nbr->id), 150 nbr_event_names[event], nbr_state_name(old_state)); 151 return (0); 152 } 153 154 if (new_state != 0) 155 nbr->state = new_state; 156 157 if (old_state != nbr->state) { 158 log_debug("%s: event %s resulted in action %s and " 159 "changing state for lsr-id %s from %s to %s", 160 __func__, nbr_event_names[event], 161 nbr_action_names[nbr_fsm_tbl[i].action], 162 inet_ntoa(nbr->id), nbr_state_name(old_state), 163 nbr_state_name(nbr->state)); 164 165 if (nbr->state == NBR_STA_OPER) { 166 gettimeofday(&now, NULL); 167 nbr->uptime = now.tv_sec; 168 } 169 } 170 171 if (nbr->state == NBR_STA_OPER || nbr->state == NBR_STA_PRESENT) 172 nbr_stop_itimeout(nbr); 173 else 174 nbr_start_itimeout(nbr); 175 176 switch (nbr_fsm_tbl[i].action) { 177 case NBR_ACT_RST_KTIMEOUT: 178 nbr_start_ktimeout(nbr); 179 break; 180 case NBR_ACT_RST_KTIMER: 181 nbr_start_ktimer(nbr); 182 break; 183 case NBR_ACT_SESSION_EST: 184 nbr_act_session_operational(nbr); 185 nbr_start_ktimer(nbr); 186 nbr_start_ktimeout(nbr); 187 if (nbr->v4_enabled) 188 send_address_all(nbr, AF_INET); 189 if (nbr->v6_enabled) 190 send_address_all(nbr, AF_INET6); 191 nbr_send_labelmappings(nbr); 192 break; 193 case NBR_ACT_CONNECT_SETUP: 194 nbr->tcp = tcp_new(nbr->fd, nbr); 195 196 /* trigger next state */ 197 send_init(nbr); 198 nbr_fsm(nbr, NBR_EVT_INIT_SENT); 199 break; 200 case NBR_ACT_PASSIVE_INIT: 201 send_init(nbr); 202 send_keepalive(nbr); 203 break; 204 case NBR_ACT_KEEPALIVE_SEND: 205 nbr_start_ktimeout(nbr); 206 send_keepalive(nbr); 207 break; 208 case NBR_ACT_CLOSE_SESSION: 209 ldpe_imsg_compose_lde(IMSG_NEIGHBOR_DOWN, nbr->peerid, 0, 210 NULL, 0); 211 session_close(nbr); 212 break; 213 case NBR_ACT_NOTHING: 214 /* do nothing */ 215 break; 216 } 217 218 return (0); 219 } 220 221 struct nbr * 222 nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr, 223 uint32_t scope_id) 224 { 225 struct nbr *nbr; 226 struct adj *adj; 227 struct pending_conn *pconn; 228 229 log_debug("%s: lsr-id %s transport-address %s", __func__, 230 inet_ntoa(id), log_addr(af, addr)); 231 232 if ((nbr = calloc(1, sizeof(*nbr))) == NULL) 233 fatal(__func__); 234 235 LIST_INIT(&nbr->adj_list); 236 nbr->state = NBR_STA_PRESENT; 237 nbr->peerid = 0; 238 nbr->af = af; 239 nbr->ds_tlv = ds_tlv; 240 if (af == AF_INET || ds_tlv) 241 nbr->v4_enabled = 1; 242 if (af == AF_INET6 || ds_tlv) 243 nbr->v6_enabled = 1; 244 nbr->id = id; 245 nbr->laddr = (ldp_af_conf_get(leconf, af))->trans_addr; 246 nbr->raddr = *addr; 247 nbr->raddr_scope = scope_id; 248 nbr->conf_seqnum = 0; 249 250 LIST_FOREACH(adj, &global.adj_list, global_entry) { 251 if (adj->lsr_id.s_addr == nbr->id.s_addr) { 252 adj->nbr = nbr; 253 LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry); 254 } 255 } 256 257 if (RB_INSERT(nbr_id_head, &nbrs_by_id, nbr) != NULL) 258 fatalx("nbr_new: RB_INSERT(nbrs_by_id) failed"); 259 if (RB_INSERT(nbr_addr_head, &nbrs_by_addr, nbr) != NULL) 260 fatalx("nbr_new: RB_INSERT(nbrs_by_addr) failed"); 261 262 TAILQ_INIT(&nbr->mapping_list); 263 TAILQ_INIT(&nbr->withdraw_list); 264 TAILQ_INIT(&nbr->request_list); 265 TAILQ_INIT(&nbr->release_list); 266 TAILQ_INIT(&nbr->abortreq_list); 267 268 /* set event structures */ 269 evtimer_set(&nbr->keepalive_timeout, nbr_ktimeout, nbr); 270 evtimer_set(&nbr->keepalive_timer, nbr_ktimer, nbr); 271 evtimer_set(&nbr->init_timeout, nbr_itimeout, nbr); 272 evtimer_set(&nbr->initdelay_timer, nbr_idtimer, nbr); 273 274 if (pfkey_establish(leconf, nbr) == -1) 275 fatalx("pfkey setup failed"); 276 277 pconn = pending_conn_find(nbr->af, &nbr->raddr); 278 if (pconn) { 279 session_accept_nbr(nbr, pconn->fd); 280 pending_conn_del(pconn); 281 } 282 283 return (nbr); 284 } 285 286 void 287 nbr_del(struct nbr *nbr) 288 { 289 log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); 290 291 nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION); 292 pfkey_remove(nbr); 293 294 if (nbr_pending_connect(nbr)) 295 event_del(&nbr->ev_connect); 296 nbr_stop_ktimer(nbr); 297 nbr_stop_ktimeout(nbr); 298 nbr_stop_itimeout(nbr); 299 nbr_stop_idtimer(nbr); 300 301 mapping_list_clr(&nbr->mapping_list); 302 mapping_list_clr(&nbr->withdraw_list); 303 mapping_list_clr(&nbr->request_list); 304 mapping_list_clr(&nbr->release_list); 305 mapping_list_clr(&nbr->abortreq_list); 306 307 if (nbr->peerid) 308 RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr); 309 RB_REMOVE(nbr_id_head, &nbrs_by_id, nbr); 310 RB_REMOVE(nbr_addr_head, &nbrs_by_addr, nbr); 311 312 free(nbr); 313 } 314 315 static void 316 nbr_update_peerid(struct nbr *nbr) 317 { 318 static uint32_t peercnt = 1; 319 320 if (nbr->peerid) 321 RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr); 322 323 /* get next unused peerid */ 324 while (nbr_find_peerid(++peercnt)) 325 ; 326 nbr->peerid = peercnt; 327 328 if (RB_INSERT(nbr_pid_head, &nbrs_by_pid, nbr) != NULL) 329 fatalx("nbr_update_peerid: RB_INSERT(nbrs_by_pid) failed"); 330 } 331 332 struct nbr * 333 nbr_find_ldpid(uint32_t lsr_id) 334 { 335 struct nbr n; 336 n.id.s_addr = lsr_id; 337 return (RB_FIND(nbr_id_head, &nbrs_by_id, &n)); 338 } 339 340 struct nbr * 341 nbr_find_addr(int af, union ldpd_addr *addr) 342 { 343 struct nbr n; 344 n.af = af; 345 n.raddr = *addr; 346 return (RB_FIND(nbr_addr_head, &nbrs_by_addr, &n)); 347 } 348 349 struct nbr * 350 nbr_find_peerid(uint32_t peerid) 351 { 352 struct nbr n; 353 n.peerid = peerid; 354 return (RB_FIND(nbr_pid_head, &nbrs_by_pid, &n)); 355 } 356 357 int 358 nbr_adj_count(struct nbr *nbr, int af) 359 { 360 struct adj *adj; 361 int total = 0; 362 363 LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) 364 if (adj_get_af(adj) == af) 365 total++; 366 367 return (total); 368 } 369 370 int 371 nbr_session_active_role(struct nbr *nbr) 372 { 373 if (ldp_addrcmp(nbr->af, &nbr->laddr, &nbr->raddr) > 0) 374 return (1); 375 376 return (0); 377 } 378 379 /* timers */ 380 381 /* Keepalive timer: timer to send keepalive message to neighbors */ 382 383 static void 384 nbr_ktimer(int fd, short event, void *arg) 385 { 386 struct nbr *nbr = arg; 387 388 send_keepalive(nbr); 389 nbr_start_ktimer(nbr); 390 } 391 392 static void 393 nbr_start_ktimer(struct nbr *nbr) 394 { 395 struct timeval tv; 396 397 /* send three keepalives per period */ 398 timerclear(&tv); 399 tv.tv_sec = (time_t)(nbr->keepalive / KEEPALIVE_PER_PERIOD); 400 if (evtimer_add(&nbr->keepalive_timer, &tv) == -1) 401 fatal(__func__); 402 } 403 404 void 405 nbr_stop_ktimer(struct nbr *nbr) 406 { 407 if (evtimer_pending(&nbr->keepalive_timer, NULL) && 408 evtimer_del(&nbr->keepalive_timer) == -1) 409 fatal(__func__); 410 } 411 412 /* Keepalive timeout: if the nbr hasn't sent keepalive */ 413 414 static void 415 nbr_ktimeout(int fd, short event, void *arg) 416 { 417 struct nbr *nbr = arg; 418 419 log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); 420 421 session_shutdown(nbr, S_KEEPALIVE_TMR, 0, 0); 422 } 423 424 static void 425 nbr_start_ktimeout(struct nbr *nbr) 426 { 427 struct timeval tv; 428 429 timerclear(&tv); 430 tv.tv_sec = nbr->keepalive; 431 432 if (evtimer_add(&nbr->keepalive_timeout, &tv) == -1) 433 fatal(__func__); 434 } 435 436 void 437 nbr_stop_ktimeout(struct nbr *nbr) 438 { 439 if (evtimer_pending(&nbr->keepalive_timeout, NULL) && 440 evtimer_del(&nbr->keepalive_timeout) == -1) 441 fatal(__func__); 442 } 443 444 /* Session initialization timeout: if nbr got stuck in the initialization FSM */ 445 446 static void 447 nbr_itimeout(int fd, short event, void *arg) 448 { 449 struct nbr *nbr = arg; 450 451 log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); 452 453 nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION); 454 } 455 456 static void 457 nbr_start_itimeout(struct nbr *nbr) 458 { 459 struct timeval tv; 460 461 timerclear(&tv); 462 tv.tv_sec = INIT_FSM_TIMEOUT; 463 if (evtimer_add(&nbr->init_timeout, &tv) == -1) 464 fatal(__func__); 465 } 466 467 void 468 nbr_stop_itimeout(struct nbr *nbr) 469 { 470 if (evtimer_pending(&nbr->init_timeout, NULL) && 471 evtimer_del(&nbr->init_timeout) == -1) 472 fatal(__func__); 473 } 474 475 /* Init delay timer: timer to retry to iniziatize session */ 476 477 static void 478 nbr_idtimer(int fd, short event, void *arg) 479 { 480 struct nbr *nbr = arg; 481 482 log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id)); 483 484 nbr_establish_connection(nbr); 485 } 486 487 void 488 nbr_start_idtimer(struct nbr *nbr) 489 { 490 struct timeval tv; 491 492 timerclear(&tv); 493 494 tv.tv_sec = INIT_DELAY_TMR; 495 switch(nbr->idtimer_cnt) { 496 default: 497 /* do not further increase the counter */ 498 tv.tv_sec = MAX_DELAY_TMR; 499 break; 500 case 2: 501 tv.tv_sec *= 2; 502 /* FALLTHROUGH */ 503 case 1: 504 tv.tv_sec *= 2; 505 /* FALLTHROUGH */ 506 case 0: 507 nbr->idtimer_cnt++; 508 break; 509 } 510 511 if (evtimer_add(&nbr->initdelay_timer, &tv) == -1) 512 fatal(__func__); 513 } 514 515 void 516 nbr_stop_idtimer(struct nbr *nbr) 517 { 518 if (evtimer_pending(&nbr->initdelay_timer, NULL) && 519 evtimer_del(&nbr->initdelay_timer) == -1) 520 fatal(__func__); 521 } 522 523 int 524 nbr_pending_idtimer(struct nbr *nbr) 525 { 526 if (evtimer_pending(&nbr->initdelay_timer, NULL)) 527 return (1); 528 529 return (0); 530 } 531 532 int 533 nbr_pending_connect(struct nbr *nbr) 534 { 535 if (event_initialized(&nbr->ev_connect) && 536 event_pending(&nbr->ev_connect, EV_WRITE, NULL)) 537 return (1); 538 539 return (0); 540 } 541 542 static void 543 nbr_connect_cb(int fd, short event, void *arg) 544 { 545 struct nbr *nbr = arg; 546 int error; 547 socklen_t len; 548 549 len = sizeof(error); 550 if (getsockopt(nbr->fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) { 551 log_warn("%s: getsockopt SOL_SOCKET SO_ERROR", __func__); 552 return; 553 } 554 555 if (error) { 556 close(nbr->fd); 557 errno = error; 558 log_debug("%s: error while connecting to %s: %s", __func__, 559 log_addr(nbr->af, &nbr->raddr), strerror(errno)); 560 return; 561 } 562 563 nbr_fsm(nbr, NBR_EVT_CONNECT_UP); 564 } 565 566 int 567 nbr_establish_connection(struct nbr *nbr) 568 { 569 struct sockaddr_storage local_sa; 570 struct sockaddr_storage remote_sa; 571 struct adj *adj; 572 struct nbr_params *nbrp; 573 int opt = 1; 574 575 nbr->fd = socket(nbr->af, 576 SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); 577 if (nbr->fd == -1) { 578 log_warn("%s: error while creating socket", __func__); 579 return (-1); 580 } 581 582 if (nbr->auth_established) { 583 if (sysdep.no_pfkey || sysdep.no_md5sig) { 584 log_warnx("md5sig configured but not available"); 585 close(nbr->fd); 586 return (-1); 587 } 588 if (setsockopt(nbr->fd, IPPROTO_TCP, TCP_MD5SIG, 589 &opt, sizeof(opt)) == -1) { 590 log_warn("setsockopt md5sig"); 591 close(nbr->fd); 592 return (-1); 593 } 594 } 595 596 memcpy(&local_sa, addr2sa(nbr->af, &nbr->laddr, 0), sizeof(local_sa)); 597 memcpy(&remote_sa, addr2sa(nbr->af, &nbr->raddr, LDP_PORT), 598 sizeof(local_sa)); 599 if (nbr->af == AF_INET6 && nbr->raddr_scope) 600 addscope((struct sockaddr_in6 *)&remote_sa, nbr->raddr_scope); 601 602 if (bind(nbr->fd, (struct sockaddr *)&local_sa, 603 local_sa.ss_len) == -1) { 604 log_warn("%s: error while binding socket to %s", __func__, 605 log_sockaddr((struct sockaddr *)&local_sa)); 606 close(nbr->fd); 607 return (-1); 608 } 609 610 nbrp = nbr_params_find(leconf, nbr->id); 611 if (nbr_gtsm_check(nbr->fd, nbr, nbrp)) { 612 close(nbr->fd); 613 return (-1); 614 } 615 616 /* 617 * Send an extra hello to guarantee that the remote peer has formed 618 * an adjacency as well. 619 */ 620 LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) 621 send_hello(adj->source.type, adj->source.link.ia, 622 adj->source.target); 623 624 if (connect(nbr->fd, (struct sockaddr *)&remote_sa, 625 remote_sa.ss_len) == -1) { 626 if (errno == EINPROGRESS) { 627 event_set(&nbr->ev_connect, nbr->fd, EV_WRITE, 628 nbr_connect_cb, nbr); 629 event_add(&nbr->ev_connect, NULL); 630 return (0); 631 } 632 log_warn("%s: error while connecting to %s", __func__, 633 log_sockaddr((struct sockaddr *)&remote_sa)); 634 close(nbr->fd); 635 return (-1); 636 } 637 638 /* connection completed immediately */ 639 nbr_fsm(nbr, NBR_EVT_CONNECT_UP); 640 641 return (0); 642 } 643 644 int 645 nbr_gtsm_enabled(struct nbr *nbr, struct nbr_params *nbrp) 646 { 647 /* 648 * RFC 6720 - Section 3: 649 * "This document allows for the implementation to provide an option to 650 * statically (e.g., via configuration) and/or dynamically override the 651 * default behavior and enable/disable GTSM on a per-peer basis". 652 */ 653 if (nbrp && (nbrp->flags & F_NBRP_GTSM)) 654 return (nbrp->gtsm_enabled); 655 656 if ((ldp_af_conf_get(leconf, nbr->af))->flags & F_LDPD_AF_NO_GTSM) 657 return (0); 658 659 /* By default, GTSM support has to be negotiated for LDPv4 */ 660 if (nbr->af == AF_INET && !(nbr->flags & F_NBR_GTSM_NEGOTIATED)) 661 return (0); 662 663 return (1); 664 } 665 666 int 667 nbr_gtsm_setup(int fd, int af, struct nbr_params *nbrp) 668 { 669 int ttl = 255; 670 671 if (nbrp && (nbrp->flags & F_NBRP_GTSM_HOPS)) 672 ttl = 256 - nbrp->gtsm_hops; 673 674 switch (af) { 675 case AF_INET: 676 if (sock_set_ipv4_minttl(fd, ttl) == -1) 677 return (-1); 678 ttl = 255; 679 if (sock_set_ipv4_ucast_ttl(fd, ttl) == -1) 680 return (-1); 681 break; 682 case AF_INET6: 683 if (sock_set_ipv6_minhopcount(fd, ttl) == -1) 684 return (-1); 685 ttl = 255; 686 if (sock_set_ipv6_ucast_hops(fd, ttl) == -1) 687 return (-1); 688 break; 689 default: 690 fatalx("nbr_gtsm_setup: unknown af"); 691 } 692 693 return (0); 694 } 695 696 int 697 nbr_gtsm_check(int fd, struct nbr *nbr, struct nbr_params *nbrp) 698 { 699 if (!nbr_gtsm_enabled(nbr, nbrp)) { 700 switch (nbr->af) { 701 case AF_INET: 702 sock_set_ipv4_ucast_ttl(fd, -1); 703 break; 704 case AF_INET6: 705 /* 706 * Send packets with a Hop Limit of 255 even when GSTM 707 * is disabled to guarantee interoperability. 708 */ 709 sock_set_ipv6_ucast_hops(fd, 255); 710 break; 711 default: 712 fatalx("nbr_gtsm_check: unknown af"); 713 break; 714 } 715 return (0); 716 } 717 718 if (nbr_gtsm_setup(fd, nbr->af, nbrp) == -1) { 719 log_warnx("%s: error enabling GTSM for lsr-id %s", __func__, 720 inet_ntoa(nbr->id)); 721 return (-1); 722 } 723 724 return (0); 725 } 726 727 static int 728 nbr_act_session_operational(struct nbr *nbr) 729 { 730 struct lde_nbr lde_nbr; 731 732 nbr->idtimer_cnt = 0; 733 734 /* this is necessary to avoid ipc synchronization issues */ 735 nbr_update_peerid(nbr); 736 737 memset(&lde_nbr, 0, sizeof(lde_nbr)); 738 lde_nbr.id = nbr->id; 739 lde_nbr.v4_enabled = nbr->v4_enabled; 740 lde_nbr.v6_enabled = nbr->v6_enabled; 741 lde_nbr.flags = nbr->flags; 742 return (ldpe_imsg_compose_lde(IMSG_NEIGHBOR_UP, nbr->peerid, 0, 743 &lde_nbr, sizeof(lde_nbr))); 744 } 745 746 static void 747 nbr_send_labelmappings(struct nbr *nbr) 748 { 749 ldpe_imsg_compose_lde(IMSG_LABEL_MAPPING_FULL, nbr->peerid, 0, 750 NULL, 0); 751 } 752 753 struct nbr_params * 754 nbr_params_new(struct in_addr lsr_id) 755 { 756 struct nbr_params *nbrp; 757 758 if ((nbrp = calloc(1, sizeof(*nbrp))) == NULL) 759 fatal(__func__); 760 761 nbrp->lsr_id = lsr_id; 762 763 return (nbrp); 764 } 765 766 struct nbr_params * 767 nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id) 768 { 769 struct nbr_params *nbrp; 770 771 LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) 772 if (nbrp->lsr_id.s_addr == lsr_id.s_addr) 773 return (nbrp); 774 775 return (NULL); 776 } 777 778 uint16_t 779 nbr_get_keepalive(int af, struct in_addr lsr_id) 780 { 781 struct nbr_params *nbrp; 782 783 nbrp = nbr_params_find(leconf, lsr_id); 784 if (nbrp && (nbrp->flags & F_NBRP_KEEPALIVE)) 785 return (nbrp->keepalive); 786 787 return ((ldp_af_conf_get(leconf, af))->keepalive); 788 } 789 790 struct ctl_nbr * 791 nbr_to_ctl(struct nbr *nbr) 792 { 793 static struct ctl_nbr nctl; 794 struct timeval now; 795 796 nctl.af = nbr->af; 797 nctl.id = nbr->id; 798 nctl.laddr = nbr->laddr; 799 nctl.raddr = nbr->raddr; 800 nctl.nbr_state = nbr->state; 801 802 gettimeofday(&now, NULL); 803 if (nbr->state == NBR_STA_OPER) { 804 nctl.uptime = now.tv_sec - nbr->uptime; 805 } else 806 nctl.uptime = 0; 807 808 return (&nctl); 809 } 810 811 void 812 nbr_clear_ctl(struct ctl_nbr *nctl) 813 { 814 struct nbr *nbr; 815 816 RB_FOREACH(nbr, nbr_addr_head, &nbrs_by_addr) { 817 if (ldp_addrisset(nctl->af, &nctl->raddr) && 818 ldp_addrcmp(nctl->af, &nctl->raddr, &nbr->raddr)) 819 continue; 820 821 log_debug("%s: neighbor %s manually cleared", __func__, 822 log_addr(nbr->af, &nbr->raddr)); 823 session_shutdown(nbr, S_SHUTDOWN, 0, 0); 824 } 825 } 826