This new abstraction layer allows multiple implementations of network
devices in a single running process. This will be useful, for example, to
support network devices that are simulated entirely in the running process
or that communicate with other processes over Unix domain sockets, etc.
The reimplemented tap device support in this commit has not been tested.