neslink

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2022 License: MIT Imports: 8 Imported by: 3

README ΒΆ

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 NsDo. As an example, to list the links in a network namespace, you would simply need to provide NsDo 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, ok := neslink.NsDo(neslink.NPName("example"), neslink.NALinks(&links))
if err != nil || !ok {
  ...

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

Here err would contain any error that occurred either in switching namespaces or within the function. However, ok will only be true if the network namespace was successfully returned to the original netns prior to running the function.

A new netns can be created similarly by specifying with the NPNew() or NPNewNamed(...) provider. The actions set can simply be left blank if you wish to only create the netns and not interact with it.

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

To manage links, any operation should be a LinkAction set in a call to LinkDo. Much like NsDo, LinkDo will execute a set of functions in a given netns, but applied to a specific link found via a LinkProvider. 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, ok := neslink.LinkDo(
  neslink.NPName("example"),
  neslink.LPNewBridge("br0"),
  neslink.LASetHw("12:23:34:45:56:67"),
  neslink.LASetUp(),
  ); err != nil || !ok {
  ...

πŸ“ 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 LinkDo 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.

Other Notes
  • Both XXDo functions have a MustXXDo variant that will still return errors, but if the function can not successfully revert to the original netns, will cause a panic.

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

  • Address inline TODOs
  • Add tests
  • Run tests via actions

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

func DeleteNamedNs ΒΆ

func DeleteNamedNs(name string) error

DeleteNamedNs literally just called the delete named from the netlink package, but is here just incase of a use case where there is no other reason to directly import that package.

func LinkDo ΒΆ

func LinkDo(nsP NsProvider, lP LinkProvider, actions ...LinkAction) (error, bool)

LinkDo runs a set of link actions on a link that is obtained from the given LinkProvider. The link provider is called and the actions are performed in the namespace obtained by the NsProvider, thus this can be used to manage links in any namespace. The actions are perfromed in the given namespace via NsDo, so the returned outputs are much the same as with NsDo.

func MustLinkDo ΒΆ

func MustLinkDo(nsP NsProvider, lP LinkProvider, actions ...LinkAction) error

MustLinkDo performs a normal LinkDo, however if it fails to revert back to the origin netns, then this will trigger a panic. Any other errors are returned as normal.

func MustNsDo ΒΆ

func MustNsDo(nsP NsProvider, actions ...NsAction) error

MustNsDo performs a normal NsDo, however if it fails to revert back to the origin netns, then this will trigger a panic. Any other errors are returned as normal.

func NsDo ΒΆ

func NsDo(nsP NsProvider, actions ...NsAction) (error, bool)

NsDo executes a given function 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. Returned is the error (if any occurred) and a bool, that if false, shows that the function did not successfully return the netns back to the origin, a potentially critical error.

Types ΒΆ

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(cidr string) LinkAction

func LADelAddr ΒΆ

func LADelAddr(cidr string) LinkAction

func LADelete ΒΆ

func LADelete() 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(name string, function func(netlink.Link) error) LinkAction

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

func LASetAlias ΒΆ

func LASetAlias(alias string) LinkAction

func LASetDown ΒΆ

func LASetDown() LinkAction

func LASetHw ΒΆ

func LASetHw(addr string) LinkAction

func LASetName ΒΆ

func LASetName(name string) LinkAction

func LASetPromiscOff ΒΆ

func LASetPromiscOff() LinkAction

func LASetPromiscOn ΒΆ

func LASetPromiscOn() LinkAction

func LASetUp ΒΆ

func LASetUp() LinkAction

func (LinkAction) ActionName ΒΆ

func (la LinkAction) ActionName() string

ActionName returns the name associated with the given link action.

func (LinkAction) Do ΒΆ

func (la LinkAction) Do(link netlink.Link) error

Do will perform the link operation immediately, supporting use outide of any LinkDo calls.

type LinkProvider ΒΆ

type LinkProvider func() (netlink.Link, error)

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 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 LPNewBridge ΒΆ

func LPNewBridge(name string) LinkProvider

LPNewBridge creates a link provider that when called, will create a new bridge with the given name and then provides the newly created bridge.

func LPNewDummy ΒΆ

func LPNewDummy(name string) LinkProvider

LPNewDummy creates a link provider that when called, will create a new dummy link with the given name and returns it, provided no errors occur.

func LPNewGRETap ΒΆ

func LPNewGRETap(name, localIP, remoteIP string) LinkProvider

LPNewGRETap creates a link provider that when called, creates a new gretap device with the given name, local IP, and remoteIP.

func LPNewVeth ΒΆ

func LPNewVeth(name, peerName string) LinkProvider

LPNewVeth creates a link provider that when called, will create a new veth pair and return the link. The names for both the new interfaces (main link and peer) should be provided. Only the main link is actually then provided by the LinkProvider. To get the peer, LAName with the peer's name should suffice. Any errors in creating/finding the veth pair are also returned.

func LPNewVxlan ΒΆ

func LPNewVxlan(name, localIP, groupIP string, id, port int) LinkProvider

LPNewVxlan creates a link provider that when called, will create a new vxlan link with the given configuration and returns it.

func LPNewWireguard ΒΆ

func LPNewWireguard(name string) LinkProvider

LPNewWireguard creates a link provider that when called, will create a new wireguard link with the given name and returns it, provided no errors occur. Further setup of this link should be done in custom LinkDos withwireguard specifc code.

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).

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

ListLinks 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 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 referencing a network namespace. This can be used to interact and mange the netns.

func (*NsFd) Close ΒΆ

func (fd *NsFd) Close() error

Close effectively closes the reference to the netns, thus after calling the file descriptor should not be used again. This is handled already by the Do functions in this package, so is only needed to be used when manually managaging netns handles.

func (NsFd) Fd ΒΆ

func (fd NsFd) Fd() int

Fd simply returns the file descriptor as an int.

func (NsFd) ID ΒΆ

func (fd NsFd) ID() string

ID provides a unique ID for the network namespace in string form. This can be useful for determining if 2 NsFds reference the same netns.

func (NsFd) Set ΒΆ

func (fd NsFd) Set() error

Set sets the current thread's network namespace to the one associated with the netns file descriptor. In most cases, the Do functions in this package should be used, so only use this function when the Do functions do not suffice.

type NsProvider ΒΆ

type NsProvider func() (NsFd, error)

NsProvider is a function that retruns a network namespace (netns) handle (file descriptor) when it is called. If the provider fails to correctly obtain the netns, an error is returned.

func NPCurrent ΒΆ

func NPCurrent() NsProvider

NPCurrent returns a netns provider that will return the current netns fd as of the time when the provider itself is called.

func NPDocker ΒΆ

func NPDocker(containerID string) NsProvider

NPDocker returns a netns provider that when called will return the netns fd associated with a given docker container.

func NPName ΒΆ

func NPName(name string) NsProvider

NPName returns a netns provider that when called will return the netns fd associated with the given name.

func NPNew ΒΆ

func NPNew() NsProvider

NPNew returns a netns provider that when called will create a new unnamed netns (in turn switching to it) and returns the fd of the newly created ns.

func NPNewNamed ΒΆ

func NPNewNamed(name string) NsProvider

NPNewNamed returns a netns provider that when called will create a new named netns (in turn switching to it) and returns the fd of the newly created ns.

func NPNow ΒΆ

func NPNow() NsProvider

NPNow returns a netns provider that simply provides the netns fd that was found at the time that the provider itself was generated (the time that this function is called).

func NPPath ΒΆ

func NPPath(path string) NsProvider

NPPath returns a netns provider that when called will return the netns fd associated with the given file path.

func NPProcess ΒΆ

func NPProcess(pid int) NsProvider

NPProcess returns a netns provider that when called will return the netns fd associated with the given process.

func NPThread ΒΆ

func NPThread(pid, tid int) NsProvider

NPThread returns a netns provider that when called will return the netns fd associated with the given thread.

Directories ΒΆ

Path Synopsis
examples
linkdo command
nescript command
nsdo command

Jump to

Keyboard shortcuts

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