1 /* nat64.c 2 * 3 * Copyright (c) 2022-2023 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 18 #include <netinet/in.h> 19 #include "srp-log.h" 20 #include "dns-msg.h" 21 #include "ioloop.h" 22 #include "srp-mdns-proxy.h" 23 #include "nat64.h" 24 #include "nat64-macos.h" 25 #include "state-machine.h" 26 #include "thread-service.h" 27 #include "omr-watcher.h" 28 #include "omr-publisher.h" 29 30 #if SRP_FEATURE_NAT64 31 static void nat64_infra_prefix_publisher_event_init(nat64_infra_prefix_publisher_event_t *event, nat64_infra_prefix_publisher_event_type_t event_type); 32 static void nat64_infra_prefix_publisher_event_deliver(nat64_infra_prefix_publisher_t *state_machine, nat64_infra_prefix_publisher_event_t *event); 33 static void nat64_br_prefix_publisher_event_init(nat64_br_prefix_publisher_event_t *event, nat64_br_prefix_publisher_event_type_t event_type); 34 static void nat64_br_prefix_publisher_event_deliver(nat64_br_prefix_publisher_t *state_machine, nat64_br_prefix_publisher_event_t *event); 35 static void nat64_add_prefix_to_update_queue(nat64_t *nat64, nat64_prefix_t *prefix, nat64_prefix_action action); 36 static void nat64_prefix_start_next_update(nat64_t *nat64); 37 static bool nat64_query_prefix_on_infra(nat64_infra_prefix_monitor_t *state_machine); 38 39 static void 40 nat64_prefix_finalize(nat64_prefix_t *prefix) 41 { 42 free(prefix); 43 } 44 45 static void 46 nat64_finalize(nat64_t *nat64) 47 { 48 free(nat64); 49 } 50 51 static nat64_ipv4_default_route_monitor_t * 52 nat64_ipv4_default_route_monitor_create(nat64_t *nat64) 53 { 54 nat64_ipv4_default_route_monitor_t *monitor = calloc(1, sizeof(*monitor)); 55 if (monitor == NULL) { 56 return monitor; 57 } 58 RETAIN_HERE(monitor, nat64_ipv4_default_route_monitor); 59 monitor->nat64 = nat64; 60 RETAIN_HERE(monitor->nat64, nat64); 61 return monitor; 62 } 63 64 static void 65 nat64_ipv4_default_route_monitor_cancel(nat64_ipv4_default_route_monitor_t *monitor) 66 { 67 if (monitor != NULL) { 68 monitor->has_ipv4_default_route = false; 69 if (monitor->nat64 != NULL) { 70 RELEASE_HERE(monitor->nat64, nat64); 71 monitor->nat64 = NULL; 72 } 73 } 74 } 75 76 static void 77 nat64_ipv4_default_route_monitor_finalize(nat64_ipv4_default_route_monitor_t *monitor) 78 { 79 free(monitor); 80 } 81 82 static void 83 nat64_infra_prefix_monitor_finalize(nat64_infra_prefix_monitor_t *monitor) 84 { 85 free(monitor); 86 } 87 88 static nat64_infra_prefix_monitor_t * 89 nat64_infra_prefix_monitor_create(nat64_t *nat64) 90 { 91 nat64_infra_prefix_monitor_t *monitor = calloc(1, sizeof(*monitor)); 92 if (monitor == NULL) { 93 return monitor; 94 } 95 RETAIN_HERE(monitor, nat64_infra_prefix_monitor); 96 monitor->nat64 = nat64; 97 RETAIN_HERE(monitor->nat64, nat64); 98 return monitor; 99 } 100 101 static void 102 nat64_infra_prefix_monitor_cancel(nat64_infra_prefix_monitor_t *monitor) 103 { 104 if (monitor != NULL) { 105 nat64_prefix_t *next; 106 for (nat64_prefix_t *prefix = monitor->infra_nat64_prefixes; prefix != NULL; prefix = next) { 107 next = prefix->next; 108 prefix->next = NULL; 109 RELEASE_HERE(prefix, nat64_prefix); 110 } 111 monitor->infra_nat64_prefixes = NULL; 112 if (monitor->sdRef != NULL) { 113 DNSServiceRefDeallocate(monitor->sdRef); 114 monitor->sdRef = NULL; 115 RELEASE_HERE(monitor, nat64_infra_prefix_monitor); 116 } 117 if (monitor->nat64 != NULL) { 118 RELEASE_HERE(monitor->nat64, nat64); 119 monitor->nat64 = NULL; 120 } 121 monitor->canceled = true; 122 } 123 } 124 125 static nat64_thread_prefix_monitor_t * 126 nat64_thread_prefix_monitor_create(nat64_t *nat64) 127 { 128 nat64_thread_prefix_monitor_t *monitor = calloc(1, sizeof(*monitor)); 129 if (monitor == NULL) { 130 return monitor; 131 } 132 RETAIN_HERE(monitor, nat64_thread_prefix_monitor); 133 monitor->nat64 = nat64; 134 RETAIN_HERE(monitor->nat64, nat64); 135 return monitor; 136 } 137 138 static void 139 nat64_thread_prefix_monitor_cancel(nat64_thread_prefix_monitor_t *monitor) 140 { 141 if (monitor != NULL) { 142 nat64_prefix_t *next; 143 for (nat64_prefix_t *prefix = monitor->thread_nat64_prefixes; prefix != NULL; prefix = next) { 144 next = prefix->next; 145 prefix->next = NULL; 146 RELEASE_HERE(prefix, nat64_prefix); 147 } 148 monitor->thread_nat64_prefixes = NULL; 149 if (monitor->timer != NULL) { 150 ioloop_cancel_wake_event(monitor->timer); 151 ioloop_wakeup_release(monitor->timer); 152 monitor->timer = NULL; 153 } 154 if (monitor->nat64 != NULL) { 155 RELEASE_HERE(monitor->nat64, nat64); 156 monitor->nat64 = NULL; 157 } 158 } 159 } 160 161 static void 162 nat64_thread_prefix_monitor_finalize(nat64_thread_prefix_monitor_t *monitor) 163 { 164 free(monitor); 165 } 166 167 static nat64_infra_prefix_publisher_t * 168 nat64_infra_prefix_publisher_create(nat64_t *nat64) 169 { 170 nat64_infra_prefix_publisher_t *publisher = calloc(1, sizeof(*publisher)); 171 if (publisher == NULL) { 172 return publisher; 173 } 174 RETAIN_HERE(publisher, nat64_infra_prefix_publisher); 175 publisher->nat64 = nat64; 176 RETAIN_HERE(publisher->nat64, nat64); 177 return publisher; 178 } 179 180 static void 181 nat64_infra_prefix_publisher_finalize(nat64_infra_prefix_publisher_t *publisher) 182 { 183 free(publisher); 184 } 185 186 static void 187 nat64_infra_prefix_publisher_cancel(nat64_infra_prefix_publisher_t *publisher) 188 { 189 if (publisher != NULL) { 190 if (publisher->state == nat64_infra_prefix_publisher_state_publishing) { 191 SEGMENTED_IPv6_ADDR_GEN_SRP(publisher->proposed_prefix->prefix.s6_addr, nat64_prefix_buf); 192 INFO("thread network shutdown, unpublishing infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 193 SEGMENTED_IPv6_ADDR_PARAM_SRP(publisher->proposed_prefix->prefix.s6_addr, nat64_prefix_buf)); 194 nat64_add_prefix_to_update_queue(publisher->nat64, publisher->proposed_prefix, nat64_prefix_action_remove); 195 } 196 if (publisher->proposed_prefix != NULL) { 197 RELEASE_HERE(publisher->proposed_prefix, nat64_prefix); 198 publisher->proposed_prefix = NULL; 199 } 200 if (publisher->nat64 != NULL) { 201 RELEASE_HERE(publisher->nat64, nat64); 202 publisher->nat64 = NULL; 203 } 204 } 205 } 206 207 static nat64_br_prefix_publisher_t * 208 nat64_br_prefix_publisher_create(nat64_t *nat64) 209 { 210 nat64_br_prefix_publisher_t *publisher = calloc(1, sizeof(*publisher)); 211 if (publisher == NULL) { 212 return publisher; 213 } 214 RETAIN_HERE(publisher, nat64_br_prefix_publisher); 215 publisher->nat64 = nat64; 216 RETAIN_HERE(publisher->nat64, nat64); 217 return publisher; 218 } 219 220 static void 221 nat64_br_prefix_publisher_finalize(nat64_br_prefix_publisher_t *publisher) 222 { 223 free(publisher); 224 } 225 226 static void 227 nat64_br_prefix_publisher_cancel(nat64_br_prefix_publisher_t *publisher) 228 { 229 if (publisher != NULL) { 230 if (publisher->state == nat64_br_prefix_publisher_state_publishing) { 231 SEGMENTED_IPv6_ADDR_GEN_SRP(publisher->br_prefix->prefix.s6_addr, nat64_prefix_buf); 232 INFO("thread network shutdown, unpublishing br prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 233 SEGMENTED_IPv6_ADDR_PARAM_SRP(publisher->br_prefix->prefix.s6_addr, nat64_prefix_buf)); 234 nat64_add_prefix_to_update_queue(publisher->nat64, publisher->br_prefix, nat64_prefix_action_remove); 235 } 236 if (publisher->br_prefix != NULL) { 237 RELEASE_HERE(publisher->br_prefix, nat64_prefix); 238 publisher->br_prefix = NULL; 239 } 240 if (publisher->timer != NULL) { 241 ioloop_cancel_wake_event(publisher->timer); 242 ioloop_wakeup_release(publisher->timer); 243 publisher->timer = NULL; 244 } 245 if (publisher->nat64 != NULL) { 246 RELEASE_HERE(publisher->nat64, nat64); 247 publisher->nat64 = NULL; 248 } 249 } 250 } 251 252 static void 253 nat64_cancel(nat64_t *nat64) 254 { 255 if (nat64->ipv4_monitor) { 256 INFO("discontinuing nat64 ipv4 default route monitor"); 257 nat64_ipv4_default_route_monitor_cancel(nat64->ipv4_monitor); 258 RELEASE_HERE(nat64->ipv4_monitor, nat64_ipv4_default_route_monitor); 259 nat64->ipv4_monitor = NULL; 260 } 261 if (nat64->thread_monitor) { 262 INFO("discontinuing nat64 thread monitor"); 263 nat64_thread_prefix_monitor_cancel(nat64->thread_monitor); 264 RELEASE_HERE(nat64->thread_monitor, nat64_thread_prefix_monitor); 265 nat64->thread_monitor = NULL; 266 } 267 if (nat64->infra_monitor) { 268 INFO("discontinuing nat64 infra monitor"); 269 nat64_infra_prefix_monitor_cancel(nat64->infra_monitor); 270 RELEASE_HERE(nat64->infra_monitor, nat64_infra_prefix_monitor); 271 nat64->infra_monitor = NULL; 272 } 273 if (nat64->nat64_infra_prefix_publisher) { 274 INFO("discontinuing nat64 infra prefix publisher"); 275 nat64_infra_prefix_publisher_cancel(nat64->nat64_infra_prefix_publisher); 276 RELEASE_HERE(nat64->nat64_infra_prefix_publisher, nat64_infra_prefix_publisher); 277 nat64->nat64_infra_prefix_publisher = NULL; 278 } 279 if (nat64->nat64_br_prefix_publisher) { 280 INFO("discontinuing nat64 br prefix publisher"); 281 nat64_br_prefix_publisher_cancel(nat64->nat64_br_prefix_publisher); 282 RELEASE_HERE(nat64->nat64_br_prefix_publisher, nat64_br_prefix_publisher); 283 nat64->nat64_br_prefix_publisher = NULL; 284 } 285 } 286 287 nat64_t * 288 nat64_create(route_state_t *route_state) 289 { 290 nat64_t *new_nat64 = calloc(1, sizeof(*new_nat64)); 291 if (new_nat64 == NULL) { 292 ERROR("no memory for nat64_t."); 293 return NULL; 294 } 295 RETAIN_HERE(new_nat64, nat64); 296 new_nat64->ipv4_monitor = nat64_ipv4_default_route_monitor_create(new_nat64); 297 new_nat64->infra_monitor = nat64_infra_prefix_monitor_create(new_nat64); 298 new_nat64->thread_monitor = nat64_thread_prefix_monitor_create(new_nat64); 299 new_nat64->nat64_infra_prefix_publisher = nat64_infra_prefix_publisher_create(new_nat64); 300 new_nat64->nat64_br_prefix_publisher = nat64_br_prefix_publisher_create(new_nat64); 301 302 if (new_nat64->ipv4_monitor == NULL || new_nat64->infra_monitor == NULL || 303 new_nat64->thread_monitor == NULL || new_nat64->nat64_infra_prefix_publisher == NULL || 304 new_nat64->nat64_br_prefix_publisher == NULL) { 305 ERROR("no memory for nat64 state machines."); 306 nat64_cancel(new_nat64); 307 return NULL; 308 } 309 new_nat64->route_state = route_state; 310 311 return new_nat64; 312 } 313 314 nat64_prefix_t * 315 nat64_prefix_create(struct in6_addr *address, int prefix_length, nat64_preference pref, int rloc) 316 { 317 nat64_prefix_t *prefix; 318 319 prefix = calloc(1, (sizeof *prefix)); 320 if (prefix == NULL) { 321 ERROR("no memory when create nat64 prefix"); 322 return NULL; 323 } 324 in6prefix_copy(&prefix->prefix, address, NAT64_PREFIX_SLASH_96_BYTES); 325 prefix->prefix_len = prefix_length; 326 prefix->priority = pref; 327 prefix->rloc = rloc; 328 RETAIN_HERE(prefix, nat64_prefix); 329 return prefix; 330 } 331 332 static nat64_prefix_t * 333 nat64_prefix_dup(nat64_prefix_t *src) 334 { 335 return nat64_prefix_create(&src->prefix, src->prefix_len, src->priority, src->rloc); 336 } 337 338 static bool 339 nat64_preference_has_higher_priority(const nat64_preference higher, const nat64_preference lower) 340 { 341 // smaller value means higher priority 342 if (higher < lower) { 343 return true; 344 } else { 345 return false; 346 } 347 } 348 349 static bool 350 nat64_thread_has_routable_prefix(const route_state_t * const route_state) 351 { 352 bool have_routable_omr_prefix; 353 if (route_state->omr_publisher != NULL && omr_publisher_have_routable_prefix(route_state->omr_publisher)) { 354 have_routable_omr_prefix = true; 355 } else { 356 have_routable_omr_prefix = false; 357 } 358 return have_routable_omr_prefix; 359 } 360 361 #define NAT64_EVENT_ANNOUNCE(state_machine, event) \ 362 do { \ 363 INFO("event " PUB_S_SRP " generated in state " PUB_S_SRP, \ 364 event.name, state_machine->state_name); \ 365 } while (false) 366 367 #define NAT64_STATE_ANNOUNCE(state_machine, event) \ 368 do { \ 369 if (event != NULL) { \ 370 INFO("event " PUB_S_SRP " received in state " PUB_S_SRP, \ 371 event->name, state_machine->state_name); \ 372 } else { \ 373 INFO("entering state " PUB_S_SRP, \ 374 state_machine->state_name); \ 375 } \ 376 } while (false) 377 378 #define NAT64_UNEXPECTED_EVENT(state_machine, event) \ 379 do { \ 380 if (event != NULL) { \ 381 INFO("unexpected event " PUB_S_SRP " received in state " PUB_S_SRP, \ 382 event->name, state_machine->state_name); \ 383 } else { \ 384 INFO("unexpected NULL event received in state " PUB_S_SRP, \ 385 state_machine->state_name); \ 386 } \ 387 } while (false) 388 389 #define DECLARE_NAT64_STATE_GET(type, total) \ 390 static type ## _state_t * \ 391 type ## _state_get(type ## _state_type_t state) \ 392 { \ 393 static bool once = false; \ 394 if (!once) { \ 395 for (unsigned i = 0; i < total ## _NUM_STATES; i++) { \ 396 if (type ## _states[i].state != (type ## _state_type_t)i) { \ 397 ERROR("type ## states %d doesn't match " PUB_S_SRP, i, type ## _states[i].name); \ 398 return NULL; \ 399 } \ 400 } \ 401 once = true; \ 402 } \ 403 if (state < 0 || state > total ## _NUM_STATES) { \ 404 return NULL; \ 405 } \ 406 return & type ## _states[state]; \ 407 } 408 409 #define DECLARE_NAT64_NEXT_STATE(type) \ 410 static void \ 411 type ## _next_state(type ## _t *state_machine, type ## _state_type_t state) \ 412 { \ 413 type ## _state_type_t next_state = state; \ 414 do { \ 415 type ## _state_t *new_state = type ## _state_get(next_state); \ 416 if (new_state == NULL) { \ 417 ERROR("next state is invalid: %d", next_state); \ 418 return; \ 419 } \ 420 state_machine->state = next_state; \ 421 state_machine->state_name = new_state->name; \ 422 type ## _action_t action = new_state->action; \ 423 if (action != NULL) { \ 424 next_state = action(state_machine, NULL); \ 425 } \ 426 } while (next_state != type ## _state_invalid); \ 427 } 428 429 #define DECLARE_NAT64_EVENT_CONFIGURATION_GET(type, total) \ 430 static type ## _configuration_t * \ 431 type ## _configuration_get(type ## _type_t event) \ 432 { \ 433 static bool once = false; \ 434 if (!once) { \ 435 for (unsigned i = 0; i < total ## _NUM_EVENT_TYPES; i++) { \ 436 if (type ## _configurations[i].event_type != (type ## _type_t)i) { \ 437 ERROR("type ## event %d doesn't match " PUB_S_SRP, i, type ## _configurations[i].name); \ 438 return NULL; \ 439 } \ 440 } \ 441 once = true; \ 442 } \ 443 if (event < 0 || event > total ## _NUM_EVENT_TYPES) { \ 444 return NULL; \ 445 } \ 446 return & type ## _configurations[event]; \ 447 } 448 449 #define NAT64_EVENT_NAME_DECL(name) { nat64_event_##name, #name } 450 451 #define DECLARE_NAT64_EVENT_INIT(type) \ 452 static void \ 453 type ## _init(type ## _t *event, type ## _type_t event_type) \ 454 { \ 455 memset(event, 0, sizeof(*event)); \ 456 type ## _configuration_t *event_config = type ## _configuration_get(event_type); \ 457 if (event_config == NULL) { \ 458 ERROR("invalid event type %d", event_type); \ 459 return; \ 460 } \ 461 event->event_type = event_type; \ 462 event->name = event_config->name; \ 463 } 464 465 #define DECLARE_NAT64_EVENT_DELIVER(type) \ 466 static void \ 467 type ## _event_deliver(type ## _t *state_machine, type ## _event_t *event) \ 468 { \ 469 type ## _state_t *state = type ## _state_get(state_machine->state); \ 470 if (state == NULL) { \ 471 ERROR("event " PUB_S_SRP " received in invalid state %d", event->name, state_machine->state); \ 472 return; \ 473 } \ 474 if (state->action == NULL) { \ 475 FAULT("event " PUB_S_SRP " received in state " PUB_S_SRP " with NULL action", event->name, state->name); \ 476 return; \ 477 } \ 478 type ## _state_type_t next_state = state->action(state_machine, event); \ 479 if (next_state != type ## _state_invalid) { \ 480 type ## _next_state(state_machine, next_state); \ 481 } \ 482 } 483 484 // ipv4 default route state machine start 485 static void nat64_ipv4_default_route_monitor_event_init(nat64_ipv4_default_route_monitor_event_t *event, nat64_ipv4_default_route_monitor_event_type_t event_type); 486 487 typedef nat64_ipv4_default_route_monitor_state_type_t (*nat64_ipv4_default_route_monitor_action_t)(nat64_ipv4_default_route_monitor_t *NONNULL state_machine, nat64_ipv4_default_route_monitor_event_t *NULLABLE event); 488 489 typedef struct { 490 nat64_ipv4_default_route_monitor_state_type_t state; 491 char *name; 492 nat64_ipv4_default_route_monitor_action_t action; 493 } nat64_ipv4_default_route_monitor_state_t; 494 495 static nat64_ipv4_default_route_monitor_state_type_t 496 nat64_ipv4_default_route_monitor_init_action(nat64_ipv4_default_route_monitor_t *state_machine, nat64_ipv4_default_route_monitor_event_t *UNUSED event) 497 { 498 NAT64_STATE_ANNOUNCE(state_machine, event); 499 state_machine->has_ipv4_default_route = false; 500 return nat64_ipv4_default_route_monitor_state_wait_for_event; 501 } 502 503 static nat64_ipv4_default_route_monitor_state_type_t 504 nat64_ipv4_default_route_monitor_wait_action(nat64_ipv4_default_route_monitor_t *state_machine, nat64_ipv4_default_route_monitor_event_t *event) 505 { 506 NAT64_STATE_ANNOUNCE(state_machine, event); 507 if (event == NULL) { 508 return nat64_ipv4_default_route_monitor_state_invalid; 509 } else if (event->event_type == nat64_event_ipv4_default_route_update) { 510 nat64_br_prefix_publisher_event_t out_event; 511 if (event->has_ipv4_connectivity == false) { 512 state_machine->has_ipv4_default_route = false; 513 nat64_br_prefix_publisher_event_init(&out_event, nat64_event_nat64_br_prefix_publisher_ipv4_default_route_went_away); 514 } else { 515 state_machine->has_ipv4_default_route = true; 516 nat64_br_prefix_publisher_event_init(&out_event, nat64_event_nat64_br_prefix_publisher_ipv4_default_route_showed_up); 517 } 518 NAT64_EVENT_ANNOUNCE(state_machine, out_event); 519 // Deliver out_event to BR prefix publisher 520 nat64_br_prefix_publisher_event_deliver(state_machine->nat64->nat64_br_prefix_publisher, &out_event); 521 } else { 522 NAT64_UNEXPECTED_EVENT(state_machine, event); 523 } 524 return nat64_ipv4_default_route_monitor_state_invalid; 525 } 526 527 #define IPV4_STATE_NAME_DECL(name) nat64_ipv4_default_route_monitor_state_##name, #name 528 static nat64_ipv4_default_route_monitor_state_t 529 nat64_ipv4_default_route_monitor_states[] = { 530 { IPV4_STATE_NAME_DECL(invalid), NULL }, 531 { IPV4_STATE_NAME_DECL(init), nat64_ipv4_default_route_monitor_init_action }, 532 { IPV4_STATE_NAME_DECL(wait_for_event), nat64_ipv4_default_route_monitor_wait_action }, 533 }; 534 #define IPV4_DEFAULT_ROUTE_MONITOR_NUM_STATES (sizeof(nat64_ipv4_default_route_monitor_states) / sizeof(nat64_ipv4_default_route_monitor_state_t)) 535 536 DECLARE_NAT64_STATE_GET(nat64_ipv4_default_route_monitor, IPV4_DEFAULT_ROUTE_MONITOR); 537 DECLARE_NAT64_NEXT_STATE(nat64_ipv4_default_route_monitor); 538 539 // ipv4 default route monitor event functions 540 typedef struct { 541 nat64_ipv4_default_route_monitor_event_type_t event_type; 542 char *name; 543 } nat64_ipv4_default_route_monitor_event_configuration_t; 544 545 nat64_ipv4_default_route_monitor_event_configuration_t nat64_ipv4_default_route_monitor_event_configurations[] = { 546 NAT64_EVENT_NAME_DECL(ipv4_default_route_invalid), 547 NAT64_EVENT_NAME_DECL(ipv4_default_route_update), 548 NAT64_EVENT_NAME_DECL(ipv4_default_route_showed_up), 549 NAT64_EVENT_NAME_DECL(ipv4_default_route_went_away), 550 }; 551 #define IPV4_DEFAULT_ROUTE_MONITOR_NUM_EVENT_TYPES (sizeof(nat64_ipv4_default_route_monitor_event_configurations) / sizeof(nat64_ipv4_default_route_monitor_event_configuration_t)) 552 553 DECLARE_NAT64_EVENT_CONFIGURATION_GET(nat64_ipv4_default_route_monitor_event, IPV4_DEFAULT_ROUTE_MONITOR); 554 DECLARE_NAT64_EVENT_INIT(nat64_ipv4_default_route_monitor_event); 555 DECLARE_NAT64_EVENT_DELIVER(nat64_ipv4_default_route_monitor); 556 557 void 558 nat64_default_route_update(nat64_t *NONNULL nat64, bool has_ipv4_connectivity) 559 { 560 if (has_ipv4_connectivity != nat64->ipv4_monitor->has_ipv4_default_route){ 561 nat64_ipv4_default_route_monitor_event_t event; 562 nat64_ipv4_default_route_monitor_event_init(&event, nat64_event_ipv4_default_route_update); 563 event.has_ipv4_connectivity = has_ipv4_connectivity; 564 nat64_ipv4_default_route_monitor_event_deliver(nat64->ipv4_monitor, &event); 565 } 566 } 567 // ipv4 default route state machine end 568 569 // Infrastructure nat64 prefix monitor state machine start 570 static void nat64_infra_prefix_monitor_event_init(nat64_infra_prefix_monitor_event_t *event, nat64_infra_prefix_monitor_event_type_t event_type); 571 static void nat64_infra_prefix_monitor_event_deliver(nat64_infra_prefix_monitor_t *state_machine, nat64_infra_prefix_monitor_event_t *event); 572 typedef nat64_infra_prefix_monitor_state_type_t (*nat64_infra_prefix_monitor_action_t)(nat64_infra_prefix_monitor_t *NONNULL sm, nat64_infra_prefix_monitor_event_t *NULLABLE event); 573 574 typedef struct { 575 nat64_infra_prefix_monitor_state_type_t state; 576 char *name; 577 nat64_infra_prefix_monitor_action_t action; 578 } nat64_infra_prefix_monitor_state_t; 579 580 static void 581 nat64_query_infra_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, 582 DNSServiceErrorType errorCode, const char *fullname, uint16_t rrtype, uint16_t rrclass, 583 uint16_t rdlen, const void *rdata, uint32_t ttl, void *context) 584 { 585 (void)(sdRef); 586 (void)(interfaceIndex); 587 588 nat64_infra_prefix_monitor_t *state_machine = context; 589 590 if (errorCode == kDNSServiceErr_NoError) { 591 SEGMENTED_IPv6_ADDR_GEN_SRP(rdata, ipv6_rdata_buf); 592 INFO("LLQ " PRI_S_SRP PRI_SEGMENTED_IPv6_ADDR_SRP 593 "name: " PRI_S_SRP ", rrtype: %u, rrclass: %u, rdlen: %u, ttl: %u.", 594 (flags & kDNSServiceFlagsAdd) ? "adding " : "removing ", 595 SEGMENTED_IPv6_ADDR_PARAM_SRP(rdata, ipv6_rdata_buf), fullname, rrtype, rrclass, rdlen, ttl); 596 nat64_infra_prefix_monitor_event_t event; 597 nat64_infra_prefix_monitor_event_init(&event, nat64_event_infra_prefix_update); 598 event.flags = flags; 599 event.rdata = rdata; 600 NAT64_EVENT_ANNOUNCE(state_machine, event); 601 nat64_infra_prefix_monitor_event_deliver(state_machine, &event); 602 } else { 603 if (errorCode == kDNSServiceErr_NoSuchRecord) { 604 // This should never happen. 605 INFO("No such record for " PRI_S_SRP , NAT64_PREFIX_LLQ_QUERY_DOMAIN); 606 } else if (errorCode == kDNSServiceErr_ServiceNotRunning) { 607 INFO("daemon disconnected (probably daemon crash)."); 608 } else { 609 INFO("Got error code %d when query " PRI_S_SRP , errorCode, NAT64_PREFIX_LLQ_QUERY_DOMAIN); 610 } 611 DNSServiceRefDeallocate(state_machine->sdRef); 612 state_machine->sdRef = NULL; 613 614 // We enter with a reference held on the state machine object. If there is no error, that means we got some kind 615 // of result, and so we don't release the reference because we can still get more results. If, on the other hand, 616 // we get an error, we will restart the query after a delay. This means that the reference we were passed is 617 // still needed for the duration of the dispatch_after call. When that timer expires, if the state machine hasn't 618 // been canceled in the meantime, we restart the query. 619 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), 620 dispatch_get_main_queue(), ^(void) { 621 if (!state_machine->canceled) { 622 nat64_query_prefix_on_infra(state_machine); 623 } 624 RELEASE_HERE(state_machine, nat64_infra_prefix_monitor); 625 }); 626 } 627 } 628 629 static bool 630 nat64_query_prefix_on_infra(nat64_infra_prefix_monitor_t *state_machine) 631 { 632 OSStatus err; 633 634 err = DNSServiceQueryRecord(&state_machine->sdRef, kDNSServiceFlagsLongLivedQuery, kDNSServiceInterfaceIndexAny, NAT64_PREFIX_LLQ_QUERY_DOMAIN, kDNSServiceType_AAAA, kDNSServiceClass_IN, nat64_query_infra_callback, state_machine); 635 if (err != kDNSServiceErr_NoError) { 636 ERROR("DNSServiceQueryRecord failed for " PRI_S_SRP ": %d", NAT64_PREFIX_LLQ_QUERY_DOMAIN, (int)err); 637 return false; 638 } 639 RETAIN_HERE(state_machine, nat64_infra_prefix_monitor); // For the callback. 640 err = DNSServiceSetDispatchQueue(state_machine->sdRef, dispatch_get_main_queue()); 641 if (err != kDNSServiceErr_NoError) { 642 ERROR("DNSServiceSetDispatchQueue failed for " PRI_S_SRP ": %d", NAT64_PREFIX_LLQ_QUERY_DOMAIN, (int)err); 643 return false; 644 } 645 return true; 646 } 647 648 static nat64_infra_prefix_monitor_state_type_t 649 nat64_infra_prefix_monitor_init_action(nat64_infra_prefix_monitor_t *state_machine, nat64_infra_prefix_monitor_event_t * event) 650 { 651 NAT64_STATE_ANNOUNCE(state_machine, event); 652 // Init action: start LLQ. 653 if (!nat64_query_prefix_on_infra(state_machine)) { 654 return nat64_infra_prefix_monitor_state_invalid; 655 } 656 // Switch to next state. 657 return nat64_infra_prefix_monitor_state_wait_for_change; 658 } 659 660 static nat64_infra_prefix_monitor_state_type_t 661 nat64_infra_prefix_monitor_wait_action(nat64_infra_prefix_monitor_t *state_machine, nat64_infra_prefix_monitor_event_t *event) 662 { 663 NAT64_STATE_ANNOUNCE(state_machine, event); 664 if (event == NULL) { 665 return nat64_infra_prefix_monitor_state_invalid; 666 } else if (event->event_type == nat64_event_infra_prefix_update){ 667 bool changed = false; 668 if (event->flags & kDNSServiceFlagsAdd) { 669 nat64_prefix_t **ppref = &state_machine->infra_nat64_prefixes, *prefix = NULL; 670 while (*ppref != NULL) { 671 prefix = *ppref; 672 if (!memcmp(&prefix->prefix, event->rdata, NAT64_PREFIX_SLASH_96_BYTES)) { 673 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, nat64_prefix_buf); 674 INFO("ignore dup infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 675 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, nat64_prefix_buf)); 676 break; 677 } else { 678 ppref = &prefix->next; 679 } 680 } 681 if (*ppref == NULL) { 682 nat64_prefix_t * new_prefix = nat64_prefix_create((struct in6_addr *)event->rdata, NAT64_PREFIX_SLASH_96_BYTES, nat64_preference_medium, state_machine->nat64->route_state->srp_server->rloc16); 683 if (new_prefix == NULL) { 684 ERROR("no memory for nat64 prefix."); 685 return nat64_infra_prefix_monitor_state_invalid; 686 } 687 SEGMENTED_IPv6_ADDR_GEN_SRP(new_prefix->prefix.s6_addr, nat64_prefix_buf); 688 INFO("adding infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " to list", 689 SEGMENTED_IPv6_ADDR_PARAM_SRP(new_prefix->prefix.s6_addr, nat64_prefix_buf)); 690 new_prefix->next = state_machine->infra_nat64_prefixes; 691 state_machine->infra_nat64_prefixes = new_prefix; 692 changed = true; 693 } 694 } else { 695 nat64_prefix_t **ppref = &state_machine->infra_nat64_prefixes, *prefix = NULL; 696 while (*ppref != NULL) { 697 prefix = *ppref; 698 if (!memcmp(&prefix->prefix, event->rdata, NAT64_PREFIX_SLASH_96_BYTES)) { 699 *ppref = prefix->next; 700 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, nat64_prefix_buf); 701 INFO("removing infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " from list", 702 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, nat64_prefix_buf)); 703 RELEASE_HERE(prefix, nat64_prefix); 704 changed = true; 705 } else { 706 ppref = &prefix->next; 707 } 708 } 709 } 710 if (changed){ 711 return nat64_infra_prefix_monitor_state_change_occurred; 712 } 713 } else { 714 NAT64_UNEXPECTED_EVENT(state_machine, event); 715 } 716 return nat64_infra_prefix_monitor_state_invalid; 717 } 718 719 static nat64_infra_prefix_monitor_state_type_t 720 nat64_infra_prefix_monitor_change_occurred_action(nat64_infra_prefix_monitor_t *state_machine, nat64_infra_prefix_monitor_event_t * event) 721 { 722 nat64_infra_prefix_publisher_event_t out_event_to_nat64_infra_prefix_publisher; 723 nat64_br_prefix_publisher_event_t out_event_to_nat64_br_prefix_publisher; 724 725 NAT64_STATE_ANNOUNCE(state_machine, event); 726 nat64_infra_prefix_publisher_event_init(&out_event_to_nat64_infra_prefix_publisher, nat64_event_nat64_infra_prefix_publisher_infra_prefix_changed); 727 out_event_to_nat64_infra_prefix_publisher.prefix = state_machine->infra_nat64_prefixes; 728 NAT64_EVENT_ANNOUNCE(state_machine, out_event_to_nat64_infra_prefix_publisher); 729 // Deliver this event to infra prefix publisher. 730 nat64_infra_prefix_publisher_event_deliver(state_machine->nat64->nat64_infra_prefix_publisher, &out_event_to_nat64_infra_prefix_publisher); 731 732 nat64_br_prefix_publisher_event_init(&out_event_to_nat64_br_prefix_publisher, nat64_event_nat64_br_prefix_publisher_infra_prefix_changed); 733 out_event_to_nat64_br_prefix_publisher.prefix = state_machine->infra_nat64_prefixes; 734 NAT64_EVENT_ANNOUNCE(state_machine, out_event_to_nat64_br_prefix_publisher); 735 // Deliver this event to BR prefix publisher. 736 nat64_br_prefix_publisher_event_deliver(state_machine->nat64->nat64_br_prefix_publisher, &out_event_to_nat64_br_prefix_publisher); 737 738 return nat64_infra_prefix_monitor_state_wait_for_change; 739 } 740 741 #define INFRA_STATE_NAME_DECL(name) nat64_infra_prefix_monitor_state_##name, #name 742 static nat64_infra_prefix_monitor_state_t 743 nat64_infra_prefix_monitor_states[] = { 744 { INFRA_STATE_NAME_DECL(invalid), NULL }, 745 { INFRA_STATE_NAME_DECL(init), nat64_infra_prefix_monitor_init_action }, 746 { INFRA_STATE_NAME_DECL(wait_for_change), nat64_infra_prefix_monitor_wait_action }, 747 { INFRA_STATE_NAME_DECL(change_occurred), nat64_infra_prefix_monitor_change_occurred_action }, 748 }; 749 #define INFRA_PREFIX_MONITOR_NUM_STATES (sizeof(nat64_infra_prefix_monitor_states) / sizeof(nat64_infra_prefix_monitor_state_t)) 750 751 DECLARE_NAT64_STATE_GET(nat64_infra_prefix_monitor, INFRA_PREFIX_MONITOR); 752 DECLARE_NAT64_NEXT_STATE(nat64_infra_prefix_monitor); 753 754 // Infra prefix monitor event functions 755 typedef struct { 756 nat64_infra_prefix_monitor_event_type_t event_type; 757 char *name; 758 } nat64_infra_prefix_monitor_event_configuration_t; 759 760 nat64_infra_prefix_monitor_event_configuration_t nat64_infra_prefix_monitor_event_configurations[] = { 761 NAT64_EVENT_NAME_DECL(infra_prefix_invalid), 762 NAT64_EVENT_NAME_DECL(infra_prefix_update), 763 }; 764 #define INFRA_PREFIX_MONITOR_NUM_EVENT_TYPES (sizeof(nat64_infra_prefix_monitor_event_configurations) / sizeof(nat64_infra_prefix_monitor_event_configuration_t)) 765 766 DECLARE_NAT64_EVENT_CONFIGURATION_GET(nat64_infra_prefix_monitor_event, INFRA_PREFIX_MONITOR); 767 DECLARE_NAT64_EVENT_INIT(nat64_infra_prefix_monitor_event); 768 DECLARE_NAT64_EVENT_DELIVER(nat64_infra_prefix_monitor); 769 770 // Infrastructure nat64 prefix monitor state machine end 771 772 773 774 // Thread nat64 prefix monitor state machine start 775 static void nat64_thread_prefix_monitor_event_init(nat64_thread_prefix_monitor_event_t *event, nat64_thread_prefix_monitor_event_type_t event_type); 776 static void nat64_thread_prefix_monitor_event_deliver(nat64_thread_prefix_monitor_t *state_machine, nat64_thread_prefix_monitor_event_t *event); 777 typedef nat64_thread_prefix_monitor_state_type_t (*nat64_thread_prefix_monitor_action_t)(nat64_thread_prefix_monitor_t *NONNULL sm, nat64_thread_prefix_monitor_event_t *NULLABLE event); 778 779 typedef struct { 780 nat64_thread_prefix_monitor_state_type_t state; 781 char *name; 782 nat64_thread_prefix_monitor_action_t action; 783 } nat64_thread_prefix_monitor_state_t; 784 785 static void 786 nat64_thread_prefix_monitor_context_release(void *context) 787 { 788 nat64_thread_prefix_monitor_t *state_machine = context; 789 RELEASE_HERE(state_machine, nat64_thread_prefix_monitor); 790 } 791 792 static void 793 nat64_thread_prefix_monitor_wakeup(void *context) 794 { 795 nat64_thread_prefix_monitor_t *state_machine = context; 796 nat64_thread_prefix_monitor_event_t out_event; 797 nat64_thread_prefix_monitor_event_init(&out_event, nat64_event_thread_prefix_init_wait_ended); 798 NAT64_EVENT_ANNOUNCE(state_machine, out_event); 799 nat64_thread_prefix_monitor_event_deliver(state_machine, &out_event); 800 } 801 802 static nat64_thread_prefix_monitor_state_type_t 803 nat64_thread_prefix_monitor_init_action(nat64_thread_prefix_monitor_t *state_machine, nat64_thread_prefix_monitor_event_t * event) 804 { 805 NAT64_STATE_ANNOUNCE(state_machine, event); 806 // Init action: start timer. 807 if (state_machine->timer == NULL) { 808 state_machine->timer = ioloop_wakeup_create(); 809 if (state_machine->timer == NULL) { 810 ERROR("no memory when create timer"); 811 return nat64_thread_prefix_monitor_state_invalid; 812 } 813 RETAIN_HERE(state_machine, nat64_thread_prefix_monitor); 814 // wait rand(0,10) seconds 815 ioloop_add_wake_event(state_machine->timer, state_machine, nat64_thread_prefix_monitor_wakeup, nat64_thread_prefix_monitor_context_release, srp_random16() % (NAT64_THREAD_PREFIX_SETTLING_TIME * IOLOOP_SECOND)); 816 } else { 817 INFO("thread prefix monitor timer already started"); 818 } 819 // Switch to next state. 820 return nat64_thread_prefix_monitor_state_wait_for_settling; 821 } 822 823 static nat64_thread_prefix_monitor_state_type_t 824 nat64_thread_prefix_monitor_wait_for_settling_action(nat64_thread_prefix_monitor_t *state_machine, nat64_thread_prefix_monitor_event_t * event) 825 { 826 NAT64_STATE_ANNOUNCE(state_machine, event); 827 if (event == NULL) { 828 return nat64_thread_prefix_monitor_state_invalid; 829 } else if (event->event_type == nat64_event_thread_prefix_init_wait_ended){ 830 // Switch to next state. 831 return nat64_thread_prefix_monitor_state_wait_for_change; 832 } else { 833 NAT64_UNEXPECTED_EVENT(state_machine, event); 834 return nat64_thread_prefix_monitor_state_invalid; 835 } 836 } 837 838 static nat64_preference 839 route_pref_to_nat64_pref(offmesh_route_preference_t route_pref) 840 { 841 if (route_pref == offmesh_route_preference_low) { 842 return nat64_preference_low; 843 } else if (route_pref == offmesh_route_preference_high) { 844 return nat64_preference_high; 845 } else if (route_pref == offmesh_route_preference_medium) { 846 return nat64_preference_medium; 847 } else { 848 ERROR("Unknown route prefix preference %d", route_pref); 849 return nat64_preference_reserved; 850 } 851 } 852 853 static char * 854 get_nat64_prefix_pref_name(nat64_preference pref) 855 { 856 if (pref == nat64_preference_low) { 857 return "low"; 858 } else if (pref == nat64_preference_high) { 859 return "high"; 860 } else if (pref == nat64_preference_medium) { 861 return "medium"; 862 } else { 863 ERROR("Unknown nat64 prefix preference %d", pref); 864 return "unknown"; 865 } 866 } 867 868 static nat64_thread_prefix_monitor_state_type_t 869 nat64_thread_prefix_monitor_wait_for_change_action(nat64_thread_prefix_monitor_t *state_machine, nat64_thread_prefix_monitor_event_t * event) 870 { 871 NAT64_STATE_ANNOUNCE(state_machine, event); 872 if (event == NULL) { 873 return nat64_thread_prefix_monitor_state_invalid; 874 } else if (event->event_type == nat64_event_thread_prefix_update){ 875 size_t i; 876 nat64_prefix_t **ppref = &state_machine->thread_nat64_prefixes, *prefix = NULL; 877 bool changed = false; 878 // Delete any NAT64 prefixes that are not in the list provided by Thread. 879 while (*ppref != NULL) { 880 prefix = *ppref; 881 for (i = 0; i < event->routes->num; i++) { 882 cti_route_t *route = event->routes->routes[i]; 883 if (route->nat64 && route->origin == offmesh_route_origin_ncp){ 884 if (!in6prefix_compare(&prefix->prefix, &route->prefix, NAT64_PREFIX_SLASH_96_BYTES)) { 885 break; 886 } 887 } 888 } 889 if (i == event->routes->num) { 890 *ppref = prefix->next; 891 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, nat64_prefix_buf); 892 INFO("prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " with pref " PRI_S_SRP " went away", 893 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, nat64_prefix_buf), 894 get_nat64_prefix_pref_name(prefix->priority)); 895 RELEASE_HERE(prefix, nat64_prefix); 896 changed = true; 897 } else { 898 ppref = &prefix->next; 899 } 900 } 901 // Add any NAT64 prefixes that are not present. 902 for (i = 0; i < event->routes->num; i++) { 903 cti_route_t *route = event->routes->routes[i]; 904 if (route->nat64 && route->origin == offmesh_route_origin_ncp) { 905 for(prefix = state_machine->thread_nat64_prefixes; prefix != NULL; prefix = prefix->next){ 906 if (!in6prefix_compare(&prefix->prefix, &route->prefix, NAT64_PREFIX_SLASH_96_BYTES)) { 907 break; 908 } 909 } 910 if (prefix == NULL) { 911 prefix = nat64_prefix_create(&route->prefix, NAT64_PREFIX_SLASH_96_BYTES, route_pref_to_nat64_pref(route->preference), route->rloc); 912 if (prefix == NULL) { 913 ERROR("no memory for nat64 prefix."); 914 return nat64_thread_prefix_monitor_state_invalid; 915 } else { 916 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, nat64_prefix_buf); 917 INFO("prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " with pref " PRI_S_SRP " showed up", 918 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, nat64_prefix_buf), 919 get_nat64_prefix_pref_name(prefix->priority)); 920 *ppref = prefix; 921 ppref = &prefix->next; 922 changed = true; 923 } 924 } 925 } 926 } 927 if (changed) { 928 // Switch to next state. 929 return nat64_thread_prefix_monitor_state_change_occurred; 930 } 931 } else { 932 NAT64_UNEXPECTED_EVENT(state_machine, event); 933 } 934 return nat64_thread_prefix_monitor_state_invalid; 935 } 936 937 static nat64_thread_prefix_monitor_state_type_t 938 nat64_thread_prefix_monitor_change_occurred_action(nat64_thread_prefix_monitor_t *state_machine, nat64_thread_prefix_monitor_event_t * event) 939 { 940 nat64_infra_prefix_publisher_event_t out_event_to_nat64_infra_prefix_publisher; 941 nat64_br_prefix_publisher_event_t out_event_to_nat64_br_prefix_publisher; 942 943 NAT64_STATE_ANNOUNCE(state_machine, event); 944 nat64_infra_prefix_publisher_event_init(&out_event_to_nat64_infra_prefix_publisher, nat64_event_nat64_infra_prefix_publisher_thread_prefix_changed); 945 out_event_to_nat64_infra_prefix_publisher.prefix = state_machine->thread_nat64_prefixes; 946 NAT64_EVENT_ANNOUNCE(state_machine, out_event_to_nat64_infra_prefix_publisher); 947 // Deliver this event to infra prefix publisher. 948 nat64_infra_prefix_publisher_event_deliver(state_machine->nat64->nat64_infra_prefix_publisher, &out_event_to_nat64_infra_prefix_publisher); 949 950 nat64_br_prefix_publisher_event_init(&out_event_to_nat64_br_prefix_publisher, nat64_event_nat64_br_prefix_publisher_thread_prefix_changed); 951 out_event_to_nat64_br_prefix_publisher.prefix = state_machine->thread_nat64_prefixes; 952 NAT64_EVENT_ANNOUNCE(state_machine, out_event_to_nat64_br_prefix_publisher); 953 // Deliver this event to BR prefix publisher. 954 nat64_br_prefix_publisher_event_deliver(state_machine->nat64->nat64_br_prefix_publisher, &out_event_to_nat64_br_prefix_publisher); 955 956 return nat64_thread_prefix_monitor_state_wait_for_change; 957 } 958 959 #define THREAD_STATE_NAME_DECL(name) nat64_thread_prefix_monitor_state_##name, #name 960 static nat64_thread_prefix_monitor_state_t 961 nat64_thread_prefix_monitor_states[] = { 962 { THREAD_STATE_NAME_DECL(invalid), NULL }, 963 { THREAD_STATE_NAME_DECL(init), nat64_thread_prefix_monitor_init_action }, 964 { THREAD_STATE_NAME_DECL(wait_for_settling), nat64_thread_prefix_monitor_wait_for_settling_action }, 965 { THREAD_STATE_NAME_DECL(wait_for_change), nat64_thread_prefix_monitor_wait_for_change_action }, 966 { THREAD_STATE_NAME_DECL(change_occurred), nat64_thread_prefix_monitor_change_occurred_action }, 967 }; 968 #define THREAD_PREFIX_MONITOR_NUM_STATES (sizeof(nat64_thread_prefix_monitor_states) / sizeof(nat64_thread_prefix_monitor_state_t)) 969 970 DECLARE_NAT64_STATE_GET(nat64_thread_prefix_monitor, THREAD_PREFIX_MONITOR); 971 DECLARE_NAT64_NEXT_STATE(nat64_thread_prefix_monitor); 972 973 // Thread prefix monitor event functions 974 typedef struct { 975 nat64_thread_prefix_monitor_event_type_t event_type; 976 char *name; 977 } nat64_thread_prefix_monitor_event_configuration_t; 978 979 nat64_thread_prefix_monitor_event_configuration_t nat64_thread_prefix_monitor_event_configurations[] = { 980 NAT64_EVENT_NAME_DECL(thread_prefix_invalid), 981 NAT64_EVENT_NAME_DECL(thread_prefix_init_wait_ended), 982 NAT64_EVENT_NAME_DECL(thread_prefix_update), 983 }; 984 #define THREAD_PREFIX_MONITOR_NUM_EVENT_TYPES (sizeof(nat64_thread_prefix_monitor_event_configurations) / sizeof(nat64_thread_prefix_monitor_event_configuration_t)) 985 986 DECLARE_NAT64_EVENT_CONFIGURATION_GET(nat64_thread_prefix_monitor_event, THREAD_PREFIX_MONITOR); 987 DECLARE_NAT64_EVENT_INIT(nat64_thread_prefix_monitor_event); 988 DECLARE_NAT64_EVENT_DELIVER(nat64_thread_prefix_monitor); 989 990 // Thread nat64 prefix monitor state machine end 991 992 993 // Infrastructure nat64 prefix publisher state machine start 994 typedef nat64_infra_prefix_publisher_state_type_t (*nat64_infra_prefix_publisher_action_t)(nat64_infra_prefix_publisher_t *NONNULL sm, nat64_infra_prefix_publisher_event_t *NULLABLE event); 995 996 typedef struct { 997 nat64_infra_prefix_publisher_state_type_t state; 998 char *name; 999 nat64_infra_prefix_publisher_action_t action; 1000 } nat64_infra_prefix_publisher_state_t; 1001 1002 static nat64_infra_prefix_publisher_state_type_t 1003 nat64_infra_prefix_publisher_init_action(nat64_infra_prefix_publisher_t *state_machine, nat64_infra_prefix_publisher_event_t * event) 1004 { 1005 NAT64_STATE_ANNOUNCE(state_machine, event); 1006 // Init action 1007 1008 // Switch to next state. 1009 return nat64_infra_prefix_publisher_state_wait; 1010 } 1011 1012 static int 1013 nat64_num_infra_prefix(const nat64_prefix_t *prefix) 1014 { 1015 int num_infra_prefix = 0; 1016 1017 for (; prefix != NULL; prefix = prefix->next) { 1018 if (nat64_preference_has_higher_priority(prefix->priority, nat64_preference_low)) { 1019 num_infra_prefix++; 1020 } 1021 } 1022 INFO("%d infra nat64 prefixes", num_infra_prefix); 1023 return num_infra_prefix; 1024 } 1025 1026 static nat64_infra_prefix_publisher_state_type_t 1027 nat64_infra_prefix_publisher_wait_action(nat64_infra_prefix_publisher_t *state_machine, nat64_infra_prefix_publisher_event_t *event) 1028 { 1029 NAT64_STATE_ANNOUNCE(state_machine, event); 1030 if (event == NULL) { 1031 return nat64_infra_prefix_publisher_state_invalid; 1032 } else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_thread_prefix_changed) { 1033 if (nat64_num_infra_prefix(event->prefix) >= NAT64_INFRA_PREFIX_LIMIT) { 1034 INFO("more than %d infra nat64 prefix present on thread network, ignore", NAT64_INFRA_PREFIX_LIMIT); 1035 return nat64_infra_prefix_publisher_state_ignore; 1036 } else { 1037 return nat64_infra_prefix_publisher_state_check; 1038 } 1039 } else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_infra_prefix_changed) { 1040 // Check to see if it's appropriate to publish infra nat64 prefix 1041 if (event->prefix) { 1042 return nat64_infra_prefix_publisher_state_check; 1043 } 1044 } else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_showed_up) { 1045 // Routable OMR prefix showed up, check to see if we should publish infra nat64 prefix 1046 return nat64_infra_prefix_publisher_state_check; 1047 } else { 1048 NAT64_UNEXPECTED_EVENT(state_machine, event); 1049 } 1050 return nat64_infra_prefix_publisher_state_invalid; 1051 } 1052 1053 static nat64_infra_prefix_publisher_state_type_t 1054 nat64_infra_prefix_publisher_ignore_action(nat64_infra_prefix_publisher_t *state_machine, nat64_infra_prefix_publisher_event_t *event) 1055 { 1056 NAT64_STATE_ANNOUNCE(state_machine, event); 1057 if (event == NULL) { 1058 return nat64_infra_prefix_publisher_state_invalid; 1059 } else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_thread_prefix_changed) { 1060 if (nat64_num_infra_prefix(event->prefix) >= NAT64_INFRA_PREFIX_LIMIT) { 1061 INFO("more than %d infra nat64 prefixes present, ignore", NAT64_INFRA_PREFIX_LIMIT); 1062 return nat64_infra_prefix_publisher_state_invalid; 1063 } else { 1064 return nat64_infra_prefix_publisher_state_check; 1065 } 1066 } else { 1067 NAT64_UNEXPECTED_EVENT(state_machine, event); 1068 } 1069 return nat64_infra_prefix_publisher_state_invalid; 1070 } 1071 1072 static nat64_infra_prefix_publisher_state_type_t 1073 nat64_infra_prefix_publisher_check_action(nat64_infra_prefix_publisher_t *state_machine, nat64_infra_prefix_publisher_event_t *event) 1074 { 1075 NAT64_STATE_ANNOUNCE(state_machine, event); 1076 // Go to publish state when all of the following conditions are met: 1077 // 1. We have infra prefix 1078 // 2. We have routable OMR prefix 1079 // 3. The number of infra prefixes on thread network is less than NAT64_INFRA_PREFIX_LIMIT 1080 nat64_prefix_t *infra_prefix = state_machine->nat64->infra_monitor->infra_nat64_prefixes; 1081 if (infra_prefix && nat64_thread_has_routable_prefix(state_machine->nat64->route_state) 1082 && nat64_num_infra_prefix(state_machine->nat64->thread_monitor->thread_nat64_prefixes) < NAT64_INFRA_PREFIX_LIMIT) { 1083 state_machine->proposed_prefix = nat64_prefix_dup(infra_prefix); 1084 if (state_machine->proposed_prefix == NULL) { 1085 return nat64_infra_prefix_publisher_state_wait; 1086 } 1087 return nat64_infra_prefix_publisher_state_publish; 1088 } else { 1089 return nat64_infra_prefix_publisher_state_wait; 1090 } 1091 } 1092 1093 static nat64_infra_prefix_publisher_state_type_t 1094 nat64_infra_prefix_publisher_publish_action(nat64_infra_prefix_publisher_t *state_machine, nat64_infra_prefix_publisher_event_t *event) 1095 { 1096 NAT64_STATE_ANNOUNCE(state_machine, event); 1097 SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf); 1098 INFO("publishing infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 1099 SEGMENTED_IPv6_ADDR_PARAM_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf)); 1100 nat64_add_prefix_to_update_queue(state_machine->nat64, state_machine->proposed_prefix, 1101 nat64_prefix_action_add); 1102 return nat64_infra_prefix_publisher_state_publishing; 1103 } 1104 1105 static void 1106 nat64_remove_prefix_from_thread_monitor(nat64_t *nat64, nat64_prefix_t *deprecated_prefix) 1107 { 1108 nat64_prefix_t **ppref = &nat64->thread_monitor->thread_nat64_prefixes, *prefix = NULL; 1109 while (*ppref != NULL) { 1110 prefix = *ppref; 1111 if (!in6prefix_compare(&prefix->prefix, &deprecated_prefix->prefix, NAT64_PREFIX_SLASH_96_BYTES) 1112 && prefix->rloc == deprecated_prefix->rloc) 1113 { 1114 *ppref = prefix->next; 1115 SEGMENTED_IPv6_ADDR_GEN_SRP(prefix->prefix.s6_addr, nat64_prefix_buf); 1116 INFO("prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " with pref " PRI_S_SRP " went away", 1117 SEGMENTED_IPv6_ADDR_PARAM_SRP(prefix->prefix.s6_addr, nat64_prefix_buf), 1118 get_nat64_prefix_pref_name(prefix->priority)); 1119 RELEASE_HERE(prefix, nat64_prefix); 1120 } else { 1121 ppref = &prefix->next; 1122 } 1123 } 1124 } 1125 1126 static nat64_infra_prefix_publisher_state_type_t 1127 nat64_infra_prefix_publisher_publishing_action(nat64_infra_prefix_publisher_t *state_machine, nat64_infra_prefix_publisher_event_t *event) 1128 { 1129 NAT64_STATE_ANNOUNCE(state_machine, event); 1130 if (event == NULL) { 1131 return nat64_infra_prefix_publisher_state_invalid; 1132 } else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_infra_prefix_changed || 1133 event->event_type == nat64_event_nat64_infra_prefix_publisher_shutdown) 1134 { 1135 nat64_prefix_t *infra_prefix; 1136 for (infra_prefix = event->prefix; infra_prefix; infra_prefix = infra_prefix->next) { 1137 if (!in6prefix_compare(&infra_prefix->prefix, &state_machine->proposed_prefix->prefix, NAT64_PREFIX_SLASH_96_BYTES)) { 1138 // The proposed prefix is still there, do nothing 1139 return nat64_infra_prefix_publisher_state_invalid; 1140 } 1141 } 1142 // The proposed infra prefix is gone 1143 SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf); 1144 INFO("The proposed infra prefix is gone, unpublishing infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 1145 SEGMENTED_IPv6_ADDR_PARAM_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf)); 1146 nat64_add_prefix_to_update_queue(state_machine->nat64, state_machine->proposed_prefix, nat64_prefix_action_remove); 1147 // Remove it from thread_monitor prefix database 1148 nat64_remove_prefix_from_thread_monitor(state_machine->nat64, state_machine->proposed_prefix); 1149 RELEASE_HERE(state_machine->proposed_prefix, nat64_prefix); 1150 state_machine->proposed_prefix = NULL; 1151 // Is there a different infra NAT64 prefix? 1152 if (event->prefix) { 1153 state_machine->proposed_prefix = nat64_prefix_dup(event->prefix); 1154 if (state_machine->proposed_prefix == NULL) { 1155 return nat64_infra_prefix_publisher_state_check; 1156 } 1157 return nat64_infra_prefix_publisher_state_publish; 1158 } else { 1159 INFO("no longer publishing infra prefix."); 1160 return nat64_infra_prefix_publisher_state_wait; 1161 } 1162 } else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_went_away || 1163 event->event_type == nat64_event_nat64_infra_prefix_publisher_shutdown) 1164 { 1165 // Routable OMR prefix is gone 1166 SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf); 1167 INFO("Routable OMR prefix is gone, unpublishing infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 1168 SEGMENTED_IPv6_ADDR_PARAM_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf)); 1169 nat64_add_prefix_to_update_queue(state_machine->nat64, state_machine->proposed_prefix, nat64_prefix_action_remove); 1170 // Remove it from thread_monitor prefix database 1171 nat64_remove_prefix_from_thread_monitor(state_machine->nat64, state_machine->proposed_prefix); 1172 RELEASE_HERE(state_machine->proposed_prefix, nat64_prefix); 1173 state_machine->proposed_prefix = NULL; 1174 INFO("no longer publishing infra prefix."); 1175 return nat64_infra_prefix_publisher_state_wait; 1176 } else if (event->event_type == nat64_event_nat64_infra_prefix_publisher_thread_prefix_changed) { 1177 nat64_prefix_t *thread_prefix; 1178 int num_infra_prefix = 0; 1179 for (thread_prefix = event->prefix; thread_prefix; thread_prefix = thread_prefix->next) { 1180 if (nat64_preference_has_higher_priority(thread_prefix->priority, nat64_preference_low)) { 1181 num_infra_prefix++; 1182 } 1183 } 1184 INFO("%d infra nat64 prefixes present on thread network", num_infra_prefix); 1185 // If more than 3 infra prefixes show on thread network, BR with highest rloc should withdraw 1186 if (num_infra_prefix > NAT64_INFRA_PREFIX_LIMIT) { 1187 int max_rloc = event->prefix->rloc; 1188 for (thread_prefix = event->prefix; thread_prefix; thread_prefix = thread_prefix->next) { 1189 if (thread_prefix->rloc > max_rloc) { 1190 max_rloc = thread_prefix->rloc; 1191 } 1192 } 1193 INFO("%d infra nat64 prefixes present on thread network with max_rloc[%d]", num_infra_prefix, max_rloc); 1194 if (max_rloc == state_machine->nat64->route_state->srp_server->rloc16) { 1195 SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf); 1196 INFO("BR has highest rloc, unpublishing infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 1197 SEGMENTED_IPv6_ADDR_PARAM_SRP(state_machine->proposed_prefix->prefix.s6_addr, nat64_prefix_buf)); 1198 nat64_add_prefix_to_update_queue(state_machine->nat64, state_machine->proposed_prefix, nat64_prefix_action_remove); 1199 // Remove it from thread_monitor prefix database 1200 nat64_remove_prefix_from_thread_monitor(state_machine->nat64, state_machine->proposed_prefix); 1201 RELEASE_HERE(state_machine->proposed_prefix, nat64_prefix); 1202 state_machine->proposed_prefix = NULL; 1203 INFO("no longer publishing infra prefix."); 1204 return nat64_infra_prefix_publisher_state_wait; 1205 } 1206 } 1207 } else { 1208 NAT64_UNEXPECTED_EVENT(state_machine, event); 1209 } 1210 return nat64_infra_prefix_publisher_state_invalid; 1211 } 1212 1213 #define INFRA_PUBLISHER_STATE_NAME_DECL(name) nat64_infra_prefix_publisher_state_##name, #name 1214 static nat64_infra_prefix_publisher_state_t 1215 nat64_infra_prefix_publisher_states[] = { 1216 { INFRA_PUBLISHER_STATE_NAME_DECL(invalid), NULL }, 1217 { INFRA_PUBLISHER_STATE_NAME_DECL(init), nat64_infra_prefix_publisher_init_action }, 1218 { INFRA_PUBLISHER_STATE_NAME_DECL(wait), nat64_infra_prefix_publisher_wait_action }, 1219 { INFRA_PUBLISHER_STATE_NAME_DECL(ignore), nat64_infra_prefix_publisher_ignore_action }, 1220 { INFRA_PUBLISHER_STATE_NAME_DECL(check), nat64_infra_prefix_publisher_check_action }, 1221 { INFRA_PUBLISHER_STATE_NAME_DECL(publish), nat64_infra_prefix_publisher_publish_action }, 1222 { INFRA_PUBLISHER_STATE_NAME_DECL(publishing), nat64_infra_prefix_publisher_publishing_action }, 1223 }; 1224 #define INFRA_PREFIX_PUBLISHER_NUM_STATES (sizeof(nat64_infra_prefix_publisher_states) / sizeof(nat64_infra_prefix_publisher_state_t)) 1225 1226 DECLARE_NAT64_STATE_GET(nat64_infra_prefix_publisher, INFRA_PREFIX_PUBLISHER); 1227 DECLARE_NAT64_NEXT_STATE(nat64_infra_prefix_publisher); 1228 1229 // Infra prefix publisher event functions 1230 typedef struct { 1231 nat64_infra_prefix_publisher_event_type_t event_type; 1232 char *name; 1233 } nat64_infra_prefix_publisher_event_configuration_t; 1234 1235 nat64_infra_prefix_publisher_event_configuration_t nat64_infra_prefix_publisher_event_configurations[] = { 1236 NAT64_EVENT_NAME_DECL(nat64_infra_prefix_publisher_invalid), 1237 NAT64_EVENT_NAME_DECL(nat64_infra_prefix_publisher_thread_prefix_changed), 1238 NAT64_EVENT_NAME_DECL(nat64_infra_prefix_publisher_infra_prefix_changed), 1239 NAT64_EVENT_NAME_DECL(nat64_infra_prefix_publisher_routable_omr_prefix_went_away), 1240 NAT64_EVENT_NAME_DECL(nat64_infra_prefix_publisher_routable_omr_prefix_showed_up), 1241 NAT64_EVENT_NAME_DECL(nat64_infra_prefix_publisher_shutdown), 1242 }; 1243 #define INFRA_PREFIX_PUBLISHER_NUM_EVENT_TYPES (sizeof(nat64_infra_prefix_publisher_event_configurations) / sizeof(nat64_infra_prefix_publisher_event_configuration_t)) 1244 1245 DECLARE_NAT64_EVENT_CONFIGURATION_GET(nat64_infra_prefix_publisher_event, INFRA_PREFIX_PUBLISHER); 1246 DECLARE_NAT64_EVENT_INIT(nat64_infra_prefix_publisher_event); 1247 DECLARE_NAT64_EVENT_DELIVER(nat64_infra_prefix_publisher); 1248 1249 void 1250 nat64_omr_route_update(nat64_t *NONNULL nat64, bool has_routable_omr_prefix) 1251 { 1252 if (!has_routable_omr_prefix && nat64->nat64_infra_prefix_publisher->routable_omr_prefix_present){ 1253 nat64_infra_prefix_publisher_event_t event; 1254 1255 nat64->nat64_infra_prefix_publisher->routable_omr_prefix_present = false; 1256 nat64_infra_prefix_publisher_event_init(&event, nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_went_away); 1257 NAT64_EVENT_ANNOUNCE(nat64->nat64_infra_prefix_publisher, event); 1258 nat64_infra_prefix_publisher_event_deliver(nat64->nat64_infra_prefix_publisher, &event); 1259 } else if (has_routable_omr_prefix && !nat64->nat64_infra_prefix_publisher->routable_omr_prefix_present){ 1260 nat64_infra_prefix_publisher_event_t event; 1261 1262 nat64->nat64_infra_prefix_publisher->routable_omr_prefix_present = true; 1263 nat64_infra_prefix_publisher_event_init(&event, nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_showed_up); 1264 NAT64_EVENT_ANNOUNCE(nat64->nat64_infra_prefix_publisher, event); 1265 nat64_infra_prefix_publisher_event_deliver(nat64->nat64_infra_prefix_publisher, &event); 1266 } 1267 } 1268 // Infrastructure nat64 prefix publisher state machine end 1269 1270 1271 // BR nat64 prefix publisher state machine start 1272 typedef nat64_br_prefix_publisher_state_type_t (*nat64_br_prefix_publisher_action_t)(nat64_br_prefix_publisher_t *NONNULL sm, nat64_br_prefix_publisher_event_t *NULLABLE event); 1273 1274 typedef struct { 1275 nat64_br_prefix_publisher_state_type_t state; 1276 char *name; 1277 nat64_br_prefix_publisher_action_t action; 1278 } nat64_br_prefix_publisher_state_t; 1279 1280 static nat64_br_prefix_publisher_state_type_t 1281 nat64_br_prefix_publisher_init_action(nat64_br_prefix_publisher_t *state_machine, nat64_br_prefix_publisher_event_t * event) 1282 { 1283 NAT64_STATE_ANNOUNCE(state_machine, event); 1284 // Setup BR nat64 prefix 1285 state_machine->br_prefix = nat64_prefix_create(&state_machine->nat64->route_state->srp_server->ula_prefix, NAT64_PREFIX_SLASH_96_BYTES, nat64_preference_low, state_machine->nat64->route_state->srp_server->rloc16); 1286 if (state_machine->br_prefix == NULL) { 1287 ERROR("no memory when create br prefix"); 1288 return nat64_br_prefix_publisher_state_invalid; 1289 } 1290 // Add 0xFFFF to make it different from OMR prefix 1291 memset(&state_machine->br_prefix->prefix.s6_addr[6], 0xFF, 2); 1292 SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->br_prefix->prefix.s6_addr, nat64_prefix_buf); 1293 INFO("set br prefix to " PRI_SEGMENTED_IPv6_ADDR_SRP, 1294 SEGMENTED_IPv6_ADDR_PARAM_SRP(state_machine->br_prefix->prefix.s6_addr, nat64_prefix_buf)); 1295 // Switch to next state. 1296 return nat64_br_prefix_publisher_state_start_timer; 1297 } 1298 1299 static void 1300 nat64_br_prefix_publisher_context_release(void *context) 1301 { 1302 nat64_br_prefix_publisher_t *state_machine = context; 1303 RELEASE_HERE(state_machine, nat64_br_prefix_publisher); 1304 } 1305 1306 static void 1307 nat64_br_prefix_publisher_wakeup(void *context) 1308 { 1309 nat64_br_prefix_publisher_t *state_machine = context; 1310 nat64_br_prefix_publisher_event_t out_event; 1311 1312 state_machine->wait_finished = true; 1313 nat64_br_prefix_publisher_event_init(&out_event, nat64_event_nat64_br_prefix_publisher_okay_to_publish); 1314 NAT64_EVENT_ANNOUNCE(state_machine, out_event); 1315 nat64_br_prefix_publisher_event_deliver(state_machine, &out_event); 1316 } 1317 1318 static nat64_br_prefix_publisher_state_type_t 1319 nat64_br_prefix_publisher_start_timer_action(nat64_br_prefix_publisher_t *state_machine, nat64_br_prefix_publisher_event_t * event) 1320 { 1321 NAT64_STATE_ANNOUNCE(state_machine, event); 1322 if (state_machine->timer == NULL) { 1323 state_machine->timer = ioloop_wakeup_create(); 1324 if (state_machine->timer == NULL) { 1325 ERROR("no memory when create timer"); 1326 return nat64_br_prefix_publisher_state_invalid; 1327 } 1328 RETAIN_HERE(state_machine, nat64_br_prefix_publisher); 1329 // wait rand(10,30) seconds, will start after thread monitor is settled 1330 ioloop_add_wake_event(state_machine->timer, state_machine, nat64_br_prefix_publisher_wakeup, nat64_br_prefix_publisher_context_release, 1331 NAT64_THREAD_PREFIX_SETTLING_TIME * IOLOOP_SECOND + srp_random16() % (NAT64_BR_PREFIX_PUBLISHER_WAIT_TIME * IOLOOP_SECOND)); 1332 state_machine->wait_finished = false; 1333 } else { 1334 INFO("thread prefix monitor timer already started"); 1335 } 1336 // Switch to next state. 1337 return nat64_br_prefix_publisher_state_wait_for_anything; 1338 } 1339 1340 static nat64_br_prefix_publisher_state_type_t 1341 nat64_br_prefix_publisher_wait_for_anything_action(nat64_br_prefix_publisher_t *state_machine, nat64_br_prefix_publisher_event_t *event) 1342 { 1343 NAT64_STATE_ANNOUNCE(state_machine, event); 1344 if (event == NULL) { 1345 return nat64_br_prefix_publisher_state_invalid; 1346 } else if (event->event_type == nat64_event_nat64_br_prefix_publisher_ipv4_default_route_showed_up) { 1347 if (state_machine->nat64->thread_monitor->thread_nat64_prefixes == NULL 1348 && state_machine->nat64->nat64_infra_prefix_publisher->proposed_prefix == NULL 1349 && state_machine->wait_finished) { 1350 return nat64_br_prefix_publisher_state_publish; 1351 } 1352 } else if (event->event_type == nat64_event_nat64_br_prefix_publisher_thread_prefix_changed) { 1353 if (event->prefix == NULL 1354 && state_machine->nat64->nat64_infra_prefix_publisher->proposed_prefix == NULL 1355 && state_machine->wait_finished 1356 && state_machine->nat64->ipv4_monitor->has_ipv4_default_route) { 1357 return nat64_br_prefix_publisher_state_publish; 1358 } 1359 } else if (event->event_type == nat64_event_nat64_br_prefix_publisher_okay_to_publish) { 1360 if (state_machine->nat64->thread_monitor->thread_nat64_prefixes == NULL 1361 && state_machine->nat64->nat64_infra_prefix_publisher->proposed_prefix == NULL 1362 && state_machine->nat64->ipv4_monitor->has_ipv4_default_route) { 1363 return nat64_br_prefix_publisher_state_publish; 1364 } 1365 } else if (event->event_type == nat64_event_nat64_br_prefix_publisher_infra_prefix_changed) { 1366 if (event->prefix == NULL 1367 && state_machine->nat64->thread_monitor->thread_nat64_prefixes == NULL 1368 && state_machine->wait_finished 1369 && state_machine->nat64->ipv4_monitor->has_ipv4_default_route) { 1370 return nat64_br_prefix_publisher_state_publish; 1371 } 1372 } else { 1373 NAT64_UNEXPECTED_EVENT(state_machine, event); 1374 } 1375 return nat64_br_prefix_publisher_state_invalid; 1376 } 1377 1378 static nat64_br_prefix_publisher_state_type_t 1379 nat64_br_prefix_publisher_publish_action(nat64_br_prefix_publisher_t *state_machine, nat64_br_prefix_publisher_event_t *event) 1380 { 1381 NAT64_STATE_ANNOUNCE(state_machine, event); 1382 // Enable NAT64 translation 1383 INFO("starting NAT64 translation on BR"); 1384 nat64_start_translation(dispatch_get_main_queue()); 1385 SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->br_prefix->prefix.s6_addr, nat64_prefix_buf); 1386 INFO("publishing br prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 1387 SEGMENTED_IPv6_ADDR_PARAM_SRP(state_machine->br_prefix->prefix.s6_addr, nat64_prefix_buf)); 1388 nat64_add_prefix_to_update_queue(state_machine->nat64, state_machine->br_prefix, 1389 nat64_prefix_action_add); 1390 return nat64_br_prefix_publisher_state_publishing; 1391 } 1392 1393 static void 1394 nat64_unpublish_br_prefix(nat64_br_prefix_publisher_t *state_machine) 1395 { 1396 SEGMENTED_IPv6_ADDR_GEN_SRP(state_machine->br_prefix->prefix.s6_addr, nat64_prefix_buf); 1397 INFO("unpublishing br prefix " PRI_SEGMENTED_IPv6_ADDR_SRP, 1398 SEGMENTED_IPv6_ADDR_PARAM_SRP(state_machine->br_prefix->prefix.s6_addr, nat64_prefix_buf)); 1399 nat64_add_prefix_to_update_queue(state_machine->nat64, state_machine->br_prefix, 1400 nat64_prefix_action_remove); 1401 // Remove it from thread_monitor prefix database 1402 nat64_remove_prefix_from_thread_monitor(state_machine->nat64, state_machine->br_prefix); 1403 INFO("stopping NAT64 translation on BR"); 1404 nat64_stop_translation(); 1405 } 1406 1407 static nat64_br_prefix_publisher_state_type_t 1408 nat64_br_prefix_publisher_publishing_action(nat64_br_prefix_publisher_t *state_machine, nat64_br_prefix_publisher_event_t *event) 1409 { 1410 NAT64_STATE_ANNOUNCE(state_machine, event); 1411 if (event == NULL) { 1412 return nat64_br_prefix_publisher_state_invalid; 1413 } else if (event->event_type == nat64_event_nat64_br_prefix_publisher_thread_prefix_changed) { 1414 nat64_prefix_t *thread_prefix; 1415 for (thread_prefix = event->prefix; thread_prefix; thread_prefix = thread_prefix->next) { 1416 if (nat64_preference_has_higher_priority(thread_prefix->priority, nat64_preference_low)) { 1417 // The thread prefix has higher preference 1418 nat64_unpublish_br_prefix(state_machine); 1419 return nat64_br_prefix_publisher_state_wait_for_anything; 1420 } else if (thread_prefix->priority == nat64_preference_low) { 1421 if (in6addr_compare(&state_machine->br_prefix->prefix, &thread_prefix->prefix) > 0) { 1422 nat64_unpublish_br_prefix(state_machine); 1423 return nat64_br_prefix_publisher_state_wait_for_anything; 1424 } 1425 } 1426 } 1427 } else if (event->event_type == nat64_event_nat64_br_prefix_publisher_ipv4_default_route_went_away || 1428 event->event_type == nat64_event_nat64_br_prefix_publisher_shutdown) 1429 { 1430 nat64_unpublish_br_prefix(state_machine); 1431 return nat64_br_prefix_publisher_state_wait_for_anything; 1432 } else if (event->event_type == nat64_event_nat64_br_prefix_publisher_infra_prefix_changed) { 1433 // Only unpublish br prefix if there is infra prefix and routable OMR prefix 1434 if (event->prefix && nat64_thread_has_routable_prefix(state_machine->nat64->route_state)) { 1435 nat64_unpublish_br_prefix(state_machine); 1436 return nat64_br_prefix_publisher_state_wait_for_anything; 1437 } 1438 } else { 1439 NAT64_UNEXPECTED_EVENT(state_machine, event); 1440 } 1441 return nat64_br_prefix_publisher_state_invalid; 1442 } 1443 1444 #define BR_PUBLISHER_STATE_NAME_DECL(name) nat64_br_prefix_publisher_state_##name, #name 1445 static nat64_br_prefix_publisher_state_t 1446 nat64_br_prefix_publisher_states[] = { 1447 { BR_PUBLISHER_STATE_NAME_DECL(invalid), NULL }, 1448 { BR_PUBLISHER_STATE_NAME_DECL(init), nat64_br_prefix_publisher_init_action }, 1449 { BR_PUBLISHER_STATE_NAME_DECL(start_timer), nat64_br_prefix_publisher_start_timer_action }, 1450 { BR_PUBLISHER_STATE_NAME_DECL(wait_for_anything), nat64_br_prefix_publisher_wait_for_anything_action }, 1451 { BR_PUBLISHER_STATE_NAME_DECL(publish), nat64_br_prefix_publisher_publish_action }, 1452 { BR_PUBLISHER_STATE_NAME_DECL(publishing), nat64_br_prefix_publisher_publishing_action }, 1453 }; 1454 #define BR_PREFIX_PUBLISHER_NUM_STATES (sizeof(nat64_br_prefix_publisher_states) / sizeof(nat64_br_prefix_publisher_state_t)) 1455 1456 DECLARE_NAT64_STATE_GET(nat64_br_prefix_publisher, BR_PREFIX_PUBLISHER); 1457 DECLARE_NAT64_NEXT_STATE(nat64_br_prefix_publisher); 1458 1459 // BR prefix publisher event functions 1460 typedef struct { 1461 nat64_br_prefix_publisher_event_type_t event_type; 1462 char *name; 1463 } nat64_br_prefix_publisher_event_configuration_t; 1464 1465 nat64_br_prefix_publisher_event_configuration_t nat64_br_prefix_publisher_event_configurations[] = { 1466 NAT64_EVENT_NAME_DECL(nat64_br_prefix_publisher_invalid), 1467 NAT64_EVENT_NAME_DECL(nat64_br_prefix_publisher_okay_to_publish), 1468 NAT64_EVENT_NAME_DECL(nat64_br_prefix_publisher_ipv4_default_route_showed_up), 1469 NAT64_EVENT_NAME_DECL(nat64_br_prefix_publisher_ipv4_default_route_went_away), 1470 NAT64_EVENT_NAME_DECL(nat64_br_prefix_publisher_thread_prefix_changed), 1471 NAT64_EVENT_NAME_DECL(nat64_br_prefix_publisher_infra_prefix_changed), 1472 NAT64_EVENT_NAME_DECL(nat64_br_prefix_publisher_shutdown), 1473 }; 1474 #define BR_PREFIX_PUBLISHER_NUM_EVENT_TYPES (sizeof(nat64_br_prefix_publisher_event_configurations) / sizeof(nat64_br_prefix_publisher_event_configuration_t)) 1475 1476 DECLARE_NAT64_EVENT_CONFIGURATION_GET(nat64_br_prefix_publisher_event, BR_PREFIX_PUBLISHER); 1477 DECLARE_NAT64_EVENT_INIT(nat64_br_prefix_publisher_event); 1478 DECLARE_NAT64_EVENT_DELIVER(nat64_br_prefix_publisher); 1479 1480 // BR nat64 prefix publisher state machine end 1481 1482 void 1483 nat64_init(route_state_t *NONNULL route_state) 1484 { 1485 INFO("nat64_init"); 1486 // Start state machines 1487 nat64_ipv4_default_route_monitor_next_state(route_state->nat64->ipv4_monitor, nat64_ipv4_default_route_monitor_state_init); 1488 nat64_infra_prefix_monitor_next_state(route_state->nat64->infra_monitor, nat64_infra_prefix_monitor_state_init); 1489 nat64_thread_prefix_monitor_next_state(route_state->nat64->thread_monitor, nat64_thread_prefix_monitor_state_init); 1490 nat64_infra_prefix_publisher_next_state(route_state->nat64->nat64_infra_prefix_publisher, nat64_infra_prefix_publisher_state_init); 1491 nat64_br_prefix_publisher_next_state(route_state->nat64->nat64_br_prefix_publisher, nat64_br_prefix_publisher_state_init); 1492 } 1493 1494 void 1495 nat64_stop(route_state_t *NONNULL route_state) 1496 { 1497 if (route_state->nat64) { 1498 INFO("stopping nat64."); 1499 nat64_cancel(route_state->nat64); 1500 RELEASE_HERE(route_state->nat64, nat64); 1501 route_state->nat64 = NULL; 1502 } 1503 } 1504 1505 void 1506 nat64_start(route_state_t *NONNULL route_state) 1507 { 1508 route_state->nat64 = nat64_create(route_state); 1509 if (route_state->nat64 == NULL) { 1510 ERROR("nat64 create failed"); 1511 return; 1512 } 1513 nat64_init(route_state); 1514 } 1515 1516 static void 1517 nat64_add_route_callback(void *context, cti_status_t status) 1518 { 1519 (void)context; 1520 INFO("%d", status); 1521 } 1522 1523 void 1524 nat64_add_prefix(route_state_t *route_state, const uint8_t *const data, offmesh_route_preference_t route_pref) 1525 { 1526 SEGMENTED_IPv6_ADDR_GEN_SRP(data, nat64_prefix_buf); 1527 INFO("nat64_add_prefix(" PRI_SEGMENTED_IPv6_ADDR_SRP ")", 1528 SEGMENTED_IPv6_ADDR_PARAM_SRP(data, nat64_prefix_buf)); 1529 int status = cti_add_route(route_state->srp_server, route_state, nat64_add_route_callback, NULL, 1530 (struct in6_addr *)data, NAT64_PREFIX_SLASH_96_BYTES * 8, 1531 route_pref, 0, true, true); 1532 if (status != kCTIStatus_NoError) { 1533 ERROR("Unable to add nat64 prefix."); 1534 } 1535 } 1536 1537 static void 1538 nat64_remove_route_callback(void *context, cti_status_t status) 1539 { 1540 (void)context; 1541 INFO("%d", status); 1542 } 1543 1544 void 1545 nat64_remove_prefix(route_state_t *route_state, const uint8_t *const data) 1546 { 1547 SEGMENTED_IPv6_ADDR_GEN_SRP(data, nat64_prefix_buf); 1548 INFO("nat64_remove_prefix(" PRI_SEGMENTED_IPv6_ADDR_SRP ")", 1549 SEGMENTED_IPv6_ADDR_PARAM_SRP(data, nat64_prefix_buf)); 1550 int status = cti_remove_route(route_state->srp_server, route_state, nat64_remove_route_callback, NULL, 1551 (struct in6_addr *)data, NAT64_PREFIX_SLASH_96_BYTES * 8, 0); 1552 if (status != kCTIStatus_NoError) { 1553 ERROR("Unable to remove nat64 prefix."); 1554 } 1555 } 1556 1557 static offmesh_route_preference_t 1558 nat64_pref_to_route_pref(nat64_preference nat64_pref) 1559 { 1560 if (nat64_pref == nat64_preference_low) { 1561 return offmesh_route_preference_low; 1562 } else if (nat64_pref == nat64_preference_high) { 1563 return offmesh_route_preference_high; 1564 } else if (nat64_pref == nat64_preference_medium) { 1565 return offmesh_route_preference_medium; 1566 } else { 1567 ERROR("Unknown nat64 prefix preference %d", nat64_pref); 1568 return offmesh_route_preference_low; 1569 } 1570 } 1571 1572 static void 1573 nat64_prefix_update_callback(void *context, cti_status_t status) 1574 { 1575 nat64_t *nat64 = context; 1576 nat64_prefix_t *prefix = nat64->update_queue; 1577 INFO("status %d", status); 1578 if (prefix == NULL) { 1579 ERROR("update seems to have disappeared"); 1580 return; 1581 } 1582 SEGMENTED_IPv6_ADDR_GEN_SRP(&prefix->prefix, prefix_buf); 1583 INFO(PRI_SEGMENTED_IPv6_ADDR_SRP " was " PUB_S_SRP, 1584 SEGMENTED_IPv6_ADDR_PARAM_SRP(&prefix->prefix, prefix_buf), 1585 prefix->action == nat64_prefix_action_add ? "added" : "removed"); 1586 // The pending flag was set to true in nat64_prefix_start_next_update(), meaning that 1587 // we sent the request to threadradiod, but it's not finished yet, so the status is pending. 1588 // when this callback function is called, the status is not pending anymore. 1589 if (prefix->pending) { 1590 prefix->pending = false; 1591 nat64->update_queue = prefix->next; 1592 prefix->next = NULL; 1593 RELEASE_HERE(prefix, nat64_prefix); 1594 } 1595 // Start next update 1596 if (nat64->update_queue != NULL) { 1597 nat64_prefix_start_next_update(nat64); 1598 } else { 1599 // The update queue holds a reference to nat64 when there is something on the queue. 1600 // Release here if there is nothing on the queue. 1601 RELEASE_HERE(nat64, nat64); 1602 } 1603 } 1604 1605 static void 1606 nat64_prefix_start_next_update(nat64_t *nat64) 1607 { 1608 cti_status_t status; 1609 nat64_prefix_t *prefix = nat64->update_queue; 1610 if (prefix == NULL) { 1611 ERROR("nat64_prefix_start_next_update called with no update"); 1612 return; 1613 } 1614 route_state_t *route_state = nat64->route_state; 1615 srp_server_t *server_state = route_state->srp_server; 1616 1617 SEGMENTED_IPv6_ADDR_GEN_SRP(&prefix->prefix, prefix_buf); 1618 if (prefix->action == nat64_prefix_action_remove) { 1619 INFO("removing: " PRI_SEGMENTED_IPv6_ADDR_SRP , 1620 SEGMENTED_IPv6_ADDR_PARAM_SRP(&prefix->prefix, prefix_buf)); 1621 status = cti_remove_route(server_state, nat64, nat64_prefix_update_callback, NULL, 1622 &prefix->prefix, NAT64_PREFIX_SLASH_96_BYTES * 8, 0); 1623 } else if (prefix->action == nat64_prefix_action_add){ 1624 INFO("adding: " PRI_SEGMENTED_IPv6_ADDR_SRP , 1625 SEGMENTED_IPv6_ADDR_PARAM_SRP(&prefix->prefix, prefix_buf)); 1626 status = cti_add_route(server_state, nat64, nat64_prefix_update_callback, NULL, 1627 &prefix->prefix, NAT64_PREFIX_SLASH_96_BYTES * 8, 1628 nat64_pref_to_route_pref(prefix->priority), 0, true, true); 1629 } else { 1630 ERROR("updating: " PRI_SEGMENTED_IPv6_ADDR_SRP " with action %d", 1631 SEGMENTED_IPv6_ADDR_PARAM_SRP(&prefix->prefix, prefix_buf), prefix->action); 1632 nat64->update_queue = prefix->next; 1633 prefix->next = NULL; 1634 RELEASE_HERE(prefix, nat64_prefix); 1635 return; 1636 } 1637 if (status != kCTIStatus_NoError) { 1638 ERROR("route update failed: %d", status); 1639 } else { 1640 prefix->pending = true; 1641 } 1642 } 1643 1644 static void 1645 nat64_add_prefix_to_update_queue(nat64_t *nat64, nat64_prefix_t *prefix, nat64_prefix_action action) 1646 { 1647 nat64_prefix_t **ppref, *old_queue = nat64->update_queue; 1648 // Find the prefix on the queue, or find the end of the queue. 1649 for (ppref = &nat64->update_queue; *ppref != NULL && *ppref != prefix; ppref = &(*ppref)->next); 1650 // Not on the queue 1651 if (*ppref == NULL) { 1652 nat64_prefix_t * new_prefix = nat64_prefix_dup(prefix); 1653 if (new_prefix == NULL) { 1654 ERROR("no memory for nat64 prefix."); 1655 return; 1656 } 1657 new_prefix->action = action; 1658 // The pending flag will be set to true in nat64_prefix_start_next_update() 1659 // when we send the request to threadradiod. 1660 new_prefix->pending = false; 1661 *ppref = new_prefix; 1662 // Turns out we added it to the beginning of the queue. 1663 if (nat64->update_queue == new_prefix) { 1664 nat64_prefix_start_next_update(nat64); 1665 } 1666 goto out; 1667 } 1668 // We have started to update the prefix, but haven't gotten the callback yet. Since we have put the prefix 1669 // back on the update queue, and it's at the beginning, mark it not pending so that when we get the callback 1670 // from the update function, we update this route again rather than going on to the next. 1671 if (prefix == nat64->update_queue) { 1672 prefix->pending = false; 1673 } 1674 out: 1675 // As long as there is anything in the queue, the queue needs to hold a reference to nat64, 1676 // so that if it's canceled and released, we finish running the queue before stopping. 1677 if (old_queue == NULL && nat64->update_queue != NULL) { 1678 RETAIN_HERE(nat64, nat64); 1679 } 1680 } 1681 1682 // Check stale prefix on thread network. 1683 // For example, prefix that belongs to current BR, but current BR is not in publishing state, this can happen when srp-mdns-proxy daemon restarted. 1684 // Remove such prefix from thread network. 1685 static void 1686 nat64_check_stale_prefix(route_state_t *route_state, const cti_route_vec_t *const routes) 1687 { 1688 size_t i; 1689 for (i = 0; i < routes->num; i++) { 1690 cti_route_t *route = routes->routes[i]; 1691 // This is nat64 prefix published by us 1692 if (route->nat64 && route->origin == offmesh_route_origin_ncp 1693 && route->rloc == route_state->srp_server->rloc16) { 1694 // br generated nat64 prefix 1695 if (route->preference == offmesh_route_preference_low) { 1696 nat64_prefix_t *prefix = route_state->nat64->nat64_br_prefix_publisher->br_prefix; 1697 // If we are not publishing or 1698 // we are publishing but the prefix is different, this can happen when ula changed 1699 if ((route_state->nat64->nat64_br_prefix_publisher->state != nat64_br_prefix_publisher_state_publishing) || 1700 (prefix && in6prefix_compare(&prefix->prefix, &route->prefix, NAT64_PREFIX_SLASH_96_BYTES))) { 1701 nat64_prefix_t *tmp = nat64_prefix_create(&route->prefix, NAT64_PREFIX_SLASH_96_BYTES, 1702 route_pref_to_nat64_pref(route->preference), route->rloc); 1703 SEGMENTED_IPv6_ADDR_GEN_SRP(tmp->prefix.s6_addr, nat64_prefix_buf); 1704 INFO("stale br prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " removing", 1705 SEGMENTED_IPv6_ADDR_PARAM_SRP(tmp->prefix.s6_addr, nat64_prefix_buf)); 1706 nat64_add_prefix_to_update_queue(route_state->nat64, tmp, nat64_prefix_action_remove); 1707 RELEASE_HERE(tmp, nat64_prefix); 1708 } 1709 // prefix from infrastructure 1710 } else if (route->preference == offmesh_route_preference_medium) { 1711 nat64_prefix_t *prefix = route_state->nat64->nat64_infra_prefix_publisher->proposed_prefix; 1712 // If we are not publishing or 1713 // we are publishing but the prefix is different, this can happen when infra prefix changed 1714 if ((route_state->nat64->nat64_infra_prefix_publisher->state != nat64_infra_prefix_publisher_state_publishing) || 1715 (prefix && in6prefix_compare(&prefix->prefix, &route->prefix, NAT64_PREFIX_SLASH_96_BYTES))) { 1716 nat64_prefix_t *tmp = nat64_prefix_create(&route->prefix, NAT64_PREFIX_SLASH_96_BYTES, 1717 route_pref_to_nat64_pref(route->preference), route->rloc); 1718 SEGMENTED_IPv6_ADDR_GEN_SRP(tmp->prefix.s6_addr, nat64_prefix_buf); 1719 INFO("stale infra prefix " PRI_SEGMENTED_IPv6_ADDR_SRP " removing", 1720 SEGMENTED_IPv6_ADDR_PARAM_SRP(tmp->prefix.s6_addr, nat64_prefix_buf)); 1721 nat64_add_prefix_to_update_queue(route_state->nat64, tmp, nat64_prefix_action_remove); 1722 RELEASE_HERE(tmp, nat64_prefix); 1723 } 1724 } 1725 } 1726 } 1727 } 1728 1729 void 1730 nat64_offmesh_route_list_callback(route_state_t *route_state, cti_route_vec_t *routes, cti_status_t status) 1731 { 1732 if (status != kCTIStatus_NoError) { 1733 ERROR("status %d", status); 1734 } else { 1735 INFO("got %zu offmesh routes", routes->num); 1736 nat64_check_stale_prefix(route_state, routes); 1737 nat64_thread_prefix_monitor_t *state_machine = route_state->nat64->thread_monitor; 1738 nat64_thread_prefix_monitor_event_t out_event; 1739 nat64_thread_prefix_monitor_event_init(&out_event, nat64_event_thread_prefix_update); 1740 out_event.routes = routes; 1741 NAT64_EVENT_ANNOUNCE(state_machine, out_event); 1742 nat64_thread_prefix_monitor_event_deliver(state_machine, &out_event); 1743 } 1744 } 1745 1746 void 1747 nat64_thread_shutdown(route_state_t *route_state) 1748 { 1749 nat64_t *nat64 = route_state->nat64; 1750 if (nat64->nat64_infra_prefix_publisher != NULL) { 1751 nat64_infra_prefix_publisher_event_t infra_event; 1752 nat64_infra_prefix_publisher_event_init(&infra_event, nat64_event_nat64_infra_prefix_publisher_shutdown); 1753 nat64_infra_prefix_publisher_event_deliver(nat64->nat64_infra_prefix_publisher, &infra_event); 1754 } 1755 if (nat64->nat64_br_prefix_publisher != NULL) { 1756 nat64_br_prefix_publisher_event_t br_event; 1757 nat64_br_prefix_publisher_event_init(&br_event, nat64_event_nat64_br_prefix_publisher_shutdown); 1758 nat64_br_prefix_publisher_event_deliver(nat64->nat64_br_prefix_publisher, &br_event); 1759 } 1760 } 1761 #endif 1762 1763 // Local Variables: 1764 // mode: C 1765 // tab-width: 4 1766 // c-file-style: "bsd" 1767 // c-basic-offset: 4 1768 // fill-column: 120 1769 // indent-tabs-mode: nil 1770 // End: 1771