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