mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-11-02 21:35:32 +00:00
Merge pull request #5462 from dslicenc/ipv6-ra-lifetime-0
zebra: send RA lifetime of 0 before ceasing to advertise RAs
This commit is contained in:
commit
0d26af1203
@ -1977,6 +1977,8 @@ DEFUN (shutdown_if,
|
||||
struct zebra_if *if_data;
|
||||
|
||||
if (ifp->ifindex != IFINDEX_INTERNAL) {
|
||||
/* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
|
||||
rtadv_stop_ra(ifp);
|
||||
ret = if_unset_flags(ifp, IFF_UP);
|
||||
if (ret < 0) {
|
||||
vty_out(vty, "Can't shutdown interface\n");
|
||||
|
||||
@ -145,6 +145,9 @@ static void sigint(void)
|
||||
atomic_store_explicit(&zrouter.in_shutdown, true,
|
||||
memory_order_relaxed);
|
||||
|
||||
/* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
|
||||
rtadv_stop_ra_all();
|
||||
|
||||
frr_early_fini();
|
||||
|
||||
zebra_dplane_pre_finish();
|
||||
|
||||
@ -166,7 +166,8 @@ static int rtadv_recv_packet(struct zebra_vrf *zvrf, int sock, uint8_t *buf,
|
||||
#define RTADV_MSG_SIZE 4096
|
||||
|
||||
/* Send router advertisement packet. */
|
||||
static void rtadv_send_packet(int sock, struct interface *ifp)
|
||||
static void rtadv_send_packet(int sock, struct interface *ifp,
|
||||
ipv6_nd_suppress_ra_status stop)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
@ -252,7 +253,10 @@ static void rtadv_send_packet(int sock, struct interface *ifp)
|
||||
zif->rtadv.AdvDefaultLifetime != -1
|
||||
? zif->rtadv.AdvDefaultLifetime
|
||||
: MAX(1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
|
||||
rtadv->nd_ra_router_lifetime = htons(pkt_RouterLifetime);
|
||||
|
||||
/* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
|
||||
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);
|
||||
|
||||
@ -512,7 +516,7 @@ static int rtadv_timer(struct thread *thread)
|
||||
ifp->name);
|
||||
|
||||
rtadv_send_packet(rtadv_get_socket(zvrf),
|
||||
ifp);
|
||||
ifp, RA_ENABLE);
|
||||
} else {
|
||||
zif->rtadv.AdvIntervalTimer -= period;
|
||||
if (zif->rtadv.AdvIntervalTimer <= 0) {
|
||||
@ -526,7 +530,7 @@ static int rtadv_timer(struct thread *thread)
|
||||
.MaxRtrAdvInterval;
|
||||
rtadv_send_packet(
|
||||
rtadv_get_socket(zvrf),
|
||||
ifp);
|
||||
ifp, RA_ENABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -556,7 +560,7 @@ static void rtadv_process_solicit(struct interface *ifp)
|
||||
if ((zif->rtadv.UseFastRexmit)
|
||||
|| (zif->rtadv.AdvIntervalTimer <=
|
||||
(zif->rtadv.MaxRtrAdvInterval - MIN_DELAY_BETWEEN_RAS))) {
|
||||
rtadv_send_packet(rtadv_get_socket(zvrf), ifp);
|
||||
rtadv_send_packet(rtadv_get_socket(zvrf), ifp, RA_ENABLE);
|
||||
zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
|
||||
} else
|
||||
zif->rtadv.AdvIntervalTimer = MIN_DELAY_BETWEEN_RAS;
|
||||
@ -911,6 +915,8 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp,
|
||||
if (status == RA_SUPPRESS) {
|
||||
/* RA is currently enabled */
|
||||
if (zif->rtadv.AdvSendAdvertisements) {
|
||||
rtadv_send_packet(rtadv_get_socket(zvrf), ifp,
|
||||
RA_SUPPRESS);
|
||||
zif->rtadv.AdvSendAdvertisements = 0;
|
||||
zif->rtadv.AdvIntervalTimer = 0;
|
||||
zvrf->rtadv.adv_if_count--;
|
||||
@ -1012,6 +1018,38 @@ stream_failure:
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* send router lifetime value of zero in RAs on this interface since we're
|
||||
* ceasing to advertise and want to let our neighbors know.
|
||||
* RFC 4861 secion 6.2.5
|
||||
*/
|
||||
void rtadv_stop_ra(struct interface *ifp)
|
||||
{
|
||||
struct zebra_if *zif;
|
||||
struct zebra_vrf *zvrf;
|
||||
|
||||
zif = ifp->info;
|
||||
zvrf = vrf_info_lookup(ifp->vrf_id);
|
||||
|
||||
if (zif->rtadv.AdvSendAdvertisements)
|
||||
rtadv_send_packet(rtadv_get_socket(zvrf), ifp, RA_SUPPRESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* send router lifetime value of zero in RAs on all interfaces since we're
|
||||
* ceasing to advertise globally and want to let all of our neighbors know
|
||||
* RFC 4861 secion 6.2.5
|
||||
*/
|
||||
void rtadv_stop_ra_all(void)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
struct interface *ifp;
|
||||
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
|
||||
FOR_ALL_INTERFACES (vrf, ifp)
|
||||
rtadv_stop_ra(ifp);
|
||||
}
|
||||
|
||||
void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
zebra_interface_radv_set(client, hdr, msg, zvrf, 0);
|
||||
|
||||
@ -140,6 +140,8 @@ typedef enum {
|
||||
|
||||
extern void rtadv_init(struct zebra_vrf *zvrf);
|
||||
extern void rtadv_terminate(struct zebra_vrf *zvrf);
|
||||
extern void rtadv_stop_ra(struct interface *ifp);
|
||||
extern void rtadv_stop_ra_all(void);
|
||||
extern void rtadv_cmd_init(void);
|
||||
extern void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS);
|
||||
extern void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user