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

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

IPVS: netns awareness to ip_vs_app



All variables moved to struct ipvs,
most external changes fixed (i.e. init_net removed)

in ip_vs_protocol param struct net *net added to:
 - register_app()
 - unregister_app()
This affected almost all proto_xxx.c files

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 9bbac6a9
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -402,9 +402,9 @@ struct ip_vs_protocol {
				const struct sk_buff *skb,
				const struct sk_buff *skb,
				struct ip_vs_proto_data *pd);
				struct ip_vs_proto_data *pd);


	int (*register_app)(struct ip_vs_app *inc);
	int (*register_app)(struct net *net, struct ip_vs_app *inc);


	void (*unregister_app)(struct ip_vs_app *inc);
	void (*unregister_app)(struct net *net, struct ip_vs_app *inc);


	int (*app_conn_bind)(struct ip_vs_conn *cp);
	int (*app_conn_bind)(struct ip_vs_conn *cp);


@@ -871,12 +871,12 @@ ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
 *      (from ip_vs_app.c)
 *      (from ip_vs_app.c)
 */
 */
#define IP_VS_APP_MAX_PORTS  8
#define IP_VS_APP_MAX_PORTS  8
extern int register_ip_vs_app(struct ip_vs_app *app);
extern int register_ip_vs_app(struct net *net, struct ip_vs_app *app);
extern void unregister_ip_vs_app(struct ip_vs_app *app);
extern void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app);
extern int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
extern int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
extern void ip_vs_unbind_app(struct ip_vs_conn *cp);
extern void ip_vs_unbind_app(struct ip_vs_conn *cp);
extern int
extern int register_ip_vs_app_inc(struct net *net, struct ip_vs_app *app,
register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port);
				  __u16 proto, __u16 port);
extern int ip_vs_app_inc_get(struct ip_vs_app *inc);
extern int ip_vs_app_inc_get(struct ip_vs_app *inc);
extern void ip_vs_app_inc_put(struct ip_vs_app *inc);
extern void ip_vs_app_inc_put(struct ip_vs_app *inc);


+5 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,11 @@ struct netns_ipvs {
	#define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1)
	#define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1)


	struct list_head	rs_table[IP_VS_RTAB_SIZE];
	struct list_head	rs_table[IP_VS_RTAB_SIZE];
	/* ip_vs_app */
	struct list_head	app_list;
	struct mutex		app_mutex;
	struct lock_class_key	app_key;	/* mutex debuging */

	/* ip_vs_proto */
	/* ip_vs_proto */
	#define IP_VS_PROTO_TAB_SIZE	32	/* must be power of 2 */
	#define IP_VS_PROTO_TAB_SIZE	32	/* must be power of 2 */
	struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE];
	struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE];
+43 −30
Original line number Original line Diff line number Diff line
@@ -43,11 +43,6 @@ EXPORT_SYMBOL(register_ip_vs_app);
EXPORT_SYMBOL(unregister_ip_vs_app);
EXPORT_SYMBOL(unregister_ip_vs_app);
EXPORT_SYMBOL(register_ip_vs_app_inc);
EXPORT_SYMBOL(register_ip_vs_app_inc);


/* ipvs application list head */
static LIST_HEAD(ip_vs_app_list);
static DEFINE_MUTEX(__ip_vs_app_mutex);


/*
/*
 *	Get an ip_vs_app object
 *	Get an ip_vs_app object
 */
 */
@@ -67,7 +62,8 @@ static inline void ip_vs_app_put(struct ip_vs_app *app)
 *	Allocate/initialize app incarnation and register it in proto apps.
 *	Allocate/initialize app incarnation and register it in proto apps.
 */
 */
static int
static int
ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
ip_vs_app_inc_new(struct net *net, struct ip_vs_app *app, __u16 proto,
		  __u16 port)
{
{
	struct ip_vs_protocol *pp;
	struct ip_vs_protocol *pp;
	struct ip_vs_app *inc;
	struct ip_vs_app *inc;
@@ -98,7 +94,7 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
		}
		}
	}
	}


	ret = pp->register_app(inc);
	ret = pp->register_app(net, inc);
	if (ret)
	if (ret)
		goto out;
		goto out;


@@ -119,7 +115,7 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
 *	Release app incarnation
 *	Release app incarnation
 */
 */
static void
static void
ip_vs_app_inc_release(struct ip_vs_app *inc)
ip_vs_app_inc_release(struct net *net, struct ip_vs_app *inc)
{
{
	struct ip_vs_protocol *pp;
	struct ip_vs_protocol *pp;


@@ -127,7 +123,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc)
		return;
		return;


	if (pp->unregister_app)
	if (pp->unregister_app)
		pp->unregister_app(inc);
		pp->unregister_app(net, inc);


	IP_VS_DBG(9, "%s App %s:%u unregistered\n",
	IP_VS_DBG(9, "%s App %s:%u unregistered\n",
		  pp->name, inc->name, ntohs(inc->port));
		  pp->name, inc->name, ntohs(inc->port));
@@ -168,15 +164,17 @@ void ip_vs_app_inc_put(struct ip_vs_app *inc)
 *	Register an application incarnation in protocol applications
 *	Register an application incarnation in protocol applications
 */
 */
int
int
register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port)
register_ip_vs_app_inc(struct net *net, struct ip_vs_app *app, __u16 proto,
		       __u16 port)
{
{
	struct netns_ipvs *ipvs = net_ipvs(net);
	int result;
	int result;


	mutex_lock(&__ip_vs_app_mutex);
	mutex_lock(&ipvs->app_mutex);


	result = ip_vs_app_inc_new(app, proto, port);
	result = ip_vs_app_inc_new(net, app, proto, port);


	mutex_unlock(&__ip_vs_app_mutex);
	mutex_unlock(&ipvs->app_mutex);


	return result;
	return result;
}
}
@@ -185,16 +183,17 @@ register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port)
/*
/*
 *	ip_vs_app registration routine
 *	ip_vs_app registration routine
 */
 */
int register_ip_vs_app(struct ip_vs_app *app)
int register_ip_vs_app(struct net *net, struct ip_vs_app *app)
{
{
	struct netns_ipvs *ipvs = net_ipvs(net);
	/* increase the module use count */
	/* increase the module use count */
	ip_vs_use_count_inc();
	ip_vs_use_count_inc();


	mutex_lock(&__ip_vs_app_mutex);
	mutex_lock(&ipvs->app_mutex);


	list_add(&app->a_list, &ip_vs_app_list);
	list_add(&app->a_list, &ipvs->app_list);


	mutex_unlock(&__ip_vs_app_mutex);
	mutex_unlock(&ipvs->app_mutex);


	return 0;
	return 0;
}
}
@@ -204,19 +203,20 @@ int register_ip_vs_app(struct ip_vs_app *app)
 *	ip_vs_app unregistration routine
 *	ip_vs_app unregistration routine
 *	We are sure there are no app incarnations attached to services
 *	We are sure there are no app incarnations attached to services
 */
 */
void unregister_ip_vs_app(struct ip_vs_app *app)
void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app)
{
{
	struct netns_ipvs *ipvs = net_ipvs(net);
	struct ip_vs_app *inc, *nxt;
	struct ip_vs_app *inc, *nxt;


	mutex_lock(&__ip_vs_app_mutex);
	mutex_lock(&ipvs->app_mutex);


	list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) {
	list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) {
		ip_vs_app_inc_release(inc);
		ip_vs_app_inc_release(net, inc);
	}
	}


	list_del(&app->a_list);
	list_del(&app->a_list);


	mutex_unlock(&__ip_vs_app_mutex);
	mutex_unlock(&ipvs->app_mutex);


	/* decrease the module use count */
	/* decrease the module use count */
	ip_vs_use_count_dec();
	ip_vs_use_count_dec();
@@ -226,7 +226,8 @@ void unregister_ip_vs_app(struct ip_vs_app *app)
/*
/*
 *	Bind ip_vs_conn to its ip_vs_app (called by cp constructor)
 *	Bind ip_vs_conn to its ip_vs_app (called by cp constructor)
 */
 */
int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp)
int ip_vs_bind_app(struct ip_vs_conn *cp,
		   struct ip_vs_protocol *pp)
{
{
	return pp->app_conn_bind(cp);
	return pp->app_conn_bind(cp);
}
}
@@ -481,11 +482,11 @@ int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb)
 *	/proc/net/ip_vs_app entry function
 *	/proc/net/ip_vs_app entry function
 */
 */


static struct ip_vs_app *ip_vs_app_idx(loff_t pos)
static struct ip_vs_app *ip_vs_app_idx(struct netns_ipvs *ipvs, loff_t pos)
{
{
	struct ip_vs_app *app, *inc;
	struct ip_vs_app *app, *inc;


	list_for_each_entry(app, &ip_vs_app_list, a_list) {
	list_for_each_entry(app, &ipvs->app_list, a_list) {
		list_for_each_entry(inc, &app->incs_list, a_list) {
		list_for_each_entry(inc, &app->incs_list, a_list) {
			if (pos-- == 0)
			if (pos-- == 0)
				return inc;
				return inc;
@@ -497,19 +498,24 @@ static struct ip_vs_app *ip_vs_app_idx(loff_t pos)


static void *ip_vs_app_seq_start(struct seq_file *seq, loff_t *pos)
static void *ip_vs_app_seq_start(struct seq_file *seq, loff_t *pos)
{
{
	mutex_lock(&__ip_vs_app_mutex);
	struct net *net = seq_file_net(seq);
	struct netns_ipvs *ipvs = net_ipvs(net);

	mutex_lock(&ipvs->app_mutex);


	return *pos ? ip_vs_app_idx(*pos - 1) : SEQ_START_TOKEN;
	return *pos ? ip_vs_app_idx(ipvs, *pos - 1) : SEQ_START_TOKEN;
}
}


static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
{
	struct ip_vs_app *inc, *app;
	struct ip_vs_app *inc, *app;
	struct list_head *e;
	struct list_head *e;
	struct net *net = seq_file_net(seq);
	struct netns_ipvs *ipvs = net_ipvs(net);


	++*pos;
	++*pos;
	if (v == SEQ_START_TOKEN)
	if (v == SEQ_START_TOKEN)
		return ip_vs_app_idx(0);
		return ip_vs_app_idx(ipvs, 0);


	inc = v;
	inc = v;
	app = inc->app;
	app = inc->app;
@@ -518,7 +524,7 @@ static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos)
		return list_entry(e, struct ip_vs_app, a_list);
		return list_entry(e, struct ip_vs_app, a_list);


	/* go on to next application */
	/* go on to next application */
	for (e = app->a_list.next; e != &ip_vs_app_list; e = e->next) {
	for (e = app->a_list.next; e != &ipvs->app_list; e = e->next) {
		app = list_entry(e, struct ip_vs_app, a_list);
		app = list_entry(e, struct ip_vs_app, a_list);
		list_for_each_entry(inc, &app->incs_list, a_list) {
		list_for_each_entry(inc, &app->incs_list, a_list) {
			return inc;
			return inc;
@@ -529,7 +535,9 @@ static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos)


static void ip_vs_app_seq_stop(struct seq_file *seq, void *v)
static void ip_vs_app_seq_stop(struct seq_file *seq, void *v)
{
{
	mutex_unlock(&__ip_vs_app_mutex);
	struct netns_ipvs *ipvs = net_ipvs(seq_file_net(seq));

	mutex_unlock(&ipvs->app_mutex);
}
}


static int ip_vs_app_seq_show(struct seq_file *seq, void *v)
static int ip_vs_app_seq_show(struct seq_file *seq, void *v)
@@ -557,7 +565,8 @@ static const struct seq_operations ip_vs_app_seq_ops = {


static int ip_vs_app_open(struct inode *inode, struct file *file)
static int ip_vs_app_open(struct inode *inode, struct file *file)
{
{
	return seq_open(file, &ip_vs_app_seq_ops);
	return seq_open_net(inode, file, &ip_vs_app_seq_ops,
			    sizeof(struct seq_net_private));
}
}


static const struct file_operations ip_vs_app_fops = {
static const struct file_operations ip_vs_app_fops = {
@@ -571,9 +580,13 @@ static const struct file_operations ip_vs_app_fops = {


static int __net_init __ip_vs_app_init(struct net *net)
static int __net_init __ip_vs_app_init(struct net *net)
{
{
	struct netns_ipvs *ipvs = net_ipvs(net);

	if (!net_eq(net, &init_net))	/* netns not enabled yet */
	if (!net_eq(net, &init_net))	/* netns not enabled yet */
		return -EPERM;
		return -EPERM;


	INIT_LIST_HEAD(&ipvs->app_list);
	__mutex_init(&ipvs->app_mutex, "ipvs->app_mutex", &ipvs->app_key);
	proc_net_fops_create(net, "ip_vs_app", 0, &ip_vs_app_fops);
	proc_net_fops_create(net, "ip_vs_app", 0, &ip_vs_app_fops);
	return 0;
	return 0;
}
}
+4 −4
Original line number Original line Diff line number Diff line
@@ -414,14 +414,14 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
	if (!net_eq(net, &init_net))	/* netns not enabled yet */
	if (!net_eq(net, &init_net))	/* netns not enabled yet */
		return -EPERM;
		return -EPERM;


	ret = register_ip_vs_app(app);
	ret = register_ip_vs_app(net, app);
	if (ret)
	if (ret)
		return ret;
		return ret;


	for (i=0; i<IP_VS_APP_MAX_PORTS; i++) {
	for (i=0; i<IP_VS_APP_MAX_PORTS; i++) {
		if (!ports[i])
		if (!ports[i])
			continue;
			continue;
		ret = register_ip_vs_app_inc(app, app->protocol, ports[i]);
		ret = register_ip_vs_app_inc(net, app, app->protocol, ports[i]);
		if (ret)
		if (ret)
			break;
			break;
		pr_info("%s: loaded support on port[%d] = %d\n",
		pr_info("%s: loaded support on port[%d] = %d\n",
@@ -429,7 +429,7 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
	}
	}


	if (ret)
	if (ret)
		unregister_ip_vs_app(app);
		unregister_ip_vs_app(net, app);


	return ret;
	return ret;
}
}
@@ -443,7 +443,7 @@ static void __ip_vs_ftp_exit(struct net *net)
	if (!net_eq(net, &init_net))	/* netns not enabled yet */
	if (!net_eq(net, &init_net))	/* netns not enabled yet */
		return;
		return;


	unregister_ip_vs_app(app);
	unregister_ip_vs_app(net, app);
}
}


static struct pernet_operations ip_vs_ftp_ops = {
static struct pernet_operations ip_vs_ftp_ops = {
+6 −6
Original line number Original line Diff line number Diff line
@@ -1016,14 +1016,14 @@ static inline __u16 sctp_app_hashkey(__be16 port)
		& SCTP_APP_TAB_MASK;
		& SCTP_APP_TAB_MASK;
}
}


static int sctp_register_app(struct ip_vs_app *inc)
static int sctp_register_app(struct net *net, struct ip_vs_app *inc)
{
{
	struct ip_vs_app *i;
	struct ip_vs_app *i;
	__u16 hash;
	__u16 hash;
	__be16 port = inc->port;
	__be16 port = inc->port;
	int ret = 0;
	int ret = 0;
	struct netns_ipvs *ipvs = net_ipvs(&init_net);
	struct netns_ipvs *ipvs = net_ipvs(net);
	struct ip_vs_proto_data *pd = ip_vs_proto_data_get(&init_net, IPPROTO_SCTP);
	struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);


	hash = sctp_app_hashkey(port);
	hash = sctp_app_hashkey(port);


@@ -1042,10 +1042,10 @@ out:
	return ret;
	return ret;
}
}


static void sctp_unregister_app(struct ip_vs_app *inc)
static void sctp_unregister_app(struct net *net, struct ip_vs_app *inc)
{
{
	struct netns_ipvs *ipvs = net_ipvs(&init_net);
	struct netns_ipvs *ipvs = net_ipvs(net);
	struct ip_vs_proto_data *pd = ip_vs_proto_data_get(&init_net, IPPROTO_SCTP);
	struct ip_vs_proto_data *pd = ip_vs_proto_data_get(net, IPPROTO_SCTP);


	spin_lock_bh(&ipvs->sctp_app_lock);
	spin_lock_bh(&ipvs->sctp_app_lock);
	atomic_dec(&pd->appcnt);
	atomic_dec(&pd->appcnt);
Loading