Skip to main content

libcontainer/network/
wrapper.rs

1use netlink_packet_core::NetlinkMessage;
2use netlink_packet_route::RouteNetlinkMessage;
3
4use super::client::NetlinkClient;
5use super::fake::FakeNetlinkClient;
6use super::traits::{Client, NetlinkMessageHandler};
7use super::{NetworkError, Result};
8
9/// Enum wrapper for different client types
10/// The `Client` trait contains generic methods, which makes it impossible to use as a trait object.
11/// Therefore, we define `ClientWrapper` as an enum-based dynamic dispatch to handle this.
12pub enum ClientWrapper {
13    /// Real NetlinkClient instance for production use
14    Client(NetlinkClient),
15    /// Error state when NetlinkClient initialization failed
16    ErrorState,
17    /// Fake client for testing purposes
18    Fake(FakeNetlinkClient),
19}
20
21impl Client for ClientWrapper {
22    fn send(&mut self, req: &NetlinkMessage<RouteNetlinkMessage>) -> Result<()> {
23        match self {
24            ClientWrapper::Client(client) => client.send(req),
25            ClientWrapper::ErrorState => Err(NetworkError::ClientInitializeError),
26            ClientWrapper::Fake(client) => client.send(req),
27        }
28    }
29
30    fn receive<T, H>(&mut self, handler: H) -> Result<T>
31    where
32        H: NetlinkMessageHandler<Response = T>,
33    {
34        match self {
35            ClientWrapper::Client(client) => client.receive(handler),
36            ClientWrapper::ErrorState => Err(NetworkError::ClientInitializeError),
37            ClientWrapper::Fake(client) => client.receive(handler),
38        }
39    }
40
41    fn receive_multiple<T, H>(&mut self, handler: H) -> Result<Vec<T>>
42    where
43        H: NetlinkMessageHandler<Response = T>,
44    {
45        match self {
46            ClientWrapper::Client(client) => client.receive_multiple(handler),
47            ClientWrapper::ErrorState => Err(NetworkError::ClientInitializeError),
48            ClientWrapper::Fake(client) => client.receive_multiple(handler),
49        }
50    }
51
52    fn send_and_receive<T, H>(
53        &mut self,
54        req: &NetlinkMessage<RouteNetlinkMessage>,
55        handler: H,
56    ) -> Result<T>
57    where
58        H: NetlinkMessageHandler<Response = T>,
59    {
60        match self {
61            ClientWrapper::Client(client) => client.send_and_receive(req, handler),
62            ClientWrapper::ErrorState => Err(NetworkError::ClientInitializeError),
63            ClientWrapper::Fake(client) => client.send_and_receive(req, handler),
64        }
65    }
66
67    fn send_and_receive_multiple<T, H>(
68        &mut self,
69        req: &NetlinkMessage<RouteNetlinkMessage>,
70        handler: H,
71    ) -> Result<Vec<T>>
72    where
73        H: NetlinkMessageHandler<Response = T>,
74    {
75        match self {
76            ClientWrapper::Client(client) => client.send_and_receive_multiple(req, handler),
77            ClientWrapper::ErrorState => Err(NetworkError::ClientInitializeError),
78            ClientWrapper::Fake(client) => client.send_and_receive_multiple(req, handler),
79        }
80    }
81}
82
83impl Default for ClientWrapper {
84    fn default() -> Self {
85        if cfg!(test) {
86            ClientWrapper::Fake(FakeNetlinkClient::new())
87        } else {
88            // If NetlinkClient initialization fails, we store the error state
89            // instead of panicking. The error will be returned when the client is used.
90            match NetlinkClient::new() {
91                Ok(client) => ClientWrapper::Client(client),
92                Err(_) => ClientWrapper::ErrorState,
93            }
94        }
95    }
96}
97
98pub fn create_network_client() -> ClientWrapper {
99    ClientWrapper::default()
100}