Commit bf99f1bd authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki Committed by David S. Miller

[IPV6] SNMP: Netlink interface.

Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 628a5c56
...@@ -126,6 +126,7 @@ enum ...@@ -126,6 +126,7 @@ enum
IFLA_INET6_STATS, /* statistics */ IFLA_INET6_STATS, /* statistics */
IFLA_INET6_MCAST, /* MC things. What of them? */ IFLA_INET6_MCAST, /* MC things. What of them? */
IFLA_INET6_CACHEINFO, /* time values and max reasm size */ IFLA_INET6_CACHEINFO, /* time values and max reasm size */
IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */
__IFLA_INET6_MAX __IFLA_INET6_MAX
}; };
......
...@@ -172,6 +172,7 @@ int snmp6_alloc_dev(struct inet6_dev *idev); ...@@ -172,6 +172,7 @@ int snmp6_alloc_dev(struct inet6_dev *idev);
int snmp6_free_dev(struct inet6_dev *idev); int snmp6_free_dev(struct inet6_dev *idev);
int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign); int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
void snmp6_mib_free(void *ptr[2]); void snmp6_mib_free(void *ptr[2]);
void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes);
struct ip6_ra_chain struct ip6_ra_chain
{ {
......
...@@ -3433,6 +3433,8 @@ static inline size_t inet6_if_nlmsg_size(void) ...@@ -3433,6 +3433,8 @@ static inline size_t inet6_if_nlmsg_size(void)
nla_total_size(4) /* IFLA_INET6_FLAGS */ nla_total_size(4) /* IFLA_INET6_FLAGS */
+ nla_total_size(sizeof(struct ifla_cacheinfo)) + nla_total_size(sizeof(struct ifla_cacheinfo))
+ nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
+ nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
+ nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
); );
} }
...@@ -3440,7 +3442,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, ...@@ -3440,7 +3442,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
u32 pid, u32 seq, int event, unsigned int flags) u32 pid, u32 seq, int event, unsigned int flags)
{ {
struct net_device *dev = idev->dev; struct net_device *dev = idev->dev;
struct nlattr *conf; struct nlattr *nla;
struct ifinfomsg *hdr; struct ifinfomsg *hdr;
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
void *protoinfo; void *protoinfo;
...@@ -3480,12 +3482,22 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, ...@@ -3480,12 +3482,22 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
ci.retrans_time = idev->nd_parms->retrans_time; ci.retrans_time = idev->nd_parms->retrans_time;
NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
conf = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
if (conf == NULL) if (nla == NULL)
goto nla_put_failure; goto nla_put_failure;
ipv6_store_devconf(&idev->cnf, nla_data(conf), nla_len(conf)); ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
/* XXX - Statistics/MC not implemented */ /* XXX - MC not implemented */
nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
if (nla == NULL)
goto nla_put_failure;
snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
if (nla == NULL)
goto nla_put_failure;
snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
nla_nest_end(skb, protoinfo); nla_nest_end(skb, protoinfo);
return nlmsg_end(skb, nlh); return nlmsg_end(skb, nlh);
......
...@@ -207,6 +207,31 @@ static const struct file_operations snmp6_seq_fops = { ...@@ -207,6 +207,31 @@ static const struct file_operations snmp6_seq_fops = {
.release = single_release, .release = single_release,
}; };
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);
stats[0] = items;
for (i = 1; i < items; i++)
stats[i] = (u64)fold_field(mib, i);
memset(&stats[items], 0, pad);
}
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;
}
}
int snmp6_register_dev(struct inet6_dev *idev) int snmp6_register_dev(struct inet6_dev *idev)
{ {
struct proc_dir_entry *p; struct proc_dir_entry *p;
...@@ -283,6 +308,13 @@ int snmp6_unregister_dev(struct inet6_dev *idev) ...@@ -283,6 +308,13 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
{ {
return 0; return 0;
} }
void
snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes)
{
memset(stats, 0, sizeof(bytes));
}
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
int snmp6_alloc_dev(struct inet6_dev *idev) int snmp6_alloc_dev(struct inet6_dev *idev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment