Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Nov 2003 15:09:33 -0800 (PST)
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 41491 for review
Message-ID:  <200311052309.hA5N9XQW054721@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=41491

Change 41491 by sam@sam_ebb on 2003/11/05 15:09:33

	o add missing locking of the inpcb in div_output; need to
	  test but this may well be the cause of various problems
	  people have been reporting
	o add locking to div_abort and div_shutdown so the code
	  is like everyone else (raw, udp, etc)

Affected files ...

.. //depot/projects/netperf/sys/netinet/ip_divert.c#11 edit

Differences ...

==== //depot/projects/netperf/sys/netinet/ip_divert.c#11 (text+ko) ====

@@ -312,9 +312,12 @@
 
 	/* Reinject packet into the system as incoming or outgoing */
 	if (!sin || sin->sin_addr.s_addr == 0) {
-		struct inpcb *const inp = sotoinpcb(so);
 		struct ip *const ip = mtod(m, struct ip *);
+		struct inpcb *inp;
 
+		INP_INFO_WLOCK(&divcbinfo);
+		inp = sotoinpcb(so);
+		INP_LOCK(inp);
 		/*
 		 * Don't allow both user specified and setsockopt options,
 		 * and don't allow packet length sizes that will crash
@@ -322,20 +325,23 @@
 		if (((ip->ip_hl != (sizeof (*ip) >> 2)) && inp->inp_options) ||
 		     ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) {
 			error = EINVAL;
-			goto cantsend;
-		}
+			m_freem(m);
+		} else {
+			/* Convert fields to host order for ip_output() */
+			ip->ip_len = ntohs(ip->ip_len);
+			ip->ip_off = ntohs(ip->ip_off);
 
-		/* Convert fields to host order for ip_output() */
-		ip->ip_len = ntohs(ip->ip_len);
-		ip->ip_off = ntohs(ip->ip_off);
+			/* Send packet to output processing */
+			ipstat.ips_rawout++;			/* XXX */
 
-		/* Send packet to output processing */
-		ipstat.ips_rawout++;			/* XXX */
-		error = ip_output((struct mbuf *)&divert_tag,
-			    inp->inp_options, &inp->inp_route,
-			    (so->so_options & SO_DONTROUTE) |
-			    IP_ALLOWBROADCAST | IP_RAWOUTPUT,
-			    inp->inp_moptions, NULL);
+			error = ip_output((struct mbuf *)&divert_tag,
+				    inp->inp_options, &inp->inp_route,
+				    (so->so_options & SO_DONTROUTE) |
+				    IP_ALLOWBROADCAST | IP_RAWOUTPUT,
+				    inp->inp_moptions, NULL);
+		}
+		INP_UNLOCK(inp);
+		INP_INFO_WUNLOCK(&divcbinfo);
 	} else {
 		if (m->m_pkthdr.rcvif == NULL) {
 			/*
@@ -424,8 +430,19 @@
 static int
 div_abort(struct socket *so)
 {
+	struct inpcb *inp;
+
+	INP_INFO_WLOCK(&divcbinfo);
+	inp = sotoinpcb(so);
+	if (inp == 0) {
+		INP_INFO_WUNLOCK(&divcbinfo);
+		return EINVAL;	/* ??? possible? panic instead? */
+	}
+	INP_LOCK(inp);
 	soisdisconnected(so);
-	return div_detach(so);
+	in_pcbdetach(inp);
+	INP_INFO_WUNLOCK(&divcbinfo);
+	return 0;
 }
 
 static int
@@ -470,7 +487,18 @@
 static int
 div_shutdown(struct socket *so)
 {
+	struct inpcb *inp;
+
+	INP_INFO_RLOCK(&divcbinfo);
+	inp = sotoinpcb(so);
+	if (inp == 0) {
+		INP_INFO_RUNLOCK(&divcbinfo);
+		return EINVAL;
+	}
+	INP_LOCK(inp);
+	INP_INFO_RUNLOCK(&divcbinfo);
 	socantsendmore(so);
+	INP_UNLOCK(inp);
 	return 0;
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311052309.hA5N9XQW054721>