|
@@ -13,13 +13,13 @@ use aya_bpf_cty::c_long;
|
|
|
|
|
|
use crate::{bindings::__sk_buff, BpfContext};
|
|
|
|
|
|
-pub struct SkBuffContext {
|
|
|
+pub struct SkBuff {
|
|
|
pub skb: *mut __sk_buff,
|
|
|
}
|
|
|
|
|
|
-impl SkBuffContext {
|
|
|
- pub fn new(skb: *mut __sk_buff) -> SkBuffContext {
|
|
|
- SkBuffContext { skb }
|
|
|
+impl SkBuff {
|
|
|
+ pub fn new(skb: *mut __sk_buff) -> SkBuff {
|
|
|
+ SkBuff { skb }
|
|
|
}
|
|
|
|
|
|
#[allow(clippy::len_without_is_empty)]
|
|
@@ -28,6 +28,16 @@ impl SkBuffContext {
|
|
|
unsafe { *self.skb }.len
|
|
|
}
|
|
|
|
|
|
+ #[inline]
|
|
|
+ pub(crate) fn data(&self) -> usize {
|
|
|
+ unsafe { (*self.skb).data as usize }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub(crate) fn data_end(&self) -> usize {
|
|
|
+ unsafe { (*self.skb).data_end as usize }
|
|
|
+ }
|
|
|
+
|
|
|
#[inline]
|
|
|
pub fn set_mark(&mut self, mark: u32) {
|
|
|
unsafe { *self.skb }.mark = mark;
|
|
@@ -76,43 +86,6 @@ impl SkBuffContext {
|
|
|
/// # Examples
|
|
|
///
|
|
|
/// Read into a `PerCpuArray`.
|
|
|
- ///
|
|
|
- /// ```no_run
|
|
|
- /// use core::mem;
|
|
|
- ///
|
|
|
- /// use aya_bpf::{bindings::TC_ACT_PIPE, macros::map, maps::PerCpuArray, programs::SkBuffContext};
|
|
|
- /// # #[allow(non_camel_case_types)]
|
|
|
- /// # struct ethhdr {};
|
|
|
- /// # #[allow(non_camel_case_types)]
|
|
|
- /// # struct iphdr {};
|
|
|
- /// # #[allow(non_camel_case_types)]
|
|
|
- /// # struct tcphdr {};
|
|
|
- ///
|
|
|
- /// const ETH_HDR_LEN: usize = mem::size_of::<ethhdr>();
|
|
|
- /// const IP_HDR_LEN: usize = mem::size_of::<iphdr>();
|
|
|
- /// const TCP_HDR_LEN: usize = mem::size_of::<tcphdr>();
|
|
|
- ///
|
|
|
- /// #[repr(C)]
|
|
|
- /// pub struct Buf {
|
|
|
- /// pub buf: [u8; 1500],
|
|
|
- /// }
|
|
|
- ///
|
|
|
- /// #[map]
|
|
|
- /// pub static mut BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
|
|
|
- ///
|
|
|
- /// fn try_classifier(ctx: SkBuffContext) -> Result<i32, i32> {
|
|
|
- /// let buf = unsafe {
|
|
|
- /// let ptr = BUF.get_ptr_mut(0).ok_or(TC_ACT_PIPE)?;
|
|
|
- /// &mut *ptr
|
|
|
- /// };
|
|
|
- /// let offset = ETH_HDR_LEN + IP_HDR_LEN + TCP_HDR_LEN;
|
|
|
- /// ctx.load_bytes(offset, &mut buf.buf).map_err(|_| TC_ACT_PIPE)?;
|
|
|
- ///
|
|
|
- /// // do something with `buf`
|
|
|
- ///
|
|
|
- /// Ok(TC_ACT_PIPE)
|
|
|
- /// }
|
|
|
- /// ```
|
|
|
#[inline(always)]
|
|
|
pub fn load_bytes(&self, offset: usize, dst: &mut [u8]) -> Result<usize, c_long> {
|
|
|
if offset >= self.len() as usize {
|
|
@@ -226,6 +199,161 @@ impl SkBuffContext {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// 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.
|
|
|
+ #[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)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub(crate) fn as_ptr(&self) -> *mut c_void {
|
|
|
+ self.skb as *mut _
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+pub struct SkBuffContext {
|
|
|
+ pub skb: SkBuff,
|
|
|
+}
|
|
|
+
|
|
|
+impl SkBuffContext {
|
|
|
+ pub fn new(skb: *mut __sk_buff) -> SkBuffContext {
|
|
|
+ let skb = SkBuff { skb };
|
|
|
+ SkBuffContext { skb }
|
|
|
+ }
|
|
|
+
|
|
|
+ #[allow(clippy::len_without_is_empty)]
|
|
|
+ #[inline]
|
|
|
+ pub fn len(&self) -> u32 {
|
|
|
+ self.skb.len()
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn set_mark(&mut self, mark: u32) {
|
|
|
+ self.skb.set_mark(mark)
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn cb(&self) -> &[u32] {
|
|
|
+ self.skb.cb()
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn cb_mut(&mut self) -> &mut [u32] {
|
|
|
+ self.skb.cb_mut()
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Returns the owner UID of the socket associated to the SKB context.
|
|
|
+ #[inline]
|
|
|
+ pub fn get_socket_uid(&self) -> u32 {
|
|
|
+ self.skb.get_socket_uid()
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn load<T>(&self, offset: usize) -> Result<T, c_long> {
|
|
|
+ self.skb.load(offset)
|
|
|
+ }
|
|
|
+
|
|
|
+ /// Reads some bytes from the packet into the specified buffer, returning
|
|
|
+ /// how many bytes were read.
|
|
|
+ ///
|
|
|
+ /// Starts reading at `offset` and reads at most `dst.len()` or
|
|
|
+ /// `self.len() - offset` bytes, depending on which one is smaller.
|
|
|
+ ///
|
|
|
+ /// # Examples
|
|
|
+ ///
|
|
|
+ /// Read into a `PerCpuArray`.
|
|
|
+ ///
|
|
|
+ /// ```no_run
|
|
|
+ /// use core::mem;
|
|
|
+ ///
|
|
|
+ /// use aya_bpf::{bindings::TC_ACT_PIPE, macros::map, maps::PerCpuArray, programs::SkBuffContext};
|
|
|
+ /// # #[allow(non_camel_case_types)]
|
|
|
+ /// # struct ethhdr {};
|
|
|
+ /// # #[allow(non_camel_case_types)]
|
|
|
+ /// # struct iphdr {};
|
|
|
+ /// # #[allow(non_camel_case_types)]
|
|
|
+ /// # struct tcphdr {};
|
|
|
+ ///
|
|
|
+ /// const ETH_HDR_LEN: usize = mem::size_of::<ethhdr>();
|
|
|
+ /// const IP_HDR_LEN: usize = mem::size_of::<iphdr>();
|
|
|
+ /// const TCP_HDR_LEN: usize = mem::size_of::<tcphdr>();
|
|
|
+ ///
|
|
|
+ /// #[repr(C)]
|
|
|
+ /// pub struct Buf {
|
|
|
+ /// pub buf: [u8; 1500],
|
|
|
+ /// }
|
|
|
+ ///
|
|
|
+ /// #[map]
|
|
|
+ /// pub static mut BUF: PerCpuArray<Buf> = PerCpuArray::with_max_entries(1, 0);
|
|
|
+ ///
|
|
|
+ /// fn try_cgroup_skb(ctx: SkBuffContext) -> Result<i32, i32> {
|
|
|
+ /// let buf = unsafe {
|
|
|
+ /// let ptr = BUF.get_ptr_mut(0).ok_or(TC_ACT_PIPE)?;
|
|
|
+ /// &mut *ptr
|
|
|
+ /// };
|
|
|
+ /// let offset = ETH_HDR_LEN + IP_HDR_LEN + TCP_HDR_LEN;
|
|
|
+ /// ctx.load_bytes(offset, &mut buf.buf).map_err(|_| TC_ACT_PIPE)?;
|
|
|
+ ///
|
|
|
+ /// // do something with `buf`
|
|
|
+ ///
|
|
|
+ /// Ok(TC_ACT_PIPE)
|
|
|
+ /// }
|
|
|
+ /// ```
|
|
|
+ #[inline(always)]
|
|
|
+ pub fn load_bytes(&self, offset: usize, dst: &mut [u8]) -> Result<usize, c_long> {
|
|
|
+ self.skb.load_bytes(offset, dst)
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn store<T>(&mut self, offset: usize, v: &T, flags: u64) -> Result<(), c_long> {
|
|
|
+ self.skb.store(offset, v, flags)
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn l3_csum_replace(
|
|
|
+ &self,
|
|
|
+ offset: usize,
|
|
|
+ from: u64,
|
|
|
+ to: u64,
|
|
|
+ size: u64,
|
|
|
+ ) -> Result<(), c_long> {
|
|
|
+ self.skb.l3_csum_replace(offset, from, to, size)
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn l4_csum_replace(
|
|
|
+ &self,
|
|
|
+ offset: usize,
|
|
|
+ from: u64,
|
|
|
+ to: u64,
|
|
|
+ flags: u64,
|
|
|
+ ) -> Result<(), c_long> {
|
|
|
+ self.skb.l4_csum_replace(offset, from, to, flags)
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn adjust_room(&self, len_diff: i32, mode: u32, flags: u64) -> Result<(), c_long> {
|
|
|
+ self.skb.adjust_room(len_diff, mode, flags)
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn clone_redirect(&self, if_index: u32, flags: u64) -> Result<(), c_long> {
|
|
|
+ self.skb.clone_redirect(if_index, flags)
|
|
|
+ }
|
|
|
+
|
|
|
+ #[inline]
|
|
|
+ pub fn change_type(&self, ty: u32) -> Result<(), c_long> {
|
|
|
+ self.skb.change_type(ty)
|
|
|
+ }
|
|
|
+
|
|
|
/// 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
|
|
@@ -242,7 +370,7 @@ impl SkBuffContext {
|
|
|
/// const IP_HLEN: usize = core::mem::size_of::<iphdr>();
|
|
|
/// const UDP_HLEN: usize = core::mem::size_of::<udphdr>();
|
|
|
///
|
|
|
- /// fn try_classifier(ctx: SkBuffContext) -> Result<i32, i32> {
|
|
|
+ /// fn try_cgroup_skb(ctx: SkBuffContext) -> Result<i32, i32> {
|
|
|
/// let len = ETH_HLEN + IP_HLEN + UDP_HLEN;
|
|
|
/// match ctx.pull_data(len as u32) {
|
|
|
/// Ok(_) => return Ok(0),
|
|
@@ -252,17 +380,12 @@ impl SkBuffContext {
|
|
|
/// ```
|
|
|
#[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)
|
|
|
- }
|
|
|
+ self.skb.pull_data(len)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
impl BpfContext for SkBuffContext {
|
|
|
fn as_ptr(&self) -> *mut c_void {
|
|
|
- self.skb as *mut _
|
|
|
+ self.skb.as_ptr()
|
|
|
}
|
|
|
}
|