summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2017-03-07 09:23:27 +0000
committermpi <mpi@openbsd.org>2017-03-07 09:23:27 +0000
commit143ab7fc259aff7c83770a7286feb60e15721391 (patch)
tree6c133422618844e51864253d24d9b090a48feb05
parenttls_close() can return TLS_WANT_POLLIN/TLS_WANT_POLLOUT, handle them (diff)
downloadwireguard-openbsd-143ab7fc259aff7c83770a7286feb60e15721391.tar.xz
wireguard-openbsd-143ab7fc259aff7c83770a7286feb60e15721391.zip
Do not grab the NET_LOCK() for routing sockets operations.
The only function that need the lock is rtm_output() as it messes with the routing table. So grab the lock there since it is safe to sleep in a process context. ok bluhm@
-rw-r--r--sys/kern/uipc_socket.c5
-rw-r--r--sys/kern/uipc_socket2.c13
-rw-r--r--sys/net/raw_usrreq.c4
-rw-r--r--sys/net/route.h6
-rw-r--r--sys/net/rtsock.c14
5 files changed, 25 insertions, 17 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 1affe913afc..93162a4e256 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.178 2017/03/03 09:41:20 mpi Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.179 2017/03/07 09:23:27 mpi Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -1038,11 +1038,12 @@ sorflush(struct socket *so)
{
struct sockbuf *sb = &so->so_rcv;
struct protosw *pr = so->so_proto;
+ sa_family_t af = pr->pr_domain->dom_family;
struct sockbuf asb;
sb->sb_flags |= SB_NOINTR;
sblock(sb, M_WAITOK,
- (pr->pr_domain->dom_family != PF_LOCAL) ? &netlock : NULL);
+ (af != PF_LOCAL && af != PF_ROUTE) ? &netlock : NULL);
socantrcvmore(so);
sbunlock(sb);
asb = *sb;
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 3a09b229477..aca06097411 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket2.c,v 1.72 2017/02/14 09:46:21 mpi Exp $ */
+/* $OpenBSD: uipc_socket2.c,v 1.73 2017/03/07 09:23:27 mpi Exp $ */
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
/*
@@ -273,7 +273,8 @@ solock(struct socket *so)
{
int s;
- if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
+ if ((so->so_proto->pr_domain->dom_family != PF_LOCAL) &&
+ (so->so_proto->pr_domain->dom_family != PF_ROUTE))
NET_LOCK(s);
else
s = -42;
@@ -291,16 +292,18 @@ sounlock(int s)
void
soassertlocked(struct socket *so)
{
- if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
+ if ((so->so_proto->pr_domain->dom_family != PF_LOCAL) &&
+ (so->so_proto->pr_domain->dom_family != PF_ROUTE))
NET_ASSERT_LOCKED();
}
int
sosleep(struct socket *so, void *ident, int prio, const char *wmesg, int timo)
{
- if (so->so_proto->pr_domain->dom_family != PF_LOCAL)
+ if ((so->so_proto->pr_domain->dom_family != PF_LOCAL) &&
+ (so->so_proto->pr_domain->dom_family != PF_ROUTE)) {
return rwsleep(ident, &netlock, prio, wmesg, timo);
- else
+ } else
return tsleep(ident, prio, wmesg, timo);
}
diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c
index 1d777cec7e0..de4b7836a92 100644
--- a/sys/net/raw_usrreq.c
+++ b/sys/net/raw_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_usrreq.c,v 1.29 2017/03/03 15:48:02 bluhm Exp $ */
+/* $OpenBSD: raw_usrreq.c,v 1.30 2017/03/07 09:23:27 mpi Exp $ */
/* $NetBSD: raw_usrreq.c,v 1.11 1996/02/13 22:00:43 christos Exp $ */
/*
@@ -63,7 +63,7 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
int error = 0;
int len;
- NET_ASSERT_LOCKED();
+ soassertlocked(so);
if (req == PRU_CONTROL)
return (EOPNOTSUPP);
diff --git a/sys/net/route.h b/sys/net/route.h
index 376d086994e..6ad78b38379 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.159 2017/03/06 08:56:39 mpi Exp $ */
+/* $OpenBSD: route.h,v 1.160 2017/03/07 09:23:27 mpi Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -417,10 +417,6 @@ struct sockaddr_in6;
struct bfd_config;
void route_init(void);
-int route_output(struct mbuf *, struct socket *, struct sockaddr *,
- struct mbuf *);
-int route_usrreq(struct socket *, int, struct mbuf *,
- struct mbuf *, struct mbuf *, struct proc *);
void rtm_ifchg(struct ifnet *);
void rtm_ifannounce(struct ifnet *, int);
void rtm_bfd(struct bfd_config *);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 67aca043704..250f411ca56 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.231 2017/03/07 06:58:55 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.232 2017/03/07 09:23:27 mpi Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -98,7 +98,11 @@ struct walkarg {
caddr_t w_where, w_tmem;
};
+int route_output(struct mbuf *, struct socket *, struct sockaddr *,
+ struct mbuf *);
int route_ctloutput(int, struct socket *, int, int, struct mbuf *);
+int route_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
+ struct mbuf *, struct proc *);
void route_input(struct mbuf *m0, struct socket *, sa_family_t);
int route_arp_conflict(struct rtentry *, struct rt_addrinfo *);
int route_cleargateway(struct rtentry *, void *, unsigned int);
@@ -159,8 +163,6 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
int af;
int error = 0;
- NET_ASSERT_LOCKED();
-
rp = sotorawcb(so);
switch (req) {
@@ -345,6 +347,8 @@ route_input(struct mbuf *m0, struct socket *so, sa_family_t sa_family)
struct socket *last = NULL;
struct sockaddr *sosrc, *sodst;
+ KERNEL_ASSERT_LOCKED();
+
sosrc = &route_src;
sodst = &route_dst;
@@ -734,7 +738,9 @@ rtm_output(struct rt_msghdr *rtm, struct rtentry **prt,
struct sockaddr_mpls *psa_mpls;
#endif
int plen, newgate = 0, error = 0;
+ int s;
+ NET_LOCK(s);
switch (rtm->rtm_type) {
case RTM_ADD:
if (info->rti_info[RTAX_GATEWAY] == NULL) {
@@ -979,6 +985,8 @@ change:
error = ESRCH;
break;
}
+ NET_UNLOCK(s);
+
*prt = rt;
return (error);
}