github.com/cilium/cilium@v1.16.2/pkg/datapath/linux/ipsec/xfrm_state_cache_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package ipsec 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 "github.com/vishvananda/netlink" 11 12 "github.com/cilium/cilium/pkg/datapath/linux/linux_defaults" 13 "github.com/cilium/cilium/pkg/option" 14 "github.com/cilium/cilium/pkg/time" 15 16 baseclocktest "k8s.io/utils/clock/testing" 17 ) 18 19 func TestXfrmStateListCache(t *testing.T) { 20 setupIPSecSuitePrivileged(t) 21 22 backupOption := option.Config.EnableIPSecXfrmStateCaching 23 defer func() { 24 option.Config.EnableIPSecXfrmStateCaching = backupOption 25 }() 26 option.Config.EnableIPSecXfrmStateCaching = true 27 28 fakeClock := baseclocktest.NewFakeClock(time.Now()) 29 xfrmStateCache := newTestableXfrmStateListCache( 30 time.Second, 31 fakeClock, 32 ) 33 34 require.True(t, xfrmStateCache.isExpired(), "Cache should be expired in the beginning") 35 36 cleanIPSecStatesAndPolicies(t) 37 state := initDummyXfrmState() 38 err := createDummyXfrmState(state) 39 require.NoError(t, err) 40 41 // Make sure that cache is correctly fetched in the beginning 42 stateList, err := xfrmStateCache.XfrmStateList() 43 require.NoError(t, err) 44 require.Len(t, stateList, 1) 45 require.Equal(t, state.Spi, stateList[0].Spi) 46 47 cleanIPSecStatesAndPolicies(t) 48 // Check that cache does not expire instantly 49 stateList, err = xfrmStateCache.XfrmStateList() 50 require.NoError(t, err) 51 require.Len(t, stateList, 1) 52 53 // Move time by half second and make sure cache still did not expire 54 fakeClock.Step(time.Millisecond * 500) 55 require.False(t, xfrmStateCache.isExpired(), "Cache should not be expired before timeout") 56 stateList, err = xfrmStateCache.XfrmStateList() 57 require.NoError(t, err) 58 require.Len(t, stateList, 1) 59 60 // Invalidate cache by moving time by 501 more miliseconds 61 fakeClock.Step(time.Millisecond * 501) 62 require.True(t, xfrmStateCache.isExpired(), "Cache should be expired after timeout") 63 stateList, err = xfrmStateCache.XfrmStateList() 64 require.NoError(t, err) 65 require.Len(t, stateList, 0) 66 67 // Create new xfrm state and check that cache is atomatically updated 68 require.True(t, xfrmStateCache.isExpired(), "Cache should be expired when list is empty") 69 err = xfrmStateCache.XfrmStateAdd(state) 70 require.NoError(t, err) 71 require.True(t, xfrmStateCache.isExpired(), "Cache should be expired after adding new state") 72 stateList, err = xfrmStateCache.XfrmStateList() 73 require.NoError(t, err) 74 require.Len(t, stateList, 1) 75 require.Equal(t, stateList[0].OutputMark.Value, uint32(linux_defaults.RouteMarkDecrypt)) 76 77 // Update xfrm state and check that cache is automatically updated 78 require.False(t, xfrmStateCache.isExpired(), "Cache should not be expired before timeout") 79 // Switch to encrypt as this is the only value we update 80 state.OutputMark.Value = linux_defaults.RouteMarkEncrypt 81 err = xfrmStateCache.XfrmStateUpdate(state) 82 require.NoError(t, err) 83 require.True(t, xfrmStateCache.isExpired(), "Cache should be expired after updating state") 84 stateList, err = xfrmStateCache.XfrmStateList() 85 require.NoError(t, err) 86 require.Len(t, stateList, 1) 87 require.Equal(t, stateList[0].OutputMark.Value, uint32(linux_defaults.RouteMarkEncrypt)) 88 89 // Delete xfrm state and check that cache is automatically updated 90 require.False(t, xfrmStateCache.isExpired(), "Cache should not be expired before timeout") 91 err = xfrmStateCache.XfrmStateDel(state) 92 require.NoError(t, err) 93 require.True(t, xfrmStateCache.isExpired(), "Cache should be expired after deleting state") 94 stateList, err = xfrmStateCache.XfrmStateList() 95 require.NoError(t, err) 96 require.Len(t, stateList, 0) 97 } 98 99 func TestXfrmStateListCacheDisabled(t *testing.T) { 100 setupIPSecSuitePrivileged(t) 101 102 backupOption := option.Config.EnableIPSecXfrmStateCaching 103 defer func() { 104 option.Config.EnableIPSecXfrmStateCaching = backupOption 105 }() 106 option.Config.EnableIPSecXfrmStateCaching = false 107 108 xfrmStateCache := newTestableXfrmStateListCache( 109 time.Second, 110 baseclocktest.NewFakeClock(time.Now()), 111 ) 112 113 state := initDummyXfrmState() 114 err := createDummyXfrmState(state) 115 require.NoError(t, err) 116 117 require.True(t, xfrmStateCache.isExpired(), "Cache should be expired in the beginning") 118 // Make sure that cache is correctly fetched in the beginning 119 stateList, err := xfrmStateCache.XfrmStateList() 120 require.NoError(t, err) 121 require.Len(t, stateList, 1) 122 123 // And is still expired 124 require.True(t, xfrmStateCache.isExpired(), "Cache should be stil expired as it's disabled") 125 } 126 127 func cleanIPSecStatesAndPolicies(t *testing.T) { 128 xfrmStateList, err := netlink.XfrmStateList(netlink.FAMILY_ALL) 129 if err != nil { 130 t.Fatalf("Can't list XFRM states: %v", err) 131 } 132 133 for _, s := range xfrmStateList { 134 if err := netlink.XfrmStateDel(&s); err != nil { 135 t.Fatalf("Can't delete XFRM state: %v", err) 136 } 137 138 } 139 140 xfrmPolicyList, err := netlink.XfrmPolicyList(netlink.FAMILY_ALL) 141 if err != nil { 142 t.Fatalf("Can't list XFRM policies: %v", err) 143 } 144 145 for _, p := range xfrmPolicyList { 146 if err := netlink.XfrmPolicyDel(&p); err != nil { 147 t.Fatalf("Can't delete XFRM policy: %v", err) 148 } 149 } 150 }