Skip to content

Commit

Permalink
chore(userspace,falco.yaml): rename new config key to driver.kind.
Browse files Browse the repository at this point in the history
Moreover, renamed driver kinds to use better naming, and move driver's related
config keys under `driver.$kind`.

Added DEPRECTATION notices on CLI options, and in falco.yaml.

DEPRECATED options (both CLI and config ones) will have priority over the new ones,
to retain compatibility with existing configs.

DEPRECATED options will be dropped in Falco 0.38.

Signed-off-by: Federico Di Pierro <[email protected]>

Co-authored-by: Andrea Terzolo <[email protected]>
  • Loading branch information
FedeDP and Andreagit97 committed Nov 14, 2023
1 parent b1d6b62 commit 513b6f8
Show file tree
Hide file tree
Showing 11 changed files with 277 additions and 119 deletions.
68 changes: 42 additions & 26 deletions falco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
# syscall_event_timeouts
# syscall_event_drops
# metrics
# Falco driver selection
# driver_mode
# Falco driver
# driver
# Falco performance tuning (advanced)
# syscall_buf_size_preset
# syscall_drop_failed_exit
Expand Down Expand Up @@ -99,7 +99,7 @@
# - "HOST_ROOT": Specifies the prefix to the underlying host `/proc` filesystem
# when deploying Falco over a container with read-only host mounts instead of
# directly on the host. Defaults to "/host".
# - "FALCO_BPF_PROBE": Specify a custom path to the BPF object code file (`bpf`
# - "FALCO_BPF_PROBE": DEPRECATED. Specify a custom path to the BPF object code file (`bpf`
# driver). This is not needed for the modern_bpf driver.
# - "FALCO_HOSTNAME": Customize the hostname output field logged by Falco by
# setting the "FALCO_HOSTNAME" environment variable.
Expand Down Expand Up @@ -775,11 +775,11 @@ metrics:
convert_memory_to_mb: true
include_empty_values: false

###############################################
# Falco driver selection #
###############################################
################
# Falco driver #
################

# [Stable] `driver_mode`
# [Stable] `driver`
#
# --- [Description]
#
Expand All @@ -788,32 +788,45 @@ metrics:
# Falco with your system. Choose the appropriate driver mode based on your
# system's configuration and requirements.
#
# Available driver modes:
# Available driver kinds:
# - `kmod`: Kernel Module (Kernel Module)
# - `bpf`: eBPF (Extended Berkeley Packet Filter)
# - `modern_bpf`: Modern eBPF (Modern Extended Berkeley Packet Filter)
# - `nodriver`: No Driver (No driver, just for testing)
# - `ebpf`: eBPF (Extended Berkeley Packet Filter)
# - `modern-ebpf`: Modern eBPF (Modern Extended Berkeley Packet Filter), available only for recent kernels
# - `none`: No Driver (No driver loaded, useful to run `syscall` source plugin or just plugins without loading any driver)
# - `gvisor`: gVisor (gVisor sandbox)
# - `custom`: Custom Driver (Specify a custom driver module)

# Example usage:
# driver_mode: kmod
# - `replay`: Replay a scap file

# Select the appropriate driver mode by uncommenting the corresponding line.
# Make sure to specify only one driver mode at a time.

driver_mode: kmod
# driver_mode: bpf
# driver_mode: modern_bpf
# driver_mode: nodriver
# driver_mode: gvisor
# driver_mode: custom
# Moreover, for each driver multiple options might be available and are grouped
# under the `driver.$kind` configuration key.

driver:
kind: kmod
kmod:
buf_size_preset: 4 # Overridden by deprecated syscall_buf_size_preset
drop_failed_exit: false # Overridden by deprecated syscall_drop_failed_exit
ebpf:
probe: /path/to/probe.o
buf_size_preset: 4 # Overridden by deprecated syscall_buf_size_preset
drop_failed_exit: false # Overridden by deprecated syscall_drop_failed_exit
modern-ebpf:
cpus_for_each_syscall_buffer: 2 # Overridden by deprecated cpus_for_each_syscall_buffer
buf_size_preset: 4 # Overridden by deprecated syscall_buf_size_preset
drop_failed_exit: false # Overridden by deprecated syscall_drop_failed_exit
replay:
scap_file: /path/to/file.scap
gvisor:
config: /path/to/gvisor.yaml
root: /gvisor/root

#######################################
# Falco performance tuning (advanced) #
#######################################

# [Stable] `syscall_buf_size_preset`
# [DEPRECATED] `syscall_buf_size_preset`
#
# Deprecated in favor of driver.{kmod,ebpf,modern-ebpf}.buf_size_preset
#
# --- [Description]
#
Expand Down Expand Up @@ -865,10 +878,11 @@ driver_mode: kmod
# if the default size is not suitable for your use case.
syscall_buf_size_preset: 4

# [Experimental] `syscall_drop_failed_exit`
# [DEPRECATED] `syscall_drop_failed_exit`
# Deprecated in favor of driver.{kmod,ebpf,modern-ebpf}.drop_failed_exit
#
# Enabling this option in Falco allows it to drop failed system call exit events
# in the kernel driver before pushing them onto the ring buffer. This
# in the kernel drivers before pushing them onto the ring buffer. This
# optimization can result in lower CPU usage and more efficient utilization of
# the ring buffer, potentially reducing the number of event losses. However, it
# is important to note that enabling this option also means sacrificing some
Expand Down Expand Up @@ -990,7 +1004,9 @@ base_syscalls:
custom_set: []
repair: false

# [Stable] `modern_bpf.cpus_for_each_syscall_buffer`, modern_bpf only
# [DEPRECATED] `modern_bpf.cpus_for_each_syscall_buffer`, modern_bpf only
#
# Deprecated in favor of driver.modern-ebpf.cpus_for_each_syscall_buffer
#
# --- [Description]
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,18 @@ TEST(ActionConfigureSyscallBufferNum, variable_number_of_CPUs)
{
falco::app::state s;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus + 1;
s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer = online_cpus + 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus);
EXPECT_EQ(s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer, online_cpus);
}

// modern bpf engine, with an valid number of CPUs
// we don't modify `m_cpus_for_each_syscall_buffer`
{
falco::app::state s;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus - 1;
s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer = online_cpus - 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus - 1);
EXPECT_EQ(s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer, online_cpus - 1);
}
}
6 changes: 3 additions & 3 deletions userspace/falco/app/actions/configure_syscall_buffer_num.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ falco::app::run_result falco::app::actions::configure_syscall_buffer_num(falco::
return run_result::fatal("cannot get the number of online CPUs from the system\n");
}

if(s.config->m_cpus_for_each_syscall_buffer > online_cpus)
if(s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer > online_cpus)
{
falco_logger::log(falco_logger::level::WARNING, "you required a buffer every '" + std::to_string(s.config->m_cpus_for_each_syscall_buffer) + "' CPUs but there are only '" + std::to_string(online_cpus) + "' online CPUs. Falco changed the config to: one buffer every '" + std::to_string(online_cpus) + "' CPUs\n");
s.config->m_cpus_for_each_syscall_buffer = online_cpus;
falco_logger::log(falco_logger::level::WARNING, "you required a buffer every '" + std::to_string(s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer) + "' CPUs but there are only '" + std::to_string(online_cpus) + "' online CPUs. Falco changed the config to: one buffer every '" + std::to_string(online_cpus) + "' CPUs\n");
s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer = online_cpus;
}
#endif
return run_result::ok();
Expand Down
12 changes: 3 additions & 9 deletions userspace/falco/app/actions/configure_syscall_buffer_size.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,12 @@ using namespace falco::app::actions;
falco::app::run_result falco::app::actions::configure_syscall_buffer_size(falco::app::state& s)
{
#ifdef __linux__
/* We don't need to compute the syscall buffer dimension if we are in capture mode or if the
* the syscall source is not enabled.
*/
if(s.is_capture_mode()
|| !s.is_source_enabled(falco_common::syscall_source)
|| s.is_gvisor_enabled()
|| s.options.nodriver)
auto index = s.driver_buf_size_preset();
if (index == -1)
{
// Chosen driver kind does not support this option.
return run_result::ok();
}

uint16_t index = s.config->m_syscall_buf_size_preset;
if(index < MIN_INDEX || index > MAX_INDEX)
{
return run_result::fatal("The 'syscall_buf_size_preset' value must be between '" + std::to_string(MIN_INDEX) + "' and '" + std::to_string(MAX_INDEX) + "'\n");
Expand Down
34 changes: 12 additions & 22 deletions userspace/falco/app/actions/helpers_inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,20 @@ limitations under the License.
#define PATH_MAX 260
#endif

/* DEPRECATED: we will remove it in Falco 0.34. */
#define FALCO_BPF_ENV_VARIABLE "FALCO_BPF_PROBE"

using namespace falco::app;
using namespace falco::app::actions;

falco::app::run_result falco::app::actions::open_offline_inspector(falco::app::state& s)
{
try
{
s.offline_inspector->open_savefile(s.options.trace_filename);
falco_logger::log(falco_logger::level::INFO, "Reading system call events from file: " + s.options.trace_filename + "\n");
s.offline_inspector->open_savefile(s.config->m_replay.m_scap_file);
falco_logger::log(falco_logger::level::INFO, "Reading system call events from file: " + s.config->m_replay.m_scap_file + "\n");
return run_result::ok();
}
catch (sinsp_exception &e)
{
return run_result::fatal("Could not open trace filename " + s.options.trace_filename + " for reading: " + e.what());
return run_result::fatal("Could not open trace filename " + s.config->m_replay.m_scap_file + " for reading: " + e.what());
}
}

Expand All @@ -53,13 +50,6 @@ falco::app::run_result falco::app::actions::open_live_inspector(
std::shared_ptr<sinsp> inspector,
const std::string& source)
{

bool is_driver_mode_from_cmdline = (s.options.nodriver ||
s.is_gvisor_enabled() ||
s.options.modern_bpf ||
getenv(FALCO_BPF_ENV_VARIABLE) != NULL
);

try
{
if (source != falco_common::syscall_source) /* Plugin engine */
Expand All @@ -79,7 +69,7 @@ falco::app::run_result falco::app::actions::open_live_inspector(
}
return run_result::fatal("Can't find plugin for event source: " + source);
}
else if (s.options.nodriver || (!is_driver_mode_from_cmdline && s.config->m_driver_mode == driver_mode_type::NODRIVER)) /* nodriver engine. */
else if (s.config->m_driver_mode == driver_mode_type::NONE) /* nodriver engine. */
{
// when opening a capture with no driver, Falco will first check
// if a plugin is capable of generating raw events from the libscap
Expand All @@ -98,20 +88,20 @@ falco::app::run_result falco::app::actions::open_live_inspector(
falco_logger::log(falco_logger::level::INFO, "Opening '" + source + "' source with no driver\n");
inspector->open_nodriver();
}
else if(s.is_gvisor_enabled() || (!is_driver_mode_from_cmdline && s.config->m_driver_mode == driver_mode_type::GVISOR)) /* gvisor engine. */
else if(s.is_gvisor_enabled()) /* gvisor engine. */
{
falco_logger::log(falco_logger::level::INFO, "Opening '" + source + "' source with gVisor. Configuration path: " + s.options.gvisor_config);
inspector->open_gvisor(s.options.gvisor_config, s.options.gvisor_root);
falco_logger::log(falco_logger::level::INFO, "Opening '" + source + "' source with gVisor. Configuration path: " + s.config->m_gvisor.m_config);
inspector->open_gvisor(s.config->m_gvisor.m_config, s.config->m_gvisor.m_root);
}
else if(s.options.modern_bpf || (!is_driver_mode_from_cmdline && s.config->m_driver_mode == driver_mode_type::MODERN_BPF)) /* modern BPF engine. */
else if(s.config->m_driver_mode == driver_mode_type::MODERN_EBPF) /* modern BPF engine. */
{
falco_logger::log(falco_logger::level::INFO, "Opening '" + source + "' source with modern BPF probe.");
falco_logger::log(falco_logger::level::INFO, "One ring buffer every '" + std::to_string(s.config->m_cpus_for_each_syscall_buffer) + "' CPUs.");
inspector->open_modern_bpf(s.syscall_buffer_bytes_size, s.config->m_cpus_for_each_syscall_buffer, true, s.selected_sc_set);
falco_logger::log(falco_logger::level::INFO, "One ring buffer every '" + std::to_string(s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer) + "' CPUs.");
inspector->open_modern_bpf(s.syscall_buffer_bytes_size, s.config->m_modern_bpf.m_cpus_for_each_syscall_buffer, true, s.selected_sc_set);
}
else if(getenv(FALCO_BPF_ENV_VARIABLE) != NULL || (!is_driver_mode_from_cmdline && s.config->m_driver_mode == driver_mode_type::BPF)) /* BPF engine. */
else if(s.config->m_driver_mode == driver_mode_type::EBPF) /* BPF engine. */
{
const char *bpf_probe_path = std::getenv(FALCO_BPF_ENV_VARIABLE);
const char *bpf_probe_path = s.config->m_bpf.m_probe_path.c_str();
char full_path[PATH_MAX];
/* If the path is empty try to load the probe from the default path. */
if(strncmp(bpf_probe_path, "", 1) == 0)
Expand Down
2 changes: 1 addition & 1 deletion userspace/falco/app/actions/init_inspectors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static void init_syscall_inspector(falco::app::state& s, std::shared_ptr<sinsp>
inspector->set_snaplen(s.options.snaplen);
}

if (s.config->m_syscall_drop_failed_exit)
if (s.is_driver_drop_failed_exit_enabled())
{
falco_logger::log(falco_logger::level::INFO, "Failed syscall exit events are dropped in the kernel driver\n");
inspector->set_dropfailed(true);
Expand Down
41 changes: 33 additions & 8 deletions userspace/falco/app/actions/load_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,42 @@ limitations under the License.
#include "actions.h"
#include "falco_utils.h"

/* DEPRECATED: we will remove it in Falco 0.38. */
#define FALCO_BPF_ENV_VARIABLE "FALCO_BPF_PROBE"

using namespace falco::app;
using namespace falco::app::actions;

// applies legacy/in-deprecation options to the current config
static void apply_deprecated_options(
const falco::app::options& opts,
const std::shared_ptr<falco_configuration>& cfg)
// applies legacy/in-deprecation options to the current state
static falco::app::run_result apply_deprecated_options(falco::app::state& s)
{
// Keep for future use cases.
// If overridden from CLI options (soon to be removed),
// use the requested driver.
if (getenv(FALCO_BPF_ENV_VARIABLE))
{
s.config->m_driver_mode = driver_mode_type::EBPF;
s.config->m_bpf.m_probe_path = getenv(FALCO_BPF_ENV_VARIABLE);
}
else if (s.options.modern_bpf)
{
s.config->m_driver_mode = driver_mode_type::MODERN_EBPF;
}
if (!s.options.gvisor_config.empty())
{
s.config->m_driver_mode = driver_mode_type::GVISOR;
s.config->m_gvisor.m_config = s.options.gvisor_config;
s.config->m_gvisor.m_root = s.options.gvisor_root;
}
if (s.options.nodriver)
{
s.config->m_driver_mode = driver_mode_type::NONE;
}
if (!s.options.trace_filename.empty())
{
s.config->m_driver_mode = driver_mode_type::REPLAY;
s.config->m_replay.m_scap_file = s.options.trace_filename;
}
return run_result::ok();
}

falco::app::run_result falco::app::actions::load_config(falco::app::state& s)
Expand Down Expand Up @@ -61,9 +88,7 @@ falco::app::run_result falco::app::actions::load_config(falco::app::state& s)

s.config->m_buffered_outputs = !s.options.unbuffered_outputs;

apply_deprecated_options(s.options, s.config);

return run_result::ok();
return apply_deprecated_options(s);
}

falco::app::run_result falco::app::actions::require_config_file(falco::app::state& s)
Expand Down
Loading

0 comments on commit 513b6f8

Please sign in to comment.