Page MenuHomeFreeBSD

D46056.diff
No OneTemporary

D46056.diff

diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1087,7 +1087,6 @@
uint16_t cscov = 0;
uint32_t flowid = 0;
uint8_t flowtype = M_HASHTYPE_NONE;
- bool use_cached_route;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp_send: inp == NULL"));
@@ -1116,16 +1115,21 @@
sin = (struct sockaddr_in *)addr;
/*
- * udp_send() may need to temporarily bind or connect the current
- * inpcb. As such, we don't know up front whether we will need the
- * pcbinfo lock or not. Do any work to decide what is needed up
- * front before acquiring any locks.
+ * 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
+ * output path:
+ * - on connected sockets (sin6 is NULL) for route cache updates,
+ * - when we are not bound to an address and source port (it is
+ * in_pcbinshash() which will require the write lock).
+ * - when we are using a mapped address on an IPv6 socket (for
+ * updating inp_vflag).
*
* We will need network epoch in either case, to safely lookup into
* pcb hash.
*/
- use_cached_route = sin == NULL || (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0);
- if (use_cached_route || (flags & PRUS_IPV6) != 0)
+ if (sin == NULL ||
+ (inp->inp_laddr.s_addr == INADDR_ANY && inp->inp_lport == 0) ||
+ (flags & PRUS_IPV6) != 0)
INP_WLOCK(inp);
else
INP_RLOCK(inp);
@@ -1476,7 +1480,7 @@
else
UDP_PROBE(send, NULL, inp, &ui->ui_i, inp, &ui->ui_u);
error = ip_output(m, inp->inp_options,
- use_cached_route ? &inp->inp_route : NULL, ipflags,
+ sin == NULL ? &inp->inp_route : NULL, ipflags,
inp->inp_moptions, inp);
INP_UNLOCK(inp);
NET_EPOCH_EXIT(et);
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -937,7 +937,7 @@
else
UDP_PROBE(send, NULL, inp, ip6, inp, udp6);
error = ip6_output(m, optp,
- INP_WLOCKED(inp) ? &inp->inp_route6 : NULL, flags,
+ sin6 == NULL ? &inp->inp_route6 : NULL, flags,
inp->in6p_moptions, NULL, inp);
INP_UNLOCK(inp);
NET_EPOCH_EXIT(et);

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 18, 4:32 AM (22 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14689866
Default Alt Text
D46056.diff (2 KB)

Event Timeline