github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/netutils/utils_solaris.go (about)

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