github.com/cilium/cilium@v1.16.2/pkg/socketlb/cgroup_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package socketlb 5 6 import ( 7 "errors" 8 "os" 9 "path/filepath" 10 "testing" 11 12 "github.com/cilium/ebpf" 13 "github.com/cilium/ebpf/asm" 14 "github.com/cilium/ebpf/link" 15 16 "github.com/cilium/cilium/pkg/testutils" 17 ) 18 19 func mustCgroupProgram(t *testing.T) *ebpf.Program { 20 p, err := ebpf.NewProgram(&ebpf.ProgramSpec{ 21 Type: ebpf.CGroupSKB, 22 Instructions: asm.Instructions{ 23 asm.Mov.Imm(asm.R0, 0), 24 asm.Return(), 25 }, 26 License: "Apache-2.0", 27 }) 28 if err != nil { 29 t.Skipf("cgroup programs not supported: %s", err) 30 } 31 return p 32 } 33 34 // Attach a program to a clean cgroup hook, no replacing necessary. 35 func TestAttachCgroup(t *testing.T) { 36 testutils.PrivilegedTest(t) 37 38 coll := &ebpf.Collection{ 39 Programs: map[string]*ebpf.Program{"test": mustCgroupProgram(t)}, 40 } 41 linkPath := testutils.TempBPFFS(t) 42 cgroupPath := testutils.TempCgroup(t) 43 44 if err := attachCgroup(coll, "test", cgroupPath, linkPath); err != nil { 45 t.Fatal(err) 46 } 47 48 if err := detachCgroup("test", cgroupPath, linkPath); err != nil { 49 t.Fatal(err) 50 } 51 } 52 53 // Replace an existing program attached using PROG_ATTACH. On newer kernels, 54 // this will attempt to replace a PROG_ATTACH with a bpf_link. 55 func TestAttachCgroupWithPreviousAttach(t *testing.T) { 56 testutils.PrivilegedTest(t) 57 58 prog := mustCgroupProgram(t) 59 coll := &ebpf.Collection{ 60 Programs: map[string]*ebpf.Program{"test": prog}, 61 } 62 63 linkPath := testutils.TempBPFFS(t) 64 cgroupPath := testutils.TempCgroup(t) 65 f, err := os.Open(cgroupPath) 66 if err != nil { 67 t.Fatal(err) 68 } 69 70 if err := link.RawAttachProgram(link.RawAttachProgramOptions{ 71 Target: int(f.Fd()), 72 Program: prog, 73 // Dummy attach type, must match the conclusion made by attachCgroup. 74 Attach: ebpf.AttachCGroupInetIngress, 75 }); err != nil { 76 t.Fatal(err) 77 } 78 79 if err := attachCgroup(coll, "test", cgroupPath, linkPath); err != nil { 80 t.Fatal(err) 81 } 82 83 if err := detachCgroup("test", cgroupPath, linkPath); err != nil { 84 t.Fatal(err) 85 } 86 } 87 88 // On kernels that support it, update a bpf_link attachment by opening a pin. 89 func TestAttachCgroupWithExistingLink(t *testing.T) { 90 testutils.PrivilegedTest(t) 91 92 prog := mustCgroupProgram(t) 93 coll := &ebpf.Collection{ 94 Programs: map[string]*ebpf.Program{"test": prog}, 95 } 96 97 linkPath := testutils.TempBPFFS(t) 98 cgroupPath := testutils.TempCgroup(t) 99 f, err := os.Open(cgroupPath) 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 l, err := link.AttachRawLink(link.RawLinkOptions{ 105 Target: int(f.Fd()), 106 Program: prog, 107 // Dummy attach type, must match the conclusion made by attachCgroup. 108 Attach: ebpf.AttachCGroupInetIngress, 109 }) 110 if errors.Is(err, ebpf.ErrNotSupported) { 111 t.Skip("bpf_link is not supported") 112 } 113 if err != nil { 114 t.Fatal(err) 115 } 116 117 if err := l.Pin(filepath.Join(linkPath, "test")); err != nil { 118 t.Fatal(err) 119 } 120 121 if err := attachCgroup(coll, "test", cgroupPath, linkPath); err != nil { 122 t.Fatal(err) 123 } 124 125 if err := detachCgroup("test", cgroupPath, linkPath); err != nil { 126 t.Fatal(err) 127 } 128 } 129 130 // Detach an existing PROG_ATTACH. 131 func TestDetachCGroupWithPreviousAttach(t *testing.T) { 132 testutils.PrivilegedTest(t) 133 134 prog := mustCgroupProgram(t) 135 linkPath := testutils.TempBPFFS(t) 136 cgroupPath := testutils.TempCgroup(t) 137 f, err := os.Open(cgroupPath) 138 if err != nil { 139 t.Fatal(err) 140 } 141 142 if err := link.RawAttachProgram(link.RawAttachProgramOptions{ 143 Target: int(f.Fd()), 144 Program: prog, 145 // Dummy attach type, must match the conclusion made by attachCgroup. 146 Attach: ebpf.AttachCGroupInetIngress, 147 }); err != nil { 148 t.Fatal(err) 149 } 150 151 if err := detachCgroup("test", cgroupPath, linkPath); err != nil { 152 t.Fatal(err) 153 } 154 } 155 156 // Detach an existing bpf_link. 157 func TestDetachCGroupWithExistingLink(t *testing.T) { 158 testutils.PrivilegedTest(t) 159 160 prog := mustCgroupProgram(t) 161 linkPath := testutils.TempBPFFS(t) 162 cgroupPath := testutils.TempCgroup(t) 163 f, err := os.Open(cgroupPath) 164 if err != nil { 165 t.Fatal(err) 166 } 167 168 l, err := link.AttachRawLink(link.RawLinkOptions{ 169 Target: int(f.Fd()), 170 Program: prog, 171 // Dummy attach type, must match the conclusion made by attachCgroup. 172 Attach: ebpf.AttachCGroupInetIngress, 173 }) 174 if errors.Is(err, ebpf.ErrNotSupported) { 175 t.Skip("bpf_link is not supported") 176 } 177 if err != nil { 178 t.Fatal(err) 179 } 180 if err := l.Pin(filepath.Join(linkPath, "test")); err != nil { 181 t.Fatal(err) 182 } 183 184 if err := detachCgroup("test", cgroupPath, linkPath); err != nil { 185 t.Fatal(err) 186 } 187 }