2 test_optimal_pmtu.c -- Execution of specific meshlink black box test cases
3 Copyright (C) 2019 Guus Sliepen <guus@meshlink.io>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "../common/containers.h"
31 #include "../common/test_step.h"
32 #include "../common/common_handlers.h"
33 #include "../common/network_namespace_framework.h"
34 #include "../../utils.h"
35 #include "../test_case_optimal_pmtu_01/test_case_optimal_pmtu.h"
36 #include "test_optimal_pmtu.h"
38 static void test_case_optimal_pmtu_01(void **state);
39 static bool test_steps_optimal_pmtu_01(void);
40 static void test_case_optimal_pmtu_02(void **state);
41 static bool test_steps_optimal_pmtu_02(void);
42 static void test_case_optimal_pmtu_03(void **state);
43 static bool test_steps_optimal_pmtu_03(void);
44 static void test_case_optimal_pmtu_04(void **state);
45 static bool test_steps_optimal_pmtu_04(void);
46 static void test_case_optimal_pmtu_05(void **state);
47 static bool test_steps_optimal_pmtu_05(void);
48 static void test_case_optimal_pmtu_06(void **state);
49 static bool test_steps_optimal_pmtu_06(void);
50 static void test_case_optimal_pmtu_07(void **state);
51 static bool test_steps_optimal_pmtu_07(void);
53 extern void *node_sim_relay_01(void *arg);
54 extern void *node_sim_peer_01(void *arg);
55 extern void *node_sim_nut_01(void *arg);
56 extern pmtu_attr_t node_pmtu[2];
58 typedef bool (*test_step_func_t)(void);
59 static int setup_test(void **state);
60 bool test_pmtu_relay_running = true;
61 bool test_pmtu_peer_running = true;
62 bool test_pmtu_nut_running = true;
63 bool ping_channel_enable_07 = false;
65 struct sync_flag test_pmtu_nut_closed = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
66 static netns_state_t *test_pmtu_state;
68 static int setup_test(void **state) {
71 netns_create_topology(test_pmtu_state);
72 fprintf(stderr, "\nCreated topology\n");
74 test_pmtu_relay_running = true;
75 test_pmtu_peer_running = true;
76 test_pmtu_nut_running = true;
77 ping_channel_enable_07 = false;
78 memset(node_pmtu, 0, sizeof(node_pmtu));
79 set_sync_flag(&test_pmtu_nut_closed, false);
80 meshlink_destroy("nut");
81 meshlink_destroy("peer");
82 meshlink_destroy("relay");
87 static int teardown_test(void **state) {
90 meshlink_destroy("nut");
91 meshlink_destroy("peer");
92 meshlink_destroy("relay");
93 netns_destroy_topology(test_pmtu_state);
98 static void execute_test(test_step_func_t step_func, void **state) {
102 fprintf(stderr, "\n\x1b[32mRunning Test\x1b[0m\n");
103 bool test_result = step_func();
110 static void *gen_inv(void *arg) {
111 mesh_invite_arg_t *mesh_invite_arg = (mesh_invite_arg_t *)arg;
112 meshlink_handle_t *mesh;
113 mesh = meshlink_open(mesh_invite_arg->mesh_arg->node_name, mesh_invite_arg->mesh_arg->confbase, mesh_invite_arg->mesh_arg->app_name, mesh_invite_arg->mesh_arg->dev_class);
116 char *invitation = meshlink_invite(mesh, NULL, mesh_invite_arg->invitee_name);
118 mesh_invite_arg->invite_str = invitation;
119 meshlink_close(mesh);
124 /* Test Steps for optimal PMTU discovery Test Case # 1 -
125 Validating NUT MTU parameters without blocking ICMP under designed
127 static void test_case_optimal_pmtu_01(void **state) {
128 execute_test(test_steps_optimal_pmtu_01, state);
132 /* Test Steps for optimal PMTU discovery Test Case # 1 - Success case
135 1. Create NAT setup and run each node instances in discrete namespace.
136 2. Open a channel from NUT to peer and hence triggering Peer to peer connection
137 3. Send the analyzed MTU parameters mesh event information to test driver
139 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
142 static bool test_steps_optimal_pmtu_01(void) {
143 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
144 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
145 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
148 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
149 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
150 run_node_in_namespace_thread(&netns_relay_nut_invite);
152 assert(relay_nut_invite_arg.invite_str);
153 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
155 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
156 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
157 run_node_in_namespace_thread(&netns_relay_peer_invite);
159 assert(relay_peer_invite_arg.invite_str);
160 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
162 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
163 run_node_in_namespace_thread(&netns_relay_handle);
165 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
166 run_node_in_namespace_thread(&netns_peer_handle);
168 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
169 run_node_in_namespace_thread(&netns_nut_handle);
171 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
172 test_pmtu_relay_running = false;
173 test_pmtu_peer_running = false;
176 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
177 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
178 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
179 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
184 /* Test Steps for optimal PMTU discovery Test Case # 2 -
185 Validating NUT MTU parameters blocking ICMP under designed
187 static void test_case_optimal_pmtu_02(void **state) {
188 execute_test(test_steps_optimal_pmtu_02, state);
192 /* Test Steps for optimal PMTU discovery Test Case # 2 -
194 1. Create NAT setup and run each node instances in discrete namespace,
195 2. Block ICMP protocol at NUT's NAT
196 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
197 4. Send the analyzed MTU parameters mesh event information to test driver
199 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
202 static bool test_steps_optimal_pmtu_02(void) {
203 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
204 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
205 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
207 assert(system("ip netns exec peer_nat iptables -A FORWARD -p icmp -j DROP") == 0);
208 assert(system("ip netns exec nut_nat iptables -A FORWARD -p icmp -j DROP") == 0);
210 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
211 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
212 run_node_in_namespace_thread(&netns_relay_nut_invite);
214 assert(relay_nut_invite_arg.invite_str);
215 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
217 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
218 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
219 run_node_in_namespace_thread(&netns_relay_peer_invite);
221 assert(relay_peer_invite_arg.invite_str);
222 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
224 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
225 run_node_in_namespace_thread(&netns_relay_handle);
227 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
228 run_node_in_namespace_thread(&netns_peer_handle);
230 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
231 run_node_in_namespace_thread(&netns_nut_handle);
233 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
234 test_pmtu_relay_running = false;
235 test_pmtu_peer_running = false;
238 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
239 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
240 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
241 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
246 /* Test Steps for optimal PMTU discovery Test Case # 3 -
247 Validating NUT MTU parameters with MTU size of NAT = 1250 under designed
249 static void test_case_optimal_pmtu_03(void **state) {
250 execute_test(test_steps_optimal_pmtu_03, state);
254 /* Test Steps for optimal PMTU discovery Test Case # 3 -
256 1. Create NAT setup and run each node instances in discrete namespace,
257 2. Change the MTU size of NUT's NAT to 1250
258 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
259 4. Send the analyzed MTU parameters mesh event information to test driver
261 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
264 static bool test_steps_optimal_pmtu_03(void) {
265 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
266 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
267 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
269 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1250") == 0);
271 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
272 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
273 run_node_in_namespace_thread(&netns_relay_nut_invite);
275 assert(relay_nut_invite_arg.invite_str);
276 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
278 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
279 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
280 run_node_in_namespace_thread(&netns_relay_peer_invite);
282 assert(relay_peer_invite_arg.invite_str);
283 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
285 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
286 run_node_in_namespace_thread(&netns_relay_handle);
288 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
289 run_node_in_namespace_thread(&netns_peer_handle);
291 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
292 run_node_in_namespace_thread(&netns_nut_handle);
294 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
295 test_pmtu_relay_running = false;
296 test_pmtu_peer_running = false;
299 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1200, 1250);
300 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1200, 1250);
305 /* Test Steps for optimal PMTU discovery Test Case # 4 -
306 Validating NUT MTU parameters with MTU size of NAT = 1000 under designed
308 static void test_case_optimal_pmtu_04(void **state) {
309 execute_test(test_steps_optimal_pmtu_04, state);
313 /* Test Steps for optimal PMTU discovery Test Case # 4 -
315 1. Create NAT setup and run each node instances in discrete namespace,
316 2. Change the MTU size of NUT's NAT to 1000
317 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
318 4. Send the analyzed MTU parameters mesh event information to test driver
320 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
323 static bool test_steps_optimal_pmtu_04(void) {
324 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
325 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
326 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
328 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1000") == 0);
330 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
331 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
332 run_node_in_namespace_thread(&netns_relay_nut_invite);
334 assert(relay_nut_invite_arg.invite_str);
335 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
337 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
338 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
339 run_node_in_namespace_thread(&netns_relay_peer_invite);
341 assert(relay_peer_invite_arg.invite_str);
342 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
344 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
345 run_node_in_namespace_thread(&netns_relay_handle);
347 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
348 run_node_in_namespace_thread(&netns_peer_handle);
350 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
351 run_node_in_namespace_thread(&netns_nut_handle);
353 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
354 test_pmtu_relay_running = false;
355 test_pmtu_peer_running = false;
358 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 925, 1000);
359 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 925, 1000);
364 /* Test Steps for optimal PMTU discovery Test Case # 5 -
365 Validating NUT MTU parameters with MTU size of NAT = 800 under designed
367 static void test_case_optimal_pmtu_05(void **state) {
368 execute_test(test_steps_optimal_pmtu_05, state);
372 /* Test Steps for optimal PMTU discovery Test Case # 5 -
374 1. Create NAT setup and run each node instances in discrete namespace,
375 2. Change the MTU size of NUT's NAT to 800
376 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
377 4. Send the analyzed MTU parameters mesh event information to test driver
379 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
382 static bool test_steps_optimal_pmtu_05(void) {
383 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
384 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
385 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
387 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 750") == 0);
389 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
390 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
391 run_node_in_namespace_thread(&netns_relay_nut_invite);
393 assert(relay_nut_invite_arg.invite_str);
394 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
396 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
397 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
398 run_node_in_namespace_thread(&netns_relay_peer_invite);
400 assert(relay_peer_invite_arg.invite_str);
401 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
403 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
404 run_node_in_namespace_thread(&netns_relay_handle);
406 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
407 run_node_in_namespace_thread(&netns_peer_handle);
409 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
410 run_node_in_namespace_thread(&netns_nut_handle);
412 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
413 test_pmtu_relay_running = false;
414 test_pmtu_peer_running = false;
417 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 700, 750);
418 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 700, 750);
423 /* Test Steps for optimal PMTU discovery Test Case # 6 -
424 Flushing the tracked connections via NUT NAT for every 60 seconds */
425 static void test_case_optimal_pmtu_06(void **state) {
426 execute_test(test_steps_optimal_pmtu_06, state);
430 static bool run_conntrack;
431 static pthread_t pmtu_test_case_conntrack_thread;
432 static void *conntrack_flush(void *arg) {
435 // flushes mappings for every 60 seconds
437 while(run_conntrack) {
439 assert(system("ip netns exec nut_nat conntrack -F") == 0);
440 assert(system("ip netns exec peer_nat conntrack -F") == 0);
446 /* Test Steps for optimal PMTU discovery Test Case # 6 -
448 1. Create NAT setup and Launch conntrack thread which flushes the tracked connections for every 90 seconds
449 2. Run each node instances in discrete namespace,
450 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
451 4. Send the analyzed MTU parameters mesh event information to test driver
453 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
456 static bool test_steps_optimal_pmtu_06(void) {
457 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
458 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
459 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
461 run_conntrack = true;
462 assert(!pthread_create(&pmtu_test_case_conntrack_thread, NULL, conntrack_flush, NULL));
464 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
465 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
466 run_node_in_namespace_thread(&netns_relay_nut_invite);
468 assert(relay_nut_invite_arg.invite_str);
469 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
471 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
472 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
473 run_node_in_namespace_thread(&netns_relay_peer_invite);
475 assert(relay_peer_invite_arg.invite_str);
476 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
478 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
479 run_node_in_namespace_thread(&netns_relay_handle);
481 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
482 run_node_in_namespace_thread(&netns_peer_handle);
484 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
485 run_node_in_namespace_thread(&netns_nut_handle);
487 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
488 test_pmtu_relay_running = false;
489 test_pmtu_peer_running = false;
490 run_conntrack = false;
491 pthread_join(pmtu_test_case_conntrack_thread, NULL);
495 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1440, 1500);
496 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1440, 1500);
497 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_ping.probes, 38, 42);
498 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_ping.probes, 38, 42);
503 /* Test Steps for optimal PMTU discovery Test Case # 7 -
504 NUT sending data to peer node via channel for every 30 seconds
506 static void test_case_optimal_pmtu_07(void **state) {
507 execute_test(test_steps_optimal_pmtu_07, state);
511 /* Test Steps for optimal PMTU discovery Test Case # 7 -
513 1. Create NAT setup and run each node instances in discrete namespace.
514 2. Open a channel from NUT to peer and hence triggering Peer to peer connection
515 3. Send data periodically via channel from NUT to peer node.
516 4. Send the analyzed MTU parameters mesh event information to test driver
518 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
521 static bool test_steps_optimal_pmtu_07(void) {
522 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
523 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
524 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
526 ping_channel_enable_07 = true;
528 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
529 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
530 run_node_in_namespace_thread(&netns_relay_nut_invite);
532 assert(relay_nut_invite_arg.invite_str);
533 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
535 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
536 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
537 run_node_in_namespace_thread(&netns_relay_peer_invite);
539 assert(relay_peer_invite_arg.invite_str);
540 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
542 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
543 run_node_in_namespace_thread(&netns_relay_handle);
545 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
546 run_node_in_namespace_thread(&netns_peer_handle);
548 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
549 run_node_in_namespace_thread(&netns_nut_handle);
551 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
552 test_pmtu_relay_running = false;
553 test_pmtu_peer_running = false;
556 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
557 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
558 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
559 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
564 // Optimal PMTU test case driver
566 int test_optimal_pmtu(void) {
567 interface_t nut_ifs[] = { { .if_peer = "nut_nat", .fetch_ip_netns_name = "nut_nat" } };
571 .interfaces = nut_ifs,
575 interface_t peer_ifs[] = { { .if_peer = "peer_nat", .fetch_ip_netns_name = "peer_nat" } };
579 .interfaces = peer_ifs,
583 interface_t relay_ifs[] = { { .if_peer = "wan_bridge" } };
584 namespace_t relay = {
587 .interfaces = relay_ifs,
591 netns_fullcone_handle_t nut_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "nut" };
592 netns_fullcone_handle_t *nut_nat_args[] = { &nut_nat_fullcone, NULL };
593 interface_t nut_nat_ifs[] = { { .if_peer = "nut", .fetch_ip_netns_name = "nut_nat" }, { .if_peer = "wan_bridge" } };
594 namespace_t nut_nat = {
597 .nat_arg = nut_nat_args,
598 .static_config_net_addr = "192.168.1.0/24",
599 .interfaces = nut_nat_ifs,
603 netns_fullcone_handle_t peer_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "peer" };
604 netns_fullcone_handle_t *peer_nat_args[] = { &peer_nat_fullcone, NULL };
605 interface_t peer_nat_ifs[] = { { .if_peer = "peer", .fetch_ip_netns_name = "peer_nat" }, { .if_peer = "wan_bridge" } };
606 namespace_t peer_nat = {
609 .nat_arg = peer_nat_args,
610 .static_config_net_addr = "192.168.1.0/24",
611 .interfaces = peer_nat_ifs,
615 interface_t wan_ifs[] = { { .if_peer = "peer_nat" }, { .if_peer = "nut_nat" }, { .if_peer = "relay" } };
616 namespace_t wan_bridge = {
617 .name = "wan_bridge",
619 .interfaces = wan_ifs,
623 namespace_t test_optimal_pmtu_1_nodes[] = { nut_nat, peer_nat, wan_bridge, nut, peer, relay };
625 netns_state_t test_pmtu_nodes = {
626 .test_case_name = "test_case_optimal_pmtu",
627 .namespaces = test_optimal_pmtu_1_nodes,
630 test_pmtu_state = &test_pmtu_nodes;
632 const struct CMUnitTest blackbox_group0_tests[] = {
633 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_01, setup_test, teardown_test,
634 (void *)&test_pmtu_state),
635 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_02, setup_test, teardown_test,
636 (void *)&test_pmtu_state),
637 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_03, setup_test, teardown_test,
638 (void *)&test_pmtu_state),
639 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_04, setup_test, teardown_test,
640 (void *)&test_pmtu_state),
641 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_05, setup_test, teardown_test,
642 (void *)&test_pmtu_state),
643 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_06, setup_test, teardown_test,
644 (void *)&test_pmtu_state),
645 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_07, setup_test, teardown_test,
646 (void *)&test_pmtu_state),
648 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
650 return cmocka_run_group_tests(blackbox_group0_tests, NULL, NULL);