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