net: if: Leave all joined IPv6 multicast groups at net_if_down
When network interface is taken down, leave only those IPv6 multicast groups that were joined. Change-Id: I414556c093ba67be7c13e6c86e0451465c2203f3 Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
c3c76f35cc
commit
f8467437e6
3 changed files with 41 additions and 23 deletions
|
@ -75,7 +75,12 @@ struct net_if_addr {
|
|||
*/
|
||||
struct net_if_mcast_addr {
|
||||
/** Is this multicast IP address used or not */
|
||||
bool is_used;
|
||||
uint8_t is_used : 1;
|
||||
|
||||
/** Did we join to this group */
|
||||
uint8_t is_joined : 1;
|
||||
|
||||
uint8_t _unused : 6;
|
||||
|
||||
/** IP address */
|
||||
struct net_addr address;
|
||||
|
@ -631,6 +636,30 @@ bool net_if_ipv6_maddr_rm(struct net_if *iface, const struct in6_addr *addr);
|
|||
struct net_if_mcast_addr *net_if_ipv6_maddr_lookup(const struct in6_addr *addr,
|
||||
struct net_if **iface);
|
||||
|
||||
/**
|
||||
* @brief Mark a given multicast address to be joined.
|
||||
*
|
||||
* @param addr IPv6 multicast address
|
||||
*/
|
||||
static inline void net_if_ipv6_maddr_join(struct net_if_mcast_addr *addr)
|
||||
{
|
||||
NET_ASSERT(addr);
|
||||
|
||||
addr->is_joined = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Mark a given multicast address to be left.
|
||||
*
|
||||
* @param addr IPv6 multicast address
|
||||
*/
|
||||
static inline void net_if_ipv6_maddr_leave(struct net_if_mcast_addr *addr)
|
||||
{
|
||||
NET_ASSERT(addr);
|
||||
|
||||
addr->is_joined = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if this IPv6 prefix belongs to this interface
|
||||
*
|
||||
|
|
|
@ -2284,7 +2284,7 @@ static int send_mldv2(struct net_if *iface, const struct in6_addr *addr,
|
|||
|
||||
int net_ipv6_mld_join(struct net_if *iface, const struct in6_addr *addr)
|
||||
{
|
||||
const struct net_if_mcast_addr *maddr;
|
||||
struct net_if_mcast_addr *maddr;
|
||||
int ret;
|
||||
|
||||
maddr = net_if_ipv6_maddr_lookup(addr, &iface);
|
||||
|
@ -2302,6 +2302,8 @@ int net_ipv6_mld_join(struct net_if *iface, const struct in6_addr *addr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
net_if_ipv6_maddr_join(maddr);
|
||||
|
||||
net_mgmt_event_notify(NET_EVENT_IPV6_MCAST_JOIN, iface);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -265,35 +265,24 @@ static void join_mcast_solicit_node(struct net_if *iface,
|
|||
net_ipv6_mld_join(iface, &addr);
|
||||
}
|
||||
|
||||
static void leave_mcast_allnodes(struct net_if *iface)
|
||||
static void leave_mcast_all(struct net_if *iface)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
|
||||
net_ipv6_addr_create_ll_allnodes_mcast(&addr);
|
||||
net_ipv6_mld_leave(iface, &addr);
|
||||
}
|
||||
|
||||
static void leave_mcast_solicit_node_all(struct net_if *iface)
|
||||
{
|
||||
struct in6_addr addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NET_IF_MAX_IPV6_MADDR; i++) {
|
||||
if (!iface->ipv6.mcast[i].is_used) {
|
||||
if (!iface->ipv6.mcast[i].is_used ||
|
||||
!iface->ipv6.mcast[i].is_joined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
net_ipv6_addr_create_solicited_node(
|
||||
&iface->ipv6.mcast[i].address.in6_addr, &addr);
|
||||
|
||||
net_ipv6_mld_leave(iface, &addr);
|
||||
net_ipv6_mld_leave(iface,
|
||||
&iface->ipv6.mcast[i].address.in6_addr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define join_mcast_allnodes(...)
|
||||
#define join_mcast_solicit_node(...)
|
||||
#define leave_mcast_allnodes(...)
|
||||
#define leave_mcast_solicit_node_all(...)
|
||||
#define leave_mcast_all(...)
|
||||
#endif /* CONFIG_NET_IPV6_MLD */
|
||||
|
||||
#if defined(CONFIG_NET_IPV6_DAD)
|
||||
|
@ -1186,8 +1175,7 @@ uint32_t net_if_ipv6_calc_reachable_time(struct net_if *iface)
|
|||
#else /* CONFIG_NET_IPV6 */
|
||||
#define join_mcast_allnodes(...)
|
||||
#define join_mcast_solicit_node(...)
|
||||
#define leave_mcast_allnodes(...)
|
||||
#define leave_mcast_solicit_node_all(...)
|
||||
#define leave_mcast_all(...)
|
||||
#endif /* CONFIG_NET_IPV6 */
|
||||
|
||||
#if defined(CONFIG_NET_IPV4)
|
||||
|
@ -1499,8 +1487,7 @@ int net_if_down(struct net_if *iface)
|
|||
/* FIXME: Make sure that the IPV6 mcast leave message
|
||||
* gets actually sent.
|
||||
*/
|
||||
leave_mcast_allnodes(iface);
|
||||
leave_mcast_solicit_node_all(iface);
|
||||
leave_mcast_all(iface);
|
||||
|
||||
/* If the L2 does not support enable just clear the flag */
|
||||
if (!iface->l2->enable) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue