diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 364520f66b7a..fa6d44c62de3 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -88,6 +88,8 @@ static int __ip_vs_addr_is_local_v6(struct net *net, | |||
88 | return 0; | 88 | return 0; |
89 | } | 89 | } |
90 | #endif | 90 | #endif |
91 | |||
92 | #ifdef CONFIG_SYSCTL | ||
91 | /* | 93 | /* |
92 | * update_defense_level is called from keventd and from sysctl, | 94 | * update_defense_level is called from keventd and from sysctl, |
93 | * so it needs to protect itself from softirqs | 95 | * so it needs to protect itself from softirqs |
@@ -229,6 +231,7 @@ static void defense_work_handler(struct work_struct *work) | |||
229 | ip_vs_random_dropentry(ipvs->net); | 231 | ip_vs_random_dropentry(ipvs->net); |
230 | schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD); | 232 | schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD); |
231 | } | 233 | } |
234 | #endif | ||
232 | 235 | ||
233 | int | 236 | int |
234 | ip_vs_use_count_inc(void) | 237 | ip_vs_use_count_inc(void) |
@@ -1511,7 +1514,7 @@ static int ip_vs_zero_all(struct net *net) | |||
1511 | return 0; | 1514 | return 0; |
1512 | } | 1515 | } |
1513 | 1516 | ||
1514 | 1517 | #ifdef CONFIG_SYSCTL | |
1515 | static int | 1518 | static int |
1516 | proc_do_defense_mode(ctl_table *table, int write, | 1519 | proc_do_defense_mode(ctl_table *table, int write, |
1517 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1520 | void __user *buffer, size_t *lenp, loff_t *ppos) |
@@ -1533,7 +1536,6 @@ proc_do_defense_mode(ctl_table *table, int write, | |||
1533 | return rc; | 1536 | return rc; |
1534 | } | 1537 | } |
1535 | 1538 | ||
1536 | |||
1537 | static int | 1539 | static int |
1538 | proc_do_sync_threshold(ctl_table *table, int write, | 1540 | proc_do_sync_threshold(ctl_table *table, int write, |
1539 | void __user *buffer, size_t *lenp, loff_t *ppos) | 1541 | void __user *buffer, size_t *lenp, loff_t *ppos) |
@@ -1767,6 +1769,7 @@ const struct ctl_path net_vs_ctl_path[] = { | |||
1767 | { } | 1769 | { } |
1768 | }; | 1770 | }; |
1769 | EXPORT_SYMBOL_GPL(net_vs_ctl_path); | 1771 | EXPORT_SYMBOL_GPL(net_vs_ctl_path); |
1772 | #endif | ||
1770 | 1773 | ||
1771 | #ifdef CONFIG_PROC_FS | 1774 | #ifdef CONFIG_PROC_FS |
1772 | 1775 | ||
@@ -3511,7 +3514,8 @@ static void ip_vs_genl_unregister(void) | |||
3511 | /* | 3514 | /* |
3512 | * per netns intit/exit func. | 3515 | * per netns intit/exit func. |
3513 | */ | 3516 | */ |
3514 | int __net_init __ip_vs_control_init(struct net *net) | 3517 | #ifdef CONFIG_SYSCTL |
3518 | int __net_init __ip_vs_control_init_sysctl(struct net *net) | ||
3515 | { | 3519 | { |
3516 | int idx; | 3520 | int idx; |
3517 | struct netns_ipvs *ipvs = net_ipvs(net); | 3521 | struct netns_ipvs *ipvs = net_ipvs(net); |
@@ -3521,33 +3525,11 @@ int __net_init __ip_vs_control_init(struct net *net) | |||
3521 | spin_lock_init(&ipvs->dropentry_lock); | 3525 | spin_lock_init(&ipvs->dropentry_lock); |
3522 | spin_lock_init(&ipvs->droppacket_lock); | 3526 | spin_lock_init(&ipvs->droppacket_lock); |
3523 | spin_lock_init(&ipvs->securetcp_lock); | 3527 | spin_lock_init(&ipvs->securetcp_lock); |
3524 | ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock); | ||
3525 | |||
3526 | /* Initialize rs_table */ | ||
3527 | for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++) | ||
3528 | INIT_LIST_HEAD(&ipvs->rs_table[idx]); | ||
3529 | |||
3530 | INIT_LIST_HEAD(&ipvs->dest_trash); | ||
3531 | atomic_set(&ipvs->ftpsvc_counter, 0); | ||
3532 | atomic_set(&ipvs->nullsvc_counter, 0); | ||
3533 | |||
3534 | /* procfs stats */ | ||
3535 | ipvs->tot_stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); | ||
3536 | if (!ipvs->tot_stats.cpustats) { | ||
3537 | pr_err("%s() alloc_percpu failed\n", __func__); | ||
3538 | goto err_alloc; | ||
3539 | } | ||
3540 | spin_lock_init(&ipvs->tot_stats.lock); | ||
3541 | |||
3542 | proc_net_fops_create(net, "ip_vs", 0, &ip_vs_info_fops); | ||
3543 | proc_net_fops_create(net, "ip_vs_stats", 0, &ip_vs_stats_fops); | ||
3544 | proc_net_fops_create(net, "ip_vs_stats_percpu", 0, | ||
3545 | &ip_vs_stats_percpu_fops); | ||
3546 | 3528 | ||
3547 | if (!net_eq(net, &init_net)) { | 3529 | if (!net_eq(net, &init_net)) { |
3548 | tbl = kmemdup(vs_vars, sizeof(vs_vars), GFP_KERNEL); | 3530 | tbl = kmemdup(vs_vars, sizeof(vs_vars), GFP_KERNEL); |
3549 | if (tbl == NULL) | 3531 | if (tbl == NULL) |
3550 | goto err_dup; | 3532 | return -ENOMEM; |
3551 | } else | 3533 | } else |
3552 | tbl = vs_vars; | 3534 | tbl = vs_vars; |
3553 | /* Initialize sysctl defaults */ | 3535 | /* Initialize sysctl defaults */ |
@@ -3576,25 +3558,73 @@ int __net_init __ip_vs_control_init(struct net *net) | |||
3576 | tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; | 3558 | tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; |
3577 | 3559 | ||
3578 | 3560 | ||
3579 | #ifdef CONFIG_SYSCTL | ||
3580 | ipvs->sysctl_hdr = register_net_sysctl_table(net, net_vs_ctl_path, | 3561 | ipvs->sysctl_hdr = register_net_sysctl_table(net, net_vs_ctl_path, |
3581 | tbl); | 3562 | tbl); |
3582 | if (ipvs->sysctl_hdr == NULL) { | 3563 | if (ipvs->sysctl_hdr == NULL) { |
3583 | if (!net_eq(net, &init_net)) | 3564 | if (!net_eq(net, &init_net)) |
3584 | kfree(tbl); | 3565 | kfree(tbl); |
3585 | goto err_dup; | 3566 | return -ENOMEM; |
3586 | } | 3567 | } |
3587 | #endif | ||
3588 | ip_vs_start_estimator(net, &ipvs->tot_stats); | 3568 | ip_vs_start_estimator(net, &ipvs->tot_stats); |
3589 | ipvs->sysctl_tbl = tbl; | 3569 | ipvs->sysctl_tbl = tbl; |
3590 | /* Schedule defense work */ | 3570 | /* Schedule defense work */ |
3591 | INIT_DELAYED_WORK(&ipvs->defense_work, defense_work_handler); | 3571 | INIT_DELAYED_WORK(&ipvs->defense_work, defense_work_handler); |
3592 | schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD); | 3572 | schedule_delayed_work(&ipvs->defense_work, DEFENSE_TIMER_PERIOD); |
3573 | |||
3593 | return 0; | 3574 | return 0; |
3575 | } | ||
3576 | |||
3577 | void __net_init __ip_vs_control_cleanup_sysctl(struct net *net) | ||
3578 | { | ||
3579 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
3580 | |||
3581 | cancel_delayed_work_sync(&ipvs->defense_work); | ||
3582 | cancel_work_sync(&ipvs->defense_work.work); | ||
3583 | unregister_net_sysctl_table(ipvs->sysctl_hdr); | ||
3584 | } | ||
3594 | 3585 | ||
3595 | err_dup: | 3586 | #else |
3587 | |||
3588 | int __net_init __ip_vs_control_init_sysctl(struct net *net) { return 0; } | ||
3589 | void __net_init __ip_vs_control_cleanup_sysctl(struct net *net) { } | ||
3590 | |||
3591 | #endif | ||
3592 | |||
3593 | int __net_init __ip_vs_control_init(struct net *net) | ||
3594 | { | ||
3595 | int idx; | ||
3596 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
3597 | |||
3598 | ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock); | ||
3599 | |||
3600 | /* Initialize rs_table */ | ||
3601 | for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++) | ||
3602 | INIT_LIST_HEAD(&ipvs->rs_table[idx]); | ||
3603 | |||
3604 | INIT_LIST_HEAD(&ipvs->dest_trash); | ||
3605 | atomic_set(&ipvs->ftpsvc_counter, 0); | ||
3606 | atomic_set(&ipvs->nullsvc_counter, 0); | ||
3607 | |||
3608 | /* procfs stats */ | ||
3609 | ipvs->tot_stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); | ||
3610 | if (ipvs->tot_stats.cpustats) { | ||
3611 | pr_err("%s(): alloc_percpu.\n", __func__); | ||
3612 | return -ENOMEM; | ||
3613 | } | ||
3614 | spin_lock_init(&ipvs->tot_stats.lock); | ||
3615 | |||
3616 | proc_net_fops_create(net, "ip_vs", 0, &ip_vs_info_fops); | ||
3617 | proc_net_fops_create(net, "ip_vs_stats", 0, &ip_vs_stats_fops); | ||
3618 | proc_net_fops_create(net, "ip_vs_stats_percpu", 0, | ||
3619 | &ip_vs_stats_percpu_fops); | ||
3620 | |||
3621 | if (__ip_vs_control_init_sysctl(net)) | ||
3622 | goto err; | ||
3623 | |||
3624 | return 0; | ||
3625 | |||
3626 | err: | ||
3596 | free_percpu(ipvs->tot_stats.cpustats); | 3627 | free_percpu(ipvs->tot_stats.cpustats); |
3597 | err_alloc: | ||
3598 | return -ENOMEM; | 3628 | return -ENOMEM; |
3599 | } | 3629 | } |
3600 | 3630 | ||
@@ -3604,11 +3634,7 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net) | |||
3604 | 3634 | ||
3605 | ip_vs_trash_cleanup(net); | 3635 | ip_vs_trash_cleanup(net); |
3606 | ip_vs_stop_estimator(net, &ipvs->tot_stats); | 3636 | ip_vs_stop_estimator(net, &ipvs->tot_stats); |
3607 | cancel_delayed_work_sync(&ipvs->defense_work); | 3637 | __ip_vs_control_cleanup_sysctl(net); |
3608 | cancel_work_sync(&ipvs->defense_work.work); | ||
3609 | #ifdef CONFIG_SYSCTL | ||
3610 | unregister_net_sysctl_table(ipvs->sysctl_hdr); | ||
3611 | #endif | ||
3612 | proc_net_remove(net, "ip_vs_stats_percpu"); | 3638 | proc_net_remove(net, "ip_vs_stats_percpu"); |
3613 | proc_net_remove(net, "ip_vs_stats"); | 3639 | proc_net_remove(net, "ip_vs_stats"); |
3614 | proc_net_remove(net, "ip_vs"); | 3640 | proc_net_remove(net, "ip_vs"); |