diff --git a/src/service/10-link-local-mgmt b/src/service/10-link-local-mgmt new file mode 100644 index 0000000..3908060 --- /dev/null +++ b/src/service/10-link-local-mgmt @@ -0,0 +1,83 @@ +#!/bin/bash +# NetworkManager dispatcher script: 10-link-local-mgmt +# +# Temporarily suppresses IPv4 link-local when a DHCP address is available, +# using nmcli device modify (active session only, NOT saved to the profile). +# The persistent profile always keeps ipv4.link-local=enabled so that +# direct-connect (no DHCP) plug-ins always activate and trigger events. +# +# Triggers: up, down, dhcp4-change on ethernet interfaces +# Install to: /etc/NetworkManager/dispatcher.d/10-link-local-mgmt +# Permissions: root:root 0755 + +INTERFACE="$1" +ACTION="$2" +CONNECTION_NAME="${CONNECTION_ID:-}" + +# Only handle ethernet interfaces +if [[ ! "$INTERFACE" =~ ^eth ]]; then + exit 0 +fi + +# If CONNECTION_ID env var is not set, look up the active connection for this interface +if [ -z "$CONNECTION_NAME" ]; then + CONNECTION_NAME=$(nmcli -t -f NAME,DEVICE connection show --active 2>/dev/null \ + | grep ":${INTERFACE}$" | cut -d: -f1 | head -n1) + [ -z "$CONNECTION_NAME" ] && exit 0 +fi + +# Update /etc/avahi/hosts to point mDNS hostname at the best available DHCP address +# across all ethernet interfaces (so Avahi doesn't advertise a link-local address). +update_avahi() { + local hostname + hostname=$(hostname) + # Find first non-link-local IPv4 across all ethernet interfaces + local dhcp_ip + dhcp_ip=$(ip -4 addr show 2>/dev/null \ + | grep -A5 ': eth' \ + | grep -oP '(?<=inet\s)\d+(\.\d+){3}' \ + | grep -v '^127\.' \ + | grep -v '^169\.254\.' \ + | head -n1) + + if [ -n "$dhcp_ip" ]; then + mkdir -p /etc/avahi + echo "$dhcp_ip $hostname $hostname.local" > /etc/avahi/hosts + logger -t nm-link-local "Avahi: pinned $hostname -> $dhcp_ip" + else + rm -f /etc/avahi/hosts + logger -t nm-link-local "Avahi: removed hosts pin, using all addresses" + fi + systemctl restart avahi-daemon 2>/dev/null +} + +case "$ACTION" in + up|dhcp4-change) + DHCP_IP=$(ip -4 addr show "$INTERFACE" 2>/dev/null \ + | grep -oP '(?<=inet\s)\d+(\.\d+){3}' \ + | grep -v '^127\.' \ + | grep -v '^169\.254\.' \ + | head -n1) + + if [ -n "$DHCP_IP" ]; then + logger -t nm-link-local "[$INTERFACE] DHCP $DHCP_IP detected — suppressing link-local (session only)" + # Use device modify (not connection modify) so the persistent profile keeps + # ipv4.link-local=enabled. This ensures direct-connect plug-ins always activate. + # Run in background after a delay — nmcli blocks on NM, which is waiting for + # this dispatcher to return, causing a deadlock if called synchronously. + (sleep 2 && nmcli device modify "$INTERFACE" ipv4.link-local disabled 2>/dev/null \ + && logger -t nm-link-local "[$INTERFACE] Link-local suppressed for current session") & + else + logger -t nm-link-local "[$INTERFACE] No DHCP on $INTERFACE — keeping link-local active" + fi + update_avahi + ;; + + down) + # Profile always has ipv4.link-local=enabled so no action needed here. + # The suppression from device modify was session-only and is gone when the + # connection goes down. + logger -t nm-link-local "[$INTERFACE] Down — link-local will be active on next connect" + update_avahi + ;; +esac diff --git a/src/service/update_and_run_server_and_frontend.sh b/src/service/update_and_run_server_and_frontend.sh index a193b5c..7e552ec 100755 --- a/src/service/update_and_run_server_and_frontend.sh +++ b/src/service/update_and_run_server_and_frontend.sh @@ -14,24 +14,10 @@ while IFS=: read -r name type; do fi done < <(nmcli -t -f NAME,TYPE connection show) -# Configure Avahi to prefer DHCP address over static fallback for mDNS -# Get the DHCP-assigned IP (first non-localhost, non-192.168.42.10 IP) -DHCP_IP=$(ip -4 addr show eth0 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | grep -v '^127\.' | grep -v '^169\.254\.' | head -n1) -HOSTNAME=$(hostname) - -if [ -n "$DHCP_IP" ]; then - echo "DHCP address detected: $DHCP_IP, configuring Avahi to prefer it for mDNS." - # Add entry to /etc/avahi/hosts to explicitly map hostname to DHCP IP - sudo mkdir -p /etc/avahi - echo "$DHCP_IP $HOSTNAME $HOSTNAME.local" | sudo tee /etc/avahi/hosts > /dev/null - # Restart avahi to apply the hosts file - sudo systemctl restart avahi-daemon -else - echo "No DHCP address detected, mDNS will use link local" - # Remove hosts file to let Avahi advertise all IPs - sudo rm -f /etc/avahi/hosts - sudo systemctl restart avahi-daemon -fi +# Install NetworkManager dispatcher script for link-local / Avahi management +sudo cp /home/caster/bumble-auracast/src/service/10-link-local-mgmt /etc/NetworkManager/dispatcher.d/10-link-local-mgmt +sudo chown root:root /etc/NetworkManager/dispatcher.d/10-link-local-mgmt +sudo chmod 755 /etc/NetworkManager/dispatcher.d/10-link-local-mgmt # Copy system service file for frontend sudo cp /home/caster/bumble-auracast/src/service/auracast-frontend.service /etc/systemd/system/auracast-frontend.service