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

Update uprobe and uretprobe support #513

Open
wants to merge 2 commits into
base: main
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
15 changes: 9 additions & 6 deletions bpfprogs/nfconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -1389,12 +1389,15 @@ func (c *NFConfigs) DeleteProgramsOnInterfaceHelper(e *list.Element, ifaceName s
return fmt.Errorf("DeleteProgramsOnInterfaceHelper - failed LinkBPFPrograms %w", err)
}
}
// Check if list contains root program only then stop the root program.
if tmpPreviousBPF.Prev() == nil && tmpPreviousBPF.Next() == nil {
log.Info().Msgf("no ebpf programs are running, stopping root program")

if err := c.StopRootProgram(ifaceName, direction); err != nil {
return fmt.Errorf("failed to stop to root program of iface %s direction %v with err %w", ifaceName, direction, err)
// check if the program is not probes
if len(direction) > 1 {
// Check if list contains root program only then stop the root program.
if tmpPreviousBPF.Prev() == nil && tmpPreviousBPF.Next() == nil {
log.Info().Msgf("no ebpf programs are running, stopping root program")

if err := c.StopRootProgram(ifaceName, direction); err != nil {
return fmt.Errorf("failed to stop to root program of iface %s direction %v with err %w", ifaceName, direction, err)
}
}
}
return nil
Expand Down
95 changes: 83 additions & 12 deletions bpfprogs/probes.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,9 @@ func (b *BPF) LoadBPFProgramProbeType(prog *ebpf.Program, sectionName string) er
b.ProbeLinks = append(b.ProbeLinks, &tp)
case ebpf.Kprobe:
progType, hookName, _ = GetProgramSectionDetails(sectionName)
var kp link.Link
var err error
if strings.ToLower(progType) == models.KProbe {
kp, err = link.Kprobe(hookName, prog, nil)
if err != nil {
return fmt.Errorf("failed to link kprobe sec name %s error %v", sectionName, err)
}
} else if strings.ToLower(progType) == models.KRetProbe {
kp, err = link.Kretprobe(hookName, prog, nil)
if err != nil {
return fmt.Errorf("failed to link kprobe sec name %s error %v", sectionName, err)
}
kp, err := b.AttachProbePerfEvent(hookName, progType, prog)
if err != nil {
return fmt.Errorf("failed to attach perf event error %v", err)
}
b.ProbeLinks = append(b.ProbeLinks, &kp)
default:
Expand Down Expand Up @@ -78,6 +69,7 @@ func (b *BPF) LoadBPFProgramProbeTypes(objSpec *ebpf.CollectionSpec) error {
// ret : prog-type, hook, subtype
// e.g.: tracepoint/sock/inet_sock_set_state
// e.g.: kprobe/sys_execve
// e.g.: uprobe/<path>:<provider>:<name>
func GetProgramSectionDetails(sectionName string) (string, string, string) {
sections := strings.Split(sectionName, "/")

Expand All @@ -86,7 +78,86 @@ func GetProgramSectionDetails(sectionName string) (string, string, string) {
return sections[0], sections[1], sections[2]
case models.KProbe, models.KRetProbe:
return sections[0], sections[1], ""
case models.UProbe, models.URetProbe:
var funcName string
if len(sections) > 2 {
funcName = strings.Join(sections[1:], "/")
}
return sections[0], funcName, ""
default:
return "", "", ""
}
}

func (b *BPF) AttachProbePerfEvent(hookName, progType string, prog *ebpf.Program) (link.Link, error) {
var kp link.Link
var err error
switch strings.ToLower(progType) {
case models.KProbe:
kp, err = link.Kprobe(hookName, prog, nil)
if err != nil {
return nil, fmt.Errorf("failed to link kprobe hook name %s error %v", hookName, err)
}
case models.KRetProbe:
kp, err = link.Kretprobe(hookName, prog, nil)
if err != nil {
return nil, fmt.Errorf("failed to link kretprobe hook name %s error %v", hookName, err)
}
case models.UProbe:
kp, err = b.AttachUProbePerfEvent(hookName, prog)
if err != nil {
return nil, fmt.Errorf("failed to attach uprobe program %v", err)
}
case models.URetProbe:
kp, err = b.AttachURetProbePerfEvent(hookName, prog)
if err != nil {
return nil, fmt.Errorf("failed to attach uretprobe program %v", err)
}
default:
return nil, fmt.Errorf("unsupported perf event progType: %s", progType)
}
return kp, nil
}

func (b *BPF) AttachUProbePerfEvent(hookName string, prog *ebpf.Program) (link.Link, error) {
var kp link.Link
funcNames := strings.Split(hookName, ":")
ex, err := link.OpenExecutable(funcNames[0])
if err != nil {
return nil, fmt.Errorf("uprobe failed to openExecutable binary file %s error %v", hookName, err)
}

kp, err = ex.Uprobe(getSymbolName(funcNames), prog, nil)

if err != nil {
return nil, fmt.Errorf("failed to link uprobe symbol %s - %v", getSymbolName(funcNames), err)
}

return kp, nil
}

func (b *BPF) AttachURetProbePerfEvent(hookName string, prog *ebpf.Program) (link.Link, error) {
var kp link.Link
funcNames := strings.Split(hookName, ":")
ex, err := link.OpenExecutable(funcNames[0])
if err != nil {
return nil, fmt.Errorf("uretprobe failed to openExecutable binary file %s error %v", hookName, err)
}

kp, err = ex.Uretprobe(getSymbolName(funcNames), prog, nil)
if err != nil {
return nil, fmt.Errorf("failed to link uretprobe symbol %s - %v", getSymbolName(funcNames), err)
}

return kp, nil
}

func getSymbolName(funcNames []string) string {
var symbol string
if len(funcNames) == 1 {
symbol = funcNames[0]
} else {
symbol = funcNames[len(funcNames)-1]
}
return symbol
}
2 changes: 2 additions & 0 deletions models/l3afd.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const (
KProbe = "kprobe"
TracePoint = "tracepoint"
KRetProbe = "kretprobe"
UProbe = "uprobe"
URetProbe = "uretprobe"
)

type L3afDNFArgs map[string]interface{}
Expand Down
Loading