Skip to main content

starnix_core/vfs/socket/socket_generic_netlink/
mod.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use async_trait::async_trait;
6use futures::FutureExt;
7use futures::channel::mpsc;
8use futures::future::join;
9use futures::stream::{FuturesUnordered, StreamExt};
10use linux_uapi::{NLM_F_ACK, NLM_F_CAPPED};
11use netlink::NETLINK_LOG_TAG;
12use netlink::messaging::Sender;
13use netlink::multicast_groups::ModernGroup;
14use netlink_packet_core::{
15    ErrorMessage, NETLINK_HEADER_LEN, NetlinkHeader, NetlinkMessage, NetlinkPayload,
16};
17use netlink_packet_generic::constants::GENL_ID_CTRL;
18use netlink_packet_generic::ctrl::nlas::{GenlCtrlAttrs, McastGrpAttrs};
19use netlink_packet_generic::ctrl::{GenlCtrl, GenlCtrlCmd};
20use netlink_packet_generic::{GenlHeader, GenlMessage};
21use netlink_packet_utils::Emitable;
22use starnix_logging::track_stub;
23use starnix_sync::{GenericNetlinkServerStateLock, LockDepMutex};
24use std::collections::{HashMap, HashSet};
25use std::num::NonZero;
26use std::ops::DerefMut;
27use std::sync::Arc;
28
29use starnix_logging::{log_error, log_info, log_warn};
30use starnix_uapi::errors::Errno;
31use starnix_uapi::{ENOENT, error};
32
33mod messages;
34mod nl80211;
35mod taskstats;
36
37pub use messages::GenericMessage;
38
39const MIN_FAMILY_ID: u16 = GENL_ID_CTRL + 1;
40const NLCTRL_FAMILY: &str = "nlctrl";
41
42#[async_trait]
43pub trait GenericNetlinkFamily<S>: Send + Sync {
44    /// Return the unique name for this generic netlink protocol.
45    ///
46    /// This name is used by the ctrl server to identify this server for clients.
47    fn name(&self) -> String;
48
49    /// Return the multicast groups that are supported by this protocol family.
50    ///
51    /// Each multicast group is assigned a unique ID by the ctrl server.
52    fn multicast_groups(&self) -> Vec<String> {
53        vec![]
54    }
55
56    /// Returns a future that pipes messages for the given multicast group into
57    /// the given sink. The parent of this server is responsible for managing
58    /// multicast group memberships and routing these messages appropriately.
59    /// The assigned family id of this multicast group is passed in to be used
60    /// appropriately when constructing messages.
61    async fn stream_multicast_messages(
62        &self,
63        group: String,
64        assigned_family_id: u16,
65        message_sink: mpsc::UnboundedSender<NetlinkMessage<GenericMessage>>,
66    );
67
68    /// Handle a netlink message targeted to this server.
69    ///
70    /// The given payload contains the generic netlink header and all subsequent data.
71    /// Protocol servers should implement their own generic netlink families and
72    /// deserialize messages using `GenlMessage::<_>::deserialize`.
73    async fn handle_message(&self, netlink_header: NetlinkHeader, payload: Vec<u8>, sender: &mut S);
74}
75
76fn extract_family_names(genl_ctrl: GenlCtrl) -> Vec<String> {
77    genl_ctrl
78        .nlas
79        .into_iter()
80        .filter_map(
81            |attr| {
82                if let GenlCtrlAttrs::FamilyName(name) = attr { Some(name) } else { None }
83            },
84        )
85        .collect()
86}
87
88#[derive(Copy, Clone, Eq, PartialEq, Hash)]
89struct ClientId(u64);
90
91/// All state required to the generic netlink server. This struct assumes
92/// synchronous access, and should be kept inside of a GenericNetlinkServer.
93struct GenericNetlinkServerState<S> {
94    /// Mapping from generic family server name to its assigned ID value.
95    family_ids: HashMap<String, u16>,
96    /// Servers for specific generic netlink families. Servers are stored in this
97    /// list by order of ID, such that protocol N is in servers[N - MIN_FAMILY_ID].
98    families: Vec<Arc<dyn GenericNetlinkFamily<S>>>,
99    /// Sink for new families to setup multicast group handling.
100    new_family_sender: mpsc::UnboundedSender<Arc<dyn GenericNetlinkFamily<S>>>,
101    /// Multicast groups, identified by (family name, group name). Multicast
102    /// group IDs are assigned uniquely across all generic families.
103    multicast_groups: HashMap<(String, String), ModernGroup>,
104    /// Counter used to generate unique ID values for all multicast groups.
105    multicast_group_id_counter: ModernGroup,
106    /// Unique internal IDs used to track clients.
107    client_id_counter: ClientId,
108    /// Senders for passing multicast traffic to clients.
109    client_senders: HashMap<ClientId, S>,
110    /// Mapping from multicast group -> list of subscribed client IDs.
111    multicast_group_memberships: HashMap<ModernGroup, HashSet<ClientId>>,
112}
113
114impl<S: Sender<GenericMessage>> GenericNetlinkServerState<S> {
115    fn new(new_family_sender: mpsc::UnboundedSender<Arc<dyn GenericNetlinkFamily<S>>>) -> Self {
116        Self {
117            family_ids: HashMap::new(),
118            families: vec![],
119            new_family_sender,
120            multicast_groups: HashMap::new(),
121            multicast_group_id_counter: ModernGroup(0),
122            client_id_counter: ClientId(0),
123            client_senders: HashMap::new(),
124            multicast_group_memberships: HashMap::new(),
125        }
126    }
127
128    fn add_family(&mut self, family: Arc<dyn GenericNetlinkFamily<S>>) {
129        match (self.families.len() as u16).checked_add(MIN_FAMILY_ID) {
130            Some(new_family_id) => {
131                self.family_ids.insert(family.name(), new_family_id);
132                if let Err(e) = self.new_family_sender.unbounded_send(Arc::clone(&family)) {
133                    log_error!(
134                        tag = NETLINK_LOG_TAG;
135                        "Failed to setup multicast group handling for new generic \
136                         netlink family {}: {}",
137                        family.name(),
138                        e
139                    );
140                }
141                self.families.push(family);
142            }
143            None => {
144                log_error!(
145                    tag = NETLINK_LOG_TAG;
146                    "Failed to add generic netlink family: too many families"
147                );
148            }
149        }
150    }
151
152    fn get_family(&self, family_id: u16) -> Option<Arc<dyn GenericNetlinkFamily<S>>> {
153        if family_id >= MIN_FAMILY_ID
154            && ((family_id - MIN_FAMILY_ID) as usize) < self.families.len()
155        {
156            Some(Arc::clone(&self.families[(family_id - MIN_FAMILY_ID) as usize]))
157        } else {
158            None
159        }
160    }
161
162    fn get_multicast_group_id(&mut self, family: String, group: String) -> ModernGroup {
163        *self.multicast_groups.entry((family, group)).or_insert_with(|| {
164            self.multicast_group_id_counter.0 += 1;
165            self.multicast_group_id_counter
166        })
167    }
168
169    fn handle_ctrl_message(
170        &mut self,
171        mut netlink_header: NetlinkHeader,
172        genl_message: GenlMessage<GenlCtrl>,
173        sender: &mut S,
174    ) {
175        let (genl_header, genl_ctrl) = genl_message.into_parts();
176        match genl_ctrl.cmd {
177            GenlCtrlCmd::GetFamily => {
178                let family_names = extract_family_names(genl_ctrl);
179                log_info!(tag = NETLINK_LOG_TAG; "Netlink GetFamily request: {:?}", family_names);
180
181                for family in &family_names {
182                    if family == NLCTRL_FAMILY {
183                        self.send_get_family_response(
184                            netlink_header,
185                            genl_header,
186                            NLCTRL_FAMILY,
187                            GENL_ID_CTRL,
188                            None,
189                            sender,
190                        );
191                    } else if let Some(id) = self.family_ids.get(family).copied() {
192                        log_info!(
193                            tag = NETLINK_LOG_TAG;
194                            "Serving requested netlink family {}",
195                            family
196                        );
197                        let mcast_groups = self
198                            .get_family(id)
199                            .expect("Known family ID should always exist")
200                            .multicast_groups()
201                            .into_iter()
202                            .map(|name| {
203                                vec![
204                                    McastGrpAttrs::Name(name.clone()),
205                                    McastGrpAttrs::Id(
206                                        self.get_multicast_group_id(family.to_string(), name).0,
207                                    ),
208                                ]
209                            })
210                            .collect();
211                        self.send_get_family_response(
212                            netlink_header,
213                            genl_header,
214                            family,
215                            id,
216                            Some(mcast_groups),
217                            sender,
218                        );
219                    } else {
220                        log_warn!(
221                            tag = NETLINK_LOG_TAG;
222                            "Cannot serve requested netlink family {}",
223                            family
224                        );
225
226                        // Send back error message
227                        let mut buffer = [0; NETLINK_HEADER_LEN];
228                        netlink_header.emit(&mut buffer[..NETLINK_HEADER_LEN]);
229                        let mut error = ErrorMessage::default();
230                        error.code = NonZero::new(-(ENOENT as i32));
231                        error.header = buffer.to_vec();
232                        netlink_header.flags = NLM_F_CAPPED as u16;
233                        let mut netlink_message =
234                            NetlinkMessage::new(netlink_header, NetlinkPayload::Error(error));
235                        netlink_message.finalize();
236                        sender.send(netlink_message, None);
237                    }
238                }
239            }
240            GenlCtrlCmd::NewFamily => {
241                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlNewFamily")
242            }
243            GenlCtrlCmd::DelFamily => {
244                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlDelFamily")
245            }
246            GenlCtrlCmd::NewOps => {
247                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlNewOps")
248            }
249            GenlCtrlCmd::DelOps => {
250                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlDelOps")
251            }
252            GenlCtrlCmd::GetOps => {
253                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlGetOps")
254            }
255            GenlCtrlCmd::NewMcastGrp => {
256                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlNewMcastGrp")
257            }
258            GenlCtrlCmd::DelMcastGrp => {
259                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlDelMcastGrp")
260            }
261            GenlCtrlCmd::GetMcastGrp => {
262                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlGetMcastGrp")
263            }
264            GenlCtrlCmd::GetPolicy => {
265                track_stub!(TODO("https://fxbug.dev/297431602"), "NetlinkCtrlGetPolicy")
266            }
267        }
268    }
269
270    fn send_get_family_response(
271        &mut self,
272        mut netlink_header: NetlinkHeader,
273        genl_header: GenlHeader,
274        family: &str,
275        id: u16,
276        mcast_groups: Option<Vec<Vec<McastGrpAttrs>>>,
277        sender: &mut S,
278    ) {
279        let mut nlas =
280            vec![GenlCtrlAttrs::FamilyId(id), GenlCtrlAttrs::FamilyName(family.to_string())];
281        mcast_groups.map(|mg| nlas.push(GenlCtrlAttrs::McastGroups(mg)));
282        let resp_ctrl = GenlCtrl { cmd: GenlCtrlCmd::NewFamily, nlas };
283        // Flags need to be cleared as we are sending a response back
284        // to the client, not requesting that the client send us
285        // data or ACKs.
286        let orig_flags = netlink_header.flags;
287        netlink_header.flags = 0;
288        let mut genl_message = GenlMessage::from_parts(genl_header, resp_ctrl);
289        genl_message.finalize();
290        let mut message = NetlinkMessage::new(
291            netlink_header,
292            NetlinkPayload::InnerMessage(GenericMessage::Ctrl(genl_message)),
293        );
294        message.finalize();
295        sender.send(message, None);
296        // Conversion is safe because 4 < 65535.
297        if orig_flags & NLM_F_ACK as u16 != 0 {
298            // ACK requested, send ACK
299            let mut buffer = [0; NETLINK_HEADER_LEN];
300            // Conversion is safe because 256 < 65535
301            netlink_header.flags = NLM_F_CAPPED as u16;
302            netlink_header.emit(&mut buffer[..NETLINK_HEADER_LEN]);
303            let mut ack = ErrorMessage::default();
304            // Netlink uses an error payload with no error code to indicate a
305            // successful ack.
306            ack.code = None;
307            ack.header = buffer.to_vec();
308            let mut netlink_message =
309                NetlinkMessage::new(netlink_header, NetlinkPayload::Error(ack));
310            netlink_message.finalize();
311            sender.send(netlink_message, None);
312        }
313    }
314}
315
316/// Coordinates all generic netlink clients and families.
317#[derive(Clone)]
318struct GenericNetlinkServer<S> {
319    state: Arc<LockDepMutex<GenericNetlinkServerState<S>, GenericNetlinkServerStateLock>>,
320}
321
322impl<S: Sender<GenericMessage>> GenericNetlinkServer<S> {
323    fn new(new_family_sender: mpsc::UnboundedSender<Arc<dyn GenericNetlinkFamily<S>>>) -> Self {
324        Self { state: Arc::new(GenericNetlinkServerState::new(new_family_sender).into()) }
325    }
326
327    async fn handle_generic_message(
328        &self,
329        message: NetlinkMessage<GenericMessage>,
330        sender: &mut S,
331    ) {
332        let (netlink_header, payload) = message.into_parts();
333        let req = match payload {
334            NetlinkPayload::InnerMessage(p) => p,
335            p => {
336                log_error!(tag = NETLINK_LOG_TAG; "Dropping unexpected netlink payload: {:?}", p);
337                return;
338            }
339        };
340        match req {
341            GenericMessage::Ctrl(ctrl_message) => {
342                self.state.lock().handle_ctrl_message(netlink_header, ctrl_message, sender)
343            }
344            GenericMessage::Other { family: family_id, payload } => {
345                let family = self.state.lock().get_family(family_id);
346                match family {
347                    Some(family) => {
348                        family.handle_message(netlink_header, payload, sender).await;
349                    }
350                    None => log_info!(
351                        tag = NETLINK_LOG_TAG;
352                        "Ignoring generic netlink message with unsupported family {}",
353                        family_id,
354                    ),
355                }
356            }
357        }
358    }
359
360    async fn run_generic_netlink_client(self, mut client: GenericNetlinkClient<S>) {
361        log_info!(tag = NETLINK_LOG_TAG; "Registered new generic netlink client");
362        loop {
363            match client.receiver.next().await {
364                Some(message) => self.handle_generic_message(message, &mut client.sender).await,
365                None => {
366                    log_info!(tag = NETLINK_LOG_TAG; "Generic netlink client exited");
367                    let mut state = self.state.lock();
368                    for memberships in state.multicast_group_memberships.values_mut() {
369                        memberships.remove(&client.client_id);
370                    }
371                    state.client_senders.remove(&client.client_id);
372                    return;
373                }
374            }
375        }
376    }
377
378    async fn pipe_single_multicast_group(
379        &self,
380        mcast_group_id: ModernGroup,
381        mcast_stream: mpsc::UnboundedReceiver<NetlinkMessage<GenericMessage>>,
382    ) {
383        if self
384            .state
385            .lock()
386            .multicast_group_memberships
387            .insert(mcast_group_id, HashSet::new())
388            .is_some()
389        {
390            log_error!(
391                tag = NETLINK_LOG_TAG;
392                "pipe_single_multicast_group called on group {} but group is already served",
393                mcast_group_id.0
394            );
395            return;
396        }
397        let fut = mcast_stream.for_each(|mcast_message| {
398            let mut state_lock = self.state.lock();
399            let state = state_lock.deref_mut();
400            for client_id in state
401                .multicast_group_memberships
402                .get(&mcast_group_id)
403                .expect("Group memberships should always be present")
404            {
405                if let Some(sender) = state.client_senders.get_mut(client_id) {
406                    sender.send(mcast_message.clone(), Some(mcast_group_id));
407                }
408            }
409            async {}
410        });
411        fut.await;
412    }
413
414    async fn pipe_multicast_traffic_for_family(self, family: Arc<dyn GenericNetlinkFamily<S>>) {
415        let unordered = FuturesUnordered::new();
416        let family_name = family.name().to_string();
417        let family_id =
418            *self.state.lock().family_ids.get(&family_name).expect("Failed to get family id");
419        for mcast_group in family.multicast_groups() {
420            let mcast_group_id =
421                self.state.lock().get_multicast_group_id(family_name.clone(), mcast_group.clone());
422            let (sink, receiver) = mpsc::unbounded();
423            unordered.push(family.stream_multicast_messages(mcast_group, family_id, sink));
424            unordered.push(Box::pin(self.pipe_single_multicast_group(mcast_group_id, receiver)));
425        }
426        unordered.collect::<Vec<()>>().await;
427    }
428}
429
430pub(crate) struct GenericNetlinkClient<S> {
431    client_id: ClientId,
432    sender: S,
433    receiver: mpsc::UnboundedReceiver<NetlinkMessage<GenericMessage>>,
434}
435
436pub struct GenericNetlinkWorkerParams<S: Sender<GenericMessage>> {
437    server: GenericNetlinkServer<S>,
438    new_client_receiver: mpsc::UnboundedReceiver<GenericNetlinkClient<S>>,
439    new_family_receiver: mpsc::UnboundedReceiver<Arc<dyn GenericNetlinkFamily<S>>>,
440}
441
442pub async fn run_generic_netlink_worker<S: Sender<GenericMessage>>(
443    params: GenericNetlinkWorkerParams<S>,
444    enable_nl80211: bool,
445) {
446    // Initialize supported families on the worker, so that they shares an
447    // executor with the main netlink future.
448    let nl80211_family = if enable_nl80211 {
449        // This boolean is tied to availability of the Wlanix protocol, so this
450        // operation will always succeed unless our product config is invalid.
451        Some(nl80211::Nl80211Family::new().expect("Failed to connect to Nl80211 netlink family"))
452    } else {
453        None
454    };
455    let taskstats_family = taskstats::TaskstatsFamily::new();
456    {
457        let mut state = params.server.state.lock();
458        if let Some(nl80211_family) = nl80211_family {
459            state.add_family(Arc::new(nl80211_family));
460        }
461        state.add_family(Arc::new(taskstats_family));
462    }
463
464    run_generic_netlink_worker_internal(params).await
465}
466
467fn run_generic_netlink_worker_internal<S: Sender<GenericMessage>>(
468    params: GenericNetlinkWorkerParams<S>,
469) -> impl std::future::Future<Output = ()> + Send {
470    let GenericNetlinkWorkerParams { server, new_client_receiver, new_family_receiver } = params;
471
472    let server_clone = server.clone();
473    let multicast_fut = new_family_receiver.for_each_concurrent(None, move |family| {
474        server_clone.clone().pipe_multicast_traffic_for_family(family)
475    });
476    let new_client_fut = new_client_receiver
477        .for_each_concurrent(None, move |client| server.clone().run_generic_netlink_client(client));
478
479    join(new_client_fut, multicast_fut).map(|_| ())
480}
481
482pub struct GenericNetlink<S> {
483    server: GenericNetlinkServer<S>,
484    new_client_sender: mpsc::UnboundedSender<GenericNetlinkClient<S>>,
485}
486
487impl<S: Sender<GenericMessage>> GenericNetlink<S> {
488    pub fn new() -> (Self, GenericNetlinkWorkerParams<S>) {
489        let (new_client_sender, new_client_receiver) = mpsc::unbounded();
490        let (new_family_sender, new_family_receiver) = mpsc::unbounded();
491        let server = GenericNetlinkServer::new(new_family_sender);
492        let generic_netlink = Self { server: server.clone(), new_client_sender };
493        let worker_params =
494            GenericNetlinkWorkerParams { server, new_client_receiver, new_family_receiver };
495        (generic_netlink, worker_params)
496    }
497
498    pub fn new_generic_client(
499        &self,
500        sender: S,
501        receiver: mpsc::UnboundedReceiver<NetlinkMessage<GenericMessage>>,
502    ) -> Result<GenericNetlinkClientHandle<S>, anyhow::Error> {
503        let mut state = self.server.state.lock();
504        let client_id = state.client_id_counter;
505        state.client_id_counter.0 += 1;
506        state.client_senders.insert(client_id, sender.clone());
507        let handle = GenericNetlinkClientHandle { client_id, server: self.server.clone() };
508        let new_client = GenericNetlinkClient { client_id, sender, receiver };
509        self.new_client_sender
510            .unbounded_send(new_client)
511            .map_err(|_| anyhow::anyhow!("Failed to connect a new generic netlink client"))?;
512        Ok(handle)
513    }
514}
515
516impl<S: Sender<GenericMessage>> GenericNetlink<S> {
517    pub fn add_family(&self, family: Arc<dyn GenericNetlinkFamily<S>>) {
518        self.server.state.lock().add_family(family)
519    }
520}
521
522pub struct GenericNetlinkClientHandle<S> {
523    client_id: ClientId,
524    server: GenericNetlinkServer<S>,
525}
526
527impl<S> GenericNetlinkClientHandle<S> {
528    pub(crate) fn add_membership(&self, group_id: ModernGroup) -> Result<(), Errno> {
529        let mut state = self.server.state.lock();
530        if let Some(memberships) = state.multicast_group_memberships.get_mut(&group_id) {
531            memberships.insert(self.client_id);
532            Ok(())
533        } else {
534            error!(EINVAL)
535        }
536    }
537}
538
539#[cfg(test)]
540mod test_utils {
541    use super::*;
542    use netlink_packet_core::NetlinkSerializable;
543
544    #[derive(Clone)]
545    pub(crate) struct TestSender<M> {
546        pub messages: Arc<starnix_sync::Mutex<Vec<NetlinkMessage<M>>>>,
547    }
548
549    impl<M: Clone + NetlinkSerializable + Send + Sync> Sender<M> for TestSender<M> {
550        fn send(&mut self, message: NetlinkMessage<M>, _group: Option<ModernGroup>) {
551            self.messages.lock().push(message);
552        }
553    }
554}
555
556#[cfg(test)]
557mod tests {
558    use super::test_utils::*;
559    use super::*;
560    use assert_matches::assert_matches;
561    use fuchsia_async::TestExecutor;
562    use fuchsia_rcu::RcuReadScope;
563    use futures::future::Future;
564    use futures::pin_mut;
565    use netlink_packet_generic::GenlHeader;
566    use starnix_rcu::RcuHashMap;
567    use std::task::Poll;
568
569    const TEST_FAMILY: &str = "test_family";
570    const MCAST_GROUP_1: &str = "m1";
571    const MCAST_GROUP_2: &str = "m2";
572
573    fn getfamily_request() -> NetlinkMessage<GenericMessage> {
574        let getfamily_ctrl = GenlCtrl {
575            cmd: GenlCtrlCmd::GetFamily,
576            nlas: vec![GenlCtrlAttrs::FamilyName(TEST_FAMILY.to_string())],
577        };
578        let mut genl_message =
579            GenlMessage::new(GenlHeader { cmd: 0, version: 0 }, getfamily_ctrl, GENL_ID_CTRL);
580        genl_message.finalize();
581        let mut netlink_message = NetlinkMessage::new(
582            Default::default(),
583            NetlinkPayload::InnerMessage(GenericMessage::Ctrl(genl_message)),
584        );
585        netlink_message.finalize();
586        netlink_message
587    }
588
589    struct TestFamily {
590        messages_to_server: starnix_sync::Mutex<Vec<Vec<u8>>>,
591        multicast_message_sinks: RcuHashMap<
592            String,
593            mpsc::UnboundedSender<NetlinkMessage<GenericMessage>>,
594            starnix_sync::RcuHashMapLock,
595            std::collections::hash_map::RandomState,
596        >,
597    }
598
599    impl Default for TestFamily {
600        fn default() -> Self {
601            Self {
602                messages_to_server: starnix_sync::Mutex::default(),
603                multicast_message_sinks: RcuHashMap::with_hasher(
604                    std::collections::hash_map::RandomState::new(),
605                ),
606            }
607        }
608    }
609
610    #[async_trait]
611    impl<S> GenericNetlinkFamily<S> for TestFamily {
612        fn name(&self) -> String {
613            TEST_FAMILY.into()
614        }
615
616        fn multicast_groups(&self) -> Vec<String> {
617            vec![MCAST_GROUP_1.to_string(), MCAST_GROUP_2.to_string()]
618        }
619
620        async fn stream_multicast_messages(
621            &self,
622            group: String,
623            _assigned_family_id: u16,
624            message_sink: mpsc::UnboundedSender<NetlinkMessage<GenericMessage>>,
625        ) {
626            self.multicast_message_sinks.insert(group, message_sink);
627        }
628
629        async fn handle_message(
630            &self,
631            _netlink_header: NetlinkHeader,
632            payload: Vec<u8>,
633            _sender: &mut S,
634        ) {
635            self.messages_to_server.lock().push(payload);
636        }
637    }
638
639    fn start_test_netlink()
640    -> (GenericNetlink<TestSender<GenericMessage>>, impl Future<Output = ()> + Send) {
641        let (netlink, worker_params) = GenericNetlink::new();
642        let worker = run_generic_netlink_worker_internal(worker_params);
643        (netlink, worker)
644    }
645
646    fn netlink_with_test_family() -> (
647        GenericNetlink<TestSender<GenericMessage>>,
648        Arc<TestFamily>,
649        impl Future<Output = ()> + Send,
650    ) {
651        let test_family = Arc::new(TestFamily::default());
652        let (netlink, worker) = start_test_netlink();
653        netlink.server.state.lock().add_family(Arc::clone(&test_family) as _);
654        (netlink, test_family, worker)
655    }
656
657    fn new_client(
658        netlink: &GenericNetlink<TestSender<GenericMessage>>,
659    ) -> (
660        Arc<starnix_sync::Mutex<Vec<NetlinkMessage<GenericMessage>>>>,
661        mpsc::UnboundedSender<NetlinkMessage<GenericMessage>>,
662        GenericNetlinkClientHandle<TestSender<GenericMessage>>,
663    ) {
664        let messages_to_client = Arc::new(starnix_sync::Mutex::new(vec![]));
665        let (netlink_sender, receiver) = mpsc::unbounded();
666        let sender = TestSender { messages: messages_to_client.clone() };
667        let client_handle =
668            netlink.new_generic_client(sender, receiver).expect("Failed to add new generic client");
669        (messages_to_client, netlink_sender, client_handle)
670    }
671
672    #[test]
673    fn test_ctrl_getfamily_missing() {
674        let mut exec = TestExecutor::new();
675        let (netlink, worker) = start_test_netlink();
676        pin_mut!(worker);
677        let (messages_to_client, sender, _client_handle) = new_client(&netlink);
678
679        sender.unbounded_send(getfamily_request()).expect("Failed to send getfamily request");
680        assert!(exec.run_until_stalled(&mut worker) == Poll::Pending);
681
682        // The family doesn't exist, so an error should be returned.
683        assert!(messages_to_client.lock().len() == 1);
684
685        let (_netlink_header, payload) = messages_to_client.lock().pop().unwrap().into_parts();
686        let err_msg = assert_matches!(payload, NetlinkPayload::Error(m) => m);
687        assert_eq!(err_msg.code, NonZero::new(-2));
688    }
689
690    #[test]
691    fn test_ctrl_getfamily() {
692        let mut exec = TestExecutor::new();
693        let (netlink, _test_family, fut) = netlink_with_test_family();
694        pin_mut!(fut);
695        let (messages_to_client, sender, _client_handle) = new_client(&netlink);
696
697        sender.unbounded_send(getfamily_request()).expect("Failed to send getfamily request");
698        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
699
700        // Verify that we got all expected information in the response.
701        assert!(messages_to_client.lock().len() == 1);
702        let (_netlink_header, payload) = messages_to_client.lock().pop().unwrap().into_parts();
703        let (_genl_header, ctrl_payload) = assert_matches!(
704            payload,
705            NetlinkPayload::InnerMessage(GenericMessage::Ctrl(m)) => m.into_parts());
706        assert_eq!(ctrl_payload.cmd, GenlCtrlCmd::NewFamily);
707        assert!(
708            ctrl_payload
709                .nlas
710                .iter()
711                .any(|nla| *nla == GenlCtrlAttrs::FamilyName(TEST_FAMILY.into()))
712        );
713        assert!(ctrl_payload.nlas.iter().any(|nla| matches!(nla, GenlCtrlAttrs::FamilyId(_))));
714        let multicast_groups = ctrl_payload
715            .nlas
716            .iter()
717            .filter_map(
718                |nla| if let GenlCtrlAttrs::McastGroups(vec) = nla { Some(vec) } else { None },
719            )
720            .next()
721            .expect("No multicast groups");
722        assert_eq!(multicast_groups.len(), 2);
723        assert!(multicast_groups.iter().any(|group| {
724            group.iter().any(|attr| matches!(attr, McastGrpAttrs::Id(_)));
725            group.iter().any(|attr| *attr == McastGrpAttrs::Name(MCAST_GROUP_1.into()))
726        }));
727        assert!(multicast_groups.iter().any(|group| {
728            group.iter().any(|attr| matches!(attr, McastGrpAttrs::Id(_)));
729            group.iter().any(|attr| *attr == McastGrpAttrs::Name(MCAST_GROUP_2.into()))
730        }));
731    }
732
733    #[test]
734    fn test_ctrl_getfamily_before_and_after_add_family() {
735        let mut exec = TestExecutor::new();
736        let (netlink, fut) = start_test_netlink();
737        pin_mut!(fut);
738        let (messages_to_client, sender, _client_handle) = new_client(&netlink);
739
740        sender.unbounded_send(getfamily_request()).expect("Failed to send getfamily request");
741        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
742
743        // The family doesn't exist, so an error should be returned.
744        assert!(messages_to_client.lock().len() == 1);
745
746        let (_netlink_header, payload) = messages_to_client.lock().pop().unwrap().into_parts();
747        let err_msg = assert_matches!(payload, NetlinkPayload::Error(m) => m);
748        assert_eq!(err_msg.code, NonZero::new(-2));
749
750        // Add the test family and try again.
751        let test_family = Arc::new(TestFamily::default());
752        netlink.add_family(test_family);
753
754        sender.unbounded_send(getfamily_request()).expect("Failed to send getfamily request");
755        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
756
757        // Verify that we got all expected information in the response.
758        assert!(messages_to_client.lock().len() == 1);
759        let (_netlink_header, payload) = messages_to_client.lock().pop().unwrap().into_parts();
760        let (_genl_header, ctrl_payload) = assert_matches!(
761            payload,
762            NetlinkPayload::InnerMessage(GenericMessage::Ctrl(m)) => m.into_parts());
763        assert_eq!(ctrl_payload.cmd, GenlCtrlCmd::NewFamily);
764        assert!(
765            ctrl_payload
766                .nlas
767                .iter()
768                .any(|nla| *nla == GenlCtrlAttrs::FamilyName(TEST_FAMILY.into()))
769        );
770        assert!(ctrl_payload.nlas.iter().any(|nla| matches!(nla, GenlCtrlAttrs::FamilyId(_))));
771        let multicast_groups = ctrl_payload
772            .nlas
773            .iter()
774            .filter_map(
775                |nla| if let GenlCtrlAttrs::McastGroups(vec) = nla { Some(vec) } else { None },
776            )
777            .next()
778            .expect("No multicast groups");
779        assert_eq!(multicast_groups.len(), 2);
780        assert!(multicast_groups.iter().any(|group| {
781            group.iter().any(|attr| matches!(attr, McastGrpAttrs::Id(_)));
782            group.iter().any(|attr| *attr == McastGrpAttrs::Name(MCAST_GROUP_1.into()))
783        }));
784        assert!(multicast_groups.iter().any(|group| {
785            group.iter().any(|attr| matches!(attr, McastGrpAttrs::Id(_)));
786            group.iter().any(|attr| *attr == McastGrpAttrs::Name(MCAST_GROUP_2.into()))
787        }));
788    }
789
790    #[test]
791    fn test_send_family_message() {
792        let mut exec = TestExecutor::new();
793        let (netlink, test_family, fut) = netlink_with_test_family();
794        pin_mut!(fut);
795        let (messages_to_client, sender, _client_handle) = new_client(&netlink);
796
797        sender.unbounded_send(getfamily_request()).expect("Failed to send getfamily request");
798        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
799
800        assert!(messages_to_client.lock().len() == 1);
801        let (_netlink_header, payload) = messages_to_client.lock().pop().unwrap().into_parts();
802        let (_genl_header, ctrl_payload) = assert_matches!(
803            payload,
804            NetlinkPayload::InnerMessage(GenericMessage::Ctrl(m)) => m.into_parts());
805        let family_id = *ctrl_payload
806            .nlas
807            .iter()
808            .filter_map(|nla| if let GenlCtrlAttrs::FamilyId(id) = nla { Some(id) } else { None })
809            .next()
810            .expect("Could not find family id");
811
812        let mut netlink_message = NetlinkMessage::new(
813            Default::default(),
814            NetlinkPayload::InnerMessage(GenericMessage::Other {
815                family: family_id,
816                payload: vec![0, 1, 2, 3],
817            }),
818        );
819        netlink_message.finalize();
820        sender.unbounded_send(netlink_message).expect("Failed to send test family message");
821
822        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
823        assert_eq!(test_family.messages_to_server.lock().len(), 1);
824    }
825
826    #[test]
827    fn test_send_invalid_family_message() {
828        let mut exec = TestExecutor::new();
829        let (netlink, test_family, fut) = netlink_with_test_family();
830        pin_mut!(fut);
831        let (messages_to_client, sender, _client_handle) = new_client(&netlink);
832
833        let mut netlink_message = NetlinkMessage::new(
834            Default::default(),
835            NetlinkPayload::InnerMessage(GenericMessage::Other {
836                family: 1337,
837                payload: vec![0, 1, 2, 3],
838            }),
839        );
840        netlink_message.finalize();
841        sender.unbounded_send(netlink_message).expect("Failed to send test family message");
842        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
843        assert!(test_family.messages_to_server.lock().is_empty());
844        assert!(messages_to_client.lock().is_empty());
845    }
846
847    #[test]
848    fn test_server_gets_multicast_messages() {
849        let mut exec = TestExecutor::new();
850        let (_netlink, test_family, fut) = netlink_with_test_family();
851        pin_mut!(fut);
852        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
853        let scope = RcuReadScope::new();
854        assert_eq!(test_family.multicast_message_sinks.iter(&scope).count(), 2);
855        assert!(test_family.multicast_message_sinks.get(&scope, MCAST_GROUP_1).is_some());
856        assert!(test_family.multicast_message_sinks.get(&scope, MCAST_GROUP_2).is_some());
857    }
858
859    #[test]
860    fn test_bad_multicast_subscription_fails() {
861        let mut exec = TestExecutor::new();
862        let (netlink, fut) = start_test_netlink();
863        pin_mut!(fut);
864        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
865
866        let (_messages_to_client, _sender, client_handle) = new_client(&netlink);
867        client_handle
868            .add_membership(ModernGroup(1337))
869            .expect_err("Should not be able to add invalid multicast membership");
870    }
871
872    #[test]
873    fn test_multicast_subscriptions() {
874        let mut exec = TestExecutor::new();
875        let (netlink, test_family, fut) = netlink_with_test_family();
876        pin_mut!(fut);
877        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
878        let (messages_to_client_1, _sender_1, client_handle_1) = new_client(&netlink);
879        let (messages_to_client_2, _sender_2, client_handle_2) = new_client(&netlink);
880        let (messages_to_client_3, _sender_3, _client_handle_3) = new_client(&netlink);
881
882        let mcast_group_1_id = netlink
883            .server
884            .state
885            .lock()
886            .get_multicast_group_id(TEST_FAMILY.to_string(), MCAST_GROUP_1.to_string());
887        client_handle_1.add_membership(mcast_group_1_id).expect("add_membership failed");
888        client_handle_2.add_membership(mcast_group_1_id).expect("add_membership failed");
889
890        assert!(messages_to_client_1.lock().is_empty());
891        assert!(messages_to_client_2.lock().is_empty());
892        assert!(messages_to_client_3.lock().is_empty());
893
894        let message_sink = test_family
895            .multicast_message_sinks
896            .get(&RcuReadScope::new(), MCAST_GROUP_1)
897            .expect("Failed to find multicast message sender")
898            .clone();
899        let netlink_message = NetlinkMessage::new(NetlinkHeader::default(), NetlinkPayload::Noop);
900        message_sink.unbounded_send(netlink_message).expect("Failed to send message");
901        assert!(exec.run_until_stalled(&mut fut) == Poll::Pending);
902
903        // All subscribed clients receive the message.
904        assert_eq!(messages_to_client_1.lock().len(), 1);
905        assert_eq!(messages_to_client_2.lock().len(), 1);
906        // Client 3 did not subscribe and should not receive the message.
907        assert!(messages_to_client_3.lock().is_empty());
908    }
909}