void
bgp_zebra_initiate_radv (struct bgp *bgp, struct peer *peer)
{
+ int ra_interval = BGP_UNNUM_DEFAULT_RA_INTERVAL;
+
/* Don't try to initiate if we're not connected to Zebra */
if (zclient->sock < 0)
return;
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("%u: Initiating RA for peer %s", bgp->vrf_id, peer->host);
- zclient_send_interface_radv_req (zclient, bgp->vrf_id, peer->ifp, 1);
+ zclient_send_interface_radv_req (zclient, bgp->vrf_id, peer->ifp, 1, ra_interval);
}
void
if (BGP_DEBUG (zebra, ZEBRA))
zlog_debug("%u: Terminating RA for peer %s", bgp->vrf_id, peer->host);
- zclient_send_interface_radv_req (zclient, bgp->vrf_id, peer->ifp, 0);
+ zclient_send_interface_radv_req (zclient, bgp->vrf_id, peer->ifp, 0, 0);
}
/* BGP has established connection with Zebra. */
#define BGP_MAX_HOSTNAME 64 /* Linux max, is larger than most other sys */
+/* Default interval for IPv6 RAs when triggered by BGP unnumbered neighbor. */
+#define BGP_UNNUM_DEFAULT_RA_INTERVAL 10
+
struct update_subgroup;
struct bpacket;
/* Send request to zebra daemon to start or stop RA. */
void
zclient_send_interface_radv_req (struct zclient *zclient, vrf_id_t vrf_id,
- struct interface *ifp, int enable)
+ struct interface *ifp, int enable, int ra_interval)
{
struct stream *s;
zclient_create_header (s, ZEBRA_INTERFACE_DISABLE_RADV, vrf_id);
stream_putl (s, ifp->ifindex);
+ stream_putl (s, ra_interval);
stream_putw_at (s, 0, stream_get_endp (s));
extern void zclient_send_dereg_requests (struct zclient *, vrf_id_t);
extern void zclient_send_interface_radv_req (struct zclient *zclient, vrf_id_t vrf_id,
- struct interface *ifp, int enable);
+ struct interface *ifp, int enable, int ra_interval);
/* Send redistribute command to zebra daemon. Do not update zclient state. */
extern int zebra_redistribute_send (int command, struct zclient *, afi_t, int type, u_short instance, vrf_id_t vrf_id);
* 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
* operator has not enabled RA, RA won't be disabled upon client request
- * if the operator has explicitly enabled RA.
+ * if the operator has explicitly enabled RA. The enable request can also
+ * specify a RA interval (in seconds).
*/
void
zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
unsigned int ifindex;
struct interface *ifp;
struct zebra_if *zif;
+ int ra_interval;
s = client->ibuf;
- /* Get interface index. */
+ /* Get interface index and RA interval. */
ifindex = stream_getl (s);
+ ra_interval = stream_getl (s);
if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%u: IF %u RA %s from client %s",
+ zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
- zebra_route_string(client->proto));
+ zebra_route_string(client->proto), ra_interval);
/* Locate interface and check VRF match. */
ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT), ifindex);
zif = ifp->info;
if (enable)
- ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
+ {
+ ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
+ if (ra_interval &&
+ (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval)
+ zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
+ }
else
{
if (!zif->rtadv.configured)
- ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
+ {
+ zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
+ ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
+ }
}
}