diff --git a/pkg/ebpf/perf/event.go b/pkg/ebpf/perf/event.go index 5552302f54af2d..043bb3af8c252c 100644 --- a/pkg/ebpf/perf/event.go +++ b/pkg/ebpf/perf/event.go @@ -15,6 +15,7 @@ import ( manager "github.com/DataDog/ebpf-manager" "github.com/cilium/ebpf" + "github.com/cilium/ebpf/asm" "github.com/cilium/ebpf/features" "github.com/cilium/ebpf/perf" "github.com/cilium/ebpf/ringbuf" @@ -95,6 +96,13 @@ func SendTelemetry(enabled bool) EventHandlerOption { } } +// RingBufferConstantName provides a constant name that will be set whether ring buffers are in use +func RingBufferConstantName(name string) EventHandlerOption { + return func(e *EventHandler) { + e.opts.ringBufferConstantName = name + } +} + // eventHandlerOptions are the options controlling the EventHandler. type eventHandlerOptions struct { // telemetryEnabled specifies whether to collect usage telemetry from the perf/ring buffer. @@ -103,9 +111,10 @@ type eventHandlerOptions struct { mode mapMode perfBufferSize int - ringBufferSize int + perfOptions perfBufferOptions - perfOptions perfBufferOptions + ringBufferSize int + ringBufferConstantName string } // PerfBufferMode is a mode for the perf buffer @@ -158,11 +167,12 @@ func NewEventHandler(mapName string, handler func([]byte), mode EventHandlerMode } // BeforeInit implements the Modifier interface -func (e *EventHandler) BeforeInit(mgr *manager.Manager, _ names.ModuleName, mgrOpts *manager.Options) error { +func (e *EventHandler) BeforeInit(mgr *manager.Manager, moduleName names.ModuleName, mgrOpts *manager.Options) (err error) { ms, _, _ := mgr.GetMapSpec(e.mapName) if ms == nil { return fmt.Errorf("unable to find map spec %q", e.mapName) } + defer e.setupConstant(mgrOpts) ringBufErr := features.HaveMapType(ebpf.RingBuf) if e.opts.mode == ringBufferOnly { @@ -202,12 +212,31 @@ func (e *EventHandler) BeforeInit(mgr *manager.Manager, _ names.ModuleName, mgrO } e.initPerfBuffer(mgr) - return nil + // add helper call remover because ring buffers are not available + return ddebpf.NewHelperCallRemover(asm.FnRingbufOutput).BeforeInit(mgr, moduleName, mgrOpts) } return fmt.Errorf("unsupported EventHandlerMode %d", e.opts.mode) } +func (e *EventHandler) setupConstant(mgrOpts *manager.Options) { + if e.opts.ringBufferConstantName == "" || e.f == nil { + return + } + + var val uint64 + switch e.f.(type) { + case *manager.RingBuffer: + val = uint64(1) + default: + val = uint64(0) + } + mgrOpts.ConstantEditors = append(mgrOpts.ConstantEditors, manager.ConstantEditor{ + Name: e.opts.ringBufferConstantName, + Value: val, + }) +} + // AfterInit implements the Modifier interface func (e *EventHandler) AfterInit(_ *manager.Manager, _ names.ModuleName, _ *manager.Options) error { return nil @@ -217,19 +246,6 @@ func (e *EventHandler) String() string { return "EventHandler" } -// MapType returns the ebpf.MapType of the underlying events map -// This is only valid after calling Init. -func (e *EventHandler) MapType() ebpf.MapType { - switch e.f.(type) { - case *manager.PerfMap: - return ebpf.PerfEventArray - case *manager.RingBuffer: - return ebpf.RingBuf - default: - return ebpf.UnspecifiedMap - } -} - // Flush flushes the pending data from the underlying perfbuf/ringbuf func (e *EventHandler) Flush() { e.f.Flush() diff --git a/pkg/network/tracer/connection/ebpf_tracer.go b/pkg/network/tracer/connection/ebpf_tracer.go index c72485e616dfe4..2ff5d584735999 100644 --- a/pkg/network/tracer/connection/ebpf_tracer.go +++ b/pkg/network/tracer/connection/ebpf_tracer.go @@ -343,7 +343,9 @@ func initClosedConnEventHandler(config *config.Config, closedCallback func(*netw mode = perf.UpgradePerfBuffers(perfBufferSize, perfMode, util.ComputeDefaultClosedConnRingBufferSize()) } - return perf.NewEventHandler(probes.ConnCloseEventMap, handler, mode, perf.SendTelemetry(config.InternalTelemetryEnabled)) + return perf.NewEventHandler(probes.ConnCloseEventMap, handler, mode, + perf.SendTelemetry(config.InternalTelemetryEnabled), + perf.RingBufferConstantName("ringbuffers_enabled")) } func boolConst(name string, value bool) manager.ConstantEditor { diff --git a/pkg/network/tracer/connection/fentry/tracer.go b/pkg/network/tracer/connection/fentry/tracer.go index e029ed215f2a13..4a7d6121b5ade6 100644 --- a/pkg/network/tracer/connection/fentry/tracer.go +++ b/pkg/network/tracer/connection/fentry/tracer.go @@ -14,7 +14,6 @@ import ( "syscall" manager "github.com/DataDog/ebpf-manager" - "github.com/cilium/ebpf" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/ebpf/bytecode" @@ -22,7 +21,6 @@ import ( ebpftelemetry "github.com/DataDog/datadog-agent/pkg/ebpf/telemetry" "github.com/DataDog/datadog-agent/pkg/network/config" netebpf "github.com/DataDog/datadog-agent/pkg/network/ebpf" - "github.com/DataDog/datadog-agent/pkg/network/tracer/connection/util" "github.com/DataDog/datadog-agent/pkg/util/fargate" ) @@ -41,7 +39,7 @@ func LoadTracer(config *config.Config, mgrOpts manager.Options, connCloseEventHa o.RLimit = mgrOpts.RLimit o.MapSpecEditors = mgrOpts.MapSpecEditors o.ConstantEditors = mgrOpts.ConstantEditors - return initFentryTracer(ar, o, config, m, connCloseEventHandler) + return initFentryTracer(ar, o, config, m) }) if err != nil { @@ -52,7 +50,7 @@ func LoadTracer(config *config.Config, mgrOpts manager.Options, connCloseEventHa } // Use a function so someone doesn't accidentally use mgrOpts from the outer scope in LoadTracer -func initFentryTracer(ar bytecode.AssetReader, o manager.Options, config *config.Config, m *ddebpf.Manager, connCloseEventHandler *perf.EventHandler) error { +func initFentryTracer(ar bytecode.AssetReader, o manager.Options, config *config.Config, m *ddebpf.Manager) error { // Use the config to determine what kernel probes should be enabled enabledProbes, err := enabledPrograms(config) if err != nil { @@ -91,6 +89,5 @@ func initFentryTracer(ar bytecode.AssetReader, o manager.Options, config *config }) } - util.AddBoolConst(&o, "ringbuffers_enabled", connCloseEventHandler.MapType() == ebpf.RingBuf) return m.InitWithOptions(ar, &o) } diff --git a/pkg/network/tracer/connection/kprobe/tracer.go b/pkg/network/tracer/connection/kprobe/tracer.go index 299c816688479b..40a0a8f49eae01 100644 --- a/pkg/network/tracer/connection/kprobe/tracer.go +++ b/pkg/network/tracer/connection/kprobe/tracer.go @@ -13,8 +13,6 @@ import ( manager "github.com/DataDog/ebpf-manager" "github.com/cilium/ebpf" - "github.com/cilium/ebpf/asm" - "github.com/cilium/ebpf/features" ddebpf "github.com/DataDog/datadog-agent/pkg/ebpf" "github.com/DataDog/datadog-agent/pkg/ebpf/bytecode" @@ -223,11 +221,6 @@ func loadTracerFromAsset(buf bytecode.AssetReader, runtimeTracer, coreTracer boo }) } - usingRingBuffers := connCloseEventHandler.MapType() == ebpf.RingBuf - util.AddBoolConst(&mgrOpts, "ringbuffers_enabled", usingRingBuffers) - if features.HaveMapType(ebpf.RingBuf) != nil { - m.EnabledModifiers = append(m.EnabledModifiers, ddebpf.NewHelperCallRemover(asm.FnRingbufOutput)) - } if err := m.InitWithOptions(buf, &mgrOpts); err != nil { return nil, nil, fmt.Errorf("failed to init ebpf manager: %w", err) }