Skip to content

Commit

Permalink
Improve module load (netbirdio#470)
Browse files Browse the repository at this point in the history
* Add additional check for needed kernel modules

* Check if wireguard and tun modules are loaded

If modules are loaded return true, otherwise attempt to load them

* fix state check

* Add module function tests

* Add test execution in container

* run client package tests on docker

* add package comment to new file

* force entrypoint

* add --privileged flag

* clean only if tables where created

* run from within the directories
  • Loading branch information
mlsmaycon authored Sep 14, 2022
1 parent 1fd5230 commit a90fbba
Show file tree
Hide file tree
Showing 8 changed files with 637 additions and 32 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/golang-test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,55 @@ jobs:

- name: Test
run: GOARCH=${{ matrix.arch }} go test -exec 'sudo --preserve-env=CI' -timeout 5m -p 1 ./...

test_client_on_docker:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.18.x


- name: Cache Go modules
uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Checkout code
uses: actions/checkout@v2

- name: Install dependencies
run: sudo apt update && sudo apt install -y -q libgtk-3-dev libappindicator3-dev libayatana-appindicator3-dev libgl1-mesa-dev xorg-dev

- name: Install modules
run: go mod tidy

- name: Generate Iface Test bin
run: go test -c -o iface-testing.bin ./iface/...

- name: Generate RouteManager Test bin
run: go test -c -o routemanager-testing.bin ./client/internal/routemanager/...

- name: Generate Engine Test bin
run: go test -c -o engine-testing.bin ./client/internal/*.go

- name: Generate Peer Test bin
run: go test -c -o peer-testing.bin ./client/internal/peer/...

- run: chmod +x *testing.bin

- name: Run Iface tests in docker
run: docker run -t --cap-add=NET_ADMIN --privileged --rm -v $PWD:/ci -w /ci/iface --entrypoint /busybox/sh gcr.io/distroless/base:debug -c /ci/iface-testing.bin

- name: Run RouteManager tests in docker
run: docker run -t --cap-add=NET_ADMIN --privileged --rm -v $PWD:/ci -w /ci/client/internal/routemanager --entrypoint /busybox/sh gcr.io/distroless/base:debug -c /ci/routemanager-testing.bin

- name: Run Engine tests in docker
run: docker run -t --cap-add=NET_ADMIN --privileged --rm -v $PWD:/ci -w /ci/client/internal --entrypoint /busybox/sh gcr.io/distroless/base:debug -c /ci/engine-testing.bin

- name: Run Peer tests in docker
run: docker run -t --cap-add=NET_ADMIN --privileged --rm -v $PWD:/ci -w /ci/client/internal/peer --entrypoint /busybox/sh gcr.io/distroless/base:debug -c /ci/peer-testing.bin
2 changes: 1 addition & 1 deletion client/internal/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func RunClient(ctx context.Context, config *Config, statusRecorder *nbStatus.Sta
localPeerState := nbStatus.LocalPeerState{
IP: loginResp.GetPeerConfig().GetAddress(),
PubKey: myPrivateKey.PublicKey().String(),
KernelInterface: iface.WireguardModExists(),
KernelInterface: iface.WireguardModuleIsLoaded(),
}

statusRecorder.UpdateLocalPeerState(localPeerState)
Expand Down
6 changes: 4 additions & 2 deletions client/internal/routemanager/nftables_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ func (n *nftablesManager) CleanRoutingRules() {
n.mux.Lock()
defer n.mux.Unlock()
log.Debug("flushing tables")
n.conn.FlushTable(n.tableIPv6)
n.conn.FlushTable(n.tableIPv4)
if n.tableIPv4 != nil && n.tableIPv6 != nil {
n.conn.FlushTable(n.tableIPv6)
n.conn.FlushTable(n.tableIPv4)
}
log.Debugf("flushing tables result in: %v error", n.conn.Flush())
}

Expand Down
4 changes: 2 additions & 2 deletions iface/iface_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (w *WGIface) assignAddr() error {
return nil
}

// WireguardModExists check if we can load wireguard mod (linux only)
func WireguardModExists() bool {
// WireguardModuleIsLoaded check if we can load wireguard mod (linux only)
func WireguardModuleIsLoaded() bool {
return false
}
31 changes: 6 additions & 25 deletions iface/iface_linux.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,29 @@
package iface

import (
"errors"
"math"
"os"
"syscall"

"fmt"
log "github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"os"
)

type NativeLink struct {
Link *netlink.Link
}

// WireguardModExists check if we can load wireguard mod (linux only)
func WireguardModExists() bool {
link := newWGLink("mustnotexist")

// We willingly try to create a device with an invalid
// MTU here as the validation of the MTU will be performed after
// the validation of the link kind and hence allows us to check
// for the existance of the wireguard module without actually
// creating a link.
//
// As a side-effect, this will also let the kernel lazy-load
// the wireguard module.
link.attrs.MTU = math.MaxInt

err := netlink.LinkAdd(link)

return errors.Is(err, syscall.EINVAL)
}

// Create creates a new Wireguard interface, sets a given IP and brings it up.
// Will reuse an existing one.
func (w *WGIface) Create() error {
w.mu.Lock()
defer w.mu.Unlock()

if WireguardModExists() {
if WireguardModuleIsLoaded() {
log.Info("using kernel WireGuard")
return w.createWithKernel()
} else {
if !tunModuleIsLoaded() {
return fmt.Errorf("couldn't check or load tun module")
}
log.Info("using userspace WireGuard")
return w.createWithUserspace()
}
Expand Down
4 changes: 2 additions & 2 deletions iface/iface_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (w *WGIface) UpdateAddr(newAddr string) error {
return w.assignAddr(luid)
}

// WireguardModExists check if we can load wireguard mod (linux only)
func WireguardModExists() bool {
// WireguardModuleIsLoaded check if we can load wireguard mod (linux only)
func WireguardModuleIsLoaded() bool {
return false
}
Loading

0 comments on commit a90fbba

Please sign in to comment.