diff --git a/cmd/tetragon/main.go b/cmd/tetragon/main.go index bde3a2b5495..f1561408ba9 100644 --- a/cmd/tetragon/main.go +++ b/cmd/tetragon/main.go @@ -436,6 +436,8 @@ func tetragonExecute() error { initialSensor.Unload() }() + base.Config(option.Config.ExecCgroupRate, option.Config.ForkCgroupRate) + // now that the base sensor was loaded, we can start the sensor manager close(sensorMgWait) sensorMgWait = nil diff --git a/docs/data/tetragon_flags.yaml b/docs/data/tetragon_flags.yaml index 42a5e5ddcee..1769bb5034c 100644 --- a/docs/data/tetragon_flags.yaml +++ b/docs/data/tetragon_flags.yaml @@ -62,6 +62,8 @@ options: - name: event-queue-size default_value: "10000" usage: Set the size of the internal event queue. + - name: exec-cgroup-rate + usage: Exec event cgroup rate (tokens,interval,throttle) - name: export-aggregation-buffer-size default_value: "10000" usage: Aggregator channel buffer size @@ -107,6 +109,8 @@ options: default_value: "false" usage: | Force loading small programs, even in kernels with >= 5.3 versions + - name: fork-cgroup-rate + usage: Fork event cgroup rate (tokens,interval,throttle) - name: generate-docs default_value: "false" usage: Generate documentation in YAML format to stdout diff --git a/pkg/api/tracingapi/client_kprobe.go b/pkg/api/tracingapi/client_kprobe.go index 5651e69e464..ea003e52d48 100644 --- a/pkg/api/tracingapi/client_kprobe.go +++ b/pkg/api/tracingapi/client_kprobe.go @@ -591,3 +591,12 @@ type EventConfig struct { PolicyID uint32 `align:"policy_id"` Flags uint32 `align:"flags"` } + +const CgroupRateConfigExec = 0 +const CgroupRateConfigFork = 1 + +type CgroupRate struct { + Tokens uint64 + Interval uint64 + Throttle uint64 +} diff --git a/pkg/option/config.go b/pkg/option/config.go index bd0dec4894f..fa260671f66 100644 --- a/pkg/option/config.go +++ b/pkg/option/config.go @@ -86,6 +86,9 @@ type config struct { EnableTracingPolicyCRD bool ExposeKernelAddresses bool + + ExecCgroupRate string + ForkCgroupRate string } var ( diff --git a/pkg/option/flags.go b/pkg/option/flags.go index 56b2d4a9fcb..f0a13284939 100644 --- a/pkg/option/flags.go +++ b/pkg/option/flags.go @@ -92,6 +92,9 @@ const ( KeyExposeKernelAddresses = "expose-kernel-addresses" KeyGenerateDocs = "generate-docs" + + KeyExecCgroupRate = "exec-cgroup-rate" + KeyForkCgroupRate = "fork-cgroup-rate" ) func ReadAndSetFlags() error { @@ -172,6 +175,8 @@ func ReadAndSetFlags() error { Config.ExposeKernelAddresses = viper.GetBool(KeyExposeKernelAddresses) + Config.ExecCgroupRate = viper.GetString(KeyExecCgroupRate) + Config.ForkCgroupRate = viper.GetString(KeyForkCgroupRate) return nil } @@ -278,4 +283,7 @@ func AddFlags(flags *pflag.FlagSet) { flags.Bool(KeyExposeKernelAddresses, false, "Expose real kernel addresses in events stack traces") flags.Bool(KeyGenerateDocs, false, "Generate documentation in YAML format to stdout") + + flags.String(KeyExecCgroupRate, "", "Exec event cgroup rate (tokens,interval,throttle)") + flags.String(KeyForkCgroupRate, "", "Fork event cgroup rate (tokens,interval,throttle)") } diff --git a/pkg/sensors/base/base.go b/pkg/sensors/base/base.go index d379ac4755c..8b3bc5192b2 100644 --- a/pkg/sensors/base/base.go +++ b/pkg/sensors/base/base.go @@ -5,8 +5,13 @@ package base import ( "log" + "strconv" + "strings" "sync" + "time" + "github.com/cilium/ebpf" + "github.com/cilium/tetragon/pkg/api/tracingapi" "github.com/cilium/tetragon/pkg/kernels" "github.com/cilium/tetragon/pkg/ksyms" "github.com/cilium/tetragon/pkg/logger" @@ -121,6 +126,7 @@ func GetDefaultMaps() []*program.Map { ExecveStats, ExecveJoinMapStats, ExecveTailCallsMap, + ExecveCgroupRate, ForkTailCallsMap, TCPMonMap, TetragonConfMap, @@ -151,3 +157,73 @@ func ExecObj() string { } return "bpf_execve_event.o" } + +func parseCgroupRate(rate string) *tracingapi.CgroupRate { + empty := tracingapi.CgroupRate{} + + if rate == "" { + return &empty + } + + s := strings.Split(rate, ",") + if len(s) != 3 { + logger.GetLogger().Warnf("failed to parse cgroup rate '%s'", rate) + return &empty + } + + var interval time.Duration + var throttle time.Duration + var tokens int + var err error + + if len(s[0]) > 0 { + tokens, err = strconv.Atoi(s[0]) + if err != nil { + logger.GetLogger().Warnf("failed to parse cgroup rate '%s' : %w", rate, err) + return &empty + } + } + + if len(s[1]) > 0 { + interval, err = time.ParseDuration(s[1]) + if err != nil { + logger.GetLogger().Warnf("failed to parse cgroup rate '%s' : %w", rate, err) + return &empty + } + } + + if len(s[2]) > 0 { + throttle, err = time.ParseDuration(s[2]) + if err != nil { + logger.GetLogger().Warnf("failed to parse cgroup rate '%s' : %w", rate, err) + return &empty + } + } + + return &tracingapi.CgroupRate{ + Tokens: uint64(tokens), + Interval: uint64(interval), + Throttle: uint64(throttle), + } +} + +func Config(execCgroupRate, forkCgroupRate string) { + var rate *tracingapi.CgroupRate + var err error + + rate = parseCgroupRate(execCgroupRate) + + err = ExecveCgroupRate.MapHandle.Update(uint32(tracingapi.CgroupRateConfigExec), + rate, ebpf.UpdateAny) + if err != nil { + logger.GetLogger().Warnf("failed to update exec cgroup rate in map '%s' : %w", ExecveCgroupRate.Name, err) + } + + rate = parseCgroupRate(forkCgroupRate) + + err = ExecveCgroupRate.MapHandle.Update(uint32(tracingapi.CgroupRateConfigFork), + rate, ebpf.UpdateAny) + if err != nil { + logger.GetLogger().Warnf("failed to update fork cgroup rate in map '%s' : %w", ExecveCgroupRate.Name, err) + } +}