Module Name: src Committed By: tls Date: Thu Apr 1 00:24:41 UTC 2010
Modified Files: src/sys/netinet: ip_flow.c tcp_input.c Log Message: After discussion with ad@: it appears that KERNEL_LOCK also protects the driver output path (that is, ifp->if_output()). In the case of entry through the socket code, we are fine, because pru_usrreq takes KERNEL_LOCK. However, there are a few other ways to cause output which require protection: 1) direct calls to tcp_output() in tcp_input() 2) fast-forwarding code (ip_flow) -- protected elsewise against itself by the softnet lock. 3) *Possibly* the ARP code. I have currently persuaded myself that it is safe because of how it's called. 4) Possibly the ICMP code. This change addresses #1 and #2. To generate a diff of this commit: cvs rdiff -u -r1.58 -r1.59 src/sys/netinet/ip_flow.c cvs rdiff -u -r1.300 -r1.301 src/sys/netinet/tcp_input.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/ip_flow.c diff -u src/sys/netinet/ip_flow.c:1.58 src/sys/netinet/ip_flow.c:1.59 --- src/sys/netinet/ip_flow.c:1.58 Sun Mar 15 22:16:09 2009 +++ src/sys/netinet/ip_flow.c Thu Apr 1 00:24:41 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_flow.c,v 1.58 2009/03/15 22:16:09 cegger Exp $ */ +/* $NetBSD: ip_flow.c,v 1.59 2010/04/01 00:24:41 tls Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.58 2009/03/15 22:16:09 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.59 2010/04/01 00:24:41 tls Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -301,12 +301,14 @@ else dst = rtcache_getdst(&ipf->ipf_ro); + KERNEL_LOCK(1, NULL); if ((error = (*rt->rt_ifp->if_output)(rt->rt_ifp, m, dst, rt)) != 0) { if (error == ENOBUFS) ipf->ipf_dropped++; else ipf->ipf_errors++; } + KERNEL_UNLOCK_ONE(NULL); return 1; } Index: src/sys/netinet/tcp_input.c diff -u src/sys/netinet/tcp_input.c:1.300 src/sys/netinet/tcp_input.c:1.301 --- src/sys/netinet/tcp_input.c:1.300 Tue Jan 26 18:09:07 2010 +++ src/sys/netinet/tcp_input.c Thu Apr 1 00:24:41 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_input.c,v 1.300 2010/01/26 18:09:07 pooka Exp $ */ +/* $NetBSD: tcp_input.c,v 1.301 2010/04/01 00:24:41 tls Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -145,7 +145,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.300 2010/01/26 18:09:07 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.301 2010/04/01 00:24:41 tls Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -1787,7 +1787,9 @@ sowwakeup(so); if (so->so_snd.sb_cc) + KERNEL_LOCK(1, NULL); (void) tcp_output(tp); + KERNEL_UNLOCK_ONE(NULL); if (tcp_saveti) m_freem(tcp_saveti); return; @@ -1883,7 +1885,9 @@ sorwakeup(so); tcp_setup_ack(tp, th); if (tp->t_flags & TF_ACKNOW) + KERNEL_LOCK(1, NULL); (void) tcp_output(tp); + KERNEL_UNLOCK_ONE(NULL); if (tcp_saveti) m_freem(tcp_saveti); return; @@ -2369,7 +2373,9 @@ goto drop; } else if (tp->t_dupacks > tcprexmtthresh) { tp->snd_cwnd += tp->t_segsz; + KERNEL_LOCK(1, NULL); (void) tcp_output(tp); + KERNEL_UNLOCK_ONE(NULL); goto drop; } } else { @@ -2730,7 +2736,9 @@ * Return any desired output. */ if (needoutput || (tp->t_flags & TF_ACKNOW)) { + KERNEL_LOCK(1, NULL); (void) tcp_output(tp); + KERNEL_UNLOCK_ONE(NULL); } if (tcp_saveti) m_freem(tcp_saveti); @@ -2767,7 +2775,9 @@ dropafterack2: m_freem(m); tp->t_flags |= TF_ACKNOW; + KERNEL_LOCK(1, NULL); (void) tcp_output(tp); + KERNEL_UNLOCK_ONE(NULL); if (tcp_saveti) m_freem(tcp_saveti); return;