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 /net | |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ftp.c | 27 |
1 files changed, 19 insertions, 8 deletions
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 = { |