From 05b7eda61820e3d1764b3210c4c58a1834094adb Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Fri, 25 Aug 2023 11:03:12 +0300 Subject: [PATCH] net: Add name support to network interface If CONFIG_NET_INTERFACE_NAME is enabled (default is y), then system will automatically set a user friendly name to the network interface like eth0, wlan0 etc. Application can change the interface name if needed. Signed-off-by: Jukka Rissanen --- include/zephyr/net/net_if.h | 48 ++++++++++++ subsys/net/ip/Kconfig | 15 ++++ subsys/net/ip/net_if.c | 146 ++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 7807e42515..cced3557b8 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -424,6 +424,14 @@ struct net_if_config { */ sys_slist_t virtual_interfaces; #endif /* CONFIG_NET_L2_VIRTUAL */ + +#if defined(CONFIG_NET_INTERFACE_NAME) + /** + * Network interface can have a name and it is possible + * to search a network interface using this name. + */ + char name[CONFIG_NET_INTERFACE_NAME_LEN + 1]; +#endif }; /** @@ -2575,6 +2583,46 @@ bool net_if_is_wifi(struct net_if *iface); */ struct net_if *net_if_get_first_wifi(void); +/** + * @brief Get network interface name. + * + * @details If interface name support is not enabled, empty string is returned. + * + * @param iface Pointer to network interface + * @param buf User supplied buffer + * @param len Length of the user supplied buffer + * + * @return Length of the interface name copied to buf, + * -EINVAL if invalid parameters, + * -ERANGE if name cannot be copied to the user supplied buffer, + * -ENOTSUP if interface name support is disabled, + */ +int net_if_get_name(struct net_if *iface, char *buf, int len); + +/** + * @brief Set network interface name. + * + * @details Normally this function is not needed to call as the system + * will automatically assign a name to the network interface. + * + * @param iface Pointer to network interface + * @param buf User supplied name + * + * @return 0 name is set correctly + * -ENOTSUP interface name support is disabled + * -EINVAL if invalid parameters are given, + * -ENAMETOOLONG if name is too long + */ +int net_if_set_name(struct net_if *iface, const char *buf); + +/** + * @brief Get interface index according to its name + * + * @param name Name of the network interface + * + * @return Interface index + */ +int net_if_get_by_name(const char *name); /** @cond INTERNAL_HIDDEN */ struct net_if_api { diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index f5b01fca0b..d7edb98855 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -859,6 +859,21 @@ config NET_DEFAULT_IF_WIFI endchoice +config NET_INTERFACE_NAME + bool "Allow setting a name to a network interface" + default y + help + Allow application to set a name to the network interface in order + to simplify network interface management. + +config NET_INTERFACE_NAME_LEN + int "Network interface max name length" + default 8 + range 1 15 + depends on NET_INTERFACE_NAME + help + Maximum length of the network interface name. + config NET_PKT_TIMESTAMP bool "Network packet timestamp support" help diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index e779ff4bb0..e6e3512e4b 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016 Intel Corporation. + * Copyright (c) 2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -4732,6 +4733,144 @@ struct net_if *net_if_get_first_wifi(void) return NULL; } +int net_if_get_name(struct net_if *iface, char *buf, int len) +{ +#if defined(CONFIG_NET_INTERFACE_NAME) + int name_len; + + if (iface == NULL || buf == NULL || len <= 0) { + return -EINVAL; + } + + name_len = strlen(net_if_get_config(iface)->name); + if (name_len >= len) { + return -ERANGE; + } + + strncpy(buf, net_if_get_config(iface)->name, name_len); + + return name_len; +#else + return -ENOTSUP; +#endif +} + +int net_if_set_name(struct net_if *iface, const char *buf) +{ +#if defined(CONFIG_NET_INTERFACE_NAME) + int name_len; + + if (iface == NULL || buf == NULL) { + return -EINVAL; + } + + name_len = strlen(buf); + if (name_len >= sizeof(iface->config.name)) { + return -ENAMETOOLONG; + } + + strncpy(net_if_get_config(iface)->name, buf, name_len); + + return 0; +#else + return -ENOTSUP; +#endif +} + +int net_if_get_by_name(const char *name) +{ +#if defined(CONFIG_NET_INTERFACE_NAME) + if (name == NULL) { + return -EINVAL; + } + + STRUCT_SECTION_FOREACH(net_if, iface) { + if (strncmp(net_if_get_config(iface)->name, name, strlen(name)) == 0) { + return net_if_get_by_iface(iface); + } + } + + return -ENOENT; +#else + return -ENOTSUP; +#endif +} + +#if defined(CONFIG_NET_INTERFACE_NAME) +static void set_default_name(struct net_if *iface) +{ + char name[CONFIG_NET_INTERFACE_NAME_LEN + 1] = { 0 }; + int ret; + + if (net_if_is_wifi(iface)) { + static int count; + + snprintk(name, sizeof(name) - 1, "wlan%d", count++); + + } else if (IS_ENABLED(CONFIG_NET_L2_ETHERNET)) { +#if defined(CONFIG_NET_L2_ETHERNET) + if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) { + static int count; + + snprintk(name, sizeof(name) - 1, "eth%d", count++); + } +#endif /* CONFIG_NET_L2_ETHERNET */ + } + + if (IS_ENABLED(CONFIG_NET_L2_IEEE802154)) { +#if defined(CONFIG_NET_L2_IEEE802154) + if (net_if_l2(iface) == &NET_L2_GET_NAME(IEEE802154)) { + static int count; + + snprintk(name, sizeof(name) - 1, "ieee%d", count++); + } +#endif /* CONFIG_NET_L2_IEEE802154 */ + } + + if (IS_ENABLED(CONFIG_NET_L2_DUMMY)) { +#if defined(CONFIG_NET_L2_DUMMY) + if (net_if_l2(iface) == &NET_L2_GET_NAME(DUMMY)) { + static int count; + + snprintk(name, sizeof(name) - 1, "dummy%d", count++); + } +#endif /* CONFIG_NET_L2_DUMMY */ + } + + if (IS_ENABLED(CONFIG_NET_L2_CANBUS_RAW)) { +#if defined(CONFIG_NET_L2_CANBUS_RAW) + if (net_if_l2(iface) == &NET_L2_GET_NAME(CANBUS_RAW)) { + static int count; + + snprintk(name, sizeof(name) - 1, "can%d", count++); + } +#endif /* CONFIG_NET_L2_CANBUS_RAW */ + } + + if (IS_ENABLED(CONFIG_NET_L2_PPP)) { +#if defined(CONFIG_NET_L2_PPP) + if (net_if_l2(iface) == &NET_L2_GET_NAME(PPP)) { + static int count; + + snprintk(name, sizeof(name) - 1, "ppp%d", count++); + } +#endif /* CONFIG_NET_L2_PPP */ + } + + if (name[0] == '\0') { + static int count; + + snprintk(name, sizeof(name) - 1, "net%d", count++); + } + + ret = net_if_set_name(iface, name); + if (ret < 0) { + NET_WARN("Cannot set default name for interface %d (%p) (%d)", + net_if_get_by_iface(iface), iface, ret); + } +} +#endif /* CONFIG_NET_INTERFACE_NAME */ + void net_if_init(void) { int if_count = 0; @@ -4745,6 +4884,13 @@ void net_if_init(void) STRUCT_SECTION_FOREACH(net_if, iface) { init_iface(iface); if_count++; + +#if defined(CONFIG_NET_INTERFACE_NAME) + memset(net_if_get_config(iface)->name, 0, + sizeof(iface->config.name)); + + set_default_name(iface); +#endif } if (if_count == 0) {