X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fcore%2Fsysctl_net_core.c;h=5fc801057244b797aafce24665147987cdd877ef;hb=cdbfc557c43ea1f1f9b7062300ecb1254969814b;hp=e322713e590ae35e84ac7d575c8c0dda5a778e33;hpb=33eb9cfc700ae9ce621d47d6ca6d6b4ad7cd97f3;p=linux-2.6 diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index e322713e59..5fc8010572 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -127,7 +127,7 @@ static struct ctl_table net_core_table[] = { { .ctl_name = NET_CORE_SOMAXCONN, .procname = "somaxconn", - .data = &sysctl_somaxconn, + .data = &init_net.core.sysctl_somaxconn, .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec @@ -151,18 +151,65 @@ static struct ctl_table net_core_table[] = { { .ctl_name = 0 } }; -static __initdata struct ctl_path net_core_path[] = { +static __net_initdata struct ctl_path net_core_path[] = { { .procname = "net", .ctl_name = CTL_NET, }, { .procname = "core", .ctl_name = NET_CORE, }, { }, }; -static __init int sysctl_core_init(void) +static __net_init int sysctl_core_net_init(struct net *net) +{ + struct ctl_table *tbl, *tmp; + + net->core.sysctl_somaxconn = SOMAXCONN; + + tbl = net_core_table; + if (net != &init_net) { + tbl = kmemdup(tbl, sizeof(net_core_table), GFP_KERNEL); + if (tbl == NULL) + goto err_dup; + + for (tmp = tbl; tmp->procname; tmp++) { + if (tmp->data >= (void *)&init_net && + tmp->data < (void *)(&init_net + 1)) + tmp->data += (char *)net - (char *)&init_net; + else + tmp->mode &= ~0222; + } + } + + net->core.sysctl_hdr = register_net_sysctl_table(net, + net_core_path, tbl); + if (net->core.sysctl_hdr == NULL) + goto err_reg; + + return 0; + +err_reg: + if (tbl != net_core_table) + kfree(tbl); +err_dup: + return -ENOMEM; +} + +static __net_exit void sysctl_core_net_exit(struct net *net) { - struct ctl_table_header *hdr; + struct ctl_table *tbl; + + tbl = net->core.sysctl_hdr->ctl_table_arg; + unregister_net_sysctl_table(net->core.sysctl_hdr); + BUG_ON(tbl == net_core_table); + kfree(tbl); +} - hdr = register_sysctl_paths(net_core_path, net_core_table); - return hdr == NULL ? -ENOMEM : 0; +static __net_initdata struct pernet_operations sysctl_core_ops = { + .init = sysctl_core_net_init, + .exit = sysctl_core_net_exit, +}; + +static __init int sysctl_core_init(void) +{ + return register_pernet_subsys(&sysctl_core_ops); } __initcall(sysctl_core_init);