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