diff --git a/component/ebpf/ebpf_linux.go b/component/ebpf/ebpf_linux.go index 0fa2e275..712770c6 100644 --- a/component/ebpf/ebpf_linux.go +++ b/component/ebpf/ebpf_linux.go @@ -1,4 +1,4 @@ -//go:build !android && linux +//go:build !android package ebpf diff --git a/config/config.go b/config/config.go index 882a2de8..181a9380 100644 --- a/config/config.go +++ b/config/config.go @@ -119,6 +119,7 @@ type Tun struct { AutoRoute bool `yaml:"auto-route" json:"auto-route"` AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"` TunAddressPrefix netip.Prefix `yaml:"-" json:"-"` + RedirectToTun []string `yaml:"-" json:"-"` } // IPTables config @@ -296,6 +297,10 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) { AutoRoute: false, AutoDetectInterface: false, }, + EBpf: EBpf{ + RedirectToTun: []string{}, + AutoRedir: []string{}, + }, IPTables: IPTables{ Enable: false, InboundInterface: "lo", @@ -967,6 +972,7 @@ func parseTun(rawTun RawTun, general *General, dnsCfg *DNS) (*Tun, error) { AutoRoute: rawTun.AutoRoute, AutoDetectInterface: rawTun.AutoDetectInterface, TunAddressPrefix: tunAddressPrefix, + RedirectToTun: rawTun.RedirectToTun, }, nil } diff --git a/hub/executor/executor.go b/hub/executor/executor.go index d35a9149..a8999e36 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -260,6 +260,7 @@ func loadProxyProvider(proxyProviders map[string]provider.ProxyProvider) { func updateTun(tun *config.Tun) { P.ReCreateTun(tun, tunnel.TCPIn(), tunnel.UDPIn()) + P.ReCreateRedirToTun(tun.RedirectToTun) } func updateSniffer(sniffer *config.Sniffer) { @@ -332,9 +333,9 @@ func updateGeneral(general *config.General, force bool) { P.ReCreateHTTP(general.Port, tcpIn) P.ReCreateSocks(general.SocksPort, tcpIn, udpIn) P.ReCreateRedir(general.RedirPort, tcpIn, udpIn) + P.ReCreateAutoRedir(general.EBpf.AutoRedir, tcpIn, udpIn) P.ReCreateTProxy(general.TProxyPort, tcpIn, udpIn) P.ReCreateMixed(general.MixedPort, tcpIn, udpIn) - P.ReCreateAutoRedir(general.EBpf.AutoRedir, tcpIn, udpIn) } func updateUsers(users []auth.AuthUser) { diff --git a/listener/listener.go b/listener/listener.go index 8184b9cf..debba89d 100644 --- a/listener/listener.go +++ b/listener/listener.go @@ -43,6 +43,7 @@ var ( tunStackListener ipstack.Stack autoRedirListener *autoredir.Listener autoRedirProgram *ebpf.TcEBpfProgram + tcProgram *ebpf.TcEBpfProgram // lock for recreate function socksMux sync.Mutex @@ -363,6 +364,37 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- * lastTunConf = tunConf } +func ReCreateRedirToTun(ifaceNames []string) { + tcMux.Lock() + defer tcMux.Unlock() + + nicArr := ifaceNames + slices.Sort(nicArr) + nicArr = slices.Compact(nicArr) + + if tcProgram != nil { + tcProgram.Close() + tcProgram = nil + } + + if len(nicArr) == 0 { + return + } + + if lastTunConf == nil || !lastTunConf.Enable { + return + } + + program, err := ebpf.NewTcEBpfProgram(nicArr, lastTunConf.Device) + if err != nil { + log.Errorln("Attached tc ebpf program error: %v", err) + return + } + tcProgram = program + + log.Infoln("Attached tc ebpf program to interfaces %v", tcProgram.RawNICs()) +} + func ReCreateAutoRedir(ifaceNames []string, tcpIn chan<- C.ConnContext, _ chan<- *inbound.PacketAdapter) { autoRedirMux.Lock() defer autoRedirMux.Unlock()