github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/bridge/setup_verify_linux.go (about) 1 package bridge 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/containerd/log" 9 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/ns" 10 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/types" 11 "github.com/vishvananda/netlink" 12 ) 13 14 // setupVerifyAndReconcile checks what IP addresses the given i interface has and ensures that they match the passed 15 // network config. It also removes any extra unicast IPv6 addresses found. 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 !config.Internal && 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.IPNet != 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 && !config.Internal && !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 log.G(context.TODO()).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 }