1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
mod socket;
pub use socket::{
BindFlags, Config as SocketConfig, ConfigBuilder as SocketConfigBuilder, Interface,
LibbpfFlags, XdpFlags,
};
mod umem;
pub use umem::{
Config as UmemConfig, ConfigBuildError as UmemConfigBuilderError,
ConfigBuilder as UmemConfigBuilder,
};
use std::{convert::TryFrom, error, fmt};
use crate::util;
pub const XDP_UMEM_MIN_CHUNK_SIZE: u32 = 2048;
#[derive(Debug, Clone, Copy)]
pub struct QueueSize(u32);
impl QueueSize {
pub fn new(size: u32) -> Result<Self, QueueSizeError> {
if !util::is_pow_of_two(size) {
Err(QueueSizeError(size))
} else {
Ok(Self(size))
}
}
pub fn get(&self) -> u32 {
self.0
}
}
impl TryFrom<u32> for QueueSize {
type Error = QueueSizeError;
fn try_from(size: u32) -> Result<Self, Self::Error> {
QueueSize::new(size)
}
}
#[derive(Debug)]
pub struct QueueSizeError(u32);
impl fmt::Display for QueueSizeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "expected a power of two as queue size, got {}", self.0)
}
}
impl error::Error for QueueSizeError {}
#[derive(Debug, Clone, Copy)]
pub struct FrameSize(u32);
impl FrameSize {
pub fn new(size: u32) -> Result<Self, FrameSizeError> {
if size < XDP_UMEM_MIN_CHUNK_SIZE {
Err(FrameSizeError(size))
} else {
Ok(Self(size))
}
}
pub fn get(&self) -> u32 {
self.0
}
}
impl TryFrom<u32> for FrameSize {
type Error = FrameSizeError;
fn try_from(size: u32) -> Result<Self, Self::Error> {
FrameSize::new(size)
}
}
#[derive(Debug)]
pub struct FrameSizeError(u32);
impl fmt::Display for FrameSizeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"expected frame size >= {}, got {}",
XDP_UMEM_MIN_CHUNK_SIZE, self.0
)
}
}
impl error::Error for FrameSizeError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn queue_size_should_accept_only_non_zero_powers_of_two() {
assert!(QueueSize::new(0).is_err());
assert!(QueueSize::new(1).is_ok());
assert!(QueueSize::new(2).is_ok());
assert!(QueueSize::new(3).is_err());
assert!(QueueSize::new(4).is_ok());
}
#[test]
fn frame_size_should_reject_values_below_2048() {
assert!(FrameSize::new(0).is_err());
assert!(FrameSize::new(XDP_UMEM_MIN_CHUNK_SIZE - 1).is_err());
assert!(FrameSize::new(XDP_UMEM_MIN_CHUNK_SIZE).is_ok());
assert!(FrameSize::new(XDP_UMEM_MIN_CHUNK_SIZE + 1).is_ok())
}
}