zebra: do not display ipv6 ra commands created by bgpd

If the frr.conf file contains bgp unnumbered peering but the associated
interfaces do not have the commands "no ipv6 nd suppress-ra" and
"ipv6 nd ra-interval 10" configured, when frr-reload.py is issued the
interface commands are removed from the running config, causing peers to
got down and stay down after a link flap.  This situation can occur if
the frr.conf file is created manually or via automation (like ansible)
but a subsequent "wr mem" has not been performed.

This fix changes the behavior so that the interface ipv6 nd ra commands
created by bgp are not displayed.  Therefore, when the above condition
occurs, there is no difference between the running and stored configs
and peers work fine.

Ticket: CM-18702
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Reviewed-by: CCR-7004
Testing-done:  Manual testing successful.  L3-smoke has no new failures
This commit is contained in:
Don Slice 2017-12-06 09:00:48 -08:00
parent 17473b9a45
commit 3ea48364e1
2 changed files with 39 additions and 14 deletions

View File

@ -170,7 +170,12 @@ struct rtadvconf {
#define RTADV_PREF_MEDIUM 0x0 /* Per RFC4191. */
u_char inFastRexmit; /* True if we're rexmits faster than usual */
u_char configured; /* Has operator configured RA? */
/* Track if RA was configured by BGP or by the Operator or both */
u_char ra_configured; /* Was RA configured? */
#define BGP_RA_CONFIGURED (1<<0) /* BGP configured RA? */
#define VTY_RA_CONFIGURED (1<<1) /* Operator configured RA? */
#define VTY_RA_INTERVAL_CONFIGURED (1<<2) /* Operator configured RA interval */
int
NumFastReXmitsRemain; /* Loaded first with number of fast
rexmits to do */

View File

@ -838,16 +838,21 @@ void zebra_interface_radv_set(struct zserv *client, u_short length,
zif = ifp->info;
if (enable) {
SET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
if (ra_interval
&& (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval)
&& (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval
&& !CHECK_FLAG(zif->rtadv.ra_configured,
VTY_RA_INTERVAL_CONFIGURED))
zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
} else {
if (!zif->rtadv.configured) {
UNSET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
if (!CHECK_FLAG(zif->rtadv.ra_configured,
VTY_RA_INTERVAL_CONFIGURED))
zif->rtadv.MaxRtrAdvInterval =
RTADV_MAX_RTR_ADV_INTERVAL;
if (!CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED))
ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
}
}
stream_failure:
return;
@ -870,8 +875,10 @@ DEFUN (ipv6_nd_suppress_ra,
return CMD_WARNING_CONFIG_FAILED;
}
ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
zif->rtadv.configured = 0;
if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
return CMD_SUCCESS;
}
@ -894,7 +901,7 @@ DEFUN (no_ipv6_nd_suppress_ra,
}
ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
zif->rtadv.configured = 1;
SET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
return CMD_SUCCESS;
}
@ -929,6 +936,7 @@ DEFUN (ipv6_nd_ra_interval_msec,
if (interval % 1000)
zns->rtadv.adv_msec_if_count++;
SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
zif->rtadv.MaxRtrAdvInterval = interval;
zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
zif->rtadv.AdvIntervalTimer = 0;
@ -966,6 +974,7 @@ DEFUN (ipv6_nd_ra_interval,
/* 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;
@ -995,9 +1004,15 @@ DEFUN (no_ipv6_nd_ra_interval,
if (zif->rtadv.MaxRtrAdvInterval % 1000)
zns->rtadv.adv_msec_if_count--;
zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
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;
}
@ -1552,15 +1567,20 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp)
if (!(if_is_loopback(ifp)
|| CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))) {
if (zif->rtadv.AdvSendAdvertisements)
if (zif->rtadv.AdvSendAdvertisements
&& CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED))
vty_out(vty, " no ipv6 nd suppress-ra\n");
}
interval = zif->rtadv.MaxRtrAdvInterval;
if (interval % 1000)
vty_out(vty, " ipv6 nd ra-interval msec %d\n", interval);
else if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
vty_out(vty, " ipv6 nd ra-interval %d\n", interval / 1000);
if (CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED)) {
if (interval % 1000)
vty_out(vty, " ipv6 nd ra-interval msec %d\n",
interval);
else if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
vty_out(vty, " ipv6 nd ra-interval %d\n",
interval / 1000);
}
if (zif->rtadv.AdvIntervalOption)
vty_out(vty, " ipv6 nd adv-interval-option\n");