diff options
Diffstat (limited to 'pimd/pim_igmpv3.c')
| -rw-r--r-- | pimd/pim_igmpv3.c | 33 |
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 */ |
