Skip to content

Commit

Permalink
net: ipv6: Clear joined flag on all mcast address when operational down
Browse files Browse the repository at this point in the history
When the network inteface goes operational DOWN (for example cable
unplugged), clear "joined" flag on all registered multicast addresses,
so that MLD report is sent for them when the interface goes back up.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
  • Loading branch information
rlubos committed May 10, 2024
1 parent faa3ffe commit 120d8d1
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions subsys/net/ip/net_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -1667,6 +1667,7 @@ static void rejoin_ipv6_mcast_groups(struct net_if *iface)
goto out;
}

/* Rejoin solicited node multicasts. */
ARRAY_FOR_EACH(ipv6->unicast, i) {
if (!ipv6->unicast[i].is_used) {
continue;
Expand All @@ -1675,6 +1676,52 @@ static void rejoin_ipv6_mcast_groups(struct net_if *iface)
join_mcast_nodes(iface, &ipv6->unicast[i].address.in6_addr);
}

/* Rejoin any mcast address present on the interface, but marked as not joined. */
ARRAY_FOR_EACH(ipv6->mcast, i) {
int ret;

if (!ipv6->mcast[i].is_used ||
net_if_ipv4_maddr_is_joined(&ipv6->mcast[i])) {
continue;
}

ret = net_ipv6_mld_join(iface, &ipv6->mcast[i].address.in6_addr);
if (ret < 0) {
NET_ERR("Cannot join mcast address %s for %d (%d)",
net_sprint_ipv6_addr(&ipv6->mcast[i].address.in6_addr),
net_if_get_by_iface(iface), ret);
}
}

out:
net_if_unlock(iface);
}

/* To be called when interface comes operational down so that multicast
* groups are rejoined when back up.
*/
static void clear_joined_ipv6_mcast_groups(struct net_if *iface)
{
struct net_if_ipv6 *ipv6;

net_if_lock(iface);

if (!net_if_flag_is_set(iface, NET_IF_IPV6)) {
goto out;
}

if (net_if_config_ipv6_get(iface, &ipv6) < 0) {
goto out;
}

ARRAY_FOR_EACH(ipv6->mcast, i) {
if (!ipv6->mcast[i].is_used) {
continue;
}

net_if_ipv6_maddr_leave(iface, &ipv6->mcast[i]);
}

out:
net_if_unlock(iface);
}
Expand Down Expand Up @@ -5033,6 +5080,7 @@ static void notify_iface_down(struct net_if *iface)

if (!net_if_is_offloaded(iface) &&
!(l2_flags_get(iface) & NET_L2_POINT_TO_POINT)) {
clear_joined_ipv6_mcast_groups(iface);
iface_ipv6_stop(iface);
net_ipv4_autoconf_reset(iface);
}
Expand Down

0 comments on commit 120d8d1

Please sign in to comment.