Explorar o código

all: migrate more code code to net/netip directly

Instead of going through the tailscale.com/net/netaddr transitional
wrappers.

Updates #5162

Change-Id: I3dafd1c2effa1a6caa9b7151ecf6edd1a3fda3dd
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick %!s(int64=3) %!d(string=hai) anos
pai
achega
8725b14056

+ 1 - 1
cmd/tailscale/depaware.txt

@@ -57,7 +57,7 @@ tailscale.com/cmd/tailscale dependencies: (generated by github.com/tailscale/dep
         tailscale.com/net/dnsfallback                                from tailscale.com/control/controlhttp
         tailscale.com/net/flowtrack                                  from tailscale.com/wgengine/filter+
      💣 tailscale.com/net/interfaces                                 from tailscale.com/cmd/tailscale/cli+
-        tailscale.com/net/netaddr                                    from tailscale.com/disco+
+        tailscale.com/net/netaddr                                    from tailscale.com/ipn+
         tailscale.com/net/netcheck                                   from tailscale.com/cmd/tailscale/cli
         tailscale.com/net/neterror                                   from tailscale.com/net/netcheck+
         tailscale.com/net/netknob                                    from tailscale.com/net/netns

+ 1 - 1
cmd/tailscaled/depaware.txt

@@ -219,7 +219,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de
         tailscale.com/net/dnsfallback                                from tailscale.com/control/controlclient+
         tailscale.com/net/flowtrack                                  from tailscale.com/net/packet+
      💣 tailscale.com/net/interfaces                                 from tailscale.com/control/controlclient+
-        tailscale.com/net/netaddr                                    from tailscale.com/disco+
+        tailscale.com/net/netaddr                                    from tailscale.com/ipn+
         tailscale.com/net/netcheck                                   from tailscale.com/wgengine/magicsock
         tailscale.com/net/neterror                                   from tailscale.com/net/dns/resolver+
         tailscale.com/net/netknob                                    from tailscale.com/net/netns+

+ 3 - 4
disco/disco.go

@@ -28,7 +28,6 @@ import (
 	"net/netip"
 
 	"go4.org/mem"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/types/key"
 )
 
@@ -200,7 +199,7 @@ func parseCallMeMaybe(ver uint8, p []byte) (m *CallMeMaybe, err error) {
 		var a [16]byte
 		copy(a[:], p)
 		m.MyNumber = append(m.MyNumber, netip.AddrPortFrom(
-			netaddr.IPFrom16(a),
+			netip.AddrFrom16(a).Unmap(),
 			binary.BigEndian.Uint16(p[16:18])))
 		p = p[epLength:]
 	}
@@ -235,10 +234,10 @@ func parsePong(ver uint8, p []byte) (m *Pong, err error) {
 	copy(m.TxID[:], p)
 	p = p[12:]
 
-	srcIP, _ := netaddr.FromStdIP(net.IP(p[:16]))
+	srcIP, _ := netip.AddrFromSlice(net.IP(p[:16]))
 	p = p[16:]
 	port := binary.BigEndian.Uint16(p)
-	m.Src = netip.AddrPortFrom(srcIP, port)
+	m.Src = netip.AddrPortFrom(srcIP.Unmap(), port)
 	return m, nil
 }
 

+ 2 - 2
net/dns/manager_windows.go

@@ -18,7 +18,6 @@ import (
 	"golang.org/x/sys/windows/registry"
 	"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
 	"tailscale.com/envknob"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/types/logger"
 	"tailscale.com/util/dnsname"
 )
@@ -394,10 +393,11 @@ func (m windowsManager) getBasePrimaryResolver() (resolvers []netip.Addr, err er
 
 	ipLoop:
 		for _, stdip := range ips {
-			ip, ok := netaddr.FromStdIP(stdip)
+			ip, ok := netip.AddrFromSlice(stdip)
 			if !ok {
 				continue
 			}
+			ip = ip.Unmap()
 			// Skip IPv6 site-local resolvers. These are an ancient
 			// and obsolete IPv6 RFC, which Windows still faithfully
 			// implements. The net result is that some low-metric

+ 4 - 4
net/dns/resolver/tsdns.go

@@ -428,8 +428,8 @@ func handleExitNodeDNSQueryWithNetPkg(ctx context.Context, resolver *net.Resolve
 			return handleError(err)
 		}
 		for _, stdIP := range ips {
-			if ip, ok := netaddr.FromStdIP(stdIP); ok {
-				resp.IPs = append(resp.IPs, ip)
+			if ip, ok := netip.AddrFromSlice(stdIP); ok {
+				resp.IPs = append(resp.IPs, ip.Unmap())
 			}
 		}
 	case dns.TypeTXT:
@@ -1124,7 +1124,7 @@ func rdnsNameToIPv6(name dnsname.FQDN) (ip netip.Addr, ok bool) {
 		return netip.Addr{}, false
 	}
 
-	return netaddr.IPFrom16(ipb), true
+	return netip.AddrFrom16(ipb), true
 }
 
 // respondReverse returns a DNS response to a PTR query.
@@ -1221,7 +1221,7 @@ func unARPA(a string) (ipStr string, ok bool) {
 			}
 		}
 		hex.Decode(a16[:], hx[:])
-		return netaddr.IPFrom16(a16).String(), true
+		return netip.AddrFrom16(a16).Unmap().String(), true
 	}
 	return "", false
 

+ 8 - 7
net/dnscache/dnscache.go

@@ -21,7 +21,6 @@ import (
 	"time"
 
 	"tailscale.com/envknob"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/util/cloudenv"
 	"tailscale.com/util/singleflight"
 )
@@ -312,7 +311,7 @@ func (r *Resolver) lookupIP(host string) (ip, ip6 net.IP, allIPs []net.IPAddr, e
 }
 
 func (r *Resolver) addIPCache(host string, ip, ip6 net.IP, allIPs []net.IPAddr, d time.Duration) {
-	if naIP, _ := netaddr.FromStdIP(ip); naIP.IsPrivate() {
+	if ip.IsPrivate() {
 		// Don't cache obviously wrong entries from captive portals.
 		// TODO: use DoH or DoT for the forwarding resolver?
 		if debug {
@@ -400,16 +399,16 @@ func (d *dialer) DialContext(ctx context.Context, network, address string) (retC
 		if debug {
 			log.Printf("dnscache: dialing %s, %s for %s", network, ip, address)
 		}
-		ipNA, ok := netaddr.FromStdIP(ip)
+		ipNA, ok := netip.AddrFromSlice(ip)
 		if !ok {
 			return nil, fmt.Errorf("invalid IP %q", ip)
 		}
-		c, err := dc.dialOne(ctx, ipNA)
+		c, err := dc.dialOne(ctx, ipNA.Unmap())
 		if err == nil || ctx.Err() != nil {
 			return c, err
 		}
 		// Fall back to trying IPv6, if any.
-		ip6NA, ok := netaddr.FromStdIP(ip6)
+		ip6NA, ok := netip.AddrFromSlice(ip6)
 		if !ok {
 			return nil, err
 		}
@@ -583,7 +582,9 @@ func (dc *dialCall) raceDial(ctx context.Context, ips []netip.Addr) (net.Conn, e
 
 func v4addrs(aa []net.IPAddr) (ret []netip.Addr) {
 	for _, a := range aa {
-		if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is4() {
+		ip, ok := netip.AddrFromSlice(a.IP)
+		ip = ip.Unmap()
+		if ok {
 			ret = append(ret, ip)
 		}
 	}
@@ -592,7 +593,7 @@ func v4addrs(aa []net.IPAddr) (ret []netip.Addr) {
 
 func v6addrs(aa []net.IPAddr) (ret []netip.Addr) {
 	for _, a := range aa {
-		if ip, ok := netaddr.FromStdIP(a.IP); ok && ip.Is6() {
+		if ip, ok := netip.AddrFromSlice(a.IP); ok && ip.Is6() {
 			ret = append(ret, ip)
 		}
 	}

+ 4 - 2
net/interfaces/interfaces.go

@@ -44,7 +44,8 @@ func Tailscale() ([]netip.Addr, *net.Interface, error) {
 		var tsIPs []netip.Addr
 		for _, a := range addrs {
 			if ipnet, ok := a.(*net.IPNet); ok {
-				nip, ok := netaddr.FromStdIP(ipnet.IP)
+				nip, ok := netip.AddrFromSlice(ipnet.IP)
+				nip = nip.Unmap()
 				if ok && tsaddr.IsTailscaleIP(nip) {
 					tsIPs = append(tsIPs, nip)
 				}
@@ -110,10 +111,11 @@ func LocalAddresses() (regular, loopback []netip.Addr, err error) {
 		for _, a := range addrs {
 			switch v := a.(type) {
 			case *net.IPNet:
-				ip, ok := netaddr.FromStdIP(v.IP)
+				ip, ok := netip.AddrFromSlice(v.IP)
 				if !ok {
 					continue
 				}
+				ip = ip.Unmap()
 				// TODO(apenwarr): don't special case cgNAT.
 				// In the general wireguard case, it might
 				// very well be something we can route to

+ 2 - 2
net/interfaces/interfaces_windows.go

@@ -15,7 +15,6 @@ import (
 
 	"golang.org/x/sys/windows"
 	"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/tsconst"
 )
 
@@ -65,11 +64,12 @@ func likelyHomeRouterIPWindows() (ret netip.Addr, ok bool) {
 			continue
 		}
 
-		ip, ok := netaddr.FromStdIP(r.NextHop.IP())
+		ip, ok := netip.AddrFromSlice(r.NextHop.IP())
 		if !ok {
 			// Not a valid gateway, so skip (won't happen though)
 			continue
 		}
+		ip = ip.Unmap()
 
 		if best == nil {
 			best = r

+ 3 - 31
net/netaddr/netaddr.go

@@ -20,42 +20,14 @@ func IPv4(a, b, c, d uint8) netip.Addr {
 	return netip.AddrFrom4([4]byte{a, b, c, d})
 }
 
-// IPFrom16 returns the IP address given by the bytes in addr, unmapping any
-// v6-mapped IPv4 address.
-//
-// It is equivalent to calling IPv6Raw(addr).Unmap().
-func IPFrom16(a [16]byte) netip.Addr {
-	return netip.AddrFrom16(a).Unmap()
-}
-
-// FromStdIP returns an IP from the standard library's IP type.
-//
-// If std is invalid, ok is false.
-//
-// FromStdIP implicitly unmaps IPv6-mapped IPv4 addresses. That is, if
-// len(std) == 16 and contains an IPv4 address, only the IPv4 part is
-// returned, without the IPv6 wrapper. This is the common form returned by
-// the standard library's ParseIP: https://play.golang.org/p/qdjylUkKWxl.
-// To convert a standard library IP without the implicit unmapping, use
-// netip.AddrFromSlice.
-func FromStdIP(std net.IP) (ip netip.Addr, ok bool) {
-	ret, ok := netip.AddrFromSlice(std)
-	if !ok {
-		return ret, false
-	}
-	if ret.Is4In6() {
-		return ret.Unmap(), true
-	}
-	return ret, true
-}
-
 // FromStdIPNet returns an IPPrefix from the standard library's IPNet type.
 // If std is invalid, ok is false.
 func FromStdIPNet(std *net.IPNet) (prefix netip.Prefix, ok bool) {
-	ip, ok := FromStdIP(std.IP)
+	ip, ok := netip.AddrFromSlice(std.IP)
 	if !ok {
 		return netip.Prefix{}, false
 	}
+	ip = ip.Unmap()
 
 	if l := len(std.Mask); l != net.IPv4len && l != net.IPv6len {
 		// Invalid mask.
@@ -74,7 +46,7 @@ func FromStdIPNet(std *net.IPNet) (prefix netip.Prefix, ok bool) {
 // FromStdAddr maps the components of a standard library TCPAddr or
 // UDPAddr into an IPPort.
 func FromStdAddr(stdIP net.IP, port int, zone string) (_ netip.AddrPort, ok bool) {
-	ip, ok := FromStdIP(stdIP)
+	ip, ok := netip.AddrFromSlice(stdIP)
 	if !ok || port < 0 || port > math.MaxUint16 {
 		return
 	}

+ 4 - 3
net/netcheck/netcheck.go

@@ -1031,7 +1031,8 @@ func (c *Client) measureHTTPSLatency(ctx context.Context, reg *tailcfg.DERPRegio
 	defer tcpConn.Close()
 
 	if ta, ok := tlsConn.RemoteAddr().(*net.TCPAddr); ok {
-		ip, _ = netaddr.FromStdIP(ta.IP)
+		ip, _ = netip.AddrFromSlice(ta.IP)
+		ip = ip.Unmap()
 	}
 	if ip == (netip.Addr{}) {
 		return 0, ip, fmt.Errorf("no unexpected RemoteAddr %#v", tlsConn.RemoteAddr())
@@ -1328,8 +1329,8 @@ func (c *Client) nodeAddr(ctx context.Context, n *tailcfg.DERPNode, proto probeP
 	addrs, _ := net.DefaultResolver.LookupIPAddr(ctx, n.HostName)
 	for _, a := range addrs {
 		if (a.IP.To4() != nil) == (proto == probeIPv4) {
-			na, _ := netaddr.FromStdIP(a.IP.To4())
-			return netip.AddrPortFrom(na, uint16(port))
+			na, _ := netip.AddrFromSlice(a.IP.To4())
+			return netip.AddrPortFrom(na.Unmap(), uint16(port))
 		}
 	}
 	return

+ 1 - 1
net/netstat/netstat_windows.go

@@ -164,7 +164,7 @@ func ipport4(addr uint32, port uint16) netip.AddrPort {
 }
 
 func ipport6(addr [16]byte, scope uint32, port uint16) netip.AddrPort {
-	ip := netaddr.IPFrom16(addr)
+	ip := netip.AddrFrom16(addr).Unmap()
 	if scope != 0 {
 		// TODO: something better here?
 		ip = ip.WithZone(fmt.Sprint(scope))

+ 2 - 2
net/packet/packet.go

@@ -250,8 +250,8 @@ func (q *Parsed) decode6(b []byte) {
 
 	// okay to ignore `ok` here, because IPs pulled from packets are
 	// always well-formed stdlib IPs.
-	srcIP, _ := netaddr.FromStdIP(net.IP(b[8:24]))
-	dstIP, _ := netaddr.FromStdIP(net.IP(b[24:40]))
+	srcIP, _ := netip.AddrFromSlice(net.IP(b[8:24]))
+	dstIP, _ := netip.AddrFromSlice(net.IP(b[24:40]))
 	q.Src = withIP(q.Src, srcIP)
 	q.Dst = withIP(q.Dst, dstIP)
 

+ 1 - 1
net/portmapper/igd_test.go

@@ -214,7 +214,7 @@ func (d *TestIGD) handlePCPQuery(pkt []byte, src netip.AddrPort) {
 	op := pkt[1]
 	pktSrcBytes := [16]byte{}
 	copy(pktSrcBytes[:], pkt[8:24])
-	pktSrc := netaddr.IPFrom16(pktSrcBytes)
+	pktSrc := netip.AddrFrom16(pktSrcBytes).Unmap()
 	if pktSrc != src.Addr() {
 		// TODO this error isn't fatal but should be rejected by server.
 		// Since it's a test it's difficult to get them the same though.

+ 1 - 3
net/portmapper/pcp.go

@@ -11,8 +11,6 @@ import (
 	"fmt"
 	"net/netip"
 	"time"
-
-	"tailscale.com/net/netaddr"
 )
 
 // References:
@@ -126,7 +124,7 @@ func parsePCPMapResponse(resp []byte) (*pcpMapping, error) {
 	externalPort := binary.BigEndian.Uint16(resp[42:44])
 	externalIPBytes := [16]byte{}
 	copy(externalIPBytes[:], resp[44:])
-	externalIP := netaddr.IPFrom16(externalIPBytes)
+	externalIP := netip.AddrFrom16(externalIPBytes).Unmap()
 
 	external := netip.AddrPortFrom(externalIP, externalPort)
 

+ 2 - 1
net/portmapper/portmapper.go

@@ -788,10 +788,11 @@ func (c *Client) Probe(ctx context.Context) (res ProbeResult, err error) {
 			}
 			return res, err
 		}
-		ip, ok := netaddr.FromStdIP(addr.(*net.UDPAddr).IP)
+		ip, ok := netip.AddrFromSlice(addr.(*net.UDPAddr).IP)
 		if !ok {
 			continue
 		}
+		ip = ip.Unmap()
 		port := uint16(addr.(*net.UDPAddr).Port)
 		switch port {
 		case c.upnpPort():

+ 3 - 2
net/portmapper/upnp_test.go

@@ -11,11 +11,11 @@ import (
 	"net"
 	"net/http"
 	"net/http/httptest"
+	"net/netip"
 	"reflect"
 	"regexp"
 	"testing"
 
-	"tailscale.com/net/netaddr"
 	"tailscale.com/tstest"
 )
 
@@ -106,7 +106,8 @@ func TestGetUPnPClient(t *testing.T) {
 				http.NotFound(w, r)
 			}))
 			defer ts.Close()
-			gw, _ := netaddr.FromStdIP(ts.Listener.Addr().(*net.TCPAddr).IP)
+			gw, _ := netip.AddrFromSlice(ts.Listener.Addr().(*net.TCPAddr).IP)
+			gw = gw.Unmap()
 			var logBuf tstest.MemLogger
 			c, err := getUPnPClient(context.Background(), logBuf.Logf, gw, uPnPDiscoResponse{
 				Location: ts.URL + "/rootDesc.xml",

+ 3 - 3
net/tsaddr/tsaddr.go

@@ -126,7 +126,7 @@ func Tailscale4To6(ipv4 netip.Addr) netip.Addr {
 	ret := Tailscale4To6Range().Addr().As16()
 	v4 := ipv4.As4()
 	copy(ret[13:], v4[1:])
-	return netaddr.IPFrom16(ret)
+	return netip.AddrFrom16(ret)
 }
 
 // Tailscale6to4 returns the IPv4 address corresponding to the given
@@ -138,7 +138,7 @@ func Tailscale6to4(ipv6 netip.Addr) (netip.Addr, bool) {
 		return netip.Addr{}, false
 	}
 	v6 := ipv6.As16()
-	return netaddr.IPv4(100, v6[13], v6[14], v6[15]), true
+	return netip.AddrFrom4([4]byte{100, v6[13], v6[14], v6[15]}), true
 }
 
 func mustPrefix(v *netip.Prefix, prefix string) {
@@ -307,5 +307,5 @@ func MapVia(siteID uint32, v4 netip.Prefix) (via netip.Prefix, err error) {
 	binary.BigEndian.PutUint32(a[8:], siteID)
 	ip4a := v4.Addr().As4()
 	copy(a[12:], ip4a[:])
-	return netip.PrefixFrom(netaddr.IPFrom16(a), v4.Bits()+64+32), nil
+	return netip.PrefixFrom(netip.AddrFrom16(a), v4.Bits()+64+32), nil
 }

+ 2 - 3
net/tsdial/tsdial.go

@@ -21,7 +21,6 @@ import (
 
 	"tailscale.com/net/dnscache"
 	"tailscale.com/net/interfaces"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/net/netknob"
 	"tailscale.com/net/netns"
 	"tailscale.com/types/logger"
@@ -250,8 +249,8 @@ func (d *Dialer) userDialResolve(ctx context.Context, network, addr string) (net
 	if len(ips) == 0 {
 		return netip.AddrPort{}, fmt.Errorf("DNS lookup returned no results for %q", host)
 	}
-	ip, _ := netaddr.FromStdIP(ips[0])
-	return netip.AddrPortFrom(ip, port), nil
+	ip, _ := netip.AddrFromSlice(ips[0])
+	return netip.AddrPortFrom(ip.Unmap(), port), nil
 }
 
 // ipNetOfNetwork returns "ip", "ip4", or "ip6" corresponding

+ 2 - 3
ssh/tailssh/tailssh.go

@@ -36,7 +36,6 @@ import (
 	"tailscale.com/envknob"
 	"tailscale.com/ipn/ipnlocal"
 	"tailscale.com/logtail/backoff"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/net/tsaddr"
 	"tailscale.com/syncs"
 	"tailscale.com/tailcfg"
@@ -410,11 +409,11 @@ func toIPPort(a net.Addr) (ipp netip.AddrPort) {
 	if !ok {
 		return
 	}
-	tanetaddr, ok := netaddr.FromStdIP(ta.IP)
+	tanetaddr, ok := netip.AddrFromSlice(ta.IP)
 	if !ok {
 		return
 	}
-	return netip.AddrPortFrom(tanetaddr, uint16(ta.Port))
+	return netip.AddrPortFrom(tanetaddr.Unmap(), uint16(ta.Port))
 }
 
 // connInfo returns a populated sshConnInfo from the provided arguments,

+ 2 - 2
tstest/natlab/natlab.go

@@ -140,7 +140,7 @@ func (n *Network) allocIPv4(iface *Interface) netip.Addr {
 	}
 	a := n.lastV4.As16()
 	addOne(&a, 15)
-	n.lastV4 = netaddr.IPFrom16(a)
+	n.lastV4 = netip.AddrFrom16(a).Unmap()
 	if !n.Prefix4.Contains(n.lastV4) {
 		panic("pool exhausted")
 	}
@@ -159,7 +159,7 @@ func (n *Network) allocIPv6(iface *Interface) netip.Addr {
 	}
 	a := n.lastV6.As16()
 	addOne(&a, 15)
-	n.lastV6 = netaddr.IPFrom16(a)
+	n.lastV6 = netip.AddrFrom16(a).Unmap()
 	if !n.Prefix6.Contains(n.lastV6) {
 		panic("pool exhausted")
 	}

+ 1 - 2
util/deephash/deephash_test.go

@@ -22,7 +22,6 @@ import (
 	"unsafe"
 
 	"go4.org/mem"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/tailcfg"
 	"tailscale.com/types/dnstype"
 	"tailscale.com/types/ipproto"
@@ -192,7 +191,7 @@ func getVal() []any {
 	return []any{
 		&wgcfg.Config{
 			Name:      "foo",
-			Addresses: []netip.Prefix{netip.PrefixFrom(netaddr.IPFrom16([16]byte{3: 3}), 5)},
+			Addresses: []netip.Prefix{netip.PrefixFrom(netip.AddrFrom16([16]byte{3: 3}).Unmap(), 5)},
 			Peers: []wgcfg.Peer{
 				{
 					PublicKey: key.NodePublic{},

+ 1 - 1
wgengine/filter/filter.go

@@ -109,7 +109,7 @@ const (
 // attacks to reach the OS network stack.
 func NewAllowAllForTest(logf logger.Logf) *Filter {
 	any4 := netip.PrefixFrom(netaddr.IPv4(0, 0, 0, 0), 0)
-	any6 := netip.PrefixFrom(netaddr.IPFrom16([16]byte{}), 0)
+	any6 := netip.PrefixFrom(netip.AddrFrom16([16]byte{}), 0)
 	ms := []Match{
 		{
 			IPProto: []ipproto.Proto{ipproto.TCP, ipproto.UDP, ipproto.ICMPv4},

+ 1 - 1
wgengine/filter/tailcfg.go

@@ -97,7 +97,7 @@ func MatchesFromFilterRules(pf []tailcfg.FilterRule) ([]Match, error) {
 
 var (
 	zeroIP4 = netaddr.IPv4(0, 0, 0, 0)
-	zeroIP6 = netaddr.IPFrom16([16]byte{})
+	zeroIP6 = netip.AddrFrom16([16]byte{})
 )
 
 // parseIPSet parses arg as one:

+ 1 - 1
wgengine/magicsock/magicsock.go

@@ -3425,7 +3425,7 @@ func (de *endpoint) initFakeUDPAddr() {
 	addr[0] = 0xfd
 	addr[1] = 0x00
 	binary.BigEndian.PutUint64(addr[2:], uint64(reflect.ValueOf(de).Pointer()))
-	de.fakeWGAddr = netip.AddrPortFrom(netaddr.IPFrom16(addr), 12345)
+	de.fakeWGAddr = netip.AddrPortFrom(netip.AddrFrom16(addr).Unmap(), 12345)
 }
 
 // noteRecvActivity records receive activity on de, and invokes

+ 4 - 5
wgengine/monitor/monitor_linux.go

@@ -16,7 +16,6 @@ import (
 	"github.com/mdlayher/netlink"
 	"golang.org/x/sys/unix"
 	"tailscale.com/envknob"
-	"tailscale.com/net/netaddr"
 	"tailscale.com/net/tsaddr"
 	"tailscale.com/types/logger"
 )
@@ -237,13 +236,13 @@ func (c *nlConn) Receive() (message, error) {
 }
 
 func netaddrIP(std net.IP) netip.Addr {
-	ip, _ := netaddr.FromStdIP(std)
-	return ip
+	ip, _ := netip.AddrFromSlice(std)
+	return ip.Unmap()
 }
 
 func netaddrIPPrefix(std net.IP, bits uint8) netip.Prefix {
-	ip, _ := netaddr.FromStdIP(std)
-	return netip.PrefixFrom(ip, int(bits))
+	ip, _ := netip.AddrFromSlice(std)
+	return netip.PrefixFrom(ip.Unmap(), int(bits))
 }
 
 func condNetAddrPrefix(ipp netip.Prefix) string {

+ 2 - 1
wgengine/monitor/monitor_windows.go

@@ -7,6 +7,7 @@ package monitor
 import (
 	"context"
 	"errors"
+	"net/netip"
 	"strings"
 	"sync"
 	"time"
@@ -132,7 +133,7 @@ func (m *winMon) Receive() (message, error) {
 // unicastAddressChanged is the callback we register with Windows to call when unicast address changes.
 func (m *winMon) unicastAddressChanged(_ winipcfg.MibNotificationType, row *winipcfg.MibUnicastIPAddressRow) {
 	what := "addr"
-	if ip, ok := netaddr.FromStdIP(row.Address.IP()); ok && tsaddr.IsTailscaleIP(ip) {
+	if ip, ok := netip.AddrFromSlice(row.Address.IP()); ok && tsaddr.IsTailscaleIP(ip.Unmap()) {
 		what = "tsaddr"
 	}
 

+ 4 - 3
wgengine/netstack/netstack.go

@@ -218,11 +218,12 @@ func (ns *Impl) SetLocalBackend(lb *ipnlocal.LocalBackend) {
 func (ns *Impl) wrapProtoHandler(h func(stack.TransportEndpointID, *stack.PacketBuffer) bool) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
 	return func(tei stack.TransportEndpointID, pb *stack.PacketBuffer) bool {
 		addr := tei.LocalAddress
-		ip, ok := netaddr.FromStdIP(net.IP(addr))
+		ip, ok := netip.AddrFromSlice(net.IP(addr))
 		if !ok {
 			ns.logf("netstack: could not parse local address for incoming connection")
 			return false
 		}
+		ip = ip.Unmap()
 		if !ns.isLocalIP(ip) {
 			ns.addSubnetAddress(ip)
 		}
@@ -486,7 +487,7 @@ func (ns *Impl) inject() {
 				}
 			case 6:
 				if len(b) >= 40 { // min ipv6 header
-					if srcIP, ok := netaddr.FromStdIP(net.IP(b[8:24])); ok && magicDNSIPv6 == srcIP {
+					if srcIP, ok := netip.AddrFromSlice(net.IP(b[8:24])); ok && magicDNSIPv6 == srcIP {
 						sendToHost = true
 					}
 				}
@@ -710,7 +711,7 @@ func netaddrIPFromNetstackIP(s tcpip.Address) netip.Addr {
 	case 16:
 		var a [16]byte
 		copy(a[:], s)
-		return netaddr.IPFrom16(a)
+		return netip.AddrFrom16(a).Unmap()
 	}
 	return netip.Addr{}
 }