From c8afec03060206547dc4744d6081cf2333543caf Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Tue, 30 Jul 2024 18:26:22 +0200 Subject: [PATCH 1/9] module: always init factories Since commit 23737963947c ("events: split ebpf and json factories") raw factories are only parsing and converting raw events, aka BPF ones. Thus we no longer have to differentiate the user of such factories and can make raw factory implementations cleaner. Signed-off-by: Antoine Tenart --- retis/src/module/ct/bpf.rs | 6 +----- retis/src/module/ct/ct.rs | 19 +++++------------- retis/src/module/skb_drop/bpf.rs | 28 +++++++-------------------- retis/src/module/skb_drop/skb_drop.rs | 9 +-------- 4 files changed, 14 insertions(+), 48 deletions(-) diff --git a/retis/src/module/ct/bpf.rs b/retis/src/module/ct/bpf.rs index acf88f203..9f0e570b4 100644 --- a/retis/src/module/ct/bpf.rs +++ b/retis/src/module/ct/bpf.rs @@ -124,11 +124,7 @@ impl RawEventSectionFactory for CtEventFactory { impl CtEventFactory { pub(super) fn new() -> Result { - Ok(Self::default()) - } - - pub(super) fn bpf() -> Result { - let mut me = Self::new()?; + let mut me = Self::default(); me.parse_tcp_states()?; Ok(me) } diff --git a/retis/src/module/ct/ct.rs b/retis/src/module/ct/ct.rs index ee0311bec..ff6d36e3c 100644 --- a/retis/src/module/ct/ct.rs +++ b/retis/src/module/ct/ct.rs @@ -15,16 +15,12 @@ use crate::{ module::Module, }; -pub(crate) struct CtModule { - // Whether the event capturing module was initialized - init: bool, -} +#[derive(Default)] +pub(crate) struct CtModule {} impl Collector for CtModule { fn new() -> Result { - Ok(CtModule { - init: cfg!(feature = "benchmark"), - }) + Ok(Self::default()) } fn known_kernel_types(&self) -> Option> { @@ -60,9 +56,7 @@ impl Collector for CtModule { _: Arc, ) -> Result<()> { // Register our generic conntrack hook. - probes.register_kernel_hook(Hook::from(ct_hook::DATA))?; - self.init = true; - Ok(()) + probes.register_kernel_hook(Hook::from(ct_hook::DATA)) } } @@ -71,9 +65,6 @@ impl Module for CtModule { self } fn section_factory(&self) -> Result> { - Ok(Box::new(match self.init { - true => CtEventFactory::bpf()?, - false => CtEventFactory::new()?, - })) + Ok(Box::new(CtEventFactory::new()?)) } } diff --git a/retis/src/module/skb_drop/bpf.rs b/retis/src/module/skb_drop/bpf.rs index 986ddcf4c..23dd8fd0b 100644 --- a/retis/src/module/skb_drop/bpf.rs +++ b/retis/src/module/skb_drop/bpf.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use anyhow::{bail, Result}; +use anyhow::Result; use btf_rs::Type; use log::warn; @@ -83,22 +83,15 @@ impl DropReasons { #[derive(crate::EventSectionFactory)] pub(crate) struct SkbDropEventFactory { - /// Map of sub-system reason ids to their custom drop reason definitions. A - /// `Some` value with an empty map means we couldn't retrieve the drop - /// reasons from the running kernel. - reasons: Option>, + /// Map of sub-system reason ids to their custom drop reason definitions. + reasons: HashMap, } impl RawEventSectionFactory for SkbDropEventFactory { fn create(&mut self, raw_sections: Vec) -> Result> { let raw = parse_single_raw_section::(SectionId::SkbDrop, &raw_sections)?; - let drop_reason = raw.drop_reason; - - // Check if the drop reasons were correctly initialized. - if self.reasons.is_none() { - bail!("Factory was not initialized for consuming BPF events"); - } + let drop_reason = raw.drop_reason; let (subsys, drop_reason) = self.get_reason(drop_reason); Ok(Box::new(SkbDropEvent { @@ -111,11 +104,6 @@ impl RawEventSectionFactory for SkbDropEventFactory { impl SkbDropEventFactory { /// Initialize a new skb drop factory. pub(crate) fn new() -> Result { - Ok(Self { reasons: None }) - } - - /// Initialize a new skb drop factory when handling events from BPF. - pub(crate) fn bpf() -> Result { let subsys = parse_enum("skb_drop_reason_subsys", &["SKB_DROP_REASON_SUBSYS_"])?; // Parse each sub-system drop reasons. @@ -134,9 +122,7 @@ impl SkbDropEventFactory { reasons.insert(0, DropReasons::from_subsystem("core")?); } - Ok(Self { - reasons: Some(reasons), - }) + Ok(Self { reasons }) } /// Converts a raw drop reason value to a tuple of an optional sub-system @@ -144,14 +130,14 @@ impl SkbDropEventFactory { fn get_reason(&self, raw_val: i32) -> (Option, String) { // Special case when drop reasons aren't supported by the kernel. Fake a // core NOT_SPECIFIED reason. - if raw_val < 0 || self.reasons.is_none() { + if raw_val < 0 { return (None, "NOT_SPECIFIED".to_string()); } let raw_val = raw_val as u32; // Retrieve the sub-system drop reason definition, if any. let subsys_id = (raw_val >> SKB_DROP_REASON_SUBSYS_SHIFT) as u16; - let subsys = match self.reasons.as_ref().unwrap().get(&subsys_id) { + let subsys = match self.reasons.get(&subsys_id) { Some(subsys) => subsys, // Handle the None case but really that should not happen, because // that means having a sub-system generating drop reasons without diff --git a/retis/src/module/skb_drop/skb_drop.rs b/retis/src/module/skb_drop/skb_drop.rs index bc2ac3913..c97e3860c 100644 --- a/retis/src/module/skb_drop/skb_drop.rs +++ b/retis/src/module/skb_drop/skb_drop.rs @@ -19,15 +19,12 @@ use crate::{ pub(crate) struct SkbDropModule { reasons_available: bool, - // Was the module initialized, aka. installed BPF probes and hooks? - initialized: bool, } impl Collector for SkbDropModule { fn new() -> Result { Ok(Self { reasons_available: true, - initialized: cfg!(feature = "benchmark"), }) } @@ -99,7 +96,6 @@ impl Collector for SkbDropModule { bail!("Could not attach to skb:kfree_skb: {}", e); } - self.initialized = true; Ok(()) } } @@ -109,9 +105,6 @@ impl Module for SkbDropModule { self } fn section_factory(&self) -> Result> { - Ok(Box::new(match self.initialized { - true => SkbDropEventFactory::bpf()?, - false => SkbDropEventFactory::new()?, - })) + Ok(Box::new(SkbDropEventFactory::new()?)) } } From 6b4b641e092c20c20eb6753840e6764773f65591 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Fri, 9 Aug 2024 14:38:29 +0200 Subject: [PATCH 2/9] module: allow modules not to provide an event factory This makes modules not required to produce events, as they can provide value by doing other scoped work (eg. installing probes). This shows again the limits of our module abstraction and it might be removed at some point to clean things up a bit. Signed-off-by: Antoine Tenart --- retis/src/collect/collector.rs | 8 ++++---- retis/src/module/ct/ct.rs | 4 ++-- retis/src/module/module.rs | 10 +++++++--- retis/src/module/nft/nft.rs | 4 ++-- retis/src/module/ovs/ovs.rs | 4 ++-- retis/src/module/skb/skb.rs | 6 +++--- retis/src/module/skb_drop/skb_drop.rs | 4 ++-- retis/src/module/skb_tracking/skb_tracking.rs | 4 ++-- 8 files changed, 24 insertions(+), 20 deletions(-) diff --git a/retis/src/collect/collector.rs b/retis/src/collect/collector.rs index 906a1d62b..13ce625b1 100644 --- a/retis/src/collect/collector.rs +++ b/retis/src/collect/collector.rs @@ -576,8 +576,8 @@ mod tests { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(TestEvent {})) + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(TestEvent {}))) } } @@ -608,8 +608,8 @@ mod tests { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(TestEvent {})) + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(TestEvent {}))) } } diff --git a/retis/src/module/ct/ct.rs b/retis/src/module/ct/ct.rs index ff6d36e3c..bd2d7ad42 100644 --- a/retis/src/module/ct/ct.rs +++ b/retis/src/module/ct/ct.rs @@ -64,7 +64,7 @@ impl Module for CtModule { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(CtEventFactory::new()?)) + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(CtEventFactory::new()?))) } } diff --git a/retis/src/module/module.rs b/retis/src/module/module.rs index 25a67647c..ec612e78b 100644 --- a/retis/src/module/module.rs +++ b/retis/src/module/module.rs @@ -20,8 +20,10 @@ use crate::{ pub(crate) trait Module { /// Return a Collector used for collect command fn collector(&mut self) -> &mut dyn Collector; - /// Return an EventSectionFactory - fn section_factory(&self) -> Result>; + /// Return an EventSectionFactory, if any + fn section_factory(&self) -> Result>> { + Ok(None) + } } /// All modules are registered there. The following is the main API and object @@ -88,7 +90,9 @@ impl Modules { ); for (id, module) in self.modules.iter() { - section_factories.insert(*id, module.section_factory()?); + if let Some(factory) = module.section_factory()? { + section_factories.insert(*id, factory); + } } Ok(section_factories) } diff --git a/retis/src/module/nft/nft.rs b/retis/src/module/nft/nft.rs index 27f114459..1d5e76f9f 100644 --- a/retis/src/module/nft/nft.rs +++ b/retis/src/module/nft/nft.rs @@ -53,8 +53,8 @@ impl Module for NftModule { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(NftEventFactory {})) + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(NftEventFactory {}))) } } diff --git a/retis/src/module/ovs/ovs.rs b/retis/src/module/ovs/ovs.rs index 2d1925e55..50480b229 100644 --- a/retis/src/module/ovs/ovs.rs +++ b/retis/src/module/ovs/ovs.rs @@ -141,8 +141,8 @@ impl Module for OvsModule { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(OvsEventFactory {})) + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(OvsEventFactory {}))) } } diff --git a/retis/src/module/skb/skb.rs b/retis/src/module/skb/skb.rs index c0e8f8892..857998c02 100644 --- a/retis/src/module/skb/skb.rs +++ b/retis/src/module/skb/skb.rs @@ -131,10 +131,10 @@ impl Module for SkbModule { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(SkbEventFactory { + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(SkbEventFactory { report_eth: self.report_eth, - })) + }))) } } diff --git a/retis/src/module/skb_drop/skb_drop.rs b/retis/src/module/skb_drop/skb_drop.rs index c97e3860c..799cc9c8f 100644 --- a/retis/src/module/skb_drop/skb_drop.rs +++ b/retis/src/module/skb_drop/skb_drop.rs @@ -104,7 +104,7 @@ impl Module for SkbDropModule { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(SkbDropEventFactory::new()?)) + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(SkbDropEventFactory::new()?))) } } diff --git a/retis/src/module/skb_tracking/skb_tracking.rs b/retis/src/module/skb_tracking/skb_tracking.rs index 730d40718..8a1e214fe 100644 --- a/retis/src/module/skb_tracking/skb_tracking.rs +++ b/retis/src/module/skb_tracking/skb_tracking.rs @@ -45,8 +45,8 @@ impl Module for SkbTrackingModule { fn collector(&mut self) -> &mut dyn Collector { self } - fn section_factory(&self) -> Result> { - Ok(Box::new(SkbTrackingEventFactory {})) + fn section_factory(&self) -> Result>> { + Ok(Some(Box::new(SkbTrackingEventFactory {}))) } } From 1600a9654add87249063146cffd0d512ce6fcdaa Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 12 Aug 2024 11:32:37 +0200 Subject: [PATCH 3/9] events: remove to_u8() from SectionId SectionId member can be directly casted as u8, there's no need to maintain an helper doing so. Signed-off-by: Antoine Tenart --- retis-events/src/events.rs | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/retis-events/src/events.rs b/retis-events/src/events.rs index cc1ccfeb7..c26ae2bd7 100644 --- a/retis-events/src/events.rs +++ b/retis-events/src/events.rs @@ -166,7 +166,7 @@ impl EventFmt for Event { f.conf.inc_level(2); // Finally show all sections. - (SectionId::Skb.to_u8()..SectionId::_MAX.to_u8()) + (SectionId::Skb as u8..SectionId::_MAX as u8) .collect::>() .iter() .filter_map(|id| self.0.get(&SectionId::from_u8(*id).unwrap())) @@ -241,26 +241,6 @@ impl SectionId { }) } - /// Converts an SectionId to a section unique identifier. - #[allow(dead_code)] - pub fn to_u8(self) -> u8 { - use SectionId::*; - match self { - Common => 1, - Kernel => 2, - Userspace => 3, - Tracking => 4, - SkbTracking => 5, - SkbDrop => 6, - Skb => 7, - Ovs => 8, - Nft => 9, - Ct => 10, - Startup => 11, - _MAX => 12, - } - } - /// Converts an SectionId to a section unique str identifier. pub fn to_str(self) -> &'static str { use SectionId::*; From e00040945b45fceab76185c268f0096706cfd18a Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 12 Aug 2024 11:37:58 +0200 Subject: [PATCH 4/9] retis-derive: merge EventSection and event_section We no longer have a need to split both definitions, EventSection is never used outside of event_section. Signed-off-by: Antoine Tenart --- retis-derive/src/lib.rs | 41 +++++++++++++++++------------------- retis/src/core/events/bpf.rs | 5 +++-- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/retis-derive/src/lib.rs b/retis-derive/src/lib.rs index 1764e8af8..efb1fa3de 100644 --- a/retis-derive/src/lib.rs +++ b/retis-derive/src/lib.rs @@ -27,36 +27,16 @@ pub fn event_section( let name: syn::LitStr = syn::parse(args).expect("Invalid event name"); let output = quote! { - #[derive(Default, crate::EventSection)] + #[derive(Default)] #[crate::event_type] #input impl #ident { pub(crate) const SECTION_NAME: &'static str = #name; } - }; - output.into() -} -#[proc_macro_attribute] -pub fn event_type( - _: proc_macro::TokenStream, - item: proc_macro::TokenStream, -) -> proc_macro::TokenStream { - let input: Item = parse_macro_input!(item); - let output = quote! { - #[serde_with::skip_serializing_none] - #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] - #input - }; - output.into() -} - -#[proc_macro_derive(EventSection)] -pub fn derive_event_section(input: TokenStream) -> TokenStream { - let DeriveInput { ident, .. } = parse_macro_input!(input); - let output = quote! { impl EventSectionInternal for #ident { + fn as_any(&self) -> &dyn std::any::Any where Self: Sized, { @@ -79,6 +59,23 @@ pub fn derive_event_section(input: TokenStream) -> TokenStream { output.into() } +#[proc_macro_attribute] +pub fn event_type( + _: proc_macro::TokenStream, + item: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + let output = format!( + r#" + #[serde_with::skip_serializing_none] + #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] + {item} + "# + ); + output + .parse() + .expect("Invalid tokens from event_section macro") +} + #[proc_macro_derive(EventSectionFactory)] pub fn derive_event_section_factory(input: TokenStream) -> TokenStream { let input: DeriveInput = parse_macro_input!(input); diff --git a/retis/src/core/events/bpf.rs b/retis/src/core/events/bpf.rs index 0f63e58de..35d137c14 100644 --- a/retis/src/core/events/bpf.rs +++ b/retis/src/core/events/bpf.rs @@ -606,12 +606,13 @@ mod tests { use serde::{Deserialize, Serialize}; use super::*; - use crate::{EventSection, EventSectionFactory}; + use crate::{event_section, EventSectionFactory}; const DATA_TYPE_U64: u8 = 1; const DATA_TYPE_U128: u8 = 2; - #[derive(Default, Deserialize, Serialize, EventSection, EventSectionFactory)] + #[derive(EventSectionFactory)] + #[event_section("test")] struct TestEvent { field0: Option, field1: Option, From 59b235aabc3ba18c5028e79f9a4a6bd522f53906 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 12 Aug 2024 11:51:07 +0200 Subject: [PATCH 5/9] tree: link event sections to section ids Those two were loosely tightened, when adding sub-sections to an event. Even more, the section names where both defined in the event sections and in the section ids. As there should be a 1:1 relationship between event sections and ids, make the id part of the event section. This has another advantage as a side effect: raw section factories do not need a 1:1 relationship with an event section and can generate any event section. Signed-off-by: Antoine Tenart --- retis-derive/src/lib.rs | 7 +- retis-events/src/common.rs | 4 +- retis-events/src/ct.rs | 2 +- retis-events/src/events.rs | 111 +++++++++++++++---------------- retis-events/src/kernel.rs | 2 +- retis-events/src/nft.rs | 2 +- retis-events/src/ovs.rs | 2 +- retis-events/src/skb.rs | 2 +- retis-events/src/skb_drop.rs | 2 +- retis-events/src/skb_tracking.rs | 4 +- retis-events/src/user.rs | 2 +- retis/src/collect/collector.rs | 2 +- retis/src/core/events/bpf.rs | 13 ++-- 13 files changed, 75 insertions(+), 80 deletions(-) diff --git a/retis-derive/src/lib.rs b/retis-derive/src/lib.rs index efb1fa3de..8ba629607 100644 --- a/retis-derive/src/lib.rs +++ b/retis-derive/src/lib.rs @@ -24,7 +24,7 @@ pub fn event_section( let input: ItemStruct = parse_macro_input!(item); let ident = &input.ident; - let name: syn::LitStr = syn::parse(args).expect("Invalid event name"); + let id: syn::Expr = syn::parse(args).expect("Invalid event id"); let output = quote! { #[derive(Default)] @@ -32,10 +32,13 @@ pub fn event_section( #input impl #ident { - pub(crate) const SECTION_NAME: &'static str = #name; + pub(crate) const SECTION_ID: u8 = #id as u8; } impl EventSectionInternal for #ident { + fn id(&self) -> u8 { + Self::SECTION_ID + } fn as_any(&self) -> &dyn std::any::Any where Self: Sized, diff --git a/retis-events/src/common.rs b/retis-events/src/common.rs index 1cc8067da..1da7bf5e8 100644 --- a/retis-events/src/common.rs +++ b/retis-events/src/common.rs @@ -6,7 +6,7 @@ use crate::*; /// Startup event section. Contains global information about a collection as a /// whole, with data gathered at collection startup time. -#[event_section("startup")] +#[event_section(SectionId::Startup)] pub struct StartupEvent { /// Retis version used while collecting events. pub retis_version: String, @@ -33,7 +33,7 @@ pub struct TaskEvent { } /// Common event section. -#[event_section("common")] +#[event_section(SectionId::Common)] pub struct CommonEvent { /// Timestamp of when the event was generated. pub timestamp: u64, diff --git a/retis-events/src/ct.rs b/retis-events/src/ct.rs index 3b878e8ca..f19b902a2 100644 --- a/retis-events/src/ct.rs +++ b/retis-events/src/ct.rs @@ -100,7 +100,7 @@ pub enum CtState { Untracked, } /// Conntrack event -#[event_section("ct")] +#[event_section(SectionId::Ct)] pub struct CtEvent { /// Packet's conntrack state pub state: CtState, diff --git a/retis-events/src/events.rs b/retis-events/src/events.rs index c26ae2bd7..13aa2a3aa 100644 --- a/retis-events/src/events.rs +++ b/retis-events/src/events.rs @@ -60,18 +60,15 @@ impl Event { .map_err(|e| anyhow!("Failed to parse json event at line {line}: {e}"))?; for (owner, value) in event_js.drain() { - let owner_mod = SectionId::from_str(&owner)?; let parser = event_sections()? .get(&owner) .ok_or_else(|| anyhow!("json contains an unsupported event {}", owner))?; debug!("Unmarshaling event section {owner}: {value}"); - event.insert_section( - owner_mod, - parser(value).map_err(|e| { - anyhow!("Failed to create EventSection for owner {owner} from json: {e}") - })?, - )?; + let section = parser(value).map_err(|e| { + anyhow!("Failed to create EventSection for owner {owner} from json: {e}") + })?; + event.insert_section(SectionId::from_u8(section.id())?, section)?; } Ok(event) } @@ -205,17 +202,17 @@ impl FromStr for SectionId { fn from_str(val: &str) -> Result { use SectionId::*; Ok(match val { - CommonEvent::SECTION_NAME => Common, - KernelEvent::SECTION_NAME => Kernel, - UserEvent::SECTION_NAME => Userspace, - TrackingInfo::SECTION_NAME => Tracking, - SkbTrackingEvent::SECTION_NAME => SkbTracking, - SkbDropEvent::SECTION_NAME => SkbDrop, - SkbEvent::SECTION_NAME => Skb, - OvsEvent::SECTION_NAME => Ovs, - NftEvent::SECTION_NAME => Nft, - CtEvent::SECTION_NAME => Ct, - StartupEvent::SECTION_NAME => Startup, + "common" => Common, + "kernel" => Kernel, + "userspace" => Userspace, + "tracking" => Tracking, + "skb-tracking" => SkbTracking, + "skb-drop" => SkbDrop, + "skb" => Skb, + "ovs" => Ovs, + "nft" => Nft, + "ct" => Ct, + "startup" => Startup, x => bail!("Can't construct a SectionId from {}", x), }) } @@ -245,17 +242,17 @@ impl SectionId { pub fn to_str(self) -> &'static str { use SectionId::*; match self { - Common => CommonEvent::SECTION_NAME, - Kernel => KernelEvent::SECTION_NAME, - Userspace => UserEvent::SECTION_NAME, - Tracking => TrackingInfo::SECTION_NAME, - SkbTracking => SkbTrackingEvent::SECTION_NAME, - SkbDrop => SkbDropEvent::SECTION_NAME, - Skb => SkbEvent::SECTION_NAME, - Ovs => OvsEvent::SECTION_NAME, - Nft => NftEvent::SECTION_NAME, - Ct => CtEvent::SECTION_NAME, - Startup => StartupEvent::SECTION_NAME, + Common => "common", + Kernel => "kernel", + Userspace => "userspace", + Tracking => "tracking", + SkbTracking => "skb-tracking", + SkbDrop => "skb-drop", + Skb => "skb", + Ovs => "ovs", + Nft => "nft", + Ct => "ct", + Startup => "startup", _MAX => "_max", } } @@ -271,39 +268,30 @@ impl fmt::Display for SectionId { type EventSectionMap = HashMap Result>>; static EVENT_SECTIONS: OnceCell = OnceCell::new(); +macro_rules! insert_section { + ($events: expr, $ty: ty) => { + $events.insert( + SectionId::from_u8(<$ty>::SECTION_ID)?.to_str().to_string(), + |v| Ok(Box::new(serde_json::from_value::<$ty>(v)?)), + ); + }; +} + fn event_sections() -> Result<&'static EventSectionMap> { EVENT_SECTIONS.get_or_try_init(|| { let mut events = EventSectionMap::new(); - events.insert(CommonEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(KernelEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(UserEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(SkbTrackingEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(SkbDropEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(SkbEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(OvsEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(NftEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(CtEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); - events.insert(StartupEvent::SECTION_NAME.to_string(), |v| { - Ok(Box::new(serde_json::from_value::(v)?)) - }); + + insert_section!(events, CommonEvent); + insert_section!(events, KernelEvent); + insert_section!(events, UserEvent); + insert_section!(events, SkbTrackingEvent); + insert_section!(events, SkbDropEvent); + insert_section!(events, SkbEvent); + insert_section!(events, OvsEvent); + insert_section!(events, NftEvent); + insert_section!(events, CtEvent); + insert_section!(events, StartupEvent); + Ok(events) }) } @@ -338,6 +326,7 @@ impl EventSection for T where T: EventSectionInternal + for<'a> EventDisplay< /// /// There should not be a need to have per-object implementations for this. pub trait EventSectionInternal { + fn id(&self) -> u8; fn as_any(&self) -> &dyn Any; fn as_any_mut(&mut self) -> &mut dyn Any; fn to_json(&self) -> serde_json::Value; @@ -346,6 +335,10 @@ pub trait EventSectionInternal { // We need this as the value given as the input when deserializing something // into an event could be mapped to (), e.g. serde_json::Value::Null. impl EventSectionInternal for () { + fn id(&self) -> u8 { + SectionId::_MAX as u8 + } + fn as_any(&self) -> &dyn Any { self } diff --git a/retis-events/src/kernel.rs b/retis-events/src/kernel.rs index 59df5690b..b9f280f97 100644 --- a/retis-events/src/kernel.rs +++ b/retis-events/src/kernel.rs @@ -3,7 +3,7 @@ use std::fmt; use super::*; use crate::{event_section, event_type, Formatter}; -#[event_section("kernel")] +#[event_section(SectionId::Kernel)] pub struct KernelEvent { /// Kernel symbol name associated with the event (i.e. which probe generated /// the event). diff --git a/retis-events/src/nft.rs b/retis-events/src/nft.rs index bbc2d8cfd..c6c1e3ebd 100644 --- a/retis-events/src/nft.rs +++ b/retis-events/src/nft.rs @@ -4,7 +4,7 @@ use super::*; use crate::{event_section, Formatter}; /// Nft event section -#[event_section("nft")] +#[event_section(SectionId::Nft)] pub struct NftEvent { pub table_name: String, pub chain_name: String, diff --git a/retis-events/src/ovs.rs b/retis-events/src/ovs.rs index f7d348889..a5b153669 100644 --- a/retis-events/src/ovs.rs +++ b/retis-events/src/ovs.rs @@ -8,7 +8,7 @@ use crate::{event_section, event_type, Formatter}; ///The OVS Event #[derive(PartialEq)] -#[event_section("ovs")] +#[event_section(SectionId::Ovs)] pub struct OvsEvent { /// Event data #[serde(flatten)] diff --git a/retis-events/src/skb.rs b/retis-events/src/skb.rs index 172fc367d..b0ef7204f 100644 --- a/retis-events/src/skb.rs +++ b/retis-events/src/skb.rs @@ -7,7 +7,7 @@ use super::{ use crate::{event_section, event_type, Formatter}; /// Skb event section. -#[event_section("skb")] +#[event_section(SectionId::Skb)] pub struct SkbEvent { /// Ethernet fields, if any. pub eth: Option, diff --git a/retis-events/src/skb_drop.rs b/retis-events/src/skb_drop.rs index ebdd89e22..b514a5236 100644 --- a/retis-events/src/skb_drop.rs +++ b/retis-events/src/skb_drop.rs @@ -4,7 +4,7 @@ use super::*; use crate::{event_section, Formatter}; /// Skb drop event section. -#[event_section("skb-drop")] +#[event_section(SectionId::SkbDrop)] pub struct SkbDropEvent { /// Sub-system who generated the below drop reason. None for core reasons. pub subsys: Option, diff --git a/retis-events/src/skb_tracking.rs b/retis-events/src/skb_tracking.rs index 78ad8dca9..620cc6ebd 100644 --- a/retis-events/src/skb_tracking.rs +++ b/retis-events/src/skb_tracking.rs @@ -15,7 +15,7 @@ use crate::{event_section, Formatter}; /// Tl;dr; the tracking unique id is `(timestamp, orig_head)` and `skb` can be /// used to distinguished between clones. #[derive(Copy, PartialEq)] -#[event_section("skb-tracking")] +#[event_section(SectionId::SkbTracking)] #[repr(C)] pub struct SkbTrackingEvent { /// Head of buffer (`skb->head`) when the packet was first seen by the @@ -54,7 +54,7 @@ impl EventFmt for SkbTrackingEvent { /// Tracking event section. Generated at postprocessing with combined skb and ovs /// tracking information. -#[event_section("tracking")] +#[event_section(SectionId::Tracking)] pub struct TrackingInfo { /// Tracking information of the original packet. pub skb: SkbTrackingEvent, diff --git a/retis-events/src/user.rs b/retis-events/src/user.rs index da2c094eb..4cc9dab22 100644 --- a/retis-events/src/user.rs +++ b/retis-events/src/user.rs @@ -3,7 +3,7 @@ use std::fmt; use super::*; use crate::{event_section, Formatter}; -#[event_section("userspace")] +#[event_section(SectionId::Userspace)] pub struct UserEvent { /// Probe type: for now only "usdt" is supported. pub probe_type: String, diff --git a/retis/src/collect/collector.rs b/retis/src/collect/collector.rs index 13ce625b1..3c1ec9b8e 100644 --- a/retis/src/collect/collector.rs +++ b/retis/src/collect/collector.rs @@ -613,7 +613,7 @@ mod tests { } } - #[event_section("test")] + #[event_section(SectionId::Common)] #[derive(crate::EventSectionFactory)] struct TestEvent {} diff --git a/retis/src/core/events/bpf.rs b/retis/src/core/events/bpf.rs index 35d137c14..4e02f3e97 100644 --- a/retis/src/core/events/bpf.rs +++ b/retis/src/core/events/bpf.rs @@ -364,12 +364,11 @@ pub(crate) fn parse_raw_event<'a>( let factory = factories .get_mut(&owner) .ok_or_else(|| anyhow!("Unknown factory for event section owner {}", &owner))?; - event.insert_section( - owner, - factory - .create(sections) - .map_err(|e| anyhow!("Failed to parse section {}: {e}", &owner))?, - ) + + let section = factory + .create(sections) + .map_err(|e| anyhow!("Failed to parse section {}: {e}", &owner))?; + event.insert_section(SectionId::from_u8(section.id())?, section) })?; Ok(event) @@ -612,7 +611,7 @@ mod tests { const DATA_TYPE_U128: u8 = 2; #[derive(EventSectionFactory)] - #[event_section("test")] + #[event_section(SectionId::Common)] struct TestEvent { field0: Option, field1: Option, From bd00c8497f1ef19a68224c8e1aa4fdd6de228133 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 12 Aug 2024 13:55:25 +0200 Subject: [PATCH 6/9] core: events: bpf: fix comment on event_section_factory Signed-off-by: Antoine Tenart --- retis/src/core/events/bpf.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/retis/src/core/events/bpf.rs b/retis/src/core/events/bpf.rs index 4e02f3e97..b86ba3ed0 100644 --- a/retis/src/core/events/bpf.rs +++ b/retis/src/core/events/bpf.rs @@ -542,8 +542,8 @@ unsafe impl Plain for BpfRawSectionHeader {} /// EventSection factory, providing helpers to create event sections from /// ebpf. /// -/// Please use `#[retis_derive::event_section_factory(SectionType)]` to -/// implement the common traits. +/// Please use `#[retis_derive::event_section_factory]` to implement the common +/// traits. pub(crate) trait EventSectionFactory: RawEventSectionFactory { fn as_any_mut(&mut self) -> &mut dyn any::Any; } From c12dbf9603a9cefcb7c7670752a2f253f9b834d2 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 12 Aug 2024 14:26:37 +0200 Subject: [PATCH 7/9] tree: untangle factories from event sections Stop using SectionId for indexing event section factories; those are tied to a BPF counterpart, not to a section id. This helps modelizing that a factory can produce different sections and that a section does not necessarily have a BPF counterpart, such as the Tracking one. To do this use a dedicated FactoryId enum instead of reusing SectionId and use a similar logic as what we do for event sections (eg. embed the id into the factory definition). While doing this we can remove the TrackingInfoEventFactory. Signed-off-by: Antoine Tenart --- retis-derive/src/lib.rs | 25 +++++-- retis/src/collect/collector.rs | 19 +++-- retis/src/core/events/bpf.rs | 74 ++++++++++++++----- retis/src/core/events/bpf/include/events.h | 15 ++-- retis/src/core/probe/kernel/kernel.rs | 17 +++-- retis/src/core/probe/user/user.rs | 7 +- retis/src/module/ct/bpf.rs | 15 ++-- retis/src/module/module.rs | 19 ++--- retis/src/module/nft/bpf.rs | 10 ++- retis/src/module/ovs/bpf.rs | 12 ++- retis/src/module/skb/bpf.rs | 15 ++-- retis/src/module/skb_drop/bpf.rs | 8 +- retis/src/module/skb_tracking/skb_tracking.rs | 20 ++--- retis/src/process/tracking.rs | 14 +--- 14 files changed, 161 insertions(+), 109 deletions(-) diff --git a/retis-derive/src/lib.rs b/retis-derive/src/lib.rs index 8ba629607..78186b41c 100644 --- a/retis-derive/src/lib.rs +++ b/retis-derive/src/lib.rs @@ -1,6 +1,5 @@ -use proc_macro::{self, TokenStream}; use quote::quote; -use syn::{parse_macro_input, DeriveInput, Item, ItemStruct}; +use syn::{parse_macro_input, Item, ItemStruct}; #[proc_macro_attribute] pub fn raw_event_section( @@ -79,13 +78,29 @@ pub fn event_type( .expect("Invalid tokens from event_section macro") } -#[proc_macro_derive(EventSectionFactory)] -pub fn derive_event_section_factory(input: TokenStream) -> TokenStream { - let input: DeriveInput = parse_macro_input!(input); +#[proc_macro_attribute] +pub fn event_section_factory( + args: proc_macro::TokenStream, + item: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + let input: ItemStruct = parse_macro_input!(item); let ident = &input.ident; + let id: syn::Expr = syn::parse(args).expect("Invalid factory id"); + let output = quote! { + #input + + impl #ident { + pub(crate) const FACTORY_ID: u8 = #id as u8; + + } + impl EventSectionFactory for #ident { + fn id(&self) -> u8 { + Self::FACTORY_ID + } + fn as_any_mut(&mut self) -> &mut dyn std::any::Any where Self: Sized, { diff --git a/retis/src/collect/collector.rs b/retis/src/collect/collector.rs index 3c1ec9b8e..24d5d3901 100644 --- a/retis/src/collect/collector.rs +++ b/retis/src/collect/collector.rs @@ -28,7 +28,10 @@ use crate::{ }; #[cfg(not(test))] -use crate::core::probe::kernel::{config::init_stack_map, kernel::KernelEventFactory}; +use crate::core::{ + events::FactoryId, + probe::kernel::{config::init_stack_map, kernel::KernelEventFactory}, +}; use crate::{ cli::{dynamic::DynamicCommand, CliConfig, FullCli}, core::{ @@ -338,7 +341,7 @@ impl Collectors { self.probes .builder_mut()? .reuse_map("log_map", self.factory.log_map_fd())?; - match section_factories.get_mut(&SectionId::Kernel) { + match section_factories.get_mut(&FactoryId::Kernel) { Some(kernel_factory) => { kernel_factory .as_any_mut() @@ -541,7 +544,7 @@ mod tests { use super::*; use crate::{ core::{events::bpf::*, probe::ProbeBuilderManager}, - event_section, + event_section, event_section_factory, module::Module, }; @@ -577,7 +580,7 @@ mod tests { self } fn section_factory(&self) -> Result>> { - Ok(Some(Box::new(TestEvent {}))) + Ok(Some(Box::new(TestEventFactory {}))) } } @@ -609,12 +612,11 @@ mod tests { self } fn section_factory(&self) -> Result>> { - Ok(Some(Box::new(TestEvent {}))) + Ok(Some(Box::new(TestEventFactory {}))) } } #[event_section(SectionId::Common)] - #[derive(crate::EventSectionFactory)] struct TestEvent {} impl EventFmt for TestEvent { @@ -623,7 +625,10 @@ mod tests { } } - impl RawEventSectionFactory for TestEvent { + #[event_section_factory(FactoryId::Common)] + struct TestEventFactory {} + + impl RawEventSectionFactory for TestEventFactory { fn create(&mut self, _: Vec) -> Result> { Ok(Box::::default()) } diff --git a/retis/src/core/events/bpf.rs b/retis/src/core/events/bpf.rs index b86ba3ed0..bff985d9a 100644 --- a/retis/src/core/events/bpf.rs +++ b/retis/src/core/events/bpf.rs @@ -17,7 +17,7 @@ use anyhow::{anyhow, bail, Result}; use log::{error, log, Level}; use plain::Plain; -use crate::{events::*, helpers::signals::Running, raw_event_section}; +use crate::{event_section_factory, events::*, helpers::signals::Running, raw_event_section}; /// Raw event sections for common. pub(super) const COMMON_SECTION_CORE: u64 = 0; @@ -338,7 +338,7 @@ pub(crate) fn parse_raw_event<'a>( } // Try converting the raw owner id into something we can use. - let owner = match SectionId::from_u8(raw_section.header.owner) { + let owner = match FactoryId::from_u8(raw_section.header.owner) { Ok(owner) => owner, Err(e) => { // Skip the section. @@ -363,11 +363,11 @@ pub(crate) fn parse_raw_event<'a>( raw_sections.drain().try_for_each(|(owner, sections)| { let factory = factories .get_mut(&owner) - .ok_or_else(|| anyhow!("Unknown factory for event section owner {}", &owner))?; + .ok_or_else(|| anyhow!("Unknown factory {}", owner as u8))?; let section = factory .create(sections) - .map_err(|e| anyhow!("Failed to parse section {}: {e}", &owner))?; + .map_err(|e| anyhow!("Factory {} failed to parse section: {e}", owner as u8))?; event.insert_section(SectionId::from_u8(section.id())?, section) })?; @@ -390,12 +390,9 @@ pub(crate) fn parse_raw_section<'a, T>(raw_section: &'a BpfRawSection) -> Result /// Helper to parse a single raw section from BPF raw sections, checking the /// section validity and parsing it into a structured type. -pub(crate) fn parse_single_raw_section<'a, T>( - id: SectionId, - raw_sections: &'a [BpfRawSection], -) -> Result<&'a T> { +pub(crate) fn parse_single_raw_section<'a, T>(raw_sections: &'a [BpfRawSection]) -> Result<&'a T> { if raw_sections.len() != 1 { - bail!("{id} event from BPF must be a single section"); + bail!("Raw event must be a single section"); } // We can access the first element safely as we just checked the vector @@ -410,7 +407,8 @@ pub(crate) struct RawCommonEvent { smp_id: u32, } -#[derive(Default, crate::EventSectionFactory)] +#[event_section_factory(FactoryId::Common)] +#[derive(Default)] pub(crate) struct CommonEventFactory {} impl RawEventSectionFactory for CommonEventFactory { @@ -545,6 +543,7 @@ unsafe impl Plain for BpfRawSectionHeader {} /// Please use `#[retis_derive::event_section_factory]` to implement the common /// traits. pub(crate) trait EventSectionFactory: RawEventSectionFactory { + fn id(&self) -> u8; fn as_any_mut(&mut self) -> &mut dyn any::Any; } @@ -554,8 +553,43 @@ pub(crate) trait RawEventSectionFactory { fn create(&mut self, raw_sections: Vec) -> Result>; } +/// Identifier for factories. Should match their counterparts in the BPF side. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub(crate) enum FactoryId { + Common = 1, + Kernel = 2, + Userspace = 3, + SkbTracking = 4, + SkbDrop = 5, + Skb = 6, + Ovs = 7, + Nft = 8, + Ct = 9, + // TODO: use std::mem::variant_count once in stable. + _MAX = 10, +} + +impl FactoryId { + /// Constructs an FactoryId from a section unique identifier + pub(crate) fn from_u8(val: u8) -> Result { + use FactoryId::*; + Ok(match val { + 1 => Common, + 2 => Kernel, + 3 => Userspace, + 4 => SkbTracking, + 5 => SkbDrop, + 6 => Skb, + 7 => Ovs, + 8 => Nft, + 9 => Ct, + x => bail!("Can't construct a FactoryId from {}", x), + }) + } +} + /// Type alias to refer to the commonly used EventSectionFactory HashMap. -pub(crate) type SectionFactories = HashMap>; +pub(crate) type SectionFactories = HashMap>; #[cfg(feature = "benchmark")] pub(crate) mod benchmark { @@ -564,8 +598,7 @@ pub(crate) mod benchmark { use super::{RawCommonEvent, RawTaskEvent}; use crate::{ benchmark::helpers::*, - core::events::{COMMON_SECTION_CORE, COMMON_SECTION_TASK}, - events::SectionId, + core::events::{FactoryId, COMMON_SECTION_CORE, COMMON_SECTION_TASK}, }; impl RawSectionBuilder for RawCommonEvent { @@ -573,7 +606,7 @@ pub(crate) mod benchmark { let data = RawCommonEvent::default(); build_raw_section( out, - SectionId::Common.to_u8(), + FactoryId::Common as u8, COMMON_SECTION_CORE as u8, &mut as_u8_vec(&data), ); @@ -591,7 +624,7 @@ pub(crate) mod benchmark { data.comm.0[4] = b's'; build_raw_section( out, - SectionId::Common.to_u8(), + FactoryId::Common as u8, COMMON_SECTION_TASK as u8, &mut as_u8_vec(&data), ); @@ -605,12 +638,11 @@ mod tests { use serde::{Deserialize, Serialize}; use super::*; - use crate::{event_section, EventSectionFactory}; + use crate::{event_section, event_section_factory}; const DATA_TYPE_U64: u8 = 1; const DATA_TYPE_U128: u8 = 2; - #[derive(EventSectionFactory)] #[event_section(SectionId::Common)] struct TestEvent { field0: Option, @@ -628,7 +660,11 @@ mod tests { } } - impl RawEventSectionFactory for TestEvent { + #[event_section_factory(FactoryId::Common)] + #[derive(Default)] + struct TestEventFactory {} + + impl RawEventSectionFactory for TestEventFactory { fn create(&mut self, raw_sections: Vec) -> Result> { let mut event = TestEvent::default(); @@ -662,7 +698,7 @@ mod tests { #[test] fn parse_raw_event() { let mut factories: SectionFactories = HashMap::new(); - factories.insert(SectionId::Common, Box::::default()); + factories.insert(FactoryId::Common, Box::::default()); // Empty event. let data = []; diff --git a/retis/src/core/events/bpf/include/events.h b/retis/src/core/events/bpf/include/events.h index 606461e5b..0825f5af9 100644 --- a/retis/src/core/events/bpf/include/events.h +++ b/retis/src/core/events/bpf/include/events.h @@ -19,19 +19,18 @@ struct retis_log_event { u8 msg[LOG_MAX]; } __attribute__((packed)); -/* We're using the section identifiers defined in retis-events. +/* We're using the factory identifiers defined in retis-events. * Please keep in sync. */ enum retis_event_owners { COMMON = 1, KERNEL = 2, USERSPACE = 3, - /* TRACKING = 4, */ - COLLECTOR_SKB_TRACKING = 5, - COLLECTOR_SKB_DROP = 6, - COLLECTOR_SKB = 7, - COLLECTOR_OVS = 8, - COLLECTOR_NFT = 9, - COLLECTOR_CT = 10, + COLLECTOR_SKB_TRACKING = 4, + COLLECTOR_SKB_DROP = 5, + COLLECTOR_SKB = 6, + COLLECTOR_OVS = 7, + COLLECTOR_NFT = 8, + COLLECTOR_CT = 9, }; struct retis_raw_event { diff --git a/retis/src/core/probe/kernel/kernel.rs b/retis/src/core/probe/kernel/kernel.rs index 172db4a08..b908cd304 100644 --- a/retis/src/core/probe/kernel/kernel.rs +++ b/retis/src/core/probe/kernel/kernel.rs @@ -5,11 +5,11 @@ use std::{collections::HashMap, fmt}; use anyhow::{bail, Result}; use super::{config::ProbeConfig, inspect::inspect_symbol}; -use crate::EventSectionFactory; use crate::{ core::{ events::{ - parse_single_raw_section, BpfRawSection, EventSectionFactory, RawEventSectionFactory, + parse_single_raw_section, BpfRawSection, EventSectionFactory, FactoryId, + RawEventSectionFactory, }, kernel::Symbol, probe::{ @@ -17,6 +17,7 @@ use crate::{ ProbeOption, }, }, + event_section_factory, events::*, raw_event_section, }; @@ -69,7 +70,8 @@ impl fmt::Display for KernelProbe { } } -#[derive(Default, EventSectionFactory)] +#[event_section_factory(FactoryId::Kernel)] +#[derive(Default)] pub(crate) struct KernelEventFactory { #[cfg(not(test))] pub(crate) stack_map: Option, @@ -124,7 +126,7 @@ pub(crate) struct RawKernelEvent { impl RawEventSectionFactory for KernelEventFactory { fn create(&mut self, raw_sections: Vec) -> Result> { - let raw = parse_single_raw_section::(SectionId::Kernel, &raw_sections)?; + let raw = parse_single_raw_section::(&raw_sections)?; let mut event = KernelEvent::default(); let symbol_addr = raw.symbol; @@ -157,7 +159,10 @@ pub(crate) mod benchmark { use anyhow::Result; use super::RawKernelEvent; - use crate::{benchmark::helpers::*, core::kernel::Symbol, events::SectionId}; + use crate::{ + benchmark::helpers::*, + core::{events::FactoryId, kernel::Symbol}, + }; impl RawSectionBuilder for RawKernelEvent { fn build_raw(out: &mut Vec) -> Result<()> { @@ -166,7 +171,7 @@ pub(crate) mod benchmark { r#type: 2, // Raw tracepoint. stack_id: u64::MAX, }; - build_raw_section(out, SectionId::Kernel.to_u8(), 0, &mut as_u8_vec(&data)); + build_raw_section(out, FactoryId::Kernel as u8, 0, &mut as_u8_vec(&data)); Ok(()) } } diff --git a/retis/src/core/probe/user/user.rs b/retis/src/core/probe/user/user.rs index b0516b506..9c558723b 100644 --- a/retis/src/core/probe/user/user.rs +++ b/retis/src/core/probe/user/user.rs @@ -4,13 +4,13 @@ use std::{any::Any, collections::HashMap, fmt, path::PathBuf}; use anyhow::{anyhow, bail, Result}; -use crate::EventSectionFactory; use crate::{ core::{ - events::{BpfRawSection, EventSectionFactory, RawEventSectionFactory}, + events::{BpfRawSection, EventSectionFactory, FactoryId, RawEventSectionFactory}, probe::common::{Counters, CountersKey}, user::proc::Process, }, + event_section_factory, events::*, }; @@ -79,7 +79,8 @@ impl fmt::Display for UsdtProbe { } } -#[derive(Default, EventSectionFactory)] +#[event_section_factory(FactoryId::Userspace)] +#[derive(Default)] pub(crate) struct UserEventFactory { cache: HashMap>, } diff --git a/retis/src/module/ct/bpf.rs b/retis/src/module/ct/bpf.rs index 9f0e570b4..5f9258d24 100644 --- a/retis/src/module/ct/bpf.rs +++ b/retis/src/module/ct/bpf.rs @@ -9,9 +9,13 @@ use std::net::Ipv6Addr; use crate::{ core::{ - events::{parse_raw_section, BpfRawSection, EventSectionFactory, RawEventSectionFactory}, + events::{ + parse_raw_section, BpfRawSection, EventSectionFactory, FactoryId, + RawEventSectionFactory, + }, inspect::inspector, }, + event_section_factory, events::*, helpers, raw_event_section, }; @@ -73,7 +77,8 @@ pub(crate) struct RawCtEvent { unsafe impl Plain for RawCtEvent {} -#[derive(Default, crate::EventSectionFactory)] +#[event_section_factory(FactoryId::Ct)] +#[derive(Default)] pub(crate) struct CtEventFactory { tcp_states: HashMap, } @@ -275,14 +280,14 @@ pub(crate) mod benchmark { use anyhow::Result; use super::*; - use crate::{benchmark::helpers::*, events::SectionId}; + use crate::{benchmark::helpers::*, core::events::FactoryId}; impl RawSectionBuilder for RawCtMetaEvent { fn build_raw(out: &mut Vec) -> Result<()> { let data = RawCtMetaEvent::default(); build_raw_section( out, - SectionId::Ct.to_u8(), + FactoryId::Ct as u8, SECTION_META as u8, &mut as_u8_vec(&data), ); @@ -298,7 +303,7 @@ pub(crate) mod benchmark { }; build_raw_section( out, - SectionId::Ct.to_u8(), + FactoryId::Ct as u8, SECTION_BASE_CONN as u8, &mut as_u8_vec(&data), ); diff --git a/retis/src/module/module.rs b/retis/src/module/module.rs index ec612e78b..71f535797 100644 --- a/retis/src/module/module.rs +++ b/retis/src/module/module.rs @@ -9,11 +9,10 @@ use super::{ use crate::{ collect::Collector, core::{ - events::{CommonEventFactory, EventSectionFactory, SectionFactories}, + events::{CommonEventFactory, EventSectionFactory, FactoryId, SectionFactories}, probe::{kernel::KernelEventFactory, user::UserEventFactory}, }, events::*, - process::tracking::TrackingInfoEventFactory, }; /// Trait that must be implemented by Modules @@ -81,17 +80,13 @@ impl Modules { let mut section_factories: SectionFactories = HashMap::new(); // Register core event sections. - section_factories.insert(SectionId::Common, Box::::default()); - section_factories.insert(SectionId::Kernel, Box::::default()); - section_factories.insert(SectionId::Userspace, Box::::default()); - section_factories.insert( - SectionId::Tracking, - Box::::default(), - ); - - for (id, module) in self.modules.iter() { + section_factories.insert(FactoryId::Common, Box::::default()); + section_factories.insert(FactoryId::Kernel, Box::::default()); + section_factories.insert(FactoryId::Userspace, Box::::default()); + + for (_, module) in self.modules.iter() { if let Some(factory) = module.section_factory()? { - section_factories.insert(*id, factory); + section_factories.insert(FactoryId::from_u8(factory.id())?, factory); } } Ok(section_factories) diff --git a/retis/src/module/nft/bpf.rs b/retis/src/module/nft/bpf.rs index 9963272e0..37669f78d 100644 --- a/retis/src/module/nft/bpf.rs +++ b/retis/src/module/nft/bpf.rs @@ -2,9 +2,10 @@ use anyhow::Result; use crate::{ core::events::{ - parse_single_raw_section, BpfRawSection, EventSectionFactory, RawEventSectionFactory, + parse_single_raw_section, BpfRawSection, EventSectionFactory, FactoryId, + RawEventSectionFactory, }, - event_byte_array, + event_byte_array, event_section_factory, events::*, raw_event_section, }; @@ -85,13 +86,14 @@ struct NftBpfEvent { p: u8, } -#[derive(Default, crate::EventSectionFactory)] +#[event_section_factory(FactoryId::Nft)] +#[derive(Default)] pub(crate) struct NftEventFactory {} impl RawEventSectionFactory for NftEventFactory { fn create(&mut self, raw_sections: Vec) -> Result> { let mut event = NftEvent::default(); - let raw = parse_single_raw_section::(SectionId::Nft, &raw_sections)?; + let raw = parse_single_raw_section::(&raw_sections)?; event.table_name = raw.tn.to_string()?; event.chain_name = raw.cn.to_string()?; diff --git a/retis/src/module/ovs/bpf.rs b/retis/src/module/ovs/bpf.rs index 22025fd9f..9f67f4a74 100644 --- a/retis/src/module/ovs/bpf.rs +++ b/retis/src/module/ovs/bpf.rs @@ -7,7 +7,10 @@ use std::net::Ipv6Addr; use anyhow::{bail, Result}; use crate::{ - core::events::{parse_raw_section, BpfRawSection, EventSectionFactory, RawEventSectionFactory}, + core::events::{ + parse_raw_section, BpfRawSection, EventSectionFactory, FactoryId, RawEventSectionFactory, + }, + event_section_factory, events::*, helpers, raw_event_section, }; @@ -346,7 +349,8 @@ pub(super) fn unmarshall_upcall_return( Ok(()) } -#[derive(Default, crate::EventSectionFactory)] +#[event_section_factory(FactoryId::Ovs)] +#[derive(Default)] pub(crate) struct OvsEventFactory {} impl RawEventSectionFactory for OvsEventFactory { @@ -377,7 +381,7 @@ pub(crate) mod benchmark { use anyhow::Result; use super::*; - use crate::{benchmark::helpers::*, events::SectionId}; + use crate::{benchmark::helpers::*, core::events::FactoryId}; impl RawSectionBuilder for BpfActionEvent { fn build_raw(out: &mut Vec) -> Result<()> { @@ -387,7 +391,7 @@ pub(crate) mod benchmark { }; build_raw_section( out, - SectionId::Ovs.to_u8(), + FactoryId::Ovs as u8, OvsDataType::ActionExec as u8, &mut as_u8_vec(&data), ); diff --git a/retis/src/module/skb/bpf.rs b/retis/src/module/skb/bpf.rs index 2a004c27e..c41a10c86 100644 --- a/retis/src/module/skb/bpf.rs +++ b/retis/src/module/skb/bpf.rs @@ -14,7 +14,9 @@ use pnet_packet::{ }; use crate::{ - core::events::{parse_raw_section, BpfRawSection, EventSectionFactory, RawEventSectionFactory}, + core::events::{ + parse_raw_section, BpfRawSection, EventSectionFactory, FactoryId, RawEventSectionFactory, + }, event_byte_array, events::{ net::{etype_str, RawPacket}, @@ -364,7 +366,8 @@ fn unmarshal_l4( Ok(()) } -#[derive(Default, crate::EventSectionFactory)] +#[event_section_factory(FactoryId::Skb)] +#[derive(Default)] pub(crate) struct SkbEventFactory { // Should we report the Ethernet header. pub(super) report_eth: bool, @@ -395,7 +398,7 @@ pub(crate) mod benchmark { use anyhow::Result; use super::*; - use crate::{benchmark::helpers::*, events::SectionId}; + use crate::{benchmark::helpers::*, core::events::FactoryId}; impl RawSectionBuilder for RawDevEvent { fn build_raw(out: &mut Vec) -> Result<()> { @@ -407,7 +410,7 @@ pub(crate) mod benchmark { }; build_raw_section( out, - SectionId::Skb.to_u8(), + FactoryId::Skb as u8, SECTION_DEV as u8, &mut as_u8_vec(&data), ); @@ -420,7 +423,7 @@ pub(crate) mod benchmark { let data = RawNsEvent::default(); build_raw_section( out, - SectionId::Skb.to_u8(), + FactoryId::Skb as u8, SECTION_NS as u8, &mut as_u8_vec(&data), ); @@ -450,7 +453,7 @@ pub(crate) mod benchmark { }; build_raw_section( out, - SectionId::Skb.to_u8(), + FactoryId::Skb as u8, SECTION_PACKET as u8, &mut as_u8_vec(&data), ); diff --git a/retis/src/module/skb_drop/bpf.rs b/retis/src/module/skb_drop/bpf.rs index 23dd8fd0b..7b8e99d0c 100644 --- a/retis/src/module/skb_drop/bpf.rs +++ b/retis/src/module/skb_drop/bpf.rs @@ -13,10 +13,12 @@ const SKB_DROP_REASON_SUBSYS_SHIFT: u32 = 16; use crate::{ core::{ events::{ - parse_single_raw_section, BpfRawSection, EventSectionFactory, RawEventSectionFactory, + parse_single_raw_section, BpfRawSection, EventSectionFactory, FactoryId, + RawEventSectionFactory, }, inspect::inspector, }, + event_section_factory, events::*, }; @@ -81,7 +83,7 @@ impl DropReasons { } } -#[derive(crate::EventSectionFactory)] +#[event_section_factory(FactoryId::SkbDrop)] pub(crate) struct SkbDropEventFactory { /// Map of sub-system reason ids to their custom drop reason definitions. reasons: HashMap, @@ -89,7 +91,7 @@ pub(crate) struct SkbDropEventFactory { impl RawEventSectionFactory for SkbDropEventFactory { fn create(&mut self, raw_sections: Vec) -> Result> { - let raw = parse_single_raw_section::(SectionId::SkbDrop, &raw_sections)?; + let raw = parse_single_raw_section::(&raw_sections)?; let drop_reason = raw.drop_reason; let (subsys, drop_reason) = self.get_reason(drop_reason); diff --git a/retis/src/module/skb_tracking/skb_tracking.rs b/retis/src/module/skb_tracking/skb_tracking.rs index 8a1e214fe..73428c678 100644 --- a/retis/src/module/skb_tracking/skb_tracking.rs +++ b/retis/src/module/skb_tracking/skb_tracking.rs @@ -10,9 +10,9 @@ use crate::{ events::*, probe::{manager::ProbeBuilderManager, Hook}, }, + event_section_factory, events::*, module::Module, - EventSectionFactory, }; #[derive(Default)] @@ -50,13 +50,13 @@ impl Module for SkbTrackingModule { } } -#[derive(Default, EventSectionFactory)] +#[event_section_factory(FactoryId::SkbTracking)] +#[derive(Default)] pub(crate) struct SkbTrackingEventFactory {} impl RawEventSectionFactory for SkbTrackingEventFactory { fn create(&mut self, raw_sections: Vec) -> Result> { - let event = - parse_single_raw_section::(SectionId::SkbTracking, &raw_sections)?; + let event = parse_single_raw_section::(&raw_sections)?; Ok(Box::new(*event)) } @@ -66,20 +66,12 @@ impl RawEventSectionFactory for SkbTrackingEventFactory { pub(crate) mod benchmark { use anyhow::Result; - use crate::{ - benchmark::helpers::*, - events::{SectionId, SkbTrackingEvent}, - }; + use crate::{benchmark::helpers::*, core::events::FactoryId, events::SkbTrackingEvent}; impl RawSectionBuilder for SkbTrackingEvent { fn build_raw(out: &mut Vec) -> Result<()> { let data = SkbTrackingEvent::default(); - build_raw_section( - out, - SectionId::SkbTracking.to_u8(), - 0, - &mut as_u8_vec(&data), - ); + build_raw_section(out, FactoryId::SkbTracking as u8, 0, &mut as_u8_vec(&data)); Ok(()) } } diff --git a/retis/src/process/tracking.rs b/retis/src/process/tracking.rs index 2be2e5fc4..15e2d96d6 100644 --- a/retis/src/process/tracking.rs +++ b/retis/src/process/tracking.rs @@ -14,19 +14,7 @@ use std::{ use anyhow::{anyhow, bail, Result}; -use crate::{ - core::events::{BpfRawSection, EventSectionFactory, RawEventSectionFactory}, - events::*, -}; - -#[derive(Default, crate::EventSectionFactory)] -pub(crate) struct TrackingInfoEventFactory {} - -impl RawEventSectionFactory for TrackingInfoEventFactory { - fn create(&mut self, _: Vec) -> Result> { - bail!("TrackingInfoEvents cannot be created from bpf") - } -} +use crate::events::*; // Data identifying an OvsUpcall Event #[derive(Debug, PartialEq, Eq, Hash)] From 0b82d69fb51a2f838e9868ecb488d3ca27442f39 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 12 Aug 2024 14:50:39 +0200 Subject: [PATCH 8/9] tree: untangle modules from event sections Stop using SectionId for indexing modules (aka. collectors nowadays); there is no 1:1 relationship between the two. Eg. core events are not tied to a module. To to this introduce a ModuleId enum. Hopefully this will go away once we remove the module abstraction. Signed-off-by: Antoine Tenart --- retis-events/src/events.rs | 25 +----------- retis/src/collect/collector.rs | 24 +++++------ retis/src/module/module.rs | 74 ++++++++++++++++++++++++++++------ retis/src/module/skb/bpf.rs | 2 +- 4 files changed, 76 insertions(+), 49 deletions(-) diff --git a/retis-events/src/events.rs b/retis-events/src/events.rs index 13aa2a3aa..353c94204 100644 --- a/retis-events/src/events.rs +++ b/retis-events/src/events.rs @@ -34,7 +34,7 @@ #![allow(dead_code)] // FIXME #![allow(clippy::wrong_self_convention)] -use std::{any::Any, collections::HashMap, fmt, str::FromStr}; +use std::{any::Any, collections::HashMap, fmt}; use anyhow::{anyhow, bail, Result}; use log::debug; @@ -195,29 +195,6 @@ pub enum SectionId { _MAX = 12, } -impl FromStr for SectionId { - type Err = anyhow::Error; - - /// Constructs an SectionId from a section unique str identifier. - fn from_str(val: &str) -> Result { - use SectionId::*; - Ok(match val { - "common" => Common, - "kernel" => Kernel, - "userspace" => Userspace, - "tracking" => Tracking, - "skb-tracking" => SkbTracking, - "skb-drop" => SkbDrop, - "skb" => Skb, - "ovs" => Ovs, - "nft" => Nft, - "ct" => Ct, - "startup" => Startup, - x => bail!("Can't construct a SectionId from {}", x), - }) - } -} - impl SectionId { /// Constructs an SectionId from a section unique identifier pub fn from_u8(val: u8) -> Result { diff --git a/retis/src/collect/collector.rs b/retis/src/collect/collector.rs index 24d5d3901..9a18a5050 100644 --- a/retis/src/collect/collector.rs +++ b/retis/src/collect/collector.rs @@ -44,9 +44,9 @@ use crate::{ probe::{kernel::probe_stack::ProbeStack, *}, tracking::{gc::TrackingGC, skb_tracking::init_tracking}, }, - events::{EventResult, SectionId}, + events::EventResult, helpers::{signals::Running, time::*}, - module::Modules, + module::{ModuleId, Modules}, }; /// Generic trait representing a collector. All collectors are required to @@ -110,7 +110,7 @@ pub(crate) struct Collectors { tracking_gc: Option, // Keep a reference on the tracking configuration map. tracking_config_map: Option, - loaded: Vec, + loaded: Vec, // Retis events factory. events_factory: Arc, } @@ -222,7 +222,7 @@ impl Collectors { // Try initializing all collectors. for name in &collect.args()?.collectors { - let id = SectionId::from_str(name)?; + let id = ModuleId::from_str(name)?; let c = self .modules .get_collector(&id) @@ -642,10 +642,10 @@ mod tests { fn register_collectors() -> Result<()> { let mut group = Modules::new()?; assert!(group - .register(SectionId::Skb, Box::new(DummyCollectorA::new()?),) + .register(ModuleId::Skb, Box::new(DummyCollectorA::new()?),) .is_ok()); assert!(group - .register(SectionId::Ovs, Box::new(DummyCollectorB::new()?),) + .register(ModuleId::Ovs, Box::new(DummyCollectorB::new()?),) .is_ok()); Ok(()) } @@ -654,10 +654,10 @@ mod tests { fn register_uniqueness() -> Result<()> { let mut group = Modules::new()?; assert!(group - .register(SectionId::Skb, Box::new(DummyCollectorA::new()?),) + .register(ModuleId::Skb, Box::new(DummyCollectorA::new()?),) .is_ok()); assert!(group - .register(SectionId::Skb, Box::new(DummyCollectorA::new()?),) + .register(ModuleId::Skb, Box::new(DummyCollectorA::new()?),) .is_err()); Ok(()) } @@ -668,8 +668,8 @@ mod tests { let mut dummy_a = Box::new(DummyCollectorA::new()?); let mut dummy_b = Box::new(DummyCollectorB::new()?); - group.register(SectionId::Skb, Box::new(DummyCollectorA::new()?))?; - group.register(SectionId::Ovs, Box::new(DummyCollectorB::new()?))?; + group.register(ModuleId::Skb, Box::new(DummyCollectorA::new()?))?; + group.register(ModuleId::Ovs, Box::new(DummyCollectorB::new()?))?; let mut collectors = Collectors::new(group)?; let mut mgr = ProbeBuilderManager::new()?; @@ -693,8 +693,8 @@ mod tests { let mut dummy_a = Box::new(DummyCollectorA::new()?); let mut dummy_b = Box::new(DummyCollectorB::new()?); - group.register(SectionId::Skb, Box::new(DummyCollectorA::new()?))?; - group.register(SectionId::Ovs, Box::new(DummyCollectorB::new()?))?; + group.register(ModuleId::Skb, Box::new(DummyCollectorA::new()?))?; + group.register(ModuleId::Ovs, Box::new(DummyCollectorB::new()?))?; let mut collectors = Collectors::new(group)?; diff --git a/retis/src/module/module.rs b/retis/src/module/module.rs index 71f535797..3e0b5dcbe 100644 --- a/retis/src/module/module.rs +++ b/retis/src/module/module.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, fmt, str::FromStr}; use anyhow::{bail, Result}; @@ -12,9 +12,59 @@ use crate::{ events::{CommonEventFactory, EventSectionFactory, FactoryId, SectionFactories}, probe::{kernel::KernelEventFactory, user::UserEventFactory}, }, - events::*, }; +/// Module identifiers. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub(crate) enum ModuleId { + SkbTracking, + Skb, + SkbDrop, + Ovs, + Nft, + Ct, +} + +impl ModuleId { + /// Converts a ModuleId to a section unique str identifier. + pub fn to_str(self) -> &'static str { + use ModuleId::*; + match self { + SkbTracking => "skb-tracking", + SkbDrop => "skb-drop", + Skb => "skb", + Ovs => "ovs", + Nft => "nft", + Ct => "ct", + } + } +} + +impl FromStr for ModuleId { + type Err = anyhow::Error; + + /// Constructs a ModuleId from a section unique str identifier. + fn from_str(val: &str) -> Result { + use ModuleId::*; + Ok(match val { + "skb-tracking" => SkbTracking, + "skb-drop" => SkbDrop, + "skb" => Skb, + "ovs" => Ovs, + "nft" => Nft, + "ct" => Ct, + x => bail!("Can't construct a ModuleId from {}", x), + }) + } +} + +// Allow using ModuleId in log messages. +impl fmt::Display for ModuleId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + /// Trait that must be implemented by Modules pub(crate) trait Module { /// Return a Collector used for collect command @@ -29,7 +79,7 @@ pub(crate) trait Module { /// to manipulate them. pub(crate) struct Modules { /// Set of registered modules we can use. - modules: HashMap>, + modules: HashMap>, } impl Modules { @@ -50,7 +100,7 @@ impl Modules { /// Box::new(SecondModule::new()?, /// )?; /// ``` - pub(crate) fn register(&mut self, id: SectionId, module: Box) -> Result<&mut Self> { + pub(crate) fn register(&mut self, id: ModuleId, module: Box) -> Result<&mut Self> { // Ensure uniqueness of the module name. This is important as their // name is used as a key. if self.modules.contains_key(&id) { @@ -63,7 +113,7 @@ impl Modules { /// Get an hashmap of all the collectors available in the registered /// modules. - pub(crate) fn collectors(&mut self) -> HashMap<&SectionId, &mut dyn Collector> { + pub(crate) fn collectors(&mut self) -> HashMap<&ModuleId, &mut dyn Collector> { self.modules .iter_mut() .map(|(id, m)| (id, m.collector())) @@ -71,7 +121,7 @@ impl Modules { } /// Get a specific collector, if found in the registered modules. - pub(crate) fn get_collector(&mut self, id: &SectionId) -> Option<&mut dyn Collector> { + pub(crate) fn get_collector(&mut self, id: &ModuleId) -> Option<&mut dyn Collector> { self.modules.get_mut(id).map(|m| m.collector()) } @@ -98,12 +148,12 @@ pub(crate) fn get_modules() -> Result { // Register all collectors here. group - .register(SectionId::SkbTracking, Box::new(SkbTrackingModule::new()?))? - .register(SectionId::Skb, Box::new(SkbModule::new()?))? - .register(SectionId::SkbDrop, Box::new(SkbDropModule::new()?))? - .register(SectionId::Ovs, Box::new(OvsModule::new()?))? - .register(SectionId::Nft, Box::new(NftModule::new()?))? - .register(SectionId::Ct, Box::new(CtModule::new()?))?; + .register(ModuleId::SkbTracking, Box::new(SkbTrackingModule::new()?))? + .register(ModuleId::Skb, Box::new(SkbModule::new()?))? + .register(ModuleId::SkbDrop, Box::new(SkbDropModule::new()?))? + .register(ModuleId::Ovs, Box::new(OvsModule::new()?))? + .register(ModuleId::Nft, Box::new(NftModule::new()?))? + .register(ModuleId::Ct, Box::new(CtModule::new()?))?; Ok(group) } diff --git a/retis/src/module/skb/bpf.rs b/retis/src/module/skb/bpf.rs index c41a10c86..1f8c359e2 100644 --- a/retis/src/module/skb/bpf.rs +++ b/retis/src/module/skb/bpf.rs @@ -17,7 +17,7 @@ use crate::{ core::events::{ parse_raw_section, BpfRawSection, EventSectionFactory, FactoryId, RawEventSectionFactory, }, - event_byte_array, + event_byte_array, event_section_factory, events::{ net::{etype_str, RawPacket}, *, From 717bfeec26d0f346575ace1f019eb13c9ae1ee81 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Mon, 12 Aug 2024 15:38:11 +0200 Subject: [PATCH 9/9] collector: merge two import blocks Cosmetic only. Signed-off-by: Antoine Tenart --- retis/src/collect/collector.rs | 35 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/retis/src/collect/collector.rs b/retis/src/collect/collector.rs index 9a18a5050..69dff83e9 100644 --- a/retis/src/collect/collector.rs +++ b/retis/src/collect/collector.rs @@ -16,14 +16,25 @@ use nix::unistd::Uid; use super::cli::Collect; use crate::{ - cli::{CliDisplayFormat, SubCommandRunner}, + cli::{dynamic::DynamicCommand, CliConfig, CliDisplayFormat, FullCli, SubCommandRunner}, core::{ - events::RetisEventsFactory, - filters::{meta::filter::FilterMeta, packets::filter::FilterPacketType}, + events::{BpfEventsFactory, RetisEventsFactory}, + filters::{ + filters::{BpfFilter, Filter}, + meta::filter::FilterMeta, + packets::filter::{FilterPacket, FilterPacketType}, + }, + inspect::check::collection_prerequisites, kernel::Symbol, - probe::kernel::utils::parse_probe, + probe::{ + kernel::{probe_stack::ProbeStack, utils::parse_probe}, + *, + }, + tracking::{gc::TrackingGC, skb_tracking::init_tracking}, }, events::*, + helpers::{signals::Running, time::*}, + module::{ModuleId, Modules}, process::display::*, }; @@ -32,22 +43,6 @@ use crate::core::{ events::FactoryId, probe::kernel::{config::init_stack_map, kernel::KernelEventFactory}, }; -use crate::{ - cli::{dynamic::DynamicCommand, CliConfig, FullCli}, - core::{ - events::BpfEventsFactory, - filters::{ - filters::{BpfFilter, Filter}, - packets::filter::FilterPacket, - }, - inspect::check::collection_prerequisites, - probe::{kernel::probe_stack::ProbeStack, *}, - tracking::{gc::TrackingGC, skb_tracking::init_tracking}, - }, - events::EventResult, - helpers::{signals::Running, time::*}, - module::{ModuleId, Modules}, -}; /// Generic trait representing a collector. All collectors are required to /// implement this, as they'll be manipulated through this trait.