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
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
36 * $FreeBSD: src/sbin/routed/if.c,v 1.8 2000/08/11 08:24:38 sheldonh Exp $
40 #include "pathnames.h"
41 #include <sys/sockio.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 };
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), \
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
),
114 * Table of broadcast capable interfaces, hashed by interface broadcast
117 static struct htbl bhash_tbl
= {
118 NULL
, ahash
, offsetof(struct interface
, int_bhash
),
119 offsetof(struct interface
, int_brdaddr
),
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
),
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
),
137 static struct physical_interface dummy_phyi
;
138 struct interface dummy_ifp
;
140 /* Hash based on an IP address. */
142 ahash(const void *arg
, size_t voffs
)
145 return ((uint_t
)*(const in_addr_t
*)((const char *)arg
+ voffs
));
149 ihash(const void *arg
, size_t voffs
)
152 return ((uint_t
)*(const uint32_t *)((const char *)arg
+ voffs
));
156 nhash(const void *arg
, size_t voffs
)
158 const char *cp
= (const char *)arg
+ voffs
;
161 for (i
= 0; *cp
!= '\0'; cp
++) {
162 i
= ((i
<<1) & 0x7fffffff) | ((i
>>30) & 0x00000003);
169 * Add an element to the head of the list.
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
);
179 if ((hlp
->hl_next
= *head
) != NULL
) {
181 ((struct hlinkage
*)((char *)*head
+ loffs
))->hl_prev
=
187 /* Remove from a list */
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
) {
197 ((struct hlinkage
*)((char *)hlp
->hl_next
+ loffs
))->hl_prev
=
204 hash_link(struct htbl
*htbl
, uint_t hval
, void *strp
)
208 if (htbl
->htbl_grow
&& htbl
->htbl_ifcount
>= htbl
->htbl_size
* 5)
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 */
218 hash_unlink(struct htbl
*htbl
, void *strp
)
220 link_out(strp
, htbl
->htbl_link_off
);
221 htbl
->htbl_ifcount
--;
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 */
244 size_t initial_size
= hash_table_sizes
[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 *));
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
;
265 htbl_grow(struct htbl
*htbl
)
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)
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
));
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
300 htbl
->htbl_grow
= _B_FALSE
;
301 while (old_size
-- > 0) {
306 htbl
->htbl_grow
= _B_TRUE
;
307 free(saved_old_ptrs
);
310 /* Link a new interface into the lists and hash tables. */
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
);
325 for (phyi
= HFIRST(&ihash_tbl
, &ifindex
);
326 phyi
!= NULL
; phyi
= phyi
->phyi_link
.hl_next
) {
327 if (phyi
->phyi_index
== ifindex
)
333 phyi
= rtmalloc(sizeof (*phyi
), "physical_interface");
334 (void) memset(phyi
, 0, sizeof (*phyi
));
335 phyi
->phyi_index
= ifindex
;
337 assert(IF_NAME_LEN
>= IF_NAMESIZE
);
339 size
= strcspn(ifp
->int_name
, ":");
340 (void) strncpy(phyi
->phyi_name
, ifp
->int_name
,
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 */
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
)
366 if (ifp
->int_state
& remote_state
)
368 if (!(ifp
->int_state
& (IS_BROKE
| IS_PASSIVE
)))
373 if (possible
!= NULL
|| !bcast
)
376 for (ifp
= HFIRST(&bhash_tbl
, &addr
); ifp
!= NULL
;
377 ifp
= ifp
->int_bhash
.hl_next
) {
378 if (ifp
->int_brdaddr
!= addr
)
380 if (ifp
->int_state
& remote_state
)
382 if (!(ifp
->int_state
& (IS_BROKE
| IS_PASSIVE
)))
391 /* find the interface with the specified name ("hme0" for example) */
393 ifwithname(const char *name
)
395 struct interface
*ifp
;
398 for (ifp
= HFIRST(&nhash_tbl
, name
); ifp
!= NULL
;
399 ifp
= ifp
->int_nhash
.hl_next
) {
400 if (strcmp(ifp
->int_name
, name
) == 0)
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())
414 /* Return physical interface with the specified name */
415 struct physical_interface
*
416 phys_byname(const char *name
)
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')
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
)
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
)
463 * Return the first interface with the given index.
466 ifwithindex(ulong_t index
,
469 struct physical_interface
*phyi
;
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())
484 rescan_ok
= _B_FALSE
;
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.
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
)
506 if (ifp
->int_if_flags
& IFF_POINTOPOINT
) {
507 if (ifp
->int_dstaddr
== addr
) {
512 if (ifp
->int_addr
== addr
) {
513 if (IS_PASSIVE_IFP(ifp
))
514 trace_misc("addr_on_ifp "
515 "returning passive intf %s",
521 /* Look for the longest approximate match. */
522 if (on_net(addr
, ifp
->int_net
, ifp
->int_mask
) &&
524 ifp
->int_mask
> p_best
->int_mask
)) {
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
539 iflookup(in_addr_t addr
)
541 struct interface
*ifp
, *maybe
;
545 for (ifp
= ifnet
; ifp
!= NULL
; ifp
= ifp
->int_next
) {
547 /* Exact match found */
548 if (addr_on_ifp(addr
, ifp
, &maybe
))
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())
562 if (maybe
!= NULL
&& IS_PASSIVE_IFP(maybe
)) {
563 trace_misc("iflookup returning passive intf %s",
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.
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
;
581 if (addr
== 0) /* default always has 0 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
;
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
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
;
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. */
627 mask
= std_mask(addr
);
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)
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
)
657 if (IN_CLASSA(addr
)) {
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
))
669 if (IN_CLASSB(addr
) || IN_CLASSC(addr
))
680 * Find an existing interface which has the given parameters, but don't
681 * return the interface with name "name" if "name" is specified.
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
);
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)
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
708 if (!allowdups
&& (ifp
->int_state
& IS_DUP
))
711 if (ifp
->int_mask
!= mask
)
714 if (!IS_IFF_UP(ifp
->int_if_flags
))
718 * The local address can only be shared with a point-to-point
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
)) {
725 if (!(ifp
->int_state
& IS_ALIAS
))
727 if (!IS_RIP_OUT_OFF(ifp
->int_state
))
729 if (IS_IFF_ROUTING(ifp
->int_if_flags
))
731 if (pref
> best_pref
) {
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
)
750 /* do not worry about other kinds */
751 if (!(ifp
->int_state
& IS_REMOTE
))
754 rt
= rtfind(ifp
->int_addr
);
756 rt
->rt_ifp
!= NULL
&&
757 on_net(ifp
->int_addr
, rt
->rt_ifp
->int_net
, rt
->rt_ifp
->int_mask
)) {
762 * the gateway cannot be reached directly from one of our
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
);
773 /* Delete an interface. */
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
);
802 * If this is a lead interface, then check first for
803 * duplicates of this interface with an eye towards promoting
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
,
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 */
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
;
826 if (!IS_RIP_OFF(wire
.if_new
->int_state
))
828 if (!IS_RIP_OUT_OFF(wire
.if_new
->int_state
))
830 if (IS_IFF_ROUTING(wire
.if_new
->int_if_flags
))
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
;
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
850 if (!(ifp
->int_state
& IS_DUP
) && !IS_IFF_QUIET(ifp
->int_if_flags
)) {
852 if (!IS_RIP_OFF(ifp
->int_state
))
854 if (!IS_RIP_OUT_OFF(ifp
->int_state
))
856 if (IS_IFF_ROUTING(ifp
->int_if_flags
))
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
);
876 /* Mark an interface ill. */
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
) {
893 if_sick(ifp1
, _B_FALSE
);
900 /* Mark an interface dead. */
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
)
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
) {
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
,
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
);
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);
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
;
954 (void) rn_walktree(rhead
, walk_bad
, ifp
);
960 /* Mark an interface alive */
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
);
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
) {
985 if_ok(ifp1
, type
, _B_FALSE
);
990 if (!(ifp
->int_state
& IS_DUP
))
993 if (ifp
->int_state
& IS_REMOTE
)
994 (void) addrouteforif(ifp
);
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
)
1004 } else if (on_net(addr
, ifp
->int_net
, ifp
->int_mask
)) {
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.
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
;
1034 static size_t lastneeded
= 0;
1036 static char *lastbuf
= NULL
;
1037 int32_t in
, ierr
, out
, oerr
;
1038 struct intnet
*intnetp
;
1041 struct lifconf lifc
;
1042 struct lifreq
*lifrp
, *lifrp_lim
;
1043 struct sockaddr_in
*sinp
;
1045 static in_addr_t myaddr
= 0;
1047 struct phyi_data newstats
;
1048 struct physical_interface
*phyi
;
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
1069 lifn
.lifn_flags
= LIFC_NOXMIT
;
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
1083 needed
= (lifn
.lifn_count
+ 4) * sizeof (struct lifreq
);
1084 if (needed
> lastneeded
|| needed
< lastneeded
/2) {
1086 if ((buf
= malloc(needed
)) == NULL
) {
1088 msglog("ifscan: malloc: %s", rip_strerror(errno
));
1095 lastneeded
= needed
;
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
)->
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;
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",
1153 naddr_ntoa(ifs
.int_addr
));
1154 complaints
|= COMP_BADADDR
;
1159 /* Ignore interface with IPv4 link local address. */
1160 if (IN_LINKLOCAL(ntohl(ifs
.int_addr
)))
1163 /* Get the interface index. */
1164 if (ioctl(sock
, SIOCGLIFINDEX
, lifrp
) == -1) {
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
;
1172 ifindex
= lifrp
->lifr_index
;
1176 * Get the destination address for point-to-point
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 "
1188 rip_strerror(errno
));
1189 complaints
|= COMP_NODST
;
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
,
1201 "destination address %s",
1203 naddr_ntoa(ifs
.int_net
));
1204 complaints
|= COMP_NODST
;
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
;
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",
1231 complaints
|= COMP_NOMASK
;
1235 ifs
.int_mask
= IP_HOST_MASK
;
1237 ifs
.int_mask
= ntohl(sinp
->sin_addr
.s_addr
);
1241 * Get the broadcast address on broadcast capable
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 "
1252 rip_strerror(errno
));
1253 complaints
|= COMP_NOBADDR
;
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 "
1267 complaints
|= COMP_NOBADDR
;
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
;
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
&
1289 writelog(LOG_NOTICE
,
1290 "%s has a metric of %d, "
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
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
);
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
1347 ifp
= check_dup(ifs
.int_name
, ifs
.int_addr
, ifs
.int_dstaddr
,
1348 ifs
.int_mask
, ifs
.int_if_flags
, _B_FALSE
);
1350 trace_misc("%s (%s%s%s) is a duplicate of %s (%s%s%s)",
1352 addrname(ifs
.int_addr
, ifs
.int_mask
, 1),
1353 ((ifs
.int_if_flags
& IFF_POINTOPOINT
) ?
1355 ((ifs
.int_if_flags
& IFF_POINTOPOINT
) ?
1356 naddr_ntoa(ifs
.int_dstaddr
) : ""),
1358 addrname(ifp
->int_addr
, ifp
->int_mask
, 1),
1359 ((ifp
->int_if_flags
& IFF_POINTOPOINT
) ?
1361 ((ifp
->int_if_flags
& IFF_POINTOPOINT
) ?
1362 naddr_ntoa(ifp
->int_dstaddr
) : ""));
1363 ifs
.int_state
|= IS_DUP
;
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
);
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",
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",
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",
1421 ifp
->int_phys
->phyi_data
.ts
);
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
+
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",
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
;
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
1469 if (ierr
< 0 || in
< 0 || oerr
< 0 || out
< 0 ||
1471 LIM_SEC(ifscan_timer
,
1472 now
.tv_sec
+ CHECK_BAD_INTERVAL
);
1476 /* Withhold judgement when there is no traffic */
1477 if (in
== 0 && out
== 0 && ierr
== 0 && oerr
== 0)
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"
1492 naddr_ntoa(ifp
->int_dstaddr
),
1493 in
, ierr
, out
, oerr
);
1494 if_sick(ifp
, _B_TRUE
);
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",
1502 naddr_ntoa(ifp
->int_dstaddr
),
1503 in
, ierr
, out
, oerr
);
1504 if_bad(ifp
, _B_TRUE
);
1509 /* otherwise, it is active and healthy */
1510 ifp
->int_act_time
= now
.tv_sec
;
1511 if_ok(ifp
, "", _B_TRUE
);
1516 * This is a new interface.
1517 * If it is dead, forget it.
1519 if (!IS_IFF_UP(ifs
.int_if_flags
))
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",
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
));
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
)
1561 * we don't care about point-to-point
1562 * or loopback aliases
1564 if (ifp1
->int_if_flags
&
1565 (IFF_POINTOPOINT
|IFF_LOOPBACK
)) {
1569 /* ignore aliases on the same network */
1570 if (ifp
->int_phys
== ifp1
->int_phys
)
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
)) {
1578 "possible netmask problem"
1579 " between %s:%s and %s:%s",
1581 addrname(htonl(ifp
->int_net
),
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. */
1595 if (!IS_RIP_OFF(ifp
->int_state
))
1597 if (!IS_RIP_OUT_OFF(ifp
->int_state
))
1598 ripout_interfaces
++;
1599 if (IS_IFF_ROUTING(ifp
->int_if_flags
))
1610 * If we are multi-homed and have at least two interfaces that
1611 * are able to forward, then output RIP by default.
1617 * If we are multi-homed, optionally advertise a route to
1620 if (advertise_mhome
|| (tot_interfaces
> 1 && mhome
)) {
1621 /* lookup myaddr if we haven't done so already */
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
;
1633 } else if (gethost(myname
, &myaddr
) == 0) {
1634 writelog(LOG_WARNING
,
1635 "unable to resolve local hostname %s",
1637 advertise_mhome
= _B_FALSE
;
1642 (ifp
= ifwithaddr(myaddr
, _B_FALSE
, _B_FALSE
)) != NULL
&&
1644 advertise_mhome
= _B_TRUE
;
1645 rt
= rtget(myaddr
, HOST_MASK
);
1647 if (rt
->rt_ifp
!= ifp
||
1648 rt
->rt_router
!= loopaddr
) {
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
,
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",
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
)) &&
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)
1705 * Add routes to the local end of point-to-point interfaces
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
) {
1721 if (!(rt
->rt_state
& RS_LOCAL
) ||
1722 rt
->rt_metric
> ifp
->int_metric
) {
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);
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
);
1748 !(rt
->rt_state
& RS_NO_NET_SYN
) &&
1749 !(rt
->rt_state
& RS_NET_INT
)) {
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
;
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
);
1781 0 == (rt
->rt_state
& RS_NO_NET_SYN
) &&
1782 (!(rt
->rt_state
& RS_NET_SYN
) ||
1783 rt
->rt_metric
> ifp
->int_metric
)) {
1788 (void) memset(&new, 0, sizeof (new));
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
,
1799 ifp
->int_state
&= ~IS_NEED_NET_SYN
;
1801 rt
= rtget(ifp
->int_std_addr
, ifp
->int_std_mask
);
1803 (rt
->rt_state
& RS_NET_SYN
) &&
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;
1821 uint16_t rt_newstate
= RS_IF
;
1824 /* skip sick interfaces */
1825 if (ifp
->int_state
& IS_BROKE
)
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))
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
)
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));
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
;
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
) &&
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
;
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
))) {
1884 rtchange(rt
, ((rt
->rt_state
| rt_newstate
) &
1885 ~(RS_NET_SYN
| RS_LOCAL
)), &new, 0);
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);
1901 * Obtains the named kstat, and places its value in *value. It
1902 * returns 0 for success, -1 for failure.
1905 kstat_named_value(kstat_t
*ksp
, char *name
, uint32_t *value
)
1912 if ((knp
= kstat_data_lookup(ksp
, name
)) == NULL
) {
1914 } else if (knp
->data_type
!= KSTAT_DATA_UINT32
) {
1917 *value
= knp
->value
.ui32
;
1923 get_if_kstats(struct interface
*ifp
, struct phyi_data
*newdata
)
1925 struct physical_interface
*phyi
= ifp
->int_phys
;
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
;
1936 if ((kc
= kstat_open()) == NULL
)
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
);
1949 if (kstat_read(kc
, ksp
, NULL
) == -1) {
1950 (void) kstat_close(kc
);
1954 if ((kstat_named_value(ksp
, "ipackets", &newdata
->ipackets
) == -1) ||
1955 (kstat_named_value(ksp
, "opackets", &newdata
->opackets
) == -1)) {
1957 (void) kstat_close(kc
);
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)) {
1968 (void) kstat_close(kc
);
1973 newdata
->ts
= now
.tv_sec
;
1974 (void) kstat_close(kc
);
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).
1986 should_supply(struct interface
*ifp
)
1988 if (ifp
!= NULL
&& !IS_IFF_ROUTING(ifp
->int_if_flags
))
1990 return ((supplier_set
&& supplier
) ||
1991 (!supplier_set
&& fwd_interfaces
> 1));