1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_DECLARE(net_shell);
9 
10 #include "net_shell_private.h"
11 
12 #include "pmtu.h"
13 
14 #if !defined(CONFIG_NET_PMTU)
print_pmtu_error(const struct shell * sh)15 static void print_pmtu_error(const struct shell *sh)
16 {
17 	PR_INFO("Set %s to enable %s support.\n",
18 		"CONFIG_NET_IPV6_PMTU or CONFIG_NET_IPV4_PMTU", "PMTU");
19 }
20 #endif
21 
22 #if defined(CONFIG_NET_PMTU)
pmtu_cb(struct net_pmtu_entry * entry,void * user_data)23 static void pmtu_cb(struct net_pmtu_entry *entry, void *user_data)
24 {
25 	struct net_shell_user_data *data = user_data;
26 	const struct shell *sh = data->sh;
27 	int *count = data->user_data;
28 
29 #if defined(CONFIG_NET_IPV4) && defined(CONFIG_NET_IPV6)
30 /* Use the value of NET_IPV6_ADDR_LEN */
31 #define ADDR_STR_LEN 40
32 #elif defined(CONFIG_NET_IPV4)
33 #define ADDR_STR_LEN INET_ADDRSTRLEN
34 #elif defined(CONFIG_NET_IPV6)
35 #define ADDR_STR_LEN 40
36 #else
37 #define ADDR_STR_LEN INET_ADDRSTRLEN
38 #endif
39 
40 	if (!entry->in_use) {
41 		return;
42 	}
43 
44 	if (*count == 0) {
45 		PR("     %" STRINGIFY(ADDR_STR_LEN) "s   MTU  Age (sec)\n",
46 		   "Destination Address");
47 	}
48 
49 	PR("[%2d] %" STRINGIFY(ADDR_STR_LEN) "s %5d  %d\n", *count + 1,
50 	   net_sprint_addr(entry->dst.family, (void *)&entry->dst.in_addr),
51 	   entry->mtu,
52 	   (k_uptime_get_32() - entry->last_update) / 1000U);
53 
54 	(*count)++;
55 }
56 #endif /* CONFIG_NET_PMTU */
57 
cmd_net_pmtu(const struct shell * sh,size_t argc,char * argv[])58 static int cmd_net_pmtu(const struct shell *sh, size_t argc, char *argv[])
59 {
60 #if defined(CONFIG_NET_PMTU)
61 	struct net_shell_user_data user_data;
62 	int arg = 1;
63 #endif
64 
65 	ARG_UNUSED(argc);
66 
67 #if defined(CONFIG_NET_PMTU)
68 	if (!argv[arg]) {
69 		/* PMTU destination cache content */
70 		int count = 0;
71 
72 		user_data.sh = sh;
73 		user_data.user_data = &count;
74 
75 		(void)net_pmtu_foreach(pmtu_cb, &user_data);
76 
77 		if (count == 0) {
78 			PR("PMTU destination cache is empty.\n");
79 		}
80 	}
81 #else
82 	print_pmtu_error(sh);
83 #endif
84 
85 	return 0;
86 }
87 
cmd_net_pmtu_flush(const struct shell * sh,size_t argc,char * argv[])88 static int cmd_net_pmtu_flush(const struct shell *sh, size_t argc, char *argv[])
89 {
90 	ARG_UNUSED(argc);
91 	ARG_UNUSED(argv);
92 
93 #if defined(CONFIG_NET_PMTU)
94 	PR("Flushing PMTU destination cache.\n");
95 	net_pmtu_init();
96 #else
97 	print_pmtu_error(sh);
98 #endif
99 
100 	return 0;
101 }
102 
103 SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_pmtu,
104 	SHELL_CMD(flush, NULL,
105 		  "Remove all entries from PMTU destination cache.",
106 		  cmd_net_pmtu_flush),
107 	SHELL_SUBCMD_SET_END
108 );
109 
110 SHELL_SUBCMD_ADD((net), pmtu, &net_cmd_pmtu,
111 		 "Show PMTU information.",
112 		 cmd_net_pmtu, 1, 0);
113