diff options
| -rw-r--r-- | yang/frr-zebra.yang | 68 | ||||
| -rw-r--r-- | zebra/rtadv.c | 208 | ||||
| -rw-r--r-- | zebra/rtadv.h | 1 | ||||
| -rw-r--r-- | zebra/zebra_nb.c | 13 | ||||
| -rw-r--r-- | zebra/zebra_nb.h | 6 | ||||
| -rw-r--r-- | zebra/zebra_nb_config.c | 60 | 
6 files changed, 206 insertions, 150 deletions
diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index fd263406f3..054192bb16 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -2278,6 +2278,74 @@ module frr-zebra {              "RFC 4861: Neighbor Discovery for IP version 6 (IPv6)                         - AdvSendAdvertisements";          } +        leaf max-rtr-adv-interval { +          type uint32 { +            range "70..1800000"; +          } +          units "milliseconds"; +          default "600000"; +          description +            "The maximum time allowed between sending unsolicited +            multicast Router Advertisements from the interface."; +          reference +            "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) +                       - MaxRtrAdvInterval +             RFC 6275: Mobility Support in IPv6"; +        } +        // Setting this value is not yet supported by the actual code. +        /* +        leaf min-rtr-adv-interval { +          type uint32 { +            range "30..1350000"; +          } +          units "milliseconds"; +          must ". <= 0.75 * ../max-rtr-adv-interval" { +            description +              "The value MUST NOT be greater than 75% of +              'max-rtr-adv-interval'."; +          } +          description +            "The minimum time allowed between sending unsolicited +            multicast Router Advertisements from the interface. + +            The default value to be used operationally if this +            leaf is not configured is determined as follows: + +            - if max-rtr-adv-interval >= 9 seconds, the default +              value is 0.33 * max-rtr-adv-interval; + +            - otherwise, it is 0.75 * max-rtr-adv-interval."; +          reference +            "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) +                       - MaxRtrAdvInterval +             RFC 6275: Mobility Support in IPv6"; +        } +        */ +        leaf default-lifetime { +          type uint16 { +            range "0..9000"; +          } +          units "seconds"; +          must ". = 0 or . * 1000 >= ../max-rtr-adv-interval" { +            description +              "The value MUST NOT be less than max-rtr-adv-interval."; +          } +          description +            "The value to be placed in the Router Lifetime field of +            Router Advertisements sent from the interface, in +            seconds.  It MUST be either zero or between +            max-rtr-adv-interval and 9000 seconds.  A value of zero +            indicates that the router is not to be used as a +            default router.  These limits may be overridden by +            specific documents that describe how IPv6 operates over +            different link layers. + +            If this parameter is not configured, the device SHOULD +            use a value of 3 * max-rtr-adv-interval."; +          reference +            "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) +                       - AdvDefaultLifetime"; +        }        }        container state {          config false; diff --git a/zebra/rtadv.c b/zebra/rtadv.c index f6d3ec40d0..fb8ebae550 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -1298,6 +1298,36 @@ void ipv6_nd_suppress_ra_set(struct interface *ifp,  	}  } +void ipv6_nd_interval_set(struct interface *ifp, uint32_t interval) +{ +	struct zebra_if *zif = ifp->info; +	struct zebra_vrf *zvrf = rtadv_interface_get_zvrf(ifp); +	struct adv_if *adv_if; + +	if (zif->rtadv.MaxRtrAdvInterval % 1000) { +		adv_if = adv_msec_if_del(zvrf, ifp->name); +		if (adv_if != NULL) +			adv_if_free(adv_if); +	} + +	if (interval % 1000) +		(void)adv_msec_if_add(zvrf, ifp->name); + +	zif->rtadv.MaxRtrAdvInterval = interval; +	zif->rtadv.MinRtrAdvInterval = 0.33 * interval; + +	if (interval != RTADV_MAX_RTR_ADV_INTERVAL) { +		SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); +		zif->rtadv.AdvIntervalTimer = 0; +	} else { +		if (CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED)) +			zif->rtadv.MaxRtrAdvInterval = 10000; + +		UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); +		zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; +	} +} +  /*   * Handle client (BGP) message to enable or disable IPv6 RA on an interface.   * Note that while the client could request RA on an interface on which the @@ -1652,173 +1682,54 @@ DEFPY_YANG (ipv6_nd_suppress_ra,  	return nb_cli_apply_changes(vty, NULL);  } -DEFUN (ipv6_nd_ra_interval_msec, -       ipv6_nd_ra_interval_msec_cmd, -       "ipv6 nd ra-interval msec (70-1800000)", -       "Interface IPv6 config commands\n" -       "Neighbor discovery\n" -       "Router Advertisement interval\n" -       "Router Advertisement interval in milliseconds\n" -       "Router Advertisement interval in milliseconds\n") -{ -	int idx_number = 4; -	VTY_DECLVAR_CONTEXT(interface, ifp); -	unsigned interval; -	struct zebra_if *zif = ifp->info; -	struct zebra_vrf *zvrf; -	struct adv_if *adv_if; - -	zvrf = rtadv_interface_get_zvrf(ifp); - -	interval = strtoul(argv[idx_number]->arg, NULL, 10); -	if ((zif->rtadv.AdvDefaultLifetime != -1 -	     && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) { -		vty_out(vty, -			"This ra-interval would conflict with configured ra-lifetime!\n"); -		return CMD_WARNING_CONFIG_FAILED; -	} - -	if (zif->rtadv.MaxRtrAdvInterval % 1000) { -		adv_if = adv_msec_if_del(zvrf, ifp->name); -		if (adv_if != NULL) -			adv_if_free(adv_if); -	} - -	if (interval % 1000) -		(void)adv_msec_if_add(zvrf, ifp->name); - -	SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); -	zif->rtadv.MaxRtrAdvInterval = interval; -	zif->rtadv.MinRtrAdvInterval = 0.33 * interval; -	zif->rtadv.AdvIntervalTimer = 0; - -	return CMD_SUCCESS; -} - -DEFUN (ipv6_nd_ra_interval, +DEFPY_YANG (ipv6_nd_ra_interval,         ipv6_nd_ra_interval_cmd, -       "ipv6 nd ra-interval (1-1800)", -       "Interface IPv6 config commands\n" -       "Neighbor discovery\n" -       "Router Advertisement interval\n" -       "Router Advertisement interval in seconds\n") -{ -	int idx_number = 3; -	VTY_DECLVAR_CONTEXT(interface, ifp); -	unsigned interval; -	struct zebra_if *zif = ifp->info; -	struct zebra_vrf *zvrf; -	struct adv_if *adv_if; - -	zvrf = rtadv_interface_get_zvrf(ifp); - -	interval = strtoul(argv[idx_number]->arg, NULL, 10); -	if ((zif->rtadv.AdvDefaultLifetime != -1 -	     && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) { -		vty_out(vty, -			"This ra-interval would conflict with configured ra-lifetime!\n"); -		return CMD_WARNING_CONFIG_FAILED; -	} - -	if (zif->rtadv.MaxRtrAdvInterval % 1000) { -		adv_if = adv_msec_if_del(zvrf, ifp->name); -		if (adv_if != NULL) -			adv_if_free(adv_if); -	} - -	/* convert to milliseconds */ -	interval = interval * 1000; - -	SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); -	zif->rtadv.MaxRtrAdvInterval = interval; -	zif->rtadv.MinRtrAdvInterval = 0.33 * interval; -	zif->rtadv.AdvIntervalTimer = 0; - -	return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_ra_interval, -       no_ipv6_nd_ra_interval_cmd, -       "no ipv6 nd ra-interval [<(1-1800)|msec (1-1800000)>]", +       "[no] ipv6 nd ra-interval ![<(1-1800)$sec|msec (70-1800000)$msec>]",         NO_STR         "Interface IPv6 config commands\n"         "Neighbor discovery\n"         "Router Advertisement interval\n"         "Router Advertisement interval in seconds\n" -       "Specify millisecond router advertisement interval\n" +       "Router Advertisement interval in milliseconds\n"         "Router Advertisement interval in milliseconds\n")  { -	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zif = ifp->info; -	struct zebra_vrf *zvrf = NULL; -	struct adv_if *adv_if; +	char value[YANG_VALUE_MAXLEN]; -	zvrf = rtadv_interface_get_zvrf(ifp); +	if (!no) { +		if (sec) +			snprintf(value, sizeof(value), "%lu", sec * 1000); +		else +			snprintf(value, sizeof(value), "%lu", msec); -	if (zif->rtadv.MaxRtrAdvInterval % 1000) { -		adv_if = adv_msec_if_del(zvrf, ifp->name); -		if (adv_if != NULL) -			adv_if_free(adv_if); +		nb_cli_enqueue_change(vty, +				      "./frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval", +				      NB_OP_MODIFY, value); +	} else { +		nb_cli_enqueue_change(vty, +				      "./frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval", +				      NB_OP_DESTROY, NULL);  	} - -	UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); - -	if (CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED)) -		zif->rtadv.MaxRtrAdvInterval = 10000; -	else -		zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL; - -	zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval; -	zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL; - -	return CMD_SUCCESS; +	return nb_cli_apply_changes(vty, NULL);  } -DEFUN (ipv6_nd_ra_lifetime, +DEFPY_YANG (ipv6_nd_ra_lifetime,         ipv6_nd_ra_lifetime_cmd, -       "ipv6 nd ra-lifetime (0-9000)", -       "Interface IPv6 config commands\n" -       "Neighbor discovery\n" -       "Router lifetime\n" -       "Router lifetime in seconds (0 stands for a non-default gw)\n") -{ -	int idx_number = 3; -	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zif = ifp->info; -	int lifetime; - -	lifetime = strtoul(argv[idx_number]->arg, NULL, 10); - -	/* The value to be placed in the Router Lifetime field -	 * of Router Advertisements sent from the interface, -	 * in seconds.  MUST be either zero or between -	 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */ -	if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval)) { -		vty_out(vty, -			"This ra-lifetime would conflict with configured ra-interval\n"); -		return CMD_WARNING_CONFIG_FAILED; -	} - -	zif->rtadv.AdvDefaultLifetime = lifetime; - -	return CMD_SUCCESS; -} - -DEFUN (no_ipv6_nd_ra_lifetime, -       no_ipv6_nd_ra_lifetime_cmd, -       "no ipv6 nd ra-lifetime [(0-9000)]", +       "[no] ipv6 nd ra-lifetime ![(0-9000)$lifetime]",         NO_STR         "Interface IPv6 config commands\n"         "Neighbor discovery\n"         "Router lifetime\n"         "Router lifetime in seconds (0 stands for a non-default gw)\n")  { -	VTY_DECLVAR_CONTEXT(interface, ifp); -	struct zebra_if *zif = ifp->info; - -	zif->rtadv.AdvDefaultLifetime = -1; - -	return CMD_SUCCESS; +	if (!no) +		nb_cli_enqueue_change(vty, +				      "./frr-zebra:zebra/ipv6-router-advertisements/default-lifetime", +				      NB_OP_MODIFY, lifetime_str); +	else +		nb_cli_enqueue_change(vty, +				      "./frr-zebra:zebra/ipv6-router-advertisements/default-lifetime", +				      NB_OP_DESTROY, NULL); +	return nb_cli_apply_changes(vty, NULL);  }  DEFUN (ipv6_nd_reachable_time, @@ -2904,10 +2815,7 @@ void rtadv_cmd_init(void)  	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_hop_limit_cmd);  	install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);  	install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd); -	install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd); -	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);  	install_element(INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd); -	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);  	install_element(INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);  	install_element(INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);  	install_element(INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd); diff --git a/zebra/rtadv.h b/zebra/rtadv.h index 79abe5f7e0..14a54435b0 100644 --- a/zebra/rtadv.h +++ b/zebra/rtadv.h @@ -387,6 +387,7 @@ extern void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p);  void ipv6_nd_suppress_ra_set(struct interface *ifp,  			     enum ipv6_nd_suppress_ra_status status); +void ipv6_nd_interval_set(struct interface *ifp, uint32_t interval);  #else /* !HAVE_RTADV */  struct rtadv { diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c index 87cfab5469..82aebda8ae 100644 --- a/zebra/zebra_nb.c +++ b/zebra/zebra_nb.c @@ -553,6 +553,19 @@ const struct frr_yang_module_info frr_zebra_info = {  			}  		},  		{ +			.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval", +			.cbs = { +				.modify = lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify, +			} +		}, +		{ +			.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-lifetime", +			.cbs = { +				.modify = lib_interface_zebra_ipv6_router_advertisements_default_lifetime_modify, +				.destroy = lib_interface_zebra_ipv6_router_advertisements_default_lifetime_destroy, +			} +		}, +		{  			.xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/up-count",  			.cbs = {  				.get_elem = lib_interface_zebra_state_up_count_get_elem, diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h index f45270f7b4..a7b6797b63 100644 --- a/zebra/zebra_nb.h +++ b/zebra/zebra_nb.h @@ -183,6 +183,12 @@ int lib_interface_zebra_evpn_mh_bypass_modify(struct nb_cb_modify_args *args);  int lib_interface_zebra_evpn_mh_uplink_modify(struct nb_cb_modify_args *args);  int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify(  	struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify( +	struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_modify( +	struct nb_cb_modify_args *args); +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_destroy( +	struct nb_cb_destroy_args *args);  struct yang_data *  lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args);  struct yang_data * diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index d13a75866f..f0d4faaf84 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -2486,6 +2486,66 @@ int lib_interface_zebra_ipv6_router_advertisements_send_advertisements_modify(  }  /* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/max-rtr-adv-interval + */ +int lib_interface_zebra_ipv6_router_advertisements_max_rtr_adv_interval_modify( +	struct nb_cb_modify_args *args) +{ +	struct interface *ifp; +	uint32_t interval; + +	if (args->event != NB_EV_APPLY) +		return NB_OK; + +	ifp = nb_running_get_entry(args->dnode, NULL, true); +	interval = yang_dnode_get_uint32(args->dnode, NULL); + +	ipv6_nd_interval_set(ifp, interval); + +	return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ipv6-router-advertisements/default-lifetime + */ +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_modify( +	struct nb_cb_modify_args *args) +{ +	struct interface *ifp; +	struct zebra_if *zif; +	uint16_t lifetime; + +	if (args->event != NB_EV_APPLY) +		return NB_OK; + +	ifp = nb_running_get_entry(args->dnode, NULL, true); +	zif = ifp->info; + +	lifetime = yang_dnode_get_uint16(args->dnode, NULL); + +	zif->rtadv.AdvDefaultLifetime = lifetime; + +	return NB_OK; +} + +int lib_interface_zebra_ipv6_router_advertisements_default_lifetime_destroy( +	struct nb_cb_destroy_args *args) +{ +	struct interface *ifp; +	struct zebra_if *zif; + +	if (args->event != NB_EV_APPLY) +		return NB_OK; + +	ifp = nb_running_get_entry(args->dnode, NULL, true); +	zif = ifp->info; + +	zif->rtadv.AdvDefaultLifetime = -1; + +	return NB_OK; +} + +/*   * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/l3vni-id   */  int lib_vrf_zebra_l3vni_id_modify(struct nb_cb_modify_args *args)  | 
