netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] IPVS: take care of return value from protocol init_netns
@ 2012-04-16 11:39 Hans Schillstrom
  2012-04-16 11:39 ` [PATCH 2/2] IPVS: make failure of netns init more stable Hans Schillstrom
  0 siblings, 1 reply; 9+ messages in thread
From: Hans Schillstrom @ 2012-04-16 11:39 UTC (permalink / raw)
  To: horms, ja, wensong, lvs-devel, netdev, netfilter-devel
  Cc: hans, Hans Schillstrom

ip_vs_create_timeout_table() can return NULL
All functions protocol init_netns is affected of this patch.

Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
---
 include/net/ip_vs.h                   |    2 +-
 net/netfilter/ipvs/ip_vs_proto.c      |    2 +-
 net/netfilter/ipvs/ip_vs_proto_sctp.c |    5 ++++-
 net/netfilter/ipvs/ip_vs_proto_tcp.c  |    5 ++++-
 net/netfilter/ipvs/ip_vs_proto_udp.c  |    5 ++++-
 5 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index a903a82..04e2211 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -393,7 +393,7 @@ struct ip_vs_protocol {
 
 	void (*exit)(struct ip_vs_protocol *pp);
 
-	void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
+	int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
 
 	void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd);
 
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 643ff67..c4d73c2 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -79,7 +79,7 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
 	atomic_set(&pd->appcnt, 0);	/* Init app counter */
 
 	if (pp->init_netns != NULL)
-		pp->init_netns(net, pd);
+		return pp->init_netns(net, pd);
 
 	return 0;
 }
diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c
index 1fbf7a2..9f3fb75 100644
--- a/net/netfilter/ipvs/ip_vs_proto_sctp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c
@@ -1090,7 +1090,7 @@ out:
  *   timeouts is netns related now.
  * ---------------------------------------------
  */
-static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
 	struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -1098,6 +1098,9 @@ static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd)
 	spin_lock_init(&ipvs->sctp_app_lock);
 	pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts,
 							sizeof(sctp_timeouts));
+	if (!pd->timeout_table)
+		return -ENOMEM;
+	return 0;
 }
 
 static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd)
diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index ef8641f..cd609cc 100644
--- a/net/netfilter/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp)
  *   timeouts is netns related now.
  * ---------------------------------------------
  */
-static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
 	struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -685,7 +685,10 @@ static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd)
 	spin_lock_init(&ipvs->tcp_app_lock);
 	pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts,
 							sizeof(tcp_timeouts));
+	if (!pd->timeout_table)
+		return -ENOMEM;
 	pd->tcp_state_table =  tcp_states;
+	return 0;
 }
 
 static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd)
diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index f4b7262..2fedb2d 100644
--- a/net/netfilter/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction,
 	cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL];
 }
 
-static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
+static int __udp_init(struct net *net, struct ip_vs_proto_data *pd)
 {
 	struct netns_ipvs *ipvs = net_ipvs(net);
 
@@ -475,6 +475,9 @@ static void __udp_init(struct net *net, struct ip_vs_proto_data *pd)
 	spin_lock_init(&ipvs->udp_app_lock);
 	pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts,
 							sizeof(udp_timeouts));
+	if (!pd->timeout_table)
+		return -ENOMEM;
+	return 0;
 }
 
 static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd)
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread
* Re[2]:  [PATCH 2/2] IPVS: make failure of netns init more stable
@ 2012-04-18 12:37 Hans Schillstrom
  2012-04-23 13:22 ` Simon Horman
  0 siblings, 1 reply; 9+ messages in thread
From: Hans Schillstrom @ 2012-04-18 12:37 UTC (permalink / raw)
  To: Julian Anastasov, horms@verge.net.au
  Cc: Hans Schillstrom, wensong@linux-vs.org, lvs-devel@vger.kernel.org,
	netdev@vger.kernel.org, netfilter-devel@vger.kernel.org

Hello 
>
>Hello,
>
>On Tue, 17 Apr 2012, Hans Schillstrom wrote:
>
>> I wonder if we are chasing ghosts...
>> 
>> With proper fault handling I can't even see a case when it (net->ipvs) can be used.
>> Can you see a case when it could happen?
>> Still we can set it to NULL on error exit and cleanup as you suggested, that doesn't harm I think.
>> 
>> A. If you add a netns and it fails the entire ns will be rolled back, 
>>    and no access to that ns can occur.
>>    That ns does not exist
>
>	Agreed
>
>> B. If you insert ip_vs.ko when having one or more name spaces and 
>>    __ip_vs_init() returns an error the module will be unloaded.
>>    All ready loaded ns will not be affected.
>
>	Yes, ip_vs_init fails.
>
>> C. insmod of ex. ip_vs_ftp only affects loaded name spaces
>>    and if the load of ip_vs_ftp fails it will be unloaded without affecting ip_vs(.ko)
>>    (If ip_vs.ko is not loaded then it has to be loaded first case B...)
>> 
>> With a "compiled in" ip_vs case B doesn't exist.
>
>	It is this case that can happen, we can only guess how
>difficult is to get ENOMEM here. IIRC, we can generate only
>ENOMEM error on IPVS core load.
>
>	I assume Simon has such setup and changes code to
>trigger load error. When I generate ENOMEM on IPVS core init
>for such case I get ENOENT from register_ip_vs_app when
>patch 1 and 2 for apps are applied, i.e. net->ipvs is NULL.
>You can check it with NF_CONNTRACK=y, IP_VS=y and
>IP_VS_FTP=m. You only need to trigger ENOMEM in __ip_vs_init.


I did test this with 4 netns loaded and modprobe ip_vs_ftp
In the 4:th netns  (ipvs->gen >= 4) fire a -ENOMEM 
The result was as expected, ip_vs_ftp was not loaded.

All patches below was loaded. (included the ipvs NULL check)

Just for "fun" I also added a printk in the ipvs NULL check
but I can't trigger it. 

Simon:
 do you have any possibility to test it or give me a hint how to do ?
(Just to make sure that the patches below will be sufficient)

>
>> With proper fault handling i.e. all ways returning fault codes to the netns init,
>> there is no need for checking for  "if (!net->ipvs)" or any other action.
>
>	Probably but one check on load does not hurt much.

I think I have tested all of above now and my conclusion is that we need the following patches
which also was applied when the tests was run.
(with a small reservation that I might have missed some..)

[PATCH v3 1/2] netfilter: ipvs: Verify that IP_VS protocol has been registered, Sasha Levin
[PATCH v3 2/2] netfilter: ipvs: use GFP_KERNEL allocation where possible, Sasha Levin

[PATCH 0/6] Convert some GFP_ATOMIC allocations, Julian Anastasov
[PATCH 1/6] ipvs: timeout tables do not need GFP_ATOMIC allocation, Julian Anastasov
[PATCH 2/6] ipvs: SH scheduler does not need GFP_ATOMIC allocation, Julian Anastasov
[PATCH 5/6] ipvs: LBLCR scheduler does not need GFP_ATOMIC allocation on init, Julian Anastasov
[PATCH 6/6] ipvs: WRR scheduler does not need GFP_ATOMIC allocation, Julian Anastasov
[PATCH 3/6] ipvs: DH scheduler does not need GFP_ATOMIC allocation, Julian Anastasov
[PATCH 4/6] ipvs: LBLC scheduler does not need GFP_ATOMIC allocation on init, Julian Anastasov

[PATCH] ipvs: fix crash in ip_vs_control_net_cleanup on unload, Julian Anastasov

[PATCH 1/2] ipvs: reset ipvs pointer in netns, Julian Anastasov
[PATCH 1/2] IPVS: take care of return value from protocol init_netns, Hans Schillstrom

To be safe,  add this to  [PATCH 1/2] ipvs: reset ipvs pointer in netns or make a new patch

diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index 538d74e..c757359 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -439,6 +439,9 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
        struct ip_vs_app *app;
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return ERR_PTR(-ENOENT);
+
        app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
        if (!app)
                return -ENOMEM;

diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 74c7278..1d74996 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -549,6 +549,9 @@ static int __net_init __ip_vs_lblc_init(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return ERR_PTR(-ENOENT);
+
        if (!net_eq(net, &init_net)) {
                ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
                                                sizeof(vs_vars_table),
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index 8620c68..c328ee0 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -743,6 +743,9 @@ static int __net_init __ip_vs_lblcr_init(struct net *net)
 {
        struct netns_ipvs *ipvs = net_ipvs(net);
 
+       if (!ipvs)
+               return ERR_PTR(-ENOENT);
+
        if (!net_eq(net, &init_net)) {
                ipvs->lblcr_ctl_table = kmemdup(vs_vars_table,
                                                sizeof(vs_vars_table),

>
>Regards
>
>--
>Julian Anastasov <ja@ssi.bg>

Regards
Hans Schillstrom <hans@schillstrom.com>


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-04-23 13:22 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-16 11:39 [PATCH 1/2] IPVS: take care of return value from protocol init_netns Hans Schillstrom
2012-04-16 11:39 ` [PATCH 2/2] IPVS: make failure of netns init more stable Hans Schillstrom
2012-04-16 14:25   ` Julian Anastasov
2012-04-16 17:16     ` Hans Schillstrom
2012-04-16 17:31       ` Julian Anastasov
2012-04-16 17:45         ` Hans Schillstrom
2012-04-17 11:15     ` Hans Schillstrom
2012-04-17 20:57       ` Julian Anastasov
  -- strict thread matches above, loose matches on Subject: below --
2012-04-18 12:37 Re[2]: " Hans Schillstrom
2012-04-23 13:22 ` Simon Horman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).