useaya_tool::generate::InputFile;usestd::{fs::File,io::Write,path::PathBuf};pubfngenerate()-> Result<(),anyhow::Error>{letdir=PathBuf::from("cgroup-skb-egress-ebpf/src");letnames: Vec<&str>=vec!["iphdr"];letbindings=aya_tool::generate(InputFile::Btf(PathBuf::from("/sys/kernel/btf/vmlinux")),&names,&[],)?;// Write the bindings to the $OUT_DIR/bindings.rs file.letmutout=File::create(dir.join("bindings.rs"))?;write!(out,"{bindings}")?;Ok(())}
usestd::net::Ipv4Addr;useaya::{include_bytes_aligned,maps::{perf::AsyncPerfEventArray,HashMap},programs::{CgroupAttachMode,CgroupSkb,CgroupSkbAttachType},util::online_cpus,Ebpf,};usebytes::BytesMut;useclap::Parser;uselog::info;usetokio::{signal,task};usecgroup_skb_egress_common::PacketLog;#[derive(Debug, Parser)]structOpt{#[clap(short, long, default_value = "/sys/fs/cgroup/unified")]cgroup_path: String,}#[tokio::main]asyncfnmain()-> Result<(),anyhow::Error>{letopt=Opt::parse();env_logger::init();// This will include your eBPF object file as raw bytes at compile-time and load it at// runtime. This approach is recommended for most real-world use cases. If you would// like to specify the eBPF program at runtime rather than at compile-time, you can// reach for `Ebpf::load_file` instead.#[cfg(debug_assertions)]letmutbpf=Ebpf::load(include_bytes_aligned!("../../target/bpfel-unknown-none/debug/cgroup-skb-egress"))?;#[cfg(not(debug_assertions))]letmutbpf=Ebpf::load(include_bytes_aligned!("../../target/bpfel-unknown-none/release/cgroup-skb-egress"))?;letprogram: &mutCgroupSkb=bpf.program_mut("cgroup_skb_egress").unwrap().try_into()?;letcgroup=std::fs::File::open(opt.cgroup_path)?;// (1)program.load()?;// (2)program.attach(cgroup,CgroupSkbAttachType::Egress,CgroupAttachMode::Single,)?;letmutblocklist: HashMap<_,u32,u32>=HashMap::try_from(bpf.map_mut("BLOCKLIST").unwrap())?;letblock_addr: u32=Ipv4Addr::new(1,1,1,1).try_into()?;// (3)blocklist.insert(block_addr,0,0)?;letmutperf_array=AsyncPerfEventArray::try_from(bpf.take_map("EVENTS").unwrap())?;forcpu_idinonline_cpus()?{letmutbuf=perf_array.open(cpu_id,None)?;task::spawn(asyncmove{letmutbuffers=(0..10).map(|_|BytesMut::with_capacity(1024)).collect::<Vec<_>>();loop{letevents=buf.read_events(&mutbuffers).await.unwrap();forbufinbuffers.iter_mut().take(events.read){letptr=buf.as_ptr()as*constPacketLog;letdata=unsafe{ptr.read_unaligned()};letsrc_addr=Ipv4Addr::from(data.ipv4_address);info!("LOG: DST {}, ACTION {}",src_addr,data.action);}}});}info!("Waiting for Ctrl-C...");signal::ctrl_c().await?;info!("Exiting...");Ok(())}