2016-05-20 16:23:53 -04:00
|
|
|
// +build solaris
|
2016-03-04 17:13:12 -05:00
|
|
|
|
2016-05-20 16:23:53 -04:00
|
|
|
package netutils
|
2016-03-04 17:13:12 -05:00
|
|
|
|
|
|
|
import (
|
2016-05-20 16:23:53 -04:00
|
|
|
"fmt"
|
2016-03-04 17:13:12 -05:00
|
|
|
"net"
|
2016-05-20 16:23:53 -04:00
|
|
|
"os/exec"
|
|
|
|
"strings"
|
2016-04-21 14:20:01 -04:00
|
|
|
|
|
|
|
"github.com/docker/libnetwork/ipamutils"
|
2016-05-20 16:23:53 -04:00
|
|
|
"github.com/vishvananda/netlink"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
networkGetRoutesFct func(netlink.Link, int) ([]netlink.Route, error)
|
2016-03-04 17:13:12 -05:00
|
|
|
)
|
|
|
|
|
2016-05-20 16:23:53 -04:00
|
|
|
// CheckRouteOverlaps checks whether the passed network overlaps with any existing routes
|
|
|
|
func CheckRouteOverlaps(toCheck *net.IPNet) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2016-03-04 17:13:12 -05:00
|
|
|
// ElectInterfaceAddresses looks for an interface on the OS with the specified name
|
2016-09-17 01:40:44 -04:00
|
|
|
// and returns returns all its IPv4 and IPv6 addresses in CIDR notation.
|
|
|
|
// If a failure in retrieving the addresses or no IPv4 address is found, an error is returned.
|
|
|
|
// If the interface does not exist, it chooses from a predefined
|
|
|
|
// list the first IPv4 address which does not conflict with other
|
|
|
|
// interfaces on the system.
|
|
|
|
func ElectInterfaceAddresses(name string) ([]*net.IPNet, []*net.IPNet, error) {
|
2016-03-04 17:13:12 -05:00
|
|
|
var (
|
|
|
|
v4Net *net.IPNet
|
|
|
|
)
|
|
|
|
|
2016-05-20 16:23:53 -04:00
|
|
|
out, err := exec.Command("/usr/sbin/ipadm", "show-addr",
|
|
|
|
"-p", "-o", "addrobj,addr").Output()
|
2016-03-04 17:13:12 -05:00
|
|
|
if err != nil {
|
2016-05-20 16:23:53 -04:00
|
|
|
fmt.Println("failed to list interfaces on system")
|
2016-03-04 17:13:12 -05:00
|
|
|
return nil, nil, err
|
|
|
|
}
|
2016-05-20 16:23:53 -04:00
|
|
|
alist := strings.Fields(string(out))
|
|
|
|
for _, a := range alist {
|
|
|
|
linkandaddr := strings.SplitN(a, ":", 2)
|
|
|
|
if len(linkandaddr) != 2 {
|
|
|
|
fmt.Println("failed to check interfaces on system: ", a)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
gw := fmt.Sprintf("%s_gw0", name)
|
|
|
|
link := strings.Split(linkandaddr[0], "/")[0]
|
|
|
|
addr := linkandaddr[1]
|
|
|
|
if gw != link {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
_, ipnet, err := net.ParseCIDR(addr)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("failed to parse address: ", addr)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
v4Net = ipnet
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if v4Net == nil {
|
|
|
|
v4Net, err = FindAvailableNetwork(ipamutils.PredefinedBroadNetworks)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
}
|
2016-09-17 01:40:44 -04:00
|
|
|
return []*net.IPNet{v4Net}, nil, nil
|
2016-03-04 17:13:12 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// FindAvailableNetwork returns a network from the passed list which does not
|
|
|
|
// overlap with existing interfaces in the system
|
|
|
|
func FindAvailableNetwork(list []*net.IPNet) (*net.IPNet, error) {
|
2016-05-20 16:23:53 -04:00
|
|
|
out, err := exec.Command("/usr/sbin/ipadm", "show-addr",
|
|
|
|
"-p", "-o", "addr").Output()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("failed to list interfaces on system")
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
ipaddrs := strings.Fields(string(out))
|
|
|
|
inuse := []*net.IPNet{}
|
|
|
|
for _, ip := range ipaddrs {
|
|
|
|
_, ipnet, err := net.ParseCIDR(ip)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("failed to check interfaces on system: ", ip)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
inuse = append(inuse, ipnet)
|
|
|
|
}
|
|
|
|
for _, avail := range list {
|
|
|
|
is_avail := true
|
|
|
|
for _, ipnet := range inuse {
|
|
|
|
if NetworkOverlaps(avail, ipnet) {
|
|
|
|
is_avail = false
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if is_avail {
|
|
|
|
return avail, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, fmt.Errorf("no available network")
|
2016-03-04 17:13:12 -05:00
|
|
|
}
|