ftth_rtnl/
lib.rs

1pub mod address;
2pub mod link;
3pub mod neighbor;
4pub mod route;
5pub mod virtual_interface;
6
7use std::any::Any;
8use std::sync::{Arc, Mutex};
9
10pub use ipnet::{IpNet, Ipv4Net, Ipv6Net};
11pub use neighbor::{NeighborDelete, NeighborEntry};
12pub use netlink_packet_route::address::AddressScope;
13pub use netlink_packet_route::neighbour::{NeighbourFlags, NeighbourState};
14pub use netlink_packet_route::route::RouteNextHopFlags;
15pub use route::{Ipv4Route, Ipv6Route, RouteNextHopInfo};
16pub use virtual_interface::{
17    Gre6Config, GreConfig, Ip6TnlConfig, IpIpConfig, VirtualInterfaceDelete, VirtualInterfaceKind,
18    VirtualInterfaceSpec, VirtualInterfaceUpdate, VlanConfig,
19};
20
21use ftth_common::channel::create_pair;
22
23use futures::{FutureExt, future::join_all};
24
25#[derive(Debug, Clone)]
26pub struct RtnlClient {
27    address: address::RtnlAddressClient,
28    link: link::RtnlLinkClient,
29    neighbor: neighbor::RtnlNeighborClient,
30    route: route::RtnlRouteClient,
31    virtual_interface: virtual_interface::RtnlVirtualInterfaceClient,
32    
33    #[allow(dead_code)]
34    receiver: Arc<Mutex<Option<Box<dyn Any + Send>>>>,
35}
36
37impl RtnlClient {
38    pub fn new() -> Self {
39        let (address_tx, address_rx) = create_pair();
40        let (link_tx, link_rx) = create_pair();
41        let (neighbor_tx, neighbor_rx) = create_pair();
42        let (route_tx, route_rx) = create_pair();
43        let (virtual_interface_tx, virtual_interface_rx) = create_pair();
44
45        let receiver_container = Arc::new(Mutex::new(None));
46        let receiver_container_clone = receiver_container.clone();
47
48        std::thread::spawn(move || {
49            let rt = match tokio::runtime::Builder::new_multi_thread()
50                .enable_all()
51                .build()
52            {
53                Ok(rt) => rt,
54                Err(e) => {
55                    log::error!("Tokio runtime building error: {}", e);
56                    return;
57                }
58            };
59
60            let _ = rt.block_on(async {
61                let (connection, handle, receiver) = rtnetlink::new_connection()?;
62
63                {
64                    *(receiver_container_clone.lock().map_err(|_e| std::io::Error::other("Poison error"))?) = Some(Box::new(receiver) as Box<dyn Any + Send>);
65                }
66                
67                tokio::spawn(connection);
68
69                let mut futures = Vec::new();
70                futures.push(address::run_server(address_rx, handle.address()).boxed());
71                futures.push(link::run_server(link_rx, handle.link()).boxed());
72                futures.push(neighbor::run_server(neighbor_rx, handle.neighbours()).boxed());
73                futures.push(route::run_server(route_rx, handle.route()).boxed());
74                futures.push(
75                    virtual_interface::run_server(virtual_interface_rx, handle.link()).boxed(),
76                );
77
78                join_all(futures).await;
79
80                Ok::<(), std::io::Error>(())
81            });
82        });
83
84        Self {
85            address: address::RtnlAddressClient::new(address_tx),
86            link: link::RtnlLinkClient::new(link_tx),
87            neighbor: neighbor::RtnlNeighborClient::new(neighbor_tx),
88            route: route::RtnlRouteClient::new(route_tx),
89            virtual_interface: virtual_interface::RtnlVirtualInterfaceClient::new(
90                virtual_interface_tx,
91            ),
92            receiver: receiver_container,
93        }
94    }
95
96    pub fn address(&self) -> address::RtnlAddressClient {
97        self.address.clone()
98    }
99
100    pub fn link(&self) -> link::RtnlLinkClient {
101        self.link.clone()
102    }
103
104    pub fn neighbor(&self) -> neighbor::RtnlNeighborClient {
105        self.neighbor.clone()
106    }
107
108    pub fn route(&self) -> route::RtnlRouteClient {
109        self.route.clone()
110    }
111
112    pub fn virtual_interface(&self) -> virtual_interface::RtnlVirtualInterfaceClient {
113        self.virtual_interface.clone()
114    }
115}