From c0ca7c2253d6b90732b39e699164493eb69c99d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E6=89=87=E6=BB=91=E7=BF=94=E7=BF=BC?= Date: Wed, 13 Nov 2024 20:20:37 +0000 Subject: [PATCH] Wireguard: Fix multi outbounds not work in KernelTun mode --- proxy/wireguard/tun_linux.go | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/proxy/wireguard/tun_linux.go b/proxy/wireguard/tun_linux.go index b8ce6488..7a46138a 100644 --- a/proxy/wireguard/tun_linux.go +++ b/proxy/wireguard/tun_linux.go @@ -4,16 +4,18 @@ package wireguard import ( "context" - "errors" + goerrors "errors" "fmt" "net" "net/netip" "os" + "sync" "golang.org/x/sys/unix" "github.com/sagernet/sing/common/control" "github.com/vishvananda/netlink" + "github.com/xtls/xray-core/common/errors" wgtun "golang.zx2c4.com/wireguard/tun" ) @@ -27,6 +29,23 @@ type deviceNet struct { rules []*netlink.Rule } +var ( + tableIndex int = 10230 + mu sync.Mutex +) + +func allocateIPv6TableIndex() int { + mu.Lock() + defer mu.Unlock() + + if tableIndex > 10230 { + errors.LogInfo(context.Background(), "allocate new ipv6 table index: ", tableIndex) + } + currentIndex := tableIndex + tableIndex++ + return currentIndex +} + func newDeviceNet(interfaceName string) *deviceNet { var dialer net.Dialer bindControl := control.BindToInterface(control.NewDefaultInterfaceFinder(), interfaceName, -1) @@ -68,7 +87,7 @@ func (d *deviceNet) Close() (err error) { if len(errs) == 0 { return nil } - return errors.Join(errs...) + return goerrors.Join(errs...) } func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (t Tunnel, err error) { @@ -138,7 +157,7 @@ func createKernelTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo } } - ipv6TableIndex := 1023 + ipv6TableIndex := allocateIPv6TableIndex() if v6 != nil { r := &netlink.Route{Table: ipv6TableIndex} for {