diff options
author | rwatson <rwatson@FreeBSD.org> | 2004-12-05 19:11:09 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2004-12-05 19:11:09 +0000 |
commit | ef102033be651137a9f0e0d39c4a9883b6abb4a0 (patch) | |
tree | ba2e6e2f16b185747a31afc35d25ccc7fb203b55 /sys/netinet/ip_output.c | |
parent | 4f260d49bc2b7c3933dccbcb5f14699ac36695d5 (diff) | |
download | FreeBSD-src-ef102033be651137a9f0e0d39c4a9883b6abb4a0.zip FreeBSD-src-ef102033be651137a9f0e0d39c4a9883b6abb4a0.tar.gz |
Start working through inpcb locking for ip_ctloutput() by cleaning up
modifications to the inpcb IP options mbuf:
- Lock the inpcb before passing it into ip_pcbopts() in order to prevent
simulatenous reads and read-modify-writes that could result in races.
- Pass the inpcb reference into ip_pcbopts() instead of the option chain
pointer in the inpcb.
- Assert the inpcb lock in ip_pcbots.
- Convert one or two uses of a pointer as a boolean or an integer
comparison to a comparison with NULL for readability.
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r-- | sys/netinet/ip_output.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index dfc939b..bbac04f 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -99,7 +99,7 @@ static void ip_mloopback (struct ifnet *, struct mbuf *, struct sockaddr_in *, int); static int ip_getmoptions (struct sockopt *, struct ip_moptions *); -static int ip_pcbopts(int, struct mbuf **, struct mbuf *); +static int ip_pcbopts(struct inpcb *, int, struct mbuf *); static int ip_setmoptions (struct sockopt *, struct ip_moptions **); @@ -1175,9 +1175,10 @@ ip_ctloutput(so, sopt) m->m_len = sopt->sopt_valsize; error = sooptcopyin(sopt, mtod(m, char *), m->m_len, m->m_len); - - return (ip_pcbopts(sopt->sopt_name, &inp->inp_options, - m)); + INP_LOCK(inp); + error = ip_pcbopts(inp, sopt->sopt_name, m); + INP_UNLOCK(inp); + return (error); } case IP_TOS: @@ -1430,24 +1431,26 @@ ip_ctloutput(so, sopt) * with destination address if source routed. */ static int -ip_pcbopts(optname, pcbopt, m) - int optname; - struct mbuf **pcbopt; - register struct mbuf *m; +ip_pcbopts(struct inpcb *inp, int optname, struct mbuf *m) { register int cnt, optlen; register u_char *cp; + struct mbuf **pcbopt; u_char opt; + INP_LOCK_ASSERT(inp); + + pcbopt = &inp->inp_options; + /* turn off any old options */ if (*pcbopt) (void)m_free(*pcbopt); *pcbopt = 0; - if (m == (struct mbuf *)0 || m->m_len == 0) { + if (m == NULL || m->m_len == 0) { /* * Only turning off any previous options. */ - if (m) + if (m != NULL) (void)m_free(m); return (0); } |