diff --git a/listener/listener.go b/listener/listener.go index 79732b66..9671bce9 100644 --- a/listener/listener.go +++ b/listener/listener.go @@ -398,7 +398,10 @@ func Cleanup() { if tunStackListener != nil { _ = tunStackListener.Close() if runtime.GOOS == "android" { - _, _ = cmd.ExecCmd("ip rule del pref 5000") + prefs := []int{9000, 9001, 9002, 9003} + for _, pref := range prefs { + _, _ = cmd.ExecCmd(fmt.Sprintf("ip rule del pref %d", pref)) + } } } } diff --git a/listener/tun/ipstack/commons/router_linux.go b/listener/tun/ipstack/commons/router_linux.go index 34281d86..1259ab75 100644 --- a/listener/tun/ipstack/commons/router_linux.go +++ b/listener/tun/ipstack/commons/router_linux.go @@ -7,6 +7,7 @@ import ( "github.com/Dreamacro/clash/log" "net/netip" "runtime" + "strconv" ) func GetAutoDetectInterface() (string, error) { @@ -39,21 +40,33 @@ func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, } func configInterfaceRouting(interfaceName string, addr netip.Prefix) error { + linkIP := addr.Masked().Addr().Next() if runtime.GOOS == "android" { - tableId := 1981801 + const tableId = 1981801 for _, route := range defaultRoutes { - if _, err := cmd.ExecCmd(fmt.Sprintf("ip route add %s dev %s scope link table %d", route, interfaceName, tableId)); err != nil { + if err := execRouterCmd("add", route, interfaceName, linkIP.String(), strconv.Itoa(tableId)); err != nil { return err } } - _, err := cmd.ExecCmd(fmt.Sprintf("ip rule add lookup %d suppress_prefixlength 0 pref 5000", tableId)) + _, err := cmd.ExecCmd(fmt.Sprintf("ip rule add from 0.0.0.0 iif lo uidrange 0-4294967294 lookup %d pref 9000", tableId)) + if err != nil { + log.Warnln("%s", err) + } + _, err = cmd.ExecCmd(fmt.Sprintf("ip rule add from %s iif lo uidrange 0-4294967294 lookup %d pref 9001", linkIP, tableId)) + if err != nil { + log.Warnln("%s", err) + } + _, err = cmd.ExecCmd(fmt.Sprintf("ip rule add from all iif %s lookup main suppress_prefixlength 0 pref 9002", interfaceName)) + if err != nil { + log.Warnln("%s", err) + } + _, err = cmd.ExecCmd(fmt.Sprintf("ip rule add not from all iif lo lookup %d pref 9003", tableId)) if err != nil { log.Warnln("%s", err) } } else { - linkIP := addr.Masked().Addr().Next() for _, route := range defaultRoutes { - if err := execRouterCmd("add", route, interfaceName, linkIP.String()); err != nil { + if err := execRouterCmd("add", route, interfaceName, linkIP.String(), "main"); err != nil { return err } } @@ -64,8 +77,8 @@ func configInterfaceRouting(interfaceName string, addr netip.Prefix) error { return nil } -func execRouterCmd(action, route string, interfaceName string, linkIP string) error { - cmdStr := fmt.Sprintf("ip route %s %s dev %s proto kernel scope link src %s", action, route, interfaceName, linkIP) +func execRouterCmd(action, route, interfaceName, linkIP, table string) error { + cmdStr := fmt.Sprintf("ip route %s %s dev %s proto kernel scope link src %s table %s", action, route, interfaceName, linkIP, table) _, err := cmd.ExecCmd(cmdStr) return err