Files
ferrix/scripts/linux-vm.sh
T
Rayhaan JaufeerallyandClaude Fable 5.1 1fc44798b7 Install best routes in the Linux kernel over netlink
New crate bgp-fib. It follows the routing table's best routes and keeps
the kernel's routing table the same, and learns the machine's interfaces
and addresses from the kernel, which is what says whether a next hop can
be reached.

- netlink: the rtnetlink messages used (routes, addresses, links, errors),
  as bytes and back. No I/O; property tested and fuzzed.
- interfaces: what is directly reachable, and from which interface.
- plan: what to ask the kernel for, given the best routes and what the
  kernel has. No I/O; tested against a model kernel.
- kernel (Linux only): the sockets and the task. Requests go in batches;
  routes of ours found at startup are kept if still right and removed if
  not; a change of interfaces has every route worked out again; a clean
  stop removes our routes.

Only routes marked proto bgp with the configured table and metric are
ever touched. A best route is installed if its next hop is a neighbor;
next hops further away are not resolved through other routes yet, and
such prefixes are counted and shown instead.

Configured with `kernel { table metric }`; off by default. The daemon
needs CAP_NET_ADMIN and stops if the kernel refuses it. On shutdown it
closes sessions and then removes its routes.

/api/kernel and the status page show installed, unresolved and refused
counts, the last error and the interfaces; five bgp_kernel_* metrics.

Testing: scripts/kernel-tests.sh runs, in network namespaces of their
own and with only the capabilities the daemon needs, the installer
against `ip route`, the daemon with a peer, and two daemons that route
for each other with pings across over IPv4 and IPv6.
scripts/linux-vm.sh runs that, or anything else, in a Lima VM from
macOS. CI runs the kernel tests and fuzzes the netlink decoder.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 15:15:43 +02:00

35 lines
1.5 KiB
Bash
Executable File

#!/bin/sh
# Runs a command in a Linux virtual machine with this repository mounted
# at the same path: for the tests that need a Linux kernel, from a machine
# that is not one. Without arguments it runs scripts/kernel-tests.sh.
#
# scripts/linux-vm.sh the kernel tests
# scripts/linux-vm.sh cargo test the whole test suite, on Linux
# scripts/linux-vm.sh bash a shell
#
# The machine is made on first use with Lima (https://lima-vm.io; on macOS
# `brew install lima`): Ubuntu, with a Rust toolchain. It sees the
# repository read-only and builds into a directory of its own.
# `limactl stop ferrix` stops it and `limactl delete ferrix` removes it.
set -eu
vm=ferrix
repository="$(cd "$(dirname "$0")/.." && pwd)"
command -v limactl >/dev/null || { echo "limactl not found: install Lima first" >&2; exit 1; }
if ! limactl list --quiet | grep -qx "$vm"; then
limactl start --name="$vm" --cpus=8 --memory=8 --disk=30 --tty=false template://ubuntu-lts
limactl shell "$vm" bash -c '
set -eu
sudo apt-get update -qq
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq build-essential iproute2 iputils-ping curl
curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal -q
'
elif [ "$(limactl list --format '{{.Status}}' "$vm")" != Running ]; then
limactl start "$vm"
fi
[ $# -gt 0 ] || set -- scripts/kernel-tests.sh
limactl shell --workdir "$repository" "$vm" \
bash -lc 'export CARGO_TARGET_DIR="$HOME/target"; exec "$@"' -- "$@"