Subject: Interface layering proposal.
To: None <tech-net@netbsd.org>
From: None <erh@nimenees.com>
List: tech-net
Date: 02/19/2000 23:12:09
	I have been working on designing interface layering code.  The
purpose of this is to be able to configure how the data that a physical
interface passes up is handled and to provide a framework for interfaces
with logical subinterfaces.  Examples:
	ntwo driver:  Currently hardwired to interpret incoming data
		as IP packets.  Splitting this off into layers will allow
		a diffferent protocol to easily be run across it.

		ntwo->ip layer->protocols
			or
		ntwo->other layer->protocols
	
	bonded interfaces: A layer that has two layers below it that it
		combines to increase speed.

		slowlink0----\
			      +-->bond-->protcols
		slowlink1----/

	vlan stuff: A driver that has sub-interfaces as logical layers
		above it.  (base fxp0 driver would of course still need
			to know about vlan to send data to the correct place)

		      /---fxp0.0-->protocols
		fxp0-+
		      \---fxp0.1-->protocols

The overall structure of interface drivers changes a bit because of this.
1) Either the {ether,token,etc...}_input functions get called directly
	and are viewed as helper functions,
 or
   They become a true layer, creating eth0, eth1, token0, ... interfaces.

  I would prefer that they be viewed as helper functions.  Either way
  they will change significantly.  (see #2)

2) The switch on the type of packet moves out of the if_<foo>subr.c files
	and into a standard top of stack routine which always gets called
	at the end of any processing by the interface layers.  The job of
	each one of the interface layers is to do whatever it needs to the
	data it gets passed and then pass it up, tagged with a type.
	Depending on what a layer is meant to do it may either discard/use,
	pass unchanged, or pass as a different type.  For instance, the
	ether_input function (whether it's a separate layer or not) will
	still have a switch on the ether type.  However, instead of
	posting a soft network interrupt it would mark the data and pass
	it up through the if_input function.  Other layers, like bond,
	would leave the data type unchanged.  Once it gets through all
	the layers, the last one has the default if_input which call the
	endpoint function which dispatches the data to the correct protocol.

	I could use some suggestions on how to pass the type of data along.
	a) Add field to mbuf.
	b) Add parameter to if_input.
	c) or ???


Other info about this:
	Interface layers will be able to register themselves at autoconf
time or when being loaded as a module.  By registering they create an
entry in the ifl_drv table which contains pointers to attach/detach
functions and a base name for the layer.  This is so you can do:
	ifconfig tlp0 attach foo
and it will create foo0 and attach it.
	When attaching a layer saves the old if_input of the layer below
so attach+detach gets you back to where you started.

	I'll post a pointer to the code I have once I clean it up a bit.
(I've been moving v e r y s l o w l y  with this)  Anyone see any problems
with what I've described so far?  Comments about eth layer and data tagging?

eric