Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for loading and attaching raw_tracepoint programs #199

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions elf/elf.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
isCgroupSock := strings.HasPrefix(secName, "cgroup/sock")
isSocketFilter := strings.HasPrefix(secName, "socket")
isTracepoint := strings.HasPrefix(secName, "tracepoint/")
isRawTracepoint := strings.HasPrefix(secName, "raw_tracepoint/")
isSchedCls := strings.HasPrefix(secName, "sched_cls/")
isSchedAct := strings.HasPrefix(secName, "sched_act/")

Expand All @@ -579,6 +580,8 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
progType = uint32(C.BPF_PROG_TYPE_SOCKET_FILTER)
case isTracepoint:
progType = uint32(C.BPF_PROG_TYPE_TRACEPOINT)
case isRawTracepoint:
progType = uint32(C.BPF_PROG_TYPE_RAW_TRACEPOINT)
case isSchedCls:
progType = uint32(C.BPF_PROG_TYPE_SCHED_CLS)
case isSchedAct:
Expand All @@ -598,7 +601,7 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
}
}

if isKprobe || isKretprobe || isUprobe || isUretprobe || isCgroupSkb || isCgroupSock || isSocketFilter || isTracepoint || isSchedCls || isSchedAct {
if isKprobe || isKretprobe || isUprobe || isUretprobe || isCgroupSkb || isCgroupSock || isSocketFilter || isTracepoint || isRawTracepoint || isSchedCls || isSchedAct {
rdata, err := rsection.Data()
if err != nil {
return err
Expand Down Expand Up @@ -662,6 +665,12 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
insns: insns,
fd: int(progFd),
}
case isRawTracepoint:
b.rawTracepointPrograms[secName] = &RawTracepointProgram{
Name: secName,
insns: insns,
fd: int(progFd),
}
case isSchedCls:
fallthrough
case isSchedAct:
Expand Down Expand Up @@ -690,6 +699,7 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
isCgroupSock := strings.HasPrefix(secName, "cgroup/sock")
isSocketFilter := strings.HasPrefix(secName, "socket")
isTracepoint := strings.HasPrefix(secName, "tracepoint/")
isRawTracepoint := strings.HasPrefix(secName, "raw_tracepoint/")
isSchedCls := strings.HasPrefix(secName, "sched_cls/")
isSchedAct := strings.HasPrefix(secName, "sched_act/")

Expand All @@ -711,6 +721,8 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
progType = uint32(C.BPF_PROG_TYPE_SOCKET_FILTER)
case isTracepoint:
progType = uint32(C.BPF_PROG_TYPE_TRACEPOINT)
case isRawTracepoint:
progType = uint32(C.BPF_PROG_TYPE_RAW_TRACEPOINT)
case isSchedCls:
progType = uint32(C.BPF_PROG_TYPE_SCHED_CLS)
case isSchedAct:
Expand All @@ -730,7 +742,7 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
}
}

if isKprobe || isKretprobe || isUprobe || isUretprobe || isCgroupSkb || isCgroupSock || isSocketFilter || isTracepoint || isSchedCls || isSchedAct {
if isKprobe || isKretprobe || isUprobe || isUretprobe || isCgroupSkb || isCgroupSock || isSocketFilter || isTracepoint || isRawTracepoint || isSchedCls || isSchedAct {
data, err := section.Data()
if err != nil {
return err
Expand Down Expand Up @@ -789,6 +801,12 @@ func (b *Module) Load(parameters map[string]SectionParams) error {
insns: insns,
fd: int(progFd),
}
case isRawTracepoint:
b.rawTracepointPrograms[secName] = &RawTracepointProgram{
Name: secName,
insns: insns,
fd: int(progFd),
}
case isSchedCls:
fallthrough
case isSchedAct:
Expand Down
81 changes: 66 additions & 15 deletions elf/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ int bpf_detach_socket(int sock, int fd)
{
return setsockopt(sock, SOL_SOCKET, SO_DETACH_BPF, &fd, sizeof(fd));
}

int bpf_attach_raw_tracepoint(int prog_fd, char *tp_name)
{
union bpf_attr attr;

bzero(&attr, sizeof(attr));
attr.raw_tracepoint.name = (__u64) tp_name;
attr.raw_tracepoint.prog_fd = prog_fd;

return syscall(__NR_bpf, BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
}
*/
import "C"

Expand All @@ -96,14 +107,15 @@ type Module struct {
fileReader io.ReaderAt
file *elf.File

log []byte
maps map[string]*Map
probes map[string]*Kprobe
uprobes map[string]*Uprobe
cgroupPrograms map[string]*CgroupProgram
socketFilters map[string]*SocketFilter
tracepointPrograms map[string]*TracepointProgram
schedPrograms map[string]*SchedProgram
log []byte
maps map[string]*Map
probes map[string]*Kprobe
uprobes map[string]*Uprobe
cgroupPrograms map[string]*CgroupProgram
socketFilters map[string]*SocketFilter
tracepointPrograms map[string]*TracepointProgram
rawTracepointPrograms map[string]*RawTracepointProgram
schedPrograms map[string]*SchedProgram

compatProbe bool // try to be automatically convert function names depending on kernel versions (SyS_ and __x64_sys_)
}
Expand Down Expand Up @@ -154,6 +166,13 @@ type TracepointProgram struct {
efd int
}

// RawTracepointProgram represents a tracepoint program
type RawTracepointProgram struct {
Name string
insns *C.struct_bpf_insn
fd int
}

// SchedProgram represents a traffic classifier program
type SchedProgram struct {
Name string
Expand All @@ -163,13 +182,14 @@ type SchedProgram struct {

func newModule() *Module {
return &Module{
probes: make(map[string]*Kprobe),
uprobes: make(map[string]*Uprobe),
cgroupPrograms: make(map[string]*CgroupProgram),
socketFilters: make(map[string]*SocketFilter),
tracepointPrograms: make(map[string]*TracepointProgram),
schedPrograms: make(map[string]*SchedProgram),
log: make([]byte, 524288),
probes: make(map[string]*Kprobe),
uprobes: make(map[string]*Uprobe),
cgroupPrograms: make(map[string]*CgroupProgram),
socketFilters: make(map[string]*SocketFilter),
tracepointPrograms: make(map[string]*TracepointProgram),
rawTracepointPrograms: make(map[string]*RawTracepointProgram),
schedPrograms: make(map[string]*SchedProgram),
log: make([]byte, 524288),
}
}

Expand Down Expand Up @@ -352,6 +372,25 @@ func (b *Module) EnableTracepoint(secName string) error {
return err
}

func (b *Module) AttachRawTracepoint(secName string) error {
prog, ok := b.rawTracepointPrograms[secName]
if !ok {
return fmt.Errorf("no such raw tracepoint program %q", secName)
}
progFd := prog.fd

name := strings.Split(secName, "raw_tracepoint/")

tpNameCS := C.CString(name[1])
res, err := C.bpf_attach_raw_tracepoint(C.int(progFd), tpNameCS)
C.free(unsafe.Pointer(tpNameCS))

if res < 0 {
return fmt.Errorf("failed to attach raw tracepoint: %v", err)
}
return nil
}

// IterKprobes returns a channel that emits the kprobes that included in the
// module.
func (b *Module) IterKprobes() <-chan *Kprobe {
Expand Down Expand Up @@ -665,6 +704,15 @@ func (b *Module) closeTracepointPrograms() error {
return nil
}

func (b *Module) closeRawTracepointPrograms() error {
for _, program := range b.rawTracepointPrograms {
if err := syscall.Close(program.fd); err != nil {
return fmt.Errorf("error closing raw tracepoint program fd: %v", err)
}
}
return nil
}

func (b *Module) closeCgroupPrograms() error {
for _, program := range b.cgroupPrograms {
if err := syscall.Close(program.fd); err != nil {
Expand Down Expand Up @@ -765,6 +813,9 @@ func (b *Module) CloseExt(options map[string]CloseOptions) error {
if err := b.closeTracepointPrograms(); err != nil {
return err
}
if err := b.closeRawTracepointPrograms(); err != nil {
return err
}
if err := b.closeSocketFilters(); err != nil {
return err
}
Expand Down