setup_verify.go 2.1 KB

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