1 /* $OpenBSD: lsupdate.c,v 1.18 2020/07/15 14:47:41 denis Exp $ */ 2 3 /* 4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org> 5 * Copyright (c) 2004, 2005, 2007 Esben Norby <norby@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/types.h> 21 #include <sys/socket.h> 22 #include <netinet/in.h> 23 #include <netinet/ip6.h> 24 #include <netinet/ip_ah.h> 25 #include <arpa/inet.h> 26 27 #include <stdlib.h> 28 #include <string.h> 29 #include <siphash.h> 30 31 #include "ospf6.h" 32 #include "ospf6d.h" 33 #include "log.h" 34 #include "ospfe.h" 35 #include "rde.h" 36 37 extern struct imsgev *iev_rde; 38 39 struct ibuf *prepare_ls_update(struct iface *, int); 40 int add_ls_update(struct ibuf *, struct iface *, void *, u_int16_t, 41 u_int16_t); 42 int send_ls_update(struct ibuf *, struct iface *, struct in6_addr, 43 u_int32_t); 44 45 void ls_retrans_list_insert(struct nbr *, struct lsa_entry *); 46 void ls_retrans_list_remove(struct nbr *, struct lsa_entry *); 47 48 /* link state update packet handling */ 49 int 50 lsa_flood(struct iface *iface, struct nbr *originator, struct lsa_hdr *lsa_hdr, 51 void *data) 52 { 53 struct nbr *nbr; 54 struct lsa_entry *le = NULL; 55 int queued = 0, dont_ack = 0; 56 int r; 57 58 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 59 if (nbr == iface->self) 60 continue; 61 if (!(nbr->state & NBR_STA_FLOOD)) 62 continue; 63 64 if (iface->state & IF_STA_DROTHER && !queued) 65 while ((le = ls_retrans_list_get(iface->self, lsa_hdr))) 66 ls_retrans_list_free(iface->self, le); 67 68 while ((le = ls_retrans_list_get(nbr, lsa_hdr))) 69 ls_retrans_list_free(nbr, le); 70 71 if (!(nbr->state & NBR_STA_FULL) && 72 (le = ls_req_list_get(nbr, lsa_hdr)) != NULL) { 73 r = lsa_newer(lsa_hdr, le->le_lsa); 74 if (r > 0) { 75 /* to flood LSA is newer than requested */ 76 ls_req_list_free(nbr, le); 77 /* new needs to be flooded */ 78 } else if (r < 0) { 79 /* to flood LSA is older than requested */ 80 continue; 81 } else { 82 /* LSA are equal */ 83 ls_req_list_free(nbr, le); 84 continue; 85 } 86 } 87 88 if (nbr == originator) { 89 dont_ack++; 90 continue; 91 } 92 93 /* non DR or BDR router keep all lsa in one retrans list */ 94 if (iface->state & IF_STA_DROTHER) { 95 if (!queued) 96 ls_retrans_list_add(iface->self, data, 97 iface->rxmt_interval, 0); 98 queued = 1; 99 } else { 100 ls_retrans_list_add(nbr, data, iface->rxmt_interval, 0); 101 queued = 1; 102 } 103 } 104 105 if (!queued) 106 return (0); 107 108 if (iface == originator->iface && iface->self != originator) { 109 if (iface->dr == originator || iface->bdr == originator) 110 return (0); 111 if (iface->state & IF_STA_BACKUP) 112 return (0); 113 dont_ack++; 114 } 115 116 /* 117 * initial flood needs to be queued separately, timeout is zero 118 * and oneshot has to be set because the retransimssion queues 119 * are already loaded. 120 */ 121 switch (iface->type) { 122 case IF_TYPE_POINTOPOINT: 123 case IF_TYPE_BROADCAST: 124 ls_retrans_list_add(iface->self, data, 0, 1); 125 break; 126 case IF_TYPE_NBMA: 127 case IF_TYPE_POINTOMULTIPOINT: 128 case IF_TYPE_VIRTUALLINK: 129 LIST_FOREACH(nbr, &iface->nbr_list, entry) { 130 if (nbr == iface->self) 131 continue; 132 if (!(nbr->state & NBR_STA_FLOOD)) 133 continue; 134 if (!TAILQ_EMPTY(&nbr->ls_retrans_list)) { 135 le = TAILQ_LAST(&nbr->ls_retrans_list, 136 lsa_head); 137 if (lsa_hdr->type != le->le_lsa->type || 138 lsa_hdr->ls_id != le->le_lsa->ls_id || 139 lsa_hdr->adv_rtr != le->le_lsa->adv_rtr) 140 continue; 141 } 142 ls_retrans_list_add(nbr, data, 0, 1); 143 } 144 break; 145 default: 146 fatalx("lsa_flood: unknown interface type"); 147 } 148 149 return (dont_ack == 2); 150 } 151 152 struct ibuf * 153 prepare_ls_update(struct iface *iface, int bigpkt) 154 { 155 struct ibuf *buf; 156 size_t size; 157 158 size = bigpkt ? IPV6_MAXPACKET : iface->mtu; 159 if (size < IPV6_MMTU) 160 size = IPV6_MMTU; 161 size -= sizeof(struct ip6_hdr); 162 163 /* 164 * Reserve space for optional ah or esp encryption. The 165 * algorithm is taken from ah_output and esp_output, the 166 * values are the maxima of crypto/xform.c. 167 */ 168 size -= max( 169 /* base-ah-header replay authsize */ 170 AH_FLENGTH + sizeof(u_int32_t) + 32, 171 /* spi sequence ivlen blocksize pad-length next-header authsize */ 172 2 * sizeof(u_int32_t) + 16 + 16 + 2 * sizeof(u_int8_t) + 32); 173 174 if ((buf = ibuf_open(size)) == NULL) 175 fatal("prepare_ls_update"); 176 177 /* OSPF header */ 178 if (gen_ospf_hdr(buf, iface, PACKET_TYPE_LS_UPDATE)) 179 goto fail; 180 181 /* reserve space for number of lsa field */ 182 if (ibuf_reserve(buf, sizeof(u_int32_t)) == NULL) 183 goto fail; 184 185 return (buf); 186 fail: 187 log_warn("prepare_ls_update"); 188 ibuf_free(buf); 189 return (NULL); 190 } 191 192 int 193 add_ls_update(struct ibuf *buf, struct iface *iface, void *data, u_int16_t len, 194 u_int16_t older) 195 { 196 size_t ageoff; 197 u_int16_t age; 198 199 if (buf->wpos + len >= buf->max) 200 return (0); 201 202 ageoff = ibuf_size(buf); 203 if (ibuf_add(buf, data, len)) { 204 log_warn("add_ls_update"); 205 return (0); 206 } 207 208 /* age LSA before sending it out */ 209 memcpy(&age, data, sizeof(age)); 210 age = ntohs(age); 211 if ((age += older + iface->transmit_delay) >= MAX_AGE) 212 age = MAX_AGE; 213 age = htons(age); 214 memcpy(ibuf_seek(buf, ageoff, sizeof(age)), &age, sizeof(age)); 215 216 return (1); 217 } 218 219 int 220 send_ls_update(struct ibuf *buf, struct iface *iface, struct in6_addr addr, 221 u_int32_t nlsa) 222 { 223 nlsa = htonl(nlsa); 224 memcpy(ibuf_seek(buf, sizeof(struct ospf_hdr), sizeof(nlsa)), 225 &nlsa, sizeof(nlsa)); 226 /* calculate checksum */ 227 if (upd_ospf_hdr(buf, iface)) 228 goto fail; 229 230 if (send_packet(iface, buf, &addr) == -1) 231 goto fail; 232 233 ibuf_free(buf); 234 return (0); 235 fail: 236 log_warn("send_ls_update"); 237 ibuf_free(buf); 238 return (-1); 239 } 240 241 void 242 recv_ls_update(struct nbr *nbr, char *buf, u_int16_t len) 243 { 244 struct lsa_hdr lsa; 245 u_int32_t nlsa; 246 247 if (len < sizeof(nlsa)) { 248 log_warnx("recv_ls_update: bad packet size, neighbor ID %s", 249 inet_ntoa(nbr->id)); 250 return; 251 } 252 memcpy(&nlsa, buf, sizeof(nlsa)); 253 nlsa = ntohl(nlsa); 254 buf += sizeof(nlsa); 255 len -= sizeof(nlsa); 256 257 switch (nbr->state) { 258 case NBR_STA_DOWN: 259 case NBR_STA_ATTEMPT: 260 case NBR_STA_INIT: 261 case NBR_STA_2_WAY: 262 case NBR_STA_XSTRT: 263 case NBR_STA_SNAP: 264 log_debug("recv_ls_update: packet ignored in state %s, " 265 "neighbor ID %s", nbr_state_name(nbr->state), 266 inet_ntoa(nbr->id)); 267 break; 268 case NBR_STA_XCHNG: 269 case NBR_STA_LOAD: 270 case NBR_STA_FULL: 271 for (; nlsa > 0 && len > 0; nlsa--) { 272 if (len < sizeof(lsa)) { 273 log_warnx("recv_ls_update: bad packet size, " 274 "neighbor ID %s", inet_ntoa(nbr->id)); 275 return; 276 } 277 memcpy(&lsa, buf, sizeof(lsa)); 278 if (len < ntohs(lsa.len)) { 279 log_warnx("recv_ls_update: bad packet size, " 280 "neighbor ID %s", inet_ntoa(nbr->id)); 281 return; 282 } 283 imsg_compose_event(iev_rde, IMSG_LS_UPD, nbr->peerid, 0, 284 -1, buf, ntohs(lsa.len)); 285 buf += ntohs(lsa.len); 286 len -= ntohs(lsa.len); 287 } 288 if (nlsa > 0 || len > 0) { 289 log_warnx("recv_ls_update: bad packet size, " 290 "neighbor ID %s", inet_ntoa(nbr->id)); 291 return; 292 } 293 break; 294 default: 295 fatalx("recv_ls_update: unknown neighbor state"); 296 } 297 } 298 299 /* link state retransmit list */ 300 void 301 ls_retrans_list_add(struct nbr *nbr, struct lsa_hdr *lsa, 302 unsigned short timeout, unsigned short oneshot) 303 { 304 struct timeval tv; 305 struct lsa_entry *le; 306 struct lsa_ref *ref; 307 308 if ((ref = lsa_cache_get(lsa)) == NULL) 309 fatalx("King Bula sez: somebody forgot to lsa_cache_add"); 310 311 if ((le = calloc(1, sizeof(*le))) == NULL) 312 fatal("ls_retrans_list_add"); 313 314 le->le_ref = ref; 315 le->le_when = timeout; 316 le->le_oneshot = oneshot; 317 318 ls_retrans_list_insert(nbr, le); 319 320 if (!evtimer_pending(&nbr->ls_retrans_timer, NULL)) { 321 timerclear(&tv); 322 tv.tv_sec = TAILQ_FIRST(&nbr->ls_retrans_list)->le_when; 323 324 if (evtimer_add(&nbr->ls_retrans_timer, &tv) == -1) 325 fatal("ls_retrans_list_add"); 326 } 327 } 328 329 int 330 ls_retrans_list_del(struct nbr *nbr, struct lsa_hdr *lsa_hdr) 331 { 332 struct lsa_entry *le; 333 334 if ((le = ls_retrans_list_get(nbr, lsa_hdr)) == NULL) 335 return (-1); 336 /* 337 * Compare LSA with the Ack by comparing not only the seq_num and 338 * checksum but also the age field. Since we only care about MAX_AGE 339 * vs. non-MAX_AGE LSA, a simple >= comparison is good enough. This 340 * ensures that a LSA withdrawal is not acked by a previous update. 341 */ 342 if (lsa_hdr->seq_num == le->le_ref->hdr.seq_num && 343 lsa_hdr->ls_chksum == le->le_ref->hdr.ls_chksum && 344 ntohs(lsa_hdr->age) >= ntohs(le->le_ref->hdr.age)) { 345 ls_retrans_list_free(nbr, le); 346 return (0); 347 } 348 349 return (-1); 350 } 351 352 struct lsa_entry * 353 ls_retrans_list_get(struct nbr *nbr, struct lsa_hdr *lsa_hdr) 354 { 355 struct lsa_entry *le; 356 357 TAILQ_FOREACH(le, &nbr->ls_retrans_list, entry) { 358 if ((lsa_hdr->type == le->le_ref->hdr.type) && 359 (lsa_hdr->ls_id == le->le_ref->hdr.ls_id) && 360 (lsa_hdr->adv_rtr == le->le_ref->hdr.adv_rtr)) 361 return (le); 362 } 363 return (NULL); 364 } 365 366 void 367 ls_retrans_list_insert(struct nbr *nbr, struct lsa_entry *new) 368 { 369 struct lsa_entry *le; 370 unsigned short when = new->le_when; 371 372 TAILQ_FOREACH(le, &nbr->ls_retrans_list, entry) { 373 if (when < le->le_when) { 374 new->le_when = when; 375 TAILQ_INSERT_BEFORE(le, new, entry); 376 nbr->ls_ret_cnt++; 377 return; 378 } 379 when -= le->le_when; 380 } 381 new->le_when = when; 382 TAILQ_INSERT_TAIL(&nbr->ls_retrans_list, new, entry); 383 nbr->ls_ret_cnt++; 384 } 385 386 void 387 ls_retrans_list_remove(struct nbr *nbr, struct lsa_entry *le) 388 { 389 struct timeval tv; 390 struct lsa_entry *next = TAILQ_NEXT(le, entry); 391 int reset = 0; 392 393 /* adjust timeout of next entry */ 394 if (next) 395 next->le_when += le->le_when; 396 397 if (TAILQ_FIRST(&nbr->ls_retrans_list) == le && 398 evtimer_pending(&nbr->ls_retrans_timer, NULL)) 399 reset = 1; 400 401 TAILQ_REMOVE(&nbr->ls_retrans_list, le, entry); 402 nbr->ls_ret_cnt--; 403 404 if (reset && TAILQ_FIRST(&nbr->ls_retrans_list)) { 405 if (evtimer_del(&nbr->ls_retrans_timer) == -1) 406 fatal("ls_retrans_list_remove"); 407 408 timerclear(&tv); 409 tv.tv_sec = TAILQ_FIRST(&nbr->ls_retrans_list)->le_when; 410 411 if (evtimer_add(&nbr->ls_retrans_timer, &tv) == -1) 412 fatal("ls_retrans_list_remove"); 413 } 414 } 415 416 void 417 ls_retrans_list_free(struct nbr *nbr, struct lsa_entry *le) 418 { 419 ls_retrans_list_remove(nbr, le); 420 421 lsa_cache_put(le->le_ref, nbr); 422 free(le); 423 } 424 425 void 426 ls_retrans_list_clr(struct nbr *nbr) 427 { 428 struct lsa_entry *le; 429 430 while ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL) 431 ls_retrans_list_free(nbr, le); 432 433 nbr->ls_ret_cnt = 0; 434 } 435 436 /* ARGSUSED */ 437 void 438 ls_retrans_timer(int fd, short event, void *bula) 439 { 440 struct timeval tv; 441 struct timespec tp; 442 struct in6_addr addr; 443 struct nbr *nbr = bula; 444 struct lsa_entry *le; 445 struct ibuf *buf; 446 time_t now; 447 int d, bigpkt; 448 u_int32_t nlsa = 0; 449 450 if ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL) 451 le->le_when = 0; /* timer fired */ 452 else 453 return; /* queue empty, nothing to do */ 454 455 clock_gettime(CLOCK_MONOTONIC, &tp); 456 now = tp.tv_sec; 457 458 if (nbr->iface->self == nbr) { 459 /* 460 * oneshot needs to be set for lsa queued for flooding, 461 * if oneshot is not set then the lsa needs to be converted 462 * because the router switched lately to DR or BDR 463 */ 464 if (le->le_oneshot && nbr->iface->state & IF_STA_DRORBDR) 465 inet_pton(AF_INET6, AllSPFRouters, &addr); 466 else if (nbr->iface->state & IF_STA_DRORBDR) { 467 /* 468 * old retransmission needs to be converted into 469 * flood by rerunning the lsa_flood. 470 */ 471 lsa_flood(nbr->iface, nbr, &le->le_ref->hdr, 472 le->le_ref->data); 473 ls_retrans_list_free(nbr, le); 474 /* ls_retrans_list_free retriggers the timer */ 475 return; 476 } else if (nbr->iface->type == IF_TYPE_POINTOPOINT) 477 memcpy(&addr, &nbr->iface->dst, sizeof(addr)); 478 else 479 inet_pton(AF_INET6, AllDRouters, &addr); 480 } else 481 memcpy(&addr, &nbr->addr, sizeof(addr)); 482 483 bigpkt = le->le_ref->len > 1024; 484 if ((buf = prepare_ls_update(nbr->iface, bigpkt)) == NULL) { 485 le->le_when = 1; 486 goto done; 487 } 488 489 while ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL && 490 le->le_when == 0) { 491 d = now - le->le_ref->stamp; 492 if (d < 0) 493 d = 0; 494 else if (d > MAX_AGE) 495 d = MAX_AGE; 496 497 if (add_ls_update(buf, nbr->iface, le->le_ref->data, 498 le->le_ref->len, d) == 0) { 499 if (nlsa == 0) { 500 /* something bad happened retry later */ 501 log_warnx("ls_retrans_timer: sending LS update " 502 "to neighbor ID %s failed", 503 inet_ntoa(nbr->id)); 504 log_debug("ls_retrans_timer: type: %04x len: %u", 505 ntohs(le->le_ref->hdr.type), 506 le->le_ref->len); 507 TAILQ_REMOVE(&nbr->ls_retrans_list, le, entry); 508 nbr->ls_ret_cnt--; 509 le->le_when = nbr->iface->rxmt_interval; 510 ls_retrans_list_insert(nbr, le); 511 } 512 break; 513 } 514 nlsa++; 515 if (le->le_oneshot) 516 ls_retrans_list_free(nbr, le); 517 else { 518 TAILQ_REMOVE(&nbr->ls_retrans_list, le, entry); 519 nbr->ls_ret_cnt--; 520 le->le_when = nbr->iface->rxmt_interval; 521 ls_retrans_list_insert(nbr, le); 522 } 523 } 524 if (nlsa) 525 send_ls_update(buf, nbr->iface, addr, nlsa); 526 else 527 ibuf_free(buf); 528 529 done: 530 if ((le = TAILQ_FIRST(&nbr->ls_retrans_list)) != NULL) { 531 timerclear(&tv); 532 tv.tv_sec = le->le_when; 533 534 if (evtimer_add(&nbr->ls_retrans_timer, &tv) == -1) 535 fatal("ls_retrans_timer"); 536 } 537 } 538 539 LIST_HEAD(lsa_cache_head, lsa_ref); 540 541 struct lsa_cache { 542 struct lsa_cache_head *hashtbl; 543 u_int32_t hashmask; 544 } lsacache; 545 546 SIPHASH_KEY lsacachekey; 547 548 struct lsa_ref *lsa_cache_look(struct lsa_hdr *); 549 550 void 551 lsa_cache_init(u_int32_t hashsize) 552 { 553 u_int32_t hs, i; 554 555 for (hs = 1; hs < hashsize; hs <<= 1) 556 ; 557 lsacache.hashtbl = calloc(hs, sizeof(struct lsa_cache_head)); 558 if (lsacache.hashtbl == NULL) 559 fatal("lsa_cache_init"); 560 561 for (i = 0; i < hs; i++) 562 LIST_INIT(&lsacache.hashtbl[i]); 563 arc4random_buf(&lsacachekey, sizeof(lsacachekey)); 564 565 lsacache.hashmask = hs - 1; 566 } 567 568 static uint32_t 569 lsa_hash_hdr(const struct lsa_hdr *hdr) 570 { 571 return SipHash24(&lsacachekey, hdr, sizeof(*hdr)); 572 } 573 574 struct lsa_ref * 575 lsa_cache_add(void *data, u_int16_t len) 576 { 577 struct lsa_cache_head *head; 578 struct lsa_ref *ref, *old; 579 struct timespec tp; 580 581 if ((ref = calloc(1, sizeof(*ref))) == NULL) 582 fatal("lsa_cache_add"); 583 memcpy(&ref->hdr, data, sizeof(ref->hdr)); 584 585 if ((old = lsa_cache_look(&ref->hdr))) { 586 free(ref); 587 old->refcnt++; 588 return (old); 589 } 590 591 if ((ref->data = malloc(len)) == NULL) 592 fatal("lsa_cache_add"); 593 memcpy(ref->data, data, len); 594 595 clock_gettime(CLOCK_MONOTONIC, &tp); 596 ref->stamp = tp.tv_sec; 597 ref->len = len; 598 ref->refcnt = 1; 599 600 head = &lsacache.hashtbl[lsa_hash_hdr(&ref->hdr) & lsacache.hashmask]; 601 LIST_INSERT_HEAD(head, ref, entry); 602 return (ref); 603 } 604 605 struct lsa_ref * 606 lsa_cache_get(struct lsa_hdr *lsa_hdr) 607 { 608 struct lsa_ref *ref; 609 610 ref = lsa_cache_look(lsa_hdr); 611 if (ref) 612 ref->refcnt++; 613 614 return (ref); 615 } 616 617 void 618 lsa_cache_put(struct lsa_ref *ref, struct nbr *nbr) 619 { 620 if (--ref->refcnt > 0) 621 return; 622 623 if (ntohs(ref->hdr.age) >= MAX_AGE) 624 ospfe_imsg_compose_rde(IMSG_LS_MAXAGE, nbr->peerid, 0, 625 ref->data, sizeof(struct lsa_hdr)); 626 627 free(ref->data); 628 LIST_REMOVE(ref, entry); 629 free(ref); 630 } 631 632 struct lsa_ref * 633 lsa_cache_look(struct lsa_hdr *lsa_hdr) 634 { 635 struct lsa_cache_head *head; 636 struct lsa_ref *ref; 637 638 head = &lsacache.hashtbl[lsa_hash_hdr(lsa_hdr) & lsacache.hashmask]; 639 640 LIST_FOREACH(ref, head, entry) { 641 if (memcmp(&ref->hdr, lsa_hdr, sizeof(*lsa_hdr)) == 0) 642 /* found match */ 643 return (ref); 644 } 645 646 return (NULL); 647 } 648