github.com/cilium/cilium@v1.16.2/pkg/maps/nodemap/node_map_v2_privileged_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package nodemap 5 6 import ( 7 "net" 8 "testing" 9 10 ciliumebpf "github.com/cilium/ebpf" 11 "github.com/cilium/ebpf/rlimit" 12 "github.com/stretchr/testify/require" 13 14 "github.com/cilium/cilium/pkg/bpf" 15 "github.com/cilium/cilium/pkg/maps/encrypt" 16 "github.com/cilium/cilium/pkg/testutils" 17 ) 18 19 func setupNodeMapV2TestSuite(tb testing.TB) { 20 testutils.PrivilegedTest(tb) 21 22 bpf.CheckOrMountFS("") 23 err := rlimit.RemoveMemlock() 24 require.Nil(tb, err) 25 } 26 27 func TestNodeMapV2(t *testing.T) { 28 setupNodeMapV2TestSuite(t) 29 nodeMap := newMapV2("test_cilium_node_map_v2", "test_cilium_node_map", Config{ 30 NodeMapMax: 1024, 31 }) 32 err := nodeMap.init() 33 require.Nil(t, err) 34 defer nodeMap.bpfMap.Unpin() 35 36 bpfNodeIDMap := map[uint16]string{} 37 bpfNodeSPI := []uint8{} 38 toMap := func(key *NodeKey, val *NodeValueV2) { 39 address := key.IP.String() 40 if key.Family == bpf.EndpointKeyIPv4 { 41 address = net.IP(key.IP[:net.IPv4len]).String() 42 } 43 bpfNodeIDMap[val.NodeID] = address 44 bpfNodeSPI = append(bpfNodeSPI, uint8(val.SPI)) 45 } 46 47 err = nodeMap.IterateWithCallback(toMap) 48 require.Nil(t, err) 49 require.Equal(t, 0, len(bpfNodeIDMap)) 50 require.Equal(t, 0, len(bpfNodeSPI)) 51 52 err = nodeMap.Update(net.ParseIP("10.1.0.0"), 10, 3) 53 require.Nil(t, err) 54 err = nodeMap.Update(net.ParseIP("10.1.0.1"), 20, 3) 55 require.Nil(t, err) 56 57 bpfNodeIDMap = map[uint16]string{} 58 bpfNodeSPI = []uint8{} 59 err = nodeMap.IterateWithCallback(toMap) 60 require.Nil(t, err) 61 require.Equal(t, 2, len(bpfNodeIDMap)) 62 require.Equal(t, 2, len(bpfNodeSPI)) 63 64 err = nodeMap.Delete(net.ParseIP("10.1.0.0")) 65 require.Nil(t, err) 66 67 bpfNodeIDMap = map[uint16]string{} 68 bpfNodeSPI = []uint8{} 69 err = nodeMap.IterateWithCallback(toMap) 70 require.Nil(t, err) 71 require.Equal(t, 1, len(bpfNodeIDMap)) 72 require.Equal(t, 1, len(bpfNodeSPI)) 73 74 // ensure we see mirrored writes in MapV1 75 _, err = ciliumebpf.LoadPinnedMap(bpf.MapPath("test_cilium_node_map"), nil) 76 require.Nil(t, err) 77 78 toMapV1 := func(key *NodeKey, val *NodeValue) { 79 address := key.IP.String() 80 if key.Family == bpf.EndpointKeyIPv4 { 81 address = net.IP(key.IP[:net.IPv4len]).String() 82 } 83 require.Equal(t, address, bpfNodeIDMap[val.NodeID]) 84 } 85 86 err = nodeMap.v1Map.IterateWithCallback(toMapV1) 87 require.Nil(t, err) 88 } 89 90 func TestNodeMapMigration(t *testing.T) { 91 setupNodeMapV2TestSuite(t) 92 name1 := "test_cilium_node_map" 93 name2 := "test_cilium_node_map_v2" 94 emName := "test_cilium_encrypt_state" 95 96 IP1 := net.ParseIP("10.1.0.0") 97 IP2 := net.ParseIP("10.1.0.1") 98 99 var ID1 uint16 = 10 100 var ID2 uint16 = 20 101 102 nodeMapV1 := newMap(name1, Config{ 103 NodeMapMax: 1024, 104 }) 105 err := nodeMapV1.init() 106 require.Nil(t, err) 107 108 nodeMapV2 := newMapV2(name2, name1, Config{ 109 NodeMapMax: 1024, 110 }) 111 err = nodeMapV2.init() 112 require.Nil(t, err) 113 defer nodeMapV2.bpfMap.Unpin() 114 115 encryptMap := encrypt.NewMap(emName) 116 err = encryptMap.OpenOrCreate() 117 require.Nil(t, err) 118 119 encrypt.MapUpdateContextWithMap(encryptMap, 0, 3) 120 121 err = nodeMapV1.Update(IP1, ID1) 122 require.Nil(t, err) 123 err = nodeMapV1.Update(IP2, ID2) 124 require.Nil(t, err) 125 126 // done with nodeMapV2 so we can close the FD. 127 nodeMapV2.close() 128 129 // do migration 130 err = nodeMapV2.migrateV1(name1, emName) 131 require.Nil(t, err) 132 133 // confirm we see the correct migrated values 134 parse := func(k *NodeKey, v *NodeValueV2) { 135 // family must be IPv4 136 if k.Family != bpf.EndpointKeyIPv4 { 137 t.Fatalf("want: %v, got: %v", bpf.EndpointKeyIPv4, k.Family) 138 } 139 ipv4 := net.IP(k.IP[:4]) 140 141 // IP must equal one of our two test IPs 142 if !ipv4.Equal(IP1) && !ipv4.Equal(IP2) { 143 t.Fatalf("migrated NodeValue2 did not match any IP under test: %v", ipv4) 144 } 145 146 // SPI must equal 3 147 if v.SPI != 3 { 148 t.Fatalf("wanted: 3, got: %v", v.SPI) 149 } 150 } 151 MapV2(nodeMapV2).IterateWithCallback(parse) 152 153 // confirm that the map is not removed, we need it around to mirror writes 154 m, err := ciliumebpf.LoadPinnedMap(bpf.MapPath(name1), nil) 155 require.Nil(t, err) 156 require.NotNil(t, m) 157 }