]> git.meshlink.io Git - meshlink/blob - test/blackbox/run_blackbox_tests/test_optimal_pmtu.c
c5638c6ebc1a312849bf795ed7e5c805585960af
[meshlink] / test / blackbox / run_blackbox_tests / test_optimal_pmtu.c
1 /*
2     test_optimal_pmtu.c -- Execution of specific meshlink black box test cases
3     Copyright (C) 2019  Guus Sliepen <guus@meshlink.io>
4
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.
9
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.
14
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.
18 */
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <setjmp.h>
22 #include <cmocka.h>
23 #include <assert.h>
24 #include <pthread.h>
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"
32
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);
47
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];
52
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;
59
60 struct sync_flag test_pmtu_nut_closed = {.mutex  = PTHREAD_MUTEX_INITIALIZER, .cond = PTHREAD_COND_INITIALIZER};
61 static netns_state_t *test_pmtu_state;
62
63 static int setup_test(void **state) {
64         netns_create_topology(test_pmtu_state);
65         fprintf(stderr, "\nCreated topology\n");
66
67         test_pmtu_relay_running = true;
68         test_pmtu_peer_running = true;
69         test_pmtu_nut_running = true;
70         ping_channel_enable_07 = false;
71         memset(node_pmtu, 2, sizeof(node_pmtu[0]));
72         set_sync_flag(&test_pmtu_nut_closed, false);
73         meshlink_destroy("nut");
74         meshlink_destroy("peer");
75         meshlink_destroy("relay");
76
77         return EXIT_SUCCESS;
78 }
79
80 static int teardown_test(void **state) {
81         meshlink_destroy("nut");
82         meshlink_destroy("peer");
83         meshlink_destroy("relay");
84         netns_destroy_topology(test_pmtu_state);
85
86         return EXIT_SUCCESS;
87 }
88
89 static void execute_test(test_step_func_t step_func, void **state) {
90
91         fprintf(stderr, "\n\x1b[32mRunning Test\x1b[0m\n");
92         bool test_result = step_func();
93
94         if(!test_result) {
95                 fail();
96         }
97 }
98
99 static void *gen_inv(void *arg) {
100         mesh_invite_arg_t *mesh_invite_arg = (mesh_invite_arg_t *)arg;
101         meshlink_handle_t *mesh;
102         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);
103         assert(mesh);
104
105         char *invitation = meshlink_invite(mesh, NULL, mesh_invite_arg->invitee_name);
106         assert(invitation);
107         mesh_invite_arg->invite_str = invitation;
108         meshlink_close(mesh);
109 }
110
111 /* Test Steps for optimal PMTU discovery Test Case # 1 -
112     Validating NUT MTU parameters without blocking ICMP under designed
113     network topology */
114 static void test_case_optimal_pmtu_01(void **state) {
115         execute_test(test_steps_optimal_pmtu_01, state);
116         return;
117 }
118
119 /* Test Steps for optimal PMTU discovery Test Case # 1 - Success case
120
121     Test Steps:
122     1. Create NAT setup and run each node instances in discrete namespace.
123     2. Open a channel from NUT to peer and hence triggering Peer to peer connection
124     3. Send the analyzed MTU parameters mesh event information to test driver
125     Expected Result:
126       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
127       the expected range
128 */
129 static bool test_steps_optimal_pmtu_01(void) {
130         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
131         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
132         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
133
134
135         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
136         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
137         run_node_in_namespace_thread(&netns_relay_nut_invite);
138         sleep(1);
139         assert(relay_nut_invite_arg.invite_str);
140         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
141
142         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
143         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
144         run_node_in_namespace_thread(&netns_relay_peer_invite);
145         sleep(1);
146         assert(relay_peer_invite_arg.invite_str);
147         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
148
149         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
150         run_node_in_namespace_thread(&netns_relay_handle);
151
152         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
153         run_node_in_namespace_thread(&netns_peer_handle);
154
155         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
156         run_node_in_namespace_thread(&netns_nut_handle);
157
158         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
159         test_pmtu_relay_running = false;
160         test_pmtu_peer_running = false;
161
162         sleep(1);
163         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
164         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
165         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
166         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
167
168         return true;
169 }
170
171 /* Test Steps for optimal PMTU discovery Test Case # 2 -
172     Validating NUT MTU parameters blocking ICMP under designed
173     network topology */
174 static void test_case_optimal_pmtu_02(void **state) {
175         execute_test(test_steps_optimal_pmtu_02, state);
176         return;
177 }
178
179 /* Test Steps for optimal PMTU discovery Test Case # 2 -
180     Test Steps:
181     1. Create NAT setup and run each node instances in discrete namespace,
182     2. Block ICMP protocol at NUT's NAT
183     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
184     4. Send the analyzed MTU parameters mesh event information to test driver
185     Expected Result:
186       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
187       the expected range
188 */
189 static bool test_steps_optimal_pmtu_02(void) {
190         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
191         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
192         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
193
194         assert(system("ip netns exec peer_nat iptables -A FORWARD -p icmp -j DROP") == 0);
195         assert(system("ip netns exec nut_nat iptables -A FORWARD -p icmp -j DROP") == 0);
196
197         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
198         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
199         run_node_in_namespace_thread(&netns_relay_nut_invite);
200         sleep(1);
201         assert(relay_nut_invite_arg.invite_str);
202         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
203
204         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
205         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
206         run_node_in_namespace_thread(&netns_relay_peer_invite);
207         sleep(1);
208         assert(relay_peer_invite_arg.invite_str);
209         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
210
211         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
212         run_node_in_namespace_thread(&netns_relay_handle);
213
214         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
215         run_node_in_namespace_thread(&netns_peer_handle);
216
217         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
218         run_node_in_namespace_thread(&netns_nut_handle);
219
220         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
221         test_pmtu_relay_running = false;
222         test_pmtu_peer_running = false;
223
224         sleep(1);
225         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
226         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
227         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
228         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
229
230         return true;
231 }
232
233 /* Test Steps for optimal PMTU discovery Test Case # 3 -
234     Validating NUT MTU parameters with MTU size of NAT = 1250 under designed
235     network topology */
236 static void test_case_optimal_pmtu_03(void **state) {
237         execute_test(test_steps_optimal_pmtu_03, state);
238         return;
239 }
240
241 /* Test Steps for optimal PMTU discovery Test Case # 3 -
242     Test Steps:
243     1. Create NAT setup and run each node instances in discrete namespace,
244     2. Change the MTU size of NUT's NAT to 1250
245     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
246     4. Send the analyzed MTU parameters mesh event information to test driver
247     Expected Result:
248       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
249       the expected range
250 */
251 static bool test_steps_optimal_pmtu_03(void) {
252         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
253         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
254         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
255
256         assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1250") == 0);
257
258         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
259         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
260         run_node_in_namespace_thread(&netns_relay_nut_invite);
261         sleep(1);
262         assert(relay_nut_invite_arg.invite_str);
263         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
264
265         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
266         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
267         run_node_in_namespace_thread(&netns_relay_peer_invite);
268         sleep(1);
269         assert(relay_peer_invite_arg.invite_str);
270         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
271
272         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
273         run_node_in_namespace_thread(&netns_relay_handle);
274
275         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
276         run_node_in_namespace_thread(&netns_peer_handle);
277
278         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
279         run_node_in_namespace_thread(&netns_nut_handle);
280
281         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
282         test_pmtu_relay_running = false;
283         test_pmtu_peer_running = false;
284
285         sleep(1);
286         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1200, 1250);
287         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1200, 1250);
288
289         return true;
290 }
291
292 /* Test Steps for optimal PMTU discovery Test Case # 4 -
293     Validating NUT MTU parameters with MTU size of NAT = 1000 under designed
294     network topology */
295 static void test_case_optimal_pmtu_04(void **state) {
296         execute_test(test_steps_optimal_pmtu_04, state);
297         return;
298 }
299
300 /* Test Steps for optimal PMTU discovery Test Case # 4 -
301     Test Steps:
302     1. Create NAT setup and run each node instances in discrete namespace,
303     2. Change the MTU size of NUT's NAT to 1000
304     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
305     4. Send the analyzed MTU parameters mesh event information to test driver
306     Expected Result:
307       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
308       the expected range
309 */
310 static bool test_steps_optimal_pmtu_04(void) {
311         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
312         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
313         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
314
315         assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 1000") == 0);
316
317         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
318         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
319         run_node_in_namespace_thread(&netns_relay_nut_invite);
320         sleep(1);
321         assert(relay_nut_invite_arg.invite_str);
322         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
323
324         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
325         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
326         run_node_in_namespace_thread(&netns_relay_peer_invite);
327         sleep(1);
328         assert(relay_peer_invite_arg.invite_str);
329         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
330
331         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
332         run_node_in_namespace_thread(&netns_relay_handle);
333
334         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
335         run_node_in_namespace_thread(&netns_peer_handle);
336
337         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
338         run_node_in_namespace_thread(&netns_nut_handle);
339
340         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
341         test_pmtu_relay_running = false;
342         test_pmtu_peer_running = false;
343
344         sleep(1);
345         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 925, 1000);
346         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 925, 1000);
347
348         return true;
349 }
350
351 /* Test Steps for optimal PMTU discovery Test Case # 5 -
352     Validating NUT MTU parameters with MTU size of NAT = 800 under designed
353     network topology */
354 static void test_case_optimal_pmtu_05(void **state) {
355         execute_test(test_steps_optimal_pmtu_05, state);
356         return;
357 }
358
359 /* Test Steps for optimal PMTU discovery Test Case # 5 -
360     Test Steps:
361     1. Create NAT setup and run each node instances in discrete namespace,
362     2. Change the MTU size of NUT's NAT to 800
363     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
364     4. Send the analyzed MTU parameters mesh event information to test driver
365     Expected Result:
366       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
367       the expected range
368 */
369 static bool test_steps_optimal_pmtu_05(void) {
370         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
371         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
372         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
373
374         assert(system("ip netns exec nut_nat ifconfig eth_nut mtu 750") == 0);
375
376         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
377         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
378         run_node_in_namespace_thread(&netns_relay_nut_invite);
379         sleep(1);
380         assert(relay_nut_invite_arg.invite_str);
381         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
382
383         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
384         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
385         run_node_in_namespace_thread(&netns_relay_peer_invite);
386         sleep(1);
387         assert(relay_peer_invite_arg.invite_str);
388         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
389
390         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
391         run_node_in_namespace_thread(&netns_relay_handle);
392
393         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
394         run_node_in_namespace_thread(&netns_peer_handle);
395
396         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
397         run_node_in_namespace_thread(&netns_nut_handle);
398
399         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
400         test_pmtu_relay_running = false;
401         test_pmtu_peer_running = false;
402
403         sleep(1);
404         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 700, 750);
405         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 700, 750);
406
407         return true;
408 }
409
410 /* Test Steps for optimal PMTU discovery Test Case # 6 -
411     Flushing the tracked connections via NUT NAT for every 60 seconds */
412 static void test_case_optimal_pmtu_06(void **state) {
413         execute_test(test_steps_optimal_pmtu_06, state);
414         return;
415 }
416
417 static bool run_conntrack;
418 static pthread_t pmtu_test_case_conntrack_thread;
419 static void *conntrack_flush(void *arg) {
420         // flushes mappings for every 60 seconds
421
422         while(run_conntrack) {
423                 sleep(100);
424                 assert(system("ip netns exec nut_nat conntrack -F") == 0);
425                 assert(system("ip netns exec peer_nat conntrack -F") == 0);
426         }
427
428         pthread_exit(NULL);
429 }
430
431 /* Test Steps for optimal PMTU discovery Test Case # 6 -
432     Test Steps:
433     1. Create NAT setup and Launch conntrack thread which flushes the tracked connections for every 90 seconds
434     2. Run each node instances in discrete namespace,
435     3. Open a channel from NUT to peer and hence triggering Peer to peer connection
436     4. Send the analyzed MTU parameters mesh event information to test driver
437     Expected Result:
438       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
439       the expected range
440 */
441 static bool test_steps_optimal_pmtu_06(void) {
442         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
443         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
444         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
445
446         run_conntrack = true;
447         assert(!pthread_create(&pmtu_test_case_conntrack_thread, NULL, conntrack_flush, NULL));
448
449         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
450         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
451         run_node_in_namespace_thread(&netns_relay_nut_invite);
452         sleep(1);
453         assert(relay_nut_invite_arg.invite_str);
454         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
455
456         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
457         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
458         run_node_in_namespace_thread(&netns_relay_peer_invite);
459         sleep(1);
460         assert(relay_peer_invite_arg.invite_str);
461         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
462
463         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
464         run_node_in_namespace_thread(&netns_relay_handle);
465
466         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
467         run_node_in_namespace_thread(&netns_peer_handle);
468
469         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
470         run_node_in_namespace_thread(&netns_nut_handle);
471
472         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
473         test_pmtu_relay_running = false;
474         test_pmtu_peer_running = false;
475         run_conntrack = false;
476         pthread_join(pmtu_test_case_conntrack_thread, NULL);
477
478         sleep(1);
479
480         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1440, 1500);
481         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1440, 1500);
482         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_ping.probes, 38, 42);
483         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_ping.probes, 38, 42);
484
485         return true;
486 }
487
488 /* Test Steps for optimal PMTU discovery Test Case # 7 -
489     NUT sending data to peer node via channel for every 30 seconds
490     */
491 static void test_case_optimal_pmtu_07(void **state) {
492         execute_test(test_steps_optimal_pmtu_07, state);
493         return;
494 }
495
496 /* Test Steps for optimal PMTU discovery Test Case # 7 -
497     Test Steps:
498     1. Create NAT setup and run each node instances in discrete namespace.
499     2. Open a channel from NUT to peer and hence triggering Peer to peer connection
500     3. Send data periodically via channel from NUT to peer node.
501     4. Send the analyzed MTU parameters mesh event information to test driver
502     Expected Result:
503       NUT and Peer should be able to hole puch the NATs and MTU parameters should be in
504       the expected range
505 */
506 static bool test_steps_optimal_pmtu_07(void) {
507         mesh_arg_t relay_arg = {.node_name = "relay", .confbase = "relay", .app_name = "relay", .dev_class = 0 };
508         mesh_arg_t peer_arg = {.node_name = "peer", .confbase = "peer", .app_name = "peer", .dev_class = 1 };
509         mesh_arg_t nut_arg = {.node_name = "nut", .confbase = "nut", .app_name = "nut", .dev_class = 1 };
510
511         ping_channel_enable_07 = true;
512
513         mesh_invite_arg_t relay_nut_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "nut" };
514         netns_thread_t netns_relay_nut_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_nut_invite_arg};
515         run_node_in_namespace_thread(&netns_relay_nut_invite);
516         sleep(1);
517         assert(relay_nut_invite_arg.invite_str);
518         nut_arg.join_invitation = relay_nut_invite_arg.invite_str;
519
520         mesh_invite_arg_t relay_peer_invite_arg = {.mesh_arg = &relay_arg, .invitee_name = "peer" };
521         netns_thread_t netns_relay_peer_invite = {.namespace_name = "relay", .netns_thread = gen_inv, .arg = &relay_peer_invite_arg};
522         run_node_in_namespace_thread(&netns_relay_peer_invite);
523         sleep(1);
524         assert(relay_peer_invite_arg.invite_str);
525         peer_arg.join_invitation = relay_peer_invite_arg.invite_str;
526
527         netns_thread_t netns_relay_handle = {.namespace_name = "relay", .netns_thread = node_sim_pmtu_relay_01, .arg = &relay_arg};
528         run_node_in_namespace_thread(&netns_relay_handle);
529
530         netns_thread_t netns_peer_handle = {.namespace_name = "peer", .netns_thread = node_sim_pmtu_peer_01, .arg = &peer_arg};
531         run_node_in_namespace_thread(&netns_peer_handle);
532
533         netns_thread_t netns_nut_handle = {.namespace_name = "nut", .netns_thread = node_sim_pmtu_nut_01, .arg = &nut_arg};
534         run_node_in_namespace_thread(&netns_nut_handle);
535
536         assert(wait_sync_flag(&test_pmtu_nut_closed, 300));
537         test_pmtu_relay_running = false;
538         test_pmtu_peer_running = false;
539
540         sleep(1);
541         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_size, 1450, 1501);
542         assert_in_range(node_pmtu[NODE_PMTU_PEER].mtu_discovery.probes, 120, 160);
543         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_size, 1450, 1501);
544         assert_in_range(node_pmtu[NODE_PMTU_RELAY].mtu_discovery.probes, 120, 160);
545
546         return true;
547 }
548
549 // Optimal PMTU test case driver
550
551 int test_optimal_pmtu(void) {
552         interface_t nut_ifs[] = { { .if_peer = "nut_nat", .fetch_ip_netns_name = "nut_nat" } };
553         namespace_t nut = {
554                 .name = "nut",
555                 .type = HOST,
556                 .interfaces = nut_ifs,
557                 .interfaces_no = 1,
558         };
559
560         interface_t peer_ifs[] = { { .if_peer = "peer_nat", .fetch_ip_netns_name = "peer_nat" } };
561         namespace_t peer = {
562                 .name = "peer",
563                 .type = HOST,
564                 .interfaces = peer_ifs,
565                 .interfaces_no = 1,
566         };
567
568         interface_t relay_ifs[] = { { .if_peer = "wan_bridge" } };
569         namespace_t relay = {
570                 .name = "relay",
571                 .type = HOST,
572                 .interfaces = relay_ifs,
573                 .interfaces_no = 1,
574         };
575
576         netns_fullcone_handle_t nut_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "nut" };
577         netns_fullcone_handle_t *nut_nat_args[] = { &nut_nat_fullcone, NULL };
578         interface_t nut_nat_ifs[] = { { .if_peer = "nut", .fetch_ip_netns_name = "nut_nat" }, { .if_peer = "wan_bridge" } };
579         namespace_t nut_nat = {
580                 .name = "nut_nat",
581                 .type = FULL_CONE,
582                 .nat_arg = nut_nat_args,
583                 .static_config_net_addr = "192.168.1.0/24",
584                 .interfaces = nut_nat_ifs,
585                 .interfaces_no = 2,
586         };
587
588         netns_fullcone_handle_t peer_nat_fullcone = { .snat_to_source = "wan_bridge", .dnat_to_destination = "peer" };
589         netns_fullcone_handle_t *peer_nat_args[] = { &peer_nat_fullcone, NULL };
590         interface_t peer_nat_ifs[] = { { .if_peer = "peer", .fetch_ip_netns_name = "peer_nat" }, { .if_peer = "wan_bridge" } };
591         namespace_t peer_nat = {
592                 .name = "peer_nat",
593                 .type = FULL_CONE,
594                 .nat_arg = peer_nat_args,
595                 .static_config_net_addr = "192.168.1.0/24",
596                 .interfaces = peer_nat_ifs,
597                 .interfaces_no = 2,
598         };
599
600         interface_t wan_ifs[] = { { .if_peer = "peer_nat" }, { .if_peer = "nut_nat" }, { .if_peer = "relay" } };
601         namespace_t wan_bridge = {
602                 .name = "wan_bridge",
603                 .type = BRIDGE,
604                 .interfaces = wan_ifs,
605                 .interfaces_no = 3,
606         };
607
608         namespace_t test_optimal_pmtu_1_nodes[] = { nut_nat, peer_nat, wan_bridge, nut, peer, relay };
609
610         netns_state_t test_pmtu_nodes = {
611                 .test_case_name =  "test_case_optimal_pmtu",
612                 .namespaces =  test_optimal_pmtu_1_nodes,
613                 .num_namespaces = 6,
614         };
615         test_pmtu_state = &test_pmtu_nodes;
616
617         const struct CMUnitTest blackbox_group0_tests[] = {
618                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_01, setup_test, teardown_test,
619                 (void *)&test_pmtu_state),
620                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_02, setup_test, teardown_test,
621                 (void *)&test_pmtu_state),
622                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_03, setup_test, teardown_test,
623                 (void *)&test_pmtu_state),
624                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_04, setup_test, teardown_test,
625                 (void *)&test_pmtu_state),
626                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_05, setup_test, teardown_test,
627                 (void *)&test_pmtu_state),
628                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_06, setup_test, teardown_test,
629                 (void *)&test_pmtu_state),
630                 cmocka_unit_test_prestate_setup_teardown(test_case_optimal_pmtu_07, setup_test, teardown_test,
631                 (void *)&test_pmtu_state),
632         };
633         total_tests += sizeof(blackbox_group0_tests) / sizeof(blackbox_group0_tests[0]);
634
635         return cmocka_run_group_tests(blackbox_group0_tests, NULL, NULL);
636 }