github.com/rawahars/moby@v24.0.4+incompatible/libnetwork/drivers/bridge/setup_verify.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package bridge
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/docker/docker/libnetwork/ns"
    11  	"github.com/docker/docker/libnetwork/types"
    12  	"github.com/sirupsen/logrus"
    13  	"github.com/vishvananda/netlink"
    14  )
    15  
    16  func setupVerifyAndReconcile(config *networkConfiguration, i *bridgeInterface) error {
    17  	// Fetch a slice of IPv4 addresses and a slice of IPv6 addresses from the bridge.
    18  	addrsv4, addrsv6, err := i.addresses()
    19  	if err != nil {
    20  		return fmt.Errorf("Failed to verify ip addresses: %v", err)
    21  	}
    22  
    23  	addrv4, _ := selectIPv4Address(addrsv4, config.AddressIPv4)
    24  
    25  	// Verify that the bridge does have an IPv4 address.
    26  	if addrv4.IPNet == nil {
    27  		return &ErrNoIPAddr{}
    28  	}
    29  
    30  	// Verify that the bridge IPv4 address matches the requested configuration.
    31  	if config.AddressIPv4 != nil && !addrv4.IP.Equal(config.AddressIPv4.IP) {
    32  		return &IPv4AddrNoMatchError{IP: addrv4.IP, CfgIP: config.AddressIPv4.IP}
    33  	}
    34  
    35  	// Verify that one of the bridge IPv6 addresses matches the requested
    36  	// configuration.
    37  	if config.EnableIPv6 && !findIPv6Address(netlink.Addr{IPNet: bridgeIPv6}, addrsv6) {
    38  		return (*IPv6AddrNoMatchError)(bridgeIPv6)
    39  	}
    40  
    41  	// Release any residual IPv6 address that might be there because of older daemon instances
    42  	for _, addrv6 := range addrsv6 {
    43  		addrv6 := addrv6
    44  		if addrv6.IP.IsGlobalUnicast() && !types.CompareIPNet(addrv6.IPNet, i.bridgeIPv6) {
    45  			if err := i.nlh.AddrDel(i.Link, &addrv6); err != nil {
    46  				logrus.Warnf("Failed to remove residual IPv6 address %s from bridge: %v", addrv6.IPNet, err)
    47  			}
    48  		}
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  func findIPv6Address(addr netlink.Addr, addresses []netlink.Addr) bool {
    55  	for _, addrv6 := range addresses {
    56  		if addrv6.String() == addr.String() {
    57  			return true
    58  		}
    59  	}
    60  	return false
    61  }
    62  
    63  func bridgeInterfaceExists(name string) (bool, error) {
    64  	nlh := ns.NlHandle()
    65  	link, err := nlh.LinkByName(name)
    66  	if err != nil {
    67  		if strings.Contains(err.Error(), "Link not found") {
    68  			return false, nil
    69  		}
    70  		return false, fmt.Errorf("failed to check bridge interface existence: %v", err)
    71  	}
    72  
    73  	if link.Type() == "bridge" {
    74  		return true, nil
    75  	}
    76  	return false, fmt.Errorf("existing interface %s is not a bridge", name)
    77  }