diff options
| -rw-r--r-- | pimd/pim_cmd.c | 423 | ||||
| -rw-r--r-- | pimd/pim_iface.c | 7 | ||||
| -rw-r--r-- | pimd/pim_iface.h | 2 | ||||
| -rw-r--r-- | pimd/pim_igmp.c | 107 | ||||
| -rw-r--r-- | pimd/pim_igmp.h | 11 | ||||
| -rw-r--r-- | pimd/pim_igmpv3.c | 176 | ||||
| -rw-r--r-- | pimd/pim_igmpv3.h | 2 | ||||
| -rw-r--r-- | pimd/pim_nb_config.c | 100 | ||||
| -rw-r--r-- | pimd/pim_zebra.c | 77 |
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); } |
