neslink

package module
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2023 License: MIT Imports: 10 Imported by: 0

README ΒΆ

Go Reference

NESlink is go package that allows for interaction with netlink. NESlink is simply a quality of life wrapper around these great netlink and netns packages. Not all the functionality of these packages remains in NESlink, but the interactions that are included are better suited to the NES platform implementation.

The main objective of this package is to make link interaction easier when dealing with many links across many network namespaces. This includes safe parallel operations in multiple namespaces.


Usage

At the core of this package are the Do functions, one for network namespaces, the other for links. These allow for low-code, go routine safe interaction with both links and namespaces (and links in namespaces).

Namespace Interaction

Any interaction with a netns should be done via a call to Do. As an example, to list the links in a network namespace, you would simply need to provide Do with a NsProvider for the target namespace, and the NsAction for listing links. So if there was a network namespace called example, then the following snippet would perform the action safely:

links := make([]netlink.Link, 0)
err := neslink.Do(neslink.NPName("example"), neslink.NALinks(&links))
if err != nil {
  ...

πŸ’‘ Any number of NSActions can be provided to a single Do call, and they will be executed in order.

Here err would contain any error that occurred either in switching namespaces or within the function. If for any reason the system thread used for the action executing go routine fails to be returned to the netns of the caller, the thread is marked as dirty and can not be accessed again.

Custom NsActions can be easily created too, see this example.

To manage links, any operation should be a LinkAction set in a call to Do. Do will execute a set of functions in a given netns. As an example, the below snippet will create a new bridge called br0 in a pre-existing named netns called example, then set its MAC address to 12:23:34:45:56:67 and set its state to UP:

if err := neslink.Do(
  neslink.NPName("example"),
  neslink.LANewBridge("br0"),
  neslink.LASetHw(neslink.LPName("br0"), "12:23:34:45:56:67"),
  neslink.LASetUp(neslink.LPName("br0")),
  ); err != nil {
  ...

πŸ“ Setting a link's netns is not a LinkAction but instead a NsAction, since after moving the link to another netns, the netns of the Do goroutine should also be changed to the netns to complete any further actions on the link.

Via the LinkProviders, new links can be created, or already created links can be obtained via their name, index, or alias.

NEScript Integration

Using this package, NEScripts can be executed on any specific netns, making it easy to specify custom actions to execute via the NsAction system.


Motivation

Whilst the 2 packages referenced at the top of this doc for netlink and netns provide all this functionality and more, they are still somewhat low-level packages. This can result in programs that use them extensively needing a lot of wrapper code to make the provided functionality easier and safer to use. This package is that wrapper code.


🚧 WIP

  • Add tests
  • Run tests via actions

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

View Source
const (
	NsFdNone         NsFd   = NsFd(-1)
	DefaultMountPath string = "/run/netns"
)

Variables ΒΆ

View Source
var (
	ErrNoLink error = errors.New("failed to obtain link from provider")
)

Functions ΒΆ

func Do ΒΆ

func Do(nsP NsProvider, actions ...Action) error

Do executes a given set of actions in a specified network namespace. It does so in a separate OS thread in order to allow the rest of the program to continue on the current network namespace. An error is returned if any netns move fails or any provided action fails. Do note that if the spawned system thread fails to be reverted to the network namespace of the caller, the thread is considered dirty and is never unlocked (thus can not be reused).

Types ΒΆ

type Action ΒΆ

type Action interface {
	// contains filtered or unexported methods
}

Action represents an entity that has a name and some function (act) that can return an error.

type LinkAction ΒΆ

type LinkAction struct {
	// contains filtered or unexported fields
}

LinkAction is a singular operation that can be performed on a generic netlink link. Actions have a name as to identify individual actions when passed as a set to a LinkDo call, providing more contextual errors. They also have a function that take a link as a parameter. When called, the function will perform the operation on the provided link, returning an error if any occurred. These do support being executed outside of LinkDo calls, but using LinkDo is still recommended.

func LAAddAddr ΒΆ

func LAAddAddr(provider LinkProvider, cidr string) LinkAction

func LAAddNetem ΒΆ added in v0.4.1

func LAAddNetem(provider LinkProvider, latency, jitter uint32, loss float32) LinkAction

LAAddNetem when acted on will add a netem qdisc to the given link. This imposes synthetc limits on latency, jitter (in Β΅s), and loss (as %).

func LAAddTbf ΒΆ added in v0.4.1

func LAAddTbf(provider LinkProvider, bw uint64) LinkAction

LAAddTbf when acted on will add a token bucket filter qdisc to the given link. This will limit the bandwidth of the link (bits/s).

func LADelAddr ΒΆ

func LADelAddr(provider LinkProvider, cidr string) LinkAction

func LADelete ΒΆ

func LADelete(provider LinkProvider) LinkAction

LADelete will simply delete the link when the action is executed. For obvious reasons this should be at the end of any LinkDo call (since the link will be deleted, further actions will error).

func LAGeneric ΒΆ

func LAGeneric(actionName string, function func() error) LinkAction

LAGeneric allows for a custom LinkAction to be created and then used in a LinkDo call.

func LANewBridge ΒΆ

func LANewBridge(name string) LinkAction

LANewBridge creates a new bridge with the given name.

func LANewDummy ΒΆ

func LANewDummy(name string) LinkAction

LANewDummy creates a new dummy link with the given name.

func LANewGRETap ΒΆ

func LANewGRETap(name, localIP, remoteIP string) LinkAction

LANewGRETap creates a new gretap device with the given name, local IP, and remoteIP.

func LANewVeth ΒΆ

func LANewVeth(name, peerName string) LinkAction

LANewVeth will create a new veth pair. The names for both the new interfaces (main link and peer) should be provided.

func LANewVxlan ΒΆ

func LANewVxlan(name, localIP, groupIP string, id, port int) LinkAction

LANewVxlan creates a new vxlan link with the given configuration.

func LANewWireguard ΒΆ

func LANewWireguard(name string) LinkAction

LANewWireguard creates a new wireguard link with the given name. Further setup of this link should be done in custom LinkActions with wireguard specifc code.

func LASetAlias ΒΆ

func LASetAlias(provider LinkProvider, alias string) LinkAction

func LASetDown ΒΆ

func LASetDown(provider LinkProvider) LinkAction

func LASetHw ΒΆ

func LASetHw(provider LinkProvider, addr string) LinkAction

func LASetName ΒΆ

func LASetName(provider LinkProvider, name string) LinkAction

func LASetPromiscOff ΒΆ

func LASetPromiscOff(provider LinkProvider) LinkAction

func LASetPromiscOn ΒΆ

func LASetPromiscOn(provider LinkProvider) LinkAction

func LASetUp ΒΆ

func LASetUp(provider LinkProvider) LinkAction

func (LinkAction) ActionName ΒΆ

func (la LinkAction) ActionName() string

ActionName returns the name associated with the given link action.

type LinkProvider ΒΆ

type LinkProvider struct {
	// contains filtered or unexported fields
}

func LPAlias ΒΆ

func LPAlias(alias string) LinkProvider

LPAlias creates a link provider that when called, will provide the pre-existing link with the given alias (in the namespace this is called in). If no matches are found, an error is returned.

func LPGeneric ΒΆ

func LPGeneric(providerName string, function func() (netlink.Link, error)) LinkProvider

LPGeneric provides the means to create custom providers.

func LPIndex ΒΆ

func LPIndex(index int) LinkProvider

LPIndex creates a link provider that when called, will provide the pre-existing link with the given index (in the namespace this is called in). If no matches are found, an error is returned.

func LPName ΒΆ

func LPName(name string) LinkProvider

LPName creates a link provider that when called, will provide the pre-existing link with the given name (in the namespace this is called in). If no matches are found, an error is returned.

func (LinkProvider) Provide ΒΆ

func (lp LinkProvider) Provide() (netlink.Link, error)

Provide determines the network namespace path based on the provider's conditions. Since some conditions are collected at the time of the provider's creation and others when this function is called, repeat calls are not always expected to produce the same result. Also note, the path is only returned, not opened.

type Namespace ΒΆ

type Namespace string

Namespace is a path to a file associated with a network namespace.

func (Namespace) Exists ΒΆ

func (ns Namespace) Exists() bool

Exists determines if the path used for the namespace exists. Whilst not an exhaustive check, this can help debug namespace providers.

func (Namespace) String ΒΆ

func (n Namespace) String() string

String returns the Namespace file path as a string.

type NsAction ΒΆ

type NsAction struct {
	// contains filtered or unexported fields
}

NsAction represents an action that should be executed in a namespace via NsDo. The action should have a relevant name as to give context to errors (as multiple actions are executed in a single NsDo call). Also the action itself should be a function that takes no parameters and returns an error (or nil in the event of success). Also noteworthy, if an action function executes logic in any other goroutines (either my channel interaction or spawning a new goroutine), that logic will not be executed within the expected network namespace.

func NADeleteNamed ΒΆ

func NADeleteNamed(name string) NsAction

NADeleteNamed when executed removes the named netns if it exists. Importantly, the netns is not removed until the tread exists (at the end of the do call).

func NADeleteNamedAt ΒΆ

func NADeleteNamedAt(mountdir, name string) NsAction

NADeleteNamedAt when executed removes the named netns if it exists. Importantly, the netns is not removed until the tread exists (at the end of the do call).

func NAExecNescript ΒΆ

func NAExecNescript(script nescript.Script, subcommand []string, process *nescript.Process) NsAction

NAExecNescript will execute a NEScript in the netns it is called in, most likely the netns of the wrapping NsDo. This opens up extensive custom options. Provided should be the already compiled NEScript, a subcommand to use for the script such as ["sh" "-c"] (or nil to use the nescript package's deafult), and a nescript.Process for the resulting process to be stored in.

func NAGeneric ΒΆ

func NAGeneric(name string, function func() error) NsAction

NAGeneric allows for a custom action (function) to be performed in a given network namespace. A name should be given to describe the custom function in a couple of words to give context to NsDo errors.

func NAGetLink(provider LinkProvider, link *netlink.Link) NsAction

NAGetLink gets a specific link from the given link provider when the action is called. The result is stored within the given link parameter. An error is returned if any occurred.

func NAGetNsFd ΒΆ

func NAGetNsFd(nsfd *NsFd) NsAction

NAGetNsFd provides an open file descriptor for the network namespace it is called in. This fd is separate from that of the one in the enclosing NsDo, so it is up to the user to close the fd when it is no longer needed.

func NALinks(links *[]netlink.Link) NsAction

NALinks returns a list of all the links in the namespace obtained via the given provider. Any errors are returned and a boolean to express if the the network namespace has returned back to the origin successfully.

func NANewNs ΒΆ

func NANewNs(name string) NsAction

NANewNs will create a new network namespace and bind it to a named file. Any action that is performed after this action executes successfully will be executed within the new netns.

func NANewNsAt ΒΆ

func NANewNsAt(mountdir, name string) NsAction

NANewNsAt will create a new network namespace and bind it to a named file in a given directory. Note that this will likely result in the netns not being visible in the iproute command line. Any action that is performed after this action executes successfully will be executed within the new netns.

func NASetLinkNs ΒΆ

func NASetLinkNs(lP LinkProvider, nsP NsProvider) NsAction

NASetLinkNs moves a link provided by the given link provider to the namespace provided by the ns provider. The link itself should br present in the namespace in which the wrapping NsDo is set to execute in.

type NsFd ΒΆ

type NsFd int

NsFd is a file descriptor for an open Namespace file.

func (NsFd) Dev ΒΆ added in v0.4.0

func (n NsFd) Dev() (uint64, error)

Dev descirbes the device in which the network ns file resides.

func (NsFd) Inode ΒΆ added in v0.4.0

func (n NsFd) Inode() (uint64, error)

Inode provides the inode of the network namespace file.

func (NsFd) Int ΒΆ

func (n NsFd) Int() int

Int returns the Namespace file descriptor as an int.

func (NsFd) Valid ΒΆ

func (n NsFd) Valid() bool

Valid determines if the file descriptor is valid. This can be used to determine if a returned NsFd is ok regardless of the error.

type NsProvider ΒΆ

type NsProvider struct {
	// contains filtered or unexported fields
}

NsProvider offers a approach to obtaining network namespace paths based on given conditions.

func NPGeneric ΒΆ

func NPGeneric(providerName string, function func() (Namespace, error)) NsProvider

NPGeneric provides the means to create custom providers. See the docker provider for an example of this.

func NPName ΒΆ

func NPName(name string) NsProvider

NPName returns a netns provider that provides the netns path for a named (mounted) netns. This assumes the ns is mounted in the default location.

func NPNameAt ΒΆ

func NPNameAt(mountdir, name string) NsProvider

NPNameAt returns a netns provider that provides the netns path for a named (mounted) netns.

func NPNow ΒΆ

func NPNow() NsProvider

NPNow returns a netns provider that provides the netns path for the process/thread that calls the Provide function.

func NPPath ΒΆ

func NPPath(path string) NsProvider

NPPath returns a netns provider that provides the netns path based on the path given.

func NPProcess ΒΆ

func NPProcess(pid int) NsProvider

NPProcess returns a netns provider that provides the netns path for the process associated with the given process ID.

func NPThread ΒΆ

func NPThread(pid, tid int) NsProvider

NPThread returns a netns provider that provides the netns path for the process associated with the given process and thread ID.

func (NsProvider) Provide ΒΆ

func (nsp NsProvider) Provide() (Namespace, error)

Provide determines the network namespace path based on the provider's conditions. Since some conditions are collected at the time of the provider's creation and others when this function is called, repeat calls are not always expected to produce the same result. Also note, the path is only returned, not opened.

Directories ΒΆ

Path Synopsis
examples
ovs

Jump to

Keyboard shortcuts

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