diff options
author | Hans Schillstrom <hans.schillstrom@ericsson.com> | 2011-05-24 08:11:05 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2011-05-27 07:37:46 -0400 |
commit | c74c0bfe0b61cf41a897c2444c038e0d3f600556 (patch) | |
tree | b8cbcf85abee59f44a6397db6ff3214c60f5c700 | |
parent | 97242c85a2c8160eac5a6e945209b5b6ae8ab5a3 (diff) |
IPVS: bug in ip_vs_ftp, same list heaad used in all netns.
When ip_vs was adapted to netns the ftp application was not adapted
in a correct way.
However this is a fix to avoid kernel errors. In the long term another solution
might be chosen. I.e the ports that the ftp appl, uses should be per netns.
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | include/net/ip_vs.h | 3 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ftp.c | 27 |
2 files changed, 21 insertions, 9 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 4fff432aeade..481f856c650f 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -797,7 +797,8 @@ struct netns_ipvs { | |||
797 | struct list_head rs_table[IP_VS_RTAB_SIZE]; | 797 | struct list_head rs_table[IP_VS_RTAB_SIZE]; |
798 | /* ip_vs_app */ | 798 | /* ip_vs_app */ |
799 | struct list_head app_list; | 799 | struct list_head app_list; |
800 | 800 | /* ip_vs_ftp */ | |
801 | struct ip_vs_app *ftp_app; | ||
801 | /* ip_vs_proto */ | 802 | /* ip_vs_proto */ |
802 | #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ | 803 | #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ |
803 | struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; | 804 | struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; |
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index 6b5dd6ddaae9..af63553fa332 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c | |||
@@ -411,25 +411,35 @@ static struct ip_vs_app ip_vs_ftp = { | |||
411 | static int __net_init __ip_vs_ftp_init(struct net *net) | 411 | static int __net_init __ip_vs_ftp_init(struct net *net) |
412 | { | 412 | { |
413 | int i, ret; | 413 | int i, ret; |
414 | struct ip_vs_app *app = &ip_vs_ftp; | 414 | struct ip_vs_app *app; |
415 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
416 | |||
417 | app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL); | ||
418 | if (!app) | ||
419 | return -ENOMEM; | ||
420 | INIT_LIST_HEAD(&app->a_list); | ||
421 | INIT_LIST_HEAD(&app->incs_list); | ||
422 | ipvs->ftp_app = app; | ||
415 | 423 | ||
416 | ret = register_ip_vs_app(net, app); | 424 | ret = register_ip_vs_app(net, app); |
417 | if (ret) | 425 | if (ret) |
418 | return ret; | 426 | goto err_exit; |
419 | 427 | ||
420 | for (i=0; i<IP_VS_APP_MAX_PORTS; i++) { | 428 | for (i=0; i<IP_VS_APP_MAX_PORTS; i++) { |
421 | if (!ports[i]) | 429 | if (!ports[i]) |
422 | continue; | 430 | continue; |
423 | ret = register_ip_vs_app_inc(net, app, app->protocol, ports[i]); | 431 | ret = register_ip_vs_app_inc(net, app, app->protocol, ports[i]); |
424 | if (ret) | 432 | if (ret) |
425 | break; | 433 | goto err_unreg; |
426 | pr_info("%s: loaded support on port[%d] = %d\n", | 434 | pr_info("%s: loaded support on port[%d] = %d\n", |
427 | app->name, i, ports[i]); | 435 | app->name, i, ports[i]); |
428 | } | 436 | } |
437 | return 0; | ||
429 | 438 | ||
430 | if (ret) | 439 | err_unreg: |
431 | unregister_ip_vs_app(net, app); | 440 | unregister_ip_vs_app(net, app); |
432 | 441 | err_exit: | |
442 | kfree(ipvs->ftp_app); | ||
433 | return ret; | 443 | return ret; |
434 | } | 444 | } |
435 | /* | 445 | /* |
@@ -437,9 +447,10 @@ static int __net_init __ip_vs_ftp_init(struct net *net) | |||
437 | */ | 447 | */ |
438 | static void __ip_vs_ftp_exit(struct net *net) | 448 | static void __ip_vs_ftp_exit(struct net *net) |
439 | { | 449 | { |
440 | struct ip_vs_app *app = &ip_vs_ftp; | 450 | struct netns_ipvs *ipvs = net_ipvs(net); |
441 | 451 | ||
442 | unregister_ip_vs_app(net, app); | 452 | unregister_ip_vs_app(net, ipvs->ftp_app); |
453 | kfree(ipvs->ftp_app); | ||
443 | } | 454 | } |
444 | 455 | ||
445 | static struct pernet_operations ip_vs_ftp_ops = { | 456 | static struct pernet_operations ip_vs_ftp_ops = { |