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