ftth_rtnl/
lib.rs

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