Replace the eBPF WireGuard proxy with loopback endpoint addressing

This commit is contained in:
Viktor Liu
2026-08-25 12:27:47 +02:00
parent 7f03a2e86f
commit 2a3b0cec08
23 changed files with 958 additions and 536 deletions

View File

@@ -8,11 +8,13 @@ import (
log "github.com/sirupsen/logrus"
"github.com/netbirdio/netbird/client/iface/wgproxy/ebpf"
"github.com/netbirdio/netbird/client/iface/wgproxy/loopback"
udpProxy "github.com/netbirdio/netbird/client/iface/wgproxy/udp"
)
const (
envDisableKernelWGProxy = "NB_DISABLE_KERNEL_WG_PROXY"
// envDisableEBPFWGProxy is a deprecated alias for envDisableKernelWGProxy.
envDisableEBPFWGProxy = "NB_DISABLE_EBPF_WG_PROXY"
)
@@ -20,7 +22,7 @@ type KernelFactory struct {
wgPort int
mtu uint16
ebpfProxy *ebpf.WGEBPFProxy
loopbackProxy *loopback.Proxy
}
func NewKernelFactory(wgPort int, mtu uint16) *KernelFactory {
@@ -29,55 +31,64 @@ func NewKernelFactory(wgPort int, mtu uint16) *KernelFactory {
mtu: mtu,
}
if isEBPFDisabled() {
if isKernelProxyDisabled() {
log.Infof("WireGuard Proxy Factory will produce UDP proxy")
log.Infof("eBPF WireGuard proxy is disabled via %s environment variable", envDisableEBPFWGProxy)
return f
}
ebpfProxy := ebpf.NewWGEBPFProxy(wgPort, mtu)
if err := ebpfProxy.Listen(); err != nil {
loopbackProxy := loopback.NewProxy(wgPort, mtu)
if err := loopbackProxy.Listen(); err != nil {
log.Infof("WireGuard Proxy Factory will produce UDP proxy")
log.Warnf("failed to initialize ebpf proxy, fallback to user space proxy: %s", err)
log.Warnf("failed to initialize loopback proxy, fallback to user space proxy: %s", err)
return f
}
log.Infof("WireGuard Proxy Factory will produce eBPF proxy")
f.ebpfProxy = ebpfProxy
log.Infof("WireGuard Proxy Factory will produce loopback proxy")
f.loopbackProxy = loopbackProxy
return f
}
func (w *KernelFactory) GetProxy() Proxy {
if w.ebpfProxy == nil {
if w.loopbackProxy == nil {
return udpProxy.NewWGUDPProxy(w.wgPort, w.mtu)
}
return ebpf.NewProxyWrapper(w.ebpfProxy)
return loopback.NewProxyWrapper(w.loopbackProxy)
}
// GetProxyPort returns the eBPF proxy port, or 0 if eBPF is not active.
// GetProxyPort returns the loopback proxy port, or 0 if the kernel proxy is not active.
func (w *KernelFactory) GetProxyPort() uint16 {
if w.ebpfProxy == nil {
if w.loopbackProxy == nil {
return 0
}
return w.ebpfProxy.GetProxyPort()
return w.loopbackProxy.GetProxyPort()
}
func (w *KernelFactory) Free() error {
if w.ebpfProxy == nil {
if w.loopbackProxy == nil {
return nil
}
return w.ebpfProxy.Free()
return w.loopbackProxy.Free()
}
func isEBPFDisabled() bool {
val := os.Getenv(envDisableEBPFWGProxy)
func isKernelProxyDisabled() bool {
env := envDisableKernelWGProxy
val := os.Getenv(env)
if val == "" {
env = envDisableEBPFWGProxy
val = os.Getenv(env)
}
if val == "" {
return false
}
disabled, err := strconv.ParseBool(val)
if err != nil {
log.Warnf("failed to parse %s: %v", envDisableEBPFWGProxy, err)
log.Warnf("failed to parse %s: %v", env, err)
return false
}
if disabled {
log.Infof("kernel WireGuard proxy is disabled via %s", env)
}
return disabled
}