mirror of
https://github.com/tailscale/tailscale.git
synced 2025-07-14 09:38:42 +00:00
all: detect JetKVM and specialize a handful of things for it
Updates #16524 Change-Id: I183428de8c65d7155d82979d2d33f031c22e3331 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
bebc796e6c
commit
fbc6a9ec5a
@ -257,14 +257,13 @@ func main() {
|
||||
// Only apply a default statepath when neither have been provided, so that a
|
||||
// user may specify only --statedir if they wish.
|
||||
if args.statepath == "" && args.statedir == "" {
|
||||
if runtime.GOOS == "plan9" {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to get home directory: %v", err)
|
||||
}
|
||||
args.statedir = filepath.Join(home, "tailscale-state")
|
||||
if err := os.MkdirAll(args.statedir, 0700); err != nil {
|
||||
log.Fatalf("failed to create state directory: %v", err)
|
||||
if paths.MakeAutomaticStateDir() {
|
||||
d := paths.DefaultTailscaledStateDir()
|
||||
if d != "" {
|
||||
args.statedir = d
|
||||
if err := os.MkdirAll(d, 0700); err != nil {
|
||||
log.Fatalf("failed to create state directory: %v", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
args.statepath = paths.DefaultTailscaledStateFile()
|
||||
|
@ -224,6 +224,9 @@ func LogsDir(logf logger.Logf) string {
|
||||
logf("logpolicy: using LocalAppData dir %v", dir)
|
||||
return dir
|
||||
case "linux":
|
||||
if distro.Get() == distro.JetKVM {
|
||||
return "/userdata/tailscale/var"
|
||||
}
|
||||
// STATE_DIRECTORY is set by systemd 240+ but we support older
|
||||
// systems-d. For example, Ubuntu 18.04 (Bionic Beaver) is 237.
|
||||
systemdStateDir := os.Getenv("STATE_DIRECTORY")
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"tailscale.com/types/logger"
|
||||
"tailscale.com/util/clientmetric"
|
||||
"tailscale.com/util/cmpver"
|
||||
"tailscale.com/version/distro"
|
||||
)
|
||||
|
||||
type kv struct {
|
||||
@ -38,6 +39,10 @@ var publishOnce sync.Once
|
||||
//
|
||||
// The health tracker may be nil; the knobs may be nil and are ignored on this platform.
|
||||
func NewOSConfigurator(logf logger.Logf, health *health.Tracker, _ *controlknobs.Knobs, interfaceName string) (ret OSConfigurator, err error) {
|
||||
if distro.Get() == distro.JetKVM {
|
||||
return NewNoopManager()
|
||||
}
|
||||
|
||||
env := newOSConfigEnv{
|
||||
fs: directFS{},
|
||||
dbusPing: dbusPing,
|
||||
|
@ -24,6 +24,9 @@ import (
|
||||
// CrateTAP is the hook set by feature/tap.
|
||||
var CreateTAP feature.Hook[func(logf logger.Logf, tapName, bridgeName string) (tun.Device, error)]
|
||||
|
||||
// modprobeTunHook is a Linux-specific hook to run "/sbin/modprobe tun".
|
||||
var modprobeTunHook feature.Hook[func() error]
|
||||
|
||||
// New returns a tun.Device for the requested device name, along with
|
||||
// the OS-dependent name that was allocated to the device.
|
||||
func New(logf logger.Logf, tunName string) (tun.Device, string, error) {
|
||||
@ -51,7 +54,22 @@ func New(logf logger.Logf, tunName string) (tun.Device, string, error) {
|
||||
if runtime.GOOS == "plan9" {
|
||||
cleanUpPlan9Interfaces()
|
||||
}
|
||||
dev, err = tun.CreateTUN(tunName, int(DefaultTUNMTU()))
|
||||
// Try to create the TUN device up to two times. If it fails
|
||||
// the first time and we're on Linux, try a desperate
|
||||
// "modprobe tun" to load the tun module and try again.
|
||||
for try := range 2 {
|
||||
dev, err = tun.CreateTUN(tunName, int(DefaultTUNMTU()))
|
||||
if err == nil || !modprobeTunHook.IsSet() {
|
||||
if try > 0 {
|
||||
logf("created TUN device %q after doing `modprobe tun`", tunName)
|
||||
}
|
||||
break
|
||||
}
|
||||
if modprobeTunHook.Get()() != nil {
|
||||
// modprobe failed; no point trying again.
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
|
@ -17,6 +17,14 @@ import (
|
||||
|
||||
func init() {
|
||||
tunDiagnoseFailure = diagnoseLinuxTUNFailure
|
||||
modprobeTunHook.Set(func() error {
|
||||
_, err := modprobeTun()
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func modprobeTun() ([]byte, error) {
|
||||
return exec.Command("/sbin/modprobe", "tun").CombinedOutput()
|
||||
}
|
||||
|
||||
func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf, createErr error) {
|
||||
@ -36,7 +44,7 @@ func diagnoseLinuxTUNFailure(tunName string, logf logger.Logf, createErr error)
|
||||
kernel := utsReleaseField(&un)
|
||||
logf("Linux kernel version: %s", kernel)
|
||||
|
||||
modprobeOut, err := exec.Command("/sbin/modprobe", "tun").CombinedOutput()
|
||||
modprobeOut, err := modprobeTun()
|
||||
if err == nil {
|
||||
logf("'modprobe tun' successful")
|
||||
// Either tun is currently loaded, or it's statically
|
||||
|
@ -6,6 +6,7 @@
|
||||
package paths
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@ -70,6 +71,37 @@ func DefaultTailscaledStateFile() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// DefaultTailscaledStateDir returns the default state directory
|
||||
// to use for tailscaled, for use when the user provided neither
|
||||
// a state directory or state file path to use.
|
||||
//
|
||||
// It returns the empty string if there's no reasonable default.
|
||||
func DefaultTailscaledStateDir() string {
|
||||
if runtime.GOOS == "plan9" {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to get home directory: %v", err)
|
||||
}
|
||||
return filepath.Join(home, "tailscale-state")
|
||||
}
|
||||
return filepath.Dir(DefaultTailscaledStateFile())
|
||||
}
|
||||
|
||||
// MakeAutomaticStateDir reports whether the platform
|
||||
// automatically creates the state directory for tailscaled
|
||||
// when it's absent.
|
||||
func MakeAutomaticStateDir() bool {
|
||||
switch runtime.GOOS {
|
||||
case "plan9":
|
||||
return true
|
||||
case "linux":
|
||||
if distro.Get() == distro.JetKVM {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// MkStateDir ensures that dirPath, the daemon's configuration directory
|
||||
// containing machine keys etc, both exists and has the correct permissions.
|
||||
// We want it to only be accessible to the user the daemon is running under.
|
||||
|
@ -21,6 +21,9 @@ func init() {
|
||||
}
|
||||
|
||||
func statePath() string {
|
||||
if runtime.GOOS == "linux" && distro.Get() == distro.JetKVM {
|
||||
return "/userdata/tailscale/var/tailscaled.state"
|
||||
}
|
||||
switch runtime.GOOS {
|
||||
case "linux", "illumos", "solaris":
|
||||
return "/var/lib/tailscale/tailscaled.state"
|
||||
|
@ -23,6 +23,11 @@ func detectFirewallMode(logf logger.Logf, prefHint string) FirewallMode {
|
||||
hostinfo.SetFirewallMode("nft-gokrazy")
|
||||
return FirewallModeNfTables
|
||||
}
|
||||
if distro.Get() == distro.JetKVM {
|
||||
// JetKVM doesn't have iptables.
|
||||
hostinfo.SetFirewallMode("nft-jetkvm")
|
||||
return FirewallModeNfTables
|
||||
}
|
||||
|
||||
mode := envknob.String("TS_DEBUG_FIREWALL_MODE")
|
||||
// If the envknob isn't set, fall back to the pref suggested by c2n or
|
||||
|
@ -688,8 +688,9 @@ func (i *iptablesRunner) DelMagicsockPortRule(port uint16, network string) error
|
||||
// IPTablesCleanUp removes all Tailscale added iptables rules.
|
||||
// Any errors that occur are logged to the provided logf.
|
||||
func IPTablesCleanUp(logf logger.Logf) {
|
||||
if distro.Get() == distro.Gokrazy {
|
||||
// Gokrazy uses nftables and doesn't have the "iptables" command.
|
||||
switch distro.Get() {
|
||||
case distro.Gokrazy, distro.JetKVM:
|
||||
// These use nftables and don't have the "iptables" command.
|
||||
// Avoid log spam on cleanup. (#12277)
|
||||
return
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ const (
|
||||
Unraid = Distro("unraid")
|
||||
Alpine = Distro("alpine")
|
||||
UBNT = Distro("ubnt") // Ubiquiti Networks
|
||||
JetKVM = Distro("jetkvm")
|
||||
)
|
||||
|
||||
var distro lazy.SyncValue[Distro]
|
||||
@ -102,6 +103,8 @@ func linuxDistro() Distro {
|
||||
return Unraid
|
||||
case have("/etc/alpine-release"):
|
||||
return Alpine
|
||||
case haveDir("/userdata/jetkvm") && haveDir("/sys/kernel/config/usb_gadget/jetkvm"):
|
||||
return JetKVM
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user