From 1467d7fa7b0ecd288c1de97db5cb0303ed8795e6 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Thu, 26 Oct 2023 10:34:53 +0300 Subject: [PATCH] net: shell: Join IPv4 mcast group if needed If user adds IPv4 address to the network interface, check if the address is a multicast one and add it to multicast group if it is. Fixes #64389 Signed-off-by: Jukka Rissanen --- subsys/net/ip/Kconfig | 1 + subsys/net/lib/shell/ipv4.c | 60 +++++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 1831816ab25..41960201b39 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -158,6 +158,7 @@ config NET_IPV4_MAPPING_TO_IPV6 config NET_SHELL bool "Network shell utilities" select SHELL + select NET_IPV4_IGMP if NET_IPV4 help Activate shell module that provides network commands like ping to the console. diff --git a/subsys/net/lib/shell/ipv4.c b/subsys/net/lib/shell/ipv4.c index 81526dc7807..8fc88168c9a 100644 --- a/subsys/net/lib/shell/ipv4.c +++ b/subsys/net/lib/shell/ipv4.c @@ -8,6 +8,8 @@ #include LOG_MODULE_DECLARE(net_shell); +#include + #include "common.h" #include "../ip/ipv4.h" @@ -92,8 +94,8 @@ static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) int idx; struct in_addr addr; - if (argc != 4) { - PR_ERROR("Correct usage: net ipv4 add
\n"); + if (argc < 3) { + PR_ERROR("Correct usage: net ipv4 add
[]\n"); return -EINVAL; } @@ -113,15 +115,38 @@ static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0); + if (net_ipv4_is_addr_mcast(&addr)) { + int ret; - if (net_addr_pton(AF_INET, argv[3], &addr)) { - PR_ERROR("Invalid netmask: %s", argv[3]); - return -EINVAL; + ret = net_ipv4_igmp_join(iface, &addr); + if (ret < 0) { + PR_ERROR("Cannot %s multicast group %s for interface %d (%d)\n", + "join", net_sprint_ipv4_addr(&addr), idx, ret); + return ret; + } + } else { + struct net_if_addr *ifaddr; + + if (argc < 4) { + PR_ERROR("Netmask is missing.\n"); + return -EINVAL; + } + + ifaddr = net_if_ipv4_addr_add(iface, &addr, NET_ADDR_MANUAL, 0); + if (ifaddr == NULL) { + PR_ERROR("Cannot add address %s to interface %d\n", + net_sprint_ipv4_addr(&addr), idx); + return -ENOMEM; + } + + if (net_addr_pton(AF_INET, argv[3], &addr)) { + PR_ERROR("Invalid netmask: %s", argv[3]); + return -EINVAL; + } + + net_if_ipv4_set_netmask(iface, &addr); } - net_if_ipv4_set_netmask(iface, &addr); - #else /* CONFIG_NET_NATIVE_IPV4 */ PR_INFO("Set %s and %s to enable native %s support.\n", "CONFIG_NET_NATIVE", "CONFIG_NET_IPV4", "IPv4"); @@ -157,9 +182,20 @@ static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) return -EINVAL; } - if (!net_if_ipv4_addr_rm(iface, &addr)) { - PR_ERROR("Failed to delete %s\n", argv[2]); - return -ENOEXEC; + if (net_ipv4_is_addr_mcast(&addr)) { + int ret; + + ret = net_ipv4_igmp_leave(iface, &addr); + if (ret < 0) { + PR_ERROR("Cannot %s multicast group %s for interface %d (%d)\n", + "leave", net_sprint_ipv4_addr(&addr), idx, ret); + return ret; + } + } else { + if (!net_if_ipv4_addr_rm(iface, &addr)) { + PR_ERROR("Failed to delete %s\n", argv[2]); + return -ENOEXEC; + } } #else /* CONFIG_NET_NATIVE_IPV4 */ PR_INFO("Set %s and %s to enable native %s support.\n", @@ -170,7 +206,7 @@ static int cmd_net_ip_del(const struct shell *sh, size_t argc, char *argv[]) SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_ip, SHELL_CMD(add, NULL, - "'net ipv4 add
' adds the address to the interface.", + "'net ipv4 add
[]' adds the address to the interface.", cmd_net_ip_add), SHELL_CMD(del, NULL, "'net ipv4 del
' deletes the address from the interface.",