mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-04 14:29:39 +00:00
Replace mem_malloc call by memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the value). It will avoid potential fragmentation problems, use a counter to know how many times a group is used on an netif, and free it when all applications leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity check if LWIP_IGMP!=0).
This commit is contained in:
parent
d794357504
commit
d4616a7fc6
@ -19,6 +19,14 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2007-09-04 Frédéric Bernon, Bill Florac
|
||||
* igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by
|
||||
memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the
|
||||
value). It will avoid potential fragmentation problems, use a counter to know
|
||||
how many times a group is used on an netif, and free it when all applications
|
||||
leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity
|
||||
check if LWIP_IGMP!=0).
|
||||
|
||||
2007-09-03 Frédéric Bernon
|
||||
* igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement".
|
||||
Initialize igmp_mac_filter to NULL in netif_add (this field should be set in
|
||||
|
@ -84,6 +84,9 @@
|
||||
#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0))
|
||||
#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1))
|
||||
#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h"
|
||||
#endif
|
||||
#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1))
|
||||
#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h"
|
||||
#endif
|
||||
|
@ -93,8 +93,7 @@ Steve Reynolds
|
||||
|
||||
#include "string.h"
|
||||
|
||||
/* IGMP support available? */
|
||||
#if defined(LWIP_IGMP) && (LWIP_IGMP > 0)
|
||||
#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Globales
|
||||
@ -133,10 +132,14 @@ igmp_start(struct netif *netif)
|
||||
group = igmp_lookup_group(netif, &allsystems);
|
||||
|
||||
if (group != NULL) {
|
||||
group->group_state = IDLE_MEMBER;
|
||||
group->group_state = IGMP_GROUP_IDLE_MEMBER;
|
||||
group->use++;
|
||||
|
||||
/* Allow the igmp messages at the MAC level */
|
||||
if (netif->igmp_mac_filter != NULL) {
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD "));
|
||||
ip_addr_debug_print(IGMP_DEBUG, &allsystems);
|
||||
LWIP_DEBUGF(IGMP_DEBUG, (") on if %x\n", (int) netif));
|
||||
netif->igmp_mac_filter( netif, &allsystems, IGMP_ADD_MAC_FILTER);
|
||||
}
|
||||
|
||||
@ -192,16 +195,17 @@ igmp_lookup_group(struct netif *ifp, struct ip_addr *addr)
|
||||
return group;
|
||||
}
|
||||
|
||||
/* Group doesn't exist yet, create a new one. */
|
||||
group = mem_malloc(sizeof(struct igmp_group));
|
||||
/* Group doesn't exist yet, create a new one */
|
||||
group = memp_malloc(MEMP_IGMP_GROUP);
|
||||
if (group != NULL) {
|
||||
group->interface = ifp;
|
||||
ip_addr_set(&(group->group_address), addr);
|
||||
group->timer = 0; /* Not running */
|
||||
group->group_state = NON_MEMBER;
|
||||
group->group_state = IGMP_GROUP_NON_MEMBER;
|
||||
group->last_reporter_flag = 0;
|
||||
group->use = 0;
|
||||
group->next = igmp_group_list;
|
||||
|
||||
|
||||
igmp_group_list = group;
|
||||
}
|
||||
|
||||
@ -212,6 +216,39 @@ igmp_lookup_group(struct netif *ifp, struct ip_addr *addr)
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a group in the global igmp_group_list
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
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 */
|
||||
struct igmp_group *tmpGroup;
|
||||
for (tmpGroup = igmp_group_list; tmpGroup != NULL; tmpGroup = tmpGroup->next) {
|
||||
if (tmpGroup->next == group) {
|
||||
tmpGroup->next = group->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Group not found in the global igmp_group_list */
|
||||
if (tmpGroup == NULL)
|
||||
err = ERR_ARG;
|
||||
}
|
||||
/* free group */
|
||||
memp_free(MEMP_IGMP_GROUP, group);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from ip_input() if a new IGMP packet is received.
|
||||
*
|
||||
@ -309,10 +346,10 @@ igmp_input(struct pbuf *p, struct netif *inp, struct ip_addr *dest)
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n"));
|
||||
|
||||
IGMP_STATS_INC(igmp.report_rxed);
|
||||
if (group->group_state == DELAYING_MEMBER) {
|
||||
if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
|
||||
/* This is on a specific group we have already looked up */
|
||||
group->timer = 0; /* stopped */
|
||||
group->group_state = IDLE_MEMBER;
|
||||
group->group_state = IGMP_GROUP_IDLE_MEMBER;
|
||||
group->last_reporter_flag = 0;
|
||||
}
|
||||
break;
|
||||
@ -343,6 +380,7 @@ igmp_joingroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
|
||||
|
||||
/* make sure it is multicast address */
|
||||
LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;);
|
||||
LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
|
||||
|
||||
/* loop through netif's */
|
||||
netif = netif_list;
|
||||
@ -354,15 +392,19 @@ igmp_joingroup(struct ip_addr *ifaddr, struct ip_addr *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"));
|
||||
if (group->group_state != IGMP_GROUP_NON_MEMBER) {
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: join to group not in state IGMP_GROUP_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) {
|
||||
/* If first use of the group, allow the group at the MAC level */
|
||||
if ((group->use==0) && (netif->igmp_mac_filter != NULL)) {
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup: igmp_mac_filter(ADD "));
|
||||
ip_addr_debug_print(IGMP_DEBUG, groupaddr);
|
||||
LWIP_DEBUGF(IGMP_DEBUG, (") on if %x\n", (int) netif));
|
||||
netif->igmp_mac_filter(netif, groupaddr, IGMP_ADD_MAC_FILTER);
|
||||
}
|
||||
|
||||
@ -372,8 +414,10 @@ igmp_joingroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
|
||||
igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR);
|
||||
|
||||
/* Need to work out where this timer comes from */
|
||||
group->group_state = DELAYING_MEMBER;
|
||||
group->group_state = IGMP_GROUP_DELAYING_MEMBER;
|
||||
}
|
||||
/* Increment group use */
|
||||
group->use++;
|
||||
/* Join on this interface */
|
||||
err = ERR_OK;
|
||||
} else {
|
||||
@ -406,6 +450,7 @@ igmp_leavegroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
|
||||
|
||||
/* make sure it is multicast address */
|
||||
LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip_addr_ismulticast(groupaddr), return ERR_VAL;);
|
||||
LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;);
|
||||
|
||||
/* loop through netif's */
|
||||
netif = netif_list;
|
||||
@ -421,19 +466,32 @@ igmp_leavegroup(struct ip_addr *ifaddr, struct ip_addr *groupaddr)
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
/* If there is no other use of the group */
|
||||
if (group->use <= 1) {
|
||||
/* If we are the last reporter for this 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);
|
||||
}
|
||||
|
||||
/* Disable the group at the MAC level */
|
||||
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));
|
||||
netif->igmp_mac_filter(netif, groupaddr, IGMP_DEL_MAC_FILTER);
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup: remove group: "));
|
||||
ip_addr_debug_print(IGMP_DEBUG, groupaddr);
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("\n"));
|
||||
|
||||
/* Free the group */
|
||||
igmp_remove_group(group);
|
||||
} else {
|
||||
/* Decrement group use */
|
||||
group->use--;
|
||||
}
|
||||
/* Leave on this interface */
|
||||
err = ERR_OK;
|
||||
@ -478,8 +536,8 @@ igmp_tmr(void)
|
||||
void
|
||||
igmp_timeout(struct igmp_group *group)
|
||||
{
|
||||
/* If the state is DELAYING_MEMBER then we send a report for this group */
|
||||
if (group->group_state == DELAYING_MEMBER) {
|
||||
/* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group */
|
||||
if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) {
|
||||
LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address "));
|
||||
ip_addr_debug_print(IGMP_DEBUG, &(group->group_address));
|
||||
LWIP_DEBUGF(IGMP_DEBUG, (" on if %x\n", (int) group->interface));
|
||||
@ -524,9 +582,9 @@ igmp_stop_timer(struct igmp_group *group)
|
||||
void
|
||||
igmp_delaying_member( struct igmp_group *group, u8_t maxresp)
|
||||
{
|
||||
if ((group->group_state == IDLE_MEMBER) || ((group->group_state == DELAYING_MEMBER) && (maxresp > group->timer))) {
|
||||
if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && (maxresp > group->timer))) {
|
||||
igmp_start_timer(group, (maxresp)/2);
|
||||
group->group_state = DELAYING_MEMBER;
|
||||
group->group_state = IGMP_GROUP_DELAYING_MEMBER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/raw.h"
|
||||
#include "lwip/tcp.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/api_msg.h"
|
||||
#include "lwip/tcpip.h"
|
||||
|
@ -36,9 +36,9 @@
|
||||
#define __LWIP_IGMP_H__
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/inet.h"
|
||||
|
||||
/* IGMP support available? */
|
||||
#if defined(LWIP_IGMP) && (LWIP_IGMP > 0)
|
||||
#if LWIP_IGMP /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -70,17 +70,17 @@ extern "C" {
|
||||
#define IGMP_ADD_MAC_FILTER 1
|
||||
|
||||
/* Group membership states */
|
||||
#define NON_MEMBER 0
|
||||
#define DELAYING_MEMBER 1
|
||||
#define IDLE_MEMBER 2
|
||||
#define IGMP_GROUP_NON_MEMBER 0
|
||||
#define IGMP_GROUP_DELAYING_MEMBER 1
|
||||
#define IGMP_GROUP_IDLE_MEMBER 2
|
||||
|
||||
/*
|
||||
* IGMP packet format.
|
||||
*/
|
||||
struct igmp_msg {
|
||||
u8_t igmp_msgtype;
|
||||
u8_t igmp_maxresp;
|
||||
u16_t igmp_checksum;
|
||||
u8_t igmp_msgtype;
|
||||
u8_t igmp_maxresp;
|
||||
u16_t igmp_checksum;
|
||||
struct ip_addr igmp_group_address;
|
||||
};
|
||||
|
||||
@ -98,11 +98,12 @@ struct igmp_msg {
|
||||
|
||||
struct igmp_group {
|
||||
struct igmp_group *next;
|
||||
struct netif *interface;
|
||||
struct ip_addr group_address;
|
||||
u8_t last_reporter_flag; /* signifies we were the last person to report */
|
||||
u8_t group_state;
|
||||
u16_t timer;
|
||||
struct netif *interface;
|
||||
struct ip_addr group_address;
|
||||
u8_t last_reporter_flag; /* signifies we were the last person to report */
|
||||
u8_t group_state;
|
||||
u16_t timer;
|
||||
u8_t use; /* counter of simultaneous uses */
|
||||
};
|
||||
|
||||
|
||||
@ -115,6 +116,8 @@ 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);
|
||||
|
||||
err_t igmp_joingroup( struct ip_addr *ifaddr, struct ip_addr *groupaddr);
|
||||
@ -125,7 +128,7 @@ void igmp_tmr(void);
|
||||
|
||||
void igmp_timeout( struct igmp_group *group);
|
||||
|
||||
void igmp_start_timer( struct igmp_group *group,u8_t max_time);
|
||||
void igmp_start_timer( struct igmp_group *group, u8_t max_time);
|
||||
|
||||
void igmp_stop_timer( struct igmp_group *group);
|
||||
|
||||
|
@ -53,6 +53,10 @@ LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg),
|
||||
LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE")
|
||||
#endif /* ARP_QUEUEING */
|
||||
|
||||
#if LWIP_IGMP
|
||||
LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP")
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
#if NO_SYS==0
|
||||
LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT")
|
||||
#endif /* NO_SYS==0 */
|
||||
|
@ -221,6 +221,16 @@
|
||||
#define MEMP_NUM_ARP_QUEUE 30
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces
|
||||
* can be members et the same time (one per netif - allsystems group -, plus one
|
||||
* per netif membership).
|
||||
* (requires the LWIP_IGMP option)
|
||||
*/
|
||||
#ifndef MEMP_NUM_IGMP_GROUP
|
||||
#define MEMP_NUM_IGMP_GROUP 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts.
|
||||
* (requires NO_SYS==0)
|
||||
|
Loading…
Reference in New Issue
Block a user