Add EXP_ExternalConfiguration for Tailscale

This commit is contained in:
世界 2026-01-07 14:05:47 +08:00
parent a5db80d710
commit 525f783d00
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 66 additions and 19 deletions

1
tun.go
View file

@ -110,6 +110,7 @@ type Options struct {
// For library usages. // For library usages.
EXP_DisableDNSHijack bool EXP_DisableDNSHijack bool
EXP_ExternalConfiguration bool
// For gvisor stack, it should be enabled when MTU is less than 32768; otherwise it should be less than or equal to 8192. // For gvisor stack, it should be enabled when MTU is less than 32768; otherwise it should be less than or equal to 8192.
// The above condition is just an estimate and not exact, calculated on M4 pro. // The above condition is just an estimate and not exact, calculated on M4 pro.

View file

@ -146,11 +146,17 @@ func New(options Options) (Tun, error) {
} }
func (t *NativeTun) Start() error { func (t *NativeTun) Start() error {
if t.options.EXP_ExternalConfiguration {
return nil
}
t.options.InterfaceMonitor.RegisterMyInterface(t.options.Name) t.options.InterfaceMonitor.RegisterMyInterface(t.options.Name)
return t.setRoutes() return t.setRoutes()
} }
func (t *NativeTun) Close() error { func (t *NativeTun) Close() error {
if t.options.EXP_ExternalConfiguration {
return t.tunFile.Close()
}
defer flushDNSCache() defer flushDNSCache()
return E.Errors(t.unsetRoutes(), t.tunFile.Close()) return E.Errors(t.unsetRoutes(), t.tunFile.Close())
} }
@ -232,6 +238,9 @@ func create(tunFd int, ifIndex int, name string, options Options) error {
if err != nil { if err != nil {
return os.NewSyscallError("IoctlSetIfreqMTU", err) return os.NewSyscallError("IoctlSetIfreqMTU", err)
} }
if options.EXP_ExternalConfiguration {
return nil
}
if len(options.Inet4Address) > 0 { if len(options.Inet4Address) > 0 {
for _, address := range options.Inet4Address { for _, address := range options.Inet4Address {
ifReq := ifAliasReq{ ifReq := ifAliasReq{
@ -396,11 +405,14 @@ func (t *NativeTun) TXChecksumOffload() bool {
} }
func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error { func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error {
t.options = tunOptions
if t.options.EXP_ExternalConfiguration {
return nil
}
err := t.unsetRoutes() err := t.unsetRoutes()
if err != nil { if err != nil {
return err return err
} }
t.options = tunOptions
return t.setRoutes() return t.setRoutes()
} }

View file

@ -125,7 +125,7 @@ func (t *NativeTun) configure(tunLink netlink.Link) error {
} else if err != nil { } else if err != nil {
return err return err
} }
if !t.options.EXP_ExternalConfiguration {
if len(t.options.Inet4Address) > 0 { if len(t.options.Inet4Address) > 0 {
for _, address := range t.options.Inet4Address { for _, address := range t.options.Inet4Address {
addr4, _ := netlink.ParseAddr(address.String()) addr4, _ := netlink.ParseAddr(address.String())
@ -144,6 +144,7 @@ func (t *NativeTun) configure(tunLink netlink.Link) error {
} }
} }
} }
}
if t.options.GSO { if t.options.GSO {
err = t.enableGSO() err = t.enableGSO()
@ -257,7 +258,9 @@ func (t *NativeTun) Start() error {
if t.options.FileDescriptor != 0 { if t.options.FileDescriptor != 0 {
return nil return nil
} }
if !t.options.EXP_ExternalConfiguration {
t.options.InterfaceMonitor.RegisterMyInterface(t.options.Name) t.options.InterfaceMonitor.RegisterMyInterface(t.options.Name)
}
tunLink, err := netlink.LinkByName(t.options.Name) tunLink, err := netlink.LinkByName(t.options.Name)
if err != nil { if err != nil {
return err return err
@ -277,6 +280,10 @@ func (t *NativeTun) Start() error {
} }
} }
if t.options.EXP_ExternalConfiguration {
return nil
}
if t.options.IPRoute2TableIndex == 0 { if t.options.IPRoute2TableIndex == 0 {
for { for {
t.options.IPRoute2TableIndex = int(rand.Uint32()) t.options.IPRoute2TableIndex = int(rand.Uint32())
@ -315,6 +322,9 @@ func (t *NativeTun) Close() error {
if t.interfaceCallback != nil { if t.interfaceCallback != nil {
t.options.InterfaceMonitor.UnregisterCallback(t.interfaceCallback) t.options.InterfaceMonitor.UnregisterCallback(t.interfaceCallback)
} }
if t.options.EXP_ExternalConfiguration {
return common.Close(common.PtrOrNil(t.tunFile))
}
return E.Errors(t.unsetRoute(), t.unsetRules(), common.Close(common.PtrOrNil(t.tunFile))) return E.Errors(t.unsetRoute(), t.unsetRules(), common.Close(common.PtrOrNil(t.tunFile)))
} }
@ -476,6 +486,9 @@ func prefixToIPNet(prefix netip.Prefix) *net.IPNet {
func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error { func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error {
if t.options.FileDescriptor > 0 { if t.options.FileDescriptor > 0 {
return nil return nil
} else if t.options.EXP_ExternalConfiguration {
t.options = tunOptions
return nil
} else if !t.options.AutoRoute { } else if !t.options.AutoRoute {
t.options = tunOptions t.options = tunOptions
return nil return nil

View file

@ -65,6 +65,9 @@ func New(options Options) (WinTun, error) {
} }
func (t *NativeTun) configure() error { func (t *NativeTun) configure() error {
if t.options.EXP_ExternalConfiguration {
return nil
}
luid := winipcfg.LUID(t.adapter.LUID()) luid := winipcfg.LUID(t.adapter.LUID())
if len(t.options.Inet4Address) > 0 { if len(t.options.Inet4Address) > 0 {
err := luid.SetIPAddressesForFamily(winipcfg.AddressFamily(windows.AF_INET), t.options.Inet4Address) err := luid.SetIPAddressesForFamily(winipcfg.AddressFamily(windows.AF_INET), t.options.Inet4Address)
@ -162,10 +165,10 @@ func (t *NativeTun) Name() (string, error) {
} }
func (t *NativeTun) Start() error { func (t *NativeTun) Start() error {
t.options.InterfaceMonitor.RegisterMyInterface(t.options.Name) if t.options.EXP_ExternalConfiguration || !t.options.AutoRoute {
if !t.options.AutoRoute {
return nil return nil
} }
t.options.InterfaceMonitor.RegisterMyInterface(t.options.Name)
luid := winipcfg.LUID(t.adapter.LUID()) luid := winipcfg.LUID(t.adapter.LUID())
gateway4, gateway6 := t.options.Inet4GatewayAddr(), t.options.Inet6GatewayAddr() gateway4, gateway6 := t.options.Inet4GatewayAddr(), t.options.Inet6GatewayAddr()
routeRanges, err := t.options.BuildAutoRouteRanges(false) routeRanges, err := t.options.BuildAutoRouteRanges(false)
@ -393,6 +396,21 @@ retry:
} }
} }
func (t *NativeTun) MTU() (int, error) {
return int(t.options.MTU), nil
}
func (t *NativeTun) ForceMTU(mtu int) {
if mtu <= 0 {
return
}
t.options.MTU = uint32(mtu)
}
func (t *NativeTun) LUID() uint64 {
return t.adapter.LUID()
}
func (t *NativeTun) ReadPacket() ([]byte, func(), error) { func (t *NativeTun) ReadPacket() ([]byte, func(), error) {
t.running.Add(1) t.running.Add(1)
retry: retry:
@ -543,6 +561,9 @@ func (t *NativeTun) Close() error {
func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error { func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error {
t.options = tunOptions t.options = tunOptions
if t.options.EXP_ExternalConfiguration {
return nil
}
if !t.options.AutoRoute { if !t.options.AutoRoute {
return nil return nil
} }