Files
x/internal/net/dialer/dialer_netns.go
T

50 lines
1023 B
Go

//go:build linux && !android
package dialer
import (
"fmt"
"runtime"
"strings"
"github.com/vishvananda/netns"
)
// switchNetns enters the named network namespace and returns a cleanup
// function that restores the original namespace. The caller must defer
// the returned function.
func switchNetns(name string) (restore func(), err error) {
runtime.LockOSThread()
originNs, err := netns.Get()
if err != nil {
runtime.UnlockOSThread()
return nil, fmt.Errorf("netns.Get(): %v", err)
}
var ns netns.NsHandle
if strings.HasPrefix(name, "/") {
ns, err = netns.GetFromPath(name)
} else {
ns, err = netns.GetFromName(name)
}
if err != nil {
netns.Set(originNs)
runtime.UnlockOSThread()
return nil, fmt.Errorf("netns.Get(%s): %v", name, err)
}
if err := netns.Set(ns); err != nil {
ns.Close()
netns.Set(originNs)
runtime.UnlockOSThread()
return nil, fmt.Errorf("netns.Set(%s): %v", name, err)
}
return func() {
netns.Set(originNs)
ns.Close()
runtime.UnlockOSThread()
}, nil
}