Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -958,7 +958,7 @@ extern struct ip_vs_stats ip_vs_stats;
extern const struct ctl_path net_vs_ctl_path[];
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 *
ip_vs_service_get(struct net *net, int af, __u32 fwmark, __u16 protocol,
		  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);
 *      IPVS sync daemon data and function prototypes
 *      (from ip_vs_sync.c)
 */
extern volatile int ip_vs_sync_state;
extern volatile int ip_vs_master_syncid;
extern volatile int ip_vs_backup_syncid;
extern char ip_vs_master_mcast_ifn[IP_VS_IFNAME_MAXLEN];
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 start_sync_thread(struct net *net, int state, char *mcast_ifn,
			     __u8 syncid);
extern int stop_sync_thread(struct net *net, int state);
extern void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp);
extern int ip_vs_sync_init(void);
extern void ip_vs_sync_cleanup(void);

+16 −0
Original line number Diff line number Diff line
@@ -74,6 +74,22 @@ struct netns_ipvs {
	struct list_head	est_list;	/* estimator list */
	spinlock_t		est_lock;
	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_ */
+9 −6
Original line number Diff line number Diff line
@@ -1471,12 +1471,13 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
static unsigned int
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_protocol *pp;
	struct ip_vs_proto_data *pd;
	struct ip_vs_conn *cp;
	int ret, restart, pkts;
	struct netns_ipvs *ipvs;

	/* Already marked as IPVS request or reply? */
	if (skb->ipvs_property)
@@ -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");

	net = skb_net(skb);
	ipvs = net_ipvs(net);
	/* Check the server status */
	if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
		/* the destination server is not available */
@@ -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.
	 */

	if (cp->flags & IP_VS_CONN_F_ONE_PACKET)
		pkts = sysctl_ip_vs_sync_threshold[0];
	else
		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) {
		if ((cp->state == IP_VS_SCTP_S_ESTABLISHED &&
			(pkts % sysctl_ip_vs_sync_threshold[1]
@@ -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_SHUT_ACK_CLI) ||
				  (cp->state == IP_VS_SCTP_S_SHUT_ACK_SER)))) {
			ip_vs_sync_conn(cp);
			ip_vs_sync_conn(net, cp);
			goto out;
		}
	}

	/* 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->state == IP_VS_TCP_S_ESTABLISHED) &&
	      (pkts % sysctl_ip_vs_sync_threshold[1]
@@ -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_WAIT) ||
	       (cp->state == IP_VS_TCP_S_TIME_WAIT)))))
		ip_vs_sync_conn(cp);
		ip_vs_sync_conn(net, cp);
out:
	cp->old_state = cp->state;

+31 −21
Original line number Diff line number Diff line
@@ -1559,7 +1559,8 @@ proc_do_sync_mode(ctl_table *table, int write,
			/* Restore the correct value */
			*valp = val;
		} else {
			ip_vs_sync_switch_mode(val);
			struct net *net = current->nsproxy->net_ns;
			ip_vs_sync_switch_mode(net, val);
		}
	}
	return rc;
@@ -2174,11 +2175,12 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
		goto out_unlock;
	} else if (cmd == IP_VS_SO_SET_STARTDAEMON) {
		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;
	} else if (cmd == IP_VS_SO_SET_STOPDAEMON) {
		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;
	}

@@ -2424,6 +2426,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
	int ret = 0;
	unsigned int copylen;
	struct net *net = sock_net(sk);
	struct netns_ipvs *ipvs = net_ipvs(net);

	BUG_ON(!net);
	if (!capable(CAP_NET_ADMIN))
@@ -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];

		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;
			strlcpy(d[0].mcast_ifn, ip_vs_master_mcast_ifn, sizeof(d[0].mcast_ifn));
			d[0].syncid = ip_vs_master_syncid;
			strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
				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;
			strlcpy(d[1].mcast_ifn, ip_vs_backup_mcast_ifn, sizeof(d[1].mcast_ifn));
			d[1].syncid = ip_vs_backup_syncid;
			strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
				sizeof(d[1].mcast_ifn));
			d[1].syncid = ipvs->backup_syncid;
		}
		if (copy_to_user(user, &d, sizeof(d)) != 0)
			ret = -EFAULT;
@@ -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,
				   struct netlink_callback *cb)
{
	struct net *net = skb_net(skb);
	struct netns_ipvs *ipvs = net_ipvs(net);

	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,
					   ip_vs_master_mcast_ifn,
					   ip_vs_master_syncid, cb) < 0)
					   ipvs->master_mcast_ifn,
					   ipvs->master_syncid, cb) < 0)
			goto nla_put_failure;

		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,
					   ip_vs_backup_mcast_ifn,
					   ip_vs_backup_syncid, cb) < 0)
					   ipvs->backup_mcast_ifn,
					   ipvs->backup_syncid, cb) < 0)
			goto nla_put_failure;

		cb->args[1] = 1;
@@ -3086,24 +3094,26 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
	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] &&
	      attrs[IPVS_DAEMON_ATTR_MCAST_IFN] &&
	      attrs[IPVS_DAEMON_ATTR_SYNC_ID]))
		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_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])
		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)
@@ -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)
			ret = ip_vs_genl_new_daemon(daemon_attrs);
			ret = ip_vs_genl_new_daemon(net, daemon_attrs);
		else
			ret = ip_vs_genl_del_daemon(daemon_attrs);
			ret = ip_vs_genl_del_daemon(net, daemon_attrs);
		goto out;
	} else if (cmd == IPVS_CMD_ZERO &&
		   !info->attrs[IPVS_CMD_ATTR_SERVICE]) {
+179 −155

File changed.

Preview size limit exceeded, changes collapsed.