From 36521b04a2d476b5bb17ac7b740eeb5c61f77551 Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Wed, 10 Feb 2016 11:52:40 +0000 Subject: [PATCH] Utility function to enforce docker bridge addr_assign_type --- net/bridge.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/net/bridge.go b/net/bridge.go index 6845c0bf..83ad0b40 100644 --- a/net/bridge.go +++ b/net/bridge.go @@ -1,7 +1,9 @@ package net import ( + "errors" "fmt" + "io/ioutil" "net" "github.com/Sirupsen/logrus" @@ -39,6 +41,40 @@ func DetectBridgeType(weaveBridgeName, datapathName string) BridgeType { } } +var ErrSetBridgeMac = errors.New("Setting $DOCKER_BRIDGE MAC (mitigate https://github.com/docker/docker/issues/14908)") + +func EnforceAddrAssignType(bridgeName string) error { + addrAssignType, err := ioutil.ReadFile(fmt.Sprintf("/sys/class/net/%s/addr_assign_type", bridgeName)) + if err != nil { + return err + } + + // From include/uapi/linux/netdevice.h + // #define NET_ADDR_PERM 0 /* address is permanent (default) */ + // #define NET_ADDR_RANDOM 1 /* address is generated randomly */ + // #define NET_ADDR_STOLEN 2 /* address is stolen from other device */ + // #define NET_ADDR_SET 3 /* address is set using dev_set_mac_address() */ + // Note the file typically has a newline at the end, so we just look at the first char + if addrAssignType[0] != '3' { + link, err := netlink.LinkByName(bridgeName) + if err != nil { + return err + } + + mac, err := RandomMAC() + if err != nil { + return err + } + + if err := netlink.LinkSetHardwareAddr(link, mac); err != nil { + return err + } + return ErrSetBridgeMac + } + + return nil +} + func isBridge(link netlink.Link) bool { _, isBridge := link.(*netlink.Bridge) return isBridge