github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/drivers/bridge/setup_device.go (about)

     1  package bridge
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"github.com/docker/libnetwork/netutils"
    10  	"github.com/sirupsen/logrus"
    11  	"github.com/vishvananda/netlink"
    12  )
    13  
    14  // SetupDevice create a new bridge interface/
    15  func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
    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  	// Set the bridge's MAC address. Requires kernel version 3.3 or up.
    30  	hwAddr := netutils.GenerateRandomMAC()
    31  	i.Link.Attrs().HardwareAddr = hwAddr
    32  	logrus.Debugf("Setting bridge mac address to %s", hwAddr)
    33  
    34  	if err := i.nlh.LinkAdd(i.Link); err != nil {
    35  		logrus.Debugf("Failed to create bridge %s via netlink. Trying ioctl", config.BridgeName)
    36  		return ioctlCreateBridge(config.BridgeName, hwAddr.String())
    37  	}
    38  
    39  	return nil
    40  }
    41  
    42  func setupDefaultSysctl(config *networkConfiguration, i *bridgeInterface) error {
    43  	// Disable IPv6 router advertisements originating on the bridge
    44  	sysPath := filepath.Join("/proc/sys/net/ipv6/conf/", config.BridgeName, "accept_ra")
    45  	if _, err := os.Stat(sysPath); err != nil {
    46  		logrus.
    47  			WithField("bridge", config.BridgeName).
    48  			WithField("syspath", sysPath).
    49  			Info("failed to read ipv6 net.ipv6.conf.<bridge>.accept_ra")
    50  		return nil
    51  	}
    52  	if err := ioutil.WriteFile(sysPath, []byte{'0', '\n'}, 0644); err != nil {
    53  		logrus.WithError(err).Warn("unable to disable IPv6 router advertisement")
    54  	}
    55  	return nil
    56  }
    57  
    58  // SetupDeviceUp ups the given bridge interface.
    59  func setupDeviceUp(config *networkConfiguration, i *bridgeInterface) error {
    60  	err := i.nlh.LinkSetUp(i.Link)
    61  	if err != nil {
    62  		return fmt.Errorf("Failed to set link up for %s: %v", config.BridgeName, err)
    63  	}
    64  
    65  	// Attempt to update the bridge interface to refresh the flags status,
    66  	// ignoring any failure to do so.
    67  	if lnk, err := i.nlh.LinkByName(config.BridgeName); err == nil {
    68  		i.Link = lnk
    69  	} else {
    70  		logrus.Warnf("Failed to retrieve link for interface (%s): %v", config.BridgeName, err)
    71  	}
    72  	return nil
    73  }