diff --git a/libnetwork/sandbox/namespace_linux.go b/libnetwork/sandbox/namespace_linux.go index 5d32d504e5..17bae5f14c 100644 --- a/libnetwork/sandbox/namespace_linux.go +++ b/libnetwork/sandbox/namespace_linux.go @@ -109,6 +109,54 @@ func loopbackUp() error { return netlink.LinkSetUp(iface) } +func (n *networkNamespace) RemoveInterface(i *Interface) error { + runtime.LockOSThread() + defer runtime.UnlockOSThread() + + origns, err := netns.Get() + if err != nil { + return err + } + defer origns.Close() + + f, err := os.OpenFile(n.path, os.O_RDONLY, 0) + if err != nil { + return fmt.Errorf("failed get network namespace %q: %v", n.path, err) + } + defer f.Close() + + nsFD := f.Fd() + if err = netns.Set(netns.NsHandle(nsFD)); err != nil { + return err + } + defer netns.Set(origns) + + // Find the network inteerface identified by the DstName attribute. + iface, err := netlink.LinkByName(i.DstName) + if err != nil { + return err + } + + // Down the interface before configuring + if err := netlink.LinkSetDown(iface); err != nil { + return err + } + + err = netlink.LinkSetName(iface, i.SrcName) + if err != nil { + fmt.Println("LinkSetName failed: ", err) + return err + } + + // Move the network interface to init namespace. + if err := netlink.LinkSetNsPid(iface, 1); err != nil { + fmt.Println("LinkSetNsPid failed: ", err) + return err + } + + return nil +} + func (n *networkNamespace) AddInterface(i *Interface) error { runtime.LockOSThread() defer runtime.UnlockOSThread() diff --git a/libnetwork/sandbox/sandbox.go b/libnetwork/sandbox/sandbox.go index 254e3417b0..b535f6e430 100644 --- a/libnetwork/sandbox/sandbox.go +++ b/libnetwork/sandbox/sandbox.go @@ -23,6 +23,10 @@ type Sandbox interface { // interface according to the specified settings. AddInterface(*Interface) error + // Remove an interface from the sandbox by renamin to original name + // and moving it out of the sandbox. + RemoveInterface(*Interface) error + // Set default IPv4 gateway for the sandbox SetGateway(gw net.IP) error