From 265e9f859e0cc457f388796e860ec1c580f16eb2 Mon Sep 17 00:00:00 2001 From: wollman Date: Mon, 23 Jan 1995 02:00:35 +0000 Subject: [PATCH] route.c: keep track of where cloned routes come from, and make sure to delete them when the ``parent'' goes away route.h: add glue to track this to rtentry structure. WARNING WILL ROBINSON! This will be yet another incompatible change in your route-using binaries. I apologize, but this was the only way to do it. I took this opportunity to increase the size of the metrics to what I believe will be the final length for 2.1, so that when the T/TCP stuff is done, this won't happen again. --- sys/net/route.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++--- sys/net/route.h | 16 +++++++++----- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/sys/net/route.c b/sys/net/route.c index 2c36e650f612..0cd589ff8001 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)route.c 8.2 (Berkeley) 11/15/93 - * $Id: route.c,v 1.11 1994/11/03 01:04:30 wollman Exp $ + * $Id: route.c,v 1.13 1994/12/13 23:07:03 wollman Exp $ */ #include @@ -350,6 +350,8 @@ ifa_ifwithroute(flags, dst, gateway) #define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +static void rt_fixfamily(struct rtentry *rt); + int rtrequest(req, dst, gateway, netmask, flags, ret_nrt) int req, flags; @@ -377,6 +379,7 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) panic ("rtrequest delete"); rt = (struct rtentry *)rn; rt->rt_flags &= ~RTF_UP; + rt_fixfamily(rt); if (rt->rt_gwroute) { rt = rt->rt_gwroute; RTFREE(rt); (rt = (struct rtentry *)rn)->rt_gwroute = 0; @@ -443,6 +446,12 @@ 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 ((req == RTM_RESOLVE) + && ((*ret_nrt)->rt_flags & RTF_PRCLONING)) { + rt->rt_parent = (*ret_nrt); + rt->rt_nextchild = (*ret_nrt)->rt_nextchild; + (*ret_nrt)->rt_nextchild = rt; + } if (ifa->ifa_rtrequest) ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0)); if (ret_nrt) { @@ -456,6 +465,50 @@ rtrequest(req, dst, gateway, netmask, flags, ret_nrt) return (error); } +/* + * Called from rtrequest(RTM_DELETE, ...) to fix up the route's ``family'' + * (i.e., the routes related to it by the operation of cloning). This + * involves deleting the entire chain of descendants (in the case of a parent + * route being deleted), or removing this route from the chain (in the case + * of a child route being deleted). + */ +static void +rt_fixfamily(struct rtentry *rt0) +{ + struct rtentry *rt, *lrt, *nrt; + + if(rt = rt0->rt_parent) { + if(rt->rt_flags & RTF_CHAINDELETE) + return; /* relax, it will all be done for us */ + + /* So what if it takes linear time? */ + do { + lrt = rt; + rt = rt->rt_nextchild; + } while(rt && rt != rt0); + lrt->rt_nextchild = rt0->rt_nextchild; + } else if((rt = rt0)->rt_nextchild) { + lrt = rt; + rt->rt_flags |= RTF_CHAINDELETE; + + rt = rt->rt_nextchild; + + while(rt) { + nrt = rt->rt_nextchild; + /* + * There might be some value to open-coding this + * rtrequest call, but I am not yet convinced of + * the value of this. + */ + rtrequest(RTM_DELETE, rt_key(rt), + (struct sockaddr *)0, rt_mask(rt), + rt->rt_flags, (struct rtentry **)0); + rt = nrt; + } + lrt->rt_flags &= ~RTF_CHAINDELETE; + } +} + int rt_setgate(rt0, dst, gate) struct rtentry *rt0; @@ -572,5 +625,4 @@ rtinit(ifa, cmd, flags) } rt_newaddrmsg(cmd, ifa, error, nrt); } - return (error); -} + return (e \ No newline at end of file diff --git a/sys/net/route.h b/sys/net/route.h index 67711137a478..fd6ead9be086 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)route.h 8.3 (Berkeley) 4/19/94 - * $Id: route.h,v 1.5 1994/11/03 01:04:32 wollman Exp $ + * $Id: route.h,v 1.6 1994/12/13 22:31:48 wollman Exp $ */ #ifndef _NET_ROUTE_H_ @@ -69,8 +69,7 @@ struct rt_metrics { u_long rmx_rtt; /* estimated round trip time */ u_long rmx_rttvar; /* estimated rtt variance */ u_long rmx_pksent; /* packets sent using this route */ - u_long rmx_ttcp_cc; /* cached last T/TCP CC option rcvd */ - u_long rmx_ttcp_ccsent; /* cached last T/TCP CC option sent */ + u_long rmx_filler[4]; /* will be used for T/TCP later */ }; /* @@ -107,7 +106,11 @@ struct rtentry { caddr_t rt_llinfo; /* pointer to link level info cache */ struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */ struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */ - int (*rt_output) __P(()); /* output routine for this (rt,if) */ + int (*rt_output) __P((struct rtentry *, struct mbuf *, + struct sockaddr *, int)); + /* output routine for this (rt,if) */ + struct rtentry *rt_parent; /* cloning parent of this route */ + struct rtentry *rt_nextchild; /* next cloned child of this route */ }; /* @@ -145,7 +148,8 @@ struct ortentry { #define RTF_PRCLONING 0x10000 /* protocol requires cloning */ #define RTF_WASCLONED 0x20000 /* route generated through cloning */ #define RTF_PROTO3 0x40000 /* protocol specific routing flag */ - /* 0x80000 and up unassigned */ +#define RTF_CHAINDELETE 0x80000 /* chain is being deleted (internal) */ + /* 0x100000 and up unassigned */ /* * Routing statistics. @@ -175,7 +179,7 @@ struct rt_msghdr { struct rt_metrics rtm_rmx; /* metrics themselves */ }; -#define RTM_VERSION 4 /* Up the ante and ignore older versions */ +#define RTM_VERSION 5 /* Up the ante and ignore older versions */ #define RTM_ADD 0x1 /* Add Route */ #define RTM_DELETE 0x2 /* Delete Route */