diff options
Diffstat (limited to 'pimd/pim_igmpv3.c')
| -rw-r--r-- | pimd/pim_igmpv3.c | 176 |
1 files changed, 82 insertions, 94 deletions
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; |
