Skip to content

Commit

Permalink
Add optional support for multiple filters.
Browse files Browse the repository at this point in the history
Add support for an additional set of individual filters that can run
alongside the main filter set in sinsp::set_filter(). Each additional
filter comes with a list of event types for which the filter should run.

sinsp::add_evttype_filter adds an event type filter to the inspector. It
provides a list of event types and a sinsp_filter pointer. The list of
event types can be empty, implying the filter is a catchall filter and
should run for all event types. This does not replace the main function
set_filter()--the idea is that you can specify a global filter as well
as per-event type filters. Both will run for all events.

An array m_filter_by_evttype maps from event type to a list of
sinsp_filter pointers. Each list at index i holds the filters that
should run for events with type i. A filter can run for multiple event
types, so the sinsp_filter pointers can appear in multiple lists.

There's a separate list m_catchall_evttype_filters that contains filters
that should run for all event types.

The individual filter pointers are also held in a list m_evttype_filters
so they can be cleaned up on close().

A new method run_filters_on_evt() handles the details of running the
main filter, catchall filters, and the individual filters. It finds the
filters related to the event's type, and runs those filters.

Falco uses the lua callbacks in lua_parser{_api} to populate filters as
the lua code parses the rule's condition, so also modify lua_parser to
add a optional flag to get_parser that steals the m_filter object and
creates a new one. Falco calls get_parser for each rule's condition,
which allows it to create a sinsp_filter object for each rule.
  • Loading branch information
mstemm committed Jul 14, 2016
1 parent c15f0ff commit b3ebbe1
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 16 deletions.
27 changes: 20 additions & 7 deletions userspace/libsinsp/lua_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ lua_parser::lua_parser(sinsp* inspector, lua_State *ls)
m_inspector = inspector;

m_ls = ls;
m_have_rel_expr = false;
m_last_boolop = BO_NONE;
m_nest_level = 0;

m_filter = new sinsp_filter(m_inspector);
reset();

// Register our c++ defined functions
luaL_openlib(m_ls, "filter", ll_filter, 0);
Expand All @@ -41,13 +37,30 @@ lua_parser::lua_parser(sinsp* inspector, lua_State *ls)

}

sinsp_filter* lua_parser::get_filter()
void lua_parser::reset()
{
m_have_rel_expr = false;
m_last_boolop = BO_NONE;
m_nest_level = 0;

m_filter = new sinsp_filter(m_inspector);
}

sinsp_filter* lua_parser::get_filter(bool reset_filter)
{
if (m_nest_level != 0)
{
throw sinsp_exception("Error in configured filter: unbalanced nesting");
}
return m_filter;

sinsp_filter *ret = m_filter;

if (reset_filter)
{
reset();
}

return ret;
}
lua_parser::~lua_parser()
{
Expand Down
4 changes: 3 additions & 1 deletion userspace/libsinsp/lua_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ class lua_parser
public:
lua_parser(sinsp* inspector, lua_State *ls);
~lua_parser();
sinsp_filter* get_filter();
sinsp_filter* get_filter(bool reset_filter = false);

private:

void reset();
sinsp* m_inspector;

sinsp_filter* m_filter;
Expand Down
13 changes: 5 additions & 8 deletions userspace/libsinsp/parsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ void sinsp_parser::process_event(sinsp_evt *evt)
#if defined(HAS_FILTERING) && defined(HAS_CAPTURE_FILTERING)
bool do_filter_later = false;

if(m_inspector->m_filter)
if(m_inspector->m_filter || m_inspector->m_evttype_filters.size() > 0)
{
ppm_event_flags eflags = evt->get_info_flags();

Expand Down Expand Up @@ -230,7 +230,7 @@ void sinsp_parser::process_event(sinsp_evt *evt)
}
else
{
if(m_inspector->m_filter->run(evt) == false)
if(m_inspector->run_filters_on_evt(evt) == false)
{
if(evt->m_tinfo != NULL)
{
Expand Down Expand Up @@ -468,13 +468,10 @@ void sinsp_parser::process_event(sinsp_evt *evt)
#if defined(HAS_FILTERING) && defined(HAS_CAPTURE_FILTERING)
if(do_filter_later)
{
if(m_inspector->m_filter)
if(m_inspector->run_filters_on_evt(evt) == false)
{
if(m_inspector->m_filter->run(evt) == false)
{
evt->m_filtered_out = true;
return;
}
evt->m_filtered_out = true;
return;
}
evt->m_filtered_out = false;
}
Expand Down
80 changes: 80 additions & 0 deletions userspace/libsinsp/sinsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,23 @@ void sinsp::close()
delete m_filter;
m_filter = NULL;
}

for(int i = 0; i < PPM_EVENT_MAX; i++)
{
if(m_filter_by_evttype[i])
{
delete m_filter_by_evttype[i];
m_filter_by_evttype[i] = NULL;
}
}

m_catchall_evttype_filters.clear();

for(auto filter : m_evttype_filters)
{
delete filter;
}
m_evttype_filters.clear();
#endif
}

Expand Down Expand Up @@ -1351,6 +1368,69 @@ const string sinsp::get_filter()
return m_filterstring;
}

void sinsp::add_evttype_filter(list<uint32_t> &evttypes,
sinsp_filter *filter)
{
m_evttype_filters.push_back(filter);

if(evttypes.size() == 0)
{
m_catchall_evttype_filters.push_back(filter);
}
else
{

for(auto evttype: evttypes)
{
list<sinsp_filter *> *filters = m_filter_by_evttype[evttype];
if(filters == NULL)
{
filters = new list<sinsp_filter*>();
m_filter_by_evttype[evttype] = filters;
}

filters->push_back(filter);
}
}
}

bool sinsp::run_filters_on_evt(sinsp_evt *evt)
{
//
// First run the global filter, if there is one.
//
if(m_filter && m_filter->run(evt) == true)
{
return true;
}

//
// Then run any catchall event type filters (ones that did not
// explicitly specify any event type.
//
for(sinsp_filter *filt : m_catchall_evttype_filters)
{
if(filt->run(evt) == true)
{
return true;
}
}

list<sinsp_filter *> *filters = m_filter_by_evttype[evt->m_pevt->type];

if(filters)
{
for(sinsp_filter *filt : *filters)
{
if(filt->run(evt) == true)
{
return true;
}
}
}

return false;
}
#endif

const scap_machine_info* sinsp::get_machine_info()
Expand Down
19 changes: 19 additions & 0 deletions userspace/libsinsp/sinsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,11 @@ class SINSP_PUBLIC sinsp
string if no filter has been set yet.
*/
const string get_filter();

void add_evttype_filter(list<uint32_t> &evttypes,
sinsp_filter* filter);

bool run_filters_on_evt(sinsp_evt *evt);
#endif

/*!
Expand Down Expand Up @@ -849,6 +854,20 @@ VISIBILITY_PRIVATE
uint64_t m_firstevent_ts;
sinsp_filter* m_filter;
string m_filterstring;

// Maps from event type to filter. There can be multiple
// filters per event type.
list<sinsp_filter *> *m_filter_by_evttype[PPM_EVENT_MAX];

// It's possible to add an event type filter with an empty
// list of event types, meaning it should run for all event
// types.
list<sinsp_filter *> m_catchall_evttype_filters;

// This holds all the filters in
// m_filter_by_evttype/m_catchall_evttype_filters, so they can
// be cleaned up.
list<sinsp_filter *> m_evttype_filters;
#endif

//
Expand Down

0 comments on commit b3ebbe1

Please sign in to comment.