zephyr/subsys/net/lib/shell/vlan.c
Jukka Rissanen 999c169d9d net: shell: Print VLAN name instead of interface type
As the interface type is always Virtual, no need to print it.
Print instead the name of the network interface as it is more
useful to the user.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2024-03-28 09:41:38 +00:00

218 lines
4.7 KiB
C

/*
* Copyright (c) 2016 Intel Corporation
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(net_shell);
#if defined(CONFIG_NET_L2_VIRTUAL)
#include <zephyr/net/virtual.h>
#endif
#include <zephyr/net/ethernet.h>
#include <zephyr/net/socket.h>
#include <stdlib.h>
#include "net_shell_private.h"
#if defined(CONFIG_NET_VLAN)
static void iface_vlan_del_cb(struct net_if *iface, void *user_data)
{
struct net_shell_user_data *data = user_data;
const struct shell *sh = data->sh;
uint16_t vlan_tag = POINTER_TO_UINT(data->user_data);
int ret;
ret = net_eth_vlan_disable(iface, vlan_tag);
if (ret < 0) {
if (ret != -ESRCH) {
PR_WARNING("Cannot delete VLAN tag %d from "
"interface %d (%p)\n",
vlan_tag,
net_if_get_by_iface(iface),
iface);
}
return;
}
PR("VLAN tag %d removed from interface %d (%p)\n", vlan_tag,
net_if_get_by_iface(iface), iface);
}
static void iface_vlan_cb(struct net_if *iface, void *user_data)
{
struct net_shell_user_data *data = user_data;
const struct shell *sh = data->sh;
int *count = data->user_data;
char name[IFNAMSIZ];
if (net_if_l2(iface) != &NET_L2_GET_NAME(VIRTUAL)) {
return;
}
if (!(net_virtual_get_iface_capabilities(iface) & VIRTUAL_INTERFACE_VLAN)) {
return;
}
if (*count == 0) {
PR(" Interface Name \tTag\tAttached\n");
}
(void)net_if_get_name(iface, name, sizeof(name));
PR("[%d] %p %-12s\t%d\t%d\n", net_if_get_by_iface(iface), iface,
name, net_eth_get_vlan_tag(iface),
net_if_get_by_iface(net_eth_get_vlan_main(iface)));
(*count)++;
}
#endif /* CONFIG_NET_VLAN */
static int cmd_net_vlan(const struct shell *sh, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_VLAN)
struct net_shell_user_data user_data;
int count = 0;
user_data.sh = sh;
user_data.user_data = &count;
net_if_foreach(iface_vlan_cb, &user_data);
#else
PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN");
#endif /* CONFIG_NET_VLAN */
return 0;
}
static int cmd_net_vlan_add(const struct shell *sh, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_VLAN)
int arg = 0;
int ret;
uint16_t tag;
struct net_if *iface;
char *endptr;
uint32_t iface_idx;
/* vlan add <tag> <interface index> */
if (!argv[++arg]) {
PR_WARNING("VLAN tag missing.\n");
goto usage;
}
tag = strtol(argv[arg], &endptr, 10);
if (*endptr != '\0') {
PR_WARNING("Invalid tag %s\n", argv[arg]);
return -ENOEXEC;
}
if (!argv[++arg]) {
PR_WARNING("Network interface index missing.\n");
goto usage;
}
iface_idx = strtol(argv[arg], &endptr, 10);
if (*endptr != '\0') {
PR_WARNING("Invalid index %s\n", argv[arg]);
goto usage;
}
iface = net_if_get_by_index(iface_idx);
if (!iface) {
PR_WARNING("Network interface index %d is invalid.\n",
iface_idx);
goto usage;
}
if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
PR_WARNING("Network interface %d (%p) is not ethernet interface\n",
net_if_get_by_iface(iface), iface);
return -ENOEXEC;
}
ret = net_eth_vlan_enable(iface, tag);
if (ret < 0) {
if (ret == -ENOENT) {
PR_WARNING("No IP address configured.\n");
}
PR_WARNING("Cannot set VLAN tag (%d)\n", ret);
return -ENOEXEC;
}
iface = net_eth_get_vlan_iface(iface, tag);
PR("VLAN tag %d set to interface %d (%p)\n", tag,
net_if_get_by_iface(iface), iface);
return 0;
usage:
PR("Usage:\n");
PR("\tvlan add <tag> <interface index>\n");
#else
PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN");
#endif /* CONFIG_NET_VLAN */
return 0;
}
static int cmd_net_vlan_del(const struct shell *sh, size_t argc, char *argv[])
{
#if defined(CONFIG_NET_VLAN)
int arg = 0;
struct net_shell_user_data user_data;
char *endptr;
uint16_t tag;
/* vlan del <tag> */
if (!argv[++arg]) {
PR_WARNING("VLAN tag missing.\n");
goto usage;
}
tag = strtol(argv[arg], &endptr, 10);
if (*endptr != '\0') {
PR_WARNING("Invalid tag %s\n", argv[arg]);
return -ENOEXEC;
}
user_data.sh = sh;
user_data.user_data = UINT_TO_POINTER((uint32_t)tag);
net_if_foreach(iface_vlan_del_cb, &user_data);
return 0;
usage:
PR("Usage:\n");
PR("\tvlan del <tag>\n");
#else
PR_INFO("Set %s to enable %s support.\n", "CONFIG_NET_VLAN", "VLAN");
#endif /* CONFIG_NET_VLAN */
return 0;
}
SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_vlan,
SHELL_CMD_ARG(add, NULL,
"'net vlan add <tag> <index>' adds VLAN tag to the "
"network interface.",
cmd_net_vlan_add, 3, 0),
SHELL_CMD_ARG(del, NULL,
"'net vlan del <tag>' deletes VLAN tag from the network "
"interface.",
cmd_net_vlan_del, 2, 0),
SHELL_SUBCMD_SET_END
);
SHELL_SUBCMD_ADD((net), vlan, &net_cmd_vlan,
"Show VLAN information.",
cmd_net_vlan, 1, 0);