Skip to content

Commit c5e9cb3

Browse files
hemanthmallati-mo
authored andcommitted
Add support for netkit
Signed-off-by: Hemanth Malla <[email protected]>
1 parent c74a234 commit c5e9cb3

File tree

9 files changed

+172
-3
lines changed

9 files changed

+172
-3
lines changed

.github/workflows/ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77

88
env:
99
TMPDIR: /tmp
10-
CI_MAX_KERNEL_VERSION: '6.6'
10+
CI_MAX_KERNEL_VERSION: '6.7'
1111
CI_MIN_CLANG_VERSION: '11'
1212
go_version: '~1.22'
1313
prev_go_version: '~1.21'

attachtype_string.go

+9-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/cmd/gentypes/main.go

+15
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,17 @@ import (
476476
rename("cnt", "count"),
477477
},
478478
},
479+
{
480+
"LinkCreateNetkit", retFd, "link_create", "BPF_LINK_CREATE",
481+
[]patch{
482+
choose(1, "target_ifindex"),
483+
choose(4, "netkit"),
484+
replace(enumTypes["AttachType"], "attach_type"),
485+
flattenAnon,
486+
flattenAnon,
487+
rename("relative_fd", "relative_fd_or_id"),
488+
},
489+
},
479490
{
480491
"LinkUpdate", retError, "link_update", "BPF_LINK_UPDATE",
481492
nil,
@@ -575,6 +586,9 @@ import (
575586
replace(enumTypes["AttachType"], "attach_type"),
576587
}},
577588
{"NetfilterLinkInfo", "netfilter", nil},
589+
{"NetkitLinkInfo", "netkit", []patch{
590+
replace(enumTypes["AttachType"], "attach_type"),
591+
}},
578592
}
579593

580594
sort.Slice(linkInfoExtraTypes, func(i, j int) bool {
@@ -604,6 +618,7 @@ import (
604618
{"kprobe_multi", "kprobe_multi"},
605619
{"perf_event", "perf_event"},
606620
{"tcx", "tcx"},
621+
{"netkit", "netkit"},
607622
})
608623
if err != nil {
609624
return nil, fmt.Errorf("splitting linkInfo: %w", err)

internal/sys/types.go

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

link/link.go

+5
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ func wrapRawLink(raw *RawLink) (_ Link, err error) {
104104
return &tcxLink{*raw}, nil
105105
case NetfilterType:
106106
return &netfilterLink{*raw}, nil
107+
case NetkitType:
108+
return &netkitLink{*raw}, nil
107109
default:
108110
return raw, nil
109111
}
@@ -140,6 +142,7 @@ type NetNsInfo sys.NetNsLinkInfo
140142
type XDPInfo sys.XDPLinkInfo
141143
type TCXInfo sys.TcxLinkInfo
142144
type NetfilterInfo sys.NetfilterLinkInfo
145+
type NetkitInfo sys.NetkitLinkInfo
143146

144147
// Tracing returns tracing type-specific link info.
145148
//
@@ -343,6 +346,8 @@ func (l *RawLink) Info() (*Info, error) {
343346
extra = &TCXInfo{}
344347
case NetfilterType:
345348
extra = &NetfilterInfo{}
349+
case NetkitType:
350+
extra = &NetkitInfo{}
346351
default:
347352
return nil, fmt.Errorf("unknown link info type: %d", info.Type)
348353
}

link/netkit.go

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package link
2+
3+
import (
4+
"fmt"
5+
"runtime"
6+
7+
"github.com/cilium/ebpf"
8+
"github.com/cilium/ebpf/internal/sys"
9+
)
10+
11+
type NetkitOptions struct {
12+
// Index of the interface to attach to.
13+
Interface int
14+
// Program to attach.
15+
Program *ebpf.Program
16+
// One of the AttachNetkit* constants.
17+
Attach ebpf.AttachType
18+
// Attach relative to an anchor. Optional.
19+
Anchor Anchor
20+
// Only attach if the expected revision matches.
21+
ExpectedRevision uint64
22+
// Flags control the attach behaviour. Specify an Anchor instead of
23+
// F_LINK, F_ID, F_BEFORE, F_AFTER and R_REPLACE. Optional.
24+
Flags uint32
25+
}
26+
27+
func AttachNetkit(opts NetkitOptions) (Link, error) {
28+
if opts.Interface < 0 {
29+
return nil, fmt.Errorf("interface %d is out of bounds", opts.Interface)
30+
}
31+
32+
if opts.Flags&anchorFlags != 0 {
33+
return nil, fmt.Errorf("disallowed flags: use Anchor to specify attach target")
34+
}
35+
36+
attr := sys.LinkCreateNetkitAttr{
37+
ProgFd: uint32(opts.Program.FD()),
38+
AttachType: sys.AttachType(opts.Attach),
39+
TargetIfindex: uint32(opts.Interface),
40+
ExpectedRevision: opts.ExpectedRevision,
41+
Flags: opts.Flags,
42+
}
43+
44+
if opts.Anchor != nil {
45+
fdOrID, flags, err := opts.Anchor.anchor()
46+
if err != nil {
47+
return nil, fmt.Errorf("attach netkit link: %w", err)
48+
}
49+
50+
attr.RelativeFdOrId = fdOrID
51+
attr.Flags |= flags
52+
}
53+
54+
fd, err := sys.LinkCreateNetkit(&attr)
55+
runtime.KeepAlive(opts.Program)
56+
runtime.KeepAlive(opts.Anchor)
57+
if err != nil {
58+
if haveFeatErr := haveNetkit(); haveFeatErr != nil {
59+
return nil, haveFeatErr
60+
}
61+
return nil, fmt.Errorf("attach netkit link: %w", err)
62+
}
63+
64+
return &netkitLink{RawLink{fd, ""}}, nil
65+
}
66+
67+
type netkitLink struct {
68+
RawLink
69+
}
70+
71+
var _ Link = (*netkitLink)(nil)

link/syscalls.go

+36
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const (
2727
TCXType = sys.BPF_LINK_TYPE_TCX
2828
UprobeMultiType = sys.BPF_LINK_TYPE_UPROBE_MULTI
2929
NetfilterType = sys.BPF_LINK_TYPE_NETFILTER
30+
NetkitType = sys.BPF_LINK_TYPE_NETKIT
3031
)
3132

3233
var haveProgAttach = internal.NewFeatureTest("BPF_PROG_ATTACH", "4.10", func() error {
@@ -162,3 +163,38 @@ var haveTCX = internal.NewFeatureTest("tcx", "6.6", func() error {
162163
}
163164
return errors.New("syscall succeeded unexpectedly")
164165
})
166+
167+
var haveNetkit = internal.NewFeatureTest("netkit", "6.7", func() error {
168+
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{
169+
Type: ebpf.SchedCLS,
170+
License: "MIT",
171+
Instructions: asm.Instructions{
172+
asm.Mov.Imm(asm.R0, 0),
173+
asm.Return(),
174+
},
175+
})
176+
177+
if err != nil {
178+
return internal.ErrNotSupported
179+
}
180+
181+
defer prog.Close()
182+
attr := sys.LinkCreateNetkitAttr{
183+
// We rely on this being checked during the syscall.
184+
// With an otherwise correct payload we expect ENODEV here
185+
// as an indication that the feature is present.
186+
TargetIfindex: ^uint32(0),
187+
ProgFd: uint32(prog.FD()),
188+
AttachType: sys.AttachType(ebpf.AttachNetkitPrimary),
189+
}
190+
191+
_, err = sys.LinkCreateNetkit(&attr)
192+
193+
if errors.Is(err, unix.ENODEV) {
194+
return nil
195+
}
196+
if err != nil {
197+
return ErrNotSupported
198+
}
199+
return errors.New("syscall succeeded unexpectedly")
200+
})

link/syscalls_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ func TestHaveProgQuery(t *testing.T) {
2525
func TestHaveTCX(t *testing.T) {
2626
testutils.CheckFeatureTest(t, haveTCX)
2727
}
28+
29+
func TestHaveNetkit(t *testing.T) {
30+
testutils.CheckFeatureTest(t, haveNetkit)
31+
}

types.go

+7
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ const (
220220
AttachTCXIngress = AttachType(sys.BPF_TCX_INGRESS)
221221
AttachTCXEgress = AttachType(sys.BPF_TCX_EGRESS)
222222
AttachTraceUprobeMulti = AttachType(sys.BPF_TRACE_UPROBE_MULTI)
223+
AttachCgroupUnixConnect = AttachType(sys.BPF_CGROUP_UNIX_CONNECT)
224+
AttachCgroupUnixSendmsg = AttachType(sys.BPF_CGROUP_UNIX_SENDMSG)
225+
AttachCgroupUnixRecvmsg = AttachType(sys.BPF_CGROUP_UNIX_RECVMSG)
226+
AttachCgroupUnixGetpeername = AttachType(sys.BPF_CGROUP_UNIX_GETPEERNAME)
227+
AttachCgroupUnixGetsockname = AttachType(sys.BPF_CGROUP_UNIX_GETSOCKNAME)
228+
AttachNetkitPrimary = AttachType(sys.BPF_NETKIT_PRIMARY)
229+
AttachNetkitPeer = AttachType(sys.BPF_NETKIT_PEER)
223230
)
224231

225232
// AttachFlags of the eBPF program used in BPF_PROG_ATTACH command

0 commit comments

Comments
 (0)