Skip to main content

push_packet/events/
route.rs

1//! Defines events for [`crate::rules::Action::Route`].
2use std::sync::Arc;
3
4use crossbeam_queue::ArrayQueue;
5use push_packet_common::RouteArgs;
6
7use crate::{af_xdp::OwnedUmem, cast, rules::RuleId};
8
9/// A packet event captured with [`crate::rules::Action::Route`]. This will take a frame in the
10/// `AF_AXP` socket until it is [dropped](`Drop`), so it should be consumed quickly. Calling
11/// [`RouteEvent::into_owned`] returns an [`OwnedRouteEvent`], releasing the frame at the cost of a
12/// copy.
13pub struct RouteEvent<'a> {
14    pub(crate) address: u64,
15    pub(crate) len: u32,
16    pub(crate) umem: &'a OwnedUmem,
17    pub(crate) free_list: &'a Arc<ArrayQueue<u64>>,
18}
19
20impl Drop for RouteEvent<'_> {
21    fn drop(&mut self) {
22        self.free_list
23            .push(self.address)
24            .expect("Frame count cannot exceed free list");
25    }
26}
27
28impl RouteEvent<'_> {
29    /// Returns the [`RuleId`] that the packet matched on
30    #[must_use]
31    pub fn rule_id(&self) -> RuleId {
32        RuleId(self.route_args().rule_id)
33    }
34
35    /// Returns the raw packet data
36    #[must_use]
37    pub fn data(&self) -> &[u8] {
38        self.umem.data(self.address, self.len)
39    }
40
41    fn route_args(&self) -> RouteArgs {
42        let address = cast::umem_offset_to_usize(self.address) - core::mem::size_of::<RouteArgs>();
43        self.umem.read(address)
44    }
45
46    /// Converts to an [`OwnedRouteEvent`], releasing the underlying `AF_XDP` socket frame.
47    #[must_use]
48    pub fn into_owned(self) -> OwnedRouteEvent {
49        let route_args = self.route_args();
50        let data = self.data().into();
51        OwnedRouteEvent { data, route_args }
52    }
53}
54/// An owned version of [`RouteEvent`] that contains data copied from the `AF_XDP` socket frame.
55pub struct OwnedRouteEvent {
56    data: Box<[u8]>,
57    route_args: RouteArgs,
58}
59
60impl OwnedRouteEvent {
61    /// Returns the [`RuleId`] that matched for this packet.
62    #[must_use]
63    pub fn rule_id(&self) -> RuleId {
64        RuleId(self.route_args.rule_id)
65    }
66
67    /// Returns the raw packet data
68    #[must_use]
69    pub fn data(&self) -> &[u8] {
70        &self.data
71    }
72}