// SPDX-License-Identifier: Apache-2.0 package prober import ( "fmt" "runtime" "github.com/vishvananda/netns" ) // inNetns runs fn while the current OS thread is switched into the named // network namespace. The thread is locked for the duration so the switch is safe. // The original netns is restored before returning. // If nsName is empty, fn is run in the current namespace without any switching. func inNetns(nsName string, fn func() error) error { if nsName == "" { return fn() } runtime.LockOSThread() defer runtime.UnlockOSThread() origNs, err := netns.Get() if err != nil { return fmt.Errorf("get current netns: %w", err) } defer func() { _ = origNs.Close() }() defer func() { _ = netns.Set(origNs) }() targetNs, err := netns.GetFromName(nsName) if err != nil { return fmt.Errorf("get netns %q: %w", nsName, err) } defer func() { _ = targetNs.Close() }() if err := netns.Set(targetNs); err != nil { return fmt.Errorf("enter netns %q: %w", nsName, err) } return fn() }