#!/bin/sh # bee-network.sh — bring up all physical network interfaces via DHCP # Unattended: starts later in boot, runs quietly, and gives up after a bounded timeout. LOG_PREFIX="bee-network" DHCP_TIMEOUT_SECS=300 log() { echo "[$LOG_PREFIX] $*"; } list_interfaces() { ip -o link show \ | awk -F': ' '{print $2}' \ | grep -v '^lo$' \ | grep -vE '^(docker|virbr|veth|tun|tap|br-|bond|dummy)' \ | sort } # Give udev a short chance to expose late NICs before the first scan. if command -v udevadm >/dev/null 2>&1; then udevadm settle --timeout=5 >/dev/null 2>&1 || log "WARN: udevadm settle timed out" fi start_dhcp() { iface="$1" if ! ip link set "$iface" up; then log "WARN: could not bring up $iface" return 1 fi carrier=$(cat "/sys/class/net/$iface/carrier" 2>/dev/null || true) if [ "$carrier" = "1" ]; then log "carrier detected on $iface" else log "carrier not detected on $iface" fi dhclient -r "$iface" >/dev/null 2>&1 || true if timeout "${DHCP_TIMEOUT_SECS}" dhclient -4 -q -1 "$iface" >/dev/null 2>&1; then addr="$(ip -4 -o addr show dev "$iface" scope global 2>/dev/null | awk '{print $4}' | head -1)" if [ -n "$addr" ]; then log "DHCP lease acquired on $iface ($addr)" else log "DHCP lease acquired on $iface" fi return 0 fi rc=$? case "$rc" in 124) log "DHCP timed out on $iface after ${DHCP_TIMEOUT_SECS}s" ;; *) log "DHCP failed on $iface (exit $rc)" ;; esac dhclient -r "$iface" >/dev/null 2>&1 || true return 1 } started_ifaces="" started_count=0 scan_pass=1 pids="" pid_ifaces="" # Some server NICs appear a bit later after module/firmware init. Do a small # bounded rescan window without turning network bring-up into a boot blocker. while [ "$scan_pass" -le 3 ]; do interfaces=$(list_interfaces) if [ -n "$interfaces" ]; then for iface in $interfaces; do case " $started_ifaces " in *" $iface "*) continue ;; esac log "starting DHCP on $iface (timeout ${DHCP_TIMEOUT_SECS}s)" start_dhcp "$iface" & pid="$!" pids="$pids $pid" pid_ifaces="$pid_ifaces $pid:$iface" started_ifaces="$started_ifaces $iface" started_count=$((started_count + 1)) done fi if [ "$scan_pass" -ge 3 ]; then break fi scan_pass=$((scan_pass + 1)) sleep 2 done if [ "$started_count" -eq 0 ]; then log "no physical interfaces found" exit 0 fi success_count=0 for pid_iface in $pid_ifaces; do pid="${pid_iface%%:*}" iface="${pid_iface#*:}" if wait "$pid"; then success_count=$((success_count + 1)) else log "DHCP did not complete successfully on $iface" fi done log "done (interfaces scanned: $started_count, leases acquired: $success_count)"