diff options
Diffstat (limited to 'net/netfilter/ipvs/ip_vs_app.c')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_app.c | 75 |
1 files changed, 51 insertions, 24 deletions
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index a475edee091..2dc6de13ac1 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c | |||
@@ -43,11 +43,8 @@ EXPORT_SYMBOL(register_ip_vs_app); | |||
43 | EXPORT_SYMBOL(unregister_ip_vs_app); | 43 | EXPORT_SYMBOL(unregister_ip_vs_app); |
44 | EXPORT_SYMBOL(register_ip_vs_app_inc); | 44 | EXPORT_SYMBOL(register_ip_vs_app_inc); |
45 | 45 | ||
46 | /* ipvs application list head */ | ||
47 | static LIST_HEAD(ip_vs_app_list); | ||
48 | static DEFINE_MUTEX(__ip_vs_app_mutex); | 46 | static DEFINE_MUTEX(__ip_vs_app_mutex); |
49 | 47 | ||
50 | |||
51 | /* | 48 | /* |
52 | * Get an ip_vs_app object | 49 | * Get an ip_vs_app object |
53 | */ | 50 | */ |
@@ -67,7 +64,8 @@ static inline void ip_vs_app_put(struct ip_vs_app *app) | |||
67 | * Allocate/initialize app incarnation and register it in proto apps. | 64 | * Allocate/initialize app incarnation and register it in proto apps. |
68 | */ | 65 | */ |
69 | static int | 66 | static int |
70 | ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port) | 67 | ip_vs_app_inc_new(struct net *net, struct ip_vs_app *app, __u16 proto, |
68 | __u16 port) | ||
71 | { | 69 | { |
72 | struct ip_vs_protocol *pp; | 70 | struct ip_vs_protocol *pp; |
73 | struct ip_vs_app *inc; | 71 | struct ip_vs_app *inc; |
@@ -98,7 +96,7 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port) | |||
98 | } | 96 | } |
99 | } | 97 | } |
100 | 98 | ||
101 | ret = pp->register_app(inc); | 99 | ret = pp->register_app(net, inc); |
102 | if (ret) | 100 | if (ret) |
103 | goto out; | 101 | goto out; |
104 | 102 | ||
@@ -119,7 +117,7 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port) | |||
119 | * Release app incarnation | 117 | * Release app incarnation |
120 | */ | 118 | */ |
121 | static void | 119 | static void |
122 | ip_vs_app_inc_release(struct ip_vs_app *inc) | 120 | ip_vs_app_inc_release(struct net *net, struct ip_vs_app *inc) |
123 | { | 121 | { |
124 | struct ip_vs_protocol *pp; | 122 | struct ip_vs_protocol *pp; |
125 | 123 | ||
@@ -127,7 +125,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc) | |||
127 | return; | 125 | return; |
128 | 126 | ||
129 | if (pp->unregister_app) | 127 | if (pp->unregister_app) |
130 | pp->unregister_app(inc); | 128 | pp->unregister_app(net, inc); |
131 | 129 | ||
132 | IP_VS_DBG(9, "%s App %s:%u unregistered\n", | 130 | IP_VS_DBG(9, "%s App %s:%u unregistered\n", |
133 | pp->name, inc->name, ntohs(inc->port)); | 131 | pp->name, inc->name, ntohs(inc->port)); |
@@ -168,13 +166,14 @@ void ip_vs_app_inc_put(struct ip_vs_app *inc) | |||
168 | * Register an application incarnation in protocol applications | 166 | * Register an application incarnation in protocol applications |
169 | */ | 167 | */ |
170 | int | 168 | int |
171 | register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port) | 169 | register_ip_vs_app_inc(struct net *net, struct ip_vs_app *app, __u16 proto, |
170 | __u16 port) | ||
172 | { | 171 | { |
173 | int result; | 172 | int result; |
174 | 173 | ||
175 | mutex_lock(&__ip_vs_app_mutex); | 174 | mutex_lock(&__ip_vs_app_mutex); |
176 | 175 | ||
177 | result = ip_vs_app_inc_new(app, proto, port); | 176 | result = ip_vs_app_inc_new(net, app, proto, port); |
178 | 177 | ||
179 | mutex_unlock(&__ip_vs_app_mutex); | 178 | mutex_unlock(&__ip_vs_app_mutex); |
180 | 179 | ||
@@ -185,14 +184,15 @@ register_ip_vs_app_inc(struct ip_vs_app *app, __u16 proto, __u16 port) | |||
185 | /* | 184 | /* |
186 | * ip_vs_app registration routine | 185 | * ip_vs_app registration routine |
187 | */ | 186 | */ |
188 | int register_ip_vs_app(struct ip_vs_app *app) | 187 | int register_ip_vs_app(struct net *net, struct ip_vs_app *app) |
189 | { | 188 | { |
189 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
190 | /* increase the module use count */ | 190 | /* increase the module use count */ |
191 | ip_vs_use_count_inc(); | 191 | ip_vs_use_count_inc(); |
192 | 192 | ||
193 | mutex_lock(&__ip_vs_app_mutex); | 193 | mutex_lock(&__ip_vs_app_mutex); |
194 | 194 | ||
195 | list_add(&app->a_list, &ip_vs_app_list); | 195 | list_add(&app->a_list, &ipvs->app_list); |
196 | 196 | ||
197 | mutex_unlock(&__ip_vs_app_mutex); | 197 | mutex_unlock(&__ip_vs_app_mutex); |
198 | 198 | ||
@@ -204,14 +204,14 @@ int register_ip_vs_app(struct ip_vs_app *app) | |||
204 | * ip_vs_app unregistration routine | 204 | * ip_vs_app unregistration routine |
205 | * We are sure there are no app incarnations attached to services | 205 | * We are sure there are no app incarnations attached to services |
206 | */ | 206 | */ |
207 | void unregister_ip_vs_app(struct ip_vs_app *app) | 207 | void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app) |
208 | { | 208 | { |
209 | struct ip_vs_app *inc, *nxt; | 209 | struct ip_vs_app *inc, *nxt; |
210 | 210 | ||
211 | mutex_lock(&__ip_vs_app_mutex); | 211 | mutex_lock(&__ip_vs_app_mutex); |
212 | 212 | ||
213 | list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) { | 213 | list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) { |
214 | ip_vs_app_inc_release(inc); | 214 | ip_vs_app_inc_release(net, inc); |
215 | } | 215 | } |
216 | 216 | ||
217 | list_del(&app->a_list); | 217 | list_del(&app->a_list); |
@@ -226,7 +226,8 @@ void unregister_ip_vs_app(struct ip_vs_app *app) | |||
226 | /* | 226 | /* |
227 | * Bind ip_vs_conn to its ip_vs_app (called by cp constructor) | 227 | * Bind ip_vs_conn to its ip_vs_app (called by cp constructor) |
228 | */ | 228 | */ |
229 | int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp) | 229 | int ip_vs_bind_app(struct ip_vs_conn *cp, |
230 | struct ip_vs_protocol *pp) | ||
230 | { | 231 | { |
231 | return pp->app_conn_bind(cp); | 232 | return pp->app_conn_bind(cp); |
232 | } | 233 | } |
@@ -481,11 +482,11 @@ int ip_vs_app_pkt_in(struct ip_vs_conn *cp, struct sk_buff *skb) | |||
481 | * /proc/net/ip_vs_app entry function | 482 | * /proc/net/ip_vs_app entry function |
482 | */ | 483 | */ |
483 | 484 | ||
484 | static struct ip_vs_app *ip_vs_app_idx(loff_t pos) | 485 | static struct ip_vs_app *ip_vs_app_idx(struct netns_ipvs *ipvs, loff_t pos) |
485 | { | 486 | { |
486 | struct ip_vs_app *app, *inc; | 487 | struct ip_vs_app *app, *inc; |
487 | 488 | ||
488 | list_for_each_entry(app, &ip_vs_app_list, a_list) { | 489 | list_for_each_entry(app, &ipvs->app_list, a_list) { |
489 | list_for_each_entry(inc, &app->incs_list, a_list) { | 490 | list_for_each_entry(inc, &app->incs_list, a_list) { |
490 | if (pos-- == 0) | 491 | if (pos-- == 0) |
491 | return inc; | 492 | return inc; |
@@ -497,19 +498,24 @@ static struct ip_vs_app *ip_vs_app_idx(loff_t pos) | |||
497 | 498 | ||
498 | static void *ip_vs_app_seq_start(struct seq_file *seq, loff_t *pos) | 499 | static void *ip_vs_app_seq_start(struct seq_file *seq, loff_t *pos) |
499 | { | 500 | { |
501 | struct net *net = seq_file_net(seq); | ||
502 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
503 | |||
500 | mutex_lock(&__ip_vs_app_mutex); | 504 | mutex_lock(&__ip_vs_app_mutex); |
501 | 505 | ||
502 | return *pos ? ip_vs_app_idx(*pos - 1) : SEQ_START_TOKEN; | 506 | return *pos ? ip_vs_app_idx(ipvs, *pos - 1) : SEQ_START_TOKEN; |
503 | } | 507 | } |
504 | 508 | ||
505 | static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 509 | static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
506 | { | 510 | { |
507 | struct ip_vs_app *inc, *app; | 511 | struct ip_vs_app *inc, *app; |
508 | struct list_head *e; | 512 | struct list_head *e; |
513 | struct net *net = seq_file_net(seq); | ||
514 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
509 | 515 | ||
510 | ++*pos; | 516 | ++*pos; |
511 | if (v == SEQ_START_TOKEN) | 517 | if (v == SEQ_START_TOKEN) |
512 | return ip_vs_app_idx(0); | 518 | return ip_vs_app_idx(ipvs, 0); |
513 | 519 | ||
514 | inc = v; | 520 | inc = v; |
515 | app = inc->app; | 521 | app = inc->app; |
@@ -518,7 +524,7 @@ static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
518 | return list_entry(e, struct ip_vs_app, a_list); | 524 | return list_entry(e, struct ip_vs_app, a_list); |
519 | 525 | ||
520 | /* go on to next application */ | 526 | /* go on to next application */ |
521 | for (e = app->a_list.next; e != &ip_vs_app_list; e = e->next) { | 527 | for (e = app->a_list.next; e != &ipvs->app_list; e = e->next) { |
522 | app = list_entry(e, struct ip_vs_app, a_list); | 528 | app = list_entry(e, struct ip_vs_app, a_list); |
523 | list_for_each_entry(inc, &app->incs_list, a_list) { | 529 | list_for_each_entry(inc, &app->incs_list, a_list) { |
524 | return inc; | 530 | return inc; |
@@ -557,7 +563,8 @@ static const struct seq_operations ip_vs_app_seq_ops = { | |||
557 | 563 | ||
558 | static int ip_vs_app_open(struct inode *inode, struct file *file) | 564 | static int ip_vs_app_open(struct inode *inode, struct file *file) |
559 | { | 565 | { |
560 | return seq_open(file, &ip_vs_app_seq_ops); | 566 | return seq_open_net(inode, file, &ip_vs_app_seq_ops, |
567 | sizeof(struct seq_net_private)); | ||
561 | } | 568 | } |
562 | 569 | ||
563 | static const struct file_operations ip_vs_app_fops = { | 570 | static const struct file_operations ip_vs_app_fops = { |
@@ -569,15 +576,35 @@ static const struct file_operations ip_vs_app_fops = { | |||
569 | }; | 576 | }; |
570 | #endif | 577 | #endif |
571 | 578 | ||
572 | int __init ip_vs_app_init(void) | 579 | static int __net_init __ip_vs_app_init(struct net *net) |
573 | { | 580 | { |
574 | /* we will replace it with proc_net_ipvs_create() soon */ | 581 | struct netns_ipvs *ipvs = net_ipvs(net); |
575 | proc_net_fops_create(&init_net, "ip_vs_app", 0, &ip_vs_app_fops); | 582 | |
583 | INIT_LIST_HEAD(&ipvs->app_list); | ||
584 | proc_net_fops_create(net, "ip_vs_app", 0, &ip_vs_app_fops); | ||
576 | return 0; | 585 | return 0; |
577 | } | 586 | } |
578 | 587 | ||
588 | static void __net_exit __ip_vs_app_cleanup(struct net *net) | ||
589 | { | ||
590 | proc_net_remove(net, "ip_vs_app"); | ||
591 | } | ||
592 | |||
593 | static struct pernet_operations ip_vs_app_ops = { | ||
594 | .init = __ip_vs_app_init, | ||
595 | .exit = __ip_vs_app_cleanup, | ||
596 | }; | ||
597 | |||
598 | int __init ip_vs_app_init(void) | ||
599 | { | ||
600 | int rv; | ||
601 | |||
602 | rv = register_pernet_subsys(&ip_vs_app_ops); | ||
603 | return rv; | ||
604 | } | ||
605 | |||
579 | 606 | ||
580 | void ip_vs_app_cleanup(void) | 607 | void ip_vs_app_cleanup(void) |
581 | { | 608 | { |
582 | proc_net_remove(&init_net, "ip_vs_app"); | 609 | unregister_pernet_subsys(&ip_vs_app_ops); |
583 | } | 610 | } |