Network manager. Wired connections only.
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Bryan 89d64149ef README: drop the lessons and history sections
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 11:19:05 +01:00
examples (unchecked): the files that use a raw primitive say so 2026-10-22 18:29:26 +02:00
lib/network (unchecked): the files that use a raw primitive say so 2026-10-22 18:29:26 +02:00
profiles network: the manager of the machine's wired links 2026-10-04 18:39:23 +02:00
scripts network: the manager of the machine's wired links 2026-10-04 18:39:23 +02:00
tools network: the manager of the machine's wired links 2026-10-04 18:39:23 +02:00
.gitignore network: the manager of the machine's wired links 2026-10-04 18:39:23 +02:00
network.talc network: the manager of the machine's wired links 2026-10-04 18:39:23 +02:00
README README: drop the lessons and history sections 2026-10-25 11:19:05 +01:00
VERSION network: the manager of the machine's wired links 2026-10-04 18:39:23 +02:00

network: the manager of the machine's links, and the libraries it is
made of. It brings wired links up, gets each an address (DHCP, or what
its profile says), installs the routes, keeps the list of name servers,
and answers every other program over a local socket: what is connected,
and how. Wired links only.

  network.talc              the manager: one isolate changes state, every
                            wait is an isolate that sends it a message
  lib/network/netlink.talc  (network netlink): the kernel's socket for
                            networking, its framing and attributes
  lib/network/links.talc    (network links): links, addresses and routes
                            as records; setting a link up; adding and
                            removing addresses and routes; the changes
                            the kernel reports
  lib/network/dhcp.talc     (network dhcp): the client as a state machine
                            of data and time, and the two calls that
                            touch a socket
  lib/network/profiles.talc (network profiles): the *.network files, and
                            which one a link gets
  lib/network/forms.talc    (network forms): forms one a line, both ways
  lib/network/serve.talc    (network serve): the socket, its clients
  lib/network/client.talc   (network client): what a program imports to
                            ask -- network-links, network-resolver
  tools/links.talc          `links`: what is connected, asked of the manager
  tools/reach.talc          `reach <url>`: fetches it through the manager's
                            name servers -- the proof of a connection
  profiles/wired.network    any wired link, everything asked for; what the
                            vm's image carries at /etc/network
  examples/                 the libraries' tests: dhcp, profiles, forms
  scripts/build.sh          builds bin/network, bin/links, bin/reach
  scripts/regress.sh        the tests, then the manager asked over its socket
  scripts/vm-network.sh     a machine booted on qemu's network: a lease,
                            the cable pulled, a lease again

Build and check:

  scripts/build.sh
  scripts/regress.sh
  scripts/vm-network.sh

which need the installed toolchain (compiler on PATH) and, for the last,
../vm built (scripts/kernel.sh and scripts/build.sh there) and qemu.

RUNNING IT. The manager needs privilege to change the kernel's links; it
is started by the supervisor on the vm (../services, from its definition
definitions/network.service), before the shell, with the profiles under
/etc/network, writing what it does to /run/log/network and listening at
/run/network/socket, which the supervisor waits for before starting what
uses the network. Everything started after it has
NETWORK in its environment naming that socket -- which is how `links`,
`reach` and any program using (network client) find it; nothing assumes a
path.

  network [-profiles <directory>] [-socket <path>] [-only <link> ...]
          [-no-name] [-seconds n] [-trace]

With no -profiles every wired link gets the built-in profile (ask for
everything). -only names the links to touch and leaves the rest alone,
which is how it is tried on a machine something else manages:

  bin/network -socket build/sock -only nothing -seconds 10 &
  NETWORK=build/sock bin/links

shows the host's links as the kernel has them, all unmanaged. -no-name
leaves the machine's name alone whatever a lease offers; -trace logs
every message the main isolate handles.

THE MODEL. LINKS are what the kernel has; the manager is told of them
over netlink and never assumes a list. A PROFILE says how a link is to be
addressed once it has carrier: ask (DHCP), a fixed address with its
gateway, or local (up, going nowhere); which name servers; a preference
when several links are up (the lower wins the default route; the other
is kept, and takes over when the first loses its carrier). Profiles are
forms files, one per profile, matched to a link by its name or, failing
that, to any wired link. A link's states, as `links` shows them:

  unmanaged      not wired, or not in -only: left alone
  down           being set up
  up             set up, no carrier (no cable, or nothing at its end)
  carrier        carrier, and no profile applies
  addressing     asking DHCP
  connected      addressed; the route and the names are in place
  held           told (down ...): left alone until (up ...)

The kernel does IPv6 by itself (its autoconfiguration is left on); the
manager's addresses are IPv4, installed with the lease's lifetime so the
kernel drops them even if the manager dies.

THE PROTOCOL, forms one a line over the socket; a request gets one answer:

  (links)              (links (link "eth0" wired connected (hardware "...")
                               (address "10.0.2.15/24" (lifetime 86400))
                               (route default via "10.0.2.2" metric 200)
                               (names "10.0.2.3") (profile "wired")) ...)
  (resolver)           (resolver (servers "10.0.2.3") (search "lan"))
  (up "eth1") (down "eth1") (renew "eth0") (reload)
                       (ok), or (refused "up" "why")
  (watch)              (watching), then (changed "eth0" carrier) and
                       (names ...) as they happen

A client that is not the manager's user may ask (links), (resolver) and
(watch) only. (network client) wraps it: (network-links), (network-name-
servers), (network-resolver) -- a (system dns) resolver asking the
manager's servers, so that no program reads a file to find them.

A PROFILE FILE:

  (network "lab"
    (wired "eth1")                   ; or (wired) for any wired link
    (address "192.0.2.10/24")        ; or ask, or local
    (gateway "192.0.2.1")
    (names "192.0.2.1" "9.9.9.9")    ; or ask
    (search "lab.example")
    (prefer 50)                      ; 100 for a named link, 200 otherwise
    (name keep))                     ; or ask (DHCP's), or "a-name"

The (wired ...) clause is written out so that another kind can join it
one day without changing a file that exists.