Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build for openbsd #812

Merged
merged 3 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name: Create release and upload binaries

jobs:
build-linux:
name: Build Linux All
name: Build Linux/BSD All
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand All @@ -19,7 +19,7 @@ jobs:

- name: Build
run: |
make BUILD_NUMBER="${GITHUB_REF#refs/tags/v}" release-linux release-freebsd
make BUILD_NUMBER="${GITHUB_REF#refs/tags/v}" release-linux release-freebsd release-openbsd release-netbsd
mkdir release
mv build/*.tar.gz release

Expand Down
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,20 @@ ALL_LINUX = linux-amd64 \
ALL_FREEBSD = freebsd-amd64 \
freebsd-arm64

ALL_OPENBSD = openbsd-amd64 \
openbsd-arm64

ALL_NETBSD = netbsd-amd64 \
netbsd-arm64

ALL = $(ALL_LINUX) \
$(ALL_FREEBSD) \
$(ALL_OPENBSD) \
$(ALL_NETBSD) \
darwin-amd64 \
darwin-arm64 \
windows-amd64 \
windows-arm64 \
netbsd-amd64
windows-arm64

e2e:
$(TEST_ENV) go test -tags=e2e_testing -count=1 $(TEST_FLAGS) ./e2e
Expand Down Expand Up @@ -83,6 +90,10 @@ release-linux: $(ALL_LINUX:%=build/nebula-%.tar.gz)

release-freebsd: $(ALL_FREEBSD:%=build/nebula-%.tar.gz)

release-openbsd: $(ALL_OPENBSD:%=build/nebula-%.tar.gz)

release-netbsd: $(ALL_NETBSD:%=build/nebula-%.tar.gz)

release-boringcrypto: build/nebula-linux-$(shell go env GOARCH)-boringcrypto.tar.gz

BUILD_ARGS = -trimpath
Expand Down
22 changes: 14 additions & 8 deletions overlay/tun_netbsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,21 @@ func (t *tun) Activate() error {
var err error

// TODO use syscalls instead of exec.Command
t.l.Debug("command: ifconfig", t.Device, t.cidr.String(), t.cidr.IP.String())
if err = exec.Command("/sbin/ifconfig", t.Device, t.cidr.String(), t.cidr.IP.String()).Run(); err != nil {
cmd := exec.Command("/sbin/ifconfig", t.Device, t.cidr.String(), t.cidr.IP.String())
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'ifconfig': %s", err)
}
t.l.Debug("command: route", "-n", "add", "-net", t.cidr.String(), t.cidr.IP.String())
if err = exec.Command("/sbin/route", "-n", "add", "-net", t.cidr.String(), t.cidr.IP.String()).Run(); err != nil {

cmd = exec.Command("/sbin/route", "-n", "add", "-net", t.cidr.String(), t.cidr.IP.String())
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'route add': %s", err)
}
t.l.Debug("command: ifconfig", t.Device, "mtu", strconv.Itoa(t.MTU))
if err = exec.Command("/sbin/ifconfig", t.Device, "mtu", strconv.Itoa(t.MTU)).Run(); err != nil {

cmd = exec.Command("/sbin/ifconfig", t.Device, "mtu", strconv.Itoa(t.MTU))
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'ifconfig': %s", err)
}
// Unsafe path routes
Expand All @@ -118,8 +123,9 @@ func (t *tun) Activate() error {
continue
}

t.l.Debug("command: route", "-n", "add", "-net", r.Cidr.String(), t.cidr.IP.String())
if err = exec.Command("/sbin/route", "-n", "add", "-net", r.Cidr.String(), t.cidr.IP.String()).Run(); err != nil {
cmd = exec.Command("/sbin/route", "-n", "add", "-net", r.Cidr.String(), t.cidr.IP.String())
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'route add' for unsafe_route %s: %s", r.Cidr.String(), err)
}
}
Expand Down
174 changes: 174 additions & 0 deletions overlay/tun_openbsd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
//go:build !e2e_testing
// +build !e2e_testing

package overlay

import (
"fmt"
"io"
"net"
"os"
"os/exec"
"regexp"
"strconv"
"syscall"

"github.com/sirupsen/logrus"
"github.com/slackhq/nebula/cidr"
"github.com/slackhq/nebula/iputil"
)

type tun struct {
Device string
cidr *net.IPNet
MTU int
Routes []Route
routeTree *cidr.Tree4
l *logrus.Logger

io.ReadWriteCloser

// cache out buffer since we need to prepend 4 bytes for tun metadata
out []byte
}

func (t *tun) Close() error {
if t.ReadWriteCloser != nil {
return t.ReadWriteCloser.Close()
}

return nil
}

func newTunFromFd(_ *logrus.Logger, _ int, _ *net.IPNet, _ int, _ []Route, _ int, _ bool) (*tun, error) {
return nil, fmt.Errorf("newTunFromFd not supported in OpenBSD")
}

var deviceNameRE = regexp.MustCompile(`^tun[0-9]+$`)

func newTun(l *logrus.Logger, deviceName string, cidr *net.IPNet, defaultMTU int, routes []Route, _ int, _ bool, _ bool) (*tun, error) {
if deviceName == "" {
return nil, fmt.Errorf("a device name in the format of tunN must be specified")
}

if !deviceNameRE.MatchString(deviceName) {
return nil, fmt.Errorf("a device name in the format of tunN must be specified")
}

file, err := os.OpenFile("/dev/"+deviceName, os.O_RDWR, 0)
if err != nil {
return nil, err
}

routeTree, err := makeRouteTree(l, routes, false)
if err != nil {
return nil, err
}

return &tun{
ReadWriteCloser: file,
Device: deviceName,
cidr: cidr,
MTU: defaultMTU,
Routes: routes,
routeTree: routeTree,
l: l,
}, nil
}

func (t *tun) Activate() error {
var err error
// TODO use syscalls instead of exec.Command
cmd := exec.Command("/sbin/ifconfig", t.Device, t.cidr.String(), t.cidr.IP.String())
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'ifconfig': %s", err)
}

cmd = exec.Command("/sbin/ifconfig", t.Device, "mtu", strconv.Itoa(t.MTU))
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'ifconfig': %s", err)
}

cmd = exec.Command("/sbin/route", "-n", "add", "-inet", t.cidr.String(), t.cidr.IP.String())
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'route add': %s", err)
}

// Unsafe path routes
for _, r := range t.Routes {
if r.Via == nil || !r.Install {
// We don't allow route MTUs so only install routes with a via
continue
}

cmd = exec.Command("/sbin/route", "-n", "add", "-inet", r.Cidr.String(), t.cidr.IP.String())
t.l.Debug("command: ", cmd.String())
if err = cmd.Run(); err != nil {
return fmt.Errorf("failed to run 'route add' for unsafe_route %s: %s", r.Cidr.String(), err)
}
}

return nil
}

func (t *tun) RouteFor(ip iputil.VpnIp) iputil.VpnIp {
r := t.routeTree.MostSpecificContains(ip)
if r != nil {
return r.(iputil.VpnIp)
}

return 0
}

func (t *tun) Cidr() *net.IPNet {
return t.cidr
}

func (t *tun) Name() string {
return t.Device
}

func (t *tun) NewMultiQueueReader() (io.ReadWriteCloser, error) {
return nil, fmt.Errorf("TODO: multiqueue not implemented for freebsd")
}

func (t *tun) Read(to []byte) (int, error) {
buf := make([]byte, len(to)+4)

n, err := t.ReadWriteCloser.Read(buf)

copy(to, buf[4:])
return n - 4, err
}

// Write is only valid for single threaded use
func (t *tun) Write(from []byte) (int, error) {
buf := t.out
if cap(buf) < len(from)+4 {
buf = make([]byte, len(from)+4)
t.out = buf
}
buf = buf[:len(from)+4]

if len(from) == 0 {
return 0, syscall.EIO
}

// Determine the IP Family for the NULL L2 Header
ipVer := from[0] >> 4
if ipVer == 4 {
buf[3] = syscall.AF_INET
} else if ipVer == 6 {
buf[3] = syscall.AF_INET6
} else {
return 0, fmt.Errorf("unable to determine IP version from packet")
}

copy(buf[4:], from)

n, err := t.ReadWriteCloser.Write(buf)
return n - 4, err
}
3 changes: 2 additions & 1 deletion udp/udp_freebsd.go → udp/udp_bsd.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//go:build !e2e_testing
//go:build (openbsd || freebsd) && !e2e_testing
// +build openbsd freebsd
// +build !e2e_testing

package udp
Expand Down