summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_igmp.h7
-rw-r--r--pimd/pim_igmpv3.c111
-rw-r--r--pimd/pim_zebra.c2
3 files changed, 59 insertions, 61 deletions
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index 460c9d9a0..dfe986e8f 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -191,6 +191,10 @@ struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr);
+struct igmp_source *igmp_get_source_by_addr(struct igmp_group *group,
+ struct in_addr src_addr,
+ bool *created);
+
void igmp_group_delete_empty_include(struct igmp_group *group);
void igmp_startup_mode_on(struct igmp_sock *igmp);
@@ -198,9 +202,6 @@ void igmp_startup_mode_on(struct igmp_sock *igmp);
void igmp_group_timer_on(struct igmp_group *group, long interval_msec,
const char *ifname);
-struct igmp_source *source_new(struct igmp_group *group,
- struct in_addr src_addr);
-
void igmp_send_query(int igmp_version, struct igmp_group *group, int fd,
const char *ifname, char *query_buf, int query_buf_size,
int num_sources, struct in_addr dst_addr,
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index 1f4d904f7..13db11fa8 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -441,11 +441,18 @@ struct igmp_source *igmp_find_source_by_addr(struct igmp_group *group,
return 0;
}
-struct igmp_source *source_new(struct igmp_group *group,
- struct in_addr src_addr)
+struct igmp_source *igmp_get_source_by_addr(struct igmp_group *group,
+ struct in_addr src_addr, bool *new)
{
struct igmp_source *src;
+ if (new)
+ *new = false;
+
+ src = igmp_find_source_by_addr(group, src_addr);
+ if (src)
+ return src;
+
if (PIM_DEBUG_IGMP_TRACE) {
char group_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN];
@@ -472,23 +479,6 @@ struct igmp_source *source_new(struct igmp_group *group,
/* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */
igmp_anysource_forward_stop(group);
-
- return src;
-}
-
-static struct igmp_source *add_source_by_addr(struct igmp_sock *igmp,
- struct igmp_group *group,
- struct in_addr src_addr)
-{
- struct igmp_source *src;
-
- src = igmp_find_source_by_addr(group, src_addr);
- if (src) {
- return src;
- }
-
- src = source_new(group, src_addr);
-
return src;
}
@@ -540,10 +530,9 @@ static void allow(struct igmp_sock *igmp, struct in_addr from,
src_addr = sources + i;
- source = add_source_by_addr(igmp, group, *src_addr);
- if (!source) {
+ source = igmp_get_source_by_addr(group, *src_addr, NULL);
+ if (!source)
continue;
- }
/*
RFC 3376: 6.4.1. Reception of Current-State Records
@@ -585,18 +574,21 @@ static void isex_excl(struct igmp_group *group, int num_sources,
/* scan received sources (A) */
for (i = 0; i < num_sources; ++i) {
struct in_addr *src_addr;
+ bool new;
src_addr = sources + i;
/* E.2: lookup reported source from (A) in (X,Y) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
+ source = igmp_get_source_by_addr(group, *src_addr, &new);
+ if (!source)
+ continue;
+
+ if (!new) {
/* E.3: if found, clear deletion flag: (X*A) or (Y*A) */
IGMP_SOURCE_DONT_DELETE(source->source_flags);
} else {
/* E.4: if not found, create source with timer=GMI:
* (A-X-Y) */
- source = source_new(group, *src_addr);
assert(!source->t_source_timer); /* timer == 0 */
igmp_source_reset_gmi(group, source);
assert(source->t_source_timer); /* (A-X-Y) timer > 0 */
@@ -637,18 +629,21 @@ static void isex_incl(struct igmp_group *group, int num_sources,
for (i = 0; i < num_sources; ++i) {
struct igmp_source *source;
struct in_addr *src_addr;
+ bool new;
src_addr = sources + i;
/* I.2: lookup reported source (B) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
+ source = igmp_get_source_by_addr(group, *src_addr, &new);
+ if (!source)
+ continue;
+
+ if (!new) {
/* I.3: if found, clear deletion flag (A*B) */
IGMP_SOURCE_DONT_DELETE(source->source_flags);
} else {
/* I.4: if not found, create source with timer=0 (B-A)
*/
- source = source_new(group, *src_addr);
assert(!source->t_source_timer); /* (B-A) timer=0 */
}
@@ -714,18 +709,19 @@ static void toin_incl(struct igmp_group *group, int num_sources,
for (i = 0; i < num_sources; ++i) {
struct igmp_source *source;
struct in_addr *src_addr;
+ bool new;
src_addr = sources + i;
/* Lookup reported source (B) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
+ source = igmp_get_source_by_addr(group, *src_addr, &new);
+ if (!source)
+ continue;
+
+ if (!new) {
/* If found, clear SEND flag (A*B) */
IGMP_SOURCE_DONT_SEND(source->source_flags);
--num_sources_tosend;
- } else {
- /* If not found, create new source */
- source = source_new(group, *src_addr);
}
/* (B)=GMI */
@@ -751,21 +747,20 @@ static void toin_excl(struct igmp_group *group, int num_sources,
for (i = 0; i < num_sources; ++i) {
struct igmp_source *source;
struct in_addr *src_addr;
+ bool new;
src_addr = sources + i;
/* Lookup reported source (A) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
- if (source->t_source_timer) {
- /* If found and timer running, clear SEND flag
- * (X*A) */
- IGMP_SOURCE_DONT_SEND(source->source_flags);
- --num_sources_tosend;
- }
- } else {
- /* If not found, create new source */
- source = source_new(group, *src_addr);
+ source = igmp_get_source_by_addr(group, *src_addr, &new);
+ if (!source)
+ continue;
+
+ if (source->t_source_timer) {
+ /* If found and timer running, clear SEND flag
+ * (X*A) */
+ IGMP_SOURCE_DONT_SEND(source->source_flags);
+ --num_sources_tosend;
}
/* (A)=GMI */
@@ -835,22 +830,18 @@ static void toex_incl(struct igmp_group *group, int num_sources,
for (i = 0; i < num_sources; ++i) {
struct igmp_source *source;
struct in_addr *src_addr;
+ bool new;
src_addr = sources + i;
/* Lookup reported source (B) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
+ source = igmp_get_source_by_addr(group, *src_addr, &new);
+ if (!new) {
/* If found, clear deletion flag: (A*B) */
IGMP_SOURCE_DONT_DELETE(source->source_flags);
/* and set SEND flag (A*B) */
IGMP_SOURCE_DO_SEND(source->source_flags);
++num_sources_tosend;
- } else {
- /* If source not found, create source with timer=0:
- * (B-A)=0 */
- source = source_new(group, *src_addr);
- assert(!source->t_source_timer); /* (B-A) timer=0 */
}
} /* Scan received sources (B) */
@@ -895,12 +886,16 @@ static void toex_excl(struct igmp_group *group, int num_sources,
for (i = 0; i < num_sources; ++i) {
struct igmp_source *source;
struct in_addr *src_addr;
+ bool new;
src_addr = sources + i;
/* lookup reported source (A) in known sources (X,Y) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (source) {
+ source = igmp_get_source_by_addr(group, *src_addr, &new);
+ if (!source)
+ continue;
+
+ if (!new) {
/* if found, clear off DELETE flag from reported source
* (A) */
IGMP_SOURCE_DONT_DELETE(source->source_flags);
@@ -908,7 +903,6 @@ static void toex_excl(struct igmp_group *group, int num_sources,
/* if not found, create source with Group Timer:
* (A-X-Y)=Group Timer */
long group_timer_msec;
- source = source_new(group, *src_addr);
assert(!source->t_source_timer); /* timer == 0 */
group_timer_msec = igmp_group_timer_remain_msec(group);
@@ -1404,16 +1398,19 @@ static void block_excl(struct igmp_group *group, int num_sources,
for (i = 0; i < num_sources; ++i) {
struct igmp_source *source;
struct in_addr *src_addr;
+ bool new;
src_addr = sources + i;
/* lookup reported source (A) in known sources (X,Y) */
- source = igmp_find_source_by_addr(group, *src_addr);
- if (!source) {
+ source = igmp_get_source_by_addr(group, *src_addr, &new);
+ if (!source)
+ continue;
+
+ if (new) {
/* 3: if not found, create source with Group Timer:
* (A-X-Y)=Group Timer */
long group_timer_msec;
- source = source_new(group, *src_addr);
assert(!source->t_source_timer); /* timer == 0 */
group_timer_msec = igmp_group_timer_remain_msec(group);
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 521e4ebc1..aa041df85 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -474,7 +474,7 @@ void igmp_anysource_forward_start(struct pim_instance *pim,
assert(group->group_filtermode_isexcl);
assert(listcount(group->group_source_list) < 1);
- source = source_new(group, src_addr);
+ source = igmp_get_source_by_addr(group, src_addr, NULL);
if (!source) {
zlog_warn("%s: Failure to create * source", __func__);
return;