mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 04:06:03 +00:00
get ips from loopback interfaces
This commit is contained in:
parent
078d2e65b5
commit
432e74d245
@ -266,6 +266,36 @@ func getIPFromInterface(intfName string, forFamily AddressFamily, nw networkInte
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// getIPFromLoopbackInterface gets the IPs on a loopback interface and returns a global unicast address, if any.
|
||||
// The loopback interface must be up, the IP must in the family requested, and the IP must be a global unicast address.
|
||||
func getIPFromLoopbackInterface(forFamily AddressFamily, nw networkInterfacer) (net.IP, error) {
|
||||
intfs, err := nw.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, intf := range intfs {
|
||||
if !isInterfaceUp(&intf) {
|
||||
continue
|
||||
}
|
||||
if intf.Flags&(net.FlagLoopback) != 0 {
|
||||
addrs, err := nw.Addrs(&intf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klog.V(4).Infof("Interface %q has %d addresses :%v.", intf.Name, len(addrs), addrs)
|
||||
matchingIP, err := getMatchingGlobalIP(addrs, forFamily)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if matchingIP != nil {
|
||||
klog.V(4).Infof("Found valid IPv%d address %v for interface %q.", int(forFamily), matchingIP, intf.Name)
|
||||
return matchingIP, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// memberOf tells if the IP is of the desired family. Used for checking interface addresses.
|
||||
func memberOf(ip net.IP, family AddressFamily) bool {
|
||||
if ip.To4() != nil {
|
||||
@ -414,8 +444,8 @@ func chooseHostInterfaceFromRoute(routes []Route, nw networkInterfacer, addressF
|
||||
}
|
||||
// In case of network setups where default routes are present, but network
|
||||
// interfaces use only link-local addresses (e.g. as described in RFC5549).
|
||||
// the global IP is assigned to the loopback interface
|
||||
loopbackIP, err := getIPFromInterface(LoopbackInterfaceName, family, nw)
|
||||
// the global IP is assigned to the loopback interface, and we should use it
|
||||
loopbackIP, err := getIPFromLoopbackInterface(family, nw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -579,6 +579,33 @@ func TestGetIPFromInterface(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetIPFromLoopbackInterface(t *testing.T) {
|
||||
testCases := []struct {
|
||||
tcase string
|
||||
family AddressFamily
|
||||
nw networkInterfacer
|
||||
expected net.IP
|
||||
errStrFrag string
|
||||
}{
|
||||
{"ipv4", familyIPv4, linkLocalLoopbackNetworkInterface{}, net.ParseIP("10.1.1.1"), ""},
|
||||
{"ipv6", familyIPv6, linkLocalLoopbackNetworkInterface{}, net.ParseIP("fd00:1:1::1"), ""},
|
||||
{"no global ipv4", familyIPv4, loopbackNetworkInterface{}, nil, ""},
|
||||
{"no global ipv6", familyIPv6, loopbackNetworkInterface{}, nil, ""},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
ip, err := getIPFromLoopbackInterface(tc.family, tc.nw)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), tc.errStrFrag) {
|
||||
t.Errorf("case[%s]: Error string %q does not contain %q", tc.tcase, err, tc.errStrFrag)
|
||||
}
|
||||
} else if tc.errStrFrag != "" {
|
||||
t.Errorf("case[%s]: Error %q expected, but seen %v", tc.tcase, tc.errStrFrag, err)
|
||||
} else if !ip.Equal(tc.expected) {
|
||||
t.Errorf("case[%v]: expected %v, got %+v .err : %v", tc.tcase, tc.expected, ip, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestChooseHostInterfaceFromRoute(t *testing.T) {
|
||||
testCases := []struct {
|
||||
tcase string
|
||||
|
Loading…
Reference in New Issue
Block a user