summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_cmd.c423
-rw-r--r--pimd/pim_iface.c7
-rw-r--r--pimd/pim_iface.h2
-rw-r--r--pimd/pim_igmp.c107
-rw-r--r--pimd/pim_igmp.h11
-rw-r--r--pimd/pim_igmpv3.c176
-rw-r--r--pimd/pim_igmpv3.h2
-rw-r--r--pimd/pim_nb_config.c100
-rw-r--r--pimd/pim_zebra.c77
9 files changed, 413 insertions, 492 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 1238e03a5b..f57bf7093e 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -3430,112 +3430,97 @@ 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
- ? "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
- ? (grp->group_filtermode_isexcl
- ? "EXCL"
- : "INCL")
- : "----",
- hhmmss,
- grp->group_source_list
- ? listcount(
- grp->group_source_list)
- : 0,
- grp->igmp_version, uptime);
+ 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);
}
- } /* scan igmp groups */
- } /* scan igmp sockets */
- } /* scan interfaces */
+
+ 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 %4s %8s %4d %d %8s\n",
+ ifp->name, group_str,
+ grp->igmp_version == 3
+ ? (grp->group_filtermode_isexcl
+ ? "EXCL"
+ : "INCL")
+ : "----",
+ 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 +3535,51 @@ 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);
+ /* 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;
- }
+
+ /* 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 +3590,59 @@ 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;
-
- 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];
- struct listnode *srcnode;
- struct igmp_source *src;
-
- 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];
- char mmss[10];
- char uptime[10];
+ /* 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));
+
+ /* 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_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_timer_to_mmss(
+ mmss, sizeof(mmss),
+ src->t_source_timer);
- pim_time_uptime(
- uptime, sizeof(uptime),
- now - src->source_creation);
+ 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)
- ? "Y"
- : "N",
- uptime);
+ 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);
- } /* 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 +3651,45 @@ 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(igmp->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(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("<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 %-15s %7d\n",
- ifp->name, ifaddr_str,
- group_str, source_str,
- src->source_query_retransmit_count);
+ vty_out(vty,
+ "%-16s %-15s %-15s %7d\n",
+ ifp->name, 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 +3942,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 +3956,13 @@ 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 0b28a3e84c..eb19cf4ddf 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 dc70b4134f..55c278d6e2 100644
--- a/pimd/pim_iface.h
+++ b/pimd/pim_iface.h
@@ -103,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_igmp.c b/pimd/pim_igmp.c
index 71b2d9187a..28f2b30ef4 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,52 @@ 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 +985,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 +1127,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 +1164,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 +1201,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 +1254,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 +1263,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 +1275,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 abb8af836b..460c9d9a07 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;
};
diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c
index bc67a1dd1d..f13dfe1b8c 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);
}
/*
@@ -189,7 +199,7 @@ static void source_timer_off(struct igmp_group *group,
zlog_debug(
"Cancelling TIMER event for group %s source %s on %s",
group_str, source_str,
- group->group_igmp_sock->interface->name);
+ group->interface->name);
}
THREAD_OFF(source->t_source_timer);
@@ -199,7 +209,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 +221,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 +235,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 +317,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 +361,9 @@ 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 +381,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 */
}
@@ -452,9 +456,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));
@@ -518,8 +521,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);
@@ -555,7 +557,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 */
}
@@ -598,8 +600,7 @@ static void isex_excl(struct igmp_group *group, int num_sources,
* (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 +616,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);
}
}
@@ -706,7 +706,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;
@@ -732,7 +731,7 @@ static void toin_incl(struct igmp_group *group, int num_sources,
}
/* (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 +743,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;
@@ -773,7 +771,7 @@ static void toin_excl(struct igmp_group *group, int num_sources,
}
/* (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) */
@@ -986,6 +984,27 @@ 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 +1014,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 +1021,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 +1050,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 +1062,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 +1080,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 +1099,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 +1139,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 +1162,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 +1177,10 @@ 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 +1200,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 +1214,10 @@ 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 +1237,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 +1285,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 +1293,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 +1304,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 +1328,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 +1353,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 +1362,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;
@@ -1504,7 +1496,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 +1514,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 +1541,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 +1549,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 5adf22a6fa..273f944b3c 100644
--- a/pimd/pim_igmpv3.h
+++ b/pimd/pim_igmpv3.h
@@ -54,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_nb_config.c b/pimd/pim_nb_config.c
index 20fc4eaef6..440db53611 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -61,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);
@@ -84,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
@@ -459,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)
@@ -475,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_zebra.c b/pimd/pim_zebra.c
index 6f933e9e72..e8df29b3e2 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -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
@@ -518,7 +518,7 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim,
"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);
+ group->interface, &sg);
}
} else {
/* If ASM group add local membership */
@@ -529,7 +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,
+ group->interface, &sg,
false /*is_vxlan*/);
}
}
@@ -541,33 +541,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 */
}
@@ -586,10 +577,9 @@ void igmp_source_forward_start(struct pim_instance *pim,
if (PIM_DEBUG_IGMP_TRACE) {
zlog_debug(
- "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__,
+ "%s: (S,G)=%s 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,
+ source->source_group->interface->name,
IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
}
@@ -600,13 +590,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 +677,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 +704,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 +718,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;
}
@@ -742,14 +727,14 @@ void igmp_source_forward_start(struct pim_instance *pim,
per-interface (S,G) state.
*/
if (!pim_ifchannel_local_membership_add(
- group->group_igmp_sock->interface, &sg,
+ 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,
+ group->interface,
PIM_OIF_FLAG_PROTO_IGMP, __func__);
return;
}
@@ -773,10 +758,9 @@ void igmp_source_forward_stop(struct igmp_source *source)
if (PIM_DEBUG_IGMP_TRACE) {
zlog_debug(
- "%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d", __func__,
+ "%s: (S,G)=%s 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,
+ source->source_group->interface->name,
IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
}
@@ -800,7 +784,7 @@ 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,
+ group->interface,
PIM_OIF_FLAG_PROTO_IGMP,
__func__);
if (result) {
@@ -815,8 +799,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);
}