diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-04-12 03:32:54 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-04-12 03:32:54 +0000 |
commit | 63a6c29297af6f89fad8cb494eb6c59c3e1b155e (patch) | |
tree | 585d68e38494f9f45df67b037dc2d72f51d2886a | |
parent | 8a39e7b800c3e1302530f1b61be756b3d627077a (diff) | |
download | FreeBSD-src-63a6c29297af6f89fad8cb494eb6c59c3e1b155e.zip FreeBSD-src-63a6c29297af6f89fad8cb494eb6c59c3e1b155e.tar.gz |
Add comment to udp6_input() that locking is missing from multicast
UDPv6 delivery.
Lock the inpcb of the UDP connection being delivered to before
processing IPSEC policy and other delivery activities.
MFC after: 3 months
-rw-r--r-- | sys/netinet6/udp6_usrreq.c | 9 |
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: |