diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-12-20 15:07:33 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2016-12-20 15:07:33 +0000 |
commit | 2ba56841b116530411c7f63bdac8e64722530b91 (patch) | |
tree | c3d724a44f56f9f6b2939a69de5f7c8e85235b84 /sys/net/if_pflow.c | |
parent | 66e00d70d92affbe9f875f43351463297f274ba4 (diff) |
Release the NET_LOCK() before calling any socket function since it is
not recursive.
This is temporary until all recursions are found and can be addressed
in a correct way.
With inputs from bluhm@
Diffstat (limited to 'sys/net/if_pflow.c')
-rw-r--r-- | sys/net/if_pflow.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/net/if_pflow.c b/sys/net/if_pflow.c index e3aeba6694f..0df0b69fd8a 100644 --- a/sys/net/if_pflow.c +++ b/sys/net/if_pflow.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pflow.c,v 1.62 2016/10/04 13:54:32 mpi Exp $ */ +/* $OpenBSD: if_pflow.c,v 1.63 2016/12/20 15:07:32 mpi Exp $ */ /* * Copyright (c) 2011 Florian Obser <florian@narrans.de> @@ -267,7 +267,10 @@ pflow_clone_destroy(struct ifnet *ifp) pflow_flush(sc); m_freem(sc->send_nam); if (sc->so != NULL) { + /* XXXSMP breaks atomicity */ + rw_exit_write(&netlock); error = soclose(sc->so); + rw_enter_write(&netlock); sc->so = NULL; } if (sc->sc_flowdst != NULL) @@ -375,6 +378,8 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } } + /* XXXSMP breaks atomicity */ + rw_exit_write(&netlock); s = splnet(); pflow_flush(sc); @@ -398,6 +403,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sizeof(struct sockaddr_in), M_DEVBUF, M_NOWAIT)) == NULL) { splx(s); + rw_enter_write(&netlock); return (ENOMEM); } memcpy(sc->sc_flowdst, &pflowr.flowdst, @@ -410,6 +416,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sizeof(struct sockaddr_in6), M_DEVBUF, M_NOWAIT)) == NULL) { splx(s); + rw_enter_write(&netlock); return (ENOMEM); } memcpy(sc->sc_flowdst, &pflowr.flowdst, @@ -449,6 +456,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sizeof(struct sockaddr_in), M_DEVBUF, M_NOWAIT)) == NULL) { splx(s); + rw_enter_write(&netlock); return (ENOMEM); } memcpy(sc->sc_flowsrc, &pflowr.flowsrc, @@ -461,6 +469,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sizeof(struct sockaddr_in6), M_DEVBUF, M_NOWAIT)) == NULL) { splx(s); + rw_enter_write(&netlock); return (ENOMEM); } memcpy(sc->sc_flowsrc, &pflowr.flowsrc, @@ -484,6 +493,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) &so, SOCK_DGRAM, 0); if (error) { splx(s); + rw_enter_write(&netlock); return (error); } if (pflowvalidsockaddr(sc->sc_flowsrc, 1)) { @@ -498,6 +508,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if (error) { soclose(so); splx(s); + rw_enter_write(&netlock); return (error); } } @@ -530,6 +541,7 @@ pflowioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } else ifp->if_flags &= ~IFF_RUNNING; + rw_enter_write(&netlock); break; default: |