dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.sbin / in.routed / if.c
blob1ff2124f8dc7470fe0f7ab2ce2f14fdd72ffd2c1
1 /*
2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
5 * Copyright (c) 1983, 1993
6 * The Regents of the University of California. All rights reserved.
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.
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.
36 * $FreeBSD: src/sbin/routed/if.c,v 1.8 2000/08/11 08:24:38 sheldonh Exp $
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>
49 /* linked list of all interfaces */
50 struct interface *ifnet;
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.
57 size_t hash_table_sizes[] = { 67, 131, 257, 521, 1031, 2053, 4099, 0 };
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 */
70 /* Get first element -- for iteration */
71 #define HFIRST(htbl, arg) \
72 ((htbl)->htbl_ptrs[(htbl)->htbl_hash((arg), 0) % (htbl)->htbl_size])
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))
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;
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, > /* */))
94 boolean_t have_ripv1_out; /* have a RIPv1 interface */
95 static boolean_t have_ripv1_in;
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 *);
106 * Table of all interfaces, hashed by interface address. For remote
107 * interfaces, the gateway address is used.
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 };
114 * Table of broadcast capable interfaces, hashed by interface broadcast
115 * address.
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 };
122 * Table of physical_interface structures (lists of interfaces by ifIndex),
123 * hashed by interface index.
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 };
130 * Table of all interfaces, hashed by interface name.
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 };
137 static struct physical_interface dummy_phyi;
138 struct interface dummy_ifp;
140 /* Hash based on an IP address. */
141 static uint_t
142 ahash(const void *arg, size_t voffs)
144 /* LINTED */
145 return ((uint_t)*(const in_addr_t *)((const char *)arg + voffs));
148 static uint_t
149 ihash(const void *arg, size_t voffs)
151 /* LINTED */
152 return ((uint_t)*(const uint32_t *)((const char *)arg + voffs));
155 static uint_t
156 nhash(const void *arg, size_t voffs)
158 const char *cp = (const char *)arg + voffs;
159 uint_t i;
161 for (i = 0; *cp != '\0'; cp++) {
162 i = ((i<<1) & 0x7fffffff) | ((i>>30) & 0x00000003);
163 i ^= *cp;
165 return (i);
169 * Add an element to the head of the list.
171 static void
172 link_in(void **head, void *strp, size_t loffs)
174 struct hlinkage *hlp;
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;
184 *head = strp;
187 /* Remove from a list */
188 static void
189 link_out(void *strp, size_t loffs)
191 struct hlinkage *hlp;
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;
202 /* Add to a hash */
203 static void
204 hash_link(struct htbl *htbl, uint_t hval, void *strp)
206 void **hep;
208 if (htbl->htbl_grow && htbl->htbl_ifcount >= htbl->htbl_size * 5)
209 htbl_grow(htbl);
211 hep = &htbl->htbl_ptrs[hval % htbl->htbl_size];
212 link_in(hep, strp, htbl->htbl_link_off);
213 htbl->htbl_ifcount++;
216 /* Remove from a hash */
217 static void
218 hash_unlink(struct htbl *htbl, void *strp)
220 link_out(strp, htbl->htbl_link_off);
221 htbl->htbl_ifcount--;
224 static void
225 dummy_ifp_init(void)
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);
240 /* allocate the interface hash tables */
241 void
242 iftbl_alloc(void)
244 size_t initial_size = hash_table_sizes[0];
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 *));
252 if (errno != 0)
253 BADERR(_B_FALSE, "Unable to allocate interface tables");
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;
260 dummy_ifp_init();
264 static void
265 htbl_grow(struct htbl *htbl)
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;
272 if ((new_size = hash_table_sizes[htbl->htbl_size_index + 1]) == 0)
273 return;
275 if ((new_ptrs = calloc(new_size, sizeof (void *))) == NULL) {
277 * This is not fatal since we already have a
278 * functional, yet crowded, interface table.
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;
287 failed_count = 0;
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;
297 * Go through the list of structures, and re-link each into
298 * this new table.
300 htbl->htbl_grow = _B_FALSE;
301 while (old_size-- > 0) {
302 strp = *old_ptrs++;
303 HADD(htbl, strp);
306 htbl->htbl_grow = _B_TRUE;
307 free(saved_old_ptrs);
310 /* Link a new interface into the lists and hash tables. */
311 void
312 if_link(struct interface *ifp, uint32_t ifindex)
314 struct physical_interface *phyi;
316 link_in((void **)&ifnet, ifp, offsetof(struct interface, int_link));
318 HADD(&ahash_tbl, ifp);
319 HADD(&nhash_tbl, ifp);
321 if (ifp->int_if_flags & IFF_BROADCAST)
322 HADD(&bhash_tbl, ifp);
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;
330 if (phyi == NULL) {
331 size_t size;
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);
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);
345 link_in((void **)&phyi->phyi_interface, ifp,
346 offsetof(struct interface, int_ilist));
347 ifp->int_phys = phyi;
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 */
357 struct interface *ifp, *possible = NULL;
358 uint32_t remote_state;
360 remote_state = (!remote ? IS_REMOTE : 0);
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;
373 if (possible != NULL || !bcast)
374 return (possible);
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;
387 return (possible);
391 /* find the interface with the specified name ("hme0" for example) */
392 struct interface *
393 ifwithname(const char *name)
395 struct interface *ifp;
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);
405 * If there is no known interface, maybe there is a
406 * new interface. So just once look for new interfaces.
408 if (IF_RESCAN_DELAY())
409 return (NULL);
410 ifscan();
414 /* Return physical interface with the specified name */
415 struct physical_interface *
416 phys_byname(const char *name)
418 int nlen;
419 size_t i;
420 struct physical_interface *phyi;
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);
431 return (NULL);
434 struct interface *
435 findremoteif(in_addr_t addr)
437 struct interface *ifp;
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);
445 return (NULL);
448 struct interface *
449 findifaddr(in_addr_t addr)
451 struct interface *ifp;
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);
459 return (NULL);
463 * Return the first interface with the given index.
465 struct interface *
466 ifwithindex(ulong_t index,
467 boolean_t rescan_ok)
469 struct physical_interface *phyi;
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);
479 * If there is no known interface, maybe there is a
480 * new interface. So just once look for new interfaces.
482 if (!rescan_ok || IF_RESCAN_DELAY())
483 return (NULL);
484 rescan_ok = _B_FALSE;
485 ifscan();
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.
494 boolean_t
495 addr_on_ifp(in_addr_t addr, struct interface *ifp,
496 struct interface **best)
498 struct interface *p_best = *best;
501 * Don't use a duplicate interface since it is unusable for output.
503 if (ifp->int_state & IS_DUP)
504 return (_B_FALSE);
506 if (ifp->int_if_flags & IFF_POINTOPOINT) {
507 if (ifp->int_dstaddr == addr) {
508 *best = NULL;
509 return (_B_TRUE);
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);
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;
528 return (_B_FALSE);
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.
538 struct interface *
539 iflookup(in_addr_t addr)
541 struct interface *ifp, *maybe;
543 maybe = NULL;
544 for (;;) {
545 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
547 /* Exact match found */
548 if (addr_on_ifp(addr, ifp, &maybe))
549 return (ifp);
553 * If there is no known interface, maybe there is a
554 * new interface. So just once look for new interfaces.
556 if (maybe == NULL && !IF_RESCAN_DELAY())
557 ifscan();
558 else
559 break;
562 if (maybe != NULL && IS_PASSIVE_IFP(maybe)) {
563 trace_misc("iflookup returning passive intf %s",
564 maybe->int_name);
566 return (maybe);
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.
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 */
578 const struct r1net *r1p;
579 in_addr_t mask = 0;
581 if (addr == 0) /* default always has 0 mask */
582 return (mask);
584 if (ifp != NULL && ifp->int_ripv1_mask != HOST_MASK) {
586 * If the target network is that of the associated interface
587 * on which it arrived, then use the netmask of the interface.
589 if (on_net(addr, ifp->int_net, ifp->int_std_mask))
590 mask = ifp->int_ripv1_mask;
592 } else {
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.
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;
609 if (mask == 0) {
611 * Check to see if the user has supplied an applicable
612 * netmask as a ripv1_mask option in /etc/gateways.
614 for (r1p = r1nets; r1p != NULL; r1p = r1p->r1net_next) {
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.
620 if (on_net(addr, r1p->r1net_net, r1p->r1net_match) &&
621 r1p->r1net_mask > mask)
622 mask = r1p->r1net_mask;
625 /* Otherwise, make the classic A/B/C guess. */
626 if (mask == 0)
627 mask = std_mask(addr);
630 return (mask);
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 */
638 in_addr_t mask = ripv1_mask_net(addr, ifp);
642 * If the computed netmask does not mask all of the set bits
643 * in the address, then assume it is a host address
645 if ((ntohl(addr) & ~mask) != 0)
646 mask = HOST_MASK;
647 return (mask);
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)
655 addr = ntohl(addr);
657 if (IN_CLASSA(addr)) {
658 if (addr == 0)
659 return (_B_TRUE); /* default */
661 addr >>= IN_CLASSA_NSHIFT;
662 return (addr != 0 && addr != IN_LOOPBACKNET);
665 /* Must not allow destination to be link local address. */
666 if (IN_LINKLOCAL(addr))
667 return (_B_FALSE);
669 if (IN_CLASSB(addr) || IN_CLASSC(addr))
670 return (_B_TRUE);
672 if (IN_CLASSD(addr))
673 return (_B_FALSE);
675 return (_B_TRUE);
680 * Find an existing interface which has the given parameters, but don't
681 * return the interface with name "name" if "name" is specified.
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 */
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;
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;
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)
708 if (!allowdups && (ifp->int_state & IS_DUP))
709 continue;
711 if (ifp->int_mask != mask)
712 continue;
714 if (!IS_IFF_UP(ifp->int_if_flags))
715 continue;
718 * The local address can only be shared with a point-to-point
719 * link.
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;
737 return (best_ifp);
742 * See that a remote gateway is reachable.
743 * Note that the answer can change as real interfaces come and go.
745 boolean_t /* _B_FALSE=bad _B_TRUE=good */
746 check_remote(struct interface *ifp)
748 struct rt_entry *rt;
750 /* do not worry about other kinds */
751 if (!(ifp->int_state & IS_REMOTE))
752 return (_B_TRUE);
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);
762 * the gateway cannot be reached directly from one of our
763 * interfaces
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);
770 return (_B_FALSE);
773 /* Delete an interface. */
774 static void
775 ifdel(struct interface *ifp)
777 struct rewire_data wire;
778 boolean_t resurrected;
779 struct physical_interface *phyi;
781 trace_if("Del", ifp);
783 ifp->int_state |= IS_BROKE;
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);
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);
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.
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)) {
813 trace_act("promoting duplicate %s in place of %s",
814 wire.if_new->int_name, ifp->int_name);
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);
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++;
833 set_rdisc_mg(wire.if_new, 1);
834 rip_mcast_on(wire.if_new);
836 /* We came out ok; no need to clobber routes over this. */
837 resurrected = _B_TRUE;
840 rip_mcast_off(ifp);
841 if (rip_sock_interface == ifp)
842 rip_sock_interface = NULL;
844 set_rdisc_mg(ifp, 0);
847 * Note that duplicates are not counted in the total number of
848 * interfaces.
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--;
860 if (!resurrected) {
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.
866 (void) rn_walktree(rhead, walk_bad, ifp);
867 kern_flush_ifp(ifp);
869 if_bad_rdisc(ifp);
872 free(ifp);
876 /* Mark an interface ill. */
877 void
878 if_sick(struct interface *ifp, boolean_t recurse)
880 struct interface *ifp1;
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);
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);
900 /* Mark an interface dead. */
901 static void
902 if_bad(struct interface *ifp, boolean_t recurse)
904 struct interface *ifp1;
905 struct rewire_data wire;
907 if (ifp->int_state & IS_BROKE)
908 return;
910 LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL);
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 */
917 trace_if("Chg", ifp);
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);
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);
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;
947 /* join the mcast groups for the replacement */
948 set_rdisc_mg(wire.if_new, 1);
949 rip_mcast_on(wire.if_new);
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);
960 /* Mark an interface alive */
961 void
962 if_ok(struct interface *ifp, const char *type, boolean_t recurse)
964 struct interface *ifp1;
965 boolean_t wasbroken = _B_FALSE;
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;
978 if (recurse && ifp->int_phys != NULL && IS_IFF_UP(ifp->int_if_flags)) {
979 ifp->int_phys->phyi_data.ts = 0;
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);
989 if (wasbroken) {
990 if (!(ifp->int_state & IS_DUP))
991 if_ok_rdisc(ifp);
993 if (ifp->int_state & IS_REMOTE)
994 (void) addrouteforif(ifp);
998 boolean_t
999 remote_address_ok(struct interface *ifp, in_addr_t addr)
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);
1007 return (_B_FALSE);
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.
1015 void
1016 ifscan(void)
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
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;
1050 last_ifscan = now;
1051 ifscan_timer.tv_sec = now.tv_sec +
1052 (supplier || tot_interfaces != 1 ?
1053 CHECK_ACT_INTERVAL : CHECK_QUIET_INTERVAL);
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;
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 */
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.
1069 lifn.lifn_flags = LIFC_NOXMIT;
1070 calculate_lifc_len:
1071 if (ioctl(sock, SIOCGLIFNUM, &lifn) == -1) {
1072 BADERR(_B_TRUE, "ifscan: ioctl(SIOCGLIFNUM)");
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.
1083 needed = (lifn.lifn_count + 4) * sizeof (struct lifreq);
1084 if (needed > lastneeded || needed < lastneeded/2) {
1085 free(lastbuf);
1086 if ((buf = malloc(needed)) == NULL) {
1087 lastbuf = NULL;
1088 msglog("ifscan: malloc: %s", rip_strerror(errno));
1089 return;
1091 } else {
1092 buf = lastbuf;
1094 lastbuf = buf;
1095 lastneeded = needed;
1097 /* Get the list */
1098 lifc.lifc_family = AF_INET; /* We only need IPv4 interfaces */
1099 lifc.lifc_flags = LIFC_NOXMIT;
1100 lifc.lifc_len = needed;
1101 lifc.lifc_buf = buf;
1102 if (ioctl(sock, SIOCGLIFCONF, &lifc) == -1) {
1104 * IP returns EINVAL if the lifc_len we passed in is
1105 * too small. If that's the case, we need to go back
1106 * and recalculate it.
1108 if (errno == EINVAL)
1109 goto calculate_lifc_len;
1110 BADERR(_B_TRUE, "ifscan: ioctl(SIOCGLIFCONF)");
1114 * If the returned lifc_len is within one lifreq of the
1115 * requested ammount, we may have used a buffer which
1116 * was too small to hold all of the interfaces. In that
1117 * case go back and recalculate needed.
1119 if (lifc.lifc_len >= needed - sizeof (struct lifreq))
1120 goto calculate_lifc_len;
1122 lifrp = lifc.lifc_req;
1123 lifrp_lim = lifrp + lifc.lifc_len / sizeof (*lifrp);
1124 for (; lifrp < lifrp_lim; lifrp++) {
1126 (void) memset(&ifs, 0, sizeof (ifs));
1128 (void) strlcpy(ifs.int_name, lifrp->lifr_name,
1129 sizeof (ifs.int_name));
1131 /* SIOCGLIFCONF fills in the lifr_addr of each lifreq */
1132 ifs.int_addr = ((struct sockaddr_in *)&lifrp->lifr_addr)->
1133 sin_addr.s_addr;
1135 if (ioctl(sock, SIOCGLIFFLAGS, lifrp) == -1) {
1136 if (!(prev_complaints & COMP_BAD_FLAGS))
1137 writelog(LOG_NOTICE,
1138 "unable to get interface flags for %s: %s",
1139 ifs.int_name, rip_strerror(errno));
1140 complaints |= COMP_BAD_FLAGS;
1141 ifs.int_if_flags = 0;
1142 } else {
1143 ifs.int_if_flags = lifrp->lifr_flags;
1146 if (IN_CLASSD(ntohl(ifs.int_addr)) ||
1147 (ntohl(ifs.int_addr) & IN_CLASSA_NET) == 0) {
1148 if (IS_IFF_UP(ifs.int_if_flags)) {
1149 if (!(prev_complaints & COMP_BADADDR))
1150 writelog(LOG_NOTICE,
1151 "%s has a bad address %s",
1152 ifs.int_name,
1153 naddr_ntoa(ifs.int_addr));
1154 complaints |= COMP_BADADDR;
1156 continue;
1159 /* Ignore interface with IPv4 link local address. */
1160 if (IN_LINKLOCAL(ntohl(ifs.int_addr)))
1161 continue;
1163 /* Get the interface index. */
1164 if (ioctl(sock, SIOCGLIFINDEX, lifrp) == -1) {
1165 ifindex = 0;
1166 ifs.int_if_flags &= ~IFF_UP;
1167 if (!(prev_complaints & COMP_NO_INDEX))
1168 writelog(LOG_NOTICE, "%s has no ifIndex: %s",
1169 ifs.int_name, rip_strerror(errno));
1170 complaints |= COMP_NO_INDEX;
1171 } else {
1172 ifindex = lifrp->lifr_index;
1176 * Get the destination address for point-to-point
1177 * interfaces.
1179 if (ifs.int_if_flags & IFF_POINTOPOINT) {
1180 sinp = (struct sockaddr_in *)&lifrp->lifr_dstaddr;
1181 if (ioctl(sock, SIOCGLIFDSTADDR, lifrp) == -1) {
1182 if (IS_IFF_UP(ifs.int_if_flags)) {
1183 if (!(prev_complaints & COMP_NODST))
1184 writelog(LOG_NOTICE,
1185 "%s has no destination "
1186 "address : %s",
1187 ifs.int_name,
1188 rip_strerror(errno));
1189 complaints |= COMP_NODST;
1191 continue;
1193 ifs.int_net = ntohl(sinp->sin_addr.s_addr);
1194 if (IN_CLASSD(ntohl(ifs.int_net)) ||
1195 (ifs.int_net != 0 &&
1196 (ifs.int_net & IN_CLASSA_NET) == 0)) {
1197 if (IS_IFF_UP(ifs.int_if_flags)) {
1198 if (!(prev_complaints & COMP_NODST))
1199 writelog(LOG_NOTICE,
1200 "%s has a bad "
1201 "destination address %s",
1202 ifs.int_name,
1203 naddr_ntoa(ifs.int_net));
1204 complaints |= COMP_NODST;
1206 continue;
1208 ifs.int_dstaddr = sinp->sin_addr.s_addr;
1211 /* Get the subnet mask */
1212 sinp = (struct sockaddr_in *)&lifrp->lifr_addr;
1213 if (ioctl(sock, SIOCGLIFNETMASK, lifrp) == -1) {
1214 if (IS_IFF_UP(ifs.int_if_flags)) {
1215 if (!(prev_complaints & COMP_NOMASK))
1216 writelog(LOG_NOTICE,
1217 "%s has no netmask: %s",
1218 ifs.int_name, rip_strerror(errno));
1219 complaints |= COMP_NOMASK;
1221 continue;
1223 if (sinp->sin_addr.s_addr == INADDR_ANY) {
1224 if (!(ifs.int_if_flags &
1225 (IFF_POINTOPOINT|IFF_LOOPBACK))) {
1226 if (IS_IFF_UP(ifs.int_if_flags)) {
1227 if (!(prev_complaints & COMP_NOMASK))
1228 writelog(LOG_NOTICE,
1229 "%s has all-zero netmask",
1230 ifs.int_name);
1231 complaints |= COMP_NOMASK;
1233 continue;
1235 ifs.int_mask = IP_HOST_MASK;
1236 } else {
1237 ifs.int_mask = ntohl(sinp->sin_addr.s_addr);
1241 * Get the broadcast address on broadcast capable
1242 * interfaces.
1244 if (ifs.int_if_flags & IFF_BROADCAST) {
1245 if (ioctl(sock, SIOCGLIFBRDADDR, lifrp) == -1) {
1246 if (IS_IFF_UP(ifs.int_if_flags)) {
1247 if (!(prev_complaints & COMP_NOBADDR))
1248 writelog(LOG_NOTICE,
1249 "%s has no broadcast "
1250 "address: %s",
1251 ifs.int_name,
1252 rip_strerror(errno));
1253 complaints |= COMP_NOBADDR;
1255 continue;
1257 haddr = ntohl(sinp->sin_addr.s_addr);
1258 if (IN_CLASSD(haddr) ||
1259 (haddr & IN_CLASSA_NET) == 0) {
1260 if (IS_IFF_UP(ifs.int_if_flags)) {
1261 if (!(prev_complaints & COMP_NOBADDR))
1262 writelog(LOG_NOTICE,
1263 "%s has a bad broadcast "
1264 "address %s",
1265 ifs.int_name,
1266 naddr_ntoa(haddr));
1267 complaints |= COMP_NOBADDR;
1269 continue;
1272 ifs.int_brdaddr = sinp->sin_addr.s_addr;
1274 /* Get interface metric, if possible. */
1275 if (ioctl(sock, SIOCGLIFMETRIC, lifrp) == -1) {
1276 if (IS_IFF_UP(ifs.int_if_flags)) {
1277 if (!(prev_complaints & COMP_BAD_METRIC))
1278 writelog(LOG_NOTICE,
1279 "%s has no metric: %s",
1280 ifs.int_name, rip_strerror(errno));
1281 complaints |= COMP_BAD_METRIC;
1283 } else {
1284 ifs.int_metric = lifrp->lifr_metric;
1285 if (ifs.int_metric > HOPCNT_INFINITY) {
1286 if (IS_IFF_UP(ifs.int_if_flags)) {
1287 if (!(prev_complaints &
1288 COMP_BAD_METRIC))
1289 writelog(LOG_NOTICE,
1290 "%s has a metric of %d, "
1291 "defaulting to %d",
1292 ifs.int_name,
1293 ifs.int_metric,
1294 HOPCNT_INFINITY);
1295 complaints |= COMP_BAD_METRIC;
1297 ifs.int_metric = HOPCNT_INFINITY;
1301 ifs.int_state |= IS_CHECKED;
1302 ifs.int_query_time = NEVER;
1305 * If this is an alias, then mark it appropriately.
1306 * Do not output RIP or Router-Discovery packets via
1307 * aliases.
1309 if (strchr(ifs.int_name, ':') != NULL)
1310 ifs.int_state |= IS_ALIAS;
1312 if (ifs.int_if_flags & IFF_LOOPBACK) {
1313 ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC;
1314 ifs.int_dstaddr = ifs.int_addr;
1315 ifs.int_mask = HOST_MASK;
1316 ifs.int_ripv1_mask = HOST_MASK;
1317 ifs.int_std_mask = std_mask(ifs.int_dstaddr);
1318 ifs.int_net = ntohl(ifs.int_dstaddr);
1319 if (!foundloopback) {
1320 foundloopback = _B_TRUE;
1321 loopaddr = ifs.int_addr;
1322 loop_rts.rts_gate = loopaddr;
1323 loop_rts.rts_router = loopaddr;
1326 } else if (ifs.int_if_flags & IFF_POINTOPOINT) {
1327 ifs.int_ripv1_mask = ifs.int_mask;
1328 ifs.int_mask = HOST_MASK;
1329 ifs.int_std_mask = std_mask(ifs.int_dstaddr);
1331 } else {
1332 ifs.int_dstaddr = ifs.int_addr;
1333 ifs.int_ripv1_mask = ifs.int_mask;
1334 ifs.int_std_mask = std_mask(ifs.int_addr);
1335 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask;
1336 if (ifs.int_mask != ifs.int_std_mask)
1337 ifs.int_state |= IS_SUBNET;
1339 ifs.int_std_net = ifs.int_net & ifs.int_std_mask;
1340 ifs.int_std_addr = htonl(ifs.int_std_net);
1343 * If this interface duplicates another, mark it
1344 * appropriately so that we don't generate duplicate
1345 * packets.
1347 ifp = check_dup(ifs.int_name, ifs.int_addr, ifs.int_dstaddr,
1348 ifs.int_mask, ifs.int_if_flags, _B_FALSE);
1349 if (ifp != NULL) {
1350 trace_misc("%s (%s%s%s) is a duplicate of %s (%s%s%s)",
1351 ifs.int_name,
1352 addrname(ifs.int_addr, ifs.int_mask, 1),
1353 ((ifs.int_if_flags & IFF_POINTOPOINT) ?
1354 "-->" : ""),
1355 ((ifs.int_if_flags & IFF_POINTOPOINT) ?
1356 naddr_ntoa(ifs.int_dstaddr) : ""),
1357 ifp->int_name,
1358 addrname(ifp->int_addr, ifp->int_mask, 1),
1359 ((ifp->int_if_flags & IFF_POINTOPOINT) ?
1360 "-->" : ""),
1361 ((ifp->int_if_flags & IFF_POINTOPOINT) ?
1362 naddr_ntoa(ifp->int_dstaddr) : ""));
1363 ifs.int_state |= IS_DUP;
1364 } else {
1365 ifs.int_state &= ~IS_DUP;
1369 * See if this is a familiar interface.
1370 * If so, stop worrying about it if it is the same.
1371 * Start it over if it now is to somewhere else, as happens
1372 * frequently with PPP and SLIP, or if its forwarding
1373 * status has changed.
1375 ifp = ifwithname(ifs.int_name);
1376 if (ifp != NULL) {
1377 ifp->int_state |= IS_CHECKED;
1378 ifp->int_state = (ifp->int_state & ~IS_DUP) |
1379 (ifs.int_state & IS_DUP);
1381 if ((ifp->int_phys == NULL && ifindex != 0) ||
1382 (ifp->int_phys != NULL &&
1383 ifp->int_phys->phyi_index != ifindex) ||
1384 0 != ((ifp->int_if_flags ^ ifs.int_if_flags)
1385 & (IFF_BROADCAST | IFF_LOOPBACK |
1386 IFF_POINTOPOINT | IFF_MULTICAST |
1387 IFF_ROUTER | IFF_NORTEXCH | IFF_NOXMIT)) ||
1388 ifp->int_addr != ifs.int_addr ||
1389 ifp->int_brdaddr != ifs.int_brdaddr ||
1390 ifp->int_dstaddr != ifs.int_dstaddr ||
1391 ifp->int_mask != ifs.int_mask ||
1392 ifp->int_metric != ifs.int_metric) {
1394 * Forget old information about
1395 * a changed interface.
1397 trace_act("interface %s has changed",
1398 ifp->int_name);
1399 ifdel(ifp);
1400 ifp = NULL;
1404 if (ifp != NULL) {
1405 /* note interfaces that have been turned off */
1406 if (!IS_IFF_UP(ifs.int_if_flags)) {
1407 if (IS_IFF_UP(ifp->int_if_flags)) {
1408 writelog(LOG_WARNING,
1409 "interface %s to %s turned off",
1410 ifp->int_name,
1411 naddr_ntoa(ifp->int_dstaddr));
1412 if_bad(ifp, _B_FALSE);
1413 ifp->int_if_flags &= ~IFF_UP;
1414 } else if (ifp->int_phys != NULL &&
1415 now.tv_sec > (ifp->int_phys->phyi_data.ts +
1416 CHECK_BAD_INTERVAL)) {
1417 trace_act("interface %s has been off"
1418 " %ld seconds; forget it",
1419 ifp->int_name,
1420 now.tv_sec -
1421 ifp->int_phys->phyi_data.ts);
1422 ifdel(ifp);
1424 continue;
1426 /* or that were off and are now ok */
1427 if (!IS_IFF_UP(ifp->int_if_flags)) {
1428 ifp->int_if_flags |= IFF_UP;
1429 if_ok(ifp, "", _B_FALSE);
1433 * If it has been long enough,
1434 * see if the interface is broken.
1436 if ((phyi = ifp->int_phys) == NULL ||
1437 now.tv_sec < phyi->phyi_data.ts +
1438 CHECK_BAD_INTERVAL)
1439 continue;
1441 (void) memset(&newstats, 0, sizeof (newstats));
1442 if (get_if_kstats(ifp, &newstats) == -1) {
1443 if (!(prev_complaints & COMP_NO_KSTATS))
1444 writelog(LOG_WARNING,
1445 "unable to obtain kstats for %s",
1446 phyi->phyi_name);
1447 complaints |= COMP_NO_KSTATS;
1451 * If the interface just awoke, restart the counters.
1453 if (phyi->phyi_data.ts == 0) {
1454 phyi->phyi_data = newstats;
1455 continue;
1458 in = newstats.ipackets - phyi->phyi_data.ipackets;
1459 ierr = newstats.ierrors - phyi->phyi_data.ierrors;
1460 out = newstats.opackets - phyi->phyi_data.opackets;
1461 oerr = newstats.oerrors - phyi->phyi_data.oerrors;
1462 phyi->phyi_data = newstats;
1465 * Withhold judgment when the short error counters
1466 * wrap, the interface is reset, or if there are
1467 * no kstats.
1469 if (ierr < 0 || in < 0 || oerr < 0 || out < 0 ||
1470 newstats.ts == 0) {
1471 LIM_SEC(ifscan_timer,
1472 now.tv_sec + CHECK_BAD_INTERVAL);
1473 continue;
1476 /* Withhold judgement when there is no traffic */
1477 if (in == 0 && out == 0 && ierr == 0 && oerr == 0)
1478 continue;
1481 * It is bad if at least 25% of input or output on
1482 * an interface results in errors. Require
1483 * presistent problems before marking it dead.
1485 if ((ierr > 0 && ierr >= in/4) ||
1486 (oerr > 0 && oerr >= out/4)) {
1487 if (!(ifp->int_state & IS_SICK)) {
1488 trace_act("interface %s to %s"
1489 " sick: in=%d ierr=%d"
1490 " out=%d oerr=%d",
1491 ifp->int_name,
1492 naddr_ntoa(ifp->int_dstaddr),
1493 in, ierr, out, oerr);
1494 if_sick(ifp, _B_TRUE);
1495 continue;
1497 if (!(ifp->int_state & IS_BROKE)) {
1498 writelog(LOG_WARNING,
1499 "interface %s to %s broken:"
1500 " in=%d ierr=%d out=%d oerr=%d",
1501 ifp->int_name,
1502 naddr_ntoa(ifp->int_dstaddr),
1503 in, ierr, out, oerr);
1504 if_bad(ifp, _B_TRUE);
1506 continue;
1509 /* otherwise, it is active and healthy */
1510 ifp->int_act_time = now.tv_sec;
1511 if_ok(ifp, "", _B_TRUE);
1512 continue;
1516 * This is a new interface.
1517 * If it is dead, forget it.
1519 if (!IS_IFF_UP(ifs.int_if_flags))
1520 continue;
1522 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT |
1523 IFF_BROADCAST | IFF_LOOPBACK)) &&
1524 !(ifs.int_state & IS_PASSIVE)) {
1525 if (!(prev_complaints & COMP_BAD_FLAGS))
1526 trace_act("%s is neither broadcast, "
1527 "point-to-point, nor loopback",
1528 ifs.int_name);
1529 complaints |= COMP_BAD_FLAGS;
1530 if (!(ifs.int_if_flags & IFF_MULTICAST))
1531 ifs.int_state |= IS_NO_RDISC;
1536 * It is new and ok. Add it to the list of interfaces
1538 ifp = rtmalloc(sizeof (*ifp), "ifscan ifp");
1539 (void) memcpy(ifp, &ifs, sizeof (*ifp));
1540 get_parms(ifp);
1541 if_link(ifp, ifindex);
1542 trace_if("Add", ifp);
1544 if (ifp->int_phys != NULL &&
1545 get_if_kstats(ifp, &ifp->int_phys->phyi_data) == -1) {
1546 if (!(prev_complaints & COMP_NO_KSTATS))
1547 writelog(LOG_NOTICE,
1548 "unable to obtain kstats for %s",
1549 ifp->int_phys->phyi_name);
1550 complaints |= COMP_NO_KSTATS;
1553 /* Detect interfaces that have conflicting netmasks. */
1554 if (!(ifp->int_if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK))) {
1555 for (ifp1 = ifnet; ifp1 != NULL;
1556 ifp1 = ifp1->int_next) {
1557 if (ifp1->int_mask == ifp->int_mask)
1558 continue;
1561 * we don't care about point-to-point
1562 * or loopback aliases
1564 if (ifp1->int_if_flags &
1565 (IFF_POINTOPOINT|IFF_LOOPBACK)) {
1566 continue;
1569 /* ignore aliases on the same network */
1570 if (ifp->int_phys == ifp1->int_phys)
1571 continue;
1573 if (on_net(ifp->int_addr,
1574 ifp1->int_net, ifp1->int_mask) ||
1575 on_net(ifp1->int_addr,
1576 ifp->int_net, ifp->int_mask)) {
1577 writelog(LOG_INFO,
1578 "possible netmask problem"
1579 " between %s:%s and %s:%s",
1580 ifp->int_name,
1581 addrname(htonl(ifp->int_net),
1582 ifp->int_mask, 1),
1583 ifp1->int_name,
1584 addrname(htonl(ifp1->int_net),
1585 ifp1->int_mask, 1));
1586 complaints |= COMP_NETMASK;
1591 if (!(ifp->int_state & IS_DUP) &&
1592 !IS_IFF_QUIET(ifp->int_if_flags)) {
1593 /* Count the # of directly connected networks. */
1594 tot_interfaces++;
1595 if (!IS_RIP_OFF(ifp->int_state))
1596 rip_interfaces++;
1597 if (!IS_RIP_OUT_OFF(ifp->int_state))
1598 ripout_interfaces++;
1599 if (IS_IFF_ROUTING(ifp->int_if_flags))
1600 fwd_interfaces++;
1602 if_ok_rdisc(ifp);
1603 rip_on(ifp);
1607 (void) close(sock);
1610 * If we are multi-homed and have at least two interfaces that
1611 * are able to forward, then output RIP by default.
1613 if (!supplier_set)
1614 set_supplier();
1617 * If we are multi-homed, optionally advertise a route to
1618 * our main address.
1620 if (advertise_mhome || (tot_interfaces > 1 && mhome)) {
1621 /* lookup myaddr if we haven't done so already */
1622 if (myaddr == 0) {
1623 char myname[MAXHOSTNAMELEN+1];
1626 * If we are unable to resolve our hostname, don't
1627 * bother trying again.
1629 if (gethostname(myname, MAXHOSTNAMELEN) == -1) {
1630 msglog("gethostname: %s", rip_strerror(errno));
1631 advertise_mhome = _B_FALSE;
1632 mhome = _B_FALSE;
1633 } else if (gethost(myname, &myaddr) == 0) {
1634 writelog(LOG_WARNING,
1635 "unable to resolve local hostname %s",
1636 myname);
1637 advertise_mhome = _B_FALSE;
1638 mhome = _B_FALSE;
1641 if (myaddr != 0 &&
1642 (ifp = ifwithaddr(myaddr, _B_FALSE, _B_FALSE)) != NULL &&
1643 foundloopback) {
1644 advertise_mhome = _B_TRUE;
1645 rt = rtget(myaddr, HOST_MASK);
1646 if (rt != NULL) {
1647 if (rt->rt_ifp != ifp ||
1648 rt->rt_router != loopaddr) {
1649 rtdelete(rt);
1650 rt = NULL;
1651 } else {
1652 loop_rts.rts_ifp = ifp;
1653 loop_rts.rts_metric = 0;
1654 loop_rts.rts_time = rt->rt_time;
1655 loop_rts.rts_origin = RO_LOOPBCK;
1656 rtchange(rt, rt->rt_state | RS_MHOME,
1657 &loop_rts, NULL);
1660 if (rt == NULL) {
1661 loop_rts.rts_ifp = ifp;
1662 loop_rts.rts_metric = 0;
1663 loop_rts.rts_origin = RO_LOOPBCK;
1664 rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts);
1669 for (ifp = ifnet; ifp != NULL; ifp = ifp1) {
1670 ifp1 = ifp->int_next; /* because we may delete it */
1672 /* Forget any interfaces that have disappeared. */
1673 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) {
1674 trace_act("interface %s has disappeared",
1675 ifp->int_name);
1676 ifdel(ifp);
1677 continue;
1680 if ((ifp->int_state & IS_BROKE) &&
1681 !(ifp->int_state & IS_PASSIVE))
1682 LIM_SEC(ifscan_timer, now.tv_sec+CHECK_BAD_INTERVAL);
1685 * If we ever have a RIPv1 interface, assume we always will.
1686 * It might come back if it ever goes away.
1688 if (!(ifp->int_state & (IS_NO_RIPV1_OUT | IS_DUP)) &&
1689 should_supply(ifp))
1690 have_ripv1_out = _B_TRUE;
1691 if (!(ifp->int_state & IS_NO_RIPV1_IN))
1692 have_ripv1_in = _B_TRUE;
1695 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) {
1697 * Ensure there is always a network route for interfaces,
1698 * after any dead interfaces have been deleted, which
1699 * might affect routes for point-to-point links.
1701 if (addrouteforif(ifp) == 0)
1702 continue;
1705 * Add routes to the local end of point-to-point interfaces
1706 * using loopback.
1708 if ((ifp->int_if_flags & IFF_POINTOPOINT) &&
1709 !(ifp->int_state & IS_REMOTE) && foundloopback) {
1711 * Delete any routes to the network address through
1712 * foreign routers. Remove even static routes.
1714 del_static(ifp->int_addr, HOST_MASK, 0, ifp, 0);
1715 rt = rtget(ifp->int_addr, HOST_MASK);
1716 if (rt != NULL && rt->rt_router != loopaddr) {
1717 rtdelete(rt);
1718 rt = NULL;
1720 if (rt != NULL) {
1721 if (!(rt->rt_state & RS_LOCAL) ||
1722 rt->rt_metric > ifp->int_metric) {
1723 ifp1 = ifp;
1724 } else {
1725 ifp1 = rt->rt_ifp;
1727 loop_rts.rts_ifp = ifp1;
1728 loop_rts.rts_metric = 0;
1729 loop_rts.rts_time = rt->rt_time;
1730 loop_rts.rts_origin = RO_LOOPBCK;
1731 rtchange(rt, ((rt->rt_state & ~RS_NET_SYN) |
1732 (RS_IF|RS_LOCAL)), &loop_rts, 0);
1733 } else {
1734 loop_rts.rts_ifp = ifp;
1735 loop_rts.rts_metric = 0;
1736 loop_rts.rts_origin = RO_LOOPBCK;
1737 rtadd(ifp->int_addr, HOST_MASK,
1738 (RS_IF | RS_LOCAL), &loop_rts);
1743 /* add the authority routes */
1744 for (intnetp = intnets; intnetp != NULL;
1745 intnetp = intnetp->intnet_next) {
1746 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask);
1747 if (rt != NULL &&
1748 !(rt->rt_state & RS_NO_NET_SYN) &&
1749 !(rt->rt_state & RS_NET_INT)) {
1750 rtdelete(rt);
1751 rt = NULL;
1753 if (rt == NULL) {
1754 loop_rts.rts_ifp = NULL;
1755 loop_rts.rts_metric = intnetp->intnet_metric-1;
1756 loop_rts.rts_origin = RO_LOOPBCK;
1757 rtadd(intnetp->intnet_addr, intnetp->intnet_mask,
1758 RS_NET_SYN | RS_NET_INT, &loop_rts);
1762 prev_complaints = complaints;
1766 static void
1767 check_net_syn(struct interface *ifp)
1769 struct rt_entry *rt;
1770 struct rt_spare new;
1773 * Turn on the need to automatically synthesize a network route
1774 * for this interface only if we are running RIPv1 on some other
1775 * interface that is on a different class-A,B,or C network.
1777 if (have_ripv1_out || have_ripv1_in) {
1778 ifp->int_state |= IS_NEED_NET_SYN;
1779 rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1780 if (rt != NULL &&
1781 0 == (rt->rt_state & RS_NO_NET_SYN) &&
1782 (!(rt->rt_state & RS_NET_SYN) ||
1783 rt->rt_metric > ifp->int_metric)) {
1784 rtdelete(rt);
1785 rt = NULL;
1787 if (rt == NULL) {
1788 (void) memset(&new, 0, sizeof (new));
1789 new.rts_ifp = ifp;
1790 new.rts_gate = ifp->int_addr;
1791 new.rts_router = ifp->int_addr;
1792 new.rts_metric = ifp->int_metric;
1793 new.rts_origin = RO_NET_SYN;
1794 rtadd(ifp->int_std_addr, ifp->int_std_mask,
1795 RS_NET_SYN, &new);
1798 } else {
1799 ifp->int_state &= ~IS_NEED_NET_SYN;
1801 rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1802 if (rt != NULL &&
1803 (rt->rt_state & RS_NET_SYN) &&
1804 rt->rt_ifp == ifp)
1805 rtbad_sub(rt, NULL);
1811 * Add route for interface if not currently installed.
1812 * Create route to other end if a point-to-point link,
1813 * otherwise a route to this (sub)network.
1815 static boolean_t /* _B_FALSE=bad interface */
1816 addrouteforif(struct interface *ifp)
1818 struct rt_entry *rt;
1819 struct rt_spare new;
1820 in_addr_t dst;
1821 uint16_t rt_newstate = RS_IF;
1824 /* skip sick interfaces */
1825 if (ifp->int_state & IS_BROKE)
1826 return (_B_FALSE);
1829 * don't install routes for duplicate interfaces, or
1830 * unnumbered point-to-point interfaces.
1832 if ((ifp->int_state & IS_DUP) ||
1833 ((ifp->int_if_flags & IFF_POINTOPOINT) && ifp->int_dstaddr == 0))
1834 return (_B_TRUE);
1837 * If the interface on a subnet, then install a RIPv1 route to
1838 * the network as well (unless it is sick).
1840 if (ifp->int_state & IS_SUBNET)
1841 check_net_syn(ifp);
1843 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) ?
1844 ifp->int_dstaddr : htonl(ifp->int_net));
1846 (void) memset(&new, 0, sizeof (new));
1847 new.rts_ifp = ifp;
1848 new.rts_router = ifp->int_addr;
1849 new.rts_gate = ifp->int_addr;
1850 new.rts_metric = ifp->int_metric;
1851 new.rts_time = now.tv_sec;
1852 if (ifp->int_if_flags & IFF_POINTOPOINT)
1853 new.rts_origin = RO_PTOPT;
1854 else if (ifp->int_if_flags & IFF_LOOPBACK)
1855 new.rts_origin = RO_LOOPBCK;
1856 else
1857 new.rts_origin = RO_IF;
1860 * If we are going to send packets to the gateway,
1861 * it must be reachable using our physical interfaces
1863 if ((ifp->int_state & IS_REMOTE) &&
1864 !(ifp->int_state & IS_EXTERNAL) &&
1865 !check_remote(ifp))
1866 return (_B_FALSE);
1869 * We are finished if the correct main interface route exists.
1870 * The right route must be for the right interface, not synthesized
1871 * from a subnet, be a "gateway" or not as appropriate, and so forth.
1873 del_static(dst, ifp->int_mask, 0, ifp, 0);
1874 rt = rtget(dst, ifp->int_mask);
1875 if (!IS_IFF_ROUTING(ifp->int_if_flags))
1876 rt_newstate |= RS_NOPROPAGATE;
1877 if (rt != NULL) {
1878 if ((rt->rt_ifp != ifp || rt->rt_router != ifp->int_addr) &&
1879 (rt->rt_ifp == NULL ||
1880 (rt->rt_ifp->int_state & IS_BROKE))) {
1881 rtdelete(rt);
1882 rt = NULL;
1883 } else {
1884 rtchange(rt, ((rt->rt_state | rt_newstate) &
1885 ~(RS_NET_SYN | RS_LOCAL)), &new, 0);
1888 if (rt == NULL) {
1889 if (ifp->int_transitions++ > 0)
1890 trace_act("re-installing interface %s;"
1891 " went up %d times",
1892 ifp->int_name, ifp->int_transitions);
1894 rtadd(dst, ifp->int_mask, rt_newstate, &new);
1897 return (_B_TRUE);
1901 * Obtains the named kstat, and places its value in *value. It
1902 * returns 0 for success, -1 for failure.
1904 static int
1905 kstat_named_value(kstat_t *ksp, char *name, uint32_t *value)
1907 kstat_named_t *knp;
1909 if (ksp == NULL)
1910 return (-1);
1912 if ((knp = kstat_data_lookup(ksp, name)) == NULL) {
1913 return (-1);
1914 } else if (knp->data_type != KSTAT_DATA_UINT32) {
1915 return (-1);
1916 } else {
1917 *value = knp->value.ui32;
1918 return (0);
1922 static int
1923 get_if_kstats(struct interface *ifp, struct phyi_data *newdata)
1925 struct physical_interface *phyi = ifp->int_phys;
1926 kstat_ctl_t *kc;
1927 kstat_t *ksp;
1929 /* We did this recently; don't do it again. */
1930 if (phyi->phyi_data.ts == now.tv_sec) {
1931 if (newdata != &phyi->phyi_data)
1932 *newdata = phyi->phyi_data;
1933 return (0);
1936 if ((kc = kstat_open()) == NULL)
1937 return (-1);
1940 * First we try to query the "link" kstats in case the link is renamed.
1941 * If that fails, fallback to legacy ktats for those non-GLDv3 links.
1943 if (((ksp = kstat_lookup(kc, "link", 0, phyi->phyi_name)) == NULL) &&
1944 ((ksp = kstat_lookup(kc, NULL, -1, phyi->phyi_name)) == NULL)) {
1945 (void) kstat_close(kc);
1946 return (-1);
1949 if (kstat_read(kc, ksp, NULL) == -1) {
1950 (void) kstat_close(kc);
1951 return (-1);
1954 if ((kstat_named_value(ksp, "ipackets", &newdata->ipackets) == -1) ||
1955 (kstat_named_value(ksp, "opackets", &newdata->opackets) == -1)) {
1956 newdata->ts = 0;
1957 (void) kstat_close(kc);
1958 return (-1);
1961 /* The loopback interface does not keep track of errors */
1962 if (!(ifp->int_if_flags & IFF_LOOPBACK)) {
1963 if ((kstat_named_value(ksp, "ierrors",
1964 &newdata->ierrors) == -1) ||
1965 (kstat_named_value(ksp, "oerrors",
1966 &newdata->oerrors) == -1)) {
1967 newdata->ts = 0;
1968 (void) kstat_close(kc);
1969 return (-1);
1973 newdata->ts = now.tv_sec;
1974 (void) kstat_close(kc);
1975 return (0);
1979 * Returns true if we should supply routes to other systems. If the
1980 * user has forced us to be a supplier (by the command line) or if we
1981 * have more than one forwarding interface and this is one of the
1982 * forwarding interfaces, then behave as a RIP supplier (supply rdisc
1983 * advertisements and RIP responses).
1985 boolean_t
1986 should_supply(struct interface *ifp)
1988 if (ifp != NULL && !IS_IFF_ROUTING(ifp->int_if_flags))
1989 return (_B_FALSE);
1990 return ((supplier_set && supplier) ||
1991 (!supplier_set && fwd_interfaces > 1));