| 123456789101112131415161718192021222324252627282930313233343536373839404142434445 |
- //go:build (openbsd || netbsd) && !e2e_testing
- package overlay
- import (
- "errors"
- "fmt"
- "log/slog"
- "os"
- "regexp"
- "runtime"
- "golang.org/x/sys/unix"
- )
- var deviceNameRE = regexp.MustCompile(`^tun[0-9]+$`)
- // tunDevNeedsRestart is true when tun.dev asks for a particular tun that isn't the running one. Anything else takes the
- // first free one, and the one we have will do
- func tunDevNeedsRestart(name, running string) bool {
- return deviceNameRE.MatchString(name) && name != running
- }
- // openTun opens /dev/name, or the first /dev/tunN nothing else has open when name is empty or not tunN
- func openTun(l *slog.Logger, name string) (int, string, error) {
- if name != "" && !deviceNameRE.MatchString(name) {
- // The name doesn't mean anything here, so like darwin a bad one isn't worth refusing to start over
- l.Warn("interface name must be tun[0-9]+ on "+runtime.GOOS+", ignoring", "name", name)
- name = ""
- }
- if name != "" {
- fd, err := unix.Open("/dev/"+name, os.O_RDWR, 0)
- return fd, name, err
- }
- for i := 0; ; i++ {
- name = fmt.Sprintf("tun%d", i)
- fd, err := unix.Open("/dev/"+name, os.O_RDWR, 0)
- if err == nil {
- return fd, name, nil
- }
- if !errors.Is(err, unix.EBUSY) {
- return -1, "", fmt.Errorf("no free tun device, %s: %w", name, err)
- }
- }
- }
|