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

Fix older kernel handling for Fentry #374

Merged
merged 2 commits into from
Aug 6, 2024
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
32 changes: 21 additions & 11 deletions pkg/ebpf/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -85,6 +86,7 @@ type FlowFetcherConfig struct {
FilterConfig *FilterConfig
}

// nolint:cyclop
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we split the function here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably can will do that in a follow on pr

func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) {
if err := rlimit.RemoveMemlock(); err != nil {
log.WithError(err).
Expand Down Expand Up @@ -168,19 +170,26 @@ 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 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 !oldKernel {
rttFentryLink, err = link.AttachTracing(link.TracingOptions{
Program: objects.BpfPrograms.TcpRcvFentry,
})
if err == nil {
goto next
}
if err != nil {
return nil, fmt.Errorf("failed to attach the BPF program to tcpReceiveKprobe: %w", err)
log.Warningf("failed to attach the BPF program to tcpReceiveFentry: %v fallback to use kprobe", 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 kprobe: %v", err)
return nil, fmt.Errorf("failed to attach the BPF program to tcpReceiveKprobe: %w", err)
}
}

next:
// read events from igress+egress ringbuffer
flows, err := ringbuf.NewReader(objects.DirectFlows)
if err != nil {
Expand Down Expand Up @@ -717,7 +726,6 @@ func kernelSpecificLoadAndAssign(oldKernel bool, spec *ebpf.CollectionSpec) (Bpf
TcIngressPcaParse *ebpf.Program `ebpf:"tc_ingress_pca_parse"`
TcxEgressPcaParse *ebpf.Program `ebpf:"tcx_egress_pca_parse"`
TcxIngressPcaParse *ebpf.Program `ebpf:"tcx_ingress_pca_parse"`
TCPRcvFentry *ebpf.Program `ebpf:"tcp_rcv_fentry"`
TCPRcvKprobe *ebpf.Program `ebpf:"tcp_rcv_kprobe"`
}
type NewBpfObjects struct {
Expand All @@ -727,6 +735,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
Expand All @@ -752,8 +762,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 {
Expand Down
25 changes: 18 additions & 7 deletions pkg/pbflow/flow_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 18 additions & 7 deletions pkg/pbpacket/packet_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading