diff options
author | Eric Dumazet <edumazet@google.com> | 2013-04-29 04:39:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-29 15:14:03 -0400 |
commit | 6a5dc9e598fe90160fee7de098fa319665f5253e (patch) | |
tree | 7f2c2130e3dec81aea01e997cec7e87744f02694 /net/ipv6 | |
parent | f233a976ad15c3b8c54c0157f3c41d23f7514279 (diff) |
net: Add MIB counters for checksum errors
Add MIB counters for checksum errors in IP layer,
and TCP/UDP/ICMP layers, to help diagnose problems.
$ nstat -a | grep Csum
IcmpInCsumErrors 72 0.0
TcpInCsumErrors 382 0.0
UdpInCsumErrors 463221 0.0
Icmp6InCsumErrors 75 0.0
Udp6InCsumErrors 173442 0.0
IpExtInCsumErrors 10884 0.0
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/icmp.c | 4 | ||||
-rw-r--r-- | net/ipv6/proc.c | 4 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 19 | ||||
-rw-r--r-- | net/ipv6/udp.c | 21 |
4 files changed, 32 insertions, 16 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 2a53a790514d..b4ff0a42b8c7 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c | |||
@@ -699,7 +699,7 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
699 | if (__skb_checksum_complete(skb)) { | 699 | if (__skb_checksum_complete(skb)) { |
700 | LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n", | 700 | LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n", |
701 | saddr, daddr); | 701 | saddr, daddr); |
702 | goto discard_it; | 702 | goto csum_error; |
703 | } | 703 | } |
704 | } | 704 | } |
705 | 705 | ||
@@ -785,6 +785,8 @@ static int icmpv6_rcv(struct sk_buff *skb) | |||
785 | kfree_skb(skb); | 785 | kfree_skb(skb); |
786 | return 0; | 786 | return 0; |
787 | 787 | ||
788 | csum_error: | ||
789 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS); | ||
788 | discard_it: | 790 | discard_it: |
789 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS); | 791 | ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS); |
790 | drop_no_count: | 792 | drop_no_count: |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index bbbe53a99b57..115cc58898f5 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -90,6 +90,7 @@ static const struct snmp_mib snmp6_ipstats_list[] = { | |||
90 | SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), | 90 | SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), |
91 | SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), | 91 | SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), |
92 | SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), | 92 | SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), |
93 | SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS), | ||
93 | SNMP_MIB_SENTINEL | 94 | SNMP_MIB_SENTINEL |
94 | }; | 95 | }; |
95 | 96 | ||
@@ -99,6 +100,7 @@ static const struct snmp_mib snmp6_icmp6_list[] = { | |||
99 | SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), | 100 | SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS), |
100 | SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), | 101 | SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS), |
101 | SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS), | 102 | SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS), |
103 | SNMP_MIB_ITEM("Icmp6InCsumErrors", ICMP6_MIB_CSUMERRORS), | ||
102 | SNMP_MIB_SENTINEL | 104 | SNMP_MIB_SENTINEL |
103 | }; | 105 | }; |
104 | 106 | ||
@@ -129,6 +131,7 @@ static const struct snmp_mib snmp6_udp6_list[] = { | |||
129 | SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS), | 131 | SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS), |
130 | SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS), | 132 | SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS), |
131 | SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS), | 133 | SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS), |
134 | SNMP_MIB_ITEM("Udp6InCsumErrors", UDP_MIB_CSUMERRORS), | ||
132 | SNMP_MIB_SENTINEL | 135 | SNMP_MIB_SENTINEL |
133 | }; | 136 | }; |
134 | 137 | ||
@@ -139,6 +142,7 @@ static const struct snmp_mib snmp6_udplite6_list[] = { | |||
139 | SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS), | 142 | SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS), |
140 | SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS), | 143 | SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS), |
141 | SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS), | 144 | SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS), |
145 | SNMP_MIB_ITEM("UdpLite6InCsumErrors", UDP_MIB_CSUMERRORS), | ||
142 | SNMP_MIB_SENTINEL | 146 | SNMP_MIB_SENTINEL |
143 | }; | 147 | }; |
144 | 148 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e51bd1a58264..71167069b394 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1405,6 +1405,7 @@ discard: | |||
1405 | kfree_skb(skb); | 1405 | kfree_skb(skb); |
1406 | return 0; | 1406 | return 0; |
1407 | csum_err: | 1407 | csum_err: |
1408 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS); | ||
1408 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); | 1409 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); |
1409 | goto discard; | 1410 | goto discard; |
1410 | 1411 | ||
@@ -1466,7 +1467,7 @@ static int tcp_v6_rcv(struct sk_buff *skb) | |||
1466 | goto discard_it; | 1467 | goto discard_it; |
1467 | 1468 | ||
1468 | if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb)) | 1469 | if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb)) |
1469 | goto bad_packet; | 1470 | goto csum_error; |
1470 | 1471 | ||
1471 | th = tcp_hdr(skb); | 1472 | th = tcp_hdr(skb); |
1472 | hdr = ipv6_hdr(skb); | 1473 | hdr = ipv6_hdr(skb); |
@@ -1530,6 +1531,8 @@ no_tcp_socket: | |||
1530 | goto discard_it; | 1531 | goto discard_it; |
1531 | 1532 | ||
1532 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { | 1533 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { |
1534 | csum_error: | ||
1535 | TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS); | ||
1533 | bad_packet: | 1536 | bad_packet: |
1534 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); | 1537 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); |
1535 | } else { | 1538 | } else { |
@@ -1537,11 +1540,6 @@ bad_packet: | |||
1537 | } | 1540 | } |
1538 | 1541 | ||
1539 | discard_it: | 1542 | discard_it: |
1540 | |||
1541 | /* | ||
1542 | * Discard frame | ||
1543 | */ | ||
1544 | |||
1545 | kfree_skb(skb); | 1543 | kfree_skb(skb); |
1546 | return 0; | 1544 | return 0; |
1547 | 1545 | ||
@@ -1555,10 +1553,13 @@ do_time_wait: | |||
1555 | goto discard_it; | 1553 | goto discard_it; |
1556 | } | 1554 | } |
1557 | 1555 | ||
1558 | if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { | 1556 | if (skb->len < (th->doff<<2)) { |
1559 | TCP_INC_STATS_BH(net, TCP_MIB_INERRS); | ||
1560 | inet_twsk_put(inet_twsk(sk)); | 1557 | inet_twsk_put(inet_twsk(sk)); |
1561 | goto discard_it; | 1558 | goto bad_packet; |
1559 | } | ||
1560 | if (tcp_checksum_complete(skb)) { | ||
1561 | inet_twsk_put(inet_twsk(sk)); | ||
1562 | goto csum_error; | ||
1562 | } | 1563 | } |
1563 | 1564 | ||
1564 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { | 1565 | switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) { |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index da6019b63730..d4defdd44937 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -483,12 +483,17 @@ out: | |||
483 | csum_copy_err: | 483 | csum_copy_err: |
484 | slow = lock_sock_fast(sk); | 484 | slow = lock_sock_fast(sk); |
485 | if (!skb_kill_datagram(sk, skb, flags)) { | 485 | if (!skb_kill_datagram(sk, skb, flags)) { |
486 | if (is_udp4) | 486 | if (is_udp4) { |
487 | UDP_INC_STATS_USER(sock_net(sk), | ||
488 | UDP_MIB_CSUMERRORS, is_udplite); | ||
487 | UDP_INC_STATS_USER(sock_net(sk), | 489 | UDP_INC_STATS_USER(sock_net(sk), |
488 | UDP_MIB_INERRORS, is_udplite); | 490 | UDP_MIB_INERRORS, is_udplite); |
489 | else | 491 | } else { |
492 | UDP6_INC_STATS_USER(sock_net(sk), | ||
493 | UDP_MIB_CSUMERRORS, is_udplite); | ||
490 | UDP6_INC_STATS_USER(sock_net(sk), | 494 | UDP6_INC_STATS_USER(sock_net(sk), |
491 | UDP_MIB_INERRORS, is_udplite); | 495 | UDP_MIB_INERRORS, is_udplite); |
496 | } | ||
492 | } | 497 | } |
493 | unlock_sock_fast(sk, slow); | 498 | unlock_sock_fast(sk, slow); |
494 | 499 | ||
@@ -637,7 +642,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
637 | 642 | ||
638 | if (rcu_access_pointer(sk->sk_filter)) { | 643 | if (rcu_access_pointer(sk->sk_filter)) { |
639 | if (udp_lib_checksum_complete(skb)) | 644 | if (udp_lib_checksum_complete(skb)) |
640 | goto drop; | 645 | goto csum_error; |
641 | } | 646 | } |
642 | 647 | ||
643 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) | 648 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) |
@@ -656,6 +661,8 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
656 | bh_unlock_sock(sk); | 661 | bh_unlock_sock(sk); |
657 | 662 | ||
658 | return rc; | 663 | return rc; |
664 | csum_error: | ||
665 | UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite); | ||
659 | drop: | 666 | drop: |
660 | UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); | 667 | UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); |
661 | atomic_inc(&sk->sk_drops); | 668 | atomic_inc(&sk->sk_drops); |
@@ -817,7 +824,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
817 | } | 824 | } |
818 | 825 | ||
819 | if (udp6_csum_init(skb, uh, proto)) | 826 | if (udp6_csum_init(skb, uh, proto)) |
820 | goto discard; | 827 | goto csum_error; |
821 | 828 | ||
822 | /* | 829 | /* |
823 | * Multicast receive code | 830 | * Multicast receive code |
@@ -850,7 +857,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, | |||
850 | goto discard; | 857 | goto discard; |
851 | 858 | ||
852 | if (udp_lib_checksum_complete(skb)) | 859 | if (udp_lib_checksum_complete(skb)) |
853 | goto discard; | 860 | goto csum_error; |
854 | 861 | ||
855 | UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); | 862 | UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE); |
856 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); | 863 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); |
@@ -867,7 +874,9 @@ short_packet: | |||
867 | skb->len, | 874 | skb->len, |
868 | daddr, | 875 | daddr, |
869 | ntohs(uh->dest)); | 876 | ntohs(uh->dest)); |
870 | 877 | goto discard; | |
878 | csum_error: | ||
879 | UDP6_INC_STATS_BH(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE); | ||
871 | discard: | 880 | discard: |
872 | UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); | 881 | UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE); |
873 | kfree_skb(skb); | 882 | kfree_skb(skb); |