Skip to content

Commit ae3ab27

Browse files
twaapoti-mo
andcommitted
prog: Allow explicit ifindex specification
Signed-off-by: Aapo Poutanen <[email protected]> Co-authored-by: Timo Beckers <[email protected]>
1 parent dad18d7 commit ae3ab27

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

prog.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ type ProgramSpec struct {
110110
// Type determines at which hook in the kernel a program will run.
111111
Type ProgramType
112112

113+
// Network interface index the user intends to attach this program to after
114+
// loading. Only valid for some program types.
115+
//
116+
// Provides driver-specific context about the target interface to the
117+
// verifier, required when using certain BPF helpers.
118+
Ifindex uint32
119+
113120
// AttachType of the program, needed to differentiate allowed context
114121
// accesses in some newer program types like CGroupSockAddr.
115122
//
@@ -280,6 +287,7 @@ func newProgramWithOptions(spec *ProgramSpec, opts ProgramOptions, c *btf.Cache)
280287
ProgName: maybeFillObjName(spec.Name),
281288
ProgType: sys.ProgType(progType),
282289
ProgFlags: spec.Flags,
290+
ProgIfindex: spec.Ifindex,
283291
ExpectedAttachType: sys.AttachType(spec.AttachType),
284292
License: sys.NewStringPointer(spec.License),
285293
KernVersion: kv,

prog_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,11 +643,14 @@ func TestProgramRejectIncorrectByteOrder(t *testing.T) {
643643
}
644644
}
645645

646+
// This uses unkeyed fields on purpose to force setting a non-zero value when
647+
// a new field is added.
646648
func TestProgramSpecCopy(t *testing.T) {
647649
a := &ProgramSpec{
648650
"test",
649651
1,
650652
1,
653+
1,
651654
"attach",
652655
nil, // Can't copy Program
653656
"section",
@@ -902,6 +905,35 @@ func TestProgramTargetsKernelModule(t *testing.T) {
902905
qt.Assert(t, qt.IsTrue(ps.targetsKernelModule()))
903906
}
904907

908+
func TestProgramLoadBoundToDevice(t *testing.T) {
909+
testutils.SkipOnOldKernel(t, "6.3", "device-bound XDP programs")
910+
911+
ins := asm.Instructions{
912+
asm.LoadImm(asm.R0, 2, asm.DWord).WithSymbol("out"),
913+
asm.Return(),
914+
}
915+
916+
_, err := NewProgram(&ProgramSpec{
917+
Type: XDP,
918+
Ifindex: math.MaxUint32,
919+
AttachType: AttachXDP,
920+
Instructions: ins,
921+
Flags: sys.BPF_F_XDP_DEV_BOUND_ONLY,
922+
License: "MIT",
923+
})
924+
testutils.SkipIfNotSupportedOnOS(t, err)
925+
926+
// Binding to loopback leads to crashes, yet is only explicitly disallowed
927+
// since 3595599fa836 ("net: xdp: Disallow attaching device-bound programs in
928+
// generic mode"). This only landed in 6.14 and returns EOPNOTSUPP.
929+
//
930+
// However, since attaching to loopback quietly succeeds on older kernels, use
931+
// a non-existent ifindex to trigger EINVAL on all kernels. Without specifying
932+
// ifindex, loading the program succeeds if the kernel knows the
933+
// DEV_BOUND_ONLY flag.
934+
qt.Assert(t, qt.ErrorIs(err, unix.EINVAL))
935+
}
936+
905937
func BenchmarkNewProgram(b *testing.B) {
906938
testutils.SkipOnOldKernel(b, "5.18", "kfunc support")
907939
spec, err := LoadCollectionSpec(testutils.NativeFile(b, "testdata/kfunc-%s.elf"))

0 commit comments

Comments
 (0)