summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-04-21 12:06:41 +0000
committerrwatson <rwatson@FreeBSD.org>2008-04-21 12:06:41 +0000
commit9ee84cddef0af6abc4d9dfc1cd142a36175a4e6a (patch)
treeb881bb2a1f9358bee7e39fc3179daaf0f697eadc /sys
parentc6e37355a2f7b8c97a9e27321b849448a8a909a8 (diff)
downloadFreeBSD-src-9ee84cddef0af6abc4d9dfc1cd142a36175a4e6a.zip
FreeBSD-src-9ee84cddef0af6abc4d9dfc1cd142a36175a4e6a.tar.gz
With IPv4 raw sockets, read lock rather than write lock the inpcb when
receiving or transmitting. With IPv6 raw sockets, read lock rather than write lock the inpcb when receiving. Unfortunately, IPv6 source address selection appears to require a write lock on the inpcb for the time being. MFC after: 3 months
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/raw_ip.c30
-rw-r--r--sys/netinet6/raw_ip6.c10
2 files changed, 20 insertions, 20 deletions
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index ead5219..23ab1fe 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -155,7 +155,7 @@ raw_append(struct inpcb *last, struct ip *ip, struct mbuf *n)
{
int policyfail = 0;
- INP_WLOCK_ASSERT(last);
+ INP_RLOCK_ASSERT(last);
#ifdef IPSEC
/* check AH/ESP integrity. */
@@ -209,10 +209,10 @@ rip_input(struct mbuf *m, int off)
ripsrc.sin_addr = ip->ip_src;
last = NULL;
LIST_FOREACH(inp, &ripcb, inp_list) {
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
if (inp->inp_ip_p && inp->inp_ip_p != proto) {
docontinue:
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
continue;
}
#ifdef INET6
@@ -236,14 +236,14 @@ rip_input(struct mbuf *m, int off)
if (n != NULL)
(void) raw_append(last, ip, n);
/* XXX count dropped packet */
- INP_WUNLOCK(last);
+ INP_RUNLOCK(last);
}
last = inp;
}
if (last != NULL) {
if (raw_append(last, ip, m) != 0)
ipstat.ips_delivered--;
- INP_WUNLOCK(last);
+ INP_RUNLOCK(last);
} else {
m_freem(m);
ipstat.ips_noproto++;
@@ -278,7 +278,7 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
if (m == NULL)
return(ENOBUFS);
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
ip = mtod(m, struct ip *);
ip->ip_tos = inp->inp_ip_tos;
if (inp->inp_flags & INP_DONTFRAG)
@@ -299,12 +299,12 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
m_freem(m);
return(EMSGSIZE);
}
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
ip = mtod(m, struct ip *);
if (jailed(inp->inp_socket->so_cred)) {
if (ip->ip_src.s_addr !=
htonl(prison_getip(inp->inp_socket->so_cred))) {
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
m_freem(m);
return (EPERM);
}
@@ -315,7 +315,7 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
&& inp->inp_options)
|| (ip->ip_len > m->m_pkthdr.len)
|| (ip->ip_len < (ip->ip_hl << 2))) {
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
m_freem(m);
return EINVAL;
}
@@ -335,7 +335,7 @@ rip_output(struct mbuf *m, struct socket *so, u_long dst)
error = ip_output(m, inp->inp_options, NULL, flags,
inp->inp_moptions, inp);
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
return error;
}
@@ -851,13 +851,13 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
INP_INFO_RLOCK(&ripcbinfo);
for (inp = LIST_FIRST(ripcbinfo.ipi_listhead), i = 0; inp && i < n;
inp = LIST_NEXT(inp, inp_list)) {
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
if (inp->inp_gencnt <= gencnt &&
cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) {
/* XXX held references? */
inp_list[i++] = inp;
}
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
}
INP_INFO_RUNLOCK(&ripcbinfo);
n = i;
@@ -865,7 +865,7 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
error = 0;
for (i = 0; i < n; i++) {
inp = inp_list[i];
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
if (inp->inp_gencnt <= gencnt) {
struct xinpcb xi;
bzero(&xi, sizeof(xi));
@@ -874,10 +874,10 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
bcopy(inp, &xi.xi_inp, sizeof *inp);
if (inp->inp_socket)
sotoxsocket(inp->inp_socket, &xi.xi_socket);
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
error = SYSCTL_OUT(req, &xi, sizeof xi);
} else
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
}
if (!error) {
/*
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index c12bde1..b791872 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -154,10 +154,10 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
INP_INFO_RLOCK(&ripcbinfo);
LIST_FOREACH(in6p, &ripcb, inp_list) {
- INP_WLOCK(in6p);
+ INP_RLOCK(in6p);
if ((in6p->in6p_vflag & INP_IPV6) == 0) {
docontinue:
- INP_WUNLOCK(in6p);
+ INP_RUNLOCK(in6p);
continue;
}
if (in6p->in6p_ip6_nxt &&
@@ -207,7 +207,7 @@ docontinue:
sorwakeup(last->in6p_socket);
opts = NULL;
}
- INP_WUNLOCK(last);
+ INP_RUNLOCK(last);
}
last = in6p;
}
@@ -220,7 +220,7 @@ docontinue:
ipsec6stat.in_polvio++;
ip6stat.ip6s_delivered--;
/* do not inject data into pcb */
- INP_WUNLOCK(last);
+ INP_RUNLOCK(last);
} else
#endif /* IPSEC */
if (last) {
@@ -237,7 +237,7 @@ docontinue:
rip6stat.rip6s_fullsock++;
} else
sorwakeup(last->in6p_socket);
- INP_WUNLOCK(last);
+ INP_RUNLOCK(last);
} else {
rip6stat.rip6s_nosock++;
if (m->m_flags & M_MCAST)
OpenPOWER on IntegriCloud