Implement detaching from socket filters

pull/1/head
Alessandro Decina 4 years ago
parent 4bd0cde199
commit 9614132724

@ -1,9 +1,9 @@
use libc::{setsockopt, SOL_SOCKET, SO_ATTACH_BPF}; use libc::{setsockopt, SOL_SOCKET, SO_ATTACH_BPF, SO_DETACH_BPF};
use std::{io, mem, os::unix::prelude::RawFd}; use std::{cell::RefCell, io, mem, os::unix::prelude::RawFd, rc::Rc};
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER, generated::bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER,
programs::{load_program, ProgramData, ProgramError}, programs::{load_program, Link, LinkRef, ProgramData, ProgramError},
}; };
#[derive(Debug)] #[derive(Debug)]
@ -16,7 +16,7 @@ impl SocketFilter {
load_program(BPF_PROG_TYPE_SOCKET_FILTER, &mut self.data) load_program(BPF_PROG_TYPE_SOCKET_FILTER, &mut self.data)
} }
pub fn attach(&self, socket: RawFd) -> Result<(), ProgramError> { pub fn attach(&self, socket: RawFd) -> Result<impl Link, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let ret = unsafe { let ret = unsafe {
@ -33,7 +33,42 @@ impl SocketFilter {
io_error: io::Error::last_os_error(), io_error: io::Error::last_os_error(),
}); });
} }
let link = Rc::new(RefCell::new(SocketFilterLink {
socket,
prog_fd: Some(prog_fd),
}));
Ok(LinkRef::new(&link))
}
}
#[derive(Debug)]
pub(crate) struct SocketFilterLink {
socket: RawFd,
prog_fd: Option<RawFd>,
}
impl Link for SocketFilterLink {
fn detach(&mut self) -> Result<(), ProgramError> {
if let Some(fd) = self.prog_fd.take() {
unsafe {
setsockopt(
self.socket,
SOL_SOCKET,
SO_DETACH_BPF,
&fd as *const _ as *const _,
mem::size_of::<RawFd>() as u32,
);
}
Ok(()) Ok(())
} else {
Err(ProgramError::AlreadyDetached)
}
}
}
impl Drop for SocketFilterLink {
fn drop(&mut self) {
let _ = self.detach();
} }
} }

Loading…
Cancel
Save