aboutsummaryrefslogtreecommitdiff
path: root/sbin/routed/if.c
diff options
context:
space:
mode:
authorMark Murray <markm@FreeBSD.org>1999-05-02 10:51:54 +0000
committerMark Murray <markm@FreeBSD.org>1999-05-02 10:51:54 +0000
commit2c7a97817b8e83a80ed67bbeb294334140b7d26d (patch)
treec0dd10cc2471be0527b6700410ae4edfbb6d940c /sbin/routed/if.c
parentcdb877c33d6cc233b12f3f889f372a15d70559e4 (diff)
downloadsrc-2c7a97817b8e83a80ed67bbeb294334140b7d26d.tar.gz
src-2c7a97817b8e83a80ed67bbeb294334140b7d26d.zip
Latest-and-greatest routed.vendor/SGI/vjs_990324vendor/SGI/v_2_17
Includes RIPv2 and Router Discovery. Submitted by: Vernon Schryver <vjs@calcite.rhyolite.com>
Notes
Notes: svn path=/vendor/SGI/dist2/; revision=46286 svn path=/vendor/SGI/tags/v_2_17/; revision=46287; tag=vendor/SGI/v_2_17 svn path=/vendor/SGI/vjs_990324/; revision=46288; tag=vendor/SGI/vjs_990324
Diffstat (limited to 'sbin/routed/if.c')
-rw-r--r--sbin/routed/if.c225
1 files changed, 142 insertions, 83 deletions
diff --git a/sbin/routed/if.c b/sbin/routed/if.c
index b68ff52a9134..54228ce24aa8 100644
--- a/sbin/routed/if.c
+++ b/sbin/routed/if.c
@@ -11,7 +11,7 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
+ * must display the following acknowledgment:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
@@ -31,16 +31,17 @@
* SUCH DAMAGE.
*/
-#if !defined(lint) && !defined(sgi) && !defined(__NetBSD__)
-static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93";
-#elif defined(__NetBSD__)
-static char rcsid[] = "$NetBSD$";
-#endif
-#ident "$Revision: 1.23 $"
-
#include "defs.h"
#include "pathnames.h"
+#if !defined(sgi) && !defined(__NetBSD__)
+static char sccsid[] __attribute__((unused)) = "@(#)if.c 8.1 (Berkeley) 6/5/93";
+#elif defined(__NetBSD__)
+#include <sys/cdefs.h>
+__RCSID("$NetBSD$");
+#endif
+#ident "$Revision: 2.17 $"
+
struct interface *ifnet; /* all interfaces */
/* hash table for all interfaces, big enough to tolerate ridiculous
@@ -69,18 +70,22 @@ int tot_interfaces; /* # of remote and local interfaces */
int rip_interfaces; /* # of interfaces doing RIP */
int foundloopback; /* valid flag for loopaddr */
naddr loopaddr; /* our address on loopback */
+struct rt_spare loop_rts;
struct timeval ifinit_timer;
static struct timeval last_ifinit;
+#define IF_RESCAN_DELAY() (last_ifinit.tv_sec == now.tv_sec \
+ && last_ifinit.tv_usec == now.tv_usec \
+ && timercmp(&ifinit_timer, &now, >))
int have_ripv1_out; /* have a RIPv1 interface */
int have_ripv1_in;
static struct interface**
-nhash(register char *p)
+nhash(char *p)
{
- register u_int i;
+ u_int i;
for (i = 0; *p != '\0'; p++) {
i = ((i<<1) & 0x7fffffff) | ((i>>31) & 1);
@@ -199,8 +204,7 @@ ifwithname(char *name, /* "ec0" or whatever */
/* If there is no known interface, maybe there is a
* new interface. So just once look for new interfaces.
*/
- if (last_ifinit.tv_sec == now.tv_sec
- && last_ifinit.tv_usec == now.tv_usec)
+ if (IF_RESCAN_DELAY())
return 0;
ifinit();
}
@@ -208,16 +212,25 @@ ifwithname(char *name, /* "ec0" or whatever */
struct interface *
-ifwithindex(u_short index)
+ifwithindex(u_short index,
+ int rescan_ok)
{
struct interface *ifp;
+ for (;;) {
+ for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
+ if (ifp->int_index == index)
+ return ifp;
+ }
- for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {
- if (ifp->int_index == index)
- return ifp;
+ /* If there is no known interface, maybe there is a
+ * new interface. So just once look for new interfaces.
+ */
+ if (!rescan_ok
+ || IF_RESCAN_DELAY())
+ return 0;
+ ifinit();
}
- return 0;
}
@@ -253,8 +266,7 @@ iflookup(naddr addr)
}
if (maybe != 0
- || (last_ifinit.tv_sec == now.tv_sec
- && last_ifinit.tv_usec == now.tv_usec))
+ || IF_RESCAN_DELAY())
return maybe;
/* If there is no known interface, maybe there is a
@@ -290,12 +302,13 @@ naddr
ripv1_mask_net(naddr addr, /* in network byte order */
struct interface *ifp) /* as seen on this interface */
{
+ struct r1net *r1p;
naddr mask = 0;
if (addr == 0) /* default always has 0 mask */
return mask;
- if (ifp != 0) {
+ if (ifp != 0 && ifp->int_ripv1_mask != HOST_MASK) {
/* If the target network is that of the associated interface
* on which it arrived, then use the netmask of the interface.
*/
@@ -311,15 +324,26 @@ ripv1_mask_net(naddr addr, /* in network byte order */
*/
for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {
if (on_net(addr, ifp->int_std_net, ifp->int_std_mask)
- && ifp->int_ripv1_mask > mask)
+ && ifp->int_ripv1_mask > mask
+ && ifp->int_ripv1_mask != HOST_MASK)
mask = ifp->int_ripv1_mask;
}
+
}
- /* Otherwise, make the classic A/B/C guess.
- */
- if (mask == 0)
- mask = std_mask(addr);
+ /* check special definitions */
+ if (mask == 0) {
+ for (r1p = r1nets; r1p != 0; r1p = r1p->r1net_next) {
+ if (on_net(addr, r1p->r1net_net, r1p->r1net_match)
+ && r1p->r1net_mask > mask)
+ mask = r1p->r1net_mask;
+ }
+
+ /* Otherwise, make the classic A/B/C guess.
+ */
+ if (mask == 0)
+ mask = std_mask(addr);
+ }
return mask;
}
@@ -374,11 +398,11 @@ check_dup(naddr addr, /* IP address, so network byte order */
if (ifp->int_mask != mask)
continue;
- if (!iff_alive(ifp->int_if_flags))
+ if (!iff_up(ifp->int_if_flags))
continue;
- /* The local address can only be shared with a point-to-
- * point link.
+ /* The local address can only be shared with a point-to-point
+ * link.
*/
if (ifp->int_addr == addr
&& (((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0))
@@ -495,8 +519,8 @@ ifdel(struct interface *ifp)
rip_interfaces--;
/* Zap all routes associated with this interface.
- * Assume routes just using gateways beyond this interface will
- * timeout naturally, and have probably already died.
+ * Assume routes just using gateways beyond this interface
+ * will timeout naturally, and have probably already died.
*/
(void)rn_walktree(rhead, walk_bad, 0);
@@ -539,7 +563,7 @@ if_bad(struct interface *ifp)
ifp->int_state |= (IS_BROKE | IS_SICK);
ifp->int_act_time = NEVER;
ifp->int_query_time = NEVER;
- ifp->int_data.ts = 0;
+ ifp->int_data.ts = now.tv_sec;
trace_if("Chg", ifp);
@@ -559,7 +583,7 @@ if_bad(struct interface *ifp)
*/
int /* 1=it was dead */
if_ok(struct interface *ifp,
- char *type)
+ const char *type)
{
struct interface *ifp1;
@@ -617,7 +641,7 @@ rt_xaddrs(struct rt_addrinfo *info,
#endif
- bzero(info, sizeof(*info));
+ memset(info, 0, sizeof(*info));
info->rti_addrs = addrs;
for (i = 0; i < RTAX_MAX && sa < lim; i++) {
if ((addrs & (1 << i)) == 0)
@@ -675,7 +699,7 @@ ifinit(void)
? CHECK_ACT_INTERVAL
: CHECK_QUIET_INTERVAL);
- /* mark all interfaces so we can get rid of thost that disappear */
+ /* mark all interfaces so we can get rid of those that disappear */
for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next)
ifp->int_state &= ~(IS_CHECKED | IS_DUP);
@@ -692,14 +716,16 @@ ifinit(void)
if ((needed = sysctl_buf_size) != 0) {
if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0)
break;
+ /* retry if the table grew */
if (errno != ENOMEM && errno != EFAULT)
- BADERR(1, "ifinit: get interface table");
+ BADERR(1, "ifinit: sysctl(RT_IFLIST)");
free(sysctl_buf);
needed = 0;
}
if (sysctl(mib, 6, 0, &needed, 0, 0) < 0)
- BADERR(1,"ifinit: route-sysctl-estimate");
- sysctl_buf = rtmalloc(sysctl_buf_size = needed, "ifinit");
+ BADERR(1,"ifinit: sysctl(RT_IFLIST) estimate");
+ sysctl_buf = rtmalloc(sysctl_buf_size = needed,
+ "ifinit sysctl");
}
ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed);
@@ -715,7 +741,7 @@ ifinit(void)
ifm = (struct if_msghdr *)ifam;
/* make prototype structure for the IP aliases
*/
- bzero(&ifs0, sizeof(ifs0));
+ memset(&ifs0, 0, sizeof(ifs0));
ifs0.int_rip_sock = -1;
ifs0.int_index = ifm->ifm_index;
ifs0.int_if_flags = ifm->ifm_flags;
@@ -748,11 +774,11 @@ ifinit(void)
* will be an alias.
* Do not output RIP or Router-Discovery packets via aliases.
*/
- bcopy(&ifs0, &ifs, sizeof(ifs));
- ifs0.int_state |= (IS_ALIAS | IS_NO_RIP | IS_NO_RDISC);
+ memcpy(&ifs, &ifs0, sizeof(ifs));
+ ifs0.int_state |= (IS_ALIAS | IS_NO_RIP_OUT | IS_NO_RDISC);
if (INFO_IFA(&info) == 0) {
- if (iff_alive(ifs.int_if_flags)) {
+ if (iff_up(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_NOADDR))
msglog("%s has no address",
ifs.int_name);
@@ -761,7 +787,7 @@ ifinit(void)
continue;
}
if (INFO_IFA(&info)->sa_family != AF_INET) {
- if (iff_alive(ifs.int_if_flags)) {
+ if (iff_up(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_NOT_INET))
trace_act("%s: not AF_INET",
ifs.int_name);
@@ -774,7 +800,7 @@ ifinit(void)
if (ntohl(ifs.int_addr)>>24 == 0
|| ntohl(ifs.int_addr)>>24 == 0xff) {
- if (iff_alive(ifs.int_if_flags)) {
+ if (iff_up(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_BADADDR))
msglog("%s has a bad address",
ifs.int_name);
@@ -793,12 +819,14 @@ ifinit(void)
if (!foundloopback) {
foundloopback = 1;
loopaddr = ifs.int_addr;
+ loop_rts.rts_gate = loopaddr;
+ loop_rts.rts_router = loopaddr;
}
} else if (ifs.int_if_flags & IFF_POINTOPOINT) {
if (INFO_BRD(&info) == 0
|| INFO_BRD(&info)->sa_family != AF_INET) {
- if (iff_alive(ifs.int_if_flags)) {
+ if (iff_up(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_NODST))
msglog("%s has a bad"
" destination address",
@@ -810,7 +838,7 @@ ifinit(void)
ifs.int_dstaddr = S_ADDR(INFO_BRD(&info));
if (ntohl(ifs.int_dstaddr)>>24 == 0
|| ntohl(ifs.int_dstaddr)>>24 == 0xff) {
- if (iff_alive(ifs.int_if_flags)) {
+ if (iff_up(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_NODST))
msglog("%s has a bad"
" destination address",
@@ -826,7 +854,7 @@ ifinit(void)
} else {
if (INFO_MASK(&info) == 0) {
- if (iff_alive(ifs.int_if_flags)) {
+ if (iff_up(ifs.int_if_flags)) {
if (!(prev_complaints & COMP_NOMASK))
msglog("%s has no netmask",
ifs.int_name);
@@ -844,7 +872,7 @@ ifinit(void)
if (ifs.int_if_flags & IFF_BROADCAST) {
if (INFO_BRD(&info) == 0) {
- if (iff_alive(ifs.int_if_flags)) {
+ if (iff_up(ifs.int_if_flags)) {
if (!(prev_complaints
& COMP_NOBADR))
msglog("%s has"
@@ -881,7 +909,7 @@ ifinit(void)
if (ifs.int_metric > HOPCNT_INFINITY) {
ifs.int_metric = 0;
if (!(prev_complaints & COMP_BAD_METRIC)
- && iff_alive(ifs.int_if_flags)) {
+ && iff_up(ifs.int_if_flags)) {
complaints |= COMP_BAD_METRIC;
msglog("%s has a metric of %d",
ifs.int_name, ifs.int_metric);
@@ -930,19 +958,26 @@ ifinit(void)
/* note interfaces that have been turned off
*/
- if (!iff_alive(ifs.int_if_flags)) {
- if (iff_alive(ifp->int_if_flags)) {
+ if (!iff_up(ifs.int_if_flags)) {
+ if (iff_up(ifp->int_if_flags)) {
msglog("interface %s to %s turned off",
ifp->int_name,
naddr_ntoa(ifp->int_dstaddr));
if_bad(ifp);
- ifp->int_if_flags &= ~IFF_UP_RUNNING;
+ ifp->int_if_flags &= ~IFF_UP;
+ } else if (now.tv_sec>(ifp->int_data.ts
+ + CHECK_BAD_INTERVAL)) {
+ trace_act("interface %s has been off"
+ " %ld seconds; forget it",
+ ifp->int_name,
+ now.tv_sec-ifp->int_data.ts);
+ ifdel(ifp);
}
continue;
}
/* or that were off and are now ok */
- if (!iff_alive(ifp->int_if_flags)) {
- ifp->int_if_flags |= IFF_UP_RUNNING;
+ if (!iff_up(ifp->int_if_flags)) {
+ ifp->int_if_flags |= IFF_UP;
(void)if_ok(ifp, "");
}
@@ -958,7 +993,7 @@ ifinit(void)
oerr = ifs.int_data.oerrors - ifp->int_data.oerrors;
#ifdef sgi
/* Through at least IRIX 6.2, PPP and SLIP
- * count packets dropped by the filters.
+ * count packets dropped by the filters.
* But FDDI rings stuck non-operational count
* dropped packets as they wait for improvement.
*/
@@ -974,7 +1009,7 @@ ifinit(void)
}
ifp->int_data = ifs.int_data;
- /* Withhold judgement when the short error
+ /* Withhold judgment when the short error
* counters wrap or the interface is reset.
*/
if (ierr < 0 || in < 0 || oerr < 0 || out < 0) {
@@ -1024,7 +1059,7 @@ ifinit(void)
/* This is a new interface.
* If it is dead, forget it.
*/
- if (!iff_alive(ifs.int_if_flags))
+ if (!iff_up(ifs.int_if_flags))
continue;
/* If it duplicates an existing interface,
@@ -1034,6 +1069,12 @@ ifinit(void)
ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask,
ifs.int_if_flags);
if (ifp != 0) {
+ /* Ignore duplicates of itself, caused by having
+ * IP aliases on the same network.
+ */
+ if (!strcmp(ifp->int_name, ifs.int_name))
+ continue;
+
if (!(prev_complaints & COMP_DUP)) {
complaints |= COMP_DUP;
msglog("%s (%s%s%s) is duplicated by"
@@ -1067,8 +1108,8 @@ ifinit(void)
/* It is new and ok. Add it to the list of interfaces
*/
- ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit");
- bcopy(&ifs, ifp, sizeof(*ifp));
+ ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit ifp");
+ memcpy(ifp, &ifs, sizeof(*ifp));
get_parms(ifp);
if_link(ifp);
trace_if("Add", ifp);
@@ -1138,14 +1179,18 @@ ifinit(void)
rtdelete(rt);
rt = 0;
} else {
+ loop_rts.rts_ifp = ifp;
+ loop_rts.rts_metric = 0;
+ loop_rts.rts_time = rt->rt_time;
rtchange(rt, rt->rt_state | RS_MHOME,
- loopaddr, loopaddr,
- 0, 0, ifp, rt->rt_time, 0);
+ &loop_rts, 0);
}
}
- if (rt == 0)
- rtadd(myaddr, HOST_MASK, loopaddr, loopaddr,
- 0, 0, RS_MHOME, ifp);
+ if (rt == 0) {
+ loop_rts.rts_ifp = ifp;
+ loop_rts.rts_metric = 0;
+ rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts);
+ }
}
for (ifp = ifnet; ifp != 0; ifp = ifp1) {
@@ -1190,7 +1235,7 @@ ifinit(void)
/* Delete any routes to the network address through
* foreign routers. Remove even static routes.
*/
- del_static(ifp->int_addr, HOST_MASK, 0);
+ del_static(ifp->int_addr, HOST_MASK, 0, 0);
rt = rtget(ifp->int_addr, HOST_MASK);
if (rt != 0 && rt->rt_router != loopaddr) {
rtdelete(rt);
@@ -1203,14 +1248,17 @@ ifinit(void)
} else {
ifp1 = rt->rt_ifp;
}
- rtchange(rt,((rt->rt_state & ~RS_NET_SYN)
- | (RS_IF|RS_LOCAL)),
- loopaddr, loopaddr,
- 0, 0, ifp1, rt->rt_time, 0);
+ loop_rts.rts_ifp = ifp1;
+ loop_rts.rts_metric = 0;
+ loop_rts.rts_time = rt->rt_time;
+ rtchange(rt, ((rt->rt_state & ~RS_NET_SYN)
+ | (RS_IF|RS_LOCAL)),
+ &loop_rts, 0);
} else {
+ loop_rts.rts_ifp = ifp;
+ loop_rts.rts_metric = 0;
rtadd(ifp->int_addr, HOST_MASK,
- loopaddr, loopaddr,
- 0, 0, (RS_IF | RS_LOCAL), ifp);
+ (RS_IF | RS_LOCAL), &loop_rts);
}
}
}
@@ -1224,10 +1272,12 @@ ifinit(void)
rtdelete(rt);
rt = 0;
}
- if (rt == 0)
+ if (rt == 0) {
+ loop_rts.rts_ifp = 0;
+ loop_rts.rts_metric = intnetp->intnet_metric-1;
rtadd(intnetp->intnet_addr, intnetp->intnet_mask,
- loopaddr, loopaddr, intnetp->intnet_metric-1,
- 0, RS_NET_SYN | RS_NET_INT, 0);
+ RS_NET_SYN | RS_NET_INT, &loop_rts);
+ }
}
prev_complaints = complaints;
@@ -1238,6 +1288,7 @@ static void
check_net_syn(struct interface *ifp)
{
struct rt_entry *rt;
+ static struct rt_spare new;
/* Turn on the need to automatically synthesize a network route
@@ -1254,10 +1305,14 @@ check_net_syn(struct interface *ifp)
rtdelete(rt);
rt = 0;
}
- if (rt == 0)
+ if (rt == 0) {
+ new.rts_ifp = ifp;
+ new.rts_gate = ifp->int_addr;
+ new.rts_router = ifp->int_addr;
+ new.rts_metric = ifp->int_metric;
rtadd(ifp->int_std_addr, ifp->int_std_mask,
- ifp->int_addr, ifp->int_addr,
- ifp->int_metric, 0, RS_NET_SYN, ifp);
+ RS_NET_SYN, &new);
+ }
} else {
ifp->int_state &= ~IS_NEED_NET_SYN;
@@ -1280,7 +1335,8 @@ int /* 0=bad interface */
addrouteforif(struct interface *ifp)
{
struct rt_entry *rt;
- naddr dst, gate;
+ static struct rt_spare new;
+ naddr dst;
/* skip sick interfaces
@@ -1294,11 +1350,16 @@ addrouteforif(struct interface *ifp)
if (ifp->int_state & IS_SUBNET)
check_net_syn(ifp);
- gate = ifp->int_addr;
dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
? ifp->int_dstaddr
: htonl(ifp->int_net));
+ new.rts_ifp = ifp;
+ new.rts_router = ifp->int_addr;
+ new.rts_gate = ifp->int_addr;
+ new.rts_metric = ifp->int_metric;
+ new.rts_time = now.tv_sec;
+
/* If we are going to send packets to the gateway,
* it must be reachable using our physical interfaces
*/
@@ -1311,7 +1372,7 @@ addrouteforif(struct interface *ifp)
* The right route must be for the right interface, not synthesized
* from a subnet, be a "gateway" or not as appropriate, and so forth.
*/
- del_static(dst, ifp->int_mask, 0);
+ del_static(dst, ifp->int_mask, 0, 0);
rt = rtget(dst, ifp->int_mask);
if (rt != 0) {
if ((rt->rt_ifp != ifp
@@ -1324,8 +1385,7 @@ addrouteforif(struct interface *ifp)
} else {
rtchange(rt, ((rt->rt_state | RS_IF)
& ~(RS_NET_SYN | RS_LOCAL)),
- ifp->int_addr, ifp->int_addr,
- ifp->int_metric, 0, ifp, now.tv_sec, 0);
+ &new, 0);
}
}
if (rt == 0) {
@@ -1333,8 +1393,7 @@ addrouteforif(struct interface *ifp)
trace_act("re-install interface %s",
ifp->int_name);
- rtadd(dst, ifp->int_mask, gate, gate,
- ifp->int_metric, 0, RS_IF, ifp);
+ rtadd(dst, ifp->int_mask, RS_IF, &new);
}
return 1;