Skip to main content

push_packet/
error.rs

1//! Defines error variants.
2
3use crate::{
4    channels::ChannelError,
5    rules::{RuleError, RuleId},
6};
7
8pub(crate) trait ErrnoExt<T> {
9    fn xsk_error(self, description: impl Into<String>) -> Result<T, Error>;
10}
11
12impl<T> ErrnoExt<T> for Result<T, xdpilone::Errno> {
13    fn xsk_error(self, description: impl Into<String>) -> Result<T, Error> {
14        let description = description.into();
15        self.map_err(|e| {
16            let source = std::io::Error::from_raw_os_error(e.get_raw());
17            Error::AfXdp {
18                description,
19                source,
20            }
21        })
22    }
23}
24
25impl Error {
26    pub(crate) fn map(map_name: impl Into<String>, e: aya::maps::MapError) -> Self {
27        let map_name = map_name.into();
28        Self::Map { map_name, e }
29    }
30
31    pub(crate) fn load_program(
32        program_name: impl Into<String>,
33        e: aya::programs::ProgramError,
34    ) -> Self {
35        let program_name = program_name.into();
36        Self::LoadProgram { program_name, e }
37    }
38
39    pub(crate) fn attach_program(
40        program_name: impl Into<String>,
41        e: aya::programs::ProgramError,
42    ) -> Self {
43        let program_name = program_name.into();
44        Self::AttachProgram { program_name, e }
45    }
46}
47
48#[allow(missing_docs)]
49#[derive(Debug, thiserror::Error)]
50#[non_exhaustive]
51pub enum Error {
52    // From internal error types
53    #[error("rule error at index: {index}")]
54    BuilderRule {
55        index: usize,
56        #[source]
57        source: RuleError,
58    },
59    #[error(transparent)]
60    RuntimeRule(#[from] RuleError),
61    #[error(transparent)]
62    Channel(#[from] ChannelError),
63
64    #[error("no such rule: {0}")]
65    MissingRule(RuleId),
66
67    // Aya errors
68    #[error("error updating map: {map_name}")]
69    Map {
70        map_name: String,
71        #[source]
72        e: aya::maps::MapError,
73    },
74    #[error("missing eBPF map: {0}")]
75    MissingMap(String),
76    #[error("error loading program: {program_name}")]
77    LoadProgram {
78        program_name: String,
79        #[source]
80        e: aya::programs::ProgramError,
81    },
82    #[error("error attaching program: {program_name}")]
83    AttachProgram {
84        program_name: String,
85        #[source]
86        e: aya::programs::ProgramError,
87    },
88
89    #[error("invalid program type for: {program_name}")]
90    InvalidProgramType {
91        program_name: String,
92        #[source]
93        e: aya::programs::ProgramError,
94    },
95    #[error("missing eBPF program: {0}")]
96    MissingProgram(String),
97    #[error("error getting file descriptor")]
98    FileDescriptor(#[source] aya::programs::ProgramError),
99    #[error("error loading eBPF")]
100    LoadEbpf(#[source] aya::EbpfError),
101
102    // Config
103    #[error("start with CopyConfig::force_enabled() or a copy rule before build")]
104    CopyNotEnabled,
105    #[error("start with RouteConfig::force_enabled() or a route rule before build")]
106    RouteNotEnabled,
107    #[error("the channel has already been taken.")]
108    ChannelNotAvailable,
109
110    // Interface Errors
111    #[error("invalid network interface {0}")]
112    InvalidInterfaceIndex(u32),
113    #[error("invalid network interface {0}")]
114    InvalidInterfaceName(String),
115    #[error("invalid frame kind: {0}")]
116    InvalidFrameKind(u32),
117
118    // Af Xdp
119    #[error("invalid size: {0}")]
120    InvalidSize(&'static str),
121    #[error("{description}")]
122    AfXdp {
123        description: String,
124        #[source]
125        source: std::io::Error,
126    },
127
128    // Engine cap
129    #[error("the matching engine is at capacity and cannot accept additional rules")]
130    EngineAtCapacity,
131}