netns

package
v1.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 11, 2024 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package netns supports running unit tests in separated transient network namespaces.

This package also helps handling network namespace identiers in form of inode numbers, as well as getting netlink.Handle objects for messing around with network interfaces, network address configurations, routing, et cetera.

Usage

The simplest use cased is to just call EnterTransient and defer its return value.

import "github.com/notwork/netns"

It("tests something inside a temporary network namespace", func() {
  defer netns.EnterTransient()() // !!! double ()()
  // ...
})

This first locks the calling go routine to its OS-level thread, then creates a new throw-away network namespace, and finally switches the OS-level thread with the locked go routine to this new network namespace. Deferring the result of EnterTransient ensures to switch the OS-level thread back to its original network namespace (usually the host network namespace) and unlocks the thread from the go routine. If there are no further references alive to the throw-away network namespace, then the Linux kernel will automatically garbage collect it.

Advanced

In more complex scenarios, such as testing with multiple throw-away network namespaces, these can be created without automatically switching into them. Instead, creating virtual network interfaces can be done by either only temporarily switching into these network namespaces using Execute, or by creating a NewNetlinkHandle to carry out RTNETLINK operations on the handle(s).

The following example uses the first method of switching into the first throw-away network namespace and then creates a VETH pair of network interfaces. One end is located in the second network interfaces.

import (
	"github.com/notwork/netns"
	"github.com/notwork/veth"
)

It("tests something inside a temporary network namespace", func() {
	dupondNetns := netns.NewTransient()
	dupontNetns := netns.NewTransient()
	var dupond, dupont netlink.Link
	netns.Execute(dupondNetns, func() {
		dupond, dupont = veth.NewTransient(WithPeerNamespace(dupontNetns))
	})
})

As for the names of the VETH pair end variables, please refer to Dupond et Dupont.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Current added in v1.3.0

func Current() int

Current returns a file descriptor referencing the current network namespace. In particular, the current network namespace of the OS-level thread of the caller's Go routine (which should ideally be thread-locked).

When not running in the initial network namesepace you should have the calling go routine locked to its OS-level thread.

Additionally, Current schedules a DeferCleanup of the returned file descriptor to be closed to avoid leaking it.

func CurrentIno added in v1.3.0

func CurrentIno() uint64

CurrentIno returns the identification/inode number of the network namespace for the current thread.

func EnterTransient added in v1.3.0

func EnterTransient() func()

EnterTransient creates and enters a new (and isolated) network namespace, returning a function that needs to be defer'ed in order to correctly switch the calling go routine and its locked OS-level thread back when the caller itself returns.

defer netns.EnterTransient()()

In case the caller cannot be switched back correctly, the defer'ed clean up will panic with an error description.

func Execute added in v1.3.0

func Execute(netnsfd int, fn func())

Execute a function fn in the network namespace referenced by the open file descriptor netnsfd.

func Ino added in v1.3.0

func Ino[R ~int | ~string](netns R) uint64

Ino returns the identification/inode number of the passed network namespace, either referenced by a file descriptor or a VFS path name.

func NewNetlinkHandle added in v1.3.0

func NewNetlinkHandle(netnsfd int) *netlink.Handle

NewNetlinkHandle returns a *netlink.Handle that is connected to the specified network namespace (in form of a file descriptor). Such a file descriptor can be obtained from especially netns.NewTransient or netns.Current.

 import (
     "github.com/notwork/netns"
 )

 It("lists links in a transient network namespace", func() {
	netnsfd := netns.NewTransient() // ...no explicit close needed
	nlh := netns.NewNetlinkHandle(netnsfd) // ...also no explicit close needed
	links := Successful(nlh.LinkList())
	Expect(links).NotTo(BeEmpty())
 })

The caller doesn't need to close the returned handle, as NewHandle automatically schedules for the netlink.Handle to be closed when the calling test node terminates (for whichever reason).

func NewTransient added in v1.3.0

func NewTransient() int

NewTransient creates a new network namespace, but doesn't enter it. Instead, it returns a file descriptor referencing the new network namespace. NewTransient also schedules a Ginkgo deferred cleanup in order to close the fd referencing the newly created network namespace. The caller thus must not close the file descriptor returned.

func NsID added in v1.7.0

func NsID[R ~int | ~string](netns R) int

NsID returns the so-called network namespace ID for the passed network namespace, either referenced by a file descriptor or a VFS path name. The nsid identifies the passed network namespace from the perspective of the current network namespace.

If no nsid has been assigned yet to the passed network namespace from the perspective of the current network namespace, NsID will assign a random nsid and return it.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL