diff --git a/zebra/interface.h b/zebra/interface.h index 6bc05e21c5..f095a32d1e 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -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 */ diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 40219599dd..32418eb82f 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -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");