1 /* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <stdint.h> 33 34 #include "defs.h" 35 #include "pathnames.h" 36 37 #ifdef __NetBSD__ 38 __RCSID("$NetBSD$"); 39 #elif defined(__FreeBSD__) 40 __RCSID("$FreeBSD$"); 41 #else 42 __RCSID("$Revision: 2.27 $"); 43 #ident "$Revision: 2.27 $" 44 #endif 45 46 struct ifhead ifnet = LIST_HEAD_INITIALIZER(ifnet); /* all interfaces */ 47 struct ifhead remote_if = LIST_HEAD_INITIALIZER(remote_if); /* remote interfaces */ 48 49 /* hash table for all interfaces, big enough to tolerate ridiculous 50 * numbers of IP aliases. Crazy numbers of aliases such as 7000 51 * still will not do well, but not just in looking up interfaces 52 * by name or address. 53 */ 54 #define AHASH_LEN 211 /* must be prime */ 55 #define AHASH(a) &ahash_tbl[(a)%AHASH_LEN] 56 static struct interface *ahash_tbl[AHASH_LEN]; 57 58 #define BHASH_LEN 211 /* must be prime */ 59 #define BHASH(a) &bhash_tbl[(a)%BHASH_LEN] 60 static struct interface *bhash_tbl[BHASH_LEN]; 61 62 63 /* hash for physical interface names. 64 * Assume there are never more 100 or 200 real interfaces, and that 65 * aliases are put on the end of the hash chains. 66 */ 67 #define NHASH_LEN 97 68 static struct interface *nhash_tbl[NHASH_LEN]; 69 70 int tot_interfaces; /* # of remote and local interfaces */ 71 int rip_interfaces; /* # of interfaces doing RIP */ 72 static int foundloopback; /* valid flag for loopaddr */ 73 naddr loopaddr; /* our address on loopback */ 74 static struct rt_spare loop_rts; 75 76 struct timeval ifinit_timer; 77 static struct timeval last_ifinit; 78 #define IF_RESCAN_DELAY() (last_ifinit.tv_sec == now.tv_sec \ 79 && last_ifinit.tv_usec == now.tv_usec \ 80 && timercmp(&ifinit_timer, &now, >)) 81 82 int have_ripv1_out; /* have a RIPv1 interface */ 83 static int have_ripv1_in; 84 85 86 static void if_bad(struct interface *); 87 static int addrouteforif(struct interface *); 88 89 static struct interface** 90 nhash(char *p) 91 { 92 u_int i; 93 94 for (i = 0; *p != '\0'; p++) { 95 i = ((i<<1) & 0x7fffffff) | ((i>>31) & 1); 96 i ^= *p; 97 } 98 return &nhash_tbl[i % NHASH_LEN]; 99 } 100 101 102 /* Link a new interface into the lists and hash tables. 103 */ 104 void 105 if_link(struct interface *ifp) 106 { 107 struct interface **hifp; 108 109 LIST_INSERT_HEAD(&ifnet, ifp, int_list); 110 111 hifp = AHASH(ifp->int_addr); 112 ifp->int_ahash_prev = hifp; 113 if ((ifp->int_ahash = *hifp) != 0) 114 (*hifp)->int_ahash_prev = &ifp->int_ahash; 115 *hifp = ifp; 116 117 if (ifp->int_if_flags & IFF_BROADCAST) { 118 hifp = BHASH(ifp->int_brdaddr); 119 ifp->int_bhash_prev = hifp; 120 if ((ifp->int_bhash = *hifp) != 0) 121 (*hifp)->int_bhash_prev = &ifp->int_bhash; 122 *hifp = ifp; 123 } 124 125 if (ifp->int_state & IS_REMOTE) 126 LIST_INSERT_HEAD(&remote_if, ifp, remote_list); 127 128 hifp = nhash(ifp->int_name); 129 if (ifp->int_state & IS_ALIAS) { 130 /* put aliases on the end of the hash chain */ 131 while (*hifp != 0) 132 hifp = &(*hifp)->int_nhash; 133 } 134 ifp->int_nhash_prev = hifp; 135 if ((ifp->int_nhash = *hifp) != 0) 136 (*hifp)->int_nhash_prev = &ifp->int_nhash; 137 *hifp = ifp; 138 } 139 140 141 /* Find the interface with an address 142 */ 143 struct interface * 144 ifwithaddr(naddr addr, 145 int bcast, /* notice IFF_BROADCAST address */ 146 int remote) /* include IS_REMOTE interfaces */ 147 { 148 struct interface *ifp, *possible = 0; 149 150 remote = (remote == 0) ? IS_REMOTE : 0; 151 152 for (ifp = *AHASH(addr); ifp; ifp = ifp->int_ahash) { 153 if (ifp->int_addr != addr) 154 continue; 155 if ((ifp->int_state & remote) != 0) 156 continue; 157 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0) 158 return ifp; 159 possible = ifp; 160 } 161 162 if (possible || !bcast) 163 return possible; 164 165 for (ifp = *BHASH(addr); ifp; ifp = ifp->int_bhash) { 166 if (ifp->int_brdaddr != addr) 167 continue; 168 if ((ifp->int_state & remote) != 0) 169 continue; 170 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0) 171 return ifp; 172 possible = ifp; 173 } 174 175 return possible; 176 } 177 178 179 /* find the interface with a name 180 */ 181 static struct interface * 182 ifwithname(char *name, /* "ec0" or whatever */ 183 naddr addr) /* 0 or network address */ 184 { 185 struct interface *ifp; 186 187 for (;;) { 188 for (ifp = *nhash(name); ifp != 0; ifp = ifp->int_nhash) { 189 /* If the network address is not specified, 190 * ignore any alias interfaces. Otherwise, look 191 * for the interface with the target name and address. 192 */ 193 if (!strcmp(ifp->int_name, name) 194 && ((addr == 0 && !(ifp->int_state & IS_ALIAS)) 195 || (ifp->int_addr == addr))) 196 return ifp; 197 } 198 199 /* If there is no known interface, maybe there is a 200 * new interface. So just once look for new interfaces. 201 */ 202 if (IF_RESCAN_DELAY()) 203 return 0; 204 ifinit(); 205 } 206 } 207 208 209 struct interface * 210 ifwithindex(u_short ifindex, 211 int rescan_ok) 212 { 213 struct interface *ifp; 214 215 for (;;) { 216 LIST_FOREACH(ifp, &ifnet, int_list) { 217 if (ifp->int_index == ifindex) 218 return ifp; 219 } 220 221 /* If there is no known interface, maybe there is a 222 * new interface. So just once look for new interfaces. 223 */ 224 if (!rescan_ok 225 || IF_RESCAN_DELAY()) 226 return 0; 227 ifinit(); 228 } 229 } 230 231 232 /* Find an interface from which the specified address 233 * should have come from. Used for figuring out which 234 * interface a packet came in on. 235 */ 236 struct interface * 237 iflookup(naddr addr) 238 { 239 struct interface *ifp, *maybe; 240 int once = 0; 241 242 maybe = 0; 243 for (;;) { 244 LIST_FOREACH(ifp, &ifnet, int_list) { 245 if (ifp->int_if_flags & IFF_POINTOPOINT) { 246 /* finished with a match */ 247 if (ifp->int_dstaddr == addr) 248 return ifp; 249 250 } else { 251 /* finished with an exact match */ 252 if (ifp->int_addr == addr) 253 return ifp; 254 255 /* Look for the longest approximate match. 256 */ 257 if (on_net(addr, ifp->int_net, ifp->int_mask) 258 && (maybe == 0 259 || ifp->int_mask > maybe->int_mask)) 260 maybe = ifp; 261 } 262 } 263 264 if (maybe != 0 || once || IF_RESCAN_DELAY()) 265 return maybe; 266 once = 1; 267 268 /* If there is no known interface, maybe there is a 269 * new interface. So just once look for new interfaces. 270 */ 271 ifinit(); 272 } 273 } 274 275 276 /* Return the classical netmask for an IP address. 277 */ 278 naddr /* host byte order */ 279 std_mask(naddr addr) /* network byte order */ 280 { 281 addr = ntohl(addr); /* was a host, not a network */ 282 283 if (addr == 0) /* default route has mask 0 */ 284 return 0; 285 if (IN_CLASSA(addr)) 286 return IN_CLASSA_NET; 287 if (IN_CLASSB(addr)) 288 return IN_CLASSB_NET; 289 return IN_CLASSC_NET; 290 } 291 292 293 /* Find the netmask that would be inferred by RIPv1 listeners 294 * on the given interface for a given network. 295 * If no interface is specified, look for the best fitting interface. 296 */ 297 naddr 298 ripv1_mask_net(naddr addr, /* in network byte order */ 299 struct interface *ifp) /* as seen on this interface */ 300 { 301 struct r1net *r1p; 302 naddr mask = 0; 303 304 if (addr == 0) /* default always has 0 mask */ 305 return mask; 306 307 if (ifp != 0 && ifp->int_ripv1_mask != HOST_MASK) { 308 /* If the target network is that of the associated interface 309 * on which it arrived, then use the netmask of the interface. 310 */ 311 if (on_net(addr, ifp->int_net, ifp->int_std_mask)) 312 mask = ifp->int_ripv1_mask; 313 314 } else { 315 /* Examine all interfaces, and if it the target seems 316 * to have the same network number of an interface, use the 317 * netmask of that interface. If there is more than one 318 * such interface, prefer the interface with the longest 319 * match. 320 */ 321 LIST_FOREACH(ifp, &ifnet, int_list) { 322 if (on_net(addr, ifp->int_std_net, ifp->int_std_mask) 323 && ifp->int_ripv1_mask > mask 324 && ifp->int_ripv1_mask != HOST_MASK) 325 mask = ifp->int_ripv1_mask; 326 } 327 328 } 329 330 /* check special definitions */ 331 if (mask == 0) { 332 for (r1p = r1nets; r1p != 0; r1p = r1p->r1net_next) { 333 if (on_net(addr, r1p->r1net_net, r1p->r1net_match) 334 && r1p->r1net_mask > mask) 335 mask = r1p->r1net_mask; 336 } 337 338 /* Otherwise, make the classic A/B/C guess. 339 */ 340 if (mask == 0) 341 mask = std_mask(addr); 342 } 343 344 return mask; 345 } 346 347 348 naddr 349 ripv1_mask_host(naddr addr, /* in network byte order */ 350 struct interface *ifp) /* as seen on this interface */ 351 { 352 naddr mask = ripv1_mask_net(addr, ifp); 353 354 355 /* If the computed netmask does not mask the address, 356 * then assume it is a host address 357 */ 358 if ((ntohl(addr) & ~mask) != 0) 359 mask = HOST_MASK; 360 return mask; 361 } 362 363 364 /* See if an IP address looks reasonable as a destination. 365 */ 366 int /* 0=bad */ 367 check_dst(naddr addr) 368 { 369 addr = ntohl(addr); 370 371 if (IN_CLASSA(addr)) { 372 if (addr == 0) 373 return 1; /* default */ 374 375 addr >>= IN_CLASSA_NSHIFT; 376 return (addr != 0 && addr != IN_LOOPBACKNET); 377 } 378 379 return (IN_CLASSB(addr) || IN_CLASSC(addr)); 380 } 381 382 383 /* See a new interface duplicates an existing interface. 384 */ 385 struct interface * 386 check_dup(naddr addr, /* IP address, so network byte order */ 387 naddr dstaddr, /* ditto */ 388 naddr mask, /* mask, so host byte order */ 389 int if_flags) 390 { 391 struct interface *ifp; 392 393 LIST_FOREACH(ifp, &ifnet, int_list) { 394 if (ifp->int_mask != mask) 395 continue; 396 397 if (!iff_up(ifp->int_if_flags)) 398 continue; 399 400 /* The local address can only be shared with a point-to-point 401 * link. 402 */ 403 if ((!(ifp->int_state & IS_REMOTE) || !(if_flags & IS_REMOTE)) 404 && ifp->int_addr == addr 405 && (((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0)) 406 return ifp; 407 408 if (on_net(ifp->int_dstaddr, ntohl(dstaddr),mask)) 409 return ifp; 410 } 411 return 0; 412 } 413 414 415 /* See that a remote gateway is reachable. 416 * Note that the answer can change as real interfaces come and go. 417 */ 418 int /* 0=bad */ 419 check_remote(struct interface *ifp) 420 { 421 struct rt_entry *rt; 422 423 /* do not worry about other kinds */ 424 if (!(ifp->int_state & IS_REMOTE)) 425 return 1; 426 427 rt = rtfind(ifp->int_addr); 428 if (rt != 0 429 && rt->rt_ifp != 0 430 &&on_net(ifp->int_addr, 431 rt->rt_ifp->int_net, rt->rt_ifp->int_mask)) 432 return 1; 433 434 /* the gateway cannot be reached directly from one of our 435 * interfaces 436 */ 437 if (!(ifp->int_state & IS_BROKE)) { 438 msglog("unreachable gateway %s in "_PATH_GATEWAYS, 439 naddr_ntoa(ifp->int_addr)); 440 if_bad(ifp); 441 } 442 return 0; 443 } 444 445 446 /* Delete an interface. 447 */ 448 static void 449 ifdel(struct interface *ifp) 450 { 451 struct interface *ifp1; 452 453 454 trace_if("Del", ifp); 455 456 ifp->int_state |= IS_BROKE; 457 458 LIST_REMOVE(ifp, int_list); 459 *ifp->int_ahash_prev = ifp->int_ahash; 460 if (ifp->int_ahash != 0) 461 ifp->int_ahash->int_ahash_prev = ifp->int_ahash_prev; 462 *ifp->int_nhash_prev = ifp->int_nhash; 463 if (ifp->int_nhash != 0) 464 ifp->int_nhash->int_nhash_prev = ifp->int_nhash_prev; 465 if (ifp->int_if_flags & IFF_BROADCAST) { 466 *ifp->int_bhash_prev = ifp->int_bhash; 467 if (ifp->int_bhash != 0) 468 ifp->int_bhash->int_bhash_prev = ifp->int_bhash_prev; 469 } 470 if (ifp->int_state & IS_REMOTE) 471 LIST_REMOVE(ifp, remote_list); 472 473 if (!(ifp->int_state & IS_ALIAS)) { 474 /* delete aliases when the main interface dies 475 */ 476 LIST_FOREACH(ifp1, &ifnet, int_list) { 477 if (ifp1 != ifp 478 && !strcmp(ifp->int_name, ifp1->int_name)) 479 ifdel(ifp1); 480 } 481 482 if ((ifp->int_if_flags & IFF_MULTICAST) && rip_sock >= 0) { 483 struct group_req gr; 484 struct sockaddr_in *sin; 485 486 memset(&gr, 0, sizeof(gr)); 487 gr.gr_interface = ifp->int_index; 488 sin = (struct sockaddr_in *)&gr.gr_group; 489 sin->sin_family = AF_INET; 490 #ifdef _HAVE_SIN_LEN 491 sin->sin_len = sizeof(struct sockaddr_in); 492 #endif 493 sin->sin_addr.s_addr = htonl(INADDR_RIP_GROUP); 494 if (setsockopt(rip_sock, IPPROTO_IP, MCAST_LEAVE_GROUP, 495 &gr, sizeof(gr)) < 0 496 && errno != EADDRNOTAVAIL 497 && !TRACEACTIONS) 498 LOGERR("setsockopt(MCAST_LEAVE_GROUP RIP)"); 499 if (rip_sock_mcast == ifp) 500 rip_sock_mcast = 0; 501 } 502 if (ifp->int_rip_sock >= 0) { 503 (void)close(ifp->int_rip_sock); 504 ifp->int_rip_sock = -1; 505 fix_select(); 506 } 507 508 tot_interfaces--; 509 if (!IS_RIP_OFF(ifp->int_state)) 510 rip_interfaces--; 511 512 /* Zap all routes associated with this interface. 513 * Assume routes just using gateways beyond this interface 514 * will timeout naturally, and have probably already died. 515 */ 516 (void)rn_walktree(rhead, walk_bad, 0); 517 518 set_rdisc_mg(ifp, 0); 519 if_bad_rdisc(ifp); 520 } 521 522 free(ifp); 523 } 524 525 526 /* Mark an interface ill. 527 */ 528 void 529 if_sick(struct interface *ifp) 530 { 531 if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) { 532 ifp->int_state |= IS_SICK; 533 ifp->int_act_time = NEVER; 534 trace_if("Chg", ifp); 535 536 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 537 } 538 } 539 540 541 /* Mark an interface dead. 542 */ 543 static void 544 if_bad(struct interface *ifp) 545 { 546 struct interface *ifp1; 547 548 549 if (ifp->int_state & IS_BROKE) 550 return; 551 552 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 553 554 ifp->int_state |= (IS_BROKE | IS_SICK); 555 ifp->int_act_time = NEVER; 556 ifp->int_query_time = NEVER; 557 ifp->int_data.ts = now.tv_sec; 558 559 trace_if("Chg", ifp); 560 561 if (!(ifp->int_state & IS_ALIAS)) { 562 LIST_FOREACH(ifp1, &ifnet, int_list) { 563 if (ifp1 != ifp 564 && !strcmp(ifp->int_name, ifp1->int_name)) 565 if_bad(ifp1); 566 } 567 (void)rn_walktree(rhead, walk_bad, 0); 568 if_bad_rdisc(ifp); 569 } 570 } 571 572 573 /* Mark an interface alive 574 */ 575 int /* 1=it was dead */ 576 if_ok(struct interface *ifp, 577 const char *type) 578 { 579 struct interface *ifp1; 580 581 582 if (!(ifp->int_state & IS_BROKE)) { 583 if (ifp->int_state & IS_SICK) { 584 trace_act("%sinterface %s to %s working better", 585 type, 586 ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 587 ifp->int_state &= ~IS_SICK; 588 } 589 return 0; 590 } 591 592 msglog("%sinterface %s to %s restored", 593 type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 594 ifp->int_state &= ~(IS_BROKE | IS_SICK); 595 ifp->int_data.ts = 0; 596 597 if (!(ifp->int_state & IS_ALIAS)) { 598 LIST_FOREACH(ifp1, &ifnet, int_list) { 599 if (ifp1 != ifp 600 && !strcmp(ifp->int_name, ifp1->int_name)) 601 if_ok(ifp1, type); 602 } 603 if_ok_rdisc(ifp); 604 } 605 606 if (ifp->int_state & IS_REMOTE) { 607 if (!addrouteforif(ifp)) 608 return 0; 609 } 610 return 1; 611 } 612 613 614 /* disassemble routing message 615 */ 616 void 617 rt_xaddrs(struct rt_addrinfo *info, 618 struct sockaddr *sa, 619 struct sockaddr *lim, 620 int addrs) 621 { 622 int i; 623 #ifdef _HAVE_SA_LEN 624 static struct sockaddr sa_zero; 625 #endif 626 627 memset(info, 0, sizeof(*info)); 628 info->rti_addrs = addrs; 629 for (i = 0; i < RTAX_MAX && sa < lim; i++) { 630 if ((addrs & (1 << i)) == 0) 631 continue; 632 info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero; 633 sa = (struct sockaddr *)((char*)(sa) + SA_SIZE(sa)); 634 } 635 } 636 637 638 /* Find the network interfaces which have configured themselves. 639 * This must be done regularly, if only for extra addresses 640 * that come and go on interfaces. 641 */ 642 void 643 ifinit(void) 644 { 645 static struct ifa_msghdr *sysctl_buf; 646 static size_t sysctl_buf_size = 0; 647 uint complaints = 0; 648 static u_int prev_complaints = 0; 649 # define COMP_NOT_INET 0x001 650 # define COMP_NOADDR 0x002 651 # define COMP_BADADDR 0x004 652 # define COMP_NODST 0x008 653 # define COMP_NOBADR 0x010 654 # define COMP_NOMASK 0x020 655 # define COMP_DUP 0x040 656 # define COMP_BAD_METRIC 0x080 657 # define COMP_NETMASK 0x100 658 659 struct interface ifs, ifs0, *ifp, *ifp1; 660 struct rt_entry *rt; 661 size_t needed; 662 int mib[6]; 663 struct if_msghdr *ifm; 664 void *ifam_lim; 665 struct ifa_msghdr *ifam, *ifam2; 666 int in, ierr, out, oerr; 667 struct intnet *intnetp; 668 struct rt_addrinfo info; 669 #ifdef SIOCGIFMETRIC 670 struct ifreq ifr; 671 #endif 672 673 674 last_ifinit = now; 675 ifinit_timer.tv_sec = now.tv_sec + (supplier 676 ? CHECK_ACT_INTERVAL 677 : CHECK_QUIET_INTERVAL); 678 679 /* mark all interfaces so we can get rid of those that disappear */ 680 LIST_FOREACH(ifp, &ifnet, int_list) 681 ifp->int_state &= ~(IS_CHECKED | IS_DUP); 682 683 /* Fetch the interface list, without too many system calls 684 * since we do it repeatedly. 685 */ 686 mib[0] = CTL_NET; 687 mib[1] = PF_ROUTE; 688 mib[2] = 0; 689 mib[3] = AF_INET; 690 mib[4] = NET_RT_IFLIST; 691 mib[5] = 0; 692 for (;;) { 693 if ((needed = sysctl_buf_size) != 0) { 694 if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0) 695 break; 696 /* retry if the table grew */ 697 if (errno != ENOMEM && errno != EFAULT) 698 BADERR(1, "ifinit: sysctl(RT_IFLIST)"); 699 free(sysctl_buf); 700 needed = 0; 701 } 702 if (sysctl(mib, 6, 0, &needed, 0, 0) < 0) 703 BADERR(1,"ifinit: sysctl(RT_IFLIST) estimate"); 704 sysctl_buf = rtmalloc(sysctl_buf_size = needed, 705 "ifinit sysctl"); 706 } 707 708 /* XXX: thanks to malloc(3), alignment can be presumed OK */ 709 ifam_lim = (char *)sysctl_buf + needed; 710 for (ifam = sysctl_buf; (void *)ifam < ifam_lim; ifam = ifam2) { 711 712 ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen); 713 714 #ifdef RTM_OIFINFO 715 if (ifam->ifam_type == RTM_OIFINFO) 716 continue; /* just ignore compat message */ 717 #endif 718 if (ifam->ifam_type == RTM_IFINFO) { 719 struct sockaddr_dl *sdl; 720 721 ifm = (struct if_msghdr *)ifam; 722 /* make prototype structure for the IP aliases 723 */ 724 memset(&ifs0, 0, sizeof(ifs0)); 725 ifs0.int_rip_sock = -1; 726 ifs0.int_index = ifm->ifm_index; 727 ifs0.int_if_flags = ifm->ifm_flags; 728 ifs0.int_state = IS_CHECKED; 729 ifs0.int_query_time = NEVER; 730 ifs0.int_act_time = now.tv_sec; 731 ifs0.int_data.ts = now.tv_sec; 732 ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets; 733 ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors; 734 ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets; 735 ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors; 736 #ifdef sgi 737 ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops; 738 #endif 739 sdl = (struct sockaddr_dl *)(ifm + 1); 740 sdl->sdl_data[sdl->sdl_nlen] = 0; 741 strncpy(ifs0.int_name, sdl->sdl_data, 742 MIN(sizeof(ifs0.int_name), sdl->sdl_nlen)); 743 continue; 744 } 745 if (ifam->ifam_type != RTM_NEWADDR) { 746 logbad(1,"ifinit: out of sync"); 747 continue; 748 } 749 rt_xaddrs(&info, (struct sockaddr *)(ifam+1), 750 (struct sockaddr *)ifam2, 751 ifam->ifam_addrs); 752 753 /* Prepare for the next address of this interface, which 754 * will be an alias. 755 * Do not output RIP or Router-Discovery packets via aliases. 756 */ 757 memcpy(&ifs, &ifs0, sizeof(ifs)); 758 ifs0.int_state |= (IS_ALIAS | IS_NO_RIP_OUT | IS_NO_RDISC); 759 760 if (INFO_IFA(&info) == 0) { 761 if (iff_up(ifs.int_if_flags)) { 762 if (!(prev_complaints & COMP_NOADDR)) 763 msglog("%s has no address", 764 ifs.int_name); 765 complaints |= COMP_NOADDR; 766 } 767 continue; 768 } 769 if (INFO_IFA(&info)->sa_family != AF_INET) { 770 if (iff_up(ifs.int_if_flags)) { 771 if (!(prev_complaints & COMP_NOT_INET)) 772 trace_act("%s: not AF_INET", 773 ifs.int_name); 774 complaints |= COMP_NOT_INET; 775 } 776 continue; 777 } 778 779 ifs.int_addr = S_ADDR(INFO_IFA(&info)); 780 781 if (ntohl(ifs.int_addr)>>24 == 0 782 || ntohl(ifs.int_addr)>>24 == 0xff) { 783 if (iff_up(ifs.int_if_flags)) { 784 if (!(prev_complaints & COMP_BADADDR)) 785 msglog("%s has a bad address", 786 ifs.int_name); 787 complaints |= COMP_BADADDR; 788 } 789 continue; 790 } 791 792 if (ifs.int_if_flags & IFF_LOOPBACK) { 793 ifs.int_state |= IS_NO_RIP | IS_NO_RDISC; 794 if (ifs.int_addr == htonl(INADDR_LOOPBACK)) 795 ifs.int_state |= IS_PASSIVE; 796 ifs.int_dstaddr = ifs.int_addr; 797 ifs.int_mask = HOST_MASK; 798 ifs.int_ripv1_mask = HOST_MASK; 799 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 800 ifs.int_net = ntohl(ifs.int_dstaddr); 801 if (!foundloopback) { 802 foundloopback = 1; 803 loopaddr = ifs.int_addr; 804 loop_rts.rts_gate = loopaddr; 805 loop_rts.rts_router = loopaddr; 806 } 807 808 } else if (ifs.int_if_flags & IFF_POINTOPOINT) { 809 if (INFO_BRD(&info) == 0 810 || INFO_BRD(&info)->sa_family != AF_INET) { 811 if (iff_up(ifs.int_if_flags)) { 812 if (!(prev_complaints & COMP_NODST)) 813 msglog("%s has a bad" 814 " destination address", 815 ifs.int_name); 816 complaints |= COMP_NODST; 817 } 818 continue; 819 } 820 ifs.int_dstaddr = S_ADDR(INFO_BRD(&info)); 821 if (ntohl(ifs.int_dstaddr)>>24 == 0 822 || ntohl(ifs.int_dstaddr)>>24 == 0xff) { 823 if (iff_up(ifs.int_if_flags)) { 824 if (!(prev_complaints & COMP_NODST)) 825 msglog("%s has a bad" 826 " destination address", 827 ifs.int_name); 828 complaints |= COMP_NODST; 829 } 830 continue; 831 } 832 ifs.int_mask = HOST_MASK; 833 ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info))); 834 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 835 ifs.int_net = ntohl(ifs.int_dstaddr); 836 837 } else { 838 if (INFO_MASK(&info) == 0) { 839 if (iff_up(ifs.int_if_flags)) { 840 if (!(prev_complaints & COMP_NOMASK)) 841 msglog("%s has no netmask", 842 ifs.int_name); 843 complaints |= COMP_NOMASK; 844 } 845 continue; 846 } 847 ifs.int_dstaddr = ifs.int_addr; 848 ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info))); 849 ifs.int_ripv1_mask = ifs.int_mask; 850 ifs.int_std_mask = std_mask(ifs.int_addr); 851 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask; 852 if (ifs.int_mask != ifs.int_std_mask) 853 ifs.int_state |= IS_SUBNET; 854 855 if (ifs.int_if_flags & IFF_BROADCAST) { 856 if (INFO_BRD(&info) == 0) { 857 if (iff_up(ifs.int_if_flags)) { 858 if (!(prev_complaints 859 & COMP_NOBADR)) 860 msglog("%s has" 861 "no broadcast address", 862 ifs.int_name); 863 complaints |= COMP_NOBADR; 864 } 865 continue; 866 } 867 ifs.int_brdaddr = S_ADDR(INFO_BRD(&info)); 868 } 869 } 870 ifs.int_std_net = ifs.int_net & ifs.int_std_mask; 871 ifs.int_std_addr = htonl(ifs.int_std_net); 872 873 /* Use a minimum metric of one. Treat the interface metric 874 * (default 0) as an increment to the hop count of one. 875 * 876 * The metric obtained from the routing socket dump of 877 * interface addresses is wrong. It is not set by the 878 * SIOCSIFMETRIC ioctl. 879 */ 880 #ifdef SIOCGIFMETRIC 881 strncpy(ifr.ifr_name, ifs.int_name, sizeof(ifr.ifr_name)); 882 if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) { 883 DBGERR(1, "ioctl(SIOCGIFMETRIC)"); 884 ifs.int_metric = 0; 885 } else { 886 ifs.int_metric = ifr.ifr_metric; 887 } 888 #else 889 ifs.int_metric = ifam->ifam_metric; 890 #endif 891 if (ifs.int_metric > HOPCNT_INFINITY) { 892 ifs.int_metric = 0; 893 if (!(prev_complaints & COMP_BAD_METRIC) 894 && iff_up(ifs.int_if_flags)) { 895 complaints |= COMP_BAD_METRIC; 896 msglog("%s has a metric of %d", 897 ifs.int_name, ifs.int_metric); 898 } 899 } 900 901 /* See if this is a familiar interface. 902 * If so, stop worrying about it if it is the same. 903 * Start it over if it now is to somewhere else, as happens 904 * frequently with PPP and SLIP. 905 */ 906 ifp = ifwithname(ifs.int_name, ((ifs.int_state & IS_ALIAS) 907 ? ifs.int_addr 908 : 0)); 909 if (ifp != 0) { 910 ifp->int_state |= IS_CHECKED; 911 912 if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags) 913 & (IFF_BROADCAST 914 | IFF_LOOPBACK 915 | IFF_POINTOPOINT 916 | IFF_MULTICAST)) 917 || 0 != ((ifp->int_state ^ ifs.int_state) 918 & IS_ALIAS) 919 || ifp->int_addr != ifs.int_addr 920 || ifp->int_brdaddr != ifs.int_brdaddr 921 || ifp->int_dstaddr != ifs.int_dstaddr 922 || ifp->int_mask != ifs.int_mask 923 || ifp->int_metric != ifs.int_metric) { 924 /* Forget old information about 925 * a changed interface. 926 */ 927 trace_act("interface %s has changed", 928 ifp->int_name); 929 ifdel(ifp); 930 ifp = 0; 931 } 932 } 933 934 if (ifp != 0) { 935 /* The primary representative of an alias worries 936 * about how things are working. 937 */ 938 if (ifp->int_state & IS_ALIAS) 939 continue; 940 941 /* note interfaces that have been turned off 942 */ 943 if (!iff_up(ifs.int_if_flags)) { 944 if (iff_up(ifp->int_if_flags)) { 945 msglog("interface %s to %s turned off", 946 ifp->int_name, 947 naddr_ntoa(ifp->int_dstaddr)); 948 if_bad(ifp); 949 ifp->int_if_flags &= ~IFF_UP; 950 } else if (now.tv_sec>(ifp->int_data.ts 951 + CHECK_BAD_INTERVAL)) { 952 trace_act("interface %s has been off" 953 " %jd seconds; forget it", 954 ifp->int_name, 955 (intmax_t)now.tv_sec - 956 ifp->int_data.ts); 957 ifdel(ifp); 958 } 959 continue; 960 } 961 /* or that were off and are now ok */ 962 if (!iff_up(ifp->int_if_flags)) { 963 ifp->int_if_flags |= IFF_UP; 964 (void)if_ok(ifp, ""); 965 } 966 967 /* If it has been long enough, 968 * see if the interface is broken. 969 */ 970 if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL) 971 continue; 972 973 in = ifs.int_data.ipackets - ifp->int_data.ipackets; 974 ierr = ifs.int_data.ierrors - ifp->int_data.ierrors; 975 out = ifs.int_data.opackets - ifp->int_data.opackets; 976 oerr = ifs.int_data.oerrors - ifp->int_data.oerrors; 977 #ifdef sgi 978 /* Through at least IRIX 6.2, PPP and SLIP 979 * count packets dropped by the filters. 980 * But FDDI rings stuck non-operational count 981 * dropped packets as they wait for improvement. 982 */ 983 if (!(ifp->int_if_flags & IFF_POINTOPOINT)) 984 oerr += (ifs.int_data.odrops 985 - ifp->int_data.odrops); 986 #endif 987 /* If the interface just awoke, restart the counters. 988 */ 989 if (ifp->int_data.ts == 0) { 990 ifp->int_data = ifs.int_data; 991 continue; 992 } 993 ifp->int_data = ifs.int_data; 994 995 /* Withhold judgment when the short error 996 * counters wrap or the interface is reset. 997 */ 998 if (ierr < 0 || in < 0 || oerr < 0 || out < 0) { 999 LIM_SEC(ifinit_timer, 1000 now.tv_sec+CHECK_BAD_INTERVAL); 1001 continue; 1002 } 1003 1004 /* Withhold judgement when there is no traffic 1005 */ 1006 if (in == 0 && out == 0 && ierr == 0 && oerr == 0) 1007 continue; 1008 1009 /* It is bad if input or output is not working. 1010 * Require presistent problems before marking it dead. 1011 */ 1012 if ((in <= ierr && ierr > 0) 1013 || (out <= oerr && oerr > 0)) { 1014 if (!(ifp->int_state & IS_SICK)) { 1015 trace_act("interface %s to %s" 1016 " sick: in=%d ierr=%d" 1017 " out=%d oerr=%d", 1018 ifp->int_name, 1019 naddr_ntoa(ifp->int_dstaddr), 1020 in, ierr, out, oerr); 1021 if_sick(ifp); 1022 continue; 1023 } 1024 if (!(ifp->int_state & IS_BROKE)) { 1025 msglog("interface %s to %s broken:" 1026 " in=%d ierr=%d out=%d oerr=%d", 1027 ifp->int_name, 1028 naddr_ntoa(ifp->int_dstaddr), 1029 in, ierr, out, oerr); 1030 if_bad(ifp); 1031 } 1032 continue; 1033 } 1034 1035 /* otherwise, it is active and healthy 1036 */ 1037 ifp->int_act_time = now.tv_sec; 1038 (void)if_ok(ifp, ""); 1039 continue; 1040 } 1041 1042 /* This is a new interface. 1043 * If it is dead, forget it. 1044 */ 1045 if (!iff_up(ifs.int_if_flags)) 1046 continue; 1047 1048 /* If it duplicates an existing interface, 1049 * complain about it, mark the other one 1050 * duplicated, and forget this one. 1051 */ 1052 ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask, 1053 ifs.int_if_flags); 1054 if (ifp != 0) { 1055 /* Ignore duplicates of itself, caused by having 1056 * IP aliases on the same network. 1057 */ 1058 if (!strcmp(ifp->int_name, ifs.int_name)) 1059 continue; 1060 1061 if (!(prev_complaints & COMP_DUP)) { 1062 complaints |= COMP_DUP; 1063 msglog("%s (%s%s%s) is duplicated by" 1064 " %s (%s%s%s)", 1065 ifs.int_name, 1066 addrname(ifs.int_addr,ifs.int_mask,1), 1067 ((ifs.int_if_flags & IFF_POINTOPOINT) 1068 ? "-->" : ""), 1069 ((ifs.int_if_flags & IFF_POINTOPOINT) 1070 ? naddr_ntoa(ifs.int_dstaddr) : ""), 1071 ifp->int_name, 1072 addrname(ifp->int_addr,ifp->int_mask,1), 1073 ((ifp->int_if_flags & IFF_POINTOPOINT) 1074 ? "-->" : ""), 1075 ((ifp->int_if_flags & IFF_POINTOPOINT) 1076 ? naddr_ntoa(ifp->int_dstaddr) : "")); 1077 } 1078 ifp->int_state |= IS_DUP; 1079 continue; 1080 } 1081 1082 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | IFF_BROADCAST | IFF_LOOPBACK))) { 1083 trace_act("%s is neither broadcast, point-to-point," 1084 " nor loopback", 1085 ifs.int_name); 1086 if (!(ifs.int_state & IFF_MULTICAST)) 1087 ifs.int_state |= IS_NO_RDISC; 1088 } 1089 1090 1091 /* It is new and ok. Add it to the list of interfaces 1092 */ 1093 ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit ifp"); 1094 memcpy(ifp, &ifs, sizeof(*ifp)); 1095 get_parms(ifp); 1096 if_link(ifp); 1097 trace_if("Add", ifp); 1098 1099 /* Notice likely bad netmask. 1100 */ 1101 if (!(prev_complaints & COMP_NETMASK) 1102 && !(ifp->int_if_flags & IFF_POINTOPOINT) 1103 && ifp->int_addr != RIP_DEFAULT) { 1104 LIST_FOREACH(ifp1, &ifnet, int_list) { 1105 if (ifp1->int_mask == ifp->int_mask) 1106 continue; 1107 if (ifp1->int_if_flags & IFF_POINTOPOINT) 1108 continue; 1109 if (ifp1->int_dstaddr == RIP_DEFAULT) 1110 continue; 1111 /* ignore aliases on the right network */ 1112 if (!strcmp(ifp->int_name, ifp1->int_name)) 1113 continue; 1114 if (on_net(ifp->int_dstaddr, 1115 ifp1->int_net, ifp1->int_mask) 1116 || on_net(ifp1->int_dstaddr, 1117 ifp->int_net, ifp->int_mask)) { 1118 msglog("possible netmask problem" 1119 " between %s:%s and %s:%s", 1120 ifp->int_name, 1121 addrname(htonl(ifp->int_net), 1122 ifp->int_mask, 1), 1123 ifp1->int_name, 1124 addrname(htonl(ifp1->int_net), 1125 ifp1->int_mask, 1)); 1126 complaints |= COMP_NETMASK; 1127 } 1128 } 1129 } 1130 1131 if (!(ifp->int_state & IS_ALIAS)) { 1132 /* Count the # of directly connected networks. 1133 */ 1134 if (!(ifp->int_if_flags & IFF_LOOPBACK)) 1135 tot_interfaces++; 1136 if (!IS_RIP_OFF(ifp->int_state)) 1137 rip_interfaces++; 1138 1139 /* turn on router discovery and RIP If needed */ 1140 if_ok_rdisc(ifp); 1141 rip_on(ifp); 1142 } 1143 } 1144 1145 /* If we are multi-homed and have at least two interfaces 1146 * listening to RIP, then output by default. 1147 */ 1148 if (!supplier_set && rip_interfaces > 1) 1149 set_supplier(); 1150 1151 /* If we are multi-homed, optionally advertise a route to 1152 * our main address. 1153 */ 1154 if (advertise_mhome 1155 || (tot_interfaces > 1 1156 && mhome 1157 && (ifp = ifwithaddr(myaddr, 0, 0)) != 0 1158 && foundloopback)) { 1159 advertise_mhome = 1; 1160 rt = rtget(myaddr, HOST_MASK); 1161 if (rt != 0) { 1162 if (rt->rt_ifp != ifp 1163 || rt->rt_router != loopaddr) { 1164 rtdelete(rt); 1165 rt = 0; 1166 } else { 1167 loop_rts.rts_ifp = ifp; 1168 loop_rts.rts_metric = 0; 1169 loop_rts.rts_time = rt->rt_time; 1170 rtchange(rt, rt->rt_state | RS_MHOME, 1171 &loop_rts, 0); 1172 } 1173 } 1174 if (rt == 0) { 1175 loop_rts.rts_ifp = ifp; 1176 loop_rts.rts_metric = 0; 1177 rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts); 1178 } 1179 } 1180 1181 LIST_FOREACH_SAFE(ifp, &ifnet, int_list, ifp1) { 1182 /* Forget any interfaces that have disappeared. 1183 */ 1184 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) { 1185 trace_act("interface %s has disappeared", 1186 ifp->int_name); 1187 ifdel(ifp); 1188 continue; 1189 } 1190 1191 if ((ifp->int_state & IS_BROKE) 1192 && !(ifp->int_state & IS_PASSIVE)) 1193 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 1194 1195 /* If we ever have a RIPv1 interface, assume we always will. 1196 * It might come back if it ever goes away. 1197 */ 1198 if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier) 1199 have_ripv1_out = 1; 1200 if (!(ifp->int_state & IS_NO_RIPV1_IN)) 1201 have_ripv1_in = 1; 1202 } 1203 1204 LIST_FOREACH(ifp, &ifnet, int_list) { 1205 /* Ensure there is always a network route for interfaces, 1206 * after any dead interfaces have been deleted, which 1207 * might affect routes for point-to-point links. 1208 */ 1209 if (!addrouteforif(ifp)) 1210 continue; 1211 1212 /* Add routes to the local end of point-to-point interfaces 1213 * using loopback. 1214 */ 1215 if ((ifp->int_if_flags & IFF_POINTOPOINT) 1216 && !(ifp->int_state & IS_REMOTE) 1217 && foundloopback) { 1218 /* Delete any routes to the network address through 1219 * foreign routers. Remove even static routes. 1220 */ 1221 del_static(ifp->int_addr, HOST_MASK, 0, 0); 1222 rt = rtget(ifp->int_addr, HOST_MASK); 1223 if (rt != 0 && rt->rt_router != loopaddr) { 1224 rtdelete(rt); 1225 rt = 0; 1226 } 1227 if (rt != 0) { 1228 if (!(rt->rt_state & RS_LOCAL) 1229 || rt->rt_metric > ifp->int_metric) { 1230 ifp1 = ifp; 1231 } else { 1232 ifp1 = rt->rt_ifp; 1233 } 1234 loop_rts.rts_ifp = ifp1; 1235 loop_rts.rts_metric = 0; 1236 loop_rts.rts_time = rt->rt_time; 1237 rtchange(rt, ((rt->rt_state & ~RS_NET_SYN) 1238 | (RS_IF|RS_LOCAL)), 1239 &loop_rts, 0); 1240 } else { 1241 loop_rts.rts_ifp = ifp; 1242 loop_rts.rts_metric = 0; 1243 rtadd(ifp->int_addr, HOST_MASK, 1244 (RS_IF | RS_LOCAL), &loop_rts); 1245 } 1246 } 1247 } 1248 1249 /* add the authority routes */ 1250 for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) { 1251 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask); 1252 if (rt != 0 1253 && !(rt->rt_state & RS_NO_NET_SYN) 1254 && !(rt->rt_state & RS_NET_INT)) { 1255 rtdelete(rt); 1256 rt = 0; 1257 } 1258 if (rt == 0) { 1259 loop_rts.rts_ifp = 0; 1260 loop_rts.rts_metric = intnetp->intnet_metric-1; 1261 rtadd(intnetp->intnet_addr, intnetp->intnet_mask, 1262 RS_NET_SYN | RS_NET_INT, &loop_rts); 1263 } 1264 } 1265 1266 prev_complaints = complaints; 1267 } 1268 1269 1270 static void 1271 check_net_syn(struct interface *ifp) 1272 { 1273 struct rt_entry *rt; 1274 static struct rt_spare new; 1275 1276 1277 /* Turn on the need to automatically synthesize a network route 1278 * for this interface only if we are running RIPv1 on some other 1279 * interface that is on a different class-A,B,or C network. 1280 */ 1281 if (have_ripv1_out || have_ripv1_in) { 1282 ifp->int_state |= IS_NEED_NET_SYN; 1283 rt = rtget(ifp->int_std_addr, ifp->int_std_mask); 1284 if (rt != 0 1285 && 0 == (rt->rt_state & RS_NO_NET_SYN) 1286 && (!(rt->rt_state & RS_NET_SYN) 1287 || rt->rt_metric > ifp->int_metric)) { 1288 rtdelete(rt); 1289 rt = 0; 1290 } 1291 if (rt == 0) { 1292 new.rts_ifp = ifp; 1293 new.rts_gate = ifp->int_addr; 1294 new.rts_router = ifp->int_addr; 1295 new.rts_metric = ifp->int_metric; 1296 rtadd(ifp->int_std_addr, ifp->int_std_mask, 1297 RS_NET_SYN, &new); 1298 } 1299 1300 } else { 1301 ifp->int_state &= ~IS_NEED_NET_SYN; 1302 1303 rt = rtget(ifp->int_std_addr, 1304 ifp->int_std_mask); 1305 if (rt != 0 1306 && (rt->rt_state & RS_NET_SYN) 1307 && rt->rt_ifp == ifp) 1308 rtbad_sub(rt); 1309 } 1310 } 1311 1312 1313 /* Add route for interface if not currently installed. 1314 * Create route to other end if a point-to-point link, 1315 * otherwise a route to this (sub)network. 1316 */ 1317 static int /* 0=bad interface */ 1318 addrouteforif(struct interface *ifp) 1319 { 1320 struct rt_entry *rt; 1321 static struct rt_spare new; 1322 naddr dst; 1323 1324 1325 /* skip sick interfaces 1326 */ 1327 if (ifp->int_state & IS_BROKE) 1328 return 0; 1329 1330 /* If the interface on a subnet, then install a RIPv1 route to 1331 * the network as well (unless it is sick). 1332 */ 1333 if (ifp->int_state & IS_SUBNET) 1334 check_net_syn(ifp); 1335 1336 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) 1337 ? ifp->int_dstaddr 1338 : htonl(ifp->int_net)); 1339 1340 new.rts_ifp = ifp; 1341 new.rts_router = ifp->int_addr; 1342 new.rts_gate = ifp->int_addr; 1343 new.rts_metric = ifp->int_metric; 1344 new.rts_time = now.tv_sec; 1345 1346 /* If we are going to send packets to the gateway, 1347 * it must be reachable using our physical interfaces 1348 */ 1349 if ((ifp->int_state & IS_REMOTE) 1350 && !(ifp->int_state & IS_EXTERNAL) 1351 && !check_remote(ifp)) 1352 return 0; 1353 1354 /* We are finished if the correct main interface route exists. 1355 * The right route must be for the right interface, not synthesized 1356 * from a subnet, be a "gateway" or not as appropriate, and so forth. 1357 */ 1358 del_static(dst, ifp->int_mask, 0, 0); 1359 rt = rtget(dst, ifp->int_mask); 1360 if (rt != 0) { 1361 if ((rt->rt_ifp != ifp 1362 || rt->rt_router != ifp->int_addr) 1363 && (!(ifp->int_state & IS_DUP) 1364 || rt->rt_ifp == 0 1365 || (rt->rt_ifp->int_state & IS_BROKE))) { 1366 rtdelete(rt); 1367 rt = 0; 1368 } else { 1369 rtchange(rt, ((rt->rt_state | RS_IF) 1370 & ~(RS_NET_SYN | RS_LOCAL)), 1371 &new, 0); 1372 } 1373 } 1374 if (rt == 0) { 1375 if (ifp->int_transitions++ > 0) 1376 trace_act("re-install interface %s", 1377 ifp->int_name); 1378 1379 rtadd(dst, ifp->int_mask, RS_IF, &new); 1380 } 1381 1382 return 1; 1383 } 1384