diff options
author | wollman <wollman@FreeBSD.org> | 1994-12-01 23:19:48 +0000 |
---|---|---|
committer | wollman <wollman@FreeBSD.org> | 1994-12-01 23:19:48 +0000 |
commit | 098465c84501c5d5bdab230a2818cbfb7f798e46 (patch) | |
tree | c5da0f2ec9698e2a259482bbf9f28ba28c1ca7a8 /sys/netinet/in_rmx.c | |
parent | 1504867da7e0ae79c8e140fa173348cd341befef (diff) | |
download | FreeBSD-src-098465c84501c5d5bdab230a2818cbfb7f798e46.zip FreeBSD-src-098465c84501c5d5bdab230a2818cbfb7f798e46.tar.gz |
Add latest version of ``advanced route metric management'' :-)
As before, this is currently conditionalized on options IN_RMX until
I'm sure it's working.
Diffstat (limited to 'sys/netinet/in_rmx.c')
-rw-r--r-- | sys/netinet/in_rmx.c | 89 |
1 files changed, 71 insertions, 18 deletions
diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c index a1a6a5e..e71f163 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -4,7 +4,7 @@ * You may copy this file verbatim until I find the official * Institute boilerplate. * - * $Id: in_rmx.c,v 1.1 1994/11/02 04:42:14 wollman Exp $ + * $Id: in_rmx.c,v 1.2 1994/11/03 01:05:34 wollman Exp $ */ /* @@ -39,6 +39,7 @@ #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/mbuf.h> +#include <sys/syslog.h> #include <net/if.h> #include <net/route.h> @@ -87,7 +88,12 @@ in_matroute(void *v_arg, struct radix_node_head *head) return rn; } +#if 0 #define RTQ_REALLYOLD 4*60*60 /* four hours is ``really old'' */ +#else +#define RTQ_REALLYOLD 120 /* for testing, make these fire faster */ +#endif +int rtq_reallyold = RTQ_REALLYOLD; /* * On last reference drop, add the route to the queue so that it can be @@ -107,34 +113,81 @@ in_clsroute(struct radix_node *rn, struct radix_node_head *head) return; rt->rt_prflags |= RTPRF_OURS; - rt->rt_rmx.rmx_expire = time.tv_sec + RTQ_REALLYOLD; + rt->rt_rmx.rmx_expire = time.tv_sec + rtq_reallyold; } -/* - * Get rid of everything in the queue, we are short on memory. - * Although this looks like an infinite loop, it really isn't; - * rtrequest() eventually calls in_delroute() which ends up deleting - * the node at the head (or so we hope). This should be called from - * ip_drain(). - */ -void -in_rtqdrain(void) -{ - /* write me! */ - ; -} +#define RTQ_TIMEOUT 60 /* run once a minute */ +int rtq_timeout = RTQ_TIMEOUT; -#define RTQ_TIMEOUT (60*hz) /* run once a minute */ +struct rtqk_arg { + struct radix_node_head *rnh; + int killed; + int found; + time_t nextstop; +}; /* * Get rid of old routes. */ +static int +in_rtqkill(struct radix_node *rn, void *rock) +{ + struct rtqk_arg *ap = rock; + struct radix_node_head *rnh = ap->rnh; + struct rtentry *rt = (struct rtentry *)rn; + int err; + + if(rt->rt_prflags & RTPRF_OURS) { + ap->found++; + + if(rt->rt_rmx.rmx_expire <= time.tv_sec) { + if(rt->rt_refcnt > 0) + panic("rtqkill route really not free\n"); + + err = rtrequest(RTM_DELETE, + (struct sockaddr *)rt_key(rt), + rt->rt_gateway, rt_mask(rt), + rt->rt_flags, 0); + if(err) { + log(LOG_WARNING, "in_rtqkill: error %d", err); + } else { + ap->killed++; + } + } else { + ap->nextstop = lmin(ap->nextstop, + rt->rt_rmx.rmx_expire); + } + } + + return 0; +} + static void in_rtqtimo(void *rock) { - /* write me! */ + struct radix_node_head *rnh = rock; + struct rtqk_arg arg; + static int level; + struct timeval atv; + + level++; + arg.found = arg.killed = 0; + arg.rnh = rnh; + arg.nextstop = time.tv_sec + 10*rtq_timeout; + rnh->rnh_walktree(rnh, in_rtqkill, &arg); + printf("in_rtqtimo: found %d, killed %d, level %d\n", arg.found, + arg.killed, level); + atv.tv_usec = 0; + atv.tv_sec = arg.nextstop; + printf("next timeout in %d seconds\n", arg.nextstop - time.tv_sec); + timeout(in_rtqtimo, rock, hzto(&atv)); + level--; +} - timeout(in_rtqtimo, rock, RTQ_TIMEOUT); +void +in_rtqdrain(void) +{ + ; } /* |