[openbeosnetteam] PPP Code - More Details [long]

Well, the new PPP code arrived last night (or was it this morning). This is
at the same time a big leap forward and a small one back. why? Read on.

I've looked at how some of the more popular ppp packages do things and drawn
inspiration from several, this may explain why the code is a real mixture.
Those wishing to look at the same code I did should look at the ppp code
that comes with BSD's :)

The starting point should really be the userland app "ppp". Currently this
simple little app just allows you to start a ppp connection. It does some
simple config on the serial port it's using, but nothing more in the way of
configuring the ppp options. Using it I have managed to dial a modem, login
and then start ppp! yes, it truly is possible, though as I'll explain ppp
doesn't work as it should so don't expect miracles. What should this app be?
Well, I'd like to think it would be a full blown command line ppp control
app. Whether it's interactive as the ppp app on BSD's or simply returns when
it's down what was asked, I don't really mind. It needs to be able to accept
options in a file as well as on the command line and so there is a lot needs
doing! Feel free to mess with the code as much as you want - what's there
was just quick and dirty to get it working so I could prove the point :)

The point is that the userland app is responsible for dealing with modem's
and configuring serial ports (speed, parity etc) and once finished ppp is
then started. This allows a nice division of "responsibility" and keeps all
the ppp stuff nicely isolated in the kernel.

How well does ppp work? Well, it works to a degree in that it can negotiate
LCP using configure requests and accepting them, rejecting them and so on.
It doesn't deal with all possible options and that needs fixed as does a lot
of the checking. At present it uses 3 layers as follows

    physical layer  ===>  LCP

    authentication  ====> PAP/CHAP (none yet written)

    network protocols  ====> IPCP

I've taken a decision in that each module is controlled by an fsm structure,
Finite State Machine, which has pointers to the appropriate protocol
specific options. This is "inside out" from the normal methods used, but I
don't see it as a problem and it seems to make sense. It requires casting
the pointers into the appropriate options structures, but again as it allows
for easier addition to the core and easier handling of the overall structure
I'm happy with that. RFC 1661 gives details of how the state is changed, and
which events trigger what changes. One big issue is the notion of parent
that some of the models I've looked at (and used code from) have that we
don't really. We allow a variable number of modules to be added/used instead
of the fixed approach that other implementations use. This means we don't
have a set hierarchy when we start, but rather create it on the fly, making
the assertion of parent/child more complicated than in fixed models. I don't
think it's hard as the function fsm_parent_start shows how I think we can
make the appropriate calls.

What's interesting and requires a lot of thought is how we actually control
things like up/down. At present you can add devices to the stack, but
removing them is a trickier proposition. I've started trying to add code for
this, but it still doesn't work and needs some serious reviewing of the code
and it's implications of simply "ripping" a device out from hte midst of the
various linked lists that are created/managed by the stack. BSD's don't have
this concern as they simply pre-allocate devices, but that seems primitive
and not what we want to do.

The serial_ppp module works, but is in need of a bit of work. The revelation
that serial ports on beos are always non-blocking explained a lot of the
issues I've been seeing, and explains why the userland ppp code has such a
hard time getting things right. There should possibly be a smarter input
routine for both the ppp app and the serial_ppp module that can buffer the
data from the non-blocking reads and deliver cohesive packets, or at least
one that works correctly :) The code shows one of the limitations of the
mbuf's in that they really work well when we know how much we'll have at the
outset. Adding/appending data isn't a supported operation, and it probably
should be, so I think we may want to add an m_append function at some point
to allow us to add memory to the end of an existing mbuf.

Well, please consider this to be a starting point for people wishing to look
at and (hopefully) work on. I'm out of contact for the next 6 days, back
Thursday evening, but may check my emails. I'd suggest that people run this
as userland for the time being as it has been known to throw an occasional
segfault. Look through the code for 'XXX' and '???' to see comments where
I've had doubts or questions about what we're doing. I haven't managed to so
tag all the places, but have done a fair number of them.

Finally, if people really hate this approach, then if you can replace it
with code you like and works, feel free, but please bear in mind my
objective is to have this working as soon as possible, so if your time frame
is 6 months then I'd suggest you put it on the back burner until post R1.
For R1 the targets are LCP, IPCP, PAP, CHAP (at least one version, maybe
more) serial_ppp, pppoe, a userland command line ppp and the gui app. Not
much to ask for really is it :)

david


Other related posts: