-
Notifications
You must be signed in to change notification settings - Fork 698
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
link: move BPF_PROG_ATTACH support into new package
Program.Attach and Program.Detach are low level interfaces: the semantics of flags, etc. depends on the kind of program you are trying to attach. At the same time they are useful as an escape hatch for features that the library doesn't yet support with a nicer API. Move the two functions into a separate link package, which will contain other primitives that handle attaching programs to various hooks. Future proof the API by using argument structs.
- Loading branch information
Showing
9 changed files
with
220 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package link | ||
|
||
import ( | ||
"github.com/cilium/ebpf" | ||
"github.com/cilium/ebpf/internal" | ||
|
||
"golang.org/x/xerrors" | ||
) | ||
|
||
type RawAttachProgramOptions struct { | ||
// File descriptor to attach to. This differs for each attach type. | ||
Target int | ||
// Program to attach. | ||
Program *ebpf.Program | ||
// Program to replace (cgroups). | ||
Replace *ebpf.Program | ||
// Attach must match the attach type of Program (and Replace). | ||
Attach ebpf.AttachType | ||
// Flags control the attach behaviour. This differs for each attach type. | ||
Flags uint32 | ||
} | ||
|
||
// RawAttachProgram is a low level wrapper around BPF_PROG_ATTACH. | ||
// | ||
// You should use one of the higher level abstractions available in this | ||
// package if possible. | ||
func RawAttachProgram(opts RawAttachProgramOptions) error { | ||
if err := haveProgAttach(); err != nil { | ||
return err | ||
} | ||
|
||
var replaceFd uint32 | ||
if opts.Replace != nil { | ||
replaceFd = uint32(opts.Replace.FD()) | ||
} | ||
|
||
attr := internal.BPFProgAttachAttr{ | ||
TargetFd: uint32(opts.Target), | ||
AttachBpfFd: uint32(opts.Program.FD()), | ||
ReplaceBpfFd: replaceFd, | ||
AttachType: uint32(opts.Attach), | ||
AttachFlags: uint32(opts.Flags), | ||
} | ||
|
||
if err := internal.BPFProgAttach(&attr); err != nil { | ||
return xerrors.Errorf("can't attach program: %s", err) | ||
} | ||
return nil | ||
} | ||
|
||
type RawDetachProgramOptions struct { | ||
Target int | ||
Program *ebpf.Program | ||
Attach ebpf.AttachType | ||
} | ||
|
||
// RawDetachProgram is a low level wrapper around BPF_PROG_DETACH. | ||
// | ||
// You should use one of the higher level abstractions available in this | ||
// package if possible. | ||
func RawDetachProgram(opts RawDetachProgramOptions) error { | ||
if err := haveProgAttach(); err != nil { | ||
return err | ||
} | ||
|
||
attr := internal.BPFProgDetachAttr{ | ||
TargetFd: uint32(opts.Target), | ||
AttachBpfFd: uint32(opts.Program.FD()), | ||
AttachType: uint32(opts.Attach), | ||
} | ||
if err := internal.BPFProgDetach(&attr); err != nil { | ||
return xerrors.Errorf("can't detach program: %s", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package link | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/cilium/ebpf" | ||
"github.com/cilium/ebpf/asm" | ||
"github.com/cilium/ebpf/internal/testutils" | ||
) | ||
|
||
func TestProgramAlter(t *testing.T) { | ||
testutils.SkipOnOldKernel(t, "4.13", "SkSKB type") | ||
|
||
var err error | ||
var prog *ebpf.Program | ||
prog, err = ebpf.NewProgram(&ebpf.ProgramSpec{ | ||
Type: ebpf.SkSKB, | ||
Instructions: asm.Instructions{ | ||
asm.LoadImm(asm.R0, 0, asm.DWord), | ||
asm.Return(), | ||
}, | ||
License: "MIT", | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer prog.Close() | ||
|
||
var sockMap *ebpf.Map | ||
sockMap, err = ebpf.NewMap(&ebpf.MapSpec{ | ||
Type: ebpf.MapType(15), // BPF_MAP_TYPE_SOCKMAP | ||
KeySize: 4, | ||
ValueSize: 4, | ||
MaxEntries: 2, | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer sockMap.Close() | ||
|
||
err = RawAttachProgram(RawAttachProgramOptions{ | ||
Target: sockMap.FD(), | ||
Program: prog, | ||
Attach: ebpf.AttachSkSKBStreamParser, | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = RawDetachProgram(RawDetachProgramOptions{ | ||
Target: sockMap.FD(), | ||
Program: prog, | ||
Attach: ebpf.AttachSkSKBStreamParser, | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package link | ||
|
||
import ( | ||
"github.com/cilium/ebpf" | ||
"github.com/cilium/ebpf/asm" | ||
"github.com/cilium/ebpf/internal" | ||
) | ||
|
||
var haveProgAttach = internal.FeatureTest("BPF_PROG_ATTACH", "4.10", func() (bool, error) { | ||
prog, err := ebpf.NewProgram(&ebpf.ProgramSpec{ | ||
Type: ebpf.CGroupSKB, | ||
AttachType: ebpf.AttachCGroupInetIngress, | ||
License: "MIT", | ||
Instructions: asm.Instructions{ | ||
asm.Mov.Imm(asm.R0, 0), | ||
asm.Return(), | ||
}, | ||
}) | ||
if err != nil { | ||
return false, nil | ||
} | ||
|
||
// BPF_PROG_ATTACH was introduced at the same time as CGgroupSKB, | ||
// so being able to load the program is enough to infer that we | ||
// have the syscall. | ||
prog.Close() | ||
return true, nil | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package link | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/cilium/ebpf/internal/testutils" | ||
) | ||
|
||
func TestHaveProgAttach(t *testing.T) { | ||
testutils.CheckFeatureTest(t, haveProgAttach) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters