aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-04-25 00:54:09 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:29:52 -0400
commit7f7d9a6b96c5708c5184cbed61bbc15b163a0f08 (patch)
treef6841ff1239e80c3083b1e41eb343b811dc92afc /net/ipv6/addrconf.c
parent5e0f04351d11e07a23b5ab4914282cbb78027e50 (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/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 33ccc95c349b..ea86bf4bfe0a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -81,6 +81,7 @@
81#endif 81#endif
82 82
83#include <asm/uaccess.h> 83#include <asm/uaccess.h>
84#include <asm/unaligned.h>
84 85
85#include <linux/proc_fs.h> 86#include <linux/proc_fs.h>
86#include <linux/seq_file.h> 87#include <linux/seq_file.h>
@@ -246,6 +247,37 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
246 add_timer(&ifp->timer); 247 add_timer(&ifp->timer);
247} 248}
248 249
250static int snmp6_alloc_dev(struct inet6_dev *idev)
251{
252 int err = -ENOMEM;
253
254 if (!idev || !idev->dev)
255 return -EINVAL;
256
257 if (snmp_mib_init((void **)idev->stats.ipv6,
258 sizeof(struct ipstats_mib),
259 __alignof__(struct ipstats_mib)) < 0)
260 goto err_ip;
261 if (snmp_mib_init((void **)idev->stats.icmpv6,
262 sizeof(struct icmpv6_mib),
263 __alignof__(struct icmpv6_mib)) < 0)
264 goto err_icmp;
265
266 return 0;
267
268err_icmp:
269 snmp_mib_free((void **)idev->stats.ipv6);
270err_ip:
271 return err;
272}
273
274static int snmp6_free_dev(struct inet6_dev *idev)
275{
276 snmp_mib_free((void **)idev->stats.icmpv6);
277 snmp_mib_free((void **)idev->stats.ipv6);
278 return 0;
279}
280
249/* Nobody refers to this device, we may destroy it. */ 281/* Nobody refers to this device, we may destroy it. */
250 282
251static void in6_dev_finish_destroy_rcu(struct rcu_head *head) 283static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
@@ -3438,6 +3470,34 @@ static inline size_t inet6_if_nlmsg_size(void)
3438 ); 3470 );
3439} 3471}
3440 3472
3473static inline void __snmp6_fill_stats(u64 *stats, void **mib, int items,
3474 int bytes)
3475{
3476 int i;
3477 int pad = bytes - sizeof(u64) * items;
3478 BUG_ON(pad < 0);
3479
3480 /* Use put_unaligned() because stats may not be aligned for u64. */
3481 put_unaligned(items, &stats[0]);
3482 for (i = 1; i < items; i++)
3483 put_unaligned(snmp_fold_field(mib, i), &stats[i]);
3484
3485 memset(&stats[items], 0, pad);
3486}
3487
3488static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3489 int bytes)
3490{
3491 switch(attrtype) {
3492 case IFLA_INET6_STATS:
3493 __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
3494 break;
3495 case IFLA_INET6_ICMP6STATS:
3496 __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
3497 break;
3498 }
3499}
3500
3441static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 3501static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3442 u32 pid, u32 seq, int event, unsigned int flags) 3502 u32 pid, u32 seq, int event, unsigned int flags)
3443{ 3503{