net: dummy L2 for offloaded ifaces

Adds dummy link layer for offloaded ifaces, allowing
ifaces to directly receive l2_enable calls

Signed-off-by: Georges Oates_Larsen <georges.larsen@nordicsemi.no>
This commit is contained in:
Georges Oates_Larsen 2023-01-19 14:17:55 -08:00 committed by Carles Cufí
parent 37b3a11d72
commit 3c6b7dc35a
20 changed files with 153 additions and 51 deletions

View file

@ -29,6 +29,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_MODEM_LOG_LEVEL);
#include <zephyr/net/net_offload.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/dns_resolve.h>
#include <zephyr/net/offloaded_netdev.h>
#if defined(CONFIG_NET_IPV6)
#include "ipv6.h"
#endif
@ -6424,8 +6425,8 @@ static void offload_iface_init(struct net_if *iface)
}
}
static struct net_if_api api_funcs = {
.init = offload_iface_init,
static struct offloaded_if_api api_funcs = {
.iface_api.init = offload_iface_init,
};
NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, hl7800_init, NULL, &ictx,

View file

@ -1096,8 +1096,8 @@ static void modem_net_iface_init(struct net_if *iface)
net_if_socket_offload_set(iface, offload_socket);
}
static struct net_if_api api_funcs = {
.init = modem_net_iface_init,
static struct offloaded_if_api api_funcs = {
.iface_api.init = modem_net_iface_init,
};
static bool offload_is_supported(int family, int type, int proto)

View file

@ -15,6 +15,7 @@
#include <zephyr/init.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/net_offload.h>
#include <zephyr/net/socket_offload.h>

View file

@ -7,6 +7,7 @@
#define DT_DRV_COMPAT simcom_sim7080
#include <zephyr/logging/log.h>
#include <zephyr/net/offloaded_netdev.h>
LOG_MODULE_REGISTER(modem_simcom_sim7080, CONFIG_MODEM_LOG_LEVEL);
#include <zephyr/drivers/modem/simcom-sim7080.h>
@ -760,8 +761,8 @@ const struct socket_dns_offload offload_dns_ops = {
.freeaddrinfo = offload_freeaddrinfo,
};
static struct net_if_api api_funcs = {
.init = modem_net_iface_init,
static struct offloaded_if_api api_funcs = {
.iface_api.init = modem_net_iface_init,
};
static bool offload_is_supported(int family, int type, int proto)

View file

@ -19,6 +19,7 @@ LOG_MODULE_REGISTER(modem_ublox_sara_r4, CONFIG_MODEM_LOG_LEVEL);
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_offload.h>
#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/socket_offload.h>
#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
@ -2103,8 +2104,8 @@ static void modem_net_iface_init(struct net_if *iface)
net_if_socket_offload_set(iface, offload_socket);
}
static struct net_if_api api_funcs = {
.init = modem_net_iface_init,
static struct offloaded_if_api api_funcs = {
.iface_api.init = modem_net_iface_init,
};
static const struct modem_cmd response_cmds[] = {

View file

@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(LOG_DOMAIN);
#include <zephyr/net/net_context.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_offload.h>
#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/net_pkt.h>
#if defined(CONFIG_NET_IPV6)
#include "ipv6.h"
@ -1773,8 +1774,8 @@ static void offload_iface_init(struct net_if *iface)
ctx->iface = iface;
}
static struct net_if_api api_funcs = {
.init = offload_iface_init,
static struct offloaded_if_api api_funcs = {
.iface_api.init = offload_iface_init,
};
NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, wncm14a2a_init, NULL,

View file

@ -1217,13 +1217,13 @@ static void esp_iface_init(struct net_if *iface)
}
static const struct net_wifi_mgmt_offload esp_api = {
.wifi_iface.init = esp_iface_init,
.scan = esp_mgmt_scan,
.connect = esp_mgmt_connect,
.disconnect = esp_mgmt_disconnect,
.ap_enable = esp_mgmt_ap_enable,
.ap_disable = esp_mgmt_ap_disable,
.iface_status = esp_mgmt_iface_status,
.wifi_iface.iface_api.init = esp_iface_init,
.scan = esp_mgmt_scan,
.connect = esp_mgmt_connect,
.disconnect = esp_mgmt_disconnect,
.ap_enable = esp_mgmt_ap_enable,
.ap_disable = esp_mgmt_ap_disable,
.iface_status = esp_mgmt_iface_status,
};
static int esp_init(const struct device *dev);

View file

@ -679,12 +679,12 @@ static int eswifi_init(const struct device *dev)
}
static const struct net_wifi_mgmt_offload eswifi_offload_api = {
.wifi_iface.init = eswifi_iface_init,
.scan = eswifi_mgmt_scan,
.connect = eswifi_mgmt_connect,
.disconnect = eswifi_mgmt_disconnect,
.ap_enable = eswifi_mgmt_ap_enable,
.ap_disable = eswifi_mgmt_ap_disable,
.wifi_iface.iface_api.init = eswifi_iface_init,
.scan = eswifi_mgmt_scan,
.connect = eswifi_mgmt_connect,
.disconnect = eswifi_mgmt_disconnect,
.ap_enable = eswifi_mgmt_ap_enable,
.ap_disable = eswifi_mgmt_ap_disable,
};
NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, eswifi_init, NULL,

View file

@ -264,10 +264,10 @@ static void simplelink_iface_init(struct net_if *iface)
}
static const struct net_wifi_mgmt_offload simplelink_api = {
.wifi_iface.init = simplelink_iface_init,
.scan = simplelink_mgmt_scan,
.connect = simplelink_mgmt_connect,
.disconnect = simplelink_mgmt_disconnect,
.wifi_iface.iface_api.init = simplelink_iface_init,
.scan = simplelink_mgmt_scan,
.connect = simplelink_mgmt_connect,
.disconnect = simplelink_mgmt_disconnect,
};
static int simplelink_init(const struct device *dev)

View file

@ -1100,12 +1100,12 @@ static void winc1500_iface_init(struct net_if *iface)
}
static const struct net_wifi_mgmt_offload winc1500_api = {
.wifi_iface.init = winc1500_iface_init,
.scan = winc1500_mgmt_scan,
.connect = winc1500_mgmt_connect,
.disconnect = winc1500_mgmt_disconnect,
.ap_enable = winc1500_mgmt_ap_enable,
.ap_disable = winc1500_mgmt_ap_disable,
.wifi_iface.iface_api.init = winc1500_iface_init,
.scan = winc1500_mgmt_scan,
.connect = winc1500_mgmt_connect,
.disconnect = winc1500_mgmt_disconnect,
.ap_enable = winc1500_mgmt_ap_enable,
.ap_disable = winc1500_mgmt_ap_disable,
};
static int winc1500_init(const struct device *dev)

View file

@ -2468,6 +2468,7 @@ struct net_if_api {
NET_IF_DEV_GET_NAME(dev_id, sfx)) = { \
.dev = &(DEVICE_NAME_GET(dev_id)), \
.mtu = _mtu, \
.l2 = &(NET_L2_GET_NAME(OFFLOADED_NETDEV)), \
}; \
static Z_DECL_ALIGN(struct net_if) \
NET_IF_GET_NAME(dev_id, sfx)[NET_IF_MAX_CONFIGS] \

View file

@ -95,6 +95,11 @@ NET_L2_DECLARE_PUBLIC(VIRTUAL_L2);
NET_L2_DECLARE_PUBLIC(DUMMY_L2);
#endif /* CONFIG_NET_L2_DUMMY */
#if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_SOCKETS_OFFLOAD)
#define OFFLOADED_NETDEV_L2 OFFLOADED_NETDEV
NET_L2_DECLARE_PUBLIC(OFFLOADED_NETDEV_L2);
#endif /* CONFIG_NET_L2_ETHERNET */
#ifdef CONFIG_NET_L2_ETHERNET
#define ETHERNET_L2 ETHERNET
NET_L2_DECLARE_PUBLIC(ETHERNET_L2);

View file

@ -0,0 +1,58 @@
/** @file
* @brief Offloaded network device iface API
*
* This is not to be included by the application.
*/
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_OFFLOADED_NETDEV_H_
#define ZEPHYR_INCLUDE_OFFLOADED_NETDEV_H_
#include <zephyr/kernel.h>
#include <zephyr/types.h>
#include <stdbool.h>
#include <zephyr/net/net_if.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Offloaded Net Devices
* @defgroup offloaded_netdev Offloaded Net Devices
* @ingroup networking
* @{
*/
/**
* @brief Extended net_if_api for offloaded ifaces/network devices, allowing handling of
* admin up/down state changes
*/
struct offloaded_if_api {
/**
* The net_if_api must be placed in first position in this
* struct so that we are compatible with network interface API.
*/
struct net_if_api iface_api;
/** Enable or disable the device (in response to admin state change) */
int (*enable)(const struct net_if *iface, bool state);
};
/* Ensure offloaded_if_api is compatible with net_if_api */
BUILD_ASSERT(offsetof(struct offloaded_if_api, iface_api) == 0);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_OFFLOADED_NETDEV_H_ */

View file

@ -15,6 +15,7 @@
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/wifi.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/offloaded_netdev.h>
#ifdef __cplusplus
extern "C" {
@ -288,7 +289,7 @@ struct net_wifi_mgmt_offload {
#ifdef CONFIG_WIFI_USE_NATIVE_NETWORKING
struct ethernet_api wifi_iface;
#else
struct net_if_api wifi_iface;
struct offloaded_if_api wifi_iface;
#endif
/* cb parameter is the cb that should be called for each

View file

@ -4202,10 +4202,6 @@ int net_if_up(struct net_if *iface)
goto out;
}
if (is_iface_offloaded(iface)) {
goto done;
}
/* If the L2 does not support enable just set the flag */
if (!net_if_l2(iface) || !net_if_l2(iface)->enable) {
goto done;
@ -4246,10 +4242,6 @@ int net_if_down(struct net_if *iface)
leave_mcast_all(iface);
leave_ipv4_mcast_all(iface);
if (is_iface_offloaded(iface)) {
goto done;
}
/* If the L2 does not support enable just clear the flag */
if (!net_if_l2(iface) || !net_if_l2(iface)->enable) {
goto done;

View file

@ -12,6 +12,10 @@ if(CONFIG_NET_L2_DUMMY)
add_subdirectory(dummy)
endif()
if (CONFIG_NET_OFFLOAD OR CONFIG_NET_SOCKETS_OFFLOAD)
add_subdirectory(offloaded_netdev)
endif()
if(CONFIG_NET_L2_ETHERNET)
add_subdirectory(ethernet)
endif()

View file

@ -0,0 +1,5 @@
# Copyright (c) 2022 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources(offloaded_netdev.c)

View file

@ -0,0 +1,22 @@
/*
* Copyright (c) 2022 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/net/net_l2.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/offloaded_netdev.h>
static inline int offloaded_netdev_if_enable(struct net_if *iface, bool state)
{
const struct offloaded_if_api *off_if = net_if_get_device(iface)->api;
if (!off_if || !(off_if->enable)) {
return 0;
}
return off_if->enable(iface, state);
}
NET_L2_INIT(OFFLOADED_NETDEV, NULL, NULL, offloaded_netdev_if_enable, NULL);

View file

@ -18,23 +18,31 @@ LOG_MODULE_REGISTER(net_test, LOG_LEVEL_DBG);
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>
#include <zephyr/net/dummy.h>
#include <zephyr/net/offloaded_netdev.h>
/* Create blank dummy and offloaded APIs */
static struct offloaded_if_api offload_dev_api;
static const struct dummy_api dummy_dev_api;
static struct offload_context {
void *none;
} offload_context_data = {
.none = NULL
};
static struct dummy_api offload_if_api = {
.iface_api.init = NULL,
.send = NULL,
};
/* Create blank dummy and offloaded net devices */
NET_DEVICE_INIT(dummy_dev, "dummy_dev",
NULL, NULL,
NULL, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&dummy_dev_api,
DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2), 0);
NET_DEVICE_OFFLOAD_INIT(net_offload, "net_offload",
NULL, NULL,
&offload_context_data, NULL,
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
&offload_if_api, 0);
&offload_dev_api, 0);
ZTEST(net_compile_all_test, test_ok)
{

View file

@ -8,6 +8,7 @@
#include <zephyr/logging/log.h>
#include <zephyr/net/dummy.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/offloaded_netdev.h>
#include <zephyr/net/socket.h>
#include <sockets_internal.h>
#include <zephyr/sys/fdtable.h>
@ -306,8 +307,8 @@ static void offloaded_1_iface_init(struct net_if *iface)
net_if_socket_offload_set(iface, offload_1_socket);
}
static struct net_if_api offloaded_1_if_api = {
.init = offloaded_1_iface_init,
static struct offloaded_if_api offloaded_1_if_api = {
.iface_api.init = offloaded_1_iface_init,
};
NET_DEVICE_OFFLOAD_INIT(offloaded_1, "offloaded_1", offloaded_1_init, NULL,
@ -376,8 +377,8 @@ static void offloaded_2_iface_init(struct net_if *iface)
net_if_socket_offload_set(iface, offload_2_socket);
}
static struct net_if_api offloaded_2_if_api = {
.init = offloaded_2_iface_init,
static struct offloaded_if_api offloaded_2_if_api = {
.iface_api.init = offloaded_2_iface_init,
};
NET_DEVICE_OFFLOAD_INIT(offloaded_2, "offloaded_2", offloaded_2_init, NULL,