tetragon

Форк
0
/
sensors.go 
168 строк · 5.4 Кб
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Tetragon
3

4
package sensors
5

6
import (
7
	"fmt"
8

9
	"github.com/cilium/tetragon/pkg/logger"
10
	"github.com/cilium/tetragon/pkg/policyfilter"
11
	"github.com/cilium/tetragon/pkg/sensors/program"
12
	"github.com/cilium/tetragon/pkg/sensors/program/cgroup"
13
	"github.com/cilium/tetragon/pkg/tracingpolicy"
14

15
	// load rthooks for policy filter
16
	_ "github.com/cilium/tetragon/pkg/policyfilter/rthooks"
17
)
18

19
var (
20
	// AllPrograms are all the loaded programs. For use with Unload().
21
	AllPrograms = []*program.Program{}
22
	// AllMaps are all the loaded programs. For use with Unload().
23
	AllMaps = []*program.Map{}
24
)
25

26
// Sensors
27
//
28
// Sensors are a mechanism for dynamically loading/unloading bpf programs.
29
// Contrarily to low-level facilities like kprobes, sensors are meant to be
30
// visible to end users who can enable/disable them.
31
//
32
// Sensor control operations are done in a separate goroutine which acts as a
33
// serialization point for concurrent client requests.
34

35
// Sensor is a set of BPF programs and maps that are managed as a unit.
36
type Sensor struct {
37
	// Name is a human-readbale description.
38
	Name string
39
	// Progs are all the BPF programs that exist on the filesystem.
40
	Progs []*program.Program
41
	// Maps are all the BPF Maps that the progs use.
42
	Maps []*program.Map
43
	// Loaded indicates whether the sensor has been Loaded.
44
	Loaded bool
45
	// Destroyed indicates whether the sensor had been destroyed.
46
	Destroyed bool
47
	// PreUnloadHook can optionally contain a pointer to a function to be
48
	// called during sensor unloading, prior to the programs and maps being
49
	// unloaded.
50
	PreUnloadHook SensorHook
51
	// PostUnloadHook can optionally contain a pointer to a function to be
52
	// called during sensor unloading, after the programs and maps being
53
	// unloaded.
54
	PostUnloadHook SensorHook
55
	// DestroyHook can optionally contain a pointer to a function to be called
56
	// when removing the sensor, sensor cannot be loaded again after this hook
57
	// being triggered and must be recreated.
58
	DestroyHook SensorHook
59
}
60

61
// SensorIface is an interface for sensors.Sensor that allows implementing sensors for testing.
62
type SensorIface interface {
63
	GetName() string
64
	IsLoaded() bool
65
	Load(bpfDir string) error
66
	Unload() error
67
	Destroy()
68
}
69

70
func (s *Sensor) GetName() string {
71
	return s.Name
72
}
73

74
func (s *Sensor) IsLoaded() bool {
75
	return s.Loaded
76
}
77

78
// SensorHook is the function signature for an optional function
79
// that can be called during sensor unloading and removing.
80
type SensorHook func() error
81

82
func SensorCombine(name string, sensors ...*Sensor) *Sensor {
83
	progs := []*program.Program{}
84
	maps := []*program.Map{}
85
	for _, s := range sensors {
86
		progs = append(progs, s.Progs...)
87
		maps = append(maps, s.Maps...)
88
	}
89
	return SensorBuilder(name, progs, maps)
90
}
91

92
func SensorBuilder(name string, p []*program.Program, m []*program.Map) *Sensor {
93
	return &Sensor{
94
		Name:  name,
95
		Progs: p,
96
		Maps:  m,
97
	}
98
}
99

100
type policyHandler interface {
101
	// PolicyHandler returns a Sensor for a given policy
102
	// sensors that support policyfilter can use the filterID to implement filtering.
103
	// sensors that do not support policyfilter need to return an error if filterID != policyfilter.NoFilterID
104
	PolicyHandler(policy tracingpolicy.TracingPolicy, filterID policyfilter.PolicyID) (SensorIface, error)
105
}
106

107
type probeLoader interface {
108
	LoadProbe(args LoadProbeArgs) error
109
}
110

111
var (
112
	// list of registered policy handlers, see RegisterPolicyHandlerAtInit()
113
	registeredPolicyHandlers = map[string]policyHandler{}
114
	// list of registers loaders, see registerProbeType()
115
	registeredProbeLoad = map[string]probeLoader{}
116
	standardTypes       = map[string]func(string, *program.Program, int) error{
117
		"tracepoint":     program.LoadTracepointProgram,
118
		"raw_tracepoint": program.LoadRawTracepointProgram,
119
		"raw_tp":         program.LoadRawTracepointProgram,
120
		"cgrp_socket":    cgroup.LoadCgroupProgram,
121
		"kprobe":         program.LoadKprobeProgram,
122
	}
123
)
124

125
// RegisterPolicyHandlerAtInit registers a handler for a tracing policy.
126
func RegisterPolicyHandlerAtInit(name string, h policyHandler) {
127
	if _, exists := registeredPolicyHandlers[name]; exists {
128
		panic(fmt.Sprintf("RegisterPolicyHandlerAtInit called, but %s is already registered", name))
129
	}
130
	registeredPolicyHandlers[name] = h
131
}
132

133
// RegisterProbeType registers a handler for a probe type string
134
//
135
// This function is meant to be called in an init() by sensors that
136
// need extra logic when loading a specific probe type.
137
func RegisterProbeType(probeType string, s probeLoader) {
138
	logger.GetLogger().WithField("probeType", probeType).WithField("sensors", s).Debug("Registered probe type")
139
	if _, exists := registeredProbeLoad[probeType]; exists {
140
		panic(fmt.Sprintf("RegisterProbeType called, but %s is already registered", probeType))
141
	}
142
	registeredProbeLoad[probeType] = s
143
}
144

145
// LoadProbeArgs are the args to the LoadProbe function.
146
type LoadProbeArgs struct {
147
	BPFDir           string
148
	Load             *program.Program
149
	Version, Verbose int
150
}
151

152
func GetMergedSensorFromParserPolicy(tp tracingpolicy.TracingPolicy) (SensorIface, error) {
153
	// NB: use a filter id of 0, so no filtering will happen
154
	sis, err := SensorsFromPolicy(tp, policyfilter.NoFilterID)
155
	if err != nil {
156
		return nil, err
157
	}
158
	sensors := make([]*Sensor, 0, len(sis))
159
	for _, si := range sis {
160
		s, ok := si.(*Sensor)
161
		if !ok {
162
			return nil, fmt.Errorf("cannot merge sensor of type %T", si)
163
		}
164
		sensors = append(sensors, s)
165
	}
166

167
	return SensorCombine(tp.TpName(), sensors...), nil
168
}
169

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.