IPSTATS_MIB_OUTMCASTOCTETS,             /* OutMcastOctets */
        IPSTATS_MIB_INBCASTOCTETS,              /* InBcastOctets */
        IPSTATS_MIB_OUTBCASTOCTETS,             /* OutBcastOctets */
+       IPSTATS_MIB_CSUMERRORS,                 /* InCsumErrors */
        __IPSTATS_MIB_MAX
 };
 
        ICMP_MIB_OUTTIMESTAMPREPS,              /* OutTimestampReps */
        ICMP_MIB_OUTADDRMASKS,                  /* OutAddrMasks */
        ICMP_MIB_OUTADDRMASKREPS,               /* OutAddrMaskReps */
+       ICMP_MIB_CSUMERRORS,                    /* InCsumErrors */
        __ICMP_MIB_MAX
 };
 
        ICMP6_MIB_INERRORS,                     /* InErrors */
        ICMP6_MIB_OUTMSGS,                      /* OutMsgs */
        ICMP6_MIB_OUTERRORS,                    /* OutErrors */
+       ICMP6_MIB_CSUMERRORS,                   /* InCsumErrors */
        __ICMP6_MIB_MAX
 };
 
        TCP_MIB_RETRANSSEGS,                    /* RetransSegs */
        TCP_MIB_INERRS,                         /* InErrs */
        TCP_MIB_OUTRSTS,                        /* OutRsts */
+       TCP_MIB_CSUMERRORS,                     /* InCsumErrors */
        __TCP_MIB_MAX
 };
 
        UDP_MIB_OUTDATAGRAMS,                   /* OutDatagrams */
        UDP_MIB_RCVBUFERRORS,                   /* RcvbufErrors */
        UDP_MIB_SNDBUFERRORS,                   /* SndbufErrors */
+       UDP_MIB_CSUMERRORS,                     /* InCsumErrors */
        __UDP_MIB_MAX
 };
 
 
        case CHECKSUM_NONE:
                skb->csum = 0;
                if (__skb_checksum_complete(skb))
-                       goto error;
+                       goto csum_error;
        }
 
        if (!pskb_pull(skb, sizeof(*icmph)))
 drop:
        kfree_skb(skb);
        return 0;
+csum_error:
+       ICMP_INC_STATS_BH(net, ICMP_MIB_CSUMERRORS);
 error:
        ICMP_INC_STATS_BH(net, ICMP_MIB_INERRORS);
        goto drop;
 
        iph = ip_hdr(skb);
 
        if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
-               goto inhdr_error;
+               goto csum_error;
 
        len = ntohs(iph->tot_len);
        if (skb->len < len) {
        return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL,
                       ip_rcv_finish);
 
+csum_error:
+       IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_CSUMERRORS);
 inhdr_error:
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS);
 drop:
 
        SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
        SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
        SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
+       SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
        SNMP_MIB_SENTINEL
 };
 
        SNMP_MIB_ITEM("RetransSegs", TCP_MIB_RETRANSSEGS),
        SNMP_MIB_ITEM("InErrs", TCP_MIB_INERRS),
        SNMP_MIB_ITEM("OutRsts", TCP_MIB_OUTRSTS),
+       SNMP_MIB_ITEM("InCsumErrors", TCP_MIB_CSUMERRORS),
        SNMP_MIB_SENTINEL
 };
 
        SNMP_MIB_ITEM("OutDatagrams", UDP_MIB_OUTDATAGRAMS),
        SNMP_MIB_ITEM("RcvbufErrors", UDP_MIB_RCVBUFERRORS),
        SNMP_MIB_ITEM("SndbufErrors", UDP_MIB_SNDBUFERRORS),
+       SNMP_MIB_ITEM("InCsumErrors", UDP_MIB_CSUMERRORS),
        SNMP_MIB_SENTINEL
 };
 
        struct net *net = seq->private;
        atomic_long_t *ptr = net->mib.icmpmsg_statistics->mibs;
 
-       seq_puts(seq, "\nIcmp: InMsgs InErrors");
+       seq_puts(seq, "\nIcmp: InMsgs InErrors InCsumErrors");
        for (i=0; icmpmibmap[i].name != NULL; i++)
                seq_printf(seq, " In%s", icmpmibmap[i].name);
        seq_printf(seq, " OutMsgs OutErrors");
        for (i=0; icmpmibmap[i].name != NULL; i++)
                seq_printf(seq, " Out%s", icmpmibmap[i].name);
-       seq_printf(seq, "\nIcmp: %lu %lu",
+       seq_printf(seq, "\nIcmp: %lu %lu %lu",
                snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_INMSGS),
-               snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_INERRORS));
+               snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_INERRORS),
+               snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_CSUMERRORS));
        for (i=0; icmpmibmap[i].name != NULL; i++)
                seq_printf(seq, " %lu",
                           atomic_long_read(ptr + icmpmibmap[i].index));
 
        return 0;
 
 csum_error:
+       TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS);
        TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
 
 discard:
 
        return 0;
 
 csum_err:
+       TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS);
        TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
        goto discard;
 }
         * provided case of th->doff==0 is eliminated.
         * So, we defer the checks. */
        if (!skb_csum_unnecessary(skb) && tcp_v4_checksum_init(skb))
-               goto bad_packet;
+               goto csum_error;
 
        th = tcp_hdr(skb);
        iph = ip_hdr(skb);
                goto discard_it;
 
        if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
+csum_error:
+               TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
                TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
        } else {
                goto discard_it;
        }
 
-       if (skb->len < (th->doff << 2) || tcp_checksum_complete(skb)) {
-               TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
+       if (skb->len < (th->doff << 2)) {
                inet_twsk_put(inet_twsk(sk));
-               goto discard_it;
+               goto bad_packet;
+       }
+       if (tcp_checksum_complete(skb)) {
+               inet_twsk_put(inet_twsk(sk));
+               goto csum_error;
        }
        switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
        case TCP_TW_SYN: {
 
 
        tp->packets_out += tcp_skb_pcount(skb);
        if (!prior_packets || icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
-           icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)
+           icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
                tcp_rearm_rto(sk);
+       }
 }
 
 /* SND.NXT, if window was not shrunk.
 
        spin_lock_bh(&rcvq->lock);
        while ((skb = skb_peek(rcvq)) != NULL &&
                udp_lib_checksum_complete(skb)) {
+               UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS,
+                                IS_UDPLITE(sk));
                UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS,
                                 IS_UDPLITE(sk));
                atomic_inc(&sk->sk_drops);
 
 csum_copy_err:
        slow = lock_sock_fast(sk);
-       if (!skb_kill_datagram(sk, skb, flags))
+       if (!skb_kill_datagram(sk, skb, flags)) {
+               UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
                UDP_INC_STATS_USER(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+       }
        unlock_sock_fast(sk, slow);
 
        if (noblock)
 
        if (rcu_access_pointer(sk->sk_filter) &&
            udp_lib_checksum_complete(skb))
-               goto drop;
+               goto csum_error;
 
 
        if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))
 
        return rc;
 
+csum_error:
+       UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
 drop:
        UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
        atomic_inc(&sk->sk_drops);
                       proto == IPPROTO_UDPLITE ? "Lite" : "",
                       &saddr, ntohs(uh->source), &daddr, ntohs(uh->dest),
                       ulen);
+       UDP_INC_STATS_BH(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
 drop:
        UDP_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
        kfree_skb(skb);
 
                if (__skb_checksum_complete(skb)) {
                        LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [%pI6 > %pI6]\n",
                                       saddr, daddr);
-                       goto discard_it;
+                       goto csum_error;
                }
        }
 
        kfree_skb(skb);
        return 0;
 
+csum_error:
+       ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_CSUMERRORS);
 discard_it:
        ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS);
 drop_no_count:
 
        SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
        SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
        SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
+       SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
        SNMP_MIB_SENTINEL
 };
 
        SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS),
        SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS),
        SNMP_MIB_ITEM("Icmp6OutErrors", ICMP6_MIB_OUTERRORS),
+       SNMP_MIB_ITEM("Icmp6InCsumErrors", ICMP6_MIB_CSUMERRORS),
        SNMP_MIB_SENTINEL
 };
 
        SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
        SNMP_MIB_ITEM("Udp6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
        SNMP_MIB_ITEM("Udp6SndbufErrors", UDP_MIB_SNDBUFERRORS),
+       SNMP_MIB_ITEM("Udp6InCsumErrors", UDP_MIB_CSUMERRORS),
        SNMP_MIB_SENTINEL
 };
 
        SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
        SNMP_MIB_ITEM("UdpLite6RcvbufErrors", UDP_MIB_RCVBUFERRORS),
        SNMP_MIB_ITEM("UdpLite6SndbufErrors", UDP_MIB_SNDBUFERRORS),
+       SNMP_MIB_ITEM("UdpLite6InCsumErrors", UDP_MIB_CSUMERRORS),
        SNMP_MIB_SENTINEL
 };
 
 
        kfree_skb(skb);
        return 0;
 csum_err:
+       TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_CSUMERRORS);
        TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
        goto discard;
 
                goto discard_it;
 
        if (!skb_csum_unnecessary(skb) && tcp_v6_checksum_init(skb))
-               goto bad_packet;
+               goto csum_error;
 
        th = tcp_hdr(skb);
        hdr = ipv6_hdr(skb);
                goto discard_it;
 
        if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
+csum_error:
+               TCP_INC_STATS_BH(net, TCP_MIB_CSUMERRORS);
 bad_packet:
                TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
        } else {
        }
 
 discard_it:
-
-       /*
-        *      Discard frame
-        */
-
        kfree_skb(skb);
        return 0;
 
                goto discard_it;
        }
 
-       if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) {
-               TCP_INC_STATS_BH(net, TCP_MIB_INERRS);
+       if (skb->len < (th->doff<<2)) {
                inet_twsk_put(inet_twsk(sk));
-               goto discard_it;
+               goto bad_packet;
+       }
+       if (tcp_checksum_complete(skb)) {
+               inet_twsk_put(inet_twsk(sk));
+               goto csum_error;
        }
 
        switch (tcp_timewait_state_process(inet_twsk(sk), skb, th)) {
 
 csum_copy_err:
        slow = lock_sock_fast(sk);
        if (!skb_kill_datagram(sk, skb, flags)) {
-               if (is_udp4)
+               if (is_udp4) {
+                       UDP_INC_STATS_USER(sock_net(sk),
+                                       UDP_MIB_CSUMERRORS, is_udplite);
                        UDP_INC_STATS_USER(sock_net(sk),
                                        UDP_MIB_INERRORS, is_udplite);
-               else
+               } else {
+                       UDP6_INC_STATS_USER(sock_net(sk),
+                                       UDP_MIB_CSUMERRORS, is_udplite);
                        UDP6_INC_STATS_USER(sock_net(sk),
                                        UDP_MIB_INERRORS, is_udplite);
+               }
        }
        unlock_sock_fast(sk, slow);
 
 
        if (rcu_access_pointer(sk->sk_filter)) {
                if (udp_lib_checksum_complete(skb))
-                       goto drop;
+                       goto csum_error;
        }
 
        if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf))
        bh_unlock_sock(sk);
 
        return rc;
+csum_error:
+       UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_CSUMERRORS, is_udplite);
 drop:
        UDP6_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
        atomic_inc(&sk->sk_drops);
        }
 
        if (udp6_csum_init(skb, uh, proto))
-               goto discard;
+               goto csum_error;
 
        /*
         *      Multicast receive code
                goto discard;
 
        if (udp_lib_checksum_complete(skb))
-               goto discard;
+               goto csum_error;
 
        UDP6_INC_STATS_BH(net, UDP_MIB_NOPORTS, proto == IPPROTO_UDPLITE);
        icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0);
                       skb->len,
                       daddr,
                       ntohs(uh->dest));
-
+       goto discard;
+csum_error:
+       UDP6_INC_STATS_BH(net, UDP_MIB_CSUMERRORS, proto == IPPROTO_UDPLITE);
 discard:
        UDP6_INC_STATS_BH(net, UDP_MIB_INERRORS, proto == IPPROTO_UDPLITE);
        kfree_skb(skb);