From 4f6b2759be9583a2efec56da38e06d5573d462b4 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 11 Oct 2023 20:37:34 +0200 Subject: [PATCH 1/5] sys/net: Add NETOPT_ACTIVE for netif on/off state Similar to forcing interface up/down on Linux. In lwIP this is separate to link state. --- sys/include/net/netopt.h | 10 ++++++++++ sys/net/crosslayer/netopt/netopt.c | 1 + 2 files changed, 11 insertions(+) diff --git a/sys/include/net/netopt.h b/sys/include/net/netopt.h index 6385e681450b..e94842dd90bd 100644 --- a/sys/include/net/netopt.h +++ b/sys/include/net/netopt.h @@ -299,6 +299,16 @@ typedef enum { */ NETOPT_LINK, + /** + * @brief (@ref netopt_enable_t) network interface status. + * + * This option is used check state or to enable/disable the interface, + * regardless of link status. + * + * @note On error this option should return a negative number. + */ + NETOPT_ACTIVE, + /** * @brief (@ref netopt_enable_t) CSMA/CA support * diff --git a/sys/net/crosslayer/netopt/netopt.c b/sys/net/crosslayer/netopt/netopt.c index 9c66cbc0b420..bfadebe8b6e2 100644 --- a/sys/net/crosslayer/netopt/netopt.c +++ b/sys/net/crosslayer/netopt/netopt.c @@ -63,6 +63,7 @@ static const char *_netopt_strmap[] = { [NETOPT_MAC_NO_SLEEP] = "NETOPT_MAC_NO_SLEEP", [NETOPT_IS_WIRED] = "NETOPT_IS_WIRED", [NETOPT_LINK] = "NETOPT_LINK", + [NETOPT_ACTIVE] = "NETOPT_ACTIVE", [NETOPT_DEVICE_TYPE] = "NETOPT_DEVICE_TYPE", [NETOPT_CHANNEL_PAGE] = "NETOPT_CHANNEL_PAGE", [NETOPT_CCA_THRESHOLD] = "NETOPT_CCA_THRESHOLD", From 8e996c0a755780680731e5ca9905b49d54ef0a37 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 11 Oct 2023 20:50:36 +0200 Subject: [PATCH 2/5] pkg/lwip: Allow reading netif active state --- pkg/lwip/contrib/_netif.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/lwip/contrib/_netif.c b/pkg/lwip/contrib/_netif.c index 42902c7bff07..4991ee0d6fb3 100644 --- a/pkg/lwip/contrib/_netif.c +++ b/pkg/lwip/contrib/_netif.c @@ -42,6 +42,17 @@ int netif_get_opt(netif_t *iface, netopt_t opt, uint16_t context, struct netdev *dev = netif->state; int res = -ENOTSUP; switch (opt) { + case NETOPT_ACTIVE: { + assert(max_len >= sizeof(netopt_enable_t)); + netopt_enable_t *tgt = value; + if (netif_is_up(netif)) { + *tgt = NETOPT_ENABLE; + } else { + *tgt = NETOPT_DISABLE; + } + res = 0; + } + break; #ifdef MODULE_LWIP_IPV6 case NETOPT_IPV6_ADDR: { assert(max_len >= sizeof(ipv6_addr_t)); From 0fc7898b348c4b058a770eccf2bfd1aca5ee1f1d Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 11 Oct 2023 20:46:55 +0200 Subject: [PATCH 3/5] sys/shell/gnrc_netif: Show interface up/down state --- sys/shell/cmds/gnrc_netif.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sys/shell/cmds/gnrc_netif.c b/sys/shell/cmds/gnrc_netif.c index 938480e89f7d..47a2f33acf72 100644 --- a/sys/shell/cmds/gnrc_netif.c +++ b/sys/shell/cmds/gnrc_netif.c @@ -776,11 +776,17 @@ static void _netif_list(netif_t *iface) } } #endif /* MODULE_NETDEV_IEEE802154 */ - netopt_enable_t link; - res = netif_get_opt(iface, NETOPT_LINK, 0, &link, sizeof(netopt_enable_t)); + netopt_enable_t enabled; + res = netif_get_opt(iface, NETOPT_LINK, 0, &enabled, sizeof(enabled)); if (res >= 0) { - printf(" Link: %s ", (link == NETOPT_ENABLE) ? "up" : "down" ); + printf(" Link: %s ", (enabled == NETOPT_ENABLE) ? "up" : "down" ); } +#if IS_USED(MODULE_LWIP_NETIF) /* only supported on lwIP for now */ + res = netif_get_opt(iface, NETOPT_ACTIVE, 0, &enabled, sizeof(enabled)); + if (res >= 0) { + printf(" State: %s ", (enabled == NETOPT_ENABLE) ? "up" : "down" ); + } +#endif /* MODULE_LWIP_NETIF */ line_thresh = _newline(0U, line_thresh); res = netif_get_opt(iface, NETOPT_ADDRESS_LONG, 0, hwaddr, sizeof(hwaddr)); if (res >= 0) { @@ -806,9 +812,9 @@ static void _netif_list(netif_t *iface) } res = netif_get_opt(iface, NETOPT_CSMA_RETRIES, 0, &u8, sizeof(u8)); if (res >= 0) { - netopt_enable_t enable = NETOPT_DISABLE; - res = netif_get_opt(iface, NETOPT_CSMA, 0, &enable, sizeof(enable)); - if ((res >= 0) && (enable == NETOPT_ENABLE)) { + enabled = NETOPT_DISABLE; + res = netif_get_opt(iface, NETOPT_CSMA, 0, &enabled, sizeof(enabled)); + if ((res >= 0) && (enabled == NETOPT_ENABLE)) { printf(" CSMA Retries: %u ", (unsigned)u8); } line_thresh++; From c49cd446a8f1667d670f8f25ea989944f115181c Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 11 Oct 2023 20:57:52 +0200 Subject: [PATCH 4/5] pkg/lwip: Allow setting netif active state --- pkg/lwip/contrib/_netif.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/pkg/lwip/contrib/_netif.c b/pkg/lwip/contrib/_netif.c index 4991ee0d6fb3..a931e68f1aad 100644 --- a/pkg/lwip/contrib/_netif.c +++ b/pkg/lwip/contrib/_netif.c @@ -18,6 +18,7 @@ #include "fmt.h" #include "lwip/netif/compat.h" +#include "lwip/netifapi.h" #include "net/netif.h" int netif_get_name(netif_t *iface, char *name) @@ -85,13 +86,28 @@ int netif_get_opt(netif_t *iface, netopt_t opt, uint16_t context, int netif_set_opt(netif_t *iface, netopt_t opt, uint16_t context, void *value, size_t value_len) { - (void)iface; - (void)opt; (void)context; - (void)value; - (void)value_len; + int res = -ENOTSUP; + lwip_netif_t *lwip_netif = (lwip_netif_t*) iface; + struct netif *netif = &lwip_netif->lwip_netif; - return -ENOTSUP; + switch (opt) { + case NETOPT_ACTIVE: { + assert(value_len >= sizeof(netopt_enable_t)); + netopt_enable_t *state = value; + if (*state == NETOPT_ENABLE) { + netifapi_netif_set_up(netif); + } else { + netifapi_netif_set_down(netif); + } + res = 0; + } + break; + default: + break; + } + + return res; } /** @} */ From 726e2eb0451abedf323250073c96d87940533f0f Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Wed, 11 Oct 2023 21:38:25 +0200 Subject: [PATCH 5/5] sys/shell/gnrc_netif: Set lwIP netif state on up/down --- sys/shell/cmds/gnrc_netif.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/shell/cmds/gnrc_netif.c b/sys/shell/cmds/gnrc_netif.c index 47a2f33acf72..e46e0423ad99 100644 --- a/sys/shell/cmds/gnrc_netif.c +++ b/sys/shell/cmds/gnrc_netif.c @@ -1684,10 +1684,17 @@ static uint8_t _get_prefix_len(char *addr) static int _netif_link(netif_t *iface, netopt_enable_t en) { +#if IS_USED(MODULE_LWIP_NETIF) /* lwIP sets netif state, not link state */ + if (netif_set_opt(iface, NETOPT_ACTIVE, 0, &en, sizeof(en)) < 0) { + printf("error: unable to set state %s\n", en == NETOPT_ENABLE ? "up" : "down"); + return 1; + } +#else if (netif_set_opt(iface, NETOPT_LINK, 0, &en, sizeof(en)) < 0) { printf("error: unable to set link %s\n", en == NETOPT_ENABLE ? "up" : "down"); return 1; } +#endif return 0; }