summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/wheel.c1
-rw-r--r--pimd/pim_cmd.c38
-rw-r--r--pimd/pim_igmp_stats.c3
-rw-r--r--pimd/pim_igmp_stats.h1
-rw-r--r--pimd/pim_igmpv2.c21
-rw-r--r--pimd/pim_igmpv3.c93
-rw-r--r--pimd/pim_upstream.c13
-rw-r--r--zebra/zebra_vxlan.c6
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;
}
}