github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/drivers/bridge/setup_verify.go (about)

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