Skip to content

Commit 8150ccc

Browse files
authored
Shrink DNSMap if DNS not enabled to save memory (#165)
Signed-off-by: msherif1234 <[email protected]>
1 parent 338d2b2 commit 8150ccc

File tree

1 file changed

+70
-55
lines changed

1 file changed

+70
-55
lines changed

pkg/ebpf/tracer.go

Lines changed: 70 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ import (
2626

2727
const (
2828
qdiscType = "clsact"
29-
// ebpf map names as defined in flows.c
29+
// ebpf map names as defined in bpf/maps_definition.h
3030
aggregatedFlowsMap = "aggregated_flows"
3131
flowSequencesMap = "flow_sequences"
32+
dnsLatencyMap = "dns_flows"
3233
// constants defined in flows.c as "volatile const"
3334
constSampling = "sampling"
3435
constTraceMessages = "trace_messages"
@@ -73,7 +74,6 @@ func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) {
7374
Warn("can't remove mem lock. The agent could not be able to start eBPF programs")
7475
}
7576

76-
objects := BpfObjects{}
7777
spec, err := LoadBpf()
7878
if err != nil {
7979
return nil, fmt.Errorf("loading BPF data: %w", err)
@@ -103,6 +103,10 @@ func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) {
103103
spec.Maps[flowSequencesMap].MaxEntries = uint32(1)
104104
}
105105

106+
if !cfg.DNSTracker {
107+
spec.Maps[dnsLatencyMap].MaxEntries = 1
108+
}
109+
106110
if err := spec.RewriteConstants(map[string]interface{}{
107111
constSampling: uint32(cfg.Sampling),
108112
constTraceMessages: uint8(traceMsgs),
@@ -112,61 +116,11 @@ func NewFlowFetcher(cfg *FlowFetcherConfig) (*FlowFetcher, error) {
112116
}
113117

114118
oldKernel := utils.IskernelOlderthan514()
115-
116-
// For older kernel (< 5.14) kfree_sbk drop hook doesn't exists
117-
if oldKernel {
118-
// Here we define another structure similar to the bpf2go created one but w/o the hooks that does not exist in older kernel
119-
// Note: if new hooks are added in the future we need to update the following structures manually
120-
type NewBpfPrograms struct {
121-
EgressFlowParse *ebpf.Program `ebpf:"egress_flow_parse"`
122-
IngressFlowParse *ebpf.Program `ebpf:"ingress_flow_parse"`
123-
TraceNetPackets *ebpf.Program `ebpf:"trace_net_packets"`
124-
}
125-
type NewBpfObjects struct {
126-
NewBpfPrograms
127-
BpfMaps
128-
}
129-
var newObjects NewBpfObjects
130-
// remove pktdrop hook from the spec
131-
delete(spec.Programs, pktDropHook)
132-
newObjects.NewBpfPrograms = NewBpfPrograms{}
133-
if err := spec.LoadAndAssign(&newObjects, nil); err != nil {
134-
var ve *ebpf.VerifierError
135-
if errors.As(err, &ve) {
136-
// Using %+v will print the whole verifier error, not just the last
137-
// few lines.
138-
log.Infof("Verifier error: %+v", ve)
139-
}
140-
return nil, fmt.Errorf("loading and assigning BPF objects: %w", err)
141-
}
142-
// Manually assign maps and programs to the original objects variable
143-
// Note for any future maps or programs make sure to copy them manually here
144-
objects.DirectFlows = newObjects.DirectFlows
145-
objects.AggregatedFlows = newObjects.AggregatedFlows
146-
objects.FlowSequences = newObjects.FlowSequences
147-
objects.EgressFlowParse = newObjects.EgressFlowParse
148-
objects.IngressFlowParse = newObjects.IngressFlowParse
149-
objects.TraceNetPackets = newObjects.TraceNetPackets
150-
objects.KfreeSkb = nil
151-
} else {
152-
if err := spec.LoadAndAssign(&objects, nil); err != nil {
153-
var ve *ebpf.VerifierError
154-
if errors.As(err, &ve) {
155-
// Using %+v will print the whole verifier error, not just the last
156-
// few lines.
157-
log.Infof("Verifier error: %+v", ve)
158-
}
159-
return nil, fmt.Errorf("loading and assigning BPF objects: %w", err)
160-
}
119+
objects, err := kernelSpecificLoadAndAssign(oldKernel, spec)
120+
if err != nil {
121+
return nil, err
161122
}
162123

163-
/*
164-
* since we load the program only when the we start we need to release
165-
* memory used by cached kernel BTF see https://github.com/cilium/ebpf/issues/1063
166-
* for more details.
167-
*/
168-
btf.FlushKernelSpec()
169-
170124
var pktDropsLink link.Link
171125
if cfg.PktDrops && !oldKernel {
172126
pktDropsLink, err = link.Tracepoint("skb", pktDropHook, objects.KfreeSkb, nil)
@@ -480,4 +434,65 @@ func (m *FlowFetcher) lookupAndDeleteRTTMap(timeOut time.Duration) {
480434
}
481435
}
482436
}
437+
438+
}
439+
440+
// kernelSpecificLoadAndAssign based on kernel version it will load only the supported ebPF hooks
441+
func kernelSpecificLoadAndAssign(oldKernel bool, spec *ebpf.CollectionSpec) (BpfObjects, error) {
442+
objects := BpfObjects{}
443+
444+
// For older kernel (< 5.14) kfree_sbk drop hook doesn't exists
445+
if oldKernel {
446+
// Here we define another structure similar to the bpf2go created one but w/o the hooks that does not exist in older kernel
447+
// Note: if new hooks are added in the future we need to update the following structures manually
448+
type NewBpfPrograms struct {
449+
EgressFlowParse *ebpf.Program `ebpf:"egress_flow_parse"`
450+
IngressFlowParse *ebpf.Program `ebpf:"ingress_flow_parse"`
451+
TraceNetPackets *ebpf.Program `ebpf:"trace_net_packets"`
452+
}
453+
type NewBpfObjects struct {
454+
NewBpfPrograms
455+
BpfMaps
456+
}
457+
var newObjects NewBpfObjects
458+
// remove pktdrop hook from the spec
459+
delete(spec.Programs, pktDropHook)
460+
newObjects.NewBpfPrograms = NewBpfPrograms{}
461+
if err := spec.LoadAndAssign(&newObjects, nil); err != nil {
462+
var ve *ebpf.VerifierError
463+
if errors.As(err, &ve) {
464+
// Using %+v will print the whole verifier error, not just the last
465+
// few lines.
466+
log.Infof("Verifier error: %+v", ve)
467+
}
468+
return objects, fmt.Errorf("loading and assigning BPF objects: %w", err)
469+
}
470+
// Manually assign maps and programs to the original objects variable
471+
// Note for any future maps or programs make sure to copy them manually here
472+
objects.DirectFlows = newObjects.DirectFlows
473+
objects.AggregatedFlows = newObjects.AggregatedFlows
474+
objects.FlowSequences = newObjects.FlowSequences
475+
objects.EgressFlowParse = newObjects.EgressFlowParse
476+
objects.IngressFlowParse = newObjects.IngressFlowParse
477+
objects.TraceNetPackets = newObjects.TraceNetPackets
478+
objects.KfreeSkb = nil
479+
} else {
480+
if err := spec.LoadAndAssign(&objects, nil); err != nil {
481+
var ve *ebpf.VerifierError
482+
if errors.As(err, &ve) {
483+
// Using %+v will print the whole verifier error, not just the last
484+
// few lines.
485+
log.Infof("Verifier error: %+v", ve)
486+
}
487+
return objects, fmt.Errorf("loading and assigning BPF objects: %w", err)
488+
}
489+
}
490+
/*
491+
* since we load the program only when the we start we need to release
492+
* memory used by cached kernel BTF see https://github.com/cilium/ebpf/issues/1063
493+
* for more details.
494+
*/
495+
btf.FlushKernelSpec()
496+
497+
return objects, nil
483498
}

0 commit comments

Comments
 (0)