Skip to main content

netlink_sys/
mio.rs

1// SPDX-License-Identifier: MIT
2
3use crate::Socket;
4use std::os::unix::io::AsRawFd;
5
6use mio::{event::Source, unix::SourceFd};
7
8impl Source for Socket {
9    fn register(
10        &mut self,
11        registry: &mio::Registry,
12        token: mio::Token,
13        interests: mio::Interest,
14    ) -> std::io::Result<()> {
15        let raw_fd = self.as_raw_fd();
16
17        SourceFd(&raw_fd).register(registry, token, interests)
18    }
19
20    fn reregister(
21        &mut self,
22        registry: &mio::Registry,
23        token: mio::Token,
24        interests: mio::Interest,
25    ) -> std::io::Result<()> {
26        let raw_fd = self.as_raw_fd();
27
28        SourceFd(&raw_fd).reregister(registry, token, interests)
29    }
30
31    fn deregister(&mut self, registry: &mio::Registry) -> std::io::Result<()> {
32        let raw_fd = self.as_raw_fd();
33
34        SourceFd(&raw_fd).deregister(registry)
35    }
36}
37
38#[cfg(target_endian = "little")]
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    fn request_neighbour_dump(socket: &mut Socket) -> std::io::Result<()> {
44        // Buffer generated from:
45        // ```
46        // let mut neighbour_dump_request = NetlinkMessage {
47        //     header: NetlinkHeader {
48        //         flags: NLM_F_DUMP | NLM_F_REQUEST,
49        //         ..Default::default()
50        //     },
51        //     payload: NetlinkPayload::from(RtnlMessage::GetNeighbour(NeighbourMessage::default())),
52        // };
53        // ```
54        let buf = [
55            28, 0, 0, 0, 30, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56            0, 0, 0, 0, 0, 0,
57        ];
58        socket.send(&buf[..], 0)?;
59
60        Ok(())
61    }
62
63    #[test]
64    fn test_event_loop() -> Result<(), Box<dyn std::error::Error>> {
65        use crate::{protocols::NETLINK_ROUTE, Socket, SocketAddr};
66        use mio::{Events, Interest, Poll, Token};
67        use std::time::Duration;
68
69        let mut poll = Poll::new()?;
70        let mut events = Events::with_capacity(128);
71
72        let mut socket = Socket::new(NETLINK_ROUTE)?;
73        socket.bind_auto()?;
74        socket.connect(&SocketAddr::new(0, 0))?;
75        poll.registry()
76            .register(&mut socket, Token(1), Interest::READABLE)?;
77
78        // Send neighbour query
79        request_neighbour_dump(&mut socket)?;
80
81        // Make sure that we got anything
82        poll.poll(&mut events, Some(Duration::from_secs(1)))?;
83        assert!(!events.is_empty());
84
85        // Make sure the we didn't get a thing after removing socket from loop
86        poll.registry().deregister(&mut socket)?;
87        poll.poll(&mut events, Some(Duration::from_secs(1)))?;
88        assert!(events.is_empty());
89
90        Ok(())
91    }
92}