utils_solaris.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // +build solaris
  2. package netutils
  3. import (
  4. "fmt"
  5. "net"
  6. "os/exec"
  7. "strings"
  8. "github.com/docker/libnetwork/ipamutils"
  9. "github.com/vishvananda/netlink"
  10. )
  11. var (
  12. networkGetRoutesFct func(netlink.Link, int) ([]netlink.Route, error)
  13. )
  14. // CheckRouteOverlaps checks whether the passed network overlaps with any existing routes
  15. func CheckRouteOverlaps(toCheck *net.IPNet) error {
  16. return nil
  17. }
  18. // ElectInterfaceAddresses looks for an interface on the OS with the specified name
  19. // and returns returns all its IPv4 and IPv6 addresses in CIDR notation.
  20. // If a failure in retrieving the addresses or no IPv4 address is found, an error is returned.
  21. // If the interface does not exist, it chooses from a predefined
  22. // list the first IPv4 address which does not conflict with other
  23. // interfaces on the system.
  24. func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
  25. var (
  26. v4Net *net.IPNet
  27. )
  28. out, err := exec.Command("/usr/sbin/ipadm", "show-addr",
  29. "-p", "-o", "addrobj,addr").Output()
  30. if err != nil {
  31. fmt.Println("failed to list interfaces on system")
  32. return nil, nil, err
  33. }
  34. alist := strings.Fields(string(out))
  35. for _, a := range alist {
  36. linkandaddr := strings.SplitN(a, ":", 2)
  37. if len(linkandaddr) != 2 {
  38. fmt.Println("failed to check interfaces on system: ", a)
  39. continue
  40. }
  41. gw := fmt.Sprintf("%s_gw0", name)
  42. link := strings.Split(linkandaddr[0], "/")[0]
  43. addr := linkandaddr[1]
  44. if gw != link {
  45. continue
  46. }
  47. _, ipnet, err := net.ParseCIDR(addr)
  48. if err != nil {
  49. fmt.Println("failed to parse address: ", addr)
  50. continue
  51. }
  52. v4Net = ipnet
  53. break
  54. }
  55. if v4Net == nil {
  56. v4Net, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
  57. if err != nil {
  58. return nil, nil, err
  59. }
  60. }
  61. return []*net.IPNet{v4Net}, nil, nil
  62. }
  63. // FindAvailableNetwork returns a network from the passed list which does not
  64. // overlap with existing interfaces in the system
  65. func FindAvailableNetwork(list []*net.IPNet) (*net.IPNet, error) {
  66. out, err := exec.Command("/usr/sbin/ipadm", "show-addr",
  67. "-p", "-o", "addr").Output()
  68. if err != nil {
  69. fmt.Println("failed to list interfaces on system")
  70. return nil, err
  71. }
  72. ipaddrs := strings.Fields(string(out))
  73. inuse := []*net.IPNet{}
  74. for _, ip := range ipaddrs {
  75. _, ipnet, err := net.ParseCIDR(ip)
  76. if err != nil {
  77. fmt.Println("failed to check interfaces on system: ", ip)
  78. continue
  79. }
  80. inuse = append(inuse, ipnet)
  81. }
  82. for _, avail := range list {
  83. is_avail := true
  84. for _, ipnet := range inuse {
  85. if NetworkOverlaps(avail, ipnet) {
  86. is_avail = false
  87. break
  88. }
  89. }
  90. if is_avail {
  91. return avail, nil
  92. }
  93. }
  94. return nil, fmt.Errorf("no available network")
  95. }