Giter Site home page Giter Site logo

tenus's Introduction

Linux networking in Golang

GoDoc License

tenus is a Golang package which allows you to configure and manage Linux network devices programmatically. It communicates with Linux Kernel via netlink to facilitate creation and configuration of network devices on the Linux host. The package also allows for more advanced network setups with Linux containers including Docker.

tenus uses runc's implementation of netlink protocol. The package only works with newer Linux Kernels (3.10+) which are shipping reasonably new netlink protocol implementation, so if you are running older kernel this package won't be of much use to you I'm afraid. I have developed this package on Ubuntu Trusty Tahr which ships with 3.13+ and verified its functionality on Precise Pangolin with upgraded kernel to version 3.10. I could worked around the netlink issues by using ioctl syscalls, but I decided to prefer "pure netlink" implementation, so suck it old Kernels.

At the moment only functional tests are available, but the interface design should hopefully allow for easy (ish) unit testing in the future. I do appreciate that the package's test coverage is not great at the moment, but the core functionality should be covered. I would massively welcome PRs.

Get started

There is a Vagrantfile available in the repo so using vagrant is the easiest way to get started:

milosgajdos@bimbonet ~ $ git clone https://github.com/milosgajdos/tenus.git
milosgajdos@bimbonet ~ $ vagrant up

Note using the provided Vagrantfile will take quite a long time to spin the VM as vagrant will setup Ubuntu Trusty VM with all the prerequisities:

  • it will install golang and docker onto the VM
  • it will export GOPATH and go get the tenus package onto the VM
  • it will also "pull" Docker ubuntu image so that you can run the tests once the VM is set up

At the moment running the tests require Docker to be installed, but in the future I'd love to separate tests per interface so that you can run only chosen test sets.

Once the VM is running, cd into particular repo directory and you can run the tests:

milosgajdos@bimbonet ~ $ cd $GOPATH/src/github.com/milosgajdos/tenus
milosgajdos@bimbonet ~ $ sudo go test

If you don't want to use the provided Vagrantfile, you can simply run your own Linux VM (with 3.10+ kernel) and follow the regular golang development flow:

milosgajdos@bimbonet ~ $ go get github.com/milosgajdos/tenus
milosgajdos@bimbonet ~ $ cd $GOPATH/src/github.com/milosgajdos/tenus
milosgajdos@bimbonet ~ $ sudo go test

Once you've got the package and ran the tests (you don't need to run the tests!), you can start hacking. Below you can find simple code samples to get started with the package.

Examples

Below you can find a few code snippets which can help you get started writing your own programs.

New network bridge, add dummy link into it

The example below shows a simple program example which creates a new network bridge, a new dummy network link and adds it into the bridge.

package main

import (
	"fmt"
	"log"

	"github.com/milosgajdos/tenus"
)

func main() {
	// Create a new network bridge
	br, err := tenus.NewBridgeWithName("mybridge")
	if err != nil {
		log.Fatal(err)
	}

	// Bring the bridge up
	if err = br.SetLinkUp(); err != nil {
		fmt.Println(err)
	}

	// Create a dummy link
	dl, err := tenus.NewLink("mydummylink")
	if err != nil {
		log.Fatal(err)
	}

	// Add the dummy link into bridge
	if err = br.AddSlaveIfc(dl.NetInterface()); err != nil {
		log.Fatal(err)
	}

	// Bring the dummy link up
	if err = dl.SetLinkUp(); err != nil {
		fmt.Println(err)
	}
}

New network bridge, veth pair, one peer in Docker

The example below shows how you can create a new network bride, configure its IP address, add a new veth pair and send one of the veth peers into Docker with a given name.

!! You must make sure that particular Docker is runnig if you want the code sample below to work properly !! So before you compile and run the program below you should create a particular docker with the below used name:

milosgajdos@bimbonet ~ $ docker run -i -t --rm --privileged -h vethdckr --name vethdckr ubuntu:14.04 /bin/bash
package main

import (
	"fmt"
	"log"
	"net"

	"github.com/milosgajdos/tenus"
)

func main() {
	// CREATE BRIDGE AND BRING IT UP
	br, err := tenus.NewBridgeWithName("vethbridge")
	if err != nil {
		log.Fatal(err)
	}

	brIp, brIpNet, err := net.ParseCIDR("10.0.41.1/16")
	if err != nil {
		log.Fatal(err)
	}

	if err := br.SetLinkIp(brIp, brIpNet); err != nil {
		fmt.Println(err)
	}

	if err = br.SetLinkUp(); err != nil {
		fmt.Println(err)
	}

	// CREATE VETH PAIR
	veth, err := tenus.NewVethPairWithOptions("myveth01", tenus.VethOptions{PeerName: "myveth02"})
	if err != nil {
		log.Fatal(err)
	}

	// ASSIGN IP ADDRESS TO THE HOST VETH INTERFACE
	vethHostIp, vethHostIpNet, err := net.ParseCIDR("10.0.41.2/16")
	if err != nil {
		log.Fatal(err)
	}

	if err := veth.SetLinkIp(vethHostIp, vethHostIpNet); err != nil {
		fmt.Println(err)
	}

	// ADD MYVETH01 INTERFACE TO THE MYBRIDGE BRIDGE
	myveth01, err := net.InterfaceByName("myveth01")
	if err != nil {
		log.Fatal(err)
	}

	if err = br.AddSlaveIfc(myveth01); err != nil {
		fmt.Println(err)
	}

	if err = veth.SetLinkUp(); err != nil {
		fmt.Println(err)
	}

	// PASS VETH PEER INTERFACE TO A RUNNING DOCKER BY PID
	pid, err := tenus.DockerPidByName("vethdckr", "/var/run/docker.sock")
	if err != nil {
		fmt.Println(err)
	}

	if err := veth.SetPeerLinkNsPid(pid); err != nil {
		log.Fatal(err)
	}

	// ALLOCATE AND SET IP FOR THE NEW DOCKER INTERFACE
	vethGuestIp, vethGuestIpNet, err := net.ParseCIDR("10.0.41.5/16")
	if err != nil {
		log.Fatal(err)
	}

	if err := veth.SetPeerLinkNetInNs(pid, vethGuestIp, vethGuestIpNet, nil); err != nil {
		log.Fatal(err)
	}
}

Working with existing bridges and interfaces

The following examples show how to retrieve exisiting interfaces as a tenus link and bridge

package main

import (
	"fmt"
	"log"
	"net"

	"github.com/milosgajdos/tenus"
)

func main() {
	// RETRIEVE EXISTING BRIDGE
	br, err := tenus.BridgeFromName("bridge0")
	if err != nil {
		log.Fatal(err)
	}

	// REMOVING AN IP FROM A BRIDGE INTERFACE (BEFORE RECONFIGURATION)
	brIp, brIpNet, err := net.ParseCIDR("10.0.41.1/16")
	if err != nil {
		log.Fatal(err)
	}
	if err := br.UnsetLinkIp(brIp, brIpNet); err != nil {
		log.Fatal(err)
	}

	// RETRIEVE EXISTING INTERFACE
	dl, err := tenus.NewLinkFrom("eth0")
	if err != nil {
		log.Fatal(err)
	}

	// RENAMING AN INTERFACE BY NAME
	if err := tenus.RenameInterfaceByName("vethPSQSEl", "vethNEWNAME"); err != nil {
		log.Fatal(err)
	}

}

VLAN and MAC VLAN interfaces

You can check out VLAN and Mac VLAN examples, too.

More examples

Repo contains few more code sample in examples folder so make sure to check them out if you're interested.

TODO

This is just a rough beginning of the project which I put together over couple of weeks in my free time. I'd like to integrate this into my own Docker fork and test the advanced netowrking functionality with the core of Docker as oppose to configuring network interfaces from a separate golang program, because advanced networking in Docker was the main motivation for writing this package.

Documentation

More in depth package documentation is available via godoc

tenus's People

Contributors

42wim avatar alrs avatar errordeveloper avatar glyn avatar guilhem avatar kdomanski avatar milosgajdos avatar xsmurf avatar yuvigold avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tenus's Issues

veth_linux does not build

Attempting to test tenus produces the following build errors.

$ go test .
# github.com/milosgajdos83/tenus
/home/vagrant/go/src/github.com/milosgajdos83/tenus/veth_linux.go:62: too many arguments in call to netlink.NetworkCreateVethPair
/home/vagrant/go/src/github.com/milosgajdos83/tenus/veth_linux.go:119: too many arguments in call to netlink.NetworkCreateVethPair
FAIL    github.com/milosgajdos83/tenus [build failed]

Avoid libcontainer fork

The Cloud Foundry project is considering using tenus to simplify its usage of netlink. However, we need to avoid being on a fork of libcontainer. We are currently planning to fork tenus, re-base it on vanilla libcontainer, and offer the re-basing as a pull request to tenus. We are also planning some functional extensions to tenus and libcontainer/netlink which we will most likely also offer back via pull requests.

For more details, please see the CF Garden tracker and search for tenus.

This issue is essentially a heads up. We acknowledge that tenus may not need to avoid being on a fork of libcontainer for its own purposes, but we wanted to make you aware of our plans.

Sniffing network traffic

Could this be used to sniff network traffic? I am trying to create a utility that watches SIP (voip) network traffic and greps it. An easier version of ngrep. Thought it would be cool to do it in go if possible.

Possible to create tuntap links?

There doesn't currently seem to be any way to create tuntap interfaces. Is this likely to be supported (i.e. just a matter of adapting the code) or was there a fundamental limitation to doing it?

Please use valid hostname in DockerPidByName when using unix sockets

Currently when docker API is served via UNIX sockets a http request is constructed with used as hostname. This gives (with golang 1.6) following error:

Fail to create http request: parse http:// /containers/e41fcca44e18c5275/json: invalid character " " in host name

Please use a valid hostname instead 'example.com' might be good :-)

Interact with wifi interfaces

This is not exactly an issue. However, I want to know whether this library is able to create virtual wifi interfaces and bridge them with networks. Thanks in adavance.

Proposal: Please start using Semantic Versioning

I found that this project already supports Go modules. But sadly, the tags doesn't follow Semantic Versioning, which means that all tags of this project will be ignored by Go modules and replaced by pseudo-versions, go get acts weirdly when tags are not in that form. It would be great to have the tagged release be named in the format vX.X.X format so that go mod can read it.

	github.com/milosgajdos/tenus v0.0.0-20200730100109-997445a7a4dd

Else the mod file shows something like github.com/milosgajdos/tenus v0.0.0-20200730100109-997445a7a4dd which is not very readable and difficult to upgrade. It’s hard to verify which version is in use. This is not conducive to version control

So, I propose this project to follow Semantic Versioning in future versions. For example, v1.0.1, v2.0.0, v3.1.0-alpha, v3.1.0-beta.2etc.

Persist configuration on reboot

Hello.I have recently started using Golang.What I want is the following,I want to be able to edit an existing interface(e.g. eth0).I want to change the IP from dhcp to static and set a custom gateway IP and subnet mask.If I do that using tenus will the changes persist after a system reboot ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.