Support reliable SECONDARY address adding

This commit is contained in:
Owen
2026-08-13 10:49:13 -04:00
parent eadac39ea7
commit abbab85bed
3 changed files with 49 additions and 3 deletions

View File

@@ -184,7 +184,9 @@ func AddSecondaryAddress(interfaceName string, addr string) error {
}
mask := net.IP(ipNet.Mask).String()
AddIPv4Address(ip.String(), mask)
if err := AddIPv4Address(ip.String(), mask); err != nil {
return err
}
if interfaceName == "" {
return nil

View File

@@ -2,6 +2,7 @@ package network
import (
"encoding/json"
"fmt"
"sync"
"github.com/fosrl/newt/logger"
@@ -86,14 +87,24 @@ func SetIPv4Settings(addresses []string, subnetMasks []string) {
// exposed to mobile (iOS/Android) packet-tunnel providers, which read the
// full IPv4Addresses/IPv4SubnetMasks arrays (not just the first entry) and
// re-apply them on every settings poll.
func AddIPv4Address(address string, subnetMask string) {
//
// It requires a primary address to already be set (via SetIPv4Settings,
// i.e. ConfigureInterface) and refuses to add otherwise: on mobile
// platforms, array order is what determines which address the OS treats as
// primary, so appending to an empty list would silently make this
// "additional" address the primary one instead.
func AddIPv4Address(address string, subnetMask string) error {
networkSettingsMutex.Lock()
defer networkSettingsMutex.Unlock()
if len(networkSettings.IPv4Addresses) == 0 {
return fmt.Errorf("cannot add secondary IPv4 address %s: no primary address configured yet", address)
}
for _, a := range networkSettings.IPv4Addresses {
if a == address {
logger.Info("IPv4 address already exists: %s", address)
return
return nil
}
}
@@ -101,6 +112,7 @@ func AddIPv4Address(address string, subnetMask string) {
networkSettings.IPv4SubnetMasks = append(networkSettings.IPv4SubnetMasks, subnetMask)
incrementor++
logger.Info("Added IPv4 address: %s/%s", address, subnetMask)
return nil
}
// RemoveIPv4Address removes a previously added secondary IPv4 address.

32
network/settings_test.go Normal file
View File

@@ -0,0 +1,32 @@
package network
import "testing"
func TestAddIPv4AddressRequiresPrimary(t *testing.T) {
ClearNetworkSettings()
defer ClearNetworkSettings()
if err := AddIPv4Address("10.10.0.5", "255.255.255.255"); err == nil {
t.Fatal("expected an error adding a secondary address before any primary address is set")
}
if got := GetSettings().IPv4Addresses; len(got) != 0 {
t.Errorf("IPv4Addresses = %v, want empty after a rejected add", got)
}
}
func TestAddIPv4AddressAfterPrimarySucceeds(t *testing.T) {
ClearNetworkSettings()
defer ClearNetworkSettings()
SetIPv4Settings([]string{"10.10.0.1"}, []string{"255.255.255.0"})
if err := AddIPv4Address("10.10.0.5", "255.255.255.255"); err != nil {
t.Fatalf("unexpected error adding secondary address: %v", err)
}
got := GetSettings().IPv4Addresses
want := []string{"10.10.0.1", "10.10.0.5"}
if len(got) != len(want) || got[0] != want[0] || got[1] != want[1] {
t.Errorf("IPv4Addresses = %v, want %v", got, want)
}
}