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_var.h> 65 #include <net/route/nhop.h> 66 #include <net/route/shared.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 #include <vm/uma.h> 77 78 #define RT_MAXFIBS UINT16_MAX 79 80 /* Kernel config default option. */ 81 #ifdef ROUTETABLES 82 #if ROUTETABLES <= 0 83 #error "ROUTETABLES defined too low" 84 #endif 85 #if ROUTETABLES > RT_MAXFIBS 86 #error "ROUTETABLES defined too big" 87 #endif 88 #define RT_NUMFIBS ROUTETABLES 89 #endif /* ROUTETABLES */ 90 /* Initialize to default if not otherwise set. */ 91 #ifndef RT_NUMFIBS 92 #define RT_NUMFIBS 1 93 #endif 94 95 /* This is read-only.. */ 96 u_int rt_numfibs = RT_NUMFIBS; 97 SYSCTL_UINT(_net, OID_AUTO, fibs, CTLFLAG_RDTUN, &rt_numfibs, 0, ""); 98 99 /* 100 * By default add routes to all fibs for new interfaces. 101 * Once this is set to 0 then only allocate routes on interface 102 * changes for the FIB of the caller when adding a new set of addresses 103 * to an interface. XXX this is a shotgun aproach to a problem that needs 104 * a more fine grained solution.. that will come. 105 * XXX also has the problems getting the FIB from curthread which will not 106 * always work given the fib can be overridden and prefixes can be added 107 * from the network stack context. 108 */ 109 VNET_DEFINE(u_int, rt_add_addr_allfibs) = 1; 110 SYSCTL_UINT(_net, OID_AUTO, add_addr_allfibs, CTLFLAG_RWTUN | CTLFLAG_VNET, 111 &VNET_NAME(rt_add_addr_allfibs), 0, ""); 112 113 VNET_PCPUSTAT_DEFINE(struct rtstat, rtstat); 114 115 VNET_PCPUSTAT_SYSINIT(rtstat); 116 #ifdef VIMAGE 117 VNET_PCPUSTAT_SYSUNINIT(rtstat); 118 #endif 119 120 VNET_DEFINE(struct rib_head *, rt_tables); 121 #define V_rt_tables VNET(rt_tables) 122 123 124 VNET_DEFINE(uma_zone_t, rtzone); /* Routing table UMA zone. */ 125 #define V_rtzone VNET(rtzone) 126 127 EVENTHANDLER_LIST_DEFINE(rt_addrmsg); 128 129 static int rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *, 130 void *arg); 131 static void destroy_rtentry_epoch(epoch_context_t ctx); 132 static int rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, 133 int flags); 134 135 /* 136 * handler for net.my_fibnum 137 */ 138 static int 139 sysctl_my_fibnum(SYSCTL_HANDLER_ARGS) 140 { 141 int fibnum; 142 int error; 143 144 fibnum = curthread->td_proc->p_fibnum; 145 error = sysctl_handle_int(oidp, &fibnum, 0, req); 146 return (error); 147 } 148 149 SYSCTL_PROC(_net, OID_AUTO, my_fibnum, 150 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, 151 &sysctl_my_fibnum, "I", 152 "default FIB of caller"); 153 154 static __inline struct rib_head ** 155 rt_tables_get_rnh_ptr(int table, int fam) 156 { 157 struct rib_head **rnh; 158 159 KASSERT(table >= 0 && table < rt_numfibs, 160 ("%s: table out of bounds (0 <= %d < %d)", __func__, table, 161 rt_numfibs)); 162 KASSERT(fam >= 0 && fam < (AF_MAX + 1), 163 ("%s: fam out of bounds (0 <= %d < %d)", __func__, fam, AF_MAX+1)); 164 165 /* rnh is [fib=0][af=0]. */ 166 rnh = (struct rib_head **)V_rt_tables; 167 /* Get the offset to the requested table and fam. */ 168 rnh += table * (AF_MAX+1) + fam; 169 170 return (rnh); 171 } 172 173 struct rib_head * 174 rt_tables_get_rnh(int table, int fam) 175 { 176 177 return (*rt_tables_get_rnh_ptr(table, fam)); 178 } 179 180 u_int 181 rt_tables_get_gen(int table, int fam) 182 { 183 struct rib_head *rnh; 184 185 rnh = *rt_tables_get_rnh_ptr(table, fam); 186 KASSERT(rnh != NULL, ("%s: NULL rib_head pointer table %d fam %d", 187 __func__, table, fam)); 188 return (rnh->rnh_gen); 189 } 190 191 192 /* 193 * route initialization must occur before ip6_init2(), which happenas at 194 * SI_ORDER_MIDDLE. 195 */ 196 static void 197 route_init(void) 198 { 199 200 /* whack the tunable ints into line. */ 201 if (rt_numfibs > RT_MAXFIBS) 202 rt_numfibs = RT_MAXFIBS; 203 if (rt_numfibs == 0) 204 rt_numfibs = 1; 205 nhops_init(); 206 } 207 SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, NULL); 208 209 static int 210 rtentry_zinit(void *mem, int size, int how) 211 { 212 struct rtentry *rt = mem; 213 214 RT_LOCK_INIT(rt); 215 216 return (0); 217 } 218 219 static void 220 rtentry_zfini(void *mem, int size) 221 { 222 struct rtentry *rt = mem; 223 224 RT_LOCK_DESTROY(rt); 225 } 226 227 static int 228 rtentry_ctor(void *mem, int size, void *arg, int how) 229 { 230 struct rtentry *rt = mem; 231 232 bzero(rt, offsetof(struct rtentry, rt_endzero)); 233 rt->rt_chain = NULL; 234 235 return (0); 236 } 237 238 static void 239 rtentry_dtor(void *mem, int size, void *arg) 240 { 241 struct rtentry *rt = mem; 242 243 RT_UNLOCK_COND(rt); 244 } 245 246 static void 247 vnet_route_init(const void *unused __unused) 248 { 249 struct domain *dom; 250 struct rib_head **rnh; 251 int table; 252 int fam; 253 254 V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) * 255 sizeof(struct rib_head *), M_RTABLE, M_WAITOK|M_ZERO); 256 257 V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), 258 rtentry_ctor, rtentry_dtor, 259 rtentry_zinit, rtentry_zfini, UMA_ALIGN_PTR, 0); 260 for (dom = domains; dom; dom = dom->dom_next) { 261 if (dom->dom_rtattach == NULL) 262 continue; 263 264 for (table = 0; table < rt_numfibs; table++) { 265 fam = dom->dom_family; 266 if (table != 0 && fam != AF_INET6 && fam != AF_INET) 267 break; 268 269 rnh = rt_tables_get_rnh_ptr(table, fam); 270 if (rnh == NULL) 271 panic("%s: rnh NULL", __func__); 272 dom->dom_rtattach((void **)rnh, 0, table); 273 } 274 } 275 } 276 VNET_SYSINIT(vnet_route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_FOURTH, 277 vnet_route_init, 0); 278 279 #ifdef VIMAGE 280 static void 281 vnet_route_uninit(const void *unused __unused) 282 { 283 int table; 284 int fam; 285 struct domain *dom; 286 struct rib_head **rnh; 287 288 for (dom = domains; dom; dom = dom->dom_next) { 289 if (dom->dom_rtdetach == NULL) 290 continue; 291 292 for (table = 0; table < rt_numfibs; table++) { 293 fam = dom->dom_family; 294 295 if (table != 0 && fam != AF_INET6 && fam != AF_INET) 296 break; 297 298 rnh = rt_tables_get_rnh_ptr(table, fam); 299 if (rnh == NULL) 300 panic("%s: rnh NULL", __func__); 301 dom->dom_rtdetach((void **)rnh, 0); 302 } 303 } 304 305 /* 306 * dom_rtdetach calls rt_table_destroy(), which 307 * schedules deletion for all rtentries, nexthops and control 308 * structures. Wait for the destruction callbacks to fire. 309 * Note that this should result in freeing all rtentries, but 310 * nexthops deletions will be scheduled for the next epoch run 311 * and will be completed after vnet teardown. 312 */ 313 epoch_drain_callbacks(net_epoch_preempt); 314 315 free(V_rt_tables, M_RTABLE); 316 uma_zdestroy(V_rtzone); 317 } 318 VNET_SYSUNINIT(vnet_route_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, 319 vnet_route_uninit, 0); 320 #endif 321 322 struct rib_head * 323 rt_table_init(int offset, int family, u_int fibnum) 324 { 325 struct rib_head *rh; 326 327 rh = malloc(sizeof(struct rib_head), M_RTABLE, M_WAITOK | M_ZERO); 328 329 /* TODO: These details should be hidded inside radix.c */ 330 /* Init masks tree */ 331 rn_inithead_internal(&rh->head, rh->rnh_nodes, offset); 332 rn_inithead_internal(&rh->rmhead.head, rh->rmhead.mask_nodes, 0); 333 rh->head.rnh_masks = &rh->rmhead; 334 335 /* Save metadata associated with this routing table. */ 336 rh->rib_family = family; 337 rh->rib_fibnum = fibnum; 338 #ifdef VIMAGE 339 rh->rib_vnet = curvnet; 340 #endif 341 342 tmproutes_init(rh); 343 344 /* Init locks */ 345 RIB_LOCK_INIT(rh); 346 347 nhops_init_rib(rh); 348 349 /* Finally, set base callbacks */ 350 rh->rnh_addaddr = rn_addroute; 351 rh->rnh_deladdr = rn_delete; 352 rh->rnh_matchaddr = rn_match; 353 rh->rnh_lookup = rn_lookup; 354 rh->rnh_walktree = rn_walktree; 355 rh->rnh_walktree_from = rn_walktree_from; 356 357 return (rh); 358 } 359 360 static int 361 rt_freeentry(struct radix_node *rn, void *arg) 362 { 363 struct radix_head * const rnh = arg; 364 struct radix_node *x; 365 366 x = (struct radix_node *)rn_delete(rn + 2, NULL, rnh); 367 if (x != NULL) 368 R_Free(x); 369 return (0); 370 } 371 372 void 373 rt_table_destroy(struct rib_head *rh) 374 { 375 376 tmproutes_destroy(rh); 377 378 rn_walktree(&rh->rmhead.head, rt_freeentry, &rh->rmhead.head); 379 380 nhops_destroy_rib(rh); 381 382 /* Assume table is already empty */ 383 RIB_LOCK_DESTROY(rh); 384 free(rh, M_RTABLE); 385 } 386 387 388 #ifndef _SYS_SYSPROTO_H_ 389 struct setfib_args { 390 int fibnum; 391 }; 392 #endif 393 int 394 sys_setfib(struct thread *td, struct setfib_args *uap) 395 { 396 if (uap->fibnum < 0 || uap->fibnum >= rt_numfibs) 397 return EINVAL; 398 td->td_proc->p_fibnum = uap->fibnum; 399 return (0); 400 } 401 402 /* 403 * Remove a reference count from an rtentry. 404 * If the count gets low enough, take it out of the routing table 405 */ 406 void 407 rtfree(struct rtentry *rt) 408 { 409 410 KASSERT(rt != NULL,("%s: NULL rt", __func__)); 411 412 RT_LOCK_ASSERT(rt); 413 414 epoch_call(net_epoch_preempt, destroy_rtentry_epoch, 415 &rt->rt_epoch_ctx); 416 RT_UNLOCK(rt); 417 } 418 419 static void 420 destroy_rtentry(struct rtentry *rt) 421 { 422 423 /* 424 * At this moment rnh, nh_control may be already freed. 425 * nhop interface may have been migrated to a different vnet. 426 * Use vnet stored in the nexthop to delete the entry. 427 */ 428 CURVNET_SET(nhop_get_vnet(rt->rt_nhop)); 429 430 /* Unreference nexthop */ 431 nhop_free(rt->rt_nhop); 432 433 uma_zfree(V_rtzone, rt); 434 435 CURVNET_RESTORE(); 436 } 437 438 /* 439 * Epoch callback indicating rtentry is safe to destroy 440 */ 441 static void 442 destroy_rtentry_epoch(epoch_context_t ctx) 443 { 444 struct rtentry *rt; 445 446 rt = __containerof(ctx, struct rtentry, rt_epoch_ctx); 447 448 destroy_rtentry(rt); 449 } 450 451 /* 452 * Adds a temporal redirect entry to the routing table. 453 * @fibnum: fib number 454 * @dst: destination to install redirect to 455 * @gateway: gateway to go via 456 * @author: sockaddr of originating router, can be NULL 457 * @ifp: interface to use for the redirected route 458 * @flags: set of flags to add. Allowed: RTF_GATEWAY 459 * @lifetime_sec: time in seconds to expire this redirect. 460 * 461 * Retuns 0 on success, errno otherwise. 462 */ 463 int 464 rib_add_redirect(u_int fibnum, struct sockaddr *dst, struct sockaddr *gateway, 465 struct sockaddr *author, struct ifnet *ifp, int flags, int lifetime_sec) 466 { 467 struct rtentry *rt; 468 int error; 469 struct rt_addrinfo info; 470 struct rt_metrics rti_rmx; 471 struct ifaddr *ifa; 472 473 NET_EPOCH_ASSERT(); 474 475 if (rt_tables_get_rnh(fibnum, dst->sa_family) == NULL) 476 return (EAFNOSUPPORT); 477 478 /* Verify the allowed flag mask. */ 479 KASSERT(((flags & ~(RTF_GATEWAY)) == 0), 480 ("invalid redirect flags: %x", flags)); 481 482 /* Get the best ifa for the given interface and gateway. */ 483 if ((ifa = ifaof_ifpforaddr(gateway, ifp)) == NULL) 484 return (ENETUNREACH); 485 ifa_ref(ifa); 486 487 bzero(&info, sizeof(info)); 488 info.rti_info[RTAX_DST] = dst; 489 info.rti_info[RTAX_GATEWAY] = gateway; 490 info.rti_ifa = ifa; 491 info.rti_ifp = ifp; 492 info.rti_flags = flags | RTF_HOST | RTF_DYNAMIC; 493 494 /* Setup route metrics to define expire time. */ 495 bzero(&rti_rmx, sizeof(rti_rmx)); 496 /* Set expire time as absolute. */ 497 rti_rmx.rmx_expire = lifetime_sec + time_second; 498 info.rti_mflags |= RTV_EXPIRE; 499 info.rti_rmx = &rti_rmx; 500 501 error = rtrequest1_fib(RTM_ADD, &info, &rt, fibnum); 502 ifa_free(ifa); 503 504 if (error != 0) { 505 /* TODO: add per-fib redirect stats. */ 506 return (error); 507 } 508 509 RT_LOCK(rt); 510 flags = rt->rt_flags; 511 RT_UNLOCK(rt); 512 513 RTSTAT_INC(rts_dynamic); 514 515 /* Send notification of a route addition to userland. */ 516 bzero(&info, sizeof(info)); 517 info.rti_info[RTAX_DST] = dst; 518 info.rti_info[RTAX_GATEWAY] = gateway; 519 info.rti_info[RTAX_AUTHOR] = author; 520 rt_missmsg_fib(RTM_REDIRECT, &info, flags, error, fibnum); 521 522 return (0); 523 } 524 525 /* 526 * Routing table ioctl interface. 527 */ 528 int 529 rtioctl_fib(u_long req, caddr_t data, u_int fibnum) 530 { 531 532 /* 533 * If more ioctl commands are added here, make sure the proper 534 * super-user checks are being performed because it is possible for 535 * prison-root to make it this far if raw sockets have been enabled 536 * in jails. 537 */ 538 #ifdef INET 539 /* Multicast goop, grrr... */ 540 return mrt_ioctl ? mrt_ioctl(req, data, fibnum) : EOPNOTSUPP; 541 #else /* INET */ 542 return ENXIO; 543 #endif /* INET */ 544 } 545 546 struct ifaddr * 547 ifa_ifwithroute(int flags, const struct sockaddr *dst, 548 const struct sockaddr *gateway, u_int fibnum) 549 { 550 struct ifaddr *ifa; 551 552 NET_EPOCH_ASSERT(); 553 if ((flags & RTF_GATEWAY) == 0) { 554 /* 555 * If we are adding a route to an interface, 556 * and the interface is a pt to pt link 557 * we should search for the destination 558 * as our clue to the interface. Otherwise 559 * we can use the local address. 560 */ 561 ifa = NULL; 562 if (flags & RTF_HOST) 563 ifa = ifa_ifwithdstaddr(dst, fibnum); 564 if (ifa == NULL) 565 ifa = ifa_ifwithaddr(gateway); 566 } else { 567 /* 568 * If we are adding a route to a remote net 569 * or host, the gateway may still be on the 570 * other end of a pt to pt link. 571 */ 572 ifa = ifa_ifwithdstaddr(gateway, fibnum); 573 } 574 if (ifa == NULL) 575 ifa = ifa_ifwithnet(gateway, 0, fibnum); 576 if (ifa == NULL) { 577 struct nhop_object *nh; 578 579 nh = rib_lookup(fibnum, gateway, NHR_NONE, 0); 580 581 /* 582 * dismiss a gateway that is reachable only 583 * through the default router 584 */ 585 if ((nh == NULL) || (nh->nh_flags & NHF_DEFAULT)) 586 return (NULL); 587 ifa = nh->nh_ifa; 588 } 589 if (ifa->ifa_addr->sa_family != dst->sa_family) { 590 struct ifaddr *oifa = ifa; 591 ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); 592 if (ifa == NULL) 593 ifa = oifa; 594 } 595 596 return (ifa); 597 } 598 599 /* 600 * Do appropriate manipulations of a routing tree given 601 * all the bits of info needed 602 */ 603 int 604 rtrequest_fib(int req, 605 struct sockaddr *dst, 606 struct sockaddr *gateway, 607 struct sockaddr *netmask, 608 int flags, 609 struct rtentry **ret_nrt, 610 u_int fibnum) 611 { 612 struct rt_addrinfo info; 613 614 if (dst->sa_len == 0) 615 return(EINVAL); 616 617 bzero((caddr_t)&info, sizeof(info)); 618 info.rti_flags = flags; 619 info.rti_info[RTAX_DST] = dst; 620 info.rti_info[RTAX_GATEWAY] = gateway; 621 info.rti_info[RTAX_NETMASK] = netmask; 622 return rtrequest1_fib(req, &info, ret_nrt, fibnum); 623 } 624 625 626 /* 627 * Copy most of @rt data into @info. 628 * 629 * If @flags contains NHR_COPY, copies dst,netmask and gw to the 630 * pointers specified by @info structure. Assume such pointers 631 * are zeroed sockaddr-like structures with sa_len field initialized 632 * to reflect size of the provided buffer. if no NHR_COPY is specified, 633 * point dst,netmask and gw @info fields to appropriate @rt values. 634 * 635 * if @flags contains NHR_REF, do refcouting on rt_ifp and rt_ifa. 636 * 637 * Returns 0 on success. 638 */ 639 int 640 rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags) 641 { 642 struct rt_metrics *rmx; 643 struct sockaddr *src, *dst; 644 struct nhop_object *nh; 645 int sa_len; 646 647 if (flags & NHR_COPY) { 648 /* Copy destination if dst is non-zero */ 649 src = rt_key(rt); 650 dst = info->rti_info[RTAX_DST]; 651 sa_len = src->sa_len; 652 if (dst != NULL) { 653 if (src->sa_len > dst->sa_len) 654 return (ENOMEM); 655 memcpy(dst, src, src->sa_len); 656 info->rti_addrs |= RTA_DST; 657 } 658 659 /* Copy mask if set && dst is non-zero */ 660 src = rt_mask(rt); 661 dst = info->rti_info[RTAX_NETMASK]; 662 if (src != NULL && dst != NULL) { 663 664 /* 665 * Radix stores different value in sa_len, 666 * assume rt_mask() to have the same length 667 * as rt_key() 668 */ 669 if (sa_len > dst->sa_len) 670 return (ENOMEM); 671 memcpy(dst, src, src->sa_len); 672 info->rti_addrs |= RTA_NETMASK; 673 } 674 675 /* Copy gateway is set && dst is non-zero */ 676 src = &rt->rt_nhop->gw_sa; 677 dst = info->rti_info[RTAX_GATEWAY]; 678 if ((rt->rt_flags & RTF_GATEWAY) && src != NULL && dst != NULL){ 679 if (src->sa_len > dst->sa_len) 680 return (ENOMEM); 681 memcpy(dst, src, src->sa_len); 682 info->rti_addrs |= RTA_GATEWAY; 683 } 684 } else { 685 info->rti_info[RTAX_DST] = rt_key(rt); 686 info->rti_addrs |= RTA_DST; 687 if (rt_mask(rt) != NULL) { 688 info->rti_info[RTAX_NETMASK] = rt_mask(rt); 689 info->rti_addrs |= RTA_NETMASK; 690 } 691 if (rt->rt_flags & RTF_GATEWAY) { 692 info->rti_info[RTAX_GATEWAY] = &rt->rt_nhop->gw_sa; 693 info->rti_addrs |= RTA_GATEWAY; 694 } 695 } 696 697 nh = rt->rt_nhop; 698 rmx = info->rti_rmx; 699 if (rmx != NULL) { 700 info->rti_mflags |= RTV_MTU; 701 rmx->rmx_mtu = nh->nh_mtu; 702 } 703 704 info->rti_flags = rt->rt_flags | nhop_get_rtflags(nh); 705 info->rti_ifp = nh->nh_ifp; 706 info->rti_ifa = nh->nh_ifa; 707 if (flags & NHR_REF) { 708 if_ref(info->rti_ifp); 709 ifa_ref(info->rti_ifa); 710 } 711 712 return (0); 713 } 714 715 /* 716 * Lookups up route entry for @dst in RIB database for fib @fibnum. 717 * Exports entry data to @info using rt_exportinfo(). 718 * 719 * If @flags contains NHR_REF, refcouting is performed on rt_ifp and rt_ifa. 720 * All references can be released later by calling rib_free_info(). 721 * 722 * Returns 0 on success. 723 * Returns ENOENT for lookup failure, ENOMEM for export failure. 724 */ 725 int 726 rib_lookup_info(uint32_t fibnum, const struct sockaddr *dst, uint32_t flags, 727 uint32_t flowid, struct rt_addrinfo *info) 728 { 729 RIB_RLOCK_TRACKER; 730 struct rib_head *rh; 731 struct radix_node *rn; 732 struct rtentry *rt; 733 int error; 734 735 KASSERT((fibnum < rt_numfibs), ("rib_lookup_rte: bad fibnum")); 736 rh = rt_tables_get_rnh(fibnum, dst->sa_family); 737 if (rh == NULL) 738 return (ENOENT); 739 740 RIB_RLOCK(rh); 741 rn = rh->rnh_matchaddr(__DECONST(void *, dst), &rh->head); 742 if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) { 743 rt = RNTORT(rn); 744 /* Ensure route & ifp is UP */ 745 if (RT_LINK_IS_UP(rt->rt_nhop->nh_ifp)) { 746 flags = (flags & NHR_REF) | NHR_COPY; 747 error = rt_exportinfo(rt, info, flags); 748 RIB_RUNLOCK(rh); 749 750 return (error); 751 } 752 } 753 RIB_RUNLOCK(rh); 754 755 return (ENOENT); 756 } 757 758 /* 759 * Releases all references acquired by rib_lookup_info() when 760 * called with NHR_REF flags. 761 */ 762 void 763 rib_free_info(struct rt_addrinfo *info) 764 { 765 766 ifa_free(info->rti_ifa); 767 if_rele(info->rti_ifp); 768 } 769 770 /* 771 * Iterates over all existing fibs in system calling 772 * @setwa_f function prior to traversing each fib. 773 * Calls @wa_f function for each element in current fib. 774 * If af is not AF_UNSPEC, iterates over fibs in particular 775 * address family. 776 */ 777 void 778 rt_foreach_fib_walk(int af, rt_setwarg_t *setwa_f, rt_walktree_f_t *wa_f, 779 void *arg) 780 { 781 struct rib_head *rnh; 782 uint32_t fibnum; 783 int i; 784 785 for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { 786 /* Do we want some specific family? */ 787 if (af != AF_UNSPEC) { 788 rnh = rt_tables_get_rnh(fibnum, af); 789 if (rnh == NULL) 790 continue; 791 if (setwa_f != NULL) 792 setwa_f(rnh, fibnum, af, arg); 793 794 RIB_WLOCK(rnh); 795 rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg); 796 RIB_WUNLOCK(rnh); 797 continue; 798 } 799 800 for (i = 1; i <= AF_MAX; i++) { 801 rnh = rt_tables_get_rnh(fibnum, i); 802 if (rnh == NULL) 803 continue; 804 if (setwa_f != NULL) 805 setwa_f(rnh, fibnum, i, arg); 806 807 RIB_WLOCK(rnh); 808 rnh->rnh_walktree(&rnh->head, (walktree_f_t *)wa_f,arg); 809 RIB_WUNLOCK(rnh); 810 } 811 } 812 } 813 814 /* 815 * Iterates over all existing fibs in system and deletes each element 816 * for which @filter_f function returns non-zero value. 817 * If @family is not AF_UNSPEC, iterates over fibs in particular 818 * address family. 819 */ 820 void 821 rt_foreach_fib_walk_del(int family, rt_filter_f_t *filter_f, void *arg) 822 { 823 u_int fibnum; 824 int i, start, end; 825 826 for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { 827 /* Do we want some specific family? */ 828 if (family != AF_UNSPEC) { 829 start = family; 830 end = family; 831 } else { 832 start = 1; 833 end = AF_MAX; 834 } 835 836 for (i = start; i <= end; i++) { 837 if (rt_tables_get_rnh(fibnum, i) == NULL) 838 continue; 839 840 rib_walk_del(fibnum, i, filter_f, arg, 0); 841 } 842 } 843 } 844 845 /* 846 * Delete Routes for a Network Interface 847 * 848 * Called for each routing entry via the rnh->rnh_walktree() call above 849 * to delete all route entries referencing a detaching network interface. 850 * 851 * Arguments: 852 * rt pointer to rtentry 853 * nh pointer to nhop 854 * arg argument passed to rnh->rnh_walktree() - detaching interface 855 * 856 * Returns: 857 * 0 successful 858 * errno failed - reason indicated 859 */ 860 static int 861 rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *nh, void *arg) 862 { 863 struct ifnet *ifp = arg; 864 865 if (nh->nh_ifp != ifp) 866 return (0); 867 868 /* 869 * Protect (sorta) against walktree recursion problems 870 * with cloned routes 871 */ 872 if ((rt->rt_flags & RTF_UP) == 0) 873 return (0); 874 875 return (1); 876 } 877 878 /* 879 * Delete all remaining routes using this interface 880 * Unfortuneatly the only way to do this is to slog through 881 * the entire routing table looking for routes which point 882 * to this interface...oh well... 883 */ 884 void 885 rt_flushifroutes_af(struct ifnet *ifp, int af) 886 { 887 KASSERT((af >= 1 && af <= AF_MAX), ("%s: af %d not >= 1 and <= %d", 888 __func__, af, AF_MAX)); 889 890 rt_foreach_fib_walk_del(af, rt_ifdelroute, ifp); 891 } 892 893 void 894 rt_flushifroutes(struct ifnet *ifp) 895 { 896 897 rt_foreach_fib_walk_del(AF_UNSPEC, rt_ifdelroute, ifp); 898 } 899 900 /* 901 * Look up rt_addrinfo for a specific fib. Note that if rti_ifa is defined, 902 * it will be referenced so the caller must free it. 903 * 904 * Assume basic consistency checks are executed by callers: 905 * RTAX_DST exists, if RTF_GATEWAY is set, RTAX_GATEWAY exists as well. 906 */ 907 int 908 rt_getifa_fib(struct rt_addrinfo *info, u_int fibnum) 909 { 910 const struct sockaddr *dst, *gateway, *ifpaddr, *ifaaddr; 911 struct epoch_tracker et; 912 int needref, error, flags; 913 914 dst = info->rti_info[RTAX_DST]; 915 gateway = info->rti_info[RTAX_GATEWAY]; 916 ifpaddr = info->rti_info[RTAX_IFP]; 917 ifaaddr = info->rti_info[RTAX_IFA]; 918 flags = info->rti_flags; 919 920 /* 921 * ifp may be specified by sockaddr_dl 922 * when protocol address is ambiguous. 923 */ 924 error = 0; 925 needref = (info->rti_ifa == NULL); 926 NET_EPOCH_ENTER(et); 927 928 /* If we have interface specified by the ifindex in the address, use it */ 929 if (info->rti_ifp == NULL && ifpaddr != NULL && 930 ifpaddr->sa_family == AF_LINK) { 931 const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)ifpaddr; 932 if (sdl->sdl_index != 0) 933 info->rti_ifp = ifnet_byindex(sdl->sdl_index); 934 } 935 /* 936 * If we have source address specified, try to find it 937 * TODO: avoid enumerating all ifas on all interfaces. 938 */ 939 if (info->rti_ifa == NULL && ifaaddr != NULL) 940 info->rti_ifa = ifa_ifwithaddr(ifaaddr); 941 if (info->rti_ifa == NULL) { 942 const struct sockaddr *sa; 943 944 /* 945 * Most common use case for the userland-supplied routes. 946 * 947 * Choose sockaddr to select ifa. 948 * -- if ifp is set -- 949 * Order of preference: 950 * 1) IFA address 951 * 2) gateway address 952 * Note: for interface routes link-level gateway address 953 * is specified to indicate the interface index without 954 * specifying RTF_GATEWAY. In this case, ignore gateway 955 * Note: gateway AF may be different from dst AF. In this case, 956 * ignore gateway 957 * 3) final destination. 958 * 4) if all of these fails, try to get at least link-level ifa. 959 * -- else -- 960 * try to lookup gateway or dst in the routing table to get ifa 961 */ 962 if (info->rti_info[RTAX_IFA] != NULL) 963 sa = info->rti_info[RTAX_IFA]; 964 else if ((info->rti_flags & RTF_GATEWAY) != 0 && 965 gateway->sa_family == dst->sa_family) 966 sa = gateway; 967 else 968 sa = dst; 969 if (info->rti_ifp != NULL) { 970 info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp); 971 /* Case 4 */ 972 if (info->rti_ifa == NULL && gateway != NULL) 973 info->rti_ifa = ifaof_ifpforaddr(gateway, info->rti_ifp); 974 } else if (dst != NULL && gateway != NULL) 975 info->rti_ifa = ifa_ifwithroute(flags, dst, gateway, 976 fibnum); 977 else if (sa != NULL) 978 info->rti_ifa = ifa_ifwithroute(flags, sa, sa, 979 fibnum); 980 } 981 if (needref && info->rti_ifa != NULL) { 982 if (info->rti_ifp == NULL) 983 info->rti_ifp = info->rti_ifa->ifa_ifp; 984 ifa_ref(info->rti_ifa); 985 } else 986 error = ENETUNREACH; 987 NET_EPOCH_EXIT(et); 988 return (error); 989 } 990 991 void 992 rt_updatemtu(struct ifnet *ifp) 993 { 994 struct rib_head *rnh; 995 int mtu; 996 int i, j; 997 998 /* 999 * Try to update rt_mtu for all routes using this interface 1000 * Unfortunately the only way to do this is to traverse all 1001 * routing tables in all fibs/domains. 1002 */ 1003 for (i = 1; i <= AF_MAX; i++) { 1004 mtu = if_getmtu_family(ifp, i); 1005 for (j = 0; j < rt_numfibs; j++) { 1006 rnh = rt_tables_get_rnh(j, i); 1007 if (rnh == NULL) 1008 continue; 1009 nhops_update_ifmtu(rnh, ifp, mtu); 1010 } 1011 } 1012 } 1013 1014 1015 #if 0 1016 int p_sockaddr(char *buf, int buflen, struct sockaddr *s); 1017 int rt_print(char *buf, int buflen, struct rtentry *rt); 1018 1019 int 1020 p_sockaddr(char *buf, int buflen, struct sockaddr *s) 1021 { 1022 void *paddr = NULL; 1023 1024 switch (s->sa_family) { 1025 case AF_INET: 1026 paddr = &((struct sockaddr_in *)s)->sin_addr; 1027 break; 1028 case AF_INET6: 1029 paddr = &((struct sockaddr_in6 *)s)->sin6_addr; 1030 break; 1031 } 1032 1033 if (paddr == NULL) 1034 return (0); 1035 1036 if (inet_ntop(s->sa_family, paddr, buf, buflen) == NULL) 1037 return (0); 1038 1039 return (strlen(buf)); 1040 } 1041 1042 int 1043 rt_print(char *buf, int buflen, struct rtentry *rt) 1044 { 1045 struct sockaddr *addr, *mask; 1046 int i = 0; 1047 1048 addr = rt_key(rt); 1049 mask = rt_mask(rt); 1050 1051 i = p_sockaddr(buf, buflen, addr); 1052 if (!(rt->rt_flags & RTF_HOST)) { 1053 buf[i++] = '/'; 1054 i += p_sockaddr(buf + i, buflen - i, mask); 1055 } 1056 1057 if (rt->rt_flags & RTF_GATEWAY) { 1058 buf[i++] = '>'; 1059 i += p_sockaddr(buf + i, buflen - i, &rt->rt_nhop->gw_sa); 1060 } 1061 1062 return (i); 1063 } 1064 #endif 1065 1066 #ifdef RADIX_MPATH 1067 /* 1068 * Deletes key for single-path routes, unlinks rtentry with 1069 * gateway specified in @info from multi-path routes. 1070 * 1071 * Returnes unlinked entry. In case of failure, returns NULL 1072 * and sets @perror to ESRCH. 1073 */ 1074 struct radix_node * 1075 rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info, 1076 struct rtentry *rto, int *perror) 1077 { 1078 /* 1079 * if we got multipath routes, we require users to specify 1080 * a matching RTAX_GATEWAY. 1081 */ 1082 struct rtentry *rt; // *rto = NULL; 1083 struct radix_node *rn; 1084 struct sockaddr *gw; 1085 1086 gw = info->rti_info[RTAX_GATEWAY]; 1087 rt = rt_mpath_matchgate(rto, gw); 1088 if (rt == NULL) { 1089 *perror = ESRCH; 1090 return (NULL); 1091 } 1092 1093 /* 1094 * this is the first entry in the chain 1095 */ 1096 if (rto == rt) { 1097 rn = rn_mpath_next((struct radix_node *)rt); 1098 /* 1099 * there is another entry, now it's active 1100 */ 1101 if (rn) { 1102 rto = RNTORT(rn); 1103 RT_LOCK(rto); 1104 rto->rt_flags |= RTF_UP; 1105 RT_UNLOCK(rto); 1106 } else if (rt->rt_flags & RTF_GATEWAY) { 1107 /* 1108 * For gateway routes, we need to 1109 * make sure that we we are deleting 1110 * the correct gateway. 1111 * rt_mpath_matchgate() does not 1112 * check the case when there is only 1113 * one route in the chain. 1114 */ 1115 if (gw && 1116 (rt->rt_nhop->gw_sa.sa_len != gw->sa_len || 1117 memcmp(&rt->rt_nhop->gw_sa, gw, gw->sa_len))) { 1118 *perror = ESRCH; 1119 return (NULL); 1120 } 1121 } 1122 1123 /* 1124 * use the normal delete code to remove 1125 * the first entry 1126 */ 1127 rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST], 1128 info->rti_info[RTAX_NETMASK], 1129 &rnh->head); 1130 *perror = 0; 1131 return (rn); 1132 } 1133 1134 /* 1135 * if the entry is 2nd and on up 1136 */ 1137 if (rt_mpath_deldup(rto, rt) == 0) 1138 panic ("rtrequest1: rt_mpath_deldup"); 1139 *perror = 0; 1140 rn = (struct radix_node *)rt; 1141 return (rn); 1142 } 1143 #endif 1144 1145 int 1146 rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, 1147 u_int fibnum) 1148 { 1149 const struct sockaddr *dst; 1150 struct rib_head *rnh; 1151 int error; 1152 1153 KASSERT((fibnum < rt_numfibs), ("rtrequest1_fib: bad fibnum")); 1154 KASSERT((info->rti_flags & RTF_RNH_LOCKED) == 0, ("rtrequest1_fib: locked")); 1155 NET_EPOCH_ASSERT(); 1156 1157 dst = info->rti_info[RTAX_DST]; 1158 1159 switch (dst->sa_family) { 1160 case AF_INET6: 1161 case AF_INET: 1162 /* We support multiple FIBs. */ 1163 break; 1164 default: 1165 fibnum = RT_DEFAULT_FIB; 1166 break; 1167 } 1168 1169 /* 1170 * Find the correct routing tree to use for this Address Family 1171 */ 1172 rnh = rt_tables_get_rnh(fibnum, dst->sa_family); 1173 if (rnh == NULL) 1174 return (EAFNOSUPPORT); 1175 1176 /* 1177 * If we are adding a host route then we don't want to put 1178 * a netmask in the tree, nor do we want to clone it. 1179 */ 1180 if (info->rti_flags & RTF_HOST) 1181 info->rti_info[RTAX_NETMASK] = NULL; 1182 1183 error = 0; 1184 switch (req) { 1185 case RTM_DELETE: 1186 error = del_route(rnh, info, ret_nrt); 1187 break; 1188 case RTM_RESOLVE: 1189 /* 1190 * resolve was only used for route cloning 1191 * here for compat 1192 */ 1193 break; 1194 case RTM_ADD: 1195 error = add_route(rnh, info, ret_nrt); 1196 break; 1197 case RTM_CHANGE: 1198 error = change_route(rnh, info, ret_nrt); 1199 break; 1200 default: 1201 error = EOPNOTSUPP; 1202 } 1203 1204 return (error); 1205 } 1206 1207 void 1208 rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt) 1209 { 1210 1211 if (info->rti_mflags & RTV_WEIGHT) 1212 rt->rt_weight = info->rti_rmx->rmx_weight; 1213 /* Kernel -> userland timebase conversion. */ 1214 if (info->rti_mflags & RTV_EXPIRE) 1215 rt->rt_expire = info->rti_rmx->rmx_expire ? 1216 info->rti_rmx->rmx_expire - time_second + time_uptime : 0; 1217 } 1218 1219 void 1220 rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask) 1221 { 1222 u_char *cp1 = (u_char *)src; 1223 u_char *cp2 = (u_char *)dst; 1224 u_char *cp3 = (u_char *)netmask; 1225 u_char *cplim = cp2 + *cp3; 1226 u_char *cplim2 = cp2 + *cp1; 1227 1228 *cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */ 1229 cp3 += 2; 1230 if (cplim > cplim2) 1231 cplim = cplim2; 1232 while (cp2 < cplim) 1233 *cp2++ = *cp1++ & *cp3++; 1234 if (cp2 < cplim2) 1235 bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2)); 1236 } 1237 1238 /* 1239 * Set up a routing table entry, normally 1240 * for an interface. 1241 */ 1242 #define _SOCKADDR_TMPSIZE 128 /* Not too big.. kernel stack size is limited */ 1243 static inline int 1244 rtinit1(struct ifaddr *ifa, int cmd, int flags, int fibnum) 1245 { 1246 RIB_RLOCK_TRACKER; 1247 struct epoch_tracker et; 1248 struct sockaddr *dst; 1249 struct sockaddr *netmask; 1250 struct rtentry *rt = NULL; 1251 struct rt_addrinfo info; 1252 int error = 0; 1253 int startfib, endfib; 1254 char tempbuf[_SOCKADDR_TMPSIZE]; 1255 int didwork = 0; 1256 int a_failure = 0; 1257 struct sockaddr_dl_short *sdl = NULL; 1258 struct rib_head *rnh; 1259 1260 if (flags & RTF_HOST) { 1261 dst = ifa->ifa_dstaddr; 1262 netmask = NULL; 1263 } else { 1264 dst = ifa->ifa_addr; 1265 netmask = ifa->ifa_netmask; 1266 } 1267 if (dst->sa_len == 0) 1268 return(EINVAL); 1269 switch (dst->sa_family) { 1270 case AF_INET6: 1271 case AF_INET: 1272 /* We support multiple FIBs. */ 1273 break; 1274 default: 1275 fibnum = RT_DEFAULT_FIB; 1276 break; 1277 } 1278 if (fibnum == RT_ALL_FIBS) { 1279 if (V_rt_add_addr_allfibs == 0 && cmd == (int)RTM_ADD) 1280 startfib = endfib = ifa->ifa_ifp->if_fib; 1281 else { 1282 startfib = 0; 1283 endfib = rt_numfibs - 1; 1284 } 1285 } else { 1286 KASSERT((fibnum < rt_numfibs), ("rtinit1: bad fibnum")); 1287 startfib = fibnum; 1288 endfib = fibnum; 1289 } 1290 1291 /* 1292 * If it's a delete, check that if it exists, 1293 * it's on the correct interface or we might scrub 1294 * a route to another ifa which would 1295 * be confusing at best and possibly worse. 1296 */ 1297 if (cmd == RTM_DELETE) { 1298 /* 1299 * It's a delete, so it should already exist.. 1300 * If it's a net, mask off the host bits 1301 * (Assuming we have a mask) 1302 * XXX this is kinda inet specific.. 1303 */ 1304 if (netmask != NULL) { 1305 rt_maskedcopy(dst, (struct sockaddr *)tempbuf, netmask); 1306 dst = (struct sockaddr *)tempbuf; 1307 } 1308 } else if (cmd == RTM_ADD) { 1309 sdl = (struct sockaddr_dl_short *)tempbuf; 1310 bzero(sdl, sizeof(struct sockaddr_dl_short)); 1311 sdl->sdl_family = AF_LINK; 1312 sdl->sdl_len = sizeof(struct sockaddr_dl_short); 1313 sdl->sdl_type = ifa->ifa_ifp->if_type; 1314 sdl->sdl_index = ifa->ifa_ifp->if_index; 1315 } 1316 /* 1317 * Now go through all the requested tables (fibs) and do the 1318 * requested action. Realistically, this will either be fib 0 1319 * for protocols that don't do multiple tables or all the 1320 * tables for those that do. 1321 */ 1322 for ( fibnum = startfib; fibnum <= endfib; fibnum++) { 1323 if (cmd == RTM_DELETE) { 1324 struct radix_node *rn; 1325 /* 1326 * Look up an rtentry that is in the routing tree and 1327 * contains the correct info. 1328 */ 1329 rnh = rt_tables_get_rnh(fibnum, dst->sa_family); 1330 if (rnh == NULL) 1331 /* this table doesn't exist but others might */ 1332 continue; 1333 RIB_RLOCK(rnh); 1334 rn = rnh->rnh_lookup(dst, netmask, &rnh->head); 1335 #ifdef RADIX_MPATH 1336 if (rt_mpath_capable(rnh)) { 1337 1338 if (rn == NULL) 1339 error = ESRCH; 1340 else { 1341 rt = RNTORT(rn); 1342 /* 1343 * for interface route the gateway 1344 * gateway is sockaddr_dl, so 1345 * rt_mpath_matchgate must use the 1346 * interface address 1347 */ 1348 rt = rt_mpath_matchgate(rt, 1349 ifa->ifa_addr); 1350 if (rt == NULL) 1351 error = ESRCH; 1352 } 1353 } 1354 #endif 1355 error = (rn == NULL || 1356 (rn->rn_flags & RNF_ROOT) || 1357 RNTORT(rn)->rt_nhop->nh_ifa != ifa); 1358 RIB_RUNLOCK(rnh); 1359 if (error) { 1360 /* this is only an error if bad on ALL tables */ 1361 continue; 1362 } 1363 } 1364 /* 1365 * Do the actual request 1366 */ 1367 bzero((caddr_t)&info, sizeof(info)); 1368 info.rti_ifa = ifa; 1369 info.rti_flags = flags | 1370 (ifa->ifa_flags & ~IFA_RTSELF) | RTF_PINNED; 1371 info.rti_info[RTAX_DST] = dst; 1372 /* 1373 * doing this for compatibility reasons 1374 */ 1375 if (cmd == RTM_ADD) 1376 info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)sdl; 1377 else 1378 info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; 1379 info.rti_info[RTAX_NETMASK] = netmask; 1380 NET_EPOCH_ENTER(et); 1381 error = rtrequest1_fib(cmd, &info, &rt, fibnum); 1382 if (error == 0 && rt != NULL) { 1383 /* 1384 * notify any listening routing agents of the change 1385 */ 1386 1387 /* TODO: interface routes/aliases */ 1388 rt_newaddrmsg_fib(cmd, ifa, rt, fibnum); 1389 didwork = 1; 1390 } 1391 NET_EPOCH_EXIT(et); 1392 if (error) 1393 a_failure = error; 1394 } 1395 if (cmd == RTM_DELETE) { 1396 if (didwork) { 1397 error = 0; 1398 } else { 1399 /* we only give an error if it wasn't in any table */ 1400 error = ((flags & RTF_HOST) ? 1401 EHOSTUNREACH : ENETUNREACH); 1402 } 1403 } else { 1404 if (a_failure) { 1405 /* return an error if any of them failed */ 1406 error = a_failure; 1407 } 1408 } 1409 return (error); 1410 } 1411 1412 /* 1413 * Set up a routing table entry, normally 1414 * for an interface. 1415 */ 1416 int 1417 rtinit(struct ifaddr *ifa, int cmd, int flags) 1418 { 1419 struct sockaddr *dst; 1420 int fib = RT_DEFAULT_FIB; 1421 1422 if (flags & RTF_HOST) { 1423 dst = ifa->ifa_dstaddr; 1424 } else { 1425 dst = ifa->ifa_addr; 1426 } 1427 1428 switch (dst->sa_family) { 1429 case AF_INET6: 1430 case AF_INET: 1431 /* We do support multiple FIBs. */ 1432 fib = RT_ALL_FIBS; 1433 break; 1434 } 1435 return (rtinit1(ifa, cmd, flags, fib)); 1436 } 1437 1438 /* 1439 * Announce interface address arrival/withdraw 1440 * Returns 0 on success. 1441 */ 1442 int 1443 rt_addrmsg(int cmd, struct ifaddr *ifa, int fibnum) 1444 { 1445 1446 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1447 ("unexpected cmd %d", cmd)); 1448 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1449 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1450 1451 EVENTHANDLER_DIRECT_INVOKE(rt_addrmsg, ifa, cmd); 1452 return (rtsock_addrmsg(cmd, ifa, fibnum)); 1453 } 1454 1455 /* 1456 * Announce kernel-originated route addition/removal to rtsock based on @rt data. 1457 * cmd: RTM_ cmd 1458 * @rt: valid rtentry 1459 * @ifp: target route interface 1460 * @fibnum: fib id or RT_ALL_FIBS 1461 * 1462 * Returns 0 on success. 1463 */ 1464 int 1465 rt_routemsg(int cmd, struct rtentry *rt, struct ifnet *ifp, int rti_addrs, 1466 int fibnum) 1467 { 1468 1469 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1470 ("unexpected cmd %d", cmd)); 1471 1472 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1473 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1474 1475 KASSERT(rt_key(rt) != NULL, (":%s: rt_key must be supplied", __func__)); 1476 1477 return (rtsock_routemsg(cmd, rt, ifp, 0, fibnum)); 1478 } 1479 1480 /* 1481 * Announce kernel-originated route addition/removal to rtsock based on @rt data. 1482 * cmd: RTM_ cmd 1483 * @info: addrinfo structure with valid data. 1484 * @fibnum: fib id or RT_ALL_FIBS 1485 * 1486 * Returns 0 on success. 1487 */ 1488 int 1489 rt_routemsg_info(int cmd, struct rt_addrinfo *info, int fibnum) 1490 { 1491 1492 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE || cmd == RTM_CHANGE, 1493 ("unexpected cmd %d", cmd)); 1494 1495 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1496 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1497 1498 KASSERT(info->rti_info[RTAX_DST] != NULL, (":%s: RTAX_DST must be supplied", __func__)); 1499 1500 return (rtsock_routemsg_info(cmd, info, fibnum)); 1501 } 1502 1503 1504 /* 1505 * This is called to generate messages from the routing socket 1506 * indicating a network interface has had addresses associated with it. 1507 */ 1508 void 1509 rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, struct rtentry *rt, int fibnum) 1510 { 1511 1512 KASSERT(cmd == RTM_ADD || cmd == RTM_DELETE, 1513 ("unexpected cmd %u", cmd)); 1514 KASSERT(fibnum == RT_ALL_FIBS || (fibnum >= 0 && fibnum < rt_numfibs), 1515 ("%s: fib out of range 0 <=%d<%d", __func__, fibnum, rt_numfibs)); 1516 1517 if (cmd == RTM_ADD) { 1518 rt_addrmsg(cmd, ifa, fibnum); 1519 if (rt != NULL) 1520 rt_routemsg(cmd, rt, ifa->ifa_ifp, 0, fibnum); 1521 } else { 1522 if (rt != NULL) 1523 rt_routemsg(cmd, rt, ifa->ifa_ifp, 0, fibnum); 1524 rt_addrmsg(cmd, ifa, fibnum); 1525 } 1526 } 1527 1528