Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Julian Anastasov and committed by
Simon Horman
be97fdb5 aaea4ed7

+49 -35
+2 -3
include/net/ip_vs.h
··· 808 808 struct list_head rs_table[IP_VS_RTAB_SIZE]; 809 809 /* ip_vs_app */ 810 810 struct list_head app_list; 811 - /* ip_vs_ftp */ 812 - struct ip_vs_app *ftp_app; 813 811 /* ip_vs_proto */ 814 812 #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */ 815 813 struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE]; ··· 1177 1179 * (from ip_vs_app.c) 1178 1180 */ 1179 1181 #define IP_VS_APP_MAX_PORTS 8 1180 - extern int register_ip_vs_app(struct net *net, struct ip_vs_app *app); 1182 + extern struct ip_vs_app *register_ip_vs_app(struct net *net, 1183 + struct ip_vs_app *app); 1181 1184 extern void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app); 1182 1185 extern int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp); 1183 1186 extern void ip_vs_unbind_app(struct ip_vs_conn *cp);
+42 -16
net/netfilter/ipvs/ip_vs_app.c
··· 180 180 } 181 181 182 182 183 - /* 184 - * ip_vs_app registration routine 185 - */ 186 - int register_ip_vs_app(struct net *net, struct ip_vs_app *app) 183 + /* Register application for netns */ 184 + struct ip_vs_app *register_ip_vs_app(struct net *net, struct ip_vs_app *app) 187 185 { 188 186 struct netns_ipvs *ipvs = net_ipvs(net); 189 - /* increase the module use count */ 190 - ip_vs_use_count_inc(); 187 + struct ip_vs_app *a; 188 + int err = 0; 189 + 190 + if (!ipvs) 191 + return ERR_PTR(-ENOENT); 191 192 192 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 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 ··· 221 205 */ 222 206 void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app) 223 207 { 224 - struct ip_vs_app *inc, *nxt; 208 + struct netns_ipvs *ipvs = net_ipvs(net); 209 + struct ip_vs_app *a, *anxt, *inc, *nxt; 210 + 211 + if (!ipvs) 212 + return; 225 213 226 214 mutex_lock(&__ip_vs_app_mutex); 227 215 228 - list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) { 229 - ip_vs_app_inc_release(net, inc); 216 + list_for_each_entry_safe(a, anxt, &ipvs->app_list, a_list) { 217 + if (app && strcmp(app->name, a->name)) 218 + continue; 219 + list_for_each_entry_safe(inc, nxt, &a->incs_list, a_list) { 220 + ip_vs_app_inc_release(net, inc); 221 + } 222 + 223 + list_del(&a->a_list); 224 + kfree(a); 225 + 226 + /* decrease the module use count */ 227 + ip_vs_use_count_dec(); 230 228 } 231 229 232 - list_del(&app->a_list); 233 - 234 230 mutex_unlock(&__ip_vs_app_mutex); 235 - 236 - /* decrease the module use count */ 237 - ip_vs_use_count_dec(); 238 231 } 239 232 240 233 ··· 611 586 612 587 void __net_exit ip_vs_app_net_cleanup(struct net *net) 613 588 { 589 + unregister_ip_vs_app(net, NULL /* all */); 614 590 proc_net_remove(net, "ip_vs_app"); 615 591 }
+5 -16
net/netfilter/ipvs/ip_vs_ftp.c
··· 441 441 442 442 if (!ipvs) 443 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); 452 - if (ret) 453 - goto err_exit; 445 + app = register_ip_vs_app(net, &ip_vs_ftp); 446 + if (IS_ERR(app)) 447 + return PTR_ERR(app); 454 448 455 449 for (i = 0; i < ports_count; i++) { 456 450 if (!ports[i]) ··· 458 464 return 0; 459 465 460 466 err_unreg: 461 - unregister_ip_vs_app(net, app); 462 - err_exit: 463 - kfree(ipvs->ftp_app); 467 + unregister_ip_vs_app(net, &ip_vs_ftp); 464 468 return ret; 465 469 } 466 470 /* ··· 466 474 */ 467 475 static void __ip_vs_ftp_exit(struct net *net) 468 476 { 469 - struct netns_ipvs *ipvs = net_ipvs(net); 470 - 471 - unregister_ip_vs_app(net, ipvs->ftp_app); 472 - kfree(ipvs->ftp_app); 477 + unregister_ip_vs_app(net, &ip_vs_ftp); 473 478 } 474 479 475 480 static struct pernet_operations ip_vs_ftp_ops = {