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

fix build-tags, fix/update deprecated features, and fix inconsistency in path used #61

Merged
merged 8 commits into from
Jan 13, 2023
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"fmt"
"net"
"runtime"

"github.com/vishvananda/netns"
)

Expand Down
9 changes: 9 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Package netns allows ultra-simple network namespace handling. NsHandles
// can be retrieved and set. Note that the current namespace is thread
// local so actions that set and reset namespaces should use LockOSThread
// to make sure the namespace doesn't change due to a goroutine switch.
// It is best to close NsHandles when you are done with them. This can be
// accomplished via a `defer ns.Close()` on the handle. Changing namespaces
// requires elevated privileges, so in most cases this code needs to be run
// as root.
package netns
24 changes: 11 additions & 13 deletions netns_linux.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//go:build linux && go1.10
// +build linux,go1.10

package netns

import (
Expand All @@ -17,15 +14,16 @@ import (

// Deprecated: use golang.org/x/sys/unix pkg instead.
const (
CLONE_NEWUTS = 0x04000000 /* New utsname group? */
CLONE_NEWIPC = 0x08000000 /* New ipcs */
CLONE_NEWUSER = 0x10000000 /* New user namespace */
CLONE_NEWPID = 0x20000000 /* New pid namespace */
CLONE_NEWNET = 0x40000000 /* New network namespace */
CLONE_IO = 0x80000000 /* Get io context */
bindMountPath = "/run/netns" /* Bind mount path for named netns */
CLONE_NEWUTS = unix.CLONE_NEWUTS /* New utsname group? */
CLONE_NEWIPC = unix.CLONE_NEWIPC /* New ipcs */
CLONE_NEWUSER = unix.CLONE_NEWUSER /* New user namespace */
CLONE_NEWPID = unix.CLONE_NEWPID /* New pid namespace */
CLONE_NEWNET = unix.CLONE_NEWNET /* New network namespace */
CLONE_IO = unix.CLONE_IO /* Get io context */
)

const bindMountPath = "/run/netns" /* Bind mount path for named netns */

// Setns sets namespace using golang.org/x/sys/unix.Setns.
//
// Deprecated: Use golang.org/x/sys/unix.Setns instead.
Expand All @@ -36,13 +34,13 @@ func Setns(ns NsHandle, nstype int) (err error) {
// Set sets the current network namespace to the namespace represented
// by NsHandle.
func Set(ns NsHandle) (err error) {
return Setns(ns, CLONE_NEWNET)
return unix.Setns(int(ns), unix.CLONE_NEWNET)
}

// New creates a new network namespace, sets it as current and returns
// a handle to it.
func New() (ns NsHandle, err error) {
if err := unix.Unshare(CLONE_NEWNET); err != nil {
if err := unix.Unshare(unix.CLONE_NEWNET); err != nil {
return -1, err
}
return Get()
Expand Down Expand Up @@ -110,7 +108,7 @@ func GetFromPath(path string) (NsHandle, error) {
// GetFromName gets a handle to a named network namespace such as one
// created by `ip netns add`.
func GetFromName(name string) (NsHandle, error) {
return GetFromPath(fmt.Sprintf("/var/run/netns/%s", name))
return GetFromPath(filepath.Join(bindMountPath, name))
}

// GetFromPid gets a handle to the network namespace of a given pid.
Expand Down
4 changes: 3 additions & 1 deletion netns_test.go → netns_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ func TestGetNewSetDelete(t *testing.T) {
if err := Set(origns); err != nil {
t.Fatal(err)
}
newns.Close()
if err := newns.Close(); err != nil {
t.Error("Failed to close ns", err)
}
if newns.IsOpen() {
t.Fatal("newns still open after close", newns)
}
Expand Down
5 changes: 5 additions & 0 deletions netns_unspecified.go → netns_others.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !linux
// +build !linux

package netns
Expand All @@ -10,6 +11,10 @@ var (
ErrNotImplemented = errors.New("not implemented")
)

// Setns sets namespace using golang.org/x/sys/unix.Setns on Linux. It
// is not implemented on other platforms.
//
// Deprecated: Use golang.org/x/sys/unix.Setns instead.
func Setns(ns NsHandle, nstype int) (err error) {
return ErrNotImplemented
}
Expand Down
10 changes: 1 addition & 9 deletions netns.go → nshandle_linux.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
// Package netns allows ultra-simple network namespace handling. NsHandles
// can be retrieved and set. Note that the current namespace is thread
// local so actions that set and reset namespaces should use LockOSThread
// to make sure the namespace doesn't change due to a goroutine switch.
// It is best to close NsHandles when you are done with them. This can be
// accomplished via a `defer ns.Close()` on the handle. Changing namespaces
// requires elevated privileges, so in most cases this code needs to be run
// as root.
package netns

import (
Expand Down Expand Up @@ -71,7 +63,7 @@ func (ns *NsHandle) Close() error {
if err := unix.Close(int(*ns)); err != nil {
return err
}
(*ns) = -1
*ns = -1
return nil
}

Expand Down
45 changes: 45 additions & 0 deletions nshandle_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//go:build !linux
// +build !linux

package netns

// NsHandle is a handle to a network namespace. It can only be used on Linux,
// but provides stub methods on other platforms.
type NsHandle int

// Equal determines if two network handles refer to the same network
// namespace. It is only implemented on Linux.
func (ns NsHandle) Equal(_ NsHandle) bool {
return false
}

// String shows the file descriptor number and its dev and inode.
// It is only implemented on Linux, and returns "NS(none)" on other
// platforms.
func (ns NsHandle) String() string {
return "NS(None)"
}

// UniqueId returns a string which uniquely identifies the namespace
// associated with the network handle. It is only implemented on Linux,
// and returns "NS(none)" on other platforms.
func (ns NsHandle) UniqueId() string {
return "NS(none)"
}

// IsOpen returns true if Close() has not been called. It is only implemented
// on Linux and always returns false on other platforms.
func (ns NsHandle) IsOpen() bool {
return false
}

// Close closes the NsHandle and resets its file descriptor to -1.
// It is only implemented on Linux.
func (ns *NsHandle) Close() error {
return nil
}

// None gets an empty (closed) NsHandle.
func None() NsHandle {
return NsHandle(-1)
}