1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2024 Nordic Semiconductor
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_test, CONFIG_NET_PMTU_LOG_LEVEL);
11 
12 #include <zephyr/types.h>
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <zephyr/linker/sections.h>
18 
19 #include <zephyr/ztest.h>
20 
21 #include <zephyr/net/net_if.h>
22 #include <zephyr/net/net_pkt.h>
23 #include <zephyr/net/net_ip.h>
24 #include <zephyr/net/net_core.h>
25 #include <zephyr/net/ethernet.h>
26 #include <zephyr/net/dummy.h>
27 #include <zephyr/net/loopback.h>
28 #include <zephyr/net/net_mgmt.h>
29 #include <zephyr/net/net_event.h>
30 #include <zephyr/net/socket.h>
31 
32 #include <zephyr/random/random.h>
33 
34 #include "../../socket/socket_helpers.h"
35 
36 #include "route.h"
37 #include "icmpv6.h"
38 #include "icmpv4.h"
39 #include "ipv6.h"
40 #include "ipv4.h"
41 #include "pmtu.h"
42 
43 #define NET_LOG_ENABLED 1
44 #include "net_private.h"
45 
46 #if defined(CONFIG_BOARD_NATIVE_SIM) || defined(CONFIG_BOARD_NATIVE_SIM_NATIVE_64)
47 #define WAIT_PROPERLY 0
48 #else
49 #define WAIT_PROPERLY 1
50 #endif
51 
52 #if defined(CONFIG_NET_PMTU_LOG_LEVEL_DBG)
53 #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
54 #else
55 #define DBG(fmt, ...)
56 #endif
57 
58 /* This is a helper function to get the MTU value for the given destination.
59  * It is implemented in tcp.c file.
60  */
61 extern uint16_t net_tcp_get_mtu(struct sockaddr *dst);
62 
63 /* Small sleep between tests makes sure that the PMTU destination
64  * cache entries are separated from each other.
65  */
66 #define SMALL_SLEEP K_MSEC(5)
67 
68 static struct in_addr dest_ipv4_addr1 = { { { 198, 51, 100, 1 } } };
69 static struct in_addr dest_ipv4_addr2 = { { { 198, 51, 100, 2 } } };
70 static struct in_addr dest_ipv4_addr3 = { { { 198, 51, 100, 3 } } };
71 static struct in_addr dest_ipv4_addr4 = { { { 198, 51, 100, 4 } } };
72 static struct in_addr dest_ipv4_addr_not_found = { { { 1, 2, 3, 4 } } };
73 
74 static struct in6_addr dest_ipv6_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 0x01, 0, 0, 0,
75 					0, 0, 0, 0, 0, 0, 0, 0x1 } } };
76 static struct in6_addr dest_ipv6_addr2 = { { { 0x20, 0x01, 0x0d, 0xb8, 0x01, 0, 0, 0,
77 					0, 0, 0, 0, 0, 0, 0, 0x2 } } };
78 static struct in6_addr dest_ipv6_addr3 = { { { 0x20, 0x01, 0x0d, 0xb8, 0x01, 0, 0, 0,
79 					0, 0, 0, 0, 0, 0, 0, 0x3 } } };
80 static struct in6_addr dest_ipv6_addr4 = { { { 0x20, 0x01, 0x0d, 0xb8, 0x01, 0, 0, 0,
81 					0, 0, 0, 0, 0, 0, 0, 0x4 } } };
82 static struct in6_addr dest_ipv6_addr_not_found = { { { 0x20, 0x01, 0x0d, 0xb8, 0xde,
83 			0xad, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x4 } } };
84 
85 static struct net_if *target_iface;
86 static char target_iface_name[CONFIG_NET_INTERFACE_NAME_LEN + 1];
87 
88 K_SEM_DEFINE(wait_data, 0, UINT_MAX);
89 
90 #define PKT_WAIT_TIME K_MSEC(500)
91 #define WAIT_TIME 500
92 #define WAIT_TIME_LONG MSEC_PER_SEC
93 #define MY_PORT 1969
94 #define PEER_PORT 2024
95 #define PEER_IPV6_ADDR "::1"
96 #define MY_IPV6_ADDR "::1"
97 #define MY_IPV4_ADDR "127.0.0.1"
98 #define PEER_IPV4_ADDR "127.0.0.1"
99 
100 #define THREAD_SLEEP 50 /* ms */
101 
102 static K_SEM_DEFINE(wait_pmtu_changed, 0, UINT_MAX);
103 static bool is_pmtu_changed;
104 
ipv6_pmtu_changed(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)105 static void ipv6_pmtu_changed(struct net_mgmt_event_callback *cb,
106 			      uint32_t mgmt_event,
107 			      struct net_if *iface)
108 {
109 	ARG_UNUSED(cb);
110 	ARG_UNUSED(iface);
111 
112 	if (mgmt_event != NET_EVENT_IPV6_PMTU_CHANGED) {
113 		return;
114 	}
115 
116 	NET_DBG("IPv6 PMTU changed event received");
117 
118 	k_sem_give(&wait_pmtu_changed);
119 	is_pmtu_changed = true;
120 
121 	/* Let the network stack to proceed */
122 	k_msleep(THREAD_SLEEP);
123 }
124 
ipv4_pmtu_changed(struct net_mgmt_event_callback * cb,uint32_t mgmt_event,struct net_if * iface)125 static void ipv4_pmtu_changed(struct net_mgmt_event_callback *cb,
126 			      uint32_t mgmt_event,
127 			      struct net_if *iface)
128 {
129 	ARG_UNUSED(cb);
130 	ARG_UNUSED(iface);
131 
132 	if (mgmt_event != NET_EVENT_IPV4_PMTU_CHANGED) {
133 		return;
134 	}
135 
136 	NET_DBG("IPv4 PMTU changed event received");
137 
138 	k_sem_give(&wait_pmtu_changed);
139 	is_pmtu_changed = true;
140 
141 	/* Let the network stack to proceed */
142 	k_msleep(THREAD_SLEEP);
143 }
144 
145 static struct mgmt_events {
146 	uint32_t event;
147 	net_mgmt_event_handler_t handler;
148 	struct net_mgmt_event_callback cb;
149 } mgmt_events[] = {
150 	{ .event = NET_EVENT_IPV6_PMTU_CHANGED, .handler = ipv6_pmtu_changed },
151 	{ .event = NET_EVENT_IPV4_PMTU_CHANGED, .handler = ipv4_pmtu_changed },
152 };
153 
iface2str(struct net_if * iface)154 static const char *iface2str(struct net_if *iface)
155 {
156 	if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) {
157 		return "No L2";
158 	}
159 
160 	return "<unknown type>";
161 }
162 
iface_cb(struct net_if * iface,void * user_data)163 static void iface_cb(struct net_if *iface, void *user_data)
164 {
165 	static int if_count;
166 
167 	NET_DBG("Interface %p (%s) [%d]", iface, iface2str(iface),
168 		net_if_get_by_iface(iface));
169 
170 	switch (if_count) {
171 	case 0:
172 		target_iface = iface;
173 		(void)net_if_get_name(iface, target_iface_name,
174 				      CONFIG_NET_INTERFACE_NAME_LEN);
175 		break;
176 	}
177 
178 	if_count++;
179 }
180 
setup_mgmt_events(void)181 static void setup_mgmt_events(void)
182 {
183 	static bool setup_done;
184 
185 	if (setup_done) {
186 		return;
187 	}
188 
189 	setup_done = true;
190 
191 	ARRAY_FOR_EACH(mgmt_events, i) {
192 		net_mgmt_init_event_callback(&mgmt_events[i].cb,
193 					     mgmt_events[i].handler,
194 					     mgmt_events[i].event);
195 
196 		net_mgmt_add_event_callback(&mgmt_events[i].cb);
197 	}
198 }
199 
test_setup(void)200 static void *test_setup(void)
201 {
202 	net_if_foreach(iface_cb, NULL);
203 
204 	zassert_not_null(target_iface, "Interface is NULL");
205 
206 	return NULL;
207 }
208 
ZTEST(net_pmtu_test_suite,test_pmtu_01_ipv4_get_entry)209 ZTEST(net_pmtu_test_suite, test_pmtu_01_ipv4_get_entry)
210 {
211 #if defined(CONFIG_NET_IPV4_PMTU)
212 	struct net_pmtu_entry *entry;
213 	struct sockaddr_in dest_ipv4;
214 
215 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr1);
216 	dest_ipv4.sin_family = AF_INET;
217 
218 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv4);
219 	zassert_is_null(entry, "PMTU IPv4 entry is not NULL");
220 
221 	k_sleep(SMALL_SLEEP);
222 #else
223 	ztest_test_skip();
224 #endif
225 }
226 
ZTEST(net_pmtu_test_suite,test_pmtu_01_ipv6_get_entry)227 ZTEST(net_pmtu_test_suite, test_pmtu_01_ipv6_get_entry)
228 {
229 #if defined(CONFIG_NET_IPV6_PMTU)
230 	struct net_pmtu_entry *entry;
231 	struct sockaddr_in6 dest_ipv6;
232 
233 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr1);
234 	dest_ipv6.sin6_family = AF_INET6;
235 
236 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv6);
237 	zassert_is_null(entry, "PMTU IPv6 entry is not NULL");
238 
239 	k_sleep(SMALL_SLEEP);
240 #else
241 	ztest_test_skip();
242 #endif
243 }
244 
ZTEST(net_pmtu_test_suite,test_pmtu_02_ipv4_update_entry)245 ZTEST(net_pmtu_test_suite, test_pmtu_02_ipv4_update_entry)
246 {
247 #if defined(CONFIG_NET_IPV4_PMTU)
248 	struct sockaddr_in dest_ipv4;
249 	int ret;
250 
251 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr1);
252 	dest_ipv4.sin_family = AF_INET;
253 
254 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv4, 1300);
255 	zassert_equal(ret, 0, "PMTU IPv4 MTU update failed (%d)", ret);
256 
257 	k_sleep(SMALL_SLEEP);
258 #else
259 	ztest_test_skip();
260 #endif
261 }
262 
ZTEST(net_pmtu_test_suite,test_pmtu_02_ipv6_update_entry)263 ZTEST(net_pmtu_test_suite, test_pmtu_02_ipv6_update_entry)
264 {
265 #if defined(CONFIG_NET_IPV6_PMTU)
266 	struct sockaddr_in6 dest_ipv6;
267 	int ret;
268 
269 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr1);
270 	dest_ipv6.sin6_family = AF_INET6;
271 
272 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv6, 1600);
273 	zassert_equal(ret, 0, "PMTU IPv6 MTU update failed (%d)", ret);
274 
275 	k_sleep(SMALL_SLEEP);
276 #else
277 	ztest_test_skip();
278 #endif
279 }
280 
ZTEST(net_pmtu_test_suite,test_pmtu_03_ipv4_create_more_entries)281 ZTEST(net_pmtu_test_suite, test_pmtu_03_ipv4_create_more_entries)
282 {
283 #if defined(CONFIG_NET_IPV4_PMTU)
284 	struct sockaddr_in dest_ipv4;
285 	struct net_pmtu_entry *entry;
286 	uint16_t mtu;
287 	int ret;
288 
289 	dest_ipv4.sin_family = AF_INET;
290 
291 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr1);
292 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv4, 1300);
293 	zassert_equal(ret, 1300, "PMTU IPv4 MTU update failed (%d)", ret);
294 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv4);
295 	zassert_equal(entry->mtu, 1300, "PMTU IPv4 MTU is not correct (%d)",
296 		      entry->mtu);
297 
298 	k_sleep(SMALL_SLEEP);
299 
300 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr2);
301 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv4, 1400);
302 	zassert_equal(ret, 0, "PMTU IPv4 MTU update failed (%d)", ret);
303 	mtu = net_pmtu_get_mtu((struct sockaddr *)&dest_ipv4);
304 	zassert_equal(mtu, 1400, "PMTU IPv4 MTU is not correct (%d)", mtu);
305 
306 	k_sleep(SMALL_SLEEP);
307 
308 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr3);
309 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv4, 1500);
310 	zassert_equal(ret, 0, "PMTU IPv4 MTU update failed (%d)", ret);
311 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv4);
312 	zassert_equal(entry->mtu, 1500, "PMTU IPv4 MTU is not correct (%d)",
313 		      entry->mtu);
314 
315 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr_not_found);
316 	ret = net_pmtu_get_mtu((struct sockaddr *)&dest_ipv4);
317 	zassert_equal(ret, -ENOENT, "PMTU IPv4 MTU update succeed (%d)", ret);
318 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv4);
319 	zassert_equal(entry, NULL, "PMTU IPv4 MTU update succeed");
320 #else
321 	ztest_test_skip();
322 #endif
323 }
324 
ZTEST(net_pmtu_test_suite,test_pmtu_03_ipv6_create_more_entries)325 ZTEST(net_pmtu_test_suite, test_pmtu_03_ipv6_create_more_entries)
326 {
327 #if defined(CONFIG_NET_IPV6_PMTU)
328 	struct sockaddr_in6 dest_ipv6;
329 	struct net_pmtu_entry *entry;
330 	uint16_t mtu;
331 	int ret;
332 
333 	dest_ipv6.sin6_family = AF_INET6;
334 
335 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr1);
336 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv6, 1600);
337 	zassert_equal(ret, 1600, "PMTU IPv6 MTU update failed (%d)", ret);
338 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv6);
339 	zassert_equal(entry->mtu, 1600, "PMTU IPv6 MTU is not correct (%d)",
340 		      entry->mtu);
341 
342 	k_sleep(SMALL_SLEEP);
343 
344 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr2);
345 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv6, 1700);
346 	zassert_equal(ret, 0, "PMTU IPv6 MTU update failed (%d)", ret);
347 	mtu = net_pmtu_get_mtu((struct sockaddr *)&dest_ipv6);
348 	zassert_equal(mtu, 1700, "PMTU IPv6 MTU is not correct (%d)", mtu);
349 
350 	k_sleep(SMALL_SLEEP);
351 
352 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr3);
353 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv6, 1800);
354 	zassert_equal(ret, 0, "PMTU IPv6 MTU update failed (%d)", ret);
355 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv6);
356 	zassert_equal(entry->mtu, 1800, "PMTU IPv6 MTU is not correct (%d)",
357 		      entry->mtu);
358 
359 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr_not_found);
360 	ret = net_pmtu_get_mtu((struct sockaddr *)&dest_ipv6);
361 	zassert_equal(ret, -ENOENT, "PMTU IPv6 MTU update succeed (%d)", ret);
362 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv6);
363 	zassert_equal(entry, NULL, "PMTU IPv6 MTU update succeed");
364 #else
365 	ztest_test_skip();
366 #endif
367 }
368 
ZTEST(net_pmtu_test_suite,test_pmtu_04_ipv4_overflow)369 ZTEST(net_pmtu_test_suite, test_pmtu_04_ipv4_overflow)
370 {
371 #if defined(CONFIG_NET_IPV4_PMTU)
372 	struct sockaddr_in dest_ipv4;
373 	struct net_pmtu_entry *entry;
374 	int ret;
375 
376 	dest_ipv4.sin_family = AF_INET;
377 
378 	/* Create more entries than we have space */
379 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr4);
380 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv4, 1450);
381 	zassert_equal(ret, 0, "PMTU IPv4 MTU update failed (%d)", ret);
382 
383 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv4);
384 	zassert_equal(entry->mtu, 1450, "PMTU IPv4 MTU is not correct (%d)",
385 		      entry->mtu);
386 
387 	k_sleep(SMALL_SLEEP);
388 
389 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr1);
390 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv4);
391 	zassert_is_null(entry, "PMTU IPv4 MTU found when it should not be");
392 #else
393 	ztest_test_skip();
394 #endif
395 }
396 
ZTEST(net_pmtu_test_suite,test_pmtu_04_ipv6_overflow)397 ZTEST(net_pmtu_test_suite, test_pmtu_04_ipv6_overflow)
398 {
399 #if defined(CONFIG_NET_IPV6_PMTU)
400 	struct sockaddr_in6 dest_ipv6;
401 	struct net_pmtu_entry *entry;
402 	int ret;
403 
404 	dest_ipv6.sin6_family = AF_INET6;
405 
406 	/* Create more entries than we have space */
407 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr4);
408 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv6, 1650);
409 	zassert_equal(ret, 0, "PMTU IPv6 MTU update failed (%d)", ret);
410 
411 	entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv6);
412 	zassert_equal(entry->mtu, 1650, "PMTU IPv6 MTU is not correct (%d)",
413 		      entry->mtu);
414 
415 	k_sleep(SMALL_SLEEP);
416 
417 	/* If we have IPv4 PMTU enabled, then the oldest one is an IPv4 entry.
418 	 */
419 	if (IS_ENABLED(CONFIG_NET_IPV4_PMTU)) {
420 		struct sockaddr_in dest_ipv4;
421 
422 		dest_ipv4.sin_family = AF_INET;
423 
424 		net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr2);
425 		entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv4);
426 	} else {
427 		net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr1);
428 		entry = net_pmtu_get_entry((struct sockaddr *)&dest_ipv6);
429 	}
430 
431 	zassert_is_null(entry, "PMTU IPv6 MTU found when it should not be");
432 #else
433 	ztest_test_skip();
434 #endif
435 }
436 
test_bind(int sock,struct sockaddr * addr,socklen_t addrlen)437 static void test_bind(int sock, struct sockaddr *addr, socklen_t addrlen)
438 {
439 	int ret;
440 
441 	ret = zsock_bind(sock, addr, addrlen);
442 	zassert_equal(ret, 0, "bind failed with error %d", errno);
443 }
444 
test_listen(int sock)445 static void test_listen(int sock)
446 {
447 	zassert_equal(zsock_listen(sock, 1),
448 		      0,
449 		      "listen failed with error %d", errno);
450 }
451 
test_connect(int sock,struct sockaddr * addr,socklen_t addrlen)452 static void test_connect(int sock, struct sockaddr *addr, socklen_t addrlen)
453 {
454 	zassert_equal(zsock_connect(sock, addr, addrlen),
455 		      0,
456 		      "connect failed with error %d", errno);
457 
458 	if (IS_ENABLED(CONFIG_NET_TC_THREAD_PREEMPTIVE)) {
459 		/* Let the connection proceed */
460 		k_msleep(THREAD_SLEEP);
461 	}
462 }
463 
test_accept(int sock,int * new_sock,struct sockaddr * addr,socklen_t * addrlen)464 static void test_accept(int sock, int *new_sock, struct sockaddr *addr,
465 			socklen_t *addrlen)
466 {
467 	zassert_not_null(new_sock, "null newsock");
468 
469 	*new_sock = zsock_accept(sock, addr, addrlen);
470 	zassert_true(*new_sock >= 0, "accept failed");
471 }
472 
473 #if defined(CONFIG_NET_IPV6_PMTU)
get_v6_send_recv_sock(int * srv_sock,struct sockaddr_in6 * my_saddr,struct sockaddr_in6 * peer_saddr,uint16_t my_port,uint16_t peer_port)474 static int get_v6_send_recv_sock(int *srv_sock,
475 				 struct sockaddr_in6 *my_saddr,
476 				 struct sockaddr_in6 *peer_saddr,
477 				 uint16_t my_port,
478 				 uint16_t peer_port)
479 {
480 	struct sockaddr addr;
481 	socklen_t addrlen = sizeof(addr);
482 	int new_sock;
483 	int c_sock;
484 	int s_sock;
485 
486 	prepare_sock_tcp_v6(PEER_IPV6_ADDR, peer_port, &s_sock, peer_saddr);
487 	test_bind(s_sock, (struct sockaddr *)peer_saddr, sizeof(*peer_saddr));
488 	test_listen(s_sock);
489 
490 	prepare_sock_tcp_v6(MY_IPV6_ADDR, my_port, &c_sock, my_saddr);
491 	test_bind(c_sock, (struct sockaddr *)my_saddr, sizeof(*my_saddr));
492 	test_connect(c_sock, (struct sockaddr *)peer_saddr, sizeof(*peer_saddr));
493 
494 	test_accept(s_sock, &new_sock, &addr, &addrlen);
495 	zassert_equal(addrlen, sizeof(struct sockaddr_in6), "wrong addrlen");
496 
497 	*srv_sock = new_sock;
498 
499 	return c_sock;
500 }
501 
create_icmpv6_ptb(struct net_if * iface,struct sockaddr_in6 * src,struct sockaddr_in6 * dst,uint32_t mtu,struct net_pkt ** pkt)502 static int create_icmpv6_ptb(struct net_if *iface,
503 			     struct sockaddr_in6 *src,
504 			     struct sockaddr_in6 *dst,
505 			     uint32_t mtu,
506 			     struct net_pkt **pkt)
507 {
508 	struct net_icmpv6_ptb ptb_hdr;
509 	struct net_pkt *ptb_pkt;
510 	struct in6_addr *dest6;
511 	struct in6_addr *src6;
512 	int ret;
513 
514 	ptb_pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_ipv6_hdr) +
515 					    sizeof(struct net_icmp_hdr) +
516 					    sizeof(struct net_icmpv6_ptb),
517 					    AF_INET6, IPPROTO_ICMPV6,
518 					    PKT_WAIT_TIME);
519 	if (ptb_pkt == NULL) {
520 		NET_DBG("No buffer");
521 		return -ENOMEM;
522 	}
523 
524 	dest6 = &dst->sin6_addr;
525 	src6 = &src->sin6_addr;
526 
527 	ret = net_ipv6_create(ptb_pkt, src6, dest6);
528 	if (ret < 0) {
529 		LOG_ERR("Cannot create IPv6 pkt (%d)", ret);
530 		return ret;
531 	}
532 
533 	ret = net_icmpv6_create(ptb_pkt, NET_ICMPV6_PACKET_TOO_BIG, 0);
534 	if (ret < 0) {
535 		LOG_ERR("Cannot create ICMPv6 pkt (%d)", ret);
536 		return ret;
537 	}
538 
539 	ptb_hdr.mtu = htonl(mtu);
540 
541 	ret = net_pkt_write(ptb_pkt, &ptb_hdr, sizeof(ptb_hdr));
542 	if (ret < 0) {
543 		LOG_ERR("Cannot write payload (%d)", ret);
544 		return ret;
545 	}
546 
547 	net_pkt_cursor_init(ptb_pkt);
548 	net_ipv6_finalize(ptb_pkt, IPPROTO_ICMPV6);
549 
550 	net_pkt_set_iface(ptb_pkt, iface);
551 
552 	*pkt = ptb_pkt;
553 
554 	return 0;
555 }
556 #endif
557 
ZTEST(net_pmtu_test_suite,test_pmtu_05_ipv6_tcp)558 ZTEST(net_pmtu_test_suite, test_pmtu_05_ipv6_tcp)
559 {
560 #if defined(CONFIG_NET_IPV6_PMTU)
561 	struct sockaddr_in6 dest_ipv6;
562 	struct sockaddr_in6 s_saddr = { 0 };  /* peer */
563 	struct sockaddr_in6 c_saddr = { 0 };  /* this host */
564 	struct net_pkt *pkt = NULL;
565 	int client_sock, server_sock;
566 	uint16_t mtu;
567 	int ret;
568 
569 	dest_ipv6.sin6_family = AF_INET6;
570 
571 	client_sock = get_v6_send_recv_sock(&server_sock, &c_saddr, &s_saddr,
572 					    MY_PORT, PEER_PORT);
573 	zassert_true(client_sock >= 0, "Failed to create client socket");
574 
575 	/* Set initial MTU for the destination */
576 	ret = net_pmtu_update_mtu((struct sockaddr *)&c_saddr, 4096);
577 	zassert_true(ret >= 0, "PMTU IPv6 MTU update failed (%d)", ret);
578 
579 	/* Send an ICMPv6 "Packet too big" message from server to client which
580 	 * will update the PMTU entry.
581 	 */
582 	ret = create_icmpv6_ptb(target_iface, &s_saddr, &c_saddr, 2048, &pkt);
583 	zassert_equal(ret, 0, "Failed to create ICMPv6 PTB message");
584 
585 	ret = net_send_data(pkt);
586 	zassert_equal(ret, 0, "Failed to send PTB message");
587 
588 	/* Check that the PMTU entry has been updated */
589 	mtu = net_tcp_get_mtu((struct sockaddr *)&s_saddr);
590 	zassert_equal(mtu, 2048, "PMTU IPv6 MTU is not correct (%d)", mtu);
591 
592 	(void)zsock_close(client_sock);
593 	(void)zsock_close(server_sock);
594 #else
595 	ztest_test_skip();
596 #endif /* CONFIG_NET_IPV6_PMTU */
597 }
598 
599 #if defined(CONFIG_NET_IPV4_PMTU)
get_v4_send_recv_sock(int * srv_sock,struct sockaddr_in * my_saddr,struct sockaddr_in * peer_saddr,uint16_t my_port,uint16_t peer_port)600 static int get_v4_send_recv_sock(int *srv_sock,
601 				 struct sockaddr_in *my_saddr,
602 				 struct sockaddr_in *peer_saddr,
603 				 uint16_t my_port,
604 				 uint16_t peer_port)
605 {
606 	struct sockaddr addr;
607 	socklen_t addrlen = sizeof(addr);
608 	int new_sock;
609 	int c_sock;
610 	int s_sock;
611 
612 	prepare_sock_tcp_v4(PEER_IPV4_ADDR, peer_port, &s_sock, peer_saddr);
613 	test_bind(s_sock, (struct sockaddr *)peer_saddr, sizeof(*peer_saddr));
614 	test_listen(s_sock);
615 
616 	prepare_sock_tcp_v4(MY_IPV4_ADDR, my_port, &c_sock, my_saddr);
617 	test_bind(c_sock, (struct sockaddr *)my_saddr, sizeof(*my_saddr));
618 	test_connect(c_sock, (struct sockaddr *)peer_saddr, sizeof(*peer_saddr));
619 
620 	test_accept(s_sock, &new_sock, &addr, &addrlen);
621 	zassert_equal(addrlen, sizeof(struct sockaddr_in), "wrong addrlen");
622 
623 	*srv_sock = new_sock;
624 
625 	return c_sock;
626 }
627 
create_icmpv4_dest_unreach(struct net_if * iface,struct sockaddr_in * src,struct sockaddr_in * dst,uint32_t mtu,struct net_pkt ** pkt)628 static int create_icmpv4_dest_unreach(struct net_if *iface,
629 				      struct sockaddr_in *src,
630 				      struct sockaddr_in *dst,
631 				      uint32_t mtu,
632 				      struct net_pkt **pkt)
633 {
634 	struct net_icmpv4_dest_unreach du_hdr;
635 	struct net_pkt *du_pkt;
636 	struct in_addr *dest4;
637 	struct in_addr *src4;
638 	int ret;
639 
640 	du_pkt = net_pkt_alloc_with_buffer(iface, sizeof(struct net_ipv4_hdr) +
641 					   sizeof(struct net_icmp_hdr) +
642 					   sizeof(struct net_icmpv4_dest_unreach),
643 					   AF_INET, IPPROTO_ICMP,
644 					   PKT_WAIT_TIME);
645 	if (du_pkt == NULL) {
646 		NET_DBG("No buffer");
647 		return -ENOMEM;
648 	}
649 
650 	dest4 = &dst->sin_addr;
651 	src4 = &src->sin_addr;
652 
653 	ret = net_ipv4_create(du_pkt, src4, dest4);
654 	if (ret < 0) {
655 		LOG_ERR("Cannot create IPv4 pkt (%d)", ret);
656 		return ret;
657 	}
658 
659 	ret = net_icmpv4_create(du_pkt, NET_ICMPV4_DST_UNREACH, 0);
660 	if (ret < 0) {
661 		LOG_ERR("Cannot create ICMPv4 pkt (%d)", ret);
662 		return ret;
663 	}
664 
665 	du_hdr.mtu = htons(mtu);
666 
667 	ret = net_pkt_write(du_pkt, &du_hdr, sizeof(du_hdr));
668 	if (ret < 0) {
669 		LOG_ERR("Cannot write payload (%d)", ret);
670 		return ret;
671 	}
672 
673 	net_pkt_cursor_init(du_pkt);
674 	net_ipv4_finalize(du_pkt, IPPROTO_ICMP);
675 
676 	net_pkt_set_iface(du_pkt, iface);
677 
678 	*pkt = du_pkt;
679 
680 	return 0;
681 }
682 #endif
683 
ZTEST(net_pmtu_test_suite,test_pmtu_05_ipv4_tcp)684 ZTEST(net_pmtu_test_suite, test_pmtu_05_ipv4_tcp)
685 {
686 #if defined(CONFIG_NET_IPV4_PMTU)
687 	struct sockaddr_in dest_ipv4;
688 	struct sockaddr_in s_saddr = { 0 };  /* peer */
689 	struct sockaddr_in c_saddr = { 0 };  /* this host */
690 	struct net_pkt *pkt = NULL;
691 	int client_sock, server_sock;
692 	uint16_t mtu;
693 	int ret;
694 
695 	dest_ipv4.sin_family = AF_INET;
696 
697 	client_sock = get_v4_send_recv_sock(&server_sock, &c_saddr, &s_saddr,
698 					    MY_PORT, PEER_PORT);
699 	zassert_true(client_sock >= 0, "Failed to create client socket");
700 
701 	/* Set initial MTU for the destination */
702 	ret = net_pmtu_update_mtu((struct sockaddr *)&c_saddr, 4096);
703 	zassert_true(ret >= 0, "PMTU IPv6 MTU update failed (%d)", ret);
704 
705 	/* Send an ICMPv4 "Destination Unreachable" message from server to client which
706 	 * will update the PMTU entry.
707 	 */
708 	ret = create_icmpv4_dest_unreach(target_iface, &s_saddr, &c_saddr, 2048, &pkt);
709 	zassert_equal(ret, 0, "Failed to create ICMPv4 Destination Unrechable message");
710 
711 	ret = net_send_data(pkt);
712 	zassert_equal(ret, 0, "Failed to send Destination Unreachable message");
713 
714 	/* Check that the PMTU entry has been updated */
715 	mtu = net_tcp_get_mtu((struct sockaddr *)&s_saddr);
716 	zassert_equal(mtu, 2048, "PMTU IPv4 MTU is not correct (%d)", mtu);
717 
718 	(void)zsock_close(client_sock);
719 	(void)zsock_close(server_sock);
720 #else
721 	ztest_test_skip();
722 #endif /* CONFIG_NET_IPV4_PMTU */
723 }
724 
ZTEST(net_pmtu_test_suite,test_pmtu_06_ipv4_event)725 ZTEST(net_pmtu_test_suite, test_pmtu_06_ipv4_event)
726 {
727 #if defined(CONFIG_NET_IPV4_PMTU) && WAIT_PROPERLY
728 	struct sockaddr_in dest_ipv4;
729 	int ret;
730 
731 	setup_mgmt_events();
732 
733 	is_pmtu_changed = false;
734 
735 	net_ipaddr_copy(&dest_ipv4.sin_addr, &dest_ipv4_addr1);
736 	dest_ipv4.sin_family = AF_INET;
737 
738 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv4, 1200);
739 	zassert_equal(ret, 0, "PMTU IPv4 MTU update failed (%d)", ret);
740 
741 	if (k_sem_take(&wait_pmtu_changed, K_MSEC(WAIT_TIME))) {
742 		zassert_true(0, "Timeout while waiting pmtu changed event");
743 	}
744 
745 	zassert_true(is_pmtu_changed, "Did not catch pmtu changed event");
746 
747 	is_pmtu_changed = false;
748 #else
749 	ztest_test_skip();
750 #endif /* CONFIG_NET_IPV4_PMTU */
751 }
752 
ZTEST(net_pmtu_test_suite,test_pmtu_06_ipv6_event)753 ZTEST(net_pmtu_test_suite, test_pmtu_06_ipv6_event)
754 {
755 #if defined(CONFIG_NET_IPV6_PMTU) && WAIT_PROPERLY
756 	struct sockaddr_in6 dest_ipv6;
757 	int ret;
758 
759 	setup_mgmt_events();
760 
761 	is_pmtu_changed = false;
762 
763 	net_ipaddr_copy(&dest_ipv6.sin6_addr, &dest_ipv6_addr1);
764 	dest_ipv6.sin6_family = AF_INET6;
765 
766 	ret = net_pmtu_update_mtu((struct sockaddr *)&dest_ipv6, 1500);
767 	zassert_equal(ret, 0, "PMTU IPv6 MTU update failed (%d)", ret);
768 
769 	if (k_sem_take(&wait_pmtu_changed, K_MSEC(WAIT_TIME))) {
770 		zassert_true(0, "Timeout while waiting pmtu changed event");
771 	}
772 
773 	zassert_true(is_pmtu_changed, "Did not catch pmtu changed event");
774 
775 	is_pmtu_changed = false;
776 #else
777 	ztest_test_skip();
778 #endif /* CONFIG_NET_IPV6_PMTU */
779 }
780 
ZTEST(net_pmtu_test_suite,test_pmtu_07_socket_api_ipv4)781 ZTEST(net_pmtu_test_suite, test_pmtu_07_socket_api_ipv4)
782 {
783 #if defined(CONFIG_NET_IPV4_PMTU)
784 	struct sockaddr_in s_saddr = { 0 };  /* peer */
785 	struct sockaddr_in c_saddr = { 0 };  /* this host */
786 	int ret, client_sock, server_sock;
787 	size_t optlen;
788 	int optval;
789 	int err;
790 
791 	client_sock = get_v4_send_recv_sock(&server_sock, &c_saddr, &s_saddr,
792 					    MY_PORT + 1, PEER_PORT + 1);
793 	zassert_true(client_sock >= 0, "Failed to create client socket");
794 
795 	/* Set initial MTU for the destination */
796 	ret = net_pmtu_update_mtu((struct sockaddr *)&c_saddr, 4096);
797 	zassert_true(ret >= 0, "PMTU IPv4 MTU update failed (%d)", ret);
798 
799 	optval = 0; optlen = sizeof(int);
800 	ret = zsock_getsockopt(client_sock, IPPROTO_IP, IP_MTU, &optval, &optlen);
801 	err = -errno;
802 	zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
803 	zexpect_equal(optlen, sizeof(int), "setsockopt optlen (%d)", optlen);
804 	zexpect_equal(optval, 4096, "setsockopt mtu (%d)", optval);
805 
806 	optval = 0; optlen = sizeof(int);
807 	ret = zsock_setsockopt(client_sock, IPPROTO_IP, IP_MTU, &optval, optlen);
808 	err = -errno;
809 	zexpect_equal(ret, -1, "setsockopt failed (%d)", err);
810 	zexpect_equal(optlen, sizeof(int), "setsockopt optlen (%d)", optlen);
811 	zexpect_equal(optval, 0, "setsockopt mtu (%d)", optval);
812 
813 	(void)zsock_close(client_sock);
814 	(void)zsock_close(server_sock);
815 #else
816 	ztest_test_skip();
817 #endif /* CONFIG_NET_IPV4_PMTU */
818 }
819 
ZTEST(net_pmtu_test_suite,test_pmtu_08_socket_api_ipv6)820 ZTEST(net_pmtu_test_suite, test_pmtu_08_socket_api_ipv6)
821 {
822 #if defined(CONFIG_NET_IPV6_PMTU)
823 	struct sockaddr_in6 s_saddr = { 0 };  /* peer */
824 	struct sockaddr_in6 c_saddr = { 0 };  /* this host */
825 	int ret, client_sock, server_sock;
826 	size_t optlen;
827 	int optval;
828 	int err;
829 
830 	client_sock = get_v6_send_recv_sock(&server_sock, &c_saddr, &s_saddr,
831 					    MY_PORT + 2, PEER_PORT + 2);
832 	zassert_true(client_sock >= 0, "Failed to create client socket");
833 
834 	/* Set initial MTU for the destination */
835 	ret = net_pmtu_update_mtu((struct sockaddr *)&c_saddr, 2048);
836 	zassert_true(ret >= 0, "PMTU IPv6 MTU update failed (%d)", ret);
837 
838 	optval = 0; optlen = sizeof(int);
839 	ret = zsock_getsockopt(client_sock, IPPROTO_IPV6, IPV6_MTU, &optval, &optlen);
840 	err = -errno;
841 	zexpect_equal(ret, 0, "getsockopt failed (%d)", err);
842 	zexpect_equal(optlen, sizeof(int), "getsockopt optlen (%d)", optlen);
843 	zexpect_equal(optval, 2048, "getsockopt mtu (%d)", optval);
844 
845 	optval = 1500; optlen = sizeof(int);
846 	ret = zsock_setsockopt(client_sock, IPPROTO_IPV6, IPV6_MTU, &optval, optlen);
847 	err = -errno;
848 	zexpect_equal(ret, 0, "setsockopt failed (%d)", err);
849 	zexpect_equal(optlen, sizeof(int), "setsockopt optlen (%d)", optlen);
850 	zexpect_equal(optval, 1500, "setsockopt mtu (%d)", optval);
851 
852 	optval = 0; optlen = sizeof(int);
853 	ret = zsock_getsockopt(client_sock, IPPROTO_IPV6, IPV6_MTU, &optval, &optlen);
854 	err = -errno;
855 	zexpect_equal(ret, 0, "getsockopt failed (%d)", err);
856 	zexpect_equal(optlen, sizeof(int), "getsockopt optlen (%d)", optlen);
857 	zexpect_equal(optval, 1500, "getsockopt mtu (%d)", optval);
858 
859 	(void)zsock_close(client_sock);
860 	(void)zsock_close(server_sock);
861 #else
862 	ztest_test_skip();
863 #endif /* CONFIG_NET_IPV6_PMTU */
864 }
865 
866 ZTEST_SUITE(net_pmtu_test_suite, NULL, test_setup, NULL, NULL, NULL);
867