Commit f131315f authored by Hans Schillstrom's avatar Hans Schillstrom Committed by Simon Horman

IPVS: netns awareness to ip_vs_sync

All global variables moved to struct ipvs,
most external changes fixed (i.e. init_net removed)
in sync_buf create  + 4 replaced by sizeof(struct..)
Signed-off-by: default avatarHans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
parent 29c2026f
...@@ -958,7 +958,7 @@ extern struct ip_vs_stats ip_vs_stats; ...@@ -958,7 +958,7 @@ extern struct ip_vs_stats ip_vs_stats;
extern const struct ctl_path net_vs_ctl_path[]; extern const struct ctl_path net_vs_ctl_path[];
extern int sysctl_ip_vs_sync_ver; extern int sysctl_ip_vs_sync_ver;
extern void ip_vs_sync_switch_mode(int mode); extern void ip_vs_sync_switch_mode(struct net *net, int mode);
extern struct ip_vs_service * extern struct ip_vs_service *
ip_vs_service_get(struct net *net, int af, __u32 fwmark, __u16 protocol, ip_vs_service_get(struct net *net, int af, __u32 fwmark, __u16 protocol,
const union nf_inet_addr *vaddr, __be16 vport); const union nf_inet_addr *vaddr, __be16 vport);
...@@ -987,14 +987,10 @@ extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp); ...@@ -987,14 +987,10 @@ extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);
* IPVS sync daemon data and function prototypes * IPVS sync daemon data and function prototypes
* (from ip_vs_sync.c) * (from ip_vs_sync.c)
*/ */
extern volatile int ip_vs_sync_state; extern int start_sync_thread(struct net *net, int state, char *mcast_ifn,
extern volatile int ip_vs_master_syncid; __u8 syncid);
extern volatile int ip_vs_backup_syncid; extern int stop_sync_thread(struct net *net, int state);
extern char ip_vs_master_mcast_ifn[IP_VS_IFNAME_MAXLEN]; extern void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp);
extern char ip_vs_backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
extern int start_sync_thread(int state, char *mcast_ifn, __u8 syncid);
extern int stop_sync_thread(int state);
extern void ip_vs_sync_conn(struct ip_vs_conn *cp);
extern int ip_vs_sync_init(void); extern int ip_vs_sync_init(void);
extern void ip_vs_sync_cleanup(void); extern void ip_vs_sync_cleanup(void);
......
...@@ -74,6 +74,22 @@ struct netns_ipvs { ...@@ -74,6 +74,22 @@ struct netns_ipvs {
struct list_head est_list; /* estimator list */ struct list_head est_list; /* estimator list */
spinlock_t est_lock; spinlock_t est_lock;
struct timer_list est_timer; /* Estimation timer */ struct timer_list est_timer; /* Estimation timer */
/* ip_vs_sync */
struct list_head sync_queue;
spinlock_t sync_lock;
struct ip_vs_sync_buff *sync_buff;
spinlock_t sync_buff_lock;
struct sockaddr_in sync_mcast_addr;
struct task_struct *master_thread;
struct task_struct *backup_thread;
int send_mesg_maxlen;
int recv_mesg_maxlen;
volatile int sync_state;
volatile int master_syncid;
volatile int backup_syncid;
/* multicast interface name */
char master_mcast_ifn[IP_VS_IFNAME_MAXLEN];
char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
}; };
#endif /* IP_VS_H_ */ #endif /* IP_VS_H_ */
...@@ -1471,12 +1471,13 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) ...@@ -1471,12 +1471,13 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
static unsigned int static unsigned int
ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
{ {
struct net *net = NULL; struct net *net;
struct ip_vs_iphdr iph; struct ip_vs_iphdr iph;
struct ip_vs_protocol *pp; struct ip_vs_protocol *pp;
struct ip_vs_proto_data *pd; struct ip_vs_proto_data *pd;
struct ip_vs_conn *cp; struct ip_vs_conn *cp;
int ret, restart, pkts; int ret, restart, pkts;
struct netns_ipvs *ipvs;
/* Already marked as IPVS request or reply? */ /* Already marked as IPVS request or reply? */
if (skb->ipvs_property) if (skb->ipvs_property)
...@@ -1556,7 +1557,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1556,7 +1557,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
} }
IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet");
net = skb_net(skb);
ipvs = net_ipvs(net);
/* Check the server status */ /* Check the server status */
if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
/* the destination server is not available */ /* the destination server is not available */
...@@ -1589,12 +1591,13 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1589,12 +1591,13 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
* *
* For ONE_PKT let ip_vs_sync_conn() do the filter work. * For ONE_PKT let ip_vs_sync_conn() do the filter work.
*/ */
if (cp->flags & IP_VS_CONN_F_ONE_PACKET) if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
pkts = sysctl_ip_vs_sync_threshold[0]; pkts = sysctl_ip_vs_sync_threshold[0];
else else
pkts = atomic_add_return(1, &cp->in_pkts); pkts = atomic_add_return(1, &cp->in_pkts);
if ((ip_vs_sync_state & IP_VS_STATE_MASTER) && if ((ipvs->sync_state & IP_VS_STATE_MASTER) &&
cp->protocol == IPPROTO_SCTP) { cp->protocol == IPPROTO_SCTP) {
if ((cp->state == IP_VS_SCTP_S_ESTABLISHED && if ((cp->state == IP_VS_SCTP_S_ESTABLISHED &&
(pkts % sysctl_ip_vs_sync_threshold[1] (pkts % sysctl_ip_vs_sync_threshold[1]
...@@ -1603,13 +1606,13 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1603,13 +1606,13 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
((cp->state == IP_VS_SCTP_S_CLOSED) || ((cp->state == IP_VS_SCTP_S_CLOSED) ||
(cp->state == IP_VS_SCTP_S_SHUT_ACK_CLI) || (cp->state == IP_VS_SCTP_S_SHUT_ACK_CLI) ||
(cp->state == IP_VS_SCTP_S_SHUT_ACK_SER)))) { (cp->state == IP_VS_SCTP_S_SHUT_ACK_SER)))) {
ip_vs_sync_conn(cp); ip_vs_sync_conn(net, cp);
goto out; goto out;
} }
} }
/* Keep this block last: TCP and others with pp->num_states <= 1 */ /* Keep this block last: TCP and others with pp->num_states <= 1 */
else if ((ip_vs_sync_state & IP_VS_STATE_MASTER) && else if ((ipvs->sync_state & IP_VS_STATE_MASTER) &&
(((cp->protocol != IPPROTO_TCP || (((cp->protocol != IPPROTO_TCP ||
cp->state == IP_VS_TCP_S_ESTABLISHED) && cp->state == IP_VS_TCP_S_ESTABLISHED) &&
(pkts % sysctl_ip_vs_sync_threshold[1] (pkts % sysctl_ip_vs_sync_threshold[1]
...@@ -1619,7 +1622,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1619,7 +1622,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
(cp->state == IP_VS_TCP_S_CLOSE) || (cp->state == IP_VS_TCP_S_CLOSE) ||
(cp->state == IP_VS_TCP_S_CLOSE_WAIT) || (cp->state == IP_VS_TCP_S_CLOSE_WAIT) ||
(cp->state == IP_VS_TCP_S_TIME_WAIT))))) (cp->state == IP_VS_TCP_S_TIME_WAIT)))))
ip_vs_sync_conn(cp); ip_vs_sync_conn(net, cp);
out: out:
cp->old_state = cp->state; cp->old_state = cp->state;
......
...@@ -1559,7 +1559,8 @@ proc_do_sync_mode(ctl_table *table, int write, ...@@ -1559,7 +1559,8 @@ proc_do_sync_mode(ctl_table *table, int write,
/* Restore the correct value */ /* Restore the correct value */
*valp = val; *valp = val;
} else { } else {
ip_vs_sync_switch_mode(val); struct net *net = current->nsproxy->net_ns;
ip_vs_sync_switch_mode(net, val);
} }
} }
return rc; return rc;
...@@ -2174,11 +2175,12 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) ...@@ -2174,11 +2175,12 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
goto out_unlock; goto out_unlock;
} else if (cmd == IP_VS_SO_SET_STARTDAEMON) { } else if (cmd == IP_VS_SO_SET_STARTDAEMON) {
struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg; struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
ret = start_sync_thread(dm->state, dm->mcast_ifn, dm->syncid); ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
dm->syncid);
goto out_unlock; goto out_unlock;
} else if (cmd == IP_VS_SO_SET_STOPDAEMON) { } else if (cmd == IP_VS_SO_SET_STOPDAEMON) {
struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg; struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
ret = stop_sync_thread(dm->state); ret = stop_sync_thread(net, dm->state);
goto out_unlock; goto out_unlock;
} }
...@@ -2424,6 +2426,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) ...@@ -2424,6 +2426,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
int ret = 0; int ret = 0;
unsigned int copylen; unsigned int copylen;
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct netns_ipvs *ipvs = net_ipvs(net);
BUG_ON(!net); BUG_ON(!net);
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
...@@ -2546,15 +2549,17 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) ...@@ -2546,15 +2549,17 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
struct ip_vs_daemon_user d[2]; struct ip_vs_daemon_user d[2];
memset(&d, 0, sizeof(d)); memset(&d, 0, sizeof(d));
if (ip_vs_sync_state & IP_VS_STATE_MASTER) { if (ipvs->sync_state & IP_VS_STATE_MASTER) {
d[0].state = IP_VS_STATE_MASTER; d[0].state = IP_VS_STATE_MASTER;
strlcpy(d[0].mcast_ifn, ip_vs_master_mcast_ifn, sizeof(d[0].mcast_ifn)); strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
d[0].syncid = ip_vs_master_syncid; sizeof(d[0].mcast_ifn));
d[0].syncid = ipvs->master_syncid;
} }
if (ip_vs_sync_state & IP_VS_STATE_BACKUP) { if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
d[1].state = IP_VS_STATE_BACKUP; d[1].state = IP_VS_STATE_BACKUP;
strlcpy(d[1].mcast_ifn, ip_vs_backup_mcast_ifn, sizeof(d[1].mcast_ifn)); strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
d[1].syncid = ip_vs_backup_syncid; sizeof(d[1].mcast_ifn));
d[1].syncid = ipvs->backup_syncid;
} }
if (copy_to_user(user, &d, sizeof(d)) != 0) if (copy_to_user(user, &d, sizeof(d)) != 0)
ret = -EFAULT; ret = -EFAULT;
...@@ -3061,20 +3066,23 @@ static int ip_vs_genl_dump_daemon(struct sk_buff *skb, __be32 state, ...@@ -3061,20 +3066,23 @@ static int ip_vs_genl_dump_daemon(struct sk_buff *skb, __be32 state,
static int ip_vs_genl_dump_daemons(struct sk_buff *skb, static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
struct netlink_callback *cb) struct netlink_callback *cb)
{ {
struct net *net = skb_net(skb);
struct netns_ipvs *ipvs = net_ipvs(net);
mutex_lock(&__ip_vs_mutex); mutex_lock(&__ip_vs_mutex);
if ((ip_vs_sync_state & IP_VS_STATE_MASTER) && !cb->args[0]) { if ((ipvs->sync_state & IP_VS_STATE_MASTER) && !cb->args[0]) {
if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_MASTER, if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_MASTER,
ip_vs_master_mcast_ifn, ipvs->master_mcast_ifn,
ip_vs_master_syncid, cb) < 0) ipvs->master_syncid, cb) < 0)
goto nla_put_failure; goto nla_put_failure;
cb->args[0] = 1; cb->args[0] = 1;
} }
if ((ip_vs_sync_state & IP_VS_STATE_BACKUP) && !cb->args[1]) { if ((ipvs->sync_state & IP_VS_STATE_BACKUP) && !cb->args[1]) {
if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_BACKUP, if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_BACKUP,
ip_vs_backup_mcast_ifn, ipvs->backup_mcast_ifn,
ip_vs_backup_syncid, cb) < 0) ipvs->backup_syncid, cb) < 0)
goto nla_put_failure; goto nla_put_failure;
cb->args[1] = 1; cb->args[1] = 1;
...@@ -3086,24 +3094,26 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb, ...@@ -3086,24 +3094,26 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
return skb->len; return skb->len;
} }
static int ip_vs_genl_new_daemon(struct nlattr **attrs) static int ip_vs_genl_new_daemon(struct net *net, struct nlattr **attrs)
{ {
if (!(attrs[IPVS_DAEMON_ATTR_STATE] && if (!(attrs[IPVS_DAEMON_ATTR_STATE] &&
attrs[IPVS_DAEMON_ATTR_MCAST_IFN] && attrs[IPVS_DAEMON_ATTR_MCAST_IFN] &&
attrs[IPVS_DAEMON_ATTR_SYNC_ID])) attrs[IPVS_DAEMON_ATTR_SYNC_ID]))
return -EINVAL; return -EINVAL;
return start_sync_thread(nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]), return start_sync_thread(net,
nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]),
nla_data(attrs[IPVS_DAEMON_ATTR_MCAST_IFN]), nla_data(attrs[IPVS_DAEMON_ATTR_MCAST_IFN]),
nla_get_u32(attrs[IPVS_DAEMON_ATTR_SYNC_ID])); nla_get_u32(attrs[IPVS_DAEMON_ATTR_SYNC_ID]));
} }
static int ip_vs_genl_del_daemon(struct nlattr **attrs) static int ip_vs_genl_del_daemon(struct net *net, struct nlattr **attrs)
{ {
if (!attrs[IPVS_DAEMON_ATTR_STATE]) if (!attrs[IPVS_DAEMON_ATTR_STATE])
return -EINVAL; return -EINVAL;
return stop_sync_thread(nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE])); return stop_sync_thread(net,
nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]));
} }
static int ip_vs_genl_set_config(struct net *net, struct nlattr **attrs) static int ip_vs_genl_set_config(struct net *net, struct nlattr **attrs)
...@@ -3159,9 +3169,9 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) ...@@ -3159,9 +3169,9 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
} }
if (cmd == IPVS_CMD_NEW_DAEMON) if (cmd == IPVS_CMD_NEW_DAEMON)
ret = ip_vs_genl_new_daemon(daemon_attrs); ret = ip_vs_genl_new_daemon(net, daemon_attrs);
else else
ret = ip_vs_genl_del_daemon(daemon_attrs); ret = ip_vs_genl_del_daemon(net, daemon_attrs);
goto out; goto out;
} else if (cmd == IPVS_CMD_ZERO && } else if (cmd == IPVS_CMD_ZERO &&
!info->attrs[IPVS_CMD_ATTR_SERVICE]) { !info->attrs[IPVS_CMD_ATTR_SERVICE]) {
......
This diff is collapsed.
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