149110Sbrian/*	$NetBSD: route.c,v 1.125 2011/03/31 19:40:52 dyoung Exp $	*/
249110Sbrian
349110Sbrian/*-
449110Sbrian * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
549110Sbrian * All rights reserved.
661412Sbrian *
761412Sbrian * This code is derived from software contributed to The NetBSD Foundation
850472Speter * by Kevin M. Lahey of the Numerical Aerospace Simulation Facility,
949110Sbrian * NASA Ames Research Center.
1049110Sbrian *
1149110Sbrian * Redistribution and use in source and binary forms, with or without
1278554Sbrian * modification, are permitted provided that the following conditions
1363509Sbrian * are met:
1449110Sbrian * 1. Redistributions of source code must retain the above copyright
1563509Sbrian *    notice, this list of conditions and the following disclaimer.
16180617Smarcel * 2. Redistributions in binary form must reproduce the above copyright
1749110Sbrian *    notice, this list of conditions and the following disclaimer in the
18180617Smarcel *    documentation and/or other materials provided with the distribution.
1949110Sbrian *
2049110Sbrian * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2161412Sbrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2261412Sbrian * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2372925Sbrian * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2461412Sbrian * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2549110Sbrian * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2649110Sbrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2749110Sbrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2849110Sbrian * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2949110Sbrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3049110Sbrian * POSSIBILITY OF SUCH DAMAGE.
3149110Sbrian */
3249110Sbrian
3349110Sbrian/*
3449110Sbrian * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3578554Sbrian * All rights reserved.
3678554Sbrian *
3778554Sbrian * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 *    notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 *    notice, this list of conditions and the following disclaimer in the
44 *    documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the project nor the names of its contributors
46 *    may be used to endorse or promote products derived from this software
47 *    without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 */
61
62/*
63 * Copyright (c) 1980, 1986, 1991, 1993
64 *	The Regents of the University of California.  All rights reserved.
65 *
66 * Redistribution and use in source and binary forms, with or without
67 * modification, are permitted provided that the following conditions
68 * are met:
69 * 1. Redistributions of source code must retain the above copyright
70 *    notice, this list of conditions and the following disclaimer.
71 * 2. Redistributions in binary form must reproduce the above copyright
72 *    notice, this list of conditions and the following disclaimer in the
73 *    documentation and/or other materials provided with the distribution.
74 * 3. Neither the name of the University nor the names of its contributors
75 *    may be used to endorse or promote products derived from this software
76 *    without specific prior written permission.
77 *
78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88 * SUCH DAMAGE.
89 *
90 *	@(#)route.c	8.3 (Berkeley) 1/9/95
91 */
92
93#include "opt_route.h"
94
95#include <sys/cdefs.h>
96__KERNEL_RCSID(0, "$NetBSD: route.c,v 1.125 2011/03/31 19:40:52 dyoung Exp $");
97
98#include <sys/param.h>
99#include <sys/kmem.h>
100#include <sys/sysctl.h>
101#include <sys/systm.h>
102#include <sys/callout.h>
103#include <sys/proc.h>
104#include <sys/mbuf.h>
105#include <sys/socket.h>
106#include <sys/socketvar.h>
107#include <sys/domain.h>
108#include <sys/protosw.h>
109#include <sys/kernel.h>
110#include <sys/ioctl.h>
111#include <sys/pool.h>
112#include <sys/kauth.h>
113
114#include <net/if.h>
115#include <net/if_dl.h>
116#include <net/route.h>
117#include <net/raw_cb.h>
118
119#include <netinet/in.h>
120#include <netinet/in_var.h>
121
122#ifdef RTFLUSH_DEBUG
123#define	rtcache_debug() __predict_false(_rtcache_debug)
124#else /* RTFLUSH_DEBUG */
125#define	rtcache_debug() 0
126#endif /* RTFLUSH_DEBUG */
127
128struct	rtstat	rtstat;
129
130int	rttrash;		/* routes not in table but not freed */
131
132struct pool rtentry_pool;
133struct pool rttimer_pool;
134
135struct callout rt_timer_ch; /* callout for rt_timer_timer() */
136
137#ifdef RTFLUSH_DEBUG
138static int _rtcache_debug = 0;
139#endif /* RTFLUSH_DEBUG */
140
141static kauth_listener_t route_listener;
142
143static int rtdeletemsg(struct rtentry *);
144static int rtflushclone1(struct rtentry *, void *);
145static void rtflushclone(sa_family_t family, struct rtentry *);
146
147#ifdef RTFLUSH_DEBUG
148static void sysctl_net_rtcache_setup(struct sysctllog **);
149static void
150sysctl_net_rtcache_setup(struct sysctllog **clog)
151{
152	const struct sysctlnode *rnode;
153
154	/* XXX do not duplicate */
155	if (sysctl_createv(clog, 0, NULL, &rnode, CTLFLAG_PERMANENT,
156	    CTLTYPE_NODE, "net", NULL, NULL, 0, NULL, 0, CTL_NET, CTL_EOL) != 0)
157		return;
158	if (sysctl_createv(clog, 0, &rnode, &rnode, CTLFLAG_PERMANENT,
159	    CTLTYPE_NODE,
160	    "rtcache", SYSCTL_DESCR("Route cache related settings"),
161	    NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0)
162		return;
163	if (sysctl_createv(clog, 0, &rnode, &rnode,
164	    CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
165	    "debug", SYSCTL_DESCR("Debug route caches"),
166	    NULL, 0, &_rtcache_debug, 0, CTL_CREATE, CTL_EOL) != 0)
167		return;
168}
169#endif /* RTFLUSH_DEBUG */
170
171struct ifaddr *
172rt_get_ifa(struct rtentry *rt)
173{
174	struct ifaddr *ifa;
175
176	if ((ifa = rt->rt_ifa) == NULL)
177		return ifa;
178	else if (ifa->ifa_getifa == NULL)
179		return ifa;
180#if 0
181	else if (ifa->ifa_seqno != NULL && *ifa->ifa_seqno == rt->rt_ifa_seqno)
182		return ifa;
183#endif
184	else {
185		ifa = (*ifa->ifa_getifa)(ifa, rt_getkey(rt));
186		rt_replace_ifa(rt, ifa);
187		return ifa;
188	}
189}
190
191static void
192rt_set_ifa1(struct rtentry *rt, struct ifaddr *ifa)
193{
194	rt->rt_ifa = ifa;
195	if (ifa->ifa_seqno != NULL)
196		rt->rt_ifa_seqno = *ifa->ifa_seqno;
197}
198
199/*
200 * Is this route the connected route for the ifa?
201 */
202static int
203rt_ifa_connected(const struct rtentry *rt, const struct ifaddr *ifa)
204{
205	const struct sockaddr *key, *dst, *odst;
206	struct sockaddr_storage maskeddst;
207
208	key = rt_getkey(rt);
209	dst = rt->rt_flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
210	if (dst == NULL ||
211	    dst->sa_family != key->sa_family ||
212	    dst->sa_len != key->sa_len)
213		return 0;
214	if ((rt->rt_flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
215		odst = dst;
216		dst = (struct sockaddr *)&maskeddst;
217		rt_maskedcopy(odst, (struct sockaddr *)&maskeddst,
218		    ifa->ifa_netmask);
219	}
220	return (memcmp(dst, key, dst->sa_len) == 0);
221}
222
223void
224rt_replace_ifa(struct rtentry *rt, struct ifaddr *ifa)
225{
226	if (rt->rt_ifa &&
227	    rt->rt_ifa != ifa &&
228	    rt->rt_ifa->ifa_flags & IFA_ROUTE &&
229	    rt_ifa_connected(rt, rt->rt_ifa))
230	{
231		RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
232		    "replace deleted IFA_ROUTE\n",
233		    (void *)rt->_rt_key, (void *)rt->rt_ifa);
234		rt->rt_ifa->ifa_flags &= ~IFA_ROUTE;
235		if (rt_ifa_connected(rt, ifa)) {
236			RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
237			    "replace added IFA_ROUTE\n",
238			    (void *)rt->_rt_key, (void *)ifa);
239			ifa->ifa_flags |= IFA_ROUTE;
240		}
241	}
242
243	IFAREF(ifa);
244	IFAFREE(rt->rt_ifa);
245	rt_set_ifa1(rt, ifa);
246}
247
248static void
249rt_set_ifa(struct rtentry *rt, struct ifaddr *ifa)
250{
251	IFAREF(ifa);
252	rt_set_ifa1(rt, ifa);
253}
254
255static int
256route_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
257    void *arg0, void *arg1, void *arg2, void *arg3)
258{
259	struct rt_msghdr *rtm;
260	int result;
261
262	result = KAUTH_RESULT_DEFER;
263	rtm = arg1;
264
265	if (action != KAUTH_NETWORK_ROUTE)
266		return result;
267
268	if (rtm->rtm_type == RTM_GET)
269		result = KAUTH_RESULT_ALLOW;
270
271	return result;
272}
273
274void
275rt_init(void)
276{
277
278#ifdef RTFLUSH_DEBUG
279	sysctl_net_rtcache_setup(NULL);
280#endif
281
282	pool_init(&rtentry_pool, sizeof(struct rtentry), 0, 0, 0, "rtentpl",
283	    NULL, IPL_SOFTNET);
284	pool_init(&rttimer_pool, sizeof(struct rttimer), 0, 0, 0, "rttmrpl",
285	    NULL, IPL_SOFTNET);
286
287	rn_init();	/* initialize all zeroes, all ones, mask table */
288	rtbl_init();
289
290	route_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
291	    route_listener_cb, NULL);
292}
293
294void
295rtflushall(int family)
296{
297	struct domain *dom;
298
299	if (rtcache_debug())
300		printf("%s: enter\n", __func__);
301
302	if ((dom = pffinddomain(family)) == NULL)
303		return;
304
305	rtcache_invalidate(&dom->dom_rtcache);
306}
307
308void
309rtcache(struct route *ro)
310{
311	struct domain *dom;
312
313	rtcache_invariants(ro);
314	KASSERT(ro->_ro_rt != NULL);
315	KASSERT(ro->ro_invalid == false);
316	KASSERT(rtcache_getdst(ro) != NULL);
317
318	if ((dom = pffinddomain(rtcache_getdst(ro)->sa_family)) == NULL)
319		return;
320
321	LIST_INSERT_HEAD(&dom->dom_rtcache, ro, ro_rtcache_next);
322	rtcache_invariants(ro);
323}
324
325/*
326 * Packet routing routines.
327 */
328struct rtentry *
329rtalloc1(const struct sockaddr *dst, int report)
330{
331	rtbl_t *rtbl = rt_gettable(dst->sa_family);
332	struct rtentry *rt;
333	struct rtentry *newrt = NULL;
334	struct rt_addrinfo info;
335	int  s = splsoftnet(), err = 0, msgtype = RTM_MISS;
336
337	if (rtbl != NULL && (rt = rt_matchaddr(rtbl, dst)) != NULL) {
338		newrt = rt;
339		if (report && (rt->rt_flags & RTF_CLONING)) {
340			err = rtrequest(RTM_RESOLVE, dst, NULL, NULL, 0,
341			    &newrt);
342			if (err) {
343				newrt = rt;
344				rt->rt_refcnt++;
345				goto miss;
346			}
347			KASSERT(newrt != NULL);
348			if ((rt = newrt) && (rt->rt_flags & RTF_XRESOLVE)) {
349				msgtype = RTM_RESOLVE;
350				goto miss;
351			}
352			/* Inform listeners of the new route */
353			memset(&info, 0, sizeof(info));
354			info.rti_info[RTAX_DST] = rt_getkey(rt);
355			info.rti_info[RTAX_NETMASK] = rt_mask(rt);
356			info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
357			if (rt->rt_ifp != NULL) {
358				info.rti_info[RTAX_IFP] =
359				    rt->rt_ifp->if_dl->ifa_addr;
360				info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
361			}
362			rt_missmsg(RTM_ADD, &info, rt->rt_flags, 0);
363		} else
364			rt->rt_refcnt++;
365	} else {
366		rtstat.rts_unreach++;
367	miss:	if (report) {
368			memset((void *)&info, 0, sizeof(info));
369			info.rti_info[RTAX_DST] = dst;
370			rt_missmsg(msgtype, &info, 0, err);
371		}
372	}
373	splx(s);
374	return newrt;
375}
376
377void
378rtfree(struct rtentry *rt)
379{
380	struct ifaddr *ifa;
381
382	if (rt == NULL)
383		panic("rtfree");
384	rt->rt_refcnt--;
385	if (rt->rt_refcnt <= 0 && (rt->rt_flags & RTF_UP) == 0) {
386		rt_assert_inactive(rt);
387		rttrash--;
388		if (rt->rt_refcnt < 0) {
389			printf("rtfree: %p not freed (neg refs)\n", rt);
390			return;
391		}
392		rt_timer_remove_all(rt, 0);
393		ifa = rt->rt_ifa;
394		rt->rt_ifa = NULL;
395		IFAFREE(ifa);
396		rt->rt_ifp = NULL;
397		rt_destroy(rt);
398		pool_put(&rtentry_pool, rt);
399	}
400}
401
402void
403ifafree(struct ifaddr *ifa)
404{
405
406#ifdef DIAGNOSTIC
407	if (ifa == NULL)
408		panic("ifafree: null ifa");
409	if (ifa->ifa_refcnt != 0)
410		panic("ifafree: ifa_refcnt != 0 (%d)", ifa->ifa_refcnt);
411#endif
412#ifdef IFAREF_DEBUG
413	printf("ifafree: freeing ifaddr %p\n", ifa);
414#endif
415	free(ifa, M_IFADDR);
416}
417
418/*
419 * Force a routing table entry to the specified
420 * destination to go through the given gateway.
421 * Normally called as a result of a routing redirect
422 * message from the network layer.
423 *
424 * N.B.: must be called at splsoftnet
425 */
426void
427rtredirect(const struct sockaddr *dst, const struct sockaddr *gateway,
428	const struct sockaddr *netmask, int flags, const struct sockaddr *src,
429	struct rtentry **rtp)
430{
431	struct rtentry *rt;
432	int error = 0;
433	uint64_t *stat = NULL;
434	struct rt_addrinfo info;
435	struct ifaddr *ifa;
436
437	/* verify the gateway is directly reachable */
438	if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
439		error = ENETUNREACH;
440		goto out;
441	}
442	rt = rtalloc1(dst, 0);
443	/*
444	 * If the redirect isn't from our current router for this dst,
445	 * it's either old or wrong.  If it redirects us to ourselves,
446	 * we have a routing loop, perhaps as a result of an interface
447	 * going down recently.
448	 */
449	if (!(flags & RTF_DONE) && rt &&
450	     (sockaddr_cmp(src, rt->rt_gateway) != 0 || rt->rt_ifa != ifa))
451		error = EINVAL;
452	else if (ifa_ifwithaddr(gateway))
453		error = EHOSTUNREACH;
454	if (error)
455		goto done;
456	/*
457	 * Create a new entry if we just got back a wildcard entry
458	 * or the lookup failed.  This is necessary for hosts
459	 * which use routing redirects generated by smart gateways
460	 * to dynamically build the routing tables.
461	 */
462	if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
463		goto create;
464	/*
465	 * Don't listen to the redirect if it's
466	 * for a route to an interface.
467	 */
468	if (rt->rt_flags & RTF_GATEWAY) {
469		if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
470			/*
471			 * Changing from route to net => route to host.
472			 * Create new route, rather than smashing route to net.
473			 */
474		create:
475			if (rt != NULL)
476				rtfree(rt);
477			flags |=  RTF_GATEWAY | RTF_DYNAMIC;
478			memset(&info, 0, sizeof(info));
479			info.rti_info[RTAX_DST] = dst;
480			info.rti_info[RTAX_GATEWAY] = gateway;
481			info.rti_info[RTAX_NETMASK] = netmask;
482			info.rti_ifa = ifa;
483			info.rti_flags = flags;
484			rt = NULL;
485			error = rtrequest1(RTM_ADD, &info, &rt);
486			if (rt != NULL)
487				flags = rt->rt_flags;
488			stat = &rtstat.rts_dynamic;
489		} else {
490			/*
491			 * Smash the current notion of the gateway to
492			 * this destination.  Should check about netmask!!!
493			 */
494			rt->rt_flags |= RTF_MODIFIED;
495			flags |= RTF_MODIFIED;
496			stat = &rtstat.rts_newgateway;
497			rt_setgate(rt, gateway);
498		}
499	} else
500		error = EHOSTUNREACH;
501done:
502	if (rt) {
503		if (rtp != NULL && !error)
504			*rtp = rt;
505		else
506			rtfree(rt);
507	}
508out:
509	if (error)
510		rtstat.rts_badredirect++;
511	else if (stat != NULL)
512		(*stat)++;
513	memset(&info, 0, sizeof(info));
514	info.rti_info[RTAX_DST] = dst;
515	info.rti_info[RTAX_GATEWAY] = gateway;
516	info.rti_info[RTAX_NETMASK] = netmask;
517	info.rti_info[RTAX_AUTHOR] = src;
518	rt_missmsg(RTM_REDIRECT, &info, flags, error);
519}
520
521/*
522 * Delete a route and generate a message
523 */
524static int
525rtdeletemsg(struct rtentry *rt)
526{
527	int error;
528	struct rt_addrinfo info;
529
530	/*
531	 * Request the new route so that the entry is not actually
532	 * deleted.  That will allow the information being reported to
533	 * be accurate (and consistent with route_output()).
534	 */
535	memset(&info, 0, sizeof(info));
536	info.rti_info[RTAX_DST] = rt_getkey(rt);
537	info.rti_info[RTAX_NETMASK] = rt_mask(rt);
538	info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
539	info.rti_flags = rt->rt_flags;
540	error = rtrequest1(RTM_DELETE, &info, &rt);
541
542	rt_missmsg(RTM_DELETE, &info, info.rti_flags, error);
543
544	/* Adjust the refcount */
545	if (error == 0 && rt->rt_refcnt <= 0) {
546		rt->rt_refcnt++;
547		rtfree(rt);
548	}
549	return error;
550}
551
552static int
553rtflushclone1(struct rtentry *rt, void *arg)
554{
555	struct rtentry *parent;
556
557	parent = (struct rtentry *)arg;
558	if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent == parent)
559		rtdeletemsg(rt);
560	return 0;
561}
562
563static void
564rtflushclone(sa_family_t family, struct rtentry *parent)
565{
566
567#ifdef DIAGNOSTIC
568	if (!parent || (parent->rt_flags & RTF_CLONING) == 0)
569		panic("rtflushclone: called with a non-cloning route");
570#endif
571	rt_walktree(family, rtflushclone1, (void *)parent);
572}
573
574/*
575 * Routing table ioctl interface.
576 */
577int
578rtioctl(u_long req, void *data, struct lwp *l)
579{
580	return EOPNOTSUPP;
581}
582
583struct ifaddr *
584ifa_ifwithroute(int flags, const struct sockaddr *dst,
585	const struct sockaddr *gateway)
586{
587	struct ifaddr *ifa;
588	if ((flags & RTF_GATEWAY) == 0) {
589		/*
590		 * If we are adding a route to an interface,
591		 * and the interface is a pt to pt link
592		 * we should search for the destination
593		 * as our clue to the interface.  Otherwise
594		 * we can use the local address.
595		 */
596		ifa = NULL;
597		if (flags & RTF_HOST)
598			ifa = ifa_ifwithdstaddr(dst);
599		if (ifa == NULL)
600			ifa = ifa_ifwithaddr(gateway);
601	} else {
602		/*
603		 * If we are adding a route to a remote net
604		 * or host, the gateway may still be on the
605		 * other end of a pt to pt link.
606		 */
607		ifa = ifa_ifwithdstaddr(gateway);
608	}
609	if (ifa == NULL)
610		ifa = ifa_ifwithnet(gateway);
611	if (ifa == NULL) {
612		struct rtentry *rt = rtalloc1(dst, 0);
613		if (rt == NULL)
614			return NULL;
615		rt->rt_refcnt--;
616		if ((ifa = rt->rt_ifa) == NULL)
617			return NULL;
618	}
619	if (ifa->ifa_addr->sa_family != dst->sa_family) {
620		struct ifaddr *oifa = ifa;
621		ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
622		if (ifa == 0)
623			ifa = oifa;
624	}
625	return ifa;
626}
627
628int
629rtrequest(int req, const struct sockaddr *dst, const struct sockaddr *gateway,
630	const struct sockaddr *netmask, int flags, struct rtentry **ret_nrt)
631{
632	struct rt_addrinfo info;
633
634	memset(&info, 0, sizeof(info));
635	info.rti_flags = flags;
636	info.rti_info[RTAX_DST] = dst;
637	info.rti_info[RTAX_GATEWAY] = gateway;
638	info.rti_info[RTAX_NETMASK] = netmask;
639	return rtrequest1(req, &info, ret_nrt);
640}
641
642int
643rt_getifa(struct rt_addrinfo *info)
644{
645	struct ifaddr *ifa;
646	const struct sockaddr *dst = info->rti_info[RTAX_DST];
647	const struct sockaddr *gateway = info->rti_info[RTAX_GATEWAY];
648	const struct sockaddr *ifaaddr = info->rti_info[RTAX_IFA];
649	const struct sockaddr *ifpaddr = info->rti_info[RTAX_IFP];
650	int flags = info->rti_flags;
651
652	/*
653	 * ifp may be specified by sockaddr_dl when protocol address
654	 * is ambiguous
655	 */
656	if (info->rti_ifp == NULL && ifpaddr != NULL
657	    && ifpaddr->sa_family == AF_LINK &&
658	    (ifa = ifa_ifwithnet(ifpaddr)) != NULL)
659		info->rti_ifp = ifa->ifa_ifp;
660	if (info->rti_ifa == NULL && ifaaddr != NULL)
661		info->rti_ifa = ifa_ifwithaddr(ifaaddr);
662	if (info->rti_ifa == NULL) {
663		const struct sockaddr *sa;
664
665		sa = ifaaddr != NULL ? ifaaddr :
666		    (gateway != NULL ? gateway : dst);
667		if (sa != NULL && info->rti_ifp != NULL)
668			info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp);
669		else if (dst != NULL && gateway != NULL)
670			info->rti_ifa = ifa_ifwithroute(flags, dst, gateway);
671		else if (sa != NULL)
672			info->rti_ifa = ifa_ifwithroute(flags, sa, sa);
673	}
674	if ((ifa = info->rti_ifa) == NULL)
675		return ENETUNREACH;
676	if (ifa->ifa_getifa != NULL)
677		info->rti_ifa = ifa = (*ifa->ifa_getifa)(ifa, dst);
678	if (info->rti_ifp == NULL)
679		info->rti_ifp = ifa->ifa_ifp;
680	return 0;
681}
682
683int
684rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt)
685{
686	int s = splsoftnet();
687	int error = 0, rc;
688	struct rtentry *rt, *crt;
689	rtbl_t *rtbl;
690	struct ifaddr *ifa, *ifa2;
691	struct sockaddr_storage maskeddst;
692	const struct sockaddr *dst = info->rti_info[RTAX_DST];
693	const struct sockaddr *gateway = info->rti_info[RTAX_GATEWAY];
694	const struct sockaddr *netmask = info->rti_info[RTAX_NETMASK];
695	int flags = info->rti_flags;
696#define senderr(x) { error = x ; goto bad; }
697
698	if ((rtbl = rt_gettable(dst->sa_family)) == NULL)
699		senderr(ESRCH);
700	if (flags & RTF_HOST)
701		netmask = NULL;
702	switch (req) {
703	case RTM_DELETE:
704		if (netmask) {
705			rt_maskedcopy(dst, (struct sockaddr *)&maskeddst,
706			    netmask);
707			dst = (struct sockaddr *)&maskeddst;
708		}
709		if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)
710			senderr(ESRCH);
711		if ((rt->rt_flags & RTF_CLONING) != 0) {
712			/* clean up any cloned children */
713			rtflushclone(dst->sa_family, rt);
714		}
715		if ((rt = rt_deladdr(rtbl, dst, netmask)) == NULL)
716			senderr(ESRCH);
717		if (rt->rt_gwroute) {
718			RTFREE(rt->rt_gwroute);
719			rt->rt_gwroute = NULL;
720		}
721		if (rt->rt_parent) {
722			rt->rt_parent->rt_refcnt--;
723			rt->rt_parent = NULL;
724		}
725		rt->rt_flags &= ~RTF_UP;
726		if ((ifa = rt->rt_ifa)) {
727			if (ifa->ifa_flags & IFA_ROUTE &&
728			    rt_ifa_connected(rt, ifa)) {
729				RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
730				    "deleted IFA_ROUTE\n",
731				    (void *)rt->_rt_key, (void *)ifa);
732				ifa->ifa_flags &= ~IFA_ROUTE;
733			}
734			if (ifa->ifa_rtrequest)
735				ifa->ifa_rtrequest(RTM_DELETE, rt, info);
736		}
737		rttrash++;
738		if (ret_nrt)
739			*ret_nrt = rt;
740		else if (rt->rt_refcnt <= 0) {
741			rt->rt_refcnt++;
742			rtfree(rt);
743		}
744		break;
745
746	case RTM_RESOLVE:
747		if (ret_nrt == NULL || (rt = *ret_nrt) == NULL)
748			senderr(EINVAL);
749		if ((rt->rt_flags & RTF_CLONING) == 0)
750			senderr(EINVAL);
751		ifa = rt->rt_ifa;
752		flags = rt->rt_flags & ~(RTF_CLONING | RTF_STATIC);
753		flags |= RTF_CLONED;
754		gateway = rt->rt_gateway;
755		flags |= RTF_HOST;
756		goto makeroute;
757
758	case RTM_ADD:
759		if (info->rti_ifa == NULL && (error = rt_getifa(info)))
760			senderr(error);
761		ifa = info->rti_ifa;
762	makeroute:
763		/* Already at splsoftnet() so pool_get/pool_put are safe */
764		rt = pool_get(&rtentry_pool, PR_NOWAIT);
765		if (rt == NULL)
766			senderr(ENOBUFS);
767		memset(rt, 0, sizeof(*rt));
768		rt->rt_flags = RTF_UP | flags;
769		LIST_INIT(&rt->rt_timer);
770		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
771		if (rt_setkey(rt, dst, M_NOWAIT) == NULL ||
772		    rt_setgate(rt, gateway) != 0) {
773			pool_put(&rtentry_pool, rt);
774			senderr(ENOBUFS);
775		}
776		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
777		if (netmask) {
778			rt_maskedcopy(dst, (struct sockaddr *)&maskeddst,
779			    netmask);
780			rt_setkey(rt, (struct sockaddr *)&maskeddst, M_NOWAIT);
781			RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
782		} else {
783			rt_setkey(rt, dst, M_NOWAIT);
784			RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
785		}
786		rt_set_ifa(rt, ifa);
787		if (info->rti_info[RTAX_TAG] != NULL)
788			rt_settag(rt, info->rti_info[RTAX_TAG]);
789		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
790		if (info->rti_info[RTAX_IFP] != NULL &&
791		    (ifa2 = ifa_ifwithnet(info->rti_info[RTAX_IFP])) != NULL &&
792		    ifa2->ifa_ifp != NULL)
793			rt->rt_ifp = ifa2->ifa_ifp;
794		else
795			rt->rt_ifp = ifa->ifa_ifp;
796		if (req == RTM_RESOLVE) {
797			rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */
798			rt->rt_parent = *ret_nrt;
799			rt->rt_parent->rt_refcnt++;
800		}
801		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
802		rc = rt_addaddr(rtbl, rt, netmask);
803		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
804		if (rc != 0 && (crt = rtalloc1(rt_getkey(rt), 0)) != NULL) {
805			/* overwrite cloned route */
806			if ((crt->rt_flags & RTF_CLONED) != 0) {
807				rtdeletemsg(crt);
808				rc = rt_addaddr(rtbl, rt, netmask);
809			}
810			RTFREE(crt);
811			RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
812		}
813		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
814		if (rc != 0) {
815			IFAFREE(ifa);
816			if ((rt->rt_flags & RTF_CLONED) != 0 && rt->rt_parent)
817				rtfree(rt->rt_parent);
818			if (rt->rt_gwroute)
819				rtfree(rt->rt_gwroute);
820			rt_destroy(rt);
821			pool_put(&rtentry_pool, rt);
822			senderr(rc);
823		}
824		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
825		if (ifa->ifa_rtrequest)
826			ifa->ifa_rtrequest(req, rt, info);
827		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
828		if (ret_nrt) {
829			*ret_nrt = rt;
830			rt->rt_refcnt++;
831		}
832		if ((rt->rt_flags & RTF_CLONING) != 0) {
833			/* clean up any cloned children */
834			rtflushclone(dst->sa_family, rt);
835		}
836		rtflushall(dst->sa_family);
837		break;
838	case RTM_GET:
839		if (netmask != NULL) {
840			rt_maskedcopy(dst, (struct sockaddr *)&maskeddst,
841			    netmask);
842			dst = (struct sockaddr *)&maskeddst;
843		}
844		if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)
845			senderr(ESRCH);
846		if (ret_nrt != NULL) {
847			*ret_nrt = rt;
848			rt->rt_refcnt++;
849		}
850		break;
851	}
852bad:
853	splx(s);
854	return error;
855}
856
857int
858rt_setgate(struct rtentry *rt, const struct sockaddr *gate)
859{
860	KASSERT(rt != rt->rt_gwroute);
861
862	KASSERT(rt->_rt_key != NULL);
863	RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
864
865	if (rt->rt_gwroute) {
866		RTFREE(rt->rt_gwroute);
867		rt->rt_gwroute = NULL;
868	}
869	KASSERT(rt->_rt_key != NULL);
870	RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
871	if (rt->rt_gateway != NULL)
872		sockaddr_free(rt->rt_gateway);
873	KASSERT(rt->_rt_key != NULL);
874	RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
875	if ((rt->rt_gateway = sockaddr_dup(gate, M_NOWAIT)) == NULL)
876		return ENOMEM;
877	KASSERT(rt->_rt_key != NULL);
878	RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
879
880	if (rt->rt_flags & RTF_GATEWAY) {
881		KASSERT(rt->_rt_key != NULL);
882		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
883		rt->rt_gwroute = rtalloc1(gate, 1);
884		/*
885		 * If we switched gateways, grab the MTU from the new
886		 * gateway route if the current MTU, if the current MTU is
887		 * greater than the MTU of gateway.
888		 * Note that, if the MTU of gateway is 0, we will reset the
889		 * MTU of the route to run PMTUD again from scratch. XXX
890		 */
891		KASSERT(rt->_rt_key != NULL);
892		RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
893		if (rt->rt_gwroute
894		    && !(rt->rt_rmx.rmx_locks & RTV_MTU)
895		    && rt->rt_rmx.rmx_mtu
896		    && rt->rt_rmx.rmx_mtu > rt->rt_gwroute->rt_rmx.rmx_mtu) {
897			rt->rt_rmx.rmx_mtu = rt->rt_gwroute->rt_rmx.rmx_mtu;
898		}
899	}
900	KASSERT(rt->_rt_key != NULL);
901	RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
902	return 0;
903}
904
905void
906rt_maskedcopy(const struct sockaddr *src, struct sockaddr *dst,
907	const struct sockaddr *netmask)
908{
909	const char *netmaskp = &netmask->sa_data[0],
910	           *srcp = &src->sa_data[0];
911	char *dstp = &dst->sa_data[0];
912	const char *maskend = (char *)dst + MIN(netmask->sa_len, src->sa_len);
913	const char *srcend = (char *)dst + src->sa_len;
914
915	dst->sa_len = src->sa_len;
916	dst->sa_family = src->sa_family;
917
918	while (dstp < maskend)
919		*dstp++ = *srcp++ & *netmaskp++;
920	if (dstp < srcend)
921		memset(dstp, 0, (size_t)(srcend - dstp));
922}
923
924/*
925 * Set up or tear down a routing table entry, normally
926 * for an interface.
927 */
928int
929rtinit(struct ifaddr *ifa, int cmd, int flags)
930{
931	struct rtentry *rt;
932	struct sockaddr *dst, *odst;
933	struct sockaddr_storage maskeddst;
934	struct rtentry *nrt = NULL;
935	int error;
936	struct rt_addrinfo info;
937	struct sockaddr_dl *sdl;
938	const struct sockaddr_dl *ifsdl;
939
940	dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
941	if (cmd == RTM_DELETE) {
942		if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
943			/* Delete subnet route for this interface */
944			odst = dst;
945			dst = (struct sockaddr *)&maskeddst;
946			rt_maskedcopy(odst, dst, ifa->ifa_netmask);
947		}
948		if ((rt = rtalloc1(dst, 0)) != NULL) {
949			rt->rt_refcnt--;
950			if (rt->rt_ifa != ifa)
951				return (flags & RTF_HOST) ? EHOSTUNREACH
952							: ENETUNREACH;
953		}
954	}
955	memset(&info, 0, sizeof(info));
956	info.rti_ifa = ifa;
957	info.rti_flags = flags | ifa->ifa_flags;
958	info.rti_info[RTAX_DST] = dst;
959	info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
960	/*
961	 * XXX here, it seems that we are assuming that ifa_netmask is NULL
962	 * for RTF_HOST.  bsdi4 passes NULL explicitly (via intermediate
963	 * variable) when RTF_HOST is 1.  still not sure if i can safely
964	 * change it to meet bsdi4 behavior.
965	 */
966	if (cmd != RTM_LLINFO_UPD)
967		info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
968	error = rtrequest1((cmd == RTM_LLINFO_UPD) ? RTM_GET : cmd, &info,
969	    &nrt);
970	if (error != 0 || (rt = nrt) == NULL)
971		;
972	else switch (cmd) {
973	case RTM_DELETE:
974		rt_newaddrmsg(cmd, ifa, error, nrt);
975		if (rt->rt_refcnt <= 0) {
976			rt->rt_refcnt++;
977			rtfree(rt);
978		}
979		break;
980	case RTM_LLINFO_UPD:
981		rt->rt_refcnt--;
982		RT_DPRINTF("%s: updating%s\n", __func__,
983		    ((rt->rt_flags & RTF_LLINFO) == 0) ? " (no llinfo)" : "");
984
985		ifsdl = ifa->ifa_ifp->if_sadl;
986
987		if ((rt->rt_flags & RTF_LLINFO) != 0 &&
988		    (sdl = satosdl(rt->rt_gateway)) != NULL &&
989		    sdl->sdl_family == AF_LINK &&
990		    sockaddr_dl_setaddr(sdl, sdl->sdl_len, CLLADDR(ifsdl),
991		                        ifa->ifa_ifp->if_addrlen) == NULL) {
992			error = EINVAL;
993			break;
994		}
995
996		if (cmd == RTM_LLINFO_UPD && ifa->ifa_rtrequest != NULL)
997			ifa->ifa_rtrequest(RTM_LLINFO_UPD, rt, &info);
998		rt_newaddrmsg(RTM_CHANGE, ifa, error, nrt);
999		break;
1000	case RTM_ADD:
1001		rt->rt_refcnt--;
1002		if (rt->rt_ifa != ifa) {
1003			printf("rtinit: wrong ifa (%p) was (%p)\n", ifa,
1004				rt->rt_ifa);
1005			if (rt->rt_ifa->ifa_rtrequest != NULL) {
1006				rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt,
1007				    &info);
1008			}
1009			rt_replace_ifa(rt, ifa);
1010			rt->rt_ifp = ifa->ifa_ifp;
1011			if (ifa->ifa_rtrequest != NULL)
1012				ifa->ifa_rtrequest(RTM_ADD, rt, &info);
1013		}
1014		rt_newaddrmsg(cmd, ifa, error, nrt);
1015		break;
1016	}
1017	return error;
1018}
1019
1020/*
1021 * Route timer routines.  These routes allow functions to be called
1022 * for various routes at any time.  This is useful in supporting
1023 * path MTU discovery and redirect route deletion.
1024 *
1025 * This is similar to some BSDI internal functions, but it provides
1026 * for multiple queues for efficiency's sake...
1027 */
1028
1029LIST_HEAD(, rttimer_queue) rttimer_queue_head;
1030static int rt_init_done = 0;
1031
1032#define RTTIMER_CALLOUT(r)	do {					\
1033		if (r->rtt_func != NULL) {				\
1034			(*r->rtt_func)(r->rtt_rt, r);			\
1035		} else {						\
1036			rtrequest((int) RTM_DELETE,			\
1037				  rt_getkey(r->rtt_rt),			\
1038				  0, 0, 0, 0);				\
1039		}							\
1040	} while (/*CONSTCOND*/0)
1041
1042/*
1043 * Some subtle order problems with domain initialization mean that
1044 * we cannot count on this being run from rt_init before various
1045 * protocol initializations are done.  Therefore, we make sure
1046 * that this is run when the first queue is added...
1047 */
1048
1049void
1050rt_timer_init(void)
1051{
1052	assert(rt_init_done == 0);
1053
1054	LIST_INIT(&rttimer_queue_head);
1055	callout_init(&rt_timer_ch, 0);
1056	callout_reset(&rt_timer_ch, hz, rt_timer_timer, NULL);
1057	rt_init_done = 1;
1058}
1059
1060struct rttimer_queue *
1061rt_timer_queue_create(u_int timeout)
1062{
1063	struct rttimer_queue *rtq;
1064
1065	if (rt_init_done == 0)
1066		rt_timer_init();
1067
1068	R_Malloc(rtq, struct rttimer_queue *, sizeof *rtq);
1069	if (rtq == NULL)
1070		return NULL;
1071	memset(rtq, 0, sizeof(*rtq));
1072
1073	rtq->rtq_timeout = timeout;
1074	TAILQ_INIT(&rtq->rtq_head);
1075	LIST_INSERT_HEAD(&rttimer_queue_head, rtq, rtq_link);
1076
1077	return rtq;
1078}
1079
1080void
1081rt_timer_queue_change(struct rttimer_queue *rtq, long timeout)
1082{
1083
1084	rtq->rtq_timeout = timeout;
1085}
1086
1087void
1088rt_timer_queue_remove_all(struct rttimer_queue *rtq, int destroy)
1089{
1090	struct rttimer *r;
1091
1092	while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL) {
1093		LIST_REMOVE(r, rtt_link);
1094		TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
1095		if (destroy)
1096			RTTIMER_CALLOUT(r);
1097		/* we are already at splsoftnet */
1098		pool_put(&rttimer_pool, r);
1099		if (rtq->rtq_count > 0)
1100			rtq->rtq_count--;
1101		else
1102			printf("rt_timer_queue_remove_all: "
1103			    "rtq_count reached 0\n");
1104	}
1105}
1106
1107void
1108rt_timer_queue_destroy(struct rttimer_queue *rtq, int destroy)
1109{
1110
1111	rt_timer_queue_remove_all(rtq, destroy);
1112
1113	LIST_REMOVE(rtq, rtq_link);
1114
1115	/*
1116	 * Caller is responsible for freeing the rttimer_queue structure.
1117	 */
1118}
1119
1120unsigned long
1121rt_timer_count(struct rttimer_queue *rtq)
1122{
1123	return rtq->rtq_count;
1124}
1125
1126void
1127rt_timer_remove_all(struct rtentry *rt, int destroy)
1128{
1129	struct rttimer *r;
1130
1131	while ((r = LIST_FIRST(&rt->rt_timer)) != NULL) {
1132		LIST_REMOVE(r, rtt_link);
1133		TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
1134		if (destroy)
1135			RTTIMER_CALLOUT(r);
1136		if (r->rtt_queue->rtq_count > 0)
1137			r->rtt_queue->rtq_count--;
1138		else
1139			printf("rt_timer_remove_all: rtq_count reached 0\n");
1140		/* we are already at splsoftnet */
1141		pool_put(&rttimer_pool, r);
1142	}
1143}
1144
1145int
1146rt_timer_add(struct rtentry *rt,
1147	void (*func)(struct rtentry *, struct rttimer *),
1148	struct rttimer_queue *queue)
1149{
1150	struct rttimer *r;
1151	int s;
1152
1153	/*
1154	 * If there's already a timer with this action, destroy it before
1155	 * we add a new one.
1156	 */
1157	LIST_FOREACH(r, &rt->rt_timer, rtt_link) {
1158		if (r->rtt_func == func)
1159			break;
1160	}
1161	if (r != NULL) {
1162		LIST_REMOVE(r, rtt_link);
1163		TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
1164		if (r->rtt_queue->rtq_count > 0)
1165			r->rtt_queue->rtq_count--;
1166		else
1167			printf("rt_timer_add: rtq_count reached 0\n");
1168	} else {
1169		s = splsoftnet();
1170		r = pool_get(&rttimer_pool, PR_NOWAIT);
1171		splx(s);
1172		if (r == NULL)
1173			return ENOBUFS;
1174	}
1175
1176	memset(r, 0, sizeof(*r));
1177
1178	r->rtt_rt = rt;
1179	r->rtt_time = time_uptime;
1180	r->rtt_func = func;
1181	r->rtt_queue = queue;
1182	LIST_INSERT_HEAD(&rt->rt_timer, r, rtt_link);
1183	TAILQ_INSERT_TAIL(&queue->rtq_head, r, rtt_next);
1184	r->rtt_queue->rtq_count++;
1185
1186	return 0;
1187}
1188
1189/* ARGSUSED */
1190void
1191rt_timer_timer(void *arg)
1192{
1193	struct rttimer_queue *rtq;
1194	struct rttimer *r;
1195	int s;
1196
1197	s = splsoftnet();
1198	LIST_FOREACH(rtq, &rttimer_queue_head, rtq_link) {
1199		while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL &&
1200		    (r->rtt_time + rtq->rtq_timeout) < time_uptime) {
1201			LIST_REMOVE(r, rtt_link);
1202			TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
1203			RTTIMER_CALLOUT(r);
1204			pool_put(&rttimer_pool, r);
1205			if (rtq->rtq_count > 0)
1206				rtq->rtq_count--;
1207			else
1208				printf("rt_timer_timer: rtq_count reached 0\n");
1209		}
1210	}
1211	splx(s);
1212
1213	callout_reset(&rt_timer_ch, hz, rt_timer_timer, NULL);
1214}
1215
1216static struct rtentry *
1217_rtcache_init(struct route *ro, int flag)
1218{
1219	rtcache_invariants(ro);
1220	KASSERT(ro->_ro_rt == NULL);
1221
1222	if (rtcache_getdst(ro) == NULL)
1223		return NULL;
1224	ro->ro_invalid = false;
1225	if ((ro->_ro_rt = rtalloc1(rtcache_getdst(ro), flag)) != NULL)
1226		rtcache(ro);
1227
1228	rtcache_invariants(ro);
1229	return ro->_ro_rt;
1230}
1231
1232struct rtentry *
1233rtcache_init(struct route *ro)
1234{
1235	return _rtcache_init(ro, 1);
1236}
1237
1238struct rtentry *
1239rtcache_init_noclone(struct route *ro)
1240{
1241	return _rtcache_init(ro, 0);
1242}
1243
1244struct rtentry *
1245rtcache_update(struct route *ro, int clone)
1246{
1247	rtcache_clear(ro);
1248	return _rtcache_init(ro, clone);
1249}
1250
1251void
1252rtcache_copy(struct route *new_ro, const struct route *old_ro)
1253{
1254	struct rtentry *rt;
1255
1256	KASSERT(new_ro != old_ro);
1257	rtcache_invariants(new_ro);
1258	rtcache_invariants(old_ro);
1259
1260	if ((rt = rtcache_validate(old_ro)) != NULL)
1261		rt->rt_refcnt++;
1262
1263	if (rtcache_getdst(old_ro) == NULL ||
1264	    rtcache_setdst(new_ro, rtcache_getdst(old_ro)) != 0)
1265		return;
1266
1267	new_ro->ro_invalid = false;
1268	if ((new_ro->_ro_rt = rt) != NULL)
1269		rtcache(new_ro);
1270	rtcache_invariants(new_ro);
1271}
1272
1273static struct dom_rtlist invalid_routes = LIST_HEAD_INITIALIZER(dom_rtlist);
1274
1275void
1276rtcache_invalidate(struct dom_rtlist *rtlist)
1277{
1278	struct route *ro;
1279
1280	while ((ro = LIST_FIRST(rtlist)) != NULL) {
1281		rtcache_invariants(ro);
1282		KASSERT(ro->_ro_rt != NULL);
1283		ro->ro_invalid = true;
1284		LIST_REMOVE(ro, ro_rtcache_next);
1285		LIST_INSERT_HEAD(&invalid_routes, ro, ro_rtcache_next);
1286		rtcache_invariants(ro);
1287	}
1288}
1289
1290void
1291rtcache_clear(struct route *ro)
1292{
1293	rtcache_invariants(ro);
1294	if (ro->_ro_rt == NULL)
1295		return;
1296
1297	LIST_REMOVE(ro, ro_rtcache_next);
1298
1299	RTFREE(ro->_ro_rt);
1300	ro->_ro_rt = NULL;
1301	ro->ro_invalid = false;
1302	rtcache_invariants(ro);
1303}
1304
1305struct rtentry *
1306rtcache_lookup2(struct route *ro, const struct sockaddr *dst, int clone,
1307    int *hitp)
1308{
1309	const struct sockaddr *odst;
1310	struct rtentry *rt = NULL;
1311
1312	rtcache_invariants(ro);
1313
1314	odst = rtcache_getdst(ro);
1315
1316	if (odst == NULL)
1317		;
1318	else if (sockaddr_cmp(odst, dst) != 0)
1319		rtcache_free(ro);
1320	else if ((rt = rtcache_validate(ro)) == NULL)
1321		rtcache_clear(ro);
1322
1323	if (rt == NULL) {
1324		*hitp = 0;
1325		if (rtcache_setdst(ro, dst) == 0)
1326			rt = _rtcache_init(ro, clone);
1327	} else
1328		*hitp = 1;
1329
1330	rtcache_invariants(ro);
1331
1332	return rt;
1333}
1334
1335void
1336rtcache_free(struct route *ro)
1337{
1338	rtcache_clear(ro);
1339	if (ro->ro_sa != NULL) {
1340		sockaddr_free(ro->ro_sa);
1341		ro->ro_sa = NULL;
1342	}
1343	rtcache_invariants(ro);
1344}
1345
1346int
1347rtcache_setdst(struct route *ro, const struct sockaddr *sa)
1348{
1349	KASSERT(sa != NULL);
1350
1351	rtcache_invariants(ro);
1352	if (ro->ro_sa != NULL && ro->ro_sa->sa_family == sa->sa_family) {
1353		rtcache_clear(ro);
1354		if (sockaddr_copy(ro->ro_sa, ro->ro_sa->sa_len, sa) != NULL) {
1355			rtcache_invariants(ro);
1356			return 0;
1357		}
1358		sockaddr_free(ro->ro_sa);
1359	} else if (ro->ro_sa != NULL)
1360		rtcache_free(ro);	/* free ro_sa, wrong family */
1361
1362	KASSERT(ro->_ro_rt == NULL);
1363
1364	if ((ro->ro_sa = sockaddr_dup(sa, M_NOWAIT)) == NULL) {
1365		rtcache_invariants(ro);
1366		return ENOMEM;
1367	}
1368	rtcache_invariants(ro);
1369	return 0;
1370}
1371
1372const struct sockaddr *
1373rt_settag(struct rtentry *rt, const struct sockaddr *tag)
1374{
1375	if (rt->rt_tag != tag) {
1376		if (rt->rt_tag != NULL)
1377			sockaddr_free(rt->rt_tag);
1378		rt->rt_tag = sockaddr_dup(tag, M_NOWAIT);
1379	}
1380	return rt->rt_tag;
1381}
1382
1383struct sockaddr *
1384rt_gettag(struct rtentry *rt)
1385{
1386	return rt->rt_tag;
1387}
1388