1 /* route.h 2 * 3 * Copyright (c) 2019-2020 Apple Computer, 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 * http://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 18 #ifndef __SERVICE_REGISTRATION_ROUTE_H 19 #define __SERVICE_REGISTRATION_ROUTE_H 20 #if defined(USE_IPCONFIGURATION_SERVICE) 21 #include <SystemConfiguration/SystemConfiguration.h> 22 #include "IPConfigurationService.h" 23 #endif 24 25 #define MIN_DELAY_BETWEEN_RAS 4000 26 #define MSEC_PER_SEC (NSEC_PER_SEC / NSEC_PER_MSEC) 27 #define MAX_ROUTER_RECEIVED_TIME_GAP_BEFORE_STALE 600 * MSEC_PER_SEC 28 29 // Fix this 30 #ifndef IPV6_ROUTER_MODE_EXCLUSIVE 31 #define IPV6_ROUTER_MODE_DISABLED 0 32 #define IPV6_ROUTER_MODE_EXCLUSIVE 1 33 #define IPV6_ROUTER_MODE_HYBRID 2 34 #endif 35 36 37 typedef struct interface interface_t; 38 typedef struct icmp_message icmp_message_t; 39 typedef struct network_link network_link_t; 40 struct interface { 41 int ref_count; 42 43 interface_t *NULLABLE next; 44 char *NONNULL name; 45 46 // Wakeup event for next beacon. 47 wakeup_t *NULLABLE beacon_wakeup; 48 49 // Wakeup event called after we're done sending solicits. At this point we delete all routes more than 10 minutes 50 // old; if none are left, then we assume there's no IPv6 service on the interface. 51 wakeup_t *NULLABLE post_solicit_wakeup; 52 53 // Wakeup event to trigger the next router solicit to be sent. 54 wakeup_t *NULLABLE router_solicit_wakeup; 55 56 // Wakeup event to deconfigure the on-link prefix after it is no longer valid. 57 wakeup_t *NULLABLE deconfigure_wakeup; 58 59 // Wakeup event to detect that vicarious router discovery is complete 60 wakeup_t *NULLABLE vicarious_discovery_complete; 61 62 // Wakeup event to periodically notice whether routers we have heard previously on this interface have gone stale. 63 wakeup_t *NULLABLE stale_evaluation_wakeup; 64 65 // List of ICMP messages from different routers. 66 icmp_message_t *NULLABLE routers; 67 68 // The link to which this interface is connected. 69 network_link_t *NULLABLE link; 70 71 #if defined(USE_IPCONFIGURATION_SERVICE) 72 // The service used to configure this interface with an address in the on-link prefix 73 IPConfigurationServiceRef NULLABLE ip_configuration_service; 74 75 // SCDynamicStoreRef 76 SCDynamicStoreRef NULLABLE ip_configuration_store; 77 #endif 78 79 struct in6_addr link_local; // Link-local address 80 struct in6_addr ipv6_prefix; // This is the prefix we advertise, if advertise_ipv6_prefix is true. 81 82 // Absolute time of last beacon, and of next beacon. 83 uint64_t last_beacon, next_beacon; 84 85 // Absolute deadline for deprecating the on-link prefix we've been announcing 86 uint64_t deprecate_deadline; 87 88 // Preferred lifetime for the on-link prefix 89 uint32_t preferred_lifetime; 90 91 // Valid lifetime for the on-link prefix 92 uint32_t valid_lifetime; 93 94 // When the interface becomes active, we send up to three solicits. 95 int num_solicits_sent; 96 97 // The interface index according to the operating systme. 98 int index; 99 100 // Number of IPv4 addresses configured on link. 101 int num_ipv4_addresses; 102 103 // Number of beacons sent. After the first three, the inter-beacon interval goes up. 104 int num_beacons_sent; 105 106 // The interface link layer address, if known. 107 uint8_t link_layer[6]; 108 109 // True if the interface is not usable. 110 bool inactive; 111 112 // True if this interface can never be used for routing to the thread network (e.g., loopback, tunnels, etc.) 113 bool ineligible; 114 115 // True if we've determined that it's the thread interface. 116 bool is_thread; 117 118 // True if we should advertise an on-link prefix. 119 bool advertise_ipv6_prefix; 120 121 // True if we've gotten a link-layer address. 122 bool have_link_layer_address; 123 124 // True if the on-link prefix is configured on the interface. 125 bool on_link_prefix_configured; 126 127 // True if we've sent our first beacon since the interface came up. 128 bool sent_first_beacon; 129 130 // Indicates whether or not router discovery has completed for this interface. 131 bool router_discovery_complete; 132 133 // Indicates whether we're currently doing router discovery, so that we don't 134 // restart it when we're already doing it. 135 bool router_discovery_in_progress; 136 137 // Indicates that we've received a router discovery message from some other host, 138 // and are waiting 20 seconds to snoop for replies to that RD message that are 139 // multicast. If we hear no replies during that time, we trigger router discovery. 140 bool vicarious_router_discovery_in_progress; 141 142 // Indicates that we have received an interface removal event, it is useful when srp-mdns-proxy is changed to a new 143 // network where the network signature are the same and they both have no IPv6 service (so no IPv6 prefix will be 144 // removed), in such case there will be no change from srp-mdns-proxy's point of view. However, configd may still 145 // flush the IPv6 routing since changing network would cause interface up/down. When the flushing happens, 146 // srp-mdns-proxy should be able to reconfigure the IPv6 routing by reconfiguring IPv6 prefix. By setting 147 // need_reconfigure_prefix only when interface address removal happens and check it during the routing evaluation 148 // srp-mdns-proxy can reconfigure it after the routing evaluation finishes, like router discovery. 149 bool need_reconfigure_prefix; 150 }; 151 152 typedef enum icmp_option_type { 153 icmp_option_source_link_layer_address = 1, 154 icmp_option_target_link_layer_address = 2, 155 icmp_option_prefix_information = 3, 156 icmp_option_redirected_header = 4, 157 icmp_option_mtu = 5, 158 icmp_option_route_information = 24, 159 } icmp_option_type_t; 160 161 typedef enum icmp_type { 162 icmp_type_echo_request = 128, 163 icmp_type_echo_reply = 129, 164 icmp_type_router_solicitation = 133, 165 icmp_type_router_advertisement = 134, 166 icmp_type_neighbor_solicitation = 135, 167 icmp_type_neighbor_advertisement = 136, 168 icmp_type_redirect = 137, 169 } icmp_type_t; 170 171 typedef struct link_layer_address { 172 uint16_t length; 173 uint8_t address[32]; 174 } link_layer_address_t; 175 176 typedef struct prefix_information { 177 struct in6_addr prefix; 178 uint8_t length; 179 uint8_t flags; 180 uint32_t valid_lifetime; 181 uint32_t preferred_lifetime; 182 } prefix_information_t; 183 184 typedef struct route_information { 185 struct in6_addr prefix; 186 uint8_t length; 187 uint8_t flags; 188 uint32_t route_lifetime; 189 } route_information_t; 190 191 typedef struct icmp_option { 192 icmp_option_type_t type; 193 union { 194 link_layer_address_t link_layer_address; 195 prefix_information_t prefix_information; 196 route_information_t route_information; 197 } option; 198 } icmp_option_t; 199 200 struct icmp_message { 201 icmp_message_t *NULLABLE next; 202 interface_t *NULLABLE interface; 203 icmp_option_t *NULLABLE options; 204 bool new_router; // If this router information is a newly recevied one. 205 bool received_time_already_adjusted; // if the received time of the message is already adjusted by vicarious mode 206 struct in6_addr source; 207 struct in6_addr destination; 208 209 uint64_t received_time; 210 211 uint32_t reachable_time; 212 uint32_t retransmission_timer; 213 uint8_t cur_hop_limit; // Current hop limit for Router Advertisement messages. 214 uint8_t flags; 215 uint8_t type; 216 uint8_t code; 217 uint16_t checksum; // We hope the kernel figures this out for us. 218 uint16_t router_lifetime; 219 220 int num_options; 221 int hop_limit; // Hop limit provided by the kernel, must be 255. 222 }; 223 224 void ula_generate(void); 225 bool start_route_listener(void); 226 bool start_icmp_listener(void); 227 void icmp_leave_join(int sock, int ifindex, bool join); 228 229 #define interface_create(name, iface) interface_create_(name, iface, __FILE__, __LINE__) 230 interface_t *NULLABLE interface_create_(const char *NONNULL name, int ifindex, 231 const char *NONNULL file, int line); 232 #define interface_retain(interface) interface_retain_(interface, __FILE__, __LINE__) 233 void interface_retain_(interface_t *NONNULL interface, const char *NONNULL file, int line); 234 #define interface_release(interface) interface_release_(interface, __FILE__, __LINE__) 235 void interface_release_(interface_t *NONNULL interface, const char *NONNULL file, int line); 236 bool interface_monitor_start(void); 237 void thread_network_startup(void); 238 void thread_network_shutdown(void); 239 void partition_stop_advertising_pref_id(void); 240 void partition_start_srp_listener(void); 241 #endif // __SERVICE_REGISTRATION_ROUTE_H 242 243 // Local Variables: 244 // mode: C 245 // tab-width: 4 246 // c-file-style: "bsd" 247 // c-basic-offset: 4 248 // fill-column: 120 249 // indent-tabs-mode: nil 250 // End: 251