net: if: Add IPv4 support to multicast monitor

Make multicast group join/leave monitor support both IPv6 and IPv4
addresses.

Fixes #26585

Signed-off-by: Markus Fuchs <markus.fuchs@ch.sauter-bc.com>
This commit is contained in:
Markus Fuchs 2021-09-13 16:44:44 +02:00 committed by Christopher Friedt
parent 49b36f4e79
commit 7926657b27
5 changed files with 72 additions and 48 deletions

View file

@ -130,6 +130,8 @@ enum net_event_ipv6_cmd {
enum net_event_ipv4_cmd {
NET_EVENT_IPV4_CMD_ADDR_ADD = 1,
NET_EVENT_IPV4_CMD_ADDR_DEL,
NET_EVENT_IPV4_CMD_MADDR_ADD,
NET_EVENT_IPV4_CMD_MADDR_DEL,
NET_EVENT_IPV4_CMD_ROUTER_ADD,
NET_EVENT_IPV4_CMD_ROUTER_DEL,
NET_EVENT_IPV4_CMD_DHCP_START,
@ -145,6 +147,12 @@ enum net_event_ipv4_cmd {
#define NET_EVENT_IPV4_ADDR_DEL \
(_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_ADDR_DEL)
#define NET_EVENT_IPV4_MADDR_ADD \
(_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_MADDR_ADD)
#define NET_EVENT_IPV4_MADDR_DEL \
(_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_MADDR_DEL)
#define NET_EVENT_IPV4_ROUTER_ADD \
(_NET_EVENT_IPV4_BASE | NET_EVENT_IPV4_CMD_ROUTER_ADD)

View file

@ -1043,11 +1043,11 @@ struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(const struct in6_addr *addr,
* @param iface A pointer to a struct net_if to which the multicast address is
* attached.
* @param addr IPv6 multicast address.
* @param addr IP multicast address.
* @param is_joined True if the address is joined, false if left.
*/
typedef void (*net_if_mcast_callback_t)(struct net_if *iface,
const struct in6_addr *addr,
const struct net_addr *addr,
bool is_joined);
/**
@ -1095,7 +1095,7 @@ void net_if_mcast_mon_unregister(struct net_if_mcast_monitor *mon);
* @param addr Multicast address
* @param is_joined Is this multicast address joined (true) or not (false)
*/
void net_if_mcast_monitor(struct net_if *iface, const struct in6_addr *addr,
void net_if_mcast_monitor(struct net_if *iface, const struct net_addr *addr,
bool is_joined);
/**

View file

@ -285,6 +285,8 @@ int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr)
net_if_ipv4_maddr_join(maddr);
net_if_mcast_monitor(iface, &maddr->address, true);
net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_JOIN, iface,
&maddr->address.in_addr,
sizeof(struct in_addr));
@ -312,6 +314,8 @@ int net_ipv4_igmp_leave(struct net_if *iface, const struct in_addr *addr)
net_if_ipv4_maddr_leave(maddr);
net_if_mcast_monitor(iface, &maddr->address, false);
net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_LEAVE, iface,
&maddr->address.in_addr,
sizeof(struct in_addr));

View file

@ -201,7 +201,7 @@ int net_ipv6_mld_join(struct net_if *iface, const struct in6_addr *addr)
net_if_ipv6_maddr_join(maddr);
net_if_mcast_monitor(iface, addr, true);
net_if_mcast_monitor(iface, &maddr->address, true);
net_mgmt_event_notify_with_info(NET_EVENT_IPV6_MCAST_JOIN, iface,
&maddr->address.in6_addr,
@ -229,7 +229,7 @@ int net_ipv6_mld_leave(struct net_if *iface, const struct in6_addr *addr)
return ret;
}
net_if_mcast_monitor(iface, addr, false);
net_if_mcast_monitor(iface, &maddr->address, false);
net_mgmt_event_notify_with_info(NET_EVENT_IPV6_MCAST_LEAVE, iface,
&maddr->address.in6_addr,

View file

@ -90,7 +90,7 @@ static struct {
*/
static sys_slist_t link_callbacks;
#if defined(CONFIG_NET_NATIVE_IPV6)
#if defined(CONFIG_NET_NATIVE_IPV4) || defined(CONFIG_NET_NATIVE_IPV6)
/* Multicast join/leave tracking.
*/
static sys_slist_t mcast_monitor_callbacks;
@ -920,6 +920,50 @@ static void iface_router_init(void)
#define iface_router_init(...)
#endif
#if defined(CONFIG_NET_NATIVE_IPV4) || defined(CONFIG_NET_NATIVE_IPV6)
void net_if_mcast_mon_register(struct net_if_mcast_monitor *mon,
struct net_if *iface,
net_if_mcast_callback_t cb)
{
k_mutex_lock(&lock, K_FOREVER);
sys_slist_find_and_remove(&mcast_monitor_callbacks, &mon->node);
sys_slist_prepend(&mcast_monitor_callbacks, &mon->node);
mon->iface = iface;
mon->cb = cb;
k_mutex_unlock(&lock);
}
void net_if_mcast_mon_unregister(struct net_if_mcast_monitor *mon)
{
k_mutex_lock(&lock, K_FOREVER);
sys_slist_find_and_remove(&mcast_monitor_callbacks, &mon->node);
k_mutex_unlock(&lock);
}
void net_if_mcast_monitor(struct net_if *iface,
const struct net_addr *addr,
bool is_joined)
{
struct net_if_mcast_monitor *mon, *tmp;
k_mutex_lock(&lock, K_FOREVER);
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&mcast_monitor_callbacks,
mon, tmp, node) {
if (iface == mon->iface) {
mon->cb(iface, addr, is_joined);
}
}
k_mutex_unlock(&lock);
}
#endif
#if defined(CONFIG_NET_NATIVE_IPV6)
int net_if_config_ipv6_get(struct net_if *iface, struct net_if_ipv6 **ipv6)
{
@ -1981,48 +2025,6 @@ void net_if_ipv6_maddr_join(struct net_if_mcast_addr *addr)
k_mutex_unlock(&lock);
}
void net_if_mcast_mon_register(struct net_if_mcast_monitor *mon,
struct net_if *iface,
net_if_mcast_callback_t cb)
{
k_mutex_lock(&lock, K_FOREVER);
sys_slist_find_and_remove(&mcast_monitor_callbacks, &mon->node);
sys_slist_prepend(&mcast_monitor_callbacks, &mon->node);
mon->iface = iface;
mon->cb = cb;
k_mutex_unlock(&lock);
}
void net_if_mcast_mon_unregister(struct net_if_mcast_monitor *mon)
{
k_mutex_lock(&lock, K_FOREVER);
sys_slist_find_and_remove(&mcast_monitor_callbacks, &mon->node);
k_mutex_unlock(&lock);
}
void net_if_mcast_monitor(struct net_if *iface,
const struct in6_addr *addr,
bool is_joined)
{
struct net_if_mcast_monitor *mon, *tmp;
k_mutex_lock(&lock, K_FOREVER);
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&mcast_monitor_callbacks,
mon, tmp, node) {
if (iface == mon->iface) {
mon->cb(iface, addr, is_joined);
}
}
k_mutex_unlock(&lock);
}
static void remove_prefix_addresses(struct net_if *iface,
struct net_if_ipv6 *ipv6,
struct in6_addr *addr,
@ -3673,6 +3675,11 @@ struct net_if_mcast_addr *net_if_ipv4_maddr_add(struct net_if *iface,
NET_DBG("interface %p address %s added", iface,
log_strdup(net_sprint_ipv4_addr(addr)));
net_mgmt_event_notify_with_info(
NET_EVENT_IPV4_MADDR_ADD, iface,
&maddr->address.in_addr,
sizeof(struct in_addr));
}
out:
@ -3695,6 +3702,11 @@ bool net_if_ipv4_maddr_rm(struct net_if *iface, const struct in_addr *addr)
NET_DBG("interface %p address %s removed",
iface, log_strdup(net_sprint_ipv4_addr(addr)));
net_mgmt_event_notify_with_info(
NET_EVENT_IPV4_MADDR_DEL, iface,
&maddr->address.in_addr,
sizeof(struct in_addr));
ret = true;
}