aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c98
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
233int 236int
234ip_vs_use_count_inc(void) 237ip_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
1515static int 1518static int
1516proc_do_defense_mode(ctl_table *table, int write, 1519proc_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
1537static int 1539static int
1538proc_do_sync_threshold(ctl_table *table, int write, 1540proc_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};
1769EXPORT_SYMBOL_GPL(net_vs_ctl_path); 1771EXPORT_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 */
3514int __net_init __ip_vs_control_init(struct net *net) 3517#ifdef CONFIG_SYSCTL
3518int __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
3577void __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
3595err_dup: 3586#else
3587
3588int __net_init __ip_vs_control_init_sysctl(struct net *net) { return 0; }
3589void __net_init __ip_vs_control_cleanup_sysctl(struct net *net) { }
3590
3591#endif
3592
3593int __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
3626err:
3596 free_percpu(ipvs->tot_stats.cpustats); 3627 free_percpu(ipvs->tot_stats.cpustats);
3597err_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");