github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/libnetwork/drivers/bridge/setup_verify.go (about)

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