github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/drivers/bridge/setup_device.go (about) 1 package bridge 2 3 import ( 4 "fmt" 5 6 "github.com/Sirupsen/logrus" 7 "github.com/docker/docker/pkg/parsers/kernel" 8 "github.com/docker/libnetwork/netutils" 9 "github.com/vishvananda/netlink" 10 ) 11 12 // SetupDevice create a new bridge interface/ 13 func setupDevice(config *networkConfiguration, i *bridgeInterface) error { 14 var setMac bool 15 16 // We only attempt to create the bridge when the requested device name is 17 // the default one. 18 if config.BridgeName != DefaultBridgeName && config.DefaultBridge { 19 return NonDefaultBridgeExistError(config.BridgeName) 20 } 21 22 // Set the bridgeInterface netlink.Bridge. 23 i.Link = &netlink.Bridge{ 24 LinkAttrs: netlink.LinkAttrs{ 25 Name: config.BridgeName, 26 }, 27 } 28 29 // Only set the bridge's MAC address if the kernel version is > 3.3, as it 30 // was not supported before that. 31 kv, err := kernel.GetKernelVersion() 32 if err != nil { 33 logrus.Errorf("Failed to check kernel versions: %v. Will not assign a MAC address to the bridge interface", err) 34 } else { 35 setMac = kv.Kernel > 3 || (kv.Kernel == 3 && kv.Major >= 3) 36 } 37 38 if err = i.nlh.LinkAdd(i.Link); err != nil { 39 logrus.Debugf("Failed to create bridge %s via netlink. Trying ioctl", config.BridgeName) 40 return ioctlCreateBridge(config.BridgeName, setMac) 41 } 42 43 if setMac { 44 hwAddr := netutils.GenerateRandomMAC() 45 if err = i.nlh.LinkSetHardwareAddr(i.Link, hwAddr); err != nil { 46 return fmt.Errorf("failed to set bridge mac-address %s : %s", hwAddr, err.Error()) 47 } 48 logrus.Debugf("Setting bridge mac address to %s", hwAddr) 49 } 50 return err 51 } 52 53 // SetupDeviceUp ups the given bridge interface. 54 func setupDeviceUp(config *networkConfiguration, i *bridgeInterface) error { 55 err := i.nlh.LinkSetUp(i.Link) 56 if err != nil { 57 return fmt.Errorf("Failed to set link up for %s: %v", config.BridgeName, err) 58 } 59 60 // Attempt to update the bridge interface to refresh the flags status, 61 // ignoring any failure to do so. 62 if lnk, err := i.nlh.LinkByName(config.BridgeName); err == nil { 63 i.Link = lnk 64 } else { 65 logrus.Warnf("Failed to retrieve link for interface (%s): %v", config.BridgeName, err) 66 } 67 return nil 68 }