From 9614132724963e0178c4ceafde52ed7e367b0d11 Mon Sep 17 00:00:00 2001 From: Alessandro Decina Date: Sat, 6 Feb 2021 20:57:32 +0000 Subject: [PATCH] Implement detaching from socket filters --- src/programs/socket_filter.rs | 45 +++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/programs/socket_filter.rs b/src/programs/socket_filter.rs index f50979dc..4e405de3 100644 --- a/src/programs/socket_filter.rs +++ b/src/programs/socket_filter.rs @@ -1,9 +1,9 @@ -use libc::{setsockopt, SOL_SOCKET, SO_ATTACH_BPF}; -use std::{io, mem, os::unix::prelude::RawFd}; +use libc::{setsockopt, SOL_SOCKET, SO_ATTACH_BPF, SO_DETACH_BPF}; +use std::{cell::RefCell, io, mem, os::unix::prelude::RawFd, rc::Rc}; use crate::{ generated::bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER, - programs::{load_program, ProgramData, ProgramError}, + programs::{load_program, Link, LinkRef, ProgramData, ProgramError}, }; #[derive(Debug)] @@ -16,7 +16,7 @@ impl SocketFilter { 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 { let prog_fd = self.data.fd_or_err()?; let ret = unsafe { @@ -33,7 +33,42 @@ impl SocketFilter { io_error: io::Error::last_os_error(), }); } + let link = Rc::new(RefCell::new(SocketFilterLink { + socket, + prog_fd: Some(prog_fd), + })); - Ok(()) + Ok(LinkRef::new(&link)) + } +} + +#[derive(Debug)] +pub(crate) struct SocketFilterLink { + socket: RawFd, + prog_fd: Option, +} + +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::() as u32, + ); + } + Ok(()) + } else { + Err(ProgramError::AlreadyDetached) + } + } +} + +impl Drop for SocketFilterLink { + fn drop(&mut self) { + let _ = self.detach(); } }