Home | History | Annotate | Line # | Download | only in ServiceRegistration
      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