diff options
| -rw-r--r-- | pimd/pim_cmd.c | 45 | ||||
| -rw-r--r-- | pimd/pim_igmp.c | 36 | ||||
| -rw-r--r-- | pimd/pim_instance.h | 2 | ||||
| -rw-r--r-- | pimd/pim_vty.c | 7 | 
4 files changed, 88 insertions, 2 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 0c14aff9ff..2958f720e7 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3419,11 +3419,19 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj)  	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) { @@ -6861,6 +6869,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", @@ -10893,6 +10930,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;  | 
