From 6b95219e3a299be7bb490028aba1efcc0c4f2f9d Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 27 Apr 2024 21:01:54 -0700 Subject: [PATCH] net/netmon, add: add netmon.State type alias of interfaces.State ... in prep for merging the net/interfaces package into net/netmon. This is a no-op change that updates a bunch of the API signatures ahead of a future change to actually move things (and remove the type alias) Updates tailscale/corp#10910 Updates tailscale/corp#18960 Updates #7967 Updates #3299 Change-Id: I477613388f09389214db0d77ccf24a65bff2199c Signed-off-by: Brad Fitzpatrick --- cmd/tailscaled/debug.go | 3 +-- cmd/tailscaled/depaware.txt | 2 +- control/controlclient/direct.go | 3 +-- ipn/ipnlocal/local.go | 4 ++-- ipn/ipnlocal/peerapi.go | 5 +++-- ipn/ipnlocal/peerapi_macios_ext.go | 4 ++-- net/netcheck/netcheck.go | 5 ++--- net/netcheck/netcheck_test.go | 3 +-- net/netmon/netmon.go | 14 +++++++------- net/netmon/state.go | 8 ++++++++ net/netutil/ip_forward.go | 8 ++++---- 11 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 net/netmon/state.go diff --git a/cmd/tailscaled/debug.go b/cmd/tailscaled/debug.go index ba1cac965..b41604d29 100644 --- a/cmd/tailscaled/debug.go +++ b/cmd/tailscaled/debug.go @@ -23,7 +23,6 @@ import ( "tailscale.com/derp/derphttp" "tailscale.com/health" "tailscale.com/ipn" - "tailscale.com/net/interfaces" "tailscale.com/net/netmon" "tailscale.com/net/tshttpproxy" "tailscale.com/tailcfg" @@ -73,7 +72,7 @@ func debugMode(args []string) error { } func runMonitor(ctx context.Context, loop bool) error { - dump := func(st *interfaces.State) { + dump := func(st *netmon.State) { j, _ := json.MarshalIndent(st, "", " ") os.Stderr.Write(j) } diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index 9eb570924..cb5399640 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -295,7 +295,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de tailscale.com/net/dnscache from tailscale.com/control/controlclient+ tailscale.com/net/dnsfallback from tailscale.com/cmd/tailscaled+ tailscale.com/net/flowtrack from tailscale.com/net/packet+ - 💣 tailscale.com/net/interfaces from tailscale.com/cmd/tailscaled+ + 💣 tailscale.com/net/interfaces from tailscale.com/doctor/ethtool+ 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+ diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index 636df148c..edc63cfb4 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -36,7 +36,6 @@ import ( "tailscale.com/logtail" "tailscale.com/net/dnscache" "tailscale.com/net/dnsfallback" - "tailscale.com/net/interfaces" "tailscale.com/net/netmon" "tailscale.com/net/netutil" "tailscale.com/net/tlsdial" @@ -1284,7 +1283,7 @@ var clock tstime.Clock = tstime.StdClock{} // // TODO(bradfitz): Change controlclient.Options.SkipIPForwardingCheck into a // func([]netip.Prefix) error signature instead. -func ipForwardingBroken(routes []netip.Prefix, state *interfaces.State) bool { +func ipForwardingBroken(routes []netip.Prefix, state *netmon.State) bool { warn, err := netutil.CheckIPForwarding(routes, state) if err != nil { // Oh well, we tried. This is just for debugging. diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index aeb180d98..e4ed287fc 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -258,7 +258,7 @@ type LocalBackend struct { authURLTime time.Time // when the authURL was received from the control server interact bool egg bool - prevIfState *interfaces.State + prevIfState *netmon.State peerAPIServer *peerAPIServer // or nil peerAPIListeners []*peerAPIListener loginFlags controlclient.LoginFlags @@ -3066,7 +3066,7 @@ var warnExitNodeUsage = health.NewWarnable(health.WithConnectivityImpact()) // updateExitNodeUsageWarning updates a warnable meant to notify users of // configuration issues that could break exit node usage. -func updateExitNodeUsageWarning(p ipn.PrefsView, state *interfaces.State, health *health.Tracker) { +func updateExitNodeUsageWarning(p ipn.PrefsView, state *netmon.State, health *health.Tracker) { var result error if p.ExitNodeIP().IsValid() || p.ExitNodeID() != "" { warn, _ := netutil.CheckReversePathFiltering(state) diff --git a/ipn/ipnlocal/peerapi.go b/ipn/ipnlocal/peerapi.go index 8fc4d11e6..9a2657034 100644 --- a/ipn/ipnlocal/peerapi.go +++ b/ipn/ipnlocal/peerapi.go @@ -36,6 +36,7 @@ import ( "tailscale.com/ipn" "tailscale.com/net/interfaces" "tailscale.com/net/netaddr" + "tailscale.com/net/netmon" "tailscale.com/net/netutil" "tailscale.com/net/sockstats" "tailscale.com/tailcfg" @@ -51,7 +52,7 @@ const ( taildrivePrefix = "/v0/drive" ) -var initListenConfig func(*net.ListenConfig, netip.Addr, *interfaces.State, string) error +var initListenConfig func(*net.ListenConfig, netip.Addr, *netmon.State, string) error // addH2C is non-nil on platforms where we want to add H2C // ("cleartext" HTTP/2) support to the peerAPI. @@ -69,7 +70,7 @@ type peerAPIServer struct { taildrop *taildrop.Manager } -func (s *peerAPIServer) listen(ip netip.Addr, ifState *interfaces.State) (ln net.Listener, err error) { +func (s *peerAPIServer) listen(ip netip.Addr, ifState *netmon.State) (ln net.Listener, err error) { // Android for whatever reason often has problems creating the peerapi listener. // But since we started intercepting it with netstack, it's not even important that // we have a real kernel-level listener. So just create a dummy listener on Android diff --git a/ipn/ipnlocal/peerapi_macios_ext.go b/ipn/ipnlocal/peerapi_macios_ext.go index c1a09ddf1..15932dfe2 100644 --- a/ipn/ipnlocal/peerapi_macios_ext.go +++ b/ipn/ipnlocal/peerapi_macios_ext.go @@ -10,7 +10,7 @@ import ( "net" "net/netip" - "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" "tailscale.com/net/netns" ) @@ -21,7 +21,7 @@ func init() { // initListenConfigNetworkExtension configures nc for listening on IP // through the iOS/macOS Network/System Extension (Packet Tunnel // Provider) sandbox. -func initListenConfigNetworkExtension(nc *net.ListenConfig, ip netip.Addr, st *interfaces.State, tunIfName string) error { +func initListenConfigNetworkExtension(nc *net.ListenConfig, ip netip.Addr, st *netmon.State, tunIfName string) error { tunIf, ok := st.Interface[tunIfName] if !ok { return fmt.Errorf("no interface with name %q", tunIfName) diff --git a/net/netcheck/netcheck.go b/net/netcheck/netcheck.go index ded2f1efe..a987df6f3 100644 --- a/net/netcheck/netcheck.go +++ b/net/netcheck/netcheck.go @@ -27,7 +27,6 @@ import ( "tailscale.com/derp/derphttp" "tailscale.com/envknob" "tailscale.com/net/dnscache" - "tailscale.com/net/interfaces" "tailscale.com/net/neterror" "tailscale.com/net/netmon" "tailscale.com/net/netns" @@ -389,7 +388,7 @@ const numIncrementalRegions = 3 // makeProbePlan generates the probe plan for a DERPMap, given the most // recent report and whether IPv6 is configured on an interface. -func makeProbePlan(dm *tailcfg.DERPMap, ifState *interfaces.State, last *Report) (plan probePlan) { +func makeProbePlan(dm *tailcfg.DERPMap, ifState *State, last *Report) (plan probePlan) { if last == nil || len(last.RegionLatency) == 0 { return makeProbePlanInitial(dm, ifState) } @@ -469,7 +468,7 @@ func makeProbePlan(dm *tailcfg.DERPMap, ifState *interfaces.State, last *Report) return plan } -func makeProbePlanInitial(dm *tailcfg.DERPMap, ifState *interfaces.State) (plan probePlan) { +func makeProbePlanInitial(dm *tailcfg.DERPMap, ifState *netmon.State) (plan probePlan) { plan = make(probePlan) for _, reg := range dm.Regions { diff --git a/net/netcheck/netcheck_test.go b/net/netcheck/netcheck_test.go index ef0fe24eb..9390f3280 100644 --- a/net/netcheck/netcheck_test.go +++ b/net/netcheck/netcheck_test.go @@ -18,7 +18,6 @@ import ( "testing" "time" - "tailscale.com/net/interfaces" "tailscale.com/net/netmon" "tailscale.com/net/stun" "tailscale.com/net/stun/stuntest" @@ -673,7 +672,7 @@ func TestMakeProbePlan(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ifState := &interfaces.State{ + ifState := &netmon.State{ HaveV6: tt.have6if, HaveV4: !tt.no4, } diff --git a/net/netmon/netmon.go b/net/netmon/netmon.go index f65e3fa7c..0b35bc301 100644 --- a/net/netmon/netmon.go +++ b/net/netmon/netmon.go @@ -64,7 +64,7 @@ type Monitor struct { mu sync.Mutex // guards all following fields cbs set.HandleSet[ChangeFunc] ruleDelCB set.HandleSet[RuleDeleteCallback] - ifState *interfaces.State + ifState *State gwValid bool // whether gw and gwSelfIP are valid gw netip.Addr // our gateway's IP gwSelfIP netip.Addr // our own IP address (that corresponds to gw) @@ -88,12 +88,12 @@ type ChangeDelta struct { // Old is the old interface state, if known. // It's nil if the old state is unknown. // Do not mutate it. - Old *interfaces.State + Old *State // New is the new network state. // It is always non-nil. // Do not mutate it. - New *interfaces.State + New *State // Major is our legacy boolean of whether the network changed in some major // way. @@ -155,13 +155,13 @@ func NewStatic() *Monitor { // interfaces. // // The returned value is owned by Mon; it must not be modified. -func (m *Monitor) InterfaceState() *interfaces.State { +func (m *Monitor) InterfaceState() *State { m.mu.Lock() defer m.mu.Unlock() return m.ifState } -func (m *Monitor) interfaceStateUncached() (*interfaces.State, error) { +func (m *Monitor) interfaceStateUncached() (*State, error) { return interfaces.GetState() } @@ -421,7 +421,7 @@ var ( // up callers and updates the monitor's state if so. // // If forceCallbacks is true, they're always notified. -func (m *Monitor) handlePotentialChange(newState *interfaces.State, forceCallbacks bool) { +func (m *Monitor) handlePotentialChange(newState *State, forceCallbacks bool) { m.mu.Lock() defer m.mu.Unlock() oldState := m.ifState @@ -476,7 +476,7 @@ func (m *Monitor) handlePotentialChange(newState *interfaces.State, forceCallbac // a bunch of connections and rebinding. // // TODO(bradiftz): tigten this definition. -func (m *Monitor) IsMajorChangeFrom(s1, s2 *interfaces.State) bool { +func (m *Monitor) IsMajorChangeFrom(s1, s2 *State) bool { if s1 == nil && s2 == nil { return false } diff --git a/net/netmon/state.go b/net/netmon/state.go new file mode 100644 index 000000000..33d4a3fb3 --- /dev/null +++ b/net/netmon/state.go @@ -0,0 +1,8 @@ +// Copyright (c) Tailscale Inc & AUTHORS +// SPDX-License-Identifier: BSD-3-Clause + +package netmon + +import "tailscale.com/net/interfaces" + +type State = interfaces.State // temporary (2024-04-27) alias during multi-step removal of net/interfaces diff --git a/net/netutil/ip_forward.go b/net/netutil/ip_forward.go index c67a802c8..8575013ae 100644 --- a/net/netutil/ip_forward.go +++ b/net/netutil/ip_forward.go @@ -16,13 +16,13 @@ import ( "strconv" "strings" - "tailscale.com/net/interfaces" + "tailscale.com/net/netmon" ) // protocolsRequiredForForwarding reports whether IPv4 and/or IPv6 protocols are // required to forward the specified routes. // The state param must be specified. -func protocolsRequiredForForwarding(routes []netip.Prefix, state *interfaces.State) (v4, v6 bool) { +func protocolsRequiredForForwarding(routes []netip.Prefix, state *netmon.State) (v4, v6 bool) { if len(routes) == 0 { // Nothing to route, so no need to warn. return false, false @@ -59,7 +59,7 @@ func protocolsRequiredForForwarding(routes []netip.Prefix, state *interfaces.Sta // It returns an error if it is unable to determine if IP forwarding is enabled. // It returns a warning describing configuration issues if IP forwarding is // non-functional or partly functional. -func CheckIPForwarding(routes []netip.Prefix, state *interfaces.State) (warn, err error) { +func CheckIPForwarding(routes []netip.Prefix, state *netmon.State) (warn, err error) { if runtime.GOOS != "linux" { switch runtime.GOOS { case "dragonfly", "freebsd", "netbsd", "openbsd": @@ -152,7 +152,7 @@ func CheckIPForwarding(routes []netip.Prefix, state *interfaces.State) (warn, er // This function returns an error if it is unable to determine whether reverse // path filtering is enabled, or a warning describing configuration issues if // reverse path fitering is non-functional or partly functional. -func CheckReversePathFiltering(state *interfaces.State) (warn []string, err error) { +func CheckReversePathFiltering(state *netmon.State) (warn []string, err error) { if runtime.GOOS != "linux" { return nil, nil }