4
0

memmove_test.rs 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #![no_std]
  2. #![no_main]
  3. use core::mem;
  4. use aya_ebpf::{
  5. bindings::{xdp_action, BPF_F_NO_PREALLOC},
  6. macros::{map, xdp},
  7. maps::HashMap,
  8. programs::XdpContext,
  9. };
  10. use network_types::{
  11. eth::{EthHdr, EtherType},
  12. ip::Ipv6Hdr,
  13. };
  14. #[inline(always)]
  15. fn ptr_at<T>(ctx: &XdpContext, offset: usize) -> Result<*const T, ()> {
  16. let start = ctx.data();
  17. let end = ctx.data_end();
  18. let len = mem::size_of::<T>();
  19. if start + offset + len > end {
  20. return Err(());
  21. }
  22. Ok((start + offset) as *const T)
  23. }
  24. struct Value {
  25. pub orig_ip: [u8; 16],
  26. }
  27. #[map]
  28. static RULES: HashMap<u8, Value> = HashMap::<u8, Value>::with_max_entries(1, BPF_F_NO_PREALLOC);
  29. #[xdp]
  30. pub fn do_dnat(ctx: XdpContext) -> u32 {
  31. try_do_dnat(ctx).unwrap_or(xdp_action::XDP_DROP)
  32. }
  33. fn try_do_dnat(ctx: XdpContext) -> Result<u32, ()> {
  34. let index = 0;
  35. if let Some(nat) = unsafe { RULES.get(&index) } {
  36. let hproto: *const EtherType = ptr_at(&ctx, mem::offset_of!(EthHdr, ether_type))?;
  37. match unsafe { *hproto } {
  38. EtherType::Ipv6 => {
  39. let ip_hdr: *const Ipv6Hdr = ptr_at(&ctx, EthHdr::LEN)?;
  40. unsafe { (*ip_hdr.cast_mut()).dst_addr.in6_u.u6_addr8 = nat.orig_ip };
  41. }
  42. _ => return Ok(xdp_action::XDP_PASS),
  43. }
  44. }
  45. Ok(xdp_action::XDP_PASS)
  46. }
  47. #[cfg(not(test))]
  48. #[panic_handler]
  49. fn panic(_info: &core::panic::PanicInfo) -> ! {
  50. loop {}
  51. }