diff options
author | glebius <glebius@FreeBSD.org> | 2006-01-30 08:39:09 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2006-01-30 08:39:09 +0000 |
commit | aecf4a6244730d904a75f88ec9ea7eba0be9dd34 (patch) | |
tree | e06d7957fe2790ef47aabd00c8f3a9d96af9e3b5 /sys/net/if_gif.h | |
parent | 02a28f2514c2622f785b9c1e84417e4971151c72 (diff) | |
download | FreeBSD-src-aecf4a6244730d904a75f88ec9ea7eba0be9dd34.zip FreeBSD-src-aecf4a6244730d904a75f88ec9ea7eba0be9dd34.tar.gz |
Add some initial locking to gif(4). It doesn't covers the whole driver,
however IPv4-in-IPv4 tunnels are now stable on SMP. Details:
- Add per-softc mutex.
- Hold the mutex on output.
The main problem was the rtentry, placed in softc. It could be
freed by ip_output(). Meanwhile, another thread being in
in_gif_output() can read and write this rtentry.
Reported by: many
Tested by: Alexander Shiryaev <aixp mail.ru>
Diffstat (limited to 'sys/net/if_gif.h')
-rw-r--r-- | sys/net/if_gif.h | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h index 698c6703..8e9ceb1 100644 --- a/sys/net/if_gif.h +++ b/sys/net/if_gif.h @@ -57,6 +57,7 @@ extern void (*ng_gif_detach_p)(struct ifnet *ifp); struct gif_softc { struct ifnet *gif_ifp; + struct mtx gif_mtx; struct sockaddr *gif_psrc; /* Physical src addr */ struct sockaddr *gif_pdst; /* Physical dst addr */ union { @@ -72,6 +73,12 @@ struct gif_softc { LIST_ENTRY(gif_softc) gif_list; /* all gif's are linked */ }; #define GIF2IFP(sc) ((sc)->gif_ifp) +#define GIF_LOCK_INIT(sc) mtx_init(&(sc)->gif_mtx, "gif softc", \ + NULL, MTX_DEF) +#define GIF_LOCK_DESTROY(sc) mtx_destroy(&(sc)->gif_mtx) +#define GIF_LOCK(sc) mtx_lock(&(sc)->gif_mtx) +#define GIF_UNLOCK(sc) mtx_unlock(&(sc)->gif_mtx) +#define GIF_LOCK_ASSERT(sc) mtx_assert(&(sc)->gif_mtx, MA_OWNED) #define gif_ro gifsc_gifscr.gifscr_ro #ifdef INET6 @@ -94,7 +101,6 @@ struct etherip_header { #define ETHERIP_VERSION 0x03 /* Prototypes */ -void gifattach0(struct gif_softc *); void gif_input(struct mbuf *, int, struct ifnet *); int gif_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); |