From 3fefdb70cbbc41f9b2f6c54f2ebf53b6ad164256 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Fri, 6 Nov 2015 11:41:04 +0000 Subject: Don't delete vmac interfaces before dropping multicast membership Further to commit afea07bd94384c8ac8125e8cdbfd18bc4a46b14e, the dropping multicast memberships were failing, since the vmac interfaces had already been deleted. This patch keeps the vmac interfaces until after the IP_DROP_MEMBERSHIP ioctls. Separating the sending of the VRRP priority 0 messages from the shutdown of the vrrp instances is necessary since vrrp_dispatcher_release closes the sockets that are needed for sending the messages. Signed-off-by: Quentin Armitage (cherry picked from commit 62e8455ffb7c9441deb367e32681ba18e1425a3f) --- keepalived/include/vrrp.h | 1 + keepalived/vrrp/vrrp.c | 21 ++++++++++++++++++--- keepalived/vrrp/vrrp_daemon.c | 10 ++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/keepalived/include/vrrp.h b/keepalived/include/vrrp.h index 37c29ca..371a229 100644 --- a/keepalived/include/vrrp.h +++ b/keepalived/include/vrrp.h @@ -303,6 +303,7 @@ extern void vrrp_state_leave_master(vrrp_t *); extern int vrrp_ipsecah_len(void); extern int vrrp_complete_init(void); extern int vrrp_ipvs_needed(void); +extern void restore_vrrp_interfaces(void); extern void shutdown_vrrp_instances(void); extern void clear_diff_vrrp(void); extern void clear_diff_script(void); diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c index b9299fe..70e2f23 100644 --- a/keepalived/vrrp/vrrp.c +++ b/keepalived/vrrp/vrrp.c @@ -1552,20 +1552,35 @@ new_vrrp_socket(vrrp_t * vrrp) return vrrp->fd_in; } -/* handle terminate state */ +/* handle terminate state phase 1 */ void -shutdown_vrrp_instances(void) +restore_vrrp_interfaces(void) { list l = vrrp_data->vrrp; element e; vrrp_t *vrrp; + /* Ensure any interfaces are in backup mode, + * sending a priority 0 vrrp message + */ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vrrp = ELEMENT_DATA(e); - /* Remove VIPs/VROUTEs/VRULEs */ if (vrrp->state == VRRP_STATE_MAST) vrrp_restore_interface(vrrp, 1); + } +} + +/* handle terminate state */ +void +shutdown_vrrp_instances(void) +{ + list l = vrrp_data->vrrp; + element e; + vrrp_t *vrrp; + + for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { + vrrp = ELEMENT_DATA(e); /* Remove VMAC */ if (__test_bit(VRRP_VMAC_BIT, &vrrp->vmac_flags)) diff --git a/keepalived/vrrp/vrrp_daemon.c b/keepalived/vrrp/vrrp_daemon.c index 70aed67..fcacf6b 100644 --- a/keepalived/vrrp/vrrp_daemon.c +++ b/keepalived/vrrp/vrrp_daemon.c @@ -56,8 +56,10 @@ extern char *vrrp_pidfile; static void stop_vrrp(void) { - if (!__test_bit(DONT_RELEASE_VRRP_BIT, &debug)) - shutdown_vrrp_instances(); + /* Ensure any interfaces are in backup mode, + * sending a priority 0 vrrp message + */ + restore_vrrp_interfaces(); /* Clear static entries */ netlink_rtlist(vrrp_data->static_routes, IPROUTE_DEL); @@ -82,6 +84,10 @@ stop_vrrp(void) /* Clean data */ free_global_data(global_data); vrrp_dispatcher_release(vrrp_data); + + if (!__test_bit(DONT_RELEASE_VRRP_BIT, &debug)) + shutdown_vrrp_instances(); + free_vrrp_data(vrrp_data); free_vrrp_buffer(); free_interface_queue(); -- 1.7.12.1