From 6488de282a4da41f932bfeae4144a5b8c3bf1c14 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Fri, 6 Nov 2015 12:51:46 +0000 Subject: Don't explicitly drop IGMP membership before interface deletion The kernel will send IGMP leave group messages when an interface is deleted, so there is no need for us to do so. Experimentation has shown that explicity doing IGMP_DROP_MEMBERSHIP doesn't make it any more likely the IGMP leave group messages will be sent. Adding the 1 second sleep significantly increases the likelihood of the IGMP messages being sent, but is doesn't guarantee it. Extending the sleep time doesn't improve the chances. Signed-off-by: Quentin Armitage (cherry picked from commit 21a7e9742c0dc78505febae6e0caa7e1abc4dbc5) --- keepalived/vrrp/vrrp.c | 11 +++++------ keepalived/vrrp/vrrp_daemon.c | 6 ++++++ keepalived/vrrp/vrrp_data.c | 11 ++--------- keepalived/vrrp/vrrp_if.c | 3 --- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c index 248a9e4..dcf4ed1 100644 --- a/keepalived/vrrp/vrrp.c +++ b/keepalived/vrrp/vrrp.c @@ -1111,10 +1111,10 @@ vrrp_restore_interface(vrrp_t * vrrp, int advF) { /* if we stop vrrp, warn the other routers to speed up the recovery */ if (advF) { - syslog(LOG_INFO, "VRRP_Instance(%s) sending 0 priority", - vrrp->iname); vrrp_send_adv(vrrp, VRRP_PRIO_STOP); ++vrrp->stats->pri_zero_sent; + syslog(LOG_INFO, "VRRP_Instance(%s) sent 0 priority", + vrrp->iname); } /* remove virtual routes */ @@ -1519,11 +1519,10 @@ open_vrrp_socket(sa_family_t family, int proto, int idx, void close_vrrp_socket(vrrp_t * vrrp) { - if (LIST_ISEMPTY(vrrp->unicast_peer)) { + if (LIST_ISEMPTY(vrrp->unicast_peer)) if_leave_vrrp_group(vrrp->family, vrrp->fd_in, vrrp->ifp); - } else { - close(vrrp->fd_in); - } + + close(vrrp->fd_in); close(vrrp->fd_out); } diff --git a/keepalived/vrrp/vrrp_daemon.c b/keepalived/vrrp/vrrp_daemon.c index fcacf6b..8b7202b 100644 --- a/keepalived/vrrp/vrrp_daemon.c +++ b/keepalived/vrrp/vrrp_daemon.c @@ -85,6 +85,12 @@ stop_vrrp(void) free_global_data(global_data); vrrp_dispatcher_release(vrrp_data); + /* This is not nice, but it significantly increases the chances + * of an IGMP leave group being sent for some reason. + * Since we are about to exit, it doesn't affect anything else + * running. */ + sleep ( 1 ); + if (!__test_bit(DONT_RELEASE_VRRP_BIT, &debug)) shutdown_vrrp_instances(); diff --git a/keepalived/vrrp/vrrp_data.c b/keepalived/vrrp/vrrp_data.c index db55f11..99a9303 100644 --- a/keepalived/vrrp/vrrp_data.c +++ b/keepalived/vrrp/vrrp_data.c @@ -150,20 +150,13 @@ static void free_sock(void *sock_data) { sock_t *sock = sock_data; - interface_t *ifp; /* First of all cancel pending thread */ thread_cancel(sock->thread); /* Close related socket */ - if (sock->fd_in > 0) { - ifp = if_get_by_ifindex(sock->ifindex); - if (sock->unicast) { - close(sock->fd_in); - } else { - if_leave_vrrp_group(sock->family, sock->fd_in, ifp); - } - } + if (sock->fd_in > 0) + close(sock->fd_in); if (sock->fd_out > 0) close(sock->fd_out); FREE(sock_data); diff --git a/keepalived/vrrp/vrrp_if.c b/keepalived/vrrp/vrrp_if.c index 1204d32..38fecf1 100644 --- a/keepalived/vrrp/vrrp_if.c +++ b/keepalived/vrrp/vrrp_if.c @@ -513,12 +513,9 @@ if_leave_vrrp_group(sa_family_t family, int sd, interface_t *ifp) if (ret < 0) { log_message(LOG_INFO, "cant do IP%s_DROP_MEMBERSHIP errno=%s (%d)", (family == AF_INET) ? "" : "V6", strerror(errno), errno); - close(sd); return -1; } - /* Finally close the desc */ - close(sd); return 0; } -- 1.7.12.1