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