summaryrefslogtreecommitdiffstats
path: root/vrrpd
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2019-03-04 21:15:25 +0100
committerQuentin Young <qlyoung@cumulusnetworks.com>2019-05-17 02:27:08 +0200
commitee5aabb6fcf84027ef7a16a49755adafc2f07183 (patch)
tree731c60517f9decad0f4c51a4ede793cd33100350 /vrrpd
parentvrrpd: delay sending adverts/garp/una for iface up (diff)
downloadfrr-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.c62
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