From 5b15202dfa1c620a407e53db9d7d4dc8a2b74043 Mon Sep 17 00:00:00 2001 From: Gianmatteo Palmieri Date: Mon, 15 Jul 2024 11:14:49 +0200 Subject: [PATCH] new(libsinsp): capture listening capability Signed-off-by: Gianmatteo Palmieri --- userspace/libsinsp/plugin.cpp | 32 ++++++++++++++++++-- userspace/libsinsp/test/plugins.ut.cpp | 1 - userspace/libsinsp/test/plugins/routines.cpp | 6 ++-- userspace/plugin/plugin_api.h | 32 +++++++++++++++----- userspace/plugin/plugin_loader.c | 10 ++++++ userspace/plugin/plugin_loader.h | 13 ++++---- 6 files changed, 74 insertions(+), 20 deletions(-) diff --git a/userspace/libsinsp/plugin.cpp b/userspace/libsinsp/plugin.cpp index c99d202206..4b91a4a2ec 100755 --- a/userspace/libsinsp/plugin.cpp +++ b/userspace/libsinsp/plugin.cpp @@ -863,9 +863,23 @@ void sinsp_plugin::capture_open() routine_vtable.subscribe = &plugin_subscribe_routine; routine_vtable.unsubscribe = &plugin_unsubscribe_routine; + ss_plugin_capture_listen_input in; + ss_plugin_table_reader_vtable_ext table_reader_ext; + ss_plugin_table_writer_vtable_ext table_writer_ext; + ss_plugin_table_reader_vtable table_reader; + ss_plugin_table_writer_vtable table_writer; + + in.owner = (ss_plugin_owner_t *) this; + in.table_reader_ext = &table_reader_ext; + in.table_writer_ext = &table_writer_ext; + in.routine = routine_vtable; + + sinsp_plugin::table_read_api(table_reader, table_reader_ext); + sinsp_plugin::table_write_api(table_writer, table_writer_ext); + if(m_handle->api.capture_open) { - m_handle->api.capture_open(m_state, routine_vtable); + m_handle->api.capture_open(m_state, &in); } } @@ -880,9 +894,23 @@ void sinsp_plugin::capture_close() routine_vtable.subscribe = &plugin_subscribe_routine; routine_vtable.unsubscribe = &plugin_unsubscribe_routine; + ss_plugin_capture_listen_input in; + ss_plugin_table_reader_vtable_ext table_reader_ext; + ss_plugin_table_writer_vtable_ext table_writer_ext; + ss_plugin_table_reader_vtable table_reader; + ss_plugin_table_writer_vtable table_writer; + + in.owner = (ss_plugin_owner_t *) this; + in.table_reader_ext = &table_reader_ext; + in.table_writer_ext = &table_writer_ext; + in.routine = routine_vtable; + + sinsp_plugin::table_read_api(table_reader, table_reader_ext); + sinsp_plugin::table_write_api(table_writer, table_writer_ext); + if(m_handle->api.capture_close) { - m_handle->api.capture_close(m_state, routine_vtable); + m_handle->api.capture_close(m_state, &in); } } diff --git a/userspace/libsinsp/test/plugins.ut.cpp b/userspace/libsinsp/test/plugins.ut.cpp index ad6acddf35..d3a413c30f 100644 --- a/userspace/libsinsp/test/plugins.ut.cpp +++ b/userspace/libsinsp/test/plugins.ut.cpp @@ -956,5 +956,4 @@ TEST_F(sinsp_with_test_input, plugin_routines) std::this_thread::sleep_for(std::chrono::nanoseconds(100));; //wait for a bit to let routine finish routines_num = m_inspector.m_thread_pool->routines_num(); ASSERT_EQ(routines_num, 0); - } diff --git a/userspace/libsinsp/test/plugins/routines.cpp b/userspace/libsinsp/test/plugins/routines.cpp index 0b1bdb928c..bb549c43b8 100644 --- a/userspace/libsinsp/test/plugins/routines.cpp +++ b/userspace/libsinsp/test/plugins/routines.cpp @@ -130,15 +130,15 @@ static ss_plugin_rc plugin_parse_event(ss_plugin_t *s, const ss_plugin_event_inp return SS_PLUGIN_SUCCESS; } -static void plugin_capture_open(ss_plugin_t* s, ss_plugin_routine_vtable r) +static void plugin_capture_open(ss_plugin_t* s, const ss_plugin_capture_listen_input* i) { plugin_state *ps = (plugin_state *) s; - ps->routine_vtable = r; + ps->routine_vtable = i->routine; ps->routine_vtable.subscribe(ps->owner, do_nothing, (ss_plugin_routine_state_t*)&ps->flag); } -static void plugin_capture_close(ss_plugin_t* s, ss_plugin_routine_vtable r) +static void plugin_capture_close(ss_plugin_t* s, const ss_plugin_capture_listen_input* i) { } diff --git a/userspace/plugin/plugin_api.h b/userspace/plugin/plugin_api.h index 38d72cbd31..b0b6a476fb 100644 --- a/userspace/plugin/plugin_api.h +++ b/userspace/plugin/plugin_api.h @@ -427,6 +427,25 @@ typedef struct void (*unsubscribe)(ss_plugin_owner_t* o, ss_plugin_routine_t* r); } ss_plugin_routine_vtable; +// Input passed to the plugin when the framework start and stops the capture. +typedef struct ss_plugin_capture_listen_input +{ + // + // The plugin's owner. Can be passed by the plugin to the callbacks available + // in this struct in order to invoke functions of its owner. + ss_plugin_owner_t* owner; + // + // Vtable containing callbacks that can be used by the plugin + // for subscribing and unsubscribing routines to the framework's thread pool. + ss_plugin_routine_vtable routine; + // + // Vtable for controlling a state table for read operations. + ss_plugin_table_reader_vtable_ext* table_reader_ext; + // + // Vtable for controlling a state table for write operations. + ss_plugin_table_writer_vtable_ext* table_writer_ext; +} ss_plugin_capture_listen_input; + // // Function handler used by plugin for sending asynchronous events to the // Falcosecurity libs during a live event capture. The asynchronous events @@ -1028,20 +1047,17 @@ typedef struct // Required: no // Arguments: // - s: the plugin state, returned by init(). Can be NULL. - // - r: a vtable containing callback that can be used by the plugin - // for subscribing and unsubscribing routines to the framework's thread pool. - // This vtable can be retained and used for the rest of the plugin's life-cycle. - void (*capture_open)(ss_plugin_t* s, ss_plugin_routine_vtable r); + // - i: input containing vtables for performing table operations and subscribe/unsubscribe async routines + void (*capture_open)(ss_plugin_t* s, const ss_plugin_capture_listen_input* i); // // Called by the framework when the event capture closes. // - // Required: no + // Required: yes if capture_open is defined // Arguments: // - s: the plugin state, returned by init(). Can be NULL. - // - r: a vtable containing callback that can be used by the plugin - // for subscribing and unsubscribing routines to the framework's thread pool. - void (*capture_close)(ss_plugin_t* s, ss_plugin_routine_vtable r); + // - i: input containing vtables for performing table operations and subscribe/unsubscribe async routines + void (*capture_close)(ss_plugin_t* s, const ss_plugin_capture_listen_input* i); }; } plugin_api; diff --git a/userspace/plugin/plugin_loader.c b/userspace/plugin/plugin_loader.c index 2f22654306..8361f121bb 100644 --- a/userspace/plugin/plugin_loader.c +++ b/userspace/plugin/plugin_loader.c @@ -296,6 +296,16 @@ plugin_caps_t plugin_get_capabilities(const plugin_handle_t* h, char* err) err_append(err, "must implement both 'plugin_get_async_events' and 'plugin_set_async_event_handler' (async events)", ", "); } + if (h->api.capture_open != NULL && h->api.capture_close != NULL) + { + caps = (plugin_caps_t)((uint32_t) caps | (uint32_t) CAP_CAPTURE_LISTENING); + } + else if (h->api.capture_open != NULL) + { + caps = (plugin_caps_t)((uint32_t) caps | (uint32_t) CAP_BROKEN); + err_append(err, "must implement both 'plugin_capture_open' and 'plugin_capture_close' (capture listening)", ", "); + } + return caps; } diff --git a/userspace/plugin/plugin_loader.h b/userspace/plugin/plugin_loader.h index 01a45bfe5c..f33b553bc1 100644 --- a/userspace/plugin/plugin_loader.h +++ b/userspace/plugin/plugin_loader.h @@ -39,12 +39,13 @@ extern "C" { */ typedef enum { - CAP_NONE = 0, - CAP_SOURCING = 1 << 0, - CAP_EXTRACTION = 1 << 1, - CAP_PARSING = 1 << 2, - CAP_ASYNC = 1 << 3, - CAP_BROKEN = 1 << 31, // used to report inconsistencies + CAP_NONE = 0, + CAP_SOURCING = 1 << 0, + CAP_EXTRACTION = 1 << 1, + CAP_PARSING = 1 << 2, + CAP_ASYNC = 1 << 3, + CAP_CAPTURE_LISTENING = 1 << 4, + CAP_BROKEN = 1 << 31, // used to report inconsistencies } plugin_caps_t; /*!