summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2020-04-21 16:14:21 -0400
committerGitHub <noreply@github.com>2020-04-21 16:14:21 -0400
commitbda96cdd33efe766703d7428a08ecf15e619996f (patch)
tree3a30bc3a335abb9e048cbd6eed9e7746c70dfb34
parent64fbc17e510d0b5e1ce3674a04f74c5145765b2b (diff)
parentdaeda8dd5770a0afa17f3384d76ed2becb7ec5d9 (diff)
Merge pull request #6126 from sarav511/watermark
pimd: Implement watermark warning for igmp group count and add igmp group count
-rw-r--r--doc/user/pim.rst8
-rw-r--r--pimd/pim_cmd.c85
-rw-r--r--pimd/pim_igmp.c36
-rw-r--r--pimd/pim_instance.h2
-rw-r--r--pimd/pim_vty.c7
5 files changed, 120 insertions, 18 deletions
diff --git a/doc/user/pim.rst b/doc/user/pim.rst
index f0ec2d26ff..2944e0b705 100644
--- a/doc/user/pim.rst
+++ b/doc/user/pim.rst
@@ -178,6 +178,14 @@ Certain signals have special meanings to *pimd*.
the existing IGMP general query timer.If no version is provided in the cli,
it will be considered as default v2 query.This is a hidden command.
+.. index:: [no] ip igmp watermark-warn (10-60000)
+.. clicmd:: [no] ip igmp watermark-warn (10-60000)
+
+ Configure watermark warning generation for an igmp group limit. Generates
+ warning once the configured group limit is reached while adding new groups.
+ 'no' form of the command disables the warning generation. This command is
+ vrf aware. To configure per vrf, enter vrf submode.
+
.. _pim-interface-configuration:
PIM Interface Configuration
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index f99888b3af..f6af98598b 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -3419,15 +3419,24 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
time_t now;
json_object *json = NULL;
json_object *json_iface = NULL;
- json_object *json_row = NULL;
+ json_object *json_group = NULL;
+ json_object *json_groups = NULL;
now = pim_time_monotonic_sec();
- if (uj)
+ if (uj) {
json = json_object_new_object();
- else
+ json_object_int_add(json, "totalGroups", pim->igmp_group_count);
+ json_object_int_add(json, "watermarkLimit",
+ pim->igmp_watermark_limit);
+ } else {
+ vty_out(vty, "Total IGMP groups: %u\n", pim->igmp_group_count);
+ vty_out(vty, "Watermark warn limit(%s): %u\n",
+ pim->igmp_watermark_limit ? "Set" : "Not Set",
+ pim->igmp_watermark_limit);
vty_out(vty,
"Interface Address Group Mode Timer Srcs V Uptime \n");
+ }
/* scan interfaces */
FOR_ALL_INTERFACES (pim->vrf, ifp) {
@@ -3474,37 +3483,44 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)
json_object_object_add(
json, ifp->name,
json_iface);
+ json_groups =
+ json_object_new_array();
+ json_object_object_add(
+ json_iface,
+ "groups",
+ json_groups);
}
- json_row = json_object_new_object();
- json_object_string_add(
- json_row, "source", ifaddr_str);
- json_object_string_add(
- json_row, "group", group_str);
+ 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_row, "mode",
+ json_group, "mode",
grp->group_filtermode_isexcl
? "EXCLUDE"
: "INCLUDE");
- json_object_string_add(json_row,
+ json_object_string_add(json_group,
"timer", hhmmss);
json_object_int_add(
- json_row, "sourcesCount",
+ json_group, "sourcesCount",
grp->group_source_list
? listcount(
grp->group_source_list)
: 0);
- json_object_int_add(json_row, "version",
- grp->igmp_version);
+ json_object_int_add(
+ json_group, "version",
+ grp->igmp_version);
json_object_string_add(
- json_row, "uptime", uptime);
- json_object_object_add(json_iface,
- group_str,
- json_row);
-
+ 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",
@@ -6865,6 +6881,35 @@ DEFUN (no_ip_pim_packets,
return CMD_SUCCESS;
}
+DEFPY (igmp_group_watermark,
+ igmp_group_watermark_cmd,
+ "ip igmp watermark-warn (10-60000)$limit",
+ IP_STR
+ IGMP_STR
+ "Configure group limit for watermark warning\n"
+ "Group count to generate watermark warning\n")
+{
+ PIM_DECLVAR_CONTEXT(vrf, pim);
+ pim->igmp_watermark_limit = limit;
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (no_igmp_group_watermark,
+ no_igmp_group_watermark_cmd,
+ "no ip igmp watermark-warn [(10-60000)$limit]",
+ NO_STR
+ IP_STR
+ IGMP_STR
+ "Unconfigure group limit for watermark warning\n"
+ "Group count to generate watermark warning\n")
+{
+ PIM_DECLVAR_CONTEXT(vrf, pim);
+ pim->igmp_watermark_limit = 0;
+
+ return CMD_SUCCESS;
+}
+
DEFUN (ip_pim_v6_secondary,
ip_pim_v6_secondary_cmd,
"ip pim send-v6-secondary",
@@ -10910,6 +10955,10 @@ void pim_cmd_init(void)
install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd);
install_element(CONFIG_NODE, &ip_pim_mlag_cmd);
install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd);
+ install_element(CONFIG_NODE, &igmp_group_watermark_cmd);
+ install_element(VRF_NODE, &igmp_group_watermark_cmd);
+ install_element(CONFIG_NODE, &no_igmp_group_watermark_cmd);
+ install_element(VRF_NODE, &no_igmp_group_watermark_cmd);
install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c
index 8d39d7e800..461c2698d5 100644
--- a/pimd/pim_igmp.c
+++ b/pimd/pim_igmp.c
@@ -753,6 +753,39 @@ 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)
+{
+ 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) {
+ zlog_warn(
+ "IGMP group count reached watermark limit: %u(vrf: %s)",
+ pim_ifp->pim->igmp_group_count,
+ VRF_LOGNAME(pim_ifp->pim->vrf));
+ }
+}
+
+static void igmp_group_count_decr(struct igmp_sock *igmp)
+{
+ 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));
+ return;
+ }
+
+ --pim_ifp->pim->igmp_group_count;
+}
+
void igmp_group_delete(struct igmp_group *group)
{
struct listnode *src_node;
@@ -778,6 +811,7 @@ void igmp_group_delete(struct igmp_group *group)
}
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);
@@ -1158,6 +1192,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
group_str, igmp->fd, igmp->interface->name);
}
+ igmp_group_count_incr(igmp);
+
/*
RFC 3376: 6.2.2. Definition of Group Timers
diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h
index 71bd7c1089..2b76da21b2 100644
--- a/pimd/pim_instance.h
+++ b/pimd/pim_instance.h
@@ -178,6 +178,8 @@ struct pim_instance {
struct list *ssmpingd_list;
struct in_addr ssmpingd_group_addr;
+ unsigned int igmp_group_count;
+ unsigned int igmp_watermark_limit;
unsigned int keep_alive_time;
unsigned int rp_keep_alive_time;
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index 72540903be..fee8d6ed1b 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -239,6 +239,13 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
vty_out(vty, "%sip pim ecmp\n", spaces);
++writes;
}
+
+ if (pim->igmp_watermark_limit != 0) {
+ vty_out(vty, "%sip igmp watermark-warn %u\n", spaces,
+ pim->igmp_watermark_limit);
+ ++writes;
+ }
+
if (pim->ssmpingd_list) {
struct listnode *node;
struct ssmpingd_sock *ss;