Skip to content

Commit

Permalink
Move eventtype filters into standalone class (#633)
Browse files Browse the repository at this point in the history
* Whitespace diffs.

Checking in separate from other changes.

* Move evttype filters into own class.

Thinking ahead to an embeddable falco, move evttype filters into its own
class sinsp_evttype_filter. The inspector creates one of these objects
on demand whenever add_evttype_filter is called. Otherwise, from falco's
view the interface hasn't changed.
  • Loading branch information
mstemm committed Jul 21, 2016
1 parent 821d4a5 commit b72c866
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 80 deletions.
23 changes: 12 additions & 11 deletions userspace/libsinsp/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ typedef struct filtercheck_field_info
{
ppm_param_type m_type; ///< Field type.
filtercheck_field_flags m_flags; ///< Field flags.
ppm_print_format m_print_format; ///< If this is a numeric field, this flag specifies if it should be rendered as decimal or hex.
ppm_print_format m_print_format; ///< If this is a numeric field, this flag specifies if it should be rendered as decimal or hex.
char m_name[64]; ///< Field name.
char m_description[1024]; ///< Field description.
}filtercheck_field_info;
Expand Down Expand Up @@ -78,17 +78,17 @@ class SINSP_PUBLIC sinsp_evt_param
inline void init(char* valptr, uint16_t len)
{
m_val = valptr;
m_len = len;
m_len = len;
}

friend class sinsp_evt;
};

/*!
\brief Event class.
This class is returned by \ref sinsp::next() and encapsulates the state
related to a captured event, and includes a bunch of members to manipulate
events and their parameters, including parsing, formatting and extracting
This class is returned by \ref sinsp::next() and encapsulates the state
related to a captured event, and includes a bunch of members to manipulate
events and their parameters, including parsing, formatting and extracting
state like the event process or FD.
*/
class SINSP_PUBLIC sinsp_evt
Expand Down Expand Up @@ -160,8 +160,8 @@ class SINSP_PUBLIC sinsp_evt
}

/*!
\brief Get the event type.
\brief Get the event type.
\note For a list of event types, refer to \ref etypes.
*/
inline uint16_t get_type()
Expand Down Expand Up @@ -227,14 +227,14 @@ class SINSP_PUBLIC sinsp_evt
/*!
\brief Return the information about the FD on which this event operated.
\note For events that are not I/O related, get_fd_info() returns NULL.
\note For events that are not I/O related, get_fd_info() returns NULL.
*/
sinsp_fdinfo_t* get_fd_info();

/*!
\brief Return the number of the FD associated with this event.
\note For events that are not I/O related, get_fd_num() returns sinsp_evt::INVALID_FD_NUM.
\note For events that are not I/O related, get_fd_num() returns sinsp_evt::INVALID_FD_NUM.
*/
int64_t get_fd_num();

Expand All @@ -255,7 +255,7 @@ class SINSP_PUBLIC sinsp_evt
\param id The parameter number.
\note Refer to the g_event_info structure in driver/event_table.c for
\note Refer to the g_event_info structure in driver/event_table.c for
a list of event descriptions.
*/
const struct ppm_param_info* get_param_info(uint32_t id);
Expand All @@ -278,7 +278,7 @@ class SINSP_PUBLIC sinsp_evt
\brief Get a parameter as a C++ string.
\param name The parameter name.
\param resolved If true, the library will try to resolve the parameter
\param resolved If true, the library will try to resolve the parameter
before returning it. For example, and FD number will be converted into
the correspondent file, TCP tuple, etc.
*/
Expand Down Expand Up @@ -403,6 +403,7 @@ VISIBILITY_PRIVATE
friend class sinsp_analyzer;
friend class sinsp_filter_check_event;
friend class sinsp_filter_check_thread;
friend class sinsp_evttype_filter;
friend class sinsp_dumper;
friend class sinsp_analyzer_fd_listener;
friend class sinsp_analyzer_parsers;
Expand Down
80 changes: 80 additions & 0 deletions userspace/libsinsp/filter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1917,4 +1917,84 @@ sinsp_filter* sinsp_filter_compiler::compile_()
return m_filter;
}

sinsp_evttype_filter::sinsp_evttype_filter()
{
memset(m_filter_by_evttype, 0, PPM_EVENT_MAX * sizeof(list<sinsp_filter *> *));
}

sinsp_evttype_filter::~sinsp_evttype_filter()
{
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();
}

void sinsp_evttype_filter::add(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_evttype_filter::run(sinsp_evt *evt)
{
//
// First 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 // HAS_FILTERING
34 changes: 34 additions & 0 deletions userspace/libsinsp/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,40 @@ class SINSP_PUBLIC sinsp_filter_compiler
friend class sinsp_evt_formatter;
};

/*!
\brief This class represents a filter optimized using event
types. It actually consists of collections of sinsp_filter objects
grouped by event type.
*/

class SINSP_PUBLIC sinsp_evttype_filter
{
public:
sinsp_evttype_filter();
virtual ~sinsp_evttype_filter();

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

bool run(sinsp_evt *evt);

private:

// 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 // HAS_FILTERING
2 changes: 1 addition & 1 deletion 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 || m_inspector->m_evttype_filters.size() > 0)
if(m_inspector->m_filter || m_inspector->m_evttype_filter)
{
ppm_event_flags eflags = evt->get_info_flags();

Expand Down
66 changes: 11 additions & 55 deletions userspace/libsinsp/sinsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ sinsp::sinsp() :

#ifdef HAS_FILTERING
m_filter = NULL;
m_evttype_filter = NULL;
#endif

m_fds_to_remove = new vector<int64_t>;
Expand Down Expand Up @@ -143,8 +144,6 @@ sinsp::sinsp() :
m_mesos_last_watch_time_ns = 0;

m_filter_proc_table_when_saving = false;

memset(m_filter_by_evttype, 0, PPM_EVENT_MAX * sizeof(list<sinsp_filter *> *));
}

sinsp::~sinsp()
Expand Down Expand Up @@ -552,22 +551,11 @@ void sinsp::close()
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)
if(m_evttype_filter != NULL)
{
delete filter;
delete m_evttype_filter;
m_evttype_filter = NULL;
}
m_evttype_filters.clear();
#endif
}

Expand Down Expand Up @@ -1373,27 +1361,13 @@ const string sinsp::get_filter()
void sinsp::add_evttype_filter(list<uint32_t> &evttypes,
sinsp_filter *filter)
{
m_evttype_filters.push_back(filter);

if(evttypes.size() == 0)
// Create the evttype filter if it doesn't exist.
if(m_evttype_filter == NULL)
{
m_catchall_evttype_filters.push_back(filter);
m_evttype_filter = new sinsp_evttype_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);
}
}
m_evttype_filter->add(evttypes, filter);
}

bool sinsp::run_filters_on_evt(sinsp_evt *evt)
Expand All @@ -1407,28 +1381,10 @@ bool sinsp::run_filters_on_evt(sinsp_evt *evt)
}

//
// 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)
// Then run the evttype filter, if there is one.
if(m_evttype_filter && m_evttype_filter->run(evt) == true)
{
for(sinsp_filter *filt : *filters)
{
if(filt->run(evt) == true)
{
return true;
}
}
return true;
}

return false;
Expand Down
14 changes: 1 addition & 13 deletions userspace/libsinsp/sinsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -853,21 +853,9 @@ VISIBILITY_PRIVATE
#ifdef HAS_FILTERING
uint64_t m_firstevent_ts;
sinsp_filter* m_filter;
sinsp_evttype_filter *m_evttype_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 b72c866

Please sign in to comment.