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  }