Re: PF_ROUTE vs NET_LOCK(), take 2

2017-03-06 Thread Alexander Bluhm
On Mon, Mar 06, 2017 at 01:33:19PM +0100, Martin Pieuchot wrote:
> After some refactoring, here's the updated diff to take the routing
> sockets out of the NET_LOCK().
> 
> ok?

OK bluhm@

> 
> Index: net/raw_usrreq.c
> ===
> RCS file: /cvs/src/sys/net/raw_usrreq.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 raw_usrreq.c
> --- net/raw_usrreq.c  3 Mar 2017 15:48:02 -   1.29
> +++ net/raw_usrreq.c  6 Mar 2017 12:23:57 -
> @@ -63,7 +63,7 @@ raw_usrreq(struct socket *so, int req, s
>   int error = 0;
>   int len;
>  
> - NET_ASSERT_LOCKED();
> + soassertlocked(so);
>  
>   if (req == PRU_CONTROL)
>   return (EOPNOTSUPP);
> Index: net/route.h
> ===
> RCS file: /cvs/src/sys/net/route.h,v
> retrieving revision 1.159
> diff -u -p -r1.159 route.h
> --- net/route.h   6 Mar 2017 08:56:39 -   1.159
> +++ net/route.h   6 Mar 2017 12:26:14 -
> @@ -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 *);
> Index: net/rtsock.c
> ===
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.230
> diff -u -p -r1.230 rtsock.c
> --- net/rtsock.c  6 Mar 2017 10:19:17 -   1.230
> +++ net/rtsock.c  6 Mar 2017 12:28:11 -
> @@ -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, 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,
>   int  af;
>   int  error = 0;
>  
> - NET_ASSERT_LOCKED();
> -
>   rp = sotorawcb(so);
>  
>   switch (req) {
> @@ -345,6 +347,8 @@ route_input(struct mbuf *m0, sa_family_t
>   struct socket *last = NULL;
>   struct sockaddr *sosrc, *sodst;
>  
> + KERNEL_ASSERT_LOCKED();
> +
>   sosrc = _src;
>   sodst = _dst;
>  
> @@ -736,7 +740,9 @@ rtm_output(struct rt_msghdr *rtm, struct
>   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) {
> @@ -981,6 +987,8 @@ change:
>   error = ESRCH;
>   break;
>   }
> + NET_UNLOCK(s);
> +
>   *prt = rt;
>   return (error);
>  }
> Index: kern/uipc_socket.c
> ===
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.178
> diff -u -p -r1.178 uipc_socket.c
> --- kern/uipc_socket.c3 Mar 2017 09:41:20 -   1.178
> +++ kern/uipc_socket.c6 Mar 2017 12:23:57 -
> @@ -1038,11 +1038,12 @@ sorflush(struct socket *so)
>  {
>   struct sockbuf *sb = >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) ?  : NULL);
> + (af != PF_LOCAL && af != PF_ROUTE) ?  : NULL);
>   socantrcvmore(so);
>   sbunlock(sb);
>   asb = *sb;
> Index: kern/uipc_socket2.c
> ===
> RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
> retrieving revision 1.72
> diff -u -p -r1.72 uipc_socket2.c
> --- kern/uipc_socket2.c   14 Feb 2017 09:46:21 -  1.72
> +++ kern/uipc_socket2.c   6 Mar 2017 12:23:57 -
> @@ -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 

PF_ROUTE vs NET_LOCK(), take 2

2017-03-06 Thread Martin Pieuchot
After some refactoring, here's the updated diff to take the routing
sockets out of the NET_LOCK().

ok?

Index: net/raw_usrreq.c
===
RCS file: /cvs/src/sys/net/raw_usrreq.c,v
retrieving revision 1.29
diff -u -p -r1.29 raw_usrreq.c
--- net/raw_usrreq.c3 Mar 2017 15:48:02 -   1.29
+++ net/raw_usrreq.c6 Mar 2017 12:23:57 -
@@ -63,7 +63,7 @@ raw_usrreq(struct socket *so, int req, s
int error = 0;
int len;
 
-   NET_ASSERT_LOCKED();
+   soassertlocked(so);
 
if (req == PRU_CONTROL)
return (EOPNOTSUPP);
Index: net/route.h
===
RCS file: /cvs/src/sys/net/route.h,v
retrieving revision 1.159
diff -u -p -r1.159 route.h
--- net/route.h 6 Mar 2017 08:56:39 -   1.159
+++ net/route.h 6 Mar 2017 12:26:14 -
@@ -417,10 +417,6 @@ struct sockaddr_in6;
 struct bfd_config;
 
 voidroute_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 *);
 voidrtm_ifchg(struct ifnet *);
 voidrtm_ifannounce(struct ifnet *, int);
 voidrtm_bfd(struct bfd_config *);
Index: net/rtsock.c
===
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.230
diff -u -p -r1.230 rtsock.c
--- net/rtsock.c6 Mar 2017 10:19:17 -   1.230
+++ net/rtsock.c6 Mar 2017 12:28:11 -
@@ -98,7 +98,11 @@ struct walkarg {
caddr_t w_where, w_tmem;
 };
 
+introute_output(struct mbuf *, struct socket *, struct sockaddr *,
+   struct mbuf *);
 introute_ctloutput(int, struct socket *, int, int, struct mbuf *);
+introute_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
+   struct mbuf *, struct proc *);
 void   route_input(struct mbuf *m0, sa_family_t);
 introute_arp_conflict(struct rtentry *, struct rt_addrinfo *);
 introute_cleargateway(struct rtentry *, void *, unsigned int);
@@ -159,8 +163,6 @@ route_usrreq(struct socket *so, int req,
int  af;
int  error = 0;
 
-   NET_ASSERT_LOCKED();
-
rp = sotorawcb(so);
 
switch (req) {
@@ -345,6 +347,8 @@ route_input(struct mbuf *m0, sa_family_t
struct socket *last = NULL;
struct sockaddr *sosrc, *sodst;
 
+   KERNEL_ASSERT_LOCKED();
+
sosrc = _src;
sodst = _dst;
 
@@ -736,7 +740,9 @@ rtm_output(struct rt_msghdr *rtm, struct
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) {
@@ -981,6 +987,8 @@ change:
error = ESRCH;
break;
}
+   NET_UNLOCK(s);
+
*prt = rt;
return (error);
 }
Index: kern/uipc_socket.c
===
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.178
diff -u -p -r1.178 uipc_socket.c
--- kern/uipc_socket.c  3 Mar 2017 09:41:20 -   1.178
+++ kern/uipc_socket.c  6 Mar 2017 12:23:57 -
@@ -1038,11 +1038,12 @@ sorflush(struct socket *so)
 {
struct sockbuf *sb = >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) ?  : NULL);
+   (af != PF_LOCAL && af != PF_ROUTE) ?  : NULL);
socantrcvmore(so);
sbunlock(sb);
asb = *sb;
Index: kern/uipc_socket2.c
===
RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
retrieving revision 1.72
diff -u -p -r1.72 uipc_socket2.c
--- kern/uipc_socket2.c 14 Feb 2017 09:46:21 -  1.72
+++ kern/uipc_socket2.c 6 Mar 2017 12:23:57 -
@@ -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