mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-10 04:30:20 +02:00
fix(wireguard): fix detection of kernelspace wireguard
This commit is contained in:
+1
-1
@@ -549,7 +549,7 @@ type netLinker interface {
|
|||||||
Router
|
Router
|
||||||
Ruler
|
Ruler
|
||||||
Linker
|
Linker
|
||||||
IsWireguardSupported() (ok bool, err error)
|
IsWireguardSupported() bool
|
||||||
IsIPv6Supported() (ok bool, err error)
|
IsIPv6Supported() (ok bool, err error)
|
||||||
PatchLoggerLevel(level log.Level)
|
PatchLoggerLevel(level log.Level)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
package netlink
|
package netlink
|
||||||
|
|
||||||
import "net/netip"
|
import (
|
||||||
|
"net/netip"
|
||||||
|
|
||||||
|
"github.com/qdm12/log"
|
||||||
|
)
|
||||||
|
|
||||||
func makeNetipPrefix(n byte) netip.Prefix {
|
func makeNetipPrefix(n byte) netip.Prefix {
|
||||||
const bits = 24
|
const bits = 24
|
||||||
return netip.PrefixFrom(netip.AddrFrom4([4]byte{n, n, n, 0}), bits)
|
return netip.PrefixFrom(netip.AddrFrom4([4]byte{n, n, n, 0}), bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type noopLogger struct{}
|
||||||
|
|
||||||
|
func (l *noopLogger) Debug(_ string) {}
|
||||||
|
func (l *noopLogger) Debugf(_ string, _ ...any) {}
|
||||||
|
func (l *noopLogger) Patch(_ ...log.Option) {}
|
||||||
|
|||||||
@@ -3,52 +3,35 @@
|
|||||||
package netlink
|
package netlink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/qdm12/gluetun/internal/mod"
|
"github.com/qdm12/gluetun/internal/mod"
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *NetLink) IsWireguardSupported() (ok bool, err error) {
|
func (n *NetLink) IsWireguardSupported() bool {
|
||||||
// Check for Wireguard family without loading the wireguard module.
|
// Check for Wireguard family without loading the wireguard module.
|
||||||
// Some kernels have the wireguard module built-in, and don't have a
|
// Some kernels have the wireguard module built-in, and don't have a
|
||||||
// modules directory, such as WSL2 kernels.
|
// modules directory, such as WSL2 kernels.
|
||||||
ok, err = hasWireguardFamily()
|
ok := hasWireguardFamily()
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("checking for wireguard family: %w", err)
|
|
||||||
}
|
|
||||||
if ok {
|
if ok {
|
||||||
return true, nil
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try loading the wireguard module, since some systems do not load
|
// Try loading the wireguard module, since some systems do not load
|
||||||
// it after a boot. If this fails, wireguard is assumed to not be supported.
|
// it after a boot. If this fails, wireguard is assumed to not be supported.
|
||||||
n.debugLogger.Debugf("wireguard family not found, trying to load wireguard kernel module")
|
n.debugLogger.Debugf("wireguard family not found, trying to load wireguard kernel module")
|
||||||
err = mod.Probe("wireguard")
|
err := mod.Probe("wireguard")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.debugLogger.Debugf("failed loading wireguard kernel module: %s", err)
|
n.debugLogger.Debugf("failed loading wireguard kernel module: %s", err)
|
||||||
return false, nil
|
return false
|
||||||
}
|
}
|
||||||
n.debugLogger.Debugf("wireguard kernel module loaded successfully")
|
n.debugLogger.Debugf("wireguard kernel module loaded successfully")
|
||||||
|
|
||||||
// Re-check if the Wireguard family is now available, after loading
|
// Re-check if the Wireguard family is now available, after loading
|
||||||
// the wireguard kernel module.
|
// the wireguard kernel module.
|
||||||
ok, err = hasWireguardFamily()
|
return hasWireguardFamily()
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("checking for wireguard family: %w", err)
|
|
||||||
}
|
|
||||||
return ok, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasWireguardFamily() (ok bool, err error) {
|
func hasWireguardFamily() bool {
|
||||||
families, err := netlink.GenlFamilyList()
|
_, err := netlink.GenlFamilyGet("wireguard")
|
||||||
if err != nil {
|
return err == nil
|
||||||
return false, fmt.Errorf("listing gen 1 families: %w", err)
|
|
||||||
}
|
|
||||||
for _, family := range families {
|
|
||||||
if family.Name == "wireguard" {
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,15 @@ package netlink
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_NetLink_IsWireguardSupported(t *testing.T) {
|
func Test_NetLink_IsWireguardSupported(t *testing.T) {
|
||||||
t.Skip() // TODO unskip once the data race problem with netlink.GenlFamilyList() is fixed
|
|
||||||
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
netLink := &NetLink{}
|
|
||||||
ok, err := netLink.IsWireguardSupported()
|
netLink := &NetLink{
|
||||||
require.NoError(t, err)
|
debugLogger: &noopLogger{},
|
||||||
|
}
|
||||||
|
ok := netLink.IsWireguardSupported()
|
||||||
if ok { // cannot assert since this depends on kernel
|
if ok { // cannot assert since this depends on kernel
|
||||||
t.Log("wireguard is supported")
|
t.Log("wireguard is supported")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -63,21 +63,6 @@ func (mr *MockNetLinkerMockRecorder) AddrReplace(arg0, arg1 interface{}) *gomock
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrReplace", reflect.TypeOf((*MockNetLinker)(nil).AddrReplace), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrReplace", reflect.TypeOf((*MockNetLinker)(nil).AddrReplace), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsWireguardSupported mocks base method.
|
|
||||||
func (m *MockNetLinker) IsWireguardSupported() (bool, error) {
|
|
||||||
m.ctrl.T.Helper()
|
|
||||||
ret := m.ctrl.Call(m, "IsWireguardSupported")
|
|
||||||
ret0, _ := ret[0].(bool)
|
|
||||||
ret1, _ := ret[1].(error)
|
|
||||||
return ret0, ret1
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsWireguardSupported indicates an expected call of IsWireguardSupported.
|
|
||||||
func (mr *MockNetLinkerMockRecorder) IsWireguardSupported() *gomock.Call {
|
|
||||||
mr.mock.ctrl.T.Helper()
|
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsWireguardSupported", reflect.TypeOf((*MockNetLinker)(nil).IsWireguardSupported))
|
|
||||||
}
|
|
||||||
|
|
||||||
// LinkAdd mocks base method.
|
// LinkAdd mocks base method.
|
||||||
func (m *MockNetLinker) LinkAdd(arg0 netlink.Link) (int, error) {
|
func (m *MockNetLinker) LinkAdd(arg0 netlink.Link) (int, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ type NetLinker interface {
|
|||||||
Router
|
Router
|
||||||
Ruler
|
Ruler
|
||||||
Linker
|
Linker
|
||||||
IsWireguardSupported() (ok bool, err error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Addresser interface {
|
type Addresser interface {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ type NetLinker interface {
|
|||||||
Router
|
Router
|
||||||
Ruler
|
Ruler
|
||||||
Linker
|
Linker
|
||||||
IsWireguardSupported() (ok bool, err error)
|
IsWireguardSupported() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Router interface {
|
type Router interface {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ type NetLinker interface {
|
|||||||
Router
|
Router
|
||||||
Ruler
|
Ruler
|
||||||
Linker
|
Linker
|
||||||
IsWireguardSupported() (ok bool, err error)
|
IsWireguardSupported() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Router interface {
|
type Router interface {
|
||||||
|
|||||||
@@ -49,12 +49,11 @@ func (mr *MockNetLinkerMockRecorder) AddrReplace(arg0, arg1 interface{}) *gomock
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsWireguardSupported mocks base method.
|
// IsWireguardSupported mocks base method.
|
||||||
func (m *MockNetLinker) IsWireguardSupported() (bool, error) {
|
func (m *MockNetLinker) IsWireguardSupported() bool {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "IsWireguardSupported")
|
ret := m.ctrl.Call(m, "IsWireguardSupported")
|
||||||
ret0, _ := ret[0].(bool)
|
ret0, _ := ret[0].(bool)
|
||||||
ret1, _ := ret[1].(error)
|
return ret0
|
||||||
return ret0, ret1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsWireguardSupported indicates an expected call of IsWireguardSupported.
|
// IsWireguardSupported indicates an expected call of IsWireguardSupported.
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrDetectKernel = errors.New("cannot detect Kernel support")
|
|
||||||
ErrCreateTun = errors.New("cannot create TUN device")
|
ErrCreateTun = errors.New("cannot create TUN device")
|
||||||
ErrAddLink = errors.New("cannot add Wireguard link")
|
ErrAddLink = errors.New("cannot add Wireguard link")
|
||||||
ErrFindLink = errors.New("cannot find link")
|
ErrFindLink = errors.New("cannot find link")
|
||||||
@@ -35,11 +34,7 @@ var (
|
|||||||
|
|
||||||
// See https://git.zx2c4.com/wireguard-go/tree/main.go
|
// See https://git.zx2c4.com/wireguard-go/tree/main.go
|
||||||
func (w *Wireguard) Run(ctx context.Context, waitError chan<- error, ready chan<- struct{}) {
|
func (w *Wireguard) Run(ctx context.Context, waitError chan<- error, ready chan<- struct{}) {
|
||||||
kernelSupported, err := w.netlink.IsWireguardSupported()
|
kernelSupported := w.netlink.IsWireguardSupported()
|
||||||
if err != nil {
|
|
||||||
waitError <- fmt.Errorf("%w: %s", ErrDetectKernel, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setupFunction := setupUserSpace
|
setupFunction := setupUserSpace
|
||||||
switch w.settings.Implementation {
|
switch w.settings.Implementation {
|
||||||
|
|||||||
Reference in New Issue
Block a user