1 /* -*- linux-c -*- 2 * sysctl_net_core.c: sysctl interface to net core subsystem. 3 * 4 * Begun April 1, 1996, Mike Shaver. 5 * Added /proc/sys/net/core directory entry (empty =) ). [MS] 6 */ 7 8 #include <linux/mm.h> 9 #include <linux/sysctl.h> 10 #include <linux/module.h> 11 #include <linux/socket.h> 12 #include <linux/netdevice.h> 13 #include <linux/init.h> 14 #include <net/ip.h> 15 #include <net/sock.h> 16 17 static struct ctl_table net_core_table[] = { 18 #ifdef CONFIG_NET 19 { 20 .ctl_name = NET_CORE_WMEM_MAX, 21 .procname = "wmem_max", 22 .data = &sysctl_wmem_max, 23 .maxlen = sizeof(int), 24 .mode = 0644, 25 .proc_handler = proc_dointvec 26 }, 27 { 28 .ctl_name = NET_CORE_RMEM_MAX, 29 .procname = "rmem_max", 30 .data = &sysctl_rmem_max, 31 .maxlen = sizeof(int), 32 .mode = 0644, 33 .proc_handler = proc_dointvec 34 }, 35 { 36 .ctl_name = NET_CORE_WMEM_DEFAULT, 37 .procname = "wmem_default", 38 .data = &sysctl_wmem_default, 39 .maxlen = sizeof(int), 40 .mode = 0644, 41 .proc_handler = proc_dointvec 42 }, 43 { 44 .ctl_name = NET_CORE_RMEM_DEFAULT, 45 .procname = "rmem_default", 46 .data = &sysctl_rmem_default, 47 .maxlen = sizeof(int), 48 .mode = 0644, 49 .proc_handler = proc_dointvec 50 }, 51 { 52 .ctl_name = NET_CORE_DEV_WEIGHT, 53 .procname = "dev_weight", 54 .data = &weight_p, 55 .maxlen = sizeof(int), 56 .mode = 0644, 57 .proc_handler = proc_dointvec 58 }, 59 { 60 .ctl_name = NET_CORE_MAX_BACKLOG, 61 .procname = "netdev_max_backlog", 62 .data = &netdev_max_backlog, 63 .maxlen = sizeof(int), 64 .mode = 0644, 65 .proc_handler = proc_dointvec 66 }, 67 { 68 .ctl_name = NET_CORE_MSG_COST, 69 .procname = "message_cost", 70 .data = &net_ratelimit_state.interval, 71 .maxlen = sizeof(int), 72 .mode = 0644, 73 .proc_handler = proc_dointvec_jiffies, 74 .strategy = sysctl_jiffies, 75 }, 76 { 77 .ctl_name = NET_CORE_MSG_BURST, 78 .procname = "message_burst", 79 .data = &net_ratelimit_state.burst, 80 .maxlen = sizeof(int), 81 .mode = 0644, 82 .proc_handler = proc_dointvec, 83 }, 84 { 85 .ctl_name = NET_CORE_OPTMEM_MAX, 86 .procname = "optmem_max", 87 .data = &sysctl_optmem_max, 88 .maxlen = sizeof(int), 89 .mode = 0644, 90 .proc_handler = proc_dointvec 91 }, 92 #endif /* CONFIG_NET */ 93 { 94 .ctl_name = NET_CORE_BUDGET, 95 .procname = "netdev_budget", 96 .data = &netdev_budget, 97 .maxlen = sizeof(int), 98 .mode = 0644, 99 .proc_handler = proc_dointvec 100 }, 101 { 102 .ctl_name = NET_CORE_WARNINGS, 103 .procname = "warnings", 104 .data = &net_msg_warn, 105 .maxlen = sizeof(int), 106 .mode = 0644, 107 .proc_handler = proc_dointvec 108 }, 109 { .ctl_name = 0 } 110 }; 111 112 static struct ctl_table netns_core_table[] = { 113 { 114 .ctl_name = NET_CORE_SOMAXCONN, 115 .procname = "somaxconn", 116 .data = &init_net.core.sysctl_somaxconn, 117 .maxlen = sizeof(int), 118 .mode = 0644, 119 .proc_handler = proc_dointvec 120 }, 121 { .ctl_name = 0 } 122 }; 123 124 __net_initdata struct ctl_path net_core_path[] = { 125 { .procname = "net", .ctl_name = CTL_NET, }, 126 { .procname = "core", .ctl_name = NET_CORE, }, 127 { }, 128 }; 129 130 static __net_init int sysctl_core_net_init(struct net *net) 131 { 132 struct ctl_table *tbl; 133 134 net->core.sysctl_somaxconn = SOMAXCONN; 135 136 tbl = netns_core_table; 137 if (net != &init_net) { 138 tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); 139 if (tbl == NULL) 140 goto err_dup; 141 142 tbl[0].data = &net->core.sysctl_somaxconn; 143 } 144 145 net->core.sysctl_hdr = register_net_sysctl_table(net, 146 net_core_path, tbl); 147 if (net->core.sysctl_hdr == NULL) 148 goto err_reg; 149 150 return 0; 151 152 err_reg: 153 if (tbl != netns_core_table) 154 kfree(tbl); 155 err_dup: 156 return -ENOMEM; 157 } 158 159 static __net_exit void sysctl_core_net_exit(struct net *net) 160 { 161 struct ctl_table *tbl; 162 163 tbl = net->core.sysctl_hdr->ctl_table_arg; 164 unregister_net_sysctl_table(net->core.sysctl_hdr); 165 BUG_ON(tbl == netns_core_table); 166 kfree(tbl); 167 } 168 169 static __net_initdata struct pernet_operations sysctl_core_ops = { 170 .init = sysctl_core_net_init, 171 .exit = sysctl_core_net_exit, 172 }; 173 174 static __init int sysctl_core_init(void) 175 { 176 static struct ctl_table empty[1]; 177 178 register_sysctl_paths(net_core_path, empty); 179 register_net_sysctl_rotable(net_core_path, net_core_table); 180 return register_pernet_subsys(&sysctl_core_ops); 181 } 182 183 fs_initcall(sysctl_core_init); 184