mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-26 11:35:35 +00:00
c608660d12
Prepare for path MTU discovery by splitting up the concept of DefaultMTU() into the concepts of the Tailscale TUN MTU, MTUs of underlying network interfaces, minimum "safe" TUN MTU, user configured TUN MTU, probed path MTU to a peer, and maximum probed MTU. Add a set of likely MTUs to probe. Updates #311 Signed-off-by: Val <valerie@tailscale.com>
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
//go:build !wasm && !plan9 && !tamago
|
|
|
|
// Package tun creates a tuntap device, working around OS-specific
|
|
// quirks if necessary.
|
|
package tstun
|
|
|
|
import (
|
|
"errors"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/tailscale/wireguard-go/tun"
|
|
"tailscale.com/types/logger"
|
|
)
|
|
|
|
// createTAP is non-nil on Linux.
|
|
var createTAP func(tapName, bridgeName string) (tun.Device, 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) {
|
|
var dev tun.Device
|
|
var err error
|
|
if strings.HasPrefix(tunName, "tap:") {
|
|
if runtime.GOOS != "linux" {
|
|
return nil, "", errors.New("tap only works on Linux")
|
|
}
|
|
if createTAP == nil { // if the ts_omit_tap tag is used
|
|
return nil, "", errors.New("tap is not supported in this build")
|
|
}
|
|
f := strings.Split(tunName, ":")
|
|
var tapName, bridgeName string
|
|
switch len(f) {
|
|
case 2:
|
|
tapName = f[1]
|
|
case 3:
|
|
tapName, bridgeName = f[1], f[2]
|
|
default:
|
|
return nil, "", errors.New("bogus tap argument")
|
|
}
|
|
dev, err = createTAP(tapName, bridgeName)
|
|
} else {
|
|
dev, err = tun.CreateTUN(tunName, int(DefaultTUNMTU()))
|
|
}
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
if err := waitInterfaceUp(dev, 90*time.Second, logf); err != nil {
|
|
dev.Close()
|
|
return nil, "", err
|
|
}
|
|
if err := setLinkAttrs(dev); err != nil {
|
|
logf("setting link attributes: %v", err)
|
|
}
|
|
name, err := interfaceName(dev)
|
|
if err != nil {
|
|
dev.Close()
|
|
return nil, "", err
|
|
}
|
|
return dev, name, nil
|
|
}
|
|
|
|
// tunDiagnoseFailure, if non-nil, does OS-specific diagnostics of why
|
|
// TUN failed to work.
|
|
var tunDiagnoseFailure func(tunName string, logf logger.Logf, err error)
|
|
|
|
// Diagnose tries to explain a tuntap device creation failure.
|
|
// It pokes around the system and logs some diagnostic info that might
|
|
// help debug why tun creation failed. Because device creation has
|
|
// already failed and the program's about to end, log a lot.
|
|
//
|
|
// The tunName is the name of the tun device that was requested but failed.
|
|
// The err error is how the tun creation failed.
|
|
func Diagnose(logf logger.Logf, tunName string, err error) {
|
|
if tunDiagnoseFailure != nil {
|
|
tunDiagnoseFailure(tunName, logf, err)
|
|
} else {
|
|
logf("no TUN failure diagnostics for OS %q", runtime.GOOS)
|
|
}
|
|
}
|