1 /* $NetBSD: route.c,v 1.120 2009/10/03 02:22:22 elad Exp $ */
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Kevin M. Lahey of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
35 * All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
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.
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
63 * Copyright (c) 1980, 1986, 1991, 1993
64 * The Regents of the University of California. All rights reserved.
66 * Redistribution and use in source and binary forms, with or without
67 * modification, are permitted provided that the following conditions
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.
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
90 * @(#)route.c 8.3 (Berkeley) 1/9/95
93 #include "opt_route.h"
95 #include <sys/cdefs.h>
96 __KERNEL_RCSID(0, "$NetBSD: route.c,v 1.120 2009/10/03 02:22:22 elad Exp $");
98 #include <sys/param.h>
99 #include <sys/sysctl.h>
100 #include <sys/systm.h>
101 #include <sys/callout.h>
102 #include <sys/proc.h>
103 #include <sys/mbuf.h>
104 #include <sys/socket.h>
105 #include <sys/socketvar.h>
106 #include <sys/domain.h>
107 #include <sys/protosw.h>
108 #include <sys/kernel.h>
109 #include <sys/ioctl.h>
110 #include <sys/pool.h>
111 #include <sys/kauth.h>
114 #include <net/if_dl.h>
115 #include <net/route.h>
116 #include <net/raw_cb.h>
118 #include <netinet/in.h>
119 #include <netinet/in_var.h>
122 #define rtcache_debug() __predict_false(_rtcache_debug)
123 #else /* RTFLUSH_DEBUG */
124 #define rtcache_debug() 0
125 #endif /* RTFLUSH_DEBUG */
127 struct route_cb route_cb
;
128 struct rtstat rtstat
;
129 struct radix_node_head
*rt_tables
[AF_MAX
+1];
131 int rttrash
; /* routes not in table but not freed */
133 struct pool rtentry_pool
;
134 struct pool rttimer_pool
;
136 struct callout rt_timer_ch
; /* callout for rt_timer_timer() */
139 static int _rtcache_debug
= 0;
140 #endif /* RTFLUSH_DEBUG */
142 static kauth_listener_t route_listener
;
144 static int rtdeletemsg(struct rtentry
*);
145 static int rtflushclone1(struct rtentry
*, void *);
146 static void rtflushclone(sa_family_t family
, struct rtentry
*);
149 static void sysctl_net_rtcache_setup(struct sysctllog
**);
151 sysctl_net_rtcache_setup(struct sysctllog
**clog
)
153 const struct sysctlnode
*rnode
;
155 /* XXX do not duplicate */
156 if (sysctl_createv(clog
, 0, NULL
, &rnode
, CTLFLAG_PERMANENT
,
157 CTLTYPE_NODE
, "net", NULL
, NULL
, 0, NULL
, 0, CTL_NET
, CTL_EOL
) != 0)
159 if (sysctl_createv(clog
, 0, &rnode
, &rnode
, CTLFLAG_PERMANENT
,
161 "rtcache", SYSCTL_DESCR("Route cache related settings"),
162 NULL
, 0, NULL
, 0, CTL_CREATE
, CTL_EOL
) != 0)
164 if (sysctl_createv(clog
, 0, &rnode
, &rnode
,
165 CTLFLAG_PERMANENT
|CTLFLAG_READWRITE
, CTLTYPE_INT
,
166 "debug", SYSCTL_DESCR("Debug route caches"),
167 NULL
, 0, &_rtcache_debug
, 0, CTL_CREATE
, CTL_EOL
) != 0)
170 #endif /* RTFLUSH_DEBUG */
173 rt_get_ifa(struct rtentry
*rt
)
177 if ((ifa
= rt
->rt_ifa
) == NULL
)
179 else if (ifa
->ifa_getifa
== NULL
)
182 else if (ifa
->ifa_seqno
!= NULL
&& *ifa
->ifa_seqno
== rt
->rt_ifa_seqno
)
186 ifa
= (*ifa
->ifa_getifa
)(ifa
, rt_getkey(rt
));
187 rt_replace_ifa(rt
, ifa
);
193 rt_set_ifa1(struct rtentry
*rt
, struct ifaddr
*ifa
)
196 if (ifa
->ifa_seqno
!= NULL
)
197 rt
->rt_ifa_seqno
= *ifa
->ifa_seqno
;
201 * Is this route the connected route for the ifa?
204 rt_ifa_connected(const struct rtentry
*rt
, const struct ifaddr
*ifa
)
206 const struct sockaddr
*key
, *dst
, *odst
;
207 struct sockaddr_storage maskeddst
;
210 dst
= rt
->rt_flags
& RTF_HOST
? ifa
->ifa_dstaddr
: ifa
->ifa_addr
;
212 dst
->sa_family
!= key
->sa_family
||
213 dst
->sa_len
!= key
->sa_len
)
215 if ((rt
->rt_flags
& RTF_HOST
) == 0 && ifa
->ifa_netmask
) {
217 dst
= (struct sockaddr
*)&maskeddst
;
218 rt_maskedcopy(odst
, (struct sockaddr
*)&maskeddst
,
221 return (memcmp(dst
, key
, dst
->sa_len
) == 0);
225 rt_replace_ifa(struct rtentry
*rt
, struct ifaddr
*ifa
)
229 rt
->rt_ifa
->ifa_flags
& IFA_ROUTE
&&
230 rt_ifa_connected(rt
, rt
->rt_ifa
))
232 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
233 "replace deleted IFA_ROUTE\n",
234 (void *)rt
->_rt_key
, (void *)rt
->rt_ifa
);
235 rt
->rt_ifa
->ifa_flags
&= ~IFA_ROUTE
;
236 if (rt_ifa_connected(rt
, ifa
)) {
237 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
238 "replace added IFA_ROUTE\n",
239 (void *)rt
->_rt_key
, (void *)ifa
);
240 ifa
->ifa_flags
|= IFA_ROUTE
;
246 rt_set_ifa1(rt
, ifa
);
250 rt_set_ifa(struct rtentry
*rt
, struct ifaddr
*ifa
)
253 rt_set_ifa1(rt
, ifa
);
257 rtable_init(void **table
)
261 if (dom
->dom_rtattach
)
262 dom
->dom_rtattach(&table
[dom
->dom_family
],
267 route_listener_cb(kauth_cred_t cred
, kauth_action_t action
, void *cookie
,
268 void *arg0
, void *arg1
, void *arg2
, void *arg3
)
270 struct rt_msghdr
*rtm
;
273 result
= KAUTH_RESULT_DEFER
;
276 if (action
!= KAUTH_NETWORK_ROUTE
)
279 if (rtm
->rtm_type
== RTM_GET
)
280 result
= KAUTH_RESULT_ALLOW
;
290 sysctl_net_rtcache_setup(NULL
);
293 pool_init(&rtentry_pool
, sizeof(struct rtentry
), 0, 0, 0, "rtentpl",
295 pool_init(&rttimer_pool
, sizeof(struct rttimer
), 0, 0, 0, "rttmrpl",
299 rn_init(); /* initialize all zeroes, all ones, mask table */
300 rtable_init((void **)rt_tables
);
302 route_listener
= kauth_listen_scope(KAUTH_SCOPE_NETWORK
,
303 route_listener_cb
, NULL
);
307 rtflushall(int family
)
312 printf("%s: enter\n", __func__
);
314 if ((dom
= pffinddomain(family
)) == NULL
)
317 rtcache_invalidate(&dom
->dom_rtcache
);
321 rtcache(struct route
*ro
)
325 rtcache_invariants(ro
);
326 KASSERT(ro
->_ro_rt
!= NULL
);
327 KASSERT(ro
->ro_invalid
== false);
328 KASSERT(rtcache_getdst(ro
) != NULL
);
330 if ((dom
= pffinddomain(rtcache_getdst(ro
)->sa_family
)) == NULL
)
333 LIST_INSERT_HEAD(&dom
->dom_rtcache
, ro
, ro_rtcache_next
);
334 rtcache_invariants(ro
);
338 * Packet routing routines.
341 rtalloc1(const struct sockaddr
*dst
, int report
)
343 struct radix_node_head
*rnh
= rt_tables
[dst
->sa_family
];
345 struct radix_node
*rn
;
346 struct rtentry
*newrt
= NULL
;
347 struct rt_addrinfo info
;
348 int s
= splsoftnet(), err
= 0, msgtype
= RTM_MISS
;
350 if (rnh
&& (rn
= rnh
->rnh_matchaddr(dst
, rnh
)) &&
351 ((rn
->rn_flags
& RNF_ROOT
) == 0)) {
352 newrt
= rt
= (struct rtentry
*)rn
;
353 if (report
&& (rt
->rt_flags
& RTF_CLONING
)) {
354 err
= rtrequest(RTM_RESOLVE
, dst
, NULL
, NULL
, 0,
361 KASSERT(newrt
!= NULL
);
362 if ((rt
= newrt
) && (rt
->rt_flags
& RTF_XRESOLVE
)) {
363 msgtype
= RTM_RESOLVE
;
366 /* Inform listeners of the new route */
367 memset(&info
, 0, sizeof(info
));
368 info
.rti_info
[RTAX_DST
] = rt_getkey(rt
);
369 info
.rti_info
[RTAX_NETMASK
] = rt_mask(rt
);
370 info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
;
371 if (rt
->rt_ifp
!= NULL
) {
372 info
.rti_info
[RTAX_IFP
] =
373 rt
->rt_ifp
->if_dl
->ifa_addr
;
374 info
.rti_info
[RTAX_IFA
] = rt
->rt_ifa
->ifa_addr
;
376 rt_missmsg(RTM_ADD
, &info
, rt
->rt_flags
, 0);
380 rtstat
.rts_unreach
++;
382 memset((void *)&info
, 0, sizeof(info
));
383 info
.rti_info
[RTAX_DST
] = dst
;
384 rt_missmsg(msgtype
, &info
, 0, err
);
392 rtfree(struct rtentry
*rt
)
399 if (rt
->rt_refcnt
<= 0 && (rt
->rt_flags
& RTF_UP
) == 0) {
400 if (rt
->rt_nodes
->rn_flags
& (RNF_ACTIVE
| RNF_ROOT
))
403 if (rt
->rt_refcnt
< 0) {
404 printf("rtfree: %p not freed (neg refs)\n", rt
);
407 rt_timer_remove_all(rt
, 0);
413 pool_put(&rtentry_pool
, rt
);
418 ifafree(struct ifaddr
*ifa
)
423 panic("ifafree: null ifa");
424 if (ifa
->ifa_refcnt
!= 0)
425 panic("ifafree: ifa_refcnt != 0 (%d)", ifa
->ifa_refcnt
);
428 printf("ifafree: freeing ifaddr %p\n", ifa
);
434 * Force a routing table entry to the specified
435 * destination to go through the given gateway.
436 * Normally called as a result of a routing redirect
437 * message from the network layer.
439 * N.B.: must be called at splsoftnet
442 rtredirect(const struct sockaddr
*dst
, const struct sockaddr
*gateway
,
443 const struct sockaddr
*netmask
, int flags
, const struct sockaddr
*src
,
444 struct rtentry
**rtp
)
448 uint64_t *stat
= NULL
;
449 struct rt_addrinfo info
;
452 /* verify the gateway is directly reachable */
453 if ((ifa
= ifa_ifwithnet(gateway
)) == NULL
) {
457 rt
= rtalloc1(dst
, 0);
459 * If the redirect isn't from our current router for this dst,
460 * it's either old or wrong. If it redirects us to ourselves,
461 * we have a routing loop, perhaps as a result of an interface
462 * going down recently.
464 if (!(flags
& RTF_DONE
) && rt
&&
465 (sockaddr_cmp(src
, rt
->rt_gateway
) != 0 || rt
->rt_ifa
!= ifa
))
467 else if (ifa_ifwithaddr(gateway
))
468 error
= EHOSTUNREACH
;
472 * Create a new entry if we just got back a wildcard entry
473 * or the lookup failed. This is necessary for hosts
474 * which use routing redirects generated by smart gateways
475 * to dynamically build the routing tables.
477 if (rt
== NULL
|| (rt_mask(rt
) && rt_mask(rt
)->sa_len
< 2))
480 * Don't listen to the redirect if it's
481 * for a route to an interface.
483 if (rt
->rt_flags
& RTF_GATEWAY
) {
484 if (((rt
->rt_flags
& RTF_HOST
) == 0) && (flags
& RTF_HOST
)) {
486 * Changing from route to net => route to host.
487 * Create new route, rather than smashing route to net.
492 flags
|= RTF_GATEWAY
| RTF_DYNAMIC
;
493 info
.rti_info
[RTAX_DST
] = dst
;
494 info
.rti_info
[RTAX_GATEWAY
] = gateway
;
495 info
.rti_info
[RTAX_NETMASK
] = netmask
;
497 info
.rti_flags
= flags
;
499 error
= rtrequest1(RTM_ADD
, &info
, &rt
);
501 flags
= rt
->rt_flags
;
502 stat
= &rtstat
.rts_dynamic
;
505 * Smash the current notion of the gateway to
506 * this destination. Should check about netmask!!!
508 rt
->rt_flags
|= RTF_MODIFIED
;
509 flags
|= RTF_MODIFIED
;
510 stat
= &rtstat
.rts_newgateway
;
511 rt_setgate(rt
, gateway
);
514 error
= EHOSTUNREACH
;
517 if (rtp
!= NULL
&& !error
)
524 rtstat
.rts_badredirect
++;
525 else if (stat
!= NULL
)
527 memset(&info
, 0, sizeof(info
));
528 info
.rti_info
[RTAX_DST
] = dst
;
529 info
.rti_info
[RTAX_GATEWAY
] = gateway
;
530 info
.rti_info
[RTAX_NETMASK
] = netmask
;
531 info
.rti_info
[RTAX_AUTHOR
] = src
;
532 rt_missmsg(RTM_REDIRECT
, &info
, flags
, error
);
536 * Delete a route and generate a message
539 rtdeletemsg(struct rtentry
*rt
)
542 struct rt_addrinfo info
;
545 * Request the new route so that the entry is not actually
546 * deleted. That will allow the information being reported to
547 * be accurate (and consistent with route_output()).
549 memset(&info
, 0, sizeof(info
));
550 info
.rti_info
[RTAX_DST
] = rt_getkey(rt
);
551 info
.rti_info
[RTAX_NETMASK
] = rt_mask(rt
);
552 info
.rti_info
[RTAX_GATEWAY
] = rt
->rt_gateway
;
553 info
.rti_flags
= rt
->rt_flags
;
554 error
= rtrequest1(RTM_DELETE
, &info
, &rt
);
556 rt_missmsg(RTM_DELETE
, &info
, info
.rti_flags
, error
);
558 /* Adjust the refcount */
559 if (error
== 0 && rt
->rt_refcnt
<= 0) {
567 rtflushclone1(struct rtentry
*rt
, void *arg
)
569 struct rtentry
*parent
;
571 parent
= (struct rtentry
*)arg
;
572 if ((rt
->rt_flags
& RTF_CLONED
) != 0 && rt
->rt_parent
== parent
)
578 rtflushclone(sa_family_t family
, struct rtentry
*parent
)
582 if (!parent
|| (parent
->rt_flags
& RTF_CLONING
) == 0)
583 panic("rtflushclone: called with a non-cloning route");
585 rt_walktree(family
, rtflushclone1
, (void *)parent
);
589 * Routing table ioctl interface.
592 rtioctl(u_long req
, void *data
, struct lwp
*l
)
598 ifa_ifwithroute(int flags
, const struct sockaddr
*dst
,
599 const struct sockaddr
*gateway
)
602 if ((flags
& RTF_GATEWAY
) == 0) {
604 * If we are adding a route to an interface,
605 * and the interface is a pt to pt link
606 * we should search for the destination
607 * as our clue to the interface. Otherwise
608 * we can use the local address.
611 if (flags
& RTF_HOST
)
612 ifa
= ifa_ifwithdstaddr(dst
);
614 ifa
= ifa_ifwithaddr(gateway
);
617 * If we are adding a route to a remote net
618 * or host, the gateway may still be on the
619 * other end of a pt to pt link.
621 ifa
= ifa_ifwithdstaddr(gateway
);
624 ifa
= ifa_ifwithnet(gateway
);
626 struct rtentry
*rt
= rtalloc1(dst
, 0);
630 if ((ifa
= rt
->rt_ifa
) == NULL
)
633 if (ifa
->ifa_addr
->sa_family
!= dst
->sa_family
) {
634 struct ifaddr
*oifa
= ifa
;
635 ifa
= ifaof_ifpforaddr(dst
, ifa
->ifa_ifp
);
643 rtrequest(int req
, const struct sockaddr
*dst
, const struct sockaddr
*gateway
,
644 const struct sockaddr
*netmask
, int flags
, struct rtentry
**ret_nrt
)
646 struct rt_addrinfo info
;
648 memset(&info
, 0, sizeof(info
));
649 info
.rti_flags
= flags
;
650 info
.rti_info
[RTAX_DST
] = dst
;
651 info
.rti_info
[RTAX_GATEWAY
] = gateway
;
652 info
.rti_info
[RTAX_NETMASK
] = netmask
;
653 return rtrequest1(req
, &info
, ret_nrt
);
657 rt_getifa(struct rt_addrinfo
*info
)
660 const struct sockaddr
*dst
= info
->rti_info
[RTAX_DST
];
661 const struct sockaddr
*gateway
= info
->rti_info
[RTAX_GATEWAY
];
662 const struct sockaddr
*ifaaddr
= info
->rti_info
[RTAX_IFA
];
663 const struct sockaddr
*ifpaddr
= info
->rti_info
[RTAX_IFP
];
664 int flags
= info
->rti_flags
;
667 * ifp may be specified by sockaddr_dl when protocol address
670 if (info
->rti_ifp
== NULL
&& ifpaddr
!= NULL
671 && ifpaddr
->sa_family
== AF_LINK
&&
672 (ifa
= ifa_ifwithnet(ifpaddr
)) != NULL
)
673 info
->rti_ifp
= ifa
->ifa_ifp
;
674 if (info
->rti_ifa
== NULL
&& ifaaddr
!= NULL
)
675 info
->rti_ifa
= ifa_ifwithaddr(ifaaddr
);
676 if (info
->rti_ifa
== NULL
) {
677 const struct sockaddr
*sa
;
679 sa
= ifaaddr
!= NULL
? ifaaddr
:
680 (gateway
!= NULL
? gateway
: dst
);
681 if (sa
!= NULL
&& info
->rti_ifp
!= NULL
)
682 info
->rti_ifa
= ifaof_ifpforaddr(sa
, info
->rti_ifp
);
683 else if (dst
!= NULL
&& gateway
!= NULL
)
684 info
->rti_ifa
= ifa_ifwithroute(flags
, dst
, gateway
);
686 info
->rti_ifa
= ifa_ifwithroute(flags
, sa
, sa
);
688 if ((ifa
= info
->rti_ifa
) == NULL
)
690 if (ifa
->ifa_getifa
!= NULL
)
691 info
->rti_ifa
= ifa
= (*ifa
->ifa_getifa
)(ifa
, dst
);
692 if (info
->rti_ifp
== NULL
)
693 info
->rti_ifp
= ifa
->ifa_ifp
;
698 rtrequest1(int req
, struct rt_addrinfo
*info
, struct rtentry
**ret_nrt
)
700 int s
= splsoftnet();
702 struct rtentry
*rt
, *crt
;
703 struct radix_node
*rn
;
704 struct radix_node_head
*rnh
;
706 struct sockaddr_storage maskeddst
;
707 const struct sockaddr
*dst
= info
->rti_info
[RTAX_DST
];
708 const struct sockaddr
*gateway
= info
->rti_info
[RTAX_GATEWAY
];
709 const struct sockaddr
*netmask
= info
->rti_info
[RTAX_NETMASK
];
710 int flags
= info
->rti_flags
;
711 #define senderr(x) { error = x ; goto bad; }
713 if ((rnh
= rt_tables
[dst
->sa_family
]) == NULL
)
715 if (flags
& RTF_HOST
)
720 rt_maskedcopy(dst
, (struct sockaddr
*)&maskeddst
,
722 dst
= (struct sockaddr
*)&maskeddst
;
724 if ((rn
= rnh
->rnh_lookup(dst
, netmask
, rnh
)) == NULL
)
726 rt
= (struct rtentry
*)rn
;
727 if ((rt
->rt_flags
& RTF_CLONING
) != 0) {
728 /* clean up any cloned children */
729 rtflushclone(dst
->sa_family
, rt
);
731 if ((rn
= rnh
->rnh_deladdr(dst
, netmask
, rnh
)) == NULL
)
733 if (rn
->rn_flags
& (RNF_ACTIVE
| RNF_ROOT
))
734 panic ("rtrequest delete");
735 rt
= (struct rtentry
*)rn
;
736 if (rt
->rt_gwroute
) {
737 RTFREE(rt
->rt_gwroute
);
738 rt
->rt_gwroute
= NULL
;
741 rt
->rt_parent
->rt_refcnt
--;
742 rt
->rt_parent
= NULL
;
744 rt
->rt_flags
&= ~RTF_UP
;
745 if ((ifa
= rt
->rt_ifa
)) {
746 if (ifa
->ifa_flags
& IFA_ROUTE
&&
747 rt_ifa_connected(rt
, ifa
)) {
748 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
749 "deleted IFA_ROUTE\n",
750 (void *)rt
->_rt_key
, (void *)ifa
);
751 ifa
->ifa_flags
&= ~IFA_ROUTE
;
753 if (ifa
->ifa_rtrequest
)
754 ifa
->ifa_rtrequest(RTM_DELETE
, rt
, info
);
759 else if (rt
->rt_refcnt
<= 0) {
766 if (ret_nrt
== NULL
|| (rt
= *ret_nrt
) == NULL
)
768 if ((rt
->rt_flags
& RTF_CLONING
) == 0)
771 flags
= rt
->rt_flags
& ~(RTF_CLONING
| RTF_STATIC
);
773 gateway
= rt
->rt_gateway
;
778 if (info
->rti_ifa
== NULL
&& (error
= rt_getifa(info
)))
782 /* Already at splsoftnet() so pool_get/pool_put are safe */
783 rt
= pool_get(&rtentry_pool
, PR_NOWAIT
);
786 memset(rt
, 0, sizeof(*rt
));
787 rt
->rt_flags
= RTF_UP
| flags
;
788 LIST_INIT(&rt
->rt_timer
);
789 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
790 if (rt_setkey(rt
, dst
, M_NOWAIT
) == NULL
||
791 rt_setgate(rt
, gateway
) != 0) {
792 pool_put(&rtentry_pool
, rt
);
795 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
797 rt_maskedcopy(dst
, (struct sockaddr
*)&maskeddst
,
799 rt_setkey(rt
, (struct sockaddr
*)&maskeddst
, M_NOWAIT
);
800 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
802 rt_setkey(rt
, dst
, M_NOWAIT
);
803 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
806 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
807 rt
->rt_ifp
= ifa
->ifa_ifp
;
808 if (req
== RTM_RESOLVE
) {
809 rt
->rt_rmx
= (*ret_nrt
)->rt_rmx
; /* copy metrics */
810 rt
->rt_parent
= *ret_nrt
;
811 rt
->rt_parent
->rt_refcnt
++;
813 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
814 rn
= rnh
->rnh_addaddr(rt_getkey(rt
), netmask
, rnh
,
816 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
817 if (rn
== NULL
&& (crt
= rtalloc1(rt_getkey(rt
), 0)) != NULL
) {
818 /* overwrite cloned route */
819 if ((crt
->rt_flags
& RTF_CLONED
) != 0) {
821 rn
= rnh
->rnh_addaddr(rt_getkey(rt
),
822 netmask
, rnh
, rt
->rt_nodes
);
825 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
827 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
830 if ((rt
->rt_flags
& RTF_CLONED
) != 0 && rt
->rt_parent
)
831 rtfree(rt
->rt_parent
);
833 rtfree(rt
->rt_gwroute
);
835 pool_put(&rtentry_pool
, rt
);
838 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
839 if (ifa
->ifa_rtrequest
)
840 ifa
->ifa_rtrequest(req
, rt
, info
);
841 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
846 if ((rt
->rt_flags
& RTF_CLONING
) != 0) {
847 /* clean up any cloned children */
848 rtflushclone(dst
->sa_family
, rt
);
850 rtflushall(dst
->sa_family
);
853 if (netmask
!= NULL
) {
854 rt_maskedcopy(dst
, (struct sockaddr
*)&maskeddst
,
856 dst
= (struct sockaddr
*)&maskeddst
;
858 rn
= rnh
->rnh_lookup(dst
, netmask
, rnh
);
859 if (rn
== NULL
|| (rn
->rn_flags
& RNF_ROOT
) != 0)
861 if (ret_nrt
!= NULL
) {
862 rt
= (struct rtentry
*)rn
;
874 rt_setgate(struct rtentry
*rt
, const struct sockaddr
*gate
)
876 KASSERT(rt
!= rt
->rt_gwroute
);
878 KASSERT(rt
->_rt_key
!= NULL
);
879 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
881 if (rt
->rt_gwroute
) {
882 RTFREE(rt
->rt_gwroute
);
883 rt
->rt_gwroute
= NULL
;
885 KASSERT(rt
->_rt_key
!= NULL
);
886 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
887 if (rt
->rt_gateway
!= NULL
)
888 sockaddr_free(rt
->rt_gateway
);
889 KASSERT(rt
->_rt_key
!= NULL
);
890 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
891 if ((rt
->rt_gateway
= sockaddr_dup(gate
, M_NOWAIT
)) == NULL
)
893 KASSERT(rt
->_rt_key
!= NULL
);
894 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
896 if (rt
->rt_flags
& RTF_GATEWAY
) {
897 KASSERT(rt
->_rt_key
!= NULL
);
898 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
899 rt
->rt_gwroute
= rtalloc1(gate
, 1);
901 * If we switched gateways, grab the MTU from the new
902 * gateway route if the current MTU, if the current MTU is
903 * greater than the MTU of gateway.
904 * Note that, if the MTU of gateway is 0, we will reset the
905 * MTU of the route to run PMTUD again from scratch. XXX
907 KASSERT(rt
->_rt_key
!= NULL
);
908 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
910 && !(rt
->rt_rmx
.rmx_locks
& RTV_MTU
)
911 && rt
->rt_rmx
.rmx_mtu
912 && rt
->rt_rmx
.rmx_mtu
> rt
->rt_gwroute
->rt_rmx
.rmx_mtu
) {
913 rt
->rt_rmx
.rmx_mtu
= rt
->rt_gwroute
->rt_rmx
.rmx_mtu
;
916 KASSERT(rt
->_rt_key
!= NULL
);
917 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt
->_rt_key
);
922 rt_maskedcopy(const struct sockaddr
*src
, struct sockaddr
*dst
,
923 const struct sockaddr
*netmask
)
925 const char *netmaskp
= &netmask
->sa_data
[0],
926 *srcp
= &src
->sa_data
[0];
927 char *dstp
= &dst
->sa_data
[0];
928 const char *maskend
= dstp
+ MIN(netmask
->sa_len
, src
->sa_len
);
929 const char *srcend
= dstp
+ src
->sa_len
;
931 dst
->sa_len
= src
->sa_len
;
932 dst
->sa_family
= src
->sa_family
;
934 while (dstp
< maskend
)
935 *dstp
++ = *srcp
++ & *netmaskp
++;
937 memset(dstp
, 0, (size_t)(srcend
- dstp
));
941 * Set up or tear down a routing table entry, normally
945 rtinit(struct ifaddr
*ifa
, int cmd
, int flags
)
948 struct sockaddr
*dst
, *odst
;
949 struct sockaddr_storage maskeddst
;
950 struct rtentry
*nrt
= NULL
;
952 struct rt_addrinfo info
;
953 struct sockaddr_dl
*sdl
;
954 const struct sockaddr_dl
*ifsdl
;
956 dst
= flags
& RTF_HOST
? ifa
->ifa_dstaddr
: ifa
->ifa_addr
;
957 if (cmd
== RTM_DELETE
) {
958 if ((flags
& RTF_HOST
) == 0 && ifa
->ifa_netmask
) {
959 /* Delete subnet route for this interface */
961 dst
= (struct sockaddr
*)&maskeddst
;
962 rt_maskedcopy(odst
, dst
, ifa
->ifa_netmask
);
964 if ((rt
= rtalloc1(dst
, 0)) != NULL
) {
966 if (rt
->rt_ifa
!= ifa
)
967 return (flags
& RTF_HOST
) ? EHOSTUNREACH
971 memset(&info
, 0, sizeof(info
));
973 info
.rti_flags
= flags
| ifa
->ifa_flags
;
974 info
.rti_info
[RTAX_DST
] = dst
;
975 info
.rti_info
[RTAX_GATEWAY
] = ifa
->ifa_addr
;
977 * XXX here, it seems that we are assuming that ifa_netmask is NULL
978 * for RTF_HOST. bsdi4 passes NULL explicitly (via intermediate
979 * variable) when RTF_HOST is 1. still not sure if i can safely
980 * change it to meet bsdi4 behavior.
982 if (cmd
!= RTM_LLINFO_UPD
)
983 info
.rti_info
[RTAX_NETMASK
] = ifa
->ifa_netmask
;
984 error
= rtrequest1((cmd
== RTM_LLINFO_UPD
) ? RTM_GET
: cmd
, &info
,
986 if (error
!= 0 || (rt
= nrt
) == NULL
)
990 rt_newaddrmsg(cmd
, ifa
, error
, nrt
);
991 if (rt
->rt_refcnt
<= 0) {
998 RT_DPRINTF("%s: updating%s\n", __func__
,
999 ((rt
->rt_flags
& RTF_LLINFO
) == 0) ? " (no llinfo)" : "");
1001 ifsdl
= ifa
->ifa_ifp
->if_sadl
;
1003 if ((rt
->rt_flags
& RTF_LLINFO
) != 0 &&
1004 (sdl
= satosdl(rt
->rt_gateway
)) != NULL
&&
1005 sdl
->sdl_family
== AF_LINK
&&
1006 sockaddr_dl_setaddr(sdl
, sdl
->sdl_len
, CLLADDR(ifsdl
),
1007 ifa
->ifa_ifp
->if_addrlen
) == NULL
) {
1012 if (cmd
== RTM_LLINFO_UPD
&& ifa
->ifa_rtrequest
!= NULL
)
1013 ifa
->ifa_rtrequest(RTM_LLINFO_UPD
, rt
, &info
);
1014 rt_newaddrmsg(RTM_CHANGE
, ifa
, error
, nrt
);
1018 if (rt
->rt_ifa
!= ifa
) {
1019 printf("rtinit: wrong ifa (%p) was (%p)\n", ifa
,
1021 if (rt
->rt_ifa
->ifa_rtrequest
!= NULL
) {
1022 rt
->rt_ifa
->ifa_rtrequest(RTM_DELETE
, rt
,
1025 rt_replace_ifa(rt
, ifa
);
1026 rt
->rt_ifp
= ifa
->ifa_ifp
;
1027 if (ifa
->ifa_rtrequest
!= NULL
)
1028 ifa
->ifa_rtrequest(RTM_ADD
, rt
, &info
);
1030 rt_newaddrmsg(cmd
, ifa
, error
, nrt
);
1037 * Route timer routines. These routes allow functions to be called
1038 * for various routes at any time. This is useful in supporting
1039 * path MTU discovery and redirect route deletion.
1041 * This is similar to some BSDI internal functions, but it provides
1042 * for multiple queues for efficiency's sake...
1045 LIST_HEAD(, rttimer_queue
) rttimer_queue_head
;
1046 static int rt_init_done
= 0;
1048 #define RTTIMER_CALLOUT(r) do { \
1049 if (r->rtt_func != NULL) { \
1050 (*r->rtt_func)(r->rtt_rt, r); \
1052 rtrequest((int) RTM_DELETE, \
1053 rt_getkey(r->rtt_rt), \
1056 } while (/*CONSTCOND*/0)
1059 * Some subtle order problems with domain initialization mean that
1060 * we cannot count on this being run from rt_init before various
1061 * protocol initializations are done. Therefore, we make sure
1062 * that this is run when the first queue is added...
1068 assert(rt_init_done
== 0);
1070 LIST_INIT(&rttimer_queue_head
);
1071 callout_init(&rt_timer_ch
, 0);
1072 callout_reset(&rt_timer_ch
, hz
, rt_timer_timer
, NULL
);
1076 struct rttimer_queue
*
1077 rt_timer_queue_create(u_int timeout
)
1079 struct rttimer_queue
*rtq
;
1081 if (rt_init_done
== 0)
1084 R_Malloc(rtq
, struct rttimer_queue
*, sizeof *rtq
);
1087 memset(rtq
, 0, sizeof(*rtq
));
1089 rtq
->rtq_timeout
= timeout
;
1090 TAILQ_INIT(&rtq
->rtq_head
);
1091 LIST_INSERT_HEAD(&rttimer_queue_head
, rtq
, rtq_link
);
1097 rt_timer_queue_change(struct rttimer_queue
*rtq
, long timeout
)
1100 rtq
->rtq_timeout
= timeout
;
1104 rt_timer_queue_remove_all(struct rttimer_queue
*rtq
, int destroy
)
1108 while ((r
= TAILQ_FIRST(&rtq
->rtq_head
)) != NULL
) {
1109 LIST_REMOVE(r
, rtt_link
);
1110 TAILQ_REMOVE(&rtq
->rtq_head
, r
, rtt_next
);
1113 /* we are already at splsoftnet */
1114 pool_put(&rttimer_pool
, r
);
1115 if (rtq
->rtq_count
> 0)
1118 printf("rt_timer_queue_remove_all: "
1119 "rtq_count reached 0\n");
1124 rt_timer_queue_destroy(struct rttimer_queue
*rtq
, int destroy
)
1127 rt_timer_queue_remove_all(rtq
, destroy
);
1129 LIST_REMOVE(rtq
, rtq_link
);
1132 * Caller is responsible for freeing the rttimer_queue structure.
1137 rt_timer_count(struct rttimer_queue
*rtq
)
1139 return rtq
->rtq_count
;
1143 rt_timer_remove_all(struct rtentry
*rt
, int destroy
)
1147 while ((r
= LIST_FIRST(&rt
->rt_timer
)) != NULL
) {
1148 LIST_REMOVE(r
, rtt_link
);
1149 TAILQ_REMOVE(&r
->rtt_queue
->rtq_head
, r
, rtt_next
);
1152 if (r
->rtt_queue
->rtq_count
> 0)
1153 r
->rtt_queue
->rtq_count
--;
1155 printf("rt_timer_remove_all: rtq_count reached 0\n");
1156 /* we are already at splsoftnet */
1157 pool_put(&rttimer_pool
, r
);
1162 rt_timer_add(struct rtentry
*rt
,
1163 void (*func
)(struct rtentry
*, struct rttimer
*),
1164 struct rttimer_queue
*queue
)
1170 * If there's already a timer with this action, destroy it before
1173 LIST_FOREACH(r
, &rt
->rt_timer
, rtt_link
) {
1174 if (r
->rtt_func
== func
)
1178 LIST_REMOVE(r
, rtt_link
);
1179 TAILQ_REMOVE(&r
->rtt_queue
->rtq_head
, r
, rtt_next
);
1180 if (r
->rtt_queue
->rtq_count
> 0)
1181 r
->rtt_queue
->rtq_count
--;
1183 printf("rt_timer_add: rtq_count reached 0\n");
1186 r
= pool_get(&rttimer_pool
, PR_NOWAIT
);
1192 memset(r
, 0, sizeof(*r
));
1195 r
->rtt_time
= time_uptime
;
1197 r
->rtt_queue
= queue
;
1198 LIST_INSERT_HEAD(&rt
->rt_timer
, r
, rtt_link
);
1199 TAILQ_INSERT_TAIL(&queue
->rtq_head
, r
, rtt_next
);
1200 r
->rtt_queue
->rtq_count
++;
1207 rt_timer_timer(void *arg
)
1209 struct rttimer_queue
*rtq
;
1214 LIST_FOREACH(rtq
, &rttimer_queue_head
, rtq_link
) {
1215 while ((r
= TAILQ_FIRST(&rtq
->rtq_head
)) != NULL
&&
1216 (r
->rtt_time
+ rtq
->rtq_timeout
) < time_uptime
) {
1217 LIST_REMOVE(r
, rtt_link
);
1218 TAILQ_REMOVE(&rtq
->rtq_head
, r
, rtt_next
);
1220 pool_put(&rttimer_pool
, r
);
1221 if (rtq
->rtq_count
> 0)
1224 printf("rt_timer_timer: rtq_count reached 0\n");
1229 callout_reset(&rt_timer_ch
, hz
, rt_timer_timer
, NULL
);
1232 static struct rtentry
*
1233 _rtcache_init(struct route
*ro
, int flag
)
1235 rtcache_invariants(ro
);
1236 KASSERT(ro
->_ro_rt
== NULL
);
1238 if (rtcache_getdst(ro
) == NULL
)
1240 ro
->ro_invalid
= false;
1241 if ((ro
->_ro_rt
= rtalloc1(rtcache_getdst(ro
), flag
)) != NULL
)
1244 rtcache_invariants(ro
);
1249 rtcache_init(struct route
*ro
)
1251 return _rtcache_init(ro
, 1);
1255 rtcache_init_noclone(struct route
*ro
)
1257 return _rtcache_init(ro
, 0);
1261 rtcache_update(struct route
*ro
, int clone
)
1264 return _rtcache_init(ro
, clone
);
1268 rtcache_copy(struct route
*new_ro
, const struct route
*old_ro
)
1272 KASSERT(new_ro
!= old_ro
);
1273 rtcache_invariants(new_ro
);
1274 rtcache_invariants(old_ro
);
1276 if ((rt
= rtcache_validate(old_ro
)) != NULL
)
1279 if (rtcache_getdst(old_ro
) == NULL
||
1280 rtcache_setdst(new_ro
, rtcache_getdst(old_ro
)) != 0)
1283 new_ro
->ro_invalid
= false;
1284 if ((new_ro
->_ro_rt
= rt
) != NULL
)
1286 rtcache_invariants(new_ro
);
1289 static struct dom_rtlist invalid_routes
= LIST_HEAD_INITIALIZER(dom_rtlist
);
1292 rtcache_invalidate(struct dom_rtlist
*rtlist
)
1296 while ((ro
= LIST_FIRST(rtlist
)) != NULL
) {
1297 rtcache_invariants(ro
);
1298 KASSERT(ro
->_ro_rt
!= NULL
);
1299 ro
->ro_invalid
= true;
1300 LIST_REMOVE(ro
, ro_rtcache_next
);
1301 LIST_INSERT_HEAD(&invalid_routes
, ro
, ro_rtcache_next
);
1302 rtcache_invariants(ro
);
1307 rtcache_clear(struct route
*ro
)
1309 rtcache_invariants(ro
);
1310 if (ro
->_ro_rt
== NULL
)
1313 LIST_REMOVE(ro
, ro_rtcache_next
);
1317 ro
->ro_invalid
= false;
1318 rtcache_invariants(ro
);
1322 rtcache_lookup2(struct route
*ro
, const struct sockaddr
*dst
, int clone
,
1325 const struct sockaddr
*odst
;
1326 struct rtentry
*rt
= NULL
;
1328 rtcache_invariants(ro
);
1330 odst
= rtcache_getdst(ro
);
1334 else if (sockaddr_cmp(odst
, dst
) != 0)
1336 else if ((rt
= rtcache_validate(ro
)) == NULL
)
1341 if (rtcache_setdst(ro
, dst
) == 0)
1342 rt
= _rtcache_init(ro
, clone
);
1346 rtcache_invariants(ro
);
1352 rtcache_free(struct route
*ro
)
1355 if (ro
->ro_sa
!= NULL
) {
1356 sockaddr_free(ro
->ro_sa
);
1359 rtcache_invariants(ro
);
1363 rtcache_setdst(struct route
*ro
, const struct sockaddr
*sa
)
1365 KASSERT(sa
!= NULL
);
1367 rtcache_invariants(ro
);
1368 if (ro
->ro_sa
!= NULL
&& ro
->ro_sa
->sa_family
== sa
->sa_family
) {
1370 if (sockaddr_copy(ro
->ro_sa
, ro
->ro_sa
->sa_len
, sa
) != NULL
) {
1371 rtcache_invariants(ro
);
1374 sockaddr_free(ro
->ro_sa
);
1375 } else if (ro
->ro_sa
!= NULL
)
1376 rtcache_free(ro
); /* free ro_sa, wrong family */
1378 KASSERT(ro
->_ro_rt
== NULL
);
1380 if ((ro
->ro_sa
= sockaddr_dup(sa
, M_NOWAIT
)) == NULL
) {
1381 rtcache_invariants(ro
);
1384 rtcache_invariants(ro
);
1389 rt_walktree_visitor(struct radix_node
*rn
, void *v
)
1391 struct rtwalk
*rw
= (struct rtwalk
*)v
;
1393 return (*rw
->rw_f
)((struct rtentry
*)rn
, rw
->rw_v
);
1397 rt_walktree(sa_family_t family
, int (*f
)(struct rtentry
*, void *), void *v
)
1399 struct radix_node_head
*rnh
= rt_tables
[family
];
1408 return rn_walktree(rnh
, rt_walktree_visitor
, &rw
);