aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-09-02 21:05:33 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-02 21:05:33 -0400
commit6ce9e7b5fe3195d1ae6e3a0753d4ddcac5cd699e (patch)
treed7228b3ea7000bc29b959556d8cb264b12365586 /net/ipv6
parent2e59af3dcbdf11635c03f22bfc9706744465d589 (diff)
ip: Report qdisc packet drops
Christoph Lameter pointed out that packet drops at qdisc level where not accounted in SNMP counters. Only if application sets IP_RECVERR, drops are reported to user (-ENOBUFS errors) and SNMP counters updated. IP_RECVERR is used to enable extended reliable error message passing, but these are not needed to update system wide SNMP stats. This patch changes things a bit to allow SNMP counters to be updated, regardless of IP_RECVERR being set or not on the socket. Example after an UDP tx flood # netstat -s ... IP: 1487048 outgoing packets dropped ... Udp: ... SndbufErrors: 1487048 send() syscalls, do however still return an OK status, to not break applications. Note : send() manual page explicitly says for -ENOBUFS error : "The output queue for a network interface was full. This generally indicates that the interface has stopped sending, but may be caused by transient congestion. (Normally, this does not occur in Linux. Packets are just silently dropped when a device queue overflows.) " This is not true for IP_RECVERR enabled sockets : a send() syscall that hit a qdisc drop returns an ENOBUFS error. Many thanks to Christoph, David, and last but not least, Alexey ! Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/raw.c4
-rw-r--r--net/ipv6/udp.c12
3 files changed, 13 insertions, 5 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index a931229856b6..cd48801a8d6f 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1511,7 +1511,7 @@ int ip6_push_pending_frames(struct sock *sk)
1511 err = ip6_local_out(skb); 1511 err = ip6_local_out(skb);
1512 if (err) { 1512 if (err) {
1513 if (err > 0) 1513 if (err > 0)
1514 err = np->recverr ? net_xmit_errno(err) : 0; 1514 err = net_xmit_errno(err);
1515 if (err) 1515 if (err)
1516 goto error; 1516 goto error;
1517 } 1517 }
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 506841030fbe..7d675b8d82d3 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -642,7 +642,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
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)
645 err = np->recverr ? net_xmit_errno(err) : 0; 645 err = net_xmit_errno(err);
646 if (err) 646 if (err)
647 goto error; 647 goto error;
648out: 648out:
@@ -653,6 +653,8 @@ error_fault:
653 kfree_skb(skb); 653 kfree_skb(skb);
654error: 654error:
655 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); 655 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
656 if (err == -ENOBUFS && !np->recverr)
657 err = 0;
656 return err; 658 return err;
657} 659}
658 660
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 20d2ffc15f0d..164040613c2e 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -724,12 +724,18 @@ static int udp_v6_push_pending_frames(struct sock *sk)
724 724
725send: 725send:
726 err = ip6_push_pending_frames(sk); 726 err = ip6_push_pending_frames(sk);
727 if (err) {
728 if (err == -ENOBUFS && !inet6_sk(sk)->recverr) {
729 UDP6_INC_STATS_USER(sock_net(sk),
730 UDP_MIB_SNDBUFERRORS, is_udplite);
731 err = 0;
732 }
733 } else
734 UDP6_INC_STATS_USER(sock_net(sk),
735 UDP_MIB_OUTDATAGRAMS, is_udplite);
727out: 736out:
728 up->len = 0; 737 up->len = 0;
729 up->pending = 0; 738 up->pending = 0;
730 if (!err)
731 UDP6_INC_STATS_USER(sock_net(sk),
732 UDP_MIB_OUTDATAGRAMS, is_udplite);
733 return err; 739 return err;
734} 740}
735 741