From 9a7cceced64d408ba2fad72513faf4d1b66e2d4d Mon Sep 17 00:00:00 2001 From: Jana Radhakrishnan Date: Wed, 6 May 2015 00:32:38 +0000 Subject: [PATCH 1/2] Added RemoveInterface support to sandbox. Signed-off-by: Jana Radhakrishnan --- sandbox/namespace_linux.go | 48 ++++++++++++++++++++++++++++++++++++++ sandbox/sandbox.go | 4 ++++ 2 files changed, 52 insertions(+) diff --git a/sandbox/namespace_linux.go b/sandbox/namespace_linux.go index 5d32d50..17bae5f 100644 --- a/sandbox/namespace_linux.go +++ b/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/sandbox/sandbox.go b/sandbox/sandbox.go index 254e341..b535f6e 100644 --- a/sandbox/sandbox.go +++ b/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 From 511459f1af748df976c6b903be5c5e06e457a8b4 Mon Sep 17 00:00:00 2001 From: Jana Radhakrishnan Date: Wed, 6 May 2015 00:33:08 +0000 Subject: [PATCH 2/2] Properly handle Leave by - Removing interface from the sandbox - Deleting Iptable rules in the bridge driver Signed-off-by: Jana Radhakrishnan --- drivers/bridge/bridge.go | 29 +++++++++++++++++++++-------- endpoint.go | 13 +++++++++++++ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/drivers/bridge/bridge.go b/drivers/bridge/bridge.go index 9461abc..0d39905 100644 --- a/drivers/bridge/bridge.go +++ b/drivers/bridge/bridge.go @@ -60,11 +60,12 @@ type ContainerConfiguration struct { } type bridgeEndpoint struct { - id types.UUID - intf *sandbox.Interface - macAddress net.HardwareAddr - config *EndpointConfiguration // User specified parameters - portMapping []netutils.PortBinding // Operation port bindings + id types.UUID + intf *sandbox.Interface + macAddress net.HardwareAddr + config *EndpointConfiguration // User specified parameters + containerConfig *ContainerConfiguration + portMapping []netutils.PortBinding // Operation port bindings } type bridgeNetwork struct { @@ -643,6 +644,8 @@ func (d *driver) Leave(nid, eid types.UUID, options map[string]interface{}) erro } func (d *driver) link(nid, eid types.UUID, options map[string]interface{}, enable bool) error { + var cc *ContainerConfiguration + network, err := d.getNetwork(nid) if err != nil { return err @@ -656,10 +659,15 @@ func (d *driver) link(nid, eid types.UUID, options map[string]interface{}, enabl return EndpointNotFoundError(eid) } - cc, err := parseContainerOptions(options) - if err != nil { - return err + if enable { + cc, err = parseContainerOptions(options) + if err != nil { + return err + } + } else { + cc = endpoint.containerConfig } + if cc == nil { return nil } @@ -725,6 +733,11 @@ func (d *driver) link(nid, eid types.UUID, options map[string]interface{}, enabl l.Disable() } } + + if enable { + endpoint.containerConfig = cc + } + return nil } diff --git a/endpoint.go b/endpoint.go index 70dd600..35b58af 100644 --- a/endpoint.go +++ b/endpoint.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" + "github.com/Sirupsen/logrus" "github.com/docker/docker/pkg/etchosts" "github.com/docker/docker/pkg/resolvconf" "github.com/docker/libnetwork/driverapi" @@ -275,6 +276,18 @@ func (ep *endpoint) Leave(containerID string, options ...EndpointOption) error { n := ep.network err := n.driver.Leave(n.id, ep.id, ep.context) + + sinfo := ep.SandboxInfo() + if sinfo != nil { + sb := ep.network.ctrlr.sandboxGet(ep.container.data.SandboxKey) + for _, i := range sinfo.Interfaces { + err = sb.RemoveInterface(i) + if err != nil { + logrus.Debugf("Remove interface failed: %v", err) + } + } + } + ep.network.ctrlr.sandboxRm(ep.container.data.SandboxKey) ep.container = nil ep.context = nil