arcbox_virtio_net/
config.rs1use std::os::unix::io::RawFd;
4use std::sync::atomic::AtomicU16;
5
6#[derive(Debug, Clone)]
8pub struct NetConfig {
9 pub mac: [u8; 6],
11 pub mtu: u16,
13 pub tap_name: Option<String>,
15 pub num_queues: u16,
17}
18
19impl Default for NetConfig {
20 fn default() -> Self {
21 Self {
22 mac: [0x52, 0x54, 0x00, 0x12, 0x34, 0x56], mtu: 1500,
24 tap_name: None,
25 num_queues: 1,
26 }
27 }
28}
29
30impl NetConfig {
31 #[must_use]
40 pub fn random_mac() -> [u8; 6] {
41 let mut mac = [0u8; 6];
42 mac[0] = 0x52;
43 mac[1] = 0x54;
44 mac[2] = 0xAB;
45 let mut suffix = [0u8; 3];
46 if getrandom::getrandom(&mut suffix).is_err() {
47 static COUNTER: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);
51 let n = COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
52 let pid = std::process::id();
53 let mixed = pid ^ n ^ 0x9E37_79B9;
54 suffix[0] = (mixed >> 16) as u8;
55 suffix[1] = (mixed >> 8) as u8;
56 suffix[2] = mixed as u8;
57 }
58 mac[3..6].copy_from_slice(&suffix);
59 mac
60 }
61}
62
63#[repr(u16)]
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub enum NetStatus {
67 LinkUp = 1,
69 Announce = 2,
71}
72
73#[derive(Debug)]
83pub struct NetPort {
84 pub host_fd: RawFd,
87 pub last_avail_tx: AtomicU16,
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_net_config_default() {
98 let config = NetConfig::default();
99 assert_eq!(config.mac, [0x52, 0x54, 0x00, 0x12, 0x34, 0x56]);
100 assert_eq!(config.mtu, 1500);
101 assert!(config.tap_name.is_none());
102 assert_eq!(config.num_queues, 1);
103 }
104
105 #[test]
106 fn test_net_config_custom() {
107 let config = NetConfig {
108 mac: [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
109 mtu: 9000, tap_name: Some("tap0".to_string()),
111 num_queues: 4,
112 };
113 assert_eq!(config.mac[0], 0x00);
114 assert_eq!(config.mtu, 9000);
115 assert_eq!(config.tap_name.as_deref(), Some("tap0"));
116 assert_eq!(config.num_queues, 4);
117 }
118
119 #[test]
120 fn test_random_mac() {
121 let mac1 = NetConfig::random_mac();
122 let mac2 = NetConfig::random_mac();
123
124 assert_eq!(mac1[0], 0x52);
125 assert_eq!(mac1[1], 0x54);
126 assert_eq!(mac1[2], 0xAB);
127
128 assert_eq!(mac2[0], 0x52);
129 assert_eq!(mac2[1], 0x54);
130 assert_eq!(mac2[2], 0xAB);
131 }
132
133 #[test]
134 fn test_net_status_values() {
135 assert_eq!(NetStatus::LinkUp as u16, 1);
136 assert_eq!(NetStatus::Announce as u16, 2);
137 }
138
139 #[test]
140 fn test_config_clone() {
141 let config = NetConfig {
142 mac: [1, 2, 3, 4, 5, 6],
143 mtu: 1234,
144 tap_name: Some("test".to_string()),
145 num_queues: 2,
146 };
147
148 let cloned = config.clone();
149 assert_eq!(cloned.mac, config.mac);
150 assert_eq!(cloned.mtu, config.mtu);
151 assert_eq!(cloned.tap_name, config.tap_name);
152 assert_eq!(cloned.num_queues, config.num_queues);
153 }
154}