route.c revision 1.169 1 /* $NetBSD: route.c,v 1.169 2016/07/07 06:55:43 msaitoh Exp $ */
2
3 /*-
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
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.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
19 *
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.
31 */
32
33 /*
34 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
35 * All rights reserved.
36 *
37 * 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 #ifdef _KERNEL_OPT
94 #include "opt_inet.h"
95 #include "opt_route.h"
96 #endif
97
98 #include <sys/cdefs.h>
99 __KERNEL_RCSID(0, "$NetBSD: route.c,v 1.169 2016/07/07 06:55:43 msaitoh Exp $");
100
101 #include <sys/param.h>
102 #ifdef RTFLUSH_DEBUG
103 #include <sys/sysctl.h>
104 #endif
105 #include <sys/systm.h>
106 #include <sys/callout.h>
107 #include <sys/proc.h>
108 #include <sys/mbuf.h>
109 #include <sys/socket.h>
110 #include <sys/socketvar.h>
111 #include <sys/domain.h>
112 #include <sys/protosw.h>
113 #include <sys/kernel.h>
114 #include <sys/ioctl.h>
115 #include <sys/pool.h>
116 #include <sys/kauth.h>
117
118 #include <net/if.h>
119 #include <net/if_dl.h>
120 #include <net/route.h>
121
122 #include <netinet/in.h>
123 #include <netinet/in_var.h>
124
125 #ifdef RTFLUSH_DEBUG
126 #define rtcache_debug() __predict_false(_rtcache_debug)
127 #else /* RTFLUSH_DEBUG */
128 #define rtcache_debug() 0
129 #endif /* RTFLUSH_DEBUG */
130
131 struct rtstat rtstat;
132
133 static int rttrash; /* routes not in table but not freed */
134
135 static struct pool rtentry_pool;
136 static struct pool rttimer_pool;
137
138 static struct callout rt_timer_ch; /* callout for rt_timer_timer() */
139
140 #ifdef RTFLUSH_DEBUG
141 static int _rtcache_debug = 0;
142 #endif /* RTFLUSH_DEBUG */
143
144 static kauth_listener_t route_listener;
145
146 static int rtdeletemsg(struct rtentry *);
147 static void rtflushall(int);
148
149 static void rt_maskedcopy(const struct sockaddr *,
150 struct sockaddr *, const struct sockaddr *);
151
152 static void rtcache_clear(struct route *);
153 static void rtcache_clear_rtentry(int, struct rtentry *);
154 static void rtcache_invalidate(struct dom_rtlist *);
155
156 #ifdef DDB
157 static void db_print_sa(const struct sockaddr *);
158 static void db_print_ifa(struct ifaddr *);
159 static int db_show_rtentry(struct rtentry *, void *);
160 #endif
161
162 #ifdef RTFLUSH_DEBUG
163 static void sysctl_net_rtcache_setup(struct sysctllog **);
164 static void
165 sysctl_net_rtcache_setup(struct sysctllog **clog)
166 {
167 const struct sysctlnode *rnode;
168
169 if (sysctl_createv(clog, 0, NULL, &rnode, CTLFLAG_PERMANENT,
170 CTLTYPE_NODE,
171 "rtcache", SYSCTL_DESCR("Route cache related settings"),
172 NULL, 0, NULL, 0, CTL_NET, CTL_CREATE, CTL_EOL) != 0)
173 return;
174 if (sysctl_createv(clog, 0, &rnode, &rnode,
175 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
176 "debug", SYSCTL_DESCR("Debug route caches"),
177 NULL, 0, &_rtcache_debug, 0, CTL_CREATE, CTL_EOL) != 0)
178 return;
179 }
180 #endif /* RTFLUSH_DEBUG */
181
182 static inline void
183 rt_destroy(struct rtentry *rt)
184 {
185 if (rt->_rt_key != NULL)
186 sockaddr_free(rt->_rt_key);
187 if (rt->rt_gateway != NULL)
188 sockaddr_free(rt->rt_gateway);
189 if (rt_gettag(rt) != NULL)
190 sockaddr_free(rt_gettag(rt));
191 rt->_rt_key = rt->rt_gateway = rt->rt_tag = NULL;
192 }
193
194 static inline const struct sockaddr *
195 rt_setkey(struct rtentry *rt, const struct sockaddr *key, int flags)
196 {
197 if (rt->_rt_key == key)
198 goto out;
199
200 if (rt->_rt_key != NULL)
201 sockaddr_free(rt->_rt_key);
202 rt->_rt_key = sockaddr_dup(key, flags);
203 out:
204 rt->rt_nodes->rn_key = (const char *)rt->_rt_key;
205 return rt->_rt_key;
206 }
207
208 struct ifaddr *
209 rt_get_ifa(struct rtentry *rt)
210 {
211 struct ifaddr *ifa;
212
213 if ((ifa = rt->rt_ifa) == NULL)
214 return ifa;
215 else if (ifa->ifa_getifa == NULL)
216 return ifa;
217 #if 0
218 else if (ifa->ifa_seqno != NULL && *ifa->ifa_seqno == rt->rt_ifa_seqno)
219 return ifa;
220 #endif
221 else {
222 ifa = (*ifa->ifa_getifa)(ifa, rt_getkey(rt));
223 if (ifa == NULL)
224 return NULL;
225 rt_replace_ifa(rt, ifa);
226 return ifa;
227 }
228 }
229
230 static void
231 rt_set_ifa1(struct rtentry *rt, struct ifaddr *ifa)
232 {
233 rt->rt_ifa = ifa;
234 if (ifa->ifa_seqno != NULL)
235 rt->rt_ifa_seqno = *ifa->ifa_seqno;
236 }
237
238 /*
239 * Is this route the connected route for the ifa?
240 */
241 static int
242 rt_ifa_connected(const struct rtentry *rt, const struct ifaddr *ifa)
243 {
244 const struct sockaddr *key, *dst, *odst;
245 struct sockaddr_storage maskeddst;
246
247 key = rt_getkey(rt);
248 dst = rt->rt_flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
249 if (dst == NULL ||
250 dst->sa_family != key->sa_family ||
251 dst->sa_len != key->sa_len)
252 return 0;
253 if ((rt->rt_flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
254 odst = dst;
255 dst = (struct sockaddr *)&maskeddst;
256 rt_maskedcopy(odst, (struct sockaddr *)&maskeddst,
257 ifa->ifa_netmask);
258 }
259 return (memcmp(dst, key, dst->sa_len) == 0);
260 }
261
262 void
263 rt_replace_ifa(struct rtentry *rt, struct ifaddr *ifa)
264 {
265 if (rt->rt_ifa &&
266 rt->rt_ifa != ifa &&
267 rt->rt_ifa->ifa_flags & IFA_ROUTE &&
268 rt_ifa_connected(rt, rt->rt_ifa))
269 {
270 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
271 "replace deleted IFA_ROUTE\n",
272 (void *)rt->_rt_key, (void *)rt->rt_ifa);
273 rt->rt_ifa->ifa_flags &= ~IFA_ROUTE;
274 if (rt_ifa_connected(rt, ifa)) {
275 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
276 "replace added IFA_ROUTE\n",
277 (void *)rt->_rt_key, (void *)ifa);
278 ifa->ifa_flags |= IFA_ROUTE;
279 }
280 }
281
282 ifaref(ifa);
283 ifafree(rt->rt_ifa);
284 rt_set_ifa1(rt, ifa);
285 }
286
287 static void
288 rt_set_ifa(struct rtentry *rt, struct ifaddr *ifa)
289 {
290 ifaref(ifa);
291 rt_set_ifa1(rt, ifa);
292 }
293
294 static int
295 route_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
296 void *arg0, void *arg1, void *arg2, void *arg3)
297 {
298 struct rt_msghdr *rtm;
299 int result;
300
301 result = KAUTH_RESULT_DEFER;
302 rtm = arg1;
303
304 if (action != KAUTH_NETWORK_ROUTE)
305 return result;
306
307 if (rtm->rtm_type == RTM_GET)
308 result = KAUTH_RESULT_ALLOW;
309
310 return result;
311 }
312
313 void
314 rt_init(void)
315 {
316
317 #ifdef RTFLUSH_DEBUG
318 sysctl_net_rtcache_setup(NULL);
319 #endif
320
321 pool_init(&rtentry_pool, sizeof(struct rtentry), 0, 0, 0, "rtentpl",
322 NULL, IPL_SOFTNET);
323 pool_init(&rttimer_pool, sizeof(struct rttimer), 0, 0, 0, "rttmrpl",
324 NULL, IPL_SOFTNET);
325
326 rn_init(); /* initialize all zeroes, all ones, mask table */
327 rtbl_init();
328
329 route_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
330 route_listener_cb, NULL);
331 }
332
333 static void
334 rtflushall(int family)
335 {
336 struct domain *dom;
337
338 if (rtcache_debug())
339 printf("%s: enter\n", __func__);
340
341 if ((dom = pffinddomain(family)) == NULL)
342 return;
343
344 rtcache_invalidate(&dom->dom_rtcache);
345 }
346
347 static void
348 rtcache(struct route *ro)
349 {
350 struct domain *dom;
351
352 rtcache_invariants(ro);
353 KASSERT(ro->_ro_rt != NULL);
354 KASSERT(ro->ro_invalid == false);
355 KASSERT(rtcache_getdst(ro) != NULL);
356
357 if ((dom = pffinddomain(rtcache_getdst(ro)->sa_family)) == NULL)
358 return;
359
360 LIST_INSERT_HEAD(&dom->dom_rtcache, ro, ro_rtcache_next);
361 rtcache_invariants(ro);
362 }
363
364 #ifdef RT_DEBUG
365 static void
366 dump_rt(const struct rtentry *rt)
367 {
368 char buf[512];
369
370 aprint_normal("rt: ");
371 aprint_normal("p=%p ", rt);
372 if (rt->_rt_key == NULL) {
373 aprint_normal("dst=(NULL) ");
374 } else {
375 sockaddr_format(rt->_rt_key, buf, sizeof(buf));
376 aprint_normal("dst=%s ", buf);
377 }
378 if (rt->rt_gateway == NULL) {
379 aprint_normal("gw=(NULL) ");
380 } else {
381 sockaddr_format(rt->_rt_key, buf, sizeof(buf));
382 aprint_normal("gw=%s ", buf);
383 }
384 aprint_normal("flags=%x ", rt->rt_flags);
385 if (rt->rt_ifp == NULL) {
386 aprint_normal("if=(NULL) ");
387 } else {
388 aprint_normal("if=%s ", rt->rt_ifp->if_xname);
389 }
390 aprint_normal("\n");
391 }
392 #endif /* RT_DEBUG */
393
394 /*
395 * Packet routing routines. If success, refcnt of a returned rtentry
396 * will be incremented. The caller has to rtfree it by itself.
397 */
398 struct rtentry *
399 rtalloc1(const struct sockaddr *dst, int report)
400 {
401 rtbl_t *rtbl;
402 struct rtentry *rt;
403 int s;
404
405 s = splsoftnet();
406 rtbl = rt_gettable(dst->sa_family);
407 if (rtbl == NULL)
408 goto miss;
409
410 rt = rt_matchaddr(rtbl, dst);
411 if (rt == NULL)
412 goto miss;
413
414 rt->rt_refcnt++;
415
416 splx(s);
417 return rt;
418 miss:
419 rtstat.rts_unreach++;
420 if (report) {
421 struct rt_addrinfo info;
422
423 memset(&info, 0, sizeof(info));
424 info.rti_info[RTAX_DST] = dst;
425 rt_missmsg(RTM_MISS, &info, 0, 0);
426 }
427 splx(s);
428 return NULL;
429 }
430
431 #ifdef DEBUG
432 /*
433 * Check the following constraint for each rtcache:
434 * if a rtcache holds a rtentry, the rtentry's refcnt is more than zero,
435 * i.e., the rtentry should be referenced at least by the rtcache.
436 */
437 static void
438 rtcache_check_rtrefcnt(int family)
439 {
440 struct domain *dom = pffinddomain(family);
441 struct route *ro;
442
443 if (dom == NULL)
444 return;
445
446 LIST_FOREACH(ro, &dom->dom_rtcache, ro_rtcache_next)
447 KDASSERT(ro->_ro_rt == NULL || ro->_ro_rt->rt_refcnt > 0);
448 }
449 #endif
450
451 void
452 rtfree(struct rtentry *rt)
453 {
454 struct ifaddr *ifa;
455
456 KASSERT(rt != NULL);
457 KASSERT(rt->rt_refcnt > 0);
458
459 rt->rt_refcnt--;
460 #ifdef DEBUG
461 if (rt_getkey(rt) != NULL)
462 rtcache_check_rtrefcnt(rt_getkey(rt)->sa_family);
463 #endif
464 if (rt->rt_refcnt == 0 && (rt->rt_flags & RTF_UP) == 0) {
465 rt_assert_inactive(rt);
466 rttrash--;
467 rt_timer_remove_all(rt, 0);
468 ifa = rt->rt_ifa;
469 rt->rt_ifa = NULL;
470 ifafree(ifa);
471 rt->rt_ifp = NULL;
472 rt_destroy(rt);
473 pool_put(&rtentry_pool, rt);
474 }
475 }
476
477 /*
478 * Force a routing table entry to the specified
479 * destination to go through the given gateway.
480 * Normally called as a result of a routing redirect
481 * message from the network layer.
482 *
483 * N.B.: must be called at splsoftnet
484 */
485 void
486 rtredirect(const struct sockaddr *dst, const struct sockaddr *gateway,
487 const struct sockaddr *netmask, int flags, const struct sockaddr *src,
488 struct rtentry **rtp)
489 {
490 struct rtentry *rt;
491 int error = 0;
492 uint64_t *stat = NULL;
493 struct rt_addrinfo info;
494 struct ifaddr *ifa;
495
496 /* verify the gateway is directly reachable */
497 if ((ifa = ifa_ifwithnet(gateway)) == NULL) {
498 error = ENETUNREACH;
499 goto out;
500 }
501 rt = rtalloc1(dst, 0);
502 /*
503 * If the redirect isn't from our current router for this dst,
504 * it's either old or wrong. If it redirects us to ourselves,
505 * we have a routing loop, perhaps as a result of an interface
506 * going down recently.
507 */
508 if (!(flags & RTF_DONE) && rt &&
509 (sockaddr_cmp(src, rt->rt_gateway) != 0 || rt->rt_ifa != ifa))
510 error = EINVAL;
511 else if (ifa_ifwithaddr(gateway))
512 error = EHOSTUNREACH;
513 if (error)
514 goto done;
515 /*
516 * Create a new entry if we just got back a wildcard entry
517 * or the lookup failed. This is necessary for hosts
518 * which use routing redirects generated by smart gateways
519 * to dynamically build the routing tables.
520 */
521 if (rt == NULL || (rt_mask(rt) && rt_mask(rt)->sa_len < 2))
522 goto create;
523 /*
524 * Don't listen to the redirect if it's
525 * for a route to an interface.
526 */
527 if (rt->rt_flags & RTF_GATEWAY) {
528 if (((rt->rt_flags & RTF_HOST) == 0) && (flags & RTF_HOST)) {
529 /*
530 * Changing from route to net => route to host.
531 * Create new route, rather than smashing route to net.
532 */
533 create:
534 if (rt != NULL)
535 rtfree(rt);
536 flags |= RTF_GATEWAY | RTF_DYNAMIC;
537 memset(&info, 0, sizeof(info));
538 info.rti_info[RTAX_DST] = dst;
539 info.rti_info[RTAX_GATEWAY] = gateway;
540 info.rti_info[RTAX_NETMASK] = netmask;
541 info.rti_ifa = ifa;
542 info.rti_flags = flags;
543 rt = NULL;
544 error = rtrequest1(RTM_ADD, &info, &rt);
545 if (rt != NULL)
546 flags = rt->rt_flags;
547 stat = &rtstat.rts_dynamic;
548 } else {
549 /*
550 * Smash the current notion of the gateway to
551 * this destination. Should check about netmask!!!
552 */
553 error = rt_setgate(rt, gateway);
554 if (error == 0) {
555 rt->rt_flags |= RTF_MODIFIED;
556 flags |= RTF_MODIFIED;
557 }
558 stat = &rtstat.rts_newgateway;
559 }
560 } else
561 error = EHOSTUNREACH;
562 done:
563 if (rt) {
564 if (rtp != NULL && !error)
565 *rtp = rt;
566 else
567 rtfree(rt);
568 }
569 out:
570 if (error)
571 rtstat.rts_badredirect++;
572 else if (stat != NULL)
573 (*stat)++;
574 memset(&info, 0, sizeof(info));
575 info.rti_info[RTAX_DST] = dst;
576 info.rti_info[RTAX_GATEWAY] = gateway;
577 info.rti_info[RTAX_NETMASK] = netmask;
578 info.rti_info[RTAX_AUTHOR] = src;
579 rt_missmsg(RTM_REDIRECT, &info, flags, error);
580 }
581
582 /*
583 * Delete a route and generate a message.
584 * It doesn't free a passed rt.
585 */
586 static int
587 rtdeletemsg(struct rtentry *rt)
588 {
589 int error;
590 struct rt_addrinfo info;
591
592 /*
593 * Request the new route so that the entry is not actually
594 * deleted. That will allow the information being reported to
595 * be accurate (and consistent with route_output()).
596 */
597 memset(&info, 0, sizeof(info));
598 info.rti_info[RTAX_DST] = rt_getkey(rt);
599 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
600 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
601 info.rti_flags = rt->rt_flags;
602 error = rtrequest1(RTM_DELETE, &info, NULL);
603
604 rt_missmsg(RTM_DELETE, &info, info.rti_flags, error);
605
606 return error;
607 }
608
609 struct ifaddr *
610 ifa_ifwithroute(int flags, const struct sockaddr *dst,
611 const struct sockaddr *gateway)
612 {
613 struct ifaddr *ifa;
614 if ((flags & RTF_GATEWAY) == 0) {
615 /*
616 * If we are adding a route to an interface,
617 * and the interface is a pt to pt link
618 * we should search for the destination
619 * as our clue to the interface. Otherwise
620 * we can use the local address.
621 */
622 ifa = NULL;
623 if ((flags & RTF_HOST) && gateway->sa_family != AF_LINK)
624 ifa = ifa_ifwithdstaddr(dst);
625 if (ifa == NULL)
626 ifa = ifa_ifwithaddr(gateway);
627 } else {
628 /*
629 * If we are adding a route to a remote net
630 * or host, the gateway may still be on the
631 * other end of a pt to pt link.
632 */
633 ifa = ifa_ifwithdstaddr(gateway);
634 }
635 if (ifa == NULL)
636 ifa = ifa_ifwithnet(gateway);
637 if (ifa == NULL) {
638 struct rtentry *rt = rtalloc1(dst, 0);
639 if (rt == NULL)
640 return NULL;
641 ifa = rt->rt_ifa;
642 rtfree(rt);
643 if (ifa == NULL)
644 return NULL;
645 }
646 if (ifa->ifa_addr->sa_family != dst->sa_family) {
647 struct ifaddr *oifa = ifa;
648 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
649 if (ifa == NULL)
650 ifa = oifa;
651 }
652 return ifa;
653 }
654
655 /*
656 * If it suceeds and ret_nrt isn't NULL, refcnt of ret_nrt is incremented.
657 * The caller has to rtfree it by itself.
658 */
659 int
660 rtrequest(int req, const struct sockaddr *dst, const struct sockaddr *gateway,
661 const struct sockaddr *netmask, int flags, struct rtentry **ret_nrt)
662 {
663 struct rt_addrinfo info;
664
665 memset(&info, 0, sizeof(info));
666 info.rti_flags = flags;
667 info.rti_info[RTAX_DST] = dst;
668 info.rti_info[RTAX_GATEWAY] = gateway;
669 info.rti_info[RTAX_NETMASK] = netmask;
670 return rtrequest1(req, &info, ret_nrt);
671 }
672
673 /*
674 * It's a utility function to add/remove a route to/from the routing table
675 * and tell user processes the addition/removal on success.
676 */
677 int
678 rtrequest_newmsg(const int req, const struct sockaddr *dst,
679 const struct sockaddr *gateway, const struct sockaddr *netmask,
680 const int flags)
681 {
682 int error;
683 struct rtentry *ret_nrt = NULL;
684
685 KASSERT(req == RTM_ADD || req == RTM_DELETE);
686
687 error = rtrequest(req, dst, gateway, netmask, flags, &ret_nrt);
688 if (error != 0)
689 return error;
690
691 KASSERT(ret_nrt != NULL);
692
693 rt_newmsg(req, ret_nrt); /* tell user process */
694 rtfree(ret_nrt);
695
696 return 0;
697 }
698
699 int
700 rt_getifa(struct rt_addrinfo *info)
701 {
702 struct ifaddr *ifa;
703 const struct sockaddr *dst = info->rti_info[RTAX_DST];
704 const struct sockaddr *gateway = info->rti_info[RTAX_GATEWAY];
705 const struct sockaddr *ifaaddr = info->rti_info[RTAX_IFA];
706 const struct sockaddr *ifpaddr = info->rti_info[RTAX_IFP];
707 int flags = info->rti_flags;
708
709 /*
710 * ifp may be specified by sockaddr_dl when protocol address
711 * is ambiguous
712 */
713 if (info->rti_ifp == NULL && ifpaddr != NULL
714 && ifpaddr->sa_family == AF_LINK &&
715 (ifa = ifa_ifwithnet(ifpaddr)) != NULL)
716 info->rti_ifp = ifa->ifa_ifp;
717 if (info->rti_ifa == NULL && ifaaddr != NULL)
718 info->rti_ifa = ifa_ifwithaddr(ifaaddr);
719 if (info->rti_ifa == NULL) {
720 const struct sockaddr *sa;
721
722 sa = ifaaddr != NULL ? ifaaddr :
723 (gateway != NULL ? gateway : dst);
724 if (sa != NULL && info->rti_ifp != NULL)
725 info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp);
726 else if (dst != NULL && gateway != NULL)
727 info->rti_ifa = ifa_ifwithroute(flags, dst, gateway);
728 else if (sa != NULL)
729 info->rti_ifa = ifa_ifwithroute(flags, sa, sa);
730 }
731 if ((ifa = info->rti_ifa) == NULL)
732 return ENETUNREACH;
733 if (ifa->ifa_getifa != NULL) {
734 info->rti_ifa = ifa = (*ifa->ifa_getifa)(ifa, dst);
735 if (ifa == NULL)
736 return ENETUNREACH;
737 }
738 if (info->rti_ifp == NULL)
739 info->rti_ifp = ifa->ifa_ifp;
740 return 0;
741 }
742
743 /*
744 * If it suceeds and ret_nrt isn't NULL, refcnt of ret_nrt is incremented.
745 * The caller has to rtfree it by itself.
746 */
747 int
748 rtrequest1(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt)
749 {
750 int s = splsoftnet();
751 int error = 0, rc;
752 struct rtentry *rt;
753 rtbl_t *rtbl;
754 struct ifaddr *ifa, *ifa2;
755 struct sockaddr_storage maskeddst;
756 const struct sockaddr *dst = info->rti_info[RTAX_DST];
757 const struct sockaddr *gateway = info->rti_info[RTAX_GATEWAY];
758 const struct sockaddr *netmask = info->rti_info[RTAX_NETMASK];
759 int flags = info->rti_flags;
760 #define senderr(x) { error = x ; goto bad; }
761
762 if ((rtbl = rt_gettable(dst->sa_family)) == NULL)
763 senderr(ESRCH);
764 if (flags & RTF_HOST)
765 netmask = NULL;
766 switch (req) {
767 case RTM_DELETE:
768 if (netmask) {
769 rt_maskedcopy(dst, (struct sockaddr *)&maskeddst,
770 netmask);
771 dst = (struct sockaddr *)&maskeddst;
772 }
773 if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)
774 senderr(ESRCH);
775 if ((rt = rt_deladdr(rtbl, dst, netmask)) == NULL)
776 senderr(ESRCH);
777 rt->rt_flags &= ~RTF_UP;
778 if ((ifa = rt->rt_ifa)) {
779 if (ifa->ifa_flags & IFA_ROUTE &&
780 rt_ifa_connected(rt, ifa)) {
781 RT_DPRINTF("rt->_rt_key = %p, ifa = %p, "
782 "deleted IFA_ROUTE\n",
783 (void *)rt->_rt_key, (void *)ifa);
784 ifa->ifa_flags &= ~IFA_ROUTE;
785 }
786 if (ifa->ifa_rtrequest)
787 ifa->ifa_rtrequest(RTM_DELETE, rt, info);
788 }
789 rttrash++;
790 if (ret_nrt) {
791 *ret_nrt = rt;
792 rt->rt_refcnt++;
793 } else if (rt->rt_refcnt <= 0) {
794 /* Adjust the refcount */
795 rt->rt_refcnt++;
796 rtfree(rt);
797 }
798 rtcache_clear_rtentry(dst->sa_family, rt);
799 break;
800
801 case RTM_ADD:
802 if (info->rti_ifa == NULL && (error = rt_getifa(info)))
803 senderr(error);
804 ifa = info->rti_ifa;
805 rt = pool_get(&rtentry_pool, PR_NOWAIT);
806 if (rt == NULL)
807 senderr(ENOBUFS);
808 memset(rt, 0, sizeof(*rt));
809 rt->rt_flags = RTF_UP | flags;
810 LIST_INIT(&rt->rt_timer);
811
812 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
813 if (netmask) {
814 rt_maskedcopy(dst, (struct sockaddr *)&maskeddst,
815 netmask);
816 rt_setkey(rt, (struct sockaddr *)&maskeddst, M_NOWAIT);
817 } else {
818 rt_setkey(rt, dst, M_NOWAIT);
819 }
820 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
821 if (rt_getkey(rt) == NULL ||
822 rt_setgate(rt, gateway) != 0) {
823 pool_put(&rtentry_pool, rt);
824 senderr(ENOBUFS);
825 }
826
827 rt_set_ifa(rt, ifa);
828 if (info->rti_info[RTAX_TAG] != NULL) {
829 const struct sockaddr *tag;
830 tag = rt_settag(rt, info->rti_info[RTAX_TAG]);
831 if (tag == NULL)
832 senderr(ENOBUFS);
833 }
834 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
835 if (info->rti_info[RTAX_IFP] != NULL &&
836 (ifa2 = ifa_ifwithnet(info->rti_info[RTAX_IFP])) != NULL &&
837 ifa2->ifa_ifp != NULL)
838 rt->rt_ifp = ifa2->ifa_ifp;
839 else
840 rt->rt_ifp = ifa->ifa_ifp;
841 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
842 rc = rt_addaddr(rtbl, rt, netmask);
843 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
844 if (rc != 0) {
845 ifafree(ifa);
846 rt_destroy(rt);
847 pool_put(&rtentry_pool, rt);
848 senderr(rc);
849 }
850 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
851 if (ifa->ifa_rtrequest)
852 ifa->ifa_rtrequest(req, rt, info);
853 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
854 if (ret_nrt) {
855 *ret_nrt = rt;
856 rt->rt_refcnt++;
857 }
858 rtflushall(dst->sa_family);
859 break;
860 case RTM_GET:
861 if (netmask != NULL) {
862 rt_maskedcopy(dst, (struct sockaddr *)&maskeddst,
863 netmask);
864 dst = (struct sockaddr *)&maskeddst;
865 }
866 if ((rt = rt_lookup(rtbl, dst, netmask)) == NULL)
867 senderr(ESRCH);
868 if (ret_nrt != NULL) {
869 *ret_nrt = rt;
870 rt->rt_refcnt++;
871 }
872 break;
873 }
874 bad:
875 splx(s);
876 return error;
877 }
878
879 int
880 rt_setgate(struct rtentry *rt, const struct sockaddr *gate)
881 {
882
883 KASSERT(rt->_rt_key != NULL);
884 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
885
886 if (rt->rt_gateway != NULL)
887 sockaddr_free(rt->rt_gateway);
888 KASSERT(rt->_rt_key != NULL);
889 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
890 if ((rt->rt_gateway = sockaddr_dup(gate, M_ZERO | M_NOWAIT)) == NULL)
891 return ENOMEM;
892 KASSERT(rt->_rt_key != NULL);
893 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
894
895 if (rt->rt_flags & RTF_GATEWAY) {
896 struct rtentry *gwrt = rtalloc1(gate, 1);
897 /*
898 * If we switched gateways, grab the MTU from the new
899 * gateway route if the current MTU, if the current MTU is
900 * greater than the MTU of gateway.
901 * Note that, if the MTU of gateway is 0, we will reset the
902 * MTU of the route to run PMTUD again from scratch. XXX
903 */
904 if (gwrt != NULL) {
905 KASSERT(gwrt->_rt_key != NULL);
906 RT_DPRINTF("gwrt->_rt_key = %p\n", gwrt->_rt_key);
907 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
908 rt->rt_rmx.rmx_mtu &&
909 rt->rt_rmx.rmx_mtu > gwrt->rt_rmx.rmx_mtu) {
910 rt->rt_rmx.rmx_mtu = gwrt->rt_rmx.rmx_mtu;
911 }
912 rtfree(gwrt);
913 }
914 }
915 KASSERT(rt->_rt_key != NULL);
916 RT_DPRINTF("rt->_rt_key = %p\n", (void *)rt->_rt_key);
917 return 0;
918 }
919
920 static void
921 rt_maskedcopy(const struct sockaddr *src, struct sockaddr *dst,
922 const struct sockaddr *netmask)
923 {
924 const char *netmaskp = &netmask->sa_data[0],
925 *srcp = &src->sa_data[0];
926 char *dstp = &dst->sa_data[0];
927 const char *maskend = (char *)dst + MIN(netmask->sa_len, src->sa_len);
928 const char *srcend = (char *)dst + src->sa_len;
929
930 dst->sa_len = src->sa_len;
931 dst->sa_family = src->sa_family;
932
933 while (dstp < maskend)
934 *dstp++ = *srcp++ & *netmaskp++;
935 if (dstp < srcend)
936 memset(dstp, 0, (size_t)(srcend - dstp));
937 }
938
939 /*
940 * Inform the routing socket of a route change.
941 */
942 void
943 rt_newmsg(const int cmd, const struct rtentry *rt)
944 {
945 struct rt_addrinfo info;
946
947 memset((void *)&info, 0, sizeof(info));
948 info.rti_info[RTAX_DST] = rt_getkey(rt);
949 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
950 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
951 if (rt->rt_ifp) {
952 info.rti_info[RTAX_IFP] = rt->rt_ifp->if_dl->ifa_addr;
953 info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
954 }
955
956 rt_missmsg(cmd, &info, rt->rt_flags, 0);
957 }
958
959 /*
960 * Set up or tear down a routing table entry, normally
961 * for an interface.
962 */
963 int
964 rtinit(struct ifaddr *ifa, int cmd, int flags)
965 {
966 struct rtentry *rt;
967 struct sockaddr *dst, *odst;
968 struct sockaddr_storage maskeddst;
969 struct rtentry *nrt = NULL;
970 int error;
971 struct rt_addrinfo info;
972
973 dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;
974 if (cmd == RTM_DELETE) {
975 if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {
976 /* Delete subnet route for this interface */
977 odst = dst;
978 dst = (struct sockaddr *)&maskeddst;
979 rt_maskedcopy(odst, dst, ifa->ifa_netmask);
980 }
981 if ((rt = rtalloc1(dst, 0)) != NULL) {
982 if (rt->rt_ifa != ifa) {
983 rtfree(rt);
984 return (flags & RTF_HOST) ? EHOSTUNREACH
985 : ENETUNREACH;
986 }
987 rtfree(rt);
988 }
989 }
990 memset(&info, 0, sizeof(info));
991 info.rti_ifa = ifa;
992 info.rti_flags = flags | ifa->ifa_flags;
993 info.rti_info[RTAX_DST] = dst;
994 info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr;
995
996 /*
997 * XXX here, it seems that we are assuming that ifa_netmask is NULL
998 * for RTF_HOST. bsdi4 passes NULL explicitly (via intermediate
999 * variable) when RTF_HOST is 1. still not sure if i can safely
1000 * change it to meet bsdi4 behavior.
1001 */
1002 if (cmd != RTM_LLINFO_UPD)
1003 info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask;
1004 error = rtrequest1((cmd == RTM_LLINFO_UPD) ? RTM_GET : cmd, &info,
1005 &nrt);
1006 if (error != 0)
1007 return error;
1008
1009 rt = nrt;
1010 switch (cmd) {
1011 case RTM_DELETE:
1012 rt_newmsg(cmd, rt);
1013 break;
1014 case RTM_LLINFO_UPD:
1015 if (cmd == RTM_LLINFO_UPD && ifa->ifa_rtrequest != NULL)
1016 ifa->ifa_rtrequest(RTM_LLINFO_UPD, rt, &info);
1017 rt_newmsg(RTM_CHANGE, rt);
1018 break;
1019 case RTM_ADD:
1020 if (rt->rt_ifa != ifa) {
1021 printf("rtinit: wrong ifa (%p) was (%p)\n", ifa,
1022 rt->rt_ifa);
1023 if (rt->rt_ifa->ifa_rtrequest != NULL) {
1024 rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt,
1025 &info);
1026 }
1027 rt_replace_ifa(rt, ifa);
1028 rt->rt_ifp = ifa->ifa_ifp;
1029 if (ifa->ifa_rtrequest != NULL)
1030 ifa->ifa_rtrequest(RTM_ADD, rt, &info);
1031 }
1032 rt_newmsg(cmd, rt);
1033 break;
1034 }
1035 rtfree(rt);
1036 return error;
1037 }
1038
1039 /*
1040 * Create a local route entry for the address.
1041 * Announce the addition of the address and the route to the routing socket.
1042 */
1043 int
1044 rt_ifa_addlocal(struct ifaddr *ifa)
1045 {
1046 struct rtentry *rt;
1047 int e;
1048
1049 /* If there is no loopback entry, allocate one. */
1050 rt = rtalloc1(ifa->ifa_addr, 0);
1051 #ifdef RT_DEBUG
1052 if (rt != NULL)
1053 dump_rt(rt);
1054 #endif
1055 if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
1056 (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
1057 {
1058 struct rt_addrinfo info;
1059 struct rtentry *nrt;
1060
1061 memset(&info, 0, sizeof(info));
1062 info.rti_flags = RTF_HOST | RTF_LOCAL;
1063 if (!(ifa->ifa_ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)))
1064 info.rti_flags |= RTF_LLDATA;
1065 info.rti_info[RTAX_DST] = ifa->ifa_addr;
1066 info.rti_info[RTAX_GATEWAY] =
1067 (const struct sockaddr *)ifa->ifa_ifp->if_sadl;
1068 info.rti_ifa = ifa;
1069 nrt = NULL;
1070 e = rtrequest1(RTM_ADD, &info, &nrt);
1071 if (nrt && ifa != nrt->rt_ifa)
1072 rt_replace_ifa(nrt, ifa);
1073 rt_newaddrmsg(RTM_ADD, ifa, e, nrt);
1074 if (nrt != NULL) {
1075 #ifdef RT_DEBUG
1076 dump_rt(nrt);
1077 #endif
1078 rtfree(nrt);
1079 }
1080 } else {
1081 e = 0;
1082 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
1083 }
1084 if (rt != NULL)
1085 rtfree(rt);
1086 return e;
1087 }
1088
1089 /*
1090 * Remove the local route entry for the address.
1091 * Announce the removal of the address and the route to the routing socket.
1092 */
1093 int
1094 rt_ifa_remlocal(struct ifaddr *ifa, struct ifaddr *alt_ifa)
1095 {
1096 struct rtentry *rt;
1097 int e = 0;
1098
1099 rt = rtalloc1(ifa->ifa_addr, 0);
1100
1101 /*
1102 * Before deleting, check if a corresponding loopbacked
1103 * host route surely exists. With this check, we can avoid
1104 * deleting an interface direct route whose destination is
1105 * the same as the address being removed. This can happen
1106 * when removing a subnet-router anycast address on an
1107 * interface attached to a shared medium.
1108 */
1109 if (rt != NULL &&
1110 (rt->rt_flags & RTF_HOST) &&
1111 (rt->rt_ifp->if_flags & IFF_LOOPBACK))
1112 {
1113 /* If we cannot replace the route's ifaddr with the equivalent
1114 * ifaddr of another interface, I believe it is safest to
1115 * delete the route.
1116 */
1117 if (alt_ifa == NULL) {
1118 e = rtdeletemsg(rt);
1119 rt_newaddrmsg(RTM_DELADDR, ifa, 0, NULL);
1120 } else {
1121 rt_replace_ifa(rt, alt_ifa);
1122 rt_newmsg(RTM_CHANGE, rt);
1123 }
1124 } else
1125 rt_newaddrmsg(RTM_DELADDR, ifa, 0, NULL);
1126 if (rt != NULL)
1127 rtfree(rt);
1128 return e;
1129 }
1130
1131 /*
1132 * Route timer routines. These routes allow functions to be called
1133 * for various routes at any time. This is useful in supporting
1134 * path MTU discovery and redirect route deletion.
1135 *
1136 * This is similar to some BSDI internal functions, but it provides
1137 * for multiple queues for efficiency's sake...
1138 */
1139
1140 LIST_HEAD(, rttimer_queue) rttimer_queue_head;
1141 static int rt_init_done = 0;
1142
1143 /*
1144 * Some subtle order problems with domain initialization mean that
1145 * we cannot count on this being run from rt_init before various
1146 * protocol initializations are done. Therefore, we make sure
1147 * that this is run when the first queue is added...
1148 */
1149
1150 void
1151 rt_timer_init(void)
1152 {
1153 assert(rt_init_done == 0);
1154
1155 LIST_INIT(&rttimer_queue_head);
1156 callout_init(&rt_timer_ch, 0);
1157 callout_reset(&rt_timer_ch, hz, rt_timer_timer, NULL);
1158 rt_init_done = 1;
1159 }
1160
1161 struct rttimer_queue *
1162 rt_timer_queue_create(u_int timeout)
1163 {
1164 struct rttimer_queue *rtq;
1165
1166 if (rt_init_done == 0)
1167 rt_timer_init();
1168
1169 R_Malloc(rtq, struct rttimer_queue *, sizeof *rtq);
1170 if (rtq == NULL)
1171 return NULL;
1172 memset(rtq, 0, sizeof(*rtq));
1173
1174 rtq->rtq_timeout = timeout;
1175 TAILQ_INIT(&rtq->rtq_head);
1176 LIST_INSERT_HEAD(&rttimer_queue_head, rtq, rtq_link);
1177
1178 return rtq;
1179 }
1180
1181 void
1182 rt_timer_queue_change(struct rttimer_queue *rtq, long timeout)
1183 {
1184
1185 rtq->rtq_timeout = timeout;
1186 }
1187
1188 void
1189 rt_timer_queue_remove_all(struct rttimer_queue *rtq, int destroy)
1190 {
1191 struct rttimer *r;
1192
1193 while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL) {
1194 LIST_REMOVE(r, rtt_link);
1195 TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
1196 if (destroy)
1197 (*r->rtt_func)(r->rtt_rt, r);
1198 rtfree(r->rtt_rt);
1199 pool_put(&rttimer_pool, r);
1200 if (rtq->rtq_count > 0)
1201 rtq->rtq_count--;
1202 else
1203 printf("rt_timer_queue_remove_all: "
1204 "rtq_count reached 0\n");
1205 }
1206 }
1207
1208 void
1209 rt_timer_queue_destroy(struct rttimer_queue *rtq, int destroy)
1210 {
1211
1212 rt_timer_queue_remove_all(rtq, destroy);
1213
1214 LIST_REMOVE(rtq, rtq_link);
1215
1216 /*
1217 * Caller is responsible for freeing the rttimer_queue structure.
1218 */
1219 }
1220
1221 unsigned long
1222 rt_timer_count(struct rttimer_queue *rtq)
1223 {
1224 return rtq->rtq_count;
1225 }
1226
1227 void
1228 rt_timer_remove_all(struct rtentry *rt, int destroy)
1229 {
1230 struct rttimer *r;
1231
1232 while ((r = LIST_FIRST(&rt->rt_timer)) != NULL) {
1233 LIST_REMOVE(r, rtt_link);
1234 TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
1235 if (destroy)
1236 (*r->rtt_func)(r->rtt_rt, r);
1237 if (r->rtt_queue->rtq_count > 0)
1238 r->rtt_queue->rtq_count--;
1239 else
1240 printf("rt_timer_remove_all: rtq_count reached 0\n");
1241 rtfree(r->rtt_rt);
1242 pool_put(&rttimer_pool, r);
1243 }
1244 }
1245
1246 int
1247 rt_timer_add(struct rtentry *rt,
1248 void (*func)(struct rtentry *, struct rttimer *),
1249 struct rttimer_queue *queue)
1250 {
1251 struct rttimer *r;
1252
1253 KASSERT(func != NULL);
1254 /*
1255 * If there's already a timer with this action, destroy it before
1256 * we add a new one.
1257 */
1258 LIST_FOREACH(r, &rt->rt_timer, rtt_link) {
1259 if (r->rtt_func == func)
1260 break;
1261 }
1262 if (r != NULL) {
1263 LIST_REMOVE(r, rtt_link);
1264 TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
1265 if (r->rtt_queue->rtq_count > 0)
1266 r->rtt_queue->rtq_count--;
1267 else
1268 printf("rt_timer_add: rtq_count reached 0\n");
1269 rtfree(r->rtt_rt);
1270 } else {
1271 r = pool_get(&rttimer_pool, PR_NOWAIT);
1272 if (r == NULL)
1273 return ENOBUFS;
1274 }
1275
1276 memset(r, 0, sizeof(*r));
1277
1278 rt->rt_refcnt++;
1279 r->rtt_rt = rt;
1280 r->rtt_time = time_uptime;
1281 r->rtt_func = func;
1282 r->rtt_queue = queue;
1283 LIST_INSERT_HEAD(&rt->rt_timer, r, rtt_link);
1284 TAILQ_INSERT_TAIL(&queue->rtq_head, r, rtt_next);
1285 r->rtt_queue->rtq_count++;
1286
1287 return 0;
1288 }
1289
1290 /* ARGSUSED */
1291 void
1292 rt_timer_timer(void *arg)
1293 {
1294 struct rttimer_queue *rtq;
1295 struct rttimer *r;
1296 int s;
1297
1298 s = splsoftnet();
1299 LIST_FOREACH(rtq, &rttimer_queue_head, rtq_link) {
1300 while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL &&
1301 (r->rtt_time + rtq->rtq_timeout) < time_uptime) {
1302 LIST_REMOVE(r, rtt_link);
1303 TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
1304 (*r->rtt_func)(r->rtt_rt, r);
1305 rtfree(r->rtt_rt);
1306 pool_put(&rttimer_pool, r);
1307 if (rtq->rtq_count > 0)
1308 rtq->rtq_count--;
1309 else
1310 printf("rt_timer_timer: rtq_count reached 0\n");
1311 }
1312 }
1313 splx(s);
1314
1315 callout_reset(&rt_timer_ch, hz, rt_timer_timer, NULL);
1316 }
1317
1318 static struct rtentry *
1319 _rtcache_init(struct route *ro, int flag)
1320 {
1321 rtcache_invariants(ro);
1322 KASSERT(ro->_ro_rt == NULL);
1323
1324 if (rtcache_getdst(ro) == NULL)
1325 return NULL;
1326 ro->ro_invalid = false;
1327 if ((ro->_ro_rt = rtalloc1(rtcache_getdst(ro), flag)) != NULL)
1328 rtcache(ro);
1329
1330 rtcache_invariants(ro);
1331 return ro->_ro_rt;
1332 }
1333
1334 struct rtentry *
1335 rtcache_init(struct route *ro)
1336 {
1337 return _rtcache_init(ro, 1);
1338 }
1339
1340 struct rtentry *
1341 rtcache_init_noclone(struct route *ro)
1342 {
1343 return _rtcache_init(ro, 0);
1344 }
1345
1346 struct rtentry *
1347 rtcache_update(struct route *ro, int clone)
1348 {
1349 rtcache_clear(ro);
1350 return _rtcache_init(ro, clone);
1351 }
1352
1353 void
1354 rtcache_copy(struct route *new_ro, const struct route *old_ro)
1355 {
1356 struct rtentry *rt;
1357
1358 KASSERT(new_ro != old_ro);
1359 rtcache_invariants(new_ro);
1360 rtcache_invariants(old_ro);
1361
1362 if ((rt = rtcache_validate(old_ro)) != NULL)
1363 rt->rt_refcnt++;
1364
1365 if (rtcache_getdst(old_ro) == NULL ||
1366 rtcache_setdst(new_ro, rtcache_getdst(old_ro)) != 0)
1367 return;
1368
1369 new_ro->ro_invalid = false;
1370 if ((new_ro->_ro_rt = rt) != NULL)
1371 rtcache(new_ro);
1372 rtcache_invariants(new_ro);
1373 }
1374
1375 static struct dom_rtlist invalid_routes = LIST_HEAD_INITIALIZER(dom_rtlist);
1376
1377 static void
1378 rtcache_invalidate(struct dom_rtlist *rtlist)
1379 {
1380 struct route *ro;
1381
1382 while ((ro = LIST_FIRST(rtlist)) != NULL) {
1383 rtcache_invariants(ro);
1384 KASSERT(ro->_ro_rt != NULL);
1385 ro->ro_invalid = true;
1386 LIST_REMOVE(ro, ro_rtcache_next);
1387 LIST_INSERT_HEAD(&invalid_routes, ro, ro_rtcache_next);
1388 rtcache_invariants(ro);
1389 }
1390 }
1391
1392 static void
1393 rtcache_clear_rtentry(int family, struct rtentry *rt)
1394 {
1395 struct domain *dom;
1396 struct route *ro;
1397
1398 if ((dom = pffinddomain(family)) == NULL)
1399 return;
1400
1401 LIST_FOREACH(ro, &dom->dom_rtcache, ro_rtcache_next) {
1402 if (ro->_ro_rt == rt)
1403 rtcache_clear(ro);
1404 }
1405 }
1406
1407 static void
1408 rtcache_clear(struct route *ro)
1409 {
1410 rtcache_invariants(ro);
1411 if (ro->_ro_rt == NULL)
1412 return;
1413
1414 LIST_REMOVE(ro, ro_rtcache_next);
1415
1416 rtfree(ro->_ro_rt);
1417 ro->_ro_rt = NULL;
1418 ro->ro_invalid = false;
1419 rtcache_invariants(ro);
1420 }
1421
1422 struct rtentry *
1423 rtcache_lookup2(struct route *ro, const struct sockaddr *dst, int clone,
1424 int *hitp)
1425 {
1426 const struct sockaddr *odst;
1427 struct rtentry *rt = NULL;
1428
1429 odst = rtcache_getdst(ro);
1430 if (odst == NULL)
1431 goto miss;
1432
1433 if (sockaddr_cmp(odst, dst) != 0) {
1434 rtcache_free(ro);
1435 goto miss;
1436 }
1437
1438 rt = rtcache_validate(ro);
1439 if (rt == NULL) {
1440 rtcache_clear(ro);
1441 goto miss;
1442 }
1443
1444 *hitp = 1;
1445 rtcache_invariants(ro);
1446
1447 return rt;
1448 miss:
1449 *hitp = 0;
1450 if (rtcache_setdst(ro, dst) == 0)
1451 rt = _rtcache_init(ro, clone);
1452
1453 rtcache_invariants(ro);
1454
1455 return rt;
1456 }
1457
1458 void
1459 rtcache_free(struct route *ro)
1460 {
1461 rtcache_clear(ro);
1462 if (ro->ro_sa != NULL) {
1463 sockaddr_free(ro->ro_sa);
1464 ro->ro_sa = NULL;
1465 }
1466 rtcache_invariants(ro);
1467 }
1468
1469 int
1470 rtcache_setdst(struct route *ro, const struct sockaddr *sa)
1471 {
1472 KASSERT(sa != NULL);
1473
1474 rtcache_invariants(ro);
1475 if (ro->ro_sa != NULL) {
1476 if (ro->ro_sa->sa_family == sa->sa_family) {
1477 rtcache_clear(ro);
1478 sockaddr_copy(ro->ro_sa, ro->ro_sa->sa_len, sa);
1479 rtcache_invariants(ro);
1480 return 0;
1481 }
1482 /* free ro_sa, wrong family */
1483 rtcache_free(ro);
1484 }
1485
1486 KASSERT(ro->_ro_rt == NULL);
1487
1488 if ((ro->ro_sa = sockaddr_dup(sa, M_ZERO | M_NOWAIT)) == NULL) {
1489 rtcache_invariants(ro);
1490 return ENOMEM;
1491 }
1492 rtcache_invariants(ro);
1493 return 0;
1494 }
1495
1496 const struct sockaddr *
1497 rt_settag(struct rtentry *rt, const struct sockaddr *tag)
1498 {
1499 if (rt->rt_tag != tag) {
1500 if (rt->rt_tag != NULL)
1501 sockaddr_free(rt->rt_tag);
1502 rt->rt_tag = sockaddr_dup(tag, M_ZERO | M_NOWAIT);
1503 }
1504 return rt->rt_tag;
1505 }
1506
1507 struct sockaddr *
1508 rt_gettag(const struct rtentry *rt)
1509 {
1510 return rt->rt_tag;
1511 }
1512
1513 int
1514 rt_check_reject_route(const struct rtentry *rt, const struct ifnet *ifp)
1515 {
1516
1517 if ((rt->rt_flags & RTF_REJECT) != 0) {
1518 /* Mimic looutput */
1519 if (ifp->if_flags & IFF_LOOPBACK)
1520 return (rt->rt_flags & RTF_HOST) ?
1521 EHOSTUNREACH : ENETUNREACH;
1522 else if (rt->rt_rmx.rmx_expire == 0 ||
1523 time_uptime < rt->rt_rmx.rmx_expire)
1524 return (rt->rt_flags & RTF_GATEWAY) ?
1525 EHOSTUNREACH : EHOSTDOWN;
1526 }
1527
1528 return 0;
1529 }
1530
1531 #ifdef DDB
1532
1533 #include <machine/db_machdep.h>
1534 #include <ddb/db_interface.h>
1535 #include <ddb/db_output.h>
1536
1537 #define rt_expire rt_rmx.rmx_expire
1538
1539 static void
1540 db_print_sa(const struct sockaddr *sa)
1541 {
1542 int len;
1543 const u_char *p;
1544
1545 if (sa == NULL) {
1546 db_printf("[NULL]");
1547 return;
1548 }
1549
1550 p = (const u_char *)sa;
1551 len = sa->sa_len;
1552 db_printf("[");
1553 while (len > 0) {
1554 db_printf("%d", *p);
1555 p++; len--;
1556 if (len) db_printf(",");
1557 }
1558 db_printf("]\n");
1559 }
1560
1561 static void
1562 db_print_ifa(struct ifaddr *ifa)
1563 {
1564 if (ifa == NULL)
1565 return;
1566 db_printf(" ifa_addr=");
1567 db_print_sa(ifa->ifa_addr);
1568 db_printf(" ifa_dsta=");
1569 db_print_sa(ifa->ifa_dstaddr);
1570 db_printf(" ifa_mask=");
1571 db_print_sa(ifa->ifa_netmask);
1572 db_printf(" flags=0x%x,refcnt=%d,metric=%d\n",
1573 ifa->ifa_flags,
1574 ifa->ifa_refcnt,
1575 ifa->ifa_metric);
1576 }
1577
1578 /*
1579 * Function to pass to rt_walktree().
1580 * Return non-zero error to abort walk.
1581 */
1582 static int
1583 db_show_rtentry(struct rtentry *rt, void *w)
1584 {
1585 db_printf("rtentry=%p", rt);
1586
1587 db_printf(" flags=0x%x refcnt=%d use=%"PRId64" expire=%"PRId64"\n",
1588 rt->rt_flags, rt->rt_refcnt,
1589 rt->rt_use, (uint64_t)rt->rt_expire);
1590
1591 db_printf(" key="); db_print_sa(rt_getkey(rt));
1592 db_printf(" mask="); db_print_sa(rt_mask(rt));
1593 db_printf(" gw="); db_print_sa(rt->rt_gateway);
1594
1595 db_printf(" ifp=%p ", rt->rt_ifp);
1596 if (rt->rt_ifp)
1597 db_printf("(%s)", rt->rt_ifp->if_xname);
1598 else
1599 db_printf("(NULL)");
1600
1601 db_printf(" ifa=%p\n", rt->rt_ifa);
1602 db_print_ifa(rt->rt_ifa);
1603
1604 db_printf(" gwroute=%p llinfo=%p\n",
1605 rt->rt_gwroute, rt->rt_llinfo);
1606
1607 return 0;
1608 }
1609
1610 /*
1611 * Function to print all the route trees.
1612 * Use this from ddb: "show routes"
1613 */
1614 void
1615 db_show_routes(db_expr_t addr, bool have_addr,
1616 db_expr_t count, const char *modif)
1617 {
1618 rt_walktree(AF_INET, db_show_rtentry, NULL);
1619 }
1620 #endif
1621