Module Name: src Committed By: bouyer Date: Mon Apr 9 13:34:11 UTC 2018
Modified Files: src/lib/libc/sys [netbsd-8]: recv.2 src/sbin/route [netbsd-8]: route.c src/sys/kern [netbsd-8]: uipc_socket.c uipc_socket2.c uipc_usrreq.c src/sys/net [netbsd-8]: raw_usrreq.c rtsock.c src/sys/netatalk [netbsd-8]: ddp_input.c src/sys/netcan [netbsd-8]: can.c src/sys/netinet [netbsd-8]: ip_mroute.c raw_ip.c udp_usrreq.c src/sys/netinet6 [netbsd-8]: icmp6.c ip6_input.c ip6_mroute.c raw_ip6.c udp6_usrreq.c src/sys/netipsec [netbsd-8]: keysock.c src/sys/sys [netbsd-8]: socketvar.h src/tests/lib/libc/sys [netbsd-8]: t_recvmmsg.c src/tests/net/icmp [netbsd-8]: t_ping.c Log Message: Pull up following revision(s) (requested by roy in ticket #724): tests/net/icmp/t_ping.c: revision 1.19 sys/netinet6/raw_ip6.c: revision 1.166 sys/netinet6/ip6_input.c: revision 1.195 sys/net/raw_usrreq.c: revision 1.59 sys/sys/socketvar.h: revision 1.151 sys/kern/uipc_socket2.c: revision 1.128 tests/lib/libc/sys/t_recvmmsg.c: revision 1.2 lib/libc/sys/recv.2: revision 1.38 sys/net/rtsock.c: revision 1.239 sys/netinet/udp_usrreq.c: revision 1.246 sys/netinet6/icmp6.c: revision 1.224 tests/net/icmp/t_ping.c: revision 1.20 sys/netipsec/keysock.c: revision 1.63 sys/netinet/raw_ip.c: revision 1.172 sys/kern/uipc_socket.c: revision 1.260 tests/net/icmp/t_ping.c: revision 1.22 sys/kern/uipc_socket.c: revision 1.261 tests/net/icmp/t_ping.c: revision 1.23 sys/netinet/ip_mroute.c: revision 1.155 sbin/route/route.c: revision 1.159 sys/netinet6/ip6_mroute.c: revision 1.123 sys/netatalk/ddp_input.c: revision 1.31 sys/netcan/can.c: revision 1.3 sys/kern/uipc_usrreq.c: revision 1.184 sys/netinet6/udp6_usrreq.c: revision 1.138 tests/net/icmp/t_ping.c: revision 1.18 socket: report receive buffer overflows Add soroverflow() which increments the overflow counter, sets so_error to ENOBUFS and wakes the receive socket up. Replace all code that manually increments this counter with soroverflow(). Add soroverflow() to raw_input(). This allows userland to detect route(4) overflows so it can re-sync with the current state. socket: clear error even when peeking The error has already been reported and it's pointless requiring another recv(2) call just to clear it. socket: remove now incorrect comment that so_error is only udp As it can be affected by route(4) sockets which are raw. rtsock: log dropped messages that we cannot report to userland Handle ENOBUFS when receiving messages. Don't send messages if the receiver has died. Sprinkle more soroverflow(). Handle ENOBUFS in recv Handle ENOBUFS in sendto Note value received. Harden another sendto for ENOBUFS. Handle the routing socket overflowing gracefully. Allow a valid sendto .... duh Handle errors better. Fix test for checking we sent all the data we asked to. To generate a diff of this commit: cvs rdiff -u -r1.36 -r1.36.20.1 src/lib/libc/sys/recv.2 cvs rdiff -u -r1.155.4.2 -r1.155.4.3 src/sbin/route/route.c cvs rdiff -u -r1.255.2.1 -r1.255.2.2 src/sys/kern/uipc_socket.c cvs rdiff -u -r1.124 -r1.124.8.1 src/sys/kern/uipc_socket2.c cvs rdiff -u -r1.181 -r1.181.8.1 src/sys/kern/uipc_usrreq.c cvs rdiff -u -r1.56.4.1 -r1.56.4.2 src/sys/net/raw_usrreq.c cvs rdiff -u -r1.213.2.7 -r1.213.2.8 src/sys/net/rtsock.c cvs rdiff -u -r1.29 -r1.29.8.1 src/sys/netatalk/ddp_input.c cvs rdiff -u -r1.2 -r1.2.2.1 src/sys/netcan/can.c cvs rdiff -u -r1.146.6.2 -r1.146.6.3 src/sys/netinet/ip_mroute.c cvs rdiff -u -r1.164.4.1 -r1.164.4.2 src/sys/netinet/raw_ip.c cvs rdiff -u -r1.233.4.1 -r1.233.4.2 src/sys/netinet/udp_usrreq.c cvs rdiff -u -r1.211.6.4 -r1.211.6.5 src/sys/netinet6/icmp6.c cvs rdiff -u -r1.178.2.6 -r1.178.2.7 src/sys/netinet6/ip6_input.c cvs rdiff -u -r1.119.6.1 -r1.119.6.2 src/sys/netinet6/ip6_mroute.c cvs rdiff -u -r1.157.2.3 -r1.157.2.4 src/sys/netinet6/raw_ip6.c cvs rdiff -u -r1.129 -r1.129.4.1 src/sys/netinet6/udp6_usrreq.c cvs rdiff -u -r1.58.2.1 -r1.58.2.2 src/sys/netipsec/keysock.c cvs rdiff -u -r1.144.6.1 -r1.144.6.2 src/sys/sys/socketvar.h cvs rdiff -u -r1.1 -r1.1.26.1 src/tests/lib/libc/sys/t_recvmmsg.c cvs rdiff -u -r1.17 -r1.17.6.1 src/tests/net/icmp/t_ping.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/sys/recv.2 diff -u src/lib/libc/sys/recv.2:1.36 src/lib/libc/sys/recv.2:1.36.20.1 --- src/lib/libc/sys/recv.2:1.36 Sun Jul 14 14:29:09 2013 +++ src/lib/libc/sys/recv.2 Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -.\" $NetBSD: recv.2,v 1.36 2013/07/14 14:29:09 njoly Exp $ +.\" $NetBSD: recv.2,v 1.36.20.1 2018/04/09 13:34:10 bouyer Exp $ .\" .\" Copyright (c) 1983, 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -29,7 +29,7 @@ .\" .\" @(#)recv.2 8.3 (Berkeley) 2/21/94 .\" -.Dd June 22, 2012 +.Dd March 19, 2018 .Dt RECV 2 .Os .Sh NAME @@ -321,6 +321,8 @@ any data were available. .It Bq Er EINVAL The total length of the I/O is more than can be expressed by the ssize_t return value. +.It Bq Er ENOBUFS +A message was not delivered because it would have overflowed the buffer. .It Bq Er ENOTCONN The socket is associated with a connection-oriented protocol and has not been connected (see Index: src/sbin/route/route.c diff -u src/sbin/route/route.c:1.155.4.2 src/sbin/route/route.c:1.155.4.3 --- src/sbin/route/route.c:1.155.4.2 Thu Dec 21 21:33:31 2017 +++ src/sbin/route/route.c Mon Apr 9 13:34:11 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.155.4.2 2017/12/21 21:33:31 snj Exp $ */ +/* $NetBSD: route.c,v 1.155.4.3 2018/04/09 13:34:11 bouyer Exp $ */ /* * Copyright (c) 1983, 1989, 1991, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19 #if 0 static char sccsid[] = "@(#)route.c 8.6 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: route.c,v 1.155.4.2 2017/12/21 21:33:31 snj Exp $"); +__RCSID("$NetBSD: route.c,v 1.155.4.3 2018/04/09 13:34:11 bouyer Exp $"); #endif #endif /* not lint */ @@ -340,8 +340,10 @@ flushroutes(int argc, char * const argv[ continue; rtm->rtm_type = RTM_DELETE; rtm->rtm_seq = seqno; - if ((rlen = prog_write(sock, next, - rtm->rtm_msglen)) < 0) { + do { + rlen = prog_write(sock, next, rtm->rtm_msglen); + } while (rlen == -1 && errno == ENOBUFS); + if (rlen == -1) { warnx("writing to routing socket: %s", route_strerror(errno)); return 1; @@ -1138,6 +1140,10 @@ monitor(int argc, char * const *argv) for(i = 0; count == 0 || i < count; i++) { time_t now; n = prog_read(sock, &u, sizeof(u)); + if (n == -1) { + warn("read"); + continue; + } now = time(NULL); (void)printf("got message of size %d on %s", n, ctime(&now)); print_rtmsg(&u.hdr, n); @@ -1213,7 +1219,10 @@ rtmsg(int cmd, int flags, struct sou *so } if (debugonly) return 0; - if ((rlen = prog_write(sock, (char *)&m_rtmsg, l)) < 0) { + do { + rlen = prog_write(sock, (char *)&m_rtmsg, l); + } while (rlen == -1 && errno == ENOBUFS); + if (rlen == -1) { warnx("writing to routing socket: %s", route_strerror(errno)); return -1; } Index: src/sys/kern/uipc_socket.c diff -u src/sys/kern/uipc_socket.c:1.255.2.1 src/sys/kern/uipc_socket.c:1.255.2.2 --- src/sys/kern/uipc_socket.c:1.255.2.1 Sun Mar 18 10:57:01 2018 +++ src/sys/kern/uipc_socket.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket.c,v 1.255.2.1 2018/03/18 10:57:01 martin Exp $ */ +/* $NetBSD: uipc_socket.c,v 1.255.2.2 2018/04/09 13:34:10 bouyer Exp $ */ /*- * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.255.2.1 2018/03/18 10:57:01 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.255.2.2 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -1244,8 +1244,7 @@ soreceive(struct socket *so, struct mbuf if (m != NULL) goto dontblock; error = so->so_error; - if ((flags & MSG_PEEK) == 0) - so->so_error = 0; + so->so_error = 0; goto release; } if (so->so_state & SS_CANTRCVMORE) { @@ -2251,7 +2250,7 @@ filt_soread(struct knote *kn, long hint) kn->kn_flags |= EV_EOF; kn->kn_fflags = so->so_error; rv = 1; - } else if (so->so_error) /* temporary udp error */ + } else if (so->so_error) rv = 1; else if (kn->kn_sfflags & NOTE_LOWAT) rv = (kn->kn_data >= kn->kn_sdata); @@ -2290,7 +2289,7 @@ filt_sowrite(struct knote *kn, long hint kn->kn_flags |= EV_EOF; kn->kn_fflags = so->so_error; rv = 1; - } else if (so->so_error) /* temporary udp error */ + } else if (so->so_error) rv = 1; else if (((so->so_state & SS_ISCONNECTED) == 0) && (so->so_proto->pr_flags & PR_CONNREQUIRED)) Index: src/sys/kern/uipc_socket2.c diff -u src/sys/kern/uipc_socket2.c:1.124 src/sys/kern/uipc_socket2.c:1.124.8.1 --- src/sys/kern/uipc_socket2.c:1.124 Sun Oct 2 19:26:46 2016 +++ src/sys/kern/uipc_socket2.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_socket2.c,v 1.124 2016/10/02 19:26:46 christos Exp $ */ +/* $NetBSD: uipc_socket2.c,v 1.124.8.1 2018/04/09 13:34:10 bouyer Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.124 2016/10/02 19:26:46 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.124.8.1 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_mbuftrace.h" @@ -495,6 +495,20 @@ socantrcvmore(struct socket *so) } /* + * soroverflow(): indicates that data was attempted to be sent + * but the receiving buffer overflowed. + */ +void +soroverflow(struct socket *so) +{ + KASSERT(solocked(so)); + + so->so_rcv.sb_overflowed++; + so->so_error = ENOBUFS; + sorwakeup(so); +} + +/* * Wait for data to arrive at/drain from a socket buffer. */ int Index: src/sys/kern/uipc_usrreq.c diff -u src/sys/kern/uipc_usrreq.c:1.181 src/sys/kern/uipc_usrreq.c:1.181.8.1 --- src/sys/kern/uipc_usrreq.c:1.181 Mon Oct 31 15:05:05 2016 +++ src/sys/kern/uipc_usrreq.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: uipc_usrreq.c,v 1.181 2016/10/31 15:05:05 maxv Exp $ */ +/* $NetBSD: uipc_usrreq.c,v 1.181.8.1 2018/04/09 13:34:10 bouyer Exp $ */ /*- * Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc. @@ -96,7 +96,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.181 2016/10/31 15:05:05 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.181.8.1 2018/04/09 13:34:10 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -329,10 +329,10 @@ unp_output(struct mbuf *m, struct mbuf * #endif if (sbappendaddr(&so2->so_rcv, (const struct sockaddr *)sun, m, control) == 0) { - so2->so_rcv.sb_overflowed++; unp_dispose(control); m_freem(control); m_freem(m); + soroverflow(so2); return (ENOBUFS); } else { sorwakeup(so2); Index: src/sys/net/raw_usrreq.c diff -u src/sys/net/raw_usrreq.c:1.56.4.1 src/sys/net/raw_usrreq.c:1.56.4.2 --- src/sys/net/raw_usrreq.c:1.56.4.1 Sat Oct 21 19:43:54 2017 +++ src/sys/net/raw_usrreq.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_usrreq.c,v 1.56.4.1 2017/10/21 19:43:54 snj Exp $ */ +/* $NetBSD: raw_usrreq.c,v 1.56.4.2 2018/04/09 13:34:10 bouyer Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -36,7 +36,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.56.4.1 2017/10/21 19:43:54 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.56.4.2 2018/04/09 13:34:10 bouyer Exp $"); #include <sys/param.h> #include <sys/mbuf.h> @@ -106,21 +106,26 @@ raw_input(struct mbuf *m0, ...) continue; if (last != NULL) { struct mbuf *n; - if ((n = m_copy(m, 0, M_COPYALL)) == NULL) - ; - else if (sbappendaddr(&last->so_rcv, src, n, NULL) == 0) - /* should notify about lost packet */ - m_freem(n); - else { + + if ((n = m_copy(m, 0, M_COPYALL)) == NULL || + sbappendaddr(&last->so_rcv, src, n, NULL) == 0) + { + if (n != NULL) + m_freem(n); + soroverflow(last); + } else sorwakeup(last); - } } last = rp->rcb_socket; } - if (last == NULL || sbappendaddr(&last->so_rcv, src, m, NULL) == 0) - m_freem(m); - else { - sorwakeup(last); + if (last != NULL) { + if (sbappendaddr(&last->so_rcv, src, m, NULL) == 0) { + m_free(m); + soroverflow(last); + } else + sorwakeup(last); + } else { + m_free(m); } } Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.213.2.7 src/sys/net/rtsock.c:1.213.2.8 --- src/sys/net/rtsock.c:1.213.2.7 Wed Feb 28 18:54:43 2018 +++ src/sys/net/rtsock.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.213.2.7 2018/02/28 18:54:43 martin Exp $ */ +/* $NetBSD: rtsock.c,v 1.213.2.8 2018/04/09 13:34:10 bouyer Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.213.2.7 2018/02/28 18:54:43 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.213.2.8 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -2114,6 +2114,7 @@ COMPATNAME(route_enqueue)(struct mbuf *m IFQ_LOCK(&ri->ri_intrq); if (IF_QFULL(&ri->ri_intrq)) { + printf("%s: queue full, dropped message\n", __func__); IF_DROP(&ri->ri_intrq); IFQ_UNLOCK(&ri->ri_intrq); m_freem(m); Index: src/sys/netatalk/ddp_input.c diff -u src/sys/netatalk/ddp_input.c:1.29 src/sys/netatalk/ddp_input.c:1.29.8.1 --- src/sys/netatalk/ddp_input.c:1.29 Thu Dec 8 05:16:33 2016 +++ src/sys/netatalk/ddp_input.c Mon Apr 9 13:34:11 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ddp_input.c,v 1.29 2016/12/08 05:16:33 ozaki-r Exp $ */ +/* $NetBSD: ddp_input.c,v 1.29.8.1 2018/04/09 13:34:11 bouyer Exp $ */ /* * Copyright (c) 1990,1994 Regents of The University of Michigan. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.29 2016/12/08 05:16:33 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.29.8.1 2018/04/09 13:34:11 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -315,6 +315,7 @@ ddp_input(struct mbuf *m, struct ifnet * if (sbappendaddr(&ddp->ddp_socket->so_rcv, (struct sockaddr *) & from, m, (struct mbuf *) 0) == 0) { DDP_STATINC(DDP_STAT_NOSOCKSPACE); + soroverflow(ddp->ddp_socket); m_freem(m); return; } Index: src/sys/netcan/can.c diff -u src/sys/netcan/can.c:1.2 src/sys/netcan/can.c:1.2.2.1 --- src/sys/netcan/can.c:1.2 Sat May 27 21:02:56 2017 +++ src/sys/netcan/can.c Mon Apr 9 13:34:11 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: can.c,v 1.2 2017/05/27 21:02:56 bouyer Exp $ */ +/* $NetBSD: can.c,v 1.2.2.1 2018/04/09 13:34:11 bouyer Exp $ */ /*- * Copyright (c) 2003, 2017 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.2 2017/05/27 21:02:56 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.2.2.1 2018/04/09 13:34:11 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -397,6 +397,7 @@ canintr(void) if (sbappendaddr(&canp->canp_socket->so_rcv, (struct sockaddr *) &from, mc, (struct mbuf *) 0) == 0) { + soroverflow(canp->canp_socket); m_freem(mc); } else sorwakeup(canp->canp_socket); Index: src/sys/netinet/ip_mroute.c diff -u src/sys/netinet/ip_mroute.c:1.146.6.2 src/sys/netinet/ip_mroute.c:1.146.6.3 --- src/sys/netinet/ip_mroute.c:1.146.6.2 Tue Jan 2 10:20:34 2018 +++ src/sys/netinet/ip_mroute.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_mroute.c,v 1.146.6.2 2018/01/02 10:20:34 snj Exp $ */ +/* $NetBSD: ip_mroute.c,v 1.146.6.3 2018/04/09 13:34:10 bouyer Exp $ */ /* * Copyright (c) 1992, 1993 @@ -93,7 +93,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.146.6.2 2018/01/02 10:20:34 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_mroute.c,v 1.146.6.3 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1282,6 +1282,7 @@ socket_send(struct socket *s, struct mbu sorwakeup(s); return (0); } + soroverflow(s); } m_freem(mm); return (-1); Index: src/sys/netinet/raw_ip.c diff -u src/sys/netinet/raw_ip.c:1.164.4.1 src/sys/netinet/raw_ip.c:1.164.4.2 --- src/sys/netinet/raw_ip.c:1.164.4.1 Thu Dec 21 21:08:13 2017 +++ src/sys/netinet/raw_ip.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip.c,v 1.164.4.1 2017/12/21 21:08:13 snj Exp $ */ +/* $NetBSD: raw_ip.c,v 1.164.4.2 2018/04/09 13:34:10 bouyer Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.164.4.1 2017/12/21 21:08:13 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.164.4.2 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -155,7 +155,7 @@ rip_sbappendaddr(struct inpcb *last, str || last->inp_socket->so_options & SO_TIMESTAMP) ip_savecontrol(last, &opts, ip, n); if (sbappendaddr(&last->inp_socket->so_rcv, sa, n, opts) == 0) { - /* should notify about lost packet */ + soroverflow(last->inp_socket); m_freem(n); if (opts) m_freem(opts); Index: src/sys/netinet/udp_usrreq.c diff -u src/sys/netinet/udp_usrreq.c:1.233.4.1 src/sys/netinet/udp_usrreq.c:1.233.4.2 --- src/sys/netinet/udp_usrreq.c:1.233.4.1 Thu Dec 21 21:08:13 2017 +++ src/sys/netinet/udp_usrreq.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: udp_usrreq.c,v 1.233.4.1 2017/12/21 21:08:13 snj Exp $ */ +/* $NetBSD: udp_usrreq.c,v 1.233.4.2 2018/04/09 13:34:10 bouyer Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.233.4.1 2017/12/21 21:08:13 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.233.4.2 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -502,8 +502,8 @@ udp4_sendup(struct mbuf *m, int off /* o m_freem(n); if (opts) m_freem(opts); - so->so_rcv.sb_overflowed++; UDP_STATINC(UDP_STAT_FULLSOCK); + soroverflow(so); } else sorwakeup(so); } Index: src/sys/netinet6/icmp6.c diff -u src/sys/netinet6/icmp6.c:1.211.6.4 src/sys/netinet6/icmp6.c:1.211.6.5 --- src/sys/netinet6/icmp6.c:1.211.6.4 Sat Mar 31 10:27:40 2018 +++ src/sys/netinet6/icmp6.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: icmp6.c,v 1.211.6.4 2018/03/31 10:27:40 martin Exp $ */ +/* $NetBSD: icmp6.c,v 1.211.6.5 2018/04/09 13:34:10 bouyer Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.211.6.4 2018/03/31 10:27:40 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.211.6.5 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -2016,7 +2016,7 @@ icmp6_rip6_input(struct mbuf **mp, int o m_adj(n, off); if (sbappendaddr(&last->in6p_socket->so_rcv, sin6tosa(&rip6src), n, opts) == 0) { - /* should notify about lost packet */ + soroverflow(last->in6p_socket); m_freem(n); if (opts) m_freem(opts); @@ -2048,6 +2048,7 @@ icmp6_rip6_input(struct mbuf **mp, int o m_adj(m, off); if (sbappendaddr(&last->in6p_socket->so_rcv, sin6tosa(&rip6src), m, opts) == 0) { + soroverflow(last->in6p_socket); m_freem(m); if (opts) m_freem(opts); Index: src/sys/netinet6/ip6_input.c diff -u src/sys/netinet6/ip6_input.c:1.178.2.6 src/sys/netinet6/ip6_input.c:1.178.2.7 --- src/sys/netinet6/ip6_input.c:1.178.2.6 Mon Feb 26 13:32:01 2018 +++ src/sys/netinet6/ip6_input.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_input.c,v 1.178.2.6 2018/02/26 13:32:01 martin Exp $ */ +/* $NetBSD: ip6_input.c,v 1.178.2.7 2018/04/09 13:34:10 bouyer Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.178.2.6 2018/02/26 13:32:01 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.178.2.7 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_gateway.h" @@ -1352,8 +1352,8 @@ ip6_notify_pmtu(struct in6pcb *in6p, con if (sbappendaddr(&so->so_rcv, (const struct sockaddr *)dst, NULL, m_mtu) == 0) { + soroverflow(so); m_freem(m_mtu); - /* XXX: should count statistics */ } else sorwakeup(so); Index: src/sys/netinet6/ip6_mroute.c diff -u src/sys/netinet6/ip6_mroute.c:1.119.6.1 src/sys/netinet6/ip6_mroute.c:1.119.6.2 --- src/sys/netinet6/ip6_mroute.c:1.119.6.1 Fri Feb 2 10:54:02 2018 +++ src/sys/netinet6/ip6_mroute.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_mroute.c,v 1.119.6.1 2018/02/02 10:54:02 martin Exp $ */ +/* $NetBSD: ip6_mroute.c,v 1.119.6.2 2018/04/09 13:34:10 bouyer Exp $ */ /* $KAME: ip6_mroute.c,v 1.49 2001/07/25 09:21:18 jinmei Exp $ */ /* @@ -117,7 +117,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.119.6.1 2018/02/02 10:54:02 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.119.6.2 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1030,6 +1030,7 @@ socket_send(struct socket *s, struct mbu sorwakeup(s); return 0; } + soroverflow(s); } m_freem(mm); return -1; Index: src/sys/netinet6/raw_ip6.c diff -u src/sys/netinet6/raw_ip6.c:1.157.2.3 src/sys/netinet6/raw_ip6.c:1.157.2.4 --- src/sys/netinet6/raw_ip6.c:1.157.2.3 Fri Mar 30 11:42:59 2018 +++ src/sys/netinet6/raw_ip6.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip6.c,v 1.157.2.3 2018/03/30 11:42:59 martin Exp $ */ +/* $NetBSD: raw_ip6.c,v 1.157.2.4 2018/04/09 13:34:10 bouyer Exp $ */ /* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.157.2.3 2018/03/30 11:42:59 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.157.2.4 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_ipsec.h" @@ -215,7 +215,7 @@ rip6_input(struct mbuf **mp, int *offp, m_adj(n, *offp); if (sbappendaddr(&last->in6p_socket->so_rcv, sin6tosa(&rip6src), n, opts) == 0) { - /* should notify about lost packet */ + soroverflow(last->in6p_socket); m_freem(n); if (opts) m_freem(opts); @@ -248,6 +248,7 @@ rip6_input(struct mbuf **mp, int *offp, m_adj(m, *offp); if (sbappendaddr(&last->in6p_socket->so_rcv, sin6tosa(&rip6src), m, opts) == 0) { + soroverflow(last->in6p_socket); m_freem(m); if (opts) m_freem(opts); Index: src/sys/netinet6/udp6_usrreq.c diff -u src/sys/netinet6/udp6_usrreq.c:1.129 src/sys/netinet6/udp6_usrreq.c:1.129.4.1 --- src/sys/netinet6/udp6_usrreq.c:1.129 Thu Apr 20 08:46:07 2017 +++ src/sys/netinet6/udp6_usrreq.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: udp6_usrreq.c,v 1.129 2017/04/20 08:46:07 ozaki-r Exp $ */ +/* $NetBSD: udp6_usrreq.c,v 1.129.4.1 2018/04/09 13:34:10 bouyer Exp $ */ /* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.129 2017/04/20 08:46:07 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.129.4.1 2018/04/09 13:34:10 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -376,8 +376,8 @@ udp6_sendup(struct mbuf *m, int off /* o m_freem(n); if (opts) m_freem(opts); - so->so_rcv.sb_overflowed++; UDP6_STATINC(UDP6_STAT_FULLSOCK); + soroverflow(so); } else sorwakeup(so); } Index: src/sys/netipsec/keysock.c diff -u src/sys/netipsec/keysock.c:1.58.2.1 src/sys/netipsec/keysock.c:1.58.2.2 --- src/sys/netipsec/keysock.c:1.58.2.1 Sat Oct 21 19:43:54 2017 +++ src/sys/netipsec/keysock.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: keysock.c,v 1.58.2.1 2017/10/21 19:43:54 snj Exp $ */ +/* $NetBSD: keysock.c,v 1.58.2.2 2018/04/09 13:34:10 bouyer Exp $ */ /* $FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */ /* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */ @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.58.2.1 2017/10/21 19:43:54 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.58.2.2 2018/04/09 13:34:10 bouyer Exp $"); /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */ @@ -207,11 +207,12 @@ key_sendup0( __func__); PFKEY_STATINC(PFKEY_STAT_IN_NOMEM); m_freem(m); + soroverflow(rp->rcb_socket); error = ENOBUFS; - rp->rcb_socket->so_rcv.sb_overflowed++; - } else + } else { + sorwakeup(rp->rcb_socket); error = 0; - sorwakeup(rp->rcb_socket); + } return error; } Index: src/sys/sys/socketvar.h diff -u src/sys/sys/socketvar.h:1.144.6.1 src/sys/sys/socketvar.h:1.144.6.2 --- src/sys/sys/socketvar.h:1.144.6.1 Sun Mar 18 10:57:01 2018 +++ src/sys/sys/socketvar.h Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: socketvar.h,v 1.144.6.1 2018/03/18 10:57:01 martin Exp $ */ +/* $NetBSD: socketvar.h,v 1.144.6.2 2018/04/09 13:34:10 bouyer Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -295,6 +295,7 @@ int sofamily(const struct socket *); int sobind(struct socket *, struct sockaddr *, struct lwp *); void socantrcvmore(struct socket *); void socantsendmore(struct socket *); +void soroverflow(struct socket *); int soclose(struct socket *); int soconnect(struct socket *, struct sockaddr *, struct lwp *); int soconnect2(struct socket *, struct socket *); Index: src/tests/lib/libc/sys/t_recvmmsg.c diff -u src/tests/lib/libc/sys/t_recvmmsg.c:1.1 src/tests/lib/libc/sys/t_recvmmsg.c:1.1.26.1 --- src/tests/lib/libc/sys/t_recvmmsg.c:1.1 Fri Jun 22 18:45:23 2012 +++ src/tests/lib/libc/sys/t_recvmmsg.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $ */ +/* $NetBSD: t_recvmmsg.c,v 1.1.26.1 2018/04/09 13:34:10 bouyer Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $"); +__RCSID("$NetBSD: t_recvmmsg.c,v 1.1.26.1 2018/04/09 13:34:10 bouyer Exp $"); #include <atf-c.h> #include <sys/types.h> @@ -47,6 +47,7 @@ __RCSID("$NetBSD: t_recvmmsg.c,v 1.1 201 #include <time.h> #include <stdint.h> #include <errno.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -57,7 +58,14 @@ __RCSID("$NetBSD: t_recvmmsg.c,v 1.1 201 #define min(a, b) ((a) < (b) ? (a) : (b)) static int debug; +static volatile sig_atomic_t rdied; +static void +handle_sigchld(__unused int pid) +{ + + rdied = 1; +} ATF_TC(recvmmsg_basic); ATF_TC_HEAD(recvmmsg_basic, tc) @@ -75,7 +83,9 @@ ATF_TC_BODY(recvmmsg_basic, tc) int status; off_t off; uint8_t DGRAM[1316] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, }; - + struct sigaction sa; + ssize_t overf = 0; + error = socketpair(AF_UNIX, SOCK_DGRAM, 0, fd); ATF_REQUIRE_MSG(error != -1, "socketpair failed (%s)", strerror(errno)); @@ -98,6 +108,14 @@ ATF_TC_BODY(recvmmsg_basic, tc) mmsghdr[n].msg_hdr.msg_namelen = 0; } + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_RESTART; + sa.sa_handler = &handle_sigchld; + sigemptyset(&sa.sa_mask); + error = sigaction(SIGCHLD, &sa, 0); + ATF_REQUIRE_MSG(error != -1, "sigaction failed (%s)", + strerror(errno)); + switch (fork()) { case -1: ATF_REQUIRE_MSG(0, "fork failed (%s)", strerror(errno)); @@ -112,6 +130,13 @@ ATF_TC_BODY(recvmmsg_basic, tc) struct timespec ts = { 1, 0 }; cnt = recvmmsg(fd[1], mmsghdr, min(mmsgcnt, n), MSG_WAITALL, &ts); + if (cnt == -1 && errno == ENOBUFS) { + overf++; + if (debug) + printf("receive buffer overflowed" + " (%zu)\n",overf); + continue; + } ATF_REQUIRE_MSG(cnt != -1, "recvmmsg failed (%s)", strerror(errno)); ATF_REQUIRE_MSG(cnt != 0, "recvmmsg timeout"); @@ -138,16 +163,19 @@ ATF_TC_BODY(recvmmsg_basic, tc) printf("sending packet %u/%u...\n", (n+1), NPKTS); do { + if (rdied) + break; DGRAM[0] = n; error = send(fd[0], DGRAM, sizeof(DGRAM), 0); } while (error == -1 && errno == ENOBUFS); - if (error == -1) - ATF_REQUIRE_MSG(error != -1, "send failed (%s)", - strerror(errno)); + ATF_REQUIRE_MSG(error != -1, "send failed (%s)", + strerror(errno)); } error = wait(&status); ATF_REQUIRE_MSG(error != -1, "wait failed (%s)", strerror(errno)); + ATF_REQUIRE_MSG(WIFEXITED(status) && WEXITSTATUS(status) == 0, + "receiver died"); break; } } Index: src/tests/net/icmp/t_ping.c diff -u src/tests/net/icmp/t_ping.c:1.17 src/tests/net/icmp/t_ping.c:1.17.6.1 --- src/tests/net/icmp/t_ping.c:1.17 Fri Jan 13 21:30:42 2017 +++ src/tests/net/icmp/t_ping.c Mon Apr 9 13:34:10 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: t_ping.c,v 1.17 2017/01/13 21:30:42 christos Exp $ */ +/* $NetBSD: t_ping.c,v 1.17.6.1 2018/04/09 13:34:10 bouyer Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: t_ping.c,v 1.17 2017/01/13 21:30:42 christos Exp $"); +__RCSID("$NetBSD: t_ping.c,v 1.17.6.1 2018/04/09 13:34:10 bouyer Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -182,17 +182,23 @@ doping(const char *target, int loops, u_ icmp->icmp_seq = htons(loop); icmp->icmp_cksum = 0; icmp->icmp_cksum = in_cksum(icmp, pktsize); - RL(rump_sys_sendto(s, icmp, pktsize, 0, - (struct sockaddr *)&dst, sizeof(dst))); + + n = rump_sys_sendto(s, icmp, pktsize, 0, + (struct sockaddr *)&dst, sizeof(dst)); + if (n == -1) { + if (errno == ENOBUFS) + continue; + atf_tc_fail_errno("sendto failed"); + } RL(rump_sys_fcntl(s, F_SETFL, xnon)); while ((n = rump_sys_recvfrom(s, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&pingee, &slen)) > 0) { succ++; } - if (n == -1 && errno == EAGAIN) + if (n == -1 && (errno == EAGAIN || errno == ENOBUFS)) continue; - atf_tc_fail_errno("recv failed"); + atf_tc_fail_errno("recv failed (n == %d)", n); } rump_sys_close(s); @@ -329,6 +335,7 @@ ATF_TC_BODY(ping_of_death, tc) pid_t cpid; size_t tot, frag; int s, x, loop; + ssize_t error; cpid = fork(); rump_init(); @@ -412,15 +419,22 @@ ATF_TC_BODY(ping_of_death, tc) ip->ip_off |= IP_MF; } - RL(rump_sys_sendto(s, data, frag, 0, - (struct sockaddr *)&dst, sizeof(dst))); + error = rump_sys_sendto(s, data, frag, 0, + (struct sockaddr *)&dst, sizeof(dst)); + if (error == -1) { + if (errno == ENOBUFS) + continue; + atf_tc_fail_errno("sendto failed"); + } + if ((size_t)error != frag) + atf_tc_fail("sendto did not write all data"); } if (waitpid(-1, &status, WNOHANG) > 0) { if (WIFEXITED(status) && WEXITSTATUS(status) == 0) break; atf_tc_fail("child did not exit clean"); } - + usleep(10000); } }