diff options
| author | Don Slice <dslice@cumulusnetworks.com> | 2020-04-28 11:54:14 +0000 | 
|---|---|---|
| committer | Don Slice <dslice@cumulusnetworks.com> | 2020-04-29 11:26:04 +0000 | 
| commit | b19ac878bed9a3bcc2527fd3747fea1ed033e5ae (patch) | |
| tree | 93f7ecf201d70820306e768f8a024f027611d76d /zebra/rtadv.c | |
| parent | f6be73082788c4be246b9b71f50237bbad40bfc8 (diff) | |
zebra: add ability to set retransmit timer for IPv6 RAs
Reported by testing agency that rfc 4861 section 6.2.1 states
that all implementations must have a configuration knob to change
the setting of the advertised retransmit timer sent in RA packets.
This fix adds that capability.
Ticket: CM-29199
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Diffstat (limited to 'zebra/rtadv.c')
| -rw-r--r-- | zebra/rtadv.c | 62 | 
1 files changed, 57 insertions, 5 deletions
diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 11434edfcf..0fb3390410 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -265,7 +265,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp,  	rtadv->nd_ra_router_lifetime =  		(stop == RA_SUPPRESS) ? htons(0) : htons(pkt_RouterLifetime);  	rtadv->nd_ra_reachable = htonl(zif->rtadv.AdvReachableTime); -	rtadv->nd_ra_retransmit = htonl(0); +	rtadv->nd_ra_retransmit = htonl(zif->rtadv.AdvRetransTimer);  	len = sizeof(struct nd_router_advert); @@ -679,9 +679,8 @@ static void rtadv_process_advert(uint8_t *msg, unsigned int len,  			ifp->name, ifp->ifindex, addr_str);  	} -	if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) -	    && (ntohl(radvert->nd_ra_retransmit) -		!= (unsigned int)zif->rtadv.AdvRetransTimer)) { +	if ((ntohl(radvert->nd_ra_retransmit) +	     != (unsigned int)zif->rtadv.AdvRetransTimer)) {  		flog_warn(  			EC_ZEBRA_RA_PARAM_MISMATCH,  			"%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s", @@ -1282,6 +1281,53 @@ DEFPY (no_ipv6_nd_ra_hop_limit,  	return CMD_SUCCESS;  } +DEFPY (ipv6_nd_ra_retrans_interval, +       ipv6_nd_ra_retrans_interval_cmd, +       "ipv6 nd ra-retrans-interval (0-4294967295)$interval", +       "Interface IPv6 config commands\n" +       "Neighbor discovery\n" +       "Advertisement Retransmit Interval\n" +       "Advertisement Retransmit Interval in msec\n") +{ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; + +	if (if_is_loopback(ifp) +	    || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { +		vty_out(vty, +			"Cannot configure IPv6 Router Advertisements on loopback interface\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	zif->rtadv.AdvRetransTimer = interval; + +	return CMD_SUCCESS; +} + +DEFPY (no_ipv6_nd_ra_retrans_interval, +       no_ipv6_nd_ra_retrans_interval_cmd, +       "no ipv6 nd ra-retrans-interval [(0-4294967295)]", +       NO_STR +       "Interface IPv6 config commands\n" +       "Neighbor discovery\n" +       "Advertisement Retransmit Interval\n" +       "Advertisement Retransmit Interval in msec\n") +{ +	VTY_DECLVAR_CONTEXT(interface, ifp); +	struct zebra_if *zif = ifp->info; + +	if (if_is_loopback(ifp) +	    || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { +		vty_out(vty, +			"Cannot remove IPv6 Router Advertisements on loopback interface\n"); +		return CMD_WARNING_CONFIG_FAILED; +	} + +	zif->rtadv.AdvRetransTimer = 0; + +	return CMD_SUCCESS; +} +  DEFUN (ipv6_nd_suppress_ra,         ipv6_nd_suppress_ra_cmd,         "ipv6 nd suppress-ra", @@ -2227,7 +2273,7 @@ static int nd_dump_vty(struct vty *vty, struct interface *ifp)  			"  ND advertised reachable time is %d milliseconds\n",  			rtadv->AdvReachableTime);  		vty_out(vty, -			"  ND advertised retransmit interval is %d milliseconds\n", +			"  ND advertised retransmit interval is %u milliseconds\n",  			rtadv->AdvRetransTimer);  		vty_out(vty, "  ND advertised hop-count limit is %d hops\n",  			rtadv->AdvCurHopLimit); @@ -2322,6 +2368,10 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp)  	if (!zif->rtadv.UseFastRexmit)  		vty_out(vty, " no ipv6 nd ra-fast-retrans\n"); +	if (zif->rtadv.AdvRetransTimer != 0) +		vty_out(vty, " ipv6 nd ra-retrans-interval %u\n", +			zif->rtadv.AdvRetransTimer); +  	if (zif->rtadv.AdvCurHopLimit != RTADV_DEFAULT_HOPLIMIT)  		vty_out(vty, " ipv6 nd ra-hop-limit %d\n",  			zif->rtadv.AdvCurHopLimit); @@ -2494,6 +2544,8 @@ void rtadv_cmd_init(void)  	install_element(INTERFACE_NODE, &ipv6_nd_ra_fast_retrans_cmd);  	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_fast_retrans_cmd); +	install_element(INTERFACE_NODE, &ipv6_nd_ra_retrans_interval_cmd); +	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_retrans_interval_cmd);  	install_element(INTERFACE_NODE, &ipv6_nd_ra_hop_limit_cmd);  	install_element(INTERFACE_NODE, &no_ipv6_nd_ra_hop_limit_cmd);  	install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);  | 
