[openbeosnetteam] Re: PPP: dial-on-demand

  • From: "Philippe Houdoin" <philippe.houdoin@xxxxxxx>
  • To: openbeosnetteam@xxxxxxxxxxxxx
  • Date: Thu, 03 Jul 2003 13:38:35 GMT

> For those who did not understand:
> This is just a joke (see the smileys). ;)

I guess that not *only* a joke, right?

> Hi,
> before I implement something that would never work with our stack, 
> could
> you please help me with some (basic?) BSD stuff?

Part of the problem in answering your question is nobody knows here 
that much 
BSD stack internals.
Me included.

A second part of the problem, and that may be only my opinion here, is 
we (I?) want to 
build a network stack the BeOS philosophy way. That is:
- modular
- dynamic (loading and unloading) of components/addons/protocols/
whatever
- light and clean architecture/design
- clever code
- easiest to maintain and understand as possible

For me, BSD code fall far away in some points here, and the current 
stack code, mostly inspired if not ported (mbuf anyone!?) is 
hard to maintain, fix and expand for this same reason: before, one need 
to become familiar with many BSD stack design concepts.

Being POSIX/BSD sockets API don't means using BSD stack design, just 
that we should support 
as much as possible of *public* BSD network API:
- sockets API
- BINDeries API
- network-related POSIX includes files, where they should be and what 
they should containt
- some most expected network command line tools, like route, ping, 
traceroute, ifconfig, etc... 

> I plan to implement dial-on-demand the following way:
> When an interface registers itself to the ppp_interface_manager it 
> gets an
> ifnet structure assigned.
> The if_flags are set to IFF_UP | IFF_POINTTOPOINT.
> This happens will all interfaces regardless whether dial-on-demand is 
> set 
> or not.

Make sense.

I know that current stack design allow to *register* an (or multiple) 
interface(s)  only at module load time, and not after.
That's a flaw, and PPP (virtuall) interfaces requires this feature.
However, I don't see the need for a separate ppp_interface_manager, a 
"ppp" module loaded by the core stack should be enough, 
if it support dynamic interface registration.

BTW, my pet new_stack project, located under current/src/tests/kits/net
/new_stack/* support this.

I don't know if 

> The following is only done with dial-on-demand interfaces:
>
> 1) The IP Control Protocol adds itself as the default route and uses 
> an
> undefined class A dst address (?10.0.0.1 + if_unit?) and an undefined
> class A interface address (?10.127.0.1 + if_unit?). 

Okay, time I look at this IPCP chapter in TCP/IP Illustrated.
:-)

> BTW, do we have a function
> that returns the netmask of some ip-address?

You mean, compute the netmask from any ip-address?
I'm not sure, no.
Maybe in ifconfig.c...[checking...], no.

Okay, what we have is these macros in current/headers/posix/netinet/
in.h:

IN_CLASS[A|B|C|D] for testing ip address class;
IN_CLASS[A|B|C|D]_NET for class ip net address.

> AFAIK, calling SIOCSIFDSTADDR also sets the default route 
> automatically
> and it has a special handling for IFF_POINTTOPOINT. Does it check if 
> the
> return value of the interface is ok and add the route only then?

If "Is ok" = IFF_UP, no it don't.
If "Is ok" = succeed to set new interface dst address, yes it do that:
curent/src/add-ons/kernel/network/core/in.c:in_control(), line 308:

-----8<-----------------
case SIOCSIFDSTADDR:
        if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
                return EINVAL;
        oldaddr = ia->ia_dstaddr;
        ia->ia_dstaddr = *(struct sockaddr_in*)&ifr->ifr_dstaddr;
        /* update the interface if required */
        if (ifp->ioctl) {
                error = ifp->ioctl(ifp, SIOCSIFDSTADDR, (caddr_t) ia);
                if (error) {
                        ia->ia_dstaddr = oldaddr;
                        return error;
                }
        }
        /* change the routing info if it's been set */
        if (ia->ia_flags & IFA_ROUTE) {
                ia->ia_ifa.ifa_dstaddr = (struct sockaddr*)&oldaddr;
                rtinit(&(ia->ia_ifa), RTM_DELETE, RTF_HOST);
                ia->ia_ifa.ifa_dstaddr = (struct sockaddr*)&ia->ia_dstaddr;
                rtinit(&(ia->ia_ifa), RTM_ADD, RTF_HOST|RTF_UP);
        }
        break;
-----8<-----------------

> Which ioctl should bring the interface up? SIOCSIFFLAGS or 
> SIOCSIFADDR or
> both?

According to current stack code, I'll say SIOCSIFADDR, but it will make 
sense to 
to handle correctly a SIOCSIFFLAGS with IFF_UP set for a PPP interface.

> How do I prevent changing the interface's ip?

Hum, really don't know. Except by rejecting SIOCSIFADDR in your PPP 
interface ioctl() hook...

> Do I have to add an ifaddr for each protocol?

No. Each interface stores his own addresses in an global ifnet_addrs 
list, for all domains.

> 2) When the interface must send some data it Up()s itself. Up() adds
> IFF_RUNNING to if_flags if it was successful.
> All threads that try to send something are blocked and wait until 
> Up() is
> done. If Up() fails they delete the mbuf and return an error.

Make sense to me.

> Also, when the IP Control Protocol is brought up it
> SIOCSIFDSTADDRs+SIOCSIFADDRs the received ip addresses.

Agreed.

> 3) A Down() (or whatever might cause it) will bring us back to 1)

Or a timeout. Each packet received or sent should reset this timeout.

> Do you think this will work?

I'm far to fully understand both all these points and the current stack 
internals to "think" it will work.
I just *feel* it *may* work...
:-\

BTW, did you give a look at first draft ppp & serial_ppp code that was 
included in the old net_kit backup
http://philippe.houdoin.free.fr/phil/beos/openbeos/network_kit/
obos_net_kit-20020822.zip ?



-Philippe

--
Fortune Cookie Says:

"The identical is equal to itself, since it is different."
                -- Franco Spisani


Other related posts: