nat64.c revision 1.1.1.1 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