diff options
author | Jonathan Lemon <jlemon@FreeBSD.org> | 2000-11-25 07:35:38 +0000 |
---|---|---|
committer | Jonathan Lemon <jlemon@FreeBSD.org> | 2000-11-25 07:35:38 +0000 |
commit | df5e1987230850fe5983a4479523708640160215 (patch) | |
tree | 05531b0125a3669b45ffc6aa7dc93115e4123969 /sys/net/if_tun.c | |
parent | f4e13f88b630686808a03dc19e3243ca37fa5645 (diff) | |
download | src-df5e1987230850fe5983a4479523708640160215.tar.gz src-df5e1987230850fe5983a4479523708640160215.zip |
Lock down the network interface queues. The queue mutex must be obtained
before adding/removing packets from the queue. Also, the if_obytes and
if_omcasts fields should only be manipulated under protection of the mutex.
IF_ENQUEUE, IF_PREPEND, and IF_DEQUEUE perform all necessary locking on
the queue. An IF_LOCK macro is provided, as well as the old (mutex-less)
versions of the macros in the form _IF_ENQUEUE, _IF_QFULL, for code which
needs them, but their use is discouraged.
Two new macros are introduced: IF_DRAIN() to drain a queue, and IF_HANDOFF,
which takes care of locking/enqueue, and also statistics updating/start
if necessary.
Notes
Notes:
svn path=/head/; revision=69152
Diffstat (limited to 'sys/net/if_tun.c')
-rw-r--r-- | sys/net/if_tun.c | 31 |
1 files changed, 6 insertions, 25 deletions
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 9187764c14f6..5cbe111b68b1 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -196,7 +196,6 @@ tunclose(dev, foo, bar, p) register int s; struct tun_softc *tp; struct ifnet *ifp; - struct mbuf *m; tp = dev->si_drv1; ifp = &tp->tun_if; @@ -207,13 +206,7 @@ tunclose(dev, foo, bar, p) /* * junk all pending output */ - do { - s = splimp(); - IF_DEQUEUE(&ifp->if_snd, m); - splx(s); - if (m) - m_freem(m); - } while (m); + IF_DRAIN(&ifp->if_snd); if (ifp->if_flags & IFF_UP) { s = splimp(); @@ -337,7 +330,6 @@ tunoutput(ifp, m0, dst, rt) struct rtentry *rt; { struct tun_softc *tp = ifp->if_softc; - int s; TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); @@ -380,10 +372,8 @@ tunoutput(ifp, m0, dst, rt) M_PREPEND(m0, dst->sa_len, M_DONTWAIT); /* if allocation failed drop packet */ - if (m0 == NULL){ - s = splimp(); /* spl on queue manipulation */ - IF_DROP(&ifp->if_snd); - splx(s); + if (m0 == NULL) { + ifp->if_iqdrops++; ifp->if_oerrors++; return (ENOBUFS); } else { @@ -396,10 +386,8 @@ tunoutput(ifp, m0, dst, rt) M_PREPEND(m0, 4, M_DONTWAIT); /* if allocation failed drop packet */ - if (m0 == NULL){ - s = splimp(); /* spl on queue manipulation */ - IF_DROP(&ifp->if_snd); - splx(s); + if (m0 == NULL) { + ifp->if_iqdrops++; ifp->if_oerrors++; return ENOBUFS; } else @@ -414,17 +402,10 @@ tunoutput(ifp, m0, dst, rt) } } - s = splimp(); - if (IF_QFULL(&ifp->if_snd)) { - IF_DROP(&ifp->if_snd); - m_freem(m0); - splx(s); + if (! IF_HANDOFF(&ifp->if_snd, m0, NULL)) { ifp->if_collisions++; return ENOBUFS; } - ifp->if_obytes += m0->m_pkthdr.len; - IF_ENQUEUE(&ifp->if_snd, m0); - splx(s); ifp->if_opackets++; if (tp->tun_flags & TUN_RWAIT) { |