aboutsummaryrefslogtreecommitdiffstats
path: root/internal/pkg/network/iface.go
blob: d49566ddba46acc078710353f75c67844b8bd762 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package network

import (
	"errors"
	"net"
	"syscall"

	"github.com/vishvananda/netlink"
)

//GetDefaultGateway return default gateway of the network namespace
func GetDefaultGateway() (string, error) {
	routes, err := netlink.RouteList(nil, syscall.AF_INET)
	if err != nil {
		return "", err
	}

	for _, route := range routes {
		if route.Dst == nil || route.Dst.String() == "0.0.0.0/0" {
			if route.Gw.To4() == nil {
				return "", errors.New("Found default route but could not determine gateway")
			}
			return route.Gw.To4().String(), nil
		}
	}

	return "", errors.New("Unable to find default route")
}

//CheckRoute return bool isPresent
func CheckRoute(dst, gw string) (bool, error) {
	var isPresent bool
	routes, err := netlink.RouteList(nil, syscall.AF_INET)
	if err != nil {
		return isPresent, err
	}

	for _, route := range routes {
		if route.Dst.String() == dst && route.Gw.To4().String() == gw {
			isPresent = true
		}
	}

	return isPresent, nil

}

// GetDefaultGatewayInterface return default gateway interface link
func GetDefaultGatewayInterface() (*net.Interface, error) {
	routes, err := netlink.RouteList(nil, syscall.AF_INET)
	if err != nil {
		return nil, err
	}

	for _, route := range routes {
		if route.Dst == nil || route.Dst.String() == "0.0.0.0/0" {
			if route.LinkIndex <= 0 {
				return nil, errors.New("Found default route but could not determine interface")
			}
			return net.InterfaceByIndex(route.LinkIndex)
		}
	}

	return nil, errors.New("Unable to find default route")
}

func getIfaceAddrs(iface *net.Interface) ([]netlink.Addr, error) {

	link := &netlink.Device{
		netlink.LinkAttrs{
			Index: iface.Index,
		},
	}

	return netlink.AddrList(link, syscall.AF_INET)
}

//GetInterfaceIP4Addr return IP4addr of a interface
func GetInterfaceIP4Addr(iface *net.Interface) (netlink.Addr, error) {
	addrs, err := getIfaceAddrs(iface)
	if err != nil {
		return netlink.Addr{}, err
	}

	// prefer non link-local addr
	var ll netlink.Addr

	for _, addr := range addrs {
		if addr.IP.To4() == nil {
			continue
		}

		if addr.IP.IsGlobalUnicast() {
			return addr, nil
		}

		if addr.IP.IsLinkLocalUnicast() {
			ll = addr
		}
	}

	if ll.IP.To4() != nil {
		// didn't find global but found link-local. it'll do.
		return ll, nil
	}

	return netlink.Addr{}, errors.New("No IPv4 address found for given interface")
}

//GetHostNetwork return default gateway interface network
func GetHostNetwork() (string, error) {

	iface, err := GetDefaultGatewayInterface()
	if err != nil {
		log.Error(err, "error in gettting default gateway interface")
		return "", err
	}

	ipv4addr, err := GetInterfaceIP4Addr(iface)
	if err != nil {
		log.Error(err, "error in gettting default gateway interface IPv4 address")
		return "", err
	}

	_, ipv4Net, err := net.ParseCIDR(ipv4addr.IPNet.String())
	if err != nil {
		log.Error(err, "error in gettting default gateway interface network")
		return "", err
	}

	return ipv4Net.String(), nil
}