diff options
-rw-r--r-- | include/linux/snmp.h | 2 | ||||
-rw-r--r-- | net/ipv4/proc.c | 2 | ||||
-rw-r--r-- | net/ipv4/udp.c | 16 |
3 files changed, 19 insertions, 1 deletions
diff --git a/include/linux/snmp.h b/include/linux/snmp.h index 4db25d5c7cd1..30156556f78d 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h | |||
@@ -155,6 +155,8 @@ enum | |||
155 | UDP_MIB_NOPORTS, /* NoPorts */ | 155 | UDP_MIB_NOPORTS, /* NoPorts */ |
156 | UDP_MIB_INERRORS, /* InErrors */ | 156 | UDP_MIB_INERRORS, /* InErrors */ |
157 | UDP_MIB_OUTDATAGRAMS, /* OutDatagrams */ | 157 | UDP_MIB_OUTDATAGRAMS, /* OutDatagrams */ |
158 | UDP_MIB_RCVBUFERRORS, /* RcvbufErrors */ | ||
159 | UDP_MIB_SNDBUFERRORS, /* SndbufErrors */ | ||
158 | __UDP_MIB_MAX | 160 | __UDP_MIB_MAX |
159 | }; | 161 | }; |
160 | 162 | ||
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index d61e2a9d394d..9c6cbe3d9fb8 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -173,6 +173,8 @@ static const struct snmp_mib snmp4_udp_list[] = { | |||
173 | SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS), | 173 | SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS), |
174 | SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS), | 174 | SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS), |
175 | SNMP_MIB_ITEM("OutDatagrams", UDP_MIB_OUTDATAGRAMS), | 175 | SNMP_MIB_ITEM("OutDatagrams", UDP_MIB_OUTDATAGRAMS), |
176 | SNMP_MIB_ITEM("RcvbufErrors", UDP_MIB_RCVBUFERRORS), | ||
177 | SNMP_MIB_ITEM("SndbufErrors", UDP_MIB_SNDBUFERRORS), | ||
176 | SNMP_MIB_SENTINEL | 178 | SNMP_MIB_SENTINEL |
177 | }; | 179 | }; |
178 | 180 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 87152510980c..514c1e9ae810 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -662,6 +662,16 @@ out: | |||
662 | UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS); | 662 | UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS); |
663 | return len; | 663 | return len; |
664 | } | 664 | } |
665 | /* | ||
666 | * ENOBUFS = no kernel mem, SOCK_NOSPACE = no sndbuf space. Reporting | ||
667 | * ENOBUFS might not be good (it's not tunable per se), but otherwise | ||
668 | * we don't have a good statistic (IpOutDiscards but it can be too many | ||
669 | * things). We could add another new stat but at least for now that | ||
670 | * seems like overkill. | ||
671 | */ | ||
672 | if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { | ||
673 | UDP_INC_STATS_USER(UDP_MIB_SNDBUFERRORS); | ||
674 | } | ||
665 | return err; | 675 | return err; |
666 | 676 | ||
667 | do_confirm: | 677 | do_confirm: |
@@ -981,6 +991,7 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb) | |||
981 | static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | 991 | static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) |
982 | { | 992 | { |
983 | struct udp_sock *up = udp_sk(sk); | 993 | struct udp_sock *up = udp_sk(sk); |
994 | int rc; | ||
984 | 995 | ||
985 | /* | 996 | /* |
986 | * Charge it to the socket, dropping if the queue is full. | 997 | * Charge it to the socket, dropping if the queue is full. |
@@ -1027,7 +1038,10 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) | |||
1027 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1038 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1028 | } | 1039 | } |
1029 | 1040 | ||
1030 | if (sock_queue_rcv_skb(sk,skb)<0) { | 1041 | if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { |
1042 | /* Note that an ENOMEM error is charged twice */ | ||
1043 | if (rc == -ENOMEM) | ||
1044 | UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS); | ||
1031 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); | 1045 | UDP_INC_STATS_BH(UDP_MIB_INERRORS); |
1032 | kfree_skb(skb); | 1046 | kfree_skb(skb); |
1033 | return -1; | 1047 | return -1; |