@@ -3,7 +3,7 @@ use std::{io, path::PathBuf, sync::Arc};
33use anyhow:: { bail, Context } ;
44use aya:: {
55 maps:: { Array , LpmTrie , MapData , PerCpuArray , RingBuf } ,
6- programs:: Lsm ,
6+ programs:: Program ,
77 Btf , Ebpf ,
88} ;
99use checks:: Checks ;
@@ -15,9 +15,13 @@ use tokio::{
1515 task:: JoinHandle ,
1616} ;
1717
18- use crate :: { event:: Event , host_info, metrics:: EventCounter } ;
18+ use crate :: {
19+ event:: { self , Event } ,
20+ host_info,
21+ metrics:: EventCounter ,
22+ } ;
1923
20- use fact_ebpf:: { event_t, metrics_t, path_prefix_t, LPM_SIZE_MAX } ;
24+ use fact_ebpf:: { cgroup_entry_t , event_t, metrics_t, path_prefix_t, LPM_SIZE_MAX } ;
2125
2226mod checks;
2327
@@ -30,6 +34,8 @@ pub struct Bpf {
3034
3135 paths : Vec < path_prefix_t > ,
3236 paths_config : watch:: Receiver < Vec < PathBuf > > ,
37+
38+ event_parser : event:: parser:: Parser ,
3339}
3440
3541impl Bpf {
@@ -44,7 +50,7 @@ impl Bpf {
4450
4551 // Include the BPF object as raw bytes at compile-time and load it
4652 // at runtime.
47- let obj = aya:: EbpfLoader :: new ( )
53+ let mut obj = aya:: EbpfLoader :: new ( )
4854 . set_global ( "host_mount_ns" , & host_info:: get_host_mount_ns ( ) , true )
4955 . set_global (
5056 "path_unlink_supports_bpf_d_path" ,
@@ -56,11 +62,17 @@ impl Bpf {
5662
5763 let paths = Vec :: new ( ) ;
5864 let ( tx, _) = broadcast:: channel ( 100 ) ;
65+ let Some ( cgroup_map) = obj. take_map ( "cgroup_map" ) else {
66+ bail ! ( "Failed to get cgroup_map" ) ;
67+ } ;
68+ let cgroup_map: aya:: maps:: HashMap < MapData , u64 , cgroup_entry_t > = cgroup_map. try_into ( ) ?;
69+ let event_parser = event:: parser:: Parser :: new ( cgroup_map) ;
5970 let mut bpf = Bpf {
6071 obj,
6172 tx,
6273 paths,
6374 paths_config,
75+ event_parser,
6476 } ;
6577
6678 bpf. load_paths ( ) ?;
@@ -138,24 +150,42 @@ impl Bpf {
138150 Ok ( ( ) )
139151 }
140152
141- fn load_lsm_prog ( & mut self , name : & str , hook : & str , btf : & Btf ) -> anyhow:: Result < ( ) > {
153+ fn load_prog ( & mut self , name : & str , hook : & str , btf : & Btf ) -> anyhow:: Result < ( ) > {
142154 let Some ( prog) = self . obj . program_mut ( name) else {
143155 bail ! ( "{name} program not found" ) ;
144156 } ;
145- let prog: & mut Lsm = prog. try_into ( ) ?;
146- prog. load ( hook, btf) ?;
157+ match prog {
158+ Program :: Lsm ( prog) => prog. load ( hook, btf) ?,
159+ Program :: BtfTracePoint ( prog) => prog. load ( hook, btf) ?,
160+ _ => todo ! ( ) ,
161+ }
147162 Ok ( ( ) )
148163 }
149164
150165 fn load_progs ( & mut self , btf : & Btf ) -> anyhow:: Result < ( ) > {
151- self . load_lsm_prog ( "trace_file_open" , "file_open" , btf) ?;
152- self . load_lsm_prog ( "trace_path_unlink" , "path_unlink" , btf)
166+ let progs = [
167+ ( "trace_file_open" , "file_open" ) ,
168+ ( "trace_path_unlink" , "path_unlink" ) ,
169+ ( "trace_cgroup_attach_task" , "cgroup_attach_task" ) ,
170+ ] ;
171+
172+ for ( name, hook) in progs {
173+ self . load_prog ( name, hook, btf) ?;
174+ }
175+ Ok ( ( ) )
153176 }
154177
155178 fn attach_progs ( & mut self ) -> anyhow:: Result < ( ) > {
156179 for ( _, prog) in self . obj . programs_mut ( ) {
157- let prog: & mut Lsm = prog. try_into ( ) ?;
158- prog. attach ( ) ?;
180+ match prog {
181+ Program :: Lsm ( prog) => {
182+ prog. attach ( ) ?;
183+ }
184+ Program :: BtfTracePoint ( prog) => {
185+ prog. attach ( ) ?;
186+ }
187+ _ => todo ! ( ) ,
188+ }
159189 }
160190 Ok ( ( ) )
161191 }
@@ -165,8 +195,10 @@ impl Bpf {
165195 mut self ,
166196 mut running : watch:: Receiver < bool > ,
167197 event_counter : EventCounter ,
198+ parser_counter : EventCounter ,
168199 ) -> JoinHandle < anyhow:: Result < ( ) > > {
169200 info ! ( "Starting BPF worker..." ) ;
201+ self . event_parser . set_metrics ( parser_counter) ;
170202
171203 tokio:: spawn ( async move {
172204 self . attach_progs ( )
@@ -183,7 +215,7 @@ impl Bpf {
183215 let ringbuf = guard. get_inner_mut( ) ;
184216 while let Some ( event) = ringbuf. next( ) {
185217 let event: & event_t = unsafe { & * ( event. as_ptr( ) as * const _) } ;
186- let event = match Event :: try_from ( event) {
218+ let event = match self . event_parser . parse ( event) {
187219 Ok ( event) => Arc :: new( event) ,
188220 Err ( e) => {
189221 error!( "Failed to parse event: '{e}'" ) ;
@@ -268,7 +300,11 @@ mod bpf_tests {
268300 // Create a metrics exporter, but don't start it
269301 let exporter = Exporter :: new ( bpf. take_metrics ( ) . unwrap ( ) ) ;
270302
271- let handle = bpf. start ( run_rx, exporter. metrics . bpf_worker . clone ( ) ) ;
303+ let handle = bpf. start (
304+ run_rx,
305+ exporter. metrics . bpf_worker . clone ( ) ,
306+ exporter. metrics . event_parser . clone ( ) ,
307+ ) ;
272308
273309 tokio:: time:: sleep ( Duration :: from_millis ( 500 ) ) . await ;
274310
@@ -277,7 +313,7 @@ mod bpf_tests {
277313 NamedTempFile :: new_in ( monitored_path) . expect ( "Failed to create temporary file" ) ;
278314 println ! ( "Created {file:?}" ) ;
279315
280- let expected = Event :: new (
316+ let expected = Event :: from_raw_parts (
281317 file_activity_type_t:: FILE_ACTIVITY_CREATION ,
282318 host_info:: get_hostname ( ) ,
283319 file. path ( ) . to_path_buf ( ) ,
0 commit comments