github.com/cilium/cilium@v1.16.2/pkg/datapath/loader/tcx_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 //go:build linux 5 6 package loader 7 8 import ( 9 "errors" 10 "testing" 11 "time" 12 13 "github.com/stretchr/testify/require" 14 15 "github.com/cilium/ebpf" 16 "github.com/cilium/ebpf/link" 17 18 "github.com/cilium/cilium/pkg/datapath/linux/probes" 19 "github.com/cilium/cilium/pkg/testutils" 20 "github.com/cilium/cilium/pkg/testutils/netns" 21 ) 22 23 func TestAttachDetachTCX(t *testing.T) { 24 testutils.PrivilegedTest(t) 25 26 skipTCXUnsupported(t) 27 28 ns := netns.NewNetNS(t) 29 ns.Do(func() error { 30 prog := mustTCProgramWithName(t, "cil_test") 31 linkDir := testutils.TempBPFFS(t) 32 33 // Attaching the same program twice should result in a link create and update. 34 require.NoError(t, upsertTCXProgram(lo, prog, "cil_test", linkDir, directionToParent(dirEgress))) 35 require.NoError(t, upsertTCXProgram(lo, prog, "cil_test", linkDir, directionToParent(dirEgress))) 36 37 // Query tcx programs. 38 hasPrograms, err := hasCiliumTCXLinks(lo, ebpf.AttachTCXEgress) 39 require.NoError(t, err) 40 require.True(t, hasPrograms) 41 42 // Detach the program. 43 err = detachSKBProgram(lo, "cil_test", linkDir, directionToParent(dirEgress)) 44 require.NoError(t, err) 45 46 // bpf_prog_query is eventually-consistent, retries may be necessary. 47 require.NoError(t, testutils.WaitUntil(func() bool { 48 hasPrograms, err := hasCiliumTCXLinks(lo, ebpf.AttachTCXIngress) 49 require.NoError(t, err) 50 return !hasPrograms 51 }, time.Second)) 52 53 return nil 54 }) 55 } 56 57 func TestHasCiliumTCXLinks(t *testing.T) { 58 testutils.PrivilegedTest(t) 59 60 skipTCXUnsupported(t) 61 62 ns := netns.NewNetNS(t) 63 ns.Do(func() error { 64 // No tcx progs attached, expect false. 65 hasPrograms, err := hasCiliumTCXLinks(lo, ebpf.AttachTCXEgress) 66 require.NoError(t, err) 67 require.False(t, hasPrograms) 68 69 l1, err := link.AttachTCX(link.TCXOptions{ 70 Program: mustTCProgram(t), 71 Attach: ebpf.AttachTCXEgress, 72 Interface: lo.Attrs().Index, 73 Anchor: link.Tail(), 74 }) 75 require.NoError(t, err) 76 77 // tcx program without cil_ prefix is attached, expect false. 78 hasPrograms, err = hasCiliumTCXLinks(lo, ebpf.AttachTCXEgress) 79 require.NoError(t, err) 80 require.False(t, hasPrograms) 81 82 l2, err := link.AttachTCX(link.TCXOptions{ 83 Program: mustTCProgramWithName(t, "cil_test"), 84 Attach: ebpf.AttachTCXEgress, 85 Interface: lo.Attrs().Index, 86 Anchor: link.Tail(), 87 }) 88 require.NoError(t, err) 89 90 // tcx program with cil_ prefix is attached, expect true. 91 hasPrograms, err = hasCiliumTCXLinks(lo, ebpf.AttachTCXEgress) 92 require.NoError(t, err) 93 require.True(t, hasPrograms) 94 95 require.NoError(t, l1.Close()) 96 require.NoError(t, l2.Close()) 97 98 return nil 99 }) 100 } 101 102 func skipTCXUnsupported(tb testing.TB) { 103 tb.Helper() 104 105 err := probes.HaveTCX() 106 if errors.Is(err, ebpf.ErrNotSupported) { 107 tb.Skip("tcx is not supported") 108 } 109 if err != nil { 110 tb.Fatalf("probing tcx support: %s", err) 111 } 112 }