1 /* 2 * Copyright (c) 2000-2022 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* 29 * Copyright (c) 1980, 1986, 1993 30 * The Regents of the University of California. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Berkeley and its contributors. 44 * 4. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)route.h 8.3 (Berkeley) 4/19/94 61 * $FreeBSD: src/sys/net/route.h,v 1.36.2.1 2000/08/16 06:14:23 jayanth Exp $ 62 */ 63 64 #ifndef _NET_ROUTE_PRIVATE_H_ 65 #define _NET_ROUTE_PRIVATE_H_ 66 #include <net/route.h> 67 #include <stdint.h> 68 #include <sys/types.h> 69 #include <sys/socket.h> 70 #include <uuid/uuid.h> 71 72 struct route_old { 73 void *ro_rt; 74 uint32_t ro_flags; 75 struct sockaddr ro_dst; 76 }; 77 78 #ifdef BSD_KERNEL_PRIVATE 79 #include <kern/locks.h> 80 #include <net/radix.h> 81 #include <sys/eventhandler.h> 82 #include <net/if_dl.h> 83 #include <netinet/in_private.h> 84 85 extern boolean_t trigger_v6_defrtr_select; 86 /* 87 * Kernel resident routing tables. 88 * 89 * The routing tables are initialized when interface addresses 90 * are set by making entries for all directly connected interfaces. 91 */ 92 93 /* forward declarations */ 94 struct ifnet_llreach_info; 95 struct rt_reach_info; 96 97 /* 98 * IP route structure 99 * 100 * A route consists of a destination address and a reference 101 * to a routing entry. These are often held by protocols 102 * in their control blocks, e.g. inpcb. 103 */ 104 struct route { 105 /* 106 * N.B: struct route must begin with ro_{rt, lle, srcia, flags} 107 * because the code does some casts of a 'struct route_in6 *' 108 * to a 'struct route *'. 109 */ 110 struct rtentry *ro_rt; 111 struct ifaddr *ro_srcia; 112 uint32_t ro_flags; /* route flags (see below) */ 113 #if __has_ptrcheck 114 struct sockaddr_in ro_dst; 115 #else 116 struct sockaddr ro_dst; 117 #endif 118 }; 119 120 #define ROF_SRCIF_SELECTED 0x0001 /* source interface was selected */ 121 122 #define ROUTE_UNUSABLE(_ro) \ 123 ((_ro)->ro_rt == NULL || \ 124 ((_ro)->ro_rt->rt_flags & (RTF_UP|RTF_CONDEMNED)) != RTF_UP || \ 125 RT_GENID_OUTOFSYNC((_ro)->ro_rt)) 126 127 #define _ROUTE_RELEASE_COMMON(_ro, _rnh_locked) do { \ 128 if ((_ro)->ro_rt != NULL) { \ 129 RT_LOCK_ASSERT_NOTHELD((_ro)->ro_rt); \ 130 if (_rnh_locked) \ 131 rtfree_locked((_ro)->ro_rt); \ 132 else \ 133 rtfree((_ro)->ro_rt); \ 134 (_ro)->ro_rt = NULL; \ 135 } \ 136 if ((_ro)->ro_srcia != NULL) { \ 137 IFA_REMREF((_ro)->ro_srcia); \ 138 (_ro)->ro_srcia = NULL; \ 139 (_ro)->ro_flags &= ~ROF_SRCIF_SELECTED; \ 140 } \ 141 } while (0) 142 143 #define ROUTE_RELEASE_LOCKED(_ro) _ROUTE_RELEASE_COMMON(_ro, TRUE) 144 #define ROUTE_RELEASE(_ro) _ROUTE_RELEASE_COMMON(_ro, FALSE) 145 146 /* 147 * We distinguish between routes to hosts and routes to networks, 148 * preferring the former if available. For each route we infer 149 * the interface to use from the gateway address supplied when 150 * the route was entered. Routes that forward packets through 151 * gateways are marked so that the output routines know to address the 152 * gateway rather than the ultimate destination. 153 */ 154 155 #define NRTT_HIST 10 156 /* 157 * Kernel routing entry structure. 158 */ 159 struct rtentry { 160 struct radix_node rt_nodes[2]; /* tree glue, and other values */ 161 #define rt_key(r) (SA((r)->rt_nodes->rn_key)) 162 #define rt_mask(r) (SA((r)->rt_nodes->rn_mask)) 163 /* 164 * See bsd/net/route.c for synchronization notes. 165 */ 166 decl_lck_mtx_data(, rt_lock); /* lock for routing entry */ 167 uint32_t rt_refcnt; /* # held references */ 168 uint32_t rt_flags; /* up/down?, host/net */ 169 uint32_t rt_genid; /* route generation id */ 170 struct sockaddr *rt_gateway; /* value */ 171 struct ifnet *rt_ifp; /* the answer: interface to use */ 172 struct ifaddr *rt_ifa; /* the answer: interface addr to use */ 173 struct sockaddr *rt_genmask; /* for generation of cloned routes */ 174 void *rt_llinfo; /* pointer to link level info cache */ 175 void (*rt_llinfo_get_ri) /* llinfo get reachability info fn */ 176 (struct rtentry *, struct rt_reach_info *); 177 void (*rt_llinfo_get_iflri) /* ifnet llinfo get reach. info fn */ 178 (struct rtentry *, struct ifnet_llreach_info *); 179 void (*rt_llinfo_purge)(struct rtentry *); /* llinfo purge fn */ 180 void (*rt_llinfo_free)(void *); /* link level info free function */ 181 void (*rt_llinfo_refresh) (struct rtentry *); /* expedite llinfo refresh */ 182 struct rt_metrics rt_rmx; /* metrics used by rx'ing protocols */ 183 #define rt_use rt_rmx.rmx_pksent 184 struct rtentry *rt_gwroute; /* implied entry for gatewayed routes */ 185 struct rtentry *rt_parent; /* cloning parent of this route */ 186 struct nstat_counts *rt_stats; /* route stats */ 187 void (*rt_if_ref_fn)(struct ifnet *, int); /* interface ref func */ 188 189 uint32_t *rt_tree_genid; /* ptr to per-tree route_genid */ 190 uint64_t rt_expire; /* expiration time in uptime seconds */ 191 uint64_t base_calendartime; /* calendar time upon entry creation */ 192 uint64_t base_uptime; /* uptime upon entry creation */ 193 u_int32_t rtt_hist[NRTT_HIST]; /* RTT history sample by TCP connections */ 194 u_int32_t rtt_min; /* minimum RTT computed from history */ 195 u_int32_t rtt_expire_ts; /* RTT history expire timestamp */ 196 u_int8_t rtt_index; /* Index into RTT history */ 197 /* Event handler context for the rtentrt */ 198 struct eventhandler_lists_ctxt rt_evhdlr_ctxt; 199 }; 200 201 #define rt_key_free(r) ({ \ 202 void *__r = rt_key(r); \ 203 kheap_free_addr(KHEAP_DATA_BUFFERS, __r); \ 204 }) 205 206 enum { 207 ROUTE_STATUS_UPDATE = 1, 208 ROUTE_ENTRY_REFRESH, 209 ROUTE_ENTRY_DELETED, 210 ROUTE_LLENTRY_RESOLVED, 211 ROUTE_LLENTRY_UNREACH, 212 ROUTE_LLENTRY_CHANGED, 213 ROUTE_LLENTRY_STALE, 214 ROUTE_LLENTRY_TIMEDOUT, 215 ROUTE_LLENTRY_DELETED, 216 ROUTE_LLENTRY_EXPIRED, 217 ROUTE_LLENTRY_PROBED, 218 ROUTE_EVHDLR_DEREGISTER, 219 }; 220 221 extern const char * route_event2str(int route_event); 222 223 typedef void (*route_event_fn) (struct eventhandler_entry_arg, 224 struct sockaddr *, int, struct sockaddr *, int); 225 EVENTHANDLER_DECLARE(route_event, route_event_fn); 226 227 /* 228 * Synchronize route entry's generation ID with the tree's. 229 */ 230 #define RT_GENID_SYNC(_rt) do { \ 231 if ((_rt)->rt_tree_genid != NULL) \ 232 (_rt)->rt_genid = *(_rt)->rt_tree_genid; \ 233 } while (0) 234 235 /* 236 * Indicates whether or not the route entry's generation ID is stale. 237 */ 238 #define RT_GENID_OUTOFSYNC(_rt) \ 239 ((_rt)->rt_tree_genid != NULL && \ 240 *(_rt)->rt_tree_genid != (_rt)->rt_genid) 241 242 enum { 243 ROUTE_OP_READ, 244 ROUTE_OP_WRITE, 245 }; 246 247 extern int route_op_entitlement_check(struct socket *, kauth_cred_t, int, boolean_t); 248 #endif /* BSD_KERNEL_PRIVATE */ 249 250 struct kev_netevent_apnfallbk_data { 251 pid_t epid; /* effective PID */ 252 uuid_t euuid; /* effective UUID */ 253 }; 254 255 /* 256 * Route reachability info. 257 */ 258 struct rt_reach_info { 259 u_int32_t ri_refcnt; /* reference count */ 260 u_int32_t ri_probes; /* total # of probes */ 261 u_int64_t ri_snd_expire; /* tx expiration (calendar) time */ 262 u_int64_t ri_rcv_expire; /* rx expiration (calendar) time */ 263 int32_t ri_rssi; /* received signal strength */ 264 int32_t ri_lqm; /* link quality metric */ 265 int32_t ri_npm; /* node proximity metric */ 266 }; 267 268 /* 269 * Extended routing message header (private). 270 */ 271 struct rt_msghdr_ext { 272 u_short rtm_msglen; /* to skip over non-understood messages */ 273 u_char rtm_version; /* future binary compatibility */ 274 u_char rtm_type; /* message type */ 275 u_int32_t rtm_index; /* index for associated ifp */ 276 u_int32_t rtm_flags; /* flags, incl. kern & message, e.g. DONE */ 277 u_int32_t rtm_reserved; /* for future use */ 278 u_int32_t rtm_addrs; /* bitmask identifying sockaddrs in msg */ 279 pid_t rtm_pid; /* identify sender */ 280 int rtm_seq; /* for sender to identify action */ 281 int rtm_errno; /* why failed */ 282 u_int32_t rtm_use; /* from rtentry */ 283 u_int32_t rtm_inits; /* which metrics we are initializing */ 284 struct rt_metrics rtm_rmx; /* metrics themselves */ 285 struct rt_reach_info rtm_ri; /* route reachability info */ 286 }; 287 288 /* 289 * Message types. 290 */ 291 #define RTM_GET_SILENT 0x11 292 #define RTM_GET_EXT 0x15 293 294 /* 295 * Bitmask values for rtm_inits and rmx_locks. 296 */ 297 #define RTV_REFRESH_HOST 0x100 /* init host route to expedite refresh */ 298 299 /* 300 * For scoped routing; a zero interface scope value means nil/no scope. 301 */ 302 #define IFSCOPE_NONE 0 303 #define IFSCOPE_UNKNOWN IFSCOPE_NONE 304 305 #ifdef BSD_KERNEL_PRIVATE 306 /* 307 * Generic call trace used by some subsystems (e.g. route, ifaddr) 308 */ 309 #define CTRACE_STACK_SIZE 8 /* depth of stack trace */ 310 #define CTRACE_HIST_SIZE 4 /* refcnt history size */ 311 typedef struct ctrace { 312 void *th; /* thread ptr */ 313 void *pc[CTRACE_STACK_SIZE]; /* PC stack trace */ 314 } ctrace_t; 315 316 extern void ctrace_record(ctrace_t *); 317 318 #define RT_LOCK_ASSERT_HELD(_rt) \ 319 LCK_MTX_ASSERT(&(_rt)->rt_lock, LCK_MTX_ASSERT_OWNED) 320 321 #define RT_LOCK_ASSERT_NOTHELD(_rt) \ 322 LCK_MTX_ASSERT(&(_rt)->rt_lock, LCK_MTX_ASSERT_NOTOWNED) 323 324 #define RT_LOCK(_rt) do { \ 325 rt_lock(_rt, FALSE); \ 326 } while (0) 327 328 #define RT_LOCK_SPIN(_rt) do { \ 329 rt_lock(_rt, TRUE); \ 330 } while (0) 331 332 #define RT_CONVERT_LOCK(_rt) do { \ 333 RT_LOCK_ASSERT_HELD(_rt); \ 334 lck_mtx_convert_spin(&(_rt)->rt_lock); \ 335 } while (0) 336 337 #define RT_UNLOCK(_rt) do { \ 338 rt_unlock(_rt); \ 339 } while (0) 340 341 #define RT_ADDREF_LOCKED(_rt) do { \ 342 rtref(_rt); \ 343 } while (0) 344 345 /* 346 * Spin variant mutex is used here; caller is responsible for 347 * converting any previously-held similar lock to full mutex. 348 */ 349 #define RT_ADDREF(_rt) do { \ 350 RT_LOCK_SPIN(_rt); \ 351 RT_ADDREF_LOCKED(_rt); \ 352 RT_UNLOCK(_rt); \ 353 } while (0) 354 355 #define RT_REMREF_LOCKED(_rt) do { \ 356 (void) rtunref(_rt); \ 357 } while (0) 358 359 /* 360 * Spin variant mutex is used here; caller is responsible for 361 * converting any previously-held similar lock to full mutex. 362 */ 363 #define RT_REMREF(_rt) do { \ 364 RT_LOCK_SPIN(_rt); \ 365 RT_REMREF_LOCKED(_rt); \ 366 RT_UNLOCK(_rt); \ 367 } while (0) 368 369 /* 370 * This macro calculates skew in wall clock, just in case the user changes the 371 * system time. This skew adjustment is required because we now keep the 372 * expiration times in uptime terms in the kernel, but the userland still 373 * expects expiration times in terms of calendar times. This is used when 374 * reporting rt_expire, ln_expire, etc. values to user space. 375 */ 376 #define NET_CALCULATE_CLOCKSKEW(cc, ic, cu, iu) \ 377 ((cc.tv_sec - ic) - (cu - iu)) 378 379 extern unsigned int rt_verbose; 380 extern struct radix_node_head *rt_tables[AF_MAX + 1]; 381 extern lck_mtx_t rnh_lock_data; 382 #define rnh_lock (&rnh_lock_data) 383 extern uint32_t route_genid_inet; /* INET route generation count */ 384 extern uint32_t route_genid_inet6; /* INET6 route generation count */ 385 extern int rttrash; 386 extern unsigned int rte_debug; 387 388 struct ifmultiaddr; 389 struct proc; 390 391 extern void route_init(void); 392 extern void routegenid_update(void); 393 extern void routegenid_inet_update(void); 394 extern void routegenid_inet6_update(void); 395 extern void rt_ifmsg(struct ifnet *); 396 extern void rt_missmsg(u_char, struct rt_addrinfo *, int, int); 397 extern void rt_newaddrmsg(u_char, struct ifaddr *, int, struct rtentry *); 398 extern void rt_newmaddrmsg(u_char, struct ifmultiaddr *); 399 extern int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *); 400 extern void set_primary_ifscope(int, unsigned int); 401 extern unsigned int get_primary_ifscope(int); 402 extern boolean_t rt_primary_default(struct rtentry *, struct sockaddr *); 403 extern struct rtentry *rt_lookup(boolean_t, struct sockaddr *, 404 struct sockaddr *, struct radix_node_head *, unsigned int); 405 extern struct rtentry *rt_lookup_coarse(boolean_t, struct sockaddr *, 406 struct sockaddr *, struct radix_node_head *); 407 extern void rtalloc(struct route *); 408 extern void rtalloc_scoped(struct route *, unsigned int); 409 extern void rtalloc_ign(struct route *, uint32_t); 410 extern void rtalloc_scoped_ign(struct route *, uint32_t, unsigned int); 411 extern struct rtentry *rtalloc1(struct sockaddr *, int, uint32_t); 412 extern struct rtentry *rtalloc1_scoped(struct sockaddr *, int, uint32_t, 413 unsigned int); 414 extern struct rtentry *rtalloc1_scoped_locked(struct sockaddr *, int, 415 uint32_t, unsigned int); 416 extern void rtfree_locked(struct rtentry *); 417 extern void rtfree(struct rtentry *); 418 extern void rtref(struct rtentry *); 419 /* 420 * rtunref will decrement the refcount, rtfree will decrement and free if 421 * the refcount has reached zero and the route is not up. 422 * Unless you have good reason to do otherwise, use rtfree. 423 */ 424 extern int rtunref(struct rtentry *); 425 extern void rtsetifa(struct rtentry *, struct ifaddr *); 426 extern int rtinit(struct ifaddr *, uint8_t, int); 427 extern int rtinit_locked(struct ifaddr *, uint8_t, int); 428 extern int rtioctl(unsigned long, caddr_t, struct proc *); 429 extern void rtredirect(struct ifnet *, struct sockaddr *, struct sockaddr *, 430 struct sockaddr *, int, struct sockaddr *, struct rtentry **); 431 extern int rtrequest(int, struct sockaddr *, 432 struct sockaddr *, struct sockaddr *, int, struct rtentry **); 433 extern int rtrequest_scoped(int, struct sockaddr *, struct sockaddr *, 434 struct sockaddr *, int, struct rtentry **, unsigned int); 435 extern int rtrequest_locked(int, struct sockaddr *, 436 struct sockaddr *, struct sockaddr *, int, struct rtentry **); 437 extern int rtrequest_scoped_locked(int, struct sockaddr *, struct sockaddr *, 438 struct sockaddr *, int, struct rtentry **, unsigned int); 439 extern void sin_set_ifscope(struct sockaddr *, unsigned int); 440 extern unsigned int sin_get_ifscope(struct sockaddr *); 441 extern unsigned int sin6_get_ifscope(struct sockaddr *); 442 extern void rt_lock(struct rtentry *, boolean_t); 443 extern void rt_unlock(struct rtentry *); 444 extern struct sockaddr *rtm_scrub(int, int, struct sockaddr *, 445 struct sockaddr *, void *, uint32_t, kauth_cred_t *); 446 extern boolean_t rt_validate(struct rtentry *); 447 extern void rt_set_proxy(struct rtentry *, boolean_t); 448 extern void rt_set_gwroute(struct rtentry *, struct sockaddr *, 449 struct rtentry *); 450 extern void rt_revalidate_gwroute(struct rtentry *, struct rtentry *); 451 extern errno_t route_to_gwroute(const struct sockaddr *, struct rtentry *, 452 struct rtentry **); 453 extern void rt_setexpire(struct rtentry *, uint64_t); 454 extern void rt_str(struct rtentry *, char *, uint32_t, char *, uint32_t); 455 extern const char *rtm2str(int); 456 extern void route_clear(struct route *); 457 extern void route_copyin(struct route *, struct route *, size_t); 458 extern void route_copyout(struct route *, const struct route *, size_t); 459 extern boolean_t rt_ifa_is_dst(struct sockaddr *, struct ifaddr *); 460 extern struct sockaddr *sa_copy(struct sockaddr *, struct sockaddr_storage *, 461 unsigned int *); 462 463 /* 464 * The following is used to enqueue work items for route events 465 * and also used to pass route event while walking the tree 466 */ 467 struct route_event { 468 struct rtentry *rt; 469 /* 470 * There's no reference taken on gwrt. 471 * We only use it to check whether we should 472 * point to rt_gateway or the embedded rt_addr 473 * structure. 474 */ 475 struct rtentry *gwrt; 476 union { 477 union sockaddr_in_4_6 _rtev_ipaddr; 478 char _rtev_addr_bytes[DLIL_SDLMAXLEN]; 479 } rt_addr; 480 uint32_t route_event_code; 481 eventhandler_tag evtag; 482 }; 483 484 #define rtev_ipaddr rt_addr._rtev_ipaddr 485 #define rtev_addr_bytes rt_addr._rtev_addr_bytes 486 487 extern void route_event_init(struct route_event *p_route_ev, struct rtentry *rt, 488 struct rtentry *gwrt, int route_ev_code); 489 extern int route_event_walktree(struct radix_node *rn, void *arg); 490 extern void route_event_enqueue_nwk_wq_entry(struct rtentry *, struct rtentry *, 491 uint32_t, eventhandler_tag, boolean_t); 492 #endif /* BSD_KERNEL_PRIVATE */ 493 #endif /* _NET_ROUTE_PRIVATE_H_ */ 494