From d941f8f7b72d954b6e984ed8b9c126864a467f67 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Sun, 1 Nov 2015 20:14:24 +0000 Subject: Stop m'cast packets being queued (and not received) on send socket If there are other vrrp instances on the same network, their multicast packets are queued to our vrrp send socket, but since we don't receive on that socket, the messages just get queued in the kernel (run netstat -anp | grep keepalived to see the queued packets increasing). This patch clears the IP_MULTICAST_ALL option, to stop these packets being queued. Signed-off-by: Quentin Armitage (cherry picked from commit b71116f0bb80119401f2867c5c6dbc085a74791f) --- keepalived/include/vrrp_if.h | 1 + keepalived/vrrp/vrrp.c | 6 +++++- keepalived/vrrp/vrrp_if.c | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/keepalived/include/vrrp_if.h b/keepalived/include/vrrp_if.h index 9d2008b..ebbd344 100644 --- a/keepalived/include/vrrp_if.h +++ b/keepalived/include/vrrp_if.h @@ -135,6 +135,7 @@ extern int if_leave_vrrp_group(sa_family_t, int, interface_t *); extern int if_setsockopt_bindtodevice(int *, interface_t *); extern int if_setsockopt_hdrincl(int *); extern int if_setsockopt_ipv6_checksum(int *); +extern int if_setsockopt_mcast_all(sa_family_t, int *); extern int if_setsockopt_mcast_loop(sa_family_t, int *); extern int if_setsockopt_mcast_hops(sa_family_t, int *); extern int if_setsockopt_mcast_if(sa_family_t, int *, interface_t *); diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c index 4babe2c..248a9e4 100644 --- a/keepalived/vrrp/vrrp.c +++ b/keepalived/vrrp/vrrp.c @@ -1451,6 +1451,7 @@ open_vrrp_send_socket(sa_family_t family, int proto, int idx, int unicast) if (family == AF_INET) { /* Set v4 related */ + if_setsockopt_mcast_all(family, &fd); if_setsockopt_hdrincl(&fd); if (unicast) if_setsockopt_bindtodevice(&fd, ifp); @@ -1467,7 +1468,6 @@ open_vrrp_send_socket(sa_family_t family, int proto, int idx, int unicast) } if_setsockopt_priority(&fd); - if (fd < 0) return -1; @@ -1493,6 +1493,10 @@ open_vrrp_socket(sa_family_t family, int proto, int idx, return -1; } + /* Ensure no unwanted multicast packets are queued to this interface */ + if (family == AF_INET) + if_setsockopt_mcast_all(family, &fd); + /* Join the VRRP MCAST group */ if (!unicast) { if_join_vrrp_group(family, &fd, ifp, proto); diff --git a/keepalived/vrrp/vrrp_if.c b/keepalived/vrrp/vrrp_if.c index 9355a5c..e57d366 100644 --- a/keepalived/vrrp/vrrp_if.c +++ b/keepalived/vrrp/vrrp_if.c @@ -592,6 +592,31 @@ if_setsockopt_ipv6_checksum(int *sd) int +if_setsockopt_mcast_all(sa_family_t family, int *sd) +{ + int ret; + unsigned char no = 0; + + if (*sd < 0) + return -1; + + if (family == AF_INET6) + return *sd; + + /* Don't accept multicast packets we haven't requested */ + ret = setsockopt(*sd, IPPROTO_IP, IP_MULTICAST_ALL, &no, sizeof(no)); + + if (ret < 0) { + log_message(LOG_INFO, "cant set IP_MULTICAST_ALL IP option. errno=%d (%m)", + errno); + close(*sd); + *sd = -1; + } + + return *sd; +} + +int if_setsockopt_mcast_loop(sa_family_t family, int *sd) { int ret; -- 1.7.12.1