1 /*
2 * Copyright (c) 2016 Intel Corporation
3 * Copyright (c) 2023 Nordic Semiconductor ASA
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <zephyr/logging/log.h>
9 LOG_MODULE_DECLARE(net_shell);
10
11 #if defined(CONFIG_NET_L2_VIRTUAL)
12 #include <zephyr/net/virtual.h>
13 #endif
14
15 #include "net_shell_private.h"
16
17 #if defined(CONFIG_NET_L2_VIRTUAL)
virtual_iface_cb(struct net_if * iface,void * user_data)18 static void virtual_iface_cb(struct net_if *iface, void *user_data)
19 {
20 struct net_shell_user_data *data = user_data;
21 const struct shell *sh = data->sh;
22 int *count = data->user_data;
23 char *name, buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN];
24 struct net_if *orig_iface;
25
26 if (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL)) {
27 return;
28 }
29
30 if (*count == 0) {
31 PR("Interface Attached-To Description\n");
32 (*count)++;
33 }
34
35 orig_iface = net_virtual_get_iface(iface);
36
37 name = net_virtual_get_name(iface, buf, sizeof(buf));
38
39 PR("%d %c %s\n",
40 net_if_get_by_iface(iface),
41 orig_iface ? net_if_get_by_iface(orig_iface) + '0' : '-',
42 name);
43
44 (*count)++;
45 }
46
attached_iface_cb(struct net_if * iface,void * user_data)47 static void attached_iface_cb(struct net_if *iface, void *user_data)
48 {
49 struct net_shell_user_data *data = user_data;
50 const struct shell *sh = data->sh;
51 int *count = data->user_data;
52 char buf[CONFIG_NET_L2_VIRTUAL_MAX_NAME_LEN];
53 const char *name;
54 struct virtual_interface_context *ctx, *tmp;
55
56 if (sys_slist_is_empty(&iface->config.virtual_interfaces)) {
57 return;
58 }
59
60 if (*count == 0) {
61 PR("Interface Below-of Description\n");
62 (*count)++;
63 }
64
65 PR("%d ", net_if_get_by_iface(iface));
66
67 SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&iface->config.virtual_interfaces,
68 ctx, tmp, node) {
69 if (ctx->virtual_iface == iface) {
70 continue;
71 }
72
73 PR("%d ", net_if_get_by_iface(ctx->virtual_iface));
74 }
75
76 name = net_virtual_get_name(iface, buf, sizeof(buf));
77 if (name == NULL) {
78 name = iface2str(iface, NULL);
79 }
80
81 PR(" %s\n", name);
82
83 (*count)++;
84 }
85 #endif /* CONFIG_NET_L2_VIRTUAL */
86
cmd_net_virtual(const struct shell * sh,size_t argc,char * argv[])87 static int cmd_net_virtual(const struct shell *sh, size_t argc, char *argv[])
88 {
89 ARG_UNUSED(argc);
90 ARG_UNUSED(argv);
91
92 #if defined(CONFIG_NET_L2_VIRTUAL)
93 struct net_shell_user_data user_data;
94 int count = 0;
95
96 user_data.sh = sh;
97 user_data.user_data = &count;
98
99 net_if_foreach(virtual_iface_cb, &user_data);
100
101 if (count == 0) {
102 PR("No virtual interfaces found.");
103 }
104
105 count = 0;
106 PR("\n");
107
108 net_if_foreach(attached_iface_cb, &user_data);
109 #else
110 PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_L2_VIRTUAL",
111 "virtual network interface");
112 #endif
113 return 0;
114 }
115
116 SHELL_SUBCMD_ADD((net), virtual, NULL,
117 "Show virtual network interfaces.",
118 cmd_net_virtual, 1, 0);
119