aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/snmp.h10
-rw-r--r--include/net/ip.h3
-rw-r--r--include/net/ipv6.h15
-rw-r--r--include/net/snmp.h19
-rw-r--r--net/ipv4/ip_input.c13
-rw-r--r--net/ipv4/ip_output.c12
-rw-r--r--net/ipv4/proc.c10
-rw-r--r--net/ipv6/ip6_input.c7
-rw-r--r--net/ipv6/ip6_output.c9
-rw-r--r--net/ipv6/mcast.c19
-rw-r--r--net/ipv6/ndisc.c4
-rw-r--r--net/ipv6/proc.c10
-rw-r--r--net/ipv6/raw.c2
13 files changed, 97 insertions, 36 deletions
diff --git a/include/linux/snmp.h b/include/linux/snmp.h
index aee3f1e1d1ce..0f953fe40413 100644
--- a/include/linux/snmp.h
+++ b/include/linux/snmp.h
@@ -18,7 +18,7 @@
18enum 18enum
19{ 19{
20 IPSTATS_MIB_NUM = 0, 20 IPSTATS_MIB_NUM = 0,
21 IPSTATS_MIB_INRECEIVES, /* InReceives */ 21 IPSTATS_MIB_INPKTS, /* InReceives */
22 IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */ 22 IPSTATS_MIB_INHDRERRORS, /* InHdrErrors */
23 IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */ 23 IPSTATS_MIB_INTOOBIGERRORS, /* InTooBigErrors */
24 IPSTATS_MIB_INNOROUTES, /* InNoRoutes */ 24 IPSTATS_MIB_INNOROUTES, /* InNoRoutes */
@@ -28,7 +28,7 @@ enum
28 IPSTATS_MIB_INDISCARDS, /* InDiscards */ 28 IPSTATS_MIB_INDISCARDS, /* InDiscards */
29 IPSTATS_MIB_INDELIVERS, /* InDelivers */ 29 IPSTATS_MIB_INDELIVERS, /* InDelivers */
30 IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */ 30 IPSTATS_MIB_OUTFORWDATAGRAMS, /* OutForwDatagrams */
31 IPSTATS_MIB_OUTREQUESTS, /* OutRequests */ 31 IPSTATS_MIB_OUTPKTS, /* OutRequests */
32 IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */ 32 IPSTATS_MIB_OUTDISCARDS, /* OutDiscards */
33 IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */ 33 IPSTATS_MIB_OUTNOROUTES, /* OutNoRoutes */
34 IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */ 34 IPSTATS_MIB_REASMTIMEOUT, /* ReasmTimeout */
@@ -42,6 +42,12 @@ enum
42 IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */ 42 IPSTATS_MIB_OUTMCASTPKTS, /* OutMcastPkts */
43 IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */ 43 IPSTATS_MIB_INBCASTPKTS, /* InBcastPkts */
44 IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */ 44 IPSTATS_MIB_OUTBCASTPKTS, /* OutBcastPkts */
45 IPSTATS_MIB_INOCTETS, /* InOctets */
46 IPSTATS_MIB_OUTOCTETS, /* OutOctets */
47 IPSTATS_MIB_INMCASTOCTETS, /* InMcastOctets */
48 IPSTATS_MIB_OUTMCASTOCTETS, /* OutMcastOctets */
49 IPSTATS_MIB_INBCASTOCTETS, /* InBcastOctets */
50 IPSTATS_MIB_OUTBCASTOCTETS, /* OutBcastOctets */
45 __IPSTATS_MIB_MAX 51 __IPSTATS_MIB_MAX
46}; 52};
47 53
diff --git a/include/net/ip.h b/include/net/ip.h
index 4ac7577f98d0..72c36926c26d 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -168,7 +168,10 @@ struct ipv4_config
168extern struct ipv4_config ipv4_config; 168extern struct ipv4_config ipv4_config;
169#define IP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.ip_statistics, field) 169#define IP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.ip_statistics, field)
170#define IP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.ip_statistics, field) 170#define IP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.ip_statistics, field)
171#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.ip_statistics, field, val)
171#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH((net)->mib.ip_statistics, field, val) 172#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH((net)->mib.ip_statistics, field, val)
173#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS((net)->mib.ip_statistics, field, val)
174#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS_BH((net)->mib.ip_statistics, field, val)
172#define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field) 175#define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field)
173#define NET_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.net_statistics, field) 176#define NET_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.net_statistics, field)
174#define NET_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)->mib.net_statistics, field) 177#define NET_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)->mib.net_statistics, field)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index c1f16fc49ade..f27fd83d67d8 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -126,15 +126,28 @@ extern struct ctl_path net_ipv6_ctl_path[];
126 SNMP_ADD_STATS##modifier((net)->mib.statname##_statistics, (field), (val));\ 126 SNMP_ADD_STATS##modifier((net)->mib.statname##_statistics, (field), (val));\
127}) 127})
128 128
129#define _DEVUPD(net, statname, modifier, idev, field, val) \
130({ \
131 struct inet6_dev *_idev = (idev); \
132 if (likely(_idev != NULL)) \
133 SNMP_UPD_PO_STATS##modifier((_idev)->stats.statname, field, (val)); \
134 SNMP_UPD_PO_STATS##modifier((net)->mib.statname##_statistics, field, (val));\
135})
136
129/* MIBs */ 137/* MIBs */
130 138
131#define IP6_INC_STATS(net, idev,field) \ 139#define IP6_INC_STATS(net, idev,field) \
132 _DEVINC(net, ipv6, , idev, field) 140 _DEVINC(net, ipv6, , idev, field)
133#define IP6_INC_STATS_BH(net, idev,field) \ 141#define IP6_INC_STATS_BH(net, idev,field) \
134 _DEVINC(net, ipv6, _BH, idev, field) 142 _DEVINC(net, ipv6, _BH, idev, field)
143#define IP6_ADD_STATS(net, idev,field,val) \
144 _DEVADD(net, ipv6, , idev, field, val)
135#define IP6_ADD_STATS_BH(net, idev,field,val) \ 145#define IP6_ADD_STATS_BH(net, idev,field,val) \
136 _DEVADD(net, ipv6, _BH, idev, field, val) 146 _DEVADD(net, ipv6, _BH, idev, field, val)
137 147#define IP6_UPD_PO_STATS(net, idev,field,val) \
148 _DEVUPD(net, ipv6, , idev, field, val)
149#define IP6_UPD_PO_STATS_BH(net, idev,field,val) \
150 _DEVUPD(net, ipv6, _BH, idev, field, val)
138#define ICMP6_INC_STATS(net, idev, field) \ 151#define ICMP6_INC_STATS(net, idev, field) \
139 _DEVINC(net, icmpv6, , idev, field) 152 _DEVINC(net, icmpv6, , idev, field)
140#define ICMP6_INC_STATS_BH(net, idev, field) \ 153#define ICMP6_INC_STATS_BH(net, idev, field) \
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 57c93628695f..8c842e06bec8 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -153,6 +153,11 @@ struct linux_xfrm_mib {
153 per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \ 153 per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \
154 put_cpu(); \ 154 put_cpu(); \
155 } while (0) 155 } while (0)
156#define SNMP_ADD_STATS(mib, field, addend) \
157 do { \
158 per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field] += addend; \
159 put_cpu(); \
160 } while (0)
156#define SNMP_ADD_STATS_BH(mib, field, addend) \ 161#define SNMP_ADD_STATS_BH(mib, field, addend) \
157 (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend) 162 (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend)
158#define SNMP_ADD_STATS_USER(mib, field, addend) \ 163#define SNMP_ADD_STATS_USER(mib, field, addend) \
@@ -160,5 +165,17 @@ struct linux_xfrm_mib {
160 per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \ 165 per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \
161 put_cpu(); \ 166 put_cpu(); \
162 } while (0) 167 } while (0)
163 168#define SNMP_UPD_PO_STATS(mib, basefield, addend) \
169 do { \
170 __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], get_cpu());\
171 ptr->mibs[basefield##PKTS]++; \
172 ptr->mibs[basefield##OCTETS] += addend;\
173 put_cpu(); \
174 } while (0)
175#define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \
176 do { \
177 __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id());\
178 ptr->mibs[basefield##PKTS]++; \
179 ptr->mibs[basefield##OCTETS] += addend;\
180 } while (0)
164#endif 181#endif
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 1a58a6fa1dc0..40f6206b2aa9 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -358,10 +358,12 @@ static int ip_rcv_finish(struct sk_buff *skb)
358 goto drop; 358 goto drop;
359 359
360 rt = skb->rtable; 360 rt = skb->rtable;
361 if (rt->rt_type == RTN_MULTICAST) 361 if (rt->rt_type == RTN_MULTICAST) {
362 IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS); 362 IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST,
363 else if (rt->rt_type == RTN_BROADCAST) 363 skb->len);
364 IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS); 364 } else if (rt->rt_type == RTN_BROADCAST)
365 IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCAST,
366 skb->len);
365 367
366 return dst_input(skb); 368 return dst_input(skb);
367 369
@@ -384,7 +386,8 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
384 if (skb->pkt_type == PACKET_OTHERHOST) 386 if (skb->pkt_type == PACKET_OTHERHOST)
385 goto drop; 387 goto drop;
386 388
387 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES); 389
390 IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len);
388 391
389 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 392 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
390 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); 393 IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 3e7e910c7c0f..ea19c37ccc0c 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -181,10 +181,10 @@ static inline int ip_finish_output2(struct sk_buff *skb)
181 struct net_device *dev = dst->dev; 181 struct net_device *dev = dst->dev;
182 unsigned int hh_len = LL_RESERVED_SPACE(dev); 182 unsigned int hh_len = LL_RESERVED_SPACE(dev);
183 183
184 if (rt->rt_type == RTN_MULTICAST) 184 if (rt->rt_type == RTN_MULTICAST) {
185 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTMCASTPKTS); 185 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len);
186 else if (rt->rt_type == RTN_BROADCAST) 186 } else if (rt->rt_type == RTN_BROADCAST)
187 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTBCASTPKTS); 187 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTBCAST, skb->len);
188 188
189 /* Be paranoid, rather than too clever. */ 189 /* Be paranoid, rather than too clever. */
190 if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) { 190 if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
@@ -244,7 +244,7 @@ int ip_mc_output(struct sk_buff *skb)
244 /* 244 /*
245 * If the indicated interface is up and running, send the packet. 245 * If the indicated interface is up and running, send the packet.
246 */ 246 */
247 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); 247 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
248 248
249 skb->dev = dev; 249 skb->dev = dev;
250 skb->protocol = htons(ETH_P_IP); 250 skb->protocol = htons(ETH_P_IP);
@@ -298,7 +298,7 @@ int ip_output(struct sk_buff *skb)
298{ 298{
299 struct net_device *dev = skb->dst->dev; 299 struct net_device *dev = skb->dst->dev;
300 300
301 IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS); 301 IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
302 302
303 skb->dev = dev; 303 skb->dev = dev;
304 skb->protocol = htons(ETH_P_IP); 304 skb->protocol = htons(ETH_P_IP);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index cf0cdeeb1db0..f25542c48b7d 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -90,14 +90,14 @@ static const struct file_operations sockstat_seq_fops = {
90 90
91/* snmp items */ 91/* snmp items */
92static const struct snmp_mib snmp4_ipstats_list[] = { 92static const struct snmp_mib snmp4_ipstats_list[] = {
93 SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES), 93 SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS),
94 SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), 94 SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
95 SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), 95 SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
96 SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), 96 SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
97 SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS), 97 SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
98 SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS), 98 SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS),
99 SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS), 99 SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS),
100 SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTREQUESTS), 100 SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS),
101 SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS), 101 SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS),
102 SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), 102 SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
103 SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), 103 SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -118,6 +118,12 @@ static const struct snmp_mib snmp4_ipextstats_list[] = {
118 SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), 118 SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
119 SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS), 119 SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS),
120 SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS), 120 SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS),
121 SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS),
122 SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS),
123 SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
124 SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
125 SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
126 SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
121 SNMP_MIB_SENTINEL 127 SNMP_MIB_SENTINEL
122}; 128};
123 129
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 8f04bd9da274..bc1a920c34a1 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -70,7 +70,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
70 70
71 idev = __in6_dev_get(skb->dev); 71 idev = __in6_dev_get(skb->dev);
72 72
73 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INRECEIVES); 73 IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_IN, skb->len);
74 74
75 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL || 75 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
76 !idev || unlikely(idev->cnf.disable_ipv6)) { 76 !idev || unlikely(idev->cnf.disable_ipv6)) {
@@ -242,8 +242,9 @@ int ip6_mc_input(struct sk_buff *skb)
242 struct ipv6hdr *hdr; 242 struct ipv6hdr *hdr;
243 int deliver; 243 int deliver;
244 244
245 IP6_INC_STATS_BH(dev_net(skb->dst->dev), 245 IP6_UPD_PO_STATS_BH(dev_net(skb->dst->dev),
246 ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); 246 ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCAST,
247 skb->len);
247 248
248 hdr = ipv6_hdr(skb); 249 hdr = ipv6_hdr(skb);
249 deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); 250 deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 9fb49c3b518a..735a2bf4b5f1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -159,7 +159,8 @@ static int ip6_output2(struct sk_buff *skb)
159 } 159 }
160 } 160 }
161 161
162 IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS); 162 IP6_UPD_PO_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCAST,
163 skb->len);
163 } 164 }
164 165
165 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, 166 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -275,8 +276,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
275 276
276 mtu = dst_mtu(dst); 277 mtu = dst_mtu(dst);
277 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { 278 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
278 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), 279 IP6_UPD_PO_STATS(net, ip6_dst_idev(skb->dst),
279 IPSTATS_MIB_OUTREQUESTS); 280 IPSTATS_MIB_OUT, skb->len);
280 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 281 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
281 dst_output); 282 dst_output);
282 } 283 }
@@ -1516,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk)
1516 skb->mark = sk->sk_mark; 1517 skb->mark = sk->sk_mark;
1517 1518
1518 skb->dst = dst_clone(&rt->u.dst); 1519 skb->dst = dst_clone(&rt->u.dst);
1519 IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 1520 IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
1520 if (proto == IPPROTO_ICMPV6) { 1521 if (proto == IPPROTO_ICMPV6) {
1521 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 1522 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
1522 1523
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index a51fb33e6864..4b48819a5b8d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1449,7 +1449,8 @@ static void mld_sendpack(struct sk_buff *skb)
1449 int err; 1449 int err;
1450 struct flowi fl; 1450 struct flowi fl;
1451 1451
1452 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); 1452 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
1453
1453 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); 1454 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
1454 mldlen = skb->tail - skb->transport_header; 1455 mldlen = skb->tail - skb->transport_header;
1455 pip6->payload_len = htons(payload_len); 1456 pip6->payload_len = htons(payload_len);
@@ -1473,13 +1474,15 @@ static void mld_sendpack(struct sk_buff *skb)
1473 if (err) 1474 if (err)
1474 goto err_out; 1475 goto err_out;
1475 1476
1477 payload_len = skb->len;
1478
1476 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1479 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1477 dst_output); 1480 dst_output);
1478out: 1481out:
1479 if (!err) { 1482 if (!err) {
1480 ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT); 1483 ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
1481 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); 1484 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
1482 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS); 1485 IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
1483 } else 1486 } else
1484 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS); 1487 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
1485 1488
@@ -1773,10 +1776,6 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1773 IPV6_TLV_PADN, 0 }; 1776 IPV6_TLV_PADN, 0 };
1774 struct flowi fl; 1777 struct flowi fl;
1775 1778
1776 rcu_read_lock();
1777 IP6_INC_STATS(net, __in6_dev_get(dev),
1778 IPSTATS_MIB_OUTREQUESTS);
1779 rcu_read_unlock();
1780 if (type == ICMPV6_MGM_REDUCTION) 1779 if (type == ICMPV6_MGM_REDUCTION)
1781 snd_addr = &in6addr_linklocal_allrouters; 1780 snd_addr = &in6addr_linklocal_allrouters;
1782 else 1781 else
@@ -1786,6 +1785,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1786 payload_len = len + sizeof(ra); 1785 payload_len = len + sizeof(ra);
1787 full_len = sizeof(struct ipv6hdr) + payload_len; 1786 full_len = sizeof(struct ipv6hdr) + payload_len;
1788 1787
1788 rcu_read_lock();
1789 IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
1790 IPSTATS_MIB_OUT, full_len);
1791 rcu_read_unlock();
1792
1789 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err); 1793 skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
1790 1794
1791 if (skb == NULL) { 1795 if (skb == NULL) {
@@ -1838,13 +1842,14 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1838 if (err) 1842 if (err)
1839 goto err_out; 1843 goto err_out;
1840 1844
1845
1841 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev, 1846 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
1842 dst_output); 1847 dst_output);
1843out: 1848out:
1844 if (!err) { 1849 if (!err) {
1845 ICMP6MSGOUT_INC_STATS(net, idev, type); 1850 ICMP6MSGOUT_INC_STATS(net, idev, type);
1846 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS); 1851 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1847 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS); 1852 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
1848 } else 1853 } else
1849 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS); 1854 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
1850 1855
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 9f061d1adbc2..ab65cc51b00e 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -533,7 +533,7 @@ void ndisc_send_skb(struct sk_buff *skb,
533 skb->dst = dst; 533 skb->dst = dst;
534 534
535 idev = in6_dev_get(dst->dev); 535 idev = in6_dev_get(dst->dev);
536 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); 536 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
537 537
538 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 538 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
539 dst_output); 539 dst_output);
@@ -1613,7 +1613,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1613 1613
1614 buff->dst = dst; 1614 buff->dst = dst;
1615 idev = in6_dev_get(dst->dev); 1615 idev = in6_dev_get(dst->dev);
1616 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS); 1616 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
1617 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, 1617 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
1618 dst_output); 1618 dst_output);
1619 if (!err) { 1619 if (!err) {
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 97c17fdd6f75..590ddefb7ffc 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -61,7 +61,7 @@ static const struct file_operations sockstat6_seq_fops = {
61 61
62static struct snmp_mib snmp6_ipstats_list[] = { 62static struct snmp_mib snmp6_ipstats_list[] = {
63/* ipv6 mib according to RFC 2465 */ 63/* ipv6 mib according to RFC 2465 */
64 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES), 64 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INPKTS),
65 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS), 65 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS),
66 SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS), 66 SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS),
67 SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES), 67 SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES),
@@ -71,7 +71,7 @@ static struct snmp_mib snmp6_ipstats_list[] = {
71 SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS), 71 SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS),
72 SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS), 72 SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS),
73 SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS), 73 SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
74 SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTREQUESTS), 74 SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTPKTS),
75 SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS), 75 SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS),
76 SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES), 76 SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
77 SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT), 77 SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -83,6 +83,12 @@ static struct snmp_mib snmp6_ipstats_list[] = {
83 SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES), 83 SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES),
84 SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS), 84 SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
85 SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS), 85 SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
86 SNMP_MIB_ITEM("Ip6InOctets", IPSTATS_MIB_INOCTETS),
87 SNMP_MIB_ITEM("Ip6OutOctets", IPSTATS_MIB_OUTOCTETS),
88 SNMP_MIB_ITEM("Ip6InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
89 SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
90 SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
91 SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
86 SNMP_MIB_SENTINEL 92 SNMP_MIB_SENTINEL
87}; 93};
88 94
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 61f6827e5906..e99307fba0b1 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -638,7 +638,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
638 if (err) 638 if (err)
639 goto error_fault; 639 goto error_fault;
640 640
641 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 641 IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
642 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, 642 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
643 dst_output); 643 dst_output);
644 if (err > 0) 644 if (err > 0)