Changes for "#20503 IGMP Improvement". Initialize igmp_mac_filter to NULL in netif_add (this field should be set in the netif's "init" function). Use the "imr_interface" field (for socket layer) and/or the "interface" field (for netconn layer), for join/leave operations. The igmp_join/leavegroup first parameter change from a netif to an ipaddr. This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany).

This commit is contained in:
fbernon
2007-09-03 14:53:18 +00:00
parent 327f06bbaf
commit 62b4741b19
6 changed files with 102 additions and 70 deletions

View File

@@ -330,102 +330,123 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest)
/**
* Join a group on one network interface.
*
* @param ifp the network interface which should join a new group
* @param ifaddr ip address of the network interface which should join a new group
* @param groupaddr the ip address of the group which to join
* @return ERR_OK if group was joined, an err_t otherwise
* @return ERR_OK if group was joined on the netif(s), an err_t otherwise
*/
err_t
igmp_joingroup(struct netif *ifp, struct ip_addr *groupaddr)
igmp_joingroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct igmp_group *group;
/* make sure netif is valid */
LWIP_ERROR("igmp_joingroup: attempt to join on NULL netif", (ifp!=NULL), return ERR_VAL;);
struct netif *netif;
/* make sure it is multicast address */
LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;);
/* find group or create a new one if not found */
group = igmp_lookup_group(ifp, groupaddr);
/* loop through netif's */
netif = netif_list;
while (netif != NULL) {
/* Should we join this interface ? */
if ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr))) {
/* find group or create a new one if not found */
group = igmp_lookup_group(netif, groupaddr);
if (group != NULL) {
/* This should create a new group, check the state to make sure */
if (group->group_state != NON_MEMBER) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state NON_MEMBER\n"));
return ERR_OK;
if (group != NULL) {
/* This should create a new group, check the state to make sure */
if (group->group_state != NON_MEMBER) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state NON_MEMBER\n"));
} else {
/* OK - it was new group */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: "));
ip_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
if (netif->igmp_mac_filter != NULL) {
netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER);
}
IGMP_STATS_INC(igmp.join_sent);
igmp_send(group, IGMP_V2_MEMB_REPORT);
igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
/* Need to work out where this timer comes from */
group->group_state = DELAYING_MEMBER;
}
/* Join on this interface */
err = ERR_OK;
} else {
/* Return an error even if some network interfaces are joined */
/** @todo undo any other netif already joined */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: Not enought memory to join to group\n"));
return ERR_MEM;
}
}
/* OK - it was new group */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to new group: "));
ip_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
if (ifp->igmp_mac_filter != NULL) {
ifp->igmp_mac_filter(ifp, groupaddr, IGMP_ADD_MAC_FILTER);
}
IGMP_STATS_INC(igmp.join_sent);
igmp_send(group, IGMP_V2_MEMB_REPORT);
igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
/* Need to work out where this timer comes from */
group->group_state = DELAYING_MEMBER;
return ERR_OK;
/* proceed to next network interface */
netif = netif->next;
}
return ERR_MEM;
return err;
}
/**
* Leave a group on one network interface.
*
* @param ifp the network interface which should leave a group
* @param ifaddr ip address of the network interface which should leave a group
* @param groupaddr the ip address of the group which to leave
* @return ERR_OK if group was left, an err_t otherwise
* @return ERR_OK if group was left on the netif(s), an err_t otherwise
*/
err_t
igmp_leavegroup(struct netif *ifp, struct ip_addr *groupaddr)
igmp_leavegroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
{
err_t err = ERR_VAL; /* no matching interface */
struct igmp_group *group;
/* make sure netif is valid */
LWIP_ERROR("igmp_leavegroup: attempt to leave on NULL netif", (ifp!=NULL), return ERR_VAL;);
struct netif *netif;
/* make sure it is multicast address */
LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;);
/* find group */
group = igmp_lookfor_group(ifp, groupaddr);
/* loop through netif's */
netif = netif_list;
while (netif != NULL) {
/* Should we leave this interface ? */
if ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr))) {
/* find group */
group = igmp_lookfor_group(netif, groupaddr);
if (group != NULL) {
/* Only send a leave if the flag is set according to the state diagram */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: "));
ip_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
if (group != NULL) {
/* Only send a leave if the flag is set according to the state diagram */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: Leaving group: "));
ip_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
if (group->last_reporter_flag) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n"));
IGMP_STATS_INC(igmp.leave_sent);
igmp_send(group, IGMP_LEAVE_GROUP);
if (group->last_reporter_flag) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: sending leaving group\n"));
IGMP_STATS_INC(igmp.leave_sent);
igmp_send(group, IGMP_LEAVE_GROUP);
}
/* The block is not deleted since the group still exists and we may rejoin */
group->last_reporter_flag = 0;
group->group_state = NON_MEMBER;
group->timer = 0;
if (netif->igmp_mac_filter != NULL) {
netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER);
}
/* Leave on this interface */
err = ERR_OK;
} else {
/* It's not a fatal error on "leavegroup" */
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n"));
}
}
/* The block is not deleted since the group still exists and we may rejoin */
group->last_reporter_flag = 0;
group->group_state = NON_MEMBER;
group->timer = 0;
if (ifp->igmp_mac_filter != NULL) {
ifp->igmp_mac_filter(ifp, groupaddr, IGMP_DEL_MAC_FILTER);
}
return ERR_OK;
/* proceed to next network interface */
netif = netif->next;
}
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: not member of group\n"));
return ERR_VAL;
return err;
}
/**

View File

@@ -115,6 +115,9 @@ netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
#if LWIP_NETIF_LINK_CALLBACK
netif->link_callback = NULL;
#endif /* LWIP_NETIF_LINK_CALLBACK */
#if LWIP_IGMP
netif->igmp_mac_filter = NULL;
#endif /* LWIP_IGMP */
/* remember netif specific state information data */
netif->state = state;