diff options
author | Julian Anastasov <ja@ssi.bg> | 2012-07-12 16:06:20 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2012-08-09 21:34:51 -0400 |
commit | be97fdb5fbcc828240c51769cd28cba609158703 (patch) | |
tree | 512958698e5023506ef8728d0c5c1800ba2dba06 | |
parent | aaea4ed74d71dda1cf2cc19c206552d537201452 (diff) |
ipvs: generalize app registration in netns
Get rid of the ftp_app pointer and allow applications
to be registered without adding fields in the netns_ipvs structure.
v2: fix coding style as suggested by Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | include/net/ip_vs.h | 5 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_app.c | 58 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ftp.c | 21 |
3 files changed, 49 insertions, 35 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 95374d1696a..4b8f18ff478 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -808,8 +808,6 @@ struct netns_ipvs { | |||
808 | struct list_head rs_table[IP_VS_RTAB_SIZE]; | 808 | struct list_head rs_table[IP_VS_RTAB_SIZE]; |
809 | /* ip_vs_app */ | 809 | /* ip_vs_app */ |
810 | struct list_head app_list; | 810 | struct list_head app_list; |
811 | /* ip_vs_ftp */ | ||
812 | struct ip_vs_app *ftp_app; | ||
813 | /* ip_vs_proto */ | 811 | /* ip_vs_proto */ |
814 | #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ | 812 | #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ |
815 | struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; | 813 | struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; |
@@ -1179,7 +1177,8 @@ extern void ip_vs_service_net_cleanup(struct net *net); | |||
1179 | * (from ip_vs_app.c) | 1177 | * (from ip_vs_app.c) |
1180 | */ | 1178 | */ |
1181 | #define IP_VS_APP_MAX_PORTS 8 | 1179 | #define IP_VS_APP_MAX_PORTS 8 |
1182 | extern int register_ip_vs_app(struct net *net, struct ip_vs_app *app); | 1180 | extern struct ip_vs_app *register_ip_vs_app(struct net *net, |
1181 | struct ip_vs_app *app); | ||
1183 | extern void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app); | 1182 | extern void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app); |
1184 | extern int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp); | 1183 | extern int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp); |
1185 | extern void ip_vs_unbind_app(struct ip_vs_conn *cp); | 1184 | extern void ip_vs_unbind_app(struct ip_vs_conn *cp); |
diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index 64f9e8f1320..9713e6e86d4 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c | |||
@@ -180,22 +180,38 @@ register_ip_vs_app_inc(struct net *net, struct ip_vs_app *app, __u16 proto, | |||
180 | } | 180 | } |
181 | 181 | ||
182 | 182 | ||
183 | /* | 183 | /* Register application for netns */ |
184 | * ip_vs_app registration routine | 184 | struct ip_vs_app *register_ip_vs_app(struct net *net, struct ip_vs_app *app) |
185 | */ | ||
186 | int register_ip_vs_app(struct net *net, struct ip_vs_app *app) | ||
187 | { | 185 | { |
188 | struct netns_ipvs *ipvs = net_ipvs(net); | 186 | struct netns_ipvs *ipvs = net_ipvs(net); |
189 | /* increase the module use count */ | 187 | struct ip_vs_app *a; |
190 | ip_vs_use_count_inc(); | 188 | int err = 0; |
189 | |||
190 | if (!ipvs) | ||
191 | return ERR_PTR(-ENOENT); | ||
191 | 192 | ||
192 | mutex_lock(&__ip_vs_app_mutex); | 193 | mutex_lock(&__ip_vs_app_mutex); |
193 | 194 | ||
194 | list_add(&app->a_list, &ipvs->app_list); | 195 | list_for_each_entry(a, &ipvs->app_list, a_list) { |
196 | if (!strcmp(app->name, a->name)) { | ||
197 | err = -EEXIST; | ||
198 | goto out_unlock; | ||
199 | } | ||
200 | } | ||
201 | a = kmemdup(app, sizeof(*app), GFP_KERNEL); | ||
202 | if (!a) { | ||
203 | err = -ENOMEM; | ||
204 | goto out_unlock; | ||
205 | } | ||
206 | INIT_LIST_HEAD(&a->incs_list); | ||
207 | list_add(&a->a_list, &ipvs->app_list); | ||
208 | /* increase the module use count */ | ||
209 | ip_vs_use_count_inc(); | ||
195 | 210 | ||
211 | out_unlock: | ||
196 | mutex_unlock(&__ip_vs_app_mutex); | 212 | mutex_unlock(&__ip_vs_app_mutex); |
197 | 213 | ||
198 | return 0; | 214 | return err ? ERR_PTR(err) : a; |
199 | } | 215 | } |
200 | 216 | ||
201 | 217 | ||
@@ -205,20 +221,29 @@ int register_ip_vs_app(struct net *net, struct ip_vs_app *app) | |||
205 | */ | 221 | */ |
206 | void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app) | 222 | void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app) |
207 | { | 223 | { |
208 | struct ip_vs_app *inc, *nxt; | 224 | struct netns_ipvs *ipvs = net_ipvs(net); |
225 | struct ip_vs_app *a, *anxt, *inc, *nxt; | ||
226 | |||
227 | if (!ipvs) | ||
228 | return; | ||
209 | 229 | ||
210 | mutex_lock(&__ip_vs_app_mutex); | 230 | mutex_lock(&__ip_vs_app_mutex); |
211 | 231 | ||
212 | list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) { | 232 | list_for_each_entry_safe(a, anxt, &ipvs->app_list, a_list) { |
213 | ip_vs_app_inc_release(net, inc); | 233 | if (app && strcmp(app->name, a->name)) |
214 | } | 234 | continue; |
235 | list_for_each_entry_safe(inc, nxt, &a->incs_list, a_list) { | ||
236 | ip_vs_app_inc_release(net, inc); | ||
237 | } | ||
215 | 238 | ||
216 | list_del(&app->a_list); | 239 | list_del(&a->a_list); |
240 | kfree(a); | ||
217 | 241 | ||
218 | mutex_unlock(&__ip_vs_app_mutex); | 242 | /* decrease the module use count */ |
243 | ip_vs_use_count_dec(); | ||
244 | } | ||
219 | 245 | ||
220 | /* decrease the module use count */ | 246 | mutex_unlock(&__ip_vs_app_mutex); |
221 | ip_vs_use_count_dec(); | ||
222 | } | 247 | } |
223 | 248 | ||
224 | 249 | ||
@@ -586,5 +611,6 @@ int __net_init ip_vs_app_net_init(struct net *net) | |||
586 | 611 | ||
587 | void __net_exit ip_vs_app_net_cleanup(struct net *net) | 612 | void __net_exit ip_vs_app_net_cleanup(struct net *net) |
588 | { | 613 | { |
614 | unregister_ip_vs_app(net, NULL /* all */); | ||
589 | proc_net_remove(net, "ip_vs_app"); | 615 | proc_net_remove(net, "ip_vs_app"); |
590 | } | 616 | } |
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index b20b29c903e..ad70b7e4ac4 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c | |||
@@ -441,16 +441,10 @@ static int __net_init __ip_vs_ftp_init(struct net *net) | |||
441 | 441 | ||
442 | if (!ipvs) | 442 | if (!ipvs) |
443 | return -ENOENT; | 443 | return -ENOENT; |
444 | app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL); | ||
445 | if (!app) | ||
446 | return -ENOMEM; | ||
447 | INIT_LIST_HEAD(&app->a_list); | ||
448 | INIT_LIST_HEAD(&app->incs_list); | ||
449 | ipvs->ftp_app = app; | ||
450 | 444 | ||
451 | ret = register_ip_vs_app(net, app); | 445 | app = register_ip_vs_app(net, &ip_vs_ftp); |
452 | if (ret) | 446 | if (IS_ERR(app)) |
453 | goto err_exit; | 447 | return PTR_ERR(app); |
454 | 448 | ||
455 | for (i = 0; i < ports_count; i++) { | 449 | for (i = 0; i < ports_count; i++) { |
456 | if (!ports[i]) | 450 | if (!ports[i]) |
@@ -464,9 +458,7 @@ static int __net_init __ip_vs_ftp_init(struct net *net) | |||
464 | return 0; | 458 | return 0; |
465 | 459 | ||
466 | err_unreg: | 460 | err_unreg: |
467 | unregister_ip_vs_app(net, app); | 461 | unregister_ip_vs_app(net, &ip_vs_ftp); |
468 | err_exit: | ||
469 | kfree(ipvs->ftp_app); | ||
470 | return ret; | 462 | return ret; |
471 | } | 463 | } |
472 | /* | 464 | /* |
@@ -474,10 +466,7 @@ err_exit: | |||
474 | */ | 466 | */ |
475 | static void __ip_vs_ftp_exit(struct net *net) | 467 | static void __ip_vs_ftp_exit(struct net *net) |
476 | { | 468 | { |
477 | struct netns_ipvs *ipvs = net_ipvs(net); | 469 | unregister_ip_vs_app(net, &ip_vs_ftp); |
478 | |||
479 | unregister_ip_vs_app(net, ipvs->ftp_app); | ||
480 | kfree(ipvs->ftp_app); | ||
481 | } | 470 | } |
482 | 471 | ||
483 | static struct pernet_operations ip_vs_ftp_ops = { | 472 | static struct pernet_operations ip_vs_ftp_ops = { |