if.c revision 1.13 1 /* $NetBSD: if.c,v 1.13 1997/09/15 11:51:54 lukem Exp $ */
2
3 /*
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #if !defined(lint) && !defined(sgi) && !defined(__NetBSD__)
37 static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
38 #elif defined(__NetBSD__)
39 #include <sys/cdefs.h>
40 __RCSID("$NetBSD: if.c,v 1.13 1997/09/15 11:51:54 lukem Exp $");
41 #endif
42
43 #include "defs.h"
44 #include "pathnames.h"
45
46 struct interface *ifnet; /* all interfaces */
47
48 /* hash table for all interfaces, big enough to tolerate ridiculous
49 * numbers of IP aliases. Crazy numbers of aliases such as 7000
50 * still will not do well, but not just in looking up interfaces
51 * by name or address.
52 */
53 #define AHASH_LEN 211 /* must be prime */
54 #define AHASH(a) &ahash_tbl[(a)%AHASH_LEN]
55 struct interface *ahash_tbl[AHASH_LEN];
56
57 #define BHASH_LEN 211 /* must be prime */
58 #define BHASH(a) &bhash_tbl[(a)%BHASH_LEN]
59 struct interface *bhash_tbl[BHASH_LEN];
60
61 struct interface *remote_if; /* remote interfaces */
62
63 /* hash for physical interface names.
64 * Assume there are never more 100 or 200 real interfaces, and that
65 * aliases are put on the end of the hash chains.
66 */
67 #define NHASH_LEN 97
68 struct interface *nhash_tbl[NHASH_LEN];
69
70 int tot_interfaces; /* # of remote and local interfaces */
71 int rip_interfaces; /* # of interfaces doing RIP */
72 int foundloopback; /* valid flag for loopaddr */
73 naddr loopaddr; /* our address on loopback */
74
75 struct timeval ifinit_timer;
76 static struct timeval last_ifinit;
77
78 int have_ripv1_out; /* have a RIPv1 interface */
79 int have_ripv1_in;
80
81
82 static struct interface**
83 nhash(char *p)
84 {
85 u_int i;
86
87 for (i = 0; *p != '\0'; p++) {
88 i = ((i<<1) & 0x7fffffff) | ((i>>31) & 1);
89 i ^= *p;
90 }
91 return &nhash_tbl[i % NHASH_LEN];
92 }
93
94
95 /* Link a new interface into the lists and hash tables.
96 */
97 void
98 if_link(struct interface *ifp)
99 {
100 struct interface **hifp;
101
102 ifp->int_prev = &ifnet;
103 ifp->int_next = ifnet;
104 if (ifnet != 0)
105 ifnet->int_prev = &ifp->int_next;
106 ifnet = ifp;
107
108 hifp = AHASH(ifp->int_addr);
109 ifp->int_ahash_prev = hifp;
110 if ((ifp->int_ahash = *hifp) != 0)
111 (*hifp)->int_ahash_prev = &ifp->int_ahash;
112 *hifp = ifp;
113
114 if (ifp->int_if_flags & IFF_BROADCAST) {
115 hifp = BHASH(ifp->int_brdaddr);
116 ifp->int_bhash_prev = hifp;
117 if ((ifp->int_bhash = *hifp) != 0)
118 (*hifp)->int_bhash_prev = &ifp->int_bhash;
119 *hifp = ifp;
120 }
121
122 if (ifp->int_state & IS_REMOTE) {
123 ifp->int_rlink_prev = &remote_if;
124 ifp->int_rlink = remote_if;
125 if (remote_if != 0)
126 remote_if->int_rlink_prev = &ifp->int_rlink;
127 remote_if = ifp;
128 }
129
130 hifp = nhash(ifp->int_name);
131 if (ifp->int_state & IS_ALIAS) {
132 /* put aliases on the end of the hash chain */
133 while (*hifp != 0)
134 hifp = &(*hifp)->int_nhash;
135 }
136 ifp->int_nhash_prev = hifp;
137 if ((ifp->int_nhash = *hifp) != 0)
138 (*hifp)->int_nhash_prev = &ifp->int_nhash;
139 *hifp = ifp;
140 }
141
142
143 /* Find the interface with an address
144 */
145 struct interface *
146 ifwithaddr(naddr addr,
147 int bcast, /* notice IFF_BROADCAST address */
148 int remote) /* include IS_REMOTE interfaces */
149 {
150 struct interface *ifp, *possible = 0;
151
152 remote = (remote == 0) ? IS_REMOTE : 0;
153
154 for (ifp = *AHASH(addr); ifp; ifp = ifp->int_ahash) {
155 if (ifp->int_addr != addr)
156 continue;
157 if ((ifp->int_state & remote) != 0)
158 continue;
159 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0)
160 return ifp;
161 possible = ifp;
162 }
163
164 if (possible || !bcast)
165 return possible;
166
167 for (ifp = *BHASH(addr); ifp; ifp = ifp->int_bhash) {
168 if (ifp->int_brdaddr != addr)
169 continue;
170 if ((ifp->int_state & remote) != 0)
171 continue;
172 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0)
173 return ifp;
174 possible = ifp;
175 }
176
177 return possible;
178 }
179
180
181 /* find the interface with a name
182 */
183 struct interface *
184 ifwithname(char *name, /* "ec0" or whatever */
185 naddr addr) /* 0 or network address */
186 {
187 struct interface *ifp;
188
189 for (;;) {
190 for (ifp = *nhash(name); ifp != 0; ifp = ifp->int_nhash) {
191 /* If the network address is not specified,
192 * ignore any alias interfaces. Otherwise, look
193 * for the interface with the target name and address.
194 */
195 if (!strcmp(ifp->int_name, name)
196 && ((addr == 0 && !(ifp->int_state & IS_ALIAS))
197 || (ifp->int_addr == addr)))
198 return ifp;
199 }
200
201 /* If there is no known interface, maybe there is a
202 * new interface. So just once look for new interfaces.
203 */
204 if (last_ifinit.tv_sec == now.tv_sec
205 && last_ifinit.tv_usec == now.tv_usec)
206 return 0;
207 ifinit();
208 }
209 }
210
211
212 struct interface *
213 ifwithindex(u_short index,
214 int rescan_ok)
215 {
216 struct interface *ifp;
217
218 for (;;) {
219 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
220 if (ifp->int_index == index)
221 return ifp;
222 }
223
224 /* If there is no known interface, maybe there is a
225 * new interface. So just once look for new interfaces.
226 */
227 if (!rescan_ok
228 || (last_ifinit.tv_sec == now.tv_sec
229 && last_ifinit.tv_usec == now.tv_usec))
230 return 0;
231 ifinit();
232 }
233 }
234
235
236 /* Find an interface from which the specified address
237 * should have come from. Used for figuring out which
238 * interface a packet came in on.
239 */
240 struct interface *
241 iflookup(naddr addr)
242 {
243 struct interface *ifp, *maybe;
244
245 maybe = 0;
246 for (;;) {
247 for (ifp = ifnet; ifp; ifp = ifp->int_next) {
248 if (ifp->int_if_flags & IFF_POINTOPOINT) {
249 /* finished with a match */
250 if (ifp->int_dstaddr == addr)
251 return ifp;
252
253 } else {
254 /* finished with an exact match */
255 if (ifp->int_addr == addr)
256 return ifp;
257
258 /* Look for the longest approximate match.
259 */
260 if (on_net(addr, ifp->int_net, ifp->int_mask)
261 && (maybe == 0
262 || ifp->int_mask > maybe->int_mask))
263 maybe = ifp;
264 }
265 }
266
267 if (maybe != 0
268 || (last_ifinit.tv_sec == now.tv_sec
269 && last_ifinit.tv_usec == now.tv_usec))
270 return maybe;
271
272 /* If there is no known interface, maybe there is a
273 * new interface. So just once look for new interfaces.
274 */
275 ifinit();
276 }
277 }
278
279
280 /* Return the classical netmask for an IP address.
281 */
282 naddr /* host byte order */
283 std_mask(naddr addr) /* network byte order */
284 {
285 NTOHL(addr); /* was a host, not a network */
286
287 if (addr == 0) /* default route has mask 0 */
288 return 0;
289 if (IN_CLASSA(addr))
290 return IN_CLASSA_NET;
291 if (IN_CLASSB(addr))
292 return IN_CLASSB_NET;
293 return IN_CLASSC_NET;
294 }
295
296
297 /* Find the netmask that would be inferred by RIPv1 listeners
298 * on the given interface for a given network.
299 * If no interface is specified, look for the best fitting interface.
300 */
301 naddr
302 ripv1_mask_net(naddr addr, /* in network byte order */
303 struct interface *ifp) /* as seen on this interface */
304 {
305 naddr mask = 0;
306
307 if (addr == 0) /* default always has 0 mask */
308 return mask;
309
310 if (ifp != 0) {
311 /* If the target network is that of the associated interface
312 * on which it arrived, then use the netmask of the interface.
313 */
314 if (on_net(addr, ifp->int_net, ifp->int_std_mask))
315 mask = ifp->int_ripv1_mask;
316
317 } else {
318 /* Examine all interfaces, and if it the target seems
319 * to have the same network number of an interface, use the
320 * netmask of that interface. If there is more than one
321 * such interface, prefer the interface with the longest
322 * match.
323 */
324 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
325 if (on_net(addr, ifp->int_std_net, ifp->int_std_mask)
326 && ifp->int_ripv1_mask > mask)
327 mask = ifp->int_ripv1_mask;
328 }
329 }
330
331 /* Otherwise, make the classic A/B/C guess.
332 */
333 if (mask == 0)
334 mask = std_mask(addr);
335
336 return mask;
337 }
338
339
340 naddr
341 ripv1_mask_host(naddr addr, /* in network byte order */
342 struct interface *ifp) /* as seen on this interface */
343 {
344 naddr mask = ripv1_mask_net(addr, ifp);
345
346
347 /* If the computed netmask does not mask the address,
348 * then assume it is a host address
349 */
350 if ((ntohl(addr) & ~mask) != 0)
351 mask = HOST_MASK;
352 return mask;
353 }
354
355
356 /* See if a IP address looks reasonable as a destination
357 */
358 int /* 0=bad */
359 check_dst(naddr addr)
360 {
361 NTOHL(addr);
362
363 if (IN_CLASSA(addr)) {
364 if (addr == 0)
365 return 1; /* default */
366
367 addr >>= IN_CLASSA_NSHIFT;
368 return (addr != 0 && addr != IN_LOOPBACKNET);
369 }
370
371 return (IN_CLASSB(addr) || IN_CLASSC(addr));
372 }
373
374
375 /* See a new interface duplicates an existing interface.
376 */
377 struct interface *
378 check_dup(naddr addr, /* IP address, so network byte order */
379 naddr dstaddr, /* ditto */
380 naddr mask, /* mask, so host byte order */
381 int if_flags)
382 {
383 struct interface *ifp;
384
385 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
386 if (ifp->int_mask != mask)
387 continue;
388
389 if (!iff_alive(ifp->int_if_flags))
390 continue;
391
392 /* The local address can only be shared with a point-to-point
393 * link.
394 */
395 if (ifp->int_addr == addr
396 && (((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0))
397 return ifp;
398
399 if (on_net(ifp->int_dstaddr, ntohl(dstaddr),mask))
400 return ifp;
401 }
402 return 0;
403 }
404
405
406 /* See that a remote gateway is reachable.
407 * Note that the answer can change as real interfaces come and go.
408 */
409 int /* 0=bad */
410 check_remote(struct interface *ifp)
411 {
412 struct rt_entry *rt;
413
414 /* do not worry about other kinds */
415 if (!(ifp->int_state & IS_REMOTE))
416 return 1;
417
418 rt = rtfind(ifp->int_addr);
419 if (rt != 0
420 && rt->rt_ifp != 0
421 &&on_net(ifp->int_addr,
422 rt->rt_ifp->int_net, rt->rt_ifp->int_mask))
423 return 1;
424
425 /* the gateway cannot be reached directly from one of our
426 * interfaces
427 */
428 if (!(ifp->int_state & IS_BROKE)) {
429 msglog("unreachable gateway %s in "_PATH_GATEWAYS,
430 naddr_ntoa(ifp->int_addr));
431 if_bad(ifp);
432 }
433 return 0;
434 }
435
436
437 /* Delete an interface.
438 */
439 static void
440 ifdel(struct interface *ifp)
441 {
442 struct ip_mreq m;
443 struct interface *ifp1;
444
445
446 trace_if("Del", ifp);
447
448 ifp->int_state |= IS_BROKE;
449
450 /* unlink the interface
451 */
452 *ifp->int_prev = ifp->int_next;
453 if (ifp->int_next != 0)
454 ifp->int_next->int_prev = ifp->int_prev;
455 *ifp->int_ahash_prev = ifp->int_ahash;
456 if (ifp->int_ahash != 0)
457 ifp->int_ahash->int_ahash_prev = ifp->int_ahash_prev;
458 *ifp->int_nhash_prev = ifp->int_nhash;
459 if (ifp->int_nhash != 0)
460 ifp->int_nhash->int_nhash_prev = ifp->int_nhash_prev;
461 if (ifp->int_if_flags & IFF_BROADCAST) {
462 *ifp->int_bhash_prev = ifp->int_bhash;
463 if (ifp->int_bhash != 0)
464 ifp->int_bhash->int_bhash_prev = ifp->int_bhash_prev;
465 }
466 if (ifp->int_state & IS_REMOTE) {
467 *ifp->int_rlink_prev = ifp->int_rlink;
468 if (ifp->int_rlink != 0)
469 ifp->int_rlink->int_rlink_prev = ifp->int_rlink_prev;
470 }
471
472 if (!(ifp->int_state & IS_ALIAS)) {
473 /* delete aliases when the main interface dies
474 */
475 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
476 if (ifp1 != ifp
477 && !strcmp(ifp->int_name, ifp1->int_name))
478 ifdel(ifp1);
479 }
480
481 if ((ifp->int_if_flags & IFF_MULTICAST)
482 #ifdef MCAST_PPP_BUG
483 && !(ifp->int_if_flags & IFF_POINTOPOINT)
484 #endif
485 && rip_sock >= 0) {
486 m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP);
487 m.imr_interface.s_addr = ((ifp->int_if_flags
488 & IFF_POINTOPOINT)
489 ? ifp->int_dstaddr
490 : ifp->int_addr);
491 if (setsockopt(rip_sock,IPPROTO_IP,IP_DROP_MEMBERSHIP,
492 &m, sizeof(m)) < 0
493 && errno != EADDRNOTAVAIL
494 && !TRACEACTIONS)
495 LOGERR("setsockopt(IP_DROP_MEMBERSHIP RIP)");
496 if (rip_sock_mcast == ifp)
497 rip_sock_mcast = 0;
498 }
499 if (ifp->int_rip_sock >= 0) {
500 (void)close(ifp->int_rip_sock);
501 ifp->int_rip_sock = -1;
502 fix_select();
503 }
504
505 tot_interfaces--;
506 if (!IS_RIP_OFF(ifp->int_state))
507 rip_interfaces--;
508
509 /* Zap all routes associated with this interface.
510 * Assume routes just using gateways beyond this interface will
511 * timeout naturally, and have probably already died.
512 */
513 (void)rn_walktree(rhead, walk_bad, 0);
514
515 set_rdisc_mg(ifp, 0);
516 if_bad_rdisc(ifp);
517 }
518
519 free(ifp);
520 }
521
522
523 /* Mark an interface ill.
524 */
525 void
526 if_sick(struct interface *ifp)
527 {
528 if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) {
529 ifp->int_state |= IS_SICK;
530 ifp->int_act_time = NEVER;
531 trace_if("Chg", ifp);
532
533 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
534 }
535 }
536
537
538 /* Mark an interface dead.
539 */
540 void
541 if_bad(struct interface *ifp)
542 {
543 struct interface *ifp1;
544
545
546 if (ifp->int_state & IS_BROKE)
547 return;
548
549 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
550
551 ifp->int_state |= (IS_BROKE | IS_SICK);
552 ifp->int_act_time = NEVER;
553 ifp->int_query_time = NEVER;
554 ifp->int_data.ts = 0;
555
556 trace_if("Chg", ifp);
557
558 if (!(ifp->int_state & IS_ALIAS)) {
559 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
560 if (ifp1 != ifp
561 && !strcmp(ifp->int_name, ifp1->int_name))
562 if_bad(ifp1);
563 }
564 (void)rn_walktree(rhead, walk_bad, 0);
565 if_bad_rdisc(ifp);
566 }
567 }
568
569
570 /* Mark an interface alive
571 */
572 int /* 1=it was dead */
573 if_ok(struct interface *ifp,
574 char *type)
575 {
576 struct interface *ifp1;
577
578
579 if (!(ifp->int_state & IS_BROKE)) {
580 if (ifp->int_state & IS_SICK) {
581 trace_act("%sinterface %s to %s working better",
582 type,
583 ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
584 ifp->int_state &= ~IS_SICK;
585 }
586 return 0;
587 }
588
589 msglog("%sinterface %s to %s restored",
590 type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr));
591 ifp->int_state &= ~(IS_BROKE | IS_SICK);
592 ifp->int_data.ts = 0;
593
594 if (!(ifp->int_state & IS_ALIAS)) {
595 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
596 if (ifp1 != ifp
597 && !strcmp(ifp->int_name, ifp1->int_name))
598 if_ok(ifp1, type);
599 }
600 if_ok_rdisc(ifp);
601 }
602
603 if (ifp->int_state & IS_REMOTE) {
604 if (!addrouteforif(ifp))
605 return 0;
606 }
607 return 1;
608 }
609
610
611 /* disassemble routing message
612 */
613 void
614 rt_xaddrs(struct rt_addrinfo *info,
615 struct sockaddr *sa,
616 struct sockaddr *lim,
617 int addrs)
618 {
619 int i;
620 #ifdef _HAVE_SA_LEN
621 static struct sockaddr sa_zero;
622 #endif
623 #ifdef sgi
624 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \
625 : sizeof(__uint64_t))
626 #else
627 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
628 : sizeof(long))
629 #endif
630
631
632 memset(info, 0, sizeof(*info));
633 info->rti_addrs = addrs;
634 for (i = 0; i < RTAX_MAX && sa < lim; i++) {
635 if ((addrs & (1 << i)) == 0)
636 continue;
637 #ifdef _HAVE_SA_LEN
638 info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero;
639 sa = (struct sockaddr *)((char*)(sa)
640 + ROUNDUP(sa->sa_len));
641 #else
642 info->rti_info[i] = sa;
643 sa = (struct sockaddr *)((char*)(sa)
644 + ROUNDUP(_FAKE_SA_LEN_DST(sa)));
645 #endif
646 }
647 }
648
649
650 /* Find the network interfaces which have configured themselves.
651 * This must be done regularly, if only for extra addresses
652 * that come and go on interfaces.
653 */
654 void
655 ifinit(void)
656 {
657 static char *sysctl_buf;
658 static size_t sysctl_buf_size = 0;
659 uint complaints = 0;
660 static u_int prev_complaints = 0;
661 # define COMP_NOT_INET 0x001
662 # define COMP_NOADDR 0x002
663 # define COMP_BADADDR 0x004
664 # define COMP_NODST 0x008
665 # define COMP_NOBADR 0x010
666 # define COMP_NOMASK 0x020
667 # define COMP_DUP 0x040
668 # define COMP_BAD_METRIC 0x080
669 # define COMP_NETMASK 0x100
670
671 struct interface ifs, ifs0, *ifp, *ifp1;
672 struct rt_entry *rt;
673 size_t needed;
674 int mib[6];
675 struct if_msghdr *ifm;
676 struct ifa_msghdr *ifam, *ifam_lim, *ifam2;
677 int in, ierr, out, oerr;
678 struct intnet *intnetp;
679 struct rt_addrinfo info;
680 #ifdef SIOCGIFMETRIC
681 struct ifreq ifr;
682 #endif
683
684
685 last_ifinit = now;
686 ifinit_timer.tv_sec = now.tv_sec + (supplier
687 ? CHECK_ACT_INTERVAL
688 : CHECK_QUIET_INTERVAL);
689
690 /* mark all interfaces so we can get rid of thost that disappear */
691 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next)
692 ifp->int_state &= ~(IS_CHECKED | IS_DUP);
693
694 /* Fetch the interface list, without too many system calls
695 * since we do it repeatedly.
696 */
697 mib[0] = CTL_NET;
698 mib[1] = PF_ROUTE;
699 mib[2] = 0;
700 mib[3] = AF_INET;
701 mib[4] = NET_RT_IFLIST;
702 mib[5] = 0;
703 for (;;) {
704 if ((needed = sysctl_buf_size) != 0) {
705 if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0)
706 break;
707 if (errno != ENOMEM && errno != EFAULT)
708 BADERR(1, "ifinit: get interface table");
709 free(sysctl_buf);
710 needed = 0;
711 }
712 if (sysctl(mib, 6, 0, &needed, 0, 0) < 0)
713 BADERR(1,"ifinit: route-sysctl-estimate");
714 sysctl_buf = rtmalloc(sysctl_buf_size = needed, "ifinit");
715 }
716
717 ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed);
718 for (ifam = (struct ifa_msghdr *)sysctl_buf;
719 ifam < ifam_lim;
720 ifam = ifam2) {
721
722 ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen);
723
724 if (ifam->ifam_type == RTM_IFINFO) {
725 struct sockaddr_dl *sdl;
726
727 ifm = (struct if_msghdr *)ifam;
728 /* make prototype structure for the IP aliases
729 */
730 memset(&ifs0, 0, sizeof(ifs0));
731 ifs0.int_rip_sock = -1;
732 ifs0.int_index = ifm->ifm_index;
733 ifs0.int_if_flags = ifm->ifm_flags;
734 ifs0.int_state = IS_CHECKED;
735 ifs0.int_query_time = NEVER;
736 ifs0.int_act_time = now.tv_sec;
737 ifs0.int_data.ts = now.tv_sec;
738 ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets;
739 ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors;
740 ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets;
741 ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors;
742 #ifdef sgi
743 ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops;
744 #endif
745 sdl = (struct sockaddr_dl *)(ifm + 1);
746 sdl->sdl_data[sdl->sdl_nlen] = 0;
747 strncpy(ifs0.int_name, sdl->sdl_data,
748 MIN(sizeof(ifs0.int_name), sdl->sdl_nlen));
749 continue;
750 }
751 if (ifam->ifam_type != RTM_NEWADDR) {
752 logbad(1,"ifinit: out of sync");
753 continue;
754 }
755 rt_xaddrs(&info, (struct sockaddr *)(ifam+1),
756 (struct sockaddr *)ifam2,
757 ifam->ifam_addrs);
758
759 /* Prepare for the next address of this interface, which
760 * will be an alias.
761 * Do not output RIP or Router-Discovery packets via aliases.
762 */
763 memmove(&ifs, &ifs0, sizeof(ifs));
764 ifs0.int_state |= (IS_ALIAS | IS_NO_RIP | IS_NO_RDISC);
765
766 if (INFO_IFA(&info) == 0) {
767 if (iff_alive(ifs.int_if_flags)) {
768 if (!(prev_complaints & COMP_NOADDR))
769 msglog("%s has no address",
770 ifs.int_name);
771 complaints |= COMP_NOADDR;
772 }
773 continue;
774 }
775 if (INFO_IFA(&info)->sa_family != AF_INET) {
776 if (iff_alive(ifs.int_if_flags)) {
777 if (!(prev_complaints & COMP_NOT_INET))
778 trace_act("%s: not AF_INET",
779 ifs.int_name);
780 complaints |= COMP_NOT_INET;
781 }
782 continue;
783 }
784
785 ifs.int_addr = S_ADDR(INFO_IFA(&info));
786
787 if (ntohl(ifs.int_addr)>>24 == 0
788 || ntohl(ifs.int_addr)>>24 == 0xff) {
789 if (iff_alive(ifs.int_if_flags)) {
790 if (!(prev_complaints & COMP_BADADDR))
791 msglog("%s has a bad address",
792 ifs.int_name);
793 complaints |= COMP_BADADDR;
794 }
795 continue;
796 }
797
798 if (ifs.int_if_flags & IFF_LOOPBACK) {
799 ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC;
800 ifs.int_dstaddr = ifs.int_addr;
801 ifs.int_mask = HOST_MASK;
802 ifs.int_ripv1_mask = HOST_MASK;
803 ifs.int_std_mask = std_mask(ifs.int_dstaddr);
804 ifs.int_net = ntohl(ifs.int_dstaddr);
805 if (!foundloopback) {
806 foundloopback = 1;
807 loopaddr = ifs.int_addr;
808 }
809
810 } else if (ifs.int_if_flags & IFF_POINTOPOINT) {
811 if (INFO_BRD(&info) == 0
812 || INFO_BRD(&info)->sa_family != AF_INET) {
813 if (iff_alive(ifs.int_if_flags)) {
814 if (!(prev_complaints & COMP_NODST))
815 msglog("%s has a bad"
816 " destination address",
817 ifs.int_name);
818 complaints |= COMP_NODST;
819 }
820 continue;
821 }
822 ifs.int_dstaddr = S_ADDR(INFO_BRD(&info));
823 if (ntohl(ifs.int_dstaddr)>>24 == 0
824 || ntohl(ifs.int_dstaddr)>>24 == 0xff) {
825 if (iff_alive(ifs.int_if_flags)) {
826 if (!(prev_complaints & COMP_NODST))
827 msglog("%s has a bad"
828 " destination address",
829 ifs.int_name);
830 complaints |= COMP_NODST;
831 }
832 continue;
833 }
834 ifs.int_mask = HOST_MASK;
835 ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info)));
836 ifs.int_std_mask = std_mask(ifs.int_dstaddr);
837 ifs.int_net = ntohl(ifs.int_dstaddr);
838
839 } else {
840 if (INFO_MASK(&info) == 0) {
841 if (iff_alive(ifs.int_if_flags)) {
842 if (!(prev_complaints & COMP_NOMASK))
843 msglog("%s has no netmask",
844 ifs.int_name);
845 complaints |= COMP_NOMASK;
846 }
847 continue;
848 }
849 ifs.int_dstaddr = ifs.int_addr;
850 ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info)));
851 ifs.int_ripv1_mask = ifs.int_mask;
852 ifs.int_std_mask = std_mask(ifs.int_addr);
853 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask;
854 if (ifs.int_mask != ifs.int_std_mask)
855 ifs.int_state |= IS_SUBNET;
856
857 if (ifs.int_if_flags & IFF_BROADCAST) {
858 if (INFO_BRD(&info) == 0) {
859 if (iff_alive(ifs.int_if_flags)) {
860 if (!(prev_complaints
861 & COMP_NOBADR))
862 msglog("%s has"
863 "no broadcast address",
864 ifs.int_name);
865 complaints |= COMP_NOBADR;
866 }
867 continue;
868 }
869 ifs.int_brdaddr = S_ADDR(INFO_BRD(&info));
870 }
871 }
872 ifs.int_std_net = ifs.int_net & ifs.int_std_mask;
873 ifs.int_std_addr = htonl(ifs.int_std_net);
874
875 /* Use a minimum metric of one. Treat the interface metric
876 * (default 0) as an increment to the hop count of one.
877 *
878 * The metric obtained from the routing socket dump of
879 * interface addresses is wrong. It is not set by the
880 * SIOCSIFMETRIC ioctl.
881 */
882 #ifdef SIOCGIFMETRIC
883 strncpy(ifr.ifr_name, ifs.int_name, sizeof(ifr.ifr_name));
884 if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) {
885 DBGERR(1, "ioctl(SIOCGIFMETRIC)");
886 ifs.int_metric = 0;
887 } else {
888 ifs.int_metric = ifr.ifr_metric;
889 }
890 #else
891 ifs.int_metric = ifam->ifam_metric;
892 #endif
893 if (ifs.int_metric > HOPCNT_INFINITY) {
894 ifs.int_metric = 0;
895 if (!(prev_complaints & COMP_BAD_METRIC)
896 && iff_alive(ifs.int_if_flags)) {
897 complaints |= COMP_BAD_METRIC;
898 msglog("%s has a metric of %d",
899 ifs.int_name, ifs.int_metric);
900 }
901 }
902
903 /* See if this is a familiar interface.
904 * If so, stop worrying about it if it is the same.
905 * Start it over if it now is to somewhere else, as happens
906 * frequently with PPP and SLIP.
907 */
908 ifp = ifwithname(ifs.int_name, ((ifs.int_state & IS_ALIAS)
909 ? ifs.int_addr
910 : 0));
911 if (ifp != 0) {
912 ifp->int_state |= IS_CHECKED;
913
914 if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags)
915 & (IFF_BROADCAST
916 | IFF_LOOPBACK
917 | IFF_POINTOPOINT
918 | IFF_MULTICAST))
919 || 0 != ((ifp->int_state ^ ifs.int_state)
920 & IS_ALIAS)
921 || ifp->int_addr != ifs.int_addr
922 || ifp->int_brdaddr != ifs.int_brdaddr
923 || ifp->int_dstaddr != ifs.int_dstaddr
924 || ifp->int_mask != ifs.int_mask
925 || ifp->int_metric != ifs.int_metric) {
926 /* Forget old information about
927 * a changed interface.
928 */
929 trace_act("interface %s has changed",
930 ifp->int_name);
931 ifdel(ifp);
932 ifp = 0;
933 }
934 }
935
936 if (ifp != 0) {
937 /* The primary representative of an alias worries
938 * about how things are working.
939 */
940 if (ifp->int_state & IS_ALIAS)
941 continue;
942
943 /* note interfaces that have been turned off
944 */
945 if (!iff_alive(ifs.int_if_flags)) {
946 if (iff_alive(ifp->int_if_flags)) {
947 msglog("interface %s to %s turned off",
948 ifp->int_name,
949 naddr_ntoa(ifp->int_dstaddr));
950 if_bad(ifp);
951 ifp->int_if_flags &= ~IFF_UP_RUNNING;
952 }
953 continue;
954 }
955 /* or that were off and are now ok */
956 if (!iff_alive(ifp->int_if_flags)) {
957 ifp->int_if_flags |= IFF_UP_RUNNING;
958 (void)if_ok(ifp, "");
959 }
960
961 /* If it has been long enough,
962 * see if the interface is broken.
963 */
964 if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL)
965 continue;
966
967 in = ifs.int_data.ipackets - ifp->int_data.ipackets;
968 ierr = ifs.int_data.ierrors - ifp->int_data.ierrors;
969 out = ifs.int_data.opackets - ifp->int_data.opackets;
970 oerr = ifs.int_data.oerrors - ifp->int_data.oerrors;
971 #ifdef sgi
972 /* Through at least IRIX 6.2, PPP and SLIP
973 * count packets dropped by the filters.
974 * But FDDI rings stuck non-operational count
975 * dropped packets as they wait for improvement.
976 */
977 if (!(ifp->int_if_flags & IFF_POINTOPOINT))
978 oerr += (ifs.int_data.odrops
979 - ifp->int_data.odrops);
980 #endif
981 /* If the interface just awoke, restart the counters.
982 */
983 if (ifp->int_data.ts == 0) {
984 ifp->int_data = ifs.int_data;
985 continue;
986 }
987 ifp->int_data = ifs.int_data;
988
989 /* Withhold judgement when the short error
990 * counters wrap or the interface is reset.
991 */
992 if (ierr < 0 || in < 0 || oerr < 0 || out < 0) {
993 LIM_SEC(ifinit_timer,
994 now.tv_sec+CHECK_BAD_INTERVAL);
995 continue;
996 }
997
998 /* Withhold judgement when there is no traffic
999 */
1000 if (in == 0 && out == 0 && ierr == 0 && oerr == 0)
1001 continue;
1002
1003 /* It is bad if input or output is not working.
1004 * Require presistent problems before marking it dead.
1005 */
1006 if ((in <= ierr && ierr > 0)
1007 || (out <= oerr && oerr > 0)) {
1008 if (!(ifp->int_state & IS_SICK)) {
1009 trace_act("interface %s to %s"
1010 " sick: in=%d ierr=%d"
1011 " out=%d oerr=%d",
1012 ifp->int_name,
1013 naddr_ntoa(ifp->int_dstaddr),
1014 in, ierr, out, oerr);
1015 if_sick(ifp);
1016 continue;
1017 }
1018 if (!(ifp->int_state & IS_BROKE)) {
1019 msglog("interface %s to %s broken:"
1020 " in=%d ierr=%d out=%d oerr=%d",
1021 ifp->int_name,
1022 naddr_ntoa(ifp->int_dstaddr),
1023 in, ierr, out, oerr);
1024 if_bad(ifp);
1025 }
1026 continue;
1027 }
1028
1029 /* otherwise, it is active and healthy
1030 */
1031 ifp->int_act_time = now.tv_sec;
1032 (void)if_ok(ifp, "");
1033 continue;
1034 }
1035
1036 /* This is a new interface.
1037 * If it is dead, forget it.
1038 */
1039 if (!iff_alive(ifs.int_if_flags))
1040 continue;
1041
1042 /* If it duplicates an existing interface,
1043 * complain about it, mark the other one
1044 * duplicated, and forget this one.
1045 */
1046 ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask,
1047 ifs.int_if_flags);
1048 if (ifp != 0) {
1049 /* Ignore duplicates of itself, caused by having
1050 * IP aliases on the same network.
1051 */
1052 if (!strcmp(ifp->int_name, ifs.int_name))
1053 continue;
1054
1055 if (!(prev_complaints & COMP_DUP)) {
1056 complaints |= COMP_DUP;
1057 msglog("%s (%s%s%s) is duplicated by"
1058 " %s (%s%s%s)",
1059 ifs.int_name,
1060 addrname(ifs.int_addr,ifs.int_mask,1),
1061 ((ifs.int_if_flags & IFF_POINTOPOINT)
1062 ? "-->" : ""),
1063 ((ifs.int_if_flags & IFF_POINTOPOINT)
1064 ? naddr_ntoa(ifs.int_dstaddr) : ""),
1065 ifp->int_name,
1066 addrname(ifp->int_addr,ifp->int_mask,1),
1067 ((ifp->int_if_flags & IFF_POINTOPOINT)
1068 ? "-->" : ""),
1069 ((ifp->int_if_flags & IFF_POINTOPOINT)
1070 ? naddr_ntoa(ifp->int_dstaddr) : ""));
1071 }
1072 ifp->int_state |= IS_DUP;
1073 continue;
1074 }
1075
1076 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | IFF_BROADCAST))
1077 && !(ifs.int_state & IS_PASSIVE)) {
1078 trace_act("%s is neither broadcast, point-to-point,"
1079 " nor loopback",
1080 ifs.int_name);
1081 if (!(ifs.int_state & IFF_MULTICAST))
1082 ifs.int_state |= IS_NO_RDISC;
1083 }
1084
1085
1086 /* It is new and ok. Add it to the list of interfaces
1087 */
1088 ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit");
1089 memmove(ifp, &ifs, sizeof(*ifp));
1090 get_parms(ifp);
1091 if_link(ifp);
1092 trace_if("Add", ifp);
1093
1094 /* Notice likely bad netmask.
1095 */
1096 if (!(prev_complaints & COMP_NETMASK)
1097 && !(ifp->int_if_flags & IFF_POINTOPOINT)
1098 && ifp->int_addr != RIP_DEFAULT) {
1099 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) {
1100 if (ifp1->int_mask == ifp->int_mask)
1101 continue;
1102 if (ifp1->int_if_flags & IFF_POINTOPOINT)
1103 continue;
1104 if (ifp1->int_dstaddr == RIP_DEFAULT)
1105 continue;
1106 if (on_net(ifp->int_dstaddr,
1107 ifp1->int_net, ifp1->int_mask)
1108 || on_net(ifp1->int_dstaddr,
1109 ifp->int_net, ifp->int_mask)) {
1110 msglog("possible netmask problem"
1111 " between %s:%s and %s:%s",
1112 ifp->int_name,
1113 addrname(htonl(ifp->int_net),
1114 ifp->int_mask, 1),
1115 ifp1->int_name,
1116 addrname(htonl(ifp1->int_net),
1117 ifp1->int_mask, 1));
1118 complaints |= COMP_NETMASK;
1119 }
1120 }
1121 }
1122
1123 if (!(ifp->int_state & IS_ALIAS)) {
1124 /* Count the # of directly connected networks.
1125 */
1126 if (!(ifp->int_if_flags & IFF_LOOPBACK))
1127 tot_interfaces++;
1128 if (!IS_RIP_OFF(ifp->int_state))
1129 rip_interfaces++;
1130
1131 /* turn on router discovery and RIP If needed */
1132 if_ok_rdisc(ifp);
1133 rip_on(ifp);
1134 }
1135 }
1136
1137 /* If we are multi-homed and have at least two interfaces
1138 * listening to RIP, then output by default.
1139 */
1140 if (!supplier_set && rip_interfaces > 1)
1141 set_supplier();
1142
1143 /* If we are multi-homed, optionally advertise a route to
1144 * our main address.
1145 */
1146 if (advertise_mhome
1147 || (tot_interfaces > 1
1148 && mhome
1149 && (ifp = ifwithaddr(myaddr, 0, 0)) != 0
1150 && foundloopback)) {
1151 advertise_mhome = 1;
1152 rt = rtget(myaddr, HOST_MASK);
1153 if (rt != 0) {
1154 if (rt->rt_ifp != ifp
1155 || rt->rt_router != loopaddr) {
1156 rtdelete(rt);
1157 rt = 0;
1158 } else {
1159 rtchange(rt, rt->rt_state | RS_MHOME,
1160 loopaddr, loopaddr,
1161 0, 0, ifp, rt->rt_time, 0);
1162 }
1163 }
1164 if (rt == 0)
1165 rtadd(myaddr, HOST_MASK, loopaddr, loopaddr,
1166 0, 0, RS_MHOME, ifp);
1167 }
1168
1169 for (ifp = ifnet; ifp != 0; ifp = ifp1) {
1170 ifp1 = ifp->int_next; /* because we may delete it */
1171
1172 /* Forget any interfaces that have disappeared.
1173 */
1174 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) {
1175 trace_act("interface %s has disappeared",
1176 ifp->int_name);
1177 ifdel(ifp);
1178 continue;
1179 }
1180
1181 if ((ifp->int_state & IS_BROKE)
1182 && !(ifp->int_state & IS_PASSIVE))
1183 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL);
1184
1185 /* If we ever have a RIPv1 interface, assume we always will.
1186 * It might come back if it ever goes away.
1187 */
1188 if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier)
1189 have_ripv1_out = 1;
1190 if (!(ifp->int_state & IS_NO_RIPV1_IN))
1191 have_ripv1_in = 1;
1192 }
1193
1194 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
1195 /* Ensure there is always a network route for interfaces,
1196 * after any dead interfaces have been deleted, which
1197 * might affect routes for point-to-point links.
1198 */
1199 if (!addrouteforif(ifp))
1200 continue;
1201
1202 /* Add routes to the local end of point-to-point interfaces
1203 * using loopback.
1204 */
1205 if ((ifp->int_if_flags & IFF_POINTOPOINT)
1206 && !(ifp->int_state & IS_REMOTE)
1207 && foundloopback) {
1208 /* Delete any routes to the network address through
1209 * foreign routers. Remove even static routes.
1210 */
1211 del_static(ifp->int_addr, HOST_MASK, 0);
1212 rt = rtget(ifp->int_addr, HOST_MASK);
1213 if (rt != 0 && rt->rt_router != loopaddr) {
1214 rtdelete(rt);
1215 rt = 0;
1216 }
1217 if (rt != 0) {
1218 if (!(rt->rt_state & RS_LOCAL)
1219 || rt->rt_metric > ifp->int_metric) {
1220 ifp1 = ifp;
1221 } else {
1222 ifp1 = rt->rt_ifp;
1223 }
1224 rtchange(rt,((rt->rt_state & ~RS_NET_SYN)
1225 | (RS_IF|RS_LOCAL)),
1226 loopaddr, loopaddr,
1227 0, 0, ifp1, rt->rt_time, 0);
1228 } else {
1229 rtadd(ifp->int_addr, HOST_MASK,
1230 loopaddr, loopaddr,
1231 0, 0, (RS_IF | RS_LOCAL), ifp);
1232 }
1233 }
1234 }
1235
1236 /* add the authority routes */
1237 for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) {
1238 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask);
1239 if (rt != 0
1240 && !(rt->rt_state & RS_NO_NET_SYN)
1241 && !(rt->rt_state & RS_NET_INT)) {
1242 rtdelete(rt);
1243 rt = 0;
1244 }
1245 if (rt == 0)
1246 rtadd(intnetp->intnet_addr, intnetp->intnet_mask,
1247 loopaddr, loopaddr, intnetp->intnet_metric-1,
1248 0, RS_NET_SYN | RS_NET_INT, 0);
1249 }
1250
1251 prev_complaints = complaints;
1252 }
1253
1254
1255 static void
1256 check_net_syn(struct interface *ifp)
1257 {
1258 struct rt_entry *rt;
1259
1260
1261 /* Turn on the need to automatically synthesize a network route
1262 * for this interface only if we are running RIPv1 on some other
1263 * interface that is on a different class-A,B,or C network.
1264 */
1265 if (have_ripv1_out || have_ripv1_in) {
1266 ifp->int_state |= IS_NEED_NET_SYN;
1267 rt = rtget(ifp->int_std_addr, ifp->int_std_mask);
1268 if (rt != 0
1269 && 0 == (rt->rt_state & RS_NO_NET_SYN)
1270 && (!(rt->rt_state & RS_NET_SYN)
1271 || rt->rt_metric > ifp->int_metric)) {
1272 rtdelete(rt);
1273 rt = 0;
1274 }
1275 if (rt == 0)
1276 rtadd(ifp->int_std_addr, ifp->int_std_mask,
1277 ifp->int_addr, ifp->int_addr,
1278 ifp->int_metric, 0, RS_NET_SYN, ifp);
1279
1280 } else {
1281 ifp->int_state &= ~IS_NEED_NET_SYN;
1282
1283 rt = rtget(ifp->int_std_addr,
1284 ifp->int_std_mask);
1285 if (rt != 0
1286 && (rt->rt_state & RS_NET_SYN)
1287 && rt->rt_ifp == ifp)
1288 rtbad_sub(rt);
1289 }
1290 }
1291
1292
1293 /* Add route for interface if not currently installed.
1294 * Create route to other end if a point-to-point link,
1295 * otherwise a route to this (sub)network.
1296 */
1297 int /* 0=bad interface */
1298 addrouteforif(struct interface *ifp)
1299 {
1300 struct rt_entry *rt;
1301 naddr dst, gate;
1302
1303
1304 /* skip sick interfaces
1305 */
1306 if (ifp->int_state & IS_BROKE)
1307 return 0;
1308
1309 /* If the interface on a subnet, then install a RIPv1 route to
1310 * the network as well (unless it is sick).
1311 */
1312 if (ifp->int_state & IS_SUBNET)
1313 check_net_syn(ifp);
1314
1315 gate = ifp->int_addr;
1316 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
1317 ? ifp->int_dstaddr
1318 : htonl(ifp->int_net));
1319
1320 /* If we are going to send packets to the gateway,
1321 * it must be reachable using our physical interfaces
1322 */
1323 if ((ifp->int_state & IS_REMOTE)
1324 && !(ifp->int_state & IS_EXTERNAL)
1325 && !check_remote(ifp))
1326 return 0;
1327
1328 /* We are finished if the correct main interface route exists.
1329 * The right route must be for the right interface, not synthesized
1330 * from a subnet, be a "gateway" or not as appropriate, and so forth.
1331 */
1332 del_static(dst, ifp->int_mask, 0);
1333 rt = rtget(dst, ifp->int_mask);
1334 if (rt != 0) {
1335 if ((rt->rt_ifp != ifp
1336 || rt->rt_router != ifp->int_addr)
1337 && (!(ifp->int_state & IS_DUP)
1338 || rt->rt_ifp == 0
1339 || (rt->rt_ifp->int_state & IS_BROKE))) {
1340 rtdelete(rt);
1341 rt = 0;
1342 } else {
1343 rtchange(rt, ((rt->rt_state | RS_IF)
1344 & ~(RS_NET_SYN | RS_LOCAL)),
1345 ifp->int_addr, ifp->int_addr,
1346 ifp->int_metric, 0, ifp, now.tv_sec, 0);
1347 }
1348 }
1349 if (rt == 0) {
1350 if (ifp->int_transitions++ > 0)
1351 trace_act("re-install interface %s",
1352 ifp->int_name);
1353
1354 rtadd(dst, ifp->int_mask, gate, gate,
1355 ifp->int_metric, 0, RS_IF, ifp);
1356 }
1357
1358 return 1;
1359 }
1360