Lines Matching defs:route_state
126 #define interface_create(route_state, name, iface) interface_create_(route_state, name, iface, __FILE__, __LINE__)
127 interface_t *NULLABLE interface_create_(route_state_t *NONNULL route_state, const char *NONNULL name, int ifindex,
136 static void routing_policy_evaluate_all_interfaces(route_state_t *route_state, bool assume_changed);
143 static void thread_network_startup(route_state_t *route_state);
144 static void thread_network_shutdown(route_state_t *route_state);
145 static void thread_network_shutdown_start(route_state_t *route_state);
146 static void partition_state_reset(route_state_t *route_state);
147 static void partition_utun0_address_changed(route_state_t *route_state, const struct in6_addr *NONNULL addr, enum interface_address_change change);
148 static void partition_utun0_pick_listener_address(route_state_t *route_state);
149 static void partition_got_tunnel_name(route_state_t *route_state);
151 static void partition_stop_advertising_service(route_state_t *route_state);
153 static void partition_maybe_advertise_service(route_state_t *route_state);
155 static void partition_maybe_enable_services(route_state_t *route_state);
156 static void partition_disable_service(route_state_t *route_state);
157 void partition_discontinue_srp_service(route_state_t *route_state);
158 static void partition_schedule_service_add_wakeup(route_state_t *route_state);
159 static void partition_schedule_anycast_service_add_wakeup(route_state_t *route_state);
220 interface_create_(route_state_t *route_state, const char *name, int ifindex, const char *file, int line)
245 ret->route_state = route_state;
286 want_routing(route_state_t *route_state)
289 (void)route_state;
292 return (route_state->partition_can_provide_routing &&
293 route_state->partition_has_xpanid);
302 route_state_t *route_state = interface->route_state;
310 route_state->partition_can_provide_routing ? " canpr" : " !canpr",
311 route_state->partition_has_xpanid ? " havexp" : " !havexp",
338 if (want_routing(route_state) || interface->our_prefix_advertised) {
358 route_state->partition_can_provide_routing ? "canpr" : "!canpr",
359 route_state->partition_has_xpanid ? " route_state->xpanid" : " !route_state->xpanid",
576 routing_policy_evaluate_all_interfaces(route_state_t *route_state, bool assume_changed)
580 for (interface = route_state->interfaces; interface; interface = interface->next) {
603 prefix_usable(interface_t *interface, route_state_t *route_state, icmp_message_t *router, prefix_information_t *prefix)
611 (route_state->config_enable_dhcpv6_prefixes && (router->flags & ND_RA_FLAG_MANAGED))) &&
620 bool_str(route_state->config_enable_dhcpv6_prefixes && (router->flags & ND_RA_FLAG_MANAGED)),
624 int cmp = in6prefix_compare(&prefix->prefix, &route_state->xpanid_prefix, 8);
663 route_state_t *route_state = interface->route_state;
673 if (route_state->have_xpanid_prefix) {
685 omr_publisher_check_prefix(route_state->omr_publisher, &prefix->prefix, prefix->length);
687 if (prefix_usable(interface, route_state, router, prefix)) {
691 if (in6prefix_compare(&option->option.prefix_information.prefix, &route_state->xpanid_prefix, 8))
850 else if (!on_link_prefix_present && interface->router_discovery_complete && route_state->have_xpanid_prefix &&
966 if (route_state->route_tracker != NULL) {
967 route_tracker_route_state_changed(route_state->route_tracker, interface);
1122 for (iface = message->route_state->interfaces; iface; iface = iface->next) {
1204 for (iface = message->route_state->interfaces; iface != NULL; iface = iface->next) {
1311 route_state_t *route_state = interface->route_state;
1323 memcpy(&interface_address.s6_addr[10], &route_state->srp_server->ula_prefix.s6_addr[0], 6);
1428 route_state_t *route_state = context;
1435 ioloop_subproc_release(route_state->thread_rti_setter_process);
1436 route_state->thread_rti_setter_process = NULL;
1440 set_thread_rti(route_state_t *route_state)
1443 route_state->thread_rti_setter_process = ioloop_subproc("/usr/sbin/sysctl", args, 2, thread_rti_done,
1444 NULL, route_state);
1445 if (route_state->thread_rti_setter_process == NULL) {
1456 route_state_t *route_state = context;
1464 for (interface = route_state->interfaces; interface; interface = interface->next) {
1470 ioloop_subproc_release(route_state->thread_prefix_adder_process);
1471 route_state->thread_prefix_adder_process = NULL;
1509 route_ula_generate(route_state_t *route_state)
1516 if (route_state->srp_server->ula_prefix.s6_addr[0] == 0xfd) {
1517 old_ula_prefix = route_state->srp_server->ula_prefix;
1543 route_state->my_thread_ula_prefix = ula_prefix;
1544 route_state->srp_server->ula_prefix = ula_prefix;
1545 route_state->have_thread_prefix = true;
1547 if (route_state->srp_server->srp_nat64_enabled) {
1554 route_ula_setup(route_state_t *route_state)
1562 if (inet_pton(AF_INET6, ula_buf, &route_state->srp_server->ula_prefix)) {
1573 route_ula_generate(route_state);
1576 route_state->my_thread_ula_prefix = route_state->srp_server->ula_prefix;
1577 route_state->have_thread_prefix = true;
1579 if (route_state->srp_server->srp_nat64_enabled) {
1580 nat64_set_ula_prefix(&route_state->srp_server->ula_prefix);
1625 find_interface(route_state_t *route_state, const char *name, int ifindex)
1629 for (p_interface = &route_state->interfaces; *p_interface; p_interface = &(*p_interface)->next) {
1643 interface = interface_create(route_state, name, ifindex);
1645 if (route_state->thread_interface_name != NULL && !strcmp(name, route_state->thread_interface_name)) {
1707 route_state_t *route_state = interface->route_state;
1709 interface->ipv6_prefix = route_state->xpanid_prefix;
1770 route_state_t *route_state = context;
1773 interface = find_interface(route_state, name, -1);
1775 interface = find_interface(route_state, name, if_nametoindex(name));
1871 if (route_state->route_tracker != NULL) {
1872 route_tracker_route_state_changed(route_state->route_tracker, interface);
1949 partition_utun0_address_changed(route_state, &address->sin6.sin6_addr, change);
1984 route_state_t *route_state = context;
1989 attempt_wpan_reconnect(route_state);
2020 if (!inet_pton(AF_INET6, prefix_addr_string, &route_state->thread_mesh_local_prefix)) {
2024 SEGMENTED_IPv6_ADDR_GEN_SRP(route_state->thread_mesh_local_prefix.s6_addr, ml_prefix_buf);
2026 SEGMENTED_IPv6_ADDR_PARAM_SRP(route_state->thread_mesh_local_prefix.s6_addr, ml_prefix_buf),
2028 route_state->have_mesh_local_prefix = true;
2031 route_state->have_mesh_local_prefix = false;
2037 route_refresh_interface_list(route_state_t *route_state)
2043 for (interface = route_state->interfaces; interface != NULL; interface = interface->next) {
2046 ioloop_map_interface_addresses_here(route_state->srp_server, &route_state->interface_addresses, NULL, route_state, ifaddr_callback);
2048 for (interface = route_state->interfaces; interface; interface = interface->next) {
2051 partition_utun0_pick_listener_address(route_state);
2067 if (have_active && !route_state->have_non_thread_interface) {
2069 route_state->have_non_thread_interface = true;
2070 route_state->partition_can_advertise_service = true;
2071 partition_maybe_advertise_anycast_service(route_state);
2072 } else if (!have_active && route_state->have_non_thread_interface) {
2074 route_state->have_non_thread_interface = false;
2075 route_state->partition_can_advertise_service = false;
2077 partition_discontinue_all_srp_service(route_state);
2088 route_state_t *route_state = context;
2089 if (route_state->wpan_reconnect_wakeup != NULL) {
2090 ioloop_wakeup_release(route_state->wpan_reconnect_wakeup);
2091 route_state->wpan_reconnect_wakeup = NULL;
2101 route_state_t *route_state = context;
2103 if (route_state->wpan_reconnect_wakeup == NULL) {
2104 route_state->wpan_reconnect_wakeup = ioloop_wakeup_create();
2105 if (route_state->wpan_reconnect_wakeup == NULL) {
2110 ioloop_add_wake_event(route_state->wpan_reconnect_wakeup, NULL,
2112 partition_state_reset(route_state);
2120 route_state_t *route_state = context;
2123 attempt_wpan_reconnect(route_state);
2131 route_state->num_thread_interfaces = 1;
2132 if (route_state->thread_interface_name != NULL) {
2133 free(route_state->thread_interface_name);
2135 route_state->thread_interface_name = strdup(name);
2136 if (route_state->thread_interface_name == NULL) {
2140 INFO("Thread interface at " PUB_S_SRP, route_state->thread_interface_name);
2141 partition_got_tunnel_name(route_state);
2147 route_state_t *route_state = context;
2152 attempt_wpan_reconnect(route_state);
2157 route_state->partition_last_role_change = ioloop_timenow();
2174 route_state_t *route_state = context;
2183 route_state->partition_last_state_change = ioloop_timenow();
2197 if (route_state->current_thread_state != state) {
2199 route_state->current_thread_state = state;
2200 partition_maybe_enable_services(route_state); // but probably not
2202 route_state->current_thread_state = state;
2203 partition_disable_service(route_state);
2209 re_evaluate_interfaces(route_state_t *route_state)
2211 for (interface_t *interface = route_state->interfaces; interface != NULL; interface = interface->next) {
2215 partition_maybe_enable_services(route_state);
2221 route_state_t *route_state = context;
2224 attempt_wpan_reconnect(route_state);
2229 if (route_state->partition_has_xpanid) {
2231 route_state->srp_server->xpanid, new_xpanid);
2240 route_state->srp_server->xpanid = new_xpanid;
2241 route_state->partition_has_xpanid = true;
2242 in6addr_zero(&route_state->xpanid_prefix);
2243 route_state->xpanid_prefix.s6_addr[0] = 0xfd;
2245 route_state->xpanid_prefix.s6_addr[i] = ((route_state->srp_server->xpanid >> ((8 - i) * 8)) & 0xFFU);
2247 route_state->have_xpanid_prefix = true;
2250 if (route_state->srp_server->srp_replication_enabled) {
2252 srpl_startup(route_state->srp_server);
2256 re_evaluate_interfaces(route_state);
2260 adv_ctl_add_prefix(route_state_t *route_state, const uint8_t *const data)
2262 if (route_state->omr_watcher != NULL) {
2263 omr_prefix_t *thread_prefixes = omr_watcher_prefixes_get(route_state->omr_watcher);
2278 if (!omr_watcher_prefix_add(route_state->omr_watcher, (struct in6_addr *)data, BR_PREFIX_SLASH_64_BYTES, omr_prefix_priority_low)) {
2286 adv_ctl_remove_prefix(route_state_t *route_state, const uint8_t *const data)
2288 if (route_state->omr_watcher != NULL) {
2289 omr_prefix_t *thread_prefixes = omr_watcher_prefixes_get(route_state->omr_watcher);
2305 if (!omr_watcher_prefix_remove(route_state->omr_watcher, data, BR_PREFIX_SLASH_64_BYTES)) {
2315 route_state_t *route_state = context;
2320 route_state->srp_server->rloc16 = rloc16;
2321 route_state->have_rloc16 = true;
2322 INFO("server_state->rloc16 updated to %d", route_state->srp_server->rloc16);
2325 partition_maybe_advertise_anycast_service(route_state);
2331 infrastructure_network_startup(route_state_t *route_state)
2343 route_omr_watcher_event(route_state_t *route_state, void *UNUSED context, omr_watcher_event_type_t event_type,
2348 route_refresh_interface_list(route_state);
2353 if (num_prefixes != route_state->num_thread_prefixes) {
2354 int old_num_prefixes = route_state->num_thread_prefixes;
2355 INFO("%d prefixes instead of %d, evaluating policy", num_prefixes, route_state->num_thread_prefixes);
2356 routing_policy_evaluate_all_interfaces(route_state, true);
2357 route_state->num_thread_prefixes = num_prefixes;
2360 partition_maybe_advertise_anycast_service(route_state);
2364 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number);
2371 thread_network_startup(route_state_t *route_state)
2373 if (route_state->thread_network_shutting_down) {
2375 ioloop_cancel_wake_event(route_state->thread_network_shutdown_wakeup);
2376 route_state->thread_network_shutting_down = false;
2379 int status = cti_get_state(route_state->srp_server, &route_state->thread_state_context, route_state,
2382 status = cti_get_network_node_type(route_state->srp_server, &route_state->thread_role_context, route_state,
2385 srp_server_t *server_state = route_state->srp_server;
2389 partition_service_set_changed, NULL, route_state);
2393 status = cti_get_tunnel_name(route_state->srp_server, route_state, cti_get_tunnel_name_callback, NULL);
2396 status = cti_get_extended_pan_id(route_state->srp_server, &route_state->thread_xpanid_context, route_state,
2400 status = cti_get_rloc16(route_state->srp_server, &route_state->thread_rloc16_context, route_state,
2404 status = cti_get_mesh_local_prefix(route_state->srp_server, route_state,
2409 attempt_wpan_reconnect(route_state);
2416 nat64_start(route_state);
2418 route_state->omr_watcher = omr_watcher_create(route_state, attempt_wpan_reconnect);
2419 if (route_state->omr_watcher == NULL) {
2423 route_state->omr_watcher_callback = omr_watcher_callback_add(route_state->omr_watcher,
2424 route_omr_watcher_event, NULL, route_state);
2425 if (route_state->omr_watcher_callback == NULL) {
2429 route_state->omr_publisher = omr_publisher_create(route_state, "main");
2430 if (route_state->omr_publisher == NULL) {
2434 omr_publisher_set_omr_watcher(route_state->omr_publisher, route_state->omr_watcher);
2435 omr_publisher_set_reconnect_callback(route_state->omr_publisher, attempt_wpan_reconnect);
2436 omr_publisher_start(route_state->omr_publisher);
2437 omr_watcher_start(route_state->omr_watcher);
2438 route_state->thread_network_running = true;
2446 route_state_t *route_state = context;
2448 thread_network_shutdown(route_state);
2452 thread_network_shutdown_start(route_state_t *route_state)
2454 if (route_state->thread_network_shutdown_wakeup == NULL) {
2455 route_state->thread_network_shutdown_wakeup = ioloop_wakeup_create();
2457 if (route_state->thread_network_shutdown_wakeup == NULL) {
2459 thread_network_shutdown(route_state);
2462 route_state->thread_network_shutting_down = true;
2463 ioloop_add_wake_event(route_state->thread_network_shutdown_wakeup,
2464 route_state, thread_network_shutdown_wakeup_callback, NULL, 10 * 1000);
2469 thread_network_shutdown(route_state_t *route_state)
2473 if (route_state->thread_network_shutdown_wakeup != NULL) {
2474 ioloop_cancel_wake_event(route_state->thread_network_shutdown_wakeup);
2476 route_state->thread_network_shutting_down = false;
2477 if (route_state->thread_state_context != NULL) {
2479 cti_events_discontinue(route_state->thread_state_context);
2480 route_state->thread_state_context = NULL;
2482 if (route_state->thread_role_context != NULL) {
2484 cti_events_discontinue(route_state->thread_role_context);
2485 route_state->thread_role_context = NULL;
2487 if (route_state->thread_route_context != NULL) {
2489 cti_events_discontinue(route_state->thread_route_context);
2490 route_state->thread_route_context = NULL;
2492 if (route_state->thread_xpanid_context != NULL) {
2494 cti_events_discontinue(route_state->thread_xpanid_context);
2495 route_state->thread_xpanid_context = NULL;
2497 if (route_state->thread_rloc16_context != NULL) {
2499 cti_events_discontinue(route_state->thread_rloc16_context);
2500 route_state->thread_rloc16_context = NULL;
2502 if (route_state->thread_ml_prefix_connection != NULL) {
2504 cti_events_discontinue(route_state->thread_ml_prefix_connection);
2505 route_state->thread_ml_prefix_connection = NULL;
2507 srp_mdns_flush(route_state->srp_server);
2510 srpl_shutdown(route_state->srp_server);
2514 nat64_stop(route_state);
2516 partition_state_reset(route_state);
2517 route_state->thread_network_running = false;
2522 infrastructure_network_shutdown(route_state_t *route_state)
2527 if (route_state->thread_network_running) {
2528 thread_network_shutdown(route_state);
2533 for (interface = route_state->interfaces; interface; interface = interface->next) {
2538 route_state->have_non_thread_interface = false;
2543 partition_state_reset(route_state_t *route_state)
2545 if (route_state->omr_watcher) {
2546 if (route_state->omr_watcher_callback != NULL) {
2548 omr_watcher_callback_cancel(route_state->omr_watcher, route_state->omr_watcher_callback);
2549 route_state->omr_watcher_callback = NULL;
2552 omr_watcher_cancel(route_state->omr_watcher);
2553 omr_watcher_release(route_state->omr_watcher);
2555 route_state->omr_watcher = NULL;
2557 if (route_state->omr_publisher) {
2559 omr_publisher_cancel(route_state->omr_publisher);
2560 omr_publisher_release(route_state->omr_publisher);
2561 route_state->omr_publisher = NULL;
2563 if (route_state->route_tracker) {
2565 route_tracker_cancel(route_state->route_tracker);
2566 route_tracker_release(route_state->route_tracker);
2567 route_state->route_tracker = NULL;
2569 srp_server_t *server_state = route_state->srp_server;
2576 route_state->current_thread_state = kCTI_NCPState_Uninitialized;
2577 route_state->partition_last_prefix_set_change = 0;
2578 route_state->partition_last_pref_id_set_change = 0;
2579 route_state->partition_last_role_change = 0;
2580 route_state->partition_last_state_change = 0;
2581 route_state->partition_settle_start = 0;
2582 route_state->partition_service_last_add_time = 0;
2583 route_state->partition_have_prefix_list = false;
2584 route_state->partition_have_pref_id_list = false;
2585 route_state->partition_tunnel_name_is_known = false;
2586 route_state->partition_can_advertise_service = false;
2587 route_state->partition_can_advertise_anycast_service = false;
2588 route_state->srp_server->srp_anycast_service_blocked = false;
2589 route_state->srp_server->srp_unicast_service_blocked = false;
2590 route_state->partition_can_provide_routing = false;
2591 route_state->partition_has_xpanid = false;
2592 route_state->partition_may_offer_service = false;
2593 route_state->partition_settle_satisfied = true;
2594 route_state->have_rloc16 = false;
2595 route_state->advertising_srp_anycast_service = false;
2597 if (route_state->partition_settle_wakeup != NULL) {
2598 ioloop_cancel_wake_event(route_state->partition_settle_wakeup);
2601 if (route_state->partition_post_partition_wakeup != NULL) {
2602 ioloop_cancel_wake_event(route_state->partition_post_partition_wakeup);
2605 if (route_state->partition_pref_id_wait_wakeup != NULL) {
2606 ioloop_cancel_wake_event(route_state->partition_pref_id_wait_wakeup);
2609 if (route_state->partition_service_add_pending_wakeup != NULL) {
2610 ioloop_cancel_wake_event(route_state->partition_service_add_pending_wakeup);
2613 if (route_state->partition_anycast_service_add_pending_wakeup != NULL) {
2614 ioloop_cancel_wake_event(route_state->partition_service_add_pending_wakeup);
2617 if (route_state->service_set_changed_wakeup != NULL) {
2618 ioloop_cancel_wake_event(route_state->service_set_changed_wakeup);
2626 route_state_t *route_state = server_state->route_state;
2629 route_state->srp_service_listen_port = port;
2630 if (route_state->have_non_thread_interface) {
2631 route_state->partition_can_advertise_service = true;
2632 partition_maybe_advertise_service(route_state);
2634 partition_discontinue_srp_service(route_state);
2642 route_state_t *route_state = server_state->route_state;
2645 if (route_state->srp_listener == listener) {
2646 ioloop_comm_release(route_state->srp_listener);
2647 route_state->srp_listener = NULL;
2650 partition_discontinue_srp_service(route_state);
2656 partition_stop_srp_listener(route_state_t *route_state)
2658 if (route_state->srp_listener != NULL) {
2659 INFO("discontinuing SRP service on port %d", route_state->srp_service_listen_port);
2660 ioloop_listener_cancel(route_state->srp_listener);
2661 ioloop_comm_release(route_state->srp_listener);
2662 route_state->srp_listener = NULL;
2667 partition_start_srp_listener(route_state_t *route_state)
2674 for (service = service_tracker_services_get(route_state->srp_server->service_tracker);
2687 partition_stop_srp_listener(route_state);
2690 route_state->srp_listener = srp_proxy_listen(avoid_ports, num_avoid_ports, NULL, partition_proxy_listener_ready,
2691 partition_srp_listener_canceled, NULL, NULL, route_state->srp_server);
2692 if (route_state->srp_listener == NULL) {
2699 partition_discontinue_srp_service(route_state_t *route_state)
2701 partition_stop_srp_listener(route_state);
2704 in6addr_zero(&route_state->srp_listener_ip_address);
2705 route_state->srp_service_listen_port = 0;
2708 partition_stop_advertising_service(route_state);
2712 partition_discontinue_all_srp_service(route_state_t *route_state)
2714 partition_discontinue_srp_service(route_state);
2715 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number);
2722 partition_utun0_address_changed(route_state_t *route_state, const struct in6_addr *addr,
2728 if (!in6addr_compare(&route_state->srp_listener_ip_address, addr)) {
2729 route_state->seen_listener_address = true;
2735 if (route_state->srp_listener != NULL) {
2738 partition_discontinue_srp_service(route_state);
2755 if (!route_state->have_mesh_local_prefix || !route_state->have_non_thread_interface) {
2775 if (!in6prefix_compare(addr, &route_state->thread_mesh_local_prefix, 8)) {
2785 else if (route_state->omr_watcher == NULL ||
2786 !omr_watcher_prefix_exists(route_state->omr_watcher, addr, 64))
2793 if (!route_state->have_proposed_srp_listener_address ||
2794 in6addr_compare(&route_state->proposed_srp_listener_address, addr) > 0)
2796 if (route_state->have_proposed_srp_listener_address) {
2803 in6addr_copy(&route_state->proposed_srp_listener_address, addr);
2804 route_state->have_proposed_srp_listener_address = true;
2814 partition_utun0_pick_listener_address(route_state_t *route_state)
2816 if (route_state->have_mesh_local_prefix && route_state->advertising_srp_anycast_service &&
2817 route_state->have_non_thread_interface && route_state->have_proposed_srp_listener_address)
2819 if (route_state->srp_listener == NULL) {
2820 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->proposed_srp_listener_address, addr_buf);
2822 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->proposed_srp_listener_address, addr_buf));
2825 in6addr_copy(&route_state->srp_listener_ip_address, &route_state->proposed_srp_listener_address);
2828 route_state->srp_service_listen_port = 0;
2829 partition_start_srp_listener(route_state);
2831 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf);
2832 if (!route_state->seen_listener_address) {
2834 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf));
2837 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf));
2843 route_state->advertising_srp_anycast_service ? "" : "not ",
2844 route_state->have_proposed_srp_listener_address ? "have" : "no",
2845 route_state->have_non_thread_interface ? "have" : "no",
2846 route_state->have_mesh_local_prefix ? "have" : "no",
2847 route_state->srp_listener != NULL ? "have" : "no");
2851 if (route_state->srp_listener != NULL && !route_state->advertising_srp_anycast_service &&
2852 !route_state->srp_server->srp_anycast_service_blocked) {
2853 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf);
2855 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf));
2856 partition_discontinue_srp_service(route_state);
2861 route_state->seen_listener_address = false;
2862 route_state->have_proposed_srp_listener_address = false;
2863 in6addr_zero(&route_state->proposed_srp_listener_address);
2867 partition_got_tunnel_name(route_state_t *route_state)
2869 route_state->partition_tunnel_name_is_known = true;
2870 for (interface_t *interface = route_state->interfaces; interface; interface = interface->next) {
2871 if (!strcmp(interface->name, route_state->thread_interface_name)) {
2876 route_refresh_interface_list(route_state);
2882 route_state_t *route_state = context;
2888 if (!route_state->srp_server->srp_replication_enabled) {
2890 srp_mdns_flush(route_state->srp_server);
2897 route_maybe_restart_service_tracker(route_state_t *route_state, int *reset, int *increment)
2902 if (route_state->srp_server->service_tracker != NULL) {
2903 service_tracker_start(route_state->srp_server->service_tracker);
2914 partition_stop_advertising_service(route_state_t *route_state)
2921 if (route_maybe_restart_service_tracker(route_state, &route_state->times_advertised_unicast, &route_state->times_unadvertised_unicast)) {
2925 status = cti_remove_service(route_state->srp_server, route_state, partition_remove_service_done, NULL,
2930 route_state->advertising_srp_unicast_service = false;
2934 partition_stop_advertising_anycast_service(route_state_t *route_state, uint8_t sequence_number)
2941 if (route_maybe_restart_service_tracker(route_state, &route_state->times_advertised_anycast, &route_state->times_unadvertised_anycast)) {
2946 status = cti_remove_service(route_state->srp_server, route_state, partition_remove_service_done, NULL,
2951 route_state->advertising_srp_anycast_service = false;
2952 if (route_state->route_tracker != NULL) {
2954 route_tracker_cancel(route_state->route_tracker);
2955 route_tracker_release(route_state->route_tracker);
2956 route_state->route_tracker = NULL;
2958 route_refresh_interface_list(route_state);
2964 route_state_t *UNUSED route_state = context;
2973 partition_start_advertising_service(route_state_t *route_state)
2979 if (route_maybe_restart_service_tracker(route_state, &route_state->times_unadvertised_unicast, &route_state->times_advertised_unicast)) {
2982 memcpy(&server_info, &route_state->srp_listener_ip_address, 16);
2983 server_info[16] = (route_state->srp_service_listen_port >> 8) & 255;
2984 server_info[17] = route_state->srp_service_listen_port & 255;
2986 SEGMENTED_IPv6_ADDR_GEN_SRP(route_state->srp_listener_ip_address.s6_addr, server_ip_buf);
2990 SEGMENTED_IPv6_ADDR_PARAM_SRP(route_state->srp_listener_ip_address.s6_addr, server_ip_buf),
2991 route_state->srp_service_listen_port);
2993 ret = cti_add_service(route_state->srp_server, route_state, partition_add_service_callback, NULL,
3000 partition_schedule_service_add_wakeup(route_state);
3001 route_state->advertising_srp_unicast_service = true;
3005 partition_start_advertising_anycast_service(route_state_t *route_state)
3010 if (route_maybe_restart_service_tracker(route_state, &route_state->times_unadvertised_anycast, &route_state->times_advertised_anycast)) {
3014 service_info[1] = route_state->thread_sequence_number;
3015 INFO("%" PRIu64 "/%02x/ %x", THREAD_ENTERPRISE_NUMBER, service_info[0], route_state->thread_sequence_number);
3017 ret = cti_add_service(route_state->srp_server, route_state, partition_add_service_callback, NULL,
3024 partition_schedule_anycast_service_add_wakeup(route_state);
3025 route_state->advertising_srp_anycast_service = true;
3026 route_refresh_interface_list(route_state);
3028 if (route_state->route_tracker == NULL) {
3029 route_state->route_tracker = route_tracker_create(route_state, "main");
3030 if (route_state->route_tracker == NULL) {
3034 route_tracker_set_reconnect_callback(route_state->route_tracker, attempt_wpan_reconnect);
3035 route_tracker_start(route_state->route_tracker);
3044 route_state_t *route_state = context;
3045 route_state->partition_service_last_add_time = 0;
3046 partition_maybe_advertise_service(route_state);
3052 route_state_t *route_state = context;
3053 route_state->partition_service_last_add_time = 0;
3054 partition_maybe_advertise_anycast_service(route_state);
3058 partition_schedule_service_add_wakeup(route_state_t *route_state)
3060 if (route_state->partition_service_add_pending_wakeup == NULL) {
3061 route_state->partition_service_add_pending_wakeup = ioloop_wakeup_create();
3062 if (route_state->partition_service_add_pending_wakeup == NULL) {
3067 ioloop_cancel_wake_event(route_state->partition_service_add_pending_wakeup);
3070 ioloop_add_wake_event(route_state->partition_service_add_pending_wakeup, route_state,
3075 partition_schedule_anycast_service_add_wakeup(route_state_t *route_state)
3077 if (route_state->partition_anycast_service_add_pending_wakeup == NULL) {
3078 route_state->partition_anycast_service_add_pending_wakeup = ioloop_wakeup_create();
3079 if (route_state->partition_anycast_service_add_pending_wakeup == NULL) {
3084 ioloop_cancel_wake_event(route_state->partition_anycast_service_add_pending_wakeup);
3087 ioloop_add_wake_event(route_state->partition_anycast_service_add_pending_wakeup, route_state,
3092 partition_maybe_advertise_service(route_state_t *route_state)
3103 if (!route_state->partition_can_advertise_service) {
3108 if (route_state->srp_server->srp_unicast_service_blocked) {
3114 if (route_state->srp_listener_ip_address.s6_addr[i] != 0) {
3126 last_add_time = ioloop_timenow() - route_state->partition_service_last_add_time;
3130 partition_schedule_service_add_wakeup(route_state);
3135 for (service = service_tracker_services_get(route_state->srp_server->service_tracker);
3142 if ((service->user || (route_state->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) &&
3143 (in6addr_compare(&service->u.unicast.address, &route_state->srp_listener_ip_address) ||
3144 ((service->u.unicast.port[0] << 8) | service->u.unicast.port[1]) != route_state->srp_service_listen_port))
3147 partition_stop_advertising_service(route_state);
3154 for (thread_service_t *aservice = service_tracker_services_get(route_state->srp_server->service_tracker);
3167 route_state->seen_legacy_service = true;
3171 int cmp = in6addr_compare(&service->u.unicast.address, &route_state->srp_listener_ip_address);
3190 if ((num_lower_services > 0 && !route_state->seen_legacy_service) || num_lower_services > 1) {
3192 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf);
3194 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf));
3195 partition_stop_advertising_service(route_state);
3196 route_state->partition_service_last_add_time = ioloop_timenow();
3204 else if (num_other_services < 1 || (num_other_services < 2 && route_state->seen_legacy_service)) {
3208 SEGMENTED_IPv6_ADDR_GEN_SRP(&route_state->srp_listener_ip_address, addr_buf);
3210 SEGMENTED_IPv6_ADDR_PARAM_SRP(&route_state->srp_listener_ip_address, addr_buf));
3211 partition_start_advertising_service(route_state);
3212 route_state->partition_service_last_add_time = ioloop_timenow();
3224 partition_maybe_advertise_anycast_service(route_state_t *route_state)
3230 if (!route_state->have_non_thread_interface) {
3235 if (!route_state->partition_can_advertise_service) {
3240 if (!route_state->partition_can_advertise_anycast_service) {
3245 if (route_state->srp_server->srp_anycast_service_blocked) {
3250 if (route_state->num_thread_prefixes == 0) {
3258 last_add_time = ioloop_timenow() - route_state->partition_service_last_add_time;
3262 partition_schedule_anycast_service_add_wakeup(route_state);
3267 uint8_t winning_seq = route_state->thread_sequence_number;
3268 for (thread_service_t *service = service_tracker_services_get(route_state->srp_server->service_tracker); service;
3276 if ((service->user || (route_state->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) &&
3277 (aservice->sequence_number != route_state->thread_sequence_number ||
3278 !route_state->advertising_srp_anycast_service))
3281 partition_stop_advertising_anycast_service(route_state, aservice->sequence_number);
3288 route_ping_aservice(route_state, service);
3302 if (winning_seq != route_state->thread_sequence_number) {
3303 INFO("our sequence number (0x%02x) loses the election to 0x%02x", route_state->thread_sequence_number, winning_seq);
3309 for (thread_service_t *service = service_tracker_services_get(route_state->srp_server->service_tracker); service;
3314 if (service->rloc16 < route_state->srp_server->rloc16) {
3322 route_state->thread_sequence_number, num_less);
3327 route_state->thread_sequence_number, num_less);
3331 if (!route_state->advertising_srp_anycast_service) {
3332 INFO("advertising our anycast service with sequence number 0x%02x", route_state->thread_sequence_number);
3333 partition_start_advertising_anycast_service(route_state);
3334 route_state->partition_service_last_add_time = ioloop_timenow();
3337 route_state->thread_sequence_number);
3340 if (!route_state->advertising_srp_anycast_service) {
3342 route_state->thread_sequence_number);
3345 route_state->thread_sequence_number);
3346 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number);
3347 route_state->partition_service_last_add_time = ioloop_timenow();
3355 route_state_t *route_state = context;
3356 service_tracker_t *tracker = route_state->srp_server->service_tracker;
3365 if (service->user || (route_state->srp_server->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) {
3367 if (in6addr_compare(&service->u.unicast.address, &route_state->srp_listener_ip_address) ||
3368 port != route_state->srp_service_listen_port)
3371 partition_stop_advertising_service(route_state);
3378 if ((service->user || (route_state->srp_server->have_rloc16 && service->rloc16 == route_state->srp_server->rloc16)) &&
3379 (!route_state->advertising_srp_anycast_service ||
3380 service->u.anycast.sequence_number != route_state->thread_sequence_number))
3383 partition_stop_advertising_anycast_service(route_state, service->u.anycast.sequence_number);
3389 partition_maybe_advertise_service(route_state);
3390 partition_maybe_advertise_anycast_service(route_state);
3396 route_state_t *route_state = context;
3397 if (route_state->service_set_changed_wakeup == NULL) {
3398 route_state->service_set_changed_wakeup = ioloop_wakeup_create();
3399 if (route_state->service_set_changed_wakeup == NULL) {
3404 ioloop_cancel_wake_event(route_state->service_set_changed_wakeup);
3408 ioloop_add_wake_event(route_state->service_set_changed_wakeup, route_state,
3412 static void partition_maybe_enable_services(route_state_t *route_state)
3414 bool am_associated = route_state->current_thread_state == kCTI_NCPState_Associated;
3418 route_state
3419 route_state->partition_can_provide_routing = true;
3420 route_refresh_interface_list(route_state);
3421 routing_policy_evaluate_all_interfaces(route_state, true);
3422 if (route_state->omr_watcher == NULL) {
3423 if (route_state->omr_publisher != NULL) {
3424 omr_publisher_cancel(route_state->omr_publisher);
3425 omr_publisher_release(route_state->omr_publisher);
3426 route_state->omr_publisher = NULL;
3428 route_state->omr_watcher = omr_watcher_create(route_state, attempt_wpan_reconnect);
3429 if (route_state->omr_watcher == NULL) {
3433 route_state->omr_watcher_callback = omr_watcher_callback_add(route_state->omr_watcher,
3434 route_omr_watcher_event, NULL, route_state);
3435 if (route_state->omr_watcher_callback == NULL) {
3441 if (route_state->omr_publisher == NULL) {
3442 route_state->omr_publisher = omr_publisher_create(route_state, "main");
3443 if (route_state->omr_publisher == NULL) {
3447 omr_publisher_set_omr_watcher(route_state->omr_publisher, route_state->omr_watcher);
3448 omr_publisher_set_reconnect_callback(route_state->omr_publisher, attempt_wpan_reconnect);
3452 omr_publisher_start(route_state->omr_publisher);
3453 omr_watcher_start(route_state->omr_watcher);
3461 static void partition_disable_service(route_state_t *route_state)
3469 if (route_state->omr_publisher != NULL) {
3470 omr_publisher_cancel(route_state->omr_publisher);
3471 omr_publisher_release(route_state->omr_publisher);
3472 route_state->omr_publisher = NULL;
3475 if (route_state->omr_watcher != NULL) {
3476 if (route_state->omr_watcher_callback != NULL) {
3477 omr_watcher_callback_cancel(route_state->omr_watcher, route_state->omr_watcher_callback);
3478 route_state->omr_watcher_callback = NULL;
3480 omr_watcher_cancel(route_state->omr_watcher);
3481 omr_watcher_release(route_state->omr_watcher);
3482 route_state->omr_watcher = NULL;
3493 route_state->partition_may_offer_service = false;
3494 route_state->partition_can_provide_routing = false;
3497 void partition_block_anycast_service(route_state_t *route_state, bool block)
3500 if (!route_state->srp_server->srp_anycast_service_blocked) {
3501 route_state->srp_server->srp_anycast_service_blocked = block;
3502 partition_stop_advertising_anycast_service(route_state, route_state->thread_sequence_number);
3505 if (route_state->srp_server->srp_anycast_service_blocked) {
3506 route_state->srp_server->srp_anycast_service_blocked = block;
3507 partition_maybe_advertise_anycast_service(route_state);
3523 route_state_t *route_state = srp_servers->route_state;
3524 if (route_state == NULL) {
3528 for (interface_t *interface = route_state->interfaces; interface != NULL; interface = interface->next) {