[comp.protocols.appletalk] performance issues with UAB/Ethertalk on the Sun

hedrick@athos.rutgers.edu (Charles Hedrick) (07/25/90)

Since my message over the weekend, I've taken a closer look at support
of Ethertalk on Suns.  Both UAB and the code I described then depended
upon /dev/nit.  /dev/nit is an "Ethernet tap".  It's really intended
for network monitoring, but it has enough capabilities that you can
use it to select packets of a specify type, and you can even set up
filters that only accept Appletalk packets directed at a specific
Appletalk socket.  (I use that facility.  UAB does not require it.)
Both UAB and my code set up /dev/nit to pass Appletalk packets and
Appletalk ARP's.

However there's a problem with using /dev/nit in this way: It's fairly
inefficient.  When /dev/nit is open, every packet arriving in the
system is copied.  This includes not just packets we are interested
in, but TCP/IP and any other packets.  Streams messages are sent to
every user of /dev/nit for every incoming packet.  The filtering is
done at a higher level.  Those packets a given user isn't interested
in are thrown away.  Apparently the packets themselves are not copied
for each user of /dev/nit.  They are copied only once, and the copy is
shared by all users of /dev/nit (at least if they are all looking at
the same portion of each packet).  Thus the first time anyone opens
/dev/nit, it increases the overhead of processing TCP/IP
substantially, and every additional user of /dev/nit increases the
overhead somewhat.  Most people feel that turning on Ethertalk should
not increase the overhead for TCP/IP traffic.  So I am rather hesitant
to use this method.

I have ported the Ethernet packet filter from the 4.3 contributed
software.  This is the code on which the /dev/nit protocol filter was
based.  It has three performance advantages over /dev/nit.

  - it is only activated for packets of types that are not
	normally handled.  That is, it does not increase overhead
	for TCP/IP.

  - the packet is not copied at all.  It stays in mbufs, which is
	where the device driver put it.

  - the filter is run at a low level, so that messages are not
	sent up to programs that are not interested in the packet.

I did the port in such a way that the packet filter can be installed
without needing source.  It's a pure device driver.  This works only
because Sun has provided hooks in the Ethernet device level code to
let people add new protocols without needing source.  Presumably these
hooks are intended for use by their DECnet product, and other similar
things.  You install it as you would any device driver, i.e.  by
adding an appropriate line in conf/files and your configuration file,
and by putting a new entry for it in conf.c.  So far I have been
testing it on 4.0.3c.  It appears that it will not work on 4.0.1, as
the hooks do not pass all the necessary data.  (However it happens
that the Appletalk code doesn't need that data, so the driver could be
made to fill in zeros.)  The only change I've had to make to the
interface is to add an ioctl to specify what Ethernet packet types
should be handled by the packet filter.  

I'm considering adding specific support for Appletalk, though I'm not
sure the extra CPU needed to run the packet filters is really enough
to worry about.