1use std::io;
4
5use futures_channel::mpsc::UnboundedReceiver;
6use netlink_packet_core::NetlinkMessage;
7use netlink_packet_route::RouteNetlinkMessage;
8use netlink_proto::Connection;
9use netlink_sys::{protocols::NETLINK_ROUTE, AsyncSocket, SocketAddr};
10
11use crate::{Handle, MulticastGroup};
12
13#[cfg(feature = "tokio_socket")]
14#[allow(clippy::type_complexity)]
15pub fn new_connection() -> io::Result<(
16 Connection<RouteNetlinkMessage>,
17 Handle,
18 UnboundedReceiver<(NetlinkMessage<RouteNetlinkMessage>, SocketAddr)>,
19)> {
20 new_connection_with_socket()
21}
22
23#[cfg(feature = "tokio_socket")]
25#[allow(clippy::type_complexity)]
26pub fn new_multicast_connection(
27 groups: &[MulticastGroup],
28) -> io::Result<(
29 Connection<RouteNetlinkMessage>,
30 Handle,
31 UnboundedReceiver<(NetlinkMessage<RouteNetlinkMessage>, SocketAddr)>,
32)> {
33 new_multicast_connection_with_socket(groups)
34}
35
36#[allow(clippy::type_complexity)]
37pub fn new_connection_with_socket<S>() -> io::Result<(
38 Connection<RouteNetlinkMessage, S>,
39 Handle,
40 UnboundedReceiver<(NetlinkMessage<RouteNetlinkMessage>, SocketAddr)>,
41)>
42where
43 S: AsyncSocket,
44{
45 let (conn, handle, messages) =
46 netlink_proto::new_connection_with_socket(NETLINK_ROUTE)?;
47 Ok((conn, Handle::new(handle), messages))
48}
49
50#[allow(clippy::type_complexity)]
52pub fn new_multicast_connection_with_socket<S>(
53 groups: &[MulticastGroup],
54) -> io::Result<(
55 Connection<RouteNetlinkMessage, S>,
56 Handle,
57 UnboundedReceiver<(NetlinkMessage<RouteNetlinkMessage>, SocketAddr)>,
58)>
59where
60 S: AsyncSocket,
61{
62 let (mut conn, handle, messages) =
63 netlink_proto::new_connection_with_socket::<RouteNetlinkMessage, S>(
64 NETLINK_ROUTE,
65 )?;
66 let mut all_groups: u32 = 0;
67 for group in groups.iter().filter(|g| !g.need_via_add_membership()) {
68 all_groups |= 1 << (*group as u32 - 1);
69 }
70
71 let addr = SocketAddr::new(0, all_groups);
72 conn.socket_mut().socket_mut().bind(&addr)?;
73
74 for group in groups.iter().filter(|g| g.need_via_add_membership()) {
75 conn.socket_mut()
76 .socket_mut()
77 .add_membership(*group as u32)?;
78 }
79
80 Ok((conn, Handle::new(handle), messages))
81}
82
83#[allow(clippy::type_complexity)]
84pub fn from_socket<S>(
85 socket: S,
86) -> (
87 Connection<RouteNetlinkMessage, S>,
88 Handle,
89 UnboundedReceiver<(NetlinkMessage<RouteNetlinkMessage>, SocketAddr)>,
90)
91where
92 S: AsyncSocket,
93{
94 let (conn, handle, messages) =
95 netlink_proto::from_socket_with_codec(socket);
96 (conn, Handle::new(handle), messages)
97}