netlink/protocol_family/
sock_diag.rs1mod eventloop;
8mod request;
9
10pub(crate) use eventloop::SockDiagEventLoop;
11pub(crate) use request::NetlinkSockDiagRequestHandler;
12
13use std::convert::Infallible as Never;
14use std::num::NonZeroU32;
15
16use linux_uapi::{
17 sknetlink_groups_SKNLGRP_INET_TCP_DESTROY, sknetlink_groups_SKNLGRP_INET_UDP_DESTROY,
18 sknetlink_groups_SKNLGRP_INET6_TCP_DESTROY, sknetlink_groups_SKNLGRP_INET6_UDP_DESTROY,
19 sknetlink_groups_SKNLGRP_NONE,
20};
21use netlink_packet_sock_diag::{SockDiagRequest, SockDiagResponse};
22
23use crate::client::{AsyncWorkCompletionWaiter, ExternalClient};
24use crate::messaging::{MessageWithPermission, Sender};
25use crate::multicast_groups::{
26 GroupSupport, InvalidLegacyGroupsError, InvalidModernGroupError, LegacyGroups, ModernGroup,
27 MulticastCapableNetlinkFamily,
28};
29use crate::protocol_family::{NamedNetlinkFamily, NetlinkClient, ProtocolFamily};
30
31pub(crate) struct NetlinkSockDiag;
33
34impl MulticastCapableNetlinkFamily for NetlinkSockDiag {
35 #[allow(non_upper_case_globals)]
36 fn check_support(
37 ModernGroup(group): &ModernGroup,
38 ) -> Result<GroupSupport, InvalidModernGroupError> {
39 match *group {
40 sknetlink_groups_SKNLGRP_INET_TCP_DESTROY
41 | sknetlink_groups_SKNLGRP_INET_UDP_DESTROY
42 | sknetlink_groups_SKNLGRP_INET6_TCP_DESTROY
43 | sknetlink_groups_SKNLGRP_INET6_UDP_DESTROY
44 | sknetlink_groups_SKNLGRP_NONE => Ok(GroupSupport::Unsupported),
45 _ => Err(InvalidModernGroupError),
46 }
47 }
48}
49
50#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
51#[allow(dead_code)]
54pub(crate) enum NetlinkSockDiagNotifiedGroup {
55 TcpV4Destroy,
56 TcpV6Destroy,
57 UdpV4Destroy,
58 UdpV6Destroy,
59}
60
61impl MessageWithPermission for SockDiagRequest {
62 fn permission(&self) -> crate::messaging::Permission {
63 match self {
64 SockDiagRequest::InetRequest(_) | SockDiagRequest::UnixRequest(_) => {
65 crate::messaging::Permission::NetlinkSockDiagRead
66 }
67 SockDiagRequest::InetSockDestroy(_) => {
68 crate::messaging::Permission::NetlinkSockDiagDestroy
69 }
70 }
71 }
72}
73
74pub struct NetlinkSockDiagClient(pub(crate) ExternalClient<NetlinkSockDiag>);
76
77impl NetlinkClient for NetlinkSockDiagClient {
78 type Request = SockDiagRequest;
79
80 fn set_pid(&self, pid: NonZeroU32) {
81 let NetlinkSockDiagClient(client) = self;
82 client.set_port_number(pid)
83 }
84
85 fn add_membership(
86 &self,
87 group: ModernGroup,
88 ) -> Result<AsyncWorkCompletionWaiter, InvalidModernGroupError> {
89 let NetlinkSockDiagClient(client) = self;
90 client.add_membership(group)
91 }
92
93 fn del_membership(&self, group: ModernGroup) -> Result<(), InvalidModernGroupError> {
94 let NetlinkSockDiagClient(client) = self;
95 client.del_membership(group)
96 }
97
98 fn set_legacy_memberships(
99 &self,
100 legacy_memberships: LegacyGroups,
101 ) -> Result<AsyncWorkCompletionWaiter, InvalidLegacyGroupsError> {
102 let NetlinkSockDiagClient(client) = self;
103 client.set_legacy_memberships(legacy_memberships)
104 }
105}
106
107impl NamedNetlinkFamily for NetlinkSockDiag {
108 const NAME: &'static str = "NETLINK_SOCK_DIAG";
109}
110
111impl ProtocolFamily for NetlinkSockDiag {
112 type Request = SockDiagRequest;
113 type Response = SockDiagResponse;
114 type RequestHandler<S: Sender<Self::Response>> = NetlinkSockDiagRequestHandler<S>;
115 type NotifiedMulticastGroup = NetlinkSockDiagNotifiedGroup;
116 type AsyncWorkItem = Never;
117
118 fn should_notify_on_group_membership_change(
119 _group: ModernGroup,
120 ) -> Option<Self::NotifiedMulticastGroup> {
121 None
125 }
126}
127
128#[cfg(test)]
129mod testutil {
130 use net_declare::{std_ip_v4, std_ip_v6};
131 use net_types::ip::{Ip, Ipv4, Ipv4Addr, Ipv6, Ipv6Addr};
132
133 pub(crate) trait TestIpExt: Ip {
134 const SRC_ADDR: Self::Addr;
135 const DST_ADDR: Self::Addr;
136 const LINUX_FAMILY: u8;
137 }
138
139 impl TestIpExt for Ipv4 {
140 const SRC_ADDR: Ipv4Addr = Ipv4Addr::new(std_ip_v4!("192.168.0.1").octets());
141 const DST_ADDR: Ipv4Addr = Ipv4Addr::new(std_ip_v4!("192.168.0.2").octets());
142 const LINUX_FAMILY: u8 = linux_uapi::AF_INET as u8;
143 }
144
145 impl TestIpExt for Ipv6 {
146 const SRC_ADDR: Ipv6Addr = Ipv6Addr::new(std_ip_v6!("2001:db8::1").segments());
147 const DST_ADDR: Ipv6Addr = Ipv6Addr::new(std_ip_v6!("2001:db8::2").segments());
148 const LINUX_FAMILY: u8 = linux_uapi::AF_INET6 as u8;
149 }
150}