Browse Source

Fix eth0 DHCP management

Critical fixes:
1. Don't restart udhcpc every second - add eth0DhcpRunning flag
2. Don't flush IP before starting DHCP - breaks SSH connections
3. Use 'ip link set' instead of 'ifconfig'
4. Use cmd.Start() instead of CombinedOutput() for background process
5. Better error logging

The main issue was that tick() was calling startEth0DHCP() every second
while !eth0HasIP, which killed and restarted udhcpc constantly,
preventing it from ever obtaining an IP address.
root 1 month ago
parent
commit
1a4649ac19
1 changed files with 21 additions and 16 deletions
  1. 21 16
      cmd/beacon-daemon/network_manager.go

+ 21 - 16
cmd/beacon-daemon/network_manager.go

@@ -40,13 +40,14 @@ type NetworkManager struct {
 	scanners *ScannerManager
 
 	// State tracking
-	eth0Carrier    bool
-	eth0HasIP      bool
-	wlan0HasIP     bool
-	currentState   NetworkState
-	lastOnlineTime time.Time
-	apRunning      bool
-	eth0DhcpPid    int
+	eth0Carrier     bool
+	eth0HasIP       bool
+	eth0DhcpRunning bool
+	wlan0HasIP      bool
+	currentState    NetworkState
+	lastOnlineTime  time.Time
+	apRunning       bool
+	eth0DhcpPid     int
 }
 
 // NewNetworkManager creates a new network manager
@@ -131,8 +132,8 @@ func (nm *NetworkManager) tick() {
 
 	// Priority 1: eth0 (independent, always configure if carrier UP)
 	if nm.eth0Carrier {
-		if !nm.eth0HasIP {
-			// Carrier UP but no IP - configure network
+		if !nm.eth0HasIP && !nm.eth0DhcpRunning {
+			// Carrier UP but no IP and DHCP not running - configure network
 			if nm.cfg.Network.Eth0.Static {
 				log.Println("[netmgr] eth0 carrier UP - configuring static IP")
 				nm.configureEth0Static()
@@ -143,7 +144,7 @@ func (nm *NetworkManager) tick() {
 		}
 	} else {
 		// No eth0 carrier - stop eth0 DHCP/IP
-		if nm.eth0HasIP {
+		if nm.eth0HasIP || nm.eth0DhcpRunning {
 			log.Println("[netmgr] eth0 carrier DOWN - stopping network")
 			nm.stopEth0()
 		}
@@ -252,11 +253,8 @@ func (nm *NetworkManager) startEth0DHCP() {
 	// Stop any existing DHCP first
 	nm.stopEth0DHCP()
 
-	// Flush old IPs
-	exec.Command("ip", "addr", "flush", "dev", eth0Interface).Run()
-
-	// Bring interface up
-	exec.Command("ifconfig", eth0Interface, "up").Run()
+	// Bring interface up (don't flush IP - udhcpc will handle it)
+	exec.Command("ip", "link", "set", eth0Interface, "up").Run()
 
 	// Start udhcpc
 	pidFile := fmt.Sprintf("/var/run/udhcpc.%s.pid", eth0Interface)
@@ -266,12 +264,18 @@ func (nm *NetworkManager) startEth0DHCP() {
 		return
 	}
 
+	nm.eth0DhcpRunning = true
 	time.Sleep(500 * time.Millisecond)
 
 	// Read PID
 	pidData, err := os.ReadFile(pidFile)
 	if err == nil {
 		fmt.Sscanf(string(pidData), "%d", &nm.eth0DhcpPid)
+		if nm.debug {
+			log.Printf("[netmgr] eth0 DHCP started (PID: %d)", nm.eth0DhcpPid)
+		}
+	} else {
+		log.Printf("[netmgr] Warning: Could not read udhcpc PID file: %v", err)
 	}
 }
 
@@ -279,7 +283,7 @@ func (nm *NetworkManager) configureEth0Static() {
 	nm.stopEth0DHCP()
 
 	// Bring interface up
-	exec.Command("ifconfig", eth0Interface, "up").Run()
+	exec.Command("ip", "link", "set", eth0Interface, "up").Run()
 
 	// Configure IP
 	if nm.cfg.Network.Eth0.Address != "" {
@@ -320,6 +324,7 @@ func (nm *NetworkManager) stopEth0DHCP() {
 	}
 	exec.Command("killall", "-q", "udhcpc").Run()
 	nm.eth0DhcpPid = 0
+	nm.eth0DhcpRunning = false
 }
 
 func (nm *NetworkManager) stopEth0() {