zephyr/subsys/net/l2/virtual/virtual_mgmt.c
Jukka Rissanen 5a9a39caf3 net: mgmt: Convert the mgmt API to use 64-bit masks
Instead of using 32 bit enum values for event numbers, convert
the code to use 64 bit long bit fields. This means that the
user API is changed to use 64 bit event values instead of 32
bit event values.

Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
2025-06-18 10:54:44 +02:00

179 lines
4.8 KiB
C

/*
* Copyright (c) 2021 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_virtual_mgmt, CONFIG_NET_L2_VIRTUAL_LOG_LEVEL);
#include <errno.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/virtual_mgmt.h>
static int virtual_interface_set_config(uint64_t mgmt_request,
struct net_if *iface,
void *data, size_t len)
{
struct virtual_interface_req_params *params =
(struct virtual_interface_req_params *)data;
const struct device *dev = net_if_get_device(iface);
const struct virtual_interface_api *api = dev->api;
struct virtual_interface_config config = { 0 };
enum virtual_interface_config_type type;
if (!api) {
return -ENOENT;
}
if (!api->set_config) {
return -ENOTSUP;
}
if (!data || (len != sizeof(struct virtual_interface_req_params))) {
return -EINVAL;
}
if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS) {
if (net_if_is_up(iface)) {
return -EACCES;
}
config.family = params->family;
memcpy(&config.peer6addr, &params->peer6addr,
sizeof(config.peer6addr));
type = VIRTUAL_INTERFACE_CONFIG_TYPE_PEER_ADDRESS;
} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU) {
if (net_if_is_up(iface)) {
return -EACCES;
}
config.family = params->family;
config.mtu = params->mtu;
type = VIRTUAL_INTERFACE_CONFIG_TYPE_MTU;
} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_LINK_TYPE) {
/* We can update the link types even if the interface is up */
config.family = params->family;
memcpy(&config.link_types, &params->link_types,
sizeof(config.link_types));
type = VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE;
} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_SET_PRIVATE_KEY) {
if (net_if_is_up(iface)) {
return -EACCES;
}
config.private_key.len = params->private_key.len;
config.private_key.data = params->private_key.data;
type = VIRTUAL_INTERFACE_CONFIG_TYPE_PRIVATE_KEY;
} else {
return -EINVAL;
}
return api->set_config(iface, type, &config);
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_PEER_ADDRESS,
virtual_interface_set_config);
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_MTU,
virtual_interface_set_config);
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_LINK_TYPE,
virtual_interface_set_config);
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_SET_PRIVATE_KEY,
virtual_interface_set_config);
static int virtual_interface_get_config(uint64_t mgmt_request,
struct net_if *iface,
void *data, size_t len)
{
struct virtual_interface_req_params *params =
(struct virtual_interface_req_params *)data;
const struct device *dev = net_if_get_device(iface);
const struct virtual_interface_api *api = dev->api;
struct virtual_interface_config config = { 0 };
enum virtual_interface_config_type type;
int ret = 0;
if (!api) {
return -ENOENT;
}
if (!api->get_config) {
return -ENOTSUP;
}
if (!data || (len != sizeof(struct virtual_interface_req_params))) {
return -EINVAL;
}
if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_PEER_ADDRESS) {
type = VIRTUAL_INTERFACE_CONFIG_TYPE_PEER_ADDRESS;
ret = api->get_config(iface, type, &config);
if (ret) {
return ret;
}
params->family = config.family;
memcpy(&params->peer6addr, &config.peer6addr,
sizeof(params->peer6addr));
} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU) {
type = VIRTUAL_INTERFACE_CONFIG_TYPE_MTU;
ret = api->get_config(iface, type, &config);
if (ret) {
return ret;
}
params->mtu = config.mtu;
} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_LINK_TYPE) {
type = VIRTUAL_INTERFACE_CONFIG_TYPE_LINK_TYPE;
ret = api->get_config(iface, type, &config);
if (ret) {
return ret;
}
memcpy(&params->link_types, &config.link_types,
sizeof(params->link_types));
} else if (mgmt_request == NET_REQUEST_VIRTUAL_INTERFACE_GET_PUBLIC_KEY) {
type = VIRTUAL_INTERFACE_CONFIG_TYPE_PUBLIC_KEY;
ret = api->get_config(iface, type, &config);
if (ret) {
return ret;
}
params->public_key.len = config.public_key.len;
memcpy(&params->public_key.data, &config.public_key.data,
MIN(sizeof(params->public_key.data),
params->public_key.len));
} else {
return -EINVAL;
}
return ret;
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_PEER_ADDRESS,
virtual_interface_get_config);
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_MTU,
virtual_interface_get_config);
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_LINK_TYPE,
virtual_interface_get_config);
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_VIRTUAL_INTERFACE_GET_PUBLIC_KEY,
virtual_interface_get_config);