PERFORCE change 41491 for review
Sam Leffler
sam at FreeBSD.org
Wed Nov 5 15:09:35 PST 2003
http://perforce.freebsd.org/chv.cgi?CH=41491
Change 41491 by sam at 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;
}
More information about the p4-projects
mailing list