net: add SNMP counters tracking incoming ECN bits
authorEric Dumazet <edumazet@google.com>
Tue, 6 Aug 2013 10:32:11 +0000 (03:32 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 9 Aug 2013 05:24:59 +0000 (22:24 -0700)
With GRO/LRO processing, there is a problem because Ip[6]InReceives SNMP
counters do not count the number of frames, but number of aggregated
segments.

Its probably too late to change this now.

This patch adds four new counters, tracking number of frames, regardless
of LRO/GRO, and on a per ECN status basis, for IPv4 and IPv6.

Ip[6]NoECTPkts : Number of packets received with NOECT
Ip[6]ECT1Pkts  : Number of packets received with ECT(1)
Ip[6]ECT0Pkts  : Number of packets received with ECT(0)
Ip[6]CEPkts    : Number of packets received with Congestion Experienced

lph37:~# nstat | egrep "Pkts|InReceive"
IpInReceives                    1634137            0.0
Ip6InReceives                   3714107            0.0
Ip6InNoECTPkts                  19205              0.0
Ip6InECT0Pkts                   52651828           0.0
IpExtInNoECTPkts                33630              0.0
IpExtInECT0Pkts                 15581379           0.0
IpExtInCEPkts                   6                  0.0

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/snmp.h
net/ipv4/ip_input.c
net/ipv4/proc.c
net/ipv6/ip6_input.c
net/ipv6/proc.c

index af0a674cc677f570bf5d5e04683957605d5e9ea1..60601d28da75962fdc0d74b655993e656e258fb4 100644 (file)
@@ -51,6 +51,10 @@ enum
        IPSTATS_MIB_INBCASTOCTETS,              /* InBcastOctets */
        IPSTATS_MIB_OUTBCASTOCTETS,             /* OutBcastOctets */
        IPSTATS_MIB_CSUMERRORS,                 /* InCsumErrors */
+       IPSTATS_MIB_NOECTPKTS,                  /* InNoECTPkts */
+       IPSTATS_MIB_ECT1PKTS,                   /* InECT1Pkts */
+       IPSTATS_MIB_ECT0PKTS,                   /* InECT0Pkts */
+       IPSTATS_MIB_CEPKTS,                     /* InCEPkts */
        __IPSTATS_MIB_MAX
 };
 
index 15e3e683adece394b02347eeed1d05afe5a62d01..054a3e97d822b61646cfff92c2ff2ed0f1e0740a 100644 (file)
 #include <net/icmp.h>
 #include <net/raw.h>
 #include <net/checksum.h>
+#include <net/inet_ecn.h>
 #include <linux/netfilter_ipv4.h>
 #include <net/xfrm.h>
 #include <linux/mroute.h>
@@ -410,6 +411,13 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
        if (iph->ihl < 5 || iph->version != 4)
                goto inhdr_error;
 
+       BUILD_BUG_ON(IPSTATS_MIB_ECT1PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_1);
+       BUILD_BUG_ON(IPSTATS_MIB_ECT0PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_0);
+       BUILD_BUG_ON(IPSTATS_MIB_CEPKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_CE);
+       IP_ADD_STATS_BH(dev_net(dev),
+                       IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK),
+                       max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
+
        if (!pskb_may_pull(skb, iph->ihl*4))
                goto inhdr_error;
 
index 6577a1149a47c17853e8c7e0e3daa267ef16d1cd..5f5fa612647fce8dbd0d948e1cdcca3efdfe7e8a 100644 (file)
@@ -111,7 +111,7 @@ static const struct snmp_mib snmp4_ipstats_list[] = {
        SNMP_MIB_SENTINEL
 };
 
-/* Following RFC4293 items are displayed in /proc/net/netstat */
+/* Following items are displayed in /proc/net/netstat */
 static const struct snmp_mib snmp4_ipextstats_list[] = {
        SNMP_MIB_ITEM("InNoRoutes", IPSTATS_MIB_INNOROUTES),
        SNMP_MIB_ITEM("InTruncatedPkts", IPSTATS_MIB_INTRUNCATEDPKTS),
@@ -125,7 +125,12 @@ static const struct snmp_mib snmp4_ipextstats_list[] = {
        SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
        SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
        SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
+       /* Non RFC4293 fields */
        SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
+       SNMP_MIB_ITEM("InNoECTPkts", IPSTATS_MIB_NOECTPKTS),
+       SNMP_MIB_ITEM("InECT1Pkts", IPSTATS_MIB_ECT1PKTS),
+       SNMP_MIB_ITEM("InECT0Pkts", IPSTATS_MIB_ECT0PKTS),
+       SNMP_MIB_ITEM("InCEPkts", IPSTATS_MIB_CEPKTS),
        SNMP_MIB_SENTINEL
 };
 
index 2bab2aa597450813ae4bd60d362998830a7e7e3b..302d6fb1ff2b43fb027a633a0ba3f87eea58d4e9 100644 (file)
@@ -44,7 +44,7 @@
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
 #include <net/xfrm.h>
-
+#include <net/inet_ecn.h>
 
 
 int ip6_rcv_finish(struct sk_buff *skb)
@@ -109,6 +109,10 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
        if (hdr->version != 6)
                goto err;
 
+       IP6_ADD_STATS_BH(dev_net(dev), idev,
+                        IPSTATS_MIB_NOECTPKTS +
+                               (ipv6_get_dsfield(hdr) & INET_ECN_MASK),
+                        max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
        /*
         * RFC4291 2.5.3
         * A packet received on an interface with a destination address
index 51c3285b5d9b582cb1d6101d3fafc70c781f5a74..091d066a57b3711c5bd0eb5a352573d0aa2f3776 100644 (file)
@@ -91,6 +91,10 @@ static const struct snmp_mib snmp6_ipstats_list[] = {
        SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
        SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
        /* IPSTATS_MIB_CSUMERRORS is not relevant in IPv6 (no checksum) */
+       SNMP_MIB_ITEM("Ip6InNoECTPkts", IPSTATS_MIB_NOECTPKTS),
+       SNMP_MIB_ITEM("Ip6InECT1Pkts", IPSTATS_MIB_ECT1PKTS),
+       SNMP_MIB_ITEM("Ip6InECT0Pkts", IPSTATS_MIB_ECT0PKTS),
+       SNMP_MIB_ITEM("Ip6InCEPkts", IPSTATS_MIB_CEPKTS),
        SNMP_MIB_SENTINEL
 };