diff --git a/pkg/lwip/contrib/_netif.c b/pkg/lwip/contrib/_netif.c index 42902c7bff07..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) @@ -42,6 +43,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)); @@ -74,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; } /** @} */ 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", diff --git a/sys/shell/cmds/gnrc_netif.c b/sys/shell/cmds/gnrc_netif.c index ac990ab97d6b..48aab41250ad 100644 --- a/sys/shell/cmds/gnrc_netif.c +++ b/sys/shell/cmds/gnrc_netif.c @@ -775,11 +775,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) { @@ -805,9 +811,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++; @@ -1677,10 +1683,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; }