1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgment: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * $FreeBSD: src/sbin/routed/if.c,v 1.8 2000/08/11 08:24:38 sheldonh Exp $ 37 */ 38 39 #pragma ident "%Z%%M% %I% %E% SMI" 40 41 #include "defs.h" 42 #include "pathnames.h" 43 #include <sys/sockio.h> 44 #include <inet/ip.h> 45 #include <kstat.h> 46 #include <stropts.h> 47 #include <fcntl.h> 48 #include <stddef.h> 49 #include <assert.h> 50 51 /* linked list of all interfaces */ 52 struct interface *ifnet; 53 54 /* 55 * Acceptable sizes (in number of interfaces) for the interface hash 56 * tables. These must all be prime. The interface hash tables all 57 * start with a size of hash_table_sizes[0], and increase as needed. 58 */ 59 size_t hash_table_sizes[] = { 67, 131, 257, 521, 1031, 2053, 4099, 0 }; 60 61 struct htbl { 62 void **htbl_ptrs; 63 uint_t (*htbl_hash)(const void *, size_t); 64 size_t htbl_link_off; /* offset of the linkage structure */ 65 size_t htbl_key_off; /* offset of the key value (rehash) */ 66 size_t htbl_size; /* size of the hash */ 67 uint_t htbl_size_index; 68 uint_t htbl_ifcount; /* count of entries */ 69 boolean_t htbl_grow; /* growth allowed */ 70 }; 71 72 /* Get first element -- for iteration */ 73 #define HFIRST(htbl, arg) \ 74 ((htbl)->htbl_ptrs[(htbl)->htbl_hash((arg), 0) % (htbl)->htbl_size]) 75 76 /* Add an element to a hash */ 77 #define HADD(htbl, strp) \ 78 hash_link((htbl), (htbl)->htbl_hash((strp), (htbl)->htbl_key_off), \ 79 (strp)) 80 81 uint_t tot_interfaces; /* # of remote and local interfaces */ 82 uint_t rip_interfaces; /* # of interfaces doing RIP */ 83 uint_t ripout_interfaces; /* # of interfaces advertising RIP */ 84 uint_t fwd_interfaces; /* # of interfaces ip_forwarding=1 */ 85 static boolean_t foundloopback; /* valid flag for loopaddr */ 86 in_addr_t loopaddr; /* our address on loopback */ 87 static struct rt_spare loop_rts; 88 89 struct timeval ifscan_timer; 90 static struct timeval last_ifscan; 91 #define IF_RESCAN_DELAY() \ 92 (last_ifscan.tv_sec == now.tv_sec && \ 93 last_ifscan.tv_usec == now.tv_usec && \ 94 timercmp(&ifscan_timer, &now, > /* */)) 95 96 boolean_t have_ripv1_out; /* have a RIPv1 interface */ 97 static boolean_t have_ripv1_in; 98 99 static void if_bad(struct interface *, boolean_t); 100 static boolean_t addrouteforif(struct interface *); 101 static int get_if_kstats(struct interface *, struct phyi_data *); 102 static uint_t ahash(const void *, uint_t); 103 static uint_t ihash(const void *, uint_t); 104 static uint_t nhash(const void *, uint_t); 105 static void htbl_grow(struct htbl *); 106 107 /* 108 * Table of all interfaces, hashed by interface address. For remote 109 * interfaces, the gateway address is used. 110 */ 111 static struct htbl ahash_tbl = { 112 NULL, ahash, offsetof(struct interface, int_ahash), 113 offsetof(struct interface, int_addr), 114 0, 0, 0, _B_TRUE }; 115 /* 116 * Table of broadcast capable interfaces, hashed by interface broadcast 117 * address. 118 */ 119 static struct htbl bhash_tbl = { 120 NULL, ahash, offsetof(struct interface, int_bhash), 121 offsetof(struct interface, int_brdaddr), 122 0, 0, 0, _B_TRUE }; 123 /* 124 * Table of physical_interface structures (lists of interfaces by ifIndex), 125 * hashed by interface index. 126 */ 127 static struct htbl ihash_tbl = { 128 NULL, ihash, offsetof(struct physical_interface, phyi_link), 129 offsetof(struct physical_interface, phyi_index), 130 0, 0, 0, _B_TRUE }; 131 /* 132 * Table of all interfaces, hashed by interface name. 133 */ 134 static struct htbl nhash_tbl = { 135 NULL, nhash, offsetof(struct interface, int_nhash), 136 offsetof(struct interface, int_name), 137 0, 0, 0, _B_TRUE }; 138 139 static struct physical_interface dummy_phyi; 140 struct interface dummy_ifp; 141 142 /* Hash based on an IP address. */ 143 static uint_t 144 ahash(const void *arg, size_t voffs) 145 { 146 /* LINTED */ 147 return ((uint_t)*(const in_addr_t *)((const char *)arg + voffs)); 148 } 149 150 static uint_t 151 ihash(const void *arg, size_t voffs) 152 { 153 /* LINTED */ 154 return ((uint_t)*(const uint32_t *)((const char *)arg + voffs)); 155 } 156 157 static uint_t 158 nhash(const void *arg, size_t voffs) 159 { 160 const char *cp = (const char *)arg + voffs; 161 uint_t i; 162 163 for (i = 0; *cp != '\0'; cp++) { 164 i = ((i<<1) & 0x7fffffff) | ((i>>30) & 0x00000003); 165 i ^= *cp; 166 } 167 return (i); 168 } 169 170 /* 171 * Add an element to the head of the list. 172 */ 173 static void 174 link_in(void **head, void *strp, size_t loffs) 175 { 176 struct hlinkage *hlp; 177 178 /* LINTED: alignment known to be good. */ 179 hlp = (struct hlinkage *)((char *)strp + loffs); 180 hlp->hl_prev = head; 181 if ((hlp->hl_next = *head) != NULL) { 182 /* LINTED */ 183 ((struct hlinkage *)((char *)*head + loffs))->hl_prev = 184 &hlp->hl_next; 185 } 186 *head = strp; 187 } 188 189 /* Remove from a list */ 190 static void 191 link_out(void *strp, size_t loffs) 192 { 193 struct hlinkage *hlp; 194 195 /* LINTED: alignment known to be good. */ 196 hlp = (struct hlinkage *)((char *)strp + loffs); 197 if ((*hlp->hl_prev = hlp->hl_next) != NULL) { 198 /* LINTED */ 199 ((struct hlinkage *)((char *)hlp->hl_next + loffs))->hl_prev = 200 hlp->hl_prev; 201 } 202 } 203 204 /* Add to a hash */ 205 static void 206 hash_link(struct htbl *htbl, uint_t hval, void *strp) 207 { 208 void **hep; 209 210 if (htbl->htbl_grow && htbl->htbl_ifcount >= htbl->htbl_size * 5) 211 htbl_grow(htbl); 212 213 hep = &htbl->htbl_ptrs[hval % htbl->htbl_size]; 214 link_in(hep, strp, htbl->htbl_link_off); 215 htbl->htbl_ifcount++; 216 } 217 218 /* Remove from a hash */ 219 static void 220 hash_unlink(struct htbl *htbl, void *strp) 221 { 222 link_out(strp, htbl->htbl_link_off); 223 htbl->htbl_ifcount--; 224 } 225 226 static void 227 dummy_ifp_init(void) 228 { 229 dummy_phyi.phyi_interface = &dummy_ifp; 230 dummy_ifp.int_phys = &dummy_phyi; 231 (void) strcpy(dummy_phyi.phyi_name, "wildcard"); 232 (void) strcpy(dummy_ifp.int_name, "wildcard"); 233 dummy_ifp.int_dstaddr = dummy_ifp.int_addr = INADDR_NONE; 234 dummy_ifp.int_mask = IP_HOST_MASK; 235 dummy_ifp.int_metric = HOPCNT_INFINITY; 236 dummy_ifp.int_state = (IS_BROKE|IS_PASSIVE|IS_NO_RIP|IS_NO_RDISC); 237 dummy_ifp.int_std_mask = std_mask(dummy_ifp.int_addr); 238 dummy_ifp.int_std_net = dummy_ifp.int_net & dummy_ifp.int_std_mask; 239 dummy_ifp.int_std_addr = htonl(dummy_ifp.int_std_net); 240 } 241 242 /* allocate the interface hash tables */ 243 void 244 iftbl_alloc(void) 245 { 246 size_t initial_size = hash_table_sizes[0]; 247 248 errno = 0; 249 ahash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *)); 250 bhash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *)); 251 ihash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *)); 252 nhash_tbl.htbl_ptrs = calloc(initial_size, sizeof (void *)); 253 254 if (errno != 0) 255 BADERR(_B_FALSE, "Unable to allocate interface tables"); 256 257 ahash_tbl.htbl_size = initial_size; 258 bhash_tbl.htbl_size = initial_size; 259 ihash_tbl.htbl_size = initial_size; 260 nhash_tbl.htbl_size = initial_size; 261 262 dummy_ifp_init(); 263 } 264 265 266 static void 267 htbl_grow(struct htbl *htbl) 268 { 269 void *strp; 270 void **new_ptrs, **saved_old_ptrs, **old_ptrs; 271 size_t new_size, old_size; 272 static uint_t failed_count; 273 274 if ((new_size = hash_table_sizes[htbl->htbl_size_index + 1]) == 0) 275 return; 276 277 if ((new_ptrs = calloc(new_size, sizeof (void *))) == NULL) { 278 /* 279 * This is not fatal since we already have a 280 * functional, yet crowded, interface table. 281 */ 282 if (++failed_count % 100 == 1) 283 msglog("%sunable to grow interface hash table: %s", 284 failed_count > 1 ? "Still " : "", 285 rip_strerror(errno)); 286 return; 287 } 288 289 failed_count = 0; 290 291 saved_old_ptrs = old_ptrs = htbl->htbl_ptrs; 292 old_size = htbl->htbl_size; 293 htbl->htbl_ptrs = new_ptrs; 294 htbl->htbl_size = new_size; 295 htbl->htbl_size_index++; 296 htbl->htbl_ifcount = 0; 297 298 /* 299 * Go through the list of structures, and re-link each into 300 * this new table. 301 */ 302 htbl->htbl_grow = _B_FALSE; 303 while (old_size-- > 0) { 304 strp = *old_ptrs++; 305 HADD(htbl, strp); 306 } 307 308 htbl->htbl_grow = _B_TRUE; 309 free(saved_old_ptrs); 310 } 311 312 /* Link a new interface into the lists and hash tables. */ 313 void 314 if_link(struct interface *ifp, uint32_t ifindex) 315 { 316 struct physical_interface *phyi; 317 318 link_in((void **)&ifnet, ifp, offsetof(struct interface, int_link)); 319 320 HADD(&ahash_tbl, ifp); 321 HADD(&nhash_tbl, ifp); 322 323 if (ifp->int_if_flags & IFF_BROADCAST) 324 HADD(&bhash_tbl, ifp); 325 326 if (ifindex != 0) { 327 for (phyi = HFIRST(&ihash_tbl, &ifindex); 328 phyi != NULL; phyi = phyi->phyi_link.hl_next) { 329 if (phyi->phyi_index == ifindex) 330 break; 331 } 332 if (phyi == NULL) { 333 size_t size; 334 335 phyi = rtmalloc(sizeof (*phyi), "physical_interface"); 336 (void) memset(phyi, 0, sizeof (*phyi)); 337 phyi->phyi_index = ifindex; 338 /* LINTED */ 339 assert(IF_NAME_LEN >= IF_NAMESIZE); 340 341 size = strcspn(ifp->int_name, ":"); 342 (void) strncpy(phyi->phyi_name, ifp->int_name, 343 size); 344 phyi->phyi_name[size] = '\0'; 345 HADD(&ihash_tbl, phyi); 346 } 347 link_in((void **)&phyi->phyi_interface, ifp, 348 offsetof(struct interface, int_ilist)); 349 ifp->int_phys = phyi; 350 } 351 } 352 353 /* Find the interface with an address */ 354 struct interface * 355 ifwithaddr(in_addr_t addr, 356 boolean_t bcast, /* notice IFF_BROADCAST address */ 357 boolean_t remote) /* include IS_REMOTE interfaces */ 358 { 359 struct interface *ifp, *possible = NULL; 360 uint32_t remote_state; 361 362 remote_state = (!remote ? IS_REMOTE : 0); 363 364 for (ifp = HFIRST(&ahash_tbl, &addr); ifp != NULL; 365 ifp = ifp->int_ahash.hl_next) { 366 if (ifp->int_addr != addr) 367 continue; 368 if (ifp->int_state & remote_state) 369 continue; 370 if (!(ifp->int_state & (IS_BROKE | IS_PASSIVE))) 371 return (ifp); 372 possible = ifp; 373 } 374 375 if (possible != NULL || !bcast) 376 return (possible); 377 378 for (ifp = HFIRST(&bhash_tbl, &addr); ifp != NULL; 379 ifp = ifp->int_bhash.hl_next) { 380 if (ifp->int_brdaddr != addr) 381 continue; 382 if (ifp->int_state & remote_state) 383 continue; 384 if (!(ifp->int_state & (IS_BROKE | IS_PASSIVE))) 385 return (ifp); 386 possible = ifp; 387 } 388 389 return (possible); 390 } 391 392 393 /* find the interface with the specified name ("hme0" for example) */ 394 struct interface * 395 ifwithname(const char *name) 396 { 397 struct interface *ifp; 398 399 for (;;) { 400 for (ifp = HFIRST(&nhash_tbl, name); ifp != NULL; 401 ifp = ifp->int_nhash.hl_next) { 402 if (strcmp(ifp->int_name, name) == 0) 403 return (ifp); 404 } 405 406 /* 407 * If there is no known interface, maybe there is a 408 * new interface. So just once look for new interfaces. 409 */ 410 if (IF_RESCAN_DELAY()) 411 return (NULL); 412 ifscan(); 413 } 414 } 415 416 struct interface * 417 findremoteif(in_addr_t addr) 418 { 419 struct interface *ifp; 420 421 for (ifp = HFIRST(&ahash_tbl, &addr); ifp != NULL; 422 ifp = ifp->int_ahash.hl_next) { 423 if ((ifp->int_state & IS_REMOTE) && ifp->int_addr == addr) 424 return (ifp); 425 } 426 427 return (NULL); 428 } 429 430 struct interface * 431 findifaddr(in_addr_t addr) 432 { 433 struct interface *ifp; 434 435 for (ifp = HFIRST(&ahash_tbl, &addr); ifp != NULL; 436 ifp = ifp->int_ahash.hl_next) { 437 if (ifp->int_addr == addr) 438 return (ifp); 439 } 440 441 return (NULL); 442 } 443 444 /* 445 * Return the first interface with the given index. 446 */ 447 struct interface * 448 ifwithindex(ulong_t index, 449 boolean_t rescan_ok) 450 { 451 struct physical_interface *phyi; 452 453 for (;;) { 454 for (phyi = HFIRST(&ihash_tbl, &index); phyi != NULL; 455 phyi = phyi->phyi_link.hl_next) { 456 if (phyi->phyi_index == index) 457 return (phyi->phyi_interface); 458 } 459 460 /* 461 * If there is no known interface, maybe there is a 462 * new interface. So just once look for new interfaces. 463 */ 464 if (!rescan_ok || IF_RESCAN_DELAY()) 465 return (NULL); 466 rescan_ok = _B_FALSE; 467 ifscan(); 468 } 469 } 470 471 472 /* 473 * Find an interface which should be receiving packets sent from the 474 * given address. Used as a last ditch effort for figuring out which 475 * interface a packet came in on. Also used for finding out which 476 * interface points towards the gateway of static routes learned from 477 * the kernel. 478 */ 479 struct interface * 480 iflookup(in_addr_t addr) 481 { 482 struct interface *ifp, *maybe; 483 484 maybe = NULL; 485 for (;;) { 486 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) { 487 /* 488 * Don't return a duplicate interface since 489 * it is unusable for output. 490 */ 491 if (ifp->int_state & IS_DUP) 492 continue; 493 494 if (ifp->int_if_flags & IFF_POINTOPOINT) { 495 /* finished with a match */ 496 if (ifp->int_dstaddr == addr) 497 return (ifp); 498 } else { 499 /* finished with an exact match */ 500 if (ifp->int_addr == addr) { 501 if (IS_PASSIVE_IFP(ifp)) 502 trace_misc("iflookup " 503 "returning passive intf %s", 504 ifp->int_name); 505 return (ifp); 506 } 507 508 /* Look for the longest approximate match. */ 509 if (on_net(addr, ifp->int_net, ifp->int_mask) && 510 (maybe == NULL || 511 ifp->int_mask > maybe->int_mask)) { 512 maybe = ifp; 513 } 514 } 515 } 516 517 /* 518 * If there is no known interface, maybe there is a 519 * new interface. So just once look for new interfaces. 520 */ 521 if (maybe == NULL && !IF_RESCAN_DELAY()) 522 ifscan(); 523 else 524 break; 525 } 526 527 if (maybe != NULL && IS_PASSIVE_IFP(maybe)) { 528 trace_misc("iflookup returning passive intf %s", 529 maybe->int_name); 530 } 531 return (maybe); 532 } 533 534 /* 535 * Find the netmask that would be inferred by RIPv1 listeners 536 * on the given interface for a given network. 537 * If no interface is specified, look for the best fitting interface. 538 */ 539 in_addr_t 540 ripv1_mask_net(in_addr_t addr, /* in network byte order */ 541 const struct interface *ifp) /* as seen on this interface */ 542 { 543 const struct r1net *r1p; 544 in_addr_t mask = 0; 545 546 if (addr == 0) /* default always has 0 mask */ 547 return (mask); 548 549 if (ifp != NULL && ifp->int_ripv1_mask != HOST_MASK) { 550 /* 551 * If the target network is that of the associated interface 552 * on which it arrived, then use the netmask of the interface. 553 */ 554 if (on_net(addr, ifp->int_net, ifp->int_std_mask)) 555 mask = ifp->int_ripv1_mask; 556 557 } else { 558 /* 559 * Examine all interfaces, and if it the target seems 560 * to have the same network number of an interface, use the 561 * netmask of that interface. If there is more than one 562 * such interface, prefer the interface with the longest 563 * match. 564 */ 565 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) { 566 if (on_net(addr, ifp->int_std_net, ifp->int_std_mask) && 567 ifp->int_ripv1_mask > mask && 568 ifp->int_ripv1_mask != HOST_MASK) 569 mask = ifp->int_ripv1_mask; 570 } 571 572 } 573 574 if (mask == 0) { 575 /* 576 * Check to see if the user has supplied an applicable 577 * netmask as a ripv1_mask option in /etc/gateways. 578 */ 579 for (r1p = r1nets; r1p != NULL; r1p = r1p->r1net_next) { 580 /* 581 * If the address is is on a matching network 582 * and we haven't already found a longer match, 583 * use the matching netmask. 584 */ 585 if (on_net(addr, r1p->r1net_net, r1p->r1net_match) && 586 r1p->r1net_mask > mask) 587 mask = r1p->r1net_mask; 588 } 589 590 /* Otherwise, make the classic A/B/C guess. */ 591 if (mask == 0) 592 mask = std_mask(addr); 593 } 594 595 return (mask); 596 } 597 598 599 in_addr_t 600 ripv1_mask_host(in_addr_t addr, /* in network byte order */ 601 const struct interface *ifp) /* as seen on this interface */ 602 { 603 in_addr_t mask = ripv1_mask_net(addr, ifp); 604 605 606 /* 607 * If the computed netmask does not mask all of the set bits 608 * in the address, then assume it is a host address 609 */ 610 if ((ntohl(addr) & ~mask) != 0) 611 mask = HOST_MASK; 612 return (mask); 613 } 614 615 616 /* See if a IP address looks reasonable as a destination */ 617 boolean_t /* _B_FALSE=bad _B_TRUE=good */ 618 check_dst(in_addr_t addr) 619 { 620 addr = ntohl(addr); 621 622 if (IN_CLASSA(addr)) { 623 if (addr == 0) 624 return (_B_TRUE); /* default */ 625 626 addr >>= IN_CLASSA_NSHIFT; 627 return (addr != 0 && addr != IN_LOOPBACKNET); 628 } 629 630 /* Must not allow destination to be link local address. */ 631 if (IN_LINKLOCAL(addr)) 632 return (_B_FALSE); 633 634 if (IN_CLASSB(addr) || IN_CLASSC(addr)) 635 return (_B_TRUE); 636 637 if (IN_CLASSD(addr)) 638 return (_B_FALSE); 639 640 return (_B_TRUE); 641 642 } 643 644 /* 645 * Find an existing interface which has the given parameters, but don't 646 * return the interface with name "name" if "name" is specified. 647 */ 648 struct interface * 649 check_dup(const char *name, /* Don't return this interface */ 650 in_addr_t addr, /* IP address, so network byte order */ 651 in_addr_t dstaddr, /* ditto */ 652 in_addr_t mask, /* mask, so host byte order */ 653 uint64_t if_flags, /* set IFF_POINTOPOINT to ignore local int_addr */ 654 boolean_t allowdups) /* set true to include duplicates */ 655 { 656 struct interface *best_ifp = NULL; 657 struct interface *ifp; 658 in_addr_t dstaddr_h = ntohl(dstaddr); 659 int best_pref = 0; 660 int pref; 661 662 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) { 663 /* This interface, not a duplicate. */ 664 if (name != NULL && strcmp(name, ifp->int_name) == 0) 665 continue; 666 667 /* 668 * Find an interface which isn't already a duplicate to 669 * avoid cyclical duplication. (i.e. qfe0:1 is a duplicate 670 * of qfe0, and qfe0 is a duplicate of qfe0:1. That would 671 * be bad) 672 */ 673 if (!allowdups && (ifp->int_state & IS_DUP)) 674 continue; 675 676 if (ifp->int_mask != mask) 677 continue; 678 679 if (!IS_IFF_UP(ifp->int_if_flags)) 680 continue; 681 682 /* 683 * The local address can only be shared with a point-to-point 684 * link. 685 */ 686 if ((ifp->int_addr == addr && 687 ((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0) || 688 on_net(ifp->int_dstaddr, dstaddr_h, mask)) { 689 pref = 0; 690 if (!(ifp->int_state & IS_ALIAS)) 691 pref++; 692 if (!IS_RIP_OUT_OFF(ifp->int_state)) 693 pref += 2; 694 if (IS_IFF_ROUTING(ifp->int_if_flags)) 695 pref += 4; 696 if (pref > best_pref) { 697 best_pref = pref; 698 best_ifp = ifp; 699 } 700 } 701 } 702 return (best_ifp); 703 } 704 705 706 /* 707 * See that a remote gateway is reachable. 708 * Note that the answer can change as real interfaces come and go. 709 */ 710 boolean_t /* _B_FALSE=bad _B_TRUE=good */ 711 check_remote(struct interface *ifp) 712 { 713 struct rt_entry *rt; 714 715 /* do not worry about other kinds */ 716 if (!(ifp->int_state & IS_REMOTE)) 717 return (_B_TRUE); 718 719 rt = rtfind(ifp->int_addr); 720 if (rt != NULL && 721 rt->rt_ifp != NULL && 722 on_net(ifp->int_addr, rt->rt_ifp->int_net, rt->rt_ifp->int_mask)) { 723 return (_B_TRUE); 724 } 725 726 /* 727 * the gateway cannot be reached directly from one of our 728 * interfaces 729 */ 730 if (!(ifp->int_state & IS_BROKE)) { 731 msglog("unreachable gateway %s in "PATH_GATEWAYS, 732 naddr_ntoa(ifp->int_addr)); 733 if_bad(ifp, _B_FALSE); 734 } 735 return (_B_FALSE); 736 } 737 738 /* Delete an interface. */ 739 static void 740 ifdel(struct interface *ifp) 741 { 742 struct rewire_data wire; 743 boolean_t resurrected; 744 struct physical_interface *phyi; 745 746 trace_if("Del", ifp); 747 748 ifp->int_state |= IS_BROKE; 749 750 /* unlink the interface */ 751 link_out(ifp, offsetof(struct interface, int_link)); 752 hash_unlink(&ahash_tbl, ifp); 753 hash_unlink(&nhash_tbl, ifp); 754 if (ifp->int_if_flags & IFF_BROADCAST) 755 hash_unlink(&bhash_tbl, ifp); 756 757 /* Remove from list of interfaces with this ifIndex */ 758 if ((phyi = ifp->int_phys) != NULL) { 759 link_out(ifp, offsetof(struct interface, int_ilist)); 760 if (phyi->phyi_interface == NULL) { 761 hash_unlink(&ihash_tbl, phyi); 762 free(phyi); 763 } 764 } 765 766 /* 767 * If this is a lead interface, then check first for 768 * duplicates of this interface with an eye towards promoting 769 * one of them. 770 */ 771 resurrected = _B_FALSE; 772 if (!(ifp->int_state & IS_DUP) && 773 (wire.if_new = check_dup(ifp->int_name, ifp->int_addr, 774 ifp->int_dstaddr, ifp->int_mask, ifp->int_if_flags, 775 _B_TRUE)) != NULL && 776 !IS_IFF_QUIET(wire.if_new->int_if_flags)) { 777 778 trace_act("promoting duplicate %s in place of %s", 779 wire.if_new->int_name, ifp->int_name); 780 781 /* Rewire routes with the replacement interface */ 782 wire.if_old = ifp; 783 wire.metric_delta = wire.if_new->int_metric - ifp->int_metric; 784 (void) rn_walktree(rhead, walk_rewire, &wire); 785 kern_rewire_ifp(wire.if_old, wire.if_new); 786 if_rewire_rdisc(wire.if_old, wire.if_new); 787 788 /* Mark the replacement as being no longer a duplicate */ 789 wire.if_new->int_state &= ~IS_DUP; 790 tot_interfaces++; 791 if (!IS_RIP_OFF(wire.if_new->int_state)) 792 rip_interfaces++; 793 if (!IS_RIP_OUT_OFF(wire.if_new->int_state)) 794 ripout_interfaces++; 795 if (IS_IFF_ROUTING(wire.if_new->int_if_flags)) 796 fwd_interfaces++; 797 798 set_rdisc_mg(wire.if_new, 1); 799 rip_mcast_on(wire.if_new); 800 801 /* We came out ok; no need to clobber routes over this. */ 802 resurrected = _B_TRUE; 803 } 804 805 rip_mcast_off(ifp); 806 if (rip_sock_interface == ifp) 807 rip_sock_interface = NULL; 808 809 set_rdisc_mg(ifp, 0); 810 811 /* 812 * Note that duplicates are not counted in the total number of 813 * interfaces. 814 */ 815 if (!(ifp->int_state & IS_DUP) && !IS_IFF_QUIET(ifp->int_if_flags)) { 816 tot_interfaces--; 817 if (!IS_RIP_OFF(ifp->int_state)) 818 rip_interfaces--; 819 if (!IS_RIP_OUT_OFF(ifp->int_state)) 820 ripout_interfaces--; 821 if (IS_IFF_ROUTING(ifp->int_if_flags)) 822 fwd_interfaces--; 823 } 824 825 if (!resurrected) { 826 /* 827 * Zap all routes associated with this interface. 828 * Assume routes just using gateways beyond this interface 829 * will timeout naturally, and have probably already died. 830 */ 831 (void) rn_walktree(rhead, walk_bad, ifp); 832 kern_flush_ifp(ifp); 833 834 if_bad_rdisc(ifp); 835 } 836 837 free(ifp); 838 } 839 840 841 /* Mark an interface ill. */ 842 void 843 if_sick(struct interface *ifp, boolean_t recurse) 844 { 845 struct interface *ifp1; 846 847 if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) { 848 ifp->int_state |= IS_SICK; 849 ifp->int_act_time = NEVER; 850 trace_if("Chg", ifp); 851 852 LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL); 853 if (recurse && ifp->int_phys != NULL) { 854 /* If an interface is sick, so are its aliases. */ 855 for (ifp1 = ifp->int_phys->phyi_interface; 856 ifp1 != NULL; ifp1 = ifp1->int_ilist.hl_next) { 857 if (ifp1 != ifp) 858 if_sick(ifp1, _B_FALSE); 859 } 860 } 861 } 862 } 863 864 865 /* Mark an interface dead. */ 866 static void 867 if_bad(struct interface *ifp, boolean_t recurse) 868 { 869 struct interface *ifp1; 870 struct rewire_data wire; 871 872 if (ifp->int_state & IS_BROKE) 873 return; 874 875 LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL); 876 877 ifp->int_state |= (IS_BROKE | IS_SICK); 878 ifp->int_act_time = NEVER; 879 ifp->int_query_time = NEVER; 880 /* Note: don't reset the stats timestamp here */ 881 882 trace_if("Chg", ifp); 883 884 if (recurse && ifp->int_phys != NULL) { 885 /* If an interface is bad, so are its aliases. */ 886 for (ifp1 = ifp->int_phys->phyi_interface; 887 ifp1 != NULL; ifp1 = ifp1->int_ilist.hl_next) { 888 if (ifp1 != ifp) 889 if_bad(ifp1, _B_FALSE); 890 } 891 } 892 893 /* If we can find a replacement, then pick it up. */ 894 if (!(ifp->int_state & IS_DUP) && 895 (wire.if_new = check_dup(ifp->int_name, ifp->int_addr, 896 ifp->int_dstaddr, ifp->int_mask, ifp->int_if_flags, 897 _B_TRUE)) != NULL && 898 !IS_IFF_QUIET(wire.if_new->int_if_flags)) { 899 trace_act("promoting duplicate %s in place of %s", 900 wire.if_new->int_name, ifp->int_name); 901 wire.if_old = ifp; 902 wire.metric_delta = wire.if_new->int_metric - ifp->int_metric; 903 (void) rn_walktree(rhead, walk_rewire, &wire); 904 if_rewire_rdisc(wire.if_old, wire.if_new); 905 906 /* The broken guy becomes the duplicate */ 907 wire.if_new->int_state &= ~IS_DUP; 908 set_rdisc_mg(ifp, 0); 909 rip_mcast_off(ifp); 910 ifp->int_state |= IS_DUP; 911 912 /* join the mcast groups for the replacement */ 913 set_rdisc_mg(wire.if_new, 1); 914 rip_mcast_on(wire.if_new); 915 916 if (rip_sock_interface == ifp) 917 rip_sock_interface = NULL; 918 } else { 919 (void) rn_walktree(rhead, walk_bad, ifp); 920 if_bad_rdisc(ifp); 921 } 922 } 923 924 925 /* Mark an interface alive */ 926 void 927 if_ok(struct interface *ifp, const char *type, boolean_t recurse) 928 { 929 struct interface *ifp1; 930 boolean_t wasbroken = _B_FALSE; 931 932 if (ifp->int_state & IS_BROKE) { 933 writelog(LOG_WARNING, "%sinterface %s to %s restored", 934 type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 935 ifp->int_state &= ~(IS_BROKE | IS_SICK); 936 wasbroken = _B_TRUE; 937 } else if (ifp->int_state & IS_SICK) { 938 trace_act("%sinterface %s to %s working better", 939 type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 940 ifp->int_state &= ~IS_SICK; 941 } 942 943 if (recurse && ifp->int_phys != NULL && IS_IFF_UP(ifp->int_if_flags)) { 944 ifp->int_phys->phyi_data.ts = 0; 945 946 /* Also mark all aliases of this interface as ok */ 947 for (ifp1 = ifp->int_phys->phyi_interface; 948 ifp1 != NULL; ifp1 = ifp1->int_ilist.hl_next) { 949 if (ifp1 != ifp) 950 if_ok(ifp1, type, _B_FALSE); 951 } 952 } 953 954 if (wasbroken) { 955 if (!(ifp->int_state & IS_DUP)) 956 if_ok_rdisc(ifp); 957 958 if (ifp->int_state & IS_REMOTE) 959 (void) addrouteforif(ifp); 960 } 961 } 962 963 boolean_t 964 remote_address_ok(struct interface *ifp, in_addr_t addr) 965 { 966 if (ifp->int_if_flags & IFF_POINTOPOINT) { 967 if (addr == ifp->int_dstaddr) 968 return (_B_TRUE); 969 } else if (on_net(addr, ifp->int_net, ifp->int_mask)) { 970 return (_B_TRUE); 971 } 972 return (_B_FALSE); 973 } 974 975 /* 976 * Find the network interfaces which have configured themselves. 977 * This must be done regularly, if only for extra addresses 978 * that come and go on interfaces. 979 */ 980 void 981 ifscan(void) 982 { 983 uint_t complaints = 0; 984 static uint_t prev_complaints = 0; 985 #define COMP_BADADDR 0x001 986 #define COMP_NODST 0x002 987 #define COMP_NOBADDR 0x004 988 #define COMP_NOMASK 0x008 989 #define COMP_BAD_METRIC 0x010 990 #define COMP_NETMASK 0x020 991 #define COMP_NO_INDEX 0x040 992 #define COMP_BAD_FLAGS 0x080 993 #define COMP_NO_KSTATS 0x100 994 #define COMP_IPFORWARD 0x200 995 996 struct interface ifs, *ifp, *ifp1; 997 struct rt_entry *rt; 998 size_t needed; 999 static size_t lastneeded = 0; 1000 char *buf; 1001 static char *lastbuf = NULL; 1002 int32_t in, ierr, out, oerr; 1003 struct intnet *intnetp; 1004 int sock; 1005 struct lifnum lifn; 1006 struct lifconf lifc; 1007 struct lifreq *lifrp, *lifrp_lim; 1008 struct sockaddr_in *sinp; 1009 in_addr_t haddr; 1010 static in_addr_t myaddr = 0; 1011 uint32_t ifindex; 1012 struct phyi_data newstats; 1013 struct physical_interface *phyi; 1014 1015 last_ifscan = now; 1016 ifscan_timer.tv_sec = now.tv_sec + 1017 (supplier || tot_interfaces != 1 ? 1018 CHECK_ACT_INTERVAL : CHECK_QUIET_INTERVAL); 1019 1020 /* mark all interfaces so we can get rid of those that disappear */ 1021 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) 1022 ifp->int_state &= ~IS_CHECKED; 1023 1024 /* Fetch the size of the current interface list */ 1025 if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1) 1026 BADERR(_B_TRUE, "ifscan: socket(SOCK_DGRAM)"); 1027 lifn.lifn_family = AF_INET; /* Only count IPv4 interfaces */ 1028 /* 1029 * Include IFF_NOXMIT interfaces. Such interfaces are exluded 1030 * from protocol operations, but their inclusion in the 1031 * internal table enables us to know when packets arrive on 1032 * such interfaces. 1033 */ 1034 lifn.lifn_flags = LIFC_NOXMIT; 1035 calculate_lifc_len: 1036 if (ioctl(sock, SIOCGLIFNUM, &lifn) == -1) { 1037 BADERR(_B_TRUE, "ifscan: ioctl(SIOCGLIFNUM)"); 1038 } 1039 1040 /* 1041 * When calculating the buffer size needed, add a small number 1042 * of interfaces to those we counted. We do this to capture 1043 * the interface status of potential interfaces which may have 1044 * been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF. 1045 * Try to reuse the buffer we already have to avoid heap 1046 * thrash. 1047 */ 1048 needed = (lifn.lifn_count + 4) * sizeof (struct lifreq); 1049 if (needed > lastneeded || needed < lastneeded/2) { 1050 if (lastbuf != NULL) 1051 free(lastbuf); 1052 if ((buf = malloc(needed)) == NULL) { 1053 lastbuf = NULL; 1054 msglog("ifscan: malloc: %s", rip_strerror(errno)); 1055 return; 1056 } 1057 } else { 1058 buf = lastbuf; 1059 } 1060 lastbuf = buf; 1061 lastneeded = needed; 1062 1063 /* Get the list */ 1064 lifc.lifc_family = AF_INET; /* We only need IPv4 interfaces */ 1065 lifc.lifc_flags = LIFC_NOXMIT; 1066 lifc.lifc_len = needed; 1067 lifc.lifc_buf = buf; 1068 if (ioctl(sock, SIOCGLIFCONF, &lifc) == -1) { 1069 /* 1070 * IP returns EINVAL if the lifc_len we passed in is 1071 * too small. If that's the case, we need to go back 1072 * and recalculate it. 1073 */ 1074 if (errno == EINVAL) 1075 goto calculate_lifc_len; 1076 BADERR(_B_TRUE, "ifscan: ioctl(SIOCGLIFCONF)"); 1077 } 1078 1079 /* 1080 * If the returned lifc_len is within one lifreq of the 1081 * requested ammount, we may have used a buffer which 1082 * was too small to hold all of the interfaces. In that 1083 * case go back and recalculate needed. 1084 */ 1085 if (lifc.lifc_len >= needed - sizeof (struct lifreq)) 1086 goto calculate_lifc_len; 1087 1088 lifrp = lifc.lifc_req; 1089 lifrp_lim = lifrp + lifc.lifc_len / sizeof (*lifrp); 1090 for (; lifrp < lifrp_lim; lifrp++) { 1091 1092 (void) memset(&ifs, 0, sizeof (ifs)); 1093 1094 (void) strlcpy(ifs.int_name, lifrp->lifr_name, 1095 sizeof (ifs.int_name)); 1096 1097 /* SIOCGLIFCONF fills in the lifr_addr of each lifreq */ 1098 ifs.int_addr = ((struct sockaddr_in *)&lifrp->lifr_addr)-> 1099 sin_addr.s_addr; 1100 1101 if (ioctl(sock, SIOCGLIFFLAGS, lifrp) == -1) { 1102 if (!(prev_complaints & COMP_BAD_FLAGS)) 1103 writelog(LOG_NOTICE, 1104 "unable to get interface flags for %s: %s", 1105 ifs.int_name, rip_strerror(errno)); 1106 complaints |= COMP_BAD_FLAGS; 1107 ifs.int_if_flags = 0; 1108 } else { 1109 ifs.int_if_flags = lifrp->lifr_flags; 1110 } 1111 1112 if (IN_CLASSD(ntohl(ifs.int_addr)) || 1113 (ntohl(ifs.int_addr) & IN_CLASSA_NET) == 0) { 1114 if (IS_IFF_UP(ifs.int_if_flags)) { 1115 if (!(prev_complaints & COMP_BADADDR)) 1116 writelog(LOG_NOTICE, 1117 "%s has a bad address %s", 1118 ifs.int_name, 1119 naddr_ntoa(ifs.int_addr)); 1120 complaints |= COMP_BADADDR; 1121 } 1122 continue; 1123 } 1124 1125 /* Ignore interface with IPv4 link local address. */ 1126 if (IN_LINKLOCAL(ntohl(ifs.int_addr))) 1127 continue; 1128 1129 /* Get the interface index. */ 1130 if (ioctl(sock, SIOCGLIFINDEX, lifrp) == -1) { 1131 ifindex = 0; 1132 ifs.int_if_flags &= ~IFF_UP; 1133 if (!(prev_complaints & COMP_NO_INDEX)) 1134 writelog(LOG_NOTICE, "%s has no ifIndex: %s", 1135 ifs.int_name, rip_strerror(errno)); 1136 complaints |= COMP_NO_INDEX; 1137 } else { 1138 ifindex = lifrp->lifr_index; 1139 } 1140 1141 /* 1142 * Get the destination address for point-to-point 1143 * interfaces. 1144 */ 1145 if (ifs.int_if_flags & IFF_POINTOPOINT) { 1146 sinp = (struct sockaddr_in *)&lifrp->lifr_dstaddr; 1147 if (ioctl(sock, SIOCGLIFDSTADDR, lifrp) == -1) { 1148 if (IS_IFF_UP(ifs.int_if_flags)) { 1149 if (!(prev_complaints & COMP_NODST)) 1150 writelog(LOG_NOTICE, 1151 "%s has no destination " 1152 "address : %s", 1153 ifs.int_name, 1154 rip_strerror(errno)); 1155 complaints |= COMP_NODST; 1156 } 1157 continue; 1158 } 1159 ifs.int_net = ntohl(sinp->sin_addr.s_addr); 1160 if (IN_CLASSD(ntohl(ifs.int_net)) || 1161 (ifs.int_net != 0 && 1162 (ifs.int_net & IN_CLASSA_NET) == 0)) { 1163 if (IS_IFF_UP(ifs.int_if_flags)) { 1164 if (!(prev_complaints & COMP_NODST)) 1165 writelog(LOG_NOTICE, 1166 "%s has a bad " 1167 "destination address %s", 1168 ifs.int_name, 1169 naddr_ntoa(ifs.int_net)); 1170 complaints |= COMP_NODST; 1171 } 1172 continue; 1173 } 1174 ifs.int_dstaddr = sinp->sin_addr.s_addr; 1175 } 1176 1177 /* Get the subnet mask */ 1178 sinp = (struct sockaddr_in *)&lifrp->lifr_addr; 1179 if (ioctl(sock, SIOCGLIFNETMASK, lifrp) == -1) { 1180 if (IS_IFF_UP(ifs.int_if_flags)) { 1181 if (!(prev_complaints & COMP_NOMASK)) 1182 writelog(LOG_NOTICE, 1183 "%s has no netmask: %s", 1184 ifs.int_name, rip_strerror(errno)); 1185 complaints |= COMP_NOMASK; 1186 } 1187 continue; 1188 } 1189 if (sinp->sin_addr.s_addr == INADDR_ANY) { 1190 if (!(ifs.int_if_flags & 1191 (IFF_POINTOPOINT|IFF_LOOPBACK))) { 1192 if (IS_IFF_UP(ifs.int_if_flags)) { 1193 if (!(prev_complaints & COMP_NOMASK)) 1194 writelog(LOG_NOTICE, 1195 "%s has all-zero netmask", 1196 ifs.int_name); 1197 complaints |= COMP_NOMASK; 1198 } 1199 continue; 1200 } 1201 ifs.int_mask = IP_HOST_MASK; 1202 } else { 1203 ifs.int_mask = ntohl(sinp->sin_addr.s_addr); 1204 } 1205 1206 /* 1207 * Get the broadcast address on broadcast capable 1208 * interfaces. 1209 */ 1210 if (ifs.int_if_flags & IFF_BROADCAST) { 1211 if (ioctl(sock, SIOCGLIFBRDADDR, lifrp) == -1) { 1212 if (IS_IFF_UP(ifs.int_if_flags)) { 1213 if (!(prev_complaints & COMP_NOBADDR)) 1214 writelog(LOG_NOTICE, 1215 "%s has no broadcast " 1216 "address: %s", 1217 ifs.int_name, 1218 rip_strerror(errno)); 1219 complaints |= COMP_NOBADDR; 1220 } 1221 continue; 1222 } 1223 haddr = ntohl(sinp->sin_addr.s_addr); 1224 if (IN_CLASSD(haddr) || 1225 (haddr & IN_CLASSA_NET) == 0) { 1226 if (IS_IFF_UP(ifs.int_if_flags)) { 1227 if (!(prev_complaints & COMP_NOBADDR)) 1228 writelog(LOG_NOTICE, 1229 "%s has a bad broadcast " 1230 "address %s", 1231 ifs.int_name, 1232 naddr_ntoa(haddr)); 1233 complaints |= COMP_NOBADDR; 1234 } 1235 continue; 1236 } 1237 } 1238 ifs.int_brdaddr = sinp->sin_addr.s_addr; 1239 1240 /* Get interface metric, if possible. */ 1241 if (ioctl(sock, SIOCGLIFMETRIC, lifrp) == -1) { 1242 if (IS_IFF_UP(ifs.int_if_flags)) { 1243 if (!(prev_complaints & COMP_BAD_METRIC)) 1244 writelog(LOG_NOTICE, 1245 "%s has no metric: %s", 1246 ifs.int_name, rip_strerror(errno)); 1247 complaints |= COMP_BAD_METRIC; 1248 } 1249 } else { 1250 ifs.int_metric = lifrp->lifr_metric; 1251 if (ifs.int_metric > HOPCNT_INFINITY) { 1252 if (IS_IFF_UP(ifs.int_if_flags)) { 1253 if (!(prev_complaints & 1254 COMP_BAD_METRIC)) 1255 writelog(LOG_NOTICE, 1256 "%s has a metric of %d, " 1257 "defaulting to %d", 1258 ifs.int_name, 1259 ifs.int_metric, 1260 HOPCNT_INFINITY); 1261 complaints |= COMP_BAD_METRIC; 1262 } 1263 ifs.int_metric = HOPCNT_INFINITY; 1264 } 1265 } 1266 1267 ifs.int_state |= IS_CHECKED; 1268 ifs.int_query_time = NEVER; 1269 1270 /* 1271 * If this is an alias, then mark it appropriately. 1272 * Do not output RIP or Router-Discovery packets via 1273 * aliases. 1274 */ 1275 if (strchr(ifs.int_name, ':') != NULL) 1276 ifs.int_state |= IS_ALIAS; 1277 1278 if (ifs.int_if_flags & IFF_LOOPBACK) { 1279 ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC; 1280 ifs.int_dstaddr = ifs.int_addr; 1281 ifs.int_mask = HOST_MASK; 1282 ifs.int_ripv1_mask = HOST_MASK; 1283 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 1284 ifs.int_net = ntohl(ifs.int_dstaddr); 1285 if (!foundloopback) { 1286 foundloopback = _B_TRUE; 1287 loopaddr = ifs.int_addr; 1288 loop_rts.rts_gate = loopaddr; 1289 loop_rts.rts_router = loopaddr; 1290 } 1291 1292 } else if (ifs.int_if_flags & IFF_POINTOPOINT) { 1293 ifs.int_ripv1_mask = ifs.int_mask; 1294 ifs.int_mask = HOST_MASK; 1295 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 1296 1297 } else { 1298 ifs.int_dstaddr = ifs.int_addr; 1299 ifs.int_ripv1_mask = ifs.int_mask; 1300 ifs.int_std_mask = std_mask(ifs.int_addr); 1301 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask; 1302 if (ifs.int_mask != ifs.int_std_mask) 1303 ifs.int_state |= IS_SUBNET; 1304 } 1305 ifs.int_std_net = ifs.int_net & ifs.int_std_mask; 1306 ifs.int_std_addr = htonl(ifs.int_std_net); 1307 1308 /* 1309 * If this interface duplicates another, mark it 1310 * appropriately so that we don't generate duplicate 1311 * packets. 1312 */ 1313 ifp = check_dup(ifs.int_name, ifs.int_addr, ifs.int_dstaddr, 1314 ifs.int_mask, ifs.int_if_flags, _B_FALSE); 1315 if (ifp != NULL) { 1316 trace_misc("%s (%s%s%s) is a duplicate of %s (%s%s%s)", 1317 ifs.int_name, 1318 addrname(ifs.int_addr, ifs.int_mask, 1), 1319 ((ifs.int_if_flags & IFF_POINTOPOINT) ? 1320 "-->" : ""), 1321 ((ifs.int_if_flags & IFF_POINTOPOINT) ? 1322 naddr_ntoa(ifs.int_dstaddr) : ""), 1323 ifp->int_name, 1324 addrname(ifp->int_addr, ifp->int_mask, 1), 1325 ((ifp->int_if_flags & IFF_POINTOPOINT) ? 1326 "-->" : ""), 1327 ((ifp->int_if_flags & IFF_POINTOPOINT) ? 1328 naddr_ntoa(ifp->int_dstaddr) : "")); 1329 ifs.int_state |= IS_DUP; 1330 } else { 1331 ifs.int_state &= ~IS_DUP; 1332 } 1333 1334 /* 1335 * See if this is a familiar interface. 1336 * If so, stop worrying about it if it is the same. 1337 * Start it over if it now is to somewhere else, as happens 1338 * frequently with PPP and SLIP, or if its forwarding 1339 * status has changed. 1340 */ 1341 ifp = ifwithname(ifs.int_name); 1342 if (ifp != NULL) { 1343 ifp->int_state |= IS_CHECKED; 1344 ifp->int_state = (ifp->int_state & ~IS_DUP) | 1345 (ifs.int_state & IS_DUP); 1346 1347 if ((ifp->int_phys == NULL && ifindex != 0) || 1348 (ifp->int_phys != NULL && 1349 ifp->int_phys->phyi_index != ifindex) || 1350 0 != ((ifp->int_if_flags ^ ifs.int_if_flags) 1351 & (IFF_BROADCAST | IFF_LOOPBACK | 1352 IFF_POINTOPOINT | IFF_MULTICAST | 1353 IFF_ROUTER | IFF_NORTEXCH | IFF_NOXMIT)) || 1354 ifp->int_addr != ifs.int_addr || 1355 ifp->int_brdaddr != ifs.int_brdaddr || 1356 ifp->int_dstaddr != ifs.int_dstaddr || 1357 ifp->int_mask != ifs.int_mask || 1358 ifp->int_metric != ifs.int_metric) { 1359 /* 1360 * Forget old information about 1361 * a changed interface. 1362 */ 1363 trace_act("interface %s has changed", 1364 ifp->int_name); 1365 ifdel(ifp); 1366 ifp = NULL; 1367 } 1368 } 1369 1370 if (ifp != NULL) { 1371 /* note interfaces that have been turned off */ 1372 if (!IS_IFF_UP(ifs.int_if_flags)) { 1373 if (IS_IFF_UP(ifp->int_if_flags)) { 1374 writelog(LOG_WARNING, 1375 "interface %s to %s turned off", 1376 ifp->int_name, 1377 naddr_ntoa(ifp->int_dstaddr)); 1378 if_bad(ifp, _B_FALSE); 1379 ifp->int_if_flags &= ~IFF_UP; 1380 } else if (ifp->int_phys != NULL && 1381 now.tv_sec > (ifp->int_phys->phyi_data.ts + 1382 CHECK_BAD_INTERVAL)) { 1383 trace_act("interface %s has been off" 1384 " %ld seconds; forget it", 1385 ifp->int_name, 1386 now.tv_sec - 1387 ifp->int_phys->phyi_data.ts); 1388 ifdel(ifp); 1389 } 1390 continue; 1391 } 1392 /* or that were off and are now ok */ 1393 if (!IS_IFF_UP(ifp->int_if_flags)) { 1394 ifp->int_if_flags |= IFF_UP; 1395 if_ok(ifp, "", _B_FALSE); 1396 } 1397 1398 /* 1399 * If it has been long enough, 1400 * see if the interface is broken. 1401 */ 1402 if ((phyi = ifp->int_phys) == NULL || 1403 now.tv_sec < phyi->phyi_data.ts + 1404 CHECK_BAD_INTERVAL) 1405 continue; 1406 1407 (void) memset(&newstats, 0, sizeof (newstats)); 1408 if (get_if_kstats(ifp, &newstats) == -1) { 1409 if (!(prev_complaints & COMP_NO_KSTATS)) 1410 writelog(LOG_WARNING, 1411 "unable to obtain kstats for %s", 1412 phyi->phyi_name); 1413 complaints |= COMP_NO_KSTATS; 1414 } 1415 1416 /* 1417 * If the interface just awoke, restart the counters. 1418 */ 1419 if (phyi->phyi_data.ts == 0) { 1420 phyi->phyi_data = newstats; 1421 continue; 1422 } 1423 1424 in = newstats.ipackets - phyi->phyi_data.ipackets; 1425 ierr = newstats.ierrors - phyi->phyi_data.ierrors; 1426 out = newstats.opackets - phyi->phyi_data.opackets; 1427 oerr = newstats.oerrors - phyi->phyi_data.oerrors; 1428 phyi->phyi_data = newstats; 1429 1430 /* 1431 * Withhold judgment when the short error counters 1432 * wrap, the interface is reset, or if there are 1433 * no kstats. 1434 */ 1435 if (ierr < 0 || in < 0 || oerr < 0 || out < 0 || 1436 newstats.ts == 0) { 1437 LIM_SEC(ifscan_timer, 1438 now.tv_sec + CHECK_BAD_INTERVAL); 1439 continue; 1440 } 1441 1442 /* Withhold judgement when there is no traffic */ 1443 if (in == 0 && out == 0 && ierr == 0 && oerr == 0) 1444 continue; 1445 1446 /* 1447 * It is bad if at least 25% of input or output on 1448 * an interface results in errors. Require 1449 * presistent problems before marking it dead. 1450 */ 1451 if ((ierr > 0 && ierr >= in/4) || 1452 (oerr > 0 && oerr >= out/4)) { 1453 if (!(ifp->int_state & IS_SICK)) { 1454 trace_act("interface %s to %s" 1455 " sick: in=%d ierr=%d" 1456 " out=%d oerr=%d", 1457 ifp->int_name, 1458 naddr_ntoa(ifp->int_dstaddr), 1459 in, ierr, out, oerr); 1460 if_sick(ifp, _B_TRUE); 1461 continue; 1462 } 1463 if (!(ifp->int_state & IS_BROKE)) { 1464 writelog(LOG_WARNING, 1465 "interface %s to %s broken:" 1466 " in=%d ierr=%d out=%d oerr=%d", 1467 ifp->int_name, 1468 naddr_ntoa(ifp->int_dstaddr), 1469 in, ierr, out, oerr); 1470 if_bad(ifp, _B_TRUE); 1471 } 1472 continue; 1473 } 1474 1475 /* otherwise, it is active and healthy */ 1476 ifp->int_act_time = now.tv_sec; 1477 if_ok(ifp, "", _B_TRUE); 1478 continue; 1479 } 1480 1481 /* 1482 * This is a new interface. 1483 * If it is dead, forget it. 1484 */ 1485 if (!IS_IFF_UP(ifs.int_if_flags)) 1486 continue; 1487 1488 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | 1489 IFF_BROADCAST | IFF_LOOPBACK)) && 1490 !(ifs.int_state & IS_PASSIVE)) { 1491 if (!(prev_complaints & COMP_BAD_FLAGS)) 1492 trace_act("%s is neither broadcast, " 1493 "point-to-point, nor loopback", 1494 ifs.int_name); 1495 complaints |= COMP_BAD_FLAGS; 1496 if (!(ifs.int_if_flags & IFF_MULTICAST)) 1497 ifs.int_state |= IS_NO_RDISC; 1498 } 1499 1500 1501 /* 1502 * It is new and ok. Add it to the list of interfaces 1503 */ 1504 ifp = rtmalloc(sizeof (*ifp), "ifscan ifp"); 1505 (void) memcpy(ifp, &ifs, sizeof (*ifp)); 1506 get_parms(ifp); 1507 if_link(ifp, ifindex); 1508 trace_if("Add", ifp); 1509 1510 if (ifp->int_phys != NULL && 1511 get_if_kstats(ifp, &ifp->int_phys->phyi_data) == -1) { 1512 if (!(prev_complaints & COMP_NO_KSTATS)) 1513 writelog(LOG_NOTICE, 1514 "unable to obtain kstats for %s", 1515 ifp->int_phys->phyi_name); 1516 complaints |= COMP_NO_KSTATS; 1517 } 1518 1519 /* Detect interfaces that have conflicting netmasks. */ 1520 if (!(ifp->int_if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK))) { 1521 for (ifp1 = ifnet; ifp1 != NULL; 1522 ifp1 = ifp1->int_next) { 1523 if (ifp1->int_mask == ifp->int_mask) 1524 continue; 1525 1526 /* 1527 * we don't care about point-to-point 1528 * or loopback aliases 1529 */ 1530 if (ifp1->int_if_flags & 1531 (IFF_POINTOPOINT|IFF_LOOPBACK)) { 1532 continue; 1533 } 1534 1535 /* ignore aliases on the same network */ 1536 if (ifp->int_phys == ifp1->int_phys) 1537 continue; 1538 1539 if (on_net(ifp->int_addr, 1540 ifp1->int_net, ifp1->int_mask) || 1541 on_net(ifp1->int_addr, 1542 ifp->int_net, ifp->int_mask)) { 1543 writelog(LOG_INFO, 1544 "possible netmask problem" 1545 " between %s:%s and %s:%s", 1546 ifp->int_name, 1547 addrname(htonl(ifp->int_net), 1548 ifp->int_mask, 1), 1549 ifp1->int_name, 1550 addrname(htonl(ifp1->int_net), 1551 ifp1->int_mask, 1)); 1552 complaints |= COMP_NETMASK; 1553 } 1554 } 1555 } 1556 1557 if (!(ifp->int_state & IS_DUP) && 1558 !IS_IFF_QUIET(ifp->int_if_flags)) { 1559 /* Count the # of directly connected networks. */ 1560 tot_interfaces++; 1561 if (!IS_RIP_OFF(ifp->int_state)) 1562 rip_interfaces++; 1563 if (!IS_RIP_OUT_OFF(ifp->int_state)) 1564 ripout_interfaces++; 1565 if (IS_IFF_ROUTING(ifp->int_if_flags)) 1566 fwd_interfaces++; 1567 1568 if_ok_rdisc(ifp); 1569 rip_on(ifp); 1570 } 1571 } 1572 1573 (void) close(sock); 1574 1575 /* 1576 * If we are multi-homed and have at least two interfaces that 1577 * are able to forward, then output RIP by default. 1578 */ 1579 if (!supplier_set) 1580 set_supplier(); 1581 1582 /* 1583 * If we are multi-homed, optionally advertise a route to 1584 * our main address. 1585 */ 1586 if (advertise_mhome || (tot_interfaces > 1 && mhome)) { 1587 /* lookup myaddr if we haven't done so already */ 1588 if (myaddr == 0) { 1589 char myname[MAXHOSTNAMELEN+1]; 1590 1591 /* 1592 * If we are unable to resolve our hostname, don't 1593 * bother trying again. 1594 */ 1595 if (gethostname(myname, MAXHOSTNAMELEN) == -1) { 1596 msglog("gethostname: %s", rip_strerror(errno)); 1597 advertise_mhome = _B_FALSE; 1598 mhome = _B_FALSE; 1599 } else if (gethost(myname, &myaddr) == 0) { 1600 writelog(LOG_WARNING, 1601 "unable to resolve local hostname %s", 1602 myname); 1603 advertise_mhome = _B_FALSE; 1604 mhome = _B_FALSE; 1605 } 1606 } 1607 if (myaddr != 0 && 1608 (ifp = ifwithaddr(myaddr, _B_FALSE, _B_FALSE)) != NULL && 1609 foundloopback) { 1610 advertise_mhome = _B_TRUE; 1611 rt = rtget(myaddr, HOST_MASK); 1612 if (rt != NULL) { 1613 if (rt->rt_ifp != ifp || 1614 rt->rt_router != loopaddr) { 1615 rtdelete(rt); 1616 rt = NULL; 1617 } else { 1618 loop_rts.rts_ifp = ifp; 1619 loop_rts.rts_metric = 0; 1620 loop_rts.rts_time = rt->rt_time; 1621 loop_rts.rts_origin = RO_LOOPBCK; 1622 rtchange(rt, rt->rt_state | RS_MHOME, 1623 &loop_rts, NULL); 1624 } 1625 } 1626 if (rt == NULL) { 1627 loop_rts.rts_ifp = ifp; 1628 loop_rts.rts_metric = 0; 1629 loop_rts.rts_origin = RO_LOOPBCK; 1630 rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts); 1631 } 1632 } 1633 } 1634 1635 for (ifp = ifnet; ifp != NULL; ifp = ifp1) { 1636 ifp1 = ifp->int_next; /* because we may delete it */ 1637 1638 /* Forget any interfaces that have disappeared. */ 1639 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) { 1640 trace_act("interface %s has disappeared", 1641 ifp->int_name); 1642 ifdel(ifp); 1643 continue; 1644 } 1645 1646 if ((ifp->int_state & IS_BROKE) && 1647 !(ifp->int_state & IS_PASSIVE)) 1648 LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL); 1649 1650 /* 1651 * If we ever have a RIPv1 interface, assume we always will. 1652 * It might come back if it ever goes away. 1653 */ 1654 if (!(ifp->int_state & (IS_NO_RIPV1_OUT | IS_DUP)) && 1655 should_supply(ifp)) 1656 have_ripv1_out = _B_TRUE; 1657 if (!(ifp->int_state & IS_NO_RIPV1_IN)) 1658 have_ripv1_in = _B_TRUE; 1659 } 1660 1661 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) { 1662 /* 1663 * Ensure there is always a network route for interfaces, 1664 * after any dead interfaces have been deleted, which 1665 * might affect routes for point-to-point links. 1666 */ 1667 if (addrouteforif(ifp) == 0) 1668 continue; 1669 1670 /* 1671 * Add routes to the local end of point-to-point interfaces 1672 * using loopback. 1673 */ 1674 if ((ifp->int_if_flags & IFF_POINTOPOINT) && 1675 !(ifp->int_state & IS_REMOTE) && foundloopback) { 1676 /* 1677 * Delete any routes to the network address through 1678 * foreign routers. Remove even static routes. 1679 */ 1680 del_static(ifp->int_addr, HOST_MASK, 0, ifp, 0); 1681 rt = rtget(ifp->int_addr, HOST_MASK); 1682 if (rt != NULL && rt->rt_router != loopaddr) { 1683 rtdelete(rt); 1684 rt = NULL; 1685 } 1686 if (rt != NULL) { 1687 if (!(rt->rt_state & RS_LOCAL) || 1688 rt->rt_metric > ifp->int_metric) { 1689 ifp1 = ifp; 1690 } else { 1691 ifp1 = rt->rt_ifp; 1692 } 1693 loop_rts.rts_ifp = ifp1; 1694 loop_rts.rts_metric = 0; 1695 loop_rts.rts_time = rt->rt_time; 1696 loop_rts.rts_origin = RO_LOOPBCK; 1697 rtchange(rt, ((rt->rt_state & ~RS_NET_SYN) | 1698 (RS_IF|RS_LOCAL)), &loop_rts, 0); 1699 } else { 1700 loop_rts.rts_ifp = ifp; 1701 loop_rts.rts_metric = 0; 1702 loop_rts.rts_origin = RO_LOOPBCK; 1703 rtadd(ifp->int_addr, HOST_MASK, 1704 (RS_IF | RS_LOCAL), &loop_rts); 1705 } 1706 } 1707 } 1708 1709 /* add the authority routes */ 1710 for (intnetp = intnets; intnetp != NULL; 1711 intnetp = intnetp->intnet_next) { 1712 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask); 1713 if (rt != NULL && 1714 !(rt->rt_state & RS_NO_NET_SYN) && 1715 !(rt->rt_state & RS_NET_INT)) { 1716 rtdelete(rt); 1717 rt = NULL; 1718 } 1719 if (rt == NULL) { 1720 loop_rts.rts_ifp = NULL; 1721 loop_rts.rts_metric = intnetp->intnet_metric-1; 1722 loop_rts.rts_origin = RO_LOOPBCK; 1723 rtadd(intnetp->intnet_addr, intnetp->intnet_mask, 1724 RS_NET_SYN | RS_NET_INT, &loop_rts); 1725 } 1726 } 1727 1728 prev_complaints = complaints; 1729 } 1730 1731 1732 static void 1733 check_net_syn(struct interface *ifp) 1734 { 1735 struct rt_entry *rt; 1736 struct rt_spare new; 1737 1738 /* 1739 * Turn on the need to automatically synthesize a network route 1740 * for this interface only if we are running RIPv1 on some other 1741 * interface that is on a different class-A,B,or C network. 1742 */ 1743 if (have_ripv1_out || have_ripv1_in) { 1744 ifp->int_state |= IS_NEED_NET_SYN; 1745 rt = rtget(ifp->int_std_addr, ifp->int_std_mask); 1746 if (rt != NULL && 1747 0 == (rt->rt_state & RS_NO_NET_SYN) && 1748 (!(rt->rt_state & RS_NET_SYN) || 1749 rt->rt_metric > ifp->int_metric)) { 1750 rtdelete(rt); 1751 rt = NULL; 1752 } 1753 if (rt == NULL) { 1754 (void) memset(&new, 0, sizeof (new)); 1755 new.rts_ifp = ifp; 1756 new.rts_gate = ifp->int_addr; 1757 new.rts_router = ifp->int_addr; 1758 new.rts_metric = ifp->int_metric; 1759 new.rts_origin = RO_NET_SYN; 1760 rtadd(ifp->int_std_addr, ifp->int_std_mask, 1761 RS_NET_SYN, &new); 1762 } 1763 1764 } else { 1765 ifp->int_state &= ~IS_NEED_NET_SYN; 1766 1767 rt = rtget(ifp->int_std_addr, ifp->int_std_mask); 1768 if (rt != NULL && 1769 (rt->rt_state & RS_NET_SYN) && 1770 rt->rt_ifp == ifp) 1771 rtbad_sub(rt, NULL); 1772 } 1773 } 1774 1775 1776 /* 1777 * Add route for interface if not currently installed. 1778 * Create route to other end if a point-to-point link, 1779 * otherwise a route to this (sub)network. 1780 */ 1781 static boolean_t /* _B_FALSE=bad interface */ 1782 addrouteforif(struct interface *ifp) 1783 { 1784 struct rt_entry *rt; 1785 struct rt_spare new; 1786 in_addr_t dst; 1787 uint16_t rt_newstate = RS_IF; 1788 1789 1790 /* skip sick interfaces */ 1791 if (ifp->int_state & IS_BROKE) 1792 return (_B_FALSE); 1793 1794 /* 1795 * don't install routes for duplicate interfaces, or 1796 * unnumbered point-to-point interfaces. 1797 */ 1798 if ((ifp->int_state & IS_DUP) || 1799 ((ifp->int_if_flags & IFF_POINTOPOINT) && ifp->int_dstaddr == 0)) 1800 return (_B_TRUE); 1801 1802 /* 1803 * If the interface on a subnet, then install a RIPv1 route to 1804 * the network as well (unless it is sick). 1805 */ 1806 if (ifp->int_state & IS_SUBNET) 1807 check_net_syn(ifp); 1808 1809 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) ? 1810 ifp->int_dstaddr : htonl(ifp->int_net)); 1811 1812 (void) memset(&new, 0, sizeof (new)); 1813 new.rts_ifp = ifp; 1814 new.rts_router = ifp->int_addr; 1815 new.rts_gate = ifp->int_addr; 1816 new.rts_metric = ifp->int_metric; 1817 new.rts_time = now.tv_sec; 1818 if (ifp->int_if_flags & IFF_POINTOPOINT) 1819 new.rts_origin = RO_PTOPT; 1820 else if (ifp->int_if_flags & IFF_LOOPBACK) 1821 new.rts_origin = RO_LOOPBCK; 1822 else 1823 new.rts_origin = RO_IF; 1824 1825 /* 1826 * If we are going to send packets to the gateway, 1827 * it must be reachable using our physical interfaces 1828 */ 1829 if ((ifp->int_state & IS_REMOTE) && 1830 !(ifp->int_state & IS_EXTERNAL) && 1831 !check_remote(ifp)) 1832 return (_B_FALSE); 1833 1834 /* 1835 * We are finished if the correct main interface route exists. 1836 * The right route must be for the right interface, not synthesized 1837 * from a subnet, be a "gateway" or not as appropriate, and so forth. 1838 */ 1839 del_static(dst, ifp->int_mask, 0, ifp, 0); 1840 rt = rtget(dst, ifp->int_mask); 1841 if (!IS_IFF_ROUTING(ifp->int_if_flags)) 1842 rt_newstate |= RS_NOPROPAGATE; 1843 if (rt != NULL) { 1844 if ((rt->rt_ifp != ifp || rt->rt_router != ifp->int_addr) && 1845 (rt->rt_ifp == NULL || 1846 (rt->rt_ifp->int_state & IS_BROKE))) { 1847 rtdelete(rt); 1848 rt = NULL; 1849 } else { 1850 rtchange(rt, ((rt->rt_state | rt_newstate) & 1851 ~(RS_NET_SYN | RS_LOCAL)), &new, 0); 1852 } 1853 } 1854 if (rt == NULL) { 1855 if (ifp->int_transitions++ > 0) 1856 trace_act("re-installing interface %s;" 1857 " went up %d times", 1858 ifp->int_name, ifp->int_transitions); 1859 1860 rtadd(dst, ifp->int_mask, rt_newstate, &new); 1861 } 1862 1863 return (_B_TRUE); 1864 } 1865 1866 /* 1867 * Obtains the named kstat, and places its value in *value. It 1868 * returns 0 for success, -1 for failure. 1869 */ 1870 static int 1871 kstat_named_value(kstat_t *ksp, char *name, uint32_t *value) 1872 { 1873 kstat_named_t *knp; 1874 1875 if (ksp == NULL) 1876 return (-1); 1877 1878 if ((knp = kstat_data_lookup(ksp, name)) == NULL) { 1879 return (-1); 1880 } else if (knp->data_type != KSTAT_DATA_UINT32) { 1881 return (-1); 1882 } else { 1883 *value = knp->value.ui32; 1884 return (0); 1885 } 1886 } 1887 1888 static int 1889 get_if_kstats(struct interface *ifp, struct phyi_data *newdata) 1890 { 1891 struct physical_interface *phyi = ifp->int_phys; 1892 kstat_ctl_t *kc; 1893 kstat_t *ksp; 1894 1895 /* We did this recently; don't do it again. */ 1896 if (phyi->phyi_data.ts == now.tv_sec) { 1897 if (newdata != &phyi->phyi_data) 1898 *newdata = phyi->phyi_data; 1899 return (0); 1900 } 1901 1902 if ((kc = kstat_open()) == NULL) 1903 return (-1); 1904 1905 if ((ksp = kstat_lookup(kc, NULL, -1, phyi->phyi_name)) == NULL) { 1906 (void) kstat_close(kc); 1907 return (-1); 1908 } 1909 1910 if (kstat_read(kc, ksp, NULL) == -1) { 1911 (void) kstat_close(kc); 1912 return (-1); 1913 } 1914 1915 if ((kstat_named_value(ksp, "ipackets", &newdata->ipackets) == -1) || 1916 (kstat_named_value(ksp, "opackets", &newdata->opackets) == -1)) { 1917 newdata->ts = 0; 1918 (void) kstat_close(kc); 1919 return (-1); 1920 } 1921 1922 /* The loopback interface does not keep track of errors */ 1923 if (!(ifp->int_if_flags & IFF_LOOPBACK)) { 1924 if ((kstat_named_value(ksp, "ierrors", 1925 &newdata->ierrors) == -1) || 1926 (kstat_named_value(ksp, "oerrors", 1927 &newdata->oerrors) == -1)) { 1928 newdata->ts = 0; 1929 (void) kstat_close(kc); 1930 return (-1); 1931 } 1932 } 1933 1934 newdata->ts = now.tv_sec; 1935 (void) kstat_close(kc); 1936 return (0); 1937 } 1938 1939 /* 1940 * Returns true if we should supply routes to other systems. If the 1941 * user has forced us to be a supplier (by the command line) or if we 1942 * have more than one forwarding interface and this is one of the 1943 * forwarding interfaces, then behave as a RIP supplier (supply rdisc 1944 * advertisements and RIP responses). 1945 */ 1946 boolean_t 1947 should_supply(struct interface *ifp) 1948 { 1949 if (ifp != NULL && !IS_IFF_ROUTING(ifp->int_if_flags)) 1950 return (_B_FALSE); 1951 return ((supplier_set && supplier) || 1952 (!supplier_set && fwd_interfaces > 1)); 1953 } 1954