-/* $OpenBSD: uipc_socket.c,v 1.315 2024/01/26 18:24:23 mvs Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.316 2024/02/03 22:50:08 mvs Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
void filt_sowdetach(struct knote *kn);
int filt_sowrite(struct knote *kn, long hint);
int filt_soexcept(struct knote *kn, long hint);
-int filt_solisten(struct knote *kn, long hint);
-int filt_somodify(struct kevent *kev, struct knote *kn);
-int filt_soprocess(struct knote *kn, struct kevent *kev);
-const struct filterops solisten_filtops = {
- .f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
- .f_attach = NULL,
- .f_detach = filt_sordetach,
- .f_event = filt_solisten,
- .f_modify = filt_somodify,
- .f_process = filt_soprocess,
-};
+int filt_sowmodify(struct kevent *kev, struct knote *kn);
+int filt_sowprocess(struct knote *kn, struct kevent *kev);
+
+int filt_sormodify(struct kevent *kev, struct knote *kn);
+int filt_sorprocess(struct knote *kn, struct kevent *kev);
const struct filterops soread_filtops = {
.f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = NULL,
.f_detach = filt_sordetach,
.f_event = filt_soread,
- .f_modify = filt_somodify,
- .f_process = filt_soprocess,
+ .f_modify = filt_sormodify,
+ .f_process = filt_sorprocess,
};
const struct filterops sowrite_filtops = {
.f_attach = NULL,
.f_detach = filt_sowdetach,
.f_event = filt_sowrite,
- .f_modify = filt_somodify,
- .f_process = filt_soprocess,
+ .f_modify = filt_sowmodify,
+ .f_process = filt_sowprocess,
};
const struct filterops soexcept_filtops = {
.f_attach = NULL,
.f_detach = filt_sordetach,
.f_event = filt_soexcept,
- .f_modify = filt_somodify,
- .f_process = filt_soprocess,
-};
-
-void klist_soassertlk(void *);
-int klist_solock(void *);
-void klist_sounlock(void *, int);
-
-const struct klistops socket_klistops = {
- .klo_assertlk = klist_soassertlk,
- .klo_lock = klist_solock,
- .klo_unlock = klist_sounlock,
+ .f_modify = filt_sormodify,
+ .f_process = filt_sorprocess,
};
#ifndef SOMINCONN
return (NULL);
rw_init_flags(&so->so_lock, dp->dom_name, RWL_DUPOK);
refcnt_init(&so->so_refcnt);
- klist_init(&so->so_rcv.sb_klist, &socket_klistops, so);
- klist_init(&so->so_snd.sb_klist, &socket_klistops, so);
+ mtx_init(&so->so_rcv.sb_mtx, IPL_MPFLOOR);
+ mtx_init(&so->so_snd.sb_mtx, IPL_MPFLOOR);
+ klist_init_mutex(&so->so_rcv.sb_klist, &so->so_rcv.sb_mtx);
+ klist_init_mutex(&so->so_snd.sb_klist, &so->so_snd.sb_mtx);
sigio_init(&so->so_sigio);
TAILQ_INIT(&so->so_q0);
TAILQ_INIT(&so->so_q);
void
sorwakeup(struct socket *so)
{
- soassertlocked(so);
+ soassertlocked_readonly(so);
#ifdef SOCKET_SPLICE
if (so->so_rcv.sb_flags & SB_SPLICE) {
void
sowwakeup(struct socket *so)
{
- soassertlocked(so);
+ soassertlocked_readonly(so);
#ifdef SOCKET_SPLICE
if (so->so_snd.sb_flags & SB_SPLICE)
sohasoutofband(struct socket *so)
{
pgsigio(&so->so_sigio, SIGURG, 0);
- knote_locked(&so->so_rcv.sb_klist, 0);
+ knote(&so->so_rcv.sb_klist, 0);
+}
+
+void
+sofilt_lock(struct socket *so, struct sockbuf *sb)
+{
+ switch (so->so_proto->pr_domain->dom_family) {
+ case PF_INET:
+ case PF_INET6:
+ NET_LOCK_SHARED();
+ break;
+ default:
+ rw_enter_write(&so->so_lock);
+ break;
+ }
+
+ mtx_enter(&sb->sb_mtx);
+}
+
+void
+sofilt_unlock(struct socket *so, struct sockbuf *sb)
+{
+ mtx_leave(&sb->sb_mtx);
+
+ switch (so->so_proto->pr_domain->dom_family) {
+ case PF_INET:
+ case PF_INET6:
+ NET_UNLOCK_SHARED();
+ break;
+ default:
+ rw_exit_write(&so->so_lock);
+ break;
+ }
+}
+
+static inline void
+sofilt_assert_locked(struct socket *so, struct sockbuf *sb)
+{
+ MUTEX_ASSERT_LOCKED(&sb->sb_mtx);
+ soassertlocked_readonly(so);
}
int
struct socket *so = kn->kn_fp->f_data;
struct sockbuf *sb;
- solock(so);
switch (kn->kn_filter) {
case EVFILT_READ:
- if (so->so_options & SO_ACCEPTCONN)
- kn->kn_fop = &solisten_filtops;
- else
- kn->kn_fop = &soread_filtops;
+ kn->kn_fop = &soread_filtops;
sb = &so->so_rcv;
break;
case EVFILT_WRITE:
sb = &so->so_rcv;
break;
default:
- sounlock(so);
return (EINVAL);
}
- klist_insert_locked(&sb->sb_klist, kn);
- sounlock(so);
+ klist_insert(&sb->sb_klist, kn);
return (0);
}
struct socket *so = kn->kn_fp->f_data;
int rv = 0;
- soassertlocked(so);
+ sofilt_assert_locked(so, &so->so_rcv);
+
+ if (so->so_options & SO_ACCEPTCONN) {
+ kn->kn_data = so->so_qlen;
+ rv = (kn->kn_data != 0);
+
+ if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) {
+ if (so->so_state & SS_ISDISCONNECTED) {
+ kn->kn_flags |= __EV_HUP;
+ rv = 1;
+ } else {
+ rv = soreadable(so);
+ }
+ }
+
+ return rv;
+ }
kn->kn_data = so->so_rcv.sb_cc;
#ifdef SOCKET_SPLICE
struct socket *so = kn->kn_fp->f_data;
int rv;
- soassertlocked(so);
+ sofilt_assert_locked(so, &so->so_snd);
kn->kn_data = sbspace(so, &so->so_snd);
if (so->so_snd.sb_state & SS_CANTSENDMORE) {
struct socket *so = kn->kn_fp->f_data;
int rv = 0;
- soassertlocked(so);
+ sofilt_assert_locked(so, &so->so_rcv);
#ifdef SOCKET_SPLICE
if (isspliced(so)) {
}
int
-filt_solisten(struct knote *kn, long hint)
+filt_sowmodify(struct kevent *kev, struct knote *kn)
{
struct socket *so = kn->kn_fp->f_data;
- int active;
-
- soassertlocked(so);
-
- kn->kn_data = so->so_qlen;
- active = (kn->kn_data != 0);
+ int rv;
- if (kn->kn_flags & (__EV_POLL | __EV_SELECT)) {
- if (so->so_state & SS_ISDISCONNECTED) {
- kn->kn_flags |= __EV_HUP;
- active = 1;
- } else {
- active = soreadable(so);
- }
- }
+ sofilt_lock(so, &so->so_snd);
+ rv = knote_modify(kev, kn);
+ sofilt_unlock(so, &so->so_snd);
- return (active);
+ return (rv);
}
int
-filt_somodify(struct kevent *kev, struct knote *kn)
+filt_sowprocess(struct knote *kn, struct kevent *kev)
{
struct socket *so = kn->kn_fp->f_data;
int rv;
- solock(so);
- rv = knote_modify(kev, kn);
- sounlock(so);
+ sofilt_lock(so, &so->so_snd);
+ rv = knote_process(kn, kev);
+ sofilt_unlock(so, &so->so_snd);
return (rv);
}
int
-filt_soprocess(struct knote *kn, struct kevent *kev)
+filt_sormodify(struct kevent *kev, struct knote *kn)
{
struct socket *so = kn->kn_fp->f_data;
int rv;
- solock(so);
- rv = knote_process(kn, kev);
- sounlock(so);
+ sofilt_lock(so, &so->so_rcv);
+ rv = knote_modify(kev, kn);
+ sofilt_unlock(so, &so->so_rcv);
return (rv);
}
-void
-klist_soassertlk(void *arg)
-{
- struct socket *so = arg;
-
- soassertlocked(so);
-}
-
int
-klist_solock(void *arg)
+filt_sorprocess(struct knote *kn, struct kevent *kev)
{
- struct socket *so = arg;
-
- solock(so);
- return (1);
-}
+ struct socket *so = kn->kn_fp->f_data;
+ int rv;
-void
-klist_sounlock(void *arg, int ls)
-{
- struct socket *so = arg;
+ sofilt_lock(so, &so->so_rcv);
+ rv = knote_process(kn, kev);
+ sofilt_unlock(so, &so->so_rcv);
- sounlock(so);
+ return (rv);
}
#ifdef DDB
-/* $OpenBSD: uipc_socket2.c,v 1.140 2024/01/11 14:15:11 bluhm Exp $ */
+/* $OpenBSD: uipc_socket2.c,v 1.141 2024/02/03 22:50:08 mvs Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
}
void
-soassertlocked(struct socket *so)
+soassertlocked_readonly(struct socket *so)
{
switch (so->so_proto->pr_domain->dom_family) {
case PF_INET:
}
}
+void
+soassertlocked(struct socket *so)
+{
+ switch (so->so_proto->pr_domain->dom_family) {
+ case PF_INET:
+ case PF_INET6:
+ if (rw_status(&netlock) == RW_READ) {
+ NET_ASSERT_LOCKED();
+
+ if (splassert_ctl > 0 && pru_locked(so) == 0 &&
+ rw_status(&so->so_lock) != RW_WRITE)
+ splassert_fail(0, RW_WRITE, __func__);
+ } else
+ NET_ASSERT_LOCKED_EXCLUSIVE();
+ break;
+ default:
+ rw_assert_wrlock(&so->so_lock);
+ break;
+ }
+}
+
int
sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg,
uint64_t nsecs)
soassertlocked(so);
+ mtx_enter(&sb->sb_mtx);
sb->sb_flags |= SB_WAIT;
+ mtx_leave(&sb->sb_mtx);
+
return sosleep_nsec(so, &sb->sb_cc, prio, "netio", sb->sb_timeo_nsecs);
}
int
sblock(struct socket *so, struct sockbuf *sb, int flags)
{
- int error, prio = PSOCK;
+ int error = 0, prio = PSOCK;
soassertlocked(so);
+ mtx_enter(&sb->sb_mtx);
if ((sb->sb_flags & SB_LOCK) == 0) {
sb->sb_flags |= SB_LOCK;
- return (0);
+ goto out;
+ }
+ if ((flags & SBL_WAIT) == 0) {
+ error = EWOULDBLOCK;
+ goto out;
}
- if ((flags & SBL_WAIT) == 0)
- return (EWOULDBLOCK);
if (!(flags & SBL_NOINTR || sb->sb_flags & SB_NOINTR))
prio |= PCATCH;
while (sb->sb_flags & SB_LOCK) {
sb->sb_flags |= SB_WANT;
+ mtx_leave(&sb->sb_mtx);
error = sosleep_nsec(so, &sb->sb_flags, prio, "netlck", INFSLP);
if (error)
return (error);
+ mtx_enter(&sb->sb_mtx);
}
sb->sb_flags |= SB_LOCK;
- return (0);
+out:
+ mtx_leave(&sb->sb_mtx);
+
+ return (error);
}
void
sbunlock(struct socket *so, struct sockbuf *sb)
{
- soassertlocked(so);
+ int dowakeup = 0;
+ mtx_enter(&sb->sb_mtx);
sb->sb_flags &= ~SB_LOCK;
if (sb->sb_flags & SB_WANT) {
sb->sb_flags &= ~SB_WANT;
- wakeup(&sb->sb_flags);
+ dowakeup = 1;
}
+ mtx_leave(&sb->sb_mtx);
+
+ if (dowakeup)
+ wakeup(&sb->sb_flags);
}
/*
void
sowakeup(struct socket *so, struct sockbuf *sb)
{
- soassertlocked(so);
+ int dowakeup = 0, dopgsigio = 0;
+ mtx_enter(&sb->sb_mtx);
if (sb->sb_flags & SB_WAIT) {
sb->sb_flags &= ~SB_WAIT;
- wakeup(&sb->sb_cc);
+ dowakeup = 1;
}
if (sb->sb_flags & SB_ASYNC)
- pgsigio(&so->so_sigio, SIGIO, 0);
+ dopgsigio = 1;
+
knote_locked(&sb->sb_klist, 0);
+ mtx_leave(&sb->sb_mtx);
+
+ if (dowakeup)
+ wakeup(&sb->sb_cc);
+
+ if (dopgsigio)
+ pgsigio(&so->so_sigio, SIGIO, 0);
}
/*
-/* $OpenBSD: uipc_syscalls.c,v 1.216 2024/01/03 11:07:04 bluhm Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.217 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
: (flags & SOCK_NONBLOCK ? FNONBLOCK : 0);
/* connection has been removed from the listen queue */
- knote_locked(&head->so_rcv.sb_klist, 0);
+ knote(&head->so_rcv.sb_klist, 0);
if (persocket)
sounlock(head);
-/* $OpenBSD: fifo_vnops.c,v 1.102 2023/03/08 04:43:08 guenther Exp $ */
+/* $OpenBSD: fifo_vnops.c,v 1.103 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
/*
void filt_fifowdetach(struct knote *kn);
int filt_fifowrite(struct knote *kn, long hint);
int filt_fifoexcept(struct knote *kn, long hint);
-int filt_fifomodify(struct kevent *kev, struct knote *kn);
-int filt_fifoprocess(struct knote *kn, struct kevent *kev);
+int filt_fiformodify(struct kevent *kev, struct knote *kn);
+int filt_fiforprocess(struct knote *kn, struct kevent *kev);
+int filt_fifowmodify(struct kevent *kev, struct knote *kn);
+int filt_fifowprocess(struct knote *kn, struct kevent *kev);
const struct filterops fiforead_filtops = {
.f_flags = FILTEROP_ISFD | FILTEROP_MPSAFE,
.f_attach = NULL,
.f_detach = filt_fifordetach,
.f_event = filt_fiforead,
- .f_modify = filt_fifomodify,
- .f_process = filt_fifoprocess,
+ .f_modify = filt_fiformodify,
+ .f_process = filt_fiforprocess,
};
const struct filterops fifowrite_filtops = {
.f_attach = NULL,
.f_detach = filt_fifowdetach,
.f_event = filt_fifowrite,
- .f_modify = filt_fifomodify,
- .f_process = filt_fifoprocess,
+ .f_modify = filt_fifowmodify,
+ .f_process = filt_fifowprocess,
};
const struct filterops fifoexcept_filtops = {
.f_attach = NULL,
.f_detach = filt_fifordetach,
.f_event = filt_fifoexcept,
- .f_modify = filt_fifomodify,
- .f_process = filt_fifoprocess,
+ .f_modify = filt_fiformodify,
+ .f_process = filt_fiforprocess,
};
/*
int rv;
soassertlocked(so);
+ MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx);
kn->kn_data = so->so_rcv.sb_cc;
if (so->so_rcv.sb_state & SS_CANTRCVMORE) {
int rv;
soassertlocked(so);
+ MUTEX_ASSERT_LOCKED(&so->so_snd.sb_mtx);
kn->kn_data = sbspace(so, &so->so_snd);
if (so->so_snd.sb_state & SS_CANTSENDMORE) {
int rv = 0;
soassertlocked(so);
+ MUTEX_ASSERT_LOCKED(&so->so_rcv.sb_mtx);
if (kn->kn_flags & __EV_POLL) {
if (so->so_state & SS_ISDISCONNECTED) {
}
int
-filt_fifomodify(struct kevent *kev, struct knote *kn)
+filt_fiformodify(struct kevent *kev, struct knote *kn)
{
struct socket *so = kn->kn_hook;
int rv;
solock(so);
+ mtx_enter(&so->so_rcv.sb_mtx);
rv = knote_modify(kev, kn);
+ mtx_leave(&so->so_rcv.sb_mtx);
sounlock(so);
return (rv);
}
int
-filt_fifoprocess(struct knote *kn, struct kevent *kev)
+filt_fiforprocess(struct knote *kn, struct kevent *kev)
{
struct socket *so = kn->kn_hook;
int rv;
solock(so);
+ mtx_enter(&so->so_rcv.sb_mtx);
rv = knote_process(kn, kev);
+ mtx_leave(&so->so_rcv.sb_mtx);
+ sounlock(so);
+
+ return (rv);
+}
+
+int
+filt_fifowmodify(struct kevent *kev, struct knote *kn)
+{
+ struct socket *so = kn->kn_hook;
+ int rv;
+
+ solock(so);
+ mtx_enter(&so->so_snd.sb_mtx);
+ rv = knote_modify(kev, kn);
+ mtx_leave(&so->so_snd.sb_mtx);
+ sounlock(so);
+
+ return (rv);
+}
+
+int
+filt_fifowprocess(struct knote *kn, struct kevent *kev)
+{
+ struct socket *so = kn->kn_hook;
+ int rv;
+
+ solock(so);
+ mtx_enter(&so->so_snd.sb_mtx);
+ rv = knote_process(kn, kev);
+ mtx_leave(&so->so_snd.sb_mtx);
sounlock(so);
return (rv);
-/* $OpenBSD: ip_divert.c,v 1.92 2023/09/16 09:33:27 mpi Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.93 2024/02/03 22:50:09 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
.pru_detach = divert_detach,
.pru_lock = divert_lock,
.pru_unlock = divert_unlock,
+ .pru_locked = divert_locked,
.pru_bind = divert_bind,
.pru_shutdown = divert_shutdown,
.pru_send = divert_send,
mtx_leave(&inp->inp_mtx);
}
+int
+divert_locked(struct socket *so)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ return mtx_owned(&inp->inp_mtx);
+}
+
int
divert_bind(struct socket *so, struct mbuf *addr, struct proc *p)
{
-/* $OpenBSD: ip_divert.h,v 1.24 2022/10/17 14:49:02 mvs Exp $ */
+/* $OpenBSD: ip_divert.h,v 1.25 2024/02/03 22:50:09 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
int divert_detach(struct socket *);
void divert_lock(struct socket *);
void divert_unlock(struct socket *);
+int divert_locked(struct socket *);
int divert_bind(struct socket *, struct mbuf *, struct proc *);
int divert_shutdown(struct socket *);
int divert_send(struct socket *, struct mbuf *, struct mbuf *,
-/* $OpenBSD: ip_var.h,v 1.110 2023/11/26 22:08:10 bluhm Exp $ */
+/* $OpenBSD: ip_var.h,v 1.111 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
int rip_detach(struct socket *);
void rip_lock(struct socket *);
void rip_unlock(struct socket *);
+int rip_locked(struct socket *);
int rip_bind(struct socket *, struct mbuf *, struct proc *);
int rip_connect(struct socket *, struct mbuf *);
int rip_disconnect(struct socket *);
-/* $OpenBSD: raw_ip.c,v 1.154 2024/01/21 01:17:20 bluhm Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.155 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
.pru_detach = rip_detach,
.pru_lock = rip_lock,
.pru_unlock = rip_unlock,
+ .pru_locked = rip_locked,
.pru_bind = rip_bind,
.pru_connect = rip_connect,
.pru_disconnect = rip_disconnect,
mtx_leave(&inp->inp_mtx);
}
+int
+rip_locked(struct socket *so)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ return mtx_owned(&inp->inp_mtx);
+}
+
int
rip_bind(struct socket *so, struct mbuf *nam, struct proc *p)
{
-/* $OpenBSD: udp_usrreq.c,v 1.316 2024/01/28 20:34:25 bluhm Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.317 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
.pru_detach = udp_detach,
.pru_lock = udp_lock,
.pru_unlock = udp_unlock,
+ .pru_locked = udp_locked,
.pru_bind = udp_bind,
.pru_connect = udp_connect,
.pru_disconnect = udp_disconnect,
.pru_detach = udp_detach,
.pru_lock = udp_lock,
.pru_unlock = udp_unlock,
+ .pru_locked = udp_locked,
.pru_bind = udp_bind,
.pru_connect = udp_connect,
.pru_disconnect = udp_disconnect,
mtx_leave(&inp->inp_mtx);
}
+int
+udp_locked(struct socket *so)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ return mtx_owned(&inp->inp_mtx);
+}
+
int
udp_bind(struct socket *so, struct mbuf *addr, struct proc *p)
{
-/* $OpenBSD: udp_var.h,v 1.50 2024/01/10 16:44:30 bluhm Exp $ */
+/* $OpenBSD: udp_var.h,v 1.51 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: udp_var.h,v 1.12 1996/02/13 23:44:41 christos Exp $ */
/*
int udp_detach(struct socket *);
void udp_lock(struct socket *);
void udp_unlock(struct socket *);
+int udp_locked(struct socket *);
int udp_bind(struct socket *, struct mbuf *, struct proc *);
int udp_connect(struct socket *, struct mbuf *);
int udp_disconnect(struct socket *);
-/* $OpenBSD: ip6_divert.c,v 1.91 2024/01/01 18:52:09 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.92 2024/02/03 22:50:09 mvs Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
.pru_detach = divert_detach,
.pru_lock = divert_lock,
.pru_unlock = divert_unlock,
+ .pru_locked = divert_locked,
.pru_bind = divert_bind,
.pru_shutdown = divert_shutdown,
.pru_send = divert6_send,
-/* $OpenBSD: ip6_mroute.c,v 1.138 2023/12/06 09:27:17 bluhm Exp $ */
+/* $OpenBSD: ip6_mroute.c,v 1.139 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: ip6_mroute.c,v 1.59 2003/12/10 09:28:38 itojun Exp $ */
/* $KAME: ip6_mroute.c,v 1.45 2001/03/25 08:38:51 itojun Exp $ */
mtx_enter(&inp->inp_mtx);
ret = sbappendaddr(so, &so->so_rcv, sin6tosa(src), mm, NULL);
+ if (ret != 0)
+ sorwakeup(so);
mtx_leave(&inp->inp_mtx);
- if (ret != 0) {
- sorwakeup(so);
+ if (ret != 0)
return 0;
- }
}
m_freem(mm);
return -1;
-/* $OpenBSD: ip6_var.h,v 1.109 2023/12/03 20:36:24 bluhm Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.110 2024/02/03 22:50:09 mvs Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
int rip6_detach(struct socket *);
void rip6_lock(struct socket *);
void rip6_unlock(struct socket *);
+int rip6_locked(struct socket *);
int rip6_bind(struct socket *, struct mbuf *, struct proc *);
int rip6_connect(struct socket *, struct mbuf *);
int rip6_disconnect(struct socket *);
-/* $OpenBSD: raw_ip6.c,v 1.179 2024/01/21 01:17:20 bluhm Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.180 2024/02/03 22:50:09 mvs Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
.pru_detach = rip6_detach,
.pru_lock = rip6_lock,
.pru_unlock = rip6_unlock,
+ .pru_locked = rip6_locked,
.pru_bind = rip6_bind,
.pru_connect = rip6_connect,
.pru_disconnect = rip6_disconnect,
mtx_leave(&inp->inp_mtx);
}
+int
+rip6_locked(struct socket *so)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ return mtx_owned(&inp->inp_mtx);
+}
+
int
rip6_bind(struct socket *so, struct mbuf *nam, struct proc *p)
{
-/* $OpenBSD: mutex.h,v 1.19 2023/12/01 14:37:22 bluhm Exp $ */
+/* $OpenBSD: mutex.h,v 1.20 2024/02/03 22:50:09 mvs Exp $ */
/*
* Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
#define mtx_init(m, ipl) mtx_init_flags(m, ipl, NULL, 0)
+#define mtx_owned(mtx) \
+ (((mtx)->mtx_owner == curcpu()) || panicstr || db_active)
+
#ifdef WITNESS
void _mtx_init_flags(struct mutex *, int, const char *, int,
-/* $OpenBSD: protosw.h,v 1.64 2024/01/11 14:15:12 bluhm Exp $ */
+/* $OpenBSD: protosw.h,v 1.65 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: protosw.h,v 1.10 1996/04/09 20:55:32 cgd Exp $ */
/*-
int (*pru_detach)(struct socket *);
void (*pru_lock)(struct socket *);
void (*pru_unlock)(struct socket *);
+ int (*pru_locked)(struct socket *so);
int (*pru_bind)(struct socket *, struct mbuf *, struct proc *);
int (*pru_listen)(struct socket *);
int (*pru_connect)(struct socket *, struct mbuf *);
(*so->so_proto->pr_usrreqs->pru_unlock)(so);
}
+static inline int
+pru_locked(struct socket *so)
+{
+ if (so->so_proto->pr_usrreqs->pru_locked)
+ return (*so->so_proto->pr_usrreqs->pru_locked)(so);
+ return (0);
+}
+
static inline int
pru_bind(struct socket *so, struct mbuf *nam, struct proc *p)
{
-/* $OpenBSD: socketvar.h,v 1.121 2024/01/11 14:15:12 bluhm Exp $ */
+/* $OpenBSD: socketvar.h,v 1.122 2024/02/03 22:50:09 mvs Exp $ */
/* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */
/*-
#include <sys/sigio.h> /* for struct sigio_ref */
#include <sys/task.h>
#include <sys/timeout.h>
+#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/refcnt.h>
* Variables for socket buffering.
*/
struct sockbuf {
+ struct mutex sb_mtx;
/* The following fields are all zeroed on flush. */
#define sb_startzero sb_cc
u_long sb_cc; /* actual chars in buffer */
#include <lib/libkern/libkern.h>
void soassertlocked(struct socket *);
+void soassertlocked_readonly(struct socket *);
static inline void
soref(struct socket *so)
static inline int
sb_notify(struct socket *so, struct sockbuf *sb)
{
+ int rv;
+
soassertlocked(so);
- return ((sb->sb_flags & (SB_WAIT|SB_ASYNC|SB_SPLICE)) != 0 ||
+
+ mtx_enter(&sb->sb_mtx);
+ rv = ((sb->sb_flags & (SB_WAIT|SB_ASYNC|SB_SPLICE)) != 0 ||
!klist_empty(&sb->sb_klist));
+ mtx_leave(&sb->sb_mtx);
+
+ return rv;
}
/*
* still be negative (cc > hiwat or mbcnt > mbmax). Should detect
* overflow and return 0.
*/
+
static inline long
sbspace(struct socket *so, struct sockbuf *sb)
{
- soassertlocked(so);
+ soassertlocked_readonly(so);
+
return lmin(sb->sb_hiwat - sb->sb_cc, sb->sb_mbmax - sb->sb_mbcnt);
}
static inline int
soreadable(struct socket *so)
{
- soassertlocked(so);
+ soassertlocked_readonly(so);
if (isspliced(so))
return 0;
return (so->so_rcv.sb_state & SS_CANTRCVMORE) || so->so_qlen ||
static inline int
sowriteable(struct socket *so)
{
- soassertlocked(so);
+ soassertlocked_readonly(so);
return ((sbspace(so, &so->so_snd) >= so->so_snd.sb_lowat &&
((so->so_state & SS_ISCONNECTED) ||
(so->so_proto->pr_flags & PR_CONNREQUIRED)==0)) ||