#!/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 < 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