1139823Simp/*-
26399Swollman * Copyright 1994, 1995 Massachusetts Institute of Technology
34074Swollman *
46399Swollman * Permission to use, copy, modify, and distribute this software and
56399Swollman * its documentation for any purpose and without fee is hereby
66399Swollman * granted, provided that both the above copyright notice and this
76399Swollman * permission notice appear in all copies, that both the above
86399Swollman * copyright notice and this permission notice appear in all
96399Swollman * supporting documentation, and that the name of M.I.T. not be used
106399Swollman * in advertising or publicity pertaining to distribution of the
116399Swollman * software without specific, written prior permission.  M.I.T. makes
126399Swollman * no representations about the suitability of this software for any
136399Swollman * purpose.  It is provided "as is" without express or implied
146399Swollman * warranty.
158876Srgrimes *
166399Swollman * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''.  M.I.T. DISCLAIMS
176399Swollman * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
186399Swollman * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
196399Swollman * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
206399Swollman * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
216399Swollman * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
226399Swollman * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
236399Swollman * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
246399Swollman * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
256399Swollman * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
266399Swollman * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
276399Swollman * SUCH DAMAGE.
284074Swollman */
294074Swollman
30172467Ssilby#include <sys/cdefs.h>
31172467Ssilby__FBSDID("$FreeBSD: releng/10.3/sys/netinet/in_rmx.c 295389 2016-02-08 00:07:01Z bz $");
32172467Ssilby
334074Swollman#include <sys/param.h>
344074Swollman#include <sys/systm.h>
354074Swollman#include <sys/kernel.h>
3612172Sphk#include <sys/sysctl.h>
374074Swollman#include <sys/socket.h>
384074Swollman#include <sys/mbuf.h>
394893Swollman#include <sys/syslog.h>
40120727Ssam#include <sys/callout.h>
414074Swollman
424074Swollman#include <net/if.h>
434074Swollman#include <net/route.h>
44196019Srwatson#include <net/vnet.h>
45185571Sbz
464074Swollman#include <netinet/in.h>
474074Swollman#include <netinet/in_var.h>
48241406Smelifaro#include <netinet/ip.h>
49241406Smelifaro#include <netinet/ip_icmp.h>
5074454Sru#include <netinet/ip_var.h>
514074Swollman
5292723Salfredextern int	in_inithead(void **head, int off);
53193731Szec#ifdef VIMAGE
54193731Szecextern int	in_detachhead(void **head, int off);
55193731Szec#endif
5612579Sbde
575101Swollman#define RTPRF_OURS		RTF_PROTO3	/* set on routes we manage */
584074Swollman
594074Swollman/*
604074Swollman * Do what we need to do when inserting a route.
614074Swollman */
624074Swollmanstatic struct radix_node *
634074Swollmanin_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
64169454Srwatson    struct radix_node *treenodes)
654074Swollman{
664074Swollman	struct rtentry *rt = (struct rtentry *)treenodes;
679470Swollman	struct sockaddr_in *sin = (struct sockaddr_in *)rt_key(rt);
684074Swollman
69186119Sqingli	RADIX_NODE_HEAD_WLOCK_ASSERT(head);
704074Swollman	/*
7115652Swollman	 * A little bit of help for both IP output and input:
7215652Swollman	 *   For host routes, we make sure that RTF_BROADCAST
7315652Swollman	 *   is set for anything that looks like a broadcast address.
7415652Swollman	 *   This way, we can avoid an expensive call to in_broadcast()
7515652Swollman	 *   in ip_output() most of the time (because the route passed
7615652Swollman	 *   to ip_output() is almost always a host route).
7715652Swollman	 *
7815652Swollman	 *   We also do the same for local addresses, with the thought
7915652Swollman	 *   that this might one day be used to speed up ip_input().
8015652Swollman	 *
8115652Swollman	 * We also mark routes to multicast addresses as such, because
8215652Swollman	 * it's easy to do and might be useful (but this is much more
83122921Sandre	 * dubious since it's so easy to inspect the address).
8415652Swollman	 */
8515652Swollman	if (rt->rt_flags & RTF_HOST) {
8615652Swollman		if (in_broadcast(sin->sin_addr, rt->rt_ifp)) {
8715652Swollman			rt->rt_flags |= RTF_BROADCAST;
88110656Shsu		} else if (satosin(rt->rt_ifa->ifa_addr)->sin_addr.s_addr ==
89110656Shsu		    sin->sin_addr.s_addr) {
90110656Shsu			rt->rt_flags |= RTF_LOCAL;
915792Swollman		}
925792Swollman	}
93122921Sandre	if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
94122921Sandre		rt->rt_flags |= RTF_MULTICAST;
954074Swollman
96263478Sglebius	if (rt->rt_mtu == 0 && rt->rt_ifp != NULL)
97263478Sglebius		rt->rt_mtu = rt->rt_ifp->if_mtu;
989470Swollman
99186119Sqingli	return (rn_addroute(v_arg, n_arg, head, treenodes));
1004074Swollman}
1014074Swollman
1024074Swollman/*
1034105Swollman * This code is the inverse of in_clsroute: on first reference, if we
1044105Swollman * were managing the route, stop doing so and set the expiration timer
1054105Swollman * back off again.
1064074Swollman */
1074074Swollmanstatic struct radix_node *
1084074Swollmanin_matroute(void *v_arg, struct radix_node_head *head)
1094074Swollman{
1104074Swollman	struct radix_node *rn = rn_match(v_arg, head);
1114074Swollman	struct rtentry *rt = (struct rtentry *)rn;
1124074Swollman
113213225Sdelphij	if (rt) {
114213225Sdelphij		RT_LOCK(rt);
115110656Shsu		if (rt->rt_flags & RTPRF_OURS) {
1165101Swollman			rt->rt_flags &= ~RTPRF_OURS;
117263478Sglebius			rt->rt_expire = 0;
1184074Swollman		}
119213225Sdelphij		RT_UNLOCK(rt);
1204074Swollman	}
1214074Swollman	return rn;
1224074Swollman}
1234074Swollman
124215701Sdimstatic VNET_DEFINE(int, rtq_reallyold) = 60*60; /* one hour is "really old" */
125195727Srwatson#define	V_rtq_reallyold		VNET(rtq_reallyold)
126195699SrwatsonSYSCTL_VNET_INT(_net_inet_ip, IPCTL_RTEXPIRE, rtexpire, CTLFLAG_RW,
127195699Srwatson    &VNET_NAME(rtq_reallyold), 0,
128183550Szec    "Default expiration time on dynamically learned routes");
129110656Shsu
130207369Sbz/* never automatically crank down to less */
131215701Sdimstatic VNET_DEFINE(int, rtq_minreallyold) = 10;
132207369Sbz#define	V_rtq_minreallyold	VNET(rtq_minreallyold)
133195699SrwatsonSYSCTL_VNET_INT(_net_inet_ip, IPCTL_RTMINEXPIRE, rtminexpire, CTLFLAG_RW,
134195699Srwatson    &VNET_NAME(rtq_minreallyold), 0,
13546381Sbillf    "Minimum time to attempt to hold onto dynamically learned routes");
1364105Swollman
137207369Sbz/* 128 cached routes is "too many" */
138215701Sdimstatic VNET_DEFINE(int, rtq_toomany) = 128;
139207369Sbz#define	V_rtq_toomany		VNET(rtq_toomany)
140195699SrwatsonSYSCTL_VNET_INT(_net_inet_ip, IPCTL_RTMAXCACHE, rtmaxcache, CTLFLAG_RW,
141195699Srwatson    &VNET_NAME(rtq_toomany), 0,
142183550Szec    "Upper limit on dynamically learned routes");
143110656Shsu
1444074Swollman/*
1455792Swollman * On last reference drop, mark the route as belong to us so that it can be
1464074Swollman * timed out.
1474074Swollman */
1484074Swollmanstatic void
1494074Swollmanin_clsroute(struct radix_node *rn, struct radix_node_head *head)
1504074Swollman{
1514074Swollman	struct rtentry *rt = (struct rtentry *)rn;
1528876Srgrimes
153120727Ssam	RT_LOCK_ASSERT(rt);
154120727Ssam
155110656Shsu	if (!(rt->rt_flags & RTF_UP))
156110656Shsu		return;			/* prophylactic measures */
1575792Swollman
158138499Sru	if (rt->rt_flags & RTPRF_OURS)
1594105Swollman		return;
1604074Swollman
161186119Sqingli	if (!(rt->rt_flags & RTF_DYNAMIC))
162138499Sru		return;
163138499Sru
1646399Swollman	/*
1656399Swollman	 * If rtq_reallyold is 0, just delete the route without
1666399Swollman	 * waiting for a timeout cycle to kill it.
1676399Swollman	 */
168181803Sbz	if (V_rtq_reallyold != 0) {
1696399Swollman		rt->rt_flags |= RTPRF_OURS;
170263478Sglebius		rt->rt_expire = time_uptime + V_rtq_reallyold;
1716399Swollman	} else {
172121770Ssam		rtexpunge(rt);
1736399Swollman	}
1744074Swollman}
1754074Swollman
1764893Swollmanstruct rtqk_arg {
1774893Swollman	struct radix_node_head *rnh;
1785101Swollman	int draining;
1794893Swollman	int killed;
1804893Swollman	int found;
1816400Swollman	int updating;
1824893Swollman	time_t nextstop;
1834893Swollman};
1844893Swollman
1854074Swollman/*
1865101Swollman * Get rid of old routes.  When draining, this deletes everything, even when
1876400Swollman * the timeout is not expired yet.  When updating, this makes sure that
1886400Swollman * nothing has a timeout longer than the current value of rtq_reallyold.
1894074Swollman */
1904893Swollmanstatic int
1914893Swollmanin_rtqkill(struct radix_node *rn, void *rock)
1924074Swollman{
1934893Swollman	struct rtqk_arg *ap = rock;
1944893Swollman	struct rtentry *rt = (struct rtentry *)rn;
1954893Swollman	int err;
1964893Swollman
197188962Srwatson	RADIX_NODE_HEAD_WLOCK_ASSERT(ap->rnh);
198188962Srwatson
199110656Shsu	if (rt->rt_flags & RTPRF_OURS) {
2004893Swollman		ap->found++;
2014893Swollman
202263478Sglebius		if (ap->draining || rt->rt_expire <= time_uptime) {
203110656Shsu			if (rt->rt_refcnt > 0)
2047170Sdg				panic("rtqkill route really not free");
2054893Swollman
206178888Sjulian			err = in_rtrequest(RTM_DELETE,
2074893Swollman					(struct sockaddr *)rt_key(rt),
2084893Swollman					rt->rt_gateway, rt_mask(rt),
209188962Srwatson					rt->rt_flags | RTF_RNH_LOCKED, 0,
210188962Srwatson					rt->rt_fibnum);
211110656Shsu			if (err) {
2126568Sdg				log(LOG_WARNING, "in_rtqkill: error %d\n", err);
2134893Swollman			} else {
2144893Swollman				ap->killed++;
2154893Swollman			}
2164893Swollman		} else {
217110656Shsu			if (ap->updating &&
218263478Sglebius			    (rt->rt_expire - time_uptime > V_rtq_reallyold))
219263478Sglebius				rt->rt_expire = time_uptime + V_rtq_reallyold;
220263478Sglebius			ap->nextstop = lmin(ap->nextstop, rt->rt_expire);
2214893Swollman		}
2224893Swollman	}
2234893Swollman
2244893Swollman	return 0;
2254074Swollman}
2264074Swollman
2276399Swollman#define RTQ_TIMEOUT	60*10	/* run no less than once every ten minutes */
228215701Sdimstatic VNET_DEFINE(int, rtq_timeout) = RTQ_TIMEOUT;
229215701Sdimstatic VNET_DEFINE(struct callout, rtq_timer);
2305792Swollman
231195727Srwatson#define	V_rtq_timeout		VNET(rtq_timeout)
232195727Srwatson#define	V_rtq_timer		VNET(rtq_timer)
233195699Srwatson
234178888Sjulianstatic void in_rtqtimo_one(void *rock);
235178888Sjulian
2364074Swollmanstatic void
2374074Swollmanin_rtqtimo(void *rock)
2384074Swollman{
239191816Szec	CURVNET_SET((struct vnet *) rock);
240178888Sjulian	int fibnum;
241178888Sjulian	void *newrock;
242178888Sjulian	struct timeval atv;
243178888Sjulian
244178888Sjulian	for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
245193232Sbz		newrock = rt_tables_get_rnh(fibnum, AF_INET);
246193232Sbz		if (newrock != NULL)
247178888Sjulian			in_rtqtimo_one(newrock);
248178888Sjulian	}
249178888Sjulian	atv.tv_usec = 0;
250181803Sbz	atv.tv_sec = V_rtq_timeout;
251181803Sbz	callout_reset(&V_rtq_timer, tvtohz(&atv), in_rtqtimo, rock);
252191816Szec	CURVNET_RESTORE();
253178888Sjulian}
254178888Sjulian
255178888Sjulianstatic void
256178888Sjulianin_rtqtimo_one(void *rock)
257178888Sjulian{
2584893Swollman	struct radix_node_head *rnh = rock;
2594893Swollman	struct rtqk_arg arg;
2606399Swollman	static time_t last_adjusted_timeout = 0;
2614074Swollman
2624893Swollman	arg.found = arg.killed = 0;
2634893Swollman	arg.rnh = rnh;
264181803Sbz	arg.nextstop = time_uptime + V_rtq_timeout;
2656400Swollman	arg.draining = arg.updating = 0;
266108250Shsu	RADIX_NODE_HEAD_LOCK(rnh);
2674893Swollman	rnh->rnh_walktree(rnh, in_rtqkill, &arg);
268108250Shsu	RADIX_NODE_HEAD_UNLOCK(rnh);
2696399Swollman
2706399Swollman	/*
2716399Swollman	 * Attempt to be somewhat dynamic about this:
2726399Swollman	 * If there are ``too many'' routes sitting around taking up space,
2736399Swollman	 * then crank down the timeout, and see if we can't make some more
2746399Swollman	 * go away.  However, we make sure that we will never adjust more
2756399Swollman	 * than once in rtq_timeout seconds, to keep from cranking down too
2766399Swollman	 * hard.
2776399Swollman	 */
278181803Sbz	if ((arg.found - arg.killed > V_rtq_toomany) &&
279181803Sbz	    (time_uptime - last_adjusted_timeout >= V_rtq_timeout) &&
280181803Sbz	    V_rtq_reallyold > V_rtq_minreallyold) {
281181803Sbz		V_rtq_reallyold = 2 * V_rtq_reallyold / 3;
282181803Sbz		if (V_rtq_reallyold < V_rtq_minreallyold) {
283181803Sbz			V_rtq_reallyold = V_rtq_minreallyold;
2846399Swollman		}
2856399Swollman
286160123Soleg		last_adjusted_timeout = time_uptime;
28716542Snate#ifdef DIAGNOSTIC
2886568Sdg		log(LOG_DEBUG, "in_rtqtimo: adjusted rtq_reallyold to %d\n",
289181803Sbz		    V_rtq_reallyold);
29016542Snate#endif
2916399Swollman		arg.found = arg.killed = 0;
2926400Swollman		arg.updating = 1;
293108250Shsu		RADIX_NODE_HEAD_LOCK(rnh);
2946399Swollman		rnh->rnh_walktree(rnh, in_rtqkill, &arg);
295108250Shsu		RADIX_NODE_HEAD_UNLOCK(rnh);
2966399Swollman	}
2976399Swollman
2984074Swollman}
2994074Swollman
30012933Swollmanvoid
3014893Swollmanin_rtqdrain(void)
3024893Swollman{
303183550Szec	VNET_ITERATOR_DECL(vnet_iter);
304178888Sjulian	struct radix_node_head *rnh;
3055101Swollman	struct rtqk_arg arg;
306178888Sjulian	int 	fibnum;
307120727Ssam
308195760Srwatson	VNET_LIST_RLOCK_NOSLEEP();
309183550Szec	VNET_FOREACH(vnet_iter) {
310183550Szec		CURVNET_SET(vnet_iter);
311185348Szec
312183550Szec		for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) {
313193232Sbz			rnh = rt_tables_get_rnh(fibnum, AF_INET);
314183550Szec			arg.found = arg.killed = 0;
315183550Szec			arg.rnh = rnh;
316183550Szec			arg.nextstop = 0;
317183550Szec			arg.draining = 1;
318183550Szec			arg.updating = 0;
319183550Szec			RADIX_NODE_HEAD_LOCK(rnh);
320183550Szec			rnh->rnh_walktree(rnh, in_rtqkill, &arg);
321183550Szec			RADIX_NODE_HEAD_UNLOCK(rnh);
322183550Szec		}
323183550Szec		CURVNET_RESTORE();
324178888Sjulian	}
325195760Srwatson	VNET_LIST_RUNLOCK_NOSLEEP();
3264893Swollman}
3274893Swollman
328241406Smelifarovoid
329241406Smelifaroin_setmatchfunc(struct radix_node_head *rnh, int val)
330241406Smelifaro{
331241406Smelifaro
332241406Smelifaro	rnh->rnh_matchaddr = (val != 0) ? rn_match : in_matroute;
333241406Smelifaro}
334241406Smelifaro
335178888Sjulianstatic int _in_rt_was_here;
3364074Swollman/*
3374074Swollman * Initialize our routing tree.
3384074Swollman */
3394074Swollmanint
3404074Swollmanin_inithead(void **head, int off)
3414074Swollman{
3424074Swollman	struct radix_node_head *rnh;
3434074Swollman
344178888Sjulian	/* XXX MRT
345178888Sjulian	 * This can be called from vfs_export.c too in which case 'off'
346178888Sjulian	 * will be 0. We know the correct value so just use that and
347178888Sjulian	 * return directly if it was 0.
348178888Sjulian	 * This is a hack that replaces an even worse hack on a bad hack
349178888Sjulian	 * on a bad design. After RELENG_7 this should be fixed but that
350178888Sjulian	 * will change the ABI, so for now do it this way.
351178888Sjulian	 */
352178888Sjulian	if (!rn_inithead(head, 32))
3534074Swollman		return 0;
3544074Swollman
355178888Sjulian	if (off == 0)		/* XXX MRT  see above */
356178888Sjulian		return 1;	/* only do the rest for a real routing table */
3574896Swollman
3584074Swollman	rnh = *head;
3594074Swollman	rnh->rnh_addaddr = in_addroute;
360241406Smelifaro	in_setmatchfunc(rnh, V_drop_redirect);
3614074Swollman	rnh->rnh_close = in_clsroute;
362178888Sjulian	if (_in_rt_was_here == 0 ) {
363181803Sbz		callout_init(&V_rtq_timer, CALLOUT_MPSAFE);
364191816Szec		callout_reset(&V_rtq_timer, 1, in_rtqtimo, curvnet);
365178888Sjulian		_in_rt_was_here = 1;
366178888Sjulian	}
3674074Swollman	return 1;
3684074Swollman}
3694074Swollman
370193731Szec#ifdef VIMAGE
371193731Szecint
372193731Szecin_detachhead(void **head, int off)
373193731Szec{
374193731Szec
375193731Szec	callout_drain(&V_rtq_timer);
376295389Sbz	return (rn_detachhead(head));
377193731Szec}
378193731Szec#endif
379193731Szec
38022672Swollman/*
38176469Sru * This zaps old routes when the interface goes down or interface
38276469Sru * address is deleted.  In the latter case, it deletes static routes
38376469Sru * that point to this address.  If we don't do this, we may end up
38476469Sru * using the old address in the future.  The ones we always want to
38576469Sru * get rid of are things like ARP entries, since the user might down
38676469Sru * the interface, walk over to a completely different network, and
38776469Sru * plug back in.
38822672Swollman */
38922672Swollmanstruct in_ifadown_arg {
39022672Swollman	struct ifaddr *ifa;
39176469Sru	int del;
39222672Swollman};
39322672Swollman
39422672Swollmanstatic int
39522672Swollmanin_ifadownkill(struct radix_node *rn, void *xap)
39622672Swollman{
39722672Swollman	struct in_ifadown_arg *ap = xap;
39822672Swollman	struct rtentry *rt = (struct rtentry *)rn;
39922672Swollman
400121770Ssam	RT_LOCK(rt);
40176469Sru	if (rt->rt_ifa == ap->ifa &&
40276469Sru	    (ap->del || !(rt->rt_flags & RTF_STATIC))) {
40334914Speter		/*
404210686Sbz		 * Aquire a reference so that it can later be freed
405210686Sbz		 * as the refcount would be 0 here in case of at least
406210686Sbz		 * ap->del.
40734914Speter		 */
408210686Sbz		RT_ADDREF(rt);
409210686Sbz		/*
410210686Sbz		 * Disconnect it from the tree and permit protocols
411210686Sbz		 * to cleanup.
412210686Sbz		 */
413121770Ssam		rtexpunge(rt);
414210686Sbz		/*
415210686Sbz		 * At this point it is an rttrash node, and in case
416210686Sbz		 * the above is the only reference we must free it.
417210686Sbz		 * If we do not noone will have a pointer and the
418210686Sbz		 * rtentry will be leaked forever.
419210686Sbz		 * In case someone else holds a reference, we are
420210686Sbz		 * fine as we only decrement the refcount. In that
421210686Sbz		 * case if the other entity calls RT_REMREF, we
422210686Sbz		 * will still be leaking but at least we tried.
423210686Sbz		 */
424210686Sbz		RTFREE_LOCKED(rt);
425210686Sbz		return (0);
426121929Ssam	}
427121929Ssam	RT_UNLOCK(rt);
42822672Swollman	return 0;
42922672Swollman}
43022672Swollman
43122672Swollmanint
43276469Sruin_ifadown(struct ifaddr *ifa, int delete)
43322672Swollman{
43422672Swollman	struct in_ifadown_arg arg;
43522672Swollman	struct radix_node_head *rnh;
436178888Sjulian	int	fibnum;
43722672Swollman
43822672Swollman	if (ifa->ifa_addr->sa_family != AF_INET)
43922672Swollman		return 1;
44022672Swollman
441178888Sjulian	for ( fibnum = 0; fibnum < rt_numfibs; fibnum++) {
442193232Sbz		rnh = rt_tables_get_rnh(fibnum, AF_INET);
443178888Sjulian		arg.ifa = ifa;
444178888Sjulian		arg.del = delete;
445178888Sjulian		RADIX_NODE_HEAD_LOCK(rnh);
446178888Sjulian		rnh->rnh_walktree(rnh, in_ifadownkill, &arg);
447178888Sjulian		RADIX_NODE_HEAD_UNLOCK(rnh);
448178888Sjulian		ifa->ifa_flags &= ~IFA_ROUTE;		/* XXXlocking? */
449178888Sjulian	}
45022672Swollman	return 0;
45122672Swollman}
452178888Sjulian
453178888Sjulian/*
454178888Sjulian * inet versions of rt functions. These have fib extensions and
455178888Sjulian * for now will just reference the _fib variants.
456178888Sjulian * eventually this order will be reversed,
457178888Sjulian */
458178888Sjulianvoid
459178888Sjulianin_rtalloc_ign(struct route *ro, u_long ignflags, u_int fibnum)
460178888Sjulian{
461178888Sjulian	rtalloc_ign_fib(ro, ignflags, fibnum);
462178888Sjulian}
463178888Sjulian
464178888Sjulianint
465178888Sjulianin_rtrequest( int req,
466178888Sjulian	struct sockaddr *dst,
467178888Sjulian	struct sockaddr *gateway,
468178888Sjulian	struct sockaddr *netmask,
469178888Sjulian	int flags,
470178888Sjulian	struct rtentry **ret_nrt,
471178888Sjulian	u_int fibnum)
472178888Sjulian{
473178888Sjulian	return (rtrequest_fib(req, dst, gateway, netmask,
474178888Sjulian	    flags, ret_nrt, fibnum));
475178888Sjulian}
476178888Sjulian
477178888Sjulianstruct rtentry *
478178888Sjulianin_rtalloc1(struct sockaddr *dst, int report, u_long ignflags, u_int fibnum)
479178888Sjulian{
480178888Sjulian	return (rtalloc1_fib(dst, report, ignflags, fibnum));
481178888Sjulian}
482178888Sjulian
483178888Sjulianvoid
484178888Sjulianin_rtredirect(struct sockaddr *dst,
485178888Sjulian	struct sockaddr *gateway,
486178888Sjulian	struct sockaddr *netmask,
487178888Sjulian	int flags,
488178888Sjulian	struct sockaddr *src,
489178888Sjulian	u_int fibnum)
490178888Sjulian{
491178888Sjulian	rtredirect_fib(dst, gateway, netmask, flags, src, fibnum);
492178888Sjulian}
493178888Sjulian
494178888Sjulianvoid
495178888Sjulianin_rtalloc(struct route *ro, u_int fibnum)
496178888Sjulian{
497178888Sjulian	rtalloc_ign_fib(ro, 0UL, fibnum);
498178888Sjulian}
499178888Sjulian
500178888Sjulian#if 0
501178888Sjulianint	 in_rt_getifa(struct rt_addrinfo *, u_int fibnum);
502178888Sjulianint	 in_rtioctl(u_long, caddr_t, u_int);
503178888Sjulianint	 in_rtrequest1(int, struct rt_addrinfo *, struct rtentry **, u_int);
504178888Sjulian#endif
505178888Sjulian
506178888Sjulian
507