diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-04-25 00:54:09 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:29:52 -0400 |
commit | 7f7d9a6b96c5708c5184cbed61bbc15b163a0f08 (patch) | |
tree | f6841ff1239e80c3083b1e41eb343b811dc92afc /net/ipv6/proc.c | |
parent | 5e0f04351d11e07a23b5ab4914282cbb78027e50 (diff) |
[IPV6]: Consolidate common SNMP code
This patch moves the non-proc SNMP code into addrconf.c and reuses
IPv4 SNMP code where applicable.
As a result we can skip proc.o if /proc is disabled.
Note that I've made a number of functions static since they're only
used by addrconf.c for now. If they ever get used elsewhere we can
always remove the static.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/proc.c')
-rw-r--r-- | net/ipv6/proc.c | 125 |
1 files changed, 2 insertions, 123 deletions
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 7a00bedb6b93..acb306a5dd56 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -23,13 +23,12 @@ | |||
23 | #include <linux/proc_fs.h> | 23 | #include <linux/proc_fs.h> |
24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
25 | #include <linux/stddef.h> | 25 | #include <linux/stddef.h> |
26 | #include <asm/unaligned.h> | 26 | #include <net/ip.h> |
27 | #include <net/sock.h> | 27 | #include <net/sock.h> |
28 | #include <net/tcp.h> | 28 | #include <net/tcp.h> |
29 | #include <net/transp_v6.h> | 29 | #include <net/transp_v6.h> |
30 | #include <net/ipv6.h> | 30 | #include <net/ipv6.h> |
31 | 31 | ||
32 | #ifdef CONFIG_PROC_FS | ||
33 | static struct proc_dir_entry *proc_net_devsnmp6; | 32 | static struct proc_dir_entry *proc_net_devsnmp6; |
34 | 33 | ||
35 | static int fold_prot_inuse(struct proto *proto) | 34 | static int fold_prot_inuse(struct proto *proto) |
@@ -142,29 +141,14 @@ static struct snmp_mib snmp6_udplite6_list[] = { | |||
142 | SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS), | 141 | SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS), |
143 | SNMP_MIB_SENTINEL | 142 | SNMP_MIB_SENTINEL |
144 | }; | 143 | }; |
145 | #endif /* CONFIG_PROC_FS */ | ||
146 | 144 | ||
147 | static unsigned long | ||
148 | fold_field(void *mib[], int offt) | ||
149 | { | ||
150 | unsigned long res = 0; | ||
151 | int i; | ||
152 | |||
153 | for_each_possible_cpu(i) { | ||
154 | res += *(((unsigned long *)per_cpu_ptr(mib[0], i)) + offt); | ||
155 | res += *(((unsigned long *)per_cpu_ptr(mib[1], i)) + offt); | ||
156 | } | ||
157 | return res; | ||
158 | } | ||
159 | |||
160 | #ifdef CONFIG_PROC_FS | ||
161 | static inline void | 145 | static inline void |
162 | snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist) | 146 | snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist) |
163 | { | 147 | { |
164 | int i; | 148 | int i; |
165 | for (i=0; itemlist[i].name; i++) | 149 | for (i=0; itemlist[i].name; i++) |
166 | seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name, | 150 | seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name, |
167 | fold_field(mib, itemlist[i].entry)); | 151 | snmp_fold_field(mib, itemlist[i].entry)); |
168 | } | 152 | } |
169 | 153 | ||
170 | static int snmp6_seq_show(struct seq_file *seq, void *v) | 154 | static int snmp6_seq_show(struct seq_file *seq, void *v) |
@@ -209,37 +193,7 @@ static const struct file_operations snmp6_seq_fops = { | |||
209 | .llseek = seq_lseek, | 193 | .llseek = seq_lseek, |
210 | .release = single_release, | 194 | .release = single_release, |
211 | }; | 195 | }; |
212 | #endif /* CONFIG_PROC_FS */ | ||
213 | 196 | ||
214 | static inline void | ||
215 | __snmp6_fill_stats(u64 *stats, void **mib, int items, int bytes) | ||
216 | { | ||
217 | int i; | ||
218 | int pad = bytes - sizeof(u64) * items; | ||
219 | BUG_ON(pad < 0); | ||
220 | |||
221 | /* Use put_unaligned() because stats may not be aligned for u64. */ | ||
222 | put_unaligned(items, &stats[0]); | ||
223 | for (i = 1; i < items; i++) | ||
224 | put_unaligned(fold_field(mib, i), &stats[i]); | ||
225 | |||
226 | memset(&stats[items], 0, pad); | ||
227 | } | ||
228 | |||
229 | void | ||
230 | snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes) | ||
231 | { | ||
232 | switch(attrtype) { | ||
233 | case IFLA_INET6_STATS: | ||
234 | __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); | ||
235 | break; | ||
236 | case IFLA_INET6_ICMP6STATS: | ||
237 | __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | #ifdef CONFIG_PROC_FS | ||
243 | int snmp6_register_dev(struct inet6_dev *idev) | 197 | int snmp6_register_dev(struct inet6_dev *idev) |
244 | { | 198 | { |
245 | struct proc_dir_entry *p; | 199 | struct proc_dir_entry *p; |
@@ -304,78 +258,3 @@ void ipv6_misc_proc_exit(void) | |||
304 | proc_net_remove("snmp6"); | 258 | proc_net_remove("snmp6"); |
305 | } | 259 | } |
306 | 260 | ||
307 | #else /* CONFIG_PROC_FS */ | ||
308 | |||
309 | |||
310 | int snmp6_register_dev(struct inet6_dev *idev) | ||
311 | { | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | int snmp6_unregister_dev(struct inet6_dev *idev) | ||
316 | { | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | #endif /* CONFIG_PROC_FS */ | ||
321 | |||
322 | int snmp6_alloc_dev(struct inet6_dev *idev) | ||
323 | { | ||
324 | int err = -ENOMEM; | ||
325 | |||
326 | if (!idev || !idev->dev) | ||
327 | return -EINVAL; | ||
328 | |||
329 | if (snmp6_mib_init((void **)idev->stats.ipv6, sizeof(struct ipstats_mib), | ||
330 | __alignof__(struct ipstats_mib)) < 0) | ||
331 | goto err_ip; | ||
332 | if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib), | ||
333 | __alignof__(struct icmpv6_mib)) < 0) | ||
334 | goto err_icmp; | ||
335 | |||
336 | return 0; | ||
337 | |||
338 | err_icmp: | ||
339 | snmp6_mib_free((void **)idev->stats.ipv6); | ||
340 | err_ip: | ||
341 | return err; | ||
342 | } | ||
343 | |||
344 | int snmp6_free_dev(struct inet6_dev *idev) | ||
345 | { | ||
346 | snmp6_mib_free((void **)idev->stats.icmpv6); | ||
347 | snmp6_mib_free((void **)idev->stats.ipv6); | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign) | ||
352 | { | ||
353 | if (ptr == NULL) | ||
354 | return -EINVAL; | ||
355 | |||
356 | ptr[0] = __alloc_percpu(mibsize); | ||
357 | if (!ptr[0]) | ||
358 | goto err0; | ||
359 | |||
360 | ptr[1] = __alloc_percpu(mibsize); | ||
361 | if (!ptr[1]) | ||
362 | goto err1; | ||
363 | |||
364 | return 0; | ||
365 | |||
366 | err1: | ||
367 | free_percpu(ptr[0]); | ||
368 | ptr[0] = NULL; | ||
369 | err0: | ||
370 | return -ENOMEM; | ||
371 | } | ||
372 | |||
373 | void snmp6_mib_free(void *ptr[2]) | ||
374 | { | ||
375 | if (ptr == NULL) | ||
376 | return; | ||
377 | free_percpu(ptr[0]); | ||
378 | free_percpu(ptr[1]); | ||
379 | ptr[0] = ptr[1] = NULL; | ||
380 | } | ||
381 | |||