Merge the socket locking patch:
- Socket layer becomes MP safe. - Unix protocols become MP safe. - Allows protocol processing interrupts to safely block on locks. - Fixes a number of race conditions. With much feedback from matt@ and plunky@.
This commit is contained in:
parent
157c460048
commit
15e29e981b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uipc_syscalls_43.c,v 1.41 2008/01/15 09:25:26 martin Exp $ */
|
||||
/* $NetBSD: uipc_syscalls_43.c,v 1.42 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1990, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_43.c,v 1.41 2008/01/15 09:25:26 martin Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_43.c,v 1.42 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -492,6 +492,8 @@ compat_ifioctl(struct socket *so, u_long ocmd, u_long cmd, void *data,
|
|||
struct ifnet *ifp = ifunit(ifr->ifr_name);
|
||||
struct sockaddr *sa;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
if (ifp == NULL)
|
||||
return ENXIO;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: linux_socket.c,v 1.90 2008/04/23 13:13:25 ad Exp $ */
|
||||
/* $NetBSD: linux_socket.c,v 1.91 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.90 2008/04/23 13:13:25 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.91 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_inet.h"
|
||||
|
@ -1212,17 +1212,17 @@ linux_sys_connect(struct lwp *l, const struct linux_sys_connect_args *uap, regis
|
|||
|
||||
if (error == EISCONN) {
|
||||
struct socket *so;
|
||||
int s, state, prflags, nbio;
|
||||
int state, prflags, nbio;
|
||||
|
||||
/* getsock() will use the descriptor for us */
|
||||
if (fd_getsock(SCARG(uap, s), &so) != 0)
|
||||
return EISCONN;
|
||||
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
state = so->so_state;
|
||||
nbio = so->so_nbio;
|
||||
prflags = so->so_proto->pr_flags;
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
fd_putfile(SCARG(uap, s));
|
||||
/*
|
||||
* We should only let this call succeed once per
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: svr4_net.c,v 1.51 2008/03/21 21:54:59 ad Exp $ */
|
||||
/* $NetBSD: svr4_net.c,v 1.52 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1994, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_net.c,v 1.51 2008/03/21 21:54:59 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: svr4_net.c,v 1.52 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#define COMPAT_SVR4 1
|
||||
|
||||
|
@ -190,7 +190,7 @@ svr4_netopen(dev_t dev, int flag, int mode, struct lwp *l)
|
|||
if ((error = fd_allocfile(&fp, &fd)) != 0)
|
||||
return error;
|
||||
|
||||
if ((error = socreate(family, &so, type, protocol, l)) != 0) {
|
||||
if ((error = socreate(family, &so, type, protocol, l, NULL)) != 0) {
|
||||
DPRINTF(("socreate error %d\n", error));
|
||||
fd_abort(curproc, fp, fd);
|
||||
return error;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bthidev.c,v 1.14 2008/03/28 21:17:37 plunky Exp $ */
|
||||
/* $NetBSD: bthidev.c,v 1.15 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.14 2008/03/28 21:17:37 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.15 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -97,7 +97,6 @@ struct bthidev_softc {
|
|||
#define BTHID_WAIT_CTL 1
|
||||
#define BTHID_WAIT_INT 2
|
||||
#define BTHID_OPEN 3
|
||||
#define BTHID_DETACHING 4
|
||||
|
||||
#define BTHID_RETRY_INTERVAL 5 /* seconds between connection attempts */
|
||||
|
||||
|
@ -180,7 +179,7 @@ bthidev_attach(device_t parent, device_t self, void *aux)
|
|||
struct hid_item h;
|
||||
const void *desc;
|
||||
int locs[BTHIDBUSCF_NLOCS];
|
||||
int maxid, rep, s, dlen;
|
||||
int maxid, rep, dlen;
|
||||
|
||||
/*
|
||||
* Init softc
|
||||
|
@ -302,13 +301,13 @@ bthidev_attach(device_t parent, device_t self, void *aux)
|
|||
/*
|
||||
* start bluetooth connections
|
||||
*/
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
if ((sc->sc_flags & BTHID_RECONNECT) == 0)
|
||||
bthidev_listen(sc);
|
||||
|
||||
if (sc->sc_flags & BTHID_CONNECTING)
|
||||
bthidev_connect(sc);
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -316,9 +315,8 @@ bthidev_detach(device_t self, int flags)
|
|||
{
|
||||
struct bthidev_softc *sc = device_private(self);
|
||||
struct bthidev *hidev;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
sc->sc_flags = 0; /* disable reconnecting */
|
||||
|
||||
/* release interrupt listen */
|
||||
|
@ -347,15 +345,10 @@ bthidev_detach(device_t self, int flags)
|
|||
sc->sc_ctl = NULL;
|
||||
}
|
||||
|
||||
/* remove callout */
|
||||
sc->sc_state = BTHID_DETACHING;
|
||||
callout_stop(&sc->sc_reconnect);
|
||||
if (callout_invoking(&sc->sc_reconnect))
|
||||
tsleep(sc, PWAIT, "bthidetach", 0);
|
||||
|
||||
callout_halt(&sc->sc_reconnect, bt_lock);
|
||||
callout_destroy(&sc->sc_reconnect);
|
||||
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
/* detach children */
|
||||
while ((hidev = LIST_FIRST(&sc->sc_list)) != NULL) {
|
||||
|
@ -396,9 +389,8 @@ static void
|
|||
bthidev_timeout(void *arg)
|
||||
{
|
||||
struct bthidev_softc *sc = arg;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
callout_ack(&sc->sc_reconnect);
|
||||
|
||||
switch (sc->sc_state) {
|
||||
|
@ -430,14 +422,10 @@ bthidev_timeout(void *arg)
|
|||
case BTHID_OPEN:
|
||||
break;
|
||||
|
||||
case BTHID_DETACHING:
|
||||
wakeup(sc);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -865,7 +853,7 @@ bthidev_output(struct bthidev *hidev, uint8_t *report, int rlen)
|
|||
{
|
||||
struct bthidev_softc *sc = device_private(hidev->sc_parent);
|
||||
struct mbuf *m;
|
||||
int s, err;
|
||||
int err;
|
||||
|
||||
if (sc == NULL || sc->sc_state != BTHID_OPEN)
|
||||
return ENOTCONN;
|
||||
|
@ -896,9 +884,9 @@ bthidev_output(struct bthidev *hidev, uint8_t *report, int rlen)
|
|||
memcpy(mtod(m, uint8_t *) + 2, report, rlen);
|
||||
m->m_pkthdr.len = m->m_len = rlen + 2;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
err = l2cap_send(sc->sc_int, m);
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: btsco.c,v 1.19 2008/03/28 21:17:37 plunky Exp $ */
|
||||
/* $NetBSD: btsco.c,v 1.20 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.19 2008/03/28 21:17:37 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.20 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/audioio.h>
|
||||
|
@ -91,6 +91,7 @@ struct btsco_softc {
|
|||
|
||||
device_t sc_audio; /* MI audio device */
|
||||
void *sc_intr; /* interrupt cookie */
|
||||
kcondvar_t sc_connect; /* connect wait */
|
||||
|
||||
/* Bluetooth */
|
||||
bdaddr_t sc_laddr; /* local address */
|
||||
|
@ -286,6 +287,7 @@ btsco_attach(device_t parent, device_t self, void *aux)
|
|||
sc->sc_vgm = 200;
|
||||
sc->sc_state = BTSCO_CLOSED;
|
||||
sc->sc_name = device_xname(self);
|
||||
cv_init(&sc->sc_connect, "connect");
|
||||
|
||||
/*
|
||||
* copy in our configuration info
|
||||
|
@ -339,11 +341,10 @@ static int
|
|||
btsco_detach(device_t self, int flags)
|
||||
{
|
||||
struct btsco_softc *sc = device_private(self);
|
||||
int s;
|
||||
|
||||
DPRINTF("sc=%p\n", sc);
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
if (sc->sc_sco != NULL) {
|
||||
DPRINTF("sc_sco=%p\n", sc->sc_sco);
|
||||
sco_disconnect(sc->sc_sco, 0);
|
||||
|
@ -356,7 +357,7 @@ btsco_detach(device_t self, int flags)
|
|||
sco_detach(&sc->sc_sco_l);
|
||||
sc->sc_sco_l = NULL;
|
||||
}
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
if (sc->sc_audio != NULL) {
|
||||
DPRINTF("sc_audio=%p\n", sc->sc_audio);
|
||||
|
@ -381,6 +382,8 @@ btsco_detach(device_t self, int flags)
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
cv_destroy(&sc->sc_connect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -417,7 +420,7 @@ btsco_sco_connected(void *arg)
|
|||
sco_detach(&sc->sc_sco_l);
|
||||
|
||||
sc->sc_state = BTSCO_OPEN;
|
||||
wakeup(sc);
|
||||
cv_broadcast(&sc->sc_connect);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -438,7 +441,7 @@ btsco_sco_disconnected(void *arg, int err)
|
|||
break;
|
||||
|
||||
case BTSCO_WAIT_CONNECT: /* connect failed */
|
||||
wakeup(sc);
|
||||
cv_broadcast(&sc->sc_connect);
|
||||
break;
|
||||
|
||||
case BTSCO_OPEN: /* link lost */
|
||||
|
@ -557,7 +560,7 @@ btsco_open(void *hdl, int flags)
|
|||
{
|
||||
struct sockaddr_bt sa;
|
||||
struct btsco_softc *sc = hdl;
|
||||
int err, s, timo;
|
||||
int err, timo;
|
||||
|
||||
DPRINTF("%s flags 0x%x\n", sc->sc_name, flags);
|
||||
/* flags FREAD & FWRITE? */
|
||||
|
@ -565,7 +568,7 @@ btsco_open(void *hdl, int flags)
|
|||
if (sc->sc_sco != NULL || sc->sc_sco_l != NULL)
|
||||
return EIO;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.bt_len = sizeof(sa);
|
||||
|
@ -613,7 +616,7 @@ btsco_open(void *hdl, int flags)
|
|||
|
||||
sc->sc_state = BTSCO_WAIT_CONNECT;
|
||||
while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT)
|
||||
err = tsleep(sc, PWAIT | PCATCH, "btsco", timo);
|
||||
err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo);
|
||||
|
||||
switch (sc->sc_state) {
|
||||
case BTSCO_CLOSED: /* disconnected */
|
||||
|
@ -639,7 +642,7 @@ btsco_open(void *hdl, int flags)
|
|||
}
|
||||
|
||||
done:
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n",
|
||||
err, sc->sc_state, sc->sc_mtu);
|
||||
|
@ -650,11 +653,10 @@ static void
|
|||
btsco_close(void *hdl)
|
||||
{
|
||||
struct btsco_softc *sc = hdl;
|
||||
int s;
|
||||
|
||||
DPRINTF("%s\n", sc->sc_name);
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
if (sc->sc_sco != NULL) {
|
||||
sco_disconnect(sc->sc_sco, 0);
|
||||
sco_detach(&sc->sc_sco);
|
||||
|
@ -663,7 +665,7 @@ btsco_close(void *hdl)
|
|||
if (sc->sc_sco_l != NULL) {
|
||||
sco_detach(&sc->sc_sco_l);
|
||||
}
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
if (sc->sc_rx_mbuf != NULL) {
|
||||
m_freem(sc->sc_rx_mbuf);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kttcp.c,v 1.27 2008/03/27 19:06:51 ad Exp $ */
|
||||
/* $NetBSD: kttcp.c,v 1.28 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Wasabi Systems, Inc.
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.27 2008/03/27 19:06:51 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.28 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -190,7 +190,7 @@ kttcp_sosend(struct socket *so, unsigned long long slen,
|
|||
{
|
||||
struct mbuf **mp, *m, *top;
|
||||
long space, len, mlen;
|
||||
int error, s, dontroute, atomic;
|
||||
int error, dontroute, atomic;
|
||||
long long resid;
|
||||
|
||||
atomic = sosendallatonce(so);
|
||||
|
@ -211,19 +211,17 @@ kttcp_sosend(struct socket *so, unsigned long long slen,
|
|||
(flags & MSG_DONTROUTE) && (so->so_options & SO_DONTROUTE) == 0 &&
|
||||
(so->so_proto->pr_flags & PR_ATOMIC);
|
||||
l->l_ru.ru_msgsnd++;
|
||||
#define snderr(errno) { error = errno; splx(s); goto release; }
|
||||
|
||||
#define snderr(errno) { error = errno; goto release; }
|
||||
solock(so);
|
||||
restart:
|
||||
if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
|
||||
goto out;
|
||||
do {
|
||||
s = splsoftnet();
|
||||
if (so->so_state & SS_CANTSENDMORE)
|
||||
snderr(EPIPE);
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
splx(s);
|
||||
goto release;
|
||||
}
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0) {
|
||||
|
@ -247,14 +245,13 @@ kttcp_sosend(struct socket *so, unsigned long long slen,
|
|||
"kttcp_soreceive sbwait 1");
|
||||
sbunlock(&so->so_snd);
|
||||
error = sbwait(&so->so_snd);
|
||||
splx(s);
|
||||
if (error)
|
||||
goto out;
|
||||
goto restart;
|
||||
}
|
||||
splx(s);
|
||||
mp = ⊤
|
||||
do {
|
||||
sounlock(so);
|
||||
do {
|
||||
if (top == 0) {
|
||||
m = m_gethdr(M_WAIT, MT_DATA);
|
||||
|
@ -305,12 +302,10 @@ nopages:
|
|||
break;
|
||||
}
|
||||
} while (space > 0 && atomic);
|
||||
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
|
||||
if (so->so_state & SS_CANTSENDMORE)
|
||||
snderr(EPIPE);
|
||||
|
||||
if (dontroute)
|
||||
so->so_options |= SO_DONTROUTE;
|
||||
if (resid > 0)
|
||||
|
@ -322,8 +317,6 @@ nopages:
|
|||
so->so_options &= ~SO_DONTROUTE;
|
||||
if (resid > 0)
|
||||
so->so_state &= ~SS_MORETOCOME;
|
||||
splx(s);
|
||||
|
||||
top = 0;
|
||||
mp = ⊤
|
||||
if (error)
|
||||
|
@ -334,6 +327,7 @@ nopages:
|
|||
release:
|
||||
sbunlock(&so->so_snd);
|
||||
out:
|
||||
sounlock(so);
|
||||
if (top)
|
||||
m_freem(top);
|
||||
*done = slen - resid;
|
||||
|
@ -348,7 +342,7 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
unsigned long long *done, struct lwp *l, int *flagsp)
|
||||
{
|
||||
struct mbuf *m, **mp;
|
||||
int flags, len, error, s, offset, moff, type;
|
||||
int flags, len, error, offset, moff, type;
|
||||
long long orig_resid, resid;
|
||||
const struct protosw *pr;
|
||||
struct mbuf *nextrecord;
|
||||
|
@ -363,8 +357,10 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
flags = 0;
|
||||
if (flags & MSG_OOB) {
|
||||
m = m_get(M_WAIT, MT_DATA);
|
||||
solock(so);
|
||||
error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
|
||||
(struct mbuf *)(long)(flags & MSG_PEEK), NULL, NULL);
|
||||
sounlock(so);
|
||||
if (error)
|
||||
goto bad;
|
||||
do {
|
||||
|
@ -378,14 +374,12 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
}
|
||||
if (mp)
|
||||
*mp = NULL;
|
||||
solock(so);
|
||||
if (so->so_state & SS_ISCONFIRMING && resid)
|
||||
(*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL, NULL);
|
||||
|
||||
restart:
|
||||
if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
|
||||
return (error);
|
||||
s = splsoftnet();
|
||||
|
||||
m = so->so_rcv.sb_mb;
|
||||
/*
|
||||
* If we have less data than requested, block awaiting more
|
||||
|
@ -439,9 +433,10 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
}
|
||||
sbunlock(&so->so_rcv);
|
||||
error = sbwait(&so->so_rcv);
|
||||
splx(s);
|
||||
if (error)
|
||||
if (error) {
|
||||
sounlock(so);
|
||||
return (error);
|
||||
}
|
||||
goto restart;
|
||||
}
|
||||
dontblock:
|
||||
|
@ -581,8 +576,11 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
if (flags & MSG_PEEK)
|
||||
moff += len;
|
||||
else {
|
||||
if (mp)
|
||||
if (mp) {
|
||||
sounlock(so);
|
||||
*mp = m_copym(m, 0, len, M_WAIT);
|
||||
solock(so);
|
||||
}
|
||||
m->m_data += len;
|
||||
m->m_len -= len;
|
||||
so->so_rcv.sb_cc -= len;
|
||||
|
@ -635,7 +633,7 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
error = sbwait(&so->so_rcv);
|
||||
if (error) {
|
||||
sbunlock(&so->so_rcv);
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
return (0);
|
||||
}
|
||||
if ((m = so->so_rcv.sb_mb) != NULL)
|
||||
|
@ -671,7 +669,6 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
if (orig_resid == resid && orig_resid &&
|
||||
(flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
|
||||
sbunlock(&so->so_rcv);
|
||||
splx(s);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
|
@ -679,7 +676,7 @@ kttcp_soreceive(struct socket *so, unsigned long long slen,
|
|||
*flagsp |= flags;
|
||||
release:
|
||||
sbunlock(&so->so_rcv);
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
*done = slen - resid;
|
||||
#if 0
|
||||
printf("soreceive: error %d slen %llu resid %lld\n", error, slen, resid);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_softint.c,v 1.15 2008/04/12 18:22:03 ad Exp $ */
|
||||
/* $NetBSD: kern_softint.c,v 1.16 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -183,7 +183,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.15 2008/04/12 18:22:03 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.16 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
|
@ -324,8 +324,8 @@ softint_init(struct cpu_info *ci)
|
|||
* XXX Needs to go away.
|
||||
*/
|
||||
#define DONETISR(n, f) \
|
||||
softint_netisrs[(n)] = \
|
||||
softint_establish(SOFTINT_NET, (void (*)(void *))(f), NULL)
|
||||
softint_netisrs[(n)] = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE,\
|
||||
(void (*)(void *))(f), NULL)
|
||||
#include <net/netisr_dispatch.h>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr_pool.c,v 1.156 2008/03/27 18:30:15 ad Exp $ */
|
||||
/* $NetBSD: subr_pool.c,v 1.157 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1999, 2000, 2002, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -38,7 +38,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.156 2008/03/27 18:30:15 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.157 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_pool.h"
|
||||
|
@ -814,14 +814,7 @@ pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags,
|
|||
pp->pr_entered_file = NULL;
|
||||
pp->pr_entered_line = 0;
|
||||
|
||||
/*
|
||||
* XXXAD hack to prevent IP input processing from blocking.
|
||||
*/
|
||||
if (ipl == IPL_SOFTNET) {
|
||||
mutex_init(&pp->pr_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
} else {
|
||||
mutex_init(&pp->pr_lock, MUTEX_DEFAULT, ipl);
|
||||
}
|
||||
mutex_init(&pp->pr_lock, MUTEX_DEFAULT, ipl);
|
||||
cv_init(&pp->pr_cv, wchan);
|
||||
pp->pr_ipl = ipl;
|
||||
|
||||
|
@ -1629,9 +1622,8 @@ pool_reclaim(struct pool *pp)
|
|||
}
|
||||
|
||||
/*
|
||||
* XXXSMP Because mutexes at IPL_SOFTXXX are still spinlocks,
|
||||
* and we are called from the pagedaemon without kernel_lock.
|
||||
* Does not apply to IPL_SOFTBIO.
|
||||
* XXXSMP Because we do not want to cause non-MPSAFE code
|
||||
* to block.
|
||||
*/
|
||||
if (pp->pr_ipl == IPL_SOFTNET || pp->pr_ipl == IPL_SOFTCLOCK ||
|
||||
pp->pr_ipl == IPL_SOFTSERIAL) {
|
||||
|
@ -2074,15 +2066,7 @@ pool_cache_bootstrap(pool_cache_t pc, size_t size, u_int align,
|
|||
if (palloc == NULL && ipl == IPL_NONE)
|
||||
palloc = &pool_allocator_nointr;
|
||||
pool_init(pp, size, align, align_offset, flags, wchan, palloc, ipl);
|
||||
|
||||
/*
|
||||
* XXXAD hack to prevent IP input processing from blocking.
|
||||
*/
|
||||
if (ipl == IPL_SOFTNET) {
|
||||
mutex_init(&pc->pc_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
} else {
|
||||
mutex_init(&pc->pc_lock, MUTEX_DEFAULT, ipl);
|
||||
}
|
||||
mutex_init(&pc->pc_lock, MUTEX_DEFAULT, ipl);
|
||||
|
||||
if (ctor == NULL) {
|
||||
ctor = (int (*)(void *, void *, int))nullop;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: subr_tftproot.c,v 1.4 2008/04/04 20:13:18 cegger Exp $ */
|
||||
/* $NetBSD: subr_tftproot.c,v 1.5 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 Emmanuel Dreyfus, all rights reserved.
|
||||
|
@ -39,7 +39,7 @@
|
|||
#include "opt_md.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_tftproot.c,v 1.4 2008/04/04 20:13:18 cegger Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: subr_tftproot.c,v 1.5 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -215,7 +215,7 @@ tftproot_getfile(trh, l)
|
|||
char *cp;
|
||||
/* struct device *dv; */
|
||||
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, l)) != 0) {
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, l, NULL)) != 0) {
|
||||
DPRINTF(("%s():%d socreate returned %d\n",
|
||||
__func__, __LINE__, error));
|
||||
goto out;
|
||||
|
|
|
@ -1,4 +1,37 @@
|
|||
/* $NetBSD: sys_socket.c,v 1.55 2008/03/21 21:55:00 ad Exp $ */
|
||||
/* $NetBSD: sys_socket.c,v 1.56 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1990, 1993
|
||||
|
@ -32,7 +65,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.55 2008/03/21 21:55:00 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sys_socket.c,v 1.56 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -64,10 +97,8 @@ soo_read(file_t *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||
struct socket *so = fp->f_data;
|
||||
int error;
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
error = (*so->so_receive)(so, (struct mbuf **)0,
|
||||
uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -80,10 +111,8 @@ soo_write(file_t *fp, off_t *offset, struct uio *uio, kauth_cred_t cred,
|
|||
struct socket *so = fp->f_data;
|
||||
int error;
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
error = (*so->so_send)(so, (struct mbuf *)0,
|
||||
uio, (struct mbuf *)0, (struct mbuf *)0, 0, curlwp);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -99,11 +128,10 @@ soo_ioctl(file_t *fp, u_long cmd, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case FIOASYNC:
|
||||
solock(so);
|
||||
if (*(int *)data) {
|
||||
so->so_state |= SS_ASYNC;
|
||||
so->so_rcv.sb_flags |= SB_ASYNC;
|
||||
|
@ -113,6 +141,7 @@ soo_ioctl(file_t *fp, u_long cmd, void *data)
|
|||
so->so_rcv.sb_flags &= ~SB_ASYNC;
|
||||
so->so_snd.sb_flags &= ~SB_ASYNC;
|
||||
}
|
||||
sounlock(so);
|
||||
break;
|
||||
|
||||
case FIONREAD:
|
||||
|
@ -130,11 +159,13 @@ soo_ioctl(file_t *fp, u_long cmd, void *data)
|
|||
* to understand the following test. We detect overflow
|
||||
* and return zero.
|
||||
*/
|
||||
solock(so);
|
||||
if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc)
|
||||
|| (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt))
|
||||
*(int *)data = 0;
|
||||
else
|
||||
*(int *)data = sbspace(&so->so_snd);
|
||||
sounlock(so);
|
||||
break;
|
||||
|
||||
case SIOCSPGRP:
|
||||
|
@ -159,18 +190,22 @@ soo_ioctl(file_t *fp, u_long cmd, void *data)
|
|||
* interface and routing ioctls should have a
|
||||
* different entry since a socket's unnecessary
|
||||
*/
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if (IOCGROUP(cmd) == 'i')
|
||||
error = ifioctl(so, cmd, data, curlwp);
|
||||
else if (IOCGROUP(cmd) == 'r')
|
||||
error = rtioctl(cmd, data, curlwp);
|
||||
else
|
||||
else {
|
||||
solock(so);
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
|
||||
(struct mbuf *)cmd, (struct mbuf *)data, NULL,
|
||||
curlwp);
|
||||
sounlock(so);
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -201,11 +236,11 @@ soo_stat(file_t *fp, struct stat *ub)
|
|||
memset((void *)ub, 0, sizeof(*ub));
|
||||
ub->st_mode = S_IFSOCK;
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
solock(so);
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SENSE,
|
||||
(struct mbuf *)ub, (struct mbuf *)0, (struct mbuf *)0,
|
||||
curlwp);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
sounlock(so);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
@ -216,11 +251,9 @@ soo_close(file_t *fp)
|
|||
{
|
||||
int error = 0;
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if (fp->f_data)
|
||||
error = soclose(fp->f_data);
|
||||
fp->f_data = 0;
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uipc_domain.c,v 1.75 2008/03/21 21:55:00 ad Exp $ */
|
||||
/* $NetBSD: uipc_domain.c,v 1.76 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.75 2008/03/21 21:55:00 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.76 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -93,8 +93,8 @@ domaininit(void)
|
|||
if (rt_domain)
|
||||
domain_attach(rt_domain);
|
||||
|
||||
callout_init(&pffasttimo_ch, 0);
|
||||
callout_init(&pfslowtimo_ch, 0);
|
||||
callout_init(&pffasttimo_ch, CALLOUT_MPSAFE);
|
||||
callout_init(&pfslowtimo_ch, CALLOUT_MPSAFE);
|
||||
|
||||
callout_reset(&pffasttimo_ch, 1, pffasttimo, NULL);
|
||||
callout_reset(&pfslowtimo_ch, 1, pfslowtimo, NULL);
|
||||
|
@ -563,7 +563,7 @@ pfslowtimo(void *arg)
|
|||
if (pr->pr_slowtimo)
|
||||
(*pr->pr_slowtimo)();
|
||||
}
|
||||
callout_reset(&pfslowtimo_ch, hz / 2, pfslowtimo, NULL);
|
||||
callout_schedule(&pfslowtimo_ch, hz / 2);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -579,5 +579,5 @@ pffasttimo(void *arg)
|
|||
if (pr->pr_fasttimo)
|
||||
(*pr->pr_fasttimo)();
|
||||
}
|
||||
callout_reset(&pffasttimo_ch, hz / 5, pffasttimo, NULL);
|
||||
callout_schedule(&pffasttimo_ch, hz / 5);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uipc_proto.c,v 1.20 2007/02/18 23:16:59 matt Exp $ */
|
||||
/* $NetBSD: uipc_proto.c,v 1.21 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_proto.c,v 1.20 2007/02/18 23:16:59 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_proto.c,v 1.21 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -74,6 +74,7 @@ const struct protosw unixsw[] = {
|
|||
|
||||
struct domain unixdomain = {
|
||||
.dom_family = AF_LOCAL,
|
||||
.dom_init = uipc_init,
|
||||
.dom_name = "unix",
|
||||
.dom_externalize = unp_externalize,
|
||||
.dom_dispose = unp_dispose,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uipc_socket.c,v 1.159 2008/04/14 15:42:20 ad Exp $ */
|
||||
/* $NetBSD: uipc_socket.c,v 1.160 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002, 2007, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -70,7 +70,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.159 2008/04/14 15:42:20 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.160 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include "opt_sock_counters.h"
|
||||
#include "opt_sosend_loan.h"
|
||||
|
@ -91,7 +91,6 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.159 2008/04/14 15:42:20 ad Exp $")
|
|||
#include <sys/socketvar.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/pool.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/kauth.h>
|
||||
|
@ -100,9 +99,6 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.159 2008/04/14 15:42:20 ad Exp $")
|
|||
|
||||
#include <uvm/uvm.h>
|
||||
|
||||
POOL_INIT(socket_pool, sizeof(struct socket), 0, 0, 0, "sockpl", NULL,
|
||||
IPL_SOFTNET);
|
||||
|
||||
MALLOC_DEFINE(M_SOOPTS, "soopts", "socket options");
|
||||
MALLOC_DEFINE(M_SONAME, "soname", "socket name");
|
||||
|
||||
|
@ -110,6 +106,7 @@ extern const struct fileops socketops;
|
|||
|
||||
extern int somaxconn; /* patchable (XXX sysctl) */
|
||||
int somaxconn = SOMAXCONN;
|
||||
kmutex_t *softnet_lock;
|
||||
|
||||
#ifdef SOSEND_COUNTERS
|
||||
#include <sys/device.h>
|
||||
|
@ -277,6 +274,9 @@ sodopendfree(void)
|
|||
{
|
||||
size_t rv;
|
||||
|
||||
if (__predict_true(so_pendfree == NULL))
|
||||
return 0;
|
||||
|
||||
mutex_enter(&so_pendfree_lock);
|
||||
rv = sodopendfreel();
|
||||
mutex_exit(&so_pendfree_lock);
|
||||
|
@ -365,7 +365,6 @@ sosend_loan(struct socket *so, struct uio *uio, struct mbuf *m, long space)
|
|||
len = eva - sva;
|
||||
npgs = len >> PAGE_SHIFT;
|
||||
|
||||
/* XXX KDASSERT */
|
||||
KASSERT(npgs <= M_EXT_MAXPAGES);
|
||||
|
||||
lva = sokvaalloc(len, so);
|
||||
|
@ -441,6 +440,7 @@ soinit(void)
|
|||
{
|
||||
|
||||
mutex_init(&so_pendfree_lock, MUTEX_DEFAULT, IPL_VM);
|
||||
softnet_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
|
||||
cv_init(&socurkva_cv, "sokva");
|
||||
|
||||
/* Set the initial adjusted socket buffer size. */
|
||||
|
@ -460,12 +460,14 @@ soinit(void)
|
|||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l)
|
||||
socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l,
|
||||
struct socket *lockso)
|
||||
{
|
||||
const struct protosw *prp;
|
||||
struct socket *so;
|
||||
uid_t uid;
|
||||
int error, s;
|
||||
int error;
|
||||
kmutex_t *lock;
|
||||
|
||||
error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_SOCKET,
|
||||
KAUTH_REQ_NETWORK_SOCKET_OPEN, KAUTH_ARG(dom), KAUTH_ARG(type),
|
||||
|
@ -490,11 +492,8 @@ socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l)
|
|||
return EPROTONOSUPPORT;
|
||||
if (prp->pr_type != type)
|
||||
return EPROTOTYPE;
|
||||
s = splsoftnet();
|
||||
so = pool_get(&socket_pool, PR_WAITOK);
|
||||
memset(so, 0, sizeof(*so));
|
||||
TAILQ_INIT(&so->so_q0);
|
||||
TAILQ_INIT(&so->so_q);
|
||||
|
||||
so = soget(true);
|
||||
so->so_type = type;
|
||||
so->so_proto = prp;
|
||||
so->so_send = sosend;
|
||||
|
@ -504,19 +503,26 @@ socreate(int dom, struct socket **aso, int type, int proto, struct lwp *l)
|
|||
so->so_snd.sb_mowner = &prp->pr_domain->dom_mowner;
|
||||
so->so_mowner = &prp->pr_domain->dom_mowner;
|
||||
#endif
|
||||
selinit(&so->so_rcv.sb_sel);
|
||||
selinit(&so->so_snd.sb_sel);
|
||||
uid = kauth_cred_geteuid(l->l_cred);
|
||||
so->so_uidinfo = uid_find(uid);
|
||||
if (lockso != NULL) {
|
||||
/* Caller wants us to share a lock. */
|
||||
lock = lockso->so_lock;
|
||||
so->so_lock = lock;
|
||||
mutex_obj_hold(lock);
|
||||
mutex_enter(lock);
|
||||
} else {
|
||||
/* Lock assigned and taken during PRU_ATTACH. */
|
||||
}
|
||||
error = (*prp->pr_usrreq)(so, PRU_ATTACH, NULL,
|
||||
(struct mbuf *)(long)proto, NULL, l);
|
||||
KASSERT(solocked(so));
|
||||
if (error != 0) {
|
||||
so->so_state |= SS_NOFDREF;
|
||||
sofree(so);
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
*aso = so;
|
||||
return 0;
|
||||
}
|
||||
|
@ -537,7 +543,7 @@ fsocreate(int domain, struct socket **sop, int type, int protocol,
|
|||
fp->f_flag = FREAD|FWRITE;
|
||||
fp->f_type = DTYPE_SOCKET;
|
||||
fp->f_ops = &socketops;
|
||||
error = socreate(domain, &so, type, protocol, l);
|
||||
error = socreate(domain, &so, type, protocol, l, NULL);
|
||||
if (error != 0) {
|
||||
fd_abort(curproc, fp, fd);
|
||||
} else {
|
||||
|
@ -553,27 +559,27 @@ fsocreate(int domain, struct socket **sop, int type, int protocol,
|
|||
int
|
||||
sobind(struct socket *so, struct mbuf *nam, struct lwp *l)
|
||||
{
|
||||
int s, error;
|
||||
int error;
|
||||
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, NULL, nam, NULL, l);
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
solisten(struct socket *so, int backlog, struct lwp *l)
|
||||
{
|
||||
int s, error;
|
||||
int error;
|
||||
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
if ((so->so_state & (SS_ISCONNECTED | SS_ISCONNECTING |
|
||||
SS_ISDISCONNECTING)) != 0)
|
||||
return (EOPNOTSUPP);
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL,
|
||||
NULL, NULL, l);
|
||||
if (error != 0) {
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
return error;
|
||||
}
|
||||
if (TAILQ_EMPTY(&so->so_q))
|
||||
|
@ -581,7 +587,7 @@ solisten(struct socket *so, int backlog, struct lwp *l)
|
|||
if (backlog < 0)
|
||||
backlog = 0;
|
||||
so->so_qlimit = min(backlog, somaxconn);
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -589,16 +595,22 @@ void
|
|||
sofree(struct socket *so)
|
||||
{
|
||||
|
||||
if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0)
|
||||
KASSERT(solocked(so));
|
||||
|
||||
if (so->so_pcb || (so->so_state & SS_NOFDREF) == 0) {
|
||||
sounlock(so);
|
||||
return;
|
||||
}
|
||||
if (so->so_head) {
|
||||
/*
|
||||
* We must not decommission a socket that's on the accept(2)
|
||||
* queue. If we do, then accept(2) may hang after select(2)
|
||||
* indicated that the listening socket was ready.
|
||||
*/
|
||||
if (!soqremque(so, 0))
|
||||
if (!soqremque(so, 0)) {
|
||||
sounlock(so);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (so->so_rcv.sb_hiwat)
|
||||
(void)chgsbsize(so->so_uidinfo, &so->so_rcv.sb_hiwat, 0,
|
||||
|
@ -607,10 +619,12 @@ sofree(struct socket *so)
|
|||
(void)chgsbsize(so->so_uidinfo, &so->so_snd.sb_hiwat, 0,
|
||||
RLIM_INFINITY);
|
||||
sbrelease(&so->so_snd, so);
|
||||
KASSERT(!cv_has_waiters(&so->so_cv));
|
||||
KASSERT(!cv_has_waiters(&so->so_rcv.sb_cv));
|
||||
KASSERT(!cv_has_waiters(&so->so_snd.sb_cv));
|
||||
sorflush(so);
|
||||
seldestroy(&so->so_rcv.sb_sel);
|
||||
seldestroy(&so->so_snd.sb_sel);
|
||||
pool_put(&socket_pool, so);
|
||||
sounlock(so);
|
||||
soput(so);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -622,19 +636,30 @@ int
|
|||
soclose(struct socket *so)
|
||||
{
|
||||
struct socket *so2;
|
||||
int s, error;
|
||||
int error;
|
||||
int error2;
|
||||
|
||||
error = 0;
|
||||
s = splsoftnet(); /* conservative */
|
||||
solock(so);
|
||||
if (so->so_options & SO_ACCEPTCONN) {
|
||||
while ((so2 = TAILQ_FIRST(&so->so_q0)) != 0) {
|
||||
(void) soqremque(so2, 0);
|
||||
(void) soabort(so2);
|
||||
}
|
||||
while ((so2 = TAILQ_FIRST(&so->so_q)) != 0) {
|
||||
(void) soqremque(so2, 1);
|
||||
(void) soabort(so2);
|
||||
}
|
||||
do {
|
||||
if ((so2 = TAILQ_FIRST(&so->so_q0)) != 0) {
|
||||
KASSERT(solocked2(so, so2));
|
||||
(void) soqremque(so2, 0);
|
||||
/* soabort drops the lock. */
|
||||
(void) soabort(so2);
|
||||
solock(so);
|
||||
continue;
|
||||
}
|
||||
if ((so2 = TAILQ_FIRST(&so->so_q)) != 0) {
|
||||
KASSERT(solocked2(so, so2));
|
||||
(void) soqremque(so2, 1);
|
||||
/* soabort drops the lock. */
|
||||
(void) soabort(so2);
|
||||
solock(so);
|
||||
continue;
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
if (so->so_pcb == 0)
|
||||
goto discard;
|
||||
|
@ -648,9 +673,7 @@ soclose(struct socket *so)
|
|||
if ((so->so_state & SS_ISDISCONNECTING) && so->so_nbio)
|
||||
goto drop;
|
||||
while (so->so_state & SS_ISCONNECTED) {
|
||||
error = tsleep((void *)&so->so_timeo,
|
||||
PSOCK | PCATCH, netcls,
|
||||
so->so_linger * hz);
|
||||
error = sowait(so, so->so_linger * hz);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
|
@ -658,7 +681,7 @@ soclose(struct socket *so)
|
|||
}
|
||||
drop:
|
||||
if (so->so_pcb) {
|
||||
int error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
|
||||
error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH,
|
||||
NULL, NULL, NULL, NULL);
|
||||
if (error == 0)
|
||||
error = error2;
|
||||
|
@ -668,23 +691,26 @@ soclose(struct socket *so)
|
|||
panic("soclose: NOFDREF");
|
||||
so->so_state |= SS_NOFDREF;
|
||||
sofree(so);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Must be called at splsoftnet...
|
||||
* Must be called with the socket locked.. Will return with it unlocked.
|
||||
*/
|
||||
int
|
||||
soabort(struct socket *so)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
||||
KASSERT(solocked(so));
|
||||
KASSERT(so->so_head == NULL);
|
||||
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_ABORT, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (error) {
|
||||
sofree(so);
|
||||
} else {
|
||||
sounlock(so);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
@ -692,10 +718,11 @@ soabort(struct socket *so)
|
|||
int
|
||||
soaccept(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
int s, error;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
error = 0;
|
||||
s = splsoftnet();
|
||||
if ((so->so_state & SS_NOFDREF) == 0)
|
||||
panic("soaccept: !NOFDREF");
|
||||
so->so_state &= ~SS_NOFDREF;
|
||||
|
@ -706,18 +733,18 @@ soaccept(struct socket *so, struct mbuf *nam)
|
|||
else
|
||||
error = ECONNABORTED;
|
||||
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
soconnect(struct socket *so, struct mbuf *nam, struct lwp *l)
|
||||
{
|
||||
int s, error;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
if (so->so_options & SO_ACCEPTCONN)
|
||||
return (EOPNOTSUPP);
|
||||
s = splsoftnet();
|
||||
/*
|
||||
* If protocol is connection-based, can only connect once.
|
||||
* Otherwise, if connected, try to disconnect first.
|
||||
|
@ -731,40 +758,36 @@ soconnect(struct socket *so, struct mbuf *nam, struct lwp *l)
|
|||
else
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
|
||||
NULL, nam, NULL, l);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
soconnect2(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
int s, error;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked2(so1, so2));
|
||||
|
||||
s = splsoftnet();
|
||||
error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2,
|
||||
NULL, (struct mbuf *)so2, NULL, NULL);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
sodisconnect(struct socket *so)
|
||||
{
|
||||
int s, error;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
s = splsoftnet();
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0) {
|
||||
error = ENOTCONN;
|
||||
goto bad;
|
||||
}
|
||||
if (so->so_state & SS_ISDISCONNECTING) {
|
||||
} else if (so->so_state & SS_ISDISCONNECTING) {
|
||||
error = EALREADY;
|
||||
goto bad;
|
||||
} else {
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
|
||||
NULL, NULL, NULL, NULL);
|
||||
}
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT,
|
||||
NULL, NULL, NULL, NULL);
|
||||
bad:
|
||||
splx(s);
|
||||
sodopendfree();
|
||||
return (error);
|
||||
}
|
||||
|
@ -798,8 +821,15 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
|
|||
|
||||
p = l->l_proc;
|
||||
sodopendfree();
|
||||
|
||||
clen = 0;
|
||||
|
||||
/*
|
||||
* solock() provides atomicity of access. splsoftnet() prevents
|
||||
* protocol processing soft interrupts from interrupting us and
|
||||
* blocking (expensive).
|
||||
*/
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
atomic = sosendallatonce(so) || top;
|
||||
if (uio)
|
||||
resid = uio->uio_resid;
|
||||
|
@ -823,47 +853,51 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
|
|||
l->l_ru.ru_msgsnd++;
|
||||
if (control)
|
||||
clen = control->m_len;
|
||||
#define snderr(errno) { error = errno; splx(s); goto release; }
|
||||
|
||||
restart:
|
||||
if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0)
|
||||
goto out;
|
||||
do {
|
||||
s = splsoftnet();
|
||||
if (so->so_state & SS_CANTSENDMORE)
|
||||
snderr(EPIPE);
|
||||
if (so->so_state & SS_CANTSENDMORE) {
|
||||
error = EPIPE;
|
||||
goto release;
|
||||
}
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
splx(s);
|
||||
goto release;
|
||||
}
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0) {
|
||||
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
|
||||
if ((so->so_state & SS_ISCONFIRMING) == 0 &&
|
||||
!(resid == 0 && clen != 0))
|
||||
snderr(ENOTCONN);
|
||||
} else if (addr == 0)
|
||||
snderr(EDESTADDRREQ);
|
||||
!(resid == 0 && clen != 0)) {
|
||||
error = ENOTCONN;
|
||||
goto release;
|
||||
}
|
||||
} else if (addr == 0) {
|
||||
error = EDESTADDRREQ;
|
||||
goto release;
|
||||
}
|
||||
}
|
||||
space = sbspace(&so->so_snd);
|
||||
if (flags & MSG_OOB)
|
||||
space += 1024;
|
||||
if ((atomic && resid > so->so_snd.sb_hiwat) ||
|
||||
clen > so->so_snd.sb_hiwat)
|
||||
snderr(EMSGSIZE);
|
||||
clen > so->so_snd.sb_hiwat) {
|
||||
error = EMSGSIZE;
|
||||
goto release;
|
||||
}
|
||||
if (space < resid + clen &&
|
||||
(atomic || space < so->so_snd.sb_lowat || space < clen)) {
|
||||
if (so->so_nbio)
|
||||
snderr(EWOULDBLOCK);
|
||||
if (so->so_nbio) {
|
||||
error = EWOULDBLOCK;
|
||||
goto release;
|
||||
}
|
||||
sbunlock(&so->so_snd);
|
||||
error = sbwait(&so->so_snd);
|
||||
splx(s);
|
||||
if (error)
|
||||
goto out;
|
||||
goto restart;
|
||||
}
|
||||
splx(s);
|
||||
mp = ⊤
|
||||
space -= clen;
|
||||
do {
|
||||
|
@ -875,6 +909,8 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
|
|||
if (flags & MSG_EOR)
|
||||
top->m_flags |= M_EOR;
|
||||
} else do {
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
if (top == NULL) {
|
||||
m = m_gethdr(M_WAIT, MT_DATA);
|
||||
mlen = MHLEN;
|
||||
|
@ -925,6 +961,8 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
|
|||
m->m_len = len;
|
||||
*mp = m;
|
||||
top->m_pkthdr.len += len;
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
if (error != 0)
|
||||
goto release;
|
||||
mp = &m->m_next;
|
||||
|
@ -935,24 +973,21 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
|
|||
}
|
||||
} while (space > 0 && atomic);
|
||||
|
||||
s = splsoftnet();
|
||||
|
||||
if (so->so_state & SS_CANTSENDMORE)
|
||||
snderr(EPIPE);
|
||||
|
||||
if (so->so_state & SS_CANTSENDMORE) {
|
||||
error = EPIPE;
|
||||
goto release;
|
||||
}
|
||||
if (dontroute)
|
||||
so->so_options |= SO_DONTROUTE;
|
||||
if (resid > 0)
|
||||
so->so_state |= SS_MORETOCOME;
|
||||
error = (*so->so_proto->pr_usrreq)(so,
|
||||
(flags & MSG_OOB) ? PRU_SENDOOB : PRU_SEND,
|
||||
top, addr, control, curlwp); /* XXX */
|
||||
top, addr, control, curlwp);
|
||||
if (dontroute)
|
||||
so->so_options &= ~SO_DONTROUTE;
|
||||
if (resid > 0)
|
||||
so->so_state &= ~SS_MORETOCOME;
|
||||
splx(s);
|
||||
|
||||
clen = 0;
|
||||
control = NULL;
|
||||
top = NULL;
|
||||
|
@ -965,6 +1000,8 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top,
|
|||
release:
|
||||
sbunlock(&so->so_snd);
|
||||
out:
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
if (top)
|
||||
m_freem(top);
|
||||
if (control)
|
||||
|
@ -984,6 +1021,8 @@ static void
|
|||
sbsync(struct sockbuf *sb, struct mbuf *nextrecord)
|
||||
{
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
/*
|
||||
* First, update for the new value of nextrecord. If necessary,
|
||||
* make it the first record.
|
||||
|
@ -1028,7 +1067,7 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
|
||||
{
|
||||
struct lwp *l = curlwp;
|
||||
struct mbuf *m, **mp;
|
||||
struct mbuf *m, **mp, *mt;
|
||||
int atomic, flags, len, error, s, offset, moff, type, orig_resid;
|
||||
const struct protosw *pr;
|
||||
struct mbuf *nextrecord;
|
||||
|
@ -1056,8 +1095,10 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
|
||||
if (flags & MSG_OOB) {
|
||||
m = m_get(M_WAIT, MT_DATA);
|
||||
solock(so);
|
||||
error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
|
||||
(struct mbuf *)(long)(flags & MSG_PEEK), NULL, l);
|
||||
sounlock(so);
|
||||
if (error)
|
||||
goto bad;
|
||||
do {
|
||||
|
@ -1072,13 +1113,23 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
}
|
||||
if (mp != NULL)
|
||||
*mp = NULL;
|
||||
|
||||
/*
|
||||
* solock() provides atomicity of access. splsoftnet() prevents
|
||||
* protocol processing soft interrupts from interrupting us and
|
||||
* blocking (expensive).
|
||||
*/
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
|
||||
(*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL, l);
|
||||
|
||||
restart:
|
||||
if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0)
|
||||
if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0) {
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
return error;
|
||||
s = splsoftnet();
|
||||
}
|
||||
|
||||
m = so->so_rcv.sb_mb;
|
||||
/*
|
||||
|
@ -1137,9 +1188,11 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1");
|
||||
sbunlock(&so->so_rcv);
|
||||
error = sbwait(&so->so_rcv);
|
||||
splx(s);
|
||||
if (error != 0)
|
||||
if (error != 0) {
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
goto restart;
|
||||
}
|
||||
dontblock:
|
||||
|
@ -1149,7 +1202,7 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
* pointer to the next record in the socket buffer. We must keep the
|
||||
* various socket buffer pointers and local stack versions of the
|
||||
* pointers in sync, pushing out modifications before dropping the
|
||||
* IPL, and re-reading them when picking it up.
|
||||
* socket lock, and re-reading them when picking it up.
|
||||
*
|
||||
* Otherwise, we will race with the network stack appending new data
|
||||
* or records onto the socket buffer by using inconsistent/stale
|
||||
|
@ -1226,9 +1279,11 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
if (controlp != NULL) {
|
||||
if (dom->dom_externalize != NULL &&
|
||||
type == SCM_RIGHTS) {
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
error = (*dom->dom_externalize)(cm, l);
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
}
|
||||
*controlp = cm;
|
||||
while (*controlp != NULL)
|
||||
|
@ -1240,9 +1295,9 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
*/
|
||||
if (dom->dom_dispose != NULL &&
|
||||
type == SCM_RIGHTS) {
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
(*dom->dom_dispose)(cm);
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
}
|
||||
m_freem(cm);
|
||||
}
|
||||
|
@ -1292,9 +1347,11 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
if (mp == NULL) {
|
||||
SBLASTRECORDCHK(&so->so_rcv, "soreceive uiomove");
|
||||
SBLASTMBUFCHK(&so->so_rcv, "soreceive uiomove");
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
error = uiomove(mtod(m, char *) + moff, (int)len, uio);
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
if (error != 0) {
|
||||
/*
|
||||
* If any part of the record has been removed
|
||||
|
@ -1351,8 +1408,15 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
} else if (flags & MSG_PEEK)
|
||||
moff += len;
|
||||
else {
|
||||
if (mp != NULL)
|
||||
*mp = m_copym(m, 0, len, M_WAIT);
|
||||
if (mp != NULL) {
|
||||
mt = m_copym(m, 0, len, M_NOWAIT);
|
||||
if (__predict_false(mt == NULL)) {
|
||||
sounlock(so);
|
||||
mt = m_copym(m, 0, len, M_WAIT);
|
||||
solock(so);
|
||||
}
|
||||
*mp = mt;
|
||||
}
|
||||
m->m_data += len;
|
||||
m->m_len -= len;
|
||||
so->so_rcv.sb_cc -= len;
|
||||
|
@ -1402,6 +1466,7 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
error = sbwait(&so->so_rcv);
|
||||
if (error != 0) {
|
||||
sbunlock(&so->so_rcv);
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1438,7 +1503,6 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
if (orig_resid == uio->uio_resid && orig_resid &&
|
||||
(flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
|
||||
sbunlock(&so->so_rcv);
|
||||
splx(s);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
|
@ -1446,6 +1510,7 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
|
|||
*flagsp |= flags;
|
||||
release:
|
||||
sbunlock(&so->so_rcv);
|
||||
sounlock(so);
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
|
@ -1454,17 +1519,23 @@ int
|
|||
soshutdown(struct socket *so, int how)
|
||||
{
|
||||
const struct protosw *pr;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
pr = so->so_proto;
|
||||
if (!(how == SHUT_RD || how == SHUT_WR || how == SHUT_RDWR))
|
||||
return (EINVAL);
|
||||
|
||||
if (how == SHUT_RD || how == SHUT_RDWR)
|
||||
if (how == SHUT_RD || how == SHUT_RDWR) {
|
||||
sorflush(so);
|
||||
error = 0;
|
||||
}
|
||||
if (how == SHUT_WR || how == SHUT_RDWR)
|
||||
return (*pr->pr_usrreq)(so, PRU_SHUTDOWN, NULL,
|
||||
error = (*pr->pr_usrreq)(so, PRU_SHUTDOWN, NULL,
|
||||
NULL, NULL, NULL);
|
||||
return 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1472,14 +1543,14 @@ sorflush(struct socket *so)
|
|||
{
|
||||
struct sockbuf *sb, asb;
|
||||
const struct protosw *pr;
|
||||
int s;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
sb = &so->so_rcv;
|
||||
pr = so->so_proto;
|
||||
sb->sb_flags |= SB_NOINTR;
|
||||
(void) sblock(sb, M_WAITOK);
|
||||
s = splnet();
|
||||
socantrcvmore(so);
|
||||
sb->sb_flags |= SB_NOINTR;
|
||||
(void )sblock(sb, M_WAITOK);
|
||||
sbunlock(sb);
|
||||
asb = *sb;
|
||||
/*
|
||||
|
@ -1488,9 +1559,11 @@ sorflush(struct socket *so)
|
|||
*/
|
||||
memset(&sb->sb_startzero, 0,
|
||||
sizeof(*sb) - offsetof(struct sockbuf, sb_startzero));
|
||||
splx(s);
|
||||
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose)
|
||||
if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) {
|
||||
sounlock(so);
|
||||
(*pr->pr_domain->dom_dispose)(asb.sb_mb);
|
||||
solock(so);
|
||||
}
|
||||
sbrelease(&asb, so);
|
||||
}
|
||||
|
||||
|
@ -1611,6 +1684,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
{
|
||||
int error, prerr;
|
||||
|
||||
solock(so);
|
||||
if (level == SOL_SOCKET)
|
||||
error = sosetopt1(so, level, optname, m);
|
||||
else
|
||||
|
@ -1627,6 +1701,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
|
|||
error = prerr;
|
||||
} else if (m != NULL)
|
||||
(void)m_free(m);
|
||||
sounlock(so);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1634,13 +1709,15 @@ int
|
|||
sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int error;
|
||||
|
||||
solock(so);
|
||||
if (level != SOL_SOCKET) {
|
||||
if (so->so_proto && so->so_proto->pr_ctloutput) {
|
||||
return ((*so->so_proto->pr_ctloutput)
|
||||
error = ((*so->so_proto->pr_ctloutput)
|
||||
(PRCO_GETOPT, so, level, optname, mp));
|
||||
} else
|
||||
return (ENOPROTOOPT);
|
||||
error = (ENOPROTOOPT);
|
||||
} else {
|
||||
m = m_get(M_WAIT, MT_SOOPTS);
|
||||
m->m_len = sizeof(int);
|
||||
|
@ -1709,12 +1786,16 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
|
|||
break;
|
||||
|
||||
default:
|
||||
sounlock(so);
|
||||
(void)m_free(m);
|
||||
return (ENOPROTOOPT);
|
||||
}
|
||||
*mp = m;
|
||||
return (0);
|
||||
error = 0;
|
||||
}
|
||||
|
||||
sounlock(so);
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1731,9 +1812,11 @@ filt_sordetach(struct knote *kn)
|
|||
struct socket *so;
|
||||
|
||||
so = ((file_t *)kn->kn_obj)->f_data;
|
||||
solock(so);
|
||||
SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
|
||||
if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
|
||||
so->so_rcv.sb_flags &= ~SB_KNOTE;
|
||||
sounlock(so);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
|
@ -1741,19 +1824,25 @@ static int
|
|||
filt_soread(struct knote *kn, long hint)
|
||||
{
|
||||
struct socket *so;
|
||||
int rv;
|
||||
|
||||
so = ((file_t *)kn->kn_obj)->f_data;
|
||||
if (hint != NOTE_SUBMIT)
|
||||
solock(so);
|
||||
kn->kn_data = so->so_rcv.sb_cc;
|
||||
if (so->so_state & SS_CANTRCVMORE) {
|
||||
kn->kn_flags |= EV_EOF;
|
||||
kn->kn_fflags = so->so_error;
|
||||
return (1);
|
||||
}
|
||||
if (so->so_error) /* temporary udp error */
|
||||
return (1);
|
||||
if (kn->kn_sfflags & NOTE_LOWAT)
|
||||
return (kn->kn_data >= kn->kn_sdata);
|
||||
return (kn->kn_data >= so->so_rcv.sb_lowat);
|
||||
rv = 1;
|
||||
} else if (so->so_error) /* temporary udp error */
|
||||
rv = 1;
|
||||
else if (kn->kn_sfflags & NOTE_LOWAT)
|
||||
rv = (kn->kn_data >= kn->kn_sdata);
|
||||
else
|
||||
rv = (kn->kn_data >= so->so_rcv.sb_lowat);
|
||||
if (hint != NOTE_SUBMIT)
|
||||
sounlock(so);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1762,9 +1851,11 @@ filt_sowdetach(struct knote *kn)
|
|||
struct socket *so;
|
||||
|
||||
so = ((file_t *)kn->kn_obj)->f_data;
|
||||
solock(so);
|
||||
SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);
|
||||
if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))
|
||||
so->so_snd.sb_flags &= ~SB_KNOTE;
|
||||
sounlock(so);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
|
@ -1772,22 +1863,28 @@ static int
|
|||
filt_sowrite(struct knote *kn, long hint)
|
||||
{
|
||||
struct socket *so;
|
||||
int rv;
|
||||
|
||||
so = ((file_t *)kn->kn_obj)->f_data;
|
||||
if (hint != NOTE_SUBMIT)
|
||||
solock(so);
|
||||
kn->kn_data = sbspace(&so->so_snd);
|
||||
if (so->so_state & SS_CANTSENDMORE) {
|
||||
kn->kn_flags |= EV_EOF;
|
||||
kn->kn_fflags = so->so_error;
|
||||
return (1);
|
||||
}
|
||||
if (so->so_error) /* temporary udp error */
|
||||
return (1);
|
||||
if (((so->so_state & SS_ISCONNECTED) == 0) &&
|
||||
rv = 1;
|
||||
} else if (so->so_error) /* temporary udp error */
|
||||
rv = 1;
|
||||
else if (((so->so_state & SS_ISCONNECTED) == 0) &&
|
||||
(so->so_proto->pr_flags & PR_CONNREQUIRED))
|
||||
return (0);
|
||||
if (kn->kn_sfflags & NOTE_LOWAT)
|
||||
return (kn->kn_data >= kn->kn_sdata);
|
||||
return (kn->kn_data >= so->so_snd.sb_lowat);
|
||||
rv = 0;
|
||||
else if (kn->kn_sfflags & NOTE_LOWAT)
|
||||
rv = (kn->kn_data >= kn->kn_sdata);
|
||||
else
|
||||
rv = (kn->kn_data >= so->so_snd.sb_lowat);
|
||||
if (hint != NOTE_SUBMIT)
|
||||
sounlock(so);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
|
@ -1795,6 +1892,7 @@ static int
|
|||
filt_solisten(struct knote *kn, long hint)
|
||||
{
|
||||
struct socket *so;
|
||||
int rv;
|
||||
|
||||
so = ((file_t *)kn->kn_obj)->f_data;
|
||||
|
||||
|
@ -1802,8 +1900,13 @@ filt_solisten(struct knote *kn, long hint)
|
|||
* Set kn_data to number of incoming connections, not
|
||||
* counting partial (incomplete) connections.
|
||||
*/
|
||||
if (hint != NOTE_SUBMIT)
|
||||
solock(so);
|
||||
kn->kn_data = so->so_qlen;
|
||||
return (kn->kn_data > 0);
|
||||
rv = (kn->kn_data > 0);
|
||||
if (hint != NOTE_SUBMIT)
|
||||
sounlock(so);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const struct filterops solisten_filtops =
|
||||
|
@ -1820,6 +1923,7 @@ soo_kqfilter(struct file *fp, struct knote *kn)
|
|||
struct sockbuf *sb;
|
||||
|
||||
so = ((file_t *)kn->kn_obj)->f_data;
|
||||
solock(so);
|
||||
switch (kn->kn_filter) {
|
||||
case EVFILT_READ:
|
||||
if (so->so_options & SO_ACCEPTCONN)
|
||||
|
@ -1833,10 +1937,12 @@ soo_kqfilter(struct file *fp, struct knote *kn)
|
|||
sb = &so->so_snd;
|
||||
break;
|
||||
default:
|
||||
sounlock(so);
|
||||
return (EINVAL);
|
||||
}
|
||||
SLIST_INSERT_HEAD(&sb->sb_sel.sel_klist, kn, kn_selnext);
|
||||
sb->sb_flags |= SB_KNOTE;
|
||||
sounlock(so);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1866,28 +1972,30 @@ int
|
|||
sopoll(struct socket *so, int events)
|
||||
{
|
||||
int revents = 0;
|
||||
int s;
|
||||
|
||||
#ifndef DIAGNOSTIC
|
||||
/*
|
||||
* Do a quick, unlocked check in expectation that the socket
|
||||
* will be ready for I/O. Don't do this check if DIAGNOSTIC,
|
||||
* as the solocked() assertions will fail.
|
||||
*/
|
||||
if ((revents = sodopoll(so, events)) != 0)
|
||||
return revents;
|
||||
#endif
|
||||
|
||||
KERNEL_LOCK(1, curlwp);
|
||||
s = splsoftnet();
|
||||
|
||||
solock(so);
|
||||
if ((revents = sodopoll(so, events)) == 0) {
|
||||
if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {
|
||||
selrecord(curlwp, &so->so_rcv.sb_sel);
|
||||
so->so_rcv.sb_flags |= SB_SEL;
|
||||
so->so_rcv.sb_flags |= SB_NOTIFY;
|
||||
}
|
||||
|
||||
if (events & (POLLOUT | POLLWRNORM)) {
|
||||
selrecord(curlwp, &so->so_snd.sb_sel);
|
||||
so->so_snd.sb_flags |= SB_SEL;
|
||||
so->so_snd.sb_flags |= SB_NOTIFY;
|
||||
}
|
||||
}
|
||||
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(curlwp);
|
||||
sounlock(so);
|
||||
|
||||
return revents;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,37 @@
|
|||
/* $NetBSD: uipc_socket2.c,v 1.90 2008/03/01 14:16:51 rmind Exp $ */
|
||||
/* $NetBSD: uipc_socket2.c,v 1.91 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988, 1990, 1993
|
||||
|
@ -32,7 +65,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.90 2008/03/01 14:16:51 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.91 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include "opt_mbuftrace.h"
|
||||
#include "opt_sb_max.h"
|
||||
|
@ -45,21 +78,57 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.90 2008/03/01 14:16:51 rmind Exp
|
|||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/kauth.h>
|
||||
#include <sys/pool.h>
|
||||
|
||||
/*
|
||||
* Primitive routines for operating on sockets and socket buffers
|
||||
* Primitive routines for operating on sockets and socket buffers.
|
||||
*
|
||||
* Locking rules and assumptions:
|
||||
*
|
||||
* o socket::so_lock can change on the fly. The low level routines used
|
||||
* to lock sockets are aware of this. When so_lock is acquired, the
|
||||
* routine locking must check to see if so_lock still points to the
|
||||
* lock that was acquired. If so_lock has changed in the meantime, the
|
||||
* now irellevant lock that was acquired must be dropped and the lock
|
||||
* operation retried. Although not proven here, this is completely safe
|
||||
* on a multiprocessor system, even with relaxed memory ordering, given
|
||||
* the next two rules:
|
||||
*
|
||||
* o In order to mutate so_lock, the lock pointed to by the current value
|
||||
* of so_lock must be held: i.e., the socket must be held locked by the
|
||||
* changing thread. The thread must issue membar_exit() to prevent
|
||||
* memory accesses being reordered, and can set so_lock to the desired
|
||||
* value. If the lock pointed to by the new value of so_lock is not
|
||||
* held by the changing thread, the socket must then be considered
|
||||
* unlocked.
|
||||
*
|
||||
* o If so_lock is mutated, and the previous lock referred to by so_lock
|
||||
* could still be visible to other threads in the system (e.g. via file
|
||||
* descriptor or protocol-internal reference), then the old lock must
|
||||
* remain valid until the socket and/or protocol control block has been
|
||||
* torn down.
|
||||
*
|
||||
* o If a socket has a non-NULL so_head value (i.e. is in the process of
|
||||
* connecting), then locking the socket must also lock the socket pointed
|
||||
* to by so_head: their lock pointers must match.
|
||||
*
|
||||
* o If a socket has connections in progress (so_q, so_q0 not empty) then
|
||||
* locking the socket must also lock the sockets attached to both queues.
|
||||
* Again, their lock pointers must match.
|
||||
*
|
||||
* o Beyond the initial lock assigment in socreate(), assigning locks to
|
||||
* sockets is the responsibility of the individual protocols / protocol
|
||||
* domains.
|
||||
*/
|
||||
|
||||
/* strings for sleep message: */
|
||||
const char netcon[] = "netcon";
|
||||
const char netcls[] = "netcls";
|
||||
const char netio[] = "netio";
|
||||
const char netlck[] = "netlck";
|
||||
static POOL_INIT(socket_pool, sizeof(struct socket), 0, 0, 0, "sockpl", NULL,
|
||||
IPL_SOFTNET);
|
||||
|
||||
u_long sb_max = SB_MAX; /* maximum socket buffer size */
|
||||
static u_long sb_max_adj; /* adjusted sb_max */
|
||||
|
@ -98,6 +167,8 @@ void
|
|||
soisconnecting(struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
so->so_state |= SS_ISCONNECTING;
|
||||
}
|
||||
|
@ -108,14 +179,18 @@ soisconnected(struct socket *so)
|
|||
struct socket *head;
|
||||
|
||||
head = so->so_head;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
KASSERT(head == NULL || solocked2(so, head));
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
|
||||
so->so_state |= SS_ISCONNECTED;
|
||||
if (head && soqremque(so, 0)) {
|
||||
soqinsque(head, so, 1);
|
||||
sorwakeup(head);
|
||||
wakeup((void *)&head->so_timeo);
|
||||
cv_broadcast(&head->so_cv);
|
||||
} else {
|
||||
wakeup((void *)&so->so_timeo);
|
||||
cv_broadcast(&so->so_cv);
|
||||
sorwakeup(so);
|
||||
sowwakeup(so);
|
||||
}
|
||||
|
@ -125,9 +200,11 @@ void
|
|||
soisdisconnecting(struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
so->so_state &= ~SS_ISCONNECTING;
|
||||
so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||
wakeup((void *)&so->so_timeo);
|
||||
cv_broadcast(&so->so_cv);
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
@ -136,9 +213,11 @@ void
|
|||
soisdisconnected(struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
|
||||
wakeup((void *)&so->so_timeo);
|
||||
cv_broadcast(&so->so_cv);
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
@ -155,15 +234,18 @@ struct socket *
|
|||
sonewconn(struct socket *head, int connstatus)
|
||||
{
|
||||
struct socket *so;
|
||||
int soqueue;
|
||||
int soqueue, error;
|
||||
|
||||
KASSERT(solocked(head));
|
||||
|
||||
soqueue = connstatus ? 1 : 0;
|
||||
if (head->so_qlen + head->so_q0len > 3 * head->so_qlimit / 2)
|
||||
return ((struct socket *)0);
|
||||
so = pool_get(&socket_pool, PR_NOWAIT);
|
||||
so = soget(false);
|
||||
if (so == NULL)
|
||||
return (NULL);
|
||||
memset((void *)so, 0, sizeof(*so));
|
||||
mutex_obj_hold(head->so_lock);
|
||||
so->so_lock = head->so_lock;
|
||||
so->so_type = head->so_type;
|
||||
so->so_options = head->so_options &~ SO_ACCEPTCONN;
|
||||
so->so_linger = head->so_linger;
|
||||
|
@ -180,8 +262,6 @@ sonewconn(struct socket *head, int connstatus)
|
|||
so->so_rcv.sb_mowner = head->so_rcv.sb_mowner;
|
||||
so->so_snd.sb_mowner = head->so_snd.sb_mowner;
|
||||
#endif
|
||||
selinit(&so->so_rcv.sb_sel);
|
||||
selinit(&so->so_snd.sb_sel);
|
||||
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
|
||||
so->so_snd.sb_lowat = head->so_snd.sb_lowat;
|
||||
so->so_rcv.sb_lowat = head->so_rcv.sb_lowat;
|
||||
|
@ -190,27 +270,65 @@ sonewconn(struct socket *head, int connstatus)
|
|||
so->so_rcv.sb_flags |= head->so_rcv.sb_flags & SB_AUTOSIZE;
|
||||
so->so_snd.sb_flags |= head->so_snd.sb_flags & SB_AUTOSIZE;
|
||||
soqinsque(head, so, soqueue);
|
||||
if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH,
|
||||
(struct mbuf *)0, (struct mbuf *)0, (struct mbuf *)0,
|
||||
(struct lwp *)0)) {
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_ATTACH, NULL, NULL,
|
||||
NULL, NULL);
|
||||
KASSERT(solocked(so));
|
||||
if (error != 0) {
|
||||
(void) soqremque(so, soqueue);
|
||||
seldestroy(&so->so_rcv.sb_sel);
|
||||
seldestroy(&so->so_snd.sb_sel);
|
||||
pool_put(&socket_pool, so);
|
||||
soput(so);
|
||||
return (NULL);
|
||||
}
|
||||
if (connstatus) {
|
||||
sorwakeup(head);
|
||||
wakeup((void *)&head->so_timeo);
|
||||
cv_broadcast(&head->so_cv);
|
||||
so->so_state |= connstatus;
|
||||
}
|
||||
return (so);
|
||||
}
|
||||
|
||||
struct socket *
|
||||
soget(bool waitok)
|
||||
{
|
||||
struct socket *so;
|
||||
|
||||
so = pool_get(&socket_pool, (waitok ? PR_WAITOK : PR_NOWAIT));
|
||||
if (__predict_false(so == NULL))
|
||||
return (NULL);
|
||||
memset(so, 0, sizeof(*so));
|
||||
TAILQ_INIT(&so->so_q0);
|
||||
TAILQ_INIT(&so->so_q);
|
||||
cv_init(&so->so_cv, "socket");
|
||||
cv_init(&so->so_rcv.sb_cv, "netio");
|
||||
cv_init(&so->so_snd.sb_cv, "netio");
|
||||
selinit(&so->so_rcv.sb_sel);
|
||||
selinit(&so->so_snd.sb_sel);
|
||||
so->so_rcv.sb_so = so;
|
||||
so->so_snd.sb_so = so;
|
||||
return so;
|
||||
}
|
||||
|
||||
void
|
||||
soput(struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(!cv_has_waiters(&so->so_cv));
|
||||
KASSERT(!cv_has_waiters(&so->so_rcv.sb_cv));
|
||||
KASSERT(!cv_has_waiters(&so->so_snd.sb_cv));
|
||||
seldestroy(&so->so_rcv.sb_sel);
|
||||
seldestroy(&so->so_snd.sb_sel);
|
||||
mutex_obj_free(so->so_lock);
|
||||
cv_destroy(&so->so_cv);
|
||||
cv_destroy(&so->so_rcv.sb_cv);
|
||||
cv_destroy(&so->so_snd.sb_cv);
|
||||
pool_put(&socket_pool, so);
|
||||
}
|
||||
|
||||
void
|
||||
soqinsque(struct socket *head, struct socket *so, int q)
|
||||
{
|
||||
|
||||
KASSERT(solocked2(head, so));
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (so->so_onq != NULL)
|
||||
panic("soqinsque");
|
||||
|
@ -233,6 +351,8 @@ soqremque(struct socket *so, int q)
|
|||
struct socket *head;
|
||||
|
||||
head = so->so_head;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
if (q == 0) {
|
||||
if (so->so_onq != &head->so_q0)
|
||||
return (0);
|
||||
|
@ -242,6 +362,7 @@ soqremque(struct socket *so, int q)
|
|||
return (0);
|
||||
head->so_qlen--;
|
||||
}
|
||||
KASSERT(solocked2(so, head));
|
||||
TAILQ_REMOVE(so->so_onq, so, so_qe);
|
||||
so->so_onq = NULL;
|
||||
so->so_head = NULL;
|
||||
|
@ -262,6 +383,8 @@ void
|
|||
socantsendmore(struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
so->so_state |= SS_CANTSENDMORE;
|
||||
sowwakeup(so);
|
||||
}
|
||||
|
@ -270,6 +393,8 @@ void
|
|||
socantrcvmore(struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
so->so_state |= SS_CANTRCVMORE;
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
@ -280,32 +405,23 @@ socantrcvmore(struct socket *so)
|
|||
int
|
||||
sbwait(struct sockbuf *sb)
|
||||
{
|
||||
struct socket *so;
|
||||
kmutex_t *lock;
|
||||
int error;
|
||||
|
||||
sb->sb_flags |= SB_WAIT;
|
||||
return (tsleep((void *)&sb->sb_cc,
|
||||
(sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH, netio,
|
||||
sb->sb_timeo));
|
||||
}
|
||||
so = sb->sb_so;
|
||||
|
||||
/*
|
||||
* Lock a sockbuf already known to be locked;
|
||||
* return any error returned from sleep (EINTR).
|
||||
*/
|
||||
int
|
||||
sb_lock(struct sockbuf *sb)
|
||||
{
|
||||
int error;
|
||||
KASSERT(solocked(so));
|
||||
|
||||
while (sb->sb_flags & SB_LOCK) {
|
||||
sb->sb_flags |= SB_WANT;
|
||||
error = tsleep((void *)&sb->sb_flags,
|
||||
(sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK|PCATCH,
|
||||
netlck, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
}
|
||||
sb->sb_flags |= SB_LOCK;
|
||||
return (0);
|
||||
sb->sb_flags |= SB_NOTIFY;
|
||||
lock = so->so_lock;
|
||||
if ((sb->sb_flags & SB_NOINTR) != 0)
|
||||
error = cv_timedwait(&sb->sb_cv, lock, sb->sb_timeo);
|
||||
else
|
||||
error = cv_timedwait_sig(&sb->sb_cv, lock, sb->sb_timeo);
|
||||
if (__predict_false(lock != so->so_lock))
|
||||
solockretry(so, lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -318,17 +434,16 @@ sowakeup(struct socket *so, struct sockbuf *sb, int code)
|
|||
{
|
||||
int band;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
KASSERT(sb->sb_so == so);
|
||||
|
||||
if (code == POLL_IN)
|
||||
band = POLLIN|POLLRDNORM;
|
||||
else
|
||||
band = POLLOUT|POLLWRNORM;
|
||||
selnotify(&sb->sb_sel, band, 0);
|
||||
|
||||
sb->sb_flags &= ~SB_SEL;
|
||||
if (sb->sb_flags & SB_WAIT) {
|
||||
sb->sb_flags &= ~SB_WAIT;
|
||||
wakeup((void *)&sb->sb_cc);
|
||||
}
|
||||
sb->sb_flags &= ~SB_NOTIFY;
|
||||
selnotify(&sb->sb_sel, band, NOTE_SUBMIT);
|
||||
cv_broadcast(&sb->sb_cv);
|
||||
if (sb->sb_flags & SB_ASYNC)
|
||||
fownsignal(so->so_pgid, SIGIO, code, band, so);
|
||||
if (sb->sb_flags & SB_UPCALL)
|
||||
|
@ -386,6 +501,9 @@ sb_max_set(u_long new_sbmax)
|
|||
int
|
||||
soreserve(struct socket *so, u_long sndcc, u_long rcvcc)
|
||||
{
|
||||
|
||||
KASSERT(so->so_lock == NULL || solocked(so));
|
||||
|
||||
/*
|
||||
* there's at least one application (a configure script of screen)
|
||||
* which expects a fifo is writable even if it has "some" bytes
|
||||
|
@ -429,7 +547,10 @@ sbreserve(struct sockbuf *sb, u_long cc, struct socket *so)
|
|||
rlim_t maxcc;
|
||||
struct uidinfo *uidinfo;
|
||||
|
||||
KDASSERT(sb_max_adj != 0);
|
||||
KASSERT(so->so_lock == NULL || solocked(so));
|
||||
KASSERT(sb->sb_so == so);
|
||||
KASSERT(sb_max_adj != 0);
|
||||
|
||||
if (cc == 0 || cc > sb_max_adj)
|
||||
return (0);
|
||||
if (so) {
|
||||
|
@ -451,12 +572,15 @@ sbreserve(struct sockbuf *sb, u_long cc, struct socket *so)
|
|||
}
|
||||
|
||||
/*
|
||||
* Free mbufs held by a socket, and reserved mbuf space.
|
||||
* Free mbufs held by a socket, and reserved mbuf space. We do not assert
|
||||
* that the socket is held locked here: see sorflush().
|
||||
*/
|
||||
void
|
||||
sbrelease(struct sockbuf *sb, struct socket *so)
|
||||
{
|
||||
|
||||
KASSERT(sb->sb_so == so);
|
||||
|
||||
sbflush(sb);
|
||||
(void)chgsbsize(so->so_uidinfo, &sb->sb_hiwat, 0, RLIM_INFINITY);
|
||||
sb->sb_mbmax = 0;
|
||||
|
@ -493,6 +617,8 @@ sblastrecordchk(struct sockbuf *sb, const char *where)
|
|||
{
|
||||
struct mbuf *m = sb->sb_mb;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
while (m && m->m_nextpkt)
|
||||
m = m->m_nextpkt;
|
||||
|
||||
|
@ -512,6 +638,8 @@ sblastmbufchk(struct sockbuf *sb, const char *where)
|
|||
struct mbuf *m = sb->sb_mb;
|
||||
struct mbuf *n;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
while (m && m->m_nextpkt)
|
||||
m = m->m_nextpkt;
|
||||
|
||||
|
@ -560,6 +688,8 @@ sbappend(struct sockbuf *sb, struct mbuf *m)
|
|||
{
|
||||
struct mbuf *n;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
if (m == 0)
|
||||
return;
|
||||
|
||||
|
@ -601,6 +731,7 @@ void
|
|||
sbappendstream(struct sockbuf *sb, struct mbuf *m)
|
||||
{
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
KDASSERT(m->m_nextpkt == NULL);
|
||||
KASSERT(sb->sb_mb == sb->sb_lastrecord);
|
||||
|
||||
|
@ -620,18 +751,22 @@ sbappendstream(struct sockbuf *sb, struct mbuf *m)
|
|||
void
|
||||
sbcheck(struct sockbuf *sb)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct mbuf *m, *m2;
|
||||
u_long len, mbcnt;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
len = 0;
|
||||
mbcnt = 0;
|
||||
for (m = sb->sb_mb; m; m = m->m_next) {
|
||||
len += m->m_len;
|
||||
mbcnt += MSIZE;
|
||||
if (m->m_flags & M_EXT)
|
||||
mbcnt += m->m_ext.ext_size;
|
||||
if (m->m_nextpkt)
|
||||
panic("sbcheck nextpkt");
|
||||
for (m = sb->sb_mb; m; m = m->m_nextpkt) {
|
||||
for (m2 = m; m2 != NULL; m2 = m2->m_next) {
|
||||
len += m2->m_len;
|
||||
mbcnt += MSIZE;
|
||||
if (m2->m_flags & M_EXT)
|
||||
mbcnt += m2->m_ext.ext_size;
|
||||
if (m2->m_nextpkt != NULL)
|
||||
panic("sbcheck nextpkt");
|
||||
}
|
||||
}
|
||||
if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) {
|
||||
printf("cc %lu != %lu || mbcnt %lu != %lu\n", len, sb->sb_cc,
|
||||
|
@ -650,6 +785,8 @@ sbappendrecord(struct sockbuf *sb, struct mbuf *m0)
|
|||
{
|
||||
struct mbuf *m;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
if (m0 == 0)
|
||||
return;
|
||||
|
||||
|
@ -683,6 +820,8 @@ sbinsertoob(struct sockbuf *sb, struct mbuf *m0)
|
|||
{
|
||||
struct mbuf *m, **mp;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
if (m0 == 0)
|
||||
return;
|
||||
|
||||
|
@ -735,6 +874,8 @@ sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0,
|
|||
struct mbuf *m, *n, *nlast;
|
||||
int space, len;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
space = asa->sa_len;
|
||||
|
||||
if (m0 != NULL) {
|
||||
|
@ -787,7 +928,6 @@ sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa, struct mbuf *m0,
|
|||
|
||||
sb->sb_mbtail = nlast;
|
||||
SBLASTMBUFCHK(sb, "sbappendaddr");
|
||||
|
||||
SBLASTRECORDCHK(sb, "sbappendaddr 2");
|
||||
|
||||
return (1);
|
||||
|
@ -804,6 +944,8 @@ m_prepend_sockaddr(struct sockbuf *sb, struct mbuf *m0,
|
|||
struct mbuf *m;
|
||||
const int salen = asa->sa_len;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
/* only the first in each chain need be a pkthdr */
|
||||
MGETHDR(m, M_DONTWAIT, MT_SONAME);
|
||||
if (m == 0)
|
||||
|
@ -836,6 +978,8 @@ sbappendaddrchain(struct sockbuf *sb, const struct sockaddr *asa,
|
|||
struct mbuf *m, *n, *n0, *nlast;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
/*
|
||||
* XXX sbprio reserved for encoding priority of this* request:
|
||||
* SB_PRIO_NONE --> honour normal sb limits
|
||||
|
@ -931,6 +1075,8 @@ sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
|
|||
struct mbuf *m, *mlast, *n;
|
||||
int space;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
space = 0;
|
||||
if (control == 0)
|
||||
panic("sbappendcontrol");
|
||||
|
@ -959,7 +1105,6 @@ sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
|
|||
|
||||
sb->sb_mbtail = mlast;
|
||||
SBLASTMBUFCHK(sb, "sbappendcontrol");
|
||||
|
||||
SBLASTRECORDCHK(sb, "sbappendcontrol 2");
|
||||
|
||||
return (1);
|
||||
|
@ -976,6 +1121,8 @@ sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n)
|
|||
int eor;
|
||||
struct mbuf *o;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
eor = 0;
|
||||
while (m) {
|
||||
eor |= m->m_flags & M_EOR;
|
||||
|
@ -1028,6 +1175,7 @@ void
|
|||
sbflush(struct sockbuf *sb)
|
||||
{
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
KASSERT((sb->sb_flags & SB_LOCK) == 0);
|
||||
|
||||
while (sb->sb_mbcnt)
|
||||
|
@ -1047,6 +1195,8 @@ sbdrop(struct sockbuf *sb, int len)
|
|||
{
|
||||
struct mbuf *m, *mn, *next;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
next = (m = sb->sb_mb) ? m->m_nextpkt : 0;
|
||||
while (len > 0) {
|
||||
if (m == 0) {
|
||||
|
@ -1099,6 +1249,8 @@ sbdroprecord(struct sockbuf *sb)
|
|||
{
|
||||
struct mbuf *m, *mn;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
m = sb->sb_mb;
|
||||
if (m) {
|
||||
sb->sb_mb = m->m_nextpkt;
|
||||
|
@ -1142,3 +1294,116 @@ sbcreatecontrol(void *p, int size, int type, int level)
|
|||
cp->cmsg_type = type;
|
||||
return (m);
|
||||
}
|
||||
|
||||
void
|
||||
solockretry(struct socket *so, kmutex_t *lock)
|
||||
{
|
||||
|
||||
while (lock != so->so_lock) {
|
||||
mutex_exit(lock);
|
||||
lock = so->so_lock;
|
||||
mutex_enter(lock);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
solocked(struct socket *so)
|
||||
{
|
||||
|
||||
return mutex_owned(so->so_lock);
|
||||
}
|
||||
|
||||
bool
|
||||
solocked2(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
kmutex_t *lock;
|
||||
|
||||
lock = so1->so_lock;
|
||||
if (lock != so2->so_lock)
|
||||
return false;
|
||||
return mutex_owned(lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign a default lock to a new socket. For PRU_ATTACH, and done by
|
||||
* protocols that do not have special locking requirements.
|
||||
*/
|
||||
void
|
||||
sosetlock(struct socket *so)
|
||||
{
|
||||
kmutex_t *lock;
|
||||
|
||||
if (so->so_lock == NULL) {
|
||||
lock = softnet_lock;
|
||||
so->so_lock = lock;
|
||||
mutex_obj_hold(lock);
|
||||
mutex_enter(lock);
|
||||
}
|
||||
|
||||
/* In all cases, lock must be held on return from PRU_ATTACH. */
|
||||
KASSERT(solocked(so));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set lock on sockbuf sb; sleep if lock is already held.
|
||||
* Unless SB_NOINTR is set on sockbuf, sleep is interruptible.
|
||||
* Returns error without lock if sleep is interrupted.
|
||||
*/
|
||||
int
|
||||
sblock(struct sockbuf *sb, int wf)
|
||||
{
|
||||
struct socket *so;
|
||||
kmutex_t *lock;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked(sb->sb_so));
|
||||
|
||||
for (;;) {
|
||||
if (__predict_true((sb->sb_flags & SB_LOCK) == 0)) {
|
||||
sb->sb_flags |= SB_LOCK;
|
||||
return 0;
|
||||
}
|
||||
if (wf != M_WAITOK)
|
||||
return EWOULDBLOCK;
|
||||
so = sb->sb_so;
|
||||
lock = so->so_lock;
|
||||
if ((sb->sb_flags & SB_NOINTR) != 0) {
|
||||
cv_wait(&so->so_cv, lock);
|
||||
error = 0;
|
||||
} else
|
||||
error = cv_wait_sig(&so->so_cv, lock);
|
||||
if (__predict_false(lock != so->so_lock))
|
||||
solockretry(so, lock);
|
||||
if (error != 0)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sbunlock(struct sockbuf *sb)
|
||||
{
|
||||
struct socket *so;
|
||||
|
||||
so = sb->sb_so;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
KASSERT((sb->sb_flags & SB_LOCK) != 0);
|
||||
|
||||
sb->sb_flags &= ~SB_LOCK;
|
||||
cv_broadcast(&so->so_cv);
|
||||
}
|
||||
|
||||
int
|
||||
sowait(struct socket *so, int timo)
|
||||
{
|
||||
kmutex_t *lock;
|
||||
int error;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
lock = so->so_lock;
|
||||
error = cv_timedwait_sig(&so->so_cv, lock, timo);
|
||||
if (__predict_false(lock != so->so_lock))
|
||||
solockretry(so, lock);
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,37 @@
|
|||
/* $NetBSD: uipc_syscalls.c,v 1.128 2008/03/21 21:55:00 ad Exp $ */
|
||||
/* $NetBSD: uipc_syscalls.c,v 1.129 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1990, 1993
|
||||
|
@ -32,7 +65,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.128 2008/03/21 21:55:00 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.129 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include "opt_pipe.h"
|
||||
|
||||
|
@ -139,7 +172,7 @@ do_sys_accept(struct lwp *l, int sock, struct mbuf **name, register_t *new_sock)
|
|||
{
|
||||
file_t *fp, *fp2;
|
||||
struct mbuf *nam;
|
||||
int error, s, fd;
|
||||
int error, fd;
|
||||
struct socket *so, *so2;
|
||||
|
||||
if ((fp = fd_getfile(sock)) == NULL)
|
||||
|
@ -150,9 +183,8 @@ do_sys_accept(struct lwp *l, int sock, struct mbuf **name, register_t *new_sock)
|
|||
return (error);
|
||||
nam = m_get(M_WAIT, MT_SONAME);
|
||||
*new_sock = fd;
|
||||
s = splsoftnet();
|
||||
so = fp->f_data;
|
||||
fd_putfile(sock); /* XXX wrong, socket can disappear */
|
||||
solock(so);
|
||||
if (!(so->so_proto->pr_flags & PR_LISTEN)) {
|
||||
error = EOPNOTSUPP;
|
||||
goto bad;
|
||||
|
@ -170,8 +202,7 @@ do_sys_accept(struct lwp *l, int sock, struct mbuf **name, register_t *new_sock)
|
|||
so->so_error = ECONNABORTED;
|
||||
break;
|
||||
}
|
||||
error = tsleep(&so->so_timeo, PSOCK | PCATCH,
|
||||
netcon, 0);
|
||||
error = sowait(so, 0);
|
||||
if (error) {
|
||||
goto bad;
|
||||
}
|
||||
|
@ -182,7 +213,7 @@ do_sys_accept(struct lwp *l, int sock, struct mbuf **name, register_t *new_sock)
|
|||
goto bad;
|
||||
}
|
||||
/* connection has been removed from the listen queue */
|
||||
KNOTE(&so->so_rcv.sb_sel.sel_klist, 0);
|
||||
KNOTE(&so->so_rcv.sb_sel.sel_klist, NOTE_SUBMIT);
|
||||
so2 = TAILQ_FIRST(&so->so_q);
|
||||
if (soqremque(so2, 1) == 0)
|
||||
panic("accept");
|
||||
|
@ -191,7 +222,7 @@ do_sys_accept(struct lwp *l, int sock, struct mbuf **name, register_t *new_sock)
|
|||
fp2->f_ops = &socketops;
|
||||
fp2->f_data = so2;
|
||||
error = soaccept(so2, nam);
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
if (error) {
|
||||
/* an error occurred, free the file descriptor and mbuf */
|
||||
m_freem(nam);
|
||||
|
@ -204,10 +235,12 @@ do_sys_accept(struct lwp *l, int sock, struct mbuf **name, register_t *new_sock)
|
|||
fd_affix(curproc, fp2, fd);
|
||||
*name = nam;
|
||||
}
|
||||
fd_putfile(sock);
|
||||
return (error);
|
||||
bad:
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
m_freem(nam);
|
||||
fd_putfile(sock);
|
||||
fd_abort(curproc, fp2, fd);
|
||||
return (error);
|
||||
}
|
||||
|
@ -263,12 +296,12 @@ do_sys_connect(struct lwp *l, int fd, struct mbuf *nam)
|
|||
struct socket *so;
|
||||
int error;
|
||||
int interrupted = 0;
|
||||
int s;
|
||||
|
||||
if ((error = fd_getsock(fd, &so)) != 0) {
|
||||
m_freem(nam);
|
||||
return (error);
|
||||
}
|
||||
solock(so);
|
||||
MCLAIM(nam, so->so_mowner);
|
||||
if (so->so_state & SS_ISCONNECTING) {
|
||||
error = EALREADY;
|
||||
|
@ -282,10 +315,8 @@ do_sys_connect(struct lwp *l, int fd, struct mbuf *nam)
|
|||
error = EINPROGRESS;
|
||||
goto out;
|
||||
}
|
||||
s = splsoftnet();
|
||||
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
|
||||
error = tsleep(&so->so_timeo, PSOCK | PCATCH,
|
||||
netcon, 0);
|
||||
error = sowait(so, 0);
|
||||
if (error) {
|
||||
if (error == EINTR || error == ERESTART)
|
||||
interrupted = 1;
|
||||
|
@ -296,13 +327,13 @@ do_sys_connect(struct lwp *l, int fd, struct mbuf *nam)
|
|||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
}
|
||||
splx(s);
|
||||
bad:
|
||||
if (!interrupted)
|
||||
so->so_state &= ~SS_ISCONNECTING;
|
||||
if (error == ERESTART)
|
||||
error = EINTR;
|
||||
out:
|
||||
sounlock(so);
|
||||
fd_putfile(fd);
|
||||
m_freem(nam);
|
||||
return (error);
|
||||
|
@ -324,11 +355,11 @@ sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap, register_t
|
|||
|
||||
p = curproc;
|
||||
error = socreate(SCARG(uap, domain), &so1, SCARG(uap, type),
|
||||
SCARG(uap, protocol), l);
|
||||
SCARG(uap, protocol), l, NULL);
|
||||
if (error)
|
||||
return (error);
|
||||
error = socreate(SCARG(uap, domain), &so2, SCARG(uap, type),
|
||||
SCARG(uap, protocol), l);
|
||||
SCARG(uap, protocol), l, so1);
|
||||
if (error)
|
||||
goto free1;
|
||||
if ((error = fd_allocfile(&fp1, &fd)) != 0)
|
||||
|
@ -345,20 +376,22 @@ sys_socketpair(struct lwp *l, const struct sys_socketpair_args *uap, register_t
|
|||
fp2->f_ops = &socketops;
|
||||
fp2->f_data = so2;
|
||||
sv[1] = fd;
|
||||
if ((error = soconnect2(so1, so2)) != 0)
|
||||
goto free4;
|
||||
if (SCARG(uap, type) == SOCK_DGRAM) {
|
||||
solock(so1);
|
||||
error = soconnect2(so1, so2);
|
||||
if (error == 0 && SCARG(uap, type) == SOCK_DGRAM) {
|
||||
/*
|
||||
* Datagram socket connection is asymmetric.
|
||||
*/
|
||||
if ((error = soconnect2(so2, so1)) != 0)
|
||||
goto free4;
|
||||
error = soconnect2(so2, so1);
|
||||
}
|
||||
sounlock(so1);
|
||||
if (error == 0)
|
||||
error = copyout(sv, SCARG(uap, rsv), 2 * sizeof(int));
|
||||
if (error == 0) {
|
||||
fd_affix(p, fp2, sv[1]);
|
||||
fd_affix(p, fp1, sv[0]);
|
||||
return (0);
|
||||
}
|
||||
error = copyout(sv, SCARG(uap, rsv), 2 * sizeof(int));
|
||||
fd_affix(p, fp2, sv[1]);
|
||||
fd_affix(p, fp1, sv[0]);
|
||||
return (error);
|
||||
free4:
|
||||
fd_abort(p, fp2, sv[1]);
|
||||
free3:
|
||||
fd_abort(p, fp1, sv[0]);
|
||||
|
@ -519,9 +552,7 @@ do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags,
|
|||
MCLAIM(control, so->so_mowner);
|
||||
|
||||
len = auio.uio_resid;
|
||||
KERNEL_LOCK(1, NULL);
|
||||
error = (*so->so_send)(so, to, &auio, NULL, control, flags, l);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
/* Protocol is responsible for freeing 'control' */
|
||||
control = NULL;
|
||||
|
||||
|
@ -798,10 +829,8 @@ do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp, struct mbuf **from,
|
|||
|
||||
len = auio.uio_resid;
|
||||
mp->msg_flags &= MSG_USERFLAGS;
|
||||
KERNEL_LOCK(1, NULL);
|
||||
error = (*so->so_receive)(so, from, &auio, NULL, control,
|
||||
&mp->msg_flags);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
&mp->msg_flags);
|
||||
len -= auio.uio_resid;
|
||||
*retsize = len;
|
||||
if (error != 0 && len != 0
|
||||
|
@ -843,7 +872,9 @@ sys_shutdown(struct lwp *l, const struct sys_shutdown_args *uap, register_t *ret
|
|||
|
||||
if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
|
||||
return (error);
|
||||
solock(so);
|
||||
error = soshutdown(so, SCARG(uap, how));
|
||||
sounlock(so);
|
||||
fd_putfile(SCARG(uap, s));
|
||||
return (error);
|
||||
}
|
||||
|
@ -951,9 +982,9 @@ sys_pipe(struct lwp *l, const void *v, register_t *retval)
|
|||
proc_t *p;
|
||||
|
||||
p = curproc;
|
||||
if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l)) != 0)
|
||||
if ((error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL)) != 0)
|
||||
return (error);
|
||||
if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l)) != 0)
|
||||
if ((error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso)) != 0)
|
||||
goto free1;
|
||||
/* remember this socket pair implements a pipe */
|
||||
wso->so_state |= SS_ISAPIPE;
|
||||
|
@ -972,7 +1003,10 @@ sys_pipe(struct lwp *l, const void *v, register_t *retval)
|
|||
wf->f_ops = &socketops;
|
||||
wf->f_data = wso;
|
||||
retval[1] = fd;
|
||||
if ((error = unp_connect2(wso, rso, PRU_CONNECT2)) != 0)
|
||||
solock(wso);
|
||||
error = unp_connect2(wso, rso, PRU_CONNECT2);
|
||||
sounlock(wso);
|
||||
if (error != 0)
|
||||
goto free4;
|
||||
fd_affix(p, wf, (int)retval[1]);
|
||||
fd_affix(p, rf, (int)retval[0]);
|
||||
|
@ -1003,20 +1037,21 @@ do_sys_getsockname(struct lwp *l, int fd, int which, struct mbuf **nam)
|
|||
if ((error = fd_getsock(fd, &so)) != 0)
|
||||
return error;
|
||||
|
||||
m = m_getclr(M_WAIT, MT_SONAME);
|
||||
MCLAIM(m, so->so_mowner);
|
||||
|
||||
solock(so);
|
||||
if (which == PRU_PEERADDR
|
||||
&& (so->so_state & (SS_ISCONNECTED | SS_ISCONFIRMING)) == 0) {
|
||||
error = ENOTCONN;
|
||||
goto bad;
|
||||
} else {
|
||||
*nam = m;
|
||||
error = (*so->so_proto->pr_usrreq)(so, which, NULL, m, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
m = m_getclr(M_WAIT, MT_SONAME);
|
||||
*nam = m;
|
||||
MCLAIM(m, so->so_mowner);
|
||||
error = (*so->so_proto->pr_usrreq)(so, which, (struct mbuf *)0,
|
||||
m, (struct mbuf *)0, (struct lwp *)0);
|
||||
sounlock(so);
|
||||
if (error != 0)
|
||||
m_free(m);
|
||||
bad:
|
||||
fd_putfile(fd);
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: uipc_usrreq.c,v 1.111 2008/04/20 07:47:18 mlelstv Exp $ */
|
||||
/* $NetBSD: uipc_usrreq.c,v 1.112 2008/04/24 11:38:36 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000, 2004, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -103,7 +103,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.111 2008/04/20 07:47:18 mlelstv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.112 2008/04/24 11:38:36 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -131,6 +131,42 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.111 2008/04/20 07:47:18 mlelstv Ex
|
|||
* SEQPACKET, RDM
|
||||
* rethink name space problems
|
||||
* need a proper out-of-band
|
||||
*
|
||||
* Notes on locking:
|
||||
*
|
||||
* The generic rules noted in uipc_socket2.c apply. In addition:
|
||||
*
|
||||
* o We have a global lock, uipc_lock.
|
||||
*
|
||||
* o All datagram sockets are locked by uipc_lock.
|
||||
*
|
||||
* o For stream socketpairs, the two endpoints are created sharing the same
|
||||
* independent lock. Sockets presented to PRU_CONNECT2 must already have
|
||||
* matching locks.
|
||||
*
|
||||
* o Stream sockets created via socket() start life with their own
|
||||
* independent lock.
|
||||
*
|
||||
* o Stream connections to a named endpoint are slightly more complicated.
|
||||
* Sockets that have called listen() have their lock pointer mutated to
|
||||
* the global uipc_lock. When establishing a connection, the connecting
|
||||
* socket also has its lock mutated to uipc_lock, which matches the head
|
||||
* (listening socket). We create a new socket for accept() to return, and
|
||||
* that also shares the head's lock. Until the connection is completely
|
||||
* done on both ends, all three sockets are locked by uipc_lock. Once the
|
||||
* connection is complete, the association with the head's lock is broken.
|
||||
* The connecting socket and the socket returned from accept() have their
|
||||
* lock pointers mutated away from uipc_lock, and back to the connecting
|
||||
* socket's original, independent lock. The head continues to be locked
|
||||
* by uipc_lock.
|
||||
*
|
||||
* o If uipc_lock is determined to be a significant source of contention,
|
||||
* it could easily be hashed out. It is difficult to simply make it an
|
||||
* independent lock because of visibility / garbage collection issues:
|
||||
* if a socket has been associated with a lock at any point, that lock
|
||||
* must remain valid until the socket is no longer visible in the system.
|
||||
* The lock must not be freed or otherwise destroyed until any sockets
|
||||
* that had referenced it have also been destroyed.
|
||||
*/
|
||||
const struct sockaddr_un sun_noname = {
|
||||
.sun_len = sizeof(sun_noname),
|
||||
|
@ -139,6 +175,106 @@ const struct sockaddr_un sun_noname = {
|
|||
ino_t unp_ino; /* prototype for fake inode numbers */
|
||||
|
||||
struct mbuf *unp_addsockcred(struct lwp *, struct mbuf *);
|
||||
static kmutex_t *uipc_lock;
|
||||
|
||||
/*
|
||||
* Initialize Unix protocols.
|
||||
*/
|
||||
void
|
||||
uipc_init(void)
|
||||
{
|
||||
|
||||
uipc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* A connection succeeded: disassociate both endpoints from the head's
|
||||
* lock, and make them share their own lock. There is a race here: for
|
||||
* a very brief time one endpoint will be locked by a different lock
|
||||
* than the other end. However, since the current thread holds the old
|
||||
* lock (the listening socket's lock, the head) access can still only be
|
||||
* made to one side of the connection.
|
||||
*/
|
||||
static void
|
||||
unp_setpeerlocks(struct socket *so, struct socket *so2)
|
||||
{
|
||||
struct unpcb *unp;
|
||||
kmutex_t *lock;
|
||||
|
||||
KASSERT(solocked2(so, so2));
|
||||
|
||||
/*
|
||||
* Bail out if either end of the socket is not yet fully
|
||||
* connected or accepted. We only break the lock association
|
||||
* with the head when the pair of sockets stand completely
|
||||
* on their own.
|
||||
*/
|
||||
if (so->so_head != NULL || so2->so_head != NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Drop references to old lock. A third reference (from the
|
||||
* queue head) must be held as we still hold its lock. Bonus:
|
||||
* we don't need to worry about garbage collecting the lock.
|
||||
*/
|
||||
lock = so->so_lock;
|
||||
KASSERT(lock == uipc_lock);
|
||||
mutex_obj_free(lock);
|
||||
mutex_obj_free(lock);
|
||||
|
||||
/*
|
||||
* Grab stream lock from the initiator and share between the two
|
||||
* endpoints. Issue memory barrier to ensure all modifications
|
||||
* become globally visible before the lock change. so2 is
|
||||
* assumed not to have a stream lock, because it was created
|
||||
* purely for the server side to accept this connection and
|
||||
* started out life using the domain-wide lock.
|
||||
*/
|
||||
unp = sotounpcb(so);
|
||||
KASSERT(unp->unp_streamlock != NULL);
|
||||
KASSERT(sotounpcb(so2)->unp_streamlock == NULL);
|
||||
lock = unp->unp_streamlock;
|
||||
unp->unp_streamlock = NULL;
|
||||
mutex_obj_hold(lock);
|
||||
membar_exit();
|
||||
so->so_lock = lock;
|
||||
so2->so_lock = lock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset a socket's lock back to the domain-wide lock.
|
||||
*/
|
||||
static void
|
||||
unp_resetlock(struct socket *so)
|
||||
{
|
||||
kmutex_t *olock, *nlock;
|
||||
struct unpcb *unp;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
olock = so->so_lock;
|
||||
nlock = uipc_lock;
|
||||
if (olock == nlock)
|
||||
return;
|
||||
unp = sotounpcb(so);
|
||||
KASSERT(unp->unp_streamlock == NULL);
|
||||
unp->unp_streamlock = olock;
|
||||
mutex_obj_hold(nlock);
|
||||
mutex_enter(nlock);
|
||||
so->so_lock = nlock;
|
||||
mutex_exit(olock);
|
||||
}
|
||||
|
||||
static void
|
||||
unp_free(struct unpcb *unp)
|
||||
{
|
||||
|
||||
if (unp->unp_addr)
|
||||
free(unp->unp_addr, M_SONAME);
|
||||
if (unp->unp_streamlock != NULL)
|
||||
mutex_obj_free(unp->unp_streamlock);
|
||||
free(unp, M_PCB);
|
||||
}
|
||||
|
||||
int
|
||||
unp_output(struct mbuf *m, struct mbuf *control, struct unpcb *unp,
|
||||
|
@ -148,6 +284,9 @@ unp_output(struct mbuf *m, struct mbuf *control, struct unpcb *unp,
|
|||
const struct sockaddr_un *sun;
|
||||
|
||||
so2 = unp->unp_conn->unp_socket;
|
||||
|
||||
KASSERT(solocked(so2));
|
||||
|
||||
if (unp->unp_addr)
|
||||
sun = unp->unp_addr;
|
||||
else
|
||||
|
@ -156,10 +295,12 @@ unp_output(struct mbuf *m, struct mbuf *control, struct unpcb *unp,
|
|||
control = unp_addsockcred(l, control);
|
||||
if (sbappendaddr(&so2->so_rcv, (const struct sockaddr *)sun, m,
|
||||
control) == 0) {
|
||||
so2->so_rcv.sb_overflowed++;
|
||||
sounlock(so2);
|
||||
unp_dispose(control);
|
||||
m_freem(control);
|
||||
m_freem(m);
|
||||
so2->so_rcv.sb_overflowed++;
|
||||
solock(so2);
|
||||
return (ENOBUFS);
|
||||
} else {
|
||||
sorwakeup(so2);
|
||||
|
@ -168,33 +309,38 @@ unp_output(struct mbuf *m, struct mbuf *control, struct unpcb *unp,
|
|||
}
|
||||
|
||||
void
|
||||
unp_setsockaddr(struct unpcb *unp, struct mbuf *nam)
|
||||
unp_setaddr(struct socket *so, struct mbuf *nam, bool peeraddr)
|
||||
{
|
||||
const struct sockaddr_un *sun;
|
||||
struct unpcb *unp;
|
||||
bool ext;
|
||||
|
||||
if (unp->unp_addr)
|
||||
sun = unp->unp_addr;
|
||||
else
|
||||
sun = &sun_noname;
|
||||
nam->m_len = sun->sun_len;
|
||||
if (nam->m_len > MLEN)
|
||||
MEXTMALLOC(nam, nam->m_len, M_WAITOK);
|
||||
memcpy(mtod(nam, void *), sun, (size_t)nam->m_len);
|
||||
}
|
||||
unp = sotounpcb(so);
|
||||
ext = false;
|
||||
|
||||
void
|
||||
unp_setpeeraddr(struct unpcb *unp, struct mbuf *nam)
|
||||
{
|
||||
const struct sockaddr_un *sun;
|
||||
|
||||
if (unp->unp_conn && unp->unp_conn->unp_addr)
|
||||
sun = unp->unp_conn->unp_addr;
|
||||
else
|
||||
sun = &sun_noname;
|
||||
nam->m_len = sun->sun_len;
|
||||
if (nam->m_len > MLEN)
|
||||
MEXTMALLOC(nam, nam->m_len, M_WAITOK);
|
||||
memcpy(mtod(nam, void *), sun, (size_t)nam->m_len);
|
||||
for (;;) {
|
||||
sun = NULL;
|
||||
if (peeraddr) {
|
||||
if (unp->unp_conn && unp->unp_conn->unp_addr)
|
||||
sun = unp->unp_conn->unp_addr;
|
||||
} else {
|
||||
if (unp->unp_addr)
|
||||
sun = unp->unp_addr;
|
||||
}
|
||||
if (sun == NULL)
|
||||
sun = &sun_noname;
|
||||
nam->m_len = sun->sun_len;
|
||||
if (nam->m_len > MLEN && !ext) {
|
||||
sounlock(so);
|
||||
MEXTMALLOC(nam, MAXPATHLEN * 2, M_WAITOK);
|
||||
solock(so);
|
||||
ext = true;
|
||||
} else {
|
||||
KASSERT(nam->m_len <= MAXPATHLEN * 2);
|
||||
memcpy(mtod(nam, void *), sun, (size_t)nam->m_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
|
@ -216,9 +362,12 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
panic("uipc_usrreq: unexpected control mbuf");
|
||||
#endif
|
||||
p = l ? l->l_proc : NULL;
|
||||
if (unp == 0 && req != PRU_ATTACH) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
if (req != PRU_ATTACH) {
|
||||
if (unp == 0) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
}
|
||||
KASSERT(solocked(so));
|
||||
}
|
||||
|
||||
switch (req) {
|
||||
|
@ -237,10 +386,15 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
|
||||
case PRU_BIND:
|
||||
KASSERT(l != NULL);
|
||||
error = unp_bind(unp, nam, l);
|
||||
error = unp_bind(so, nam, l);
|
||||
break;
|
||||
|
||||
case PRU_LISTEN:
|
||||
/*
|
||||
* If the socket can accept a connection, it must be
|
||||
* locked by uipc_lock.
|
||||
*/
|
||||
unp_resetlock(so);
|
||||
if (unp->unp_vnode == 0)
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
@ -259,15 +413,35 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
break;
|
||||
|
||||
case PRU_ACCEPT:
|
||||
unp_setpeeraddr(unp, nam);
|
||||
KASSERT(so->so_lock == uipc_lock);
|
||||
/*
|
||||
* Mark the initiating STREAM socket as connected *ONLY*
|
||||
* after it's been accepted. This prevents a client from
|
||||
* overrunning a server and receiving ECONNREFUSED.
|
||||
*/
|
||||
if (unp->unp_conn != NULL &&
|
||||
(unp->unp_conn->unp_socket->so_state & SS_ISCONNECTING))
|
||||
soisconnected(unp->unp_conn->unp_socket);
|
||||
if (unp->unp_conn == NULL)
|
||||
break;
|
||||
so2 = unp->unp_conn->unp_socket;
|
||||
if (so2->so_state & SS_ISCONNECTING) {
|
||||
KASSERT(solocked2(so, so->so_head));
|
||||
KASSERT(solocked2(so2, so->so_head));
|
||||
soisconnected(so2);
|
||||
}
|
||||
/*
|
||||
* If the connection is fully established, break the
|
||||
* association with uipc_lock and give the connected
|
||||
* pair a seperate lock to share.
|
||||
*/
|
||||
unp_setpeerlocks(so2, so);
|
||||
/*
|
||||
* Only now return peer's address, as we may need to
|
||||
* block in order to allocate memory.
|
||||
*
|
||||
* XXX Minor race: connection can be broken while
|
||||
* lock is dropped in unp_setaddr(). We will return
|
||||
* error == 0 and sun_noname as the peer address.
|
||||
*/
|
||||
unp_setaddr(so, nam, true);
|
||||
break;
|
||||
|
||||
case PRU_SHUTDOWN:
|
||||
|
@ -288,6 +462,7 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
if (unp->unp_conn == 0)
|
||||
break;
|
||||
so2 = unp->unp_conn->unp_socket;
|
||||
KASSERT(solocked2(so, so2));
|
||||
/*
|
||||
* Adjust backpressure on sender
|
||||
* and wakeup any waiting to write.
|
||||
|
@ -316,8 +491,10 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
* forging SCM_CREDS.
|
||||
*/
|
||||
if (control) {
|
||||
KASSERT(l != NULL);
|
||||
if ((error = unp_internalize(&control, l)) != 0) {
|
||||
sounlock(so);
|
||||
error = unp_internalize(&control);
|
||||
solock(so);
|
||||
if (error != 0) {
|
||||
m_freem(control);
|
||||
m_freem(m);
|
||||
break;
|
||||
|
@ -326,11 +503,20 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
switch (so->so_type) {
|
||||
|
||||
case SOCK_DGRAM: {
|
||||
KASSERT(so->so_lock == uipc_lock);
|
||||
if (nam) {
|
||||
if ((so->so_state & SS_ISCONNECTED) != 0)
|
||||
error = EISCONN;
|
||||
else {
|
||||
KASSERT(l != NULL);
|
||||
/*
|
||||
* Note: once connected, the
|
||||
* socket's lock must not be
|
||||
* dropped until we have sent
|
||||
* the message and disconnected.
|
||||
* This is necessary to prevent
|
||||
* intervening control ops, like
|
||||
* another connection.
|
||||
*/
|
||||
error = unp_connect(so, nam, l);
|
||||
}
|
||||
} else {
|
||||
|
@ -338,9 +524,11 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
error = ENOTCONN;
|
||||
}
|
||||
if (error) {
|
||||
sounlock(so);
|
||||
unp_dispose(control);
|
||||
m_freem(control);
|
||||
m_freem(m);
|
||||
solock(so);
|
||||
break;
|
||||
}
|
||||
KASSERT(p != NULL);
|
||||
|
@ -358,6 +546,7 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
break;
|
||||
}
|
||||
so2 = unp->unp_conn->unp_socket;
|
||||
KASSERT(solocked2(so, so2));
|
||||
if (unp->unp_conn->unp_flags & UNP_WANTCRED) {
|
||||
/*
|
||||
* Credentials are passed only once on
|
||||
|
@ -372,10 +561,8 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
* Wake up readers.
|
||||
*/
|
||||
if (control) {
|
||||
if (sbappendcontrol(rcv, m, control) == 0) {
|
||||
unp_dispose(control);
|
||||
m_freem(control);
|
||||
}
|
||||
if (sbappendcontrol(rcv, m, control) != 0)
|
||||
control = NULL;
|
||||
} else
|
||||
sbappend(rcv, m);
|
||||
snd->sb_mbmax -=
|
||||
|
@ -389,6 +576,12 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
sorwakeup(so2);
|
||||
#undef snd
|
||||
#undef rcv
|
||||
if (control != NULL) {
|
||||
sounlock(so);
|
||||
unp_dispose(control);
|
||||
m_freem(control);
|
||||
solock(so);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -397,7 +590,7 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
break;
|
||||
|
||||
case PRU_ABORT:
|
||||
unp_drop(unp, ECONNABORTED);
|
||||
(void)unp_drop(unp, ECONNABORTED);
|
||||
|
||||
KASSERT(so->so_head == NULL);
|
||||
#ifdef DIAGNOSTIC
|
||||
|
@ -411,6 +604,7 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
|
||||
if (so->so_type == SOCK_STREAM && unp->unp_conn != 0) {
|
||||
so2 = unp->unp_conn->unp_socket;
|
||||
KASSERT(solocked2(so, so2));
|
||||
((struct stat *) m)->st_blksize += so2->so_rcv.sb_cc;
|
||||
}
|
||||
((struct stat *) m)->st_dev = NODEV;
|
||||
|
@ -433,11 +627,11 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
break;
|
||||
|
||||
case PRU_SOCKADDR:
|
||||
unp_setsockaddr(unp, nam);
|
||||
unp_setaddr(so, nam, false);
|
||||
break;
|
||||
|
||||
case PRU_PEERADDR:
|
||||
unp_setpeeraddr(unp, nam);
|
||||
unp_setaddr(so, nam, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -459,6 +653,8 @@ uipc_ctloutput(int op, struct socket *so, int level, int optname,
|
|||
struct mbuf *m = *mp;
|
||||
int optval = 0, error = 0;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
if (level != 0) {
|
||||
error = ENOPROTOOPT;
|
||||
if (op == PRCO_SETOPT && m)
|
||||
|
@ -500,6 +696,7 @@ uipc_ctloutput(int op, struct socket *so, int level, int optname,
|
|||
break;
|
||||
|
||||
case PRCO_GETOPT:
|
||||
sounlock(so);
|
||||
switch (optname) {
|
||||
case LOCAL_PEEREID:
|
||||
if (unp->unp_flags & UNP_EIDSVALID) {
|
||||
|
@ -525,6 +722,7 @@ uipc_ctloutput(int op, struct socket *so, int level, int optname,
|
|||
error = ENOPROTOOPT;
|
||||
break;
|
||||
}
|
||||
solock(so);
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
|
@ -552,23 +750,40 @@ unp_attach(struct socket *so)
|
|||
struct unpcb *unp;
|
||||
int error;
|
||||
|
||||
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
|
||||
switch (so->so_type) {
|
||||
|
||||
case SOCK_STREAM:
|
||||
error = soreserve(so, unpst_sendspace, unpst_recvspace);
|
||||
break;
|
||||
|
||||
case SOCK_DGRAM:
|
||||
error = soreserve(so, unpdg_sendspace, unpdg_recvspace);
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("unp_attach");
|
||||
switch (so->so_type) {
|
||||
case SOCK_STREAM:
|
||||
if (so->so_lock == NULL) {
|
||||
/*
|
||||
* XXX Assuming that no socket locks are held,
|
||||
* as this call may sleep.
|
||||
*/
|
||||
so->so_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
|
||||
solock(so);
|
||||
}
|
||||
if (error)
|
||||
return (error);
|
||||
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
|
||||
error = soreserve(so, unpst_sendspace, unpst_recvspace);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
break;
|
||||
|
||||
case SOCK_DGRAM:
|
||||
if (so->so_lock == NULL) {
|
||||
mutex_obj_hold(uipc_lock);
|
||||
so->so_lock = uipc_lock;
|
||||
solock(so);
|
||||
}
|
||||
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
|
||||
error = soreserve(so, unpdg_sendspace, unpdg_recvspace);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("unp_attach");
|
||||
}
|
||||
KASSERT(solocked(so));
|
||||
unp = malloc(sizeof(*unp), M_PCB, M_NOWAIT);
|
||||
if (unp == NULL)
|
||||
return (ENOBUFS);
|
||||
|
@ -582,20 +797,32 @@ unp_attach(struct socket *so)
|
|||
void
|
||||
unp_detach(struct unpcb *unp)
|
||||
{
|
||||
struct socket *so;
|
||||
vnode_t *vp;
|
||||
|
||||
if (unp->unp_vnode) {
|
||||
unp->unp_vnode->v_socket = 0;
|
||||
vrele(unp->unp_vnode);
|
||||
unp->unp_vnode = 0;
|
||||
so = unp->unp_socket;
|
||||
|
||||
retry:
|
||||
if ((vp = unp->unp_vnode) != NULL) {
|
||||
sounlock(so);
|
||||
/* Acquire v_interlock to protect against unp_connect(). */
|
||||
mutex_enter(&vp->v_interlock);
|
||||
vp->v_socket = NULL;
|
||||
vrelel(vp, 0);
|
||||
solock(so);
|
||||
unp->unp_vnode = NULL;
|
||||
}
|
||||
if (unp->unp_conn)
|
||||
unp_disconnect(unp);
|
||||
while (unp->unp_refs)
|
||||
unp_drop(unp->unp_refs, ECONNRESET);
|
||||
soisdisconnected(unp->unp_socket);
|
||||
unp->unp_socket->so_pcb = 0;
|
||||
if (unp->unp_addr)
|
||||
free(unp->unp_addr, M_SONAME);
|
||||
while (unp->unp_refs) {
|
||||
KASSERT(solocked2(so, unp->unp_refs->unp_socket));
|
||||
if (unp_drop(unp->unp_refs, ECONNRESET)) {
|
||||
solock(so);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
soisdisconnected(so);
|
||||
so->so_pcb = NULL;
|
||||
if (unp_rights) {
|
||||
/*
|
||||
* Normally the receive buffer is flushed later,
|
||||
|
@ -604,27 +831,30 @@ unp_detach(struct unpcb *unp)
|
|||
* of those descriptor references after the garbage collector
|
||||
* gets them (resulting in a "panic: closef: count < 0").
|
||||
*/
|
||||
sorflush(unp->unp_socket);
|
||||
free(unp, M_PCB);
|
||||
sorflush(so);
|
||||
unp_free(unp);
|
||||
sounlock(so);
|
||||
unp_gc();
|
||||
solock(so);
|
||||
} else
|
||||
free(unp, M_PCB);
|
||||
unp_free(unp);
|
||||
}
|
||||
|
||||
int
|
||||
unp_bind(struct unpcb *unp, struct mbuf *nam, struct lwp *l)
|
||||
unp_bind(struct socket *so, struct mbuf *nam, struct lwp *l)
|
||||
{
|
||||
struct sockaddr_un *sun;
|
||||
struct unpcb *unp;
|
||||
vnode_t *vp;
|
||||
struct vattr vattr;
|
||||
size_t addrlen;
|
||||
struct proc *p;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
proc_t *p;
|
||||
|
||||
if (unp->unp_vnode != 0)
|
||||
unp = sotounpcb(so);
|
||||
if (unp->unp_vnode != NULL)
|
||||
return (EINVAL);
|
||||
|
||||
if ((unp->unp_flags & UNP_BUSY) != 0) {
|
||||
/*
|
||||
* EALREADY may not be strictly accurate, but since this
|
||||
|
@ -633,13 +863,14 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct lwp *l)
|
|||
return (EALREADY);
|
||||
}
|
||||
unp->unp_flags |= UNP_BUSY;
|
||||
sounlock(so);
|
||||
|
||||
p = l->l_proc;
|
||||
/*
|
||||
* Allocate the new sockaddr. We have to allocate one
|
||||
* extra byte so that we can ensure that the pathname
|
||||
* is nul-terminated.
|
||||
*/
|
||||
p = l->l_proc;
|
||||
addrlen = nam->m_len + 1;
|
||||
sun = malloc(addrlen, M_SONAME, M_WAITOK);
|
||||
m_copydata(nam, 0, nam->m_len, (void *)sun);
|
||||
|
@ -669,13 +900,14 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct lwp *l)
|
|||
if (error)
|
||||
goto bad;
|
||||
vp = nd.ni_vp;
|
||||
solock(so);
|
||||
vp->v_socket = unp->unp_socket;
|
||||
unp->unp_vnode = vp;
|
||||
unp->unp_addrlen = addrlen;
|
||||
unp->unp_addr = sun;
|
||||
unp->unp_connid.unp_pid = p->p_pid;
|
||||
unp->unp_connid.unp_euid = kauth_cred_geteuid(p->p_cred);
|
||||
unp->unp_connid.unp_egid = kauth_cred_getegid(p->p_cred);
|
||||
unp->unp_connid.unp_euid = kauth_cred_geteuid(l->l_cred);
|
||||
unp->unp_connid.unp_egid = kauth_cred_getegid(l->l_cred);
|
||||
unp->unp_flags |= UNP_EIDSBIND;
|
||||
VOP_UNLOCK(vp, 0);
|
||||
unp->unp_flags &= ~UNP_BUSY;
|
||||
|
@ -683,6 +915,7 @@ unp_bind(struct unpcb *unp, struct mbuf *nam, struct lwp *l)
|
|||
|
||||
bad:
|
||||
free(sun, M_SONAME);
|
||||
solock(so);
|
||||
unp->unp_flags &= ~UNP_BUSY;
|
||||
return (error);
|
||||
}
|
||||
|
@ -695,7 +928,6 @@ unp_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
|
|||
struct socket *so2, *so3;
|
||||
struct unpcb *unp, *unp2, *unp3;
|
||||
size_t addrlen;
|
||||
struct proc *p;
|
||||
int error;
|
||||
struct nameidata nd;
|
||||
|
||||
|
@ -708,8 +940,8 @@ unp_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
|
|||
return (EALREADY);
|
||||
}
|
||||
unp->unp_flags |= UNP_BUSY;
|
||||
sounlock(so);
|
||||
|
||||
p = l->l_proc;
|
||||
/*
|
||||
* Allocate a temporary sockaddr. We have to allocate one extra
|
||||
* byte so that we can ensure that the pathname is nul-terminated.
|
||||
|
@ -733,19 +965,34 @@ unp_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
|
|||
}
|
||||
if ((error = VOP_ACCESS(vp, VWRITE, l->l_cred)) != 0)
|
||||
goto bad;
|
||||
/* Acquire v_interlock to protect against unp_detach(). */
|
||||
mutex_enter(&vp->v_interlock);
|
||||
so2 = vp->v_socket;
|
||||
if (so2 == 0) {
|
||||
if (so2 == NULL) {
|
||||
mutex_exit(&vp->v_interlock);
|
||||
error = ECONNREFUSED;
|
||||
goto bad;
|
||||
}
|
||||
if (so->so_type != so2->so_type) {
|
||||
mutex_exit(&vp->v_interlock);
|
||||
error = EPROTOTYPE;
|
||||
goto bad;
|
||||
}
|
||||
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
|
||||
solock(so);
|
||||
unp_resetlock(so);
|
||||
mutex_exit(&vp->v_interlock);
|
||||
if ((so->so_proto->pr_flags & PR_CONNREQUIRED) != 0) {
|
||||
/*
|
||||
* This may seem somewhat fragile but is OK: if we can
|
||||
* see SO_ACCEPTCONN set on the endpoint, then it must
|
||||
* be locked by the domain-wide uipc_lock.
|
||||
*/
|
||||
KASSERT((so->so_options & SO_ACCEPTCONN) == 0 ||
|
||||
so2->so_lock == uipc_lock);
|
||||
if ((so2->so_options & SO_ACCEPTCONN) == 0 ||
|
||||
(so3 = sonewconn(so2, 0)) == 0) {
|
||||
error = ECONNREFUSED;
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
unp2 = sotounpcb(so2);
|
||||
|
@ -758,21 +1005,23 @@ unp_connect(struct socket *so, struct mbuf *nam, struct lwp *l)
|
|||
unp3->unp_addrlen = unp2->unp_addrlen;
|
||||
}
|
||||
unp3->unp_flags = unp2->unp_flags;
|
||||
unp3->unp_connid.unp_pid = p->p_pid;
|
||||
unp3->unp_connid.unp_euid = kauth_cred_geteuid(p->p_cred);
|
||||
unp3->unp_connid.unp_egid = kauth_cred_getegid(p->p_cred);
|
||||
unp3->unp_connid.unp_pid = l->l_proc->p_pid;
|
||||
unp3->unp_connid.unp_euid = kauth_cred_geteuid(l->l_cred);
|
||||
unp3->unp_connid.unp_egid = kauth_cred_getegid(l->l_cred);
|
||||
unp3->unp_flags |= UNP_EIDSVALID;
|
||||
so2 = so3;
|
||||
if (unp2->unp_flags & UNP_EIDSBIND) {
|
||||
unp->unp_connid = unp2->unp_connid;
|
||||
unp->unp_flags |= UNP_EIDSVALID;
|
||||
}
|
||||
so2 = so3;
|
||||
}
|
||||
error = unp_connect2(so, so2, PRU_CONNECT);
|
||||
sounlock(so);
|
||||
bad:
|
||||
vput(vp);
|
||||
bad2:
|
||||
free(sun, M_SONAME);
|
||||
solock(so);
|
||||
unp->unp_flags &= ~UNP_BUSY;
|
||||
return (error);
|
||||
}
|
||||
|
@ -785,6 +1034,20 @@ unp_connect2(struct socket *so, struct socket *so2, int req)
|
|||
|
||||
if (so2->so_type != so->so_type)
|
||||
return (EPROTOTYPE);
|
||||
|
||||
/*
|
||||
* All three sockets involved must be locked by same lock:
|
||||
*
|
||||
* local endpoint (so)
|
||||
* remote endpoint (so2)
|
||||
* queue head (so->so_head, only if PR_CONNREQUIRED)
|
||||
*/
|
||||
KASSERT(solocked2(so, so2));
|
||||
if (so->so_head != NULL) {
|
||||
KASSERT(so->so_lock == uipc_lock);
|
||||
KASSERT(solocked2(so, so->so_head));
|
||||
}
|
||||
|
||||
unp2 = sotounpcb(so2);
|
||||
unp->unp_conn = unp2;
|
||||
switch (so->so_type) {
|
||||
|
@ -803,6 +1066,15 @@ unp_connect2(struct socket *so, struct socket *so2, int req)
|
|||
else
|
||||
soisconnected(so);
|
||||
soisconnected(so2);
|
||||
/*
|
||||
* If the connection is fully established, break the
|
||||
* association with uipc_lock and give the connected
|
||||
* pair a seperate lock to share. For CONNECT2, we
|
||||
* require that the locks already match (the sockets
|
||||
* are created that way).
|
||||
*/
|
||||
if (req == PRU_CONNECT)
|
||||
unp_setpeerlocks(so, so2);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -815,18 +1087,20 @@ void
|
|||
unp_disconnect(struct unpcb *unp)
|
||||
{
|
||||
struct unpcb *unp2 = unp->unp_conn;
|
||||
struct socket *so;
|
||||
|
||||
if (unp2 == 0)
|
||||
return;
|
||||
unp->unp_conn = 0;
|
||||
switch (unp->unp_socket->so_type) {
|
||||
|
||||
so = unp->unp_socket;
|
||||
switch (so->so_type) {
|
||||
case SOCK_DGRAM:
|
||||
if (unp2->unp_refs == unp)
|
||||
unp2->unp_refs = unp->unp_nextref;
|
||||
else {
|
||||
unp2 = unp2->unp_refs;
|
||||
for (;;) {
|
||||
KASSERT(solocked2(so, unp2->unp_socket));
|
||||
if (unp2 == 0)
|
||||
panic("unp_disconnect");
|
||||
if (unp2->unp_nextref == unp)
|
||||
|
@ -836,11 +1110,12 @@ unp_disconnect(struct unpcb *unp)
|
|||
unp2->unp_nextref = unp->unp_nextref;
|
||||
}
|
||||
unp->unp_nextref = 0;
|
||||
unp->unp_socket->so_state &= ~SS_ISCONNECTED;
|
||||
so->so_state &= ~SS_ISCONNECTED;
|
||||
break;
|
||||
|
||||
case SOCK_STREAM:
|
||||
soisdisconnected(unp->unp_socket);
|
||||
KASSERT(solocked2(so, unp2->unp_socket));
|
||||
soisdisconnected(so);
|
||||
unp2->unp_conn = 0;
|
||||
soisdisconnected(unp2->unp_socket);
|
||||
break;
|
||||
|
@ -864,20 +1139,23 @@ unp_shutdown(struct unpcb *unp)
|
|||
socantrcvmore(so);
|
||||
}
|
||||
|
||||
void
|
||||
bool
|
||||
unp_drop(struct unpcb *unp, int errno)
|
||||
{
|
||||
struct socket *so = unp->unp_socket;
|
||||
|
||||
KASSERT(solocked(so));
|
||||
|
||||
so->so_error = errno;
|
||||
unp_disconnect(unp);
|
||||
if (so->so_head) {
|
||||
so->so_pcb = 0;
|
||||
so->so_pcb = NULL;
|
||||
/* sofree() drops the socket lock */
|
||||
sofree(so);
|
||||
if (unp->unp_addr)
|
||||
free(unp->unp_addr, M_SONAME);
|
||||
free(unp, M_PCB);
|
||||
unp_free(unp);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
|
@ -971,7 +1249,8 @@ unp_externalize(struct mbuf *rights, struct lwp *l)
|
|||
|
||||
/*
|
||||
* Now that adding them has succeeded, update all of the
|
||||
* descriptor passing state. */
|
||||
* descriptor passing state.
|
||||
*/
|
||||
rp = (file_t **)CMSG_DATA(cm);
|
||||
for (i = 0; i < nfds; i++) {
|
||||
fp = *rp++;
|
||||
|
@ -1003,7 +1282,7 @@ unp_externalize(struct mbuf *rights, struct lwp *l)
|
|||
}
|
||||
|
||||
int
|
||||
unp_internalize(struct mbuf **controlp, struct lwp *l)
|
||||
unp_internalize(struct mbuf **controlp)
|
||||
{
|
||||
struct filedesc *fdescp = curlwp->l_fd;
|
||||
struct mbuf *control = *controlp;
|
||||
|
@ -1013,8 +1292,6 @@ unp_internalize(struct mbuf **controlp, struct lwp *l)
|
|||
int i, fd, *fdp;
|
||||
int nfds, error;
|
||||
|
||||
KASSERT(l == curlwp);
|
||||
|
||||
error = 0;
|
||||
newcm = NULL;
|
||||
|
||||
|
@ -1212,7 +1489,7 @@ unp_gc(void)
|
|||
atomic_or_uint(&fp->f_flag, FMARK);
|
||||
|
||||
if (fp->f_type != DTYPE_SOCKET ||
|
||||
(so = (struct socket *)fp->f_data) == NULL ||
|
||||
(so = fp->f_data) == NULL ||
|
||||
so->so_proto->pr_domain != &unixdomain ||
|
||||
(so->so_proto->pr_flags&PR_RIGHTS) == 0) {
|
||||
mutex_exit(&fp->f_lock);
|
||||
|
@ -1239,6 +1516,13 @@ unp_gc(void)
|
|||
#endif
|
||||
mutex_exit(&fp->f_lock);
|
||||
|
||||
/*
|
||||
* XXX Locking a socket with filelist_lock held
|
||||
* is ugly. filelist_lock can be taken by the
|
||||
* pagedaemon when reclaiming items from file_cache.
|
||||
* Socket activity could delay the pagedaemon.
|
||||
*/
|
||||
solock(so);
|
||||
unp_scan(so->so_rcv.sb_mb, unp_mark, 0);
|
||||
/*
|
||||
* Mark descriptors referenced from sockets queued
|
||||
|
@ -1252,6 +1536,7 @@ unp_gc(void)
|
|||
unp_scan(so1->so_rcv.sb_mb, unp_mark, 0);
|
||||
}
|
||||
}
|
||||
sounlock(so);
|
||||
}
|
||||
} while (unp_defer);
|
||||
|
||||
|
@ -1318,8 +1603,12 @@ unp_gc(void)
|
|||
|
||||
for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
|
||||
fp = *fpp;
|
||||
if (fp->f_type == DTYPE_SOCKET)
|
||||
if (fp->f_type == DTYPE_SOCKET) {
|
||||
so = fp->f_data;
|
||||
solock(so);
|
||||
sorflush(fp->f_data);
|
||||
sounlock(so);
|
||||
}
|
||||
}
|
||||
for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) {
|
||||
closef(*fpp);
|
||||
|
|
|
@ -1,4 +1,37 @@
|
|||
/* $NetBSD: fifo_vnops.c,v 1.63 2008/03/21 21:55:00 ad Exp $ */
|
||||
/* $NetBSD: fifo_vnops.c,v 1.64 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1993, 1995
|
||||
|
@ -32,7 +65,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.63 2008/03/21 21:55:00 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.64 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -47,11 +80,11 @@ __KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.63 2008/03/21 21:55:00 ad Exp $");
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/kmem.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/event.h>
|
||||
#include <sys/atomic.h>
|
||||
#include <sys/condvar.h>
|
||||
|
||||
#include <miscfs/fifofs/fifo.h>
|
||||
#include <miscfs/genfs/genfs.h>
|
||||
|
@ -63,8 +96,10 @@ __KERNEL_RCSID(0, "$NetBSD: fifo_vnops.c,v 1.63 2008/03/21 21:55:00 ad Exp $");
|
|||
struct fifoinfo {
|
||||
struct socket *fi_readsock;
|
||||
struct socket *fi_writesock;
|
||||
long fi_readers;
|
||||
long fi_writers;
|
||||
kcondvar_t fi_rcv;
|
||||
int fi_readers;
|
||||
kcondvar_t fi_wcv;
|
||||
int fi_writers;
|
||||
};
|
||||
|
||||
int (**fifo_vnodeop_p)(void *);
|
||||
|
@ -153,60 +188,69 @@ fifo_open(void *v)
|
|||
vp = ap->a_vp;
|
||||
p = l->l_proc;
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if ((fip = vp->v_fifoinfo) == NULL) {
|
||||
MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
|
||||
fip = kmem_alloc(sizeof(*fip), KM_SLEEP);
|
||||
vp->v_fifoinfo = fip;
|
||||
error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l);
|
||||
error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, l, NULL);
|
||||
if (error != 0) {
|
||||
free(fip, M_VNODE);
|
||||
kmem_free(fip, sizeof(*fip));
|
||||
vp->v_fifoinfo = NULL;
|
||||
goto done;
|
||||
return (error);
|
||||
}
|
||||
fip->fi_readsock = rso;
|
||||
error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l);
|
||||
error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, l, rso);
|
||||
if (error != 0) {
|
||||
(void)soclose(rso);
|
||||
free(fip, M_VNODE);
|
||||
kmem_free(fip, sizeof(*fip));
|
||||
vp->v_fifoinfo = NULL;
|
||||
goto done;
|
||||
return (error);
|
||||
}
|
||||
fip->fi_writesock = wso;
|
||||
solock(wso);
|
||||
if ((error = unp_connect2(wso, rso, PRU_CONNECT2)) != 0) {
|
||||
sounlock(wso);
|
||||
(void)soclose(wso);
|
||||
(void)soclose(rso);
|
||||
free(fip, M_VNODE);
|
||||
kmem_free(fip, sizeof(*fip));
|
||||
vp->v_fifoinfo = NULL;
|
||||
goto done;
|
||||
return (error);
|
||||
}
|
||||
fip->fi_readers = fip->fi_writers = 0;
|
||||
fip->fi_readers = 0;
|
||||
fip->fi_writers = 0;
|
||||
wso->so_state |= SS_CANTRCVMORE;
|
||||
rso->so_state |= SS_CANTSENDMORE;
|
||||
cv_init(&fip->fi_rcv, "fiford");
|
||||
cv_init(&fip->fi_wcv, "fifowr");
|
||||
} else {
|
||||
wso = fip->fi_writesock;
|
||||
rso = fip->fi_readsock;
|
||||
solock(wso);
|
||||
}
|
||||
|
||||
if (ap->a_mode & FREAD) {
|
||||
if (fip->fi_readers++ == 0) {
|
||||
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
|
||||
if (fip->fi_writers > 0)
|
||||
wakeup(&fip->fi_writers);
|
||||
wso->so_state &= ~SS_CANTSENDMORE;
|
||||
cv_broadcast(&fip->fi_wcv);
|
||||
}
|
||||
}
|
||||
if (ap->a_mode & FWRITE) {
|
||||
if (fip->fi_writers++ == 0) {
|
||||
fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
|
||||
if (fip->fi_readers > 0)
|
||||
wakeup(&fip->fi_readers);
|
||||
rso->so_state &= ~SS_CANTRCVMORE;
|
||||
cv_broadcast(&fip->fi_rcv);
|
||||
}
|
||||
}
|
||||
if (ap->a_mode & FREAD) {
|
||||
if (ap->a_mode & O_NONBLOCK) {
|
||||
} else {
|
||||
while (!soreadable(fip->fi_readsock) && fip->fi_writers == 0) {
|
||||
while (!soreadable(rso) && fip->fi_writers == 0) {
|
||||
VOP_UNLOCK(vp, 0);
|
||||
error = tsleep(&fip->fi_readers,
|
||||
PCATCH | PSOCK, "fifor", 0);
|
||||
error = cv_wait_sig(&fip->fi_rcv,
|
||||
wso->so_lock);
|
||||
sounlock(wso);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (error)
|
||||
goto bad;
|
||||
solock(wso);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -214,25 +258,26 @@ fifo_open(void *v)
|
|||
if (ap->a_mode & O_NONBLOCK) {
|
||||
if (fip->fi_readers == 0) {
|
||||
error = ENXIO;
|
||||
sounlock(wso);
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
while (fip->fi_readers == 0) {
|
||||
VOP_UNLOCK(vp, 0);
|
||||
error = tsleep(&fip->fi_writers,
|
||||
PCATCH | PSOCK, "fifow", 0);
|
||||
error = cv_wait_sig(&fip->fi_wcv,
|
||||
wso->so_lock);
|
||||
sounlock(wso);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (error)
|
||||
goto bad;
|
||||
solock(wso);
|
||||
}
|
||||
}
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
sounlock(wso);
|
||||
return (0);
|
||||
bad:
|
||||
VOP_CLOSE(vp, ap->a_mode, ap->a_cred);
|
||||
done:
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -262,14 +307,13 @@ fifo_read(void *v)
|
|||
#endif
|
||||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if (ap->a_ioflag & IO_NDELAY)
|
||||
rso->so_nbio = 1;
|
||||
startresid = uio->uio_resid;
|
||||
VOP_UNLOCK(ap->a_vp, 0);
|
||||
error = (*rso->so_receive)(rso, (struct mbuf **)0, uio,
|
||||
(struct mbuf **)0, (struct mbuf **)0, (int *)0);
|
||||
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (ap->a_ioflag & IO_NDELAY) {
|
||||
/* XXX Bogus, affects other threads. */
|
||||
rso->so_nbio = 1;
|
||||
}
|
||||
error = (*rso->so_receive)(rso, NULL, uio, NULL, NULL, NULL);
|
||||
/*
|
||||
* Clear EOF indication after first such return.
|
||||
*/
|
||||
|
@ -281,7 +325,7 @@ fifo_read(void *v)
|
|||
ap->a_vp->v_fifoinfo->fi_writers == 0)
|
||||
error = 0;
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -306,16 +350,15 @@ fifo_write(void *v)
|
|||
if (ap->a_uio->uio_rw != UIO_WRITE)
|
||||
panic("fifo_write mode");
|
||||
#endif
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if (ap->a_ioflag & IO_NDELAY)
|
||||
wso->so_nbio = 1;
|
||||
VOP_UNLOCK(ap->a_vp, 0);
|
||||
error = (*wso->so_send)(wso, (struct mbuf *)0, ap->a_uio, 0,
|
||||
(struct mbuf *)0, 0, curlwp /*XXX*/);
|
||||
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (ap->a_ioflag & IO_NDELAY) {
|
||||
/* XXX Bogus, affects other threads. */
|
||||
wso->so_nbio = 1;
|
||||
}
|
||||
error = (*wso->so_send)(wso, NULL, ap->a_uio, 0, NULL, 0, curlwp);
|
||||
if (ap->a_ioflag & IO_NDELAY)
|
||||
wso->so_nbio = 0;
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -363,19 +406,19 @@ fifo_poll(void *v)
|
|||
int a_events;
|
||||
struct lwp *a_l;
|
||||
} */ *ap = v;
|
||||
struct file filetmp;
|
||||
struct socket *so;
|
||||
int revents;
|
||||
|
||||
revents = 0;
|
||||
if (ap->a_events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {
|
||||
filetmp.f_data = ap->a_vp->v_fifoinfo->fi_readsock;
|
||||
if (filetmp.f_data)
|
||||
revents |= soo_poll(&filetmp, ap->a_events);
|
||||
so = ap->a_vp->v_fifoinfo->fi_readsock;
|
||||
if (so)
|
||||
revents |= sopoll(so, ap->a_events);
|
||||
}
|
||||
if (ap->a_events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
|
||||
filetmp.f_data = ap->a_vp->v_fifoinfo->fi_writesock;
|
||||
if (filetmp.f_data)
|
||||
revents |= soo_poll(&filetmp, ap->a_events);
|
||||
so = ap->a_vp->v_fifoinfo->fi_writesock;
|
||||
if (so)
|
||||
revents |= sopoll(so, ap->a_events);
|
||||
}
|
||||
|
||||
return (revents);
|
||||
|
@ -431,35 +474,40 @@ fifo_close(void *v)
|
|||
} */ *ap = v;
|
||||
struct vnode *vp;
|
||||
struct fifoinfo *fip;
|
||||
struct socket *wso, *rso;
|
||||
int isrevoke;
|
||||
|
||||
vp = ap->a_vp;
|
||||
fip = vp->v_fifoinfo;
|
||||
isrevoke = (ap->a_fflag & (FREAD | FWRITE | FNONBLOCK)) == FNONBLOCK;
|
||||
KERNEL_LOCK(1, NULL);
|
||||
wso = fip->fi_writesock;
|
||||
rso = fip->fi_readsock;
|
||||
solock(wso);
|
||||
if (isrevoke) {
|
||||
if (fip->fi_readers != 0) {
|
||||
fip->fi_readers = 0;
|
||||
socantsendmore(fip->fi_writesock);
|
||||
socantsendmore(wso);
|
||||
}
|
||||
if (fip->fi_writers != 0) {
|
||||
fip->fi_writers = 0;
|
||||
socantrcvmore(fip->fi_readsock);
|
||||
socantrcvmore(rso);
|
||||
}
|
||||
} else {
|
||||
if ((ap->a_fflag & FREAD) && --fip->fi_readers == 0)
|
||||
socantsendmore(fip->fi_writesock);
|
||||
socantsendmore(wso);
|
||||
if ((ap->a_fflag & FWRITE) && --fip->fi_writers == 0)
|
||||
socantrcvmore(fip->fi_readsock);
|
||||
socantrcvmore(rso);
|
||||
}
|
||||
/* Shut down if all readers and writers are gone. */
|
||||
if ((fip->fi_readers + fip->fi_writers) == 0) {
|
||||
(void) soclose(fip->fi_readsock);
|
||||
(void) soclose(fip->fi_writesock);
|
||||
FREE(fip, M_VNODE);
|
||||
sounlock(wso);
|
||||
(void) soclose(rso);
|
||||
(void) soclose(wso);
|
||||
cv_destroy(&fip->fi_rcv);
|
||||
cv_destroy(&fip->fi_wcv);
|
||||
kmem_free(fip, sizeof(*fip));
|
||||
vp->v_fifoinfo = NULL;
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
} else
|
||||
sounlock(wso);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -488,7 +536,7 @@ fifo_printinfo(struct vnode *vp)
|
|||
struct fifoinfo *fip;
|
||||
|
||||
fip = vp->v_fifoinfo;
|
||||
printf(", fifo with %ld readers and %ld writers",
|
||||
printf(", fifo with %d readers and %d writers",
|
||||
fip->fi_readers, fip->fi_writers);
|
||||
}
|
||||
|
||||
|
@ -529,24 +577,32 @@ filt_fifordetach(struct knote *kn)
|
|||
struct socket *so;
|
||||
|
||||
so = (struct socket *)kn->kn_hook;
|
||||
solock(so);
|
||||
SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext);
|
||||
if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist))
|
||||
so->so_rcv.sb_flags &= ~SB_KNOTE;
|
||||
sounlock(so);
|
||||
}
|
||||
|
||||
static int
|
||||
filt_fiforead(struct knote *kn, long hint)
|
||||
{
|
||||
struct socket *so;
|
||||
int rv;
|
||||
|
||||
so = (struct socket *)kn->kn_hook;
|
||||
if (hint != NOTE_SUBMIT)
|
||||
solock(so);
|
||||
kn->kn_data = so->so_rcv.sb_cc;
|
||||
if (so->so_state & SS_CANTRCVMORE) {
|
||||
kn->kn_flags |= EV_EOF;
|
||||
return (1);
|
||||
}
|
||||
kn->kn_flags &= ~EV_EOF;
|
||||
return (kn->kn_data > 0);
|
||||
rv = (kn->kn_data > 0);
|
||||
if (hint != NOTE_SUBMIT)
|
||||
sounlock(so);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -555,24 +611,32 @@ filt_fifowdetach(struct knote *kn)
|
|||
struct socket *so;
|
||||
|
||||
so = (struct socket *)kn->kn_hook;
|
||||
solock(so);
|
||||
SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext);
|
||||
if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))
|
||||
so->so_snd.sb_flags &= ~SB_KNOTE;
|
||||
sounlock(so);
|
||||
}
|
||||
|
||||
static int
|
||||
filt_fifowrite(struct knote *kn, long hint)
|
||||
{
|
||||
struct socket *so;
|
||||
int rv;
|
||||
|
||||
so = (struct socket *)kn->kn_hook;
|
||||
if (hint != NOTE_SUBMIT)
|
||||
sounlock(so);
|
||||
kn->kn_data = sbspace(&so->so_snd);
|
||||
if (so->so_state & SS_CANTSENDMORE) {
|
||||
kn->kn_flags |= EV_EOF;
|
||||
return (1);
|
||||
}
|
||||
kn->kn_flags &= ~EV_EOF;
|
||||
return (kn->kn_data >= so->so_snd.sb_lowat);
|
||||
rv = (kn->kn_data >= so->so_snd.sb_lowat);
|
||||
if (hint != NOTE_SUBMIT)
|
||||
sounlock(so);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const struct filterops fiforead_filtops =
|
||||
|
@ -607,7 +671,10 @@ fifo_kqfilter(void *v)
|
|||
|
||||
ap->a_kn->kn_hook = so;
|
||||
|
||||
solock(so);
|
||||
SLIST_INSERT_HEAD(&sb->sb_sel.sel_klist, ap->a_kn, kn_selnext);
|
||||
sb->sb_flags |= SB_KNOTE;
|
||||
sounlock(so);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: portal_vnops.c,v 1.78 2008/03/21 21:55:00 ad Exp $ */
|
||||
/* $NetBSD: portal_vnops.c,v 1.79 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -40,7 +40,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: portal_vnops.c,v 1.78 2008/03/21 21:55:00 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: portal_vnops.c,v 1.79 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -254,8 +254,7 @@ portal_connect(so, so2)
|
|||
struct unpcb *unp2;
|
||||
struct unpcb *unp3;
|
||||
|
||||
if (so2 == 0)
|
||||
return (ECONNREFUSED);
|
||||
KASSERT(solocked2(so, so2));
|
||||
|
||||
if (so->so_type != so2->so_type)
|
||||
return (EPROTOTYPE);
|
||||
|
@ -289,11 +288,10 @@ portal_open(v)
|
|||
int a_mode;
|
||||
kauth_cred_t a_cred;
|
||||
} */ *ap = v;
|
||||
struct socket *so = 0;
|
||||
struct socket *so = 0, *so2;
|
||||
struct portalnode *pt;
|
||||
struct lwp *l = curlwp;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
int s;
|
||||
struct uio auio;
|
||||
struct iovec aiov[2];
|
||||
int res;
|
||||
|
@ -324,11 +322,17 @@ portal_open(v)
|
|||
|
||||
pt = VTOPORTAL(vp);
|
||||
fmp = VFSTOPORTAL(vp->v_mount);
|
||||
so2 = fmp->pm_server->f_data;
|
||||
|
||||
if (so2 == NULL) {
|
||||
/* XXX very fishy */
|
||||
return ECONNREFUSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new socket.
|
||||
*/
|
||||
error = socreate(AF_LOCAL, &so, SOCK_STREAM, 0, l);
|
||||
error = socreate(AF_LOCAL, &so, SOCK_STREAM, 0, l, so2);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
|
@ -336,16 +340,21 @@ portal_open(v)
|
|||
* Reserve some buffer space
|
||||
*/
|
||||
res = pt->pt_size + sizeof(pcred) + 512; /* XXX */
|
||||
solock(so);
|
||||
error = soreserve(so, res, res);
|
||||
if (error)
|
||||
if (error) {
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Kick off connection
|
||||
*/
|
||||
error = portal_connect(so, (struct socket *)fmp->pm_server->f_data);
|
||||
if (error)
|
||||
error = portal_connect(so, so2);
|
||||
if (error) {
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for connection to complete
|
||||
|
@ -360,19 +369,17 @@ portal_open(v)
|
|||
* will happen if the server dies. Sleep for 5 second intervals
|
||||
* and keep polling the reference count. XXX.
|
||||
*/
|
||||
s = splsoftnet();
|
||||
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
|
||||
if (fmp->pm_server->f_count == 1) {
|
||||
error = ECONNREFUSED;
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
(void) tsleep(&so->so_timeo, PSOCK, "portalcon", 5 * hz);
|
||||
sowait(so, 5 * hz);
|
||||
}
|
||||
splx(s);
|
||||
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
|
@ -383,7 +390,7 @@ portal_open(v)
|
|||
so->so_snd.sb_timeo = 0;
|
||||
so->so_rcv.sb_flags |= SB_NOINTR;
|
||||
so->so_snd.sb_flags |= SB_NOINTR;
|
||||
|
||||
sounlock(so);
|
||||
|
||||
pcred.pcr_flag = ap->a_mode;
|
||||
pcred.pcr_uid = kauth_cred_geteuid(ap->a_cred);
|
||||
|
@ -402,8 +409,7 @@ portal_open(v)
|
|||
auio.uio_resid = aiov[0].iov_len + aiov[1].iov_len;
|
||||
UIO_SETUP_SYSSPACE(&auio);
|
||||
|
||||
error = (*so->so_send)(so, (struct mbuf *) 0, &auio,
|
||||
(struct mbuf *) 0, (struct mbuf *) 0, 0, l);
|
||||
error = (*so->so_send)(so, NULL, &auio, NULL, NULL, 0, l);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
|
@ -508,7 +514,9 @@ bad:;
|
|||
}
|
||||
|
||||
if (so) {
|
||||
solock(so);
|
||||
soshutdown(so, 2);
|
||||
sounlock(so);
|
||||
soclose(so);
|
||||
}
|
||||
return (error);
|
||||
|
|
10
sys/net/if.c
10
sys/net/if.c
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: if.c,v 1.218 2008/02/29 21:23:55 dyoung Exp $ */
|
||||
/* $NetBSD: if.c,v 1.219 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -97,7 +97,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.218 2008/02/29 21:23:55 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.219 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
|
@ -1637,13 +1637,15 @@ ifioctl(struct socket *so, u_long cmd, void *data, struct lwp *l)
|
|||
break;
|
||||
if (so->so_proto == NULL)
|
||||
return EOPNOTSUPP;
|
||||
solock(so);
|
||||
#ifdef COMPAT_OSOCK
|
||||
error = compat_ifioctl(so, ocmd, cmd, data, l);
|
||||
#else
|
||||
error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
|
||||
(struct mbuf *)cmd, (struct mbuf *)data,
|
||||
(struct mbuf *)ifp, l));
|
||||
#endif
|
||||
sounlock(so);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_etherip.c,v 1.18 2008/04/05 13:53:07 cegger Exp $ */
|
||||
/* $NetBSD: if_etherip.c,v 1.19 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006, Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
|
||||
|
@ -29,7 +29,7 @@
|
|||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2003, 2004 The NetBSD Foundation.
|
||||
* Copyright (c) 2003, 2004, 2008 The NetBSD Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -86,7 +86,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_etherip.c,v 1.18 2008/04/05 13:53:07 cegger Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_etherip.c,v 1.19 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "bpfilter.h"
|
||||
|
@ -103,6 +103,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_etherip.c,v 1.18 2008/04/05 13:53:07 cegger Exp $
|
|||
#include <sys/queue.h>
|
||||
#include <sys/kauth.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/intr.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
@ -361,12 +362,13 @@ etheripintr(void *arg)
|
|||
struct mbuf *m;
|
||||
int s, error;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
for (;;) {
|
||||
s = splnet();
|
||||
IFQ_DEQUEUE(&ifp->if_snd, m);
|
||||
splx(s);
|
||||
if (m == NULL)
|
||||
return;
|
||||
break;
|
||||
|
||||
#if NBPFILTER > 0
|
||||
if (ifp->if_bpf)
|
||||
|
@ -393,6 +395,7 @@ etheripintr(void *arg)
|
|||
ifp->if_flags &= ~IFF_OACTIVE;
|
||||
} else m_freem(m);
|
||||
}
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_gre.c,v 1.129 2008/04/03 21:40:59 dyoung Exp $ */
|
||||
/* $NetBSD: if_gre.c,v 1.130 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -47,7 +47,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.129 2008/04/03 21:40:59 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.130 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_gre.h"
|
||||
#include "opt_inet.h"
|
||||
|
@ -544,24 +544,23 @@ gre_sosend(struct socket *so, struct mbuf *top, struct lwp *l)
|
|||
struct mbuf **mp;
|
||||
struct proc *p;
|
||||
long space, resid;
|
||||
int error, s;
|
||||
int error;
|
||||
|
||||
p = l->l_proc;
|
||||
|
||||
resid = top->m_pkthdr.len;
|
||||
if (p)
|
||||
l->l_ru.ru_msgsnd++;
|
||||
#define snderr(errno) { error = errno; splx(s); goto release; }
|
||||
#define snderr(errno) { error = errno; goto release; }
|
||||
|
||||
solock(so);
|
||||
if ((error = sblock(&so->so_snd, M_NOWAIT)) != 0)
|
||||
goto out;
|
||||
s = splsoftnet();
|
||||
if (so->so_state & SS_CANTSENDMORE)
|
||||
snderr(EPIPE);
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
splx(s);
|
||||
goto release;
|
||||
}
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0) {
|
||||
|
@ -576,27 +575,19 @@ gre_sosend(struct socket *so, struct mbuf *top, struct lwp *l)
|
|||
snderr(EMSGSIZE);
|
||||
if (space < resid)
|
||||
snderr(EWOULDBLOCK);
|
||||
splx(s);
|
||||
mp = ⊤
|
||||
/*
|
||||
* Data is prepackaged in "top".
|
||||
*/
|
||||
s = splsoftnet();
|
||||
|
||||
if (so->so_state & SS_CANTSENDMORE)
|
||||
snderr(EPIPE);
|
||||
|
||||
error = (*so->so_proto->pr_usrreq)(so, PRU_SEND, top, NULL, NULL, l);
|
||||
splx(s);
|
||||
|
||||
top = NULL;
|
||||
mp = ⊤
|
||||
if (error != 0)
|
||||
goto release;
|
||||
|
||||
release:
|
||||
sbunlock(&so->so_snd);
|
||||
out:
|
||||
sounlock(so);
|
||||
if (top != NULL)
|
||||
m_freem(top);
|
||||
return error;
|
||||
|
@ -610,7 +601,7 @@ static int
|
|||
gre_soreceive(struct socket *so, struct mbuf **mp0)
|
||||
{
|
||||
struct mbuf *m, **mp;
|
||||
int flags, len, error, s, type;
|
||||
int flags, len, error, type;
|
||||
const struct protosw *pr;
|
||||
struct mbuf *nextrecord;
|
||||
|
||||
|
@ -625,14 +616,14 @@ gre_soreceive(struct socket *so, struct mbuf **mp0)
|
|||
|
||||
KASSERT(pr->pr_flags & PR_ATOMIC);
|
||||
|
||||
solock(so);
|
||||
if (so->so_state & SS_ISCONFIRMING)
|
||||
(*pr->pr_usrreq)(so, PRU_RCVD, NULL, NULL, NULL, curlwp);
|
||||
|
||||
restart:
|
||||
if ((error = sblock(&so->so_rcv, M_NOWAIT)) != 0)
|
||||
if ((error = sblock(&so->so_rcv, M_NOWAIT)) != 0) {
|
||||
sounlock(so);
|
||||
return error;
|
||||
s = splsoftnet();
|
||||
|
||||
}
|
||||
m = so->so_rcv.sb_mb;
|
||||
/*
|
||||
* If we have less data than requested, do not block awaiting more.
|
||||
|
@ -796,13 +787,12 @@ gre_soreceive(struct socket *so, struct mbuf **mp0)
|
|||
if (*mp0 == NULL && (flags & MSG_EOR) == 0 &&
|
||||
(so->so_state & SS_CANTRCVMORE) == 0) {
|
||||
sbunlock(&so->so_rcv);
|
||||
splx(s);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
release:
|
||||
sbunlock(&so->so_rcv);
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1057,6 +1047,7 @@ gre_getnames(struct socket *so, struct lwp *l, struct sockaddr_storage *src,
|
|||
|
||||
ss = mtod(m, struct sockaddr_storage *);
|
||||
|
||||
solock(so);
|
||||
if ((rc = gre_getsockname(so, m, l)) != 0)
|
||||
goto out;
|
||||
*src = *ss;
|
||||
|
@ -1064,8 +1055,8 @@ gre_getnames(struct socket *so, struct lwp *l, struct sockaddr_storage *src,
|
|||
if ((rc = gre_getpeername(so, m, l)) != 0)
|
||||
goto out;
|
||||
*dst = *ss;
|
||||
|
||||
out:
|
||||
sounlock(so);
|
||||
m_freem(m);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_ppp.c,v 1.121 2008/02/07 01:22:01 dyoung Exp $ */
|
||||
/* $NetBSD: if_ppp.c,v 1.122 2008/04/24 11:38:37 ad Exp $ */
|
||||
/* Id: if_ppp.c,v 1.6 1997/03/04 03:33:00 paulus Exp */
|
||||
|
||||
/*
|
||||
|
@ -102,7 +102,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.121 2008/02/07 01:22:01 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.122 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "ppp.h"
|
||||
|
||||
|
@ -128,6 +128,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.121 2008/02/07 01:22:01 dyoung Exp $");
|
|||
#include <sys/kauth.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/simplelock.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
|
@ -1268,6 +1269,7 @@ pppintr(void *arg)
|
|||
struct mbuf *m;
|
||||
int s;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
if (!(sc->sc_flags & SC_TBUSY)
|
||||
&& (IFQ_IS_EMPTY(&sc->sc_if.if_snd) == 0 || sc->sc_fastq.ifq_head
|
||||
|| sc->sc_outm)) {
|
||||
|
@ -1284,6 +1286,7 @@ pppintr(void *arg)
|
|||
break;
|
||||
ppp_inproc(sc, m);
|
||||
}
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
#ifdef PPP_COMPRESS
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_pppoe.c,v 1.84 2008/02/20 17:05:53 matt Exp $ */
|
||||
/* $NetBSD: if_pppoe.c,v 1.85 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.84 2008/02/20 17:05:53 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.85 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "pppoe.h"
|
||||
#include "bpfilter.h"
|
||||
|
@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.84 2008/02/20 17:05:53 matt Exp $");
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/kauth.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
|
@ -363,7 +364,9 @@ static void
|
|||
pppoe_softintr_handler(void *dummy)
|
||||
{
|
||||
/* called at splsoftnet() */
|
||||
mutex_enter(softnet_lock);
|
||||
pppoe_input();
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/* called at appropriate protection level */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_sl.c,v 1.110 2008/02/07 01:22:01 dyoung Exp $ */
|
||||
/* $NetBSD: if_sl.c,v 1.111 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1989, 1992, 1993
|
||||
|
@ -60,7 +60,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_sl.c,v 1.110 2008/02/07 01:22:01 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_sl.c,v 1.111 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "bpfilter.h"
|
||||
|
@ -77,6 +77,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_sl.c,v 1.110 2008/02/07 01:22:01 dyoung Exp $");
|
|||
#include <sys/conf.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socketvar.h>
|
||||
#if __NetBSD__
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kauth.h>
|
||||
|
@ -697,6 +698,7 @@ slintr(void *arg)
|
|||
/*
|
||||
* Output processing loop.
|
||||
*/
|
||||
mutex_enter(softnet_lock);
|
||||
for (;;) {
|
||||
#ifdef INET
|
||||
struct ip *ip;
|
||||
|
@ -965,6 +967,7 @@ slintr(void *arg)
|
|||
splx(s);
|
||||
#endif
|
||||
}
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_strip.c,v 1.85 2008/02/20 17:05:53 matt Exp $ */
|
||||
/* $NetBSD: if_strip.c,v 1.86 2008/04/24 11:38:37 ad Exp $ */
|
||||
/* from: NetBSD: if_sl.c,v 1.38 1996/02/13 22:00:23 christos Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -87,7 +87,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_strip.c,v 1.85 2008/02/20 17:05:53 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_strip.c,v 1.86 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "bpfilter.h"
|
||||
|
@ -111,6 +111,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_strip.c,v 1.85 2008/02/20 17:05:53 matt Exp $");
|
|||
#include <sys/syslog.h>
|
||||
#include <sys/cpu.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
@ -1068,6 +1069,7 @@ stripintr(void *arg)
|
|||
/*
|
||||
* Output processing loop.
|
||||
*/
|
||||
mutex_enter(softnet_lock);
|
||||
for (;;) {
|
||||
#ifdef INET
|
||||
struct ip *ip;
|
||||
|
@ -1259,6 +1261,7 @@ stripintr(void *arg)
|
|||
splx(s);
|
||||
#endif
|
||||
}
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: raw_cb.c,v 1.18 2007/03/04 06:03:18 christos Exp $ */
|
||||
/* $NetBSD: raw_cb.c,v 1.19 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_cb.c,v 1.18 2007/03/04 06:03:18 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_cb.c,v 1.19 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -98,7 +98,10 @@ raw_detach(struct rawcb *rp)
|
|||
struct socket *so = rp->rcb_socket;
|
||||
|
||||
so->so_pcb = 0;
|
||||
KASSERT(so->so_lock == softnet_lock); /* XXX */
|
||||
/* sofree drops the socket's lock. */
|
||||
sofree(so);
|
||||
mutex_enter(softnet_lock);
|
||||
LIST_REMOVE(rp, rcb_list);
|
||||
#ifdef notdef
|
||||
if (rp->rcb_laddr)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: raw_usrreq.c,v 1.33 2007/05/06 06:21:26 dyoung Exp $ */
|
||||
/* $NetBSD: raw_usrreq.c,v 1.34 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.33 2007/05/06 06:21:26 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.34 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
|
@ -51,6 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.33 2007/05/06 06:21:26 dyoung Exp $
|
|||
#include <net/raw_cb.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
/*
|
||||
* Initialize raw connection block q.
|
||||
*/
|
||||
|
@ -86,6 +87,8 @@ raw_input(struct mbuf *m0, ...)
|
|||
struct sockproto *proto;
|
||||
struct sockaddr *src, *dst;
|
||||
|
||||
KASSERT(mutex_owned(softnet_lock));
|
||||
|
||||
va_start(ap, m0);
|
||||
proto = va_arg(ap, struct sockproto *);
|
||||
src = va_arg(ap, struct sockaddr *);
|
||||
|
@ -173,6 +176,7 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
return (EOPNOTSUPP);
|
||||
|
||||
s = splsoftnet();
|
||||
KERNEL_LOCK(1, NULL);
|
||||
rp = sotorawcb(so);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (req != PRU_SEND && req != PRU_SENDOOB && control)
|
||||
|
@ -191,6 +195,7 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
* the appropriate raw interface routine.
|
||||
*/
|
||||
case PRU_ATTACH:
|
||||
sosetlock(so);
|
||||
if (l == NULL)
|
||||
break;
|
||||
|
||||
|
@ -310,6 +315,7 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
}
|
||||
|
||||
release:
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rtsock.c,v 1.100 2008/03/29 13:00:43 yamt Exp $ */
|
||||
/* $NetBSD: rtsock.c,v 1.101 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -61,7 +61,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.100 2008/03/29 13:00:43 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.101 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
|
@ -160,6 +160,7 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
int s;
|
||||
|
||||
if (req == PRU_ATTACH) {
|
||||
sosetlock(so);
|
||||
MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
|
||||
if ((so->so_pcb = rp) != NULL)
|
||||
memset(so->so_pcb, 0, sizeof(*rp));
|
||||
|
@ -1173,6 +1174,8 @@ route_intr(void *cookie)
|
|||
struct mbuf *m;
|
||||
int s;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
while (!IF_IS_EMPTY(&route_intrq)) {
|
||||
s = splnet();
|
||||
IF_DEQUEUE(&route_intrq, m);
|
||||
|
@ -1182,6 +1185,8 @@ route_intr(void *cookie)
|
|||
proto.sp_protocol = M_GETCTX(m, uintptr_t);
|
||||
raw_input(m, &proto, &route_src, &route_dst);
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1211,12 +1216,15 @@ rt_init(void)
|
|||
{
|
||||
|
||||
route_intrq.ifq_maxlen = route_maxqlen;
|
||||
route_sih = softint_establish(SOFTINT_NET, route_intr, NULL);
|
||||
route_sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
|
||||
route_intr, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Definitions of protocols supported in the ROUTE domain.
|
||||
*/
|
||||
PR_WRAP_USRREQ(route_usrreq)
|
||||
#define route_usrreq route_usrreq_wrapper
|
||||
|
||||
const struct protosw routesw[] = {
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: aarp.c,v 1.26 2007/12/04 10:22:34 dyoung Exp $ */
|
||||
/* $NetBSD: aarp.c,v 1.27 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1991 Regents of The University of Michigan.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: aarp.c,v 1.26 2007/12/04 10:22:34 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: aarp.c,v 1.27 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_mbuftrace.h"
|
||||
|
||||
|
@ -40,6 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: aarp.c,v 1.26 2007/12/04 10:22:34 dyoung Exp $");
|
|||
#include <sys/mbuf.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_ether.h>
|
||||
|
@ -106,6 +107,7 @@ aarptimer(void *ignored)
|
|||
struct aarptab *aat;
|
||||
int i, s;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
callout_reset(&aarptimer_callout, AARPT_AGE * hz, aarptimer, NULL);
|
||||
aat = aarptab;
|
||||
for (i = 0; i < AARPTAB_SIZE; i++, aat++) {
|
||||
|
@ -119,6 +121,7 @@ aarptimer(void *ignored)
|
|||
aarptfree(aat);
|
||||
splx(s);
|
||||
}
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -545,6 +548,8 @@ aarpprobe(arp)
|
|||
struct sockaddr sa;
|
||||
struct ifnet *ifp = arp;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
|
||||
/*
|
||||
* We need to check whether the output ethernet type should
|
||||
* be phase 1 or 2. We have the interface that we'll be sending
|
||||
|
@ -560,18 +565,22 @@ aarpprobe(arp)
|
|||
}
|
||||
if (ia == NULL) { /* serious error XXX */
|
||||
printf("aarpprobe why did this happen?!\n");
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
if (aa->aa_probcnt <= 0) {
|
||||
aa->aa_flags &= ~AFA_PROBING;
|
||||
wakeup(aa);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
} else {
|
||||
callout_reset(&aa->aa_probe_ch, hz / 5, aarpprobe, arp);
|
||||
}
|
||||
|
||||
if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
|
||||
if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
MCLAIM(m, &aarp_mowner);
|
||||
m->m_len = sizeof(*ea);
|
||||
|
@ -595,8 +604,10 @@ aarpprobe(arp)
|
|||
sizeof(eh->ether_dhost));
|
||||
eh->ether_type = 0; /* if_output will treat as 802 */
|
||||
M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
|
||||
if (!m)
|
||||
if (!m) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
llc = mtod(m, struct llc *);
|
||||
llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
|
||||
|
@ -627,6 +638,7 @@ aarpprobe(arp)
|
|||
sa.sa_family = AF_UNSPEC;
|
||||
(*ifp->if_output) (ifp, m, &sa, NULL); /* XXX */
|
||||
aa->aa_probcnt--;
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: at_proto.c,v 1.15 2007/08/30 02:17:36 dyoung Exp $ */
|
||||
/* $NetBSD: at_proto.c,v 1.16 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1991 Regents of The University of Michigan.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: at_proto.c,v 1.15 2007/08/30 02:17:36 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: at_proto.c,v 1.16 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -50,6 +50,9 @@ __KERNEL_RCSID(0, "$NetBSD: at_proto.c,v 1.15 2007/08/30 02:17:36 dyoung Exp $")
|
|||
|
||||
DOMAIN_DEFINE(atalkdomain); /* forward declare and add to link set */
|
||||
|
||||
PR_WRAP_USRREQ(ddp_usrreq)
|
||||
#define ddp_usrreq ddp_usrreq_wrapper
|
||||
|
||||
const struct protosw atalksw[] = {
|
||||
{
|
||||
.pr_type = SOCK_DGRAM,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ddp_input.c,v 1.18 2008/04/23 15:17:42 thorpej Exp $ */
|
||||
/* $NetBSD: ddp_input.c,v 1.19 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1994 Regents of The University of Michigan.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.18 2008/04/23 15:17:42 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.19 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -67,6 +67,7 @@ atintr()
|
|||
struct at_ifaddr *aa;
|
||||
int s;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
for (;;) {
|
||||
s = splnet();
|
||||
|
||||
|
@ -127,6 +128,7 @@ atintr()
|
|||
ddp_input(m, ifp, &elh, 1);
|
||||
}
|
||||
}
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
struct route forwro;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ddp_usrreq.c,v 1.31 2008/04/23 15:17:42 thorpej Exp $ */
|
||||
/* $NetBSD: ddp_usrreq.c,v 1.32 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990,1991 Regents of The University of Michigan.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.31 2008/04/23 15:17:42 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.32 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_mbuftrace.h"
|
||||
|
||||
|
@ -96,7 +96,9 @@ ddp_usrreq(so, req, m, addr, rights, l)
|
|||
(struct ifnet *) rights, l));
|
||||
}
|
||||
if (req == PRU_PURGEIF) {
|
||||
mutex_enter(softnet_lock);
|
||||
at_purgeif((struct ifnet *) rights);
|
||||
mutex_exit(softnet_lock);
|
||||
return (0);
|
||||
}
|
||||
if (rights && rights->m_len) {
|
||||
|
@ -113,6 +115,7 @@ ddp_usrreq(so, req, m, addr, rights, l)
|
|||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sosetlock(so);
|
||||
if ((error = at_pcballoc(so)) != 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -471,7 +474,9 @@ at_pcbdetach(so, ddp)
|
|||
{
|
||||
soisdisconnected(so);
|
||||
so->so_pcb = 0;
|
||||
/* sofree drops the lock */
|
||||
sofree(so);
|
||||
mutex_enter(softnet_lock);
|
||||
|
||||
/* remove ddp from ddp_ports list */
|
||||
if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT &&
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bluetooth.h,v 1.6 2007/09/17 01:23:17 rillig Exp $ */
|
||||
/* $NetBSD: bluetooth.h,v 1.7 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -144,6 +144,8 @@ extern int bluetooth_debug;
|
|||
# define UNKNOWN(x) ((void)0)
|
||||
#endif /* BLUETOOTH_DEBUG */
|
||||
|
||||
extern kmutex_t *bt_lock;
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _NETBT_BLUETOOTH_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: bt_proto.c,v 1.9 2007/11/20 20:18:00 plunky Exp $ */
|
||||
/* $NetBSD: bt_proto.c,v 1.10 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: bt_proto.c,v 1.9 2007/11/20 20:18:00 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: bt_proto.c,v 1.10 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/domain.h>
|
||||
|
@ -50,6 +50,28 @@ __KERNEL_RCSID(0, "$NetBSD: bt_proto.c,v 1.9 2007/11/20 20:18:00 plunky Exp $");
|
|||
|
||||
DOMAIN_DEFINE(btdomain); /* forward declare and add to link set */
|
||||
|
||||
static void bt_init(void);
|
||||
|
||||
PR_WRAP_CTLOUTPUT(hci_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(sco_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(l2cap_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(rfcomm_ctloutput)
|
||||
|
||||
#define hci_ctloutput hci_ctloutput_wrapper
|
||||
#define sco_ctloutput sco_ctloutput_wrapper
|
||||
#define l2cap_ctloutput l2cap_ctloutput_wrapper
|
||||
#define rfcomm_ctloutput rfcomm_ctloutput_wrapper
|
||||
|
||||
PR_WRAP_USRREQ(hci_usrreq)
|
||||
PR_WRAP_USRREQ(sco_usrreq)
|
||||
PR_WRAP_USRREQ(l2cap_usrreq)
|
||||
PR_WRAP_USRREQ(rfcomm_usrreq)
|
||||
|
||||
#define hci_usrreq hci_usrreq_wrapper
|
||||
#define sco_usrreq sco_usrreq_wrapper
|
||||
#define l2cap_usrreq l2cap_usrreq_wrapper
|
||||
#define rfcomm_usrreq rfcomm_usrreq_wrapper
|
||||
|
||||
const struct protosw btsw[] = {
|
||||
{ /* raw HCI commands */
|
||||
.pr_type = SOCK_RAW,
|
||||
|
@ -88,6 +110,16 @@ const struct protosw btsw[] = {
|
|||
struct domain btdomain = {
|
||||
.dom_family = AF_BLUETOOTH,
|
||||
.dom_name = "bluetooth",
|
||||
.dom_init = bt_init,
|
||||
.dom_protosw = btsw,
|
||||
.dom_protoswNPROTOSW = &btsw[__arraycount(btsw)],
|
||||
};
|
||||
|
||||
kmutex_t *bt_lock;
|
||||
|
||||
static void
|
||||
bt_init(void)
|
||||
{
|
||||
|
||||
bt_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hci.h,v 1.25 2008/03/17 09:16:17 plunky Exp $ */
|
||||
/* $NetBSD: hci.h,v 1.26 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -54,7 +54,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: hci.h,v 1.25 2008/03/17 09:16:17 plunky Exp $
|
||||
* $Id: hci.h,v 1.26 2008/04/24 11:38:37 ad Exp $
|
||||
* $FreeBSD: src/sys/netgraph/bluetooth/include/ng_hci.h,v 1.6 2005/01/07 01:45:43 imp Exp $
|
||||
*/
|
||||
|
||||
|
@ -2360,6 +2360,7 @@ struct btreq {
|
|||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/condvar.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
struct l2cap_channel;
|
||||
|
@ -2463,6 +2464,7 @@ struct hci_unit {
|
|||
/* device info */
|
||||
bdaddr_t hci_bdaddr; /* device address */
|
||||
uint16_t hci_flags; /* see BTF_ above */
|
||||
kcondvar_t hci_init; /* sleep on this */
|
||||
|
||||
uint16_t hci_packet_type; /* packet types */
|
||||
uint16_t hci_acl_mask; /* ACL packet capabilities */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hci_event.c,v 1.17 2008/03/17 09:16:17 plunky Exp $ */
|
||||
/* $NetBSD: hci_event.c,v 1.18 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.17 2008/03/17 09:16:17 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.18 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -839,7 +839,7 @@ hci_cmd_read_bdaddr(struct hci_unit *unit, struct mbuf *m)
|
|||
|
||||
unit->hci_flags &= ~BTF_INIT_BDADDR;
|
||||
|
||||
wakeup(unit);
|
||||
cv_broadcast(&unit->hci_init);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -867,7 +867,7 @@ hci_cmd_read_buffer_size(struct hci_unit *unit, struct mbuf *m)
|
|||
|
||||
unit->hci_flags &= ~BTF_INIT_BUFFER_SIZE;
|
||||
|
||||
wakeup(unit);
|
||||
cv_broadcast(&unit->hci_init);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -955,7 +955,7 @@ hci_cmd_read_local_features(struct hci_unit *unit, struct mbuf *m)
|
|||
|
||||
unit->hci_flags &= ~BTF_INIT_FEATURES;
|
||||
|
||||
wakeup(unit);
|
||||
cv_broadcast(&unit->hci_init);
|
||||
|
||||
DPRINTFN(1, "%s: lmp_mask %4.4x, acl_mask %4.4x, sco_mask %4.4x\n",
|
||||
device_xname(unit->hci_dev), unit->hci_lmp_mask,
|
||||
|
@ -984,7 +984,7 @@ hci_cmd_read_local_ver(struct hci_unit *unit, struct mbuf *m)
|
|||
|
||||
if (rp.hci_version < HCI_SPEC_V12) {
|
||||
unit->hci_flags &= ~BTF_INIT_COMMANDS;
|
||||
wakeup(unit);
|
||||
cv_broadcast(&unit->hci_init);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1012,7 @@ hci_cmd_read_local_commands(struct hci_unit *unit, struct mbuf *m)
|
|||
unit->hci_flags &= ~BTF_INIT_COMMANDS;
|
||||
memcpy(unit->hci_cmds, rp.commands, HCI_COMMANDS_SIZE);
|
||||
|
||||
wakeup(unit);
|
||||
cv_broadcast(&unit->hci_init);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hci_link.c,v 1.19 2008/03/16 23:28:10 plunky Exp $ */
|
||||
/* $NetBSD: hci_link.c,v 1.20 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.19 2008/03/16 23:28:10 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_link.c,v 1.20 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -194,9 +194,9 @@ hci_acl_timeout(void *arg)
|
|||
{
|
||||
struct hci_link *link = arg;
|
||||
hci_discon_cp cp;
|
||||
int s, err;
|
||||
int err;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
callout_ack(&link->hl_expire);
|
||||
|
||||
if (link->hl_refcnt > 0)
|
||||
|
@ -233,7 +233,7 @@ hci_acl_timeout(void *arg)
|
|||
}
|
||||
|
||||
out:
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hci_socket.c,v 1.14 2008/02/10 17:40:54 plunky Exp $ */
|
||||
/* $NetBSD: hci_socket.c,v 1.15 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.14 2008/02/10 17:40:54 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.15 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
|
@ -562,9 +562,14 @@ hci_usrreq(struct socket *up, int req, struct mbuf *m,
|
|||
return EOPNOTSUPP;
|
||||
|
||||
case PRU_ATTACH:
|
||||
if (up->so_lock == NULL) {
|
||||
mutex_obj_hold(bt_lock);
|
||||
up->so_lock = bt_lock;
|
||||
solock(up);
|
||||
}
|
||||
KASSERT(solocked(up));
|
||||
if (pcb)
|
||||
return EINVAL;
|
||||
|
||||
err = soreserve(up, hci_sendspace, hci_recvspace);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: hci_unit.c,v 1.10 2008/03/17 09:16:17 plunky Exp $ */
|
||||
/* $NetBSD: hci_unit.c,v 1.11 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_unit.c,v 1.10 2008/03/17 09:16:17 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: hci_unit.c,v 1.11 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -43,6 +43,7 @@ __KERNEL_RCSID(0, "$NetBSD: hci_unit.c,v 1.10 2008/03/17 09:16:17 plunky Exp $")
|
|||
#include <sys/queue.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/intr.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <netbt/bluetooth.h>
|
||||
#include <netbt/hci.h>
|
||||
|
@ -83,7 +84,6 @@ struct hci_unit *
|
|||
hci_attach(const struct hci_if *hci_if, device_t dev, uint16_t flags)
|
||||
{
|
||||
struct hci_unit *unit;
|
||||
int s;
|
||||
|
||||
KASSERT(dev != NULL);
|
||||
KASSERT(hci_if->enable != NULL);
|
||||
|
@ -101,6 +101,7 @@ hci_attach(const struct hci_if *hci_if, device_t dev, uint16_t flags)
|
|||
unit->hci_flags = flags;
|
||||
|
||||
mutex_init(&unit->hci_devlock, MUTEX_DRIVER, hci_if->ipl);
|
||||
cv_init(&unit->hci_init, "hci_init");
|
||||
|
||||
MBUFQ_INIT(&unit->hci_eventq);
|
||||
MBUFQ_INIT(&unit->hci_aclrxq);
|
||||
|
@ -111,9 +112,9 @@ hci_attach(const struct hci_if *hci_if, device_t dev, uint16_t flags)
|
|||
TAILQ_INIT(&unit->hci_links);
|
||||
LIST_INIT(&unit->hci_memos);
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
SIMPLEQ_INSERT_TAIL(&hci_unit_list, unit, hci_next);
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
@ -121,14 +122,14 @@ hci_attach(const struct hci_if *hci_if, device_t dev, uint16_t flags)
|
|||
void
|
||||
hci_detach(struct hci_unit *unit)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
hci_disable(unit);
|
||||
|
||||
SIMPLEQ_REMOVE(&hci_unit_list, unit, hci_unit, hci_next);
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
cv_destroy(&unit->hci_init);
|
||||
mutex_destroy(&unit->hci_devlock);
|
||||
free(unit, M_BLUETOOTH);
|
||||
}
|
||||
|
@ -179,7 +180,7 @@ hci_enable(struct hci_unit *unit)
|
|||
goto bad2;
|
||||
|
||||
while (unit->hci_flags & BTF_INIT) {
|
||||
err = tsleep(unit, PWAIT | PCATCH, __func__, 5 * hz);
|
||||
err = cv_timedwait_sig(&unit->hci_init, bt_lock, 5 * hz);
|
||||
if (err)
|
||||
goto bad2;
|
||||
|
||||
|
@ -345,6 +346,7 @@ hci_intr(void *arg)
|
|||
struct hci_unit *unit = arg;
|
||||
struct mbuf *m;
|
||||
|
||||
mutex_enter(bt_lock);
|
||||
another:
|
||||
mutex_enter(&unit->hci_devlock);
|
||||
|
||||
|
@ -422,6 +424,7 @@ another:
|
|||
}
|
||||
|
||||
mutex_exit(&unit->hci_devlock);
|
||||
mutex_exit(bt_lock);
|
||||
|
||||
DPRINTFN(10, "done\n");
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: l2cap_misc.c,v 1.5 2007/11/03 17:20:17 plunky Exp $ */
|
||||
/* $NetBSD: l2cap_misc.c,v 1.6 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: l2cap_misc.c,v 1.5 2007/11/03 17:20:17 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: l2cap_misc.c,v 1.6 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -185,9 +185,8 @@ l2cap_rtx(void *arg)
|
|||
{
|
||||
struct l2cap_req *req = arg;
|
||||
struct l2cap_channel *chan;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
callout_ack(&req->lr_rtx);
|
||||
|
||||
chan = req->lr_chan;
|
||||
|
@ -198,7 +197,7 @@ l2cap_rtx(void *arg)
|
|||
if (chan && chan->lc_state != L2CAP_CLOSED)
|
||||
l2cap_close(chan, ETIMEDOUT);
|
||||
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $ */
|
||||
/* $NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 Iain Hibbert.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.7 2007/04/21 06:15:23 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.8 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
|
@ -120,9 +120,14 @@ l2cap_usrreq(struct socket *up, int req, struct mbuf *m,
|
|||
return EOPNOTSUPP;
|
||||
|
||||
case PRU_ATTACH:
|
||||
if (up->so_lock == NULL) {
|
||||
mutex_obj_hold(bt_lock);
|
||||
up->so_lock = bt_lock;
|
||||
solock(up);
|
||||
}
|
||||
KASSERT(solocked(up));
|
||||
if (pcb != NULL)
|
||||
return EINVAL;
|
||||
|
||||
/*
|
||||
* For L2CAP socket PCB we just use an l2cap_channel structure
|
||||
* since we have nothing to add..
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rfcomm_dlc.c,v 1.4 2007/11/03 17:20:17 plunky Exp $ */
|
||||
/* $NetBSD: rfcomm_dlc.c,v 1.5 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_dlc.c,v 1.4 2007/11/03 17:20:17 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_dlc.c,v 1.5 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -195,9 +195,8 @@ void
|
|||
rfcomm_dlc_timeout(void *arg)
|
||||
{
|
||||
struct rfcomm_dlc *dlc = arg;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
callout_ack(&dlc->rd_timeout);
|
||||
|
||||
if (dlc->rd_state != RFCOMM_DLC_CLOSED)
|
||||
|
@ -207,7 +206,7 @@ rfcomm_dlc_timeout(void *arg)
|
|||
free(dlc, M_BLUETOOTH);
|
||||
}
|
||||
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rfcomm_session.c,v 1.12 2008/01/31 19:30:23 plunky Exp $ */
|
||||
/* $NetBSD: rfcomm_session.c,v 1.13 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.12 2008/01/31 19:30:23 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.13 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -292,11 +292,10 @@ rfcomm_session_timeout(void *arg)
|
|||
{
|
||||
struct rfcomm_session *rs = arg;
|
||||
struct rfcomm_dlc *dlc;
|
||||
int s;
|
||||
|
||||
KASSERT(rs != NULL);
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(bt_lock);
|
||||
callout_ack(&rs->rs_timeout);
|
||||
|
||||
if (rs->rs_state != RFCOMM_SESSION_OPEN) {
|
||||
|
@ -314,7 +313,7 @@ rfcomm_session_timeout(void *arg)
|
|||
DPRINTF("expiring\n");
|
||||
rfcomm_session_free(rs);
|
||||
}
|
||||
splx(s);
|
||||
mutex_exit(bt_lock);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: rfcomm_socket.c,v 1.8 2007/10/15 18:04:34 plunky Exp $ */
|
||||
/* $NetBSD: rfcomm_socket.c,v 1.9 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.8 2007/10/15 18:04:34 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.9 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
|
@ -119,9 +119,14 @@ rfcomm_usrreq(struct socket *up, int req, struct mbuf *m,
|
|||
return EOPNOTSUPP;
|
||||
|
||||
case PRU_ATTACH:
|
||||
if (up->so_lock == NULL) {
|
||||
mutex_obj_hold(bt_lock);
|
||||
up->so_lock = bt_lock;
|
||||
solock(up);
|
||||
}
|
||||
KASSERT(solocked(up));
|
||||
if (pcb != NULL)
|
||||
return EINVAL;
|
||||
|
||||
/*
|
||||
* Since we have nothing to add, we attach the DLC
|
||||
* structure directly to our PCB pointer.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sco_socket.c,v 1.9 2007/04/21 06:15:23 plunky Exp $ */
|
||||
/* $NetBSD: sco_socket.c,v 1.10 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.9 2007/04/21 06:15:23 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.10 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
/* load symbolic names */
|
||||
#ifdef BLUETOOTH_DEBUG
|
||||
|
@ -113,9 +113,14 @@ sco_usrreq(struct socket *up, int req, struct mbuf *m,
|
|||
return EOPNOTSUPP;
|
||||
|
||||
case PRU_ATTACH:
|
||||
if (up->so_lock == NULL) {
|
||||
mutex_obj_hold(bt_lock);
|
||||
up->so_lock = bt_lock;
|
||||
solock(up);
|
||||
}
|
||||
KASSERT(solocked(up));
|
||||
if (pcb)
|
||||
return EINVAL;
|
||||
|
||||
err = soreserve(up, sco_sendspace, sco_recvspace);
|
||||
if (err)
|
||||
return err;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: if_arp.c,v 1.133 2008/04/23 05:26:50 thorpej Exp $ */
|
||||
/* $NetBSD: if_arp.c,v 1.134 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -75,7 +75,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.133 2008/04/23 05:26:50 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.134 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_inet.h"
|
||||
|
@ -100,6 +100,8 @@ __KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.133 2008/04/23 05:26:50 thorpej Exp $")
|
|||
#include <sys/protosw.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/percpu.h>
|
||||
|
||||
#include <net/ethertypes.h>
|
||||
#include <net/if.h>
|
||||
|
@ -341,8 +343,13 @@ arp_drain(void)
|
|||
int count = 0;
|
||||
struct mbuf *mold;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
if (arp_lock_try(0) == 0) {
|
||||
printf("arp_drain: locked; punting\n");
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -359,6 +366,8 @@ arp_drain(void)
|
|||
}
|
||||
ARP_UNLOCK();
|
||||
ARP_STATADD(ARP_STAT_DFRDROPPED, count);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -369,14 +378,15 @@ arp_drain(void)
|
|||
static void
|
||||
arptimer(void *arg)
|
||||
{
|
||||
int s;
|
||||
struct llinfo_arp *la, *nla;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
if (arp_lock_try(0) == 0) {
|
||||
/* get it later.. */
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -403,7 +413,8 @@ arptimer(void *arg)
|
|||
|
||||
ARP_UNLOCK();
|
||||
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -473,7 +484,7 @@ arp_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
|
|||
ts.tv_nsec = 0;
|
||||
tc_setclock(&ts);
|
||||
}
|
||||
callout_init(&arptimer_ch, 0);
|
||||
callout_init(&arptimer_ch, CALLOUT_MPSAFE);
|
||||
callout_reset(&arptimer_ch, hz, arptimer, NULL);
|
||||
}
|
||||
|
||||
|
@ -822,6 +833,8 @@ arpintr(void)
|
|||
int s;
|
||||
int arplen;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
while (arpintrq.ifq_head) {
|
||||
s = splnet();
|
||||
IF_DEQUEUE(&arpintrq, m);
|
||||
|
@ -866,6 +879,8 @@ badlen:
|
|||
}
|
||||
m_freem(m);
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: igmp.c,v 1.47 2008/04/23 05:26:50 thorpej Exp $ */
|
||||
/* $NetBSD: igmp.c,v 1.48 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -40,13 +40,14 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: igmp.c,v 1.47 2008/04/23 05:26:50 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: igmp.c,v 1.48 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_mrouting.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
@ -479,7 +480,6 @@ igmp_fasttimo(void)
|
|||
{
|
||||
struct in_multi *inm;
|
||||
struct in_multistep step;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* Quick check to see if any work needs to be done, in order
|
||||
|
@ -488,7 +488,9 @@ igmp_fasttimo(void)
|
|||
if (!igmp_timers_are_running)
|
||||
return;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
igmp_timers_are_running = 0;
|
||||
IN_FIRST_MULTI(step, inm);
|
||||
while (inm != NULL) {
|
||||
|
@ -509,23 +511,26 @@ igmp_fasttimo(void)
|
|||
}
|
||||
IN_NEXT_MULTI(step, inm);
|
||||
}
|
||||
splx(s);
|
||||
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
igmp_slowtimo(void)
|
||||
{
|
||||
struct router_info *rti;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
LIST_FOREACH(rti, &rti_head, rti_link) {
|
||||
if (rti->rti_type == IGMP_v1_ROUTER &&
|
||||
++rti->rti_age >= IGMP_AGE_THRESHOLD) {
|
||||
rti->rti_type = IGMP_v2_ROUTER;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in_pcb.c,v 1.122 2008/01/14 04:19:09 dyoung Exp $ */
|
||||
/* $NetBSD: in_pcb.c,v 1.123 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -98,7 +98,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.122 2008/01/14 04:19:09 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.123 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -494,7 +494,9 @@ in_pcbdetach(void *v)
|
|||
ipsec4_delete_pcbpolicy(inp);
|
||||
#endif /*IPSEC*/
|
||||
so->so_pcb = 0;
|
||||
/* sofree drop's the socket's lock */
|
||||
sofree(so);
|
||||
mutex_enter(softnet_lock);
|
||||
if (inp->inp_options)
|
||||
(void)m_free(inp->inp_options);
|
||||
rtcache_free(&inp->inp_route);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in_proto.c,v 1.93 2008/04/23 06:09:04 thorpej Exp $ */
|
||||
/* $NetBSD: in_proto.c,v 1.94 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -61,7 +61,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.93 2008/04/23 06:09:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.94 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_mrouting.h"
|
||||
#include "opt_eon.h" /* ISO CLNL over IP */
|
||||
|
@ -150,6 +150,60 @@ __KERNEL_RCSID(0, "$NetBSD: in_proto.c,v 1.93 2008/04/23 06:09:04 thorpej Exp $"
|
|||
|
||||
DOMAIN_DEFINE(inetdomain); /* forward declare and add to link set */
|
||||
|
||||
/* Wrappers to acquire kernel_lock. */
|
||||
|
||||
PR_WRAP_USRREQ(rip_usrreq)
|
||||
PR_WRAP_USRREQ(udp_usrreq)
|
||||
PR_WRAP_USRREQ(tcp_usrreq)
|
||||
|
||||
#define rip_usrreq rip_usrreq_wrapper
|
||||
#define udp_usrreq udp_usrreq_wrapper
|
||||
#define tcp_usrreq tcp_usrreq_wrapper
|
||||
|
||||
PR_WRAP_CTLINPUT(rip_ctlinput)
|
||||
PR_WRAP_CTLINPUT(udp_ctlinput)
|
||||
PR_WRAP_CTLINPUT(tcp_ctlinput)
|
||||
|
||||
#define rip_ctlinput rip_ctlinput_wrapper
|
||||
#define udp_ctlinput udp_ctlinput_wrapper
|
||||
#define tcp_ctlinput tcp_ctlinput_wrapper
|
||||
|
||||
PR_WRAP_CTLOUTPUT(rip_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(udp_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(tcp_ctloutput)
|
||||
|
||||
#define rip_ctloutput rip_ctloutput_wrapper
|
||||
#define udp_ctloutput udp_ctloutput_wrapper
|
||||
#define tcp_ctloutput tcp_ctloutput_wrapper
|
||||
|
||||
#if defined(IPSEC) || defined(FAST_IPSEC)
|
||||
PR_WRAP_CTLINPUT(ah4_ctlinput)
|
||||
|
||||
#define ah4_ctlinput ah4_ctlinput_wrapper
|
||||
#endif
|
||||
|
||||
#if defined(IPSEC_ESP) || defined(FAST_IPSEC)
|
||||
PR_WRAP_CTLINPUT(esp4_ctlinput)
|
||||
|
||||
#define esp4_ctlinput esp4_ctlinput_wrapper
|
||||
#endif
|
||||
|
||||
#ifdef TPIP
|
||||
PR_WRAP_CTLOUTPUT(tp_ctloutput)
|
||||
|
||||
#define tp_ctloutput tp_ctloutput_wrapper
|
||||
|
||||
PR_WRAP_CTLINPUT(tpip_ctlinput)
|
||||
|
||||
#define tpip_ctlinput tpip_ctlinput_wrapper
|
||||
#endif
|
||||
|
||||
#ifdef EON
|
||||
PR_WRAP_CTLINPUT(eonctlinput)
|
||||
|
||||
#define eonctlinput eonctlinput_wrapper
|
||||
#endif
|
||||
|
||||
const struct protosw inetsw[] = {
|
||||
{ .pr_domain = &inetdomain,
|
||||
.pr_init = ip_init,
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
#define USE_RADIX
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.31 2007/06/13 04:55:25 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.32 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_mrouting.h"
|
||||
#include "opt_inet.h"
|
||||
|
@ -684,7 +684,7 @@ fail:
|
|||
/* XXX encap4_ctlinput() is necessary if we set DF=1 on outer IPv4 header */
|
||||
|
||||
#ifdef INET6
|
||||
void
|
||||
void *
|
||||
encap6_ctlinput(int cmd, const struct sockaddr *sa, void *d0)
|
||||
{
|
||||
void *d = d0;
|
||||
|
@ -698,16 +698,16 @@ encap6_ctlinput(int cmd, const struct sockaddr *sa, void *d0)
|
|||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
return NULL;
|
||||
if (cmd == PRC_HOSTDEAD)
|
||||
d = NULL;
|
||||
else if (cmd == PRC_MSGSIZE)
|
||||
; /* special code is present, see below */
|
||||
else if (inet6ctlerrmap[cmd] == 0)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
|
@ -759,6 +759,7 @@ encap6_ctlinput(int cmd, const struct sockaddr *sa, void *d0)
|
|||
}
|
||||
|
||||
rip6_ctlinput(cmd, sa, d0);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_encap.h,v 1.11 2007/02/17 22:34:11 dyoung Exp $ */
|
||||
/* $NetBSD: ip_encap.h,v 1.12 2008/04/24 11:38:37 ad Exp $ */
|
||||
/* $KAME: ip_encap.h,v 1.7 2000/03/25 07:23:37 sumikawa Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -65,7 +65,7 @@ const struct encaptab *encap_attach(int, int, const struct sockaddr *,
|
|||
const struct encaptab *encap_attach_func(int, int,
|
||||
int (*)(struct mbuf *, int, int, void *),
|
||||
const struct protosw *, void *);
|
||||
void encap6_ctlinput(int, const struct sockaddr *, void *);
|
||||
void *encap6_ctlinput(int, const struct sockaddr *, void *);
|
||||
int encap_detach(const struct encaptab *);
|
||||
void *encap_getarg(struct mbuf *);
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_flow.c,v 1.54 2008/04/12 05:58:22 thorpej Exp $ */
|
||||
/* $NetBSD: ip_flow.c,v 1.55 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.54 2008/04/12 05:58:22 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_flow.c,v 1.55 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -408,6 +408,8 @@ ipflow_slowtimo(void)
|
|||
struct ipflow *ipf, *next_ipf;
|
||||
uint64_t *ips;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
for (ipf = LIST_FIRST(&ipflowlist); ipf != NULL; ipf = next_ipf) {
|
||||
next_ipf = LIST_NEXT(ipf, ipf_list);
|
||||
if (PRT_SLOW_ISEXPIRED(ipf->ipf_timer) ||
|
||||
|
@ -424,6 +426,8 @@ ipflow_slowtimo(void)
|
|||
ipf->ipf_uses = 0;
|
||||
}
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip_input.c,v 1.267 2008/04/23 06:09:04 thorpej Exp $ */
|
||||
/* $NetBSD: ip_input.c,v 1.268 2008/04/24 11:38:37 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -98,7 +98,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.267 2008/04/23 06:09:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.268 2008/04/24 11:38:37 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_gateway.h"
|
||||
|
@ -469,14 +469,18 @@ ipintr(void)
|
|||
int s;
|
||||
struct mbuf *m;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
while (!IF_IS_EMPTY(&ipintrq)) {
|
||||
s = splnet();
|
||||
IF_DEQUEUE(&ipintrq, m);
|
||||
splx(s);
|
||||
if (m == 0)
|
||||
return;
|
||||
if (m == NULL)
|
||||
break;
|
||||
ip_input(m);
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1389,7 +1393,9 @@ ip_slowtimo(void)
|
|||
static u_int dropscanidx = 0;
|
||||
u_int i;
|
||||
u_int median_ttl;
|
||||
int s = splsoftnet();
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
IPQ_LOCK();
|
||||
|
||||
|
@ -1431,7 +1437,9 @@ ip_slowtimo(void)
|
|||
dropscanidx = i;
|
||||
}
|
||||
IPQ_UNLOCK();
|
||||
splx(s);
|
||||
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1441,20 +1449,24 @@ void
|
|||
ip_drain(void)
|
||||
{
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
/*
|
||||
* We may be called from a device's interrupt context. If
|
||||
* the ipq is already busy, just bail out now.
|
||||
*/
|
||||
if (ipq_lock_try() == 0)
|
||||
return;
|
||||
if (ipq_lock_try() != 0) {
|
||||
/*
|
||||
* Drop half the total fragments now. If more mbufs are
|
||||
* needed, we will be called again soon.
|
||||
*/
|
||||
ip_reass_drophalf();
|
||||
IPQ_UNLOCK();
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop half the total fragments now. If more mbufs are needed,
|
||||
* we will be called again soon.
|
||||
*/
|
||||
ip_reass_drophalf();
|
||||
|
||||
IPQ_UNLOCK();
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: raw_ip.c,v 1.106 2008/04/23 06:09:04 thorpej Exp $ */
|
||||
/* $NetBSD: raw_ip.c,v 1.107 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -61,7 +61,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.106 2008/04/23 06:09:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.107 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -528,9 +528,11 @@ rip_usrreq(struct socket *so, int req,
|
|||
s = splsoftnet();
|
||||
|
||||
if (req == PRU_PURGEIF) {
|
||||
mutex_enter(softnet_lock);
|
||||
in_pcbpurgeif0(&rawcbtable, (struct ifnet *)control);
|
||||
in_purgeif((struct ifnet *)control);
|
||||
in_pcbpurgeif(&rawcbtable, (struct ifnet *)control);
|
||||
mutex_exit(softnet_lock);
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
@ -548,6 +550,7 @@ rip_usrreq(struct socket *so, int req,
|
|||
switch (req) {
|
||||
|
||||
case PRU_ATTACH:
|
||||
sosetlock(so);
|
||||
if (inp != 0) {
|
||||
error = EISCONN;
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tcp_input.c,v 1.285 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: tcp_input.c,v 1.286 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -152,7 +152,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.285 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.286 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -3468,16 +3468,17 @@ void
|
|||
syn_cache_timer(void *arg)
|
||||
{
|
||||
struct syn_cache *sc = arg;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
callout_ack(&sc->sc_timer);
|
||||
|
||||
if (__predict_false(sc->sc_flags & SCF_DEAD)) {
|
||||
TCP_STATINC(TCP_STAT_SC_DELAYED_FREE);
|
||||
callout_destroy(&sc->sc_timer);
|
||||
pool_put(&syn_cache_pool, sc);
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3502,14 +3503,16 @@ syn_cache_timer(void *arg)
|
|||
sc->sc_rxtshift++;
|
||||
SYN_CACHE_TIMER_ARM(sc);
|
||||
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
|
||||
dropit:
|
||||
TCP_STATINC(TCP_STAT_SC_TIMED_OUT);
|
||||
syn_cache_rm(sc);
|
||||
syn_cache_put(sc); /* calls pool_put but see spl above */
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4082,7 +4085,7 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
|
|||
* options into the reply.
|
||||
*/
|
||||
bzero(sc, sizeof(struct syn_cache));
|
||||
callout_init(&sc->sc_timer, 0);
|
||||
callout_init(&sc->sc_timer, CALLOUT_MPSAFE);
|
||||
bcopy(src, &sc->sc_src, src->sa_len);
|
||||
bcopy(dst, &sc->sc_dst, dst->sa_len);
|
||||
sc->sc_flags = 0;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tcp_subr.c,v 1.227 2008/04/12 05:58:22 thorpej Exp $ */
|
||||
/* $NetBSD: tcp_subr.c,v 1.228 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 2000, 2001 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1997, 1998, 2000, 2001, 2008 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -98,7 +98,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.227 2008/04/12 05:58:22 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_subr.c,v 1.228 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -1008,10 +1008,10 @@ tcp_newtcpcb(int family, void *aux)
|
|||
|
||||
/* Don't sweat this loop; hopefully the compiler will unroll it. */
|
||||
for (i = 0; i < TCPT_NTIMERS; i++) {
|
||||
callout_init(&tp->t_timer[i], 0);
|
||||
callout_init(&tp->t_timer[i], CALLOUT_MPSAFE);
|
||||
TCP_TIMER_INIT(tp, i);
|
||||
}
|
||||
callout_init(&tp->t_delack_ch, 0);
|
||||
callout_init(&tp->t_delack_ch, CALLOUT_MPSAFE);
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
|
@ -1105,34 +1105,6 @@ tcp_drop(struct tcpcb *tp, int errno)
|
|||
return (tcp_close(tp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return whether this tcpcb is marked as dead, indicating
|
||||
* to the calling timer function that no further action should
|
||||
* be taken, as we are about to release this tcpcb. The release
|
||||
* of the storage will be done if this is the last timer running.
|
||||
*
|
||||
* This should be called from the callout handler function after
|
||||
* callout_ack() is done, so that the number of invoking timer
|
||||
* functions is 0.
|
||||
*/
|
||||
int
|
||||
tcp_isdead(struct tcpcb *tp)
|
||||
{
|
||||
int i, dead = (tp->t_flags & TF_DEAD);
|
||||
|
||||
if (__predict_false(dead)) {
|
||||
if (tcp_timers_invoking(tp) > 0)
|
||||
/* not quite there yet -- count separately? */
|
||||
return dead;
|
||||
TCP_STATINC(TCP_STAT_DELAYED_FREE);
|
||||
for (i = 0; i < TCPT_NTIMERS; i++)
|
||||
callout_destroy(&tp->t_timer[i]);
|
||||
callout_destroy(&tp->t_delack_ch);
|
||||
pool_put(&tcpcb_pool, tp); /* splsoftnet via tcp_timer.c */
|
||||
}
|
||||
return dead;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a TCP control block:
|
||||
* discard all space held by the tcp
|
||||
|
@ -1256,14 +1228,14 @@ tcp_close(struct tcpcb *tp)
|
|||
m_free(tp->t_template);
|
||||
tp->t_template = NULL;
|
||||
}
|
||||
if (tcp_timers_invoking(tp))
|
||||
tp->t_flags |= TF_DEAD;
|
||||
else {
|
||||
for (j = 0; j < TCPT_NTIMERS; j++)
|
||||
callout_destroy(&tp->t_timer[j]);
|
||||
callout_destroy(&tp->t_delack_ch);
|
||||
pool_put(&tcpcb_pool, tp);
|
||||
tp->t_flags |= TF_DEAD;
|
||||
for (j = 0; j < TCPT_NTIMERS; j++) {
|
||||
callout_halt(&tp->t_timer[j], softnet_lock);
|
||||
callout_destroy(&tp->t_timer[j]);
|
||||
}
|
||||
callout_halt(&tp->t_delack_ch, softnet_lock);
|
||||
callout_destroy(&tp->t_delack_ch);
|
||||
pool_put(&tcpcb_pool, tp);
|
||||
|
||||
if (inp) {
|
||||
inp->inp_ppcb = 0;
|
||||
|
@ -1318,6 +1290,9 @@ tcp_drain(void)
|
|||
struct inpcb_hdr *inph;
|
||||
struct tcpcb *tp;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
/*
|
||||
* Free the sequence queue of all TCP connections.
|
||||
*/
|
||||
|
@ -1348,6 +1323,9 @@ tcp_drain(void)
|
|||
TCP_REASS_UNLOCK(tp);
|
||||
}
|
||||
}
|
||||
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1377,7 +1355,7 @@ tcp_notify(struct inpcb *inp, int error)
|
|||
so->so_error = error;
|
||||
else
|
||||
tp->t_softerror = error;
|
||||
wakeup((void *) &so->so_timeo);
|
||||
cv_broadcast(&so->so_cv);
|
||||
sorwakeup(so);
|
||||
sowwakeup(so);
|
||||
}
|
||||
|
@ -1405,14 +1383,14 @@ tcp6_notify(struct in6pcb *in6p, int error)
|
|||
so->so_error = error;
|
||||
else
|
||||
tp->t_softerror = error;
|
||||
wakeup((void *) &so->so_timeo);
|
||||
cv_broadcast(&so->so_cv);
|
||||
sorwakeup(so);
|
||||
sowwakeup(so);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INET6
|
||||
void
|
||||
void *
|
||||
tcp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
||||
{
|
||||
struct tcphdr th;
|
||||
|
@ -1426,15 +1404,15 @@ tcp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
return NULL;
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
return NULL;
|
||||
else if (cmd == PRC_QUENCH) {
|
||||
/*
|
||||
* Don't honor ICMP Source Quench messages meant for
|
||||
* TCP connections.
|
||||
*/
|
||||
return;
|
||||
return NULL;
|
||||
} else if (PRC_IS_REDIRECT(cmd))
|
||||
notify = in6_rtchange, d = NULL;
|
||||
else if (cmd == PRC_MSGSIZE)
|
||||
|
@ -1442,7 +1420,7 @@ tcp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
else if (cmd == PRC_HOSTDEAD)
|
||||
d = NULL;
|
||||
else if (inet6ctlerrmap[cmd] == 0)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
|
@ -1468,7 +1446,7 @@ tcp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
if (m->m_pkthdr.len < off + sizeof(th)) {
|
||||
if (cmd == PRC_MSGSIZE)
|
||||
icmp6_mtudisc_update((struct ip6ctlparam *)d, 0);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bzero(&th, sizeof(th));
|
||||
|
@ -1501,7 +1479,7 @@ tcp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
* no need to call in6_pcbnotify, it should have been
|
||||
* called via callback if necessary
|
||||
*/
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nmatch = in6_pcbnotify(&tcbtable, sa, th.th_dport,
|
||||
|
@ -1516,6 +1494,8 @@ tcp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
(void) in6_pcbnotify(&tcbtable, sa, 0,
|
||||
(const struct sockaddr *)sa6_src, 0, cmd, NULL, notify);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tcp_timer.c,v 1.79 2008/04/12 05:58:22 thorpej Exp $ */
|
||||
/* $NetBSD: tcp_timer.c,v 1.80 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -100,7 +100,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.79 2008/04/12 05:58:22 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.80 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_tcp_debug.h"
|
||||
|
@ -200,24 +200,6 @@ tcp_timer_init(void)
|
|||
tcp_delack_ticks = TCP_DELACK_TICKS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return how many timers are currently being invoked.
|
||||
*/
|
||||
int
|
||||
tcp_timers_invoking(struct tcpcb *tp)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
|
||||
for (i = 0; i < TCPT_NTIMERS; i++)
|
||||
if (callout_invoking(&tp->t_timer[i]))
|
||||
count++;
|
||||
if (callout_invoking(&tp->t_delack_ch))
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callout to process delayed ACKs for a TCPCB.
|
||||
*/
|
||||
|
@ -225,7 +207,6 @@ void
|
|||
tcp_delack(void *arg)
|
||||
{
|
||||
struct tcpcb *tp = arg;
|
||||
int s;
|
||||
|
||||
/*
|
||||
* If tcp_output() wasn't able to transmit the ACK
|
||||
|
@ -233,16 +214,17 @@ tcp_delack(void *arg)
|
|||
* ACK callout.
|
||||
*/
|
||||
|
||||
s = splsoftnet();
|
||||
callout_ack(&tp->t_delack_ch);
|
||||
if (tcp_isdead(tp)) {
|
||||
splx(s);
|
||||
mutex_enter(softnet_lock);
|
||||
if ((tp->t_flags & TF_DEAD) != 0) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
tp->t_flags |= TF_ACKNOW;
|
||||
KERNEL_LOCK(1, NULL);
|
||||
(void) tcp_output(tp);
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -253,12 +235,11 @@ tcp_delack(void *arg)
|
|||
void
|
||||
tcp_slowtimo(void)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
tcp_iss_seq += TCP_ISSINCR; /* increment iss */
|
||||
tcp_now++; /* for timestamps */
|
||||
splx(s);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -287,19 +268,18 @@ tcp_timer_rexmt(void *arg)
|
|||
{
|
||||
struct tcpcb *tp = arg;
|
||||
uint32_t rto;
|
||||
int s;
|
||||
#ifdef TCP_DEBUG
|
||||
struct socket *so = NULL;
|
||||
short ostate;
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
callout_ack(&tp->t_timer[TCPT_REXMT]);
|
||||
if (tcp_isdead(tp)) {
|
||||
splx(s);
|
||||
mutex_enter(softnet_lock);
|
||||
if ((tp->t_flags & TF_DEAD) != 0) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if ((tp->t_flags & TF_PMTUD_PEND) && tp->t_inpcb &&
|
||||
SEQ_GEQ(tp->t_pmtud_th_seq, tp->snd_una) &&
|
||||
SEQ_LT(tp->t_pmtud_th_seq, (int)(tp->snd_una + tp->t_ourmss))) {
|
||||
|
@ -321,7 +301,8 @@ tcp_timer_rexmt(void *arg)
|
|||
*/
|
||||
in_pcbnotifyall(&tcbtable, icmpsrc.sin_addr, EMSGSIZE,
|
||||
tcp_mtudisc);
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
#ifdef TCP_DEBUG
|
||||
|
@ -435,7 +416,8 @@ tcp_timer_rexmt(void *arg)
|
|||
tcp_trace(TA_USER, ostate, tp, NULL,
|
||||
PRU_SLOWTIMO | (TCPT_REXMT << 8));
|
||||
#endif
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -443,19 +425,18 @@ tcp_timer_persist(void *arg)
|
|||
{
|
||||
struct tcpcb *tp = arg;
|
||||
uint32_t rto;
|
||||
int s;
|
||||
#ifdef TCP_DEBUG
|
||||
struct socket *so = NULL;
|
||||
short ostate;
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
callout_ack(&tp->t_timer[TCPT_PERSIST]);
|
||||
if (tcp_isdead(tp)) {
|
||||
splx(s);
|
||||
mutex_enter(softnet_lock);
|
||||
if ((tp->t_flags & TF_DEAD) != 0) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
#ifdef TCP_DEBUG
|
||||
#ifdef INET
|
||||
if (tp->t_inpcb)
|
||||
|
@ -503,7 +484,8 @@ tcp_timer_persist(void *arg)
|
|||
tcp_trace(TA_USER, ostate, tp, NULL,
|
||||
PRU_SLOWTIMO | (TCPT_PERSIST << 8));
|
||||
#endif
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -511,18 +493,18 @@ tcp_timer_keep(void *arg)
|
|||
{
|
||||
struct tcpcb *tp = arg;
|
||||
struct socket *so = NULL; /* Quell compiler warning */
|
||||
int s;
|
||||
#ifdef TCP_DEBUG
|
||||
short ostate;
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
callout_ack(&tp->t_timer[TCPT_KEEP]);
|
||||
if (tcp_isdead(tp)) {
|
||||
splx(s);
|
||||
mutex_enter(softnet_lock);
|
||||
if ((tp->t_flags & TF_DEAD) != 0) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
#ifdef TCP_DEBUG
|
||||
ostate = tp->t_state;
|
||||
#endif /* TCP_DEBUG */
|
||||
|
@ -585,29 +567,29 @@ tcp_timer_keep(void *arg)
|
|||
tcp_trace(TA_USER, ostate, tp, NULL,
|
||||
PRU_SLOWTIMO | (TCPT_KEEP << 8));
|
||||
#endif
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
|
||||
dropit:
|
||||
TCP_STATINC(TCP_STAT_KEEPDROPS);
|
||||
(void) tcp_drop(tp, ETIMEDOUT);
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
tcp_timer_2msl(void *arg)
|
||||
{
|
||||
struct tcpcb *tp = arg;
|
||||
int s;
|
||||
#ifdef TCP_DEBUG
|
||||
struct socket *so = NULL;
|
||||
short ostate;
|
||||
#endif
|
||||
|
||||
s = splsoftnet();
|
||||
callout_ack(&tp->t_timer[TCPT_2MSL]);
|
||||
if (tcp_isdead(tp)) {
|
||||
splx(s);
|
||||
mutex_enter(softnet_lock);
|
||||
if ((tp->t_flags & TF_DEAD) != 0) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -615,6 +597,7 @@ tcp_timer_2msl(void *arg)
|
|||
* 2 MSL timeout went off, clear the SACK scoreboard, reset
|
||||
* the FACK estimate.
|
||||
*/
|
||||
KERNEL_LOCK(1, NULL);
|
||||
tcp_free_sackholes(tp);
|
||||
tp->snd_fack = tp->snd_una;
|
||||
|
||||
|
@ -649,5 +632,6 @@ tcp_timer_2msl(void *arg)
|
|||
tcp_trace(TA_USER, ostate, tp, NULL,
|
||||
PRU_SLOWTIMO | (TCPT_2MSL << 8));
|
||||
#endif
|
||||
splx(s);
|
||||
mutex_exit(softnet_lock);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tcp_usrreq.c,v 1.143 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: tcp_usrreq.c,v 1.144 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -102,7 +102,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.143 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.144 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -210,6 +210,7 @@ tcp_usrreq(struct socket *so, int req,
|
|||
s = splsoftnet();
|
||||
|
||||
if (req == PRU_PURGEIF) {
|
||||
mutex_enter(softnet_lock);
|
||||
switch (family) {
|
||||
#ifdef INET
|
||||
case PF_INET:
|
||||
|
@ -226,13 +227,18 @@ tcp_usrreq(struct socket *so, int req,
|
|||
break;
|
||||
#endif
|
||||
default:
|
||||
mutex_exit(softnet_lock);
|
||||
splx(s);
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
mutex_exit(softnet_lock);
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (req == PRU_ATTACH)
|
||||
sosetlock(so);
|
||||
|
||||
switch (family) {
|
||||
#ifdef INET
|
||||
case PF_INET:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tcp_var.h,v 1.155 2008/04/12 05:58:22 thorpej Exp $ */
|
||||
/* $NetBSD: tcp_var.h,v 1.156 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -822,12 +822,11 @@ struct secasvar;
|
|||
|
||||
int tcp_attach(struct socket *);
|
||||
void tcp_canceltimers(struct tcpcb *);
|
||||
int tcp_timers_invoking(struct tcpcb*);
|
||||
struct tcpcb *
|
||||
tcp_close(struct tcpcb *);
|
||||
int tcp_isdead(struct tcpcb *);
|
||||
#ifdef INET6
|
||||
void tcp6_ctlinput(int, const struct sockaddr *, void *);
|
||||
void *tcp6_ctlinput(int, const struct sockaddr *, void *);
|
||||
#endif
|
||||
void *tcp_ctlinput(int, const struct sockaddr *, void *);
|
||||
int tcp_ctloutput(int, struct socket *, int, int, struct mbuf **);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: udp_usrreq.c,v 1.169 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: udp_usrreq.c,v 1.170 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
|
@ -61,7 +61,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.169 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.170 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -1181,9 +1181,11 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
s = splsoftnet();
|
||||
|
||||
if (req == PRU_PURGEIF) {
|
||||
mutex_enter(softnet_lock);
|
||||
in_pcbpurgeif0(&udbtable, (struct ifnet *)control);
|
||||
in_purgeif((struct ifnet *)control);
|
||||
in_pcbpurgeif(&udbtable, (struct ifnet *)control);
|
||||
mutex_exit(softnet_lock);
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
@ -1193,7 +1195,9 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
if (req != PRU_SEND && req != PRU_SENDOOB && control)
|
||||
panic("udp_usrreq: unexpected control mbuf");
|
||||
#endif
|
||||
if (inp == 0 && req != PRU_ATTACH) {
|
||||
if (req == PRU_ATTACH) {
|
||||
sosetlock(so);
|
||||
} else if (inp == 0) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ah.h,v 1.24 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: ah.h,v 1.25 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: ah.h,v 1.16 2001/09/04 08:43:19 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -101,7 +101,7 @@ extern int ah6_calccksum(struct mbuf *, u_int8_t *, size_t,
|
|||
const struct ah_algorithm *, struct secasvar *);
|
||||
|
||||
extern void ah6_init(void);
|
||||
extern void ah6_ctlinput(int, const struct sockaddr *, void *);
|
||||
extern void *ah6_ctlinput(int, const struct sockaddr *, void *);
|
||||
#endif /* INET6 */
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ah_input.c,v 1.56 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: ah_input.c,v 1.57 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: ah_input.c,v 1.64 2001/09/04 08:43:19 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ah_input.c,v 1.56 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ah_input.c,v 1.57 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -923,7 +923,7 @@ fail:
|
|||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
void
|
||||
void *
|
||||
ah6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
||||
{
|
||||
const struct newah *ahp;
|
||||
|
@ -937,9 +937,9 @@ ah6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
return NULL;
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
|
@ -961,7 +961,7 @@ ah6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
/* check if we can safely examine src and dst ports */
|
||||
if (m->m_pkthdr.len < off + sizeof(ah))
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if (m->m_len < off + sizeof(ah)) {
|
||||
/*
|
||||
|
@ -1009,5 +1009,7 @@ ah6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
} else {
|
||||
/* we normally notify any pcb here */
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: esp.h,v 1.24 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: esp.h,v 1.25 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: esp.h,v 1.19 2001/09/04 08:43:19 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -109,7 +109,7 @@ extern int esp6_output __P((struct mbuf *, u_char *, struct mbuf *,
|
|||
extern int esp6_input __P((struct mbuf **, int *, int));
|
||||
|
||||
extern void esp6_init(void);
|
||||
extern void esp6_ctlinput(int, const struct sockaddr *, void *);
|
||||
extern void *esp6_ctlinput(int, const struct sockaddr *, void *);
|
||||
#endif /* INET6 */
|
||||
|
||||
extern int esp_schedule __P((const struct esp_algorithm *, struct secasvar *));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: esp_input.c,v 1.46 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: esp_input.c,v 1.47 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: esp_input.c,v 1.60 2001/09/04 08:43:19 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: esp_input.c,v 1.46 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: esp_input.c,v 1.47 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -897,7 +897,7 @@ bad:
|
|||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
void
|
||||
void *
|
||||
esp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
||||
{
|
||||
const struct newesp *espp;
|
||||
|
@ -911,9 +911,9 @@ esp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
return NULL;
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
|
@ -953,7 +953,7 @@ esp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
/* check if we can safely examine src and dst ports */
|
||||
if (m->m_pkthdr.len < off + sizeof(esp))
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if (m->m_len < off + sizeof(esp)) {
|
||||
/*
|
||||
|
@ -999,5 +999,7 @@ esp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
} else {
|
||||
/* we normally notify any pcb here */
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: frag6.c,v 1.44 2008/04/15 03:57:04 thorpej Exp $ */
|
||||
/* $NetBSD: frag6.c,v 1.45 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.44 2008/04/15 03:57:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.45 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -40,6 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.44 2008/04/15 03:57:04 thorpej Exp $");
|
|||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -678,7 +679,9 @@ void
|
|||
frag6_slowtimo(void)
|
||||
{
|
||||
struct ip6q *q6;
|
||||
int s = splsoftnet();
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
IP6Q_LOCK();
|
||||
q6 = ip6q.ip6q_next;
|
||||
|
@ -715,7 +718,8 @@ frag6_slowtimo(void)
|
|||
rtcache_free(&ipsrcchk_rt);
|
||||
#endif
|
||||
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -725,12 +729,16 @@ void
|
|||
frag6_drain(void)
|
||||
{
|
||||
|
||||
if (ip6q_lock_try() == 0)
|
||||
return;
|
||||
while (ip6q.ip6q_next != &ip6q) {
|
||||
IP6_STATINC(IP6_STAT_FRAGDROPPED);
|
||||
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
||||
frag6_freef(ip6q.ip6q_next);
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
if (ip6q_lock_try() != 0) {
|
||||
while (ip6q.ip6q_next != &ip6q) {
|
||||
IP6_STATINC(IP6_STAT_FRAGDROPPED);
|
||||
/* XXX in6_ifstat_inc(ifp, ifs6_reass_fail) */
|
||||
frag6_freef(ip6q.ip6q_next);
|
||||
}
|
||||
IP6Q_UNLOCK();
|
||||
}
|
||||
IP6Q_UNLOCK();
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6_gif.c,v 1.55 2008/04/15 03:57:04 thorpej Exp $ */
|
||||
/* $NetBSD: in6_gif.c,v 1.56 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: in6_gif.c,v 1.62 2001/07/29 04:27:25 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.55 2008/04/15 03:57:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.56 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_iso.h"
|
||||
|
@ -76,16 +76,10 @@ static int gif_validate6 __P((const struct ip6_hdr *, struct gif_softc *,
|
|||
|
||||
int ip6_gif_hlim = GIF_HLIM;
|
||||
|
||||
extern struct domain inet6domain;
|
||||
const struct ip6protosw in6_gif_protosw =
|
||||
{ SOCK_RAW, &inet6domain, 0/* IPPROTO_IPV[46] */, PR_ATOMIC|PR_ADDR,
|
||||
in6_gif_input, rip6_output, in6_gif_ctlinput, rip6_ctloutput,
|
||||
rip6_usrreq,
|
||||
0, 0, 0, 0,
|
||||
};
|
||||
|
||||
extern LIST_HEAD(, gif_softc) gif_softc_list;
|
||||
|
||||
extern const struct ip6protosw in6_gif_protosw;
|
||||
|
||||
/*
|
||||
* family - family of the packet to be encapsulate.
|
||||
*/
|
||||
|
@ -406,7 +400,7 @@ in6_gif_detach(struct gif_softc *sc)
|
|||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
void *
|
||||
in6_gif_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
||||
{
|
||||
struct gif_softc *sc;
|
||||
|
@ -416,14 +410,14 @@ in6_gif_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
return NULL;
|
||||
if (cmd == PRC_HOSTDEAD)
|
||||
d = NULL;
|
||||
else if (inet6ctlerrmap[cmd] == 0)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
|
@ -434,7 +428,7 @@ in6_gif_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
}
|
||||
|
||||
if (!ip6)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* for now we don't care which type it was, just flush the route cache.
|
||||
|
@ -454,4 +448,22 @@ in6_gif_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
else if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst6->sin6_addr))
|
||||
rtcache_free(&sc->gif_ro);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PR_WRAP_CTLINPUT(in6_gif_ctlinput)
|
||||
PR_WRAP_CTLOUTPUT(rip6_ctloutput)
|
||||
PR_WRAP_USRREQ(rip6_usrreq)
|
||||
|
||||
#define in6_gif_ctlinput in6_gif_ctlinput_wrapper
|
||||
#define rip6_ctloutput rip6_ctloutput_wrapper
|
||||
#define rip6_usrreq rip6_usrreq_wrapper
|
||||
|
||||
extern struct domain inet6domain;
|
||||
const struct ip6protosw in6_gif_protosw =
|
||||
{ SOCK_RAW, &inet6domain, 0/* IPPROTO_IPV[46] */, PR_ATOMIC|PR_ADDR,
|
||||
in6_gif_input, rip6_output, in6_gif_ctlinput, rip6_ctloutput,
|
||||
rip6_usrreq,
|
||||
0, 0, 0, 0,
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6_gif.h,v 1.12 2007/02/17 22:34:13 dyoung Exp $ */
|
||||
/* $NetBSD: in6_gif.h,v 1.13 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: in6_gif.h,v 1.7 2001/07/26 06:53:16 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -45,6 +45,6 @@ int gif_encapcheck6(struct mbuf *, int, int, void *);
|
|||
#endif
|
||||
int in6_gif_attach(struct gif_softc *);
|
||||
int in6_gif_detach(struct gif_softc *);
|
||||
void in6_gif_ctlinput(int, const struct sockaddr *, void *);
|
||||
void *in6_gif_ctlinput(int, const struct sockaddr *, void *);
|
||||
|
||||
#endif /* !_NETINET6_IN6_GIF_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6_ifattach.c,v 1.79 2007/12/06 00:28:36 dyoung Exp $ */
|
||||
/* $NetBSD: in6_ifattach.c,v 1.80 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.79 2007/12/06 00:28:36 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.80 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.79 2007/12/06 00:28:36 dyoung Exp
|
|||
#include <sys/kernel.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/md5.h>
|
||||
#include <sys/socketvar.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
@ -961,7 +962,9 @@ in6_tmpaddrtimer(void *ignored_arg)
|
|||
struct nd_ifinfo *ndi;
|
||||
u_int8_t nullbuf[8];
|
||||
struct ifnet *ifp;
|
||||
int s = splsoftnet();
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
callout_reset(&in6_tmpaddrtimer_ch,
|
||||
(ip6_temp_preferred_lifetime - ip6_desync_factor -
|
||||
|
@ -980,5 +983,6 @@ in6_tmpaddrtimer(void *ignored_arg)
|
|||
}
|
||||
}
|
||||
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6_pcb.c,v 1.96 2008/03/20 20:32:00 dyoung Exp $ */
|
||||
/* $NetBSD: in6_pcb.c,v 1.97 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.96 2008/03/20 20:32:00 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.97 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -499,7 +499,9 @@ in6_pcbdetach(struct in6pcb *in6p)
|
|||
ipsec6_delete_pcbpolicy(in6p);
|
||||
#endif /* IPSEC */
|
||||
so->so_pcb = 0;
|
||||
/* sofree drops the socket's lock */
|
||||
sofree(so);
|
||||
mutex_enter(softnet_lock);
|
||||
if (in6p->in6p_options)
|
||||
m_freem(in6p->in6p_options);
|
||||
if (in6p->in6p_outputopts != NULL) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6_proto.c,v 1.81 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: in6_proto.c,v 1.82 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.81 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.82 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -146,6 +146,44 @@ __KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.81 2008/04/23 06:09:05 thorpej Exp $
|
|||
|
||||
DOMAIN_DEFINE(inet6domain); /* forward declare and add to link set */
|
||||
|
||||
/* Wrappers to acquire kernel_lock. */
|
||||
|
||||
PR_WRAP_USRREQ(rip6_usrreq)
|
||||
PR_WRAP_USRREQ(udp6_usrreq)
|
||||
PR_WRAP_USRREQ(tcp_usrreq)
|
||||
|
||||
#define rip6_usrreq rip6_usrreq_wrapper
|
||||
#define udp6_usrreq udp6_usrreq_wrapper
|
||||
#define tcp_usrreq tcp_usrreq_wrapper
|
||||
|
||||
PR_WRAP_CTLINPUT(rip6_ctlinput)
|
||||
PR_WRAP_CTLINPUT(encap6_ctlinput)
|
||||
PR_WRAP_CTLINPUT(udp6_ctlinput)
|
||||
PR_WRAP_CTLINPUT(tcp6_ctlinput)
|
||||
|
||||
#define rip6_ctlinput rip6_ctlinput_wrapper
|
||||
#define encap6_ctlinput encap6_ctlinput_wrapper
|
||||
#define udp6_ctlinput udp6_ctlinput_wrapper
|
||||
#define tcp6_ctlinput tcp6_ctlinput_wrapper
|
||||
|
||||
PR_WRAP_CTLOUTPUT(rip6_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(ip6_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(tcp_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(icmp6_ctloutput)
|
||||
|
||||
#define rip6_ctloutput rip6_ctloutput_wrapper
|
||||
#define ip6_ctloutput ip6_ctloutput_wrapper
|
||||
#define tcp_ctloutput tcp_ctloutput_wrapper
|
||||
#define icmp6_ctloutput icmp6_ctloutput_wrapper
|
||||
|
||||
#if defined(IPSEC) || defined(FAST_IPSEC)
|
||||
PR_WRAP_CTLINPUT(ah6_ctlinput)
|
||||
PR_WRAP_CTLINPUT(esp6_ctlinput)
|
||||
|
||||
#define ah6_ctlinput ah6_ctlinput_wrapper
|
||||
#define esp6_ctlinput esp6_ctlinput_wrapper
|
||||
#endif
|
||||
|
||||
const struct ip6protosw inet6sw[] = {
|
||||
{ .pr_domain = &inet6domain,
|
||||
.pr_protocol = IPPROTO_IPV6,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip6_flow.c,v 1.15 2008/04/15 03:57:04 thorpej Exp $ */
|
||||
/* $NetBSD: ip6_flow.c,v 1.16 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -45,7 +45,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_flow.c,v 1.15 2008/04/15 03:57:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_flow.c,v 1.16 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -410,6 +410,9 @@ ip6flow_slowtimo(void)
|
|||
{
|
||||
struct ip6flow *ip6f, *next_ip6f;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
for (ip6f = LIST_FIRST(&ip6flowlist); ip6f != NULL; ip6f = next_ip6f) {
|
||||
next_ip6f = LIST_NEXT(ip6f, ip6f_list);
|
||||
if (PRT_SLOW_ISEXPIRED(ip6f->ip6f_timer) ||
|
||||
|
@ -423,6 +426,9 @@ ip6flow_slowtimo(void)
|
|||
ip6f->ip6f_forwarded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip6_input.c,v 1.117 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: ip6_input.c,v 1.118 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.117 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.118 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
|
@ -206,11 +206,11 @@ ip6_init2(void *dummy)
|
|||
{
|
||||
|
||||
/* nd6_timer_init */
|
||||
callout_init(&nd6_timer_ch, 0);
|
||||
callout_init(&nd6_timer_ch, CALLOUT_MPSAFE);
|
||||
callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL);
|
||||
|
||||
/* timer for regeneranation of temporary addresses randomize ID */
|
||||
callout_init(&in6_tmpaddrtimer_ch, 0);
|
||||
callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE);
|
||||
callout_reset(&in6_tmpaddrtimer_ch,
|
||||
(ip6_temp_preferred_lifetime - ip6_desync_factor -
|
||||
ip6_temp_regen_advance) * hz,
|
||||
|
@ -226,19 +226,23 @@ ip6intr(void)
|
|||
int s;
|
||||
struct mbuf *m;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
for (;;) {
|
||||
s = splnet();
|
||||
IF_DEQUEUE(&ip6intrq, m);
|
||||
splx(s);
|
||||
if (m == 0)
|
||||
return;
|
||||
break;
|
||||
/* drop the packet if IPv6 operation is disabled on the IF */
|
||||
if ((ND_IFINFO(m->m_pkthdr.rcvif)->flags & ND6_IFF_IFDISABLED)) {
|
||||
m_freem(m);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
ip6_input(m);
|
||||
}
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
extern struct route ip6_forward_rt;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip6_mroute.c,v 1.91 2008/04/23 05:26:50 thorpej Exp $ */
|
||||
/* $NetBSD: ip6_mroute.c,v 1.92 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: ip6_mroute.c,v 1.49 2001/07/25 09:21:18 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -117,7 +117,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.91 2008/04/23 05:26:50 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.92 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_mrouting.h"
|
||||
|
@ -487,7 +487,7 @@ ip6_mrouter_init(struct socket *so, int v, int cmd)
|
|||
|
||||
pim6 = 0;/* used for stubbing out/in pim stuff */
|
||||
|
||||
callout_init(&expire_upcalls_ch, 0);
|
||||
callout_init(&expire_upcalls_ch, CALLOUT_MPSAFE);
|
||||
callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT,
|
||||
expire_upcalls, NULL);
|
||||
|
||||
|
@ -1296,9 +1296,10 @@ expire_upcalls(void *unused)
|
|||
struct rtdetq *rte;
|
||||
struct mf6c *mfc, **nptr;
|
||||
int i;
|
||||
int s;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
for (i = 0; i < MF6CTBLSIZ; i++) {
|
||||
if (n6expire[i] == 0)
|
||||
continue;
|
||||
|
@ -1339,9 +1340,11 @@ expire_upcalls(void *unused)
|
|||
}
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT,
|
||||
expire_upcalls, NULL);
|
||||
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip6_var.h,v 1.49 2008/04/15 03:57:04 thorpej Exp $ */
|
||||
/* $NetBSD: ip6_var.h,v 1.50 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -367,7 +367,7 @@ int ip6flow_invalidate_all(int);
|
|||
|
||||
void rip6_init(void);
|
||||
int rip6_input(struct mbuf **, int *, int);
|
||||
void rip6_ctlinput(int, const struct sockaddr *, void *);
|
||||
void *rip6_ctlinput(int, const struct sockaddr *, void *);
|
||||
int rip6_ctloutput(int, struct socket *, int, int, struct mbuf **);
|
||||
int rip6_output(struct mbuf *, struct socket *, struct sockaddr_in6 *,
|
||||
struct mbuf *);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ip6protosw.h,v 1.19 2007/07/19 20:48:57 dyoung Exp $ */
|
||||
/* $NetBSD: ip6protosw.h,v 1.20 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: ip6protosw.h,v 1.22 2001/02/08 18:02:08 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -123,7 +123,7 @@ struct ip6protosw {
|
|||
int (*pr_output) /* output to protocol (from above) */
|
||||
(struct mbuf *, struct socket *, struct sockaddr_in6 *,
|
||||
struct mbuf *);
|
||||
void (*pr_ctlinput) /* control input (from below) */
|
||||
void *(*pr_ctlinput) /* control input (from below) */
|
||||
(int, const struct sockaddr *, void *);
|
||||
int (*pr_ctloutput) /* control output (from above) */
|
||||
(int, struct socket *, int, int, struct mbuf **);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mld6.c,v 1.44 2008/04/15 03:57:04 thorpej Exp $ */
|
||||
/* $NetBSD: mld6.c,v 1.45 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -102,7 +102,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.44 2008/04/15 03:57:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.45 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
|
@ -110,6 +110,7 @@ __KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.44 2008/04/15 03:57:04 thorpej Exp $");
|
|||
#include <sys/systm.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
@ -221,7 +222,9 @@ static void
|
|||
mld_timeo(void *arg)
|
||||
{
|
||||
struct in6_multi *in6m = arg;
|
||||
int s = splsoftnet();
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
in6m->in6m_timer = IN6M_TIMER_UNDEF;
|
||||
|
||||
|
@ -234,7 +237,8 @@ mld_timeo(void *arg)
|
|||
break;
|
||||
}
|
||||
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
static u_long
|
||||
|
@ -674,7 +678,7 @@ in6_addmulti(struct in6_addr *maddr6, struct ifnet *ifp,
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
callout_init(&in6m->in6m_timer_ch, 0);
|
||||
callout_init(&in6m->in6m_timer_ch, CALLOUT_MPSAFE);
|
||||
callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m);
|
||||
in6m->in6m_timer = timer;
|
||||
if (in6m->in6m_timer > 0) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nd6.c,v 1.125 2008/04/15 03:57:04 thorpej Exp $ */
|
||||
/* $NetBSD: nd6.c,v 1.126 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.125 2008/04/15 03:57:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.126 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
|
@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.125 2008/04/15 03:57:04 thorpej Exp $");
|
|||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -148,8 +149,8 @@ nd6_init(void)
|
|||
|
||||
nd6_init_done = 1;
|
||||
|
||||
callout_init(&nd6_slowtimo_ch, 0);
|
||||
callout_init(&nd6_timer_ch, 0);
|
||||
callout_init(&nd6_slowtimo_ch, CALLOUT_MPSAFE);
|
||||
callout_init(&nd6_timer_ch, CALLOUT_MPSAFE);
|
||||
|
||||
/* start timer */
|
||||
callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
|
||||
|
@ -410,20 +411,21 @@ nd6_llinfo_settimer(struct llinfo_nd6 *ln, long xtick)
|
|||
static void
|
||||
nd6_llinfo_timer(void *arg)
|
||||
{
|
||||
int s;
|
||||
struct llinfo_nd6 *ln;
|
||||
struct rtentry *rt;
|
||||
const struct sockaddr_in6 *dst;
|
||||
struct ifnet *ifp;
|
||||
struct nd_ifinfo *ndi = NULL;
|
||||
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
ln = (struct llinfo_nd6 *)arg;
|
||||
|
||||
if (ln->ln_ntick > 0) {
|
||||
nd6_llinfo_settimer(ln, ln->ln_ntick);
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -509,7 +511,8 @@ nd6_llinfo_timer(void *arg)
|
|||
break;
|
||||
}
|
||||
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -518,16 +521,17 @@ nd6_llinfo_timer(void *arg)
|
|||
void
|
||||
nd6_timer(void *ignored_arg)
|
||||
{
|
||||
int s;
|
||||
struct nd_defrouter *next_dr, *dr;
|
||||
struct nd_prefix *next_pr, *pr;
|
||||
struct in6_ifaddr *ia6, *nia6;
|
||||
struct in6_addrlifetime *lt6;
|
||||
|
||||
s = splsoftnet();
|
||||
callout_reset(&nd6_timer_ch, nd6_prune * hz,
|
||||
nd6_timer, NULL);
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
/* expire default router list */
|
||||
|
||||
for (dr = TAILQ_FIRST(&nd_defrouter); dr != NULL; dr = next_dr) {
|
||||
|
@ -628,7 +632,9 @@ nd6_timer(void *ignored_arg)
|
|||
prelist_remove(pr);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/* ia6: deprecated/invalidated temporary address */
|
||||
|
@ -1272,7 +1278,7 @@ nd6_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
|
|||
nd6_allocated++;
|
||||
bzero(ln, sizeof(*ln));
|
||||
ln->ln_rt = rt;
|
||||
callout_init(&ln->ln_timer_ch, 0);
|
||||
callout_init(&ln->ln_timer_ch, CALLOUT_MPSAFE);
|
||||
/* this is required for "ndp" command. - shin */
|
||||
if (req == RTM_ADD) {
|
||||
/*
|
||||
|
@ -1870,11 +1876,12 @@ fail:
|
|||
static void
|
||||
nd6_slowtimo(void *ignored_arg)
|
||||
{
|
||||
int s = splsoftnet();
|
||||
struct nd_ifinfo *nd6if;
|
||||
struct ifnet *ifp;
|
||||
|
||||
callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
callout_reset(&nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz,
|
||||
nd6_slowtimo, NULL);
|
||||
TAILQ_FOREACH(ifp, &ifnet, if_list) {
|
||||
nd6if = ND_IFINFO(ifp);
|
||||
|
@ -1890,7 +1897,8 @@ nd6_slowtimo(void *ignored_arg)
|
|||
nd6if->reachable = ND_COMPUTE_RTIME(nd6if->basereachable);
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
#define senderr(e) { error = (e); goto bad;}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nd6_nbr.c,v 1.85 2008/04/15 03:57:04 thorpej Exp $ */
|
||||
/* $NetBSD: nd6_nbr.c,v 1.86 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.85 2008/04/15 03:57:04 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.86 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.85 2008/04/15 03:57:04 thorpej Exp $")
|
|||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -1099,7 +1100,7 @@ nd6_dad_start(struct ifaddr *ifa, int xtick)
|
|||
return;
|
||||
}
|
||||
bzero(dp, sizeof(*dp));
|
||||
callout_init(&dp->dad_timer_ch, 0);
|
||||
callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE);
|
||||
TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
|
||||
|
||||
nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
|
||||
|
@ -1151,11 +1152,11 @@ nd6_dad_stop(struct ifaddr *ifa)
|
|||
static void
|
||||
nd6_dad_timer(struct ifaddr *ifa)
|
||||
{
|
||||
int s;
|
||||
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
|
||||
struct dadq *dp;
|
||||
|
||||
s = splsoftnet(); /* XXX */
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
|
||||
/* Sanity check */
|
||||
if (ia == NULL) {
|
||||
|
@ -1248,7 +1249,8 @@ nd6_dad_timer(struct ifaddr *ifa)
|
|||
}
|
||||
|
||||
done:
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: raw_ip6.c,v 1.97 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: raw_ip6.c,v 1.98 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.97 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.98 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
|
@ -293,7 +293,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
|
|||
return IPPROTO_DONE;
|
||||
}
|
||||
|
||||
void
|
||||
void *
|
||||
rip6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
||||
{
|
||||
struct ip6_hdr *ip6;
|
||||
|
@ -305,10 +305,10 @@ rip6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
return NULL;;
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
return NULL;;
|
||||
if (PRC_IS_REDIRECT(cmd))
|
||||
notify = in6_rtchange, d = NULL;
|
||||
else if (cmd == PRC_HOSTDEAD)
|
||||
|
@ -316,7 +316,7 @@ rip6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
else if (cmd == PRC_MSGSIZE)
|
||||
; /* special code is present, see below */
|
||||
else if (inet6ctlerrmap[cmd] == 0)
|
||||
return;
|
||||
return NULL;;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
|
@ -385,6 +385,7 @@ rip6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
(void) in6_pcbnotify(&raw6cbtable, sa, 0,
|
||||
(const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -627,14 +628,17 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m,
|
|||
(struct ifnet *)control, l);
|
||||
|
||||
if (req == PRU_PURGEIF) {
|
||||
mutex_enter(softnet_lock);
|
||||
in6_pcbpurgeif0(&raw6cbtable, (struct ifnet *)control);
|
||||
in6_purgeif((struct ifnet *)control);
|
||||
in6_pcbpurgeif(&raw6cbtable, (struct ifnet *)control);
|
||||
mutex_exit(softnet_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (req) {
|
||||
case PRU_ATTACH:
|
||||
sosetlock(so);
|
||||
if (in6p != NULL)
|
||||
panic("rip6_attach");
|
||||
if (!priv) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: udp6_usrreq.c,v 1.83 2008/04/23 05:26:50 thorpej Exp $ */
|
||||
/* $NetBSD: udp6_usrreq.c,v 1.84 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.83 2008/04/23 05:26:50 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.84 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/malloc.h>
|
||||
|
@ -132,7 +132,7 @@ udp6_notify(struct in6pcb *in6p, int errno)
|
|||
sowwakeup(in6p->in6p_socket);
|
||||
}
|
||||
|
||||
void
|
||||
void *
|
||||
udp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
||||
{
|
||||
struct udphdr uh;
|
||||
|
@ -151,10 +151,10 @@ udp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
|
||||
if (sa->sa_family != AF_INET6 ||
|
||||
sa->sa_len != sizeof(struct sockaddr_in6))
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if ((unsigned)cmd >= PRC_NCMDS)
|
||||
return;
|
||||
return NULL;
|
||||
if (PRC_IS_REDIRECT(cmd))
|
||||
notify = in6_rtchange, d = NULL;
|
||||
else if (cmd == PRC_HOSTDEAD)
|
||||
|
@ -164,7 +164,7 @@ udp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
notify = in6_rtchange;
|
||||
}
|
||||
else if (inet6ctlerrmap[cmd] == 0)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
/* if the parameter is from icmp6, decode it. */
|
||||
if (d != NULL) {
|
||||
|
@ -192,7 +192,7 @@ udp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
if (m->m_pkthdr.len < off + sizeof(*uhp)) {
|
||||
if (cmd == PRC_MSGSIZE)
|
||||
icmp6_mtudisc_update((struct ip6ctlparam *)d, 0);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bzero(&uh, sizeof(uh));
|
||||
|
@ -249,6 +249,7 @@ udp6_ctlinput(int cmd, const struct sockaddr *sa, void *d)
|
|||
(void) in6_pcbnotify(&udbtable, sa, 0,
|
||||
(const struct sockaddr *)sa6_src, 0, cmd, cmdarg, notify);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern int udp6_sendspace;
|
||||
|
@ -277,15 +278,17 @@ udp6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr6,
|
|||
(struct ifnet *)control, l);
|
||||
|
||||
if (req == PRU_PURGEIF) {
|
||||
s = splsoftnet();
|
||||
mutex_enter(softnet_lock);
|
||||
in6_pcbpurgeif0(&udbtable, (struct ifnet *)control);
|
||||
in6_purgeif((struct ifnet *)control);
|
||||
in6_pcbpurgeif(&udbtable, (struct ifnet *)control);
|
||||
splx(s);
|
||||
mutex_exit(softnet_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in6p == NULL && req != PRU_ATTACH) {
|
||||
if (req == PRU_ATTACH)
|
||||
sosetlock(so);
|
||||
else if (in6p == NULL) {
|
||||
error = EINVAL;
|
||||
goto release;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: udp6_var.h,v 1.22 2008/04/15 04:43:25 thorpej Exp $ */
|
||||
/* $NetBSD: udp6_var.h,v 1.23 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: udp6_var.h,v 1.11 2000/06/05 00:14:31 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -99,7 +99,7 @@
|
|||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
void udp6_ctlinput(int, const struct sockaddr *, void *);
|
||||
void *udp6_ctlinput(int, const struct sockaddr *, void *);
|
||||
void udp6_init(void);
|
||||
int udp6_input(struct mbuf **, int *, int);
|
||||
int udp6_output(struct in6pcb *, struct mbuf *, struct mbuf *,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: key.c,v 1.52 2008/04/23 07:29:47 thorpej Exp $ */
|
||||
/* $NetBSD: key.c,v 1.53 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
|
||||
/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.52 2008/04/23 07:29:47 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.53 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
/*
|
||||
* This code is referd to RFC 2367
|
||||
|
@ -4451,7 +4451,7 @@ key_bbcmp(const void *a1, const void *a2, u_int bits)
|
|||
* time handler.
|
||||
* scanning SPD and SAD to check status for each entries,
|
||||
* and do to remove or to expire.
|
||||
* XXX: year 2038 problem may remain.
|
||||
* XXX2038: year 2038 problem may remain.
|
||||
*/
|
||||
void
|
||||
key_timehandler(void* arg)
|
||||
|
@ -4461,6 +4461,7 @@ key_timehandler(void* arg)
|
|||
time_t now = time_second;
|
||||
|
||||
s = splsoftnet(); /*called from softclock()*/
|
||||
mutex_enter(softnet_lock);
|
||||
|
||||
/* SPD */
|
||||
{
|
||||
|
@ -4707,6 +4708,7 @@ key_timehandler(void* arg)
|
|||
callout_reset(&key_timehandler_ch, hz, key_timehandler, NULL);
|
||||
#endif /* IPSEC_DEBUG2 */
|
||||
|
||||
mutex_exit(softnet_lock);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: keysock.c,v 1.15 2008/04/23 07:29:47 thorpej Exp $ */
|
||||
/* $NetBSD: keysock.c,v 1.16 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $ */
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.15 2008/04/23 07:29:47 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.16 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_ipsec.h"
|
||||
|
||||
|
@ -641,6 +641,7 @@ key_usrreq(struct socket *so, int req,struct mbuf *m, struct mbuf *nam,
|
|||
s = splsoftnet();
|
||||
if (req == PRU_ATTACH) {
|
||||
kp = (struct keycb *)malloc(sizeof(*kp), M_PCB, M_WAITOK);
|
||||
sosetlock(so);
|
||||
so->so_pcb = kp;
|
||||
if (so->so_pcb)
|
||||
bzero(so->so_pcb, sizeof(*kp));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: xform_ipip.c,v 1.22 2008/04/23 06:09:05 thorpej Exp $ */
|
||||
/* $NetBSD: xform_ipip.c,v 1.23 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */
|
||||
/* $OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.22 2008/04/23 06:09:05 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: xform_ipip.c,v 1.23 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
/*
|
||||
* IP-inside-IP processing
|
||||
|
@ -686,6 +686,11 @@ static struct xformsw ipe4_xformsw = {
|
|||
};
|
||||
|
||||
#ifdef INET
|
||||
PR_WRAP_CTLOUTPUT(rip_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(rip_usrreq)
|
||||
#define rip_ctloutput rip_ctloutput_wrapper
|
||||
#define rip_usrreq rip_usrreq_wrapper
|
||||
|
||||
extern struct domain inetdomain;
|
||||
static struct ipprotosw ipe4_protosw = {
|
||||
.pr_type = SOCK_RAW,
|
||||
|
@ -704,6 +709,11 @@ static struct ipprotosw ipe4_protosw = {
|
|||
};
|
||||
#endif
|
||||
#ifdef INET6
|
||||
PR_WRAP_CTLOUTPUT(rip6_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(rip6_usrreq)
|
||||
#define rip6_ctloutput rip6_ctloutput_wrapper
|
||||
#define rip6_usrreq rip6_usrreq_wrapper
|
||||
|
||||
extern struct domain inet6domain;
|
||||
static struct ip6protosw ipe4_protosw6 = {
|
||||
.pr_type = SOCK_RAW,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: clnp_timer.c,v 1.13 2005/12/11 12:25:12 christos Exp $ */
|
||||
/* $NetBSD: clnp_timer.c,v 1.14 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -59,7 +59,7 @@ SOFTWARE.
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: clnp_timer.c,v 1.13 2005/12/11 12:25:12 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: clnp_timer.c,v 1.14 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mbuf.h>
|
||||
|
@ -145,9 +145,11 @@ clnp_freefrags(
|
|||
void
|
||||
clnp_slowtimo(void)
|
||||
{
|
||||
struct clnp_fragl *cfh = clnp_frags;
|
||||
int s = splsoftnet();
|
||||
struct clnp_fragl *cfh;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
cfh = clnp_frags;
|
||||
while (cfh != NULL) {
|
||||
if (--cfh->cfl_ttl == 0) {
|
||||
cfh = clnp_freefrags(cfh);
|
||||
|
@ -156,7 +158,8 @@ clnp_slowtimo(void)
|
|||
cfh = cfh->cfl_next;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -174,8 +177,13 @@ clnp_slowtimo(void)
|
|||
void
|
||||
clnp_drain(void)
|
||||
{
|
||||
struct clnp_fragl *cfh = clnp_frags;
|
||||
struct clnp_fragl *cfh;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
cfh = clnp_frags;
|
||||
while (cfh != NULL)
|
||||
cfh = clnp_freefrags(cfh);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cltp_usrreq.c,v 1.32 2007/03/04 06:03:31 christos Exp $ */
|
||||
/* $NetBSD: cltp_usrreq.c,v 1.33 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: cltp_usrreq.c,v 1.32 2007/03/04 06:03:31 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: cltp_usrreq.c,v 1.33 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
|
||||
#include <sys/param.h>
|
||||
|
@ -298,7 +298,9 @@ cltp_usrreq(so, req, m, nam, control, l)
|
|||
(struct ifnet *)control, l));
|
||||
|
||||
if (req == PRU_PURGEIF) {
|
||||
mutex_enter(softnet_lock);
|
||||
iso_purgeif((struct ifnet *)control);
|
||||
mutex_exit(softnet_lock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: iso_pcb.c,v 1.43 2008/04/23 09:57:59 plunky Exp $ */
|
||||
/* $NetBSD: iso_pcb.c,v 1.44 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -62,7 +62,7 @@ SOFTWARE.
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: iso_pcb.c,v 1.43 2008/04/23 09:57:59 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: iso_pcb.c,v 1.44 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_iso.h"
|
||||
|
||||
|
@ -488,7 +488,9 @@ iso_pcbdetach(void *v)
|
|||
if (so) { /* in the x.25 domain, we sometimes have no
|
||||
* socket */
|
||||
so->so_pcb = 0;
|
||||
/* sofree drops the lock */
|
||||
sofree(so);
|
||||
mutex_enter(softnet_lock);
|
||||
}
|
||||
#ifdef ARGO_DEBUG
|
||||
if (argo_debug[D_ISO]) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: iso_proto.c,v 1.27 2008/04/23 09:57:59 plunky Exp $ */
|
||||
/* $NetBSD: iso_proto.c,v 1.28 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -65,7 +65,7 @@ SOFTWARE.
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: iso_proto.c,v 1.27 2008/04/23 09:57:59 plunky Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: iso_proto.c,v 1.28 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -97,6 +97,32 @@ const int isoctlerrmap[PRC_NCMDS] = {
|
|||
|
||||
DOMAIN_DEFINE(isodomain); /* forward declare and add to link set */
|
||||
|
||||
/* Wrappers to acquire kernel_lock. */
|
||||
|
||||
PR_WRAP_USRREQ(cltp_usrreq)
|
||||
PR_WRAP_USRREQ(clnp_usrreq)
|
||||
PR_WRAP_USRREQ(idrp_usrreq)
|
||||
PR_WRAP_USRREQ(tp_usrreq)
|
||||
PR_WRAP_USRREQ(esis_usrreq)
|
||||
|
||||
#define cltp_usrreq cltp_usrreq_wrapper
|
||||
#define clnp_usrreq clnp_usrreq_wrapper
|
||||
#define idrp_usrreq idrp_usrreq_wrapper
|
||||
#define tp_usrreq tp_usrreq_wrapper
|
||||
#define esis_usrreq esis_usrreq_wrapper
|
||||
|
||||
PR_WRAP_CTLOUTPUT(rclnp_ctloutput)
|
||||
PR_WRAP_CTLOUTPUT(tp_ctloutput)
|
||||
|
||||
#define rclnp_ctloutput rclnp_ctloutput_wrapper
|
||||
#define tp_ctloutput tp_ctloutput_wrapper
|
||||
|
||||
PR_WRAP_CTLINPUT(esis_ctlinput)
|
||||
PR_WRAP_CTLINPUT(tpclnp_ctlinput)
|
||||
|
||||
#define esis_ctlinput esis_ctlinput_wrapper
|
||||
#define tpclnp_ctlinput tpclnp_ctlinput_wrapper
|
||||
|
||||
const struct protosw isosw[] = {
|
||||
/*
|
||||
* We need a datagram entry through which net mgmt programs can get
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tp_timer.c,v 1.18 2007/03/04 06:03:33 christos Exp $ */
|
||||
/* $NetBSD: tp_timer.c,v 1.19 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -59,7 +59,7 @@ SOFTWARE.
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tp_timer.c,v 1.18 2007/03/04 06:03:33 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tp_timer.c,v 1.19 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -188,8 +188,10 @@ tp_slowtimo(void)
|
|||
struct tp_ref *rp;
|
||||
struct tp_pcb *tpcb;
|
||||
struct tp_event E;
|
||||
int s = splsoftnet(), t;
|
||||
int t;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
/* check only open reference structures */
|
||||
IncStat(ts_Cticks);
|
||||
/* tp_ref[0] is never used */
|
||||
|
@ -226,7 +228,8 @@ tp_slowtimo(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -281,9 +284,10 @@ void
|
|||
tp_fasttimo(void)
|
||||
{
|
||||
struct tp_pcb *t;
|
||||
int s = splsoftnet();
|
||||
struct tp_event E;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
KERNEL_LOCK(1, NULL);
|
||||
E.ev_number = TM_sendack;
|
||||
while ((t = tp_ftimeolist) != (struct tp_pcb *) & tp_ftimeolist) {
|
||||
if (t == 0) {
|
||||
|
@ -300,7 +304,8 @@ tp_fasttimo(void)
|
|||
t->tp_fasttimeo = 0;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(NULL);
|
||||
mutex_exit(softnet_lock);
|
||||
}
|
||||
|
||||
#ifdef TP_DEBUG_TIMERS
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tp_usrreq.c,v 1.34 2008/02/06 21:57:55 ad Exp $ */
|
||||
/* $NetBSD: tp_usrreq.c,v 1.35 2008/04/24 11:38:38 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -65,7 +65,7 @@ SOFTWARE.
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: tp_usrreq.c,v 1.34 2008/02/06 21:57:55 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: tp_usrreq.c,v 1.35 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -381,7 +381,6 @@ tp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
struct mbuf *control, struct lwp *l)
|
||||
{
|
||||
struct tp_pcb *tpcb;
|
||||
int s;
|
||||
int error = 0;
|
||||
int flags, *outflags = &flags;
|
||||
u_long eotsdu = 0;
|
||||
|
@ -404,7 +403,6 @@ tp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
if (req == PRU_CONTROL)
|
||||
return (EOPNOTSUPP);
|
||||
|
||||
s = splsoftnet();
|
||||
tpcb = sototpcb(so);
|
||||
if (tpcb == 0 && req != PRU_ATTACH) {
|
||||
#ifdef TPPT
|
||||
|
@ -725,7 +723,6 @@ tp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
/*
|
||||
* stat: don't bother with a blocksize.
|
||||
*/
|
||||
splx(s);
|
||||
return (0);
|
||||
|
||||
case PRU_SOCKADDR:
|
||||
|
@ -757,7 +754,6 @@ tp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
|
|||
}
|
||||
#endif
|
||||
release:
|
||||
splx(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: key.c,v 1.158 2008/04/23 07:29:47 thorpej Exp $ */
|
||||
/* $NetBSD: key.c,v 1.159 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: key.c,v 1.310 2003/09/08 02:23:44 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.158 2008/04/23 07:29:47 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.159 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
#include "opt_ipsec.h"
|
||||
|
@ -4651,7 +4651,7 @@ key_bbcmp(p1v, p2v, bits)
|
|||
* time handler.
|
||||
* scanning SPD and SAD to check status for each entries,
|
||||
* and do to remove or to expire.
|
||||
* XXX: year 2038 problem may remain.
|
||||
* XXX2038: year 2038 problem may remain.
|
||||
*/
|
||||
void
|
||||
key_timehandler(void *arg)
|
||||
|
@ -4663,6 +4663,7 @@ key_timehandler(void *arg)
|
|||
getmicrotime(&tv);
|
||||
|
||||
s = splsoftnet(); /*called from softclock()*/
|
||||
mutex_enter(softnet_lock);
|
||||
|
||||
/* SPD */
|
||||
{
|
||||
|
@ -4925,6 +4926,7 @@ key_timehandler(void *arg)
|
|||
|
||||
callout_reset(&key_timehandler_ch, hz, key_timehandler, (void *)0);
|
||||
|
||||
mutex_exit(softnet_lock);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: keysock.c,v 1.46 2008/04/23 07:29:47 thorpej Exp $ */
|
||||
/* $NetBSD: keysock.c,v 1.47 2008/04/24 11:38:38 ad Exp $ */
|
||||
/* $KAME: keysock.c,v 1.32 2003/08/22 05:45:08 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.46 2008/04/23 07:29:47 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.47 2008/04/24 11:38:38 ad Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
|
@ -456,6 +456,10 @@ key_sendup_mbuf(so, m, target)
|
|||
|
||||
DOMAIN_DEFINE(keydomain);
|
||||
|
||||
PR_WRAP_USRREQ(key_usrreq)
|
||||
|
||||
#define key_usrreq key_usrreq_wrapper
|
||||
|
||||
const struct protosw keysw[] = {
|
||||
{ .pr_type = SOCK_RAW,
|
||||
.pr_domain = &keydomain,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: natm.c,v 1.14 2007/03/04 06:03:35 christos Exp $ */
|
||||
/* $NetBSD: natm.c,v 1.15 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.14 2007/03/04 06:03:35 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.15 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -137,7 +137,9 @@ struct proc *p;
|
|||
|
||||
npcb_free(npcb, NPCB_DESTROY); /* drain */
|
||||
so->so_pcb = NULL;
|
||||
/* sofree drops the lock */
|
||||
sofree(so);
|
||||
mutex_enter(softnet_lock);
|
||||
|
||||
break;
|
||||
|
||||
|
@ -359,12 +361,15 @@ natmintr()
|
|||
struct socket *so;
|
||||
struct natmpcb *npcb;
|
||||
|
||||
mutex_enter(softnet_lock);
|
||||
next:
|
||||
s = splnet();
|
||||
IF_DEQUEUE(&natmintrq, m);
|
||||
splx(s);
|
||||
if (m == NULL)
|
||||
if (m == NULL) {
|
||||
mutex_exit(softnet_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if ((m->m_flags & M_PKTHDR) == 0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: natm_proto.c,v 1.12 2007/12/07 19:46:19 elad Exp $ */
|
||||
/* $NetBSD: natm_proto.c,v 1.13 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: natm_proto.c,v 1.12 2007/12/07 19:46:19 elad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: natm_proto.c,v 1.13 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -64,6 +64,10 @@ struct npcblist natm_pcbs = LIST_HEAD_INITIALIZER(natm_pcbs);
|
|||
struct ifqueue natmintrq; /* natm packet input queue */
|
||||
int natmqmaxlen = IFQ_MAXLEN; /* max # of packets on queue */
|
||||
|
||||
PR_WRAP_USRREQ(natm_usrreq)
|
||||
|
||||
#define natm_usrreq natm_usrreq_wrapper
|
||||
|
||||
const struct protosw natmsw[] = {
|
||||
{ .pr_type = SOCK_STREAM,
|
||||
.pr_domain = &natmdomain,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: smb_trantcp.c,v 1.33 2008/03/22 18:04:42 ad Exp $ */
|
||||
/* $NetBSD: smb_trantcp.c,v 1.34 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -68,7 +68,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: smb_trantcp.c,v 1.33 2008/03/22 18:04:42 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: smb_trantcp.c,v 1.34 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -105,19 +105,8 @@ static int nb_tcpsndbuf = NB_SNDQ;
|
|||
static int nb_tcprcvbuf = NB_RCVQ;
|
||||
static const struct timeval nb_timo = { 15, 0 }; /* XXX sysctl? */
|
||||
|
||||
#ifndef __NetBSD__
|
||||
SYSCTL_DECL(_net_smb);
|
||||
SYSCTL_INT(_net_smb, OID_AUTO, tcpsndbuf, CTLFLAG_RW, &nb_tcpsndbuf, 0, "");
|
||||
SYSCTL_INT(_net_smb, OID_AUTO, tcprcvbuf, CTLFLAG_RW, &nb_tcprcvbuf, 0, "");
|
||||
#endif
|
||||
|
||||
#ifndef __NetBSD__
|
||||
#define nb_sosend(so,m,flags,p) (so)->so_proto->pr_usrreqs->pru_sosend( \
|
||||
so, NULL, 0, m, 0, flags, p)
|
||||
#else
|
||||
#define nb_sosend(so,m,flags,l) (*(so)->so_send)(so, NULL, (struct uio *)0, \
|
||||
m, (struct mbuf *)0, flags, l)
|
||||
#endif
|
||||
|
||||
static int nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
|
||||
u_int8_t *rpcodep, struct lwp *l);
|
||||
|
@ -126,18 +115,7 @@ static int smb_nbst_disconnect(struct smb_vc *vcp, struct lwp *l);
|
|||
static int
|
||||
nb_setsockopt_int(struct socket *so, int level, int name, int val)
|
||||
{
|
||||
#ifdef __NetBSD__
|
||||
return sosetopt(so, level, name, NULL); /* XXX */
|
||||
#else
|
||||
struct sockopt sopt;
|
||||
|
||||
bzero(&sopt, sizeof(sopt));
|
||||
sopt.sopt_level = level;
|
||||
sopt.sopt_name = name;
|
||||
sopt.sopt_val = &val;
|
||||
sopt.sopt_valsize = sizeof(val);
|
||||
return sosetopt(so, &sopt);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -199,55 +177,53 @@ static int
|
|||
nb_connect_in(struct nbpcb *nbp, struct sockaddr_in *to, struct lwp *l)
|
||||
{
|
||||
struct socket *so;
|
||||
int error, s;
|
||||
#ifdef __NetBSD__
|
||||
int error;
|
||||
struct mbuf *m;
|
||||
#endif
|
||||
|
||||
error = socreate(AF_INET, &so, SOCK_STREAM, IPPROTO_TCP, l);
|
||||
error = socreate(AF_INET, &so, SOCK_STREAM, IPPROTO_TCP, l, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
solock(so);
|
||||
nbp->nbp_tso = so;
|
||||
so->so_upcallarg = (void *)nbp;
|
||||
so->so_upcall = nb_upcall;
|
||||
so->so_rcv.sb_flags |= SB_UPCALL;
|
||||
so->so_rcv.sb_flags &= ~SB_NOINTR;
|
||||
so->so_snd.sb_flags &= ~SB_NOINTR;
|
||||
so->so_rcv.sb_timeo = NB_SNDTIMEO;
|
||||
so->so_snd.sb_timeo = NB_RCVTIMEO;
|
||||
error = soreserve(so, nb_tcpsndbuf, nb_tcprcvbuf);
|
||||
sounlock(so);
|
||||
if (error)
|
||||
goto bad;
|
||||
nb_setsockopt_int(so, SOL_SOCKET, SO_KEEPALIVE, 1);
|
||||
nb_setsockopt_int(so, IPPROTO_TCP, TCP_NODELAY, 1);
|
||||
so->so_rcv.sb_flags &= ~SB_NOINTR;
|
||||
so->so_snd.sb_flags &= ~SB_NOINTR;
|
||||
#ifndef __NetBSD__
|
||||
error = soconnect(so, (struct sockaddr*)to, l);
|
||||
#else
|
||||
m = m_get(M_WAIT, MT_SONAME);
|
||||
*mtod(m, struct sockaddr *) = *(struct sockaddr *)to;
|
||||
m->m_len = sizeof(struct sockaddr);
|
||||
solock(so);
|
||||
error = soconnect(so, m, l);
|
||||
m_free(m);
|
||||
#endif
|
||||
if (error)
|
||||
if (error) {
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
s = splnet();
|
||||
}
|
||||
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
|
||||
tsleep(&so->so_timeo, PSOCK, "smbcon", 2 * hz);
|
||||
sowait(so, 2 * hz);
|
||||
if ((so->so_state & SS_ISCONNECTING) && so->so_error == 0 &&
|
||||
(error = nb_intr(nbp, l)) != 0) {
|
||||
so->so_state &= ~SS_ISCONNECTING;
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
return 0;
|
||||
bad:
|
||||
smb_nbst_disconnect(nbp->nbp_vc, l);
|
||||
|
@ -348,15 +324,7 @@ nbssn_recvhdr(struct nbpcb *nbp, int *lenp,
|
|||
auio.uio_offset = 0;
|
||||
auio.uio_resid = sizeof(len);
|
||||
UIO_SETUP_SYSSPACE(&auio);
|
||||
#ifndef __NetBSD__
|
||||
error = so->so_proto->pr_usrreqs->pru_soreceive
|
||||
(so, (struct sockaddr **)NULL, &auio,
|
||||
(struct mbuf **)NULL, (struct mbuf **)NULL, &flags);
|
||||
#else
|
||||
error = (*so->so_receive)(so, (struct mbuf **)0, &auio,
|
||||
(struct mbuf **)NULL,
|
||||
(struct mbuf **)NULL, &flags);
|
||||
#endif
|
||||
error = (*so->so_receive)(so, NULL, &auio, NULL, NULL, &flags);
|
||||
if (error)
|
||||
return error;
|
||||
if (auio.uio_resid > 0) {
|
||||
|
@ -441,15 +409,8 @@ nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
|
|||
*/
|
||||
do {
|
||||
rcvflg = MSG_WAITALL;
|
||||
#ifdef __NetBSD__
|
||||
error = (*so->so_receive)(so, (struct mbuf **)0,
|
||||
&auio, &tm, (struct mbuf **)NULL,
|
||||
&rcvflg);
|
||||
#else
|
||||
error = so->so_proto->pr_usrreqs->pru_soreceive
|
||||
(so, (struct sockaddr **)NULL,
|
||||
&auio, &tm, (struct mbuf **)NULL, &rcvflg);
|
||||
#endif
|
||||
error = (*so->so_receive)(so, NULL, &auio, &tm,
|
||||
NULL, &rcvflg);
|
||||
} while (error == EWOULDBLOCK || error == EINTR ||
|
||||
error == ERESTART);
|
||||
if (error)
|
||||
|
@ -610,7 +571,9 @@ smb_nbst_disconnect(struct smb_vc *vcp, struct lwp *l)
|
|||
if ((so = nbp->nbp_tso) != NULL) {
|
||||
nbp->nbp_flags &= ~NBF_CONNECTED;
|
||||
nbp->nbp_tso = (struct socket *)NULL;
|
||||
solock(so);
|
||||
soshutdown(so, 2);
|
||||
sounlock(so);
|
||||
soclose(so);
|
||||
}
|
||||
if (nbp->nbp_state != NBST_RETARGET) {
|
||||
|
@ -666,11 +629,15 @@ static void
|
|||
smb_nbst_intr(struct smb_vc *vcp)
|
||||
{
|
||||
struct nbpcb *nbp = vcp->vc_tdata;
|
||||
struct socket *so;
|
||||
|
||||
if (nbp == NULL || nbp->nbp_tso == NULL)
|
||||
if (nbp == NULL || (so = nbp->nbp_tso) == NULL)
|
||||
return;
|
||||
sorwakeup(nbp->nbp_tso);
|
||||
sowwakeup(nbp->nbp_tso);
|
||||
|
||||
solock(so);
|
||||
sorwakeup(so);
|
||||
sowwakeup(so);
|
||||
sounlock(so);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -733,4 +700,3 @@ struct smb_tran_desc smb_tran_nbtcp_desc = {
|
|||
smb_nbst_fatal,
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: krpc_subr.c,v 1.32 2007/03/04 06:03:36 christos Exp $ */
|
||||
/* $NetBSD: krpc_subr.c,v 1.33 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Gordon Ross, Adam Glass
|
||||
|
@ -43,7 +43,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: krpc_subr.c,v 1.32 2007/03/04 06:03:36 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: krpc_subr.c,v 1.33 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -246,7 +246,7 @@ krpc_call(sa, prog, vers, func, data, from_p, l)
|
|||
/*
|
||||
* Create socket and set its receive timeout.
|
||||
*/
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, l)))
|
||||
if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0, l, NULL)))
|
||||
goto out;
|
||||
|
||||
if ((error = nfs_boot_setrecvtimo(so)))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_boot.c,v 1.70 2008/04/05 13:49:36 cegger Exp $ */
|
||||
/* $NetBSD: nfs_boot.c,v 1.71 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995, 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -42,7 +42,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_boot.c,v 1.70 2008/04/05 13:49:36 cegger Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_boot.c,v 1.71 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include "opt_nfs.h"
|
||||
#include "opt_tftproot.h"
|
||||
|
@ -206,7 +206,7 @@ nfs_boot_ifupdown(ifp, lwp, up)
|
|||
* Get a socket to use for various things in here.
|
||||
* After this, use "goto out" to cleanup and return.
|
||||
*/
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp);
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp, NULL);
|
||||
if (error) {
|
||||
printf("ifupdown: socreate, error=%d\n", error);
|
||||
return (error);
|
||||
|
@ -255,7 +255,7 @@ nfs_boot_setaddress(ifp, lwp, addr, netmask, braddr)
|
|||
* Get a socket to use for various things in here.
|
||||
* After this, use "goto out" to cleanup and return.
|
||||
*/
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp);
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp, NULL);
|
||||
if (error) {
|
||||
printf("setaddress: socreate, error=%d\n", error);
|
||||
return (error);
|
||||
|
@ -315,7 +315,7 @@ nfs_boot_deladdress(ifp, lwp, addr)
|
|||
* Get a socket to use for various things in here.
|
||||
* After this, use "goto out" to cleanup and return.
|
||||
*/
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp);
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp, NULL);
|
||||
if (error) {
|
||||
printf("deladdress: socreate, error=%d\n", error);
|
||||
return (error);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_bootdhcp.c,v 1.37 2007/12/20 16:19:38 dyoung Exp $ */
|
||||
/* $NetBSD: nfs_bootdhcp.c,v 1.38 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995, 1997 The NetBSD Foundation, Inc.
|
||||
|
@ -51,7 +51,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_bootdhcp.c,v 1.37 2007/12/20 16:19:38 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_bootdhcp.c,v 1.38 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include "opt_nfs_boot.h"
|
||||
#include "opt_tftproot.h"
|
||||
|
@ -459,7 +459,7 @@ bootpc_call(nd, lwp)
|
|||
int vcilen;
|
||||
#endif
|
||||
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp);
|
||||
error = socreate(AF_INET, &so, SOCK_DGRAM, 0, lwp, NULL);
|
||||
if (error) {
|
||||
printf("bootp: socreate, error=%d\n", error);
|
||||
return (error);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_socket.c,v 1.169 2008/04/10 12:32:37 yamt Exp $ */
|
||||
/* $NetBSD: nfs_socket.c,v 1.170 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1991, 1993, 1995
|
||||
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.169 2008/04/10 12:32:37 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.170 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include "fs_nfs.h"
|
||||
#include "opt_nfs.h"
|
||||
|
@ -192,7 +192,7 @@ nfs_connect(nmp, rep, l)
|
|||
struct lwp *l;
|
||||
{
|
||||
struct socket *so;
|
||||
int s, error, rcvreserve, sndreserve;
|
||||
int error, rcvreserve, sndreserve;
|
||||
struct sockaddr *saddr;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef INET6
|
||||
|
@ -203,7 +203,7 @@ nfs_connect(nmp, rep, l)
|
|||
nmp->nm_so = (struct socket *)0;
|
||||
saddr = mtod(nmp->nm_nam, struct sockaddr *);
|
||||
error = socreate(saddr->sa_family, &nmp->nm_so,
|
||||
nmp->nm_sotype, nmp->nm_soproto, l);
|
||||
nmp->nm_sotype, nmp->nm_soproto, l, NULL);
|
||||
if (error)
|
||||
goto bad;
|
||||
so = nmp->nm_so;
|
||||
|
@ -262,40 +262,41 @@ nfs_connect(nmp, rep, l)
|
|||
* Protocols that do not require connections may be optionally left
|
||||
* unconnected for servers that reply from a port other than NFS_PORT.
|
||||
*/
|
||||
solock(so);
|
||||
if (nmp->nm_flag & NFSMNT_NOCONN) {
|
||||
if (nmp->nm_soflags & PR_CONNREQUIRED) {
|
||||
sounlock(so);
|
||||
error = ENOTCONN;
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
error = soconnect(so, nmp->nm_nam, l);
|
||||
if (error)
|
||||
if (error) {
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the connection to complete. Cribbed from the
|
||||
* connect system call but with the wait timing out so
|
||||
* that interruptible mounts don't hang here for a long time.
|
||||
*/
|
||||
s = splsoftnet();
|
||||
while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
|
||||
(void) tsleep((void *)&so->so_timeo, PSOCK,
|
||||
"nfscn1", 2 * hz);
|
||||
(void)sowait(so, 2 * hz);
|
||||
if ((so->so_state & SS_ISCONNECTING) &&
|
||||
so->so_error == 0 && rep &&
|
||||
(error = nfs_sigintr(nmp, rep, rep->r_lwp)) != 0){
|
||||
so->so_state &= ~SS_ISCONNECTING;
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
if (so->so_error) {
|
||||
error = so->so_error;
|
||||
so->so_error = 0;
|
||||
splx(s);
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
if (nmp->nm_flag & (NFSMNT_SOFT | NFSMNT_INT)) {
|
||||
so->so_rcv.sb_timeo = (5 * hz);
|
||||
|
@ -317,6 +318,7 @@ nfs_connect(nmp, rep, l)
|
|||
rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
|
||||
NFS_MAXPKTHDR) * 2;
|
||||
} else {
|
||||
sounlock(so);
|
||||
if (nmp->nm_sotype != SOCK_STREAM)
|
||||
panic("nfscon sotype");
|
||||
if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
|
||||
|
@ -337,12 +339,16 @@ nfs_connect(nmp, rep, l)
|
|||
sizeof (u_int32_t)) * 2;
|
||||
rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR +
|
||||
sizeof (u_int32_t)) * 2;
|
||||
solock(so);
|
||||
}
|
||||
error = soreserve(so, sndreserve, rcvreserve);
|
||||
if (error)
|
||||
if (error) {
|
||||
sounlock(so);
|
||||
goto bad;
|
||||
}
|
||||
so->so_rcv.sb_flags |= SB_NOINTR;
|
||||
so->so_snd.sb_flags |= SB_NOINTR;
|
||||
sounlock(so);
|
||||
|
||||
/* Initialize other non-zero congestion variables */
|
||||
nmp->nm_srtt[0] = nmp->nm_srtt[1] = nmp->nm_srtt[2] = nmp->nm_srtt[3] =
|
||||
|
@ -409,7 +415,9 @@ nfs_disconnect(nmp)
|
|||
if (nmp->nm_so) {
|
||||
so = nmp->nm_so;
|
||||
nmp->nm_so = (struct socket *)0;
|
||||
solock(so);
|
||||
soshutdown(so, SHUT_RDWR);
|
||||
sounlock(so);
|
||||
drain = (nmp->nm_iflag & NFSMNT_DISMNT) != 0;
|
||||
if (drain) {
|
||||
/*
|
||||
|
@ -499,9 +507,7 @@ nfs_send(so, nam, top, rep, l)
|
|||
else
|
||||
flags = 0;
|
||||
|
||||
KERNEL_LOCK(1, curlwp);
|
||||
error = (*so->so_send)(so, sendnam, NULL, top, NULL, flags, l);
|
||||
KERNEL_UNLOCK_ONE(curlwp);
|
||||
if (error) {
|
||||
if (rep) {
|
||||
if (error == ENOBUFS && so->so_type == SOCK_DGRAM) {
|
||||
|
@ -1674,6 +1680,7 @@ nfs_timer(void *arg)
|
|||
* Resend it
|
||||
* Set r_rtt to -1 in case we fail to send it now.
|
||||
*/
|
||||
solock(so);
|
||||
rep->r_rtt = -1;
|
||||
if (sbspace(&so->so_snd) >= rep->r_mreq->m_pkthdr.len &&
|
||||
((nmp->nm_flag & NFSMNT_DUMBTIMR) ||
|
||||
|
@ -1715,6 +1722,7 @@ nfs_timer(void *arg)
|
|||
rep->r_rtt = 0;
|
||||
}
|
||||
}
|
||||
sounlock(so);
|
||||
}
|
||||
splx(s);
|
||||
|
||||
|
@ -2240,9 +2248,7 @@ nfsrv_rcv(struct nfssvc_sock *slp)
|
|||
auio.uio_resid = 1000000000;
|
||||
/* not need to setup uio_vmspace */
|
||||
flags = MSG_DONTWAIT;
|
||||
KERNEL_LOCK(1, curlwp);
|
||||
error = (*so->so_receive)(so, &nam, &auio, &mp, NULL, &flags);
|
||||
KERNEL_UNLOCK_ONE(curlwp);
|
||||
if (error || mp == NULL) {
|
||||
if (error == EWOULDBLOCK)
|
||||
setflags |= SLP_A_NEEDQ;
|
||||
|
@ -2278,10 +2284,8 @@ nfsrv_rcv(struct nfssvc_sock *slp)
|
|||
auio.uio_resid = 1000000000;
|
||||
/* not need to setup uio_vmspace */
|
||||
flags = MSG_DONTWAIT;
|
||||
KERNEL_LOCK(1, curlwp);
|
||||
error = (*so->so_receive)(so, &nam, &auio, &mp, NULL,
|
||||
&flags);
|
||||
KERNEL_UNLOCK_ONE(curlwp);
|
||||
if (mp) {
|
||||
if (nam) {
|
||||
m = nam;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: nfs_syscalls.c,v 1.133 2008/03/23 00:46:25 rmind Exp $ */
|
||||
/* $NetBSD: nfs_syscalls.c,v 1.134 2008/04/24 11:38:39 ad Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
|
@ -35,7 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.133 2008/03/23 00:46:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nfs_syscalls.c,v 1.134 2008/04/24 11:38:39 ad Exp $");
|
||||
|
||||
#include "fs_nfs.h"
|
||||
#include "opt_nfs.h"
|
||||
|
@ -393,7 +393,7 @@ nfssvc_addsock(fp, mynam)
|
|||
struct nfssvc_sock *slp;
|
||||
struct socket *so;
|
||||
struct nfssvc_sock *tslp;
|
||||
int error, s;
|
||||
int error;
|
||||
|
||||
so = (struct socket *)fp->f_data;
|
||||
tslp = (struct nfssvc_sock *)0;
|
||||
|
@ -424,7 +424,9 @@ nfssvc_addsock(fp, mynam)
|
|||
siz = NFS_MAXPACKET + sizeof (u_long);
|
||||
else
|
||||
siz = NFS_MAXPACKET;
|
||||
solock(so);
|
||||
error = soreserve(so, siz, siz);
|
||||
sounlock(so);
|
||||
if (error) {
|
||||
m_freem(mynam);
|
||||
return (error);
|
||||
|
@ -454,10 +456,12 @@ nfssvc_addsock(fp, mynam)
|
|||
m->m_len = sizeof(int32_t);
|
||||
sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
|
||||
}
|
||||
solock(so);
|
||||
so->so_rcv.sb_flags &= ~SB_NOINTR;
|
||||
so->so_rcv.sb_timeo = 0;
|
||||
so->so_snd.sb_flags &= ~SB_NOINTR;
|
||||
so->so_snd.sb_timeo = 0;
|
||||
sounlock(so);
|
||||
if (tslp) {
|
||||
slp = tslp;
|
||||
} else {
|
||||
|
@ -473,13 +477,11 @@ nfssvc_addsock(fp, mynam)
|
|||
slp->ns_aflags = SLP_A_NEEDQ;
|
||||
slp->ns_gflags = 0;
|
||||
slp->ns_sflags = 0;
|
||||
KERNEL_LOCK(1, curlwp);
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
so->so_upcallarg = (void *)slp;
|
||||
so->so_upcall = nfsrv_soupcall;
|
||||
so->so_rcv.sb_flags |= SB_UPCALL;
|
||||
splx(s);
|
||||
KERNEL_UNLOCK_ONE(curlwp);
|
||||
sounlock(so);
|
||||
nfsrv_wakenfsd(slp);
|
||||
return (0);
|
||||
}
|
||||
|
@ -802,7 +804,6 @@ nfsrv_zapsock(slp)
|
|||
struct nfsrv_descript *nwp;
|
||||
struct socket *so;
|
||||
struct mbuf *m;
|
||||
int s;
|
||||
|
||||
if (nfsdsock_drain(slp)) {
|
||||
return;
|
||||
|
@ -816,14 +817,12 @@ nfsrv_zapsock(slp)
|
|||
|
||||
so = slp->ns_so;
|
||||
KASSERT(so != NULL);
|
||||
KERNEL_LOCK(1, curlwp);
|
||||
s = splsoftnet();
|
||||
solock(so);
|
||||
so->so_upcall = NULL;
|
||||
so->so_upcallarg = NULL;
|
||||
so->so_rcv.sb_flags &= ~SB_UPCALL;
|
||||
splx(s);
|
||||
soshutdown(so, SHUT_RDWR);
|
||||
KERNEL_UNLOCK_ONE(curlwp);
|
||||
sounlock(so);
|
||||
|
||||
if (slp->ns_nam)
|
||||
m_free(slp->ns_nam);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue