net: if: Allow app to disable IPv4 or IPv6 for the interface

Application can disable IPv4 or IPv6 later if those are not
needed nor used for a given network interface.

Fixes #14581

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2021-02-23 12:19:10 +02:00 committed by Anas Nashif
commit 897698bc78
3 changed files with 61 additions and 5 deletions

View file

@ -187,6 +187,12 @@ enum net_if_flag {
*/
NET_IF_FORWARD_MULTICASTS,
/** Interface supports IPv4 */
NET_IF_IPV4,
/** Interface supports IPv6 */
NET_IF_IPV6,
/** @cond INTERNAL_HIDDEN */
/* Total number of flags - must be at the end of the enum */
NET_IF_NUM_FLAGS

View file

@ -427,6 +427,16 @@ static inline void init_iface(struct net_if *iface)
return;
}
/* By default IPv4 and IPv6 are enabled for a given network interface.
* These can be turned off later if needed.
*/
#if defined(CONFIG_NET_NATIVE_IPV4)
net_if_flag_set(iface, NET_IF_IPV4);
#endif
#if defined(CONFIG_NET_NATIVE_IPV6)
net_if_flag_set(iface, NET_IF_IPV6);
#endif
NET_DBG("On iface %p", iface);
#ifdef CONFIG_USERSPACE
@ -940,6 +950,11 @@ int net_if_config_ipv6_get(struct net_if *iface, struct net_if_ipv6 **ipv6)
k_mutex_lock(&lock, K_FOREVER);
if (!net_if_flag_is_set(iface, NET_IF_IPV6)) {
ret = -ENOTSUP;
goto out;
}
if (iface->config.ip.ipv6) {
if (ipv6) {
*ipv6 = iface->config.ip.ipv6;
@ -977,6 +992,11 @@ int net_if_config_ipv6_put(struct net_if *iface)
k_mutex_lock(&lock, K_FOREVER);
if (!net_if_flag_is_set(iface, NET_IF_IPV6)) {
ret = -ENOTSUP;
goto out;
}
if (!iface->config.ip.ipv6) {
ret = -EALREADY;
goto out;
@ -1173,14 +1193,18 @@ void net_if_start_dad(struct net_if *iface)
struct net_if_addr *ifaddr;
struct net_if_ipv6 *ipv6;
struct in6_addr addr = { };
int i;
int ret, i;
k_mutex_lock(&lock, K_FOREVER);
NET_DBG("Starting DAD for iface %p", iface);
if (net_if_config_ipv6_get(iface, &ipv6) < 0) {
NET_WARN("Cannot do DAD IPv6 config is not valid.");
ret = net_if_config_ipv6_get(iface, &ipv6);
if (ret < 0) {
if (ret != -ENOTSUP) {
NET_WARN("Cannot do DAD IPv6 config is not valid.");
}
goto out;
}
@ -2786,6 +2810,11 @@ int net_if_config_ipv4_get(struct net_if *iface, struct net_if_ipv4 **ipv4)
k_mutex_lock(&lock, K_FOREVER);
if (!net_if_flag_is_set(iface, NET_IF_IPV4)) {
ret = -ENOTSUP;
goto out;
}
if (iface->config.ip.ipv4) {
if (ipv4) {
*ipv4 = iface->config.ip.ipv4;
@ -2823,6 +2852,11 @@ int net_if_config_ipv4_put(struct net_if *iface)
k_mutex_lock(&lock, K_FOREVER);
if (!net_if_flag_is_set(iface, NET_IF_IPV4)) {
ret = -ENOTSUP;
goto out;
}
if (!iface->config.ip.ipv4) {
ret = -EALREADY;
goto out;

View file

@ -395,6 +395,12 @@ static void iface_cb(struct net_if *iface, void *user_data)
#if defined(CONFIG_NET_IPV6)
count = 0;
if (!net_if_flag_is_set(iface, NET_IF_IPV6)) {
PR("%s not %s for this interface.\n", "IPv6", "enabled");
ipv6 = NULL;
goto skip_ipv6;
}
ipv6 = iface->config.ip.ipv6;
PR("IPv6 unicast addresses (max %d):\n", NET_IF_MAX_IPV6_ADDR);
@ -466,6 +472,8 @@ static void iface_cb(struct net_if *iface, void *user_data)
router->is_infinite ? " infinite" : "");
}
skip_ipv6:
if (ipv6) {
PR("IPv6 hop limit : %d\n",
ipv6->hop_limit);
@ -476,7 +484,6 @@ static void iface_cb(struct net_if *iface, void *user_data)
PR("IPv6 retransmit timer : %d\n",
ipv6->retrans_timer);
}
#endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_IPV4)
@ -491,12 +498,19 @@ static void iface_cb(struct net_if *iface, void *user_data)
(net_if_l2(iface) == &NET_L2_GET_NAME(BLUETOOTH)) ||
#endif
0) {
PR_WARNING("IPv4 not supported for this interface.\n");
PR_WARNING("%s not %s for this interface.\n", "IPv4",
"supported");
return;
}
count = 0;
if (!net_if_flag_is_set(iface, NET_IF_IPV4)) {
PR("%s not %s for this interface.\n", "IPv4", "enabled");
ipv4 = NULL;
goto skip_ipv4;
}
ipv4 = iface->config.ip.ipv4;
PR("IPv4 unicast addresses (max %d):\n", NET_IF_MAX_IPV4_ADDR);
@ -539,6 +553,8 @@ static void iface_cb(struct net_if *iface, void *user_data)
PR("\t<none>\n");
}
skip_ipv4:
if (ipv4) {
PR("IPv4 gateway : %s\n",
net_sprint_ipv4_addr(&ipv4->gw));