aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorQuentin Armitage <quentin@armitage.org.uk>2016-06-16 03:00:14 -0400
committerSimon Horman <horms@verge.net.au>2016-07-07 14:21:32 -0400
commit3777ed688fba82d0bd43f9fc1ebbc6abe788576d (patch)
treefd76274971e0e33347434e57b24ca1d49e6cd7bf /net/netfilter
parent62131e5d735226074cba53095545d76b491e5003 (diff)
ipvs: fix bind to link-local mcast IPv6 address in backup
When using HEAD from https://git.kernel.org/cgit/utils/kernel/ipvsadm/ipvsadm.git/, the command: ipvsadm --start-daemon backup --mcast-interface eth0.60 \ --mcast-group ff02::1:81 fails with the error message: Argument list too long whereas both: ipvsadm --start-daemon master --mcast-interface eth0.60 \ --mcast-group ff02::1:81 and: ipvsadm --start-daemon backup --mcast-interface eth0.60 \ --mcast-group 224.0.0.81 are successful. The error message "Argument list too long" isn't helpful. The error occurs because an IPv6 address is given in backup mode. The error is in make_receive_sock() in net/netfilter/ipvs/ip_vs_sync.c, since it fails to set the interface on the address or the socket before calling inet6_bind() (via sock->ops->bind), where the test 'if (!sk->sk_bound_dev_if)' failed. Setting sock->sk->sk_bound_dev_if on the socket before calling inet6_bind() resolves the issue. Fixes: d33288172e72 ("ipvs: add more mcast parameters for the sync daemon") Signed-off-by: Quentin Armitage <quentin@armitage.org.uk> Acked-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 803001a45aa1..1b07578bedf3 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -1545,7 +1545,8 @@ error:
1545/* 1545/*
1546 * Set up receiving multicast socket over UDP 1546 * Set up receiving multicast socket over UDP
1547 */ 1547 */
1548static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id) 1548static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
1549 int ifindex)
1549{ 1550{
1550 /* multicast addr */ 1551 /* multicast addr */
1551 union ipvs_sockaddr mcast_addr; 1552 union ipvs_sockaddr mcast_addr;
@@ -1566,6 +1567,7 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id)
1566 set_sock_size(sock->sk, 0, result); 1567 set_sock_size(sock->sk, 0, result);
1567 1568
1568 get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id); 1569 get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
1570 sock->sk->sk_bound_dev_if = ifindex;
1569 result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen); 1571 result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
1570 if (result < 0) { 1572 if (result < 0) {
1571 pr_err("Error binding to the multicast addr\n"); 1573 pr_err("Error binding to the multicast addr\n");
@@ -1868,7 +1870,7 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
1868 if (state == IP_VS_STATE_MASTER) 1870 if (state == IP_VS_STATE_MASTER)
1869 sock = make_send_sock(ipvs, id); 1871 sock = make_send_sock(ipvs, id);
1870 else 1872 else
1871 sock = make_receive_sock(ipvs, id); 1873 sock = make_receive_sock(ipvs, id, dev->ifindex);
1872 if (IS_ERR(sock)) { 1874 if (IS_ERR(sock)) {
1873 result = PTR_ERR(sock); 1875 result = PTR_ERR(sock);
1874 goto outtinfo; 1876 goto outtinfo;