From 8e98ecb5f7cf2dc8c36b482030bea0c45ab1d123 Mon Sep 17 00:00:00 2001 From: Jonathan Nobels Date: Fri, 10 Oct 2025 12:34:27 -0400 Subject: [PATCH] net/netmon: handle net.IPAddr types during interface address parsing (#17523) updates tailscale/tailscale#16836 Android's altNetInterfaces implementation now returns net.IPAddr types which netmon wasn't handling. Signed-off-by: Jonathan Nobels --- net/netmon/netmon_test.go | 40 +++++++++++++++++++++++++++++++++++++++ net/netmon/state.go | 8 ++++++++ 2 files changed, 48 insertions(+) diff --git a/net/netmon/netmon_test.go b/net/netmon/netmon_test.go index 5fcdcc6cc..358dc0373 100644 --- a/net/netmon/netmon_test.go +++ b/net/netmon/netmon_test.go @@ -7,6 +7,7 @@ import ( "flag" "net" "net/netip" + "reflect" "sync/atomic" "testing" "time" @@ -267,6 +268,45 @@ func TestIsMajorChangeFrom(t *testing.T) { }) } } +func TestForeachInterface(t *testing.T) { + tests := []struct { + name string + addrs []net.Addr + want []string + }{ + { + name: "Mixed_IPv4_and_IPv6", + addrs: []net.Addr{ + &net.IPNet{IP: net.IPv4(1, 2, 3, 4), Mask: net.CIDRMask(24, 32)}, + &net.IPAddr{IP: net.IP{5, 6, 7, 8}, Zone: ""}, + &net.IPNet{IP: net.ParseIP("2001:db8::1"), Mask: net.CIDRMask(64, 128)}, + &net.IPAddr{IP: net.ParseIP("2001:db8::2"), Zone: ""}, + }, + want: []string{"1.2.3.4", "5.6.7.8", "2001:db8::1", "2001:db8::2"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got []string + ifaces := InterfaceList{ + { + Interface: &net.Interface{Name: "eth0"}, + AltAddrs: tt.addrs, + }, + } + ifaces.ForeachInterface(func(iface Interface, prefixes []netip.Prefix) { + for _, prefix := range prefixes { + ip := prefix.Addr() + got = append(got, ip.String()) + } + }) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("got %q, want %q", got, tt.want) + } + }) + } +} type testOSMon struct { osMon diff --git a/net/netmon/state.go b/net/netmon/state.go index 73497e93f..27e3524e8 100644 --- a/net/netmon/state.go +++ b/net/netmon/state.go @@ -183,6 +183,10 @@ func (ifaces InterfaceList) ForeachInterfaceAddress(fn func(Interface, netip.Pre if pfx, ok := netaddr.FromStdIPNet(v); ok { fn(iface, pfx) } + case *net.IPAddr: + if ip, ok := netip.AddrFromSlice(v.IP); ok { + fn(iface, netip.PrefixFrom(ip, ip.BitLen())) + } } } } @@ -215,6 +219,10 @@ func (ifaces InterfaceList) ForeachInterface(fn func(Interface, []netip.Prefix)) if pfx, ok := netaddr.FromStdIPNet(v); ok { pfxs = append(pfxs, pfx) } + case *net.IPAddr: + if ip, ok := netip.AddrFromSlice(v.IP); ok { + pfxs = append(pfxs, netip.PrefixFrom(ip, ip.BitLen())) + } } } sort.Slice(pfxs, func(i, j int) bool {