zephyr/subsys/net/lib/shell/vlan.c
Jukka Rissanen 477a4a5d34 net: shell: Rename the common.h to be more unique
As the common.h is only meant to be used by the network
shell files, rename it to be more descriptive in order to
avoid possible conflicts with any other common.h file.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2023-12-13 20:13:39 +01:00

226 lines
4.8 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 <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 ethernet_context *ctx = net_if_l2_data(iface);
struct net_shell_user_data *data = user_data;
const struct shell *sh = data->sh;
int *count = data->user_data;
int i;
if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
return;
}
if (*count == 0) {
PR(" Interface Type Tag\n");
}
if (!ctx->vlan_enabled) {
PR_WARNING("VLAN tag(s) not set\n");
return;
}
for (i = 0; i < NET_VLAN_MAX_COUNT; i++) {
if (!ctx->vlan[i].iface || ctx->vlan[i].iface != iface) {
continue;
}
if (ctx->vlan[i].tag == NET_VLAN_TAG_UNSPEC) {
continue;
}
PR("[%d] %p %s %d\n", net_if_get_by_iface(iface), iface,
iface2str(iface, NULL), ctx->vlan[i].tag);
break;
}
(*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;
}
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);