Skip to content

Commit e82f639

Browse files
authored
link: add Detach()
Signed-off-by: Florian Lehner <[email protected]>
1 parent f87d8e6 commit e82f639

File tree

8 files changed

+70
-0
lines changed

8 files changed

+70
-0
lines changed

internal/cmd/gentypes/main.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,10 @@ import (
609609
rename("relative_fd", "relative_fd_or_id"),
610610
},
611611
},
612+
{
613+
"LinkDetach", retError, "link_detach", "BPF_LINK_DETACH",
614+
nil,
615+
},
612616
{
613617
"LinkUpdate", retError, "link_update", "BPF_LINK_UPDATE",
614618
nil,

internal/sys/types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,16 @@ func LinkCreateUprobeMulti(attr *LinkCreateUprobeMultiAttr) (*FD, error) {
10641064
return NewFD(int(fd))
10651065
}
10661066

1067+
type LinkDetachAttr struct {
1068+
_ structs.HostLayout
1069+
LinkFd uint32
1070+
}
1071+
1072+
func LinkDetach(attr *LinkDetachAttr) error {
1073+
_, err := BPF(BPF_LINK_DETACH, unsafe.Pointer(attr), unsafe.Sizeof(*attr))
1074+
return err
1075+
}
1076+
10671077
type LinkGetFdByIdAttr struct {
10681078
_ structs.HostLayout
10691079
Id LinkID

link/cgroup.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ func (cg *progAttachCgroup) Unpin() error {
167167
return fmt.Errorf("can't unpin cgroup: %w", ErrNotSupported)
168168
}
169169

170+
func (cg *progAttachCgroup) Detach() error {
171+
return fmt.Errorf("can't detach cgroup: %w", ErrNotSupported)
172+
}
173+
170174
func (cg *progAttachCgroup) Info() (*Info, error) {
171175
return nil, fmt.Errorf("can't get cgroup info: %w", ErrNotSupported)
172176
}

link/link.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/cilium/ebpf/btf"
1010
"github.com/cilium/ebpf/internal"
1111
"github.com/cilium/ebpf/internal/sys"
12+
"github.com/cilium/ebpf/internal/unix"
1213
)
1314

1415
// Type is the kind of link.
@@ -40,6 +41,11 @@ type Link interface {
4041
// not called.
4142
Close() error
4243

44+
// Detach the link from its corresponding attachment point.
45+
//
46+
// May return an error wrapping ErrNotSupported.
47+
Detach() error
48+
4349
// Info returns metadata on a link.
4450
//
4551
// May return an error wrapping ErrNotSupported.
@@ -225,6 +231,24 @@ func (l *RawLink) UpdateArgs(opts RawLinkUpdateOptions) error {
225231
return nil
226232
}
227233

234+
// Detach the link from its corresponding attachment point.
235+
func (l *RawLink) Detach() error {
236+
attr := sys.LinkDetachAttr{
237+
LinkFd: l.fd.Uint(),
238+
}
239+
240+
err := sys.LinkDetach(&attr)
241+
242+
switch {
243+
case errors.Is(err, unix.EOPNOTSUPP):
244+
return internal.ErrNotSupported
245+
case err != nil:
246+
return fmt.Errorf("detach link: %w", err)
247+
default:
248+
return nil
249+
}
250+
}
251+
228252
// Info returns metadata about the link.
229253
//
230254
// Linktype specific metadata is not included and can be retrieved

link/link_other_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,15 @@ func mustLoadProgram(tb testing.TB, typ ebpf.ProgramType, attachType ebpf.Attach
141141

142142
return prog
143143
}
144+
145+
func TestDetachLinkFail(t *testing.T) {
146+
prog := mustLoadProgram(t, ebpf.Kprobe, 0, "")
147+
defer prog.Close()
148+
149+
uprobeLink, err := bashEx.Uprobe(bashSym, prog, nil)
150+
qt.Assert(t, qt.IsNil(err))
151+
defer uprobeLink.Close()
152+
153+
err = uprobeLink.Detach()
154+
qt.Assert(t, qt.ErrorIs(err, ErrNotSupported), qt.Commentf("got error: %s", err))
155+
}

link/link_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ func TestUnpinRawLink(t *testing.T) {
5656
qt.Assert(t, qt.IsFalse(link.IsPinned()))
5757
}
5858

59+
func TestDetachRawLink(t *testing.T) {
60+
link, _ := newRawLink(t)
61+
62+
if err := link.Detach(); err != nil {
63+
t.Fatal(err)
64+
}
65+
}
66+
5967
func TestRawLinkLoadPinnedWithOptions(t *testing.T) {
6068
link, path := newPinnedRawLink(t)
6169
defer link.Close()

link/perf_event.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ func (pi *perfEventIoctl) Unpin() error {
199199
return fmt.Errorf("perf event ioctl unpin: %w", ErrNotSupported)
200200
}
201201

202+
func (pi *perfEventIoctl) Detach() error {
203+
return fmt.Errorf("perf event ioctl detach: %w", ErrNotSupported)
204+
}
205+
202206
func (pi *perfEventIoctl) Info() (*Info, error) {
203207
return nil, fmt.Errorf("perf event ioctl info: %w", ErrNotSupported)
204208
}

link/raw_tracepoint.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ func (frt *simpleRawTracepoint) Unpin() error {
7474
return fmt.Errorf("unpin raw_tracepoint: %w", ErrNotSupported)
7575
}
7676

77+
func (frt *simpleRawTracepoint) Detach() error {
78+
return fmt.Errorf("detach raw_tracepoint: %w", ErrNotSupported)
79+
}
80+
7781
func (frt *simpleRawTracepoint) Info() (*Info, error) {
7882
return nil, fmt.Errorf("can't get raw_tracepoint info: %w", ErrNotSupported)
7983
}

0 commit comments

Comments
 (0)