maps.rs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //! Map struct and type bindings.
  2. use alloc::vec::Vec;
  3. use core::mem;
  4. use crate::{EbpfSectionKind, InvalidTypeBinding};
  5. impl TryFrom<u32> for crate::generated::bpf_map_type {
  6. type Error = InvalidTypeBinding<u32>;
  7. fn try_from(map_type: u32) -> Result<Self, Self::Error> {
  8. use crate::generated::bpf_map_type::*;
  9. Ok(match map_type {
  10. x if x == BPF_MAP_TYPE_UNSPEC as u32 => BPF_MAP_TYPE_UNSPEC,
  11. x if x == BPF_MAP_TYPE_HASH as u32 => BPF_MAP_TYPE_HASH,
  12. x if x == BPF_MAP_TYPE_ARRAY as u32 => BPF_MAP_TYPE_ARRAY,
  13. x if x == BPF_MAP_TYPE_PROG_ARRAY as u32 => BPF_MAP_TYPE_PROG_ARRAY,
  14. x if x == BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 => BPF_MAP_TYPE_PERF_EVENT_ARRAY,
  15. x if x == BPF_MAP_TYPE_PERCPU_HASH as u32 => BPF_MAP_TYPE_PERCPU_HASH,
  16. x if x == BPF_MAP_TYPE_PERCPU_ARRAY as u32 => BPF_MAP_TYPE_PERCPU_ARRAY,
  17. x if x == BPF_MAP_TYPE_STACK_TRACE as u32 => BPF_MAP_TYPE_STACK_TRACE,
  18. x if x == BPF_MAP_TYPE_CGROUP_ARRAY as u32 => BPF_MAP_TYPE_CGROUP_ARRAY,
  19. x if x == BPF_MAP_TYPE_LRU_HASH as u32 => BPF_MAP_TYPE_LRU_HASH,
  20. x if x == BPF_MAP_TYPE_LRU_PERCPU_HASH as u32 => BPF_MAP_TYPE_LRU_PERCPU_HASH,
  21. x if x == BPF_MAP_TYPE_LPM_TRIE as u32 => BPF_MAP_TYPE_LPM_TRIE,
  22. x if x == BPF_MAP_TYPE_ARRAY_OF_MAPS as u32 => BPF_MAP_TYPE_ARRAY_OF_MAPS,
  23. x if x == BPF_MAP_TYPE_HASH_OF_MAPS as u32 => BPF_MAP_TYPE_HASH_OF_MAPS,
  24. x if x == BPF_MAP_TYPE_DEVMAP as u32 => BPF_MAP_TYPE_DEVMAP,
  25. x if x == BPF_MAP_TYPE_SOCKMAP as u32 => BPF_MAP_TYPE_SOCKMAP,
  26. x if x == BPF_MAP_TYPE_CPUMAP as u32 => BPF_MAP_TYPE_CPUMAP,
  27. x if x == BPF_MAP_TYPE_XSKMAP as u32 => BPF_MAP_TYPE_XSKMAP,
  28. x if x == BPF_MAP_TYPE_SOCKHASH as u32 => BPF_MAP_TYPE_SOCKHASH,
  29. x if x == BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED as u32 => {
  30. BPF_MAP_TYPE_CGROUP_STORAGE_DEPRECATED
  31. }
  32. x if x == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY as u32 => BPF_MAP_TYPE_REUSEPORT_SOCKARRAY,
  33. x if x == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED as u32 => {
  34. BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE_DEPRECATED
  35. }
  36. x if x == BPF_MAP_TYPE_QUEUE as u32 => BPF_MAP_TYPE_QUEUE,
  37. x if x == BPF_MAP_TYPE_STACK as u32 => BPF_MAP_TYPE_STACK,
  38. x if x == BPF_MAP_TYPE_SK_STORAGE as u32 => BPF_MAP_TYPE_SK_STORAGE,
  39. x if x == BPF_MAP_TYPE_DEVMAP_HASH as u32 => BPF_MAP_TYPE_DEVMAP_HASH,
  40. x if x == BPF_MAP_TYPE_STRUCT_OPS as u32 => BPF_MAP_TYPE_STRUCT_OPS,
  41. x if x == BPF_MAP_TYPE_RINGBUF as u32 => BPF_MAP_TYPE_RINGBUF,
  42. x if x == BPF_MAP_TYPE_INODE_STORAGE as u32 => BPF_MAP_TYPE_INODE_STORAGE,
  43. x if x == BPF_MAP_TYPE_TASK_STORAGE as u32 => BPF_MAP_TYPE_TASK_STORAGE,
  44. x if x == BPF_MAP_TYPE_BLOOM_FILTER as u32 => BPF_MAP_TYPE_BLOOM_FILTER,
  45. x if x == BPF_MAP_TYPE_USER_RINGBUF as u32 => BPF_MAP_TYPE_USER_RINGBUF,
  46. x if x == BPF_MAP_TYPE_CGRP_STORAGE as u32 => BPF_MAP_TYPE_CGRP_STORAGE,
  47. x if x == BPF_MAP_TYPE_ARENA as u32 => BPF_MAP_TYPE_ARENA,
  48. _ => return Err(InvalidTypeBinding { value: map_type }),
  49. })
  50. }
  51. }
  52. /// BTF definition of a map
  53. #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
  54. pub struct BtfMapDef {
  55. pub(crate) map_type: u32,
  56. pub(crate) key_size: u32,
  57. pub(crate) value_size: u32,
  58. pub(crate) max_entries: u32,
  59. pub(crate) map_flags: u32,
  60. pub(crate) pinning: PinningType,
  61. /// BTF type id of the map key
  62. pub btf_key_type_id: u32,
  63. /// BTF type id of the map value
  64. pub btf_value_type_id: u32,
  65. }
  66. /// The pinning type
  67. ///
  68. /// Upon pinning a map, a file representation is created for the map,
  69. /// so that the map can be alive and retrievable across sessions.
  70. #[repr(u32)]
  71. #[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
  72. pub enum PinningType {
  73. /// No pinning
  74. #[default]
  75. None = 0,
  76. /// Pin by the name
  77. ByName = 1,
  78. }
  79. /// The error type returned when failing to parse a [PinningType]
  80. #[derive(Debug, thiserror::Error)]
  81. pub enum PinningError {
  82. /// Unsupported pinning type
  83. #[error("unsupported pinning type `{pinning_type}`")]
  84. Unsupported {
  85. /// The unsupported pinning type
  86. pinning_type: u32,
  87. },
  88. }
  89. impl TryFrom<u32> for PinningType {
  90. type Error = PinningError;
  91. fn try_from(value: u32) -> Result<Self, Self::Error> {
  92. match value {
  93. 0 => Ok(PinningType::None),
  94. 1 => Ok(PinningType::ByName),
  95. pinning_type => Err(PinningError::Unsupported { pinning_type }),
  96. }
  97. }
  98. }
  99. /// Map definition in legacy BPF map declaration style
  100. #[allow(non_camel_case_types)]
  101. #[repr(C)]
  102. #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
  103. pub struct bpf_map_def {
  104. // minimum features required by old BPF programs
  105. /// The map type
  106. pub map_type: u32,
  107. /// The key_size
  108. pub key_size: u32,
  109. /// The value size
  110. pub value_size: u32,
  111. /// Max entry number
  112. pub max_entries: u32,
  113. /// Map flags
  114. pub map_flags: u32,
  115. // optional features
  116. /// Id
  117. pub id: u32,
  118. /// Pinning type
  119. pub pinning: PinningType,
  120. }
  121. /// The first five __u32 of `bpf_map_def` must be defined.
  122. pub(crate) const MINIMUM_MAP_SIZE: usize = mem::size_of::<u32>() * 5;
  123. /// Map data defined in `maps` or `.maps` sections
  124. #[derive(Debug, Clone)]
  125. pub enum Map {
  126. /// A map defined in the `maps` section
  127. Legacy(LegacyMap),
  128. /// A map defined in the `.maps` section
  129. Btf(BtfMap),
  130. }
  131. impl Map {
  132. /// Returns the map type
  133. pub fn map_type(&self) -> u32 {
  134. match self {
  135. Map::Legacy(m) => m.def.map_type,
  136. Map::Btf(m) => m.def.map_type,
  137. }
  138. }
  139. /// Returns the key size in bytes
  140. pub fn key_size(&self) -> u32 {
  141. match self {
  142. Map::Legacy(m) => m.def.key_size,
  143. Map::Btf(m) => m.def.key_size,
  144. }
  145. }
  146. /// Returns the value size in bytes
  147. pub fn value_size(&self) -> u32 {
  148. match self {
  149. Map::Legacy(m) => m.def.value_size,
  150. Map::Btf(m) => m.def.value_size,
  151. }
  152. }
  153. /// Set the value size in bytes
  154. pub fn set_value_size(&mut self, size: u32) {
  155. match self {
  156. Map::Legacy(m) => m.def.value_size = size,
  157. Map::Btf(m) => m.def.value_size = size,
  158. }
  159. }
  160. /// Returns the max entry number
  161. pub fn max_entries(&self) -> u32 {
  162. match self {
  163. Map::Legacy(m) => m.def.max_entries,
  164. Map::Btf(m) => m.def.max_entries,
  165. }
  166. }
  167. /// Sets the max entry number
  168. pub fn set_max_entries(&mut self, v: u32) {
  169. match self {
  170. Map::Legacy(m) => m.def.max_entries = v,
  171. Map::Btf(m) => m.def.max_entries = v,
  172. }
  173. }
  174. /// Returns the map flags
  175. pub fn map_flags(&self) -> u32 {
  176. match self {
  177. Map::Legacy(m) => m.def.map_flags,
  178. Map::Btf(m) => m.def.map_flags,
  179. }
  180. }
  181. /// Returns the pinning type of the map
  182. pub fn pinning(&self) -> PinningType {
  183. match self {
  184. Map::Legacy(m) => m.def.pinning,
  185. Map::Btf(m) => m.def.pinning,
  186. }
  187. }
  188. /// Returns the map data
  189. pub fn data(&self) -> &[u8] {
  190. match self {
  191. Map::Legacy(m) => &m.data,
  192. Map::Btf(m) => &m.data,
  193. }
  194. }
  195. /// Returns the map data as mutable
  196. pub fn data_mut(&mut self) -> &mut Vec<u8> {
  197. match self {
  198. Map::Legacy(m) => m.data.as_mut(),
  199. Map::Btf(m) => m.data.as_mut(),
  200. }
  201. }
  202. /// Returns the section index
  203. pub fn section_index(&self) -> usize {
  204. match self {
  205. Map::Legacy(m) => m.section_index,
  206. Map::Btf(m) => m.section_index,
  207. }
  208. }
  209. /// Returns the section kind.
  210. pub fn section_kind(&self) -> EbpfSectionKind {
  211. match self {
  212. Map::Legacy(m) => m.section_kind,
  213. Map::Btf(_) => EbpfSectionKind::BtfMaps,
  214. }
  215. }
  216. /// Returns the symbol index.
  217. ///
  218. /// This is `None` for data maps (.bss, .data and .rodata) since those don't
  219. /// need symbols in order to be relocated.
  220. pub fn symbol_index(&self) -> Option<usize> {
  221. match self {
  222. Map::Legacy(m) => m.symbol_index,
  223. Map::Btf(m) => Some(m.symbol_index),
  224. }
  225. }
  226. }
  227. /// A map declared with legacy BPF map declaration style, most likely from a `maps` section.
  228. ///
  229. /// See [Drop support for legacy BPF map declaration syntax - Libbpf: the road to v1.0](https://github.com/libbpf/libbpf/wiki/Libbpf:-the-road-to-v1.0#drop-support-for-legacy-bpf-map-declaration-syntax)
  230. /// for more info.
  231. #[derive(Debug, Clone)]
  232. pub struct LegacyMap {
  233. /// The definition of the map
  234. pub def: bpf_map_def,
  235. /// The section index
  236. pub section_index: usize,
  237. /// The section kind
  238. pub section_kind: EbpfSectionKind,
  239. /// The symbol index.
  240. ///
  241. /// This is None for data maps (.bss .data and .rodata). We don't need
  242. /// symbols to relocate those since they don't contain multiple maps, but
  243. /// are just a flat array of bytes.
  244. pub symbol_index: Option<usize>,
  245. /// The map data
  246. pub data: Vec<u8>,
  247. }
  248. /// A BTF-defined map, most likely from a `.maps` section.
  249. #[derive(Debug, Clone)]
  250. pub struct BtfMap {
  251. /// The definition of the map
  252. pub def: BtfMapDef,
  253. pub(crate) section_index: usize,
  254. pub(crate) symbol_index: usize,
  255. pub(crate) data: Vec<u8>,
  256. }