From 13e907bbd00c7c51b27bedf2e10bd8b57a31121f Mon Sep 17 00:00:00 2001 From: adlyq Date: Sun, 29 May 2022 15:03:27 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BD=BF=E7=94=A8=20netlink=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20ip=20rule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 4 +- go.sum | 6 +- listener/listener.go | 12 ++-- .../tun/ipstack/commons/router_android.go | 65 +++++++++++++------ 4 files changed, 61 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index e629e7775..cb9e8ea4d 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/oschwald/geoip2-golang v1.7.0 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.1 - github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86 + github.com/vishvananda/netlink v1.2.0-beta.0.20220404152918-5e915e014938 github.com/xtls/go v0.0.0-20210920065950-d4af136d3672 go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.9.0 @@ -60,3 +60,5 @@ require ( ) replace golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 => github.com/MetaCubeX/wintun-go v0.0.0-20220319102620-bbc5e6b2015e + +replace github.com/vishvananda/netlink v1.2.0-beta.0.20220404152918-5e915e014938 => github.com/MetaCubeX/netlink v1.2.0-beta.0.20220428021510-cbf1fc89c622 diff --git a/go.sum b/go.sum index bb38823c0..83bb085bb 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGy github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Dreamacro/go-shadowsocks2 v0.1.8 h1:Ixejp5JscEc866gAvm/l6TFd7BOBvDviKgwb1quWw3g= github.com/Dreamacro/go-shadowsocks2 v0.1.8/go.mod h1:51y4Q6tJoCE7e8TmYXcQRqfoxPfE9Cvn79V6pB6Df7Y= +github.com/MetaCubeX/netlink v1.2.0-beta.0.20220428021510-cbf1fc89c622 h1:Rs71V26e5N/5EEK2p2o2iG763sAjD4lit4ob061Tf9E= +github.com/MetaCubeX/netlink v1.2.0-beta.0.20220428021510-cbf1fc89c622/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/MetaCubeX/wintun-go v0.0.0-20220319102620-bbc5e6b2015e h1:GRfT5Lf8HP7RNczKIwTYLoCh1PPuIs/sY9hj+W+3deg= github.com/MetaCubeX/wintun-go v0.0.0-20220319102620-bbc5e6b2015e/go.mod h1:ARUuShAtcziEJ/vnZ2hgoP+zc0J7Ukcca2S/NPDoQCc= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -202,8 +204,7 @@ github.com/u-root/uio v0.0.0-20220204230159-dac05f7d2cb4 h1:hl6sK6aFgTLISijk6xIz github.com/u-root/uio v0.0.0-20220204230159-dac05f7d2cb4/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86 h1:7SWt9pGCMaw+N1ZhRsaLKaYNviFhxambdoaoYlDqz1w= -github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/xtls/go v0.0.0-20210920065950-d4af136d3672 h1:4mkzGhKqt3JO1BWYjtD3iRFyAx4ow67hmSqOcGjuxqQ= @@ -297,6 +298,7 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/listener/listener.go b/listener/listener.go index 80429dd7b..abedb8422 100644 --- a/listener/listener.go +++ b/listener/listener.go @@ -2,9 +2,9 @@ package proxy import ( "fmt" - "github.com/Dreamacro/clash/common/cmd" "github.com/Dreamacro/clash/listener/inner" "github.com/Dreamacro/clash/listener/tun/ipstack/commons" + "github.com/vishvananda/netlink" "net" "runtime" "sort" @@ -457,9 +457,13 @@ func Cleanup(wait bool) { } if runtime.GOOS == "android" { - prefs := []int{9000, 9001, 9002, 9003, 9004} - for _, pref := range prefs { - _, _ = cmd.ExecCmd(fmt.Sprintf("ip rule del pref %d", pref)) + r := netlink.NewRule() + for i := 0; i < 5; i++ { + r.Priority = 9000 + i*10 + err := netlink.RuleDel(r) + if err != nil { + log.Warnln("[TOUTE] cleanup route rule: %s", err) + } } } } diff --git a/listener/tun/ipstack/commons/router_android.go b/listener/tun/ipstack/commons/router_android.go index 68e90b8e2..8c8c3a347 100644 --- a/listener/tun/ipstack/commons/router_android.go +++ b/listener/tun/ipstack/commons/router_android.go @@ -57,6 +57,7 @@ func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, func configInterfaceRouting(index int, interfaceName string, ip netip.Addr) error { const tableId = 1981801 + var pref = 9000 for _, route := range defaultRoutes { _, ipn, err := net.ParseCIDR(route) @@ -75,25 +76,51 @@ func configInterfaceRouting(index int, interfaceName string, ip netip.Addr) erro return err } } - execAddRuleCmd(fmt.Sprintf("lookup main pref 9000")) - execAddRuleCmd(fmt.Sprintf("from 0.0.0.0 iif lo uidrange 0-4294967294 lookup %d pref 9001", tableId)) - execAddRuleCmd(fmt.Sprintf("from %s iif lo uidrange 0-4294967294 lookup %d pref 9002", ip, tableId)) - execAddRuleCmd(fmt.Sprintf("from all iif %s lookup main suppress_prefixlength 0 pref 9003", interfaceName)) - execAddRuleCmd(fmt.Sprintf("not from all iif lo lookup %d pref 9004", tableId)) + + logIfErr := func(e error) { + if e != nil { + log.Warnln("[TOUTE] config route rule: %s", e) + } + } + + var r *netlink.Rule + r = netlink.NewRule() + r.Table = 254 + r.Priority = pref + logIfErr(netlink.RuleAdd(r)) + pref += 10 + + r = netlink.NewRule() + _, nl, _ := net.ParseCIDR("0.0.0.0/32") + r.Table = tableId + r.Priority = pref + r.Src = nl + r.IifName = "lo" + r.UID = netlink.NewRuleUIDRange(0, 4294967294) + logIfErr(netlink.RuleAdd(r)) + pref += 10 + + _, nl, _ = net.ParseCIDR(ip.String()) + r.Priority = pref + r.Src = nl + logIfErr(netlink.RuleAdd(r)) + pref += 10 + + r = netlink.NewRule() + r.Table = 254 + r.Priority = pref + r.IifName = interfaceName + r.SuppressPrefixlen = 0 + logIfErr(netlink.RuleAdd(r)) + pref += 10 + + r = netlink.NewRule() + r.Table = tableId + r.Priority = pref + r.IifName = "lo" + r.SuppressPrefixlen = 0 + r.Invert = true + logIfErr(netlink.RuleAdd(r)) return nil } - -func execAddRuleCmd(rule string) { - _, err := cmd.ExecCmd("ip rule add " + rule) - if err != nil { - log.Warnln("%s", err) - } -} - -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 -}