1use 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 #[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 #[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 #[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 #[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 #[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 #[error("the matching engine is at capacity and cannot accept additional rules")]
130 EngineAtCapacity,
131}