vmm/mmds/
persist.rs

1// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Defines the structures needed for saving/restoring MmdsNetworkStack.
5
6use std::net::Ipv4Addr;
7use std::sync::{Arc, Mutex};
8
9use serde::{Deserialize, Serialize};
10
11use super::ns::MmdsNetworkStack;
12use crate::mmds::data_store::Mmds;
13use crate::snapshot::Persist;
14use crate::utils::net::mac::{MAC_ADDR_LEN, MacAddr};
15
16/// State of a MmdsNetworkStack.
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct MmdsNetworkStackState {
19    mac_addr: [u8; MAC_ADDR_LEN as usize],
20    ipv4_addr: u32,
21    tcp_port: u16,
22}
23
24impl Persist<'_> for MmdsNetworkStack {
25    type State = MmdsNetworkStackState;
26    type ConstructorArgs = Arc<Mutex<Mmds>>;
27    type Error = ();
28
29    fn save(&self) -> Self::State {
30        let mut mac_addr = [0; MAC_ADDR_LEN as usize];
31        mac_addr.copy_from_slice(self.mac_addr.get_bytes());
32
33        MmdsNetworkStackState {
34            mac_addr,
35            ipv4_addr: self.ipv4_addr.into(),
36            tcp_port: self.tcp_handler.local_port(),
37        }
38    }
39
40    fn restore(mmds: Self::ConstructorArgs, state: &Self::State) -> Result<Self, Self::Error> {
41        Ok(MmdsNetworkStack::new(
42            MacAddr::from_bytes_unchecked(&state.mac_addr),
43            Ipv4Addr::from(state.ipv4_addr),
44            state.tcp_port,
45            mmds,
46        ))
47    }
48}
49
50#[cfg(test)]
51mod tests {
52
53    use super::*;
54    use crate::snapshot::Snapshot;
55
56    #[test]
57    fn test_persistence() {
58        let ns = MmdsNetworkStack::new_with_defaults(None, Arc::new(Mutex::new(Mmds::default())));
59
60        let mut mem = vec![0; 4096];
61
62        Snapshot::new(ns.save())
63            .save(&mut mem.as_mut_slice())
64            .unwrap();
65
66        let restored_ns = MmdsNetworkStack::restore(
67            Arc::new(Mutex::new(Mmds::default())),
68            &Snapshot::load_without_crc_check(mem.as_slice())
69                .unwrap()
70                .data,
71        )
72        .unwrap();
73
74        assert_eq!(restored_ns.mac_addr, ns.mac_addr);
75        assert_eq!(restored_ns.ipv4_addr, ns.ipv4_addr);
76        assert_eq!(
77            restored_ns.tcp_handler.local_port(),
78            ns.tcp_handler.local_port()
79        );
80    }
81}