diff --git a/main.go b/main.go index 69bc6d4..7a69a33 100644 --- a/main.go +++ b/main.go @@ -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() { @@ -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() } @@ -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") @@ -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 @@ -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 ...") } @@ -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 @@ -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 @@ -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 }