github.com/cilium/cilium@v1.16.2/pkg/node/address_linux_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 //go:build !darwin 5 6 package node 7 8 import ( 9 "fmt" 10 "net" 11 "testing" 12 13 "github.com/stretchr/testify/require" 14 "github.com/vishvananda/netlink" 15 16 "github.com/cilium/cilium/pkg/testutils" 17 ) 18 19 func setUpSuite(tb testing.TB) { 20 testutils.PrivilegedTest(tb) 21 } 22 23 func Test_firstGlobalV4Addr(t *testing.T) { 24 setUpSuite(t) 25 26 testCases := []struct { 27 name string 28 ipsOnInterface []string 29 preferredIP string 30 preferPublic bool 31 want string 32 }{ 33 { 34 name: "public IP preferred by default", 35 ipsOnInterface: []string{"192.168.0.1", "21.0.0.1"}, 36 want: "21.0.0.1", 37 }, 38 { 39 name: "prefer IP when not preferPublic", 40 ipsOnInterface: []string{"192.168.0.1", "21.0.0.1"}, 41 preferredIP: "192.168.0.1", 42 want: "192.168.0.1", 43 }, 44 { 45 name: "preferPublic when not prefer IP", 46 ipsOnInterface: []string{"192.168.0.1", "21.0.0.1"}, 47 preferPublic: true, 48 want: "21.0.0.1", 49 }, 50 { 51 name: "preferPublic when prefer IP", 52 ipsOnInterface: []string{"192.168.0.1", "21.0.0.1"}, 53 preferPublic: true, 54 preferredIP: "192.168.0.1", 55 want: "21.0.0.1", 56 }, 57 { 58 name: "primary IP preferred by default", 59 ipsOnInterface: []string{"192.168.0.2", "192.168.0.1"}, 60 want: "192.168.0.2", 61 }, 62 } 63 const ifName = "dummy_iface" 64 for _, tc := range testCases { 65 err := setupDummyDevice(ifName, tc.ipsOnInterface...) 66 require.NoError(t, err) 67 68 got, err := firstGlobalV4Addr(ifName, net.ParseIP(tc.preferredIP), tc.preferPublic) 69 require.NoError(t, err) 70 require.Equal(t, tc.want, got.String()) 71 removeDevice(ifName) 72 } 73 } 74 75 func setupDummyDevice(name string, ips ...string) error { 76 dummy := &netlink.Dummy{ 77 LinkAttrs: netlink.LinkAttrs{ 78 Name: name, 79 }, 80 } 81 if err := netlink.LinkAdd(dummy); err != nil { 82 return fmt.Errorf("netlink.LinkAdd failed: %w", err) 83 } 84 85 if err := netlink.LinkSetUp(dummy); err != nil { 86 removeDevice(name) 87 return fmt.Errorf("netlink.LinkSetUp failed: %w", err) 88 } 89 90 for _, ipStr := range ips { 91 ip := net.ParseIP(ipStr) 92 if ip == nil || ip.To4() == nil { 93 removeDevice(name) 94 return fmt.Errorf("invalid ipv4 IP : %v", ipStr) 95 } 96 ipnet := &net.IPNet{IP: ip, Mask: net.CIDRMask(32, 32)} 97 addr := &netlink.Addr{IPNet: ipnet} 98 if err := netlink.AddrAdd(dummy, addr); err != nil { 99 removeDevice(name) 100 return err 101 } 102 } 103 104 return nil 105 } 106 107 func removeDevice(name string) { 108 l, err := netlink.LinkByName(name) 109 if err == nil { 110 netlink.LinkDel(l) 111 } 112 }