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.c38
1 files changed, 29 insertions, 9 deletions
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index afa2db5f15..bc67a1dd1d 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -499,6 +499,35 @@ static void allow(struct igmp_sock *igmp, struct in_addr from,
struct igmp_group *group;
int i;
+ if (num_sources == 0) {
+ /*
+ RFC 3376: 3.1. Socket-State
+ If the requested filter mode is INCLUDE *and* the requested
+ source list is empty, then the entry corresponding to the
+ requested interface and multicast address is deleted if
+ present. If no such entry is present, the request is ignored.
+ So, deleting the group present.
+ */
+ group = find_group_by_addr(igmp, group_addr);
+ if (!group) {
+ return;
+ }
+ if (group->group_filtermode_isexcl) {
+ if (listcount(group->group_source_list) == 1) {
+ struct in_addr star = {.s_addr = INADDR_ANY};
+
+ source = igmp_find_source_by_addr(group, star);
+ if (source)
+ igmp_source_reset_gmi(igmp, group,
+ source);
+ }
+ } else {
+ igmp_group_delete(group);
+ }
+
+ return;
+ }
+
/* non-existant group is created as INCLUDE {empty} */
group = igmp_add_group_by_addr(igmp, group_addr);
if (!group) {
@@ -529,15 +558,6 @@ static void allow(struct igmp_sock *igmp, struct in_addr from,
igmp_source_reset_gmi(igmp, group, source);
} /* scan received sources */
-
- if ((num_sources == 0) && (group->group_filtermode_isexcl)
- && (listcount(group->group_source_list) == 1)) {
- struct in_addr star = {.s_addr = INADDR_ANY};
-
- source = igmp_find_source_by_addr(group, star);
- if (source)
- igmp_source_reset_gmi(igmp, group, source);
- }
}
void igmpv3_report_isin(struct igmp_sock *igmp, struct in_addr from,