aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/ip_vs.h4
-rw-r--r--net/netfilter/ipvs/ip_vs_lblc.c50
2 files changed, 38 insertions, 16 deletions
diff --git a/include/net/netns/ip_vs.h b/include/net/netns/ip_vs.h
index 51a92ee1b167..d14581cc4fe0 100644
--- a/include/net/netns/ip_vs.h
+++ b/include/net/netns/ip_vs.h
@@ -29,6 +29,10 @@ struct netns_ipvs {
29 29
30 struct list_head rs_table[IP_VS_RTAB_SIZE]; 30 struct list_head rs_table[IP_VS_RTAB_SIZE];
31 31
32 /* ip_vs_lblc */
33 int sysctl_lblc_expiration;
34 struct ctl_table_header *lblc_ctl_header;
35 struct ctl_table *lblc_ctl_table;
32 /* ip_vs_lblcr */ 36 /* ip_vs_lblcr */
33 int sysctl_lblcr_expiration; 37 int sysctl_lblcr_expiration;
34 struct ctl_table_header *lblcr_ctl_header; 38 struct ctl_table_header *lblcr_ctl_header;
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 84278fb4e055..d5bec3371871 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -70,7 +70,6 @@
70 * entries that haven't been touched for a day. 70 * entries that haven't been touched for a day.
71 */ 71 */
72#define COUNT_FOR_FULL_EXPIRATION 30 72#define COUNT_FOR_FULL_EXPIRATION 30
73static int sysctl_ip_vs_lblc_expiration = 24*60*60*HZ;
74 73
75 74
76/* 75/*
@@ -117,7 +116,7 @@ struct ip_vs_lblc_table {
117static ctl_table vs_vars_table[] = { 116static ctl_table vs_vars_table[] = {
118 { 117 {
119 .procname = "lblc_expiration", 118 .procname = "lblc_expiration",
120 .data = &sysctl_ip_vs_lblc_expiration, 119 .data = NULL,
121 .maxlen = sizeof(int), 120 .maxlen = sizeof(int),
122 .mode = 0644, 121 .mode = 0644,
123 .proc_handler = proc_dointvec_jiffies, 122 .proc_handler = proc_dointvec_jiffies,
@@ -125,8 +124,6 @@ static ctl_table vs_vars_table[] = {
125 { } 124 { }
126}; 125};
127 126
128static struct ctl_table_header * sysctl_header;
129
130static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en) 127static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en)
131{ 128{
132 list_del(&en->list); 129 list_del(&en->list);
@@ -248,6 +245,7 @@ static inline void ip_vs_lblc_full_check(struct ip_vs_service *svc)
248 struct ip_vs_lblc_entry *en, *nxt; 245 struct ip_vs_lblc_entry *en, *nxt;
249 unsigned long now = jiffies; 246 unsigned long now = jiffies;
250 int i, j; 247 int i, j;
248 struct netns_ipvs *ipvs = net_ipvs(svc->net);
251 249
252 for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) { 250 for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
253 j = (j + 1) & IP_VS_LBLC_TAB_MASK; 251 j = (j + 1) & IP_VS_LBLC_TAB_MASK;
@@ -255,7 +253,8 @@ static inline void ip_vs_lblc_full_check(struct ip_vs_service *svc)
255 write_lock(&svc->sched_lock); 253 write_lock(&svc->sched_lock);
256 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) { 254 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
257 if (time_before(now, 255 if (time_before(now,
258 en->lastuse + sysctl_ip_vs_lblc_expiration)) 256 en->lastuse +
257 ipvs->sysctl_lblc_expiration))
259 continue; 258 continue;
260 259
261 ip_vs_lblc_free(en); 260 ip_vs_lblc_free(en);
@@ -548,23 +547,43 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
548 */ 547 */
549static int __net_init __ip_vs_lblc_init(struct net *net) 548static int __net_init __ip_vs_lblc_init(struct net *net)
550{ 549{
551 if (!net_eq(net, &init_net)) /* netns not enabled yet */ 550 struct netns_ipvs *ipvs = net_ipvs(net);
552 return -EPERM; 551
553 552 if (!net_eq(net, &init_net)) {
554 sysctl_header = register_net_sysctl_table(net, net_vs_ctl_path, 553 ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
555 vs_vars_table); 554 sizeof(vs_vars_table),
556 if (!sysctl_header) 555 GFP_KERNEL);
557 return -ENOMEM; 556 if (ipvs->lblc_ctl_table == NULL)
557 goto err_dup;
558 } else
559 ipvs->lblc_ctl_table = vs_vars_table;
560 ipvs->sysctl_lblc_expiration = 24*60*60*HZ;
561 ipvs->lblc_ctl_table[0].data = &ipvs->sysctl_lblc_expiration;
562
563 ipvs->lblc_ctl_header =
564 register_net_sysctl_table(net, net_vs_ctl_path,
565 ipvs->lblc_ctl_table);
566 if (!ipvs->lblc_ctl_header)
567 goto err_reg;
558 568
559 return 0; 569 return 0;
570
571err_reg:
572 if (!net_eq(net, &init_net))
573 kfree(ipvs->lblc_ctl_table);
574
575err_dup:
576 return -ENOMEM;
560} 577}
561 578
562static void __net_exit __ip_vs_lblc_exit(struct net *net) 579static void __net_exit __ip_vs_lblc_exit(struct net *net)
563{ 580{
564 if (!net_eq(net, &init_net)) /* netns not enabled yet */ 581 struct netns_ipvs *ipvs = net_ipvs(net);
565 return; 582
583 unregister_net_sysctl_table(ipvs->lblc_ctl_header);
566 584
567 unregister_net_sysctl_table(sysctl_header); 585 if (!net_eq(net, &init_net))
586 kfree(ipvs->lblc_ctl_table);
568} 587}
569 588
570static struct pernet_operations ip_vs_lblc_ops = { 589static struct pernet_operations ip_vs_lblc_ops = {
@@ -586,7 +605,6 @@ static int __init ip_vs_lblc_init(void)
586 return ret; 605 return ret;
587} 606}
588 607
589
590static void __exit ip_vs_lblc_cleanup(void) 608static void __exit ip_vs_lblc_cleanup(void)
591{ 609{
592 unregister_ip_vs_scheduler(&ip_vs_lblc_scheduler); 610 unregister_ip_vs_scheduler(&ip_vs_lblc_scheduler);