summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_assert.h18
-rw-r--r--pimd/pim_bfd.c1
-rw-r--r--pimd/pim_bsm.c1
-rw-r--r--pimd/pim_cmd.c390
-rw-r--r--pimd/pim_iface.c7
-rw-r--r--pimd/pim_iface.h3
-rw-r--r--pimd/pim_ifchannel.h16
-rw-r--r--pimd/pim_igmp.c105
-rw-r--r--pimd/pim_igmp.h18
-rw-r--r--pimd/pim_igmpv3.c284
-rw-r--r--pimd/pim_igmpv3.h4
-rw-r--r--pimd/pim_instance.h2
-rw-r--r--pimd/pim_mroute.h2
-rw-r--r--pimd/pim_nb_config.c101
-rw-r--r--pimd/pim_neighbor.h1
-rw-r--r--pimd/pim_oil.h3
-rw-r--r--pimd/pim_rp.c2
-rw-r--r--pimd/pim_rp.h3
-rw-r--r--pimd/pim_rpf.c1
-rw-r--r--pimd/pim_rpf.h3
-rw-r--r--pimd/pim_upstream.h2
-rw-r--r--pimd/pim_zebra.c98
-rw-r--r--pimd/pim_zlookup.c1
-rw-r--r--pimd/pimd.h1
24 files changed, 483 insertions, 584 deletions
diff --git a/pimd/pim_assert.h b/pimd/pim_assert.h
index 63fda3fe3..c07cbeb01 100644
--- a/pimd/pim_assert.h
+++ b/pimd/pim_assert.h
@@ -24,8 +24,22 @@
#include "if.h"
-#include "pim_neighbor.h"
-#include "pim_ifchannel.h"
+struct pim_ifchannel;
+struct pim_neighbor;
+
+enum pim_ifassert_state {
+ PIM_IFASSERT_NOINFO,
+ PIM_IFASSERT_I_AM_WINNER,
+ PIM_IFASSERT_I_AM_LOSER
+};
+
+struct pim_assert_metric {
+ uint32_t rpt_bit_flag;
+ uint32_t metric_preference;
+ uint32_t route_metric;
+ struct in_addr ip_address; /* neighbor router that sourced the Assert
+ message */
+};
/*
RFC 4601: 4.11. Timer Values
diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c
index dfe2d5f2f..c7fcbba71 100644
--- a/pimd/pim_bfd.c
+++ b/pimd/pim_bfd.c
@@ -28,6 +28,7 @@
#include "zclient.h"
#include "pim_instance.h"
+#include "pim_neighbor.h"
#include "pim_cmd.h"
#include "pim_vty.h"
#include "pim_iface.h"
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c
index f2845ee6e..a3a3426f3 100644
--- a/pimd/pim_bsm.c
+++ b/pimd/pim_bsm.c
@@ -28,6 +28,7 @@
#include "pimd.h"
#include "pim_iface.h"
#include "pim_instance.h"
+#include "pim_neighbor.h"
#include "pim_rpf.h"
#include "pim_hello.h"
#include "pim_pim.h"
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 1238e03a5..14aa71052 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -3430,112 +3430,87 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
pim->igmp_watermark_limit ? "Set" : "Not Set",
pim->igmp_watermark_limit);
vty_out(vty,
- "Interface Address Group Mode Timer Srcs V Uptime \n");
+ "Interface Group Mode Timer Srcs V Uptime \n");
}
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *grpnode;
+ struct igmp_group *grp;
if (!pim_ifp)
continue;
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
- igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
- sizeof(ifaddr_str));
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
- grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- char hhmmss[10];
- char uptime[10];
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode,
+ grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ char hhmmss[10];
+ char uptime[10];
- pim_inet4_dump("<group?>", grp->group_addr,
- group_str, sizeof(group_str));
- pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
- grp->t_group_timer);
- pim_time_uptime(uptime, sizeof(uptime),
- now - grp->group_creation);
+ pim_inet4_dump("<group?>", grp->group_addr, group_str,
+ sizeof(group_str));
+ pim_time_timer_to_hhmmss(hhmmss, sizeof(hhmmss),
+ grp->t_group_timer);
+ pim_time_uptime(uptime, sizeof(uptime),
+ now - grp->group_creation);
- if (uj) {
- json_object_object_get_ex(
- json, ifp->name, &json_iface);
-
- if (!json_iface) {
- json_iface =
- json_object_new_object();
- json_object_pim_ifp_add(
- json_iface, ifp);
- json_object_object_add(
- json, ifp->name,
- json_iface);
- json_groups =
- json_object_new_array();
- json_object_object_add(
- json_iface,
- "groups",
- json_groups);
- }
+ if (uj) {
+ json_object_object_get_ex(json, ifp->name,
+ &json_iface);
- json_group = json_object_new_object();
- json_object_string_add(json_group,
- "source",
- ifaddr_str);
- json_object_string_add(json_group,
- "group",
- group_str);
-
- if (grp->igmp_version == 3)
- json_object_string_add(
- json_group, "mode",
- grp->group_filtermode_isexcl
+ if (!json_iface) {
+ json_iface = json_object_new_object();
+ json_object_pim_ifp_add(json_iface,
+ ifp);
+ json_object_object_add(json, ifp->name,
+ json_iface);
+ json_groups = json_object_new_array();
+ json_object_object_add(json_iface,
+ "groups",
+ json_groups);
+ }
+
+ json_group = json_object_new_object();
+ json_object_string_add(json_group, "group",
+ group_str);
+
+ if (grp->igmp_version == 3)
+ json_object_string_add(
+ json_group, "mode",
+ grp->group_filtermode_isexcl
? "EXCLUDE"
: "INCLUDE");
- json_object_string_add(json_group,
- "timer", hhmmss);
- json_object_int_add(
- json_group, "sourcesCount",
- grp->group_source_list
- ? listcount(
- grp->group_source_list)
- : 0);
- json_object_int_add(
- json_group, "version",
- grp->igmp_version);
- json_object_string_add(
- json_group, "uptime", uptime);
- json_object_array_add(json_groups,
- json_group);
- } else {
- vty_out(vty,
- "%-16s %-15s %-15s %4s %8s %4d %d %8s\n",
- ifp->name, ifaddr_str,
- group_str,
- grp->igmp_version == 3
+ json_object_string_add(json_group, "timer",
+ hhmmss);
+ json_object_int_add(
+ json_group, "sourcesCount",
+ grp->group_source_list ? listcount(
+ grp->group_source_list)
+ : 0);
+ json_object_int_add(json_group, "version",
+ grp->igmp_version);
+ json_object_string_add(json_group, "uptime",
+ uptime);
+ json_object_array_add(json_groups, json_group);
+ } else {
+ vty_out(vty, "%-16s %-15s %4s %8s %4d %d %8s\n",
+ ifp->name, group_str,
+ grp->igmp_version == 3
? (grp->group_filtermode_isexcl
- ? "EXCL"
- : "INCL")
+ ? "EXCL"
+ : "INCL")
: "----",
- hhmmss,
- grp->group_source_list
- ? listcount(
- grp->group_source_list)
- : 0,
- grp->igmp_version, uptime);
- }
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ hhmmss,
+ grp->group_source_list ? listcount(
+ grp->group_source_list)
+ : 0,
+ grp->igmp_version, uptime);
+ }
+ } /* scan igmp groups */
+ } /* scan interfaces */
if (uj) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
@@ -3550,63 +3525,49 @@ static void igmp_show_group_retransmission(struct pim_instance *pim,
struct interface *ifp;
vty_out(vty,
- "Interface Address Group RetTimer Counter RetSrcs\n");
+ "Interface Group RetTimer Counter RetSrcs\n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *grpnode;
+ struct igmp_group *grp;
if (!pim_ifp)
continue;
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
- igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
- sizeof(ifaddr_str));
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
- grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- char grp_retr_mmss[10];
- struct listnode *src_node;
- struct igmp_source *src;
- int grp_retr_sources = 0;
-
- pim_inet4_dump("<group?>", grp->group_addr,
- group_str, sizeof(group_str));
- pim_time_timer_to_mmss(
- grp_retr_mmss, sizeof(grp_retr_mmss),
- grp->t_group_query_retransmit_timer);
-
-
- /* count group sources with retransmission state
- */
- for (ALL_LIST_ELEMENTS_RO(
- grp->group_source_list, src_node,
- src)) {
- if (src->source_query_retransmit_count
- > 0) {
- ++grp_retr_sources;
- }
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode,
+ grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ char grp_retr_mmss[10];
+ struct listnode *src_node;
+ struct igmp_source *src;
+ int grp_retr_sources = 0;
+
+ pim_inet4_dump("<group?>", grp->group_addr, group_str,
+ sizeof(group_str));
+ pim_time_timer_to_mmss(
+ grp_retr_mmss, sizeof(grp_retr_mmss),
+ grp->t_group_query_retransmit_timer);
+
+
+ /* count group sources with retransmission state
+ */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ src_node, src)) {
+ if (src->source_query_retransmit_count > 0) {
+ ++grp_retr_sources;
}
+ }
- vty_out(vty, "%-16s %-15s %-15s %-8s %7d %7d\n",
- ifp->name, ifaddr_str, group_str,
- grp_retr_mmss,
- grp->group_specific_query_retransmit_count,
- grp_retr_sources);
+ vty_out(vty, "%-16s %-15s %-8s %7d %7d\n", ifp->name,
+ group_str, grp_retr_mmss,
+ grp->group_specific_query_retransmit_count,
+ grp_retr_sources);
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ } /* scan igmp groups */
+ } /* scan interfaces */
}
static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
@@ -3617,71 +3578,54 @@ static void igmp_show_sources(struct pim_instance *pim, struct vty *vty)
now = pim_time_monotonic_sec();
vty_out(vty,
- "Interface Address Group Source Timer Fwd Uptime \n");
+ "Interface Group Source Timer Fwd Uptime \n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *grpnode;
+ struct igmp_group *grp;
if (!pim_ifp)
continue;
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
- igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode,
+ grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ struct listnode *srcnode;
+ struct igmp_source *src;
+
+ pim_inet4_dump("<group?>", grp->group_addr, group_str,
+ sizeof(group_str));
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
- sizeof(ifaddr_str));
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ srcnode, src)) {
+ char source_str[INET_ADDRSTRLEN];
+ char mmss[10];
+ char uptime[10];
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
- grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- struct listnode *srcnode;
- struct igmp_source *src;
+ pim_inet4_dump("<source?>", src->source_addr,
+ source_str, sizeof(source_str));
- pim_inet4_dump("<group?>", grp->group_addr,
- group_str, sizeof(group_str));
+ pim_time_timer_to_mmss(mmss, sizeof(mmss),
+ src->t_source_timer);
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(
- grp->group_source_list, srcnode,
- src)) {
- char source_str[INET_ADDRSTRLEN];
- char mmss[10];
- char uptime[10];
-
- pim_inet4_dump(
- "<source?>", src->source_addr,
- source_str, sizeof(source_str));
-
- pim_time_timer_to_mmss(
- mmss, sizeof(mmss),
- src->t_source_timer);
-
- pim_time_uptime(
- uptime, sizeof(uptime),
+ pim_time_uptime(uptime, sizeof(uptime),
now - src->source_creation);
- vty_out(vty,
- "%-16s %-15s %-15s %-15s %5s %3s %8s\n",
- ifp->name, ifaddr_str,
- group_str, source_str, mmss,
- IGMP_SOURCE_TEST_FORWARDING(
- src->source_flags)
+ vty_out(vty, "%-16s %-15s %-15s %5s %3s %8s\n",
+ ifp->name, group_str, source_str, mmss,
+ IGMP_SOURCE_TEST_FORWARDING(
+ src->source_flags)
? "Y"
: "N",
- uptime);
+ uptime);
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ } /* scan group sources */
+ } /* scan igmp groups */
+ } /* scan interfaces */
}
static void igmp_show_source_retransmission(struct pim_instance *pim,
@@ -3690,57 +3634,42 @@ static void igmp_show_source_retransmission(struct pim_instance *pim,
struct interface *ifp;
vty_out(vty,
- "Interface Address Group Source Counter\n");
+ "Interface Group Source Counter\n");
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *grpnode;
+ struct igmp_group *grp;
if (!pim_ifp)
continue;
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
- igmp)) {
- char ifaddr_str[INET_ADDRSTRLEN];
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- pim_inet4_dump("<ifaddr?>", igmp->ifaddr, ifaddr_str,
- sizeof(ifaddr_str));
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode,
+ grp)) {
+ char group_str[INET_ADDRSTRLEN];
+ struct listnode *srcnode;
+ struct igmp_source *src;
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
- grpnode, grp)) {
- char group_str[INET_ADDRSTRLEN];
- struct listnode *srcnode;
- struct igmp_source *src;
+ pim_inet4_dump("<group?>", grp->group_addr, group_str,
+ sizeof(group_str));
- pim_inet4_dump("<group?>", grp->group_addr,
- group_str, sizeof(group_str));
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ srcnode, src)) {
+ char source_str[INET_ADDRSTRLEN];
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(
- grp->group_source_list, srcnode,
- src)) {
- char source_str[INET_ADDRSTRLEN];
+ pim_inet4_dump("<source?>", src->source_addr,
+ source_str, sizeof(source_str));
- pim_inet4_dump(
- "<source?>", src->source_addr,
- source_str, sizeof(source_str));
+ vty_out(vty, "%-16s %-15s %-15s %7d\n",
+ ifp->name, group_str, source_str,
+ src->source_query_retransmit_count);
- vty_out(vty,
- "%-16s %-15s %-15s %-15s %7d\n",
- ifp->name, ifaddr_str,
- group_str, source_str,
- src->source_query_retransmit_count);
-
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+ } /* scan group sources */
+ } /* scan igmp groups */
+ } /* scan interfaces */
}
static void pim_show_bsr(struct pim_instance *pim,
@@ -3993,8 +3922,7 @@ static void clear_mroute(struct pim_instance *pim)
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct igmp_group *grp;
struct pim_ifchannel *ch;
if (!pim_ifp)
@@ -4008,20 +3936,12 @@ static void clear_mroute(struct pim_instance *pim)
}
/* clean up all igmp groups */
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
- igmp)) {
-
- struct igmp_group *grp;
- if (igmp->igmp_group_list) {
- while (igmp->igmp_group_list->count) {
- grp = listnode_head(
- igmp->igmp_group_list);
- igmp_group_delete(grp);
- }
+ if (pim_ifp->igmp_group_list) {
+ while (pim_ifp->igmp_group_list->count) {
+ grp = listnode_head(pim_ifp->igmp_group_list);
+ igmp_group_delete(grp);
}
-
}
}
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 0b28a3e84..eb19cf4dd 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -156,14 +156,12 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,
PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
pim_ifp->igmp_join_list = NULL;
- pim_ifp->igmp_socket_list = NULL;
pim_ifp->pim_neighbor_list = NULL;
pim_ifp->upstream_switch_list = NULL;
pim_ifp->pim_generation_id = 0;
/* list of struct igmp_sock */
- pim_ifp->igmp_socket_list = list_new();
- pim_ifp->igmp_socket_list->del = (void (*)(void *))igmp_sock_free;
+ pim_igmp_if_init(pim_ifp, ifp);
/* list of struct pim_neighbor */
pim_ifp->pim_neighbor_list = list_new();
@@ -214,7 +212,8 @@ void pim_if_delete(struct interface *ifp)
pim_if_del_vif(ifp);
pim_ifp->pim->mcast_if_count--;
- list_delete(&pim_ifp->igmp_socket_list);
+ pim_igmp_if_fini(pim_ifp);
+
list_delete(&pim_ifp->pim_neighbor_list);
list_delete(&pim_ifp->upstream_switch_list);
list_delete(&pim_ifp->sec_addr_list);
diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h
index 92784103f..55c278d6e 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -30,6 +30,7 @@
#include "pim_igmp.h"
#include "pim_upstream.h"
+#include "pim_instance.h"
#include "bfd.h"
#define PIM_IF_MASK_PIM (1 << 0)
@@ -102,6 +103,8 @@ struct pim_interface {
int igmp_last_member_query_count; /* IGMP last member query count */
struct list *igmp_socket_list; /* list of struct igmp_sock */
struct list *igmp_join_list; /* list of struct igmp_join */
+ struct list *igmp_group_list; /* list of struct igmp_group */
+ struct hash *igmp_group_hash;
int pim_sock_fd; /* PIM socket file descriptor */
struct thread *t_pim_sock_read; /* thread for reading PIM socket */
diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h
index 7ec8191e5..52f02a660 100644
--- a/pimd/pim_ifchannel.h
+++ b/pimd/pim_ifchannel.h
@@ -25,6 +25,8 @@
#include "if.h"
#include "prefix.h"
+#include "pim_assert.h"
+
struct pim_ifchannel;
#include "pim_upstream.h"
@@ -39,20 +41,6 @@ enum pim_ifjoin_state {
PIM_IFJOIN_PRUNE_PENDING_TMP,
};
-enum pim_ifassert_state {
- PIM_IFASSERT_NOINFO,
- PIM_IFASSERT_I_AM_WINNER,
- PIM_IFASSERT_I_AM_LOSER
-};
-
-struct pim_assert_metric {
- uint32_t rpt_bit_flag;
- uint32_t metric_preference;
- uint32_t route_metric;
- struct in_addr ip_address; /* neighbor router that sourced the Assert
- message */
-};
-
/*
Flag to detect change in CouldAssert(S,G,I)
*/
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 71b2d9187..50de7124d 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -810,13 +810,8 @@ static void igmp_group_free(struct igmp_group *group)
XFREE(MTYPE_PIM_IGMP_GROUP, group);
}
-static void igmp_group_count_incr(struct igmp_sock *igmp)
+static void igmp_group_count_incr(struct pim_interface *pim_ifp)
{
- struct pim_interface *pim_ifp = igmp->interface->info;
-
- if (!pim_ifp)
- return;
-
++pim_ifp->pim->igmp_group_count;
if (pim_ifp->pim->igmp_group_count
== pim_ifp->pim->igmp_watermark_limit) {
@@ -827,13 +822,8 @@ static void igmp_group_count_incr(struct igmp_sock *igmp)
}
}
-static void igmp_group_count_decr(struct igmp_sock *igmp)
+static void igmp_group_count_decr(struct pim_interface *pim_ifp)
{
- struct pim_interface *pim_ifp = igmp->interface->info;
-
- if (!pim_ifp)
- return;
-
if (pim_ifp->pim->igmp_group_count == 0) {
zlog_warn("Cannot decrement igmp group count below 0(vrf: %s)",
VRF_LOGNAME(pim_ifp->pim->vrf));
@@ -848,14 +838,14 @@ void igmp_group_delete(struct igmp_group *group)
struct listnode *src_node;
struct listnode *src_nextnode;
struct igmp_source *src;
+ struct pim_interface *pim_ifp = group->interface->info;
if (PIM_DEBUG_IGMP_TRACE) {
char group_str[INET_ADDRSTRLEN];
pim_inet4_dump("<group?>", group->group_addr, group_str,
sizeof(group_str));
- zlog_debug("Deleting IGMP group %s from socket %d interface %s",
- group_str, group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name);
+ zlog_debug("Deleting IGMP group %s from interface %s",
+ group_str, group->interface->name);
}
for (ALL_LIST_ELEMENTS(group->group_source_list, src_node, src_nextnode,
@@ -866,9 +856,9 @@ void igmp_group_delete(struct igmp_group *group)
THREAD_OFF(group->t_group_query_retransmit_timer);
group_timer_off(group);
- igmp_group_count_decr(group->group_igmp_sock);
- listnode_delete(group->group_igmp_sock->igmp_group_list, group);
- hash_release(group->group_igmp_sock->igmp_group_hash, group);
+ igmp_group_count_decr(pim_ifp);
+ listnode_delete(pim_ifp->igmp_group_list, group);
+ hash_release(pim_ifp->igmp_group_hash, group);
igmp_group_free(group);
}
@@ -886,11 +876,6 @@ void igmp_sock_free(struct igmp_sock *igmp)
assert(!igmp->t_igmp_read);
assert(!igmp->t_igmp_query_timer);
assert(!igmp->t_other_querier_timer);
- assert(igmp->igmp_group_list);
- assert(!listcount(igmp->igmp_group_list));
-
- list_delete(&igmp->igmp_group_list);
- hash_free(igmp->igmp_group_hash);
XFREE(MTYPE_PIM_IGMP_SOCKET, igmp);
}
@@ -898,14 +883,6 @@ void igmp_sock_free(struct igmp_sock *igmp)
void igmp_sock_delete(struct igmp_sock *igmp)
{
struct pim_interface *pim_ifp;
- struct listnode *grp_node;
- struct listnode *grp_nextnode;
- struct igmp_group *grp;
-
- for (ALL_LIST_ELEMENTS(igmp->igmp_group_list, grp_node, grp_nextnode,
- grp)) {
- igmp_group_delete(grp);
- }
sock_close(igmp);
@@ -914,6 +891,9 @@ void igmp_sock_delete(struct igmp_sock *igmp)
listnode_delete(pim_ifp->igmp_socket_list, igmp);
igmp_sock_free(igmp);
+
+ if (!listcount(pim_ifp->igmp_socket_list))
+ pim_igmp_if_reset(pim_ifp);
}
void igmp_sock_delete_all(struct interface *ifp)
@@ -948,12 +928,50 @@ static bool igmp_group_hash_equal(const void *arg1, const void *arg2)
return false;
}
+void pim_igmp_if_init(struct pim_interface *pim_ifp, struct interface *ifp)
+{
+ char hash_name[64];
+
+ pim_ifp->igmp_socket_list = list_new();
+ pim_ifp->igmp_socket_list->del = (void (*)(void *))igmp_sock_free;
+
+ pim_ifp->igmp_group_list = list_new();
+ pim_ifp->igmp_group_list->del = (void (*)(void *))igmp_group_free;
+
+ snprintf(hash_name, sizeof(hash_name), "IGMP %s hash", ifp->name);
+ pim_ifp->igmp_group_hash = hash_create(
+ igmp_group_hash_key, igmp_group_hash_equal, hash_name);
+}
+
+void pim_igmp_if_reset(struct pim_interface *pim_ifp)
+{
+ struct listnode *grp_node, *grp_nextnode;
+ struct igmp_group *grp;
+
+ for (ALL_LIST_ELEMENTS(pim_ifp->igmp_group_list, grp_node, grp_nextnode,
+ grp)) {
+ igmp_group_delete(grp);
+ }
+}
+
+void pim_igmp_if_fini(struct pim_interface *pim_ifp)
+{
+ pim_igmp_if_reset(pim_ifp);
+
+ assert(pim_ifp->igmp_group_list);
+ assert(!listcount(pim_ifp->igmp_group_list));
+
+ list_delete(&pim_ifp->igmp_group_list);
+ hash_free(pim_ifp->igmp_group_hash);
+
+ list_delete(&pim_ifp->igmp_socket_list);
+}
+
static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
struct interface *ifp, int mtrace_only)
{
struct pim_interface *pim_ifp;
struct igmp_sock *igmp;
- char hash_name[64];
pim_ifp = ifp->info;
@@ -965,13 +983,6 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
- igmp->igmp_group_list = list_new();
- igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free;
-
- snprintf(hash_name, sizeof(hash_name), "IGMP %s hash", ifp->name);
- igmp->igmp_group_hash = hash_create(igmp_group_hash_key,
- igmp_group_hash_equal, hash_name);
-
igmp->fd = fd;
igmp->interface = ifp;
igmp->ifaddr = ifaddr;
@@ -1114,7 +1125,7 @@ static int igmp_group_timer(struct thread *t)
pim_inet4_dump("<group?>", group->group_addr, group_str,
sizeof(group_str));
zlog_debug("%s: Timer for group %s on interface %s", __func__,
- group_str, group->group_igmp_sock->interface->name);
+ group_str, group->interface->name);
}
assert(group->group_filtermode_isexcl);
@@ -1151,7 +1162,7 @@ static void group_timer_off(struct igmp_group *group)
pim_inet4_dump("<group?>", group->group_addr, group_str,
sizeof(group_str));
zlog_debug("Cancelling TIMER event for group %s on %s",
- group_str, group->group_igmp_sock->interface->name);
+ group_str, group->interface->name);
}
THREAD_OFF(group->t_group_timer);
}
@@ -1188,16 +1199,18 @@ struct igmp_group *find_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr)
{
struct igmp_group lookup;
+ struct pim_interface *pim_ifp = igmp->interface->info;
lookup.group_addr.s_addr = group_addr.s_addr;
- return hash_lookup(igmp->igmp_group_hash, &lookup);
+ return hash_lookup(pim_ifp->igmp_group_hash, &lookup);
}
struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
struct in_addr group_addr)
{
struct igmp_group *group;
+ struct pim_interface *pim_ifp = igmp->interface->info;
group = find_group_by_addr(igmp, group_addr);
if (group) {
@@ -1239,7 +1252,7 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
group->t_group_query_retransmit_timer = NULL;
group->group_specific_query_retransmit_count = 0;
group->group_addr = group_addr;
- group->group_igmp_sock = igmp;
+ group->interface = igmp->interface;
group->last_igmp_v1_report_dsec = -1;
group->last_igmp_v2_report_dsec = -1;
group->group_creation = pim_time_monotonic_sec();
@@ -1248,8 +1261,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
/* initialize new group as INCLUDE {empty} */
group->group_filtermode_isexcl = 0; /* 0=INCLUDE, 1=EXCLUDE */
- listnode_add(igmp->igmp_group_list, group);
- group = hash_get(igmp->igmp_group_hash, group, hash_alloc_intern);
+ listnode_add(pim_ifp->igmp_group_list, group);
+ group = hash_get(pim_ifp->igmp_group_hash, group, hash_alloc_intern);
if (PIM_DEBUG_IGMP_TRACE) {
char group_str[INET_ADDRSTRLEN];
@@ -1260,7 +1273,7 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
group_str, igmp->fd, igmp->interface->name);
}
- igmp_group_count_incr(igmp);
+ igmp_group_count_incr(pim_ifp);
/*
RFC 3376: 6.2.2. Definition of Group Timers
diff --git a/pimd/pim_igmp.h b/pimd/pim_igmp.h
index abb8af836..dfe986e8f 100644
--- a/pimd/pim_igmp.h
+++ b/pimd/pim_igmp.h
@@ -99,12 +99,15 @@ struct igmp_sock {
bool mtrace_only;
- struct list *igmp_group_list; /* list of struct igmp_group */
- struct hash *igmp_group_hash;
-
struct igmp_stats rx_stats;
};
+struct pim_interface;
+
+void pim_igmp_if_init(struct pim_interface *pim_ifp, struct interface *ifp);
+void pim_igmp_if_reset(struct pim_interface *pim_ifp);
+void pim_igmp_if_fini(struct pim_interface *pim_ifp);
+
struct igmp_sock *pim_igmp_sock_lookup_ifaddr(struct list *igmp_sock_list,
struct in_addr ifaddr);
struct igmp_sock *igmp_sock_lookup_by_fd(struct list *igmp_sock_list, int fd);
@@ -178,7 +181,7 @@ struct igmp_group {
int group_filtermode_isexcl; /* 0=INCLUDE, 1=EXCLUDE */
struct list *group_source_list; /* list of struct igmp_source */
time_t group_creation;
- struct igmp_sock *group_igmp_sock; /* back pointer */
+ struct interface *interface;
int64_t last_igmp_v1_report_dsec;
int64_t last_igmp_v2_report_dsec;
};
@@ -188,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);
@@ -195,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 bc67a1dd1..13db11fa8 100644
--- a/pimd/pim_igmpv3.c
+++ b/pimd/pim_igmpv3.c
@@ -57,16 +57,28 @@ static void on_trace(const char *label, struct interface *ifp,
}
}
+static inline long igmp_gmi_msec(struct igmp_group *group)
+{
+ struct pim_interface *pim_ifp = group->interface->info;
+ struct igmp_sock *igmp;
+ struct listnode *sock_node;
+
+ long qrv = 0, qqi = 0;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+ qrv = MAX(qrv, igmp->querier_robustness_variable);
+ qqi = MAX(qqi, igmp->querier_query_interval);
+ }
+ return PIM_IGMP_GMI_MSEC(qrv, qqi,
+ pim_ifp->igmp_query_max_response_time_dsec);
+}
+
void igmp_group_reset_gmi(struct igmp_group *group)
{
long group_membership_interval_msec;
- struct pim_interface *pim_ifp;
- struct igmp_sock *igmp;
struct interface *ifp;
- igmp = group->group_igmp_sock;
- ifp = igmp->interface;
- pim_ifp = ifp->info;
+ ifp = group->interface;
/*
RFC 3376: 8.4. Group Membership Interval
@@ -82,9 +94,7 @@ void igmp_group_reset_gmi(struct igmp_group *group)
(1000 * querier_query_interval) +
100 * query_response_interval_dsec;
*/
- group_membership_interval_msec = PIM_IGMP_GMI_MSEC(
- igmp->querier_robustness_variable, igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
+ group_membership_interval_msec = igmp_gmi_msec(group);
if (PIM_DEBUG_IGMP_TRACE) {
char group_str[INET_ADDRSTRLEN];
@@ -127,7 +137,7 @@ static int igmp_source_timer(struct thread *t)
zlog_debug(
"%s: Source timer expired for group %s source %s on %s",
__func__, group_str, source_str,
- group->group_igmp_sock->interface->name);
+ group->interface->name);
}
/*
@@ -188,8 +198,7 @@ static void source_timer_off(struct igmp_group *group,
sizeof(source_str));
zlog_debug(
"Cancelling TIMER event for group %s source %s on %s",
- group_str, source_str,
- group->group_igmp_sock->interface->name);
+ group_str, source_str, group->interface->name);
}
THREAD_OFF(source->t_source_timer);
@@ -199,7 +208,7 @@ static void igmp_source_timer_on(struct igmp_group *group,
struct igmp_source *source, long interval_msec)
{
source_timer_off(group, source);
- struct pim_interface *pim_ifp = group->group_igmp_sock->interface->info;
+ struct pim_interface *pim_ifp = group->interface->info;
if (PIM_DEBUG_IGMP_EVENTS) {
char group_str[INET_ADDRSTRLEN];
@@ -211,7 +220,7 @@ static void igmp_source_timer_on(struct igmp_group *group,
zlog_debug(
"Scheduling %ld.%03ld sec TIMER event for group %s source %s on %s",
interval_msec / 1000, interval_msec % 1000, group_str,
- source_str, group->group_igmp_sock->interface->name);
+ source_str, group->interface->name);
}
thread_add_timer_msec(router->master, igmp_source_timer, source,
@@ -225,19 +234,14 @@ static void igmp_source_timer_on(struct igmp_group *group,
igmp_source_forward_start(pim_ifp->pim, source);
}
-void igmp_source_reset_gmi(struct igmp_sock *igmp, struct igmp_group *group,
- struct igmp_source *source)
+void igmp_source_reset_gmi(struct igmp_group *group, struct igmp_source *source)
{
long group_membership_interval_msec;
- struct pim_interface *pim_ifp;
struct interface *ifp;
- ifp = igmp->interface;
- pim_ifp = ifp->info;
+ ifp = group->interface;
- group_membership_interval_msec = PIM_IGMP_GMI_MSEC(
- igmp->querier_robustness_variable, igmp->querier_query_interval,
- pim_ifp->igmp_query_max_response_time_dsec);
+ group_membership_interval_msec = igmp_gmi_msec(group);
if (PIM_DEBUG_IGMP_TRACE) {
char group_str[INET_ADDRSTRLEN];
@@ -312,7 +316,7 @@ static void source_clear_send_flag(struct list *source_list)
*/
static void group_exclude_fwd_anysrc_ifempty(struct igmp_group *group)
{
- struct pim_interface *pim_ifp = group->group_igmp_sock->interface->info;
+ struct pim_interface *pim_ifp = group->interface->info;
assert(group->group_filtermode_isexcl);
@@ -356,9 +360,8 @@ void igmp_source_delete(struct igmp_source *source)
pim_inet4_dump("<source?>", source->source_addr, source_str,
sizeof(source_str));
zlog_debug(
- "Deleting IGMP source %s for group %s from socket %d interface %s c_oil ref_count %d",
- source_str, group_str, group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name,
+ "Deleting IGMP source %s for group %s from interface %s c_oil ref_count %d",
+ source_str, group_str, group->interface->name,
source->source_channel_oil
? source->source_channel_oil->oil_ref_count
: 0);
@@ -376,10 +379,9 @@ void igmp_source_delete(struct igmp_source *source)
pim_inet4_dump("<source?>", source->source_addr, source_str,
sizeof(source_str));
zlog_warn(
- "%s: forwarding=ON(!) IGMP source %s for group %s from socket %d interface %s",
+ "%s: forwarding=ON(!) IGMP source %s for group %s from interface %s",
__func__, source_str, group_str,
- group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name);
+ group->interface->name);
/* warning only */
}
@@ -439,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];
@@ -452,9 +461,8 @@ struct igmp_source *source_new(struct igmp_group *group,
pim_inet4_dump("<source?>", src_addr, source_str,
sizeof(source_str));
zlog_debug(
- "Creating new IGMP source %s for group %s on socket %d interface %s",
- source_str, group_str, group->group_igmp_sock->fd,
- group->group_igmp_sock->interface->name);
+ "Creating new IGMP source %s for group %s on interface %s",
+ source_str, group_str, group->interface->name);
}
src = XCALLOC(MTYPE_PIM_IGMP_GROUP_SOURCE, sizeof(*src));
@@ -471,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;
}
@@ -518,8 +509,7 @@ static void allow(struct igmp_sock *igmp, struct in_addr from,
source = igmp_find_source_by_addr(group, star);
if (source)
- igmp_source_reset_gmi(igmp, group,
- source);
+ igmp_source_reset_gmi(group, source);
}
} else {
igmp_group_delete(group);
@@ -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
@@ -555,7 +544,7 @@ static void allow(struct igmp_sock *igmp, struct in_addr from,
igmp_source_reset_gmi() below, resetting the source timers to
GMI, accomplishes this.
*/
- igmp_source_reset_gmi(igmp, group, source);
+ igmp_source_reset_gmi(group, source);
} /* scan received sources */
}
@@ -585,21 +574,23 @@ 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->group_igmp_sock, group,
- source);
+ igmp_source_reset_gmi(group, source);
assert(source->t_source_timer); /* (A-X-Y) timer > 0 */
}
@@ -615,8 +606,7 @@ static void isex_excl(struct igmp_group *group, int num_sources,
source = igmp_find_source_by_addr(group, star);
if (source) {
IGMP_SOURCE_DONT_DELETE(source->source_flags);
- igmp_source_reset_gmi(group->group_igmp_sock, group,
- source);
+ igmp_source_reset_gmi(group, source);
}
}
@@ -639,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 */
}
@@ -706,7 +699,6 @@ void igmpv3_report_isex(struct igmp_sock *igmp, struct in_addr from,
static void toin_incl(struct igmp_group *group, int num_sources,
struct in_addr *sources)
{
- struct igmp_sock *igmp = group->group_igmp_sock;
int num_sources_tosend = listcount(group->group_source_list);
int i;
@@ -717,22 +709,23 @@ 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 */
- igmp_source_reset_gmi(igmp, group, source);
+ igmp_source_reset_gmi(group, source);
}
/* Send sources marked with SEND flag: Q(G,A-B) */
@@ -744,7 +737,6 @@ static void toin_incl(struct igmp_group *group, int num_sources,
static void toin_excl(struct igmp_group *group, int num_sources,
struct in_addr *sources)
{
- struct igmp_sock *igmp = group->group_igmp_sock;
int num_sources_tosend;
int i;
@@ -755,25 +747,24 @@ 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 */
- igmp_source_reset_gmi(igmp, group, source);
+ igmp_source_reset_gmi(group, source);
}
/* Send sources marked with SEND flag: Q(G,X-A) */
@@ -839,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) */
@@ -899,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);
@@ -912,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);
@@ -986,6 +976,26 @@ void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from,
allow(igmp, from, group_addr, num_sources, sources);
}
+static void igmp_send_query_group(struct igmp_group *group, char *query_buf,
+ size_t query_buf_size, int num_sources,
+ int s_flag)
+{
+ struct interface *ifp = group->interface;
+ struct pim_interface *pim_ifp = ifp->info;
+ struct igmp_sock *igmp;
+ struct listnode *sock_node;
+
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
+ igmp_send_query(
+ pim_ifp->igmp_version, group, igmp->fd, ifp->name,
+ query_buf, query_buf_size, num_sources,
+ group->group_addr, group->group_addr,
+ pim_ifp->igmp_specific_query_max_response_time_dsec,
+ s_flag, igmp->querier_robustness_variable,
+ igmp->querier_query_interval);
+ }
+}
+
/*
RFC3376: 6.6.3.1. Building and Sending Group Specific Queries
@@ -995,7 +1005,6 @@ void igmpv3_report_allow(struct igmp_sock *igmp, struct in_addr from,
*/
static void group_retransmit_group(struct igmp_group *group)
{
- struct igmp_sock *igmp;
struct pim_interface *pim_ifp;
long lmqc; /* Last Member Query Count */
long lmqi_msec; /* Last Member Query Interval */
@@ -1003,8 +1012,7 @@ static void group_retransmit_group(struct igmp_group *group)
int s_flag;
int query_buf_size;
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
+ pim_ifp = group->interface->info;
if (pim_ifp->igmp_version == 3) {
query_buf_size = PIM_IGMP_BUFSIZE_WRITE;
@@ -1033,7 +1041,7 @@ static void group_retransmit_group(struct igmp_group *group)
sizeof(group_str));
zlog_debug(
"retransmit_group_specific_query: group %s on %s: s_flag=%d count=%d",
- group_str, igmp->interface->name, s_flag,
+ group_str, group->interface->name, s_flag,
group->group_specific_query_retransmit_count);
}
@@ -1045,14 +1053,7 @@ static void group_retransmit_group(struct igmp_group *group)
interest.
*/
- igmp_send_query(pim_ifp->igmp_version, group, igmp->fd,
- igmp->interface->name, query_buf, sizeof(query_buf),
- 0 /* num_sources_tosend */,
- group->group_addr /* dst_addr */,
- group->group_addr /* group_addr */,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- s_flag, igmp->querier_robustness_variable,
- igmp->querier_query_interval);
+ igmp_send_query_group(group, query_buf, sizeof(query_buf), 0, s_flag);
}
/*
@@ -1070,7 +1071,6 @@ static void group_retransmit_group(struct igmp_group *group)
static int group_retransmit_sources(struct igmp_group *group,
int send_with_sflag_set)
{
- struct igmp_sock *igmp;
struct pim_interface *pim_ifp;
long lmqc; /* Last Member Query Count */
long lmqi_msec; /* Last Member Query Interval */
@@ -1090,8 +1090,7 @@ static int group_retransmit_sources(struct igmp_group *group,
source_addr1 = (struct in_addr *)(query_buf1 + IGMP_V3_SOURCES_OFFSET);
source_addr2 = (struct in_addr *)(query_buf2 + IGMP_V3_SOURCES_OFFSET);
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
+ pim_ifp = group->interface->info;
lmqc = pim_ifp->igmp_last_member_query_count;
lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
@@ -1131,7 +1130,7 @@ static int group_retransmit_sources(struct igmp_group *group,
sizeof(group_str));
zlog_debug(
"retransmit_grp&src_specific_query: group %s on %s: srcs_with_sflag=%d srcs_wo_sflag=%d will_send_sflag=%d retransmit_src_left=%d",
- group_str, igmp->interface->name, num_sources_tosend1,
+ group_str, group->interface->name, num_sources_tosend1,
num_sources_tosend2, send_with_sflag_set,
num_retransmit_sources_left);
}
@@ -1154,7 +1153,7 @@ static int group_retransmit_sources(struct igmp_group *group,
zlog_warn(
"%s: group %s on %s: s_flag=1 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
__func__, group_str,
- igmp->interface->name,
+ group->interface->name,
num_sources_tosend1, sizeof(query_buf1),
query_buf1_max_sources);
} else {
@@ -1169,15 +1168,9 @@ static int group_retransmit_sources(struct igmp_group *group,
interest.
*/
- igmp_send_query(
- pim_ifp->igmp_version, group, igmp->fd,
- igmp->interface->name, query_buf1,
- sizeof(query_buf1), num_sources_tosend1,
- group->group_addr, group->group_addr,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- 1 /* s_flag */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
+ igmp_send_query_group(
+ group, query_buf1, sizeof(query_buf1),
+ num_sources_tosend1, 1 /* s_flag */);
}
} /* send_with_sflag_set */
@@ -1197,7 +1190,7 @@ static int group_retransmit_sources(struct igmp_group *group,
sizeof(group_str));
zlog_warn(
"%s: group %s on %s: s_flag=0 unable to fit %d sources into buf_size=%zu (max_sources=%d)",
- __func__, group_str, igmp->interface->name,
+ __func__, group_str, group->interface->name,
num_sources_tosend2, sizeof(query_buf2),
query_buf2_max_sources);
} else {
@@ -1211,15 +1204,9 @@ static int group_retransmit_sources(struct igmp_group *group,
interest.
*/
- igmp_send_query(
- pim_ifp->igmp_version, group, igmp->fd,
- igmp->interface->name, query_buf2,
- sizeof(query_buf2), num_sources_tosend2,
- group->group_addr, group->group_addr,
- pim_ifp->igmp_specific_query_max_response_time_dsec,
- 0 /* s_flag */,
- igmp->querier_robustness_variable,
- igmp->querier_query_interval);
+ igmp_send_query_group(
+ group, query_buf2, sizeof(query_buf2),
+ num_sources_tosend2, 0 /* s_flag */);
}
}
@@ -1239,7 +1226,7 @@ static int igmp_group_retransmit(struct thread *t)
pim_inet4_dump("<group?>", group->group_addr, group_str,
sizeof(group_str));
zlog_debug("group_retransmit_timer: group %s on %s", group_str,
- group->group_igmp_sock->interface->name);
+ group->interface->name);
}
/* Retransmit group-specific queries? (RFC3376: 6.6.3.1) */
@@ -1287,7 +1274,6 @@ static int igmp_group_retransmit(struct thread *t)
*/
static void group_retransmit_timer_on(struct igmp_group *group)
{
- struct igmp_sock *igmp;
struct pim_interface *pim_ifp;
long lmqi_msec; /* Last Member Query Interval */
@@ -1296,8 +1282,7 @@ static void group_retransmit_timer_on(struct igmp_group *group)
return;
}
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
+ pim_ifp = group->interface->info;
lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
@@ -1308,7 +1293,7 @@ static void group_retransmit_timer_on(struct igmp_group *group)
zlog_debug(
"Scheduling %ld.%03ld sec retransmit timer for group %s on %s",
lmqi_msec / 1000, lmqi_msec % 1000, group_str,
- igmp->interface->name);
+ group->interface->name);
}
thread_add_timer_msec(router->master, igmp_group_retransmit, group,
@@ -1332,11 +1317,9 @@ static long igmp_source_timer_remain_msec(struct igmp_source *source)
static void group_query_send(struct igmp_group *group)
{
struct pim_interface *pim_ifp;
- struct igmp_sock *igmp;
long lmqc; /* Last Member Query Count */
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
+ pim_ifp = group->interface->info;
lmqc = pim_ifp->igmp_last_member_query_count;
/* lower group timer to lmqt */
@@ -1359,7 +1342,6 @@ static void group_query_send(struct igmp_group *group)
static void source_query_send_by_flag(struct igmp_group *group,
int num_sources_tosend)
{
- struct igmp_sock *igmp;
struct pim_interface *pim_ifp;
struct listnode *src_node;
struct igmp_source *src;
@@ -1369,8 +1351,7 @@ static void source_query_send_by_flag(struct igmp_group *group,
assert(num_sources_tosend > 0);
- igmp = group->group_igmp_sock;
- pim_ifp = igmp->interface->info;
+ pim_ifp = group->interface->info;
lmqc = pim_ifp->igmp_last_member_query_count;
lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;
@@ -1417,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);
@@ -1504,7 +1488,6 @@ void igmpv3_report_block(struct igmp_sock *igmp, struct in_addr from,
void igmp_group_timer_lower_to_lmqt(struct igmp_group *group)
{
- struct igmp_sock *igmp;
struct interface *ifp;
struct pim_interface *pim_ifp;
char *ifname;
@@ -1523,8 +1506,7 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group)
return;
}
- igmp = group->group_igmp_sock;
- ifp = igmp->interface;
+ ifp = group->interface;
pim_ifp = ifp->info;
ifname = ifp->name;
@@ -1551,7 +1533,6 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group)
void igmp_source_timer_lower_to_lmqt(struct igmp_source *source)
{
struct igmp_group *group;
- struct igmp_sock *igmp;
struct interface *ifp;
struct pim_interface *pim_ifp;
char *ifname;
@@ -1560,8 +1541,7 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source)
int lmqt_msec; /* Last Member Query Time */
group = source->source_group;
- igmp = group->group_igmp_sock;
- ifp = igmp->interface;
+ ifp = group->interface;
pim_ifp = ifp->info;
ifname = ifp->name;
diff --git a/pimd/pim_igmpv3.h b/pimd/pim_igmpv3.h
index 6abaef6e2..273f944b3 100644
--- a/pimd/pim_igmpv3.h
+++ b/pimd/pim_igmpv3.h
@@ -23,6 +23,8 @@
#include <zebra.h>
#include "if.h"
+#include "pim_igmp.h"
+
#define IGMP_V3_CHECKSUM_OFFSET (2)
#define IGMP_V3_REPORT_NUMGROUPS_OFFSET (6)
#define IGMP_V3_REPORT_GROUPPRECORD_OFFSET (8)
@@ -52,7 +54,7 @@
#define PIM_IGMP_OHPI_DSEC(qrv,qqi,qri_dsec) ((qrv) * (10 * (qqi)) + (qri_dsec))
void igmp_group_reset_gmi(struct igmp_group *group);
-void igmp_source_reset_gmi(struct igmp_sock *igmp, struct igmp_group *group,
+void igmp_source_reset_gmi(struct igmp_group *group,
struct igmp_source *source);
void igmp_source_free(struct igmp_source *source);
diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h
index 52ded08ae..68c5b9167 100644
--- a/pimd/pim_instance.h
+++ b/pimd/pim_instance.h
@@ -210,6 +210,8 @@ struct pim_instance {
void pim_vrf_init(void);
void pim_vrf_terminate(void);
+extern struct pim_router *router;
+
struct pim_instance *pim_get_pim_instance(vrf_id_t vrf_id);
#endif
diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h
index 2d8e1b01f..4cd6b9f0a 100644
--- a/pimd/pim_mroute.h
+++ b/pimd/pim_mroute.h
@@ -167,6 +167,8 @@ struct igmpmsg {
Above: from <linux/mroute.h>
*/
+struct channel_oil;
+
int pim_mroute_socket_enable(struct pim_instance *pim);
int pim_mroute_socket_disable(struct pim_instance *pim);
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index 4b4c1ec7d..f4627cbcc 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -23,6 +23,7 @@
#include "pim_nb.h"
#include "lib/northbound_cli.h"
#include "pim_igmpv3.h"
+#include "pim_neighbor.h"
#include "pim_pim.h"
#include "pim_mlag.h"
#include "pim_bfd.h"
@@ -60,8 +61,9 @@ static void pim_if_membership_clear(struct interface *ifp)
static void pim_if_membership_refresh(struct interface *ifp)
{
struct pim_interface *pim_ifp;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *grpnode;
+ struct igmp_group *grp;
+
pim_ifp = ifp->info;
assert(pim_ifp);
@@ -83,36 +85,27 @@ static void pim_if_membership_refresh(struct interface *ifp)
* the interface
*/
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grpnode,
- grp)) {
- struct listnode *srcnode;
- struct igmp_source *src;
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
- srcnode, src)) {
-
- if (IGMP_SOURCE_TEST_FORWARDING(
- src->source_flags)) {
- struct prefix_sg sg;
-
- memset(&sg, 0,
- sizeof(struct prefix_sg));
- sg.src = src->source_addr;
- sg.grp = grp->group_addr;
- pim_ifchannel_local_membership_add(
- ifp, &sg, false /*is_vxlan*/);
- }
-
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode, grp)) {
+ struct listnode *srcnode;
+ struct igmp_source *src;
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, srcnode,
+ src)) {
+
+ if (IGMP_SOURCE_TEST_FORWARDING(src->source_flags)) {
+ struct prefix_sg sg;
+
+ memset(&sg, 0, sizeof(struct prefix_sg));
+ sg.src = src->source_addr;
+ sg.grp = grp->group_addr;
+ pim_ifchannel_local_membership_add(
+ ifp, &sg, false /*is_vxlan*/);
+ }
+
+ } /* scan group sources */
+ } /* scan igmp groups */
/*
* Finally delete every PIM (S,G) entry lacking all state info
@@ -458,6 +451,8 @@ static void change_query_max_response_time(struct pim_interface *pim_ifp,
{
struct listnode *sock_node;
struct igmp_sock *igmp;
+ struct listnode *grp_node;
+ struct igmp_group *grp;
if (pim_ifp->igmp_query_max_response_time_dsec
== query_max_response_time_dsec)
@@ -474,32 +469,28 @@ static void change_query_max_response_time(struct pim_interface *pim_ifp,
/* scan all sockets */
for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, igmp)) {
- struct listnode *grp_node;
- struct igmp_group *grp;
-
/* reschedule socket general query */
igmp_sock_query_reschedule(igmp);
+ }
- /* scan socket groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, grp_node,
- grp)) {
- struct listnode *src_node;
- struct igmp_source *src;
-
- /* reset group timers for groups in EXCLUDE mode */
- if (grp->group_filtermode_isexcl)
- igmp_group_reset_gmi(grp);
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
- src_node, src)) {
-
- /* reset source timers for sources with running
- * timers
- */
- if (src->t_source_timer)
- igmp_source_reset_gmi(igmp, grp, src);
- }
+ /* scan socket groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grp_node, grp)) {
+ struct listnode *src_node;
+ struct igmp_source *src;
+
+ /* reset group timers for groups in EXCLUDE mode */
+ if (grp->group_filtermode_isexcl)
+ igmp_group_reset_gmi(grp);
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list, src_node,
+ src)) {
+
+ /* reset source timers for sources with running
+ * timers
+ */
+ if (src->t_source_timer)
+ igmp_source_reset_gmi(grp, src);
}
}
}
diff --git a/pimd/pim_neighbor.h b/pimd/pim_neighbor.h
index b461098a6..d71b2b87c 100644
--- a/pimd/pim_neighbor.h
+++ b/pimd/pim_neighbor.h
@@ -27,6 +27,7 @@
#include "prefix.h"
#include "pim_tlv.h"
+#include "pim_iface.h"
struct pim_neighbor {
int64_t creation; /* timestamp of creation */
diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h
index b0aa2b17c..af8ac8459 100644
--- a/pimd/pim_oil.h
+++ b/pimd/pim_oil.h
@@ -20,8 +20,9 @@
#ifndef PIM_OIL_H
#define PIM_OIL_H
+struct pim_interface;
+
#include "pim_mroute.h"
-#include "pim_iface.h"
/*
* Where did we get this (S,G) from?
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index 3e3b6dddb..f2a969e04 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -42,7 +42,7 @@
#include "pim_rpf.h"
#include "pim_sock.h"
#include "pim_memory.h"
-#include "pim_iface.h"
+#include "pim_neighbor.h"
#include "pim_msdp.h"
#include "pim_nht.h"
#include "pim_mroute.h"
diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h
index dd7cd5d75..595025e5c 100644
--- a/pimd/pim_rp.h
+++ b/pimd/pim_rp.h
@@ -24,9 +24,10 @@
#include "prefix.h"
#include "vty.h"
#include "plist.h"
-#include "pim_iface.h"
#include "pim_rpf.h"
+struct pim_interface;
+
enum rp_source {
RP_SRC_NONE = 0,
RP_SRC_STATIC,
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index 66c6df65a..b93f85e48 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -31,6 +31,7 @@
#include "pim_pim.h"
#include "pim_str.h"
#include "pim_iface.h"
+#include "pim_neighbor.h"
#include "pim_zlookup.h"
#include "pim_ifchannel.h"
#include "pim_time.h"
diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h
index f006519b7..006aa1b63 100644
--- a/pimd/pim_rpf.h
+++ b/pimd/pim_rpf.h
@@ -22,9 +22,6 @@
#include <zebra.h>
-#include "pim_upstream.h"
-#include "pim_neighbor.h"
-
/*
RFC 4601:
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index 56039d560..ea3b564f8 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -24,7 +24,7 @@
#include <prefix.h>
#include "plist.h"
-#include <pimd/pim_rpf.h>
+#include "pim_rpf.h"
#include "pim_str.h"
#include "pim_ifchannel.h"
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 6f933e9e7..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;
@@ -508,7 +508,7 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim,
sg.src = source->source_addr;
sg.grp = group->group_addr;
- ch = pim_ifchannel_find(group->group_igmp_sock->interface, &sg);
+ ch = pim_ifchannel_find(group->interface, &sg);
if (pim_is_grp_ssm(pim, group->group_addr)) {
/* If SSM group withdraw local membership */
if (ch
@@ -517,8 +517,8 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim,
zlog_debug(
"local membership del for %s as G is now SSM",
pim_str_sg_dump(&sg));
- pim_ifchannel_local_membership_del(
- group->group_igmp_sock->interface, &sg);
+ pim_ifchannel_local_membership_del(group->interface,
+ &sg);
}
} else {
/* If ASM group add local membership */
@@ -529,8 +529,7 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim,
"local membership add for %s as G is now ASM",
pim_str_sg_dump(&sg));
pim_ifchannel_local_membership_add(
- group->group_igmp_sock->interface, &sg,
- false /*is_vxlan*/);
+ group->interface, &sg, false /*is_vxlan*/);
}
}
}
@@ -541,33 +540,24 @@ void igmp_source_forward_reevaluate_all(struct pim_instance *pim)
FOR_ALL_INTERFACES (pim->vrf, ifp) {
struct pim_interface *pim_ifp = ifp->info;
- struct listnode *sock_node;
- struct igmp_sock *igmp;
+ struct listnode *grpnode;
+ struct igmp_group *grp;
if (!pim_ifp)
continue;
- /* scan igmp sockets */
- for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node,
- igmp)) {
- struct listnode *grpnode;
- struct igmp_group *grp;
-
- /* scan igmp groups */
- for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list,
- grpnode, grp)) {
- struct listnode *srcnode;
- struct igmp_source *src;
-
- /* scan group sources */
- for (ALL_LIST_ELEMENTS_RO(
- grp->group_source_list, srcnode,
- src)) {
- igmp_source_forward_reevaluate_one(pim,
- src);
- } /* scan group sources */
- } /* scan igmp groups */
- } /* scan igmp sockets */
+ /* scan igmp groups */
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_group_list, grpnode,
+ grp)) {
+ struct listnode *srcnode;
+ struct igmp_source *src;
+
+ /* scan group sources */
+ for (ALL_LIST_ELEMENTS_RO(grp->group_source_list,
+ srcnode, src)) {
+ igmp_source_forward_reevaluate_one(pim, src);
+ } /* scan group sources */
+ } /* scan igmp groups */
} /* scan interfaces */
}
@@ -585,12 +575,10 @@ void igmp_source_forward_start(struct pim_instance *pim,
sg.grp = source->source_group->group_addr;
if (PIM_DEBUG_IGMP_TRACE) {
- zlog_debug(
- "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__,
- pim_str_sg_dump(&sg),
- source->source_group->group_igmp_sock->fd,
- source->source_group->group_igmp_sock->interface->name,
- IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
+ zlog_debug("%s: (S,G)=%s oif=%s fwd=%d", __func__,
+ pim_str_sg_dump(&sg),
+ source->source_group->interface->name,
+ IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
}
/* Prevent IGMP interface from installing multicast route multiple
@@ -600,13 +588,12 @@ void igmp_source_forward_start(struct pim_instance *pim,
}
group = source->source_group;
- pim_oif = group->group_igmp_sock->interface->info;
+ pim_oif = group->interface->info;
if (!pim_oif) {
if (PIM_DEBUG_IGMP_TRACE) {
zlog_debug("%s: multicast not enabled on oif=%s ?",
__func__,
- source->source_group->group_igmp_sock
- ->interface->name);
+ source->source_group->interface->name);
}
return;
}
@@ -688,14 +675,10 @@ void igmp_source_forward_start(struct pim_instance *pim,
*/
if (PIM_DEBUG_IGMP_TRACE) {
zlog_debug(
- "%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
+ "%s: ignoring request for looped MFC entry (S,G)=%s: oif=%s vif_index=%d",
__func__,
pim_str_sg_dump(&sg),
source->source_group
- ->group_igmp_sock
- ->fd,
- source->source_group
- ->group_igmp_sock
->interface->name,
input_iface_vif_index);
}
@@ -719,7 +702,7 @@ void igmp_source_forward_start(struct pim_instance *pim,
if (PIM_I_am_DR(pim_oif) || PIM_I_am_DualActive(pim_oif)) {
result = pim_channel_add_oif(source->source_channel_oil,
- group->group_igmp_sock->interface,
+ group->interface,
PIM_OIF_FLAG_PROTO_IGMP, __func__);
if (result) {
if (PIM_DEBUG_MROUTE) {
@@ -733,7 +716,7 @@ void igmp_source_forward_start(struct pim_instance *pim,
zlog_debug(
"%s: %s was received on %s interface but we are not DR for that interface",
__func__, pim_str_sg_dump(&sg),
- group->group_igmp_sock->interface->name);
+ group->interface->name);
return;
}
@@ -741,16 +724,15 @@ void igmp_source_forward_start(struct pim_instance *pim,
Feed IGMPv3-gathered local membership information into PIM
per-interface (S,G) state.
*/
- if (!pim_ifchannel_local_membership_add(
- group->group_igmp_sock->interface, &sg,
+ if (!pim_ifchannel_local_membership_add(group->interface, &sg,
false /*is_vxlan*/)) {
if (PIM_DEBUG_MROUTE)
zlog_warn("%s: Failure to add local membership for %s",
__func__, pim_str_sg_dump(&sg));
pim_channel_del_oif(source->source_channel_oil,
- group->group_igmp_sock->interface,
- PIM_OIF_FLAG_PROTO_IGMP, __func__);
+ group->interface, PIM_OIF_FLAG_PROTO_IGMP,
+ __func__);
return;
}
@@ -772,12 +754,10 @@ void igmp_source_forward_stop(struct igmp_source *source)
sg.grp = source->source_group->group_addr;
if (PIM_DEBUG_IGMP_TRACE) {
- zlog_debug(
- "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__,
- pim_str_sg_dump(&sg),
- source->source_group->group_igmp_sock->fd,
- source->source_group->group_igmp_sock->interface->name,
- IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
+ zlog_debug("%s: (S,G)=%s oif=%s fwd=%d", __func__,
+ pim_str_sg_dump(&sg),
+ source->source_group->interface->name,
+ IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
}
/* Prevent IGMP interface from removing multicast route multiple
@@ -800,9 +780,8 @@ void igmp_source_forward_stop(struct igmp_source *source)
pim_forward_stop below.
*/
result = pim_channel_del_oif(source->source_channel_oil,
- group->group_igmp_sock->interface,
- PIM_OIF_FLAG_PROTO_IGMP,
- __func__);
+ group->interface, PIM_OIF_FLAG_PROTO_IGMP,
+ __func__);
if (result) {
if (PIM_DEBUG_IGMP_TRACE)
zlog_debug(
@@ -815,8 +794,7 @@ void igmp_source_forward_stop(struct igmp_source *source)
Feed IGMPv3-gathered local membership information into PIM
per-interface (S,G) state.
*/
- pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
- &sg);
+ pim_ifchannel_local_membership_del(group->interface, &sg);
IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
}
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index dce936b8a..abf9577bd 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -31,6 +31,7 @@
#include "pimd.h"
#include "pim_iface.h"
+#include "pim_neighbor.h"
#include "pim_pim.h"
#include "pim_str.h"
#include "pim_oil.h"
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 88e692b50..4cb860a6b 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -136,7 +136,6 @@ extern const char *const PIM_ALL_ROUTERS;
extern const char *const PIM_ALL_PIM_ROUTERS;
extern const char *const PIM_ALL_IGMP_ROUTERS;
-extern struct pim_router *router;
extern struct zebra_privs_t pimd_privs;
extern struct in_addr qpim_all_pim_routers_addr;
extern uint8_t qpim_ecmp_enable;