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.
25 #include "../common/containers.h"
26 #include "../common/test_step.h"
27 #include "../common/common_handlers.h"
28 #include "../common/network_namespace_framework.h"
29 #include "../../utils.h"
30 #include "../test_case_optimal_pmtu_01/test_case_optimal_pmtu.h"
31 #include "test_optimal_pmtu.h"
33 static void test_case_optimal_pmtu_01(void **state);
34 static bool test_steps_optimal_pmtu_01(void);
35 static void test_case_optimal_pmtu_02(void **state);
36 static bool test_steps_optimal_pmtu_02(void);
37 static void test_case_optimal_pmtu_03(void **state);
38 static bool test_steps_optimal_pmtu_03(void);
39 static void test_case_optimal_pmtu_04(void **state);
40 static bool test_steps_optimal_pmtu_04(void);
41 static void test_case_optimal_pmtu_05(void **state);
42 static bool test_steps_optimal_pmtu_05(void);
43 static void test_case_optimal_pmtu_06(void **state);
44 static bool test_steps_optimal_pmtu_06(void);
45 static void test_case_optimal_pmtu_07(void **state);
46 static bool test_steps_optimal_pmtu_07(void);
48 extern void *node_sim_relay_01(void *arg);
49 extern void *node_sim_peer_01(void *arg);
50 extern void *node_sim_nut_01(void *arg);
51 extern pmtu_attr_t node_pmtu[2];
53 typedef bool (*test_step_func_t)(void);
54 static int setup_test(void **state);
55 bool test_pmtu_relay_running = true;
56 bool test_pmtu_peer_running = true;
57 bool test_pmtu_nut_running = true;
58 bool ping_channel_enable_07 = false;
60 struct sync_flag test_pmtu_nut_closed = {.mutex = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
61 static netns_state_t *test_pmtu_state;
63 static int setup_test(void **state) {
66 netns_create_topology(test_pmtu_state);
67 fprintf(stderr, "\nCreated topology\n");
69 test_pmtu_relay_running = true;
70 test_pmtu_peer_running = true;
71 test_pmtu_nut_running = true;
72 ping_channel_enable_07 = false;
73 memset(node_pmtu, 0, sizeof(node_pmtu));
74 set_sync_flag(&test_pmtu_nut_closed, false);
75 meshlink_destroy("nut");
76 meshlink_destroy("peer");
77 meshlink_destroy("relay");
82 static int teardown_test(void **state) {
85 meshlink_destroy("nut");
86 meshlink_destroy("peer");
87 meshlink_destroy("relay");
88 netns_destroy_topology(test_pmtu_state);
93 static void execute_test(test_step_func_t step_func, void **state) {
97 fprintf(stderr, "\n\x1b[32mRunning Test\x1b[0m\n");
98 bool test_result = step_func();
105 static void *gen_inv(void *arg) {
106 mesh_invite_arg_t *mesh_invite_arg = (mesh_invite_arg_t *)arg;
107 meshlink_handle_t *mesh;
108 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);
111 char *invitation = meshlink_invite(mesh, NULL, mesh_invite_arg->invitee_name);
113 mesh_invite_arg->invite_str = invitation;
114 meshlink_close(mesh);
119 /* Test Steps for optimal PMTU discovery Test Case # 1 -
120 Validating NUT MTU parameters without blocking ICMP under designed
122 static void test_case_optimal_pmtu_01(void **state) {
123 execute_test(test_steps_optimal_pmtu_01, state);
127 /* Test Steps for optimal PMTU discovery Test Case # 1 - Success case
130 1. Create NAT setup and run each node instances in discrete namespace.
131 2. Open a channel from NUT to peer and hence triggering Peer to peer connection
132 3. Send the analyzed MTU parameters mesh event information to test driver
134 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
137 static bool test_steps_optimal_pmtu_01(void) {
138 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
139 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
140 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
143 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
144 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
145 run_node_in_namespace_thread(&netns_relay_nut_invite);
147 assert(relay_nut_invite_arg.invite_str);
148 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
150 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
151 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
152 run_node_in_namespace_thread(&netns_relay_peer_invite);
154 assert(relay_peer_invite_arg.invite_str);
155 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
157 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
158 run_node_in_namespace_thread(&netns_relay_handle);
160 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
161 run_node_in_namespace_thread(&netns_peer_handle);
163 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
164 run_node_in_namespace_thread(&netns_nut_handle);
166 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
167 test_pmtu_relay_running = false;
168 test_pmtu_peer_running = false;
171 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
172 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
173 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
174 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
179 /* Test Steps for optimal PMTU discovery Test Case # 2 -
180 Validating NUT MTU parameters blocking ICMP under designed
182 static void test_case_optimal_pmtu_02(void **state) {
183 execute_test(test_steps_optimal_pmtu_02, state);
187 /* Test Steps for optimal PMTU discovery Test Case # 2 -
189 1. Create NAT setup and run each node instances in discrete namespace,
190 2. Block ICMP protocol at NUT's NAT
191 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
192 4. Send the analyzed MTU parameters mesh event information to test driver
194 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
197 static bool test_steps_optimal_pmtu_02(void) {
198 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
199 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
200 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
202 assert(system("ip netns exec peer_nat iptables -A FORWARD -p icmp -j DROP") == 0);
203 assert(system("ip netns exec nut_nat iptables -A FORWARD -p icmp -j DROP") == 0);
205 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
206 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
207 run_node_in_namespace_thread(&netns_relay_nut_invite);
209 assert(relay_nut_invite_arg.invite_str);
210 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
212 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
213 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
214 run_node_in_namespace_thread(&netns_relay_peer_invite);
216 assert(relay_peer_invite_arg.invite_str);
217 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
219 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
220 run_node_in_namespace_thread(&netns_relay_handle);
222 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
223 run_node_in_namespace_thread(&netns_peer_handle);
225 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
226 run_node_in_namespace_thread(&netns_nut_handle);
228 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
229 test_pmtu_relay_running = false;
230 test_pmtu_peer_running = false;
233 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
234 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
235 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
236 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
241 /* Test Steps for optimal PMTU discovery Test Case # 3 -
242 Validating NUT MTU parameters with MTU size of NAT = 1250 under designed
244 static void test_case_optimal_pmtu_03(void **state) {
245 execute_test(test_steps_optimal_pmtu_03, state);
249 /* Test Steps for optimal PMTU discovery Test Case # 3 -
251 1. Create NAT setup and run each node instances in discrete namespace,
252 2. Change the MTU size of NUT's NAT to 1250
253 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
254 4. Send the analyzed MTU parameters mesh event information to test driver
256 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
259 static bool test_steps_optimal_pmtu_03(void) {
260 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
261 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
262 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
264 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1250") == 0);
266 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
267 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
268 run_node_in_namespace_thread(&netns_relay_nut_invite);
270 assert(relay_nut_invite_arg.invite_str);
271 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
273 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
274 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
275 run_node_in_namespace_thread(&netns_relay_peer_invite);
277 assert(relay_peer_invite_arg.invite_str);
278 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
280 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
281 run_node_in_namespace_thread(&netns_relay_handle);
283 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
284 run_node_in_namespace_thread(&netns_peer_handle);
286 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
287 run_node_in_namespace_thread(&netns_nut_handle);
289 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
290 test_pmtu_relay_running = false;
291 test_pmtu_peer_running = false;
294 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1200, 1250);
295 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1200, 1250);
300 /* Test Steps for optimal PMTU discovery Test Case # 4 -
301 Validating NUT MTU parameters with MTU size of NAT = 1000 under designed
303 static void test_case_optimal_pmtu_04(void **state) {
304 execute_test(test_steps_optimal_pmtu_04, state);
308 /* Test Steps for optimal PMTU discovery Test Case # 4 -
310 1. Create NAT setup and run each node instances in discrete namespace,
311 2. Change the MTU size of NUT's NAT to 1000
312 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
313 4. Send the analyzed MTU parameters mesh event information to test driver
315 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
318 static bool test_steps_optimal_pmtu_04(void) {
319 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
320 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
321 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
323 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1000") == 0);
325 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
326 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
327 run_node_in_namespace_thread(&netns_relay_nut_invite);
329 assert(relay_nut_invite_arg.invite_str);
330 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
332 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
333 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
334 run_node_in_namespace_thread(&netns_relay_peer_invite);
336 assert(relay_peer_invite_arg.invite_str);
337 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
339 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
340 run_node_in_namespace_thread(&netns_relay_handle);
342 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
343 run_node_in_namespace_thread(&netns_peer_handle);
345 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
346 run_node_in_namespace_thread(&netns_nut_handle);
348 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
349 test_pmtu_relay_running = false;
350 test_pmtu_peer_running = false;
353 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 925, 1000);
354 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 925, 1000);
359 /* Test Steps for optimal PMTU discovery Test Case # 5 -
360 Validating NUT MTU parameters with MTU size of NAT = 800 under designed
362 static void test_case_optimal_pmtu_05(void **state) {
363 execute_test(test_steps_optimal_pmtu_05, state);
367 /* Test Steps for optimal PMTU discovery Test Case # 5 -
369 1. Create NAT setup and run each node instances in discrete namespace,
370 2. Change the MTU size of NUT's NAT to 800
371 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
372 4. Send the analyzed MTU parameters mesh event information to test driver
374 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
377 static bool test_steps_optimal_pmtu_05(void) {
378 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
379 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
380 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
382 assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 750") == 0);
384 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
385 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
386 run_node_in_namespace_thread(&netns_relay_nut_invite);
388 assert(relay_nut_invite_arg.invite_str);
389 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
391 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
392 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
393 run_node_in_namespace_thread(&netns_relay_peer_invite);
395 assert(relay_peer_invite_arg.invite_str);
396 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
398 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
399 run_node_in_namespace_thread(&netns_relay_handle);
401 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
402 run_node_in_namespace_thread(&netns_peer_handle);
404 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
405 run_node_in_namespace_thread(&netns_nut_handle);
407 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
408 test_pmtu_relay_running = false;
409 test_pmtu_peer_running = false;
412 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 700, 750);
413 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 700, 750);
418 /* Test Steps for optimal PMTU discovery Test Case # 6 -
419 Flushing the tracked connections via NUT NAT for every 60 seconds */
420 static void test_case_optimal_pmtu_06(void **state) {
421 execute_test(test_steps_optimal_pmtu_06, state);
425 static bool run_conntrack;
426 static pthread_t pmtu_test_case_conntrack_thread;
427 static void *conntrack_flush(void *arg) {
430 // flushes mappings for every 60 seconds
432 while(run_conntrack) {
434 assert(system("ip netns exec nut_nat conntrack -F") == 0);
435 assert(system("ip netns exec peer_nat conntrack -F") == 0);
441 /* Test Steps for optimal PMTU discovery Test Case # 6 -
443 1. Create NAT setup and Launch conntrack thread which flushes the tracked connections for every 90 seconds
444 2. Run each node instances in discrete namespace,
445 3. Open a channel from NUT to peer and hence triggering Peer to peer connection
446 4. Send the analyzed MTU parameters mesh event information to test driver
448 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
451 static bool test_steps_optimal_pmtu_06(void) {
452 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
453 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
454 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
456 run_conntrack = true;
457 assert(!pthread_create(&pmtu_test_case_conntrack_thread, NULL, conntrack_flush, NULL));
459 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
460 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
461 run_node_in_namespace_thread(&netns_relay_nut_invite);
463 assert(relay_nut_invite_arg.invite_str);
464 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
466 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
467 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
468 run_node_in_namespace_thread(&netns_relay_peer_invite);
470 assert(relay_peer_invite_arg.invite_str);
471 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
473 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
474 run_node_in_namespace_thread(&netns_relay_handle);
476 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
477 run_node_in_namespace_thread(&netns_peer_handle);
479 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
480 run_node_in_namespace_thread(&netns_nut_handle);
482 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
483 test_pmtu_relay_running = false;
484 test_pmtu_peer_running = false;
485 run_conntrack = false;
486 pthread_join(pmtu_test_case_conntrack_thread, NULL);
490 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1440, 1500);
491 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1440, 1500);
492 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_ping.probes, 38, 42);
493 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_ping.probes, 38, 42);
498 /* Test Steps for optimal PMTU discovery Test Case # 7 -
499 NUT sending data to peer node via channel for every 30 seconds
501 static void test_case_optimal_pmtu_07(void **state) {
502 execute_test(test_steps_optimal_pmtu_07, state);
506 /* Test Steps for optimal PMTU discovery Test Case # 7 -
508 1. Create NAT setup and run each node instances in discrete namespace.
509 2. Open a channel from NUT to peer and hence triggering Peer to peer connection
510 3. Send data periodically via channel from NUT to peer node.
511 4. Send the analyzed MTU parameters mesh event information to test driver
513 NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
516 static bool test_steps_optimal_pmtu_07(void) {
517 mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
518 mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
519 mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
521 ping_channel_enable_07 = true;
523 mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
524 netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
525 run_node_in_namespace_thread(&netns_relay_nut_invite);
527 assert(relay_nut_invite_arg.invite_str);
528 nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
530 mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
531 netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
532 run_node_in_namespace_thread(&netns_relay_peer_invite);
534 assert(relay_peer_invite_arg.invite_str);
535 peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
537 netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
538 run_node_in_namespace_thread(&netns_relay_handle);
540 netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
541 run_node_in_namespace_thread(&netns_peer_handle);
543 netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
544 run_node_in_namespace_thread(&netns_nut_handle);
546 assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
547 test_pmtu_relay_running = false;
548 test_pmtu_peer_running = false;
551 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
552 assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
553 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
554 assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
559 // Optimal PMTU test case driver
561 int test_optimal_pmtu(void) {
562 interface_t nut_ifs[] = { { .if_peer = "nut_nat", .fetch_ip_netns_name = "nut_nat" } };
566 .interfaces = nut_ifs,
570 interface_t peer_ifs[] = { { .if_peer = "peer_nat", .fetch_ip_netns_name = "peer_nat" } };
574 .interfaces = peer_ifs,
578 interface_t relay_ifs[] = { { .if_peer = "wan_bridge" } };
579 namespace_t relay = {
582 .interfaces = relay_ifs,
586 netns_fullcone_handle_t nut_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "nut" };
587 netns_fullcone_handle_t *nut_nat_args[] = { &nut_nat_fullcone, NULL };
588 interface_t nut_nat_ifs[] = { { .if_peer = "nut", .fetch_ip_netns_name = "nut_nat" }, { .if_peer = "wan_bridge" } };
589 namespace_t nut_nat = {
592 .nat_arg = nut_nat_args,
593 .static_config_net_addr = "192.168.1.0/24",
594 .interfaces = nut_nat_ifs,
598 netns_fullcone_handle_t peer_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "peer" };
599 netns_fullcone_handle_t *peer_nat_args[] = { &peer_nat_fullcone, NULL };
600 interface_t peer_nat_ifs[] = { { .if_peer = "peer", .fetch_ip_netns_name = "peer_nat" }, { .if_peer = "wan_bridge" } };
601 namespace_t peer_nat = {
604 .nat_arg = peer_nat_args,
605 .static_config_net_addr = "192.168.1.0/24",
606 .interfaces = peer_nat_ifs,
610 interface_t wan_ifs[] = { { .if_peer = "peer_nat" }, { .if_peer = "nut_nat" }, { .if_peer = "relay" } };
611 namespace_t wan_bridge = {
612 .name = "wan_bridge",
614 .interfaces = wan_ifs,
618 namespace_t test_optimal_pmtu_1_nodes[] = { nut_nat, peer_nat, wan_bridge, nut, peer, relay };
620 netns_state_t test_pmtu_nodes = {
621 .test_case_name = "test_case_optimal_pmtu",
622 .namespaces = test_optimal_pmtu_1_nodes,
625 test_pmtu_state = &test_pmtu_nodes;
627 const struct CMUnitTest blackbox_group0_tests[] = {
628 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_01, setup_test, teardown_test,
629 (void *)&test_pmtu_state),
630 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_02, setup_test, teardown_test,
631 (void *)&test_pmtu_state),
632 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_03, setup_test, teardown_test,
633 (void *)&test_pmtu_state),
634 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_04, setup_test, teardown_test,
635 (void *)&test_pmtu_state),
636 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_05, setup_test, teardown_test,
637 (void *)&test_pmtu_state),
638 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_06, setup_test, teardown_test,
639 (void *)&test_pmtu_state),
640 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_07, setup_test, teardown_test,
641 (void *)&test_pmtu_state),
643 total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
645 return cmocka_run_group_tests(blackbox_group0_tests, NULL, NULL);