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  }