bpf: add support for BPF_PROG_TYPE_SCHED_CLS programs

pull/1/head
Alessandro Decina 4 years ago
parent 5effc972ac
commit afcc5dc662

@ -1,4 +1,6 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
// needed for TC_ACT_*
#include <linux/pkt_cls.h>
#include "bpf_helpers.h" #include "bpf_helpers.h"

@ -7,11 +7,14 @@ mod x86_64;
#[cfg(bpf_target_arch = "aarch64")] #[cfg(bpf_target_arch = "aarch64")]
mod aarch64; mod aarch64;
#[cfg(bpf_target_arch = "x86_64")] mod gen {
pub use x86_64::*; #[cfg(bpf_target_arch = "x86_64")]
pub use super::x86_64::*;
#[cfg(bpf_target_arch = "aarch64")] #[cfg(bpf_target_arch = "aarch64")]
pub use aarch64::*; pub use super::aarch64::*;
}
pub use gen::*;
use aya_bpf_cty::{c_long, c_void}; use aya_bpf_cty::{c_long, c_void};
use core::mem::{self, MaybeUninit}; use core::mem::{self, MaybeUninit};
@ -30,3 +33,15 @@ unsafe fn bpf_probe_read<T>(src: *const T) -> Result<T, c_long> {
Ok(v.assume_init()) Ok(v.assume_init())
} }
pub const TC_ACT_OK: i32 = gen::bindings::TC_ACT_OK as i32;
pub const TC_ACT_RECLASSIFY: i32 = gen::bindings::TC_ACT_RECLASSIFY as i32;
pub const TC_ACT_SHOT: i32 = gen::bindings::TC_ACT_SHOT as i32;
pub const TC_ACT_PIPE: i32 = gen::bindings::TC_ACT_PIPE as i32;
pub const TC_ACT_STOLEN: i32 = gen::bindings::TC_ACT_STOLEN as i32;
pub const TC_ACT_QUEUED: i32 = gen::bindings::TC_ACT_QUEUED as i32;
pub const TC_ACT_REPEAT: i32 = gen::bindings::TC_ACT_REPEAT as i32;
pub const TC_ACT_REDIRECT: i32 = gen::bindings::TC_ACT_REDIRECT as i32;
pub const TC_ACT_TRAP: i32 = gen::bindings::TC_ACT_TRAP as i32;
pub const TC_ACT_VALUE_MAX: i32 = gen::bindings::TC_ACT_VALUE_MAX as i32;
pub const TC_ACT_EXT_VAL_MASK: i32 = 268435455;

@ -181,6 +181,38 @@ impl Xdp {
} }
} }
pub struct SchedClassifier {
item: ItemFn,
name: Option<String>,
}
impl SchedClassifier {
pub fn from_syn(args: Args, item: ItemFn) -> Result<SchedClassifier> {
let name = name_arg(&args)?;
Ok(SchedClassifier { item, name })
}
pub fn expand(&self) -> Result<TokenStream> {
let section_name = if let Some(name) = &self.name {
format!("classifier/{}", name)
} else {
"classifier".to_owned()
};
let fn_name = &self.item.sig.ident;
let item = &self.item;
Ok(quote! {
#[no_mangle]
#[link_section = #section_name]
fn #fn_name(ctx: *mut ::aya_bpf::bindings::__sk_buff) -> i32 {
return #fn_name(::aya_bpf::programs::SkSkbContext::new(ctx));
#item
}
})
}
}
fn name_arg(args: &Args) -> Result<Option<String>> { fn name_arg(args: &Args) -> Result<Option<String>> {
for arg in &args.args { for arg in &args.args {
if arg.name == "name" { if arg.name == "name" {

@ -1,6 +1,6 @@
mod expand; mod expand;
use expand::{Args, Map, Probe, ProbeKind, SkMsg, SockOps, Xdp}; use expand::{Args, Map, Probe, ProbeKind, SchedClassifier, SkMsg, SockOps, Xdp};
use proc_macro::TokenStream; use proc_macro::TokenStream;
use syn::{parse_macro_input, ItemFn, ItemStatic}; use syn::{parse_macro_input, ItemFn, ItemStatic};
@ -68,6 +68,17 @@ pub fn xdp(attrs: TokenStream, item: TokenStream) -> TokenStream {
.into() .into()
} }
#[proc_macro_attribute]
pub fn classifier(attrs: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attrs as Args);
let item = parse_macro_input!(item as ItemFn);
SchedClassifier::from_syn(args, item)
.and_then(|u| u.expand())
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
fn probe(kind: ProbeKind, attrs: TokenStream, item: TokenStream) -> TokenStream { fn probe(kind: ProbeKind, attrs: TokenStream, item: TokenStream) -> TokenStream {
let args = parse_macro_input!(attrs as Args); let args = parse_macro_input!(attrs as Args);
let item = parse_macro_input!(item as ItemFn); let item = parse_macro_input!(item as ItemFn);

Loading…
Cancel
Save