Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 53 additions & 31 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/vishvananda/netns"
)

var ip, command, gateway, intf, logLevel string
var ip, command, gateway, intf, logLevel, nsPath string
var log = logrus.New()

func init() {
Expand All @@ -26,6 +26,12 @@ func init() {
flag.StringVar(&command, "command", "ip route", "command to be executed")
flag.StringVar(&gateway, "gw", "", "gateway of the request")
flag.StringVar(&logLevel, "log-level", "info", "min level of logs to print")
flag.StringVar(
&nsPath,
"ns-path",
fmt.Sprintf("/var/run/netns/w000t%d", os.Getpid()),
"path of the temporary namespace to be created, default will be /var/run/netns/w000t$PID",
)
flag.Parse()
}

Expand Down Expand Up @@ -58,18 +64,17 @@ func main() {
// Check the /run/netns mount
err = setupNetnsDir()
if err != nil {
log.Warn("Error setting up netns", err)
log.Warn("Error setting up netns: ", err)
return
}

eth, err := netlink.LinkByName(intf)
if err != nil {
log.Warnf("error while getting %s : %s", intf, err)
log.Warnf("Error while getting %s : %s", intf, err)
return
}
log.Debugf("%s : %+v", intf, eth.Attrs().Flags)

// askAndPrint()
// ============================== Create the macVLAN

log.Debug("Create a new macVlan")
Expand All @@ -96,26 +101,27 @@ func main() {

link, err := netlink.LinkByName("peth0")
if err != nil {
log.Warn("error while getting macVlan :", err)
log.Warn("Error while getting macVlan: ", err)
return
}
log.Debugf("MacVlan created : %+v", link)

// askAndPrint()
// ============================== Create the new Namespace

newns, err := newNS()
if err != nil {
log.Warn("error while creating new NS :", err)
log.Warn("error while creating new NS: ", err)
return
}
defer delNS(newns)
defer deleteNS(newns)

log.Debug("Go back to original NS")

netns.Set(origns)

// askAndPrint()
err = netns.Set(origns)
if err != nil {
log.Warn("Failed to change the namespace: ", err)
return
}

// ============================== Add the MacVlan in the new Namespace

Expand All @@ -129,46 +135,62 @@ func main() {

log.Debug("Enter the namespace")

netns.Set(*newns)
err = netns.Set(*newns)
if err != nil {
log.Warn("Failed to enter the namespace: ", err)
return
}

// ============================= Configure the new namespace to configure it

addr, err := netlink.ParseAddr(ip)
if err != nil {
log.Warn("Failed to parse ip", err)
log.Warn("Failed to parse the given IP: ", err)
return
}

log.Debugf("Add the addr to the macVlan: %+v", addr)
netlink.AddrAdd(link, addr)
// ============================= Set the address in the namespace
err = netlink.AddrAdd(link, addr)
if err != nil {
log.Warn("Failed to add the IP to the macVlan: ", err)
return
}
gwaddr := net.ParseIP(gateway)

log.Debug("Set the macVlan interface UP")
// ============================= Set the link up in the namespace
err = netlink.LinkSetUp(link)
if err != nil {
log.Warn("Error while setting up the interface peth0", err)
log.Warn("Error while setting up the interface peth0: ", err)
return
}

log.Debugf("Set %s as the route", gwaddr)
// ============================= Set the default route in the namespace
err = netlink.RouteAdd(&netlink.Route{
Scope: netlink.SCOPE_UNIVERSE,
LinkIndex: link.Attrs().Index,
Gw: gwaddr,
})
if err != nil {
log.Warn("Error while setting up route on interface peth0", err)
log.Warn("Error while setting up route on interface peth0 :", err)
return
}

// ============================= Execute the command in the namespace
err = execCmd(command)
if err != nil {
log.Warn("error while checking IP", err)
log.Warn("Error while running command : ", err)
}

log.Debug("Go back to orignal namspace")

netns.Set(origns)
err = netns.Set(origns)
if err != nil {
log.Warn("Error while going back to the original namespace: ", err)
return
}

log.Debug("Cleaning ...")
}
Expand Down Expand Up @@ -238,7 +260,7 @@ func newNS() (*netns.NsHandle, error) {
}

src := fmt.Sprintf("/proc/%d/ns/net", pid)
target := getNsName()
target := nsPath

log.Debugf("Create file %s", target)
// Create an empty file
Expand All @@ -248,9 +270,14 @@ func newNS() (*netns.NsHandle, error) {
return nil, err
}
// And close it
file.Close()
err = file.Close()
if err != nil {
log.Warn(err)
return nil, err
}

log.Debugf("Mount %s", target)

// Mount the namespace in /var/run/netns so it becomes a named namespace
if err := syscall.Mount(src, target, "proc", syscall.MS_BIND|syscall.MS_NOEXEC|syscall.MS_NOSUID|syscall.MS_NODEV, ""); err != nil {
return nil, err
Expand All @@ -259,33 +286,28 @@ func newNS() (*netns.NsHandle, error) {
return &newns, nil
}

// getNsName gets the default namespace name : w000t$PID$
func getNsName() string {
pid := os.Getpid()
return fmt.Sprintf("/var/run/netns/w000t%d", pid)
}

func delNS(ns *netns.NsHandle) error {
// deleteNS will delete the given namespace
func deleteNS(ns *netns.NsHandle) error {
// Close the nsHandler
err := ns.Close()
if err != nil {
log.Warn("Error while closing", err)
log.Warn("Error while closing the namespace: ", err)
return err
}

// Unmount the named namespace
target := getNsName()
target := nsPath

log.Debugf("Unmounting %s", target)
if err := syscall.Unmount(target, 0); err != nil {
log.Warn("Error while unmounting", err)
log.Warnf("Error while unmounting %s : %s", target, err)
return err
}

// Delete the namespace file
log.Debugf("Deleting %s", target)
if err := os.Remove(target); err != nil {
log.Warn(err)
log.Warn("Error while deleting %s : %s", target, err)
return err
}

Expand Down