1 /* $NetBSD: table.c,v 1.13 2000/03/02 21:01:34 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1983, 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgment: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) 37 static char sccsid[] __attribute__((unused)) = "@(#)tables.c 8.1 (Berkeley) 6/5/93"; 38 #elif defined(__NetBSD__) 39 #include <sys/cdefs.h> 40 __RCSID("$NetBSD: table.c,v 1.13 2000/03/02 21:01:34 christos Exp $"); 41 #endif 42 43 #include "defs.h" 44 45 static struct rt_spare *rts_better(struct rt_entry *); 46 static struct rt_spare rts_empty = {0,0,0,HOPCNT_INFINITY,0,0,0}; 47 48 static void set_need_flash(void); 49 #ifdef _HAVE_SIN_LEN 50 static void masktrim(struct sockaddr_in *ap); 51 #else 52 static void masktrim(struct sockaddr_in_new *ap); 53 #endif 54 55 56 struct radix_node_head *rhead; /* root of the radix tree */ 57 58 int need_flash = 1; /* flash update needed 59 * start =1 to suppress the 1st 60 */ 61 62 struct timeval age_timer; /* next check of old routes */ 63 struct timeval need_kern = { /* need to update kernel table */ 64 EPOCH+MIN_WAITTIME-1 65 }; 66 67 int stopint; 68 69 int total_routes; 70 71 /* zap any old routes through this gateway */ 72 naddr age_bad_gate; 73 74 75 /* It is desirable to "aggregate" routes, to combine differing routes of 76 * the same metric and next hop into a common route with a smaller netmask 77 * or to suppress redundant routes, routes that add no information to 78 * routes with smaller netmasks. 79 * 80 * A route is redundant if and only if any and all routes with smaller 81 * but matching netmasks and nets are the same. Since routes are 82 * kept sorted in the radix tree, redundant routes always come second. 83 * 84 * There are two kinds of aggregations. First, two routes of the same bit 85 * mask and differing only in the least significant bit of the network 86 * number can be combined into a single route with a coarser mask. 87 * 88 * Second, a route can be suppressed in favor of another route with a more 89 * coarse mask provided no incompatible routes with intermediate masks 90 * are present. The second kind of aggregation involves suppressing routes. 91 * A route must not be suppressed if an incompatible route exists with 92 * an intermediate mask, since the suppressed route would be covered 93 * by the intermediate. 94 * 95 * This code relies on the radix tree walk encountering routes 96 * sorted first by address, with the smallest address first. 97 */ 98 99 struct ag_info ag_slots[NUM_AG_SLOTS], *ag_avail, *ag_corsest, *ag_finest; 100 101 /* #define DEBUG_AG */ 102 #ifdef DEBUG_AG 103 #define CHECK_AG() {int acnt = 0; struct ag_info *cag; \ 104 for (cag = ag_avail; cag != 0; cag = cag->ag_fine) \ 105 acnt++; \ 106 for (cag = ag_corsest; cag != 0; cag = cag->ag_fine) \ 107 acnt++; \ 108 if (acnt != NUM_AG_SLOTS) { \ 109 (void)fflush(stderr); \ 110 abort(); \ 111 } \ 112 } 113 #else 114 #define CHECK_AG() 115 #endif 116 117 118 /* Output the contents of an aggregation table slot. 119 * This function must always be immediately followed with the deletion 120 * of the target slot. 121 */ 122 static void 123 ag_out(struct ag_info *ag, 124 void (*out)(struct ag_info *)) 125 { 126 struct ag_info *ag_cors; 127 naddr bit; 128 129 130 /* Forget it if this route should not be output for split-horizon. */ 131 if (ag->ag_state & AGS_SPLIT_HZ) 132 return; 133 134 /* If we output both the even and odd twins, then the immediate parent, 135 * if it is present, is redundant, unless the parent manages to 136 * aggregate into something coarser. 137 * On successive calls, this code detects the even and odd twins, 138 * and marks the parent. 139 * 140 * Note that the order in which the radix tree code emits routes 141 * ensures that the twins are seen before the parent is emitted. 142 */ 143 ag_cors = ag->ag_cors; 144 if (ag_cors != 0 145 && ag_cors->ag_mask == ag->ag_mask<<1 146 && ag_cors->ag_dst_h == (ag->ag_dst_h & ag_cors->ag_mask)) { 147 ag_cors->ag_state |= ((ag_cors->ag_dst_h == ag->ag_dst_h) 148 ? AGS_REDUN0 149 : AGS_REDUN1); 150 } 151 152 /* Skip it if this route is itself redundant. 153 * 154 * It is ok to change the contents of the slot here, since it is 155 * always deleted next. 156 */ 157 if (ag->ag_state & AGS_REDUN0) { 158 if (ag->ag_state & AGS_REDUN1) 159 return; /* quit if fully redundant */ 160 /* make it finer if it is half-redundant */ 161 bit = (-ag->ag_mask) >> 1; 162 ag->ag_dst_h |= bit; 163 ag->ag_mask |= bit; 164 165 } else if (ag->ag_state & AGS_REDUN1) { 166 /* make it finer if it is half-redundant */ 167 bit = (-ag->ag_mask) >> 1; 168 ag->ag_mask |= bit; 169 } 170 out(ag); 171 } 172 173 174 static void 175 ag_del(struct ag_info *ag) 176 { 177 CHECK_AG(); 178 179 if (ag->ag_cors == 0) 180 ag_corsest = ag->ag_fine; 181 else 182 ag->ag_cors->ag_fine = ag->ag_fine; 183 184 if (ag->ag_fine == 0) 185 ag_finest = ag->ag_cors; 186 else 187 ag->ag_fine->ag_cors = ag->ag_cors; 188 189 ag->ag_fine = ag_avail; 190 ag_avail = ag; 191 192 CHECK_AG(); 193 } 194 195 196 /* Flush routes waiting for aggregation. 197 * This must not suppress a route unless it is known that among all 198 * routes with coarser masks that match it, the one with the longest 199 * mask is appropriate. This is ensured by scanning the routes 200 * in lexical order, and with the most restrictive mask first 201 * among routes to the same destination. 202 */ 203 void 204 ag_flush(naddr lim_dst_h, /* flush routes to here */ 205 naddr lim_mask, /* matching this mask */ 206 void (*out)(struct ag_info *)) 207 { 208 struct ag_info *ag, *ag_cors; 209 naddr dst_h; 210 211 212 for (ag = ag_finest; 213 ag != 0 && ag->ag_mask >= lim_mask; 214 ag = ag_cors) { 215 ag_cors = ag->ag_cors; 216 217 /* work on only the specified routes */ 218 dst_h = ag->ag_dst_h; 219 if ((dst_h & lim_mask) != lim_dst_h) 220 continue; 221 222 if (!(ag->ag_state & AGS_SUPPRESS)) 223 ag_out(ag, out); 224 225 else for ( ; ; ag_cors = ag_cors->ag_cors) { 226 /* Look for a route that can suppress the 227 * current route */ 228 if (ag_cors == 0) { 229 /* failed, so output it and look for 230 * another route to work on 231 */ 232 ag_out(ag, out); 233 break; 234 } 235 236 if ((dst_h & ag_cors->ag_mask) == ag_cors->ag_dst_h) { 237 /* We found a route with a coarser mask that 238 * aggregates the current target. 239 * 240 * If it has a different next hop, it 241 * cannot replace the target, so output 242 * the target. 243 */ 244 if (ag->ag_gate != ag_cors->ag_gate 245 && !(ag->ag_state & AGS_FINE_GATE) 246 && !(ag_cors->ag_state & AGS_CORS_GATE)) { 247 ag_out(ag, out); 248 break; 249 } 250 251 /* If the coarse route has a good enough 252 * metric, it suppresses the target. 253 * If the suppressed target was redundant, 254 * then mark the suppressor redundant. 255 */ 256 if (ag_cors->ag_pref <= ag->ag_pref) { 257 if (ag_cors->ag_seqno > ag->ag_seqno) 258 ag_cors->ag_seqno = ag->ag_seqno; 259 if (AG_IS_REDUN(ag->ag_state) 260 && ag_cors->ag_mask==ag->ag_mask<<1) { 261 if (ag_cors->ag_dst_h == dst_h) 262 ag_cors->ag_state |= AGS_REDUN0; 263 else 264 ag_cors->ag_state |= AGS_REDUN1; 265 } 266 if (ag->ag_tag != ag_cors->ag_tag) 267 ag_cors->ag_tag = 0; 268 if (ag->ag_nhop != ag_cors->ag_nhop) 269 ag_cors->ag_nhop = 0; 270 break; 271 } 272 } 273 } 274 275 /* That route has either been output or suppressed */ 276 ag_cors = ag->ag_cors; 277 ag_del(ag); 278 } 279 280 CHECK_AG(); 281 } 282 283 284 /* Try to aggregate a route with previous routes. 285 */ 286 void 287 ag_check(naddr dst, 288 naddr mask, 289 naddr gate, 290 naddr nhop, 291 char metric, 292 char pref, 293 u_int seqno, 294 u_short tag, 295 u_short state, 296 void (*out)(struct ag_info *)) /* output using this */ 297 { 298 struct ag_info *ag, *nag, *ag_cors; 299 naddr xaddr; 300 int x; 301 302 NTOHL(dst); 303 304 /* Punt non-contiguous subnet masks. 305 * 306 * (X & -X) contains a single bit if and only if X is a power of 2. 307 * (X + (X & -X)) == 0 if and only if X is a power of 2. 308 */ 309 if ((mask & -mask) + mask != 0) { 310 struct ag_info nc_ag; 311 312 nc_ag.ag_dst_h = dst; 313 nc_ag.ag_mask = mask; 314 nc_ag.ag_gate = gate; 315 nc_ag.ag_nhop = nhop; 316 nc_ag.ag_metric = metric; 317 nc_ag.ag_pref = pref; 318 nc_ag.ag_tag = tag; 319 nc_ag.ag_state = state; 320 nc_ag.ag_seqno = seqno; 321 out(&nc_ag); 322 return; 323 } 324 325 /* Search for the right slot in the aggregation table. 326 */ 327 ag_cors = 0; 328 ag = ag_corsest; 329 while (ag != 0) { 330 if (ag->ag_mask >= mask) 331 break; 332 333 /* Suppress old routes (i.e. combine with compatible routes 334 * with coarser masks) as we look for the right slot in the 335 * aggregation table for the new route. 336 * A route to an address less than the current destination 337 * will not be affected by the current route or any route 338 * seen hereafter. That means it is safe to suppress it. 339 * This check keeps poor routes (e.g. with large hop counts) 340 * from preventing suppression of finer routes. 341 */ 342 if (ag_cors != 0 343 && ag->ag_dst_h < dst 344 && (ag->ag_state & AGS_SUPPRESS) 345 && ag_cors->ag_pref <= ag->ag_pref 346 && (ag->ag_dst_h & ag_cors->ag_mask) == ag_cors->ag_dst_h 347 && (ag_cors->ag_gate == ag->ag_gate 348 || (ag->ag_state & AGS_FINE_GATE) 349 || (ag_cors->ag_state & AGS_CORS_GATE))) { 350 if (ag_cors->ag_seqno > ag->ag_seqno) 351 ag_cors->ag_seqno = ag->ag_seqno; 352 /* If the suppressed target was redundant, 353 * then mark the suppressor redundant. 354 */ 355 if (AG_IS_REDUN(ag->ag_state) 356 && ag_cors->ag_mask == ag->ag_mask<<1) { 357 if (ag_cors->ag_dst_h == dst) 358 ag_cors->ag_state |= AGS_REDUN0; 359 else 360 ag_cors->ag_state |= AGS_REDUN1; 361 } 362 if (ag->ag_tag != ag_cors->ag_tag) 363 ag_cors->ag_tag = 0; 364 if (ag->ag_nhop != ag_cors->ag_nhop) 365 ag_cors->ag_nhop = 0; 366 ag_del(ag); 367 CHECK_AG(); 368 } else { 369 ag_cors = ag; 370 } 371 ag = ag_cors->ag_fine; 372 } 373 374 /* If we find the even/odd twin of the new route, and if the 375 * masks and so forth are equal, we can aggregate them. 376 * We can probably promote one of the pair. 377 * 378 * Since the routes are encountered in lexical order, 379 * the new route must be odd. However, the second or later 380 * times around this loop, it could be the even twin promoted 381 * from the even/odd pair of twins of the finer route. 382 */ 383 while (ag != 0 384 && ag->ag_mask == mask 385 && ((ag->ag_dst_h ^ dst) & (mask<<1)) == 0) { 386 387 /* Here we know the target route and the route in the current 388 * slot have the same netmasks and differ by at most the 389 * last bit. They are either for the same destination, or 390 * for an even/odd pair of destinations. 391 */ 392 if (ag->ag_dst_h == dst) { 393 /* We have two routes to the same destination. 394 * Routes are encountered in lexical order, so a 395 * route is never promoted until the parent route is 396 * already present. So we know that the new route is 397 * a promoted (or aggregated) pair and the route 398 * already in the slot is the explicit route. 399 * 400 * Prefer the best route if their metrics differ, 401 * or the aggregated one if not, following a sort 402 * of longest-match rule. 403 */ 404 if (pref <= ag->ag_pref) { 405 ag->ag_gate = gate; 406 ag->ag_nhop = nhop; 407 ag->ag_tag = tag; 408 ag->ag_metric = metric; 409 ag->ag_pref = pref; 410 x = ag->ag_state; 411 ag->ag_state = state; 412 state = x; 413 } 414 415 /* The sequence number controls flash updating, 416 * and should be the smaller of the two. 417 */ 418 if (ag->ag_seqno > seqno) 419 ag->ag_seqno = seqno; 420 421 /* Some bits are set if they are set on either route, 422 * except when the route is for an interface. 423 */ 424 if (!(ag->ag_state & AGS_IF)) 425 ag->ag_state |= (state & (AGS_AGGREGATE_EITHER 426 | AGS_REDUN0 427 | AGS_REDUN1)); 428 return; 429 } 430 431 /* If one of the routes can be promoted and the other can 432 * be suppressed, it may be possible to combine them or 433 * worthwhile to promote one. 434 * 435 * Any route that can be promoted is always 436 * marked to be eligible to be suppressed. 437 */ 438 if (!((state & AGS_AGGREGATE) 439 && (ag->ag_state & AGS_SUPPRESS)) 440 && !((ag->ag_state & AGS_AGGREGATE) 441 && (state & AGS_SUPPRESS))) 442 break; 443 444 /* A pair of even/odd twin routes can be combined 445 * if either is redundant, or if they are via the 446 * same gateway and have the same metric. 447 */ 448 if (AG_IS_REDUN(ag->ag_state) 449 || AG_IS_REDUN(state) 450 || (ag->ag_gate == gate 451 && ag->ag_pref == pref 452 && (state & ag->ag_state & AGS_AGGREGATE) != 0)) { 453 454 /* We have both the even and odd pairs. 455 * Since the routes are encountered in order, 456 * the route in the slot must be the even twin. 457 * 458 * Combine and promote (aggregate) the pair of routes. 459 */ 460 if (seqno > ag->ag_seqno) 461 seqno = ag->ag_seqno; 462 if (!AG_IS_REDUN(state)) 463 state &= ~AGS_REDUN1; 464 if (AG_IS_REDUN(ag->ag_state)) 465 state |= AGS_REDUN0; 466 else 467 state &= ~AGS_REDUN0; 468 state |= (ag->ag_state & AGS_AGGREGATE_EITHER); 469 if (ag->ag_tag != tag) 470 tag = 0; 471 if (ag->ag_nhop != nhop) 472 nhop = 0; 473 474 /* Get rid of the even twin that was already 475 * in the slot. 476 */ 477 ag_del(ag); 478 479 } else if (ag->ag_pref >= pref 480 && (ag->ag_state & AGS_AGGREGATE)) { 481 /* If we cannot combine the pair, maybe the route 482 * with the worse metric can be promoted. 483 * 484 * Promote the old, even twin, by giving its slot 485 * in the table to the new, odd twin. 486 */ 487 ag->ag_dst_h = dst; 488 489 xaddr = ag->ag_gate; 490 ag->ag_gate = gate; 491 gate = xaddr; 492 493 xaddr = ag->ag_nhop; 494 ag->ag_nhop = nhop; 495 nhop = xaddr; 496 497 x = ag->ag_tag; 498 ag->ag_tag = tag; 499 tag = x; 500 501 /* The promoted route is even-redundant only if the 502 * even twin was fully redundant. It is not 503 * odd-redundant because the odd-twin will still be 504 * in the table. 505 */ 506 x = ag->ag_state; 507 if (!AG_IS_REDUN(x)) 508 x &= ~AGS_REDUN0; 509 x &= ~AGS_REDUN1; 510 ag->ag_state = state; 511 state = x; 512 513 x = ag->ag_metric; 514 ag->ag_metric = metric; 515 metric = x; 516 517 x = ag->ag_pref; 518 ag->ag_pref = pref; 519 pref = x; 520 521 /* take the newest sequence number */ 522 if (seqno >= ag->ag_seqno) 523 seqno = ag->ag_seqno; 524 else 525 ag->ag_seqno = seqno; 526 527 } else { 528 if (!(state & AGS_AGGREGATE)) 529 break; /* cannot promote either twin */ 530 531 /* Promote the new, odd twin by shaving its 532 * mask and address. 533 * The promoted route is odd-redundant only if the 534 * odd twin was fully redundant. It is not 535 * even-redundant because the even twin is still in 536 * the table. 537 */ 538 if (!AG_IS_REDUN(state)) 539 state &= ~AGS_REDUN1; 540 state &= ~AGS_REDUN0; 541 if (seqno > ag->ag_seqno) 542 seqno = ag->ag_seqno; 543 else 544 ag->ag_seqno = seqno; 545 } 546 547 mask <<= 1; 548 dst &= mask; 549 550 if (ag_cors == 0) { 551 ag = ag_corsest; 552 break; 553 } 554 ag = ag_cors; 555 ag_cors = ag->ag_cors; 556 } 557 558 /* When we can no longer promote and combine routes, 559 * flush the old route in the target slot. Also flush 560 * any finer routes that we know will never be aggregated by 561 * the new route. 562 * 563 * In case we moved toward coarser masks, 564 * get back where we belong 565 */ 566 if (ag != 0 567 && ag->ag_mask < mask) { 568 ag_cors = ag; 569 ag = ag->ag_fine; 570 } 571 572 /* Empty the target slot 573 */ 574 if (ag != 0 && ag->ag_mask == mask) { 575 ag_flush(ag->ag_dst_h, ag->ag_mask, out); 576 ag = (ag_cors == 0) ? ag_corsest : ag_cors->ag_fine; 577 } 578 579 #ifdef DEBUG_AG 580 (void)fflush(stderr); 581 if (ag == 0 && ag_cors != ag_finest) 582 abort(); 583 if (ag_cors == 0 && ag != ag_corsest) 584 abort(); 585 if (ag != 0 && ag->ag_cors != ag_cors) 586 abort(); 587 if (ag_cors != 0 && ag_cors->ag_fine != ag) 588 abort(); 589 CHECK_AG(); 590 #endif 591 592 /* Save the new route on the end of the table. 593 */ 594 nag = ag_avail; 595 ag_avail = nag->ag_fine; 596 597 nag->ag_dst_h = dst; 598 nag->ag_mask = mask; 599 nag->ag_gate = gate; 600 nag->ag_nhop = nhop; 601 nag->ag_metric = metric; 602 nag->ag_pref = pref; 603 nag->ag_tag = tag; 604 nag->ag_state = state; 605 nag->ag_seqno = seqno; 606 607 nag->ag_fine = ag; 608 if (ag != 0) 609 ag->ag_cors = nag; 610 else 611 ag_finest = nag; 612 nag->ag_cors = ag_cors; 613 if (ag_cors == 0) 614 ag_corsest = nag; 615 else 616 ag_cors->ag_fine = nag; 617 CHECK_AG(); 618 } 619 620 621 static const char * 622 rtm_type_name(u_char type) 623 { 624 static const char *rtm_types[] = { 625 "RTM_ADD", 626 "RTM_DELETE", 627 "RTM_CHANGE", 628 "RTM_GET", 629 "RTM_LOSING", 630 "RTM_REDIRECT", 631 "RTM_MISS", 632 "RTM_LOCK", 633 "RTM_OLDADD", 634 "RTM_OLDDEL", 635 "RTM_RESOLVE", 636 "RTM_NEWADDR", 637 "RTM_DELADDR", 638 #ifdef RTM_OIFINFO 639 "RTM_OIFINFO", 640 #endif 641 "RTM_IFINFO" 642 }; 643 static char name0[10]; 644 645 646 if (type > sizeof(rtm_types)/sizeof(rtm_types[0]) 647 || type == 0) { 648 sprintf(name0, "RTM type %#x", type); 649 return name0; 650 } else { 651 return rtm_types[type-1]; 652 } 653 } 654 655 656 /* Trim a mask in a sockaddr 657 * Produce a length of 0 for an address of 0. 658 * Otherwise produce the index of the first zero byte. 659 */ 660 void 661 #ifdef _HAVE_SIN_LEN 662 masktrim(struct sockaddr_in *ap) 663 #else 664 masktrim(struct sockaddr_in_new *ap) 665 #endif 666 { 667 char *cp; 668 669 if (ap->sin_addr.s_addr == 0) { 670 ap->sin_len = 0; 671 return; 672 } 673 cp = (char *)(&ap->sin_addr.s_addr+1); 674 while (*--cp == 0) 675 continue; 676 ap->sin_len = cp - (char*)ap + 1; 677 } 678 679 680 /* Tell the kernel to add, delete or change a route 681 */ 682 static void 683 rtioctl(int action, /* RTM_DELETE, etc */ 684 naddr dst, 685 naddr gate, 686 naddr mask, 687 int metric, 688 int flags) 689 { 690 struct { 691 struct rt_msghdr w_rtm; 692 struct sockaddr_in w_dst; 693 struct sockaddr_in w_gate; 694 #ifdef _HAVE_SA_LEN 695 struct sockaddr_in w_mask; 696 #else 697 struct sockaddr_in_new w_mask; 698 #endif 699 } w; 700 long cc; 701 # define PAT " %-10s %s metric=%d flags=%#x" 702 # define ARGS rtm_type_name(action), rtname(dst,mask,gate), metric, flags 703 704 again: 705 memset(&w, 0, sizeof(w)); 706 w.w_rtm.rtm_msglen = sizeof(w); 707 w.w_rtm.rtm_version = RTM_VERSION; 708 w.w_rtm.rtm_type = action; 709 w.w_rtm.rtm_flags = flags; 710 w.w_rtm.rtm_seq = ++rt_sock_seqno; 711 w.w_rtm.rtm_addrs = RTA_DST|RTA_GATEWAY; 712 if (metric != 0 || action == RTM_CHANGE) { 713 w.w_rtm.rtm_rmx.rmx_hopcount = metric; 714 w.w_rtm.rtm_inits |= RTV_HOPCOUNT; 715 } 716 w.w_dst.sin_family = AF_INET; 717 w.w_dst.sin_addr.s_addr = dst; 718 w.w_gate.sin_family = AF_INET; 719 w.w_gate.sin_addr.s_addr = gate; 720 #ifdef _HAVE_SA_LEN 721 w.w_dst.sin_len = sizeof(w.w_dst); 722 w.w_gate.sin_len = sizeof(w.w_gate); 723 #endif 724 if (mask == HOST_MASK) { 725 w.w_rtm.rtm_flags |= RTF_HOST; 726 w.w_rtm.rtm_msglen -= sizeof(w.w_mask); 727 } else { 728 w.w_rtm.rtm_addrs |= RTA_NETMASK; 729 w.w_mask.sin_addr.s_addr = htonl(mask); 730 #ifdef _HAVE_SA_LEN 731 masktrim(&w.w_mask); 732 if (w.w_mask.sin_len == 0) 733 w.w_mask.sin_len = sizeof(long); 734 w.w_rtm.rtm_msglen -= (sizeof(w.w_mask) - w.w_mask.sin_len); 735 #endif 736 } 737 738 #ifndef NO_INSTALL 739 cc = write(rt_sock, &w, w.w_rtm.rtm_msglen); 740 if (cc < 0) { 741 if (errno == ESRCH 742 && (action == RTM_CHANGE || action == RTM_DELETE)) { 743 trace_act("route disappeared before" PAT, ARGS); 744 if (action == RTM_CHANGE) { 745 action = RTM_ADD; 746 goto again; 747 } 748 return; 749 } 750 msglog("write(rt_sock)" PAT ": %s", ARGS, strerror(errno)); 751 return; 752 } else if (cc != w.w_rtm.rtm_msglen) { 753 msglog("write(rt_sock) wrote %ld instead of %d for" PAT, 754 cc, w.w_rtm.rtm_msglen, ARGS); 755 return; 756 } 757 #endif 758 if (TRACEKERNEL) 759 trace_misc("write kernel" PAT, ARGS); 760 #undef PAT 761 #undef ARGS 762 } 763 764 765 #define KHASH_SIZE 71 /* should be prime */ 766 #define KHASH(a,m) khash_bins[((a) ^ (m)) % KHASH_SIZE] 767 static struct khash { 768 struct khash *k_next; 769 naddr k_dst; 770 naddr k_mask; 771 naddr k_gate; 772 short k_metric; 773 u_short k_state; 774 #define KS_NEW 0x001 775 #define KS_DELETE 0x002 /* need to delete the route */ 776 #define KS_ADD 0x004 /* add to the kernel */ 777 #define KS_CHANGE 0x008 /* tell kernel to change the route */ 778 #define KS_DEL_ADD 0x010 /* delete & add to change the kernel */ 779 #define KS_STATIC 0x020 /* Static flag in kernel */ 780 #define KS_GATEWAY 0x040 /* G flag in kernel */ 781 #define KS_DYNAMIC 0x080 /* result of redirect */ 782 #define KS_DELETED 0x100 /* already deleted from kernel */ 783 #define KS_CHECK 0x200 784 time_t k_keep; 785 #define K_KEEP_LIM 30 786 time_t k_redirect_time; /* when redirected route 1st seen */ 787 } *khash_bins[KHASH_SIZE]; 788 789 790 static struct khash* 791 kern_find(naddr dst, naddr mask, struct khash ***ppk) 792 { 793 struct khash *k, **pk; 794 795 for (pk = &KHASH(dst,mask); (k = *pk) != 0; pk = &k->k_next) { 796 if (k->k_dst == dst && k->k_mask == mask) 797 break; 798 } 799 if (ppk != 0) 800 *ppk = pk; 801 return k; 802 } 803 804 805 static struct khash* 806 kern_add(naddr dst, naddr mask) 807 { 808 struct khash *k, **pk; 809 810 k = kern_find(dst, mask, &pk); 811 if (k != 0) 812 return k; 813 814 k = (struct khash *)rtmalloc(sizeof(*k), "kern_add"); 815 816 memset(k, 0, sizeof(*k)); 817 k->k_dst = dst; 818 k->k_mask = mask; 819 k->k_state = KS_NEW; 820 k->k_keep = now.tv_sec; 821 *pk = k; 822 823 return k; 824 } 825 826 827 /* If a kernel route has a non-zero metric, check that it is still in the 828 * daemon table, and not deleted by interfaces coming and going. 829 */ 830 static void 831 kern_check_static(struct khash *k, 832 struct interface *ifp) 833 { 834 struct rt_entry *rt; 835 struct rt_spare new; 836 837 if (k->k_metric == 0) 838 return; 839 840 memset(&new, 0, sizeof(new)); 841 new.rts_ifp = ifp; 842 new.rts_gate = k->k_gate; 843 new.rts_router = (ifp != 0) ? ifp->int_addr : loopaddr; 844 new.rts_metric = k->k_metric; 845 new.rts_time = now.tv_sec; 846 847 rt = rtget(k->k_dst, k->k_mask); 848 if (rt != 0) { 849 if (!(rt->rt_state & RS_STATIC)) 850 rtchange(rt, rt->rt_state | RS_STATIC, &new, 0); 851 } else { 852 rtadd(k->k_dst, k->k_mask, RS_STATIC, &new); 853 } 854 } 855 856 857 /* operate on a kernel entry 858 */ 859 static void 860 kern_ioctl(struct khash *k, 861 int action, /* RTM_DELETE, etc */ 862 int flags) 863 864 { 865 switch (action) { 866 case RTM_DELETE: 867 k->k_state &= ~KS_DYNAMIC; 868 if (k->k_state & KS_DELETED) 869 return; 870 k->k_state |= KS_DELETED; 871 break; 872 case RTM_ADD: 873 k->k_state &= ~KS_DELETED; 874 break; 875 case RTM_CHANGE: 876 if (k->k_state & KS_DELETED) { 877 action = RTM_ADD; 878 k->k_state &= ~KS_DELETED; 879 } 880 break; 881 } 882 883 rtioctl(action, k->k_dst, k->k_gate, k->k_mask, k->k_metric, flags); 884 } 885 886 887 /* add a route the kernel told us 888 */ 889 static void 890 rtm_add(struct rt_msghdr *rtm, 891 struct rt_addrinfo *info, 892 time_t keep) 893 { 894 struct khash *k; 895 struct interface *ifp; 896 naddr mask; 897 898 899 if (rtm->rtm_flags & RTF_HOST) { 900 mask = HOST_MASK; 901 } else if (INFO_MASK(info) != 0) { 902 mask = ntohl(S_ADDR(INFO_MASK(info))); 903 } else { 904 msglog("ignore %s without mask", rtm_type_name(rtm->rtm_type)); 905 return; 906 } 907 908 k = kern_add(S_ADDR(INFO_DST(info)), mask); 909 if (k->k_state & KS_NEW) 910 k->k_keep = now.tv_sec+keep; 911 if (INFO_GATE(info) == 0) { 912 trace_act("note %s without gateway", 913 rtm_type_name(rtm->rtm_type)); 914 k->k_metric = HOPCNT_INFINITY; 915 } else if (INFO_GATE(info)->sa_family != AF_INET) { 916 trace_act("note %s with gateway AF=%d", 917 rtm_type_name(rtm->rtm_type), 918 INFO_GATE(info)->sa_family); 919 k->k_metric = HOPCNT_INFINITY; 920 } else { 921 k->k_gate = S_ADDR(INFO_GATE(info)); 922 k->k_metric = rtm->rtm_rmx.rmx_hopcount; 923 if (k->k_metric < 0) 924 k->k_metric = 0; 925 else if (k->k_metric > HOPCNT_INFINITY-1) 926 k->k_metric = HOPCNT_INFINITY-1; 927 } 928 k->k_state &= ~(KS_DELETE | KS_ADD | KS_CHANGE | KS_DEL_ADD 929 | KS_DELETED | KS_GATEWAY | KS_STATIC 930 | KS_NEW | KS_CHECK); 931 if (rtm->rtm_flags & RTF_GATEWAY) 932 k->k_state |= KS_GATEWAY; 933 if (rtm->rtm_flags & RTF_STATIC) 934 k->k_state |= KS_STATIC; 935 936 if (0 != (rtm->rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED))) { 937 if (INFO_AUTHOR(info) != 0 938 && INFO_AUTHOR(info)->sa_family == AF_INET) 939 ifp = iflookup(S_ADDR(INFO_AUTHOR(info))); 940 else 941 ifp = 0; 942 if (supplier 943 && (ifp == 0 || !(ifp->int_state & IS_REDIRECT_OK))) { 944 /* Routers are not supposed to listen to redirects, 945 * so delete it if it came via an unknown interface 946 * or the interface does not have special permission. 947 */ 948 k->k_state &= ~KS_DYNAMIC; 949 k->k_state |= KS_DELETE; 950 LIM_SEC(need_kern, 0); 951 trace_act("mark for deletion redirected %s --> %s" 952 " via %s", 953 addrname(k->k_dst, k->k_mask, 0), 954 naddr_ntoa(k->k_gate), 955 ifp ? ifp->int_name : "unknown interface"); 956 } else { 957 k->k_state |= KS_DYNAMIC; 958 k->k_redirect_time = now.tv_sec; 959 trace_act("accept redirected %s --> %s via %s", 960 addrname(k->k_dst, k->k_mask, 0), 961 naddr_ntoa(k->k_gate), 962 ifp ? ifp->int_name : "unknown interface"); 963 } 964 return; 965 } 966 967 /* If it is not a static route, quit until the next comparison 968 * between the kernel and daemon tables, when it will be deleted. 969 */ 970 if (!(k->k_state & KS_STATIC)) { 971 k->k_state |= KS_DELETE; 972 LIM_SEC(need_kern, k->k_keep); 973 return; 974 } 975 976 /* Put static routes with real metrics into the daemon table so 977 * they can be advertised. 978 * 979 * Find the interface toward the gateway. 980 */ 981 ifp = iflookup(k->k_gate); 982 if (ifp == 0) 983 msglog("static route %s --> %s impossibly lacks ifp", 984 addrname(S_ADDR(INFO_DST(info)), mask, 0), 985 naddr_ntoa(k->k_gate)); 986 987 kern_check_static(k, ifp); 988 } 989 990 991 /* deal with packet loss 992 */ 993 static void 994 rtm_lose(struct rt_msghdr *rtm, 995 struct rt_addrinfo *info) 996 { 997 if (INFO_GATE(info) == 0 998 || INFO_GATE(info)->sa_family != AF_INET) { 999 trace_act("ignore %s without gateway", 1000 rtm_type_name(rtm->rtm_type)); 1001 return; 1002 } 1003 1004 if (rdisc_ok) 1005 rdisc_age(S_ADDR(INFO_GATE(info))); 1006 age(S_ADDR(INFO_GATE(info))); 1007 } 1008 1009 1010 /* Make the gateway slot of an info structure point to something 1011 * useful. If it is not already useful, but it specifies an interface, 1012 * then fill in the sockaddr_in provided and point it there. 1013 */ 1014 static int 1015 get_info_gate(struct sockaddr **sap, 1016 struct sockaddr_in *sin) 1017 { 1018 struct sockaddr_dl *sdl = (struct sockaddr_dl *)*sap; 1019 struct interface *ifp; 1020 1021 if (sdl == 0) 1022 return 0; 1023 if ((sdl)->sdl_family == AF_INET) 1024 return 1; 1025 if ((sdl)->sdl_family != AF_LINK) 1026 return 0; 1027 1028 ifp = ifwithindex(sdl->sdl_index, 1); 1029 if (ifp == 0) 1030 return 0; 1031 1032 sin->sin_addr.s_addr = ifp->int_addr; 1033 #ifdef _HAVE_SA_LEN 1034 sin->sin_len = sizeof(*sin); 1035 #endif 1036 sin->sin_family = AF_INET; 1037 *sap = (struct sockaddr*)sin; 1038 1039 return 1; 1040 } 1041 1042 1043 /* Clean the kernel table by copying it to the daemon image. 1044 * Eventually the daemon will delete any extra routes. 1045 */ 1046 void 1047 flush_kern(void) 1048 { 1049 static char *sysctl_buf; 1050 static size_t sysctl_buf_size = 0; 1051 size_t needed; 1052 int mib[6]; 1053 char *next, *lim; 1054 struct rt_msghdr *rtm; 1055 struct sockaddr_in gate_sin; 1056 struct rt_addrinfo info; 1057 int i; 1058 struct khash *k; 1059 1060 1061 for (i = 0; i < KHASH_SIZE; i++) { 1062 for (k = khash_bins[i]; k != 0; k = k->k_next) { 1063 k->k_state |= KS_CHECK; 1064 } 1065 } 1066 1067 mib[0] = CTL_NET; 1068 mib[1] = PF_ROUTE; 1069 mib[2] = 0; /* protocol */ 1070 mib[3] = 0; /* wildcard address family */ 1071 mib[4] = NET_RT_DUMP; 1072 mib[5] = 0; /* no flags */ 1073 for (;;) { 1074 if ((needed = sysctl_buf_size) != 0) { 1075 if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0) 1076 break; 1077 if (errno != ENOMEM && errno != EFAULT) 1078 BADERR(1,"flush_kern: sysctl(RT_DUMP)"); 1079 free(sysctl_buf); 1080 needed = 0; 1081 } 1082 if (sysctl(mib, 6, 0, &needed, 0, 0) < 0) 1083 BADERR(1,"flush_kern: sysctl(RT_DUMP) estimate"); 1084 /* Kludge around the habit of some systems, such as 1085 * BSD/OS 3.1, to not admit how many routes are in the 1086 * kernel, or at least to be quite wrong. 1087 */ 1088 needed += 50*(sizeof(*rtm)+5*sizeof(struct sockaddr)); 1089 sysctl_buf = rtmalloc(sysctl_buf_size = needed, 1090 "flush_kern sysctl(RT_DUMP)"); 1091 } 1092 1093 lim = sysctl_buf + needed; 1094 for (next = sysctl_buf; next < lim; next += rtm->rtm_msglen) { 1095 rtm = (struct rt_msghdr *)next; 1096 if (rtm->rtm_msglen == 0) { 1097 msglog("zero length kernel route at " 1098 " %#lx in buffer %#lx before %#lx", 1099 (u_long)rtm, (u_long)sysctl_buf, (u_long)lim); 1100 break; 1101 } 1102 1103 rt_xaddrs(&info, 1104 (struct sockaddr *)(rtm+1), 1105 (struct sockaddr *)(next + rtm->rtm_msglen), 1106 rtm->rtm_addrs); 1107 1108 if (INFO_DST(&info) == 0 1109 || INFO_DST(&info)->sa_family != AF_INET) 1110 continue; 1111 1112 /* ignore ARP table entries on systems with a merged route 1113 * and ARP table. 1114 */ 1115 if (rtm->rtm_flags & RTF_LLINFO) 1116 continue; 1117 1118 /* ignore multicast addresses 1119 */ 1120 if (IN_MULTICAST(ntohl(S_ADDR(INFO_DST(&info))))) 1121 continue; 1122 1123 if (!get_info_gate(&INFO_GATE(&info), &gate_sin)) 1124 continue; 1125 1126 /* Note static routes and interface routes, and also 1127 * preload the image of the kernel table so that 1128 * we can later clean it, as well as avoid making 1129 * unneeded changes. Keep the old kernel routes for a 1130 * few seconds to allow a RIP or router-discovery 1131 * response to be heard. 1132 */ 1133 rtm_add(rtm,&info,MIN_WAITTIME); 1134 } 1135 1136 for (i = 0; i < KHASH_SIZE; i++) { 1137 for (k = khash_bins[i]; k != 0; k = k->k_next) { 1138 if (k->k_state & KS_CHECK) { 1139 msglog("%s --> %s disappeared from kernel", 1140 addrname(k->k_dst, k->k_mask, 0), 1141 naddr_ntoa(k->k_gate)); 1142 del_static(k->k_dst, k->k_mask, k->k_gate, 1); 1143 } 1144 } 1145 } 1146 } 1147 1148 1149 /* Listen to announcements from the kernel 1150 */ 1151 void 1152 read_rt(void) 1153 { 1154 long cc; 1155 struct interface *ifp; 1156 struct sockaddr_in gate_sin; 1157 naddr mask, gate; 1158 union { 1159 struct { 1160 struct rt_msghdr rtm; 1161 struct sockaddr addrs[RTAX_MAX]; 1162 } r; 1163 struct if_msghdr ifm; 1164 } m; 1165 char str[100], *strp; 1166 struct rt_addrinfo info; 1167 1168 1169 for (;;) { 1170 cc = read(rt_sock, &m, sizeof(m)); 1171 if (cc <= 0) { 1172 if (cc < 0 && errno != EWOULDBLOCK) 1173 LOGERR("read(rt_sock)"); 1174 return; 1175 } 1176 1177 if (m.r.rtm.rtm_version != RTM_VERSION) { 1178 msglog("bogus routing message version %d", 1179 m.r.rtm.rtm_version); 1180 continue; 1181 } 1182 1183 /* Ignore our own results. 1184 */ 1185 if (m.r.rtm.rtm_type <= RTM_CHANGE 1186 && m.r.rtm.rtm_pid == mypid) { 1187 static int complained = 0; 1188 if (!complained) { 1189 msglog("receiving our own change messages"); 1190 complained = 1; 1191 } 1192 continue; 1193 } 1194 1195 if (m.r.rtm.rtm_type == RTM_IFINFO 1196 || m.r.rtm.rtm_type == RTM_NEWADDR 1197 || m.r.rtm.rtm_type == RTM_DELADDR) { 1198 ifp = ifwithindex(m.ifm.ifm_index, 1199 m.r.rtm.rtm_type != RTM_DELADDR); 1200 if (ifp == 0) 1201 trace_act("note %s with flags %#x" 1202 " for unknown interface index #%d", 1203 rtm_type_name(m.r.rtm.rtm_type), 1204 m.ifm.ifm_flags, 1205 m.ifm.ifm_index); 1206 else 1207 trace_act("note %s with flags %#x for %s", 1208 rtm_type_name(m.r.rtm.rtm_type), 1209 m.ifm.ifm_flags, 1210 ifp->int_name); 1211 1212 /* After being informed of a change to an interface, 1213 * check them all now if the check would otherwise 1214 * be a long time from now, if the interface is 1215 * not known, or if the interface has been turned 1216 * off or on. 1217 */ 1218 if (ifinit_timer.tv_sec-now.tv_sec>=CHECK_BAD_INTERVAL 1219 || ifp == 0 1220 || ((ifp->int_if_flags ^ m.ifm.ifm_flags) 1221 & IFF_UP) != 0) 1222 ifinit_timer.tv_sec = now.tv_sec; 1223 continue; 1224 } 1225 #ifdef RTM_OIFINFO 1226 if (m.r.rtm.rtm_type == RTM_OIFINFO) { 1227 continue; /* ignore compat message */ 1228 } 1229 #endif 1230 1231 strcpy(str, rtm_type_name(m.r.rtm.rtm_type)); 1232 strp = &str[strlen(str)]; 1233 if (m.r.rtm.rtm_type <= RTM_CHANGE) 1234 strp += sprintf(strp," from pid %d",m.r.rtm.rtm_pid); 1235 1236 rt_xaddrs(&info, m.r.addrs, &m.r.addrs[RTAX_MAX], 1237 m.r.rtm.rtm_addrs); 1238 1239 if (INFO_DST(&info) == 0) { 1240 trace_act("ignore %s without dst", str); 1241 continue; 1242 } 1243 1244 if (INFO_DST(&info)->sa_family != AF_INET) { 1245 trace_act("ignore %s for AF %d", str, 1246 INFO_DST(&info)->sa_family); 1247 continue; 1248 } 1249 1250 mask = ((INFO_MASK(&info) != 0) 1251 ? ntohl(S_ADDR(INFO_MASK(&info))) 1252 : (m.r.rtm.rtm_flags & RTF_HOST) 1253 ? HOST_MASK 1254 : std_mask(S_ADDR(INFO_DST(&info)))); 1255 1256 strp += sprintf(strp, ": %s", 1257 addrname(S_ADDR(INFO_DST(&info)), mask, 0)); 1258 1259 if (IN_MULTICAST(ntohl(S_ADDR(INFO_DST(&info))))) { 1260 trace_act("ignore multicast %s", str); 1261 continue; 1262 } 1263 1264 if (m.r.rtm.rtm_flags & RTF_LLINFO) { 1265 trace_act("ignore ARP %s", str); 1266 continue; 1267 } 1268 1269 if (get_info_gate(&INFO_GATE(&info), &gate_sin)) { 1270 gate = S_ADDR(INFO_GATE(&info)); 1271 strp += sprintf(strp, " --> %s", naddr_ntoa(gate)); 1272 } else { 1273 gate = 0; 1274 } 1275 1276 if (INFO_AUTHOR(&info) != 0) 1277 strp += sprintf(strp, " by authority of %s", 1278 saddr_ntoa(INFO_AUTHOR(&info))); 1279 1280 switch (m.r.rtm.rtm_type) { 1281 case RTM_ADD: 1282 case RTM_CHANGE: 1283 case RTM_REDIRECT: 1284 if (m.r.rtm.rtm_errno != 0) { 1285 trace_act("ignore %s with \"%s\" error", 1286 str, strerror(m.r.rtm.rtm_errno)); 1287 } else { 1288 trace_act("%s", str); 1289 rtm_add(&m.r.rtm,&info,0); 1290 } 1291 break; 1292 1293 case RTM_DELETE: 1294 if (m.r.rtm.rtm_errno != 0 1295 && m.r.rtm.rtm_errno != ESRCH) { 1296 trace_act("ignore %s with \"%s\" error", 1297 str, strerror(m.r.rtm.rtm_errno)); 1298 } else { 1299 trace_act("%s", str); 1300 del_static(S_ADDR(INFO_DST(&info)), mask, 1301 gate, 1); 1302 } 1303 break; 1304 1305 case RTM_LOSING: 1306 trace_act("%s", str); 1307 rtm_lose(&m.r.rtm,&info); 1308 break; 1309 1310 default: 1311 trace_act("ignore %s", str); 1312 break; 1313 } 1314 } 1315 } 1316 1317 1318 /* after aggregating, note routes that belong in the kernel 1319 */ 1320 static void 1321 kern_out(struct ag_info *ag) 1322 { 1323 struct khash *k; 1324 1325 1326 /* Do not install bad routes if they are not already present. 1327 * This includes routes that had RS_NET_SYN for interfaces that 1328 * recently died. 1329 */ 1330 if (ag->ag_metric == HOPCNT_INFINITY) { 1331 k = kern_find(htonl(ag->ag_dst_h), ag->ag_mask, 0); 1332 if (k == 0) 1333 return; 1334 } else { 1335 k = kern_add(htonl(ag->ag_dst_h), ag->ag_mask); 1336 } 1337 1338 if (k->k_state & KS_NEW) { 1339 /* will need to add new entry to the kernel table */ 1340 k->k_state = KS_ADD; 1341 if (ag->ag_state & AGS_GATEWAY) 1342 k->k_state |= KS_GATEWAY; 1343 k->k_gate = ag->ag_gate; 1344 k->k_metric = ag->ag_metric; 1345 return; 1346 } 1347 1348 if (k->k_state & KS_STATIC) 1349 return; 1350 1351 /* modify existing kernel entry if necessary */ 1352 if (k->k_gate != ag->ag_gate 1353 || k->k_metric != ag->ag_metric) { 1354 /* Must delete bad interface routes etc. to change them. */ 1355 if (k->k_metric == HOPCNT_INFINITY) 1356 k->k_state |= KS_DEL_ADD; 1357 k->k_gate = ag->ag_gate; 1358 k->k_metric = ag->ag_metric; 1359 k->k_state |= KS_CHANGE; 1360 } 1361 1362 /* If the daemon thinks the route should exist, forget 1363 * about any redirections. 1364 * If the daemon thinks the route should exist, eventually 1365 * override manual intervention by the operator. 1366 */ 1367 if ((k->k_state & (KS_DYNAMIC | KS_DELETED)) != 0) { 1368 k->k_state &= ~KS_DYNAMIC; 1369 k->k_state |= (KS_ADD | KS_DEL_ADD); 1370 } 1371 1372 if ((k->k_state & KS_GATEWAY) 1373 && !(ag->ag_state & AGS_GATEWAY)) { 1374 k->k_state &= ~KS_GATEWAY; 1375 k->k_state |= (KS_ADD | KS_DEL_ADD); 1376 } else if (!(k->k_state & KS_GATEWAY) 1377 && (ag->ag_state & AGS_GATEWAY)) { 1378 k->k_state |= KS_GATEWAY; 1379 k->k_state |= (KS_ADD | KS_DEL_ADD); 1380 } 1381 1382 /* Deleting-and-adding is necessary to change aspects of a route. 1383 * Just delete instead of deleting and then adding a bad route. 1384 * Otherwise, we want to keep the route in the kernel. 1385 */ 1386 if (k->k_metric == HOPCNT_INFINITY 1387 && (k->k_state & KS_DEL_ADD)) 1388 k->k_state |= KS_DELETE; 1389 else 1390 k->k_state &= ~KS_DELETE; 1391 #undef RT 1392 } 1393 1394 1395 /* ARGSUSED */ 1396 static int 1397 walk_kern(struct radix_node *rn, 1398 struct walkarg *argp UNUSED) 1399 { 1400 #define RT ((struct rt_entry *)rn) 1401 char metric, pref; 1402 u_int ags = 0; 1403 1404 1405 /* Do not install synthetic routes */ 1406 if (RT->rt_state & RS_NET_SYN) 1407 return 0; 1408 1409 if (!(RT->rt_state & RS_IF)) { 1410 /* This is an ordinary route, not for an interface. 1411 */ 1412 1413 /* aggregate, ordinary good routes without regard to 1414 * their metric 1415 */ 1416 pref = 1; 1417 ags |= (AGS_GATEWAY | AGS_SUPPRESS | AGS_AGGREGATE); 1418 1419 /* Do not install host routes directly to hosts, to avoid 1420 * interfering with ARP entries in the kernel table. 1421 */ 1422 if (RT_ISHOST(RT) 1423 && ntohl(RT->rt_dst) == RT->rt_gate) 1424 return 0; 1425 1426 } else { 1427 /* This is an interface route. 1428 * Do not install routes for "external" remote interfaces. 1429 */ 1430 if (RT->rt_ifp != 0 && (RT->rt_ifp->int_state & IS_EXTERNAL)) 1431 return 0; 1432 1433 /* Interfaces should override received routes. 1434 */ 1435 pref = 0; 1436 ags |= (AGS_IF | AGS_CORS_GATE); 1437 1438 /* If it is not an interface, or an alias for an interface, 1439 * it must be a "gateway." 1440 * 1441 * If it is a "remote" interface, it is also a "gateway" to 1442 * the kernel if is not a alias. 1443 */ 1444 if (RT->rt_ifp == 0 1445 || (RT->rt_ifp->int_state & IS_REMOTE)) 1446 ags |= (AGS_GATEWAY | AGS_SUPPRESS | AGS_AGGREGATE); 1447 } 1448 1449 /* If RIP is off and IRDP is on, let the route to the discovered 1450 * route suppress any RIP routes. Eventually the RIP routes 1451 * will time-out and be deleted. This reaches the steady-state 1452 * quicker. 1453 */ 1454 if ((RT->rt_state & RS_RDISC) && rip_sock < 0) 1455 ags |= AGS_CORS_GATE; 1456 1457 metric = RT->rt_metric; 1458 if (metric == HOPCNT_INFINITY) { 1459 /* if the route is dead, so try hard to aggregate. */ 1460 pref = HOPCNT_INFINITY; 1461 ags |= (AGS_FINE_GATE | AGS_SUPPRESS); 1462 ags &= ~(AGS_IF | AGS_CORS_GATE); 1463 } 1464 1465 ag_check(RT->rt_dst, RT->rt_mask, RT->rt_gate, 0, 1466 metric,pref, 0, 0, ags, kern_out); 1467 return 0; 1468 #undef RT 1469 } 1470 1471 1472 /* Update the kernel table to match the daemon table. 1473 */ 1474 static void 1475 fix_kern(void) 1476 { 1477 int i; 1478 struct khash *k, **pk; 1479 1480 1481 need_kern = age_timer; 1482 1483 /* Walk daemon table, updating the copy of the kernel table. 1484 */ 1485 (void)rn_walktree(rhead, walk_kern, 0); 1486 ag_flush(0,0,kern_out); 1487 1488 for (i = 0; i < KHASH_SIZE; i++) { 1489 for (pk = &khash_bins[i]; (k = *pk) != 0; ) { 1490 /* Do not touch static routes */ 1491 if (k->k_state & KS_STATIC) { 1492 kern_check_static(k,0); 1493 pk = &k->k_next; 1494 continue; 1495 } 1496 1497 /* check hold on routes deleted by the operator */ 1498 if (k->k_keep > now.tv_sec) { 1499 /* ensure we check when the hold is over */ 1500 LIM_SEC(need_kern, k->k_keep); 1501 /* mark for the next cycle */ 1502 k->k_state |= KS_DELETE; 1503 pk = &k->k_next; 1504 continue; 1505 } 1506 1507 if ((k->k_state & KS_DELETE) 1508 && !(k->k_state & KS_DYNAMIC)) { 1509 kern_ioctl(k, RTM_DELETE, 0); 1510 *pk = k->k_next; 1511 free(k); 1512 continue; 1513 } 1514 1515 if (k->k_state & KS_DEL_ADD) 1516 kern_ioctl(k, RTM_DELETE, 0); 1517 1518 if (k->k_state & KS_ADD) { 1519 kern_ioctl(k, RTM_ADD, 1520 ((0 != (k->k_state & (KS_GATEWAY 1521 | KS_DYNAMIC))) 1522 ? RTF_GATEWAY : 0)); 1523 } else if (k->k_state & KS_CHANGE) { 1524 kern_ioctl(k, RTM_CHANGE, 1525 ((0 != (k->k_state & (KS_GATEWAY 1526 | KS_DYNAMIC))) 1527 ? RTF_GATEWAY : 0)); 1528 } 1529 k->k_state &= ~(KS_ADD|KS_CHANGE|KS_DEL_ADD); 1530 1531 /* Mark this route to be deleted in the next cycle. 1532 * This deletes routes that disappear from the 1533 * daemon table, since the normal aging code 1534 * will clear the bit for routes that have not 1535 * disappeared from the daemon table. 1536 */ 1537 k->k_state |= KS_DELETE; 1538 pk = &k->k_next; 1539 } 1540 } 1541 } 1542 1543 1544 /* Delete a static route in the image of the kernel table. 1545 */ 1546 void 1547 del_static(naddr dst, 1548 naddr mask, 1549 naddr gate, 1550 int gone) 1551 { 1552 struct khash *k; 1553 struct rt_entry *rt; 1554 1555 /* Just mark it in the table to be deleted next time the kernel 1556 * table is updated. 1557 * If it has already been deleted, mark it as such, and set its 1558 * keep-timer so that it will not be deleted again for a while. 1559 * This lets the operator delete a route added by the daemon 1560 * and add a replacement. 1561 */ 1562 k = kern_find(dst, mask, 0); 1563 if (k != 0 && (gate == 0 || k->k_gate == gate)) { 1564 k->k_state &= ~(KS_STATIC | KS_DYNAMIC | KS_CHECK); 1565 k->k_state |= KS_DELETE; 1566 if (gone) { 1567 k->k_state |= KS_DELETED; 1568 k->k_keep = now.tv_sec + K_KEEP_LIM; 1569 } 1570 } 1571 1572 rt = rtget(dst, mask); 1573 if (rt != 0 && (rt->rt_state & RS_STATIC)) 1574 rtbad(rt); 1575 } 1576 1577 1578 /* Delete all routes generated from ICMP Redirects that use a given gateway, 1579 * as well as old redirected routes. 1580 */ 1581 void 1582 del_redirects(naddr bad_gate, 1583 time_t old) 1584 { 1585 int i; 1586 struct khash *k; 1587 1588 1589 for (i = 0; i < KHASH_SIZE; i++) { 1590 for (k = khash_bins[i]; k != 0; k = k->k_next) { 1591 if (!(k->k_state & KS_DYNAMIC) 1592 || (k->k_state & KS_STATIC)) 1593 continue; 1594 1595 if (k->k_gate != bad_gate 1596 && k->k_redirect_time > old 1597 && !supplier) 1598 continue; 1599 1600 k->k_state |= KS_DELETE; 1601 k->k_state &= ~KS_DYNAMIC; 1602 need_kern.tv_sec = now.tv_sec; 1603 trace_act("mark redirected %s --> %s for deletion", 1604 addrname(k->k_dst, k->k_mask, 0), 1605 naddr_ntoa(k->k_gate)); 1606 } 1607 } 1608 } 1609 1610 1611 /* Start the daemon tables. 1612 */ 1613 extern int max_keylen; 1614 1615 void 1616 rtinit(void) 1617 { 1618 int i; 1619 struct ag_info *ag; 1620 1621 /* Initialize the radix trees */ 1622 max_keylen = sizeof(struct sockaddr_in); 1623 rn_init(); 1624 rn_inithead((void**)&rhead, 32); 1625 1626 /* mark all of the slots in the table free */ 1627 ag_avail = ag_slots; 1628 for (ag = ag_slots, i = 1; i < NUM_AG_SLOTS; i++) { 1629 ag->ag_fine = ag+1; 1630 ag++; 1631 } 1632 } 1633 1634 1635 #ifdef _HAVE_SIN_LEN 1636 static struct sockaddr_in dst_sock = {sizeof(dst_sock), AF_INET}; 1637 static struct sockaddr_in mask_sock = {sizeof(mask_sock), AF_INET}; 1638 #else 1639 static struct sockaddr_in_new dst_sock = {_SIN_ADDR_SIZE, AF_INET}; 1640 static struct sockaddr_in_new mask_sock = {_SIN_ADDR_SIZE, AF_INET}; 1641 #endif 1642 1643 1644 static void 1645 set_need_flash(void) 1646 { 1647 if (!need_flash) { 1648 need_flash = 1; 1649 /* Do not send the flash update immediately. Wait a little 1650 * while to hear from other routers. 1651 */ 1652 no_flash.tv_sec = now.tv_sec + MIN_WAITTIME; 1653 } 1654 } 1655 1656 1657 /* Get a particular routing table entry 1658 */ 1659 struct rt_entry * 1660 rtget(naddr dst, naddr mask) 1661 { 1662 struct rt_entry *rt; 1663 1664 dst_sock.sin_addr.s_addr = dst; 1665 mask_sock.sin_addr.s_addr = htonl(mask); 1666 masktrim(&mask_sock); 1667 rt = (struct rt_entry *)rhead->rnh_lookup(&dst_sock,&mask_sock,rhead); 1668 if (!rt 1669 || rt->rt_dst != dst 1670 || rt->rt_mask != mask) 1671 return 0; 1672 1673 return rt; 1674 } 1675 1676 1677 /* Find a route to dst as the kernel would. 1678 */ 1679 struct rt_entry * 1680 rtfind(naddr dst) 1681 { 1682 dst_sock.sin_addr.s_addr = dst; 1683 return (struct rt_entry *)rhead->rnh_matchaddr(&dst_sock, rhead); 1684 } 1685 1686 1687 /* add a route to the table 1688 */ 1689 void 1690 rtadd(naddr dst, 1691 naddr mask, 1692 u_int state, /* rt_state for the entry */ 1693 struct rt_spare *new) 1694 { 1695 struct rt_entry *rt; 1696 naddr smask; 1697 int i; 1698 struct rt_spare *rts; 1699 1700 rt = (struct rt_entry *)rtmalloc(sizeof (*rt), "rtadd"); 1701 memset(rt, 0, sizeof(*rt)); 1702 for (rts = rt->rt_spares, i = NUM_SPARES; i != 0; i--, rts++) 1703 rts->rts_metric = HOPCNT_INFINITY; 1704 1705 rt->rt_nodes->rn_key = (caddr_t)&rt->rt_dst_sock; 1706 rt->rt_dst = dst; 1707 rt->rt_dst_sock.sin_family = AF_INET; 1708 #ifdef _HAVE_SIN_LEN 1709 rt->rt_dst_sock.sin_len = dst_sock.sin_len; 1710 #endif 1711 if (mask != HOST_MASK) { 1712 smask = std_mask(dst); 1713 if ((smask & ~mask) == 0 && mask > smask) 1714 state |= RS_SUBNET; 1715 } 1716 mask_sock.sin_addr.s_addr = htonl(mask); 1717 masktrim(&mask_sock); 1718 rt->rt_mask = mask; 1719 rt->rt_state = state; 1720 rt->rt_spares[0] = *new; 1721 rt->rt_time = now.tv_sec; 1722 rt->rt_poison_metric = HOPCNT_INFINITY; 1723 rt->rt_seqno = update_seqno; 1724 1725 if (++total_routes == MAX_ROUTES) 1726 msglog("have maximum (%d) routes", total_routes); 1727 if (TRACEACTIONS) 1728 trace_add_del("Add", rt); 1729 1730 need_kern.tv_sec = now.tv_sec; 1731 set_need_flash(); 1732 1733 if (0 == rhead->rnh_addaddr(&rt->rt_dst_sock, &mask_sock, 1734 rhead, rt->rt_nodes)) { 1735 msglog("rnh_addaddr() failed for %s mask=%#lx", 1736 naddr_ntoa(dst), (u_long)mask); 1737 free(rt); 1738 } 1739 } 1740 1741 1742 /* notice a changed route 1743 */ 1744 void 1745 rtchange(struct rt_entry *rt, 1746 u_int state, /* new state bits */ 1747 struct rt_spare *new, 1748 char *label) 1749 { 1750 if (rt->rt_metric != new->rts_metric) { 1751 /* Fix the kernel immediately if it seems the route 1752 * has gone bad, since there may be a working route that 1753 * aggregates this route. 1754 */ 1755 if (new->rts_metric == HOPCNT_INFINITY) { 1756 need_kern.tv_sec = now.tv_sec; 1757 if (new->rts_time >= now.tv_sec - EXPIRE_TIME) 1758 new->rts_time = now.tv_sec - EXPIRE_TIME; 1759 } 1760 rt->rt_seqno = update_seqno; 1761 set_need_flash(); 1762 } 1763 1764 if (rt->rt_gate != new->rts_gate) { 1765 need_kern.tv_sec = now.tv_sec; 1766 rt->rt_seqno = update_seqno; 1767 set_need_flash(); 1768 } 1769 1770 state |= (rt->rt_state & RS_SUBNET); 1771 1772 /* Keep various things from deciding ageless routes are stale. 1773 */ 1774 if (!AGE_RT(state, new->rts_ifp)) 1775 new->rts_time = now.tv_sec; 1776 1777 if (TRACEACTIONS) 1778 trace_change(rt, state, new, 1779 label ? label : "Chg "); 1780 1781 rt->rt_state = state; 1782 rt->rt_spares[0] = *new; 1783 } 1784 1785 1786 /* check for a better route among the spares 1787 */ 1788 static struct rt_spare * 1789 rts_better(struct rt_entry *rt) 1790 { 1791 struct rt_spare *rts, *rts1; 1792 int i; 1793 1794 /* find the best alternative among the spares */ 1795 rts = rt->rt_spares+1; 1796 for (i = NUM_SPARES, rts1 = rts+1; i > 2; i--, rts1++) { 1797 if (BETTER_LINK(rt,rts1,rts)) 1798 rts = rts1; 1799 } 1800 1801 return rts; 1802 } 1803 1804 1805 /* switch to a backup route 1806 */ 1807 void 1808 rtswitch(struct rt_entry *rt, 1809 struct rt_spare *rts) 1810 { 1811 struct rt_spare swap; 1812 char label[10]; 1813 1814 1815 /* Do not change permanent routes */ 1816 if (0 != (rt->rt_state & (RS_MHOME | RS_STATIC | RS_RDISC 1817 | RS_NET_SYN | RS_IF))) 1818 return; 1819 1820 /* find the best alternative among the spares */ 1821 if (rts == 0) 1822 rts = rts_better(rt); 1823 1824 /* Do not bother if it is not worthwhile. 1825 */ 1826 if (!BETTER_LINK(rt, rts, rt->rt_spares)) 1827 return; 1828 1829 swap = rt->rt_spares[0]; 1830 (void)sprintf(label, "Use #%d", (int)(rts - rt->rt_spares)); 1831 rtchange(rt, rt->rt_state & ~(RS_NET_SYN | RS_RDISC), rts, label); 1832 if (swap.rts_metric == HOPCNT_INFINITY) { 1833 *rts = rts_empty; 1834 } else { 1835 *rts = swap; 1836 } 1837 } 1838 1839 1840 void 1841 rtdelete(struct rt_entry *rt) 1842 { 1843 struct khash *k; 1844 1845 1846 if (TRACEACTIONS) 1847 trace_add_del("Del", rt); 1848 1849 k = kern_find(rt->rt_dst, rt->rt_mask, 0); 1850 if (k != 0) { 1851 k->k_state |= KS_DELETE; 1852 need_kern.tv_sec = now.tv_sec; 1853 } 1854 1855 dst_sock.sin_addr.s_addr = rt->rt_dst; 1856 mask_sock.sin_addr.s_addr = htonl(rt->rt_mask); 1857 masktrim(&mask_sock); 1858 if (rt != (struct rt_entry *)rhead->rnh_deladdr(&dst_sock, &mask_sock, 1859 rhead)) { 1860 msglog("rnh_deladdr() failed"); 1861 } else { 1862 free(rt); 1863 total_routes--; 1864 } 1865 } 1866 1867 1868 void 1869 rts_delete(struct rt_entry *rt, 1870 struct rt_spare *rts) 1871 { 1872 trace_upslot(rt, rts, &rts_empty); 1873 *rts = rts_empty; 1874 } 1875 1876 1877 /* Get rid of a bad route, and try to switch to a replacement. 1878 */ 1879 void 1880 rtbad(struct rt_entry *rt) 1881 { 1882 struct rt_spare new; 1883 1884 /* Poison the route */ 1885 new = rt->rt_spares[0]; 1886 new.rts_metric = HOPCNT_INFINITY; 1887 rtchange(rt, rt->rt_state & ~(RS_IF | RS_LOCAL | RS_STATIC), &new, 0); 1888 rtswitch(rt, 0); 1889 } 1890 1891 1892 /* Junk a RS_NET_SYN or RS_LOCAL route, 1893 * unless it is needed by another interface. 1894 */ 1895 void 1896 rtbad_sub(struct rt_entry *rt) 1897 { 1898 struct interface *ifp, *ifp1; 1899 struct intnet *intnetp; 1900 u_int state; 1901 1902 1903 ifp1 = 0; 1904 state = 0; 1905 1906 if (rt->rt_state & RS_LOCAL) { 1907 /* Is this the route through loopback for the interface? 1908 * If so, see if it is used by any other interfaces, such 1909 * as a point-to-point interface with the same local address. 1910 */ 1911 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 1912 /* Retain it if another interface needs it. 1913 */ 1914 if (ifp->int_addr == rt->rt_ifp->int_addr) { 1915 state |= RS_LOCAL; 1916 ifp1 = ifp; 1917 break; 1918 } 1919 } 1920 1921 } 1922 1923 if (!(state & RS_LOCAL)) { 1924 /* Retain RIPv1 logical network route if there is another 1925 * interface that justifies it. 1926 */ 1927 if (rt->rt_state & RS_NET_SYN) { 1928 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 1929 if ((ifp->int_state & IS_NEED_NET_SYN) 1930 && rt->rt_mask == ifp->int_std_mask 1931 && rt->rt_dst == ifp->int_std_addr) { 1932 state |= RS_NET_SYN; 1933 ifp1 = ifp; 1934 break; 1935 } 1936 } 1937 } 1938 1939 /* or if there is an authority route that needs it. */ 1940 for (intnetp = intnets; 1941 intnetp != 0; 1942 intnetp = intnetp->intnet_next) { 1943 if (intnetp->intnet_addr == rt->rt_dst 1944 && intnetp->intnet_mask == rt->rt_mask) { 1945 state |= (RS_NET_SYN | RS_NET_INT); 1946 break; 1947 } 1948 } 1949 } 1950 1951 if (ifp1 != 0 || (state & RS_NET_SYN)) { 1952 struct rt_spare new = rt->rt_spares[0]; 1953 new.rts_ifp = ifp1; 1954 rtchange(rt, ((rt->rt_state & ~(RS_NET_SYN|RS_LOCAL)) | state), 1955 &new, 0); 1956 } else { 1957 rtbad(rt); 1958 } 1959 } 1960 1961 1962 /* Called while walking the table looking for sick interfaces 1963 * or after a time change. 1964 */ 1965 /* ARGSUSED */ 1966 int 1967 walk_bad(struct radix_node *rn, 1968 struct walkarg *argp UNUSED) 1969 { 1970 #define RT ((struct rt_entry *)rn) 1971 struct rt_spare *rts; 1972 int i; 1973 1974 1975 /* fix any spare routes through the interface 1976 */ 1977 rts = RT->rt_spares; 1978 for (i = NUM_SPARES; i != 1; i--) { 1979 rts++; 1980 if (rts->rts_metric < HOPCNT_INFINITY 1981 && (rts->rts_ifp == 0 1982 || (rts->rts_ifp->int_state & IS_BROKE))) 1983 rts_delete(RT, rts); 1984 } 1985 1986 /* Deal with the main route 1987 */ 1988 /* finished if it has been handled before or if its interface is ok 1989 */ 1990 if (RT->rt_ifp == 0 || !(RT->rt_ifp->int_state & IS_BROKE)) 1991 return 0; 1992 1993 /* Bad routes for other than interfaces are easy. 1994 */ 1995 if (0 == (RT->rt_state & (RS_IF | RS_NET_SYN | RS_LOCAL))) { 1996 rtbad(RT); 1997 return 0; 1998 } 1999 2000 rtbad_sub(RT); 2001 return 0; 2002 #undef RT 2003 } 2004 2005 2006 /* Check the age of an individual route. 2007 */ 2008 /* ARGSUSED */ 2009 static int 2010 walk_age(struct radix_node *rn, 2011 struct walkarg *argp UNUSED) 2012 { 2013 #define RT ((struct rt_entry *)rn) 2014 struct interface *ifp; 2015 struct rt_spare *rts; 2016 int i; 2017 2018 2019 /* age all of the spare routes, including the primary route 2020 * currently in use 2021 */ 2022 rts = RT->rt_spares; 2023 for (i = NUM_SPARES; i != 0; i--, rts++) { 2024 2025 ifp = rts->rts_ifp; 2026 if (i == NUM_SPARES) { 2027 if (!AGE_RT(RT->rt_state, ifp)) { 2028 /* Keep various things from deciding ageless 2029 * routes are stale 2030 */ 2031 rts->rts_time = now.tv_sec; 2032 continue; 2033 } 2034 2035 /* forget RIP routes after RIP has been turned off. 2036 */ 2037 if (rip_sock < 0) { 2038 rtdelete(RT); 2039 return 0; 2040 } 2041 } 2042 2043 /* age failing routes 2044 */ 2045 if (age_bad_gate == rts->rts_gate 2046 && rts->rts_time >= now_stale) { 2047 rts->rts_time -= SUPPLY_INTERVAL; 2048 } 2049 2050 /* trash the spare routes when they go bad */ 2051 if (rts->rts_metric < HOPCNT_INFINITY 2052 && now_garbage > rts->rts_time 2053 && i != NUM_SPARES) 2054 rts_delete(RT, rts); 2055 } 2056 2057 2058 /* finished if the active route is still fresh */ 2059 if (now_stale <= RT->rt_time) 2060 return 0; 2061 2062 /* try to switch to an alternative */ 2063 rtswitch(RT, 0); 2064 2065 /* Delete a dead route after it has been publically mourned. */ 2066 if (now_garbage > RT->rt_time) { 2067 rtdelete(RT); 2068 return 0; 2069 } 2070 2071 /* Start poisoning a bad route before deleting it. */ 2072 if (now.tv_sec - RT->rt_time > EXPIRE_TIME) { 2073 struct rt_spare new = RT->rt_spares[0]; 2074 new.rts_metric = HOPCNT_INFINITY; 2075 rtchange(RT, RT->rt_state, &new, 0); 2076 } 2077 return 0; 2078 } 2079 2080 2081 /* Watch for dead routes and interfaces. 2082 */ 2083 void 2084 age(naddr bad_gate) 2085 { 2086 struct interface *ifp; 2087 int need_query = 0; 2088 2089 /* If not listening to RIP, there is no need to age the routes in 2090 * the table. 2091 */ 2092 age_timer.tv_sec = (now.tv_sec 2093 + ((rip_sock < 0) ? NEVER : SUPPLY_INTERVAL)); 2094 2095 /* Check for dead IS_REMOTE interfaces by timing their 2096 * transmissions. 2097 */ 2098 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 2099 if (!(ifp->int_state & IS_REMOTE)) 2100 continue; 2101 2102 /* ignore unreachable remote interfaces */ 2103 if (!check_remote(ifp)) 2104 continue; 2105 2106 /* Restore remote interface that has become reachable 2107 */ 2108 if (ifp->int_state & IS_BROKE) 2109 if_ok(ifp, "remote "); 2110 2111 if (ifp->int_act_time != NEVER 2112 && now.tv_sec - ifp->int_act_time > EXPIRE_TIME) { 2113 msglog("remote interface %s to %s timed out after" 2114 " %ld:%ld", 2115 ifp->int_name, 2116 naddr_ntoa(ifp->int_dstaddr), 2117 (now.tv_sec - ifp->int_act_time)/60, 2118 (now.tv_sec - ifp->int_act_time)%60); 2119 if_sick(ifp); 2120 } 2121 2122 /* If we have not heard from the other router 2123 * recently, ask it. 2124 */ 2125 if (now.tv_sec >= ifp->int_query_time) { 2126 ifp->int_query_time = NEVER; 2127 need_query = 1; 2128 } 2129 } 2130 2131 /* Age routes. */ 2132 age_bad_gate = bad_gate; 2133 (void)rn_walktree(rhead, walk_age, 0); 2134 2135 /* delete old redirected routes to keep the kernel table small 2136 * and prevent blackholes 2137 */ 2138 del_redirects(bad_gate, now.tv_sec-STALE_TIME); 2139 2140 /* Update the kernel routing table. */ 2141 fix_kern(); 2142 2143 /* poke reticent remote gateways */ 2144 if (need_query) 2145 rip_query(); 2146 } 2147