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