[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>
This commit is contained in:
Herbert Xu
2007-04-24 21:54:09 -07:00
committed by David S. Miller
parent 5e0f04351d
commit 7f7d9a6b96
5 changed files with 91 additions and 147 deletions

View File

@@ -81,6 +81,7 @@
#endif
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
@@ -246,6 +247,37 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp,
add_timer(&ifp->timer);
}
static int snmp6_alloc_dev(struct inet6_dev *idev)
{
int err = -ENOMEM;
if (!idev || !idev->dev)
return -EINVAL;
if (snmp_mib_init((void **)idev->stats.ipv6,
sizeof(struct ipstats_mib),
__alignof__(struct ipstats_mib)) < 0)
goto err_ip;
if (snmp_mib_init((void **)idev->stats.icmpv6,
sizeof(struct icmpv6_mib),
__alignof__(struct icmpv6_mib)) < 0)
goto err_icmp;
return 0;
err_icmp:
snmp_mib_free((void **)idev->stats.ipv6);
err_ip:
return err;
}
static int snmp6_free_dev(struct inet6_dev *idev)
{
snmp_mib_free((void **)idev->stats.icmpv6);
snmp_mib_free((void **)idev->stats.ipv6);
return 0;
}
/* Nobody refers to this device, we may destroy it. */
static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
@@ -3438,6 +3470,34 @@ static inline size_t inet6_if_nlmsg_size(void)
);
}
static inline void __snmp6_fill_stats(u64 *stats, void **mib, int items,
int bytes)
{
int i;
int pad = bytes - sizeof(u64) * items;
BUG_ON(pad < 0);
/* Use put_unaligned() because stats may not be aligned for u64. */
put_unaligned(items, &stats[0]);
for (i = 1; i < items; i++)
put_unaligned(snmp_fold_field(mib, i), &stats[i]);
memset(&stats[items], 0, pad);
}
static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
int bytes)
{
switch(attrtype) {
case IFLA_INET6_STATS:
__snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
break;
case IFLA_INET6_ICMP6STATS:
__snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
break;
}
}
static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
u32 pid, u32 seq, int event, unsigned int flags)
{