pimd: Stale IGMP groups left behind

When a toin IGMPv3 join is received, the code
was always auto creating the igmp group associated
with the received packet.  The RFC clearly states
though that if a INCLUDE is received for a group
with 0 sources and we have received nothing the
igmpv3 packet should be ignored.

Ticket: CM-11260
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2016-07-12 11:31:45 -04:00
parent 2560106c04
commit 5b1207f72c
3 changed files with 25 additions and 10 deletions

View file

@ -46,9 +46,6 @@
static void group_timer_off(struct igmp_group *group);
static struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr);
static int igmp_sock_open(struct in_addr ifaddr, int ifindex, uint32_t pim_options)
{
int fd;
@ -1358,8 +1355,9 @@ void igmp_group_timer_on(struct igmp_group *group,
group, interval_msec);
}
static struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr)
struct igmp_group *
find_group_by_addr (struct igmp_sock *igmp,
struct in_addr group_addr)
{
struct igmp_group *group;
struct listnode *node;

View file

@ -162,6 +162,8 @@ struct igmp_group {
int64_t last_igmp_v2_report_dsec;
};
struct igmp_group *find_group_by_addr (struct igmp_sock *igmp,
struct in_addr group_addr);
struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr);

View file

@ -834,11 +834,26 @@ void igmpv3_report_toin(struct igmp_sock *igmp, struct in_addr from,
on_trace(__PRETTY_FUNCTION__,
ifp, from, group_addr, num_sources, sources);
/* non-existant group is created as INCLUDE {empty} */
group = igmp_add_group_by_addr(igmp, group_addr);
if (!group) {
return;
}
/*
* 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.
*/
if (num_sources)
{
/* non-existant group is created as INCLUDE {empty} */
group = igmp_add_group_by_addr(igmp, group_addr);
if (!group) {
return;
}
}
else
{
group = find_group_by_addr (igmp, group_addr);
if (!group)
return;
}
if (group->group_filtermode_isexcl) {
/* EXCLUDE mode */