diff options
| -rw-r--r-- | lib/wheel.c | 1 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 38 | ||||
| -rw-r--r-- | pimd/pim_igmp_stats.c | 3 | ||||
| -rw-r--r-- | pimd/pim_igmp_stats.h | 1 | ||||
| -rw-r--r-- | pimd/pim_igmpv2.c | 21 | ||||
| -rw-r--r-- | pimd/pim_igmpv3.c | 93 | ||||
| -rw-r--r-- | pimd/pim_upstream.c | 13 | ||||
| -rw-r--r-- | zebra/zebra_vxlan.c | 6 |
8 files changed, 118 insertions, 58 deletions
diff --git a/lib/wheel.c b/lib/wheel.c index 463410bea4..cdf738a137 100644 --- a/lib/wheel.c +++ b/lib/wheel.c @@ -40,7 +40,6 @@ static void wheel_timer_thread_helper(struct thread *t) void *data; wheel = THREAD_ARG(t); - THREAD_OFF(wheel->timer); wheel->curr_slot += wheel->slots_to_skip; diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 3c2f59bf2f..78dbbf9326 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1348,6 +1348,8 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty, igmp_stats.mtrace_req); json_object_int_add(json_row, "unsupported", igmp_stats.unsupported); + json_object_int_add(json_row, "totalReceivedMessages", + igmp_stats.total_recv_messages); json_object_int_add(json_row, "totalGroups", igmp_stats.total_groups); json_object_int_add(json_row, "totalSourceGroups", @@ -1365,39 +1367,41 @@ static void igmp_show_statistics(struct pim_instance *pim, struct vty *vty, vty_json(vty, json); } else { vty_out(vty, "IGMP statistics\n"); - vty_out(vty, "Interface : %s\n", + vty_out(vty, "Interface : %s\n", ifname ? ifname : "global"); - vty_out(vty, "V1 query : %u\n", + vty_out(vty, "V1 query : %u\n", igmp_stats.query_v1); - vty_out(vty, "V2 query : %u\n", + vty_out(vty, "V2 query : %u\n", igmp_stats.query_v2); - vty_out(vty, "V3 query : %u\n", + vty_out(vty, "V3 query : %u\n", igmp_stats.query_v3); - vty_out(vty, "V2 leave : %u\n", + vty_out(vty, "V2 leave : %u\n", igmp_stats.leave_v2); - vty_out(vty, "V1 report : %u\n", + vty_out(vty, "V1 report : %u\n", igmp_stats.report_v1); - vty_out(vty, "V2 report : %u\n", + vty_out(vty, "V2 report : %u\n", igmp_stats.report_v2); - vty_out(vty, "V3 report : %u\n", + vty_out(vty, "V3 report : %u\n", igmp_stats.report_v3); - vty_out(vty, "mtrace response : %u\n", + vty_out(vty, "mtrace response : %u\n", igmp_stats.mtrace_rsp); - vty_out(vty, "mtrace request : %u\n", + vty_out(vty, "mtrace request : %u\n", igmp_stats.mtrace_req); - vty_out(vty, "unsupported : %u\n", + vty_out(vty, "unsupported : %u\n", igmp_stats.unsupported); - vty_out(vty, "joins failed : %u\n", + vty_out(vty, "total received messages : %u\n", + igmp_stats.total_recv_messages); + vty_out(vty, "joins failed : %u\n", igmp_stats.joins_failed); - vty_out(vty, "joins sent : %u\n", + vty_out(vty, "joins sent : %u\n", igmp_stats.joins_sent); - vty_out(vty, "general queries sent : %u\n", + vty_out(vty, "general queries sent : %u\n", igmp_stats.general_queries_sent); - vty_out(vty, "group queries sent : %u\n", + vty_out(vty, "group queries sent : %u\n", igmp_stats.group_queries_sent); - vty_out(vty, "total groups : %u\n", + vty_out(vty, "total groups : %u\n", igmp_stats.total_groups); - vty_out(vty, "total source groups : %u\n", + vty_out(vty, "total source groups : %u\n", igmp_stats.total_source_groups); } } diff --git a/pimd/pim_igmp_stats.c b/pimd/pim_igmp_stats.c index b2f1d6b3cc..6a5ce4dc8d 100644 --- a/pimd/pim_igmp_stats.c +++ b/pimd/pim_igmp_stats.c @@ -49,4 +49,7 @@ void igmp_stats_add(struct igmp_stats *a, struct igmp_stats *b) a->joins_failed += b->joins_failed; a->general_queries_sent += b->general_queries_sent; a->group_queries_sent += b->group_queries_sent; + a->total_recv_messages += b->query_v1 + b->query_v2 + b->query_v3 + + b->report_v1 + b->report_v2 + b->report_v3 + + b->leave_v2 + b->mtrace_rsp + b->mtrace_req; } diff --git a/pimd/pim_igmp_stats.h b/pimd/pim_igmp_stats.h index c22922a316..560132a19a 100644 --- a/pimd/pim_igmp_stats.h +++ b/pimd/pim_igmp_stats.h @@ -39,6 +39,7 @@ struct igmp_stats { uint32_t joins_failed; uint32_t general_queries_sent; uint32_t group_queries_sent; + uint32_t total_recv_messages; }; #if PIM_IPV == 4 diff --git a/pimd/pim_igmpv2.c b/pimd/pim_igmpv2.c index 09a82069a2..34cda25963 100644 --- a/pimd/pim_igmpv2.c +++ b/pimd/pim_igmpv2.c @@ -24,6 +24,7 @@ #include "pim_igmp.h" #include "pim_igmpv2.h" #include "pim_igmpv3.h" +#include "pim_ssm.h" #include "pim_str.h" #include "pim_time.h" #include "pim_util.h" @@ -107,10 +108,13 @@ int igmp_v2_recv_report(struct gm_sock *igmp, struct in_addr from, { struct interface *ifp = igmp->interface; struct in_addr group_addr; + struct pim_interface *pim_ifp; char group_str[INET_ADDRSTRLEN]; on_trace(__func__, igmp->interface, from); + pim_ifp = ifp->info; + if (igmp->mtrace_only) return 0; @@ -142,6 +146,23 @@ int igmp_v2_recv_report(struct gm_sock *igmp, struct in_addr from, } /* + * RFC 4604 + * section 2.2.1 + * EXCLUDE mode does not apply to SSM addresses, and an SSM-aware router + * will ignore MODE_IS_EXCLUDE and CHANGE_TO_EXCLUDE_MODE requests in + * the SSM range. + */ + if (pim_is_grp_ssm(pim_ifp->pim, group_addr)) { + if (PIM_DEBUG_IGMP_PACKETS) { + zlog_debug( + "Ignoring IGMPv2 group record %pI4 from %s on %s exclude mode in SSM range", + &group_addr.s_addr, from_str, ifp->name); + } + return -1; + } + + + /* * RFC 3376 * 7.3.2. In the Presence of Older Version Group Members * diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 027a79da98..b6114f9ead 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -32,6 +32,7 @@ #include "pim_time.h" #include "pim_zebra.h" #include "pim_oil.h" +#include "pim_ssm.h" static void group_retransmit_timer_on(struct gm_group *group); static long igmp_group_timer_remain_msec(struct gm_group *group); @@ -1820,6 +1821,64 @@ void igmp_v3_recv_query(struct gm_sock *igmp, const char *from_str, } /* s_flag is clear: timer updates */ } +static bool igmp_pkt_grp_addr_ok(struct interface *ifp, const char *from_str, + struct in_addr grp, int rec_type) +{ + struct pim_interface *pim_ifp; + struct in_addr grp_addr; + + pim_ifp = ifp->info; + + /* determine filtering status for group */ + if (pim_is_group_filtered(pim_ifp, &grp)) { + if (PIM_DEBUG_IGMP_PACKETS) { + zlog_debug( + "Filtering IGMPv3 group record %pI4 from %s on %s per prefix-list %s", + &grp.s_addr, from_str, ifp->name, + pim_ifp->boundary_oil_plist); + } + return false; + } + + /* + * If we receive a igmp report with the group in 224.0.0.0/24 + * then we should ignore it + */ + + grp_addr.s_addr = ntohl(grp.s_addr); + + if (pim_is_group_224_0_0_0_24(grp_addr)) { + if (PIM_DEBUG_IGMP_PACKETS) { + zlog_debug( + "Ignoring IGMPv3 group record %pI4 from %s on %s group range falls in 224.0.0.0/24", + &grp.s_addr, from_str, ifp->name); + } + return false; + } + + /* + * RFC 4604 + * section 2.2.1 + * EXCLUDE mode does not apply to SSM addresses, and an SSM-aware router + * will ignore MODE_IS_EXCLUDE and CHANGE_TO_EXCLUDE_MODE requests in + * the SSM range. + */ + if (pim_is_grp_ssm(pim_ifp->pim, grp)) { + switch (rec_type) { + case IGMP_GRP_REC_TYPE_MODE_IS_EXCLUDE: + case IGMP_GRP_REC_TYPE_CHANGE_TO_EXCLUDE_MODE: + if (PIM_DEBUG_IGMP_PACKETS) { + zlog_debug( + "Ignoring IGMPv3 group record %pI4 from %s on %s exclude mode in SSM range", + &grp.s_addr, from_str, ifp->name); + } + return false; + } + } + + return true; +} + int igmp_v3_recv_report(struct gm_sock *igmp, struct in_addr from, const char *from_str, char *igmp_msg, int igmp_msg_len) { @@ -1828,14 +1887,10 @@ int igmp_v3_recv_report(struct gm_sock *igmp, struct in_addr from, uint8_t *report_pastend = (uint8_t *)igmp_msg + igmp_msg_len; struct interface *ifp = igmp->interface; int i; - int local_ncb = 0; - struct pim_interface *pim_ifp; if (igmp->mtrace_only) return 0; - pim_ifp = igmp->interface->info; - if (igmp_msg_len < IGMP_V3_MSG_MIN_SIZE) { zlog_warn( "Recv IGMP report v3 from %s on %s: size=%d shorter than minimum=%d", @@ -1880,9 +1935,6 @@ int igmp_v3_recv_report(struct gm_sock *igmp, struct in_addr from, int rec_auxdatalen; int rec_num_sources; int j; - struct prefix lncb; - struct prefix g; - bool filtered = false; if ((group_record + IGMP_V3_GROUP_RECORD_MIN_SIZE) > report_pastend) { @@ -1940,31 +1992,7 @@ int igmp_v3_recv_report(struct gm_sock *igmp, struct in_addr from, } /* for (sources) */ - lncb.family = AF_INET; - lncb.u.prefix4.s_addr = 0x000000E0; - lncb.prefixlen = 24; - - g.family = AF_INET; - g.u.prefix4 = rec_group; - g.prefixlen = IPV4_MAX_BITLEN; - - /* determine filtering status for group */ - filtered = pim_is_group_filtered(ifp->info, &rec_group); - - if (PIM_DEBUG_IGMP_PACKETS && filtered) - zlog_debug( - "Filtering IGMPv3 group record %pI4 from %s on %s per prefix-list %s", - &rec_group, from_str, ifp->name, - pim_ifp->boundary_oil_plist); - - /* - * If we receive a igmp report with the group in 224.0.0.0/24 - * then we should ignore it - */ - if (prefix_match(&lncb, &g)) - local_ncb = 1; - - if (!local_ncb && !filtered) + if (igmp_pkt_grp_addr_ok(ifp, from_str, rec_group, rec_type)) switch (rec_type) { case IGMP_GRP_REC_TYPE_MODE_IS_INCLUDE: igmpv3_report_isin(igmp, from, rec_group, @@ -2004,7 +2032,6 @@ int igmp_v3_recv_report(struct gm_sock *igmp, struct in_addr from, group_record += 8 + (rec_num_sources << 2) + (rec_auxdatalen << 2); - local_ncb = 0; } /* for (group records) */ diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 24833f5a63..571117ac0a 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -178,6 +178,14 @@ static void upstream_channel_oil_detach(struct pim_upstream *up) } +static void pim_upstream_timers_stop(struct pim_upstream *up) +{ + THREAD_OFF(up->t_ka_timer); + THREAD_OFF(up->t_rs_timer); + THREAD_OFF(up->t_msdp_reg_timer); + THREAD_OFF(up->t_join_timer); +} + struct pim_upstream *pim_upstream_del(struct pim_instance *pim, struct pim_upstream *up, const char *name) { @@ -207,9 +215,7 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim, if (pim_up_mlag_is_local(up)) pim_mlag_up_local_del(pim, up); - THREAD_OFF(up->t_ka_timer); - THREAD_OFF(up->t_rs_timer); - THREAD_OFF(up->t_msdp_reg_timer); + pim_upstream_timers_stop(up); if (up->join_state == PIM_UPSTREAM_JOINED) { pim_jp_agg_single_upstream_send(&up->rpf, up, 0); @@ -1945,6 +1951,7 @@ void pim_upstream_terminate(struct pim_instance *pim) while ((up = rb_pim_upstream_first(&pim->upstream_head))) { pim_upstream_del(pim, up, __func__); + pim_upstream_timers_stop(up); } rb_pim_upstream_fini(&pim->upstream_head); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index d01d8158de..676b92d429 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -826,8 +826,7 @@ static int zvni_map_to_svi_ns(struct ns *ns, struct interface **p_ifp = (struct interface **)_p_ifp; struct zebra_if *zif; - if (!in_param) - return NS_WALK_STOP; + assert(in_param && p_ifp); /* TODO: Optimize with a hash. */ for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { @@ -842,8 +841,7 @@ static int zvni_map_to_svi_ns(struct ns *ns, vl = (struct zebra_l2info_vlan *)&zif->l2info.vl; if (vl->vid == in_param->vid) { - if (p_ifp) - *p_ifp = tmp_if; + *p_ifp = tmp_if; return NS_WALK_STOP; } } |
