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