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}