From 1c84d6b3b6df733111f4d20b57e8c3ce674be437 Mon Sep 17 00:00:00 2001 From: Zoltan Papp Date: Wed, 16 Aug 2023 15:25:14 +0200 Subject: [PATCH] Avoid ebpf lib usage on non Linux --- client/internal/dns/service_listener.go | 6 +++--- .../ebpf/{dns_fwd.go => dns_fwd_linux.go} | 6 ++++-- client/internal/ebpf/manager.go | 8 ++++++++ .../ebpf/{loader.go => manager_linux.go} | 20 ++++++++++--------- .../{loader_test.go => manager_linux_test.go} | 4 ++-- client/internal/ebpf/manager_nonlinux.go | 8 ++++++++ .../ebpf/{wg_proxy.go => wg_proxy_linux.go} | 6 ++++-- client/internal/wgproxy/proxy_ebpf.go | 2 +- 8 files changed, 41 insertions(+), 19 deletions(-) rename client/internal/ebpf/{dns_fwd.go => dns_fwd_linux.go} (86%) create mode 100644 client/internal/ebpf/manager.go rename client/internal/ebpf/{loader.go => manager_linux.go} (79%) rename client/internal/ebpf/{loader_test.go => manager_linux_test.go} (94%) create mode 100644 client/internal/ebpf/manager_nonlinux.go rename client/internal/ebpf/{wg_proxy.go => wg_proxy_linux.go} (83%) diff --git a/client/internal/dns/service_listener.go b/client/internal/dns/service_listener.go index cc9eb3e00..d9997d543 100644 --- a/client/internal/dns/service_listener.go +++ b/client/internal/dns/service_listener.go @@ -30,7 +30,7 @@ type serviceViaListener struct { listenPort int listenerIsRunning bool listenerFlagLock sync.Mutex - ebpfService *ebpf.Manager + ebpfService ebpf.Manager } func newServiceViaListener(wgIface WGIface, customAddr *netip.AddrPort) *serviceViaListener { @@ -59,7 +59,7 @@ func (s *serviceViaListener) Listen() error { } var err error - s.listenIP, s.listenPort, err = s.evalRuntimeAddress() + s.listenIP, s.listenPort, err = s.evalListenAddress() if err != nil { log.Errorf("failed to eval runtime address: %s", err) return err @@ -163,7 +163,7 @@ func (s *serviceViaListener) getFirstListenerAvailable() (string, int, error) { return "", 0, fmt.Errorf("unable to find an unused ip and port combination. IPs tested: %v and ports %v", ips, ports) } -func (s *serviceViaListener) evalRuntimeAddress() (string, int, error) { +func (s *serviceViaListener) evalListenAddress() (string, int, error) { if s.customAddr != nil { return s.customAddr.Addr().String(), int(s.customAddr.Port()), nil } diff --git a/client/internal/ebpf/dns_fwd.go b/client/internal/ebpf/dns_fwd_linux.go similarity index 86% rename from client/internal/ebpf/dns_fwd.go rename to client/internal/ebpf/dns_fwd_linux.go index c534ab953..e3ea6a4af 100644 --- a/client/internal/ebpf/dns_fwd.go +++ b/client/internal/ebpf/dns_fwd_linux.go @@ -1,3 +1,5 @@ +//go:build !android + package ebpf import ( @@ -12,7 +14,7 @@ const ( mapKeyDNSPort uint32 = 1 ) -func (tf *Manager) LoadDNSFwd(ip string, dnsPort int) error { +func (tf *GeneralManager) LoadDNSFwd(ip string, dnsPort int) error { log.Debugf("load ebpf DNS forwarder: address: %s:%d", ip, dnsPort) tf.lock.Lock() defer tf.lock.Unlock() @@ -40,7 +42,7 @@ func (tf *Manager) LoadDNSFwd(ip string, dnsPort int) error { return nil } -func (tf *Manager) FreeDNSFwd() error { +func (tf *GeneralManager) FreeDNSFwd() error { log.Debugf("free ebpf DNS forwarder") return tf.unsetFeatureFlag(featureFlagDnsForwarder) } diff --git a/client/internal/ebpf/manager.go b/client/internal/ebpf/manager.go new file mode 100644 index 000000000..95c2fdc28 --- /dev/null +++ b/client/internal/ebpf/manager.go @@ -0,0 +1,8 @@ +package ebpf + +type Manager interface { + LoadDNSFwd(ip string, dnsPort int) error + FreeDNSFwd() error + LoadWgProxy(proxyPort, wgPort int) error + FreeWGProxy() error +} diff --git a/client/internal/ebpf/loader.go b/client/internal/ebpf/manager_linux.go similarity index 79% rename from client/internal/ebpf/loader.go rename to client/internal/ebpf/manager_linux.go index d96ae4795..b1d986f20 100644 --- a/client/internal/ebpf/loader.go +++ b/client/internal/ebpf/manager_linux.go @@ -1,3 +1,5 @@ +//go:build !android + package ebpf import ( @@ -18,14 +20,14 @@ const ( ) var ( - singleton *Manager + singleton Manager singletonLock = &sync.Mutex{} ) -// libbpf-dev, libc6-dev-i386-amd64-cross +// required packages libbpf-dev, libc6-dev-i386-amd64-cross //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang-14 bpf src/prog.c -- -I /usr/x86_64-linux-gnu/include -type Manager struct { +type GeneralManager struct { lock sync.Mutex link link.Link featureFlags uint16 @@ -33,21 +35,21 @@ type Manager struct { } // GetEbpfManagerInstance return a static eBpf Manager instance -func GetEbpfManagerInstance() *Manager { +func GetEbpfManagerInstance() Manager { singletonLock.Lock() defer singletonLock.Unlock() if singleton != nil { return singleton } - singleton = &Manager{} + singleton = &GeneralManager{} return singleton } -func (tf *Manager) setFeatureFlag(feature uint16) { +func (tf *GeneralManager) setFeatureFlag(feature uint16) { tf.featureFlags = tf.featureFlags | feature } -func (tf *Manager) loadXdp() error { +func (tf *GeneralManager) loadXdp() error { if tf.link != nil { return nil } @@ -75,7 +77,7 @@ func (tf *Manager) loadXdp() error { return err } -func (tf *Manager) unsetFeatureFlag(feature uint16) error { +func (tf *GeneralManager) unsetFeatureFlag(feature uint16) error { tf.lock.Lock() defer tf.lock.Unlock() tf.featureFlags &^= feature @@ -91,7 +93,7 @@ func (tf *Manager) unsetFeatureFlag(feature uint16) error { return tf.bpfObjs.NbFeatures.Put(mapKeyFeatures, tf.featureFlags) } -func (tf *Manager) close() error { +func (tf *GeneralManager) close() error { log.Debugf("detach ebpf program ") err := tf.bpfObjs.Close() if err != nil { diff --git a/client/internal/ebpf/loader_test.go b/client/internal/ebpf/manager_linux_test.go similarity index 94% rename from client/internal/ebpf/loader_test.go rename to client/internal/ebpf/manager_linux_test.go index b63a9b6f8..956499e5b 100644 --- a/client/internal/ebpf/loader_test.go +++ b/client/internal/ebpf/manager_linux_test.go @@ -5,7 +5,7 @@ import ( ) func TestManager_setFeatureFlag(t *testing.T) { - mgr := Manager{} + mgr := GeneralManager{} mgr.setFeatureFlag(featureFlagWGProxy) if mgr.featureFlags != 1 { t.Errorf("invalid faeture state") @@ -18,7 +18,7 @@ func TestManager_setFeatureFlag(t *testing.T) { } func TestManager_unsetFeatureFlag(t *testing.T) { - mgr := Manager{} + mgr := GeneralManager{} mgr.setFeatureFlag(featureFlagWGProxy) mgr.setFeatureFlag(featureFlagDnsForwarder) diff --git a/client/internal/ebpf/manager_nonlinux.go b/client/internal/ebpf/manager_nonlinux.go new file mode 100644 index 000000000..d38b27cbb --- /dev/null +++ b/client/internal/ebpf/manager_nonlinux.go @@ -0,0 +1,8 @@ +//go:build !linux || android + +package ebpf + +// GetEbpfManagerInstance return error because ebpf is not supported on all os +func GetEbpfManagerInstance() Manager { + panic("unsupported os") +} diff --git a/client/internal/ebpf/wg_proxy.go b/client/internal/ebpf/wg_proxy_linux.go similarity index 83% rename from client/internal/ebpf/wg_proxy.go rename to client/internal/ebpf/wg_proxy_linux.go index 242cfa0e7..bdaa3da06 100644 --- a/client/internal/ebpf/wg_proxy.go +++ b/client/internal/ebpf/wg_proxy_linux.go @@ -1,3 +1,5 @@ +//go:build !android + package ebpf import log "github.com/sirupsen/logrus" @@ -7,7 +9,7 @@ const ( mapKeyWgPort uint32 = 1 ) -func (tf *Manager) LoadWgProxy(proxyPort, wgPort int) error { +func (tf *GeneralManager) LoadWgProxy(proxyPort, wgPort int) error { log.Debugf("load ebpf WG proxy") tf.lock.Lock() defer tf.lock.Unlock() @@ -35,7 +37,7 @@ func (tf *Manager) LoadWgProxy(proxyPort, wgPort int) error { return nil } -func (tf *Manager) FreeWGProxy() error { +func (tf *GeneralManager) FreeWGProxy() error { log.Debugf("free ebpf WG proxy") return tf.unsetFeatureFlag(featureFlagWGProxy) } diff --git a/client/internal/wgproxy/proxy_ebpf.go b/client/internal/wgproxy/proxy_ebpf.go index 4d3e199de..906ac76d3 100644 --- a/client/internal/wgproxy/proxy_ebpf.go +++ b/client/internal/wgproxy/proxy_ebpf.go @@ -19,7 +19,7 @@ import ( // WGEBPFProxy definition for proxy with EBPF support type WGEBPFProxy struct { - ebpfManager *ebpf.Manager + ebpfManager ebpf.Manager lastUsedPort uint16 localWGListenPort int