diff options
| -rw-r--r-- | doc/user/pim.rst | 13 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 120 | ||||
| -rw-r--r-- | pimd/pim_cmd.h | 2 | ||||
| -rw-r--r-- | pimd/pim_iface.c | 2 | ||||
| -rw-r--r-- | pimd/pim_iface.h | 10 | ||||
| -rw-r--r-- | pimd/pim_igmpv3.c | 16 | ||||
| -rw-r--r-- | pimd/pim_vty.c | 18 | 
7 files changed, 171 insertions, 10 deletions
diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 5148d3baff..a89730f7ad 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -218,6 +218,19 @@ is in a vrf, enter the interface command with the vrf keyword at the end.     or IGMP report is received on this interface and the Group is denied by the     prefix-list, PIM will ignore the join or report. +.. index:: ip igmp last-member-query-count (1-7) +.. clicmd:: ip igmp last-member-query-count (1-7) + +   Set the IGMP last member query count. The default value is 2. 'no' form of +   this command is used to to configure back to the default value. + +.. index:: ip igmp last-member-query-interval (1-255) +.. clicmd:: ip igmp last-member-query-interval (1-255) + +   Set the IGMP last member query interval in deciseconds. The default value is +   10 deciseconds. 'no' form of this command is used to to configure back to the +   default value. +  .. _pim-multicast-rib-insertion:  PIM Multicast RIB insertion: diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index cb2ba87ec6..cbbbe0234d 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -657,6 +657,7 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,  	long oqpi_msec; /* Other Querier Present Interval */  	long qri_msec;  	time_t now; +	int lmqc;  	json_object *json = NULL;  	json_object *json_row = NULL; @@ -701,8 +702,8 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,  				pim_ifp->igmp_query_max_response_time_dsec);  			lmqt_msec = PIM_IGMP_LMQT_MSEC( -				pim_ifp->igmp_query_max_response_time_dsec, -				igmp->querier_robustness_variable); +				pim_ifp->igmp_specific_query_max_response_time_dsec, +				pim_ifp->igmp_last_member_query_count);  			ohpi_msec =  				PIM_IGMP_OHPI_DSEC( @@ -718,6 +719,7 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,  					pim_ifp->pim_sock_fd);  			else  				mloop = 0; +			lmqc = pim_ifp->igmp_last_member_query_count;  			if (uj) {  				json_row = json_object_new_object(); @@ -743,6 +745,9 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,  					"timerGroupMembershipIntervalMsec",  					gmi_msec);  				json_object_int_add(json_row, +						    "lastMemberQueryCount", +						    lmqc); +				json_object_int_add(json_row,  						    "timerLastMemberQueryMsec",  						    lmqt_msec);  				json_object_int_add( @@ -809,6 +814,9 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,  					"Group Membership Interval      : %lis\n",  					gmi_msec / 1000);  				vty_out(vty, +					"Last Member Query Count        : %d\n", +					lmqc); +				vty_out(vty,  					"Last Member Query Time         : %lis\n",  					lmqt_msec / 1000);  				vty_out(vty, @@ -6455,6 +6463,106 @@ DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,  	return CMD_SUCCESS;  } +#define IGMP_LAST_MEMBER_QUERY_COUNT_MIN (1) +#define IGMP_LAST_MEMBER_QUERY_COUNT_MAX (7) + +DEFUN (interface_ip_igmp_last_member_query_count, +       interface_ip_igmp_last_member_query_count_cmd, +       "ip igmp last-member-query-count (1-7)", +       IP_STR +       IFACE_IGMP_STR +       IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR +       "Last member query count\n") +{ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct pim_interface *pim_ifp = ifp->info; +	int last_member_query_count; +	int ret; + +	if (!pim_ifp) { +		ret = pim_cmd_igmp_start(vty, ifp); +		if (ret != CMD_SUCCESS) +			return ret; +		pim_ifp = ifp->info; +	} + +	last_member_query_count = atoi(argv[3]->arg); + +	pim_ifp->igmp_last_member_query_count = last_member_query_count; + +	return CMD_SUCCESS; +} + +DEFUN (interface_no_ip_igmp_last_member_query_count, +       interface_no_ip_igmp_last_member_query_count_cmd, +       "no ip igmp last-member-query-count", +       NO_STR +       IP_STR +       IFACE_IGMP_STR +       IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR) +{ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct pim_interface *pim_ifp = ifp->info; + +	if (!pim_ifp) +		return CMD_SUCCESS; + +	pim_ifp->igmp_last_member_query_count = +		IGMP_DEFAULT_ROBUSTNESS_VARIABLE; + +	return CMD_SUCCESS; +} + +#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MIN (1) +#define IGMP_LAST_MEMBER_QUERY_INTERVAL_MAX (255) + +DEFUN (interface_ip_igmp_last_member_query_interval, +       interface_ip_igmp_last_member_query_interval_cmd, +       "ip igmp last-member-query-interval (1-255)", +       IP_STR +       IFACE_IGMP_STR +       IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR +       "Last member query interval in deciseconds\n") +{ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct pim_interface *pim_ifp = ifp->info; +	int last_member_query_interval; +	int ret; + +	if (!pim_ifp) { +		ret = pim_cmd_igmp_start(vty, ifp); +		if (ret != CMD_SUCCESS) +			return ret; +		pim_ifp = ifp->info; +	} + +	last_member_query_interval = atoi(argv[3]->arg); +	pim_ifp->igmp_specific_query_max_response_time_dsec +		= last_member_query_interval; + +	return CMD_SUCCESS; +} + +DEFUN (interface_no_ip_igmp_last_member_query_interval, +       interface_no_ip_igmp_last_member_query_interval_cmd, +       "no ip igmp last-member-query-interval", +       NO_STR +       IP_STR +       IFACE_IGMP_STR +       IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR) +{ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct pim_interface *pim_ifp = ifp->info; + +	if (!pim_ifp) +		return CMD_SUCCESS; + +	pim_ifp->igmp_specific_query_max_response_time_dsec = +		IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC; + +	return CMD_SUCCESS; +} +  DEFUN (interface_ip_pim_drprio,         interface_ip_pim_drprio_cmd,         "ip pim drpriority (1-4294967295)", @@ -9296,6 +9404,14 @@ void pim_cmd_init(void)  			&interface_ip_igmp_query_max_response_time_dsec_cmd);  	install_element(INTERFACE_NODE,  			&interface_no_ip_igmp_query_max_response_time_dsec_cmd); +	install_element(INTERFACE_NODE, +			&interface_ip_igmp_last_member_query_count_cmd); +	install_element(INTERFACE_NODE, +			&interface_no_ip_igmp_last_member_query_count_cmd); +	install_element(INTERFACE_NODE, +			&interface_ip_igmp_last_member_query_interval_cmd); +	install_element(INTERFACE_NODE, +			&interface_no_ip_igmp_last_member_query_interval_cmd);  	install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd);  	install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd);  	install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd); diff --git a/pimd/pim_cmd.h b/pimd/pim_cmd.h index 67d6e43c34..0bbd003f95 100644 --- a/pimd/pim_cmd.h +++ b/pimd/pim_cmd.h @@ -35,6 +35,8 @@  #define IFACE_IGMP_QUERY_INTERVAL_STR          "IGMP host query interval\n"  #define IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_STR      "IGMP max query response value (seconds)\n"  #define IFACE_IGMP_QUERY_MAX_RESPONSE_TIME_DSEC_STR "IGMP max query response value (deciseconds)\n" +#define IFACE_IGMP_LAST_MEMBER_QUERY_INTERVAL_STR   "IGMP last member query interval\n" +#define IFACE_IGMP_LAST_MEMBER_QUERY_COUNT_STR      "IGMP last member query count\n"  #define DEBUG_IGMP_STR                              "IGMP protocol activity\n"  #define DEBUG_IGMP_EVENTS_STR                       "IGMP protocol events\n"  #define DEBUG_IGMP_PACKETS_STR                      "IGMP protocol packets\n" diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 0fb7f176ce..74fb6424bc 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -131,6 +131,8 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim,  		IGMP_QUERY_MAX_RESPONSE_TIME_DSEC;  	pim_ifp->igmp_specific_query_max_response_time_dsec =  		IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC; +	pim_ifp->igmp_last_member_query_count = +		IGMP_DEFAULT_ROBUSTNESS_VARIABLE;  	/*  	  RFC 3376: 8.3. Query Response Interval diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index fe96c07758..8bf829470e 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -88,8 +88,14 @@ struct pim_interface {  	int igmp_query_max_response_time_dsec; /* IGMPv3 Max Response Time in  						  dsecs for general queries */  	int igmp_specific_query_max_response_time_dsec; /* IGMPv3 Max Response -							   Time in dsecs for -							   specific queries */ +							   Time in dsecs called +							   as last member query +							   interval, defines the +							   maximum response time +							   advertised in IGMP +							   group-specific +							   queries */ +	int igmp_last_member_query_count; /* IGMP last member query count */  	struct list *igmp_socket_list; /* list of struct igmp_sock */  	struct list *igmp_join_list;   /* list of struct igmp_join */ diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index b845f54f06..bc0460fa03 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -997,7 +997,7 @@ static void group_retransmit_group(struct igmp_group *group)  	char query_buf[query_buf_size]; -	lmqc = igmp->querier_robustness_variable; +	lmqc = pim_ifp->igmp_last_member_query_count;  	lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;  	lmqt_msec = lmqc * lmqi_msec; @@ -1076,7 +1076,7 @@ static int group_retransmit_sources(struct igmp_group *group,  	igmp = group->group_igmp_sock;  	pim_ifp = igmp->interface->info; -	lmqc = igmp->querier_robustness_variable; +	lmqc = pim_ifp->igmp_last_member_query_count;  	lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;  	lmqt_msec = lmqc * lmqi_msec; @@ -1314,9 +1314,13 @@ 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 */ -	lmqc = group->group_igmp_sock->querier_robustness_variable; +	igmp = group->group_igmp_sock; +	pim_ifp = igmp->interface->info; +	lmqc = pim_ifp->igmp_last_member_query_count;  	/* lower group timer to lmqt */  	igmp_group_timer_lower_to_lmqt(group); @@ -1351,7 +1355,7 @@ static void source_query_send_by_flag(struct igmp_group *group,  	igmp = group->group_igmp_sock;  	pim_ifp = igmp->interface->info; -	lmqc = igmp->querier_robustness_variable; +	lmqc = pim_ifp->igmp_last_member_query_count;  	lmqi_msec = 100 * pim_ifp->igmp_specific_query_max_response_time_dsec;  	lmqt_msec = lmqc * lmqi_msec; @@ -1509,7 +1513,7 @@ void igmp_group_timer_lower_to_lmqt(struct igmp_group *group)  	ifname = ifp->name;  	lmqi_dsec = pim_ifp->igmp_specific_query_max_response_time_dsec; -	lmqc = igmp->querier_robustness_variable; +	lmqc = pim_ifp->igmp_last_member_query_count;  	lmqt_msec = PIM_IGMP_LMQT_MSEC(  		lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */ @@ -1546,7 +1550,7 @@ void igmp_source_timer_lower_to_lmqt(struct igmp_source *source)  	ifname = ifp->name;  	lmqi_dsec = pim_ifp->igmp_specific_query_max_response_time_dsec; -	lmqc = igmp->querier_robustness_variable; +	lmqc = pim_ifp->igmp_last_member_query_count;  	lmqt_msec = PIM_IGMP_LMQT_MSEC(  		lmqi_dsec, lmqc); /* lmqt_msec = (100 * lmqi_dsec) * lmqc */ diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 2654ebc588..e5587503b6 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -344,6 +344,24 @@ int pim_interface_config_write(struct vty *vty)  					++writes;  				} +				/* IF ip igmp last-member_query-count */ +				if (pim_ifp->igmp_last_member_query_count +				    != IGMP_DEFAULT_ROBUSTNESS_VARIABLE) { +					vty_out(vty, +						" ip igmp last-member-query-count %d\n", +						pim_ifp->igmp_last_member_query_count); +					++writes; +				} + +				/* IF ip igmp last-member_query-interval */ +				if (pim_ifp->igmp_specific_query_max_response_time_dsec +				    != IGMP_SPECIFIC_QUERY_MAX_RESPONSE_TIME_DSEC) { +					vty_out(vty, +						" ip igmp last-member-query-interval %d\n", +						pim_ifp->igmp_specific_query_max_response_time_dsec); +					  ++writes; +				} +  				/* IF ip igmp join */  				if (pim_ifp->igmp_join_list) {  					struct listnode *node;  | 
