summaryrefslogtreecommitdiff
path: root/pimd/pim_igmpv3.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_igmpv3.c')
-rw-r--r--pimd/pim_igmpv3.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 7348d8130f..2de2b32688 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -423,6 +423,7 @@ struct gm_source *igmp_find_source_by_addr(struct gm_group *group,
struct gm_source *igmp_get_source_by_addr(struct gm_group *group,
struct in_addr src_addr, bool *new)
{
+ const struct pim_interface *pim_interface = group->interface->info;
struct gm_source *src;
if (new)
@@ -432,6 +433,14 @@ struct gm_source *igmp_get_source_by_addr(struct gm_group *group,
if (src)
return src;
+ if (listcount(group->group_source_list) >= pim_interface->gm_source_limit) {
+ if (PIM_DEBUG_GM_TRACE)
+ zlog_debug("interface %s has reached source limit (%u), refusing to add source %pI4 (group %pI4)",
+ group->interface->name, pim_interface->gm_source_limit,
+ &src_addr, &group->group_addr);
+ return NULL;
+ }
+
if (PIM_DEBUG_GM_TRACE) {
char group_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN];
@@ -719,9 +728,25 @@ static void toin_incl(struct gm_group *group, int num_sources,
static void toin_excl(struct gm_group *group, int num_sources,
struct in_addr *sources)
{
+ struct listnode *src_node, *src_next;
+ struct pim_interface *pim_ifp = group->interface->info;
int num_sources_tosend;
int i;
+ if (group->igmp_version == 2 && pim_ifp->gmp_immediate_leave) {
+ struct gm_source *src;
+
+ if (PIM_DEBUG_GM_TRACE)
+ zlog_debug("IGMP(v2) Immediate-leave group %pI4 on %s", &group->group_addr,
+ group->interface->name);
+
+ igmp_group_timer_on(group, 0, group->interface->name);
+
+ for (ALL_LIST_ELEMENTS(group->group_source_list, src_node, src_next, src))
+ igmp_source_delete(src);
+ return;
+ }
+
/* Set SEND flag for X (sources with timer > 0) */
num_sources_tosend = source_mark_send_flag_by_timer(group);
@@ -1487,7 +1512,9 @@ void igmp_group_timer_lower_to_lmqt(struct gm_group *group)
pim_ifp = ifp->info;
ifname = ifp->name;
- lmqi_dsec = pim_ifp->gm_specific_query_max_response_time_dsec;
+ lmqi_dsec = pim_ifp->gmp_immediate_leave
+ ? 0
+ : pim_ifp->gm_specific_query_max_response_time_dsec;
lmqc = pim_ifp->gm_last_member_query_count;
lmqt_msec = PIM_IGMP_LMQT_MSEC(
lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */
@@ -1522,7 +1549,9 @@ void igmp_source_timer_lower_to_lmqt(struct gm_source *source)
pim_ifp = ifp->info;
ifname = ifp->name;
- lmqi_dsec = pim_ifp->gm_specific_query_max_response_time_dsec;
+ lmqi_dsec = pim_ifp->gmp_immediate_leave
+ ? 0
+ : pim_ifp->gm_specific_query_max_response_time_dsec;
lmqc = pim_ifp->gm_last_member_query_count;
lmqt_msec = PIM_IGMP_LMQT_MSEC(
lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */