1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1980, 1986, 1991, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)route.c 8.3.1.1 (Berkeley) 2/23/95 32 * $FreeBSD$ 33 */ 34 /************************************************************************ 35 * Note: In this file a 'fib' is a "forwarding information base" * 36 * Which is the new name for an in kernel routing (next hop) table. * 37 ***********************************************************************/ 38 39 #include "opt_inet.h" 40 #include "opt_inet6.h" 41 #include "opt_mrouting.h" 42 #include "opt_mpath.h" 43 #include "opt_route.h" 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/malloc.h> 48 #include <sys/mbuf.h> 49 #include <sys/socket.h> 50 #include <sys/sysctl.h> 51 #include <sys/syslog.h> 52 #include <sys/sysproto.h> 53 #include <sys/proc.h> 54 #include <sys/domain.h> 55 #include <sys/eventhandler.h> 56 #include <sys/kernel.h> 57 #include <sys/lock.h> 58 #include <sys/rmlock.h> 59 60 #include <net/if.h> 61 #include <net/if_var.h> 62 #include <net/if_dl.h> 63 #include <net/route.h> 64 #include <net/route/route_ctl.h> 65 #include <net/route/route_var.h> 66 #include <net/route/nhop.h> 67 #include <net/vnet.h> 68 69 #ifdef RADIX_MPATH 70 #include <net/radix_mpath.h> 71 #endif 72 73 #include <netinet/in.h> 74 #include <netinet/ip_mroute.h> 75 76 /* 77 * By default add routes to all fibs for new interfaces. 78 * Once this is set to 0 then only allocate routes on interface 79 * changes for the FIB of the caller when adding a new set of addresses 80 * to an interface. XXX this is a shotgun aproach to a problem that needs 81 * a more fine grained solution.. that will come. 82 * XXX also has the problems getting the FIB from curthread which will not 83 * always work given the fib can be overridden and prefixes can be added 84 * from the network stack context. 85 */ 86 VNET_DEFINE(u_int, rt_add_addr_allfibs) = 1; 87 SYSCTL_UINT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RWTUN | CTLFLAG_VNET, 88 &VNET_NAME(rt_add_addr_allfibs), 0, ""); 89 90 VNET_PCPUSTAT_DEFINE(struct rtstat, rtstat); 91 92 VNET_PCPUSTAT_SYSINIT(rtstat); 93 #ifdef VIMAGE 94 VNET_PCPUSTAT_SYSUNINIT(rtstat); 95 #endif 96 97 EVENTHANDLER_LIST_DEFINE(rt_addrmsg); 98 99 static int rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *, 100 void *arg); 101 static int rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, 102 int flags); 103 104 /* 105 * route initialization must occur before ip6_init2(), which happenas at 106 * SI_ORDER_MIDDLE. 107 */ 108 static void 109 route_init(void) 110 { 111 112 nhops_init(); 113 } 114 SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, NULL); 115 116 struct rib_head * 117 rt_table_init(int offset, int family, u_int fibnum) 118 { 119 struct rib_head *rh; 120 121 rh = malloc(sizeof(struct rib_head), M_RTABLE, M_WAITOK | M_ZERO); 122 123 /* TODO: These details should be hidded inside radix.c */ 124 /* Init masks tree */ 125 rn_inithead_internal(&rh->head, rh->rnh_nodes, offset); 126 rn_inithead_internal(&rh->rmhead.head, rh->rmhead.mask_nodes, 0); 127 rh->head.rnh_masks = &rh->rmhead; 128 129 /* Save metadata associated with this routing table. */ 130 rh->rib_family = family; 131 rh->rib_fibnum = fibnum; 132 #ifdef VIMAGE 133 rh->rib_vnet = curvnet; 134 #endif 135 136 tmproutes_init(rh); 137 138 /* Init locks */ 139 RIB_LOCK_INIT(rh); 140 141 nhops_init_rib(rh); 142 143 /* Init subscription system */ 144 rib_init_subscriptions(rh); 145 146 /* Finally, set base callbacks */ 147 rh->rnh_addaddr = rn_addroute; 148 rh->rnh_deladdr = rn_delete; 149 rh->rnh_matchaddr = rn_match; 150 rh->rnh_lookup = rn_lookup; 151 rh->rnh_walktree = rn_walktree; 152 rh->rnh_walktree_from = rn_walktree_from; 153 154 return (rh); 155 } 156 157 static int 158 rt_freeentry(struct radix_node *rn, void *arg) 159 { 160 struct radix_head * const rnh = arg; 161 struct radix_node *x; 162 163 x = (struct radix_node *)rn_delete(rn + 2, NULL, rnh); 164 if (x != NULL) 165 R_Free(x); 166 return (0); 167 } 168 169 void 170 rt_table_destroy(struct rib_head *rh) 171 { 172 173 tmproutes_destroy(rh); 174 175 rn_walktree(&rh->rmhead.head, rt_freeentry, &rh->rmhead.head); 176 177 nhops_destroy_rib(rh); 178 179 rib_destroy_subscriptions(rh); 180 181 /* Assume table is already empty */ 182 RIB_LOCK_DESTROY(rh); 183 free(rh, M_RTABLE); 184 } 185 186 /* 187 * Adds a temporal redirect entry to the routing table. 188 * @fibnum: fib number 189 * @dst: destination to install redirect to 190 * @gateway: gateway to go via 191 * @author: sockaddr of originating router, can be NULL 192 * @ifp: interface to use for the redirected route 193 * @flags: set of flags to add. Allowed: RTF_GATEWAY 194 * @lifetime_sec: time in seconds to expire this redirect. 195 * 196 * Retuns 0 on success, errno otherwise. 197 */ 198 int 199 rib_add_redirect(u_int fibnum, struct sockaddr *dst, struct sockaddr *gateway, 200 struct sockaddr *author, struct ifnet *ifp, int flags, int lifetime_sec) 201 { 202 struct rib_cmd_info rc; 203 int error; 204 struct rt_addrinfo info; 205 struct rt_metrics rti_rmx; 206 struct ifaddr *ifa; 207 208 NET_EPOCH_ASSERT(); 209 210 if (rt_tables_get_rnh(fibnum, dst->sa_family) == NULL) 211 return (EAFNOSUPPORT); 212 213 /* Verify the allowed flag mask. */ 214 KASSERT(((flags & ~(RTF_GATEWAY)) == 0), 215 ("invalid redirect flags: %x", flags)); 216 flags |= RTF_HOST | RTF_DYNAMIC; 217 218 /* Get the best ifa for the given interface and gateway. */ 219 if ((ifa = ifaof_ifpforaddr(gateway, ifp)) == NULL) 220 return (ENETUNREACH); 221 ifa_ref(ifa); 222 223 bzero(&info, sizeof(info)); 224 info.rti_info[RTAX_DST] = dst; 225 info.rti_info[RTAX_GATEWAY] = gateway; 226 info.rti_ifa = ifa; 227 info.rti_ifp = ifp; 228 info.rti_flags = flags; 229 230 /* Setup route metrics to define expire time. */ 231 bzero(&rti_rmx, sizeof(rti_rmx)); 232 /* Set expire time as absolute. */ 233 rti_rmx.rmx_expire = lifetime_sec + time_second; 234 info.rti_mflags |= RTV_EXPIRE; 235 info.rti_rmx = &rti_rmx; 236 237 error = rib_action(fibnum, RTM_ADD, &info, &rc); 238 ifa_free(ifa); 239 240 if (error != 0) { 241 /* TODO: add per-fib redirect stats. */ 242 return (error); 243 } 244 245 RTSTAT_INC(rts_dynamic); 246 247 /* Send notification of a route addition to userland. */ 248 bzero(&info, sizeof(info)); 249 info.rti_info[RTAX_DST] = dst; 250 info.rti_info[RTAX_GATEWAY] = gateway; 251 info.rti_info[RTAX_AUTHOR] = author; 252 rt_missmsg_fib(RTM_REDIRECT, &info, flags | RTF_UP, error, fibnum); 253 254 return (0); 255 } 256 257 /* 258 * Routing table ioctl interface. 259 */ 260 int 261 rtioctl_fib(u_long req, caddr_t data, u_int fibnum) 262 { 263 264 /* 265 * If more ioctl commands are added here, make sure the proper 266 * super-user checks are being performed because it is possible for 267 * prison-root to make it this far if raw sockets have been enabled 268 * in jails. 269 */ 270 #ifdef INET 271 /* Multicast goop, grrr... */ 272 return mrt_ioctl ? mrt_ioctl(req, data, fibnum) : EOPNOTSUPP; 273 #else /* INET */ 274 return ENXIO; 275 #endif /* INET */ 276 } 277 278 struct ifaddr * 279 ifa_ifwithroute(int flags, const struct sockaddr *dst, 280 const struct sockaddr *gateway, u_int fibnum) 281 { 282 struct ifaddr *ifa; 283 284 NET_EPOCH_ASSERT(); 285 if ((flags & RTF_GATEWAY) == 0) { 286 /* 287 * If we are adding a route to an interface, 288 * and the interface is a pt to pt link 289 * we should search for the destination 290 * as our clue to the interface. Otherwise 291 * we can use the local address. 292 */ 293 ifa = NULL; 294 if (flags & RTF_HOST) 295 ifa = ifa_ifwithdstaddr(dst, fibnum); 296 if (ifa == NULL) 297 ifa = ifa_ifwithaddr(gateway); 298 } else { 299 /* 300 * If we are adding a route to a remote net 301 * or host, the gateway may still be on the 302 * other end of a pt to pt link. 303 */ 304 ifa = ifa_ifwithdstaddr(gateway, fibnum); 305 } 306 if (ifa == NULL) 307 ifa = ifa_ifwithnet(gateway, 0, fibnum); 308 if (ifa == NULL) { 309 struct nhop_object *nh; 310 311 nh = rib_lookup(fibnum, gateway, NHR_NONE, 0); 312 313 /* 314 * dismiss a gateway that is reachable only 315 * through the default router 316 */ 317 if ((nh == NULL) || (nh->nh_flags & NHF_DEFAULT)) 318 return (NULL); 319 ifa = nh->nh_ifa; 320 } 321 if (ifa->ifa_addr->sa_family != dst->sa_family) { 322 struct ifaddr *oifa = ifa; 323 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); 324 if (ifa == NULL) 325 ifa = oifa; 326 } 327 328 return (ifa); 329 } 330 331 /* 332 * Copy most of @rt data into @info. 333 * 334 * If @flags contains NHR_COPY, copies dst,netmask and gw to the 335 * pointers specified by @info structure. Assume such pointers 336 * are zeroed sockaddr-like structures with sa_len field initialized 337 * to reflect size of the provided buffer. if no NHR_COPY is specified, 338 * point dst,netmask and gw @info fields to appropriate @rt values. 339 * 340 * if @flags contains NHR_REF, do refcouting on rt_ifp and rt_ifa. 341 * 342 * Returns 0 on success. 343 */ 344 int 345 rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags) 346 { 347 struct rt_metrics *rmx; 348 struct sockaddr *src, *dst; 349 struct nhop_object *nh; 350 int sa_len; 351 352 nh = rt->rt_nhop; 353 if (flags & NHR_COPY) { 354 /* Copy destination if dst is non-zero */ 355 src = rt_key(rt); 356 dst = info->rti_info[RTAX_DST]; 357 sa_len = src->sa_len; 358 if (dst != NULL) { 359 if (src->sa_len > dst->sa_len) 360 return (ENOMEM); 361 memcpy(dst, src, src->sa_len); 362 info->rti_addrs |= RTA_DST; 363 } 364 365 /* Copy mask if set && dst is non-zero */ 366 src = rt_mask(rt); 367 dst = info->rti_info[RTAX_NETMASK]; 368 if (src != NULL && dst != NULL) { 369 /* 370 * Radix stores different value in sa_len, 371 * assume rt_mask() to have the same length 372 * as rt_key() 373 */ 374 if (sa_len > dst->sa_len) 375 return (ENOMEM); 376 memcpy(dst, src, src->sa_len); 377 info->rti_addrs |= RTA_NETMASK; 378 } 379 380 /* Copy gateway is set && dst is non-zero */ 381 src = &nh->gw_sa; 382 dst = info->rti_info[RTAX_GATEWAY]; 383 if ((nhop_get_rtflags(nh) & RTF_GATEWAY) && 384 src != NULL && dst != NULL) { 385 if (src->sa_len > dst->sa_len) 386 return (ENOMEM); 387 memcpy(dst, src, src->sa_len); 388 info->rti_addrs |= RTA_GATEWAY; 389 } 390 } else { 391 info->rti_info[RTAX_DST] = rt_key(rt); 392 info->rti_addrs |= RTA_DST; 393 if (rt_mask(rt) != NULL) { 394 info->rti_info[RTAX_NETMASK] = rt_mask(rt); 395 info->rti_addrs |= RTA_NETMASK; 396 } 397 if (nhop_get_rtflags(nh) & RTF_GATEWAY) { 398 info->rti_info[RTAX_GATEWAY] = &nh->gw_sa; 399 info->rti_addrs |= RTA_GATEWAY; 400 } 401 } 402 403 rmx = info->rti_rmx; 404 if (rmx != NULL) { 405 info->rti_mflags |= RTV_MTU; 406 rmx->rmx_mtu = nh->nh_mtu; 407 } 408 409 info->rti_flags = rt->rte_flags | nhop_get_rtflags(nh); 410 info->rti_ifp = nh->nh_ifp; 411 info->rti_ifa = nh->nh_ifa; 412 if (flags & NHR_REF) { 413 if_ref(info->rti_ifp); 414 ifa_ref(info->rti_ifa); 415 } 416 417 return (0); 418 } 419 420 /* 421 * Lookups up route entry for @dst in RIB database for fib @fibnum. 422 * Exports entry data to @info using rt_exportinfo(). 423 * 424 * If @flags contains NHR_REF, refcouting is performed on rt_ifp and rt_ifa. 425 * All references can be released later by calling rib_free_info(). 426 * 427 * Returns 0 on success. 428 * Returns ENOENT for lookup failure, ENOMEM for export failure. 429 */ 430 int 431 rib_lookup_info(uint32_t fibnum, const struct sockaddr *dst, uint32_t flags, 432 uint32_t flowid, struct rt_addrinfo *info) 433 { 434 RIB_RLOCK_TRACKER; 435 struct rib_head *rh; 436 struct radix_node *rn; 437 struct rtentry *rt; 438 int error; 439 440 KASSERT((fibnum < rt_numfibs), ("rib_lookup_rte: bad fibnum")); 441 rh = rt_tables_get_rnh(fibnum, dst->sa_family); 442 if (rh == NULL) 443 return (ENOENT); 444 445 RIB_RLOCK(rh); 446 rn = rh->rnh_matchaddr(__DECONST(void *, dst), &rh->head); 447 if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { 448 rt = RNTORT(rn); 449 /* Ensure route & ifp is UP */ 450 if (RT_LINK_IS_UP(rt->rt_nhop->nh_ifp)) { 451 flags = (flags & NHR_REF) | NHR_COPY; 452 error = rt_exportinfo(rt, info, flags); 453 RIB_RUNLOCK(rh); 454 455 return (error); 456 } 457 } 458 RIB_RUNLOCK(rh); 459 460 return (ENOENT); 461 } 462 463 /* 464 * Releases all references acquired by rib_lookup_info() when 465 * called with NHR_REF flags. 466 */ 467 void 468 rib_free_info(struct rt_addrinfo *info) 469 { 470 471 ifa_free(info->rti_ifa); 472 if_rele(info->rti_ifp); 473 } 474 475 /* 476 * Iterates over all existing fibs in system calling 477 * @setwa_f function prior to traversing each fib. 478 * Calls @wa_f function for each element in current fib. 479 * If af is not AF_UNSPEC, iterates over fibs in particular 480 * address family. 481 */ 482 void 483 rt_foreach_fib_walk(int af, rt_setwarg_t *setwa_f, rt_walktree_f_t *wa_f, 484 void *arg) 485 { 486 struct rib_head *rnh; 487 uint32_t fibnum; 488 int i; 489 490 for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { 491 /* Do we want some specific family? */ 492 if (af != AF_UNSPEC) { 493 rnh = rt_tables_get_rnh(fibnum, af); 494 if (rnh == NULL) 495 continue; 496 if (setwa_f != NULL) 497 setwa_f(rnh, fibnum, af, arg); 498 499 RIB_WLOCK(rnh); 500 rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg); 501 RIB_WUNLOCK(rnh); 502 continue; 503 } 504 505 for (i = 1; i <= AF_MAX; i++) { 506 rnh = rt_tables_get_rnh(fibnum, i); 507 if (rnh == NULL) 508 continue; 509 if (setwa_f != NULL) 510 setwa_f(rnh, fibnum, i, arg); 511 512 RIB_WLOCK(rnh); 513 rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg); 514 RIB_WUNLOCK(rnh); 515 } 516 } 517 } 518 519 /* 520 * Iterates over all existing fibs in system and deletes each element 521 * for which @filter_f function returns non-zero value. 522 * If @family is not AF_UNSPEC, iterates over fibs in particular 523 * address family. 524 */ 525 void 526 rt_foreach_fib_walk_del(int family, rt_filter_f_t *filter_f, void *arg) 527 { 528 u_int fibnum; 529 int i, start, end; 530 531 for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { 532 /* Do we want some specific family? */ 533 if (family != AF_UNSPEC) { 534 start = family; 535 end = family; 536 } else { 537 start = 1; 538 end = AF_MAX; 539 } 540 541 for (i = start; i <= end; i++) { 542 if (rt_tables_get_rnh(fibnum, i) == NULL) 543 continue; 544 545 rib_walk_del(fibnum, i, filter_f, arg, 0); 546 } 547 } 548 } 549 550 /* 551 * Delete Routes for a Network Interface 552 * 553 * Called for each routing entry via the rnh->rnh_walktree() call above 554 * to delete all route entries referencing a detaching network interface. 555 * 556 * Arguments: 557 * rt pointer to rtentry 558 * nh pointer to nhop 559 * arg argument passed to rnh->rnh_walktree() - detaching interface 560 * 561 * Returns: 562 * 0 successful 563 * errno failed - reason indicated 564 */ 565 static int 566 rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *nh, void *arg) 567 { 568 struct ifnet *ifp = arg; 569 570 if (nh->nh_ifp != ifp) 571 return (0); 572 573 /* 574 * Protect (sorta) against walktree recursion problems 575 * with cloned routes 576 */ 577 if ((rt->rte_flags & RTF_UP) == 0) 578 return (0); 579 580 return (1); 581 } 582 583 /* 584 * Delete all remaining routes using this interface 585 * Unfortuneatly the only way to do this is to slog through 586 * the entire routing table looking for routes which point 587 * to this interface...oh well... 588 */ 589 void 590 rt_flushifroutes_af(struct ifnet *ifp, int af) 591 { 592 KASSERT((af >= 1 && af <= AF_MAX), ("%s: af %d not >= 1 and <= %d", 593 __func__, af, AF_MAX)); 594 595 rt_foreach_fib_walk_del(af, rt_ifdelroute, ifp); 596 } 597 598 void 599 rt_flushifroutes(struct ifnet *ifp) 600 { 601 602 rt_foreach_fib_walk_del(AF_UNSPEC, rt_ifdelroute, ifp); 603 } 604 605 /* 606 * Look up rt_addrinfo for a specific fib. Note that if rti_ifa is defined, 607 * it will be referenced so the caller must free it. 608 * 609 * Assume basic consistency checks are executed by callers: 610 * RTAX_DST exists, if RTF_GATEWAY is set, RTAX_GATEWAY exists as well. 611 */ 612 int 613 rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum) 614 { 615 const struct sockaddr *dst, *gateway, *ifpaddr, *ifaaddr; 616 struct epoch_tracker et; 617 int needref, error, flags; 618 619 dst = info->rti_info[RTAX_DST]; 620 gateway = info->rti_info[RTAX_GATEWAY]; 621 ifpaddr = info->rti_info[RTAX_IFP]; 622 ifaaddr = info->rti_info[RTAX_IFA]; 623 flags = info->rti_flags; 624 625 /* 626 * ifp may be specified by sockaddr_dl 627 * when protocol address is ambiguous. 628 */ 629 error = 0; 630 needref = (info->rti_ifa == NULL); 631 NET_EPOCH_ENTER(et); 632 633 /* If we have interface specified by the ifindex in the address, use it */ 634 if (info->rti_ifp == NULL && ifpaddr != NULL && 635 ifpaddr->sa_family == AF_LINK) { 636 const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)ifpaddr; 637 if (sdl->sdl_index != 0) 638 info->rti_ifp = ifnet_byindex(sdl->sdl_index); 639 } 640 /* 641 * If we have source address specified, try to find it 642 * TODO: avoid enumerating all ifas on all interfaces. 643 */ 644 if (info->rti_ifa == NULL && ifaaddr != NULL) 645 info->rti_ifa = ifa_ifwithaddr(ifaaddr); 646 if (info->rti_ifa == NULL) { 647 const struct sockaddr *sa; 648 649 /* 650 * Most common use case for the userland-supplied routes. 651 * 652 * Choose sockaddr to select ifa. 653 * -- if ifp is set -- 654 * Order of preference: 655 * 1) IFA address 656 * 2) gateway address 657 * Note: for interface routes link-level gateway address 658 * is specified to indicate the interface index without 659 * specifying RTF_GATEWAY. In this case, ignore gateway 660 * Note: gateway AF may be different from dst AF. In this case, 661 * ignore gateway 662 * 3) final destination. 663 * 4) if all of these fails, try to get at least link-level ifa. 664 * -- else -- 665 * try to lookup gateway or dst in the routing table to get ifa 666 */ 667 if (info->rti_info[RTAX_IFA] != NULL) 668 sa = info->rti_info[RTAX_IFA]; 669 else if ((info->rti_flags & RTF_GATEWAY) != 0 && 670 gateway->sa_family == dst->sa_family) 671 sa = gateway; 672 else 673 sa = dst; 674 if (info->rti_ifp != NULL) { 675 info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp); 676 /* Case 4 */ 677 if (info->rti_ifa == NULL && gateway != NULL) 678 info->rti_ifa = ifaof_ifpforaddr(gateway, info->rti_ifp); 679 } else if (dst != NULL && gateway != NULL) 680 info->rti_ifa = ifa_ifwithroute(flags, dst, gateway, 681 fibnum); 682 else if (sa != NULL) 683 info->rti_ifa = ifa_ifwithroute(flags, sa, sa, 684 fibnum); 685 } 686 if (needref && info->rti_ifa != NULL) { 687 if (info->rti_ifp == NULL) 688 info->rti_ifp = info->rti_ifa->ifa_ifp; 689 ifa_ref(info->rti_ifa); 690 } else 691 error = ENETUNREACH; 692 NET_EPOCH_EXIT(et); 693 return (error); 694 } 695 696 void 697 rt_updatemtu(struct ifnet *ifp) 698 { 699 struct rib_head *rnh; 700 int mtu; 701 int i, j; 702 703 /* 704 * Try to update rt_mtu for all routes using this interface 705 * Unfortunately the only way to do this is to traverse all 706 * routing tables in all fibs/domains. 707 */ 708 for (i = 1; i <= AF_MAX; i++) { 709 mtu = if_getmtu_family(ifp, i); 710 for (j = 0; j < rt_numfibs; j++) { 711 rnh = rt_tables_get_rnh(j, i); 712 if (rnh == NULL) 713 continue; 714 nhops_update_ifmtu(rnh, ifp, mtu); 715 } 716 } 717 } 718 719 #if 0 720 int p_sockaddr(char *buf, int buflen, struct sockaddr *s); 721 int rt_print(char *buf, int buflen, struct rtentry *rt); 722 723 int 724 p_sockaddr(char *buf, int buflen, struct sockaddr *s) 725 { 726 void *paddr = NULL; 727 728 switch (s->sa_family) { 729 case AF_INET: 730 paddr = &((struct sockaddr_in *)s)->sin_addr; 731 break; 732 case AF_INET6: 733 paddr = &((struct sockaddr_in6 *)s)->sin6_addr; 734 break; 735 } 736 737 if (paddr == NULL) 738 return (0); 739 740 if (inet_ntop(s->sa_family, paddr, buf, buflen) == NULL) 741 return (0); 742 743 return (strlen(buf)); 744 } 745 746 int 747 rt_print(char *buf, int buflen, struct rtentry *rt) 748 { 749 struct sockaddr *addr, *mask; 750 int i = 0; 751 752 addr = rt_key(rt); 753 mask = rt_mask(rt); 754 755 i = p_sockaddr(buf, buflen, addr); 756 if (!(rt->rt_flags & RTF_HOST)) { 757 buf[i++] = '/'; 758 i += p_sockaddr(buf + i, buflen - i, mask); 759 } 760 761 if (rt->rt_flags & RTF_GATEWAY) { 762 buf[i++] = '>'; 763 i += p_sockaddr(buf + i, buflen - i, &rt->rt_nhop->gw_sa); 764 } 765 766 return (i); 767 } 768 #endif 769 770 #ifdef RADIX_MPATH 771 /* 772 * Deletes key for single-path routes, unlinks rtentry with 773 * gateway specified in @info from multi-path routes. 774 * 775 * Returnes unlinked entry. In case of failure, returns NULL 776 * and sets @perror to ESRCH. 777 */ 778 struct radix_node * 779 rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info, 780 struct rtentry *rto, int *perror) 781 { 782 /* 783 * if we got multipath routes, we require users to specify 784 * a matching RTAX_GATEWAY. 785 */ 786 struct rtentry *rt; // *rto = NULL; 787 struct radix_node *rn; 788 struct sockaddr *gw; 789 790 gw = info->rti_info[RTAX_GATEWAY]; 791 rt = rt_mpath_matchgate(rto, gw); 792 if (rt == NULL) { 793 *perror = ESRCH; 794 return (NULL); 795 } 796 797 /* 798 * this is the first entry in the chain 799 */ 800 if (rto == rt) { 801 rn = rn_mpath_next((struct radix_node *)rt); 802 /* 803 * there is another entry, now it's active 804 */ 805 if (rn) { 806 rto = RNTORT(rn); 807 rto->rte_flags |= RTF_UP; 808 } else if (rt->rte_flags & RTF_GATEWAY) { 809 /* 810 * For gateway routes, we need to 811 * make sure that we we are deleting 812 * the correct gateway. 813 * rt_mpath_matchgate() does not 814 * check the case when there is only 815 * one route in the chain. 816 */ 817 if (gw && 818 (rt->rt_nhop->gw_sa.sa_len != gw->sa_len || 819 memcmp(&rt->rt_nhop->gw_sa, gw, gw->sa_len))) { 820 *perror = ESRCH; 821 return (NULL); 822 } 823 } 824 825 /* 826 * use the normal delete code to remove 827 * the first entry 828 */ 829 rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST], 830 info->rti_info[RTAX_NETMASK], 831 &rnh->head); 832 if (rn != NULL) { 833 *perror = 0; 834 } else { 835 *perror = ESRCH; 836 } 837 return (rn); 838 } 839 840 /* 841 * if the entry is 2nd and on up 842 */ 843 if (rt_mpath_deldup(rto, rt) == 0) 844 panic ("rtrequest1: rt_mpath_deldup"); 845 *perror = 0; 846 rn = (struct radix_node *)rt; 847 return (rn); 848 } 849 #endif 850 851 void 852 rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt) 853 { 854 855 if (info->rti_mflags & RTV_WEIGHT) 856 rt->rt_weight = info->rti_rmx->rmx_weight; 857 /* Kernel -> userland timebase conversion. */ 858 if (info->rti_mflags & RTV_EXPIRE) 859 rt->rt_expire = info->rti_rmx->rmx_expire ? 860 info->rti_rmx->rmx_expire - time_second + time_uptime : 0; 861 } 862 863 void 864 rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask) 865 { 866 u_char *cp1 = (u_char *)src; 867 u_char *cp2 = (u_char *)dst; 868 u_char *cp3 = (u_char *)netmask; 869 u_char *cplim = cp2 + *cp3; 870 u_char *cplim2 = cp2 + *cp1; 871 872 *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */ 873 cp3 += 2; 874 if (cplim > cplim2) 875 cplim = cplim2; 876 while (cp2 < cplim) 877 *cp2++ = *cp1++ & *cp3++; 878 if (cp2 < cplim2) 879 bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2)); 880 } 881 882 /* 883 * Set up a routing table entry, normally 884 * for an interface. 885 */ 886 #define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */ 887 static inline int 888 rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) 889 { 890 RIB_RLOCK_TRACKER; 891 struct epoch_tracker et; 892 struct sockaddr *dst; 893 struct sockaddr *netmask; 894 struct rib_cmd_info rc; 895 struct rt_addrinfo info; 896 int error = 0; 897 int startfib, endfib; 898 char tempbuf[_SOCKADDR_TMPSIZE]; 899 int didwork = 0; 900 int a_failure = 0; 901 struct sockaddr_dl_short *sdl = NULL; 902 struct rib_head *rnh; 903 904 if (flags & RTF_HOST) { 905 dst = ifa->ifa_dstaddr; 906 netmask = NULL; 907 } else { 908 dst = ifa->ifa_addr; 909 netmask = ifa->ifa_netmask; 910 } 911 if (dst->sa_len == 0) 912 return(EINVAL); 913 switch (dst->sa_family) { 914 case AF_INET6: 915 case AF_INET: 916 /* We support multiple FIBs. */ 917 break; 918 default: 919 fibnum = RT_DEFAULT_FIB; 920 break; 921 } 922 if (fibnum == RT_ALL_FIBS) { 923 if (V_rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) 924 startfib = endfib = ifa->ifa_ifp->if_fib; 925 else { 926 startfib = 0; 927 endfib = rt_numfibs - 1; 928 } 929 } else { 930 KASSERT((fibnum < rt_numfibs), ("rtinit1: bad fibnum")); 931 startfib = fibnum; 932 endfib = fibnum; 933 } 934 935 /* 936 * If it's a delete, check that if it exists, 937 * it's on the correct interface or we might scrub 938 * a route to another ifa which would 939 * be confusing at best and possibly worse. 940 */ 941 if (cmd == RTM_DELETE) { 942 /* 943 * It's a delete, so it should already exist.. 944 * If it's a net, mask off the host bits 945 * (Assuming we have a mask) 946 * XXX this is kinda inet specific.. 947 */ 948 if (netmask != NULL) { 949 rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask); 950 dst = (struct sockaddr *)tempbuf; 951 } 952 } else if (cmd == RTM_ADD) { 953 sdl = (struct sockaddr_dl_short *)tempbuf; 954 bzero(sdl, sizeof(struct sockaddr_dl_short)); 955 sdl->sdl_family = AF_LINK; 956 sdl->sdl_len = sizeof(struct sockaddr_dl_short); 957 sdl->sdl_type = ifa->ifa_ifp->if_type; 958 sdl->sdl_index = ifa->ifa_ifp->if_index; 959 } 960 /* 961 * Now go through all the requested tables (fibs) and do the 962 * requested action. Realistically, this will either be fib 0 963 * for protocols that don't do multiple tables or all the 964 * tables for those that do. 965 */ 966 for ( fibnum = startfib; fibnum <= endfib; fibnum++) { 967 if (cmd == RTM_DELETE) { 968 struct radix_node *rn; 969 /* 970 * Look up an rtentry that is in the routing tree and 971 * contains the correct info. 972 */ 973 rnh = rt_tables_get_rnh(fibnum, dst->sa_family); 974 if (rnh == NULL) 975 /* this table doesn't exist but others might */ 976 continue; 977 RIB_RLOCK(rnh); 978 rn = rnh->rnh_lookup(dst, netmask, &rnh->head); 979 #ifdef RADIX_MPATH 980 if (rt_mpath_capable(rnh)) { 981 if (rn == NULL) 982 error = ESRCH; 983 else { 984 struct rtentry *rt = RNTORT(rn); 985 /* 986 * for interface route the gateway 987 * gateway is sockaddr_dl, so 988 * rt_mpath_matchgate must use the 989 * interface address 990 */ 991 rt = rt_mpath_matchgate(rt, 992 ifa->ifa_addr); 993 if (rt == NULL) 994 error = ESRCH; 995 } 996 } 997 #endif 998 error = (rn == NULL || 999 (rn->rn_flags & RNF_ROOT) || 1000 RNTORT(rn)->rt_nhop->nh_ifa != ifa); 1001 RIB_RUNLOCK(rnh); 1002 if (error) { 1003 /* this is only an error if bad on ALL tables */ 1004 continue; 1005 } 1006 } 1007 /* 1008 * Do the actual request 1009 */ 1010 bzero((caddr_t)&info, sizeof(info)); 1011 info.rti_ifa = ifa; 1012 info.rti_flags = flags | 1013 (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED; 1014 info.rti_info[RTAX_DST] = dst; 1015 /* 1016 * doing this for compatibility reasons 1017 */ 1018 if (cmd == RTM_ADD) 1019 info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)sdl; 1020 else 1021 info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; 1022 info.rti_info[RTAX_NETMASK] = netmask; 1023 NET_EPOCH_ENTER(et); 1024 error = rib_action(fibnum, cmd, &info, &rc); 1025 if (error == 0 && rc.rc_rt != NULL) { 1026 /* 1027 * notify any listening routing agents of the change 1028 */ 1029 1030 /* TODO: interface routes/aliases */ 1031 rt_newaddrmsg_fib(cmd, ifa, rc.rc_rt, fibnum); 1032 didwork = 1; 1033 } 1034 NET_EPOCH_EXIT(et); 1035 if (error) 1036 a_failure = error; 1037 } 1038 if (cmd == RTM_DELETE) { 1039 if (didwork) { 1040 error = 0; 1041 } else { 1042 /* we only give an error if it wasn't in any table */ 1043 error = ((flags & RTF_HOST) ? 1044 EHOSTUNREACH : ENETUNREACH); 1045 } 1046 } else { 1047 if (a_failure) { 1048 /* return an error if any of them failed */ 1049 error = a_failure; 1050 } 1051 } 1052 return (error); 1053 } 1054 1055 /* 1056 * Set up a routing table entry, normally 1057 * for an interface. 1058 */ 1059 int 1060 rtinit(struct ifaddr *ifa, int cmd, int flags) 1061 { 1062 struct sockaddr *dst; 1063 int fib = RT_DEFAULT_FIB; 1064 1065 if (flags & RTF_HOST) { 1066 dst = ifa->ifa_dstaddr; 1067 } else { 1068 dst = ifa->ifa_addr; 1069 } 1070 1071 switch (dst->sa_family) { 1072 case AF_INET6: 1073 case AF_INET: 1074 /* We do support multiple FIBs. */ 1075 fib = RT_ALL_FIBS; 1076 break; 1077 } 1078 return (rtinit1(ifa, cmd, flags, fib)); 1079 } 1080 1081 /* 1082 * Announce interface address arrival/withdraw 1083 * Returns 0 on success. 1084 */ 1085 int 1086 rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum) 1087 { 1088 1089 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1090 ("unexpected cmd %d", cmd)); 1091 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1092 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1093 1094 EVENTHANDLER_DIRECT_INVOKE(rt_addrmsg, ifa, cmd); 1095 return (rtsock_addrmsg(cmd, ifa, fibnum)); 1096 } 1097 1098 /* 1099 * Announce kernel-originated route addition/removal to rtsock based on @rt data. 1100 * cmd: RTM_ cmd 1101 * @rt: valid rtentry 1102 * @ifp: target route interface 1103 * @fibnum: fib id or RT_ALL_FIBS 1104 * 1105 * Returns 0 on success. 1106 */ 1107 int 1108 rt_routemsg(int cmd, struct rtentry *rt, struct ifnet *ifp, int rti_addrs, 1109 int fibnum) 1110 { 1111 1112 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1113 ("unexpected cmd %d", cmd)); 1114 1115 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1116 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1117 1118 KASSERT(rt_key(rt) != NULL, (":%s: rt_key must be supplied", __func__)); 1119 1120 return (rtsock_routemsg(cmd, rt, ifp, 0, fibnum)); 1121 } 1122 1123 /* 1124 * Announce kernel-originated route addition/removal to rtsock based on @rt data. 1125 * cmd: RTM_ cmd 1126 * @info: addrinfo structure with valid data. 1127 * @fibnum: fib id or RT_ALL_FIBS 1128 * 1129 * Returns 0 on success. 1130 */ 1131 int 1132 rt_routemsg_info(int cmd, struct rt_addrinfo *info, int fibnum) 1133 { 1134 1135 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE || cmd == RTM_CHANGE, 1136 ("unexpected cmd %d", cmd)); 1137 1138 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1139 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1140 1141 KASSERT(info->rti_info[RTAX_DST] != NULL, (":%s: RTAX_DST must be supplied", __func__)); 1142 1143 return (rtsock_routemsg_info(cmd, info, fibnum)); 1144 } 1145 1146 /* 1147 * This is called to generate messages from the routing socket 1148 * indicating a network interface has had addresses associated with it. 1149 */ 1150 void 1151 rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, struct rtentry *rt, int fibnum) 1152 { 1153 1154 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1155 ("unexpected cmd %u", cmd)); 1156 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1157 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1158 1159 if (cmd == RTM_ADD) { 1160 rt_addrmsg(cmd, ifa, fibnum); 1161 if (rt != NULL) 1162 rt_routemsg(cmd, rt, ifa->ifa_ifp, 0, fibnum); 1163 } else { 1164 if (rt != NULL) 1165 rt_routemsg(cmd, rt, ifa->ifa_ifp, 0, fibnum); 1166 rt_addrmsg(cmd, ifa, fibnum); 1167 } 1168 } 1169