Bug #49125 addendum: Remove group from list before callback

When leaving a multicast group, remove the group from the list
before invoking the MAC filter callback. This avoids the need
for the callee to skip over the group that is about to be deleted.
This commit is contained in:
Daniel Elstner 2016-09-19 10:01:47 +02:00 committed by Dirk Ziegelmeier
parent 2facd2d64d
commit 4d4710dadf
2 changed files with 18 additions and 16 deletions

View File

@ -284,7 +284,7 @@ igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr)
}
/**
* Remove a group in the global igmp_group_list
* Remove a group in the global igmp_group_list, but don't free it yet
*
* @param group the group to remove from the global igmp_group_list
* @return ERR_OK if group was removed from the list, an err_t otherwise
@ -311,8 +311,6 @@ igmp_remove_group(struct igmp_group *group)
err = ERR_ARG;
}
}
/* free group */
memp_free(MEMP_IGMP_GROUP, group);
return err;
}
@ -601,6 +599,9 @@ igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
/* If there is no other use of the group */
if (group->use <= 1) {
/* Remove the group from the list */
igmp_remove_group(group);
/* If we are the last reporter for this group */
if (group->last_reporter_flag) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: sending leaving group\n"));
@ -608,6 +609,10 @@ igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
igmp_send(group, IGMP_LEAVE_GROUP);
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: remove group: "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
/* Disable the group at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: igmp_mac_filter(DEL "));
@ -616,12 +621,8 @@ igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr)
netif->igmp_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER);
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: remove group: "));
ip4_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
/* Free the group */
igmp_remove_group(group);
/* Free group struct */
memp_free(MEMP_IGMP_GROUP, group);
} else {
/* Decrement group use */
group->use--;

View File

@ -82,7 +82,7 @@ struct mld_group* mld_group_list;
/* Forward declarations. */
static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr);
static err_t mld6_free_group(struct mld_group *group);
static err_t mld6_remove_group(struct mld_group *group);
static void mld6_delayed_report(struct mld_group *group, u16_t maxresp);
static void mld6_send(struct mld_group *group, u8_t type);
@ -200,13 +200,13 @@ mld6_new_group(struct netif *ifp, const ip6_addr_t *addr)
}
/**
* Remove a group in the mld_group_list and free
* Remove a group from the mld_group_list, but do not free it yet
*
* @param group the group to remove
* @return ERR_OK if group was removed from the list, an err_t otherwise
*/
static err_t
mld6_free_group(struct mld_group *group)
mld6_remove_group(struct mld_group *group)
{
err_t err = ERR_OK;
@ -227,8 +227,6 @@ mld6_free_group(struct mld_group *group)
err = ERR_ARG;
}
}
/* free group */
memp_free(MEMP_MLD6_GROUP, group);
return err;
}
@ -440,6 +438,9 @@ mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
if (group != NULL) {
/* Leave if there is no other use of the group */
if (group->use <= 1) {
/* Remove the group from the list */
mld6_remove_group(group);
/* If we are the last reporter for this group */
if (group->last_reporter_flag) {
MLD6_STATS_INC(mld6.tx_leave);
@ -451,8 +452,8 @@ mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr)
netif->mld_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER);
}
/* Free the group */
mld6_free_group(group);
/* free group struct */
memp_free(MEMP_MLD6_GROUP, group);
} else {
/* Decrement group use */
group->use--;