Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet6/udp6_usrreq.c
Show First 20 Lines • Show All 736 Lines • ▼ Show 20 Lines | udp6_output(struct socket *so, int flags_arg, struct mbuf *m, | ||||
/* | /* | ||||
* In the following cases we want a write lock on the inp for either | * In the following cases we want a write lock on the inp for either | ||||
* local operations or for possible route cache updates in the IPv6 | * local operations or for possible route cache updates in the IPv6 | ||||
* output path: | * output path: | ||||
* - on connected sockets (sin6 is NULL) for route cache updates, | * - on connected sockets (sin6 is NULL) for route cache updates, | ||||
* - when we are not bound to an address and source port (it is | * - when we are not bound to an address and source port (it is | ||||
* in6_pcbsetport() which will require the write lock). | * in6_pcbsetport() which will require the write lock). | ||||
*/ | */ | ||||
retry: | |||||
if (sin6 == NULL || (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) && | if (sin6 == NULL || (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) && | ||||
inp->inp_lport == 0)) { | inp->inp_lport == 0)) { | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
/* | |||||
* In case we lost a race and another thread bound addr/port | |||||
* on the inp we cannot keep the wlock (which still would be | |||||
* fine) as further down, based on these values we make | |||||
* decisions for the pcbinfo lock. If the locks are not in | |||||
* synch the assertions on unlock will fire, hence we go for | |||||
* one retry loop. | |||||
*/ | |||||
if (sin6 != NULL && | |||||
(!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) || | |||||
inp->inp_lport != 0)) { | |||||
INP_WUNLOCK(inp); | |||||
goto retry; | |||||
} | |||||
unlock_inp = UH_WLOCKED; | unlock_inp = UH_WLOCKED; | ||||
} else { | } else { | ||||
INP_RLOCK(inp); | INP_RLOCK(inp); | ||||
unlock_inp = UH_RLOCKED; | unlock_inp = UH_RLOCKED; | ||||
} | } | ||||
nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ? | nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ? | ||||
IPPROTO_UDP : IPPROTO_UDPLITE; | IPPROTO_UDP : IPPROTO_UDPLITE; | ||||
▲ Show 20 Lines • Show All 625 Lines • Show Last 20 Lines |