summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/udp6_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/udp6_usrreq.c')
-rw-r--r--sys/netinet6/udp6_usrreq.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 61c8ea1..7157845 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -217,6 +217,9 @@ udp6_input(mp, offp, proto)
/*
* Locate pcb(s) for datagram.
* (Algorithm copied from raw_intr().)
+ *
+ * XXXRW: The individual inpcbs need to be locked in the
+ * style of udp_input().
*/
last = NULL;
LIST_FOREACH(in6p, &udb, inp_list) {
@@ -331,7 +334,7 @@ udp6_input(mp, offp, proto)
in6p = in6_pcblookup_hash(&udbinfo, &ip6->ip6_src, uh->uh_sport,
&ip6->ip6_dst, uh->uh_dport, 1,
m->m_pkthdr.rcvif);
- if (in6p == 0) {
+ if (in6p == NULL) {
if (log_in_vain) {
char buf[INET6_ADDRSTRLEN];
@@ -351,11 +354,13 @@ udp6_input(mp, offp, proto)
icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
return IPPROTO_DONE;
}
+ INP_LOCK(in6p);
#if defined(IPSEC) || defined(FAST_IPSEC)
/*
* Check AH/ESP integrity.
*/
if (ipsec6_in_reject(m, in6p)) {
+ INP_UNLOCK(in6p);
#ifdef IPSEC
ipsec6stat.in_polvio++;
#endif /* IPSEC */
@@ -375,10 +380,12 @@ udp6_input(mp, offp, proto)
m_adj(m, off + sizeof(struct udphdr));
if (sbappendaddr(&in6p->in6p_socket->so_rcv,
(struct sockaddr *)&fromsa, m, opts) == 0) {
+ INP_UNLOCK(in6p);
udpstat.udps_fullsock++;
goto bad;
}
sorwakeup(in6p->in6p_socket);
+ INP_UNLOCK(in6p);
INP_INFO_RUNLOCK(&udbinfo);
return IPPROTO_DONE;
bad:
OpenPOWER on IntegriCloud