Skip to main content

net_backend/
tests.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Types to help test backends.
5
6use crate::BufferAccess;
7use crate::RxBufferSegment;
8use crate::RxId;
9use crate::RxMetadata;
10use guestmem::GuestMemory;
11use memory_range::MemoryRange;
12use parking_lot::Mutex;
13use std::sync::Arc;
14use std::sync::atomic::AtomicU32;
15use std::sync::atomic::Ordering;
16use vm_topology::memory::MemoryLayout;
17
18pub fn test_layout() -> MemoryLayout {
19    MemoryLayout::new(
20        64 * 4096,
21        &[
22            MemoryRange::new(64 * 4096..65 * 4096),
23            MemoryRange::new(65 * 4096..66 * 4096),
24        ],
25        &[],
26        &[],
27        None,
28    )
29    .unwrap()
30}
31
32#[derive(Clone)]
33pub struct Bufs {
34    inner: Arc<BufsInner>,
35}
36
37struct BufsInner {
38    rx_metadata: Vec<Mutex<Option<RxMetadata>>>,
39    rx_capacity: Vec<AtomicU32>,
40    guest_memory: GuestMemory,
41}
42
43impl Bufs {
44    pub fn new(guest_memory: GuestMemory) -> Self {
45        let mut rx_metadata = Vec::new();
46        rx_metadata.resize_with(128, Default::default);
47        let mut rx_capacity = Vec::new();
48        rx_capacity.resize_with(128, || AtomicU32::new(2048));
49        Self {
50            inner: Arc::new(BufsInner {
51                rx_metadata,
52                rx_capacity,
53                guest_memory,
54            }),
55        }
56    }
57}
58
59impl BufferAccess for Bufs {
60    fn guest_memory(&self) -> &GuestMemory {
61        &self.inner.guest_memory
62    }
63
64    fn push_guest_addresses(&self, id: RxId, buf: &mut Vec<RxBufferSegment>) {
65        let gpa = id.0 as u64 * 2048;
66        buf.push(RxBufferSegment { gpa, len: 2048 });
67    }
68
69    fn capacity(&self, id: RxId) -> u32 {
70        self.inner.rx_capacity[id.0 as usize].load(Ordering::Relaxed)
71    }
72
73    fn write_data(&mut self, id: RxId, buf: &[u8]) {
74        self.inner
75            .guest_memory
76            .write_at(id.0 as u64 * 2048, buf)
77            .unwrap();
78    }
79
80    fn write_header(&mut self, id: RxId, metadata: &RxMetadata) {
81        *self.inner.rx_metadata[id.0 as usize].lock() = Some(*metadata);
82    }
83}
84
85impl Bufs {
86    /// Returns the [`RxMetadata`] written for the given receive buffer, if any.
87    pub fn rx_metadata(&self, id: RxId) -> Option<RxMetadata> {
88        *self.inner.rx_metadata[id.0 as usize].lock()
89    }
90
91    /// Overrides the capacity reported for a receive buffer.
92    pub fn set_capacity(&self, id: RxId, capacity: u32) {
93        self.inner.rx_capacity[id.0 as usize].store(capacity, Ordering::Relaxed);
94    }
95}