aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/snmp.h27
-rw-r--r--include/net/if_inet6.h1
-rw-r--r--include/net/ipv6.h67
-rw-r--r--include/net/snmp.h6
-rw-r--r--net/ipv6/addrconf.c7
-rw-r--r--net/ipv6/af_inet6.c5
-rw-r--r--net/ipv6/icmp.c12
-rw-r--r--net/ipv6/ip6_output.c7
-rw-r--r--net/ipv6/mcast.c12
-rw-r--r--net/ipv6/ndisc.c21
-rw-r--r--net/ipv6/proc.c92
11 files changed, 135 insertions, 122 deletions
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index d24c55473821..86977e31548a 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -91,35 +91,12 @@ enum
91 ICMP6_MIB_NUM = 0, 91 ICMP6_MIB_NUM = 0,
92 ICMP6_MIB_INMSGS, /* InMsgs */ 92 ICMP6_MIB_INMSGS, /* InMsgs */
93 ICMP6_MIB_INERRORS, /* InErrors */ 93 ICMP6_MIB_INERRORS, /* InErrors */
94 ICMP6_MIB_INDESTUNREACHS, /* InDestUnreachs */
95 ICMP6_MIB_INPKTTOOBIGS, /* InPktTooBigs */
96 ICMP6_MIB_INTIMEEXCDS, /* InTimeExcds */
97 ICMP6_MIB_INPARMPROBLEMS, /* InParmProblems */
98 ICMP6_MIB_INECHOS, /* InEchos */
99 ICMP6_MIB_INECHOREPLIES, /* InEchoReplies */
100 ICMP6_MIB_INGROUPMEMBQUERIES, /* InGroupMembQueries */
101 ICMP6_MIB_INGROUPMEMBRESPONSES, /* InGroupMembResponses */
102 ICMP6_MIB_INGROUPMEMBREDUCTIONS, /* InGroupMembReductions */
103 ICMP6_MIB_INROUTERSOLICITS, /* InRouterSolicits */
104 ICMP6_MIB_INROUTERADVERTISEMENTS, /* InRouterAdvertisements */
105 ICMP6_MIB_INNEIGHBORSOLICITS, /* InNeighborSolicits */
106 ICMP6_MIB_INNEIGHBORADVERTISEMENTS, /* InNeighborAdvertisements */
107 ICMP6_MIB_INREDIRECTS, /* InRedirects */
108 ICMP6_MIB_OUTMSGS, /* OutMsgs */ 94 ICMP6_MIB_OUTMSGS, /* OutMsgs */
109 ICMP6_MIB_OUTDESTUNREACHS, /* OutDestUnreachs */
110 ICMP6_MIB_OUTPKTTOOBIGS, /* OutPktTooBigs */
111 ICMP6_MIB_OUTTIMEEXCDS, /* OutTimeExcds */
112 ICMP6_MIB_OUTPARMPROBLEMS, /* OutParmProblems */
113 ICMP6_MIB_OUTECHOREPLIES, /* OutEchoReplies */
114 ICMP6_MIB_OUTROUTERSOLICITS, /* OutRouterSolicits */
115 ICMP6_MIB_OUTNEIGHBORSOLICITS, /* OutNeighborSolicits */
116 ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS, /* OutNeighborAdvertisements */
117 ICMP6_MIB_OUTREDIRECTS, /* OutRedirects */
118 ICMP6_MIB_OUTGROUPMEMBRESPONSES, /* OutGroupMembResponses */
119 ICMP6_MIB_OUTGROUPMEMBREDUCTIONS, /* OutGroupMembReductions */
120 __ICMP6_MIB_MAX 95 __ICMP6_MIB_MAX
121}; 96};
122 97
98#define __ICMP6MSG_MIB_MAX 512 /* Out+In for all 8-bit ICMPv6 types */
99
123/* tcp mib definitions */ 100/* tcp mib definitions */
124/* 101/*
125 * RFC 1213: MIB-II TCP group 102 * RFC 1213: MIB-II TCP group
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 3ec7d07346d6..448eccb20638 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -154,6 +154,7 @@ struct ipv6_devstat {
154 struct proc_dir_entry *proc_dir_entry; 154 struct proc_dir_entry *proc_dir_entry;
155 DEFINE_SNMP_STAT(struct ipstats_mib, ipv6); 155 DEFINE_SNMP_STAT(struct ipstats_mib, ipv6);
156 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6); 156 DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6);
157 DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg);
157}; 158};
158 159
159struct inet6_dev 160struct inet6_dev
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 9573c8d19153..31b3f1b45a2b 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -112,45 +112,28 @@ struct frag_hdr {
112extern int sysctl_ipv6_bindv6only; 112extern int sysctl_ipv6_bindv6only;
113extern int sysctl_mld_max_msf; 113extern int sysctl_mld_max_msf;
114 114
115/* MIBs */ 115#define _DEVINC(statname, modifier, idev, field) \
116DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); 116({ \
117#define IP6_INC_STATS(idev,field) ({ \
118 struct inet6_dev *_idev = (idev); \ 117 struct inet6_dev *_idev = (idev); \
119 if (likely(_idev != NULL)) \ 118 if (likely(_idev != NULL)) \
120 SNMP_INC_STATS(_idev->stats.ipv6, field); \ 119 SNMP_INC_STATS##modifier((_idev)->stats.statname, (field)); \
121 SNMP_INC_STATS(ipv6_statistics, field); \ 120 SNMP_INC_STATS##modifier(statname##_statistics, (field)); \
122})
123#define IP6_INC_STATS_BH(idev,field) ({ \
124 struct inet6_dev *_idev = (idev); \
125 if (likely(_idev != NULL)) \
126 SNMP_INC_STATS_BH(_idev->stats.ipv6, field); \
127 SNMP_INC_STATS_BH(ipv6_statistics, field); \
128})
129#define IP6_INC_STATS_USER(idev,field) ({ \
130 struct inet6_dev *_idev = (idev); \
131 if (likely(_idev != NULL)) \
132 SNMP_INC_STATS_USER(_idev->stats.ipv6, field); \
133 SNMP_INC_STATS_USER(ipv6_statistics, field); \
134}) 121})
122
123/* MIBs */
124DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics);
125
126#define IP6_INC_STATS(idev,field) _DEVINC(ipv6, , idev, field)
127#define IP6_INC_STATS_BH(idev,field) _DEVINC(ipv6, _BH, idev, field)
128#define IP6_INC_STATS_USER(idev,field) _DEVINC(ipv6, _USER, idev, field)
129
135DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); 130DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
136#define ICMP6_INC_STATS(idev, field) ({ \ 131DECLARE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics);
137 struct inet6_dev *_idev = (idev); \ 132
138 if (likely(_idev != NULL)) \ 133#define ICMP6_INC_STATS(idev, field) _DEVINC(icmpv6, , idev, field)
139 SNMP_INC_STATS(idev->stats.icmpv6, field); \ 134#define ICMP6_INC_STATS_BH(idev, field) _DEVINC(icmpv6, _BH, idev, field)
140 SNMP_INC_STATS(icmpv6_statistics, field); \ 135#define ICMP6_INC_STATS_USER(idev, field) _DEVINC(icmpv6, _USER, idev, field)
141}) 136
142#define ICMP6_INC_STATS_BH(idev, field) ({ \
143 struct inet6_dev *_idev = (idev); \
144 if (likely(_idev != NULL)) \
145 SNMP_INC_STATS_BH((_idev)->stats.icmpv6, field); \
146 SNMP_INC_STATS_BH(icmpv6_statistics, field); \
147})
148#define ICMP6_INC_STATS_USER(idev, field) ({ \
149 struct inet6_dev *_idev = (idev); \
150 if (likely(_idev != NULL)) \
151 SNMP_INC_STATS_USER(_idev->stats.icmpv6, field); \
152 SNMP_INC_STATS_USER(icmpv6_statistics, field); \
153})
154#define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({ \ 137#define ICMP6_INC_STATS_OFFSET_BH(idev, field, offset) ({ \
155 struct inet6_dev *_idev = idev; \ 138 struct inet6_dev *_idev = idev; \
156 __typeof__(offset) _offset = (offset); \ 139 __typeof__(offset) _offset = (offset); \
@@ -158,6 +141,20 @@ DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics);
158 SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset); \ 141 SNMP_INC_STATS_OFFSET_BH(_idev->stats.icmpv6, field, _offset); \
159 SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \ 142 SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \
160}) 143})
144
145#define ICMP6MSGOUT_INC_STATS(idev, field) \
146 _DEVINC(icmpv6msg, , idev, field +256)
147#define ICMP6MSGOUT_INC_STATS_BH(idev, field) \
148 _DEVINC(icmpv6msg, _BH, idev, field +256)
149#define ICMP6MSGOUT_INC_STATS_USER(idev, field) \
150 _DEVINC(icmpv6msg, _USER, idev, field +256)
151#define ICMP6MSGIN_INC_STATS(idev, field) \
152 _DEVINC(icmpv6msg, , idev, field)
153#define ICMP6MSGIN_INC_STATS_BH(idev, field) \
154 _DEVINC(icmpv6msg, _BH, idev, field)
155#define ICMP6MSGIN_INC_STATS_USER(idev, field) \
156 _DEVINC(icmpv6msg, _USER, idev, field)
157
161DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6); 158DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
162DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6); 159DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6);
163#define UDP6_INC_STATS_BH(field, is_udplite) do { \ 160#define UDP6_INC_STATS_BH(field, is_udplite) do { \
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 464970e39ec0..a566e11d2f98 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -88,6 +88,12 @@ struct icmpv6_mib {
88 unsigned long mibs[ICMP6_MIB_MAX]; 88 unsigned long mibs[ICMP6_MIB_MAX];
89} __SNMP_MIB_ALIGN__; 89} __SNMP_MIB_ALIGN__;
90 90
91#define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX
92struct icmpv6msg_mib {
93 unsigned long mibs[ICMP6MSG_MIB_MAX];
94} __SNMP_MIB_ALIGN__;
95
96
91/* TCP */ 97/* TCP */
92#define TCP_MIB_MAX __TCP_MIB_MAX 98#define TCP_MIB_MAX __TCP_MIB_MAX
93struct tcp_mib { 99struct tcp_mib {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a68c626567f2..9c2e94f1c637 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -261,9 +261,15 @@ static int snmp6_alloc_dev(struct inet6_dev *idev)
261 sizeof(struct icmpv6_mib), 261 sizeof(struct icmpv6_mib),
262 __alignof__(struct icmpv6_mib)) < 0) 262 __alignof__(struct icmpv6_mib)) < 0)
263 goto err_icmp; 263 goto err_icmp;
264 if (snmp_mib_init((void **)idev->stats.icmpv6msg,
265 sizeof(struct icmpv6msg_mib),
266 __alignof__(struct icmpv6msg_mib)) < 0)
267 goto err_icmpmsg;
264 268
265 return 0; 269 return 0;
266 270
271err_icmpmsg:
272 snmp_mib_free((void **)idev->stats.icmpv6);
267err_icmp: 273err_icmp:
268 snmp_mib_free((void **)idev->stats.ipv6); 274 snmp_mib_free((void **)idev->stats.ipv6);
269err_ip: 275err_ip:
@@ -272,6 +278,7 @@ err_ip:
272 278
273static int snmp6_free_dev(struct inet6_dev *idev) 279static int snmp6_free_dev(struct inet6_dev *idev)
274{ 280{
281 snmp_mib_free((void **)idev->stats.icmpv6msg);
275 snmp_mib_free((void **)idev->stats.icmpv6); 282 snmp_mib_free((void **)idev->stats.icmpv6);
276 snmp_mib_free((void **)idev->stats.ipv6); 283 snmp_mib_free((void **)idev->stats.ipv6);
277 return 0; 284 return 0;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e5c5aad44bb1..bc929381fa46 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -719,6 +719,9 @@ static int __init init_ipv6_mibs(void)
719 if (snmp_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib), 719 if (snmp_mib_init((void **)icmpv6_statistics, sizeof (struct icmpv6_mib),
720 __alignof__(struct icmpv6_mib)) < 0) 720 __alignof__(struct icmpv6_mib)) < 0)
721 goto err_icmp_mib; 721 goto err_icmp_mib;
722 if (snmp_mib_init((void **)icmpv6msg_statistics,
723 sizeof (struct icmpv6msg_mib), __alignof__(struct icmpv6_mib)) < 0)
724 goto err_icmpmsg_mib;
722 if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib), 725 if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib),
723 __alignof__(struct udp_mib)) < 0) 726 __alignof__(struct udp_mib)) < 0)
724 goto err_udp_mib; 727 goto err_udp_mib;
@@ -730,6 +733,8 @@ static int __init init_ipv6_mibs(void)
730err_udplite_mib: 733err_udplite_mib:
731 snmp_mib_free((void **)udp_stats_in6); 734 snmp_mib_free((void **)udp_stats_in6);
732err_udp_mib: 735err_udp_mib:
736 snmp_mib_free((void **)icmpv6msg_statistics);
737err_icmpmsg_mib:
733 snmp_mib_free((void **)icmpv6_statistics); 738 snmp_mib_free((void **)icmpv6_statistics);
734err_icmp_mib: 739err_icmp_mib:
735 snmp_mib_free((void **)ipv6_statistics); 740 snmp_mib_free((void **)ipv6_statistics);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 6a6714d154ed..47b8ce232e84 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -69,6 +69,8 @@
69 69
70DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly; 70DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
71EXPORT_SYMBOL(icmpv6_statistics); 71EXPORT_SYMBOL(icmpv6_statistics);
72DEFINE_SNMP_STAT(struct icmpv6msg_mib, icmpv6msg_statistics) __read_mostly;
73EXPORT_SYMBOL(icmpv6msg_statistics);
72 74
73/* 75/*
74 * The ICMP socket(s). This is the most convenient way to flow control 76 * The ICMP socket(s). This is the most convenient way to flow control
@@ -456,8 +458,6 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
456 } 458 }
457 err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr)); 459 err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
458 460
459 if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
460 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_OUTDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
461 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); 461 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
462 462
463out_put: 463out_put:
@@ -547,9 +547,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
547 } 547 }
548 err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr)); 548 err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, skb->len + sizeof(struct icmp6hdr));
549 549
550 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTECHOREPLIES);
551 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
552
553out_put: 550out_put:
554 if (likely(idev != NULL)) 551 if (likely(idev != NULL))
555 in6_dev_put(idev); 552 in6_dev_put(idev);
@@ -656,10 +653,7 @@ static int icmpv6_rcv(struct sk_buff **pskb)
656 653
657 type = hdr->icmp6_type; 654 type = hdr->icmp6_type;
658 655
659 if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB) 656 ICMP6MSGIN_INC_STATS_BH(idev, type);
660 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INDESTUNREACHS, type - ICMPV6_DEST_UNREACH);
661 else if (type >= ICMPV6_ECHO_REQUEST && type <= NDISC_REDIRECT)
662 ICMP6_INC_STATS_OFFSET_BH(idev, ICMP6_MIB_INECHOS, type - ICMPV6_ECHO_REQUEST);
663 657
664 switch (type) { 658 switch (type) {
665 case ICMPV6_ECHO_REQUEST: 659 case ICMPV6_ECHO_REQUEST:
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e46d4683eab0..011082ed921a 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1399,6 +1399,13 @@ int ip6_push_pending_frames(struct sock *sk)
1399 1399
1400 skb->dst = dst_clone(&rt->u.dst); 1400 skb->dst = dst_clone(&rt->u.dst);
1401 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 1401 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
1402 if (proto == IPPROTO_ICMPV6) {
1403 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
1404
1405 ICMP6MSGOUT_INC_STATS_BH(idev, icmp6_hdr(skb)->icmp6_type);
1406 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
1407 }
1408
1402 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); 1409 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
1403 if (err) { 1410 if (err) {
1404 if (err > 0) 1411 if (err > 0)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index e2ab43c989d4..86d908b1caea 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1479,10 +1479,11 @@ static void mld_sendpack(struct sk_buff *skb)
1479 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, 1479 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
1480 mld_dev_queue_xmit); 1480 mld_dev_queue_xmit);
1481 if (!err) { 1481 if (!err) {
1482 ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); 1482 ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT);
1483 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); 1483 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
1484 IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTMCASTPKTS);
1484 } else 1485 } else
1485 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 1486 IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTDISCARDS);
1486 1487
1487 if (likely(idev != NULL)) 1488 if (likely(idev != NULL))
1488 in6_dev_put(idev); 1489 in6_dev_put(idev);
@@ -1822,10 +1823,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1822 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev, 1823 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dev,
1823 mld_dev_queue_xmit); 1824 mld_dev_queue_xmit);
1824 if (!err) { 1825 if (!err) {
1825 if (type == ICMPV6_MGM_REDUCTION) 1826 ICMP6MSGOUT_INC_STATS(idev, type);
1826 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBREDUCTIONS);
1827 else
1828 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBRESPONSES);
1829 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 1827 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1830 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); 1828 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
1831 } else 1829 } else
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index d2d44dc22f19..7ea5a502ca08 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -431,7 +431,7 @@ static void __ndisc_send(struct net_device *dev,
431 struct neighbour *neigh, 431 struct neighbour *neigh,
432 struct in6_addr *daddr, struct in6_addr *saddr, 432 struct in6_addr *daddr, struct in6_addr *saddr,
433 struct icmp6hdr *icmp6h, struct in6_addr *target, 433 struct icmp6hdr *icmp6h, struct in6_addr *target,
434 int llinfo, int icmp6_mib_outnd) 434 int llinfo)
435{ 435{
436 struct flowi fl; 436 struct flowi fl;
437 struct dst_entry *dst; 437 struct dst_entry *dst;
@@ -441,9 +441,11 @@ static void __ndisc_send(struct net_device *dev,
441 struct inet6_dev *idev; 441 struct inet6_dev *idev;
442 int len; 442 int len;
443 int err; 443 int err;
444 u8 *opt; 444 u8 *opt, type;
445
446 type = icmp6h->icmp6_type;
445 447
446 ndisc_flow_init(&fl, icmp6h->icmp6_type, saddr, daddr, 448 ndisc_flow_init(&fl, type, saddr, daddr,
447 dev->ifindex); 449 dev->ifindex);
448 450
449 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); 451 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output);
@@ -504,7 +506,7 @@ static void __ndisc_send(struct net_device *dev,
504 506
505 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); 507 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
506 if (!err) { 508 if (!err) {
507 ICMP6_INC_STATS(idev, icmp6_mib_outnd); 509 ICMP6MSGOUT_INC_STATS(idev, type);
508 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 510 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
509 } 511 }
510 512
@@ -542,8 +544,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
542 544
543 __ndisc_send(dev, neigh, daddr, src_addr, 545 __ndisc_send(dev, neigh, daddr, src_addr,
544 &icmp6h, solicited_addr, 546 &icmp6h, solicited_addr,
545 inc_opt ? ND_OPT_TARGET_LL_ADDR : 0, 547 inc_opt ? ND_OPT_TARGET_LL_ADDR : 0);
546 ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
547} 548}
548 549
549void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, 550void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
@@ -564,8 +565,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
564 565
565 __ndisc_send(dev, neigh, daddr, saddr, 566 __ndisc_send(dev, neigh, daddr, saddr,
566 &icmp6h, solicit, 567 &icmp6h, solicit,
567 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0, 568 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
568 ICMP6_MIB_OUTNEIGHBORSOLICITS);
569} 569}
570 570
571void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, 571void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
@@ -599,8 +599,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
599#endif 599#endif
600 __ndisc_send(dev, NULL, daddr, saddr, 600 __ndisc_send(dev, NULL, daddr, saddr,
601 &icmp6h, NULL, 601 &icmp6h, NULL,
602 send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0, 602 send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
603 ICMP6_MIB_OUTROUTERSOLICITS);
604} 603}
605 604
606 605
@@ -1455,7 +1454,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1455 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); 1454 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
1456 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output); 1455 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1457 if (!err) { 1456 if (!err) {
1458 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS); 1457 ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT);
1459 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 1458 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1460 } 1459 }
1461 1460
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index a712a2289484..db945018579e 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -86,47 +86,33 @@ static struct snmp_mib snmp6_ipstats_list[] = {
86}; 86};
87 87
88static struct snmp_mib snmp6_icmp6_list[] = { 88static struct snmp_mib snmp6_icmp6_list[] = {
89/* icmpv6 mib according to RFC 2466 89/* icmpv6 mib according to RFC 2466 */
90
91 Exceptions: {In|Out}AdminProhibs are removed, because I see
92 no good reasons to account them separately
93 of another dest.unreachs.
94 OutErrs is zero identically.
95 OutEchos too.
96 OutRouterAdvertisements too.
97 OutGroupMembQueries too.
98 */
99 SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS), 90 SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS),
100 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), 91 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS),
101 SNMP_MIB_ITEM("Icmp6InDestUnreachs", ICMP6_MIB_INDESTUNREACHS),
102 SNMP_MIB_ITEM("Icmp6InPktTooBigs", ICMP6_MIB_INPKTTOOBIGS),
103 SNMP_MIB_ITEM("Icmp6InTimeExcds", ICMP6_MIB_INTIMEEXCDS),
104 SNMP_MIB_ITEM("Icmp6InParmProblems", ICMP6_MIB_INPARMPROBLEMS),
105 SNMP_MIB_ITEM("Icmp6InEchos", ICMP6_MIB_INECHOS),
106 SNMP_MIB_ITEM("Icmp6InEchoReplies", ICMP6_MIB_INECHOREPLIES),
107 SNMP_MIB_ITEM("Icmp6InGroupMembQueries", ICMP6_MIB_INGROUPMEMBQUERIES),
108 SNMP_MIB_ITEM("Icmp6InGroupMembResponses", ICMP6_MIB_INGROUPMEMBRESPONSES),
109 SNMP_MIB_ITEM("Icmp6InGroupMembReductions", ICMP6_MIB_INGROUPMEMBREDUCTIONS),
110 SNMP_MIB_ITEM("Icmp6InRouterSolicits", ICMP6_MIB_INROUTERSOLICITS),
111 SNMP_MIB_ITEM("Icmp6InRouterAdvertisements", ICMP6_MIB_INROUTERADVERTISEMENTS),
112 SNMP_MIB_ITEM("Icmp6InNeighborSolicits", ICMP6_MIB_INNEIGHBORSOLICITS),
113 SNMP_MIB_ITEM("Icmp6InNeighborAdvertisements", ICMP6_MIB_INNEIGHBORADVERTISEMENTS),
114 SNMP_MIB_ITEM("Icmp6InRedirects", ICMP6_MIB_INREDIRECTS),
115 SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), 92 SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS),
116 SNMP_MIB_ITEM("Icmp6OutDestUnreachs", ICMP6_MIB_OUTDESTUNREACHS),
117 SNMP_MIB_ITEM("Icmp6OutPktTooBigs", ICMP6_MIB_OUTPKTTOOBIGS),
118 SNMP_MIB_ITEM("Icmp6OutTimeExcds", ICMP6_MIB_OUTTIMEEXCDS),
119 SNMP_MIB_ITEM("Icmp6OutParmProblems", ICMP6_MIB_OUTPARMPROBLEMS),
120 SNMP_MIB_ITEM("Icmp6OutEchoReplies", ICMP6_MIB_OUTECHOREPLIES),
121 SNMP_MIB_ITEM("Icmp6OutRouterSolicits", ICMP6_MIB_OUTROUTERSOLICITS),
122 SNMP_MIB_ITEM("Icmp6OutNeighborSolicits", ICMP6_MIB_OUTNEIGHBORSOLICITS),
123 SNMP_MIB_ITEM("Icmp6OutNeighborAdvertisements", ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS),
124 SNMP_MIB_ITEM("Icmp6OutRedirects", ICMP6_MIB_OUTREDIRECTS),
125 SNMP_MIB_ITEM("Icmp6OutGroupMembResponses", ICMP6_MIB_OUTGROUPMEMBRESPONSES),
126 SNMP_MIB_ITEM("Icmp6OutGroupMembReductions", ICMP6_MIB_OUTGROUPMEMBREDUCTIONS),
127 SNMP_MIB_SENTINEL 93 SNMP_MIB_SENTINEL
128}; 94};
129 95
96/* RFC 4293 v6 ICMPMsgStatsTable; named items for RFC 2466 compatibility */
97static char *icmp6type2name[256] = {
98 [ICMPV6_DEST_UNREACH] = "DestUnreachs",
99 [ICMPV6_PKT_TOOBIG] = "PktTooBigs",
100 [ICMPV6_TIME_EXCEED] = "TimeExcds",
101 [ICMPV6_PARAMPROB] = "ParmProblems",
102 [ICMPV6_ECHO_REQUEST] = "EchoRequest",
103 [ICMPV6_ECHO_REPLY] = "EchoReplies",
104 [ICMPV6_MGM_QUERY] = "GroupMembQueries",
105 [ICMPV6_MGM_REPORT] = "GroupMembResponses",
106 [ICMPV6_MGM_REDUCTION] = "GroupMembReductions",
107 [ICMPV6_MLD2_REPORT] = "MLDv2Reports",
108 [NDISC_ROUTER_ADVERTISEMENT] = "RouterAdvertisements",
109 [NDISC_ROUTER_SOLICITATION] = "RouterSolicits",
110 [NDISC_NEIGHBOUR_ADVERTISEMENT] = "NeighborAdvertisements",
111 [NDISC_NEIGHBOUR_SOLICITATION] = "NeighborSolicits",
112 [NDISC_REDIRECT] = "NeighborRedirects",
113};
114
115
130static struct snmp_mib snmp6_udp6_list[] = { 116static struct snmp_mib snmp6_udp6_list[] = {
131 SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS), 117 SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS),
132 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS), 118 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS),
@@ -143,6 +129,40 @@ static struct snmp_mib snmp6_udplite6_list[] = {
143 SNMP_MIB_SENTINEL 129 SNMP_MIB_SENTINEL
144}; 130};
145 131
132static void snmp6_seq_show_icmpv6msg(struct seq_file *seq, void **mib)
133{
134 static char name[32];
135 int i;
136
137 /* print by name -- deprecated items */
138 for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
139 int icmptype;
140 char *p;
141
142 icmptype = i & 0xff;
143 p = icmp6type2name[icmptype];
144 if (!p) /* don't print un-named types here */
145 continue;
146 (void) snprintf(name, sizeof(name)-1, "Icmp6%s%s",
147 i & 0x100 ? "Out" : "In", p);
148 seq_printf(seq, "%-32s\t%lu\n", name,
149 snmp_fold_field(mib, i));
150 }
151
152 /* print by number (nonzero only) - ICMPMsgStat format */
153 for (i = 0; i < ICMP6MSG_MIB_MAX; i++) {
154 unsigned long val;
155
156 val = snmp_fold_field(mib, i);
157 if (!val)
158 continue;
159 (void) snprintf(name, sizeof(name)-1, "Icmp6%sType%u",
160 i & 0x100 ? "Out" : "In", i & 0xff);
161 seq_printf(seq, "%-32s\t%lu\n", name, val);
162 }
163 return;
164}
165
146static inline void 166static inline void
147snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist) 167snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist)
148{ 168{
@@ -160,9 +180,11 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
160 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); 180 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
161 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); 181 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
162 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); 182 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
183 snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg);
163 } else { 184 } else {
164 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); 185 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
165 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); 186 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
187 snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics);
166 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); 188 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
167 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list); 189 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
168 } 190 }