igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). igmp_report_groups() is now called inside netif_set_link_up() (need to have LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait the next query message to receive the matching multicast streams).

This commit is contained in:
fbernon 2007-09-09 20:46:33 +00:00
parent 8205737fdb
commit 939180c1a1
6 changed files with 127 additions and 12 deletions

View File

@ -19,6 +19,14 @@ HISTORY
++ New features:
2007-09-09 Frédéric Bernon, Bill Florac
* igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP,
and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags
if you want IGMP on an interface. igmp_stop() is now called inside netif_remove().
igmp_report_groups() is now called inside netif_set_link_up() (need to have
LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait
the next query message to receive the matching multicast streams).
2007-09-08 Frédéric Bernon
* sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains
IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change).

View File

@ -117,6 +117,27 @@ igmp_init(void)
igmp_group_list = NULL;
}
#ifdef LWIP_DEBUG
/**
* Dump global IGMP groups list
*/
void
igmp_dump_group_list()
{
struct igmp_group *group = igmp_group_list;
while (group != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_dump_group_list: [%"U32_F"] ", (u32_t)(group->group_state)));
ip_addr_debug_print(IGMP_DEBUG, &group->group_address);
LWIP_DEBUGF(IGMP_DEBUG, (" on if %x\n", (int) group->interface));
group = group->next;
}
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
}
#else
#define igmp_dump_group_list()
#endif /* LWIP_DEBUG */
/**
* Start IGMP processing on interface
*
@ -149,6 +170,70 @@ igmp_start(struct netif *netif)
return ERR_MEM;
}
/**
* Stop IGMP processing on interface
*
* @param netif network interface on which stop IGMP processing
*/
err_t
igmp_stop(struct netif *netif)
{
struct igmp_group *group = igmp_group_list;
struct igmp_group *prev = NULL;
struct igmp_group *next;
/* look for groups joined on this interface further down the list */
while (group != NULL) {
next = group->next;
/* is it a group joined on this interface? */
if (group->interface == netif) {
/* is it the first group of the list? */
if (group == igmp_group_list) {
igmp_group_list = next;
}
/* is there a "previous" group defined? */
if (prev != NULL) {
prev->next = next;
}
/* disable the group at the MAC level */
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL "));
ip_addr_debug_print(IGMP_DEBUG, &group->group_address);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %x\n", (int) netif));
netif->igmp_mac_filter(netif, &(group->group_address), IGMP_DEL_MAC_FILTER);
}
/* free group */
memp_free(MEMP_IGMP_GROUP, group);
} else {
/* change the "previous" */
prev = group;
}
/* move to "next" */
group = next;
}
return ERR_OK;
}
/**
* Report IGMP memberships for this interface
*
* @param netif network interface on which report IGMP memberships
*/
void
igmp_report_groups( struct netif *netif)
{
struct igmp_group *group = igmp_group_list;
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %x\n", (int) netif));
while (group != NULL) {
if (group->interface == netif) {
igmp_delaying_member( group, IGMP_JOIN_DELAYING_MEMBER_TMR);
}
group = group->next;
}
}
/**
* Search for a group in the global igmp_group_list
*
@ -162,7 +247,7 @@ igmp_lookfor_group(struct netif *ifp, struct ip_addr *addr)
{
struct igmp_group *group = igmp_group_list;
while (group) {
while (group != NULL) {
if ((group->interface == ifp) && (ip_addr_cmp(&(group->group_address), addr))) {
return group;
}
@ -224,14 +309,14 @@ igmp_lookup_group(struct netif *ifp, struct ip_addr *addr)
*/
err_t
igmp_remove_group(struct igmp_group *group)
{
{
err_t err = ERR_OK;
/* Is it the first group? */
if (igmp_group_list == group) {
igmp_group_list = group->next;
} else {
/* look for group further down the list */
/* look for group further down the list */
struct igmp_group *tmpGroup;
for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) {
if (tmpGroup->next == group) {
@ -245,7 +330,7 @@ igmp_remove_group(struct igmp_group *group)
}
/* free group */
memp_free(MEMP_IGMP_GROUP, group);
return err;
}
@ -386,7 +471,7 @@ igmp_joingroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
netif = netif_list;
while (netif != NULL) {
/* Should we join this interface ? */
if ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr))) {
if ((netif->flags & NETIF_FLAG_IGMP) && ((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);
@ -456,7 +541,7 @@ igmp_leavegroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
netif = netif_list;
while (netif != NULL) {
/* Should we leave this interface ? */
if ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr))) {
if ((netif->flags & NETIF_FLAG_IGMP) && ((ip_addr_isany(ifaddr) || ip_addr_cmp(&(netif->ip_addr), ifaddr)))) {
/* find group */
group = igmp_lookfor_group(netif, groupaddr);
@ -479,7 +564,7 @@ igmp_leavegroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
if (netif->igmp_mac_filter != NULL) {
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: igmp_mac_filter(DEL "));
ip_addr_debug_print(IGMP_DEBUG, groupaddr);
LWIP_DEBUGF(IGMP_DEBUG, (") on if %x\n", (int) netif));
LWIP_DEBUGF(IGMP_DEBUG, (") on if %x\n", (int) netif));
netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER);
}

View File

@ -237,7 +237,7 @@ ip_input(struct pbuf *p, struct netif *inp) {
/* match packet against an interface, i.e. is this packet for us? */
#if LWIP_IGMP
if (ip_addr_ismulticast(&(iphdr->dest)))
{ if (igmp_lookfor_group( inp, &(iphdr->dest)))
{ if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group( inp, &(iphdr->dest))))
{ netif = inp;
}
else

View File

@ -138,7 +138,9 @@ netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
#if LWIP_IGMP
/* start IGMP processing */
igmp_start( netif);
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_start( netif);
}
#endif /* LWIP_IGMP */
LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP addr ",
@ -179,6 +181,13 @@ void netif_remove(struct netif * netif)
{
if ( netif == NULL ) return;
#if LWIP_IGMP
/* stop IGMP processing */
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_stop( netif);
}
#endif /* LWIP_IGMP */
snmp_delete_ipaddridx_tree(netif);
/* is it the first netif? */
@ -461,6 +470,13 @@ void netif_set_link_up(struct netif *netif )
}
#endif /* LWIP_ARP */
#if LWIP_IGMP
/* resend IGMP memberships */
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_report_groups( netif);
}
#endif /* LWIP_IGMP */
NETIF_LINK_CALLBACK(netif);
}

View File

@ -112,11 +112,15 @@ void igmp_init(void);
err_t igmp_start( struct netif *netif);
struct igmp_group *igmp_lookfor_group(struct netif *ifp, struct ip_addr *addr);
err_t igmp_stop( struct netif *netif);
struct igmp_group *igmp_lookup_group(struct netif *ifp, struct ip_addr *addr);
void igmp_report_groups( struct netif *netif);
err_t igmp_remove_group(struct igmp_group *group);
struct igmp_group *igmp_lookfor_group( struct netif *ifp, struct ip_addr *addr);
struct igmp_group *igmp_lookup_group( struct netif *ifp, struct ip_addr *addr);
err_t igmp_remove_group( struct igmp_group *group);
void igmp_input( struct pbuf *p, struct netif *inp, struct ip_addr *dest);

View File

@ -76,6 +76,8 @@ extern "C" {
#define NETIF_FLAG_LINK_UP 0x10U
/** if set, the netif is an device using ARP */
#define NETIF_FLAG_ETHARP 0x20U
/** if set, the netif has IGMP capability */
#define NETIF_FLAG_IGMP 0x40U
/** Generic data structure used for all lwIP network interfaces.
* The following fields should be filled in by the initialization