Commit 391f503d authored by Alex Gartrell's avatar Alex Gartrell Committed by Simon Horman

ipvs: prevent mixing heterogeneous pools and synchronization

The synchronization protocol is not compatible with heterogeneous pools, so
we need to verify that we're not turning both on at the same time.
Signed-off-by: default avatarAlex Gartrell <agartrell@fb.com>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent ba38528a
...@@ -990,6 +990,10 @@ struct netns_ipvs { ...@@ -990,6 +990,10 @@ struct netns_ipvs {
char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN]; char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
/* net name space ptr */ /* net name space ptr */
struct net *net; /* Needed by timer routines */ struct net *net; /* Needed by timer routines */
/* Number of heterogeneous destinations, needed because
* heterogeneous are not supported when synchronization is
* enabled */
unsigned int mixed_address_family_dests;
}; };
#define DEFAULT_SYNC_THRESHOLD 3 #define DEFAULT_SYNC_THRESHOLD 3
......
...@@ -779,6 +779,12 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, ...@@ -779,6 +779,12 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
struct ip_vs_scheduler *sched; struct ip_vs_scheduler *sched;
int conn_flags; int conn_flags;
/* We cannot modify an address and change the address family */
BUG_ON(!add && udest->af != dest->af);
if (add && udest->af != svc->af)
ipvs->mixed_address_family_dests++;
/* set the weight and the flags */ /* set the weight and the flags */
atomic_set(&dest->weight, udest->weight); atomic_set(&dest->weight, udest->weight);
conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK; conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK;
...@@ -1061,6 +1067,9 @@ static void __ip_vs_unlink_dest(struct ip_vs_service *svc, ...@@ -1061,6 +1067,9 @@ static void __ip_vs_unlink_dest(struct ip_vs_service *svc,
list_del_rcu(&dest->n_list); list_del_rcu(&dest->n_list);
svc->num_dests--; svc->num_dests--;
if (dest->af != svc->af)
net_ipvs(svc->net)->mixed_address_family_dests--;
if (svcupd) { if (svcupd) {
struct ip_vs_scheduler *sched; struct ip_vs_scheduler *sched;
...@@ -3256,6 +3265,12 @@ static int ip_vs_genl_new_daemon(struct net *net, struct nlattr **attrs) ...@@ -3256,6 +3265,12 @@ static int ip_vs_genl_new_daemon(struct net *net, struct nlattr **attrs)
attrs[IPVS_DAEMON_ATTR_SYNC_ID])) attrs[IPVS_DAEMON_ATTR_SYNC_ID]))
return -EINVAL; return -EINVAL;
/* The synchronization protocol is incompatible with mixed family
* services
*/
if (net_ipvs(net)->mixed_address_family_dests > 0)
return -EINVAL;
return start_sync_thread(net, return start_sync_thread(net,
nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]), nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]),
nla_data(attrs[IPVS_DAEMON_ATTR_MCAST_IFN]), nla_data(attrs[IPVS_DAEMON_ATTR_MCAST_IFN]),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment