Files
rebbarb/scripts/gc-testlink.sh
T
Roflin b363e76ec4 scripts: add gc-testlink.sh to configure the PC side of the test link
Sets the PC to 10.0.0.50/24 so the GC test suite's RX test can pass: its TX
test ARPs for that address and the kernel answers ARP for an address it
actually holds, so no listener process is needed.  Without it RX fails
legitimately for lack of traffic.

Handles the NetworkManager trap -- NM silently strips a hand-added address
within seconds, so the device is set unmanaged first and handed back on
'down'.  Warns that this drops any existing connection on that NIC.

up / down / status / watch, with wired-interface auto-detection (prefers one
with a carrier) and a status readout that flags no-carrier along with the
likely cause: the W5100S rail is gated off GC_ON, so it is dead whenever the
console is off.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-03 11:26:52 +02:00

144 lines
5.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Configure a PC ethernet interface for the direct link to the re-bba-rb board.
#
# The board's socket-3 UDP test identity and the ARP the on-console test suite
# sends both assume a point-to-point 10.0.0.0/24 link:
#
# PC 10.0.0.50 <-- this script
# board 10.0.0.99 <-- baked into the gateware at synth time
#
# The address matters: the GC test app's TX test ARPs for 10.0.0.50, and the
# kernel answers ARP for an address it actually holds -- no listener process is
# needed. That reply is what makes the suite's RX test pass, so without this
# configuration RX fails legitimately for lack of traffic.
#
# Run this ON THE PC (not in the devcontainer).
#
# sudo ./scripts/gc-testlink.sh up # configure (auto-detects the NIC)
# sudo ./scripts/gc-testlink.sh up eth0 # ...or name it explicitly
# sudo ./scripts/gc-testlink.sh status
# sudo ./scripts/gc-testlink.sh down # undo, hand the NIC back
# sudo ./scripts/gc-testlink.sh watch # configure, then tcpdump the link
set -euo pipefail
PC_IP=10.0.0.50
PREFIX=24
BOARD_IP=10.0.0.99
STATE_DIR=/run/gc-testlink
die() { echo "error: $*" >&2; exit 1; }
need_root() { [ "$(id -u)" -eq 0 ] || die "must run as root (use sudo)"; }
command -v ip >/dev/null 2>&1 || die "'ip' not found (iproute2). Run this on the PC, not in the devcontainer."
# Pick a wired interface: prefer one with a carrier, else the first en*/eth*.
detect_iface() {
local candidates=() i
for i in /sys/class/net/*; do
i=$(basename "$i")
case "$i" in
lo|docker*|veth*|br-*|virbr*|tap*|wl*|tun*) continue ;;
esac
[ -e "/sys/class/net/$i/device" ] || continue
candidates+=("$i")
done
[ ${#candidates[@]} -gt 0 ] || die "no wired interface found; pass one explicitly"
for i in "${candidates[@]}"; do
if [ "$(cat "/sys/class/net/$i/carrier" 2>/dev/null || echo 0)" = "1" ]; then
echo "$i"; return
fi
done
echo "${candidates[0]}"
}
nm_present() { command -v nmcli >/dev/null 2>&1 && systemctl is-active --quiet NetworkManager 2>/dev/null; }
do_up() {
local IF="$1"
echo "==> interface: $IF"
# NetworkManager will strip a hand-added address (often within seconds, and
# silently). Take the device out of its control first and remember that we
# did, so `down` can hand it back.
mkdir -p "$STATE_DIR"
if nm_present && [ "$(nmcli -g GENERAL.STATE device show "$IF" 2>/dev/null | head -1)" != "" ] \
&& nmcli -g GENERAL.STATE device show "$IF" 2>/dev/null | grep -qv unmanaged; then
echo "==> NetworkManager manages $IF -- setting it unmanaged"
echo " NOTE: this drops any existing connection on $IF (DHCP lease,"
echo " routes, DNS). If $IF is your only network interface you"
echo " will lose internet until '$0 down $IF'."
nmcli device set "$IF" managed no
touch "$STATE_DIR/$IF.was-managed"
fi
ip link set "$IF" up
if ip -4 addr show dev "$IF" | grep -q "inet $PC_IP/$PREFIX"; then
echo "==> $PC_IP/$PREFIX already present"
else
ip addr add "$PC_IP/$PREFIX" dev "$IF"
touch "$STATE_DIR/$IF.addr-added"
echo "==> added $PC_IP/$PREFIX"
fi
echo
do_status "$IF"
cat <<TXT
Ready. On the console, run gc_bba_test.dol from Swiss and press START.
The TX test ARPs for $PC_IP; this machine answers it, which is what the
RX test waits for.
To see the traffic: sudo tcpdump -ni $IF -e
To undo: sudo $0 down $IF
TXT
}
do_down() {
local IF="$1"
echo "==> interface: $IF"
if ip -4 addr show dev "$IF" | grep -q "inet $PC_IP/$PREFIX"; then
ip addr del "$PC_IP/$PREFIX" dev "$IF" && echo "==> removed $PC_IP/$PREFIX"
else
echo "==> $PC_IP/$PREFIX not present, nothing to remove"
fi
rm -f "$STATE_DIR/$IF.addr-added"
if [ -f "$STATE_DIR/$IF.was-managed" ]; then
echo "==> handing $IF back to NetworkManager"
nmcli device set "$IF" managed yes || true
rm -f "$STATE_DIR/$IF.was-managed"
fi
}
do_status() {
local IF="$1" carrier speed
carrier=$(cat "/sys/class/net/$IF/carrier" 2>/dev/null || echo "?")
speed=$(cat "/sys/class/net/$IF/speed" 2>/dev/null || echo "?")
echo " link carrier : $carrier (1 = cable up)"
echo " link speed : ${speed} Mb/s (expect 100 - the W5100S is 100BASE-TX)"
echo " addresses : $(ip -4 -br addr show dev "$IF" | tr -s ' ')"
if [ "$carrier" != "1" ]; then
echo " ** no carrier -- check the cable, and that the console is powered"
echo " (the W5100S rail is gated off GC_ON, so it is dead with the GC off)"
fi
if ip -4 addr show dev "$IF" | grep -q "inet $PC_IP/$PREFIX"; then
echo " config : OK, $PC_IP/$PREFIX is set"
else
echo " config : NOT configured -- run '$0 up $IF'"
fi
echo " board should be reachable at $BOARD_IP once its socket-3 test runs"
}
ACTION="${1:-up}"
IFACE="${2:-}"
[ -n "$IFACE" ] || IFACE=$(detect_iface)
[ -e "/sys/class/net/$IFACE" ] || die "no such interface: $IFACE"
case "$ACTION" in
up) need_root; do_up "$IFACE" ;;
down) need_root; do_down "$IFACE" ;;
status) do_status "$IFACE" ;;
watch) need_root; do_up "$IFACE"
echo; echo "==> tcpdump on $IFACE (ctrl-C to stop)"; echo
exec tcpdump -ni "$IFACE" -e ;;
*) die "usage: $0 {up|down|status|watch} [interface]" ;;
esac