[En-Nut-Discussion] RFC: Registering Protocols

Nathan Moore nategoose at gmail.com
Mon Aug 11 17:04:37 CEST 2008


I've been messing around with a customized version of the network code for a
while now
and have thought about similar things.  Particularly the inclusion of TCP
when it might not
be used, though I'm using it so it wasn't a big deal to me.
A linked list of protocols of the form (protocol number, protocol handler,
next protocol) would
work well for this at every level (PPP, ethernet, TCP/IP), and in the case
of PPP more protocols
would be added to the list as the PPP was being negotiated.  This would
probably work nearly as
fast as a static jump table (switch/case) since it is likely to be sparsely
populated and compile to
if/else if... code.  The library code size for the linked list of protocols
would be constant and the library
would only need configuration at run time.
Problems would manifest when there were more than a few protocols and the
list got long.
This would also using pointers opens up more opportunity for ram corruption
to cause program
flow problems that are hard to debug and code that is difficult to follow.
Another benefit to this would be that alternate handlers could be placed
into this list to provide
firewall, forwarding, encryption, ... which is similar to what I've done in
my customized version,
but it is within the framework of the existing code and strategic points
rather than a total reworking
of the code.
As far as the need to register the protocols at run time and it's effect on
application code this could
be taken care of be having the option of default (as it is now) protocols
registered when you open the
network device or to let the application code take care of doing it's own
thing with protocol setup.

One issue would be that if multiple network devices were installed would
they share protocol lists?
This could save memory but wouldn't lend itself to configuring one interface
differently from another.
It's not a big deal for 1 PPP and 1 ethernet device until you get into the
IP layer since they have
different protocol numbers and couldn't share, but at the IP layer or with
two different ethernet devices
it could be an issue.

Oh, one other idea that could help offset the additional ram usage that the
list of protocols approach
could bring would be if a way could be found to implement this as a
trampoline where all of the calls
to different layers of the protocol stack actually happened within the
context of a low level function via
the higher levels returning pointers to the next level's list of protocols
and handlers.  This would keep
keep the stack requirements down, especially on avr-gcc which doesn't
actually do tail recurrsion
optimization.
This could change the protocol handler list to include actions for unhandled
higher protocols.
while (1) {
   switch (next_network_layer) {
       case NULL:
           current_network_layer->not_handled(dev, nb);  // the next layer
protocol isn't handled -- this could just free the buf or send an ICMP
message
           return;
       case -1:
           NutNetBufFree(nb);  // the next layer rejected the buffer
           return;
       default:
           current_network_layer = next_network_layer;
           next_network_layer = current_network_layer->handle(dev, nb);
    }
}
This would just go until the nb could be passed to another thread or be
freed.
This differs a lot from my custom code, btw.

Nathan



More information about the En-Nut-Discussion mailing list