tunio/platform/linux/
interface.rs1use super::queue::{create_device, Device};
2use super::Driver;
3use super::PlatformIfConfig;
4use crate::config::IfConfig;
5use crate::platform::util::{sync::Queue, QueueFdT};
6use crate::traits::{InterfaceT, SyncQueueT};
7use crate::Error;
8use delegate::delegate;
9use io_lifetimes::IntoFd;
10use log::debug;
11use netconfig::sys::InterfaceHandleExt;
12use std::io;
13use std::io::{Read, Write};
14
15pub struct LinuxInterface<Q> {
16 name: String,
17 pub(crate) queue: Q,
18}
19
20impl<Q> LinuxInterface<Q> {
21 pub fn name(&self) -> &str {
22 &*self.name
23 }
24}
25
26impl<Q: QueueFdT> InterfaceT for LinuxInterface<Q> {
27 type PlatformDriver = Driver;
28 type PlatformIfConfig = PlatformIfConfig;
29
30 fn new(
31 _driver: &mut Self::PlatformDriver,
32 params: IfConfig<Self::PlatformIfConfig>,
33 ) -> Result<Self, Error> {
34 let Device { device, name } = create_device(&*params.name, params.layer)?;
35 let queue = Q::new(device.into_fd());
36
37 if &*params.name != name {
38 debug!(
39 "Interface name is changed \"{}\" -> \"{}\"",
40 &*params.name, name
41 );
42 }
43
44 Ok(Self { name, queue })
45 }
46
47 fn up(&mut self) -> Result<(), Error> {
48 Ok(self.handle().set_up(true)?)
49 }
50
51 fn down(&mut self) -> Result<(), Error> {
52 Ok(self.handle().set_up(false)?)
53 }
54
55 fn handle(&self) -> netconfig::InterfaceHandle {
56 netconfig::InterfaceHandle::try_from_name(self.name()).unwrap()
57 }
58}
59
60pub type Interface = LinuxInterface<Queue>;
61
62impl SyncQueueT for Interface {}
63
64impl Read for Interface {
65 delegate! {
66 to self.queue {
67 fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error>;
68 }
69 }
70}
71
72impl Write for Interface {
73 delegate! {
74 to self.queue {
75 fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
76 fn flush(&mut self) -> io::Result<()>;
77 }
78 }
79}