diff options
author | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-03-04 21:15:25 +0100 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-05-17 02:27:08 +0200 |
commit | ee5aabb6fcf84027ef7a16a49755adafc2f07183 (patch) | |
tree | 731c60517f9decad0f4c51a4ede793cd33100350 /vrrpd | |
parent | vrrpd: delay sending adverts/garp/una for iface up (diff) | |
download | frr-ee5aabb6fcf84027ef7a16a49755adafc2f07183.tar.xz frr-ee5aabb6fcf84027ef7a16a49755adafc2f07183.zip |
vrrpd: delay sending advert/garp/una for ifup pt 2
Pt 2: When transitioning directly into Master (because we are the
address owner), wait until Zebra sets the macvlan device to protodown
off before transmitting advertisements, gratuitous ARPs, or Unsolicited
Neighbor Advertisements.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'vrrpd')
-rw-r--r-- | vrrpd/vrrp.c | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index 070bb9cc7..a4e4a62b0 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -1260,7 +1260,41 @@ static void vrrp_change_state_master(struct vrrp_router *r) if (r->family == AF_INET6) vrrp_zebra_radv_set(r, true); + /* Set protodown off */ vrrp_zclient_send_interface_protodown(r->mvl_ifp, false); + + /* + * If protodown is already off, we can send our stuff, otherwise we + * have to delay until the interface is all the way up + */ + if (if_is_operative(r->mvl_ifp)) { + vrrp_send_advertisement(r); + + if (r->family == AF_INET) + vrrp_garp_send_all(r); + else if (r->family == AF_INET6) + vrrp_ndisc_una_send_all(r); + } else { + DEBUGD(&vrrp_dbg_proto, + VRRP_LOGPFX VRRP_LOGPFX_VRID + "Delaying VRRP advertisement until interface is up", + r->vr->vrid); + r->advert_pending = true; + + if (r->family == AF_INET) { + DEBUGD(&vrrp_dbg_proto, + VRRP_LOGPFX VRRP_LOGPFX_VRID + "Delaying VRRP gratuitous ARPs until interface is up", + r->vr->vrid); + r->garp_pending = true; + } else if (r->family == AF_INET6) { + DEBUGD(&vrrp_dbg_proto, + VRRP_LOGPFX VRRP_LOGPFX_VRID + "Delaying VRRP unsolicited neighbor advertisement until interface is up", + r->vr->vrid); + r->ndisc_pending = true; + } + } } /* @@ -1278,7 +1312,6 @@ static void vrrp_change_state_backup(struct vrrp_router *r) /* Disable Adver_Timer */ THREAD_OFF(r->t_adver_timer); - /* This should not be necessary, but just in case */ r->advert_pending = false; r->garp_pending = false; r->ndisc_pending = false; @@ -1301,7 +1334,6 @@ static void vrrp_change_state_initialize(struct vrrp_router *r) r->master_adver_interval = 0; vrrp_recalculate_timers(r); - /* This should not be necessary, but just in case */ r->advert_pending = false; r->garp_pending = false; r->ndisc_pending = false; @@ -1384,18 +1416,6 @@ static int vrrp_master_down_timer_expire(struct thread *thread) &r->t_adver_timer); vrrp_change_state(r, VRRP_STATE_MASTER); - /* - * Since this implemention uses protodown to implement backup status, - * we have to wait for the interface to come up before we can send our - * initial advert and garp/ndisc packets. This will be handled in - * vrrp_if_up(). - */ - r->advert_pending = true; - if (r->family == AF_INET) - r->garp_pending = true; - if (r->family == AF_INET6) - r->ndisc_pending = true; - return 0; } @@ -1464,13 +1484,6 @@ static int vrrp_startup(struct vrrp_router *r) } if (r->priority == VRRP_PRIO_MASTER) { - vrrp_send_advertisement(r); - - if (r->family == AF_INET) - vrrp_garp_send_all(r); - if (r->family == AF_INET6) - vrrp_ndisc_una_send_all(r); - thread_add_timer_msec(master, vrrp_adver_timer_expire, r, r->vr->advertisement_interval * 10, &r->t_adver_timer); @@ -1531,10 +1544,6 @@ static int vrrp_shutdown(struct vrrp_router *r) r->sock_tx = -1; } - r->advert_pending = false; - r->garp_pending = false; - r->ndisc_pending = false; - vrrp_change_state(r, VRRP_STATE_INITIALIZE); r->is_active = false; @@ -1968,6 +1977,9 @@ void vrrp_if_up(struct interface *ifp) for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr)) { vrrp_check_start(vr); + if (!if_is_operative(ifp)) + continue; + /* * Handle the situation in which we performed a state * transition on this VRRP router but needed to wait for the |