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 }