diff options
-rw-r--r-- | include/linux/if_link.h | 1 | ||||
-rw-r--r-- | include/net/ipv6.h | 1 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 22 | ||||
-rw-r--r-- | net/ipv6/proc.c | 32 |
4 files changed, 51 insertions, 5 deletions
diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 35ed3b5467f3..604c2434f71c 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h | |||
@@ -126,6 +126,7 @@ enum | |||
126 | IFLA_INET6_STATS, /* statistics */ | 126 | IFLA_INET6_STATS, /* statistics */ |
127 | IFLA_INET6_MCAST, /* MC things. What of them? */ | 127 | IFLA_INET6_MCAST, /* MC things. What of them? */ |
128 | IFLA_INET6_CACHEINFO, /* time values and max reasm size */ | 128 | IFLA_INET6_CACHEINFO, /* time values and max reasm size */ |
129 | IFLA_INET6_ICMP6STATS, /* statistics (icmpv6) */ | ||
129 | __IFLA_INET6_MAX | 130 | __IFLA_INET6_MAX |
130 | }; | 131 | }; |
131 | 132 | ||
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 00328b71a08c..4408def379bf 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -172,6 +172,7 @@ int snmp6_alloc_dev(struct inet6_dev *idev); | |||
172 | int snmp6_free_dev(struct inet6_dev *idev); | 172 | int snmp6_free_dev(struct inet6_dev *idev); |
173 | int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign); | 173 | int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign); |
174 | void snmp6_mib_free(void *ptr[2]); | 174 | void snmp6_mib_free(void *ptr[2]); |
175 | void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes); | ||
175 | 176 | ||
176 | struct ip6_ra_chain | 177 | struct ip6_ra_chain |
177 | { | 178 | { |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1486f76f7878..9ba9e92d1934 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3433,6 +3433,8 @@ static inline size_t inet6_if_nlmsg_size(void) | |||
3433 | nla_total_size(4) /* IFLA_INET6_FLAGS */ | 3433 | nla_total_size(4) /* IFLA_INET6_FLAGS */ |
3434 | + nla_total_size(sizeof(struct ifla_cacheinfo)) | 3434 | + nla_total_size(sizeof(struct ifla_cacheinfo)) |
3435 | + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ | 3435 | + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */ |
3436 | + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */ | ||
3437 | + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */ | ||
3436 | ); | 3438 | ); |
3437 | } | 3439 | } |
3438 | 3440 | ||
@@ -3440,7 +3442,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, | |||
3440 | u32 pid, u32 seq, int event, unsigned int flags) | 3442 | u32 pid, u32 seq, int event, unsigned int flags) |
3441 | { | 3443 | { |
3442 | struct net_device *dev = idev->dev; | 3444 | struct net_device *dev = idev->dev; |
3443 | struct nlattr *conf; | 3445 | struct nlattr *nla; |
3444 | struct ifinfomsg *hdr; | 3446 | struct ifinfomsg *hdr; |
3445 | struct nlmsghdr *nlh; | 3447 | struct nlmsghdr *nlh; |
3446 | void *protoinfo; | 3448 | void *protoinfo; |
@@ -3480,12 +3482,22 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, | |||
3480 | ci.retrans_time = idev->nd_parms->retrans_time; | 3482 | ci.retrans_time = idev->nd_parms->retrans_time; |
3481 | NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); | 3483 | NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); |
3482 | 3484 | ||
3483 | conf = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); | 3485 | nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); |
3484 | if (conf == NULL) | 3486 | if (nla == NULL) |
3485 | goto nla_put_failure; | 3487 | goto nla_put_failure; |
3486 | ipv6_store_devconf(&idev->cnf, nla_data(conf), nla_len(conf)); | 3488 | ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla)); |
3487 | 3489 | ||
3488 | /* XXX - Statistics/MC not implemented */ | 3490 | /* XXX - MC not implemented */ |
3491 | |||
3492 | nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64)); | ||
3493 | if (nla == NULL) | ||
3494 | goto nla_put_failure; | ||
3495 | snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla)); | ||
3496 | |||
3497 | nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64)); | ||
3498 | if (nla == NULL) | ||
3499 | goto nla_put_failure; | ||
3500 | snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla)); | ||
3489 | 3501 | ||
3490 | nla_nest_end(skb, protoinfo); | 3502 | nla_nest_end(skb, protoinfo); |
3491 | return nlmsg_end(skb, nlh); | 3503 | return nlmsg_end(skb, nlh); |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index fa3fb509f187..0dc551501519 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -207,6 +207,31 @@ static const struct file_operations snmp6_seq_fops = { | |||
207 | .release = single_release, | 207 | .release = single_release, |
208 | }; | 208 | }; |
209 | 209 | ||
210 | static inline void | ||
211 | __snmp6_fill_stats(u64 *stats, void **mib, int items, int bytes) | ||
212 | { | ||
213 | int i; | ||
214 | int pad = bytes - sizeof(u64) * items; | ||
215 | BUG_ON(pad < 0); | ||
216 | stats[0] = items; | ||
217 | for (i = 1; i < items; i++) | ||
218 | stats[i] = (u64)fold_field(mib, i); | ||
219 | memset(&stats[items], 0, pad); | ||
220 | } | ||
221 | |||
222 | void | ||
223 | snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes) | ||
224 | { | ||
225 | switch(attrtype) { | ||
226 | case IFLA_INET6_STATS: | ||
227 | __snmp6_fill_stats(stats, (void **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); | ||
228 | break; | ||
229 | case IFLA_INET6_ICMP6STATS: | ||
230 | __snmp6_fill_stats(stats, (void **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); | ||
231 | break; | ||
232 | } | ||
233 | } | ||
234 | |||
210 | int snmp6_register_dev(struct inet6_dev *idev) | 235 | int snmp6_register_dev(struct inet6_dev *idev) |
211 | { | 236 | { |
212 | struct proc_dir_entry *p; | 237 | struct proc_dir_entry *p; |
@@ -283,6 +308,13 @@ int snmp6_unregister_dev(struct inet6_dev *idev) | |||
283 | { | 308 | { |
284 | return 0; | 309 | return 0; |
285 | } | 310 | } |
311 | |||
312 | void | ||
313 | snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes) | ||
314 | { | ||
315 | memset(stats, 0, sizeof(bytes)); | ||
316 | } | ||
317 | |||
286 | #endif /* CONFIG_PROC_FS */ | 318 | #endif /* CONFIG_PROC_FS */ |
287 | 319 | ||
288 | int snmp6_alloc_dev(struct inet6_dev *idev) | 320 | int snmp6_alloc_dev(struct inet6_dev *idev) |