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