-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aya: Add support for BPF_PROG_TYPE_SK_LOOKUP
Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
- Loading branch information
1 parent
63b6286
commit f05726f
Showing
4 changed files
with
123 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
use std::os::unix::prelude::{AsRawFd, RawFd}; | ||
|
||
use crate::{ | ||
generated::{bpf_attach_type::BPF_SK_LOOKUP, bpf_prog_type::BPF_PROG_TYPE_SK_LOOKUP}, | ||
programs::{define_link_wrapper, load_program, FdLinkId, OwnedLink, ProgramData, ProgramError}, | ||
sys::bpf_link_create, | ||
}; | ||
|
||
use super::links::FdLink; | ||
|
||
/// A program used to redirect incoming packets to a local socket. | ||
/// | ||
/// [`SkLookup`] programs are attached to [network namespaces] to provide programmable | ||
/// socket lookup for TCP/UDP when a packet is to be delievered locally | ||
/// | ||
/// You may attach multiple programs to the same namespace and they are executed | ||
/// in the order they were attached. | ||
/// | ||
/// [network namespaces]: https://www.man7.org/linux/man-pages/man8/ip-netns.8.html | ||
/// | ||
/// # Minimum kernel version | ||
/// | ||
/// The minimum kernel version required to use this feature is 5.9. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```no_run | ||
/// # #[derive(Debug, thiserror::Error)] | ||
/// # enum Error { | ||
/// # #[error(transparent)] | ||
/// # IO(#[from] std::io::Error), | ||
/// # #[error(transparent)] | ||
/// # Map(#[from] aya::maps::MapError), | ||
/// # #[error(transparent)] | ||
/// # Program(#[from] aya::programs::ProgramError), | ||
/// # #[error(transparent)] | ||
/// # Bpf(#[from] aya::BpfError) | ||
/// # } | ||
/// # let mut bpf = aya::Bpf::load(&[])?; | ||
/// use std::fs::File; | ||
/// use std::convert::TryInto; | ||
/// use aya::programs::SkLookup; | ||
/// | ||
/// let file = File::open("/var/run/netns/test")?; | ||
/// let program: &mut SkLookup = bpf.program_mut("sk_lookup").unwrap().try_into()?; | ||
/// program.load()?; | ||
/// program.attach(file)?; | ||
/// # Ok::<(), Error>(()) | ||
/// ``` | ||
#[derive(Debug)] | ||
#[doc(alias = "BPF_PROG_TYPE_SK_LOOKUP")] | ||
pub struct SkLookup { | ||
pub(crate) data: ProgramData<SkLookupLink>, | ||
} | ||
|
||
impl SkLookup { | ||
/// Loads the program inside the kernel. | ||
pub fn load(&mut self) -> Result<(), ProgramError> { | ||
self.data.expected_attach_type = Some(BPF_SK_LOOKUP); | ||
load_program(BPF_PROG_TYPE_SK_LOOKUP, &mut self.data) | ||
} | ||
|
||
/// Attaches the program to the given network namespace | ||
/// | ||
/// The returned value can be used to detach, see [SkLookup::detach]. | ||
pub fn attach<T: AsRawFd>(&mut self, netns: T) -> Result<SkLookupLinkId, ProgramError> { | ||
let prog_fd = self.data.fd_or_err()?; | ||
let netns_fd = netns.as_raw_fd(); | ||
|
||
let link_fd = bpf_link_create(prog_fd, netns_fd, BPF_SK_LOOKUP, None, 0).map_err( | ||
|(_, io_error)| ProgramError::SyscallError { | ||
call: "bpf_link_create".to_owned(), | ||
io_error, | ||
}, | ||
)? as RawFd; | ||
self.data.links.insert(SkLookupLink(FdLink::new(link_fd))) | ||
} | ||
|
||
/// Takes ownership of the link referenced by the provided link_id. | ||
/// | ||
/// The link will be detached on `Drop` and the caller is now responsible | ||
/// for managing its lifetime. | ||
pub fn forget_link( | ||
&mut self, | ||
link_id: SkLookupLinkId, | ||
) -> Result<OwnedLink<SkLookupLink>, ProgramError> { | ||
Ok(OwnedLink::new(self.data.forget_link(link_id)?)) | ||
} | ||
|
||
/// Detaches the program. | ||
/// | ||
/// See [SkLookup::attach]. | ||
pub fn detach(&mut self, link_id: SkLookupLinkId) -> Result<(), ProgramError> { | ||
self.data.links.remove(link_id) | ||
} | ||
} | ||
|
||
define_link_wrapper!( | ||
/// The link used by [SkLookup] programs. | ||
SkLookupLink, | ||
/// The type returned by [SkLookup::attach]. Can be passed to [SkLookup::detach]. | ||
SkLookupLinkId, | ||
FdLink, | ||
FdLinkId | ||
); |