bridge.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. use crate::{
  2. driver::net::{
  3. napi::napi_schedule, register_netdevice, veth::VethInterface, Iface, NetDeivceState,
  4. Operstate,
  5. },
  6. init::initcall::INITCALL_DEVICE,
  7. libs::{rwlock::RwLock, spinlock::SpinLock},
  8. process::namespace::net_namespace::{NetNamespace, INIT_NET_NAMESPACE},
  9. time::Instant,
  10. };
  11. use alloc::string::ToString;
  12. use alloc::sync::Weak;
  13. use alloc::{collections::BTreeMap, string::String, sync::Arc};
  14. use core::sync::atomic::AtomicUsize;
  15. use hashbrown::HashMap;
  16. use smoltcp::wire::{EthernetAddress, EthernetFrame, IpAddress, IpCidr};
  17. use system_error::SystemError;
  18. use unified_init::macros::unified_init;
  19. /// MAC地址表老化时间
  20. const MAC_ENTRY_TIMEOUT: u64 = 300_000; // 5分钟
  21. pub type BridgePortId = usize;
  22. #[derive(Debug)]
  23. struct MacEntry {
  24. port_id: BridgePortId,
  25. pub(self) record: RwLock<MacEntryRecord>,
  26. // 存活时间(动态学习的老化)
  27. }
  28. impl MacEntry {
  29. pub fn new(port: BridgePortId) -> Self {
  30. MacEntry {
  31. port_id: port,
  32. record: RwLock::new(MacEntryRecord {
  33. last_seen: Instant::now(),
  34. }),
  35. }
  36. }
  37. /// 更新最后一次被看到的时间为现在
  38. pub(self) fn update_last_seen(&self) {
  39. self.record.write_irqsave().last_seen = Instant::now();
  40. }
  41. }
  42. #[derive(Debug)]
  43. struct MacEntryRecord {
  44. last_seen: Instant,
  45. }
  46. /// 代表一个加入bridge的网络接口
  47. #[derive(Debug, Clone)]
  48. pub struct BridgePort {
  49. pub id: BridgePortId,
  50. pub(super) bridge_enable: Arc<dyn BridgeEnableDevice>,
  51. pub(super) bridge_driver_ref: Weak<BridgeDriver>,
  52. // 当前接口状态?forwarding, learning, blocking?
  53. // mac mtu信息
  54. }
  55. impl BridgePort {
  56. fn new(
  57. id: BridgePortId,
  58. device: Arc<dyn BridgeEnableDevice>,
  59. bridge: &Arc<BridgeDriver>,
  60. ) -> Self {
  61. let port = BridgePort {
  62. id,
  63. bridge_enable: device.clone(),
  64. bridge_driver_ref: Arc::downgrade(bridge),
  65. };
  66. device.set_common_bridge_data(&port);
  67. port
  68. }
  69. }
  70. #[derive(Debug)]
  71. pub struct Bridge {
  72. name: String,
  73. // 端口列表,key为MAC地址
  74. ports: BTreeMap<BridgePortId, BridgePort>,
  75. // FDB(Forwarding Database)
  76. mac_table: HashMap<EthernetAddress, MacEntry>,
  77. // 配置参数,比如aging timeout, max age, hello time, forward delay
  78. // bridge_mac: EthernetAddress,
  79. }
  80. impl Bridge {
  81. pub fn new(name: &str) -> Self {
  82. Self {
  83. name: name.into(),
  84. ports: BTreeMap::new(),
  85. mac_table: HashMap::new(),
  86. }
  87. }
  88. pub fn add_port(&mut self, id: BridgePortId, port: BridgePort) {
  89. self.ports.insert(id, port);
  90. }
  91. pub fn remove_port(&mut self, port_id: BridgePortId) {
  92. self.ports.remove(&port_id);
  93. // 清理MAC地址表中与该端口相关的条目
  94. self.mac_table
  95. .retain(|_mac, entry| entry.port_id != port_id);
  96. }
  97. fn insert_or_update_mac_entry(&mut self, src_mac: EthernetAddress, port_id: BridgePortId) {
  98. if let Some(entry) = self.mac_table.get(&src_mac) {
  99. entry.update_last_seen();
  100. // 如果 MAC 地址学习到了不同的端口,需要更新
  101. if entry.port_id != port_id {
  102. // log::info!("Bridge {}: MAC {} moved from port {} to port {}", self.name, src_mac, entry.port_id, port_id);
  103. self.mac_table.insert(src_mac, MacEntry::new(port_id));
  104. }
  105. } else {
  106. // log::info!("Bridge {}: Learned MAC {} on port {}", self.name, src_mac, port_id);
  107. self.mac_table.insert(src_mac, MacEntry::new(port_id));
  108. }
  109. }
  110. pub fn handle_frame(&mut self, ingress_port_id: BridgePortId, frame: &[u8]) {
  111. if frame.len() < 14 {
  112. // 使用 smoltcp 提供的最小长度
  113. // log::warn!("Bridge {}: Received malformed Ethernet frame (too short).", self.name);
  114. return;
  115. }
  116. let ether_frame = match EthernetFrame::new_checked(frame) {
  117. Ok(f) => f,
  118. Err(_) => {
  119. // log::warn!("Bridge {}: Received malformed Ethernet frame.", self.name);
  120. return;
  121. }
  122. };
  123. let dst_mac = ether_frame.dst_addr();
  124. let src_mac = ether_frame.src_addr();
  125. self.insert_or_update_mac_entry(src_mac, ingress_port_id);
  126. if dst_mac.is_broadcast() {
  127. // 广播 这里有可能是arp请求
  128. self.flood(Some(ingress_port_id), frame);
  129. } else {
  130. // 单播
  131. if let Some(entry) = self.mac_table.get(&dst_mac) {
  132. let target_port = entry.port_id;
  133. // 避免发回自己
  134. // if target_port != ingress_port_id {
  135. self.transmit_to_port(target_port, frame);
  136. // }
  137. } else {
  138. // 未知单播 → 广播
  139. log::info!("unknown unicast, flooding frame");
  140. self.flood(Some(ingress_port_id), frame);
  141. }
  142. }
  143. self.sweep_mac_table();
  144. }
  145. fn flood(&self, except_port_id: Option<BridgePortId>, frame: &[u8]) {
  146. match except_port_id {
  147. Some(except_id) => {
  148. for (&port_id, bridge_port) in &self.ports {
  149. if port_id != except_id {
  150. self.transmit_to_device(bridge_port, frame);
  151. }
  152. }
  153. }
  154. None => {
  155. for bridge_port in self.ports.values() {
  156. self.transmit_to_device(bridge_port, frame);
  157. }
  158. }
  159. }
  160. }
  161. fn transmit_to_port(&self, target_port_id: BridgePortId, frame: &[u8]) {
  162. if let Some(device_arc) = self.ports.get(&target_port_id) {
  163. self.transmit_to_device(device_arc, frame);
  164. } else {
  165. // log::warn!("Bridge {}: Attempted to transmit to non-existent port ID {}", self.name, target_port_id);
  166. }
  167. }
  168. fn transmit_to_device(&self, device: &BridgePort, frame: &[u8]) {
  169. device.bridge_enable.receive_from_bridge(frame);
  170. if let Some(napi) = device.bridge_enable.napi_struct() {
  171. napi_schedule(napi);
  172. }
  173. }
  174. pub fn sweep_mac_table(&mut self) {
  175. let now = Instant::now();
  176. self.mac_table.retain(|_mac, entry| {
  177. now.duration_since(entry.record.read().last_seen)
  178. .unwrap_or_default()
  179. .total_millis()
  180. < MAC_ENTRY_TIMEOUT
  181. });
  182. }
  183. pub fn name(&self) -> &str {
  184. &self.name
  185. }
  186. }
  187. #[derive(Debug)]
  188. pub struct BridgeDriver {
  189. pub inner: SpinLock<Bridge>,
  190. pub netns: RwLock<Weak<NetNamespace>>,
  191. self_ref: Weak<BridgeDriver>,
  192. next_port_id: AtomicUsize,
  193. }
  194. impl BridgeDriver {
  195. pub fn new(name: &str) -> Arc<Self> {
  196. Arc::new_cyclic(|self_ref| BridgeDriver {
  197. inner: SpinLock::new(Bridge::new(name)),
  198. netns: RwLock::new(Weak::new()),
  199. self_ref: self_ref.clone(),
  200. next_port_id: AtomicUsize::new(0),
  201. })
  202. }
  203. fn next_port_id(&self) -> BridgePortId {
  204. self.next_port_id
  205. .fetch_add(1, core::sync::atomic::Ordering::Relaxed)
  206. }
  207. pub fn add_device(&self, device: Arc<dyn BridgeEnableDevice>) {
  208. if let Some(netns) = self.netns() {
  209. if !Arc::ptr_eq(
  210. &netns,
  211. &device.net_namespace().unwrap_or(INIT_NET_NAMESPACE.clone()),
  212. ) {
  213. log::warn!("Port and bridge are in different net namespaces");
  214. return;
  215. }
  216. }
  217. let port = BridgePort::new(
  218. self.next_port_id(),
  219. device.clone(),
  220. &self.self_ref.upgrade().unwrap(),
  221. );
  222. log::info!("Adding port with id: {}", port.id);
  223. self.inner.lock().add_port(port.id, port);
  224. }
  225. pub fn remove_device(&self, device: Arc<dyn BridgeEnableDevice>) {
  226. let Some(common_data) = device.common_bridge_data() else {
  227. log::warn!("Device is not part of any bridge");
  228. return;
  229. };
  230. self.inner.lock().remove_port(common_data.id);
  231. }
  232. pub fn handle_frame(&self, ingress_port_id: BridgePortId, frame: &[u8]) {
  233. self.inner.lock().handle_frame(ingress_port_id, frame);
  234. }
  235. pub fn name(&self) -> String {
  236. self.inner.lock().name().to_string()
  237. }
  238. pub fn set_netns(&self, netns: &Arc<NetNamespace>) {
  239. *self.netns.write() = Arc::downgrade(netns);
  240. }
  241. pub fn netns(&self) -> Option<Arc<NetNamespace>> {
  242. self.netns.read().upgrade()
  243. }
  244. }
  245. /// 可供桥接设备应该实现的 trait
  246. pub trait BridgeEnableDevice: Iface {
  247. /// 接收来自桥的数据帧
  248. fn receive_from_bridge(&self, frame: &[u8]);
  249. /// 设置桥接相关的公共数据
  250. fn set_common_bridge_data(&self, _port: &BridgePort);
  251. /// 获取桥接相关的公共数据
  252. fn common_bridge_data(&self) -> Option<BridgeCommonData>;
  253. // fn bridge(&self) -> Weak<BridgeIface> {
  254. // let Some(data) = self.common_bridge_data() else {
  255. // return Weak::default();
  256. // };
  257. // data.bridge_driver
  258. // }
  259. }
  260. #[derive(Debug, Clone)]
  261. pub struct BridgeCommonData {
  262. pub id: BridgePortId,
  263. pub bridge_driver_ref: Weak<BridgeDriver>,
  264. }
  265. fn bridge_probe() {
  266. let (iface1, iface2) = VethInterface::new_pair("veth_a", "veth_b");
  267. let (iface3, iface4) = VethInterface::new_pair("veth_c", "veth_d");
  268. let addr1 = IpAddress::v4(200, 0, 0, 1);
  269. let cidr1 = IpCidr::new(addr1, 24);
  270. let addr2 = IpAddress::v4(200, 0, 0, 2);
  271. let cidr2 = IpCidr::new(addr2, 24);
  272. let addr3 = IpAddress::v4(200, 0, 0, 3);
  273. let cidr3 = IpCidr::new(addr3, 24);
  274. let addr4 = IpAddress::v4(200, 0, 0, 4);
  275. let cidr4 = IpCidr::new(addr4, 24);
  276. iface1.update_ip_addrs(cidr1);
  277. iface2.update_ip_addrs(cidr2);
  278. iface3.update_ip_addrs(cidr3);
  279. iface4.update_ip_addrs(cidr4);
  280. iface1.add_default_route_to_peer(addr2);
  281. iface2.add_default_route_to_peer(addr1);
  282. iface3.add_default_route_to_peer(addr4);
  283. iface4.add_default_route_to_peer(addr3);
  284. // iface1.add_direct_route(cidr4, addr2);
  285. let turn_on = |a: &Arc<VethInterface>| {
  286. a.set_net_state(NetDeivceState::__LINK_STATE_START);
  287. a.set_operstate(Operstate::IF_OPER_UP);
  288. // NET_DEVICES.write_irqsave().insert(a.nic_id(), a.clone());
  289. INIT_NET_NAMESPACE.add_device(a.clone());
  290. a.common().set_net_namespace(INIT_NET_NAMESPACE.clone());
  291. register_netdevice(a.clone()).expect("register veth device failed");
  292. };
  293. turn_on(&iface1);
  294. turn_on(&iface2);
  295. turn_on(&iface3);
  296. turn_on(&iface4);
  297. let bridge = BridgeDriver::new("bridge0");
  298. bridge.set_netns(&INIT_NET_NAMESPACE);
  299. INIT_NET_NAMESPACE.insert_bridge(bridge.clone());
  300. bridge.add_device(iface3);
  301. bridge.add_device(iface2);
  302. log::info!("Bridge device created");
  303. }
  304. #[unified_init(INITCALL_DEVICE)]
  305. pub fn bridge_init() -> Result<(), SystemError> {
  306. bridge_probe();
  307. // log::info!("bridge initialized.");
  308. Ok(())
  309. }