[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 ------------------------------------------------------------------------------