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