1#![allow(non_upper_case_globals)]
7
8use super::BpfMap;
9use crate::bpf::attachments::{BpfAttachAttr, bpf_prog_attach, bpf_prog_detach};
10use crate::bpf::fs::{BpfFsDir, BpfHandle, get_bpf_object, resolve_pinned_bpf_object};
11use crate::bpf::program::{Program, ProgramInfo};
12use crate::mm::{MemoryAccessor, MemoryAccessorExt};
13use crate::security;
14use crate::task::CurrentTask;
15use crate::vfs::{
16 Anon, FdFlags, FdNumber, FileObject, LookupContext, NamespaceNode, OutputBuffer,
17 UserBuffersOutputBuffer,
18};
19use ebpf::{EbpfInstruction, MapFlags, MapSchema};
20use ebpf_api::{Map, MapError, MapKey};
21use smallvec::smallvec;
22use starnix_logging::{log_error, log_trace, track_stub};
23use starnix_sync::{Locked, Unlocked};
24use starnix_syscalls::{SUCCESS, SyscallResult};
25use starnix_types::user_buffer::UserBuffer;
26use starnix_uapi::errors::Errno;
27use starnix_uapi::open_flags::OpenFlags;
28use starnix_uapi::user_address::{UserAddress, UserCString, UserRef};
29use starnix_uapi::{
30 BPF_F_RDONLY, BPF_F_WRONLY, bpf_attr__bindgen_ty_1, bpf_attr__bindgen_ty_2,
31 bpf_attr__bindgen_ty_4, bpf_attr__bindgen_ty_5, bpf_attr__bindgen_ty_8, bpf_attr__bindgen_ty_9,
32 bpf_attr__bindgen_ty_10, bpf_attr__bindgen_ty_12, bpf_cmd, bpf_cmd_BPF_BTF_GET_FD_BY_ID,
33 bpf_cmd_BPF_BTF_GET_NEXT_ID, bpf_cmd_BPF_BTF_LOAD, bpf_cmd_BPF_ENABLE_STATS,
34 bpf_cmd_BPF_ITER_CREATE, bpf_cmd_BPF_LINK_CREATE, bpf_cmd_BPF_LINK_DETACH,
35 bpf_cmd_BPF_LINK_GET_FD_BY_ID, bpf_cmd_BPF_LINK_GET_NEXT_ID, bpf_cmd_BPF_LINK_UPDATE,
36 bpf_cmd_BPF_MAP_CREATE, bpf_cmd_BPF_MAP_DELETE_BATCH, bpf_cmd_BPF_MAP_DELETE_ELEM,
37 bpf_cmd_BPF_MAP_FREEZE, bpf_cmd_BPF_MAP_GET_FD_BY_ID, bpf_cmd_BPF_MAP_GET_NEXT_ID,
38 bpf_cmd_BPF_MAP_GET_NEXT_KEY, bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_BATCH,
39 bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_ELEM, bpf_cmd_BPF_MAP_LOOKUP_BATCH,
40 bpf_cmd_BPF_MAP_LOOKUP_ELEM, bpf_cmd_BPF_MAP_UPDATE_BATCH, bpf_cmd_BPF_MAP_UPDATE_ELEM,
41 bpf_cmd_BPF_OBJ_GET, bpf_cmd_BPF_OBJ_GET_INFO_BY_FD, bpf_cmd_BPF_OBJ_PIN,
42 bpf_cmd_BPF_PROG_ATTACH, bpf_cmd_BPF_PROG_BIND_MAP, bpf_cmd_BPF_PROG_DETACH,
43 bpf_cmd_BPF_PROG_GET_FD_BY_ID, bpf_cmd_BPF_PROG_GET_NEXT_ID, bpf_cmd_BPF_PROG_LOAD,
44 bpf_cmd_BPF_PROG_QUERY, bpf_cmd_BPF_PROG_RUN, bpf_cmd_BPF_RAW_TRACEPOINT_OPEN,
45 bpf_cmd_BPF_TASK_FD_QUERY, bpf_cmd_BPF_TOKEN_CREATE, bpf_map_info,
46 bpf_map_type_BPF_MAP_TYPE_DEVMAP, bpf_map_type_BPF_MAP_TYPE_DEVMAP_HASH, bpf_prog_info, errno,
47 error,
48};
49use zerocopy::{FromBytes, IntoBytes};
50
51fn read_attr<Attr: FromBytes>(
56 current_task: &CurrentTask,
57 attr_addr: UserAddress,
58 attr_size: u32,
59) -> Result<Attr, Errno> {
60 let mut attr_size = attr_size as usize;
61 let sizeof_attr = std::mem::size_of::<Attr>();
62
63 if attr_size > sizeof_attr {
65 let tail_addr = attr_addr.checked_add(sizeof_attr).ok_or_else(|| errno!(EFAULT))?;
66 let tail = current_task.read_memory_to_vec(tail_addr, attr_size - sizeof_attr)?;
67 if tail.into_iter().any(|byte| byte != 0) {
68 return error!(E2BIG);
69 }
70
71 attr_size = sizeof_attr;
72 }
73
74 current_task.read_object_partial(UserRef::new(attr_addr), attr_size)
77}
78
79fn reopen_bpf_fd(
80 locked: &mut Locked<Unlocked>,
81 current_task: &CurrentTask,
82 node: NamespaceNode,
83 handle: BpfHandle,
84 open_flags: OpenFlags,
85) -> Result<SyscallResult, Errno> {
86 let file = FileObject::new(
88 locked,
89 current_task,
90 Box::new(handle),
91 node,
92 open_flags | OpenFlags::CLOEXEC,
93 )?;
94 Ok(current_task.add_file(locked, file, FdFlags::CLOEXEC)?.into())
95}
96
97fn install_bpf_fd(
98 locked: &mut Locked<Unlocked>,
99 current_task: &CurrentTask,
100 obj: impl Into<BpfHandle>,
101) -> Result<SyscallResult, Errno> {
102 let handle: BpfHandle = obj.into();
103 let name = handle.type_name();
104 handle.security_check_open_fd(current_task, None)?;
105
106 let file = Anon::new_private_file(
108 locked,
109 current_task,
110 Box::new(handle),
111 OpenFlags::RDWR | OpenFlags::CLOEXEC,
112 name,
113 );
114 Ok(current_task.add_file(locked, file, FdFlags::CLOEXEC)?.into())
115}
116
117#[derive(Debug, Clone)]
118pub struct BpfTypeFormat {
119 #[allow(dead_code)]
120 data: Vec<u8>,
121}
122
123fn read_map_key(
124 current_task: &CurrentTask,
125 addr: UserAddress,
126 key_size: u32,
127) -> Result<MapKey, Errno> {
128 let key_size = key_size as usize;
129 current_task.read_objects_to_smallvec(UserRef::<u8>::new(addr), key_size as usize)
130}
131
132fn map_error_to_errno(e: MapError) -> Errno {
133 match e {
134 MapError::InvalidParam => errno!(EINVAL),
135 MapError::InvalidKey => errno!(ENOENT),
136 MapError::EntryExists => errno!(EEXIST),
137 MapError::NoMemory => errno!(ENOMEM),
138 MapError::SizeLimit => errno!(E2BIG),
139 MapError::MapTypeNotSupported | MapError::NotSupported => errno!(ENOSYS),
140 MapError::InvalidVmo | MapError::Internal => errno!(EIO),
141 }
142}
143
144fn validate_bpf_name(name: &[u8]) -> Result<&str, Errno> {
145 let name = std::ffi::CStr::from_bytes_until_nul(name)
146 .map_err(|_| errno!(EINVAL))?
147 .to_str()
148 .map_err(|_| errno!(EINVAL))?;
149 if !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '.') {
152 return error!(EINVAL);
153 }
154 Ok(name)
155}
156
157pub fn sys_bpf(
158 locked: &mut Locked<Unlocked>,
159 current_task: &CurrentTask,
160 cmd: bpf_cmd,
161 attr_addr: UserAddress,
162 attr_size: u32,
163) -> Result<SyscallResult, Errno> {
164 match cmd {
172 bpf_cmd_BPF_MAP_CREATE => {
174 let map_attr: bpf_attr__bindgen_ty_1 = read_attr(current_task, attr_addr, attr_size)?;
175 log_trace!("BPF_MAP_CREATE {:?}", map_attr);
176 security::check_bpf_access(current_task, cmd, &map_attr, attr_size)?;
177
178 let map_type = map_attr.map_type;
179 let mut flags =
180 MapFlags::from_bits(map_attr.map_flags).ok_or_else(|| errno!(EINVAL))?;
181 if map_type == bpf_map_type_BPF_MAP_TYPE_DEVMAP
186 || map_type == bpf_map_type_BPF_MAP_TYPE_DEVMAP_HASH
187 {
188 flags |= MapFlags::ProgReadOnly;
189 }
190
191 let schema = MapSchema {
192 map_type,
193 key_size: map_attr.key_size,
194 value_size: map_attr.value_size,
195 max_entries: map_attr.max_entries,
196 flags,
197 };
198
199 let map = Map::new(schema, validate_bpf_name(map_attr.map_name.as_bytes())?)
200 .map_err(map_error_to_errno)?;
201 let map = BpfMap::new(locked, current_task, map, security::bpf_map_alloc(current_task));
202 install_bpf_fd(locked, current_task, map)
203 }
204
205 bpf_cmd_BPF_MAP_LOOKUP_ELEM => {
206 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
207 log_trace!("BPF_MAP_LOOKUP_ELEM");
208 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
209 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
210 let map = get_bpf_object(current_task, map_fd)?;
211 let map = map.as_map()?;
212
213 if map.schema.flags.contains(MapFlags::SyscallWriteOnly) {
214 return error!(EPERM);
215 }
216
217 let key =
218 read_map_key(current_task, UserAddress::from(elem_attr.key), map.schema.key_size)?;
219
220 let user_value = UserAddress::from(unsafe { elem_attr.__bindgen_anon_1.value });
223
224 let _suspend_lock =
225 current_task.kernel().suspend_resume_manager.acquire_ebpf_suspend_lock(locked);
226
227 let value = map.load(&key).ok_or_else(|| errno!(ENOENT))?;
228 current_task.write_memory(user_value, &value)?;
229
230 Ok(SUCCESS)
231 }
232
233 bpf_cmd_BPF_MAP_UPDATE_ELEM => {
235 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
236 log_trace!("BPF_MAP_UPDATE_ELEM");
237 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
238 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
239 let map = get_bpf_object(current_task, map_fd)?;
240 let map = map.as_map()?;
241
242 let (frozen, locked) = map.frozen(locked);
244
245 if *frozen || map.schema.flags.contains(MapFlags::SyscallReadOnly) {
246 return error!(EPERM);
247 }
248
249 let flags = elem_attr.flags;
250 let key =
251 read_map_key(current_task, UserAddress::from(elem_attr.key), map.schema.key_size)?;
252
253 let user_value = UserAddress::from(unsafe { elem_attr.__bindgen_anon_1.value });
256 let value =
257 current_task.read_memory_to_vec(user_value, map.schema.value_size as usize)?;
258
259 let _suspend_lock =
260 current_task.kernel().suspend_resume_manager.acquire_ebpf_suspend_lock(locked);
261
262 map.update(key, &value, flags).map_err(map_error_to_errno)?;
263 Ok(SUCCESS)
264 }
265
266 bpf_cmd_BPF_MAP_DELETE_ELEM => {
267 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
268 log_trace!("BPF_MAP_DELETE_ELEM");
269 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
270 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
271 let map = get_bpf_object(current_task, map_fd)?;
272 let map = map.as_map()?;
273
274 let (frozen, locked) = map.frozen(locked);
276
277 if *frozen || map.schema.flags.contains(MapFlags::SyscallReadOnly) {
278 return error!(EPERM);
279 }
280
281 let key =
282 read_map_key(current_task, UserAddress::from(elem_attr.key), map.schema.key_size)?;
283
284 let _suspend_lock =
285 current_task.kernel().suspend_resume_manager.acquire_ebpf_suspend_lock(locked);
286
287 map.delete(&key).map_err(map_error_to_errno)?;
288 Ok(SUCCESS)
289 }
290
291 bpf_cmd_BPF_MAP_GET_NEXT_KEY => {
294 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
295 log_trace!("BPF_MAP_GET_NEXT_KEY");
296 security::check_bpf_access(current_task, cmd, &elem_attr, attr_size)?;
297 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
298 let map = get_bpf_object(current_task, map_fd)?;
299 let map = map.as_map()?;
300
301 if map.schema.flags.contains(MapFlags::SyscallWriteOnly) {
302 return error!(EPERM);
303 }
304
305 let key = if elem_attr.key != 0 {
306 Some(read_map_key(
307 current_task,
308 UserAddress::from(elem_attr.key),
309 map.schema.key_size,
310 )?)
311 } else {
312 None
313 };
314
315 let next_key =
316 map.get_next_key(key.as_ref().map(|k| &k[..])).map_err(map_error_to_errno)?;
317
318 let user_next_key = UserAddress::from(unsafe { elem_attr.__bindgen_anon_1.next_key });
321 current_task.write_memory(user_next_key, &next_key)?;
322
323 Ok(SUCCESS)
324 }
325
326 bpf_cmd_BPF_PROG_LOAD => {
329 let prog_attr: bpf_attr__bindgen_ty_4 = read_attr(current_task, attr_addr, attr_size)?;
330 log_trace!("BPF_PROG_LOAD");
331 security::check_bpf_access(current_task, cmd, &prog_attr, attr_size)?;
332
333 let user_code = UserRef::<EbpfInstruction>::new(UserAddress::from(prog_attr.insns));
334 let code = current_task.read_objects_to_vec(user_code, prog_attr.insn_cnt as usize)?;
335
336 let mut log_buffer = if prog_attr.log_buf != 0 && prog_attr.log_size > 1 {
337 UserBuffersOutputBuffer::unified_new(
338 current_task,
339 smallvec![UserBuffer {
340 address: prog_attr.log_buf.into(),
341 length: (prog_attr.log_size - 1) as usize
342 }],
343 )?
344 } else {
345 UserBuffersOutputBuffer::unified_new(current_task, smallvec![])?
346 };
347 let name = validate_bpf_name(prog_attr.prog_name.as_bytes())?;
348 let program = ProgramInfo::try_from(&prog_attr)
349 .and_then(|info| Program::new(locked, current_task, info, &mut log_buffer, code));
350 let program_or_stub = match program {
351 Ok(program) => BpfHandle::Program(program),
352 Err(e) => {
353 if current_task.kernel().features.bpf_v2 {
354 return Err(e.into());
355 }
356 log_error!("Unable to load bpf program {name}: {e:?}");
359 BpfHandle::ProgramStub(prog_attr.prog_type)
360 }
361 };
362 log_buffer.write(b"\0")?;
364 install_bpf_fd(locked, current_task, program_or_stub)
365 }
366
367 bpf_cmd_BPF_PROG_ATTACH => {
369 let attach_attr: BpfAttachAttr = read_attr(current_task, attr_addr, attr_size)?;
370 security::check_bpf_access(current_task, cmd, &attach_attr, attr_size)?;
371 bpf_prog_attach(locked, current_task, attach_attr)
372 }
373
374 bpf_cmd_BPF_PROG_QUERY => {
376 let mut prog_attr: bpf_attr__bindgen_ty_10 =
377 read_attr(current_task, attr_addr, attr_size)?;
378 log_trace!("BPF_PROG_QUERY");
379 security::check_bpf_access(current_task, cmd, &prog_attr, attr_size)?;
380 track_stub!(TODO("https://fxbug.dev/322873416"), "Bpf::BPF_PROG_QUERY");
381 current_task.write_memory(UserAddress::from(prog_attr.prog_ids), 1.as_bytes())?;
382 prog_attr.__bindgen_anon_2.prog_cnt = std::mem::size_of::<u64>() as u32;
383 current_task.write_memory(attr_addr, prog_attr.as_bytes())?;
384 Ok(SUCCESS)
385 }
386
387 bpf_cmd_BPF_OBJ_PIN => {
390 let pin_attr: bpf_attr__bindgen_ty_5 = read_attr(current_task, attr_addr, attr_size)?;
391 log_trace!("BPF_OBJ_PIN {:?}", pin_attr);
392 security::check_bpf_access(current_task, cmd, &pin_attr, attr_size)?;
393 let bpf_fd = FdNumber::from_raw(pin_attr.bpf_fd as i32);
394 let object = get_bpf_object(current_task, bpf_fd)?;
395 let path_addr = UserCString::new(current_task, UserAddress::from(pin_attr.pathname));
396 let pathname = current_task.read_path(path_addr)?;
397 let (parent, basename) = current_task.lookup_parent_at(
398 locked,
399 &mut LookupContext::default(),
400 FdNumber::AT_FDCWD,
401 pathname.as_ref(),
402 )?;
403 let bpf_dir =
404 parent.entry.node.downcast_ops::<BpfFsDir>().ok_or_else(|| errno!(EINVAL))?;
405 bpf_dir.register_pin(locked, current_task, &parent, basename, object)?;
406 Ok(SUCCESS)
407 }
408
409 bpf_cmd_BPF_OBJ_GET => {
411 let path_attr: bpf_attr__bindgen_ty_5 = read_attr(current_task, attr_addr, attr_size)?;
412 log_trace!("BPF_OBJ_GET {:?}", path_attr);
413 security::check_bpf_access(current_task, cmd, &path_attr, attr_size)?;
414 let path_addr = UserCString::new(current_task, UserAddress::from(path_attr.pathname));
415 let open_flags = match path_attr.file_flags {
416 BPF_F_RDONLY => OpenFlags::RDONLY,
417 BPF_F_WRONLY => OpenFlags::WRONLY,
418 0 => OpenFlags::RDWR,
419 _ => return error!(EINVAL),
420 };
421 let pathname = current_task.read_path(path_addr)?;
422 let (handle, node) =
423 resolve_pinned_bpf_object(locked, current_task, pathname.as_ref(), open_flags)?;
424 reopen_bpf_fd(locked, current_task, node, handle, open_flags)
425 }
426
427 bpf_cmd_BPF_OBJ_GET_INFO_BY_FD => {
429 let mut get_info_attr: bpf_attr__bindgen_ty_9 =
430 read_attr(current_task, attr_addr, attr_size)?;
431 log_trace!("BPF_OBJ_GET_INFO_BY_FD {:?}", get_info_attr);
432 security::check_bpf_access(current_task, cmd, &get_info_attr, attr_size)?;
433 let bpf_fd = FdNumber::from_raw(get_info_attr.bpf_fd as i32);
434 let object = get_bpf_object(current_task, bpf_fd)?;
435
436 let mut info = match object {
437 BpfHandle::Map(map) => bpf_map_info {
438 type_: map.schema.map_type,
439 id: map.id(),
440 key_size: map.schema.key_size,
441 value_size: map.schema.value_size,
442 max_entries: map.schema.max_entries,
443 map_flags: map.schema.flags.bits(),
444 ..Default::default()
445 }
446 .as_bytes()
447 .to_owned(),
448 BpfHandle::Program(prog) => {
449 #[allow(unknown_lints, clippy::unnecessary_struct_initialization)]
450 bpf_prog_info {
451 type_: prog.info.program_type.into(),
452 id: prog.id(),
453 jited_prog_len: 1,
455 ..Default::default()
456 }
457 .as_bytes()
458 .to_owned()
459 }
460 BpfHandle::ProgramStub(type_) => {
461 #[allow(unknown_lints, clippy::unnecessary_struct_initialization)]
462 bpf_prog_info {
463 type_,
464 jited_prog_len: 1,
466 ..Default::default()
467 }
468 .as_bytes()
469 .to_owned()
470 }
471 _ => {
472 return error!(EINVAL);
473 }
474 };
475
476 info.truncate(get_info_attr.info_len as usize);
481 get_info_attr.info_len = info.len() as u32;
482 current_task.write_memory(UserAddress::from(get_info_attr.info), &info)?;
483 current_task.write_memory(attr_addr, get_info_attr.as_bytes())?;
484 Ok(SUCCESS)
485 }
486
487 bpf_cmd_BPF_BTF_LOAD => {
491 let btf_attr: bpf_attr__bindgen_ty_12 = read_attr(current_task, attr_addr, attr_size)?;
492 log_trace!("BPF_BTF_LOAD {:?}", btf_attr);
493 security::check_bpf_access(current_task, cmd, &btf_attr, attr_size)?;
494 let data = current_task
495 .read_memory_to_vec(UserAddress::from(btf_attr.btf), btf_attr.btf_size as usize)?;
496 install_bpf_fd(locked, current_task, BpfTypeFormat { data })
497 }
498 bpf_cmd_BPF_PROG_DETACH => {
499 let attach_attr: BpfAttachAttr = read_attr(current_task, attr_addr, attr_size)?;
500 security::check_bpf_access(current_task, cmd, &attach_attr, attr_size)?;
501 bpf_prog_detach(locked, current_task, attach_attr)
502 }
503 bpf_cmd_BPF_PROG_RUN => {
504 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_PROG_RUN");
505 error!(EINVAL)
506 }
507 bpf_cmd_BPF_PROG_GET_NEXT_ID => {
508 let mut get_next_attr: bpf_attr__bindgen_ty_8 =
509 read_attr(current_task, attr_addr, attr_size)?;
510 let start_id = unsafe { get_next_attr.__bindgen_anon_1.start_id };
512 get_next_attr.next_id = current_task
513 .kernel()
514 .ebpf_state
515 .get_next_program_id(locked, start_id)
516 .ok_or_else(|| errno!(ENOENT))?;
517 current_task.write_object(UserRef::new(attr_addr), &get_next_attr)?;
518 Ok(SUCCESS)
519 }
520 bpf_cmd_BPF_MAP_GET_NEXT_ID => {
521 let mut get_next_attr: bpf_attr__bindgen_ty_8 =
522 read_attr(current_task, attr_addr, attr_size)?;
523 let start_id = unsafe { get_next_attr.__bindgen_anon_1.start_id };
525 get_next_attr.next_id = current_task
526 .kernel()
527 .ebpf_state
528 .get_next_map_id(locked, start_id)
529 .ok_or_else(|| errno!(ENOENT))?;
530 current_task.write_object(UserRef::new(attr_addr), &get_next_attr)?;
531 Ok(SUCCESS)
532 }
533 bpf_cmd_BPF_PROG_GET_FD_BY_ID => {
534 let get_by_id_attr: bpf_attr__bindgen_ty_8 =
535 read_attr(current_task, attr_addr, attr_size)?;
536 let prog_id = unsafe { get_by_id_attr.__bindgen_anon_1.prog_id };
538 let prog = current_task
539 .kernel()
540 .ebpf_state
541 .get_program_by_id(locked, prog_id)
542 .ok_or_else(|| errno!(ENOENT))?;
543 install_bpf_fd(locked, current_task, prog)
544 }
545 bpf_cmd_BPF_MAP_GET_FD_BY_ID => {
546 let get_by_id_attr: bpf_attr__bindgen_ty_8 =
547 read_attr(current_task, attr_addr, attr_size)?;
548 let map_id = unsafe { get_by_id_attr.__bindgen_anon_1.map_id };
550 let map = current_task
551 .kernel()
552 .ebpf_state
553 .get_map_by_id(locked, map_id)
554 .ok_or_else(|| errno!(ENOENT))?;
555 install_bpf_fd(locked, current_task, map)
556 }
557 bpf_cmd_BPF_RAW_TRACEPOINT_OPEN => {
558 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_RAW_TRACEPOINT_OPEN");
559 error!(EINVAL)
560 }
561 bpf_cmd_BPF_BTF_GET_FD_BY_ID => {
562 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_BTF_GET_FD_BY_ID");
563 error!(EINVAL)
564 }
565 bpf_cmd_BPF_TASK_FD_QUERY => {
566 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_TASK_FD_QUERY");
567 error!(EINVAL)
568 }
569 bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_ELEM => {
570 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_LOOKUP_AND_DELETE_ELEM");
571 error!(EINVAL)
572 }
573 bpf_cmd_BPF_MAP_FREEZE => {
574 let elem_attr: bpf_attr__bindgen_ty_2 = read_attr(current_task, attr_addr, attr_size)?;
575 log_trace!("BPF_MAP_FREEZE");
576 let map_fd = FdNumber::from_raw(elem_attr.map_fd as i32);
577 let map = get_bpf_object(current_task, map_fd)?;
578 let map = map.as_map()?;
579 map.freeze(locked)?;
580 Ok(SUCCESS)
581 }
582 bpf_cmd_BPF_BTF_GET_NEXT_ID => {
583 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_BTF_GET_NEXT_ID");
584 error!(EINVAL)
585 }
586 bpf_cmd_BPF_MAP_LOOKUP_BATCH => {
587 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_LOOKUP_BATCH");
588 error!(EINVAL)
589 }
590 bpf_cmd_BPF_MAP_LOOKUP_AND_DELETE_BATCH => {
591 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_LOOKUP_AND_DELETE_BATCH");
592 error!(EINVAL)
593 }
594 bpf_cmd_BPF_MAP_UPDATE_BATCH => {
595 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_UPDATE_BATCH");
596 error!(EINVAL)
597 }
598 bpf_cmd_BPF_MAP_DELETE_BATCH => {
599 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_MAP_DELETE_BATCH");
600 error!(EINVAL)
601 }
602 bpf_cmd_BPF_LINK_CREATE => {
603 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_CREATE");
604 error!(EINVAL)
605 }
606 bpf_cmd_BPF_LINK_UPDATE => {
607 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_UPDATE");
608 error!(EINVAL)
609 }
610 bpf_cmd_BPF_LINK_GET_FD_BY_ID => {
611 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_GET_FD_BY_ID");
612 error!(EINVAL)
613 }
614 bpf_cmd_BPF_LINK_GET_NEXT_ID => {
615 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_GET_NEXT_ID");
616 error!(EINVAL)
617 }
618 bpf_cmd_BPF_ENABLE_STATS => {
619 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_ENABLE_STATS");
620 error!(EINVAL)
621 }
622 bpf_cmd_BPF_ITER_CREATE => {
623 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_ITER_CREATE");
624 error!(EINVAL)
625 }
626 bpf_cmd_BPF_LINK_DETACH => {
627 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_LINK_DETACH");
628 error!(EINVAL)
629 }
630 bpf_cmd_BPF_PROG_BIND_MAP => {
631 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_PROG_BIND_MAP");
632 error!(EINVAL)
633 }
634 bpf_cmd_BPF_TOKEN_CREATE => {
635 track_stub!(TODO("https://fxbug.dev/322874055"), "BPF_TOKEN_CREATE");
636 error!(EINVAL)
637 }
638 _ => {
639 track_stub!(TODO("https://fxbug.dev/322874055"), "bpf", cmd);
640 error!(EINVAL)
641 }
642 }
643}
644
645#[cfg(target_arch = "aarch64")]
647mod arch32 {
648 pub use super::sys_bpf as sys_arch32_bpf;
649}
650
651#[cfg(target_arch = "aarch64")]
652pub use arch32::*;