- Add tun_mtx to tun_softc. Annotate what is (and isn't) locked by it.
- Lock down tun_flags, tun_pid.
- In the output path, cache the value of tun_flags so it's consistent
when processing a particular packet rather than re-reading the field.
- In general, use unlocked reads for debugging.
- Annotate a couple of places where additional unlocked reads may be
possible.
- Annotate that tun_pid is used as a bug in tunopen().
if_tun is now largely MPSAFE, although questions remain about some of
the cdevsw fields and how they are synchronized.
other pseudo-interfaces, break out tear-down of a softc into a
separate tun_destroy() function, and invoke that from the module
unloader. Hold tunmtx across manipulations of the global softc list.
- Add gre_mtx to protect global softc list.
- Hold gre_mtx over various list operations (insert, delete).
- Centralize if_gre interface teardown in gre_destroy(), and call this
from modevent unload and gre_clone_destroy().
- Export gre_mtx to ip_gre.c, which walks the gre list to look up gre
interfaces during encapsulation. Add a wonking comment on how we need
some sort of drain/reference count mechanism to keep gre references
alive while in use and simultaneous destroy.
This commit does not lockdown softc data, which follows in a future
commit.
- Add gif_mtx, which protects globals.
- Hold gif_mtx around manipulation of gif_softc_list.
- Abstract gif destruction code into gif_destroy(), which tears down
a softc after it's been removed from the global list by either module
unload or clone destroy.
- Lock gif_called, even though we know gif_called is broken with reentrant
network processing.
- Document an event ordering problem in gif_set_tunnel() that will need
to be fixed.
gif_softc fields not locked down in this commit.
processing with gif interfaces, to a global variable named "gif_called".
Add an annotation that this approach will not work with a reentrant
network stack, and that we should instead use packet tags to detect
excessive recursive processing.
the tap driver, even with Giant over the cdev operation vector, due to
a non-atomic test-and-set of the si_drv1 field in the dev_t. This bug
exists with Giant under high memory pressure, as malloc() may sleep
in tapcreate(), but is less likely to occur. The resolution will
probably be to cover si_drv1 using the global tapmtx since no softc is
available, but I need to think about this problem more generally
across a range of drivers using si_drv1 in combination with SI_CHEAPCLONE
to defer expensive allocation to open().
Correct what appears to be a bug in the original if_tap implementation,
in which tapopen() will panic if a tap device instance is opened more
than once due to an incorrect assertion -- only triggered if INVARIANTS
is compiled in (i.e., when built into a kernel). Return EBUSY instead.
Expand mtx_lock() coverage using tp->tap_mtx to include tp->ether_addr.
as the process that opens tun_softc can exit before the file
descriptor is closed.
Taiwan experience provided by: keichii
Crashing breakers provided by: Chia-liang Kao <clkao@clkao.org>
(tap_pid, tap_flags). if_tap should now be entirely MPSAFE.
Committed from: Bamboo house by ocean in Taiwan
Tropical paradise provided by: Chia-liang Kao <clkao@clkao.org>
add tapmtx, which protects globale variables.
Notes:
- The EBUSY check in MOD_UNLOAD may be subject to a race. Moving the
event handler unregister inside the mutex grab may prevent that race.
- Locking of global variables safely is now possible because tapclones
is only modified when the module is loading or unloading, thanks to
phk's recent chang to clone_setup().
- softc locking to follow.
stf_destroy() to handle the common softc destruction path for the
two destruction sources: interface cloning destroy, and module
unload.
NOTE: sc_ro, the cached route for stf conversion, is not synchronized
against concurrent access in this change, that will follow in a future
change.
Reviewed by: pjd
Push if_faith softc destruction logic into faith_destroy() so that
it can be called after softc list removal in both the clone destroy
and module unload paths.
really sure why we have a softc list for if_loop, given that it
can't be unloaded, but that's an issue to revisit in the future as
corrupting the softc list would still cause panics.
Reviewed by: benno
Since there are two destroy paths for if_disc interfaces --
module unload and cloan interface destroy, create a new utility
function disc_destroy(), which is callded on a softc after it
has been removed from the global softc list; the cloaner and
module unload entry paths will both remove it before calling
disc_destroy().
Reviewed by: pjd
ifp is now passed explicitly to ether_demux; no need to look it up again.
Make mtag a global var in ip_input.
Noticed by: rwatson
Approved by: bms(mentor)
functions in kern_socket.c.
Rename the "canwait" field to "mflags" and pass M_WAITOK and M_NOWAIT
in from the caller context rather than "1" or "0".
Correct mflags pass into mac_init_socket() from previous commit to not
include M_ZERO.
Submitted by: sam
Assert the BPF descriptor lock in the MAC calls referencing live
BPF descriptors.
Obtained from: TrustedBSD Project
Sponsored by: DARPA, McAfee Research
BPF. Grab the BPF descriptor lock before entering MAC since the MAC
Framework references BPF descriptor fields, including the BPF
descriptor label.
Submitted by: sam
This enables pf to track dynamic address changes on interfaces (dailup) with
the "on (<ifname>)"-syntax. This also brings hooks in anticipation of
tracking cloned interfaces, which will be in future versions of pf.
Approved by: bms(mentor)
pf/pflog/pfsync as modules. Do not list them in NOTES or modules/Makefile
(i.e. do not connect it to any (automatic) builds - yet).
Approved by: bms(mentor)
Introduce d_version field in struct cdevsw, this must always be
initialized to D_VERSION.
Flip sense of D_NOGIANT flag to D_NEEDGIANT, this involves removing
four D_NOGIANT flags and adding 145 D_NEEDGIANT flags.
This commit adds a couple of functions for pseudodrivers to use for
implementing cloning in a manner we will be able to lock down (shortly).
Basically what happens is that pseudo drivers get a way to ask for
"give me the dev_t with this unit number" or alternatively "give
me a dev_t with the lowest guaranteed free unit number" (there is
unfortunately a lot of non-POLA in the exact numeric value of this
number, just live with it for now)
Managing the unit number space this way removes the need to use
rman(9) to do so in the drivers this greatly simplifies the code in
the drivers because even using rman(9) they still needed to manage
their dev_t's anyway.
I have taken the if_tun, if_tap, snp and nmdm drivers through the
mill, partly because they (ab)used makedev(), but mostly because
together they represent three different problems for device-cloning:
if_tun and snp is the plain case: just give me a device.
if_tap has two kinds of devices, with a flag for device type.
nmdm has paired devices (ala pty) can you can clone either of them.
Free approx 86 major numbers with a mostly automatically generated patch.
A number of strategic drivers have been left behind by caution, and a few
because they still (ab)use their major number.
- allow for ifp->if_ioctl being NULL, as the rest of ifioctl() does;
- give the interface driver a chance to report a error to the caller;
- don't forget to update ifp->if_lastchange upon successful modification
of interface operation parameters.