From 5df7296441e98a1e91f8f41633f05bc7a6a74ed6 Mon Sep 17 00:00:00 2001 From: Garrett Wollman Date: Tue, 11 Oct 1994 23:16:38 +0000 Subject: [PATCH] Fix a bug which caused panics when attempting to change just the flags of a route. (This still doesn't work, but it doesn't panic now.) It looks like there may be a number of incipient bugs in this code. Also, get ready for the time when all IP gateway routes are cloning, which is necessary to keep proper TCP statistics. --- sys/net/if_ethersubr.c | 4 ++-- sys/net/route.c | 32 ++++++++++++++++++++++++++++++-- sys/net/rtsock.c | 13 ++++++++++++- sys/netinet/if_ether.c | 15 +++++++++++++-- sys/netinet/if_ether.h | 6 +++--- 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index daba4b65f5bb..3929fa3236e6 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93 - * $Id$ + * $Id: if_ethersubr.c,v 1.2 1994/08/02 07:46:14 davidg Exp $ */ #include @@ -138,7 +138,7 @@ ether_output(ifp, m0, dst, rt0) #ifdef INET case AF_INET: - if (!arpresolve(ac, rt, m, dst, edst)) + if (!arpresolve(ac, rt, m, dst, edst, rt0)) return (0); /* if not yet resolved */ /* If broadcasting on a simplex interface, loopback a copy */ if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)) diff --git a/sys/net/route.c b/sys/net/route.c index 15c6bf914ca1..84fc40ac8969 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -31,11 +31,12 @@ * SUCH DAMAGE. * * @(#)route.c 8.2 (Berkeley) 11/15/93 - * $Id: route.c,v 1.7 1994/09/14 03:10:05 wollman Exp $ + * $Id: route.c,v 1.8 1994/10/02 17:48:26 phk Exp $ */ #include #include +#include #include #include #include @@ -297,8 +298,9 @@ ifa_ifwithroute(flags, dst, gateway) * we can use the local address. */ ifa = 0; - if (flags & RTF_HOST) + if (flags & RTF_HOST) { ifa = ifa_ifwithdstaddr(dst); + } if (ifa == 0) ifa = ifa_ifwithaddr(gateway); } else { @@ -342,6 +344,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) register struct radix_node_head *rnh; struct ifaddr *ifa; struct sockaddr *ndst; + int doexpire = 0; #define senderr(x) { error = x ; goto bad; } if ((rnh = rt_tables[dst->sa_family]) == 0) @@ -379,11 +382,33 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) gateway = rt->rt_gateway; if ((netmask = rt->rt_genmask) == 0) flags |= RTF_HOST; + if (flags & RTF_STATIC) { + /* + * We make a few assumptions here which are not + * necessarily valid for everybody. + * 1) static cloning routes want this treatment + * 2) somebody's link layer out there is + * timing these things out + * + * (2) in particular is not presently true for any + * p2p links, but we hope that this will not cause + * problems. (I believe that these extra routes + * can never cause incorrect operation, but they + * really should get timed out to free the memory.) + */ + flags &= ~RTF_STATIC; + doexpire = 1; + } + goto makeroute; case RTM_ADD: + if ((flags & RTF_GATEWAY) && !gateway) + panic("rtrequest: GATEWAY but no gateway"); + if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0) senderr(ENETUNREACH); + makeroute: R_Malloc(rt, struct rtentry *, sizeof(*rt)); if (rt == 0) @@ -413,6 +438,9 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) rt->rt_ifp = ifa->ifa_ifp; if (req == RTM_RESOLVE) rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */ + if (doexpire) + rt->rt_rmx.rmx_expire = + time.tv_sec + 1200; /* XXX MAGIC CONSTANT */ if (ifa->ifa_rtrequest) ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); if (ret_nrt) { diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 3341a42c4310..d482a9796ee0 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)rtsock.c 8.3 (Berkeley) 1/4/94 - * $Id: rtsock.c,v 1.5 1994/10/05 20:11:28 wollman Exp $ + * $Id: rtsock.c,v 1.6 1994/10/08 22:38:26 phk Exp $ */ #include @@ -253,6 +253,17 @@ route_output(m, so) case RTM_CHANGE: if (gate && rt_setgate(rt, rt_key(rt), gate)) senderr(EDQUOT); + + /* + * If they tried to change things but didn't specify + * the required gateway, then just use the old one. + * This can happen if the user tries to change the + * flags on the default route without changing the + * default gateway. Changing flags still doesn't work. + */ + if ((rt->rt_flags & RTF_GATEWAY) && !gate) + gate = rt->rt_gateway; + /* new gateway could require new ifaddr, ifp; flags may also be different; ifp may be specified by ll sockaddr when protocol address is ambiguous */ diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 56b1b7cd3880..f568caee540c 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if_ether.c 8.1 (Berkeley) 6/10/93 - * $Id: if_ether.c,v 1.4 1994/10/01 21:50:33 wollman Exp $ + * $Id: if_ether.c,v 1.5 1994/10/02 17:48:36 phk Exp $ */ /* @@ -147,6 +147,16 @@ arp_rtrequest(req, rt, sa) if ((rt->rt_flags & RTF_HOST) == 0 && SIN(rt_mask(rt))->sin_addr.s_addr != 0xffffffff) rt->rt_flags |= RTF_CLONING; +#if 0 + /* + * Actually, all IP gateway routes should have the cloning + * flag turned on. We can't do this yet because the expiration + * stuff isn't working yet. + */ + if (rt->rt_flags & RTF_GATEWAY) { + rt->rt_flags |= RTF_CLONING; + } +#endif if (rt->rt_flags & RTF_CLONING) { /* * Case 1: This route should come from a route to iface. @@ -288,12 +298,13 @@ arprequest(ac, sip, tip, enaddr) * taken over here, either now or for later transmission. */ int -arpresolve(ac, rt, m, dst, desten) +arpresolve(ac, rt, m, dst, desten, rt0) register struct arpcom *ac; register struct rtentry *rt; struct mbuf *m; register struct sockaddr *dst; register u_char *desten; + struct rtentry *rt0; { register struct llinfo_arp *la; struct sockaddr_dl *sdl; diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h index 4ad31397b8da..147bee684488 100644 --- a/sys/netinet/if_ether.h +++ b/sys/netinet/if_ether.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)if_ether.h 8.1 (Berkeley) 6/10/93 - * $Id: if_ether.h,v 1.3 1994/08/18 22:35:27 wollman Exp $ + * $Id: if_ether.h,v 1.4 1994/08/21 05:27:24 paul Exp $ */ #ifndef _NETINET_IF_ETHER_H_ @@ -151,8 +151,8 @@ extern struct llinfo_arp llinfo_arp; /* head of the llinfo queue */ void arpwhohas __P((struct arpcom *, struct in_addr *)); void arpintr __P((void)); -int arpresolve __P((struct arpcom *, - struct rtentry *, struct mbuf *, struct sockaddr *, u_char *)); +int arpresolve __P((struct arpcom *, struct rtentry *, struct mbuf *, + struct sockaddr *, u_char *, struct rtentry *)); void arp_rtrequest __P((int, struct rtentry *, struct sockaddr *)); int ether_addmulti __P((struct ifreq *, struct arpcom *));