|
if(! test -d /mnt/fw)
mntgen /mnt/fw
mount(2) needs its mount point to exist, so mntgen cannot create
/mnt/fw -- and this ran it only when /mnt/fw was missing, which is
exactly the case where it fails:
mntgen: mount /tmp/mg/fw: file does not exist: '/tmp/mg'
So on a machine that had never had a /mnt/fw, the control directories
never appeared, and fw's own "not touching the card until the mountpoint
exists" check then refused every card in the file. The script has never
worked on a fresh machine. It has also never been run by the suite,
which is the other half of why nobody noticed.
Now the directory first, then mntgen only if it is not already there --
under mntgen every name exists, which is the test.
Both mntgen and fw leave a server behind, and a server started from a
shell keeps that shell's descriptors, so at boot they sit on the
console's input and it reads as a wedged terminal. This is the trap
CLAUDE.md documents; the script was walking into it. They get
/dev/null.
Three checks, and fwstart now gets run at all: a control directory
appears, a card that is not there is reported and skipped, and nothing
left running holds the descriptors we started it with. The first fails
against the old script. The third does not, because the old script
never started anything for want of the directory -- it guards the fix
from here, not the bug that was there.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
One program with three modes, sharing one rule engine and one ndb rule
language. Which mode it is depends on what you point it at, and it says
so at startup rather than choosing silently.
fw -e /net/ether0 rules.ndb a card: every packet in or out
fw rules.ndb <side> <side> two networks: everything crossing
fw rules.ndb one namespace: what programs ask for
The first two filter packets on a wire, using the pkt medium: the stack
gives up its card and gets a synthetic one with fw on the other end, so
nothing reaches it that fw did not pass. Since the stack no longer has
ethernet, fw answers ARP for the address it stands in for.
The third serves a filtered /net and matches connect and announce before
they reach the kernel, so a refusal comes back out of dial(2) with a
reason. That is only a boundary if the program also loses #I, which
/dev/drivers does and cannot be undone; fw.rc does it in the right order.
Rules are ndb, matched top to bottom, first match wins, no match denies.
Connections are tracked, so permitting traffic one way permits the
replies. A rule change drops connections the new rules forbid rather
than letting them finish: a block blocks. Logging is per rule, to
/sys/log/fw.
Tested on the init-test VM in all three modes: a page fetched through a
real card, a TCP handshake across two networks, request filtering with
the escape routes closed, live rule changes killing established
connections, and one rule file working unchanged at both altitudes.
doc/todo.md has what is not done. Item 1 is the one that matters: a fw
that dies takes the card's address with it, so the machine loses its
network and fw cannot restart unaided. That also blocks svc supervision.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|