mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Prefer Netlink calls over ioctl
As seen in https://github.com/docker/docker/issues/14738 there is general instability in the later kernels under race conditions when ioctl calls are used in parallel with netlink calls for various operations. (We are yet to narrow down to the exact root-cause on the kernel). For those older kernels which doesnt support some of the netlink APIs, we can fallback to using ioctl calls. Hence bringing back the original code that used netlink (https://github.com/docker/libnetwork/pull/349). Also, there was an existing bug in bridge creation using netlink which was setting bridge mac during bridge creation. That operation is not supported in the netlink library (and doesnt throw an error either). Included a fix for that condition by setting the bridge mac after creating the bridge. Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
parent
94791877ee
commit
6901ea51dc
2 changed files with 31 additions and 7 deletions
|
@ -763,17 +763,26 @@ func (d *driver) DeleteNetwork(nid types.UUID) error {
|
|||
}
|
||||
|
||||
func addToBridge(ifaceName, bridgeName string) error {
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
link, err := netlink.LinkByName(ifaceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find interface %s: %v", ifaceName, err)
|
||||
}
|
||||
if err = netlink.LinkSetMaster(link,
|
||||
&netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}); err != nil {
|
||||
logrus.Debugf("Failed to add %s to bridge via netlink.Trying ioctl: %v", ifaceName, err)
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find network interface %s: %v", ifaceName, err)
|
||||
}
|
||||
|
||||
master, err := net.InterfaceByName(bridgeName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find bridge %s: %v", bridgeName, err)
|
||||
master, err := net.InterfaceByName(bridgeName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not find bridge %s: %v", bridgeName, err)
|
||||
}
|
||||
|
||||
return ioctlAddToBridge(iface, master)
|
||||
}
|
||||
|
||||
return ioctlAddToBridge(iface, master)
|
||||
return nil
|
||||
}
|
||||
|
||||
func setHairpinMode(link netlink.Link, enable bool) error {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/pkg/parsers/kernel"
|
||||
"github.com/docker/libnetwork/netutils"
|
||||
"github.com/vishvananda/netlink"
|
||||
)
|
||||
|
||||
|
@ -32,7 +35,19 @@ func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
|
|||
setMac = kv.Kernel > 3 || (kv.Kernel == 3 && kv.Major >= 3)
|
||||
}
|
||||
|
||||
return ioctlCreateBridge(config.BridgeName, setMac)
|
||||
if err = netlink.LinkAdd(i.Link); err != nil {
|
||||
logrus.Debugf("Failed to create bridge %s via netlink. Trying ioctl", config.BridgeName)
|
||||
return ioctlCreateBridge(config.BridgeName, setMac)
|
||||
}
|
||||
|
||||
if setMac {
|
||||
hwAddr := netutils.GenerateRandomMAC()
|
||||
if err = netlink.LinkSetHardwareAddr(i.Link, hwAddr); err != nil {
|
||||
return fmt.Errorf("failed to set bridge mac-address %s : %s", hwAddr, err.Error())
|
||||
}
|
||||
logrus.Debugf("Setting bridge mac address to %s", hwAddr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// SetupDeviceUp ups the given bridge interface.
|
||||
|
|
Loading…
Reference in a new issue