From d702083b6da11710548248b99da02f0e0a59ac44 Mon Sep 17 00:00:00 2001 From: Mohamed Mahmoud Date: Thu, 25 Jul 2024 07:53:18 -0400 Subject: [PATCH] Fix older kernel handling for Fentry Signed-off-by: Mohamed Mahmoud --- README.md | 2 +- pkg/ebpf/tracer.go | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bd0d3bfb1..7d94c135b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/netobserv/netobserv-ebpf-agent)](https://goreportcard.com/report/github.com/netobserv/netobserv-ebpf-agent) The Network Observability eBPF Agent allows collecting and aggregating all the ingress and -egress flows on a Linux host (required a Kernel 4.18+ with eBPF enabled). +egress flows on a Linux host (required a Kernel 5.8+ with eBPF enabled). * [How to build](#how-to-build) * [How to configure](#how-to-configure) diff --git a/pkg/ebpf/tracer.go b/pkg/ebpf/tracer.go index 74b7bb248..102e0be42 100644 --- a/pkg/ebpf/tracer.go +++ b/pkg/ebpf/tracer.go @@ -45,6 +45,7 @@ const ( pcaRecordsMap = "packet_record" tcEgressFilterName = "tc/tc_egress_flow_parse" tcIngressFilterName = "tc/tc_ingress_flow_parse" + tcpFentryHook = "tcp_rcv_fentry" ) var log = logrus.WithField("component", "ebpf.FlowFetcher") @@ -85,6 +86,7 @@ type FlowFetcherConfig struct { FilterConfig *FilterConfig } +// nolint:cyclop func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) { if err := rlimit.RemoveMemlock(); err != nil { log.WithError(err). @@ -168,16 +170,20 @@ func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) { var rttFentryLink, rttKprobeLink link.Link if cfg.EnableRTT { - rttFentryLink, err = link.AttachTracing(link.TracingOptions{ - Program: objects.BpfPrograms.TcpRcvFentry, - }) + if !oldKernel { + rttFentryLink, err = link.AttachTracing(link.TracingOptions{ + Program: objects.BpfPrograms.TcpRcvFentry, + }) + } if err != nil { log.Warningf("failed to attach the BPF program to tcpReceiveFentry: %v fallback to use kprobe", err) - // try to use kprobe for older kernels - rttKprobeLink, err = link.Kprobe("tcp_rcv_established", objects.TcpRcvKprobe, nil) - if err != nil { - return nil, fmt.Errorf("failed to attach the BPF program to tcpReceiveKprobe: %w", err) - } + // Fall through to use kprobe + } + // try to use kprobe for older kernels + rttKprobeLink, err = link.Kprobe("tcp_rcv_established", objects.TcpRcvKprobe, nil) + if err != nil { + log.Warningf("failed to attach the BPF program to tcpReceiveFentry: %v fallback to use kprobe", err) + return nil, fmt.Errorf("failed to attach the BPF program to tcpReceiveKprobe: %w", err) } } @@ -727,6 +733,8 @@ func kernelSpecificLoadAndAssign(oldKernel bool, spec *ebpf.CollectionSpec) (Bpf var newObjects NewBpfObjects // remove pktdrop hook from the spec delete(spec.Programs, pktDropHook) + // remove fentry hook from the spec + delete(spec.Programs, tcpFentryHook) newObjects.NewBpfPrograms = NewBpfPrograms{} if err := spec.LoadAndAssign(&newObjects, nil); err != nil { var ve *ebpf.VerifierError @@ -752,8 +760,8 @@ func kernelSpecificLoadAndAssign(oldKernel bool, spec *ebpf.CollectionSpec) (Bpf objects.TcIngressPcaParse = newObjects.TcIngressPcaParse objects.TcxEgressPcaParse = newObjects.TcxEgressPcaParse objects.TcxIngressPcaParse = newObjects.TcxIngressPcaParse - objects.TcpRcvFentry = newObjects.TCPRcvFentry objects.TcpRcvKprobe = newObjects.TCPRcvKprobe + objects.TcpRcvFentry = nil objects.KfreeSkb = nil } else { if err := spec.LoadAndAssign(&objects, nil); err != nil {