1 /* route.h 2 * 3 * Copyright (c) 2019-2024 Apple Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * This code adds border router support to 3rd party HomeKit Routers as part of Apples commitment to the CHIP project. 18 * 19 * Definitions for route.c 20 */ 21 22 #ifndef __SERVICE_REGISTRATION_ROUTE_H 23 #define __SERVICE_REGISTRATION_ROUTE_H 24 #if defined(USE_IPCONFIGURATION_SERVICE) 25 #include <SystemConfiguration/SystemConfiguration.h> 26 #include "IPConfigurationService.h" 27 #endif 28 29 typedef struct icmp_listener icmp_listener_t; 30 typedef struct route_state route_state_t; 31 typedef struct srp_server_state srp_server_t; 32 typedef struct nat64 nat64_t; 33 typedef struct omr_watcher omr_watcher_t; 34 typedef struct omr_watcher_callback omr_watcher_callback_t; 35 typedef struct omr_publisher omr_publisher_t; 36 typedef struct route_tracker route_tracker_t; 37 38 // RFC 4861 specifies a minimum of 4 seconds between RAs. We add a bit of fuzz. 39 #define MIN_DELAY_BETWEEN_RAS 4000 40 #define RA_FUZZ_TIME 1000 41 42 // RFC 4861 specifies a maximum of three transmissions when sending an RA. 43 #define MAX_RA_RETRANSMISSION 3 44 45 // There's no limit for unicast neighbor solicits, but we limit it to three. 46 #define MAX_NS_RETRANSMISSIONS 3 47 48 // 60 seconds between router probes, three retries, four seconds per retry. We should have an answer from the router at 49 // most 76 seconds after the previous answer, assuming that it takes four seconds for the response to arrive, which is 50 // of course ridiculously long. 51 #define MAX_ROUTER_RECEIVED_TIME_GAP_BEFORE_UNREACHABLE 76 * MSEC_PER_SEC 52 53 // The end of the valid lifetime of the prefix is the time we received it plus the valid lifetime that was expressed in 54 // the PIO option of the RA that advertised the prefix. If we have a prefix that is within ten minutes of expiring, we 55 // consider it stale and start advertising a prefix. This should never happen in a network where a router is advertising 56 // a prefix--if it does, either we're having trouble receiving multicast RAs (meaning that we don't get every beacon) or 57 // the router has gone away. 58 #define MAX_ROUTER_RECEIVED_TIME_GAP_BEFORE_STALE 600 * MSEC_PER_SEC 59 60 // The Thread BR prefix needs to stick around long enough that it's not likely to accidentally disappear because of 61 // dropped multicasts, but short enough that it goes away quickly when a router that's advertising IPv6 connectivity 62 // comes online. 63 #define BR_PREFIX_LIFETIME 30 * 60 64 65 #define BR_PREFIX_SLASH_64_BYTES 8 66 67 68 #ifndef RTR_SOLICITATION_INTERVAL 69 #define RTR_SOLICITATION_INTERVAL 4 /* 4sec */ 70 #endif 71 72 #ifndef ND6_INFINITE_LIFETIME 73 #define ND6_INFINITE_LIFETIME 0xffffffff 74 #endif 75 76 #define MAX_ANYCAST_NUM 5 77 78 typedef struct interface interface_t; 79 typedef struct icmp_message icmp_message_t; 80 struct interface { 81 int ref_count; 82 83 interface_t *NULLABLE next; 84 char *NONNULL name; 85 86 // Wakeup event for next beacon. 87 wakeup_t *NULLABLE beacon_wakeup; 88 89 // Wakeup event called after we're done sending solicits. At this point we delete all routes more than 10 minutes 90 // old; if none are left, then we assume there's no IPv6 service on the interface. 91 wakeup_t *NULLABLE post_solicit_wakeup; 92 93 // Wakeup event to trigger the next router solicit or neighbor solicit to be sent. 94 wakeup_t *NULLABLE router_solicit_wakeup; 95 96 // Wakeup event to trigger the next router solicit to be sent. 97 wakeup_t *NULLABLE neighbor_solicit_wakeup; 98 99 // Wakeup event to deconfigure the on-link prefix after it is no longer valid. 100 wakeup_t *NULLABLE deconfigure_wakeup; 101 102 #if SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 103 // Wakeup event to detect that vicarious router discovery is complete 104 wakeup_t *NULLABLE vicarious_discovery_complete; 105 #endif // SRP_FEATURE_VICARIOUS_ROUTER_DISCOVERY 106 107 // Wakeup event to periodically notice whether routers we have heard previously on this interface have gone stale. 108 wakeup_t *NULLABLE stale_evaluation_wakeup; 109 110 // Wakeup event to periodically probe routers for reachability 111 wakeup_t *NULLABLE router_probe_wakeup; 112 113 // The route state object to which this interface belongs. 114 route_state_t *NULLABLE route_state; 115 116 // List of Router Advertisement messages from different routers. 117 icmp_message_t *NULLABLE routers; 118 119 // List of Router Solicit messages from different hosts for which we are still transmitting unicast 120 // RAs (we sent three unicast RAs per solicit to ensure delivery). 121 icmp_message_t *NULLABLE solicits; 122 123 int prefix_number; 124 125 #if defined(USE_IPCONFIGURATION_SERVICE) 126 // The service used to configure this interface with an address in the on-link prefix 127 IPConfigurationServiceRef NULLABLE ip_configuration_service; 128 129 // SCDynamicStoreRef 130 SCDynamicStoreRef NULLABLE ip_configuration_store; 131 #else 132 subproc_t *NULLABLE link_route_adder_process; 133 #endif 134 135 struct in6_addr link_local; // Link-local address 136 struct in6_addr ipv6_prefix; // This is the prefix we advertise, if advertise_ipv6_prefix is true. 137 138 // Absolute time of last beacon, and of next beacon. 139 uint64_t last_beacon, next_beacon; 140 141 // Absolute deadline for deprecating the on-link prefix we've been announcing 142 uint64_t deprecate_deadline; 143 144 // Last time we did a router probe 145 uint64_t last_router_probe; 146 147 // Preferred lifetime for the on-link prefix 148 uint32_t preferred_lifetime; 149 150 // Valid lifetime for the on-link prefix 151 uint32_t valid_lifetime; 152 153 // When the interface becomes active, we send up to three solicits. 154 // Later on, we send three neighbor solicit probes every sixty seconds to verify router reachability 155 int num_solicits_sent; 156 157 // The interface index according to the operating systme. 158 int index; 159 160 // Number of IPv4 addresses configured on link. 161 int num_ipv4_addresses; 162 163 // Number of IPv4 addresses configured on link. 164 int num_ipv6_addresses, old_num_ipv6_addresses; 165 166 // Number of beacons sent. After the first three, the inter-beacon interval goes up. 167 int num_beacons_sent; 168 169 // The interface link layer address, if known. 170 uint8_t link_layer[6]; 171 172 // True if the interface is not usable. 173 bool inactive, previously_inactive; 174 175 // True if this interface can never be used for routing to the thread network (e.g., loopback, tunnels, etc.) 176 bool ineligible, previously_ineligible; 177 178 // True if we've determined that it's the thread interface. 179 bool is_thread; 180 181 182 // True if we have (or intended to) advertised our own prefix on this link. It should be true until the prefix 183 // we advertised should have expired on all hosts that might have received it. This will be set before we actually 184 // advertise a prefix, so before the first time we advertise a prefix it may be set even though the prefix can't 185 // appear in any host's routing table yet. 186 bool our_prefix_advertised; 187 188 // True if we should suppress on-link prefix. This would be the case when deprecating if we aren't sending 189 // periodic updates of the deprecated prefix. 190 bool suppress_ipv6_prefix; 191 192 // True if we've gotten a link-layer address. 193 bool have_link_layer_address; 194 195 // True if the on-link prefix is configured on the interface. 196 bool on_link_prefix_configured; 197 198 // True if we've sent our first beacon since the interface came up. 199 bool sent_first_beacon; 200 201 // Indicates whether or not router discovery was ever started for this interface. 202 bool router_discovery_started; 203 204 // Indicates whether or not router discovery has completed for this interface. 205 bool router_discovery_complete; 206 207 // Indicates whether we're currently doing router discovery, so that we don't 208 // restart it when we're already doing it. 209 bool router_discovery_in_progress; 210 211 // Indicates that we've received a router discovery message from some other host, 212 // and are waiting 20 seconds to snoop for replies to that RD message that are 213 // multicast. If we hear no replies during that time, we trigger router discovery. 214 bool vicarious_router_discovery_in_progress; 215 216 // True if we are probing usable routers with neighbor solicits to see if they are still alive. 217 bool probing; 218 219 // Indicates that we have received an interface removal event, it is useful when srp-mdns-proxy is changed to a new 220 // network where the network signature are the same and they both have no IPv6 service (so no IPv6 prefix will be 221 // removed), in such case there will be no change from srp-mdns-proxy's point of view. However, configd may still 222 // flush the IPv6 routing since changing network would cause interface up/down. When the flushing happens, 223 // srp-mdns-proxy should be able to reconfigure the IPv6 routing by reconfiguring IPv6 prefix. By setting 224 // need_reconfigure_prefix only when interface address removal happens and check it during the routing evaluation 225 // srp-mdns-proxy can reconfigure it after the routing evaluation finishes, like router discovery. 226 bool need_reconfigure_prefix; 227 228 // This variable is used to notice when the path evaluator doesn't return an interface on the interface list. 229 // In this situation, the interface is inactive and if we are using it we should stop. 230 bool listed; 231 }; 232 233 typedef enum icmp_option_type { 234 icmp_option_source_link_layer_address = 1, 235 icmp_option_target_link_layer_address = 2, 236 icmp_option_prefix_information = 3, 237 icmp_option_redirected_header = 4, 238 icmp_option_mtu = 5, 239 icmp_option_route_information = 24, 240 icmp_option_ra_flags_extension = 26, 241 } icmp_option_type_t; 242 243 typedef enum icmp_type { 244 icmp_type_echo_request = 128, 245 icmp_type_echo_reply = 129, 246 icmp_type_router_solicitation = 133, 247 icmp_type_router_advertisement = 134, 248 icmp_type_neighbor_solicitation = 135, 249 icmp_type_neighbor_advertisement = 136, 250 icmp_type_redirect = 137, 251 } icmp_type_t; 252 253 #ifndef ND_OPT_RA_FLAGS_EXTENSION 254 #define ND_OPT_RA_FLAGS_EXTENSION icmp_option_ra_flags_extension 255 #endif 256 #define RA_FLAGS1_STUB_ROUTER 0x80 257 258 typedef struct link_layer_address { 259 uint16_t length; 260 uint8_t address[32]; 261 } link_layer_address_t; 262 263 typedef uint8_t ra_flags_extension_t[6]; 264 265 typedef struct prefix_information { 266 struct in6_addr prefix; 267 uint8_t length; 268 uint8_t flags; 269 uint32_t valid_lifetime; 270 uint32_t preferred_lifetime; 271 bool found; // For comparing RAs 272 } prefix_information_t; 273 274 typedef struct route_information { 275 struct in6_addr prefix; 276 uint8_t length; 277 uint8_t flags; 278 uint32_t route_lifetime; 279 } route_information_t; 280 281 typedef struct icmp_option { 282 icmp_option_type_t type; 283 union { 284 link_layer_address_t link_layer_address; 285 prefix_information_t prefix_information; 286 route_information_t route_information; 287 ra_flags_extension_t ra_flags_extension; 288 } option; 289 } icmp_option_t; 290 291 struct icmp_message { 292 icmp_message_t *NULLABLE next; 293 interface_t *NULLABLE interface; 294 icmp_option_t *NULLABLE options; 295 wakeup_t *NULLABLE wakeup; 296 route_state_t *NULLABLE route_state; 297 298 bool usable; // True if this router was usable at the last policy evaluation 299 bool reachable; // True if this router was reachable when last probed 300 bool reached; // Set to true when we get a neighbor advertise from the router 301 bool new_router; // If this router information is a newly received one. 302 bool received_time_already_adjusted; // if the received time of the message is already adjusted by vicarious mode 303 bool stub_router; // True if this RA came from a stub router. 304 int retransmissions_received; // # times we've received a solicit from this host during retransmit window 305 int messages_sent; // # of unicast RAs we've sent in response to a solicit, or # of unicast NSs 306 // we've sent to confirm router aliveness 307 308 struct in6_addr source; 309 struct in6_addr destination; 310 311 uint64_t received_time; 312 uint64_t latest_na; // Most recent time at which we successfully got a neighbor advertise 313 314 uint32_t reachable_time; 315 uint32_t retransmission_timer; 316 uint8_t cur_hop_limit; // Current hop limit for Router Advertisement messages. 317 uint8_t flags; 318 uint8_t type; 319 uint8_t code; 320 uint16_t checksum; // We hope the kernel figures this out for us. 321 uint16_t router_lifetime; 322 323 int num_options; 324 int hop_limit; // Hop limit provided by the kernel, must be 255. 325 }; 326 327 struct route_state { 328 route_state_t *NULLABLE next; 329 const char *NULLABLE name; 330 srp_server_t *NULLABLE srp_server; 331 interface_address_state_t *NULLABLE interface_addresses; 332 omr_watcher_t *NULLABLE omr_watcher; 333 omr_publisher_t *NULLABLE omr_publisher; 334 route_tracker_t *NULLABLE route_tracker; 335 omr_watcher_callback_t *NULLABLE omr_watcher_callback; 336 337 // If true, a prefix with L=1, A=0 in an RA with M=1 is treated as usable. The reason it's not treated as 338 // usable by default is that this will break Thread for Android phones on networks where IPv6 is present 339 // but only DHCPv6 is supported. 340 bool config_enable_dhcpv6_prefixes; 341 342 interface_t *NULLABLE interfaces; 343 bool have_thread_prefix; 344 struct in6_addr my_thread_ula_prefix; 345 bool have_mesh_local_prefix; 346 bool have_mesh_local_address; 347 bool advertising_srp_anycast_service; 348 bool advertising_srp_unicast_service; 349 bool have_proposed_srp_listener_address; 350 bool seen_listener_address; 351 struct in6_addr thread_mesh_local_prefix; 352 struct in6_addr thread_mesh_local_address; 353 struct in6_addr proposed_srp_listener_address; 354 struct in6_addr srp_listener_ip_address; 355 uint16_t srp_service_listen_port; 356 comm_t *NULLABLE srp_listener; 357 struct in6_addr xpanid_prefix; 358 bool have_xpanid_prefix; 359 int num_thread_interfaces; // Should be zero or one. 360 int ula_serial; 361 int num_thread_prefixes; 362 int times_advertised_unicast, times_advertised_anycast; 363 int times_unadvertised_unicast, times_unadvertised_anycast; 364 subproc_t *NULLABLE thread_interface_enumerator_process; 365 subproc_t *NULLABLE thread_prefix_adder_process; 366 subproc_t *NULLABLE thread_rti_setter_process; 367 subproc_t *NULLABLE thread_forwarding_setter_process; 368 subproc_t *NULLABLE tcpdump_logger_process; 369 char *NULLABLE thread_interface_name; 370 char *NULLABLE home_interface_name; 371 bool have_non_thread_interface; 372 bool seen_legacy_service; 373 #if SRP_FEATURE_NAT64 374 nat64_t *NULLABLE nat64; 375 #endif 376 bool have_rloc16; 377 uint8_t thread_sequence_number; 378 379 #ifndef RA_TESTER 380 wakeup_t *NULLABLE thread_network_shutdown_wakeup; 381 cti_network_state_t current_thread_state; 382 cti_connection_t NULLABLE thread_role_context; 383 cti_connection_t NULLABLE thread_state_context; 384 cti_connection_t NULLABLE thread_xpanid_context; 385 cti_connection_t NULLABLE thread_route_context; 386 cti_connection_t NULLABLE thread_rloc16_context; 387 cti_connection_t NULLABLE thread_ml_prefix_connection; 388 bool thread_network_running; 389 bool thread_network_shutting_down; 390 #endif 391 392 #if !defined(RA_TESTER) 393 wakeup_t *NULLABLE wpan_reconnect_wakeup; 394 #endif // !defined(RA_TESTER) 395 #if !defined(RA_TESTER) 396 uint64_t partition_last_prefix_set_change; 397 uint64_t partition_last_pref_id_set_change; 398 uint64_t partition_last_role_change; 399 uint64_t partition_last_state_change; 400 uint64_t partition_settle_start; 401 uint64_t partition_service_last_add_time; 402 bool partition_have_prefix_list; 403 bool partition_have_pref_id_list; 404 bool partition_tunnel_name_is_known; 405 bool partition_can_advertise_service; 406 bool partition_can_advertise_anycast_service; 407 bool partition_can_provide_routing; 408 bool partition_has_xpanid; 409 bool partition_may_offer_service; 410 bool partition_settle_satisfied; 411 wakeup_t *NULLABLE partition_settle_wakeup; 412 wakeup_t *NULLABLE partition_post_partition_wakeup; 413 wakeup_t *NULLABLE partition_pref_id_wait_wakeup; 414 wakeup_t *NULLABLE partition_service_add_pending_wakeup; 415 wakeup_t *NULLABLE partition_anycast_service_add_pending_wakeup; 416 wakeup_t *NULLABLE service_set_changed_wakeup; 417 #endif // RA_TESTER 418 }; 419 420 extern route_state_t *NONNULL route_states; // same 421 422 route_state_t *NULLABLE route_state_create(srp_server_t *NONNULL server_state, const char *NONNULL name); 423 void route_ula_setup(route_state_t *NULLABLE route_state); 424 void route_ula_generate(route_state_t *NULLABLE route_state); 425 bool start_route_listener(route_state_t *NULLABLE route_state); 426 bool start_icmp_listener(void); 427 void icmp_leave_join(int sock, int ifindex, bool join); 428 void infrastructure_network_startup(route_state_t *NULLABLE route_state); 429 void infrastructure_network_shutdown(route_state_t *NULLABLE route_state); 430 void partition_maybe_advertise_anycast_service(route_state_t *NULLABLE route_state); 431 void partition_stop_advertising_anycast_service(route_state_t *NULLABLE route_state, uint8_t sequence_number); 432 void partition_stop_advertising_pref_id(route_state_t *NULLABLE route_state); 433 void partition_start_srp_listener(route_state_t *NULLABLE route_state); 434 void partition_discontinue_srp_service(route_state_t *NULLABLE route_state); 435 void partition_discontinue_all_srp_service(route_state_t *NULLABLE route_state); 436 void partition_block_anycast_service(route_state_t *NULLABLE route_state, bool block); 437 void adv_ctl_add_prefix(route_state_t *NONNULL route_state, const uint8_t *NONNULL data); 438 void adv_ctl_remove_prefix(route_state_t *NONNULL route_state, const uint8_t *NONNULL data); 439 #define interface_retain(interface) interface_retain_(interface, __FILE__, __LINE__) 440 void interface_retain_(interface_t *NONNULL interface, const char *NONNULL file, int line); 441 #define interface_release(interface) interface_release_(interface, __FILE__, __LINE__) 442 void interface_release_(interface_t *NONNULL interface, const char *NONNULL file, int line); 443 void route_refresh_interface_list(route_state_t *NONNULL route_state); 444 445 void router_solicit(icmp_message_t *NONNULL message); 446 void router_advertisement(icmp_message_t *NONNULL message); 447 void neighbor_advertisement(icmp_message_t *NONNULL message); 448 449 int route_get_current_infra_interface_index(void); 450 #endif // __SERVICE_REGISTRATION_ROUTE_H 451 452 // Local Variables: 453 // mode: C 454 // tab-width: 4 455 // c-file-style: "bsd" 456 // c-basic-offset: 4 457 // fill-column: 120 458 // indent-tabs-mode: nil 459 // End: 460