mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
refactor(eBPF): reduce size of maps (#8849)
Whilst developing the eBPF module for the relay, I needed to manually add padding within the key and value structs used in the maps in order for the kernel to be able to correctly retrieve the data. For some reason, this seems no longer necessary as the integration test now passes without this as well. Being able to remove the padding drastically reduces the size of these maps for the current number of entries that we allow. This brings the overall memory usage of the relay down. Resolves: #8682
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
//! Shared data structures between the kernel and userspace.
|
||||
//!
|
||||
//! To learn more about the layout requirements of these structs, read <https://github.com/foniod/redbpf/issues/150#issuecomment-964017857>.
|
||||
//! In order to make sure endianness is correct, we store everything in byte-arrays in _big-endian_ order.
|
||||
//! This makes it easier to directly take the values from the network buffer and use them in these structs (and vice-versa).
|
||||
|
||||
@@ -13,15 +12,8 @@ use core::net::{Ipv4Addr, Ipv6Addr};
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct ClientAndChannelV4 {
|
||||
ipv4_address: [u8; 4],
|
||||
_padding_ipv4_address: [u8; 4],
|
||||
|
||||
port: [u8; 2],
|
||||
_padding_port: [u8; 6],
|
||||
|
||||
channel: [u8; 2],
|
||||
_padding_channel: [u8; 6],
|
||||
|
||||
_padding_struct: [u8; 40],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@@ -29,29 +21,16 @@ pub struct ClientAndChannelV4 {
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct ClientAndChannelV6 {
|
||||
ipv6_address: [u8; 16],
|
||||
|
||||
port: [u8; 2],
|
||||
_padding_port: [u8; 6],
|
||||
|
||||
channel: [u8; 2],
|
||||
_padding_channel: [u8; 6],
|
||||
|
||||
_padding_struct: [u8; 32],
|
||||
}
|
||||
|
||||
impl ClientAndChannelV4 {
|
||||
pub fn new(ipv4_address: Ipv4Addr, port: u16, channel: u16) -> Self {
|
||||
Self {
|
||||
ipv4_address: ipv4_address.octets(),
|
||||
_padding_ipv4_address: [0u8; 4],
|
||||
|
||||
port: port.to_be_bytes(),
|
||||
_padding_port: [0u8; 6],
|
||||
|
||||
channel: channel.to_be_bytes(),
|
||||
_padding_channel: [0u8; 6],
|
||||
|
||||
_padding_struct: [0u8; 40],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,14 +55,8 @@ impl ClientAndChannelV6 {
|
||||
pub fn new(ipv6_address: Ipv6Addr, port: u16, channel: u16) -> Self {
|
||||
Self {
|
||||
ipv6_address: ipv6_address.octets(),
|
||||
|
||||
port: port.to_be_bytes(),
|
||||
_padding_port: [0u8; 6],
|
||||
|
||||
channel: channel.to_be_bytes(),
|
||||
_padding_channel: [0u8; 6],
|
||||
|
||||
_padding_struct: [0u8; 32],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,15 +82,8 @@ impl ClientAndChannelV6 {
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub struct PortAndPeerV4 {
|
||||
ipv4_address: [u8; 4],
|
||||
_padding_ipv4_address: [u8; 4],
|
||||
|
||||
allocation_port: [u8; 2],
|
||||
_padding_allocation_port: [u8; 6],
|
||||
|
||||
peer_port: [u8; 2],
|
||||
_padding_dest_port: [u8; 6],
|
||||
|
||||
_padding_struct: [u8; 40],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@@ -127,27 +93,15 @@ pub struct PortAndPeerV6 {
|
||||
ipv6_address: [u8; 16],
|
||||
|
||||
allocation_port: [u8; 2],
|
||||
_padding_allocation_port: [u8; 6],
|
||||
|
||||
peer_port: [u8; 2],
|
||||
_padding_dest_port: [u8; 6],
|
||||
|
||||
_padding_struct: [u8; 32],
|
||||
}
|
||||
|
||||
impl PortAndPeerV4 {
|
||||
pub fn new(ipv4_address: Ipv4Addr, allocation_port: u16, peer_port: u16) -> Self {
|
||||
Self {
|
||||
ipv4_address: ipv4_address.octets(),
|
||||
_padding_ipv4_address: [0u8; 4],
|
||||
|
||||
allocation_port: allocation_port.to_be_bytes(),
|
||||
_padding_allocation_port: [0u8; 6],
|
||||
|
||||
peer_port: peer_port.to_be_bytes(),
|
||||
_padding_dest_port: [0u8; 6],
|
||||
|
||||
_padding_struct: [0u8; 40],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,12 +128,7 @@ impl PortAndPeerV6 {
|
||||
ipv6_address: ipv6_address.octets(),
|
||||
|
||||
allocation_port: allocation_port.to_be_bytes(),
|
||||
_padding_allocation_port: [0u8; 6],
|
||||
|
||||
peer_port: peer_port.to_be_bytes(),
|
||||
_padding_dest_port: [0u8; 6],
|
||||
|
||||
_padding_struct: [0u8; 32],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,28 +234,3 @@ mod userspace {
|
||||
|
||||
unsafe impl aya::Pod for Config {}
|
||||
}
|
||||
|
||||
#[cfg(all(test, feature = "std"))]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn client_and_channel_v4_has_size_64() {
|
||||
assert_eq!(std::mem::size_of::<ClientAndChannelV4>(), 64)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn port_and_peer_v4_has_size_64() {
|
||||
assert_eq!(std::mem::size_of::<PortAndPeerV4>(), 64)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_and_channel_v6_has_size_64() {
|
||||
assert_eq!(std::mem::size_of::<ClientAndChannelV6>(), 64)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn port_and_peer_v6_has_size_64() {
|
||||
assert_eq!(std::mem::size_of::<PortAndPeerV6>(), 64)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ mod tests {
|
||||
const HASH_MAP_OVERHEAD: f32 = 1.5;
|
||||
|
||||
#[test]
|
||||
fn hashmaps_are_less_than_100_mb() {
|
||||
fn hashmaps_are_less_than_11_mb() {
|
||||
let ipv4_datatypes =
|
||||
core::mem::size_of::<PortAndPeerV4>() + core::mem::size_of::<ClientAndChannelV4>();
|
||||
let ipv6_datatypes =
|
||||
@@ -427,6 +427,9 @@ mod tests {
|
||||
let total_map_size = (ipv4_map_size + ipv6_map_size) * 2_f32;
|
||||
let total_map_size_mb = total_map_size / 1024_f32 / 1024_f32;
|
||||
|
||||
assert!(total_map_size_mb < 100_f32);
|
||||
assert!(
|
||||
total_map_size_mb < 11_f32,
|
||||
"Total map size = {total_map_size_mb} MB"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user