maps.rs 9.6 KB

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