summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-12-05 19:11:09 +0000
committerrwatson <rwatson@FreeBSD.org>2004-12-05 19:11:09 +0000
commitef102033be651137a9f0e0d39c4a9883b6abb4a0 (patch)
treeba2e6e2f16b185747a31afc35d25ccc7fb203b55 /sys/netinet
parent4f260d49bc2b7c3933dccbcb5f14699ac36695d5 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/netinet/ip_output.c23
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);
}
OpenPOWER on IntegriCloud