From 6cacb7019676648e9fac894e04e23e184b76fbe2 Mon Sep 17 00:00:00 2001 From: Jana Radhakrishnan Date: Mon, 29 Jun 2015 23:10:30 -0700 Subject: [PATCH] Fix networking issues in RHEL/Centos 6.6 Some parts of the bridge driver code needs to use a different kernel api or use the already existing apis in slightly different ways to make the bridge driver work in RHEL/Centos 6.6. This PR provides those fixes. Signed-off-by: Jana Radhakrishnan --- drivers/bridge/bridge.go | 42 +++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/bridge/bridge.go b/drivers/bridge/bridge.go index a0a3987..3cc417a 100644 --- a/drivers/bridge/bridge.go +++ b/drivers/bridge/bridge.go @@ -2,12 +2,14 @@ package bridge import ( "errors" + "fmt" "net" "os/exec" "strings" "sync" "github.com/Sirupsen/logrus" + bri "github.com/docker/libcontainer/netlink" "github.com/docker/libnetwork/driverapi" "github.com/docker/libnetwork/ipallocator" "github.com/docker/libnetwork/iptables" @@ -397,6 +399,20 @@ func (d *driver) DeleteNetwork(nid types.UUID) error { return err } +func addToBridge(ifaceName, bridgeName string) error { + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + return fmt.Errorf("could not find interface %s: %v", ifaceName, err) + } + + master, err := net.InterfaceByName(bridgeName) + if err != nil { + return fmt.Errorf("could not find bridge %s: %v", bridgeName, err) + } + + return bri.AddToBridge(iface, master) +} + func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error { var ( ipv6Addr *net.IPNet @@ -461,27 +477,27 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn }() // Generate a name for what will be the host side pipe interface - name1, err := generateIfaceName() + hostIfName, err := generateIfaceName() if err != nil { return err } // Generate a name for what will be the sandbox side pipe interface - name2, err := generateIfaceName() + containerIfName, err := generateIfaceName() if err != nil { return err } // Generate and add the interface pipe host <-> sandbox veth := &netlink.Veth{ - LinkAttrs: netlink.LinkAttrs{Name: name1, TxQLen: 0}, - PeerName: name2} + LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0}, + PeerName: containerIfName} if err = netlink.LinkAdd(veth); err != nil { return err } // Get the host side pipe interface handler - host, err := netlink.LinkByName(name1) + host, err := netlink.LinkByName(hostIfName) if err != nil { return err } @@ -492,7 +508,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn }() // Get the sandbox side pipe interface handler - sbox, err := netlink.LinkByName(name2) + sbox, err := netlink.LinkByName(containerIfName) if err != nil { return err } @@ -515,9 +531,8 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn } // Attach host side pipe interface into the bridge - if err = netlink.LinkSetMaster(host, - &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: config.BridgeName}}); err != nil { - return err + if err = addToBridge(hostIfName, config.BridgeName); err != nil { + return fmt.Errorf("adding interface %s to bridge %s failed: %v", hostIfName, config.BridgeName, err) } if !config.EnableUserlandProxy { @@ -534,11 +549,16 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn } ipv4Addr := &net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask} + // Down the interface before configuring mac address. + if err := netlink.LinkSetDown(sbox); err != nil { + return fmt.Errorf("could not set link down for container interface %s: %v", containerIfName, err) + } + // Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP. mac := electMacAddress(epConfig, ip4) err = netlink.LinkSetHardwareAddr(sbox, mac) if err != nil { - return err + return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err) } endpoint.macAddress = mac @@ -571,7 +591,7 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn // Create the sandbox side pipe interface intf := &sandbox.Interface{} - intf.SrcName = name2 + intf.SrcName = containerIfName intf.DstName = containerVethPrefix intf.Address = ipv4Addr