github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/link/program_test.go (about) 1 package link 2 3 import ( 4 "fmt" 5 "net" 6 "testing" 7 8 "github.com/cilium/ebpf" 9 "github.com/cilium/ebpf/internal/testutils" 10 11 "github.com/go-quicktest/qt" 12 ) 13 14 func TestProgramAlter(t *testing.T) { 15 testutils.SkipOnOldKernel(t, "4.13", "SkSKB type") 16 17 prog := mustLoadProgram(t, ebpf.SkSKB, 0, "") 18 19 var sockMap *ebpf.Map 20 sockMap, err := ebpf.NewMap(&ebpf.MapSpec{ 21 Type: ebpf.MapType(15), // BPF_MAP_TYPE_SOCKMAP 22 KeySize: 4, 23 ValueSize: 4, 24 MaxEntries: 2, 25 }) 26 if err != nil { 27 t.Fatal(err) 28 } 29 defer sockMap.Close() 30 31 err = RawAttachProgram(RawAttachProgramOptions{ 32 Target: sockMap.FD(), 33 Program: prog, 34 Attach: ebpf.AttachSkSKBStreamParser, 35 }) 36 if err != nil { 37 t.Fatal(err) 38 } 39 40 err = RawDetachProgram(RawDetachProgramOptions{ 41 Target: sockMap.FD(), 42 Program: prog, 43 Attach: ebpf.AttachSkSKBStreamParser, 44 }) 45 if err != nil { 46 t.Fatal(err) 47 } 48 } 49 50 func TestRawAttachProgramAnchor(t *testing.T) { 51 testutils.SkipOnOldKernel(t, "6.6", "attach anchor") 52 53 iface, err := net.InterfaceByName("lo") 54 qt.Assert(t, qt.IsNil(err)) 55 56 a := mustLoadProgram(t, ebpf.SchedCLS, 0, "") 57 info, err := a.Info() 58 qt.Assert(t, qt.IsNil(err)) 59 aID, _ := info.ID() 60 61 err = RawAttachProgram(RawAttachProgramOptions{ 62 Target: iface.Index, 63 Program: a, 64 Attach: ebpf.AttachTCXIngress, 65 }) 66 qt.Assert(t, qt.IsNil(err)) 67 defer RawDetachProgram(RawDetachProgramOptions{ 68 Target: iface.Index, 69 Program: a, 70 Attach: ebpf.AttachTCXIngress, 71 }) 72 73 link, err := AttachTCX(TCXOptions{ 74 Interface: iface.Index, 75 Program: mustLoadProgram(t, ebpf.SchedCLS, 0, ""), 76 Attach: ebpf.AttachTCXIngress, 77 }) 78 qt.Assert(t, qt.IsNil(err)) 79 defer link.Close() 80 81 linkInfo, err := link.Info() 82 qt.Assert(t, qt.IsNil(err)) 83 84 b := mustLoadProgram(t, ebpf.SchedCLS, 0, "") 85 86 for _, anchor := range []Anchor{ 87 Head(), 88 Tail(), 89 AfterProgram(a), 90 AfterProgramByID(aID), 91 AfterLink(link), 92 AfterLinkByID(linkInfo.ID), 93 } { 94 t.Run(fmt.Sprintf("%T", anchor), func(t *testing.T) { 95 err := RawAttachProgram(RawAttachProgramOptions{ 96 Target: iface.Index, 97 Program: b, 98 Attach: ebpf.AttachTCXIngress, 99 Anchor: anchor, 100 }) 101 qt.Assert(t, qt.IsNil(err)) 102 103 // Detach doesn't allow first or last anchor. 104 if _, ok := anchor.(firstAnchor); ok { 105 anchor = nil 106 } else if _, ok := anchor.(lastAnchor); ok { 107 anchor = nil 108 } 109 110 err = RawDetachProgram(RawDetachProgramOptions{ 111 Target: iface.Index, 112 Program: b, 113 Attach: ebpf.AttachTCXIngress, 114 Anchor: anchor, 115 }) 116 qt.Assert(t, qt.IsNil(err)) 117 }) 118 } 119 120 // Check that legacy replacement with a program works. 121 err = RawAttachProgram(RawAttachProgramOptions{ 122 Target: iface.Index, 123 Program: b, 124 Attach: ebpf.AttachTCXIngress, 125 Anchor: ReplaceProgram(a), 126 }) 127 qt.Assert(t, qt.IsNil(err)) 128 129 err = RawDetachProgram(RawDetachProgramOptions{ 130 Target: iface.Index, 131 Program: b, 132 Attach: ebpf.AttachTCXIngress, 133 }) 134 qt.Assert(t, qt.IsNil(err)) 135 }