[PATCH 06/12] Stop m'cast packets being queued (and not received) on send socket

[email protected] (Quentin Armitage)
Newsgroups gmane.linux.keepalived.devel
Message-ID <[email protected]>
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 <[email protected]>
---
 keepalived/include/vrrp_if.h |    1 +
 keepalived/vrrp/vrrp.c       |    6 +++++-
 keepalived/vrrp/vrrp_if.c    |   25 +++++++++++++++++++++++++
 3 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/keepalived/include/vrrp_if.h b/keepalived/include/vrrp_if.h
index ec6064f..a48feef 100644
--- a/keepalived/include/vrrp_if.h
+++ b/keepalived/include/vrrp_if.h
@@ -131,6 +131,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 1be1e72..a9408d4 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.7.6


------------------------------------------------------------------------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.