[comp.os.minix] Minix TCP/IP

alnitak@tardis.computer-science.edinburgh.ac.uk (05/02/90)

[Originally a reply to a message I received in response
to my previous posting Re: TCP/IP and Minix]

The idea I have for the Minix TCP/IP implementation is to have the TCP/IP
handler run as one module on the same layer as the MM and FS. This would allow
any BSD type system calls (ie `socket', `accept', and even `read' and `write')
to run as Minix system calls. The `read' and `write' calls I would either trap
in the FS and send to the IP module, or modify the library calls to do the
trapping (ie check in read.c and write.c if the file handle is for a socket,
and if so send the message to the IP module instead of the FS).

This allows compatibility with currently available socket based code, so the
extra effort involved with this probably far outweighs (IMHO) the effort
required to re-write/modify existing clients and servers. I do not know yet
how I would actually handle the sockets as far as the FS is concerned. They
could take the form of either pure entities in memory, or a variation on the
named pipe. I really haven't studied the original code enough to see how
feasible this is.

I don't know if anyone out there has studied the Sun Networking Guide, but
that shows all of the data structures and protocol layers that are used in the
Sun TCP/IP implementation. Their version is based on the OSI communications
model. This also shows useful things like the use of system IOCTL calls to
alter the SunOS kernels copy of the kernel routing table. If anyone ones to
learn how a fairly good networking system is implemented, take a look at this
book.

At the moment, I see all of my networking code (apart from the actual device
I/O) happening in the IP module, which would be a single executable. I hope to
make this code completely machine independent so that the only dependencies
will be in the device drivers, which should normally exist in the kernel
anyway. Obviously with the 64k I & D restriction on MINIX/PC there may be some
coding problems in keeping the software small enough, but I would like to
think that this won't be a problem.

I feel that it is important that IP packets should be capable of using
any bidirectional communications device on the system, hence the IP module
would find from the routing table which I/O device a particular packet must go
through in order to reach its destination, then call a routine which will
append or prepend any extra information needed for the device (ie, nothing for
Ethernet devices, start of packet' and `end of packet' blocks for Serial Line
IP, etc.). This is because the vast majority of Minix users will not be able
to afford or connect to an ethernet system, and may well end up relying on a
SLIP connection to any other hosts.

Hence the overall model that I am currently working on is:

  Revised Figure 2.26, Page 87 [AST]

 +--------+-----------------------------------+
   4 |  INIT  |        Application layer          |
 +--------+-----+--------------+--------------+
   3 |      FS      |      MM      |      IP      |
 +--------------+--------------+--------------+
   2 |  Disk  |  TTY  |  Clock  |  System  | .... |
 +--------+-------+---------+----------+------+
   1 |              Process Management            |
 +--------------------------------------------+

       Layout of IP module

 +--------------------------------------------+
   4    |                Socket Handler              |
 +-------+-------+----------------------------+
   3 |  TCP  |  UDP  |  ........................  |
 +-------+-------+----------------------------+
   2 |                 IP / Router                |
 +---------+--------+-------------------------+
   1 |  ETHER  |  SLIP  |  .....................  |
 +---------+--------+-------------------------+

The socket handler determines which Protocol Module to send the data within
the packet to (eg TCP or UDP). The Protocol Module then passes the packet on
to the IP Module. When an IP packet is to be sent out, it is first passed to
the Router which figures out which I/O device the packet is to be sent to, and
then calls the relevant output routine. The output routine for that device
appends and prepends any extra info (see above). The packet is then finally
passed to the output device using normal `read' and `write' calls to the
relevant device from /dev. In this way minimal (or even non-existant) changes
need to be made to the MM, FS and Kernel, and machince dependancy is minimised
(I would hope that no changes at all would need to be made to the Kernel, as
this is the only one of the three layers which is machine dependent. Any
additional device drivers here would be needed in order to use that device
anyway).

Hope this all makes sense...

Ray Bellis

p.s. Please, please, please, let's have any comments on this, good or bad, I
don't care. I really do think that Minix warrents having a properly written
version of TCP/IP written from scratch, rather than hacked together from
somebody elses code for a different O.S.

------------------------------------------------------------------------------
  Ray Bellis: Janet (UK): alnitak@uk.ac.ed.cs.tardis
         &  u87rpb@uk.ac.oxford.ecs
  Elsewhere: alnitak@tardis.cs.ed.ac.uk
------------------------------------------------------------------------------

pak@BEACH.CIS.UFL.EDU ("Philip A. Kufeldt") (05/03/90)

Ray,
 Originally I did not correctly estimate the degree of your interest
and that is why I did not give any real details of our implementation.  So let
me now go into our development. But, first let me say that we are committed to
Minix as a teaching tool and plan to have a complete Minix lab of *inexpensive*
PC's for students to tinker with.  This is why we are using Minix 1.3 as our
base for development.  This commitment will come back to haunt us.

 First we are following, as best we can, this model:

        +-------------------------------+
        |        Application Layer      |
        |            (Clients)          |
        +-------------------------------+
        |         Transport Layer       |
        |          (TCP,UDP,..          |
        +-------------------------------+
        |         Internet Layer        |
        |              (IP)             |
        +-------------------------------+
        |       Network Interface       |
        |           Upper Layer         |
        |           (ARP/RARP)          |
        |  ---------------------------  |
        |       Network Interface       |
        |          Lower Layer          |
        |           (Drivers)           |
        +-------------------------------+
        |         Hardware Layer       |
        +-------------------------------+

This loosely conforms to the OSI layered model.

 Now how does this all fit into Minix?  Our layout matches yours almost
exactly:

 +--------+-----------------------------------+
   4 |  INIT  |        Application layer          |
 +--------+-----+--------------+--------------+
   3 |      FS      |      MM      |      NM      | (Network Manager)
 +--------------+--------------+--------------+
   2 |  Disk  |  TTY  |  Clock  |  System  | .... |
 +--------+-------+---------+----------+------+
   1 |              Process Management            |
 +--------------------------------------------+

       Layout of NM server

 +--------------------------------------------+
   3    |                Socket Handler              |
 +-------+-------+----------------------------+
   2 |  TCP  |  UDP  |  ........................  |
 +-------+-------+----------------------------+
   1 |                 IP / Router                |
 +--------------------------------------------+

As you can see we don't have any hardware-specific support in our network
manager.  We feel as if those are the things that belong inside the kernel.
This includes ARP/RARP.  These two protocols are very hardware specific and
really don't belong anywhere besides the driver.  That is why we have put the
network interface within the kernel.  Realizing that the routines governing
the ethernet and the routines governing ARP/RARP are vastly ideologically
different, we split the driver into two halves.

 We at present are not making use of the FS for any reason.  But your
comments are making me rethink this position.  Also our scope has been narrow.
We have only been considering ethernet support, but you make a very good case
for generalizing that area.

 I understand your concern for a good version of TCP/IP written from
scratch.  That is one of the driving forces behind our development.  The other
is the Minix lab which *must* have decent performance or it is useless to the
students using it.  Unfortunately, the ultimate layered designs set forth by
OSI will cost too much in the final implementation, so minor concessions must
be made.

 One other goal I should let you know of is our commitment to the coding
style of the Minix operating system.  We want our final product to look like
it came from the hand of Andy himself.  So a close observance to the style of
servers and drivers is essential.

 I appreciate your comments and welcome them in the future.

Philip A. Kufeldt
Computer and Information Sciences
University of Florida

overby@plains.UUCP (Glen Overby) (05/03/90)

In article <sent.Wed.May..2.15:00:33.GMT.1990.via.CS.TARDIS> alnitak@tardis.computer-science.edinburgh.ac.uk writes:
[ a description of how to impliment TCP/IP under Minix as a server process ]

The Berkeley socketts are file descriptors, and can be manipulated the same
as any other type of file.  To do the same under Minix, there must be a
sockett "hook" in the File System.  If you're going to do something like
this, read Maruice Bach's "Design of the Unix Operating System" book's
chapter (near the back) that talks about the SysV File System Switch (this
first came about in V8, and there is an abstract of a paper on it in a older
(1985-6?) Usenix conference proceedings).  A "switch" like this could
potentially allow other types of file systems to be mounted, as well as
remote filesystems.  Jeff Hernes started on this for his MS thesis here at
NDSU.  It didn't work well though.

The other way I see of doing this is to make the IP server look like a
device driver to the FS and use ioctls for everything.  I don't like putting
this in the library, since it will reqire recompiling every single user
program that wants to use the networking (the Newcastle Connection did
something like this with remote filesystems).

I agree that the networking code should be implimented as a server process,
but because it does not belong in the Kernel because of size (the kernel
is already large enough) and because device drivers are non-preemptable and
the networking code does not (or should not) require this.

There isn't a good way to add more server processes to Minix.  This is
because of how ingrained the number of servers is in the system.  You will
find a constant, LOW_USER (include/minix/const.h), for defining the "first
user not part of operating system".  First glance will say "just increase
this number", and that is a good first step.  Next you will have to find all
the places that know about *THREE* server processes (FS, MM, Init):

 * the _sizes area at the start of Kernel data (start.x),
   which is patched by build (or ShoeLace).  This contains the sizes (or
   is it start addresses?) of each piece of the pre-loaded OS.

 * the File System and Memory Manager, which have a similar area
   at the beginning of their data areas.  I'm not sure if all of them use
   it.

A nicer way to do this (which I started working on in my "new bootstrap"
program of about a year ago, and ShoeLace does about the same thing) is to
allow each piece of the OS to be loaded from a separate a.out file.  I
passed a 'struct proc' into the kernel (ShoeLace just did a build-like
binary patch), which would allow me to theoretically pre-load as many
processes as I wanted.

While making radical changes like this, why not go the rest of the way and
split all the device drivers into separate executables?  To break the
devices into separate programs, several changes to the kernel need to be
made: hook into "umap" that can be called only by device drivers to
translate a virtual address into a real address, fix things up so alarms can
be delivered to devices (in 1.3 there was an alarm-like way to have a
function called after so much time) and interrupt handling will have to be
distributed into each driver program.  There are probably a few other things
I haven't thought of, too...

I don't think the IP, ICMP, TCP and UCP protocols alone (along with buffers)
will blow the 64K limit.  If you start putting SMTP and Telnet servers in
with it, you certainly will.
-- 
		Glen Overby	<overby@plains.nodak.edu>
	uunet!plains!overby (UUCP)  overby@plains (Bitnet)

cagney@chook.ua.oz (Andrew Cagney - aka Noid) (05/04/90)

From article <4478@plains.UUCP>, by overby@plains.UUCP (Glen Overby):

> While making radical changes like this, why not go the rest of the way and
> split all the device drivers into separate executables?

Hmm, Did some one mention Chorus :-)

						Andrew Cagney

ggm@cuscus.cc.uq.oz.au (George Michaelson) (05/04/90)

This is a comment on TCP/IP and minix from a minix-ignorant p.o.v which
you can feel free to ignore.

I recall Charles Forsyth at *.york.ac.uk putting a version of streams into
a V7(ish) kernel in what he described as 

	"an amazingly short lineprinter listing"

worth of code. This is streams as described by Ritchie in papers, not as
implemented in sysV.x 

Streams seem a nicer abstraction for I/O. they also would seem to fit
into (what I understand to be) minix's architecture quite nicely.

If you must do TCP/IP for minix, choose a good abstraction to work on.
sockets can always be emulated by a tiny layer of code on top can't they?
--
	George Michaelson
Internet: G.Michaelson@cc.uq.oz.au                     Phone: +61 7 377 4079
  Postal: George Michaelson, Prentice Computer Centre
          Queensland University, St Lucia, QLD Australia 4067. 

peter@ficc.uu.net (Peter da Silva) (05/04/90)

> > While making radical changes like this, why not go the rest of the way and
> > split all the device drivers into separate executables?

> Hmm, Did some one mention Chorus :-)

This is a fairly common technique, actually. AmigaOS does the same thing:
apart from the drivers you need to boot (trackdisk.device, the default
file system, the default console driver, etc...), which are in ROM, all
device drivers are loaded at run-time.
-- 
`-_-' Peter da Silva. +1 713 274 5180.      <peter@ficc.uu.net>
 'U`  Have you hugged your wolf today?  <peter@sugar.hackercorp.com>
@FIN  Commercial solicitation *is* accepted by email to this address.

archer%segin4.segin.fr@prime.com (Vincent Archer) (05/05/90)

Glen Overby <overby@plains.UUCP> said:
>I don't think the IP, ICMP, TCP and UDP protocols alone (along with buffers)
>will blow the 64K limit.  If you start putting SMTP and Telnet servers in
>with it, you certainly will.

Basically, SMTP, Telnet and other network services are not (properly speaking)
part of the network software. On HP-UX (and undoubtly most Unix systems), the
support for such handy things is started either by inetd (Internet Daemon) or
by the /etc/netrc shell script executed by /etc/rc at boot time. Anyway, these
services run as user processes using sockets. So don't worry about the 64K
limit, it's mainly irrelevant.

Btw, Frans said (in his list of "things to do") that it did not see the use
of Midi support on Atari ST. Here's a good example of things a 30+Kb link can
be used for: Networking using SLIP. There was a game some years ago, called
MidiMaze, that allowed up to 15 users to play a "hide and seek" game in a
common setting, each user playing on his/her ST, and STs being connected
together in a "ring" network thru their Midi connectors.


    Vincent


Reply to: archer%segin4.segin.fr@prime.com , not archer@segin4.segin.fr