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