From c713dde0612bb521e46c73963bfdf55c8675f0fc Mon Sep 17 00:00:00 2001 From: Hengqi Chen Date: Fri, 26 Aug 2022 04:08:46 +0000 Subject: [PATCH] aya-bpf/programs: Add `pull_data` method to SKB context The pull_data method is used to ensure that all the required bytes are available in the linear portion of the skb. Signed-off-by: Hengqi Chen --- bpf/aya-bpf/src/programs/sk_buff.rs | 37 ++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/bpf/aya-bpf/src/programs/sk_buff.rs b/bpf/aya-bpf/src/programs/sk_buff.rs index 57f9d127..597c715f 100644 --- a/bpf/aya-bpf/src/programs/sk_buff.rs +++ b/bpf/aya-bpf/src/programs/sk_buff.rs @@ -6,7 +6,8 @@ use core::{ use aya_bpf_bindings::helpers::{ bpf_clone_redirect, bpf_get_socket_uid, bpf_l3_csum_replace, bpf_l4_csum_replace, - bpf_skb_adjust_room, bpf_skb_change_type, bpf_skb_load_bytes, bpf_skb_store_bytes, + bpf_skb_adjust_room, bpf_skb_change_type, bpf_skb_load_bytes, bpf_skb_pull_data, + bpf_skb_store_bytes, }; use aya_bpf_cty::c_long; @@ -224,6 +225,40 @@ impl SkBuffContext { Err(ret) } } + + /// Pulls in non-linear data in case the skb is non-linear. + /// + /// Make len bytes from skb readable and writable. If a zero value is passed for + /// `len`, then the whole length of the skb is pulled. This helper is only needed + /// for reading and writing with direct packet access. + /// + /// # Examples + /// + /// ```no_run + /// mod bindings; + /// use bindings::{ethhdr, iphdr, udphdr}; + /// + /// const ETH_HLEN: usize = core::mem::size_of::(); + /// const IP_HLEN: usize = core::mem::size_of::(); + /// const UDP_HLEN: usize = core::mem::size_of::(); + /// + /// fn try_classifier(ctx: SkBuffContext) -> Result { + /// let len = ETH_HLEN + IP_HLEN + UDP_HLEN; + /// match ctx.pull_data(len as u32) { + /// Ok(_) => return Ok(0), + /// Err(ret) => return Err(ret as i32), + /// } + /// } + /// ``` + #[inline(always)] + pub fn pull_data(&self, len: u32) -> Result<(), c_long> { + let ret = unsafe { bpf_skb_pull_data(self.as_ptr() as *mut _, len) }; + if ret == 0 { + Ok(()) + } else { + Err(ret) + } + } } impl BpfContext for SkBuffContext {