route.c revision 1.146 1 /* $NetBSD: route.c,v 1.146 2015/07/17 02:21:08 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.146 2015/07/17 02:21:08 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 rtfree(rt);
1045 break;
1046 case RTM_LLINFO_UPD:
1047 RT_DPRINTF("%s: updating%s\n", __func__,
1048 ((rt->rt_flags & RTF_LLINFO) == 0) ? " (no llinfo)" : "");
1049
1050 ifsdl = ifa->ifa_ifp->if_sadl;
1051
1052 if ((rt->rt_flags & RTF_LLINFO) != 0 &&
1053 (sdl = satosdl(rt->rt_gateway)) != NULL &&
1054 sdl->sdl_family == AF_LINK &&
1055 sockaddr_dl_setaddr(sdl, sdl->sdl_len, CLLADDR(ifsdl),
1056 ifa->ifa_ifp->if_addrlen) == NULL) {
1057 error = EINVAL;
1058 break;
1059 }
1060
1061 if (cmd == RTM_LLINFO_UPD && ifa->ifa_rtrequest != NULL)
1062 ifa->ifa_rtrequest(RTM_LLINFO_UPD, rt, &info);
1063 rt_newmsg(RTM_CHANGE, rt);
1064 rtfree(rt);
1065 break;
1066 case RTM_ADD:
1067 if (rt->rt_ifa != ifa) {
1068 printf("rtinit: wrong ifa (%p) was (%p)\n", ifa,
1069 rt->rt_ifa);
1070 if (rt->rt_ifa->ifa_rtrequest != NULL) {
1071 rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt,
1072 &info);
1073 }
1074 rt_replace_ifa(rt, ifa);
1075 rt->rt_ifp = ifa->ifa_ifp;
1076 if (ifa->ifa_rtrequest != NULL)
1077 ifa->ifa_rtrequest(RTM_ADD, rt, &info);
1078 }
1079 rt_newmsg(cmd, rt);
1080 rtfree(rt);
1081 break;
1082 }
1083 return error;
1084 }
1085
1086 static const struct in_addr inmask32 = {.s_addr = INADDR_BROADCAST};
1087
1088 /* Subroutine for rt_ifa_addlocal() and rt_ifa_remlocal() */
1089 static int
1090 rt_ifa_localrequest(int cmd, struct ifaddr *ifa)
1091 {
1092 struct sockaddr *all1_sa;
1093 struct sockaddr_in all1_sin;
1094 #ifdef INET6
1095 struct sockaddr_in6 all1_sin6;
1096 #endif
1097 struct rtentry *nrt = NULL;
1098 int flags, e;
1099
1100 switch(ifa->ifa_addr->sa_family) {
1101 case AF_INET:
1102 sockaddr_in_init(&all1_sin, &inmask32, 0);
1103 all1_sa = (struct sockaddr *)&all1_sin;
1104 break;
1105 #ifdef INET6
1106 case AF_INET6:
1107 sockaddr_in6_init(&all1_sin6, &in6mask128, 0, 0, 0);
1108 all1_sa = (struct sockaddr *)&all1_sin6;
1109 break;
1110 #endif
1111 default:
1112 return 0;
1113 }
1114
1115 flags = RTF_UP | RTF_HOST | RTF_LOCAL;
1116 if (!(ifa->ifa_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)))
1117 flags |= RTF_LLINFO;
1118 e = rtrequest(cmd, ifa->ifa_addr, ifa->ifa_addr, all1_sa, flags, &nrt);
1119
1120 /* Make sure rt_ifa be equal to IFA, the second argument of the
1121 * function. */
1122 if (cmd == RTM_ADD && nrt && ifa != nrt->rt_ifa)
1123 rt_replace_ifa(nrt, ifa);
1124
1125 rt_newaddrmsg(cmd, ifa, e, nrt);
1126 if (nrt != NULL)
1127 rtfree(nrt);
1128
1129 return e;
1130 }
1131
1132 /*
1133 * Create a local route entry for the address.
1134 * Announce the addition of the address and the route to the routing socket.
1135 */
1136 int
1137 rt_ifa_addlocal(struct ifaddr *ifa)
1138 {
1139 struct rtentry *rt;
1140 int e;
1141
1142 /* If there is no loopback entry, allocate one. */
1143 rt = rtalloc1(ifa->ifa_addr, 0);
1144 if (rt == NULL || (rt->rt_flags & RTF_HOST) == 0 ||
1145 (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0)
1146 e = rt_ifa_localrequest(RTM_ADD, ifa);
1147 else {
1148 e = 0;
1149 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
1150 }
1151 if (rt != NULL)
1152 rtfree(rt);
1153 return e;
1154 }
1155
1156 /*
1157 * Remove the local route entry for the address.
1158 * Announce the removal of the address and the route to the routing socket.
1159 */
1160 int
1161 rt_ifa_remlocal(struct ifaddr *ifa, struct ifaddr *alt_ifa)
1162 {
1163 struct rtentry *rt;
1164 int e = 0;
1165
1166 rt = rtalloc1(ifa->ifa_addr, 0);
1167
1168 /*
1169 * Before deleting, check if a corresponding loopbacked
1170 * host route surely exists. With this check, we can avoid
1171 * deleting an interface direct route whose destination is
1172 * the same as the address being removed. This can happen
1173 * when removing a subnet-router anycast address on an
1174 * interface attached to a shared medium.
1175 */
1176 if (rt != NULL &&
1177 (rt->rt_flags & RTF_HOST) &&
1178 (rt->rt_ifp->if_flags & IFF_LOOPBACK))
1179 {
1180 /* If we cannot replace the route's ifaddr with the equivalent
1181 * ifaddr of another interface, I believe it is safest to
1182 * delete the route.
1183 */
1184 if (alt_ifa == NULL)
1185 e = rt_ifa_localrequest(RTM_DELETE, ifa);
1186 else {
1187 rt_replace_ifa(rt, alt_ifa);
1188 rt_newmsg(RTM_CHANGE, rt);
1189 }
1190 } else
1191 rt_newaddrmsg(RTM_DELADDR, ifa, 0, NULL);
1192 if (rt != NULL)
1193 rtfree(rt);
1194 return e;
1195 }
1196
1197 /*
1198 * Route timer routines. These routes allow functions to be called
1199 * for various routes at any time. This is useful in supporting
1200 * path MTU discovery and redirect route deletion.
1201 *
1202 * This is similar to some BSDI internal functions, but it provides
1203 * for multiple queues for efficiency's sake...
1204 */
1205
1206 LIST_HEAD(, rttimer_queue) rttimer_queue_head;
1207 static int rt_init_done = 0;
1208
1209 #define RTTIMER_CALLOUT(r) do { \
1210 if (r->rtt_func != NULL) { \
1211 (*r->rtt_func)(r->rtt_rt, r); \
1212 } else { \
1213 rtrequest((int) RTM_DELETE, \
1214 rt_getkey(r->rtt_rt), \
1215 0, 0, 0, 0); \
1216 } \
1217 } while (/*CONSTCOND*/0)
1218
1219 /*
1220 * Some subtle order problems with domain initialization mean that
1221 * we cannot count on this being run from rt_init before various
1222 * protocol initializations are done. Therefore, we make sure
1223 * that this is run when the first queue is added...
1224 */
1225
1226 void
1227 rt_timer_init(void)
1228 {
1229 assert(rt_init_done == 0);
1230
1231 LIST_INIT(&rttimer_queue_head);
1232 callout_init(&rt_timer_ch, 0);
1233 callout_reset(&rt_timer_ch, hz, rt_timer_timer, NULL);
1234 rt_init_done = 1;
1235 }
1236
1237 struct rttimer_queue *
1238 rt_timer_queue_create(u_int timeout)
1239 {
1240 struct rttimer_queue *rtq;
1241
1242 if (rt_init_done == 0)
1243 rt_timer_init();
1244
1245 R_Malloc(rtq, struct rttimer_queue *, sizeof *rtq);
1246 if (rtq == NULL)
1247 return NULL;
1248 memset(rtq, 0, sizeof(*rtq));
1249
1250 rtq->rtq_timeout = timeout;
1251 TAILQ_INIT(&rtq->rtq_head);
1252 LIST_INSERT_HEAD(&rttimer_queue_head, rtq, rtq_link);
1253
1254 return rtq;
1255 }
1256
1257 void
1258 rt_timer_queue_change(struct rttimer_queue *rtq, long timeout)
1259 {
1260
1261 rtq->rtq_timeout = timeout;
1262 }
1263
1264 void
1265 rt_timer_queue_remove_all(struct rttimer_queue *rtq, int destroy)
1266 {
1267 struct rttimer *r;
1268
1269 while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL) {
1270 LIST_REMOVE(r, rtt_link);
1271 TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
1272 if (destroy)
1273 RTTIMER_CALLOUT(r);
1274 /* we are already at splsoftnet */
1275 pool_put(&rttimer_pool, r);
1276 if (rtq->rtq_count > 0)
1277 rtq->rtq_count--;
1278 else
1279 printf("rt_timer_queue_remove_all: "
1280 "rtq_count reached 0\n");
1281 }
1282 }
1283
1284 void
1285 rt_timer_queue_destroy(struct rttimer_queue *rtq, int destroy)
1286 {
1287
1288 rt_timer_queue_remove_all(rtq, destroy);
1289
1290 LIST_REMOVE(rtq, rtq_link);
1291
1292 /*
1293 * Caller is responsible for freeing the rttimer_queue structure.
1294 */
1295 }
1296
1297 unsigned long
1298 rt_timer_count(struct rttimer_queue *rtq)
1299 {
1300 return rtq->rtq_count;
1301 }
1302
1303 void
1304 rt_timer_remove_all(struct rtentry *rt, int destroy)
1305 {
1306 struct rttimer *r;
1307
1308 while ((r = LIST_FIRST(&rt->rt_timer)) != NULL) {
1309 LIST_REMOVE(r, rtt_link);
1310 TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
1311 if (destroy)
1312 RTTIMER_CALLOUT(r);
1313 if (r->rtt_queue->rtq_count > 0)
1314 r->rtt_queue->rtq_count--;
1315 else
1316 printf("rt_timer_remove_all: rtq_count reached 0\n");
1317 /* we are already at splsoftnet */
1318 pool_put(&rttimer_pool, r);
1319 }
1320 }
1321
1322 int
1323 rt_timer_add(struct rtentry *rt,
1324 void (*func)(struct rtentry *, struct rttimer *),
1325 struct rttimer_queue *queue)
1326 {
1327 struct rttimer *r;
1328 int s;
1329
1330 /*
1331 * If there's already a timer with this action, destroy it before
1332 * we add a new one.
1333 */
1334 LIST_FOREACH(r, &rt->rt_timer, rtt_link) {
1335 if (r->rtt_func == func)
1336 break;
1337 }
1338 if (r != NULL) {
1339 LIST_REMOVE(r, rtt_link);
1340 TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
1341 if (r->rtt_queue->rtq_count > 0)
1342 r->rtt_queue->rtq_count--;
1343 else
1344 printf("rt_timer_add: rtq_count reached 0\n");
1345 } else {
1346 s = splsoftnet();
1347 r = pool_get(&rttimer_pool, PR_NOWAIT);
1348 splx(s);
1349 if (r == NULL)
1350 return ENOBUFS;
1351 }
1352
1353 memset(r, 0, sizeof(*r));
1354
1355 r->rtt_rt = rt;
1356 r->rtt_time = time_uptime;
1357 r->rtt_func = func;
1358 r->rtt_queue = queue;
1359 LIST_INSERT_HEAD(&rt->rt_timer, r, rtt_link);
1360 TAILQ_INSERT_TAIL(&queue->rtq_head, r, rtt_next);
1361 r->rtt_queue->rtq_count++;
1362
1363 return 0;
1364 }
1365
1366 /* ARGSUSED */
1367 void
1368 rt_timer_timer(void *arg)
1369 {
1370 struct rttimer_queue *rtq;
1371 struct rttimer *r;
1372 int s;
1373
1374 s = splsoftnet();
1375 LIST_FOREACH(rtq, &rttimer_queue_head, rtq_link) {
1376 while ((r = TAILQ_FIRST(&rtq->rtq_head)) != NULL &&
1377 (r->rtt_time + rtq->rtq_timeout) < time_uptime) {
1378 LIST_REMOVE(r, rtt_link);
1379 TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
1380 RTTIMER_CALLOUT(r);
1381 pool_put(&rttimer_pool, r);
1382 if (rtq->rtq_count > 0)
1383 rtq->rtq_count--;
1384 else
1385 printf("rt_timer_timer: rtq_count reached 0\n");
1386 }
1387 }
1388 splx(s);
1389
1390 callout_reset(&rt_timer_ch, hz, rt_timer_timer, NULL);
1391 }
1392
1393 static struct rtentry *
1394 _rtcache_init(struct route *ro, int flag)
1395 {
1396 rtcache_invariants(ro);
1397 KASSERT(ro->_ro_rt == NULL);
1398
1399 if (rtcache_getdst(ro) == NULL)
1400 return NULL;
1401 ro->ro_invalid = false;
1402 if ((ro->_ro_rt = rtalloc1(rtcache_getdst(ro), flag)) != NULL)
1403 rtcache(ro);
1404
1405 rtcache_invariants(ro);
1406 return ro->_ro_rt;
1407 }
1408
1409 struct rtentry *
1410 rtcache_init(struct route *ro)
1411 {
1412 return _rtcache_init(ro, 1);
1413 }
1414
1415 struct rtentry *
1416 rtcache_init_noclone(struct route *ro)
1417 {
1418 return _rtcache_init(ro, 0);
1419 }
1420
1421 struct rtentry *
1422 rtcache_update(struct route *ro, int clone)
1423 {
1424 rtcache_clear(ro);
1425 return _rtcache_init(ro, clone);
1426 }
1427
1428 void
1429 rtcache_copy(struct route *new_ro, const struct route *old_ro)
1430 {
1431 struct rtentry *rt;
1432
1433 KASSERT(new_ro != old_ro);
1434 rtcache_invariants(new_ro);
1435 rtcache_invariants(old_ro);
1436
1437 if ((rt = rtcache_validate(old_ro)) != NULL)
1438 rt->rt_refcnt++;
1439
1440 if (rtcache_getdst(old_ro) == NULL ||
1441 rtcache_setdst(new_ro, rtcache_getdst(old_ro)) != 0)
1442 return;
1443
1444 new_ro->ro_invalid = false;
1445 if ((new_ro->_ro_rt = rt) != NULL)
1446 rtcache(new_ro);
1447 rtcache_invariants(new_ro);
1448 }
1449
1450 static struct dom_rtlist invalid_routes = LIST_HEAD_INITIALIZER(dom_rtlist);
1451
1452 static void
1453 rtcache_invalidate(struct dom_rtlist *rtlist)
1454 {
1455 struct route *ro;
1456
1457 while ((ro = LIST_FIRST(rtlist)) != NULL) {
1458 rtcache_invariants(ro);
1459 KASSERT(ro->_ro_rt != NULL);
1460 ro->ro_invalid = true;
1461 LIST_REMOVE(ro, ro_rtcache_next);
1462 LIST_INSERT_HEAD(&invalid_routes, ro, ro_rtcache_next);
1463 rtcache_invariants(ro);
1464 }
1465 }
1466
1467 static void
1468 rtcache_clear(struct route *ro)
1469 {
1470 rtcache_invariants(ro);
1471 if (ro->_ro_rt == NULL)
1472 return;
1473
1474 LIST_REMOVE(ro, ro_rtcache_next);
1475
1476 rtfree(ro->_ro_rt);
1477 ro->_ro_rt = NULL;
1478 ro->ro_invalid = false;
1479 rtcache_invariants(ro);
1480 }
1481
1482 struct rtentry *
1483 rtcache_lookup2(struct route *ro, const struct sockaddr *dst, int clone,
1484 int *hitp)
1485 {
1486 const struct sockaddr *odst;
1487 struct rtentry *rt = NULL;
1488
1489 odst = rtcache_getdst(ro);
1490 if (odst == NULL)
1491 goto miss;
1492
1493 if (sockaddr_cmp(odst, dst) != 0) {
1494 rtcache_free(ro);
1495 goto miss;
1496 }
1497
1498 rt = rtcache_validate(ro);
1499 if (rt == NULL) {
1500 rtcache_clear(ro);
1501 goto miss;
1502 }
1503
1504 *hitp = 1;
1505 rtcache_invariants(ro);
1506
1507 return rt;
1508 miss:
1509 *hitp = 0;
1510 if (rtcache_setdst(ro, dst) == 0)
1511 rt = _rtcache_init(ro, clone);
1512
1513 rtcache_invariants(ro);
1514
1515 return rt;
1516 }
1517
1518 void
1519 rtcache_free(struct route *ro)
1520 {
1521 rtcache_clear(ro);
1522 if (ro->ro_sa != NULL) {
1523 sockaddr_free(ro->ro_sa);
1524 ro->ro_sa = NULL;
1525 }
1526 rtcache_invariants(ro);
1527 }
1528
1529 int
1530 rtcache_setdst(struct route *ro, const struct sockaddr *sa)
1531 {
1532 KASSERT(sa != NULL);
1533
1534 rtcache_invariants(ro);
1535 if (ro->ro_sa != NULL) {
1536 if (ro->ro_sa->sa_family == sa->sa_family) {
1537 rtcache_clear(ro);
1538 sockaddr_copy(ro->ro_sa, ro->ro_sa->sa_len, sa);
1539 rtcache_invariants(ro);
1540 return 0;
1541 }
1542 /* free ro_sa, wrong family */
1543 rtcache_free(ro);
1544 }
1545
1546 KASSERT(ro->_ro_rt == NULL);
1547
1548 if ((ro->ro_sa = sockaddr_dup(sa, M_ZERO | M_NOWAIT)) == NULL) {
1549 rtcache_invariants(ro);
1550 return ENOMEM;
1551 }
1552 rtcache_invariants(ro);
1553 return 0;
1554 }
1555
1556 const struct sockaddr *
1557 rt_settag(struct rtentry *rt, const struct sockaddr *tag)
1558 {
1559 if (rt->rt_tag != tag) {
1560 if (rt->rt_tag != NULL)
1561 sockaddr_free(rt->rt_tag);
1562 rt->rt_tag = sockaddr_dup(tag, M_ZERO | M_NOWAIT);
1563 }
1564 return rt->rt_tag;
1565 }
1566
1567 struct sockaddr *
1568 rt_gettag(struct rtentry *rt)
1569 {
1570 return rt->rt_tag;
1571 }
1572