Merge pull request #519 from dave-tucker/frags

XDP Multi-Buffer Support
pull/523/head
Alessandro Decina 2 years ago committed by GitHub
commit bc83f208b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -200,20 +200,33 @@ impl SkMsg {
pub struct Xdp { pub struct Xdp {
item: ItemFn, item: ItemFn,
name: Option<String>, name: Option<String>,
frags: bool,
} }
impl Xdp { impl Xdp {
pub fn from_syn(mut args: Args, item: ItemFn) -> Result<Xdp> { pub fn from_syn(mut args: Args, item: ItemFn) -> Result<Xdp> {
let name = name_arg(&mut args)?; let name = pop_arg(&mut args, "name");
let mut frags = false;
Ok(Xdp { item, name }) if let Some(s) = pop_arg(&mut args, "frags") {
if let Ok(m) = s.parse() {
frags = m
} else {
return Err(Error::new_spanned(
"mutlibuffer",
"invalid value. should be 'true' or 'false'",
));
}
}
err_on_unknown_args(&args)?;
Ok(Xdp { item, name, frags })
} }
pub fn expand(&self) -> Result<TokenStream> { pub fn expand(&self) -> Result<TokenStream> {
let section_prefix = if self.frags { "xdp.frags" } else { "xdp" };
let section_name = if let Some(name) = &self.name { let section_name = if let Some(name) = &self.name {
format!("xdp/{name}") format!("{section_prefix}/{name}")
} else { } else {
"xdp".to_owned() section_prefix.to_string()
}; };
let fn_vis = &self.item.vis; let fn_vis = &self.item.vis;
let fn_name = &self.item.sig.ident; let fn_name = &self.item.sig.ident;

@ -160,7 +160,6 @@ pub struct Function {
/// - `iter+`, `iter.s+` /// - `iter+`, `iter.s+`
/// - `xdp.frags/cpumap`, `xdp/cpumap` /// - `xdp.frags/cpumap`, `xdp/cpumap`
/// - `xdp.frags/devmap`, `xdp/devmap` /// - `xdp.frags/devmap`, `xdp/devmap`
/// - `xdp.frags`
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub enum ProgramSection { pub enum ProgramSection {
@ -184,6 +183,7 @@ pub enum ProgramSection {
}, },
Xdp { Xdp {
name: String, name: String,
frags_supported: bool,
}, },
SkMsg { SkMsg {
name: String, name: String,
@ -266,7 +266,7 @@ impl ProgramSection {
ProgramSection::URetProbe { name } => name, ProgramSection::URetProbe { name } => name,
ProgramSection::TracePoint { name } => name, ProgramSection::TracePoint { name } => name,
ProgramSection::SocketFilter { name } => name, ProgramSection::SocketFilter { name } => name,
ProgramSection::Xdp { name } => name, ProgramSection::Xdp { name, .. } => name,
ProgramSection::SkMsg { name } => name, ProgramSection::SkMsg { name } => name,
ProgramSection::SkSkbStreamParser { name } => name, ProgramSection::SkSkbStreamParser { name } => name,
ProgramSection::SkSkbStreamVerdict { name } => name, ProgramSection::SkSkbStreamVerdict { name } => name,
@ -313,7 +313,14 @@ impl FromStr for ProgramSection {
"kretprobe" => KRetProbe { name }, "kretprobe" => KRetProbe { name },
"uprobe" => UProbe { name }, "uprobe" => UProbe { name },
"uretprobe" => URetProbe { name }, "uretprobe" => URetProbe { name },
"xdp" => Xdp { name }, "xdp" => Xdp {
name,
frags_supported: false,
},
"xdp.frags" => Xdp {
name,
frags_supported: true,
},
"tp_btf" => BtfTracePoint { name }, "tp_btf" => BtfTracePoint { name },
_ if kind.starts_with("tracepoint") || kind.starts_with("tp") => { _ if kind.starts_with("tracepoint") || kind.starts_with("tp") => {
// tracepoint sections are named `tracepoint/category/event_name`, // tracepoint sections are named `tracepoint/category/event_name`,
@ -1837,6 +1844,30 @@ mod tests {
); );
} }
#[test]
fn test_parse_section_xdp_frags() {
let mut obj = fake_obj();
assert_matches!(
obj.parse_section(fake_section(
BpfSectionKind::Program,
"xdp.frags/foo",
bytes_of(&fake_ins())
)),
Ok(())
);
assert_matches!(
obj.programs.get("foo"),
Some(Program {
section: ProgramSection::Xdp {
frags_supported: true,
..
},
..
})
);
}
#[test] #[test]
fn test_parse_section_raw_tp() { fn test_parse_section_raw_tp() {
let mut obj = fake_obj(); let mut obj = fake_obj();

@ -9,6 +9,7 @@ use std::{
use aya_obj::{ use aya_obj::{
btf::{BtfFeatures, BtfRelocationError}, btf::{BtfFeatures, BtfRelocationError},
generated::BPF_F_XDP_HAS_FRAGS,
relocation::BpfRelocationError, relocation::BpfRelocationError,
}; };
use log::debug; use log::debug;
@ -485,9 +486,16 @@ impl<'a> BpfLoader<'a> {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level), data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
}) })
} }
ProgramSection::Xdp { .. } => Program::Xdp(Xdp { ProgramSection::Xdp {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level), frags_supported, ..
}), } => {
let mut data =
ProgramData::new(prog_name, obj, btf_fd, verifier_log_level);
if *frags_supported {
data.flags = BPF_F_XDP_HAS_FRAGS;
}
Program::Xdp(Xdp { data })
}
ProgramSection::SkMsg { .. } => Program::SkMsg(SkMsg { ProgramSection::SkMsg { .. } => Program::SkMsg(SkMsg {
data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level), data: ProgramData::new(prog_name, obj, btf_fd, verifier_log_level),
}), }),

@ -415,6 +415,7 @@ pub(crate) struct ProgramData<T: Link> {
pub(crate) btf_fd: Option<RawFd>, pub(crate) btf_fd: Option<RawFd>,
pub(crate) verifier_log_level: u32, pub(crate) verifier_log_level: u32,
pub(crate) path: Option<PathBuf>, pub(crate) path: Option<PathBuf>,
pub(crate) flags: u32,
} }
impl<T: Link> ProgramData<T> { impl<T: Link> ProgramData<T> {
@ -436,6 +437,7 @@ impl<T: Link> ProgramData<T> {
btf_fd, btf_fd,
verifier_log_level, verifier_log_level,
path: None, path: None,
flags: 0,
} }
} }
@ -474,6 +476,7 @@ impl<T: Link> ProgramData<T> {
btf_fd: None, btf_fd: None,
verifier_log_level: 0, verifier_log_level: 0,
path: Some(path.to_path_buf()), path: Some(path.to_path_buf()),
flags: 0,
}) })
} }
@ -606,6 +609,7 @@ fn load_program<T: Link>(
func_info: func_info.clone(), func_info: func_info.clone(),
line_info_rec_size: *line_info_rec_size, line_info_rec_size: *line_info_rec_size,
line_info: line_info.clone(), line_info: line_info.clone(),
flags: data.flags,
}; };
let verifier_log_level = data.verifier_log_level; let verifier_log_level = data.verifier_log_level;

@ -115,6 +115,7 @@ pub(crate) struct BpfLoadProgramAttrs<'a> {
pub(crate) func_info: FuncSecInfo, pub(crate) func_info: FuncSecInfo,
pub(crate) line_info_rec_size: usize, pub(crate) line_info_rec_size: usize,
pub(crate) line_info: LineSecInfo, pub(crate) line_info: LineSecInfo,
pub(crate) flags: u32,
} }
pub(crate) fn bpf_load_program( pub(crate) fn bpf_load_program(
@ -136,6 +137,7 @@ pub(crate) fn bpf_load_program(
u.prog_name = name; u.prog_name = name;
} }
u.prog_flags = aya_attr.flags;
u.prog_type = aya_attr.ty as u32; u.prog_type = aya_attr.ty as u32;
if let Some(v) = aya_attr.expected_attach_type { if let Some(v) = aya_attr.expected_attach_type {
u.expected_attach_type = v as u32; u.expected_attach_type = v as u32;
@ -179,7 +181,6 @@ pub(crate) fn bpf_load_program(
if let Some(v) = aya_attr.attach_btf_id { if let Some(v) = aya_attr.attach_btf_id {
u.attach_btf_id = v; u.attach_btf_id = v;
} }
sys_bpf(bpf_cmd::BPF_PROG_LOAD, &attr) sys_bpf(bpf_cmd::BPF_PROG_LOAD, &attr)
} }

@ -14,7 +14,7 @@ static FOO: Array<u32> = Array::<u32>::with_max_entries(10, 0);
#[map(name = "BAR")] #[map(name = "BAR")]
static BAZ: Array<u32> = Array::<u32>::with_max_entries(10, 0); static BAZ: Array<u32> = Array::<u32>::with_max_entries(10, 0);
#[xdp] #[xdp(frags = "true")]
pub fn pass(ctx: XdpContext) -> u32 { pub fn pass(ctx: XdpContext) -> u32 {
match unsafe { try_pass(ctx) } { match unsafe { try_pass(ctx) } {
Ok(ret) => ret, Ok(ret) => ret,

@ -3,7 +3,7 @@
use aya_bpf::{bindings::xdp_action, macros::xdp, programs::XdpContext}; use aya_bpf::{bindings::xdp_action, macros::xdp, programs::XdpContext};
#[xdp(name = "pass")] #[xdp(name = "pass", frags = "true")]
pub fn pass(ctx: XdpContext) -> u32 { pub fn pass(ctx: XdpContext) -> u32 {
match unsafe { try_pass(ctx) } { match unsafe { try_pass(ctx) } {
Ok(ret) => ret, Ok(ret) => ret,

Loading…
Cancel
Save