50 lines
1023 B
Go
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
|
|
}
|