starnix_core/vfs/socket/
socket_netlink.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 crate::security::{self, AuditLogger, AuditMessage, AuditRequest};
6use crate::vfs::socket::{SockOptValue, SocketDomain};
7use futures::channel::mpsc::{
8    UnboundedReceiver, UnboundedSender, {self},
9};
10use linux_uapi::{AUDIT_GET, audit_status};
11use netlink::messaging::{
12    AccessControl, MessageWithPermission, NetlinkContext, NetlinkMessageWithCreds, Permission,
13    Sender, UnparsedNetlinkMessage,
14};
15use netlink::multicast_groups::{
16    InvalidLegacyGroupsError, InvalidModernGroupError, LegacyGroups, ModernGroup,
17    NoMappingFromModernToLegacyGroupError, SingleLegacyGroup,
18};
19use netlink::protocol_family::NetlinkClient;
20use netlink::protocol_family::route::NetlinkRouteClient;
21use netlink::{NETLINK_LOG_TAG, NewClientError};
22use netlink_packet_core::{
23    ErrorMessage, NETLINK_HEADER_LEN, NLMSG_ERROR, NetlinkBuffer, NetlinkDeserializable,
24    NetlinkHeader, NetlinkMessage, NetlinkPayload, NetlinkSerializable,
25};
26use netlink_packet_route::RouteNetlinkMessage;
27use netlink_packet_utils::{DecodeError, Emitable as _};
28use starnix_sync::{FileOpsCore, LockEqualOrBefore, Locked, Mutex};
29use std::marker::PhantomData;
30use std::num::{NonZeroI32, NonZeroU32};
31use std::sync::Arc;
32use zerocopy::{FromBytes, IntoBytes};
33
34use crate::device::kobject::{Device, UEventAction, UEventContext};
35use crate::device::{DeviceListener, DeviceListenerKey};
36use crate::task::{
37    CurrentTask, EventHandler, FullCredentials, Kernel, WaitCanceler, WaitQueue, Waiter,
38};
39use crate::vfs::buffers::{
40    AncillaryData, InputBuffer, Message, MessageQueue, MessageReadInfo, OutputBuffer,
41    UnixControlData, VecInputBuffer,
42};
43use crate::vfs::socket::{
44    GenericMessage, GenericNetlinkClientHandle, Socket, SocketAddress, SocketHandle,
45    SocketMessageFlags, SocketOps, SocketPeer, SocketShutdownFlags, SocketType,
46};
47use starnix_logging::{log_debug, log_error, log_warn, track_stub};
48use starnix_uapi::auth::{CAP_AUDIT_CONTROL, CAP_AUDIT_WRITE, CAP_NET_ADMIN};
49use starnix_uapi::errors::Errno;
50use starnix_uapi::vfs::FdEvents;
51use starnix_uapi::{
52    AF_NETLINK, NETLINK_ADD_MEMBERSHIP, NETLINK_AUDIT, NETLINK_CONNECTOR, NETLINK_CRYPTO,
53    NETLINK_DNRTMSG, NETLINK_DROP_MEMBERSHIP, NETLINK_ECRYPTFS, NETLINK_FIB_LOOKUP,
54    NETLINK_FIREWALL, NETLINK_GENERIC, NETLINK_IP6_FW, NETLINK_ISCSI, NETLINK_KOBJECT_UEVENT,
55    NETLINK_NETFILTER, NETLINK_NFLOG, NETLINK_RDMA, NETLINK_ROUTE, NETLINK_SCSITRANSPORT,
56    NETLINK_SELINUX, NETLINK_SMC, NETLINK_SOCK_DIAG, NETLINK_USERSOCK, NETLINK_XFRM, NLM_F_MULTI,
57    NLMSG_DONE, SO_PASSCRED, SO_PROTOCOL, SO_RCVBUF, SO_RCVBUFFORCE, SO_SNDBUF, SO_SNDBUFFORCE,
58    SO_TIMESTAMP, SOL_SOCKET, errno, error, nlmsghdr, sockaddr_nl, socklen_t, ucred,
59};
60
61// From netlink/socket.go in gVisor.
62pub const SOCKET_MIN_SIZE: usize = 4 << 10;
63pub const SOCKET_DEFAULT_SIZE: usize = 16 * 1024;
64pub const SOCKET_MAX_SIZE: usize = 4 << 20;
65
66// From linux/socket.go in gVisor.
67const SOL_NETLINK: u32 = 270;
68
69pub fn new_netlink_socket(
70    kernel: &Arc<Kernel>,
71    socket_type: SocketType,
72    family: NetlinkFamily,
73) -> Result<Box<dyn SocketOps>, Errno> {
74    log_debug!(tag = NETLINK_LOG_TAG; "Creating {:?} Netlink Socket", family);
75    if socket_type != SocketType::Datagram && socket_type != SocketType::Raw {
76        return error!(ESOCKTNOSUPPORT);
77    }
78
79    let ops: Box<dyn SocketOps> = match family {
80        NetlinkFamily::KobjectUevent => Box::new(UEventNetlinkSocket::default()),
81        NetlinkFamily::Route => Box::new(RouteNetlinkSocket::new(kernel)?),
82        NetlinkFamily::Generic => Box::new(GenericNetlinkSocket::new(kernel)?),
83        NetlinkFamily::SockDiag => Box::new(SockDiagNetlinkSocket::default()),
84        NetlinkFamily::Audit => Box::new(AuditNetlinkSocket::new(kernel)?),
85        NetlinkFamily::Usersock
86        | NetlinkFamily::Firewall
87        | NetlinkFamily::Nflog
88        | NetlinkFamily::Xfrm
89        | NetlinkFamily::Selinux
90        | NetlinkFamily::Iscsi
91        | NetlinkFamily::FibLookup
92        | NetlinkFamily::Connector
93        | NetlinkFamily::Netfilter
94        | NetlinkFamily::Ip6Fw
95        | NetlinkFamily::Dnrtmsg
96        | NetlinkFamily::Scsitransport
97        | NetlinkFamily::Ecryptfs
98        | NetlinkFamily::Rdma
99        | NetlinkFamily::Crypto
100        | NetlinkFamily::Smc => Box::new(StubbedNetlinkSocket::new(family)),
101        NetlinkFamily::Invalid => return error!(EINVAL),
102    };
103    Ok(ops)
104}
105
106#[derive(Default, Debug, Clone, PartialEq, Eq)]
107#[repr(C)]
108pub struct NetlinkAddress {
109    pid: u32,
110    groups: u32,
111}
112
113impl NetlinkAddress {
114    pub fn new(pid: u32, groups: u32) -> Self {
115        NetlinkAddress { pid, groups }
116    }
117
118    pub fn set_pid_if_zero(&mut self, pid: i32) {
119        if self.pid == 0 {
120            self.pid = pid as u32;
121        }
122    }
123
124    pub fn to_bytes(&self) -> Vec<u8> {
125        sockaddr_nl { nl_family: AF_NETLINK, nl_pid: self.pid, nl_pad: 0, nl_groups: self.groups }
126            .as_bytes()
127            .to_vec()
128    }
129}
130
131#[derive(Debug, Hash, Eq, PartialEq, Clone)]
132pub enum NetlinkFamily {
133    Invalid,
134    Route,
135    Usersock,
136    Firewall,
137    SockDiag,
138    Nflog,
139    Xfrm,
140    Selinux,
141    Iscsi,
142    Audit,
143    FibLookup,
144    Connector,
145    Netfilter,
146    Ip6Fw,
147    Dnrtmsg,
148    KobjectUevent,
149    Generic,
150    Scsitransport,
151    Ecryptfs,
152    Rdma,
153    Crypto,
154    Smc,
155}
156
157impl NetlinkFamily {
158    pub fn from_raw(family: u32) -> Self {
159        match family {
160            NETLINK_ROUTE => NetlinkFamily::Route,
161            NETLINK_USERSOCK => NetlinkFamily::Usersock,
162            NETLINK_FIREWALL => NetlinkFamily::Firewall,
163            NETLINK_SOCK_DIAG => NetlinkFamily::SockDiag,
164            NETLINK_NFLOG => NetlinkFamily::Nflog,
165            NETLINK_XFRM => NetlinkFamily::Xfrm,
166            NETLINK_SELINUX => NetlinkFamily::Selinux,
167            NETLINK_ISCSI => NetlinkFamily::Iscsi,
168            NETLINK_AUDIT => NetlinkFamily::Audit,
169            NETLINK_FIB_LOOKUP => NetlinkFamily::FibLookup,
170            NETLINK_CONNECTOR => NetlinkFamily::Connector,
171            NETLINK_NETFILTER => NetlinkFamily::Netfilter,
172            NETLINK_IP6_FW => NetlinkFamily::Ip6Fw,
173            NETLINK_DNRTMSG => NetlinkFamily::Dnrtmsg,
174            NETLINK_KOBJECT_UEVENT => NetlinkFamily::KobjectUevent,
175            NETLINK_GENERIC => NetlinkFamily::Generic,
176            NETLINK_SCSITRANSPORT => NetlinkFamily::Scsitransport,
177            NETLINK_ECRYPTFS => NetlinkFamily::Ecryptfs,
178            NETLINK_RDMA => NetlinkFamily::Rdma,
179            NETLINK_CRYPTO => NetlinkFamily::Crypto,
180            NETLINK_SMC => NetlinkFamily::Smc,
181            _ => NetlinkFamily::Invalid,
182        }
183    }
184
185    pub fn as_raw(&self) -> u32 {
186        match self {
187            NetlinkFamily::Route => NETLINK_ROUTE,
188            NetlinkFamily::KobjectUevent => NETLINK_KOBJECT_UEVENT,
189            NetlinkFamily::Audit => NETLINK_AUDIT,
190            _ => 0,
191        }
192    }
193}
194
195struct NetlinkSocketInner {
196    /// The specific type of netlink socket.
197    family: NetlinkFamily,
198
199    /// The [`MessageQueue`] that contains messages from netlink to the client.
200    receive_buffer: MessageQueue,
201
202    /// The socket's send buffer size. Note, This value is only used
203    /// to serve getsockopt calls for `SO_SNDBUF`. It does not yet enforce a
204    /// limit on the number of messages netlink will buffer from the client.
205    /// TODO(https://fxbug.dev/285880057): Limit the size of the send buffer.
206    send_buf_size: usize,
207
208    /// This queue will be notified on reads, writes, disconnects etc.
209    waiters: WaitQueue,
210
211    /// The address of this socket.
212    address: Option<NetlinkAddress>,
213
214    /// See SO_PASSCRED.
215    pub passcred: bool,
216
217    /// See SO_TIMESTAMP.
218    pub timestamp: bool,
219}
220
221impl NetlinkSocketInner {
222    fn new(family: NetlinkFamily) -> Self {
223        Self {
224            family,
225            receive_buffer: MessageQueue::new(SOCKET_DEFAULT_SIZE),
226            send_buf_size: SOCKET_DEFAULT_SIZE,
227            waiters: WaitQueue::default(),
228            address: None,
229            passcred: false,
230            timestamp: false,
231        }
232    }
233
234    fn bind(
235        &mut self,
236        current_task: &CurrentTask,
237        socket_address: SocketAddress,
238    ) -> Result<(), Errno> {
239        if self.address.is_some() {
240            return error!(EINVAL);
241        }
242
243        let netlink_address = match socket_address {
244            SocketAddress::Netlink(mut netlink_address) => {
245                // TODO: Support distinct IDs for processes with multiple netlink sockets.
246                netlink_address.set_pid_if_zero(current_task.get_pid());
247                netlink_address
248            }
249            _ => return error!(EINVAL),
250        };
251
252        self.address = Some(netlink_address);
253        Ok(())
254    }
255
256    fn connect(&mut self, current_task: &CurrentTask, peer: SocketPeer) -> Result<(), Errno> {
257        let address = match peer {
258            SocketPeer::Address(address) => address,
259            _ => return error!(EINVAL),
260        };
261        // Connect is equivalent to bind, but error are ignored.
262        let _ = self.bind(current_task, address);
263        Ok(())
264    }
265
266    fn read_message(&mut self) -> Option<Message> {
267        let message = self.receive_buffer.read_message();
268        if message.is_some() {
269            self.waiters.notify_fd_events(FdEvents::POLLOUT);
270        }
271        message
272    }
273
274    fn read_datagram(
275        &mut self,
276        data: &mut dyn OutputBuffer,
277        flags: SocketMessageFlags,
278    ) -> Result<MessageReadInfo, Errno> {
279        let mut info = if flags.contains(SocketMessageFlags::PEEK) {
280            self.receive_buffer.peek_datagram(data)
281        } else {
282            self.receive_buffer.read_datagram(data)
283        }?;
284        if info.message_length == 0 {
285            return error!(EAGAIN);
286        }
287
288        if self.passcred {
289            track_stub!(TODO("https://fxbug.dev/297373991"), "SCM_CREDENTIALS/SO_PASSCRED");
290            info.ancillary_data.push(AncillaryData::Unix(UnixControlData::unknown_creds()));
291        }
292
293        Ok(info)
294    }
295
296    fn write_to_queue(
297        &mut self,
298        data: &mut dyn InputBuffer,
299        address: Option<NetlinkAddress>,
300        ancillary_data: &mut Vec<AncillaryData>,
301    ) -> Result<usize, Errno> {
302        let socket_address = match address {
303            Some(addr) => Some(SocketAddress::Netlink(addr)),
304            None => self.address.as_ref().map(|addr| SocketAddress::Netlink(addr.clone())),
305        };
306        let bytes_written =
307            self.receive_buffer.write_datagram(data, socket_address, ancillary_data)?;
308        if bytes_written > 0 {
309            self.waiters.notify_fd_events(FdEvents::POLLIN);
310        }
311        Ok(bytes_written)
312    }
313
314    fn wait_async(
315        &mut self,
316        waiter: &Waiter,
317        events: FdEvents,
318        handler: EventHandler,
319    ) -> WaitCanceler {
320        self.waiters.wait_async_fd_events(waiter, events, handler)
321    }
322
323    fn query_events(&self) -> FdEvents {
324        self.receive_buffer.query_events()
325    }
326
327    fn getsockname(&self) -> Result<SocketAddress, Errno> {
328        match &self.address {
329            Some(addr) => Ok(SocketAddress::Netlink(addr.clone())),
330            _ => Ok(SocketAddress::default_for_domain(SocketDomain::Netlink)),
331        }
332    }
333
334    fn getpeername(&self) -> Result<SocketAddress, Errno> {
335        match &self.address {
336            Some(addr) => Ok(SocketAddress::Netlink(addr.clone())),
337            _ => Ok(SocketAddress::default_for_domain(SocketDomain::Netlink)),
338        }
339    }
340
341    fn getsockopt(&self, level: u32, optname: u32) -> Result<Vec<u8>, Errno> {
342        let opt_value = match level {
343            SOL_SOCKET => match optname {
344                SO_PASSCRED => (self.passcred as u32).as_bytes().to_vec(),
345                SO_TIMESTAMP => (self.timestamp as u32).as_bytes().to_vec(),
346                SO_SNDBUF => (self.send_buf_size as socklen_t).to_ne_bytes().to_vec(),
347                SO_RCVBUF => (self.receive_buffer.capacity() as socklen_t).to_ne_bytes().to_vec(),
348                SO_SNDBUFFORCE => (self.send_buf_size as socklen_t).to_ne_bytes().to_vec(),
349                SO_RCVBUFFORCE => {
350                    (self.receive_buffer.capacity() as socklen_t).to_ne_bytes().to_vec()
351                }
352                SO_PROTOCOL => self.family.as_raw().as_bytes().to_vec(),
353                _ => return error!(ENOSYS),
354            },
355            _ => vec![],
356        };
357
358        Ok(opt_value)
359    }
360
361    fn setsockopt(
362        &mut self,
363        current_task: &CurrentTask,
364        level: u32,
365        optname: u32,
366        optval: SockOptValue,
367    ) -> Result<(), Errno> {
368        match level {
369            SOL_SOCKET => match optname {
370                SO_SNDBUF => {
371                    let requested_capacity: socklen_t = optval.read(current_task)?;
372                    // SO_SNDBUF doubles the requested capacity to leave space for bookkeeping.
373                    // See https://man7.org/linux/man-pages/man7/socket.7.html
374                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
375                    // TODO(https://fxbug.dev/322907334): Clamp to `wmem_max`.
376                    let capacity = capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
377                    self.send_buf_size = capacity;
378                }
379                SO_SNDBUFFORCE => {
380                    security::check_task_capable(current_task, CAP_NET_ADMIN)?;
381                    let requested_capacity: socklen_t = optval.read(current_task)?;
382                    // SO_SNDBUFFORE doubles the requested capacity to leave space for bookkeeping.
383                    // See https://man7.org/linux/man-pages/man7/socket.7.html
384                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
385                    self.send_buf_size = capacity;
386                }
387                SO_RCVBUF => {
388                    let requested_capacity: socklen_t = optval.read(current_task)?;
389                    // SO_RCVBUF doubles the requested capacity to leave space for bookkeeping.
390                    // See https://man7.org/linux/man-pages/man7/socket.7.html
391                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
392                    // TODO(https://fxbug.dev/322906968): Clamp to `rmem_max`.
393                    let capacity = capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
394                    self.receive_buffer.set_capacity(capacity)?;
395                }
396                SO_RCVBUFFORCE => {
397                    security::check_task_capable(current_task, CAP_NET_ADMIN)?;
398                    let requested_capacity: socklen_t = optval.read(current_task)?;
399                    // SO_RCVBUFFORE doubles the requested capacity to leave space for bookkeeping.
400                    // See https://man7.org/linux/man-pages/man7/socket.7.html
401                    let capacity = usize::try_from(requested_capacity * 2).unwrap_or(usize::MAX);
402                    self.receive_buffer.set_capacity(capacity)?;
403                }
404                SO_PASSCRED => {
405                    let passcred: u32 = optval.read(current_task)?;
406                    self.passcred = passcred != 0;
407                }
408                SO_TIMESTAMP => {
409                    let timestamp: u32 = optval.read(current_task)?;
410                    self.timestamp = timestamp != 0;
411                }
412                _ => return error!(ENOSYS),
413            },
414            _ => return error!(ENOSYS),
415        }
416
417        Ok(())
418    }
419}
420
421/// A fake Netlink socket that loops messages back to the client.
422///
423/// Used as a placeholder implementation for protocol families that lack a real
424/// implementation.
425struct StubbedNetlinkSocket {
426    inner: Mutex<NetlinkSocketInner>,
427}
428
429impl StubbedNetlinkSocket {
430    pub fn new(family: NetlinkFamily) -> Self {
431        track_stub!(
432            TODO("https://fxbug.dev/278565021"),
433            format!("Creating StubbedNetlinkSocket: {:?}", family).as_str()
434        );
435        StubbedNetlinkSocket { inner: Mutex::new(NetlinkSocketInner::new(family)) }
436    }
437
438    /// Locks and returns the inner state of the Socket.
439    fn lock(&self) -> starnix_sync::MutexGuard<'_, NetlinkSocketInner> {
440        self.inner.lock()
441    }
442}
443
444impl SocketOps for StubbedNetlinkSocket {
445    fn connect(
446        &self,
447        _locked: &mut Locked<FileOpsCore>,
448        _socket: &SocketHandle,
449        current_task: &CurrentTask,
450        peer: SocketPeer,
451    ) -> Result<(), Errno> {
452        self.lock().connect(current_task, peer)
453    }
454
455    fn listen(
456        &self,
457        _locked: &mut Locked<FileOpsCore>,
458        _socket: &Socket,
459        _backlog: i32,
460        _credentials: ucred,
461    ) -> Result<(), Errno> {
462        error!(EOPNOTSUPP)
463    }
464
465    fn accept(
466        &self,
467        _locked: &mut Locked<FileOpsCore>,
468        _socket: &Socket,
469        _current_task: &CurrentTask,
470    ) -> Result<SocketHandle, Errno> {
471        error!(EOPNOTSUPP)
472    }
473
474    fn bind(
475        &self,
476        _locked: &mut Locked<FileOpsCore>,
477        _socket: &Socket,
478        current_task: &CurrentTask,
479        socket_address: SocketAddress,
480    ) -> Result<(), Errno> {
481        self.lock().bind(current_task, socket_address)
482    }
483
484    fn read(
485        &self,
486        _locked: &mut Locked<FileOpsCore>,
487        _socket: &Socket,
488        _current_task: &CurrentTask,
489        data: &mut dyn OutputBuffer,
490        _flags: SocketMessageFlags,
491    ) -> Result<MessageReadInfo, Errno> {
492        let msg = self.lock().read_message();
493        match msg {
494            Some(message) => {
495                // Mark the message as complete and return it.
496                let (mut nl_msg, _) =
497                    nlmsghdr::read_from_prefix(&message.data).map_err(|_| errno!(EINVAL))?;
498                nl_msg.nlmsg_type = NLMSG_DONE as u16;
499                nl_msg.nlmsg_flags &= NLM_F_MULTI as u16;
500                let msg_bytes = nl_msg.as_bytes();
501                let bytes_read = data.write(msg_bytes)?;
502
503                let info = MessageReadInfo {
504                    bytes_read,
505                    message_length: msg_bytes.len(),
506                    address: Some(SocketAddress::Netlink(NetlinkAddress::default())),
507                    ancillary_data: vec![],
508                };
509                Ok(info)
510            }
511            None => Ok(MessageReadInfo::default()),
512        }
513    }
514
515    fn write(
516        &self,
517        _locked: &mut Locked<FileOpsCore>,
518        _socket: &Socket,
519        _current_task: &CurrentTask,
520        data: &mut dyn InputBuffer,
521        dest_address: &mut Option<SocketAddress>,
522        ancillary_data: &mut Vec<AncillaryData>,
523    ) -> Result<usize, Errno> {
524        let mut local_address = self.lock().address.clone();
525
526        let destination = match dest_address {
527            Some(SocketAddress::Netlink(addr)) => addr,
528            _ => match &mut local_address {
529                Some(addr) => addr,
530                _ => return Ok(data.drain()),
531            },
532        };
533
534        if destination.groups != 0 {
535            track_stub!(TODO("https://fxbug.dev/322874956"), "StubbedNetlinkSockets multicasting");
536            return Ok(data.drain());
537        }
538
539        self.lock().write_to_queue(data, Some(NetlinkAddress::default()), ancillary_data)
540    }
541
542    fn wait_async(
543        &self,
544        _locked: &mut Locked<FileOpsCore>,
545        _socket: &Socket,
546        _current_task: &CurrentTask,
547        waiter: &Waiter,
548        events: FdEvents,
549        handler: EventHandler,
550    ) -> WaitCanceler {
551        self.lock().wait_async(waiter, events, handler)
552    }
553
554    fn query_events(
555        &self,
556        _locked: &mut Locked<FileOpsCore>,
557        _socket: &Socket,
558        _current_task: &CurrentTask,
559    ) -> Result<FdEvents, Errno> {
560        Ok(self.lock().query_events() & FdEvents::POLLIN)
561    }
562
563    fn shutdown(
564        &self,
565        _locked: &mut Locked<FileOpsCore>,
566        _socket: &Socket,
567        _how: SocketShutdownFlags,
568    ) -> Result<(), Errno> {
569        track_stub!(TODO("https://fxbug.dev/322875507"), "StubbedNetlinkSocket::shutdown");
570        Ok(())
571    }
572
573    fn close(
574        &self,
575        _locked: &mut Locked<FileOpsCore>,
576        _current_task: &CurrentTask,
577        _socket: &Socket,
578    ) {
579    }
580
581    fn getsockname(
582        &self,
583        _locked: &mut Locked<FileOpsCore>,
584        _socket: &Socket,
585    ) -> Result<SocketAddress, Errno> {
586        self.lock().getsockname()
587    }
588
589    fn getpeername(
590        &self,
591        _locked: &mut Locked<FileOpsCore>,
592        _socket: &Socket,
593    ) -> Result<SocketAddress, Errno> {
594        self.lock().getpeername()
595    }
596
597    fn getsockopt(
598        &self,
599        _locked: &mut Locked<FileOpsCore>,
600        _socket: &Socket,
601        _current_task: &CurrentTask,
602        level: u32,
603        optname: u32,
604        _optlen: u32,
605    ) -> Result<Vec<u8>, Errno> {
606        self.lock().getsockopt(level, optname)
607    }
608
609    fn setsockopt(
610        &self,
611        _locked: &mut Locked<FileOpsCore>,
612        _socket: &Socket,
613        current_task: &CurrentTask,
614        level: u32,
615        optname: u32,
616        optval: SockOptValue,
617    ) -> Result<(), Errno> {
618        self.lock().setsockopt(current_task, level, optname, optval)
619    }
620}
621
622/// Socket implementation for the NETLINK_KOBJECT_UEVENT family of netlink sockets.
623struct UEventNetlinkSocket {
624    inner: Arc<Mutex<NetlinkSocketInner>>,
625    device_listener_key: Mutex<Option<DeviceListenerKey>>,
626}
627
628impl Default for UEventNetlinkSocket {
629    #[allow(clippy::let_and_return)]
630    fn default() -> Self {
631        let result = Self {
632            inner: Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::KobjectUevent))),
633            device_listener_key: Default::default(),
634        };
635        #[cfg(any(test, debug_assertions))]
636        {
637            let _l1 = result.device_listener_key.lock();
638            let _l2 = result.lock();
639        }
640        result
641    }
642}
643
644impl UEventNetlinkSocket {
645    /// Locks and returns the inner state of the Socket.
646    fn lock(&self) -> starnix_sync::MutexGuard<'_, NetlinkSocketInner> {
647        self.inner.lock()
648    }
649
650    fn register_listener<L>(
651        &self,
652        locked: &mut Locked<L>,
653        current_task: &CurrentTask,
654        state: starnix_sync::MutexGuard<'_, NetlinkSocketInner>,
655    ) where
656        L: LockEqualOrBefore<FileOpsCore>,
657    {
658        if state.address.is_none() {
659            return;
660        }
661        std::mem::drop(state);
662        let mut key_state = self.device_listener_key.lock();
663        if key_state.is_none() {
664            *key_state = Some(
665                current_task.kernel().device_registry.register_listener(locked, self.inner.clone()),
666            );
667        }
668    }
669}
670
671impl SocketOps for UEventNetlinkSocket {
672    fn connect(
673        &self,
674        locked: &mut Locked<FileOpsCore>,
675        _socket: &SocketHandle,
676        current_task: &CurrentTask,
677        peer: SocketPeer,
678    ) -> Result<(), Errno> {
679        let mut state = self.lock();
680        state.connect(current_task, peer)?;
681        self.register_listener(locked, current_task, state);
682        Ok(())
683    }
684
685    fn listen(
686        &self,
687        _locked: &mut Locked<FileOpsCore>,
688        _socket: &Socket,
689        _backlog: i32,
690        _credentials: ucred,
691    ) -> Result<(), Errno> {
692        error!(EOPNOTSUPP)
693    }
694
695    fn accept(
696        &self,
697        _locked: &mut Locked<FileOpsCore>,
698        _socket: &Socket,
699        _current_task: &CurrentTask,
700    ) -> Result<SocketHandle, Errno> {
701        error!(EOPNOTSUPP)
702    }
703
704    fn bind(
705        &self,
706        locked: &mut Locked<FileOpsCore>,
707        _socket: &Socket,
708        current_task: &CurrentTask,
709        socket_address: SocketAddress,
710    ) -> Result<(), Errno> {
711        let mut state = self.lock();
712        state.bind(current_task, socket_address)?;
713        self.register_listener(locked, current_task, state);
714        Ok(())
715    }
716
717    fn read(
718        &self,
719        _locked: &mut Locked<FileOpsCore>,
720        _socket: &Socket,
721        _current_task: &CurrentTask,
722        data: &mut dyn OutputBuffer,
723        flags: SocketMessageFlags,
724    ) -> Result<MessageReadInfo, Errno> {
725        self.lock().read_datagram(data, flags)
726    }
727
728    fn write(
729        &self,
730        _locked: &mut Locked<FileOpsCore>,
731        _socket: &Socket,
732        _current_task: &CurrentTask,
733        _data: &mut dyn InputBuffer,
734        _dest_address: &mut Option<SocketAddress>,
735        _ancillary_data: &mut Vec<AncillaryData>,
736    ) -> Result<usize, Errno> {
737        error!(EOPNOTSUPP)
738    }
739
740    fn wait_async(
741        &self,
742        _locked: &mut Locked<FileOpsCore>,
743        _socket: &Socket,
744        _current_task: &CurrentTask,
745        waiter: &Waiter,
746        events: FdEvents,
747        handler: EventHandler,
748    ) -> WaitCanceler {
749        self.lock().wait_async(waiter, events, handler)
750    }
751
752    fn query_events(
753        &self,
754        _locked: &mut Locked<FileOpsCore>,
755        _socket: &Socket,
756        _current_task: &CurrentTask,
757    ) -> Result<FdEvents, Errno> {
758        Ok(self.lock().query_events() & FdEvents::POLLIN)
759    }
760
761    fn shutdown(
762        &self,
763        _locked: &mut Locked<FileOpsCore>,
764        _socket: &Socket,
765        _how: SocketShutdownFlags,
766    ) -> Result<(), Errno> {
767        track_stub!(TODO("https://fxbug.dev/322875507"), "UEventNetlinkSocket::shutdown");
768        Ok(())
769    }
770
771    fn close(
772        &self,
773        locked: &mut Locked<FileOpsCore>,
774        current_task: &CurrentTask,
775        _socket: &Socket,
776    ) {
777        let id = self.device_listener_key.lock().take();
778        if let Some(id) = id {
779            current_task.kernel().device_registry.unregister_listener(locked, &id);
780        }
781    }
782
783    fn getsockname(
784        &self,
785        _locked: &mut Locked<FileOpsCore>,
786        _socket: &Socket,
787    ) -> Result<SocketAddress, Errno> {
788        self.lock().getsockname()
789    }
790
791    fn getpeername(
792        &self,
793        _locked: &mut Locked<FileOpsCore>,
794        _socket: &Socket,
795    ) -> Result<SocketAddress, Errno> {
796        self.lock().getpeername()
797    }
798
799    fn getsockopt(
800        &self,
801        _locked: &mut Locked<FileOpsCore>,
802        _socket: &Socket,
803        _current_task: &CurrentTask,
804        level: u32,
805        optname: u32,
806        _optlen: u32,
807    ) -> Result<Vec<u8>, Errno> {
808        self.lock().getsockopt(level, optname)
809    }
810
811    fn setsockopt(
812        &self,
813        _locked: &mut Locked<FileOpsCore>,
814        _socket: &Socket,
815        current_task: &CurrentTask,
816        level: u32,
817        optname: u32,
818        optval: SockOptValue,
819    ) -> Result<(), Errno> {
820        self.lock().setsockopt(current_task, level, optname, optval)
821    }
822}
823
824impl DeviceListener for Arc<Mutex<NetlinkSocketInner>> {
825    fn on_device_event(&self, action: UEventAction, device: Device, context: UEventContext) {
826        let path = device.path_from_depth(0);
827        let message = format!(
828            "{action}@/{path}\0\
829                            ACTION={action}\0\
830                            SEQNUM={seqnum}\0\
831                            {other_props}",
832            seqnum = context.seqnum,
833            other_props = device.uevent_properties('\0'),
834        );
835        let ancillary_data = AncillaryData::Unix(UnixControlData::Credentials(Default::default()));
836        let mut ancillary_data = vec![ancillary_data];
837        // Ignore write errors
838        let _ = self.lock().write_to_queue(
839            &mut VecInputBuffer::new(message.as_bytes()),
840            Some(NetlinkAddress { pid: 0, groups: 1 }),
841            &mut ancillary_data,
842        );
843    }
844}
845
846/// Type for sending messages from [`netlink::Netlink`] to an individual socket.
847#[derive(Clone)]
848pub struct NetlinkToClientSender<M> {
849    /// The inner socket implementation, which holds a message queue.
850    inner: Arc<Mutex<NetlinkSocketInner>>,
851
852    /// `PhantomData<fn(M) -> M>` is used instead of `PhantomData<M>` in order
853    /// to ensure that the type is invariant over `M` and that it implements
854    /// `Sync` even if `M` is not `Sync`.
855    _message_type: PhantomData<fn(M) -> M>,
856}
857
858impl<M> NetlinkToClientSender<M> {
859    fn new(inner: Arc<Mutex<NetlinkSocketInner>>) -> Self {
860        NetlinkToClientSender { _message_type: Default::default(), inner }
861    }
862}
863
864impl<M: Clone + NetlinkSerializable + Send> Sender<M> for NetlinkToClientSender<M> {
865    fn send(&mut self, message: NetlinkMessage<M>, group: Option<ModernGroup>) {
866        // Serialize the message
867        let mut buf = vec![0; message.buffer_len()];
868        message.emit(&mut buf);
869        let mut buf: VecInputBuffer = buf.into();
870        // Write the message into the inner socket buffer.
871        let NetlinkToClientSender { _message_type: _, inner } = self;
872        let mut guard = inner.lock();
873
874        // To avoid dropping messages when the receive buffer is
875        // full, grow the buffer on behalf of the client.
876        // This is a stop gap measure to avoid dropping messages
877        // when netlink produces a large response to a
878        // NLM_F_DUMP request.
879        //
880        // TODO(https://fxbug.dev/459883760): The memory
881        // implications of this may be problematic. It should be
882        // replaced with a proper mechanism to handle a backlog
883        // of NLM_F_DUMP responses.
884        let available = guard.receive_buffer.available_capacity();
885        let required = buf.available();
886        if available < required {
887            let delta = required - available;
888            let current_capacity = guard.receive_buffer.capacity();
889            let new_capacity = (current_capacity + delta).min(SOCKET_MAX_SIZE);
890            match guard.receive_buffer.set_capacity(new_capacity) {
891                Ok(()) => {}
892                Err(e) => {
893                    log_error!(
894                        tag = NETLINK_LOG_TAG;
895                        "Failed to increase receive buffer size: {:?}",
896                        e
897                    );
898                }
899            }
900        }
901
902        let _bytes_written: usize = guard
903            .write_to_queue(
904                &mut buf,
905                Some(NetlinkAddress {
906                    // All messages come from the "kernel" which has PID of 0.
907                    pid: 0,
908                    // If this is a multicast message, set the group the multicast
909                    // message is from.
910                    groups: group
911                        .map(SingleLegacyGroup::try_from)
912                        .and_then(Result::<_, NoMappingFromModernToLegacyGroupError>::ok)
913                        .map_or(0, |g| g.inner()),
914                }),
915                &mut Vec::new(),
916            )
917            .unwrap_or_else(|e| {
918                log_error!(
919                    tag = NETLINK_LOG_TAG;
920                    "Failed to write message into buffer for socket. Errno: {:?}",
921                    e
922                );
923                0
924            });
925    }
926}
927
928#[derive(Clone)]
929pub struct NetlinkAccessControl<'a> {
930    current_task: &'a CurrentTask,
931}
932
933impl<'a> NetlinkAccessControl<'a> {
934    pub fn new(current_task: &'a CurrentTask) -> Self {
935        Self { current_task }
936    }
937}
938
939impl<'a> AccessControl<FullCredentials> for NetlinkAccessControl<'a> {
940    fn grant_assess(
941        &self,
942        creds: &FullCredentials,
943        permission: Permission,
944    ) -> Result<(), netlink::Errno> {
945        let need_cap_net_admin = match permission {
946            Permission::NetlinkRouteRead => false,
947            Permission::NetlinkRouteWrite => true,
948        };
949        if !need_cap_net_admin {
950            return Ok(());
951        }
952
953        self.current_task.override_creds(creds.clone(), || {
954            security::check_task_capable(self.current_task, CAP_NET_ADMIN).map_err(|error| {
955                netlink::Errno::new(error.code.error_code() as i32)
956                    .expect("Errno::error_code() is expected to be in range [1..max_i32]")
957            })
958        })
959    }
960}
961pub struct NetlinkContextImpl;
962
963impl NetlinkContext for NetlinkContextImpl {
964    type Creds = FullCredentials;
965    type Sender<M: Clone + NetlinkSerializable + Send> = NetlinkToClientSender<M>;
966    type Receiver<
967        M: Send + MessageWithPermission + NetlinkDeserializable<Error: Into<DecodeError>>,
968    > = UnboundedReceiver<NetlinkMessageWithCreds<UnparsedNetlinkMessage<Vec<u8>, M>, Self::Creds>>;
969    type AccessControl<'a> = NetlinkAccessControl<'a>;
970}
971
972fn bind_netlink_socket<C: NetlinkClient>(
973    inner: &Arc<Mutex<NetlinkSocketInner>>,
974    client: &C,
975    current_task: &CurrentTask,
976    socket_address: SocketAddress,
977) -> Result<(), Errno> {
978    let multicast_groups = match &socket_address {
979        SocketAddress::Netlink(NetlinkAddress { pid: _, groups }) => *groups,
980        _ => return error!(EINVAL),
981    };
982    let pid = {
983        let mut inner = inner.lock();
984        inner.bind(current_task, socket_address)?;
985        inner.address.as_ref().and_then(|NetlinkAddress { pid, groups: _ }| NonZeroU32::new(*pid))
986    };
987    if let Some(pid) = pid {
988        client.set_pid(pid);
989    }
990    // This "blocks" in order to synchronize with the internal
991    // state of the netlink worker, but we're not blocking on
992    // the completion of any i/o or any expensive computation,
993    // so there's no need to support interrupts here.
994    client
995        .set_legacy_memberships(LegacyGroups(multicast_groups))
996        .map_err(|InvalidLegacyGroupsError {}| errno!(EPERM))?
997        .wait_until_complete();
998    Ok(())
999}
1000
1001fn send_netlink_message<M>(
1002    current_task: &CurrentTask,
1003    socket: &Socket,
1004    data: &mut dyn InputBuffer,
1005    message_sender: &UnboundedSender<
1006        NetlinkMessageWithCreds<UnparsedNetlinkMessage<Vec<u8>, M>, FullCredentials>,
1007    >,
1008) -> Result<usize, Errno>
1009where
1010    M: Send + 'static,
1011{
1012    let bytes = data.peek_all()?;
1013    let bytes_len = bytes.len();
1014
1015    // Parse only the netlink header to send it through security check.
1016    match NetlinkBuffer::new(&bytes) {
1017        Ok(buffer) => {
1018            security::check_netlink_send_access(current_task, socket, buffer.message_type())?;
1019        }
1020        Err(e) => {
1021            // If we can't even decode the header of the netlink message,
1022            // then return early here as a stronger statement that we're not
1023            // going to accidentally operate on it and violate the security
1024            // check. The netlink crate would end up dropping this with no
1025            // response as well.
1026            log_warn!(tag = NETLINK_LOG_TAG;
1027                "Failed to parse netlink header {e:?}"
1028            );
1029            data.drain();
1030            return Ok(bytes_len);
1031        }
1032    }
1033
1034    let msg = NetlinkMessageWithCreds::new(
1035        UnparsedNetlinkMessage::new(bytes),
1036        current_task.full_current_creds(),
1037    );
1038    message_sender.unbounded_send(msg).map_err(|e| {
1039        log_warn!(
1040            tag = NETLINK_LOG_TAG;
1041            "Netlink receiver unexpectedly disconnected for socket: {:?}",
1042            e
1043        );
1044        errno!(EPIPE)
1045    })?;
1046    data.drain();
1047    Ok(bytes_len)
1048}
1049
1050/// Socket implementation for the NETLINK_ROUTE family of netlink sockets.
1051struct RouteNetlinkSocket {
1052    /// The inner Netlink socket implementation
1053    inner: Arc<Mutex<NetlinkSocketInner>>,
1054    /// The implementation of a client (socket connection) to NETLINK_ROUTE.
1055    client: NetlinkRouteClient,
1056    /// The sender of messages from this socket to Netlink.
1057    // TODO(https://issuetracker.google.com/285880057): Bound the capacity of
1058    // the "send buffer".
1059    message_sender: UnboundedSender<
1060        NetlinkMessageWithCreds<
1061            UnparsedNetlinkMessage<Vec<u8>, RouteNetlinkMessage>,
1062            FullCredentials,
1063        >,
1064    >,
1065}
1066
1067impl RouteNetlinkSocket {
1068    pub fn new(kernel: &Arc<Kernel>) -> Result<Self, Errno> {
1069        let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::Route)));
1070        let (message_sender, message_receiver) = mpsc::unbounded();
1071        let client = match kernel
1072            .network_netlink()
1073            .new_route_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
1074        {
1075            Ok(client) => client,
1076            Err(NewClientError::Disconnected) => {
1077                log_error!(
1078                    tag = NETLINK_LOG_TAG;
1079                    "Netlink async worker is unexpectedly disconnected"
1080                );
1081                return error!(EPIPE);
1082            }
1083        };
1084        Ok(RouteNetlinkSocket { inner, client, message_sender })
1085    }
1086}
1087
1088impl SocketOps for RouteNetlinkSocket {
1089    fn connect(
1090        &self,
1091        _locked: &mut Locked<FileOpsCore>,
1092        _socket: &SocketHandle,
1093        current_task: &CurrentTask,
1094        peer: SocketPeer,
1095    ) -> Result<(), Errno> {
1096        let RouteNetlinkSocket { inner, client: _, message_sender: _ } = self;
1097        inner.lock().connect(current_task, peer)
1098    }
1099
1100    fn listen(
1101        &self,
1102        _locked: &mut Locked<FileOpsCore>,
1103        _socket: &Socket,
1104        _backlog: i32,
1105        _credentials: ucred,
1106    ) -> Result<(), Errno> {
1107        error!(EOPNOTSUPP)
1108    }
1109
1110    fn accept(
1111        &self,
1112        _locked: &mut Locked<FileOpsCore>,
1113        _socket: &Socket,
1114        _current_task: &CurrentTask,
1115    ) -> Result<SocketHandle, Errno> {
1116        error!(EOPNOTSUPP)
1117    }
1118
1119    fn bind(
1120        &self,
1121        _locked: &mut Locked<FileOpsCore>,
1122        _socket: &Socket,
1123        current_task: &CurrentTask,
1124        socket_address: SocketAddress,
1125    ) -> Result<(), Errno> {
1126        let RouteNetlinkSocket { inner, client, message_sender: _ } = self;
1127        bind_netlink_socket(inner, client, current_task, socket_address)
1128    }
1129
1130    fn read(
1131        &self,
1132        _locked: &mut Locked<FileOpsCore>,
1133        _socket: &Socket,
1134        _current_task: &CurrentTask,
1135        data: &mut dyn OutputBuffer,
1136        flags: SocketMessageFlags,
1137    ) -> Result<MessageReadInfo, Errno> {
1138        let RouteNetlinkSocket { inner, client: _, message_sender: _ } = self;
1139        inner.lock().read_datagram(data, flags)
1140    }
1141
1142    fn write(
1143        &self,
1144        _locked: &mut Locked<FileOpsCore>,
1145        socket: &Socket,
1146        current_task: &CurrentTask,
1147        data: &mut dyn InputBuffer,
1148        _dest_address: &mut Option<SocketAddress>,
1149        _ancillary_data: &mut Vec<AncillaryData>,
1150    ) -> Result<usize, Errno> {
1151        let RouteNetlinkSocket { inner: _, client: _, message_sender } = self;
1152        send_netlink_message(current_task, socket, data, message_sender)
1153    }
1154
1155    fn wait_async(
1156        &self,
1157        _locked: &mut Locked<FileOpsCore>,
1158        _socket: &Socket,
1159        _current_task: &CurrentTask,
1160        waiter: &Waiter,
1161        events: FdEvents,
1162        handler: EventHandler,
1163    ) -> WaitCanceler {
1164        let RouteNetlinkSocket { inner, client: _, message_sender: _ } = self;
1165        inner.lock().wait_async(waiter, events, handler)
1166    }
1167
1168    fn query_events(
1169        &self,
1170        _locked: &mut Locked<FileOpsCore>,
1171        _socket: &Socket,
1172        _current_task: &CurrentTask,
1173    ) -> Result<FdEvents, Errno> {
1174        let RouteNetlinkSocket { inner, client: _, message_sender: _ } = self;
1175        Ok(inner.lock().query_events() & FdEvents::POLLIN)
1176    }
1177
1178    fn shutdown(
1179        &self,
1180        _locked: &mut Locked<FileOpsCore>,
1181        _socket: &Socket,
1182        _how: SocketShutdownFlags,
1183    ) -> Result<(), Errno> {
1184        error!(EOPNOTSUPP)
1185    }
1186
1187    fn close(
1188        &self,
1189        _locked: &mut Locked<FileOpsCore>,
1190        _current_task: &CurrentTask,
1191        _socket: &Socket,
1192    ) {
1193        // Close the underlying channel to the Netlink worker.
1194        self.message_sender.close_channel();
1195    }
1196
1197    fn getsockname(
1198        &self,
1199        _locked: &mut Locked<FileOpsCore>,
1200        _socket: &Socket,
1201    ) -> Result<SocketAddress, Errno> {
1202        let RouteNetlinkSocket { inner, client: _, message_sender: _ } = self;
1203        inner.lock().getsockname()
1204    }
1205
1206    fn getpeername(
1207        &self,
1208        _locked: &mut Locked<FileOpsCore>,
1209        _socket: &Socket,
1210    ) -> Result<SocketAddress, Errno> {
1211        self.inner.lock().getpeername()
1212    }
1213
1214    fn getsockopt(
1215        &self,
1216        _locked: &mut Locked<FileOpsCore>,
1217        _socket: &Socket,
1218        _current_task: &CurrentTask,
1219        level: u32,
1220        optname: u32,
1221        _optlen: u32,
1222    ) -> Result<Vec<u8>, Errno> {
1223        self.inner.lock().getsockopt(level, optname)
1224    }
1225
1226    fn setsockopt(
1227        &self,
1228        _locked: &mut Locked<FileOpsCore>,
1229        _socket: &Socket,
1230        current_task: &CurrentTask,
1231        level: u32,
1232        optname: u32,
1233        optval: SockOptValue,
1234    ) -> Result<(), Errno> {
1235        match (level, optname) {
1236            (SOL_NETLINK, NETLINK_ADD_MEMBERSHIP) => {
1237                let RouteNetlinkSocket { inner: _, client, message_sender: _ } = self;
1238                let group: u32 = optval.read(current_task)?;
1239                let async_work = client
1240                    .add_membership(ModernGroup(group))
1241                    .map_err(|InvalidModernGroupError| errno!(EINVAL))?;
1242                // This "blocks" in order to synchronize with the internal
1243                // state of the rtnetlink worker, but we're not blocking on
1244                // the completion of any i/o or any expensive computation,
1245                // so there's no need to support interrupts here.
1246                async_work.wait_until_complete();
1247                Ok(())
1248            }
1249            (SOL_NETLINK, NETLINK_DROP_MEMBERSHIP) => {
1250                let RouteNetlinkSocket { inner: _, client, message_sender: _ } = self;
1251                let group: u32 = optval.read(current_task)?;
1252                client
1253                    .del_membership(ModernGroup(group))
1254                    .map_err(|InvalidModernGroupError| errno!(EINVAL))?;
1255                Ok(())
1256            }
1257            _ => self.inner.lock().setsockopt(current_task, level, optname, optval),
1258        }
1259    }
1260}
1261
1262/// Socket implementation for the NETLINK_SOCK_DIAG family of netlink sockets.
1263struct SockDiagNetlinkSocket {
1264    /// The inner Netlink socket implementation
1265    inner: Arc<Mutex<NetlinkSocketInner>>,
1266}
1267
1268impl Default for SockDiagNetlinkSocket {
1269    fn default() -> Self {
1270        Self { inner: Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::SockDiag))) }
1271    }
1272}
1273
1274impl SocketOps for SockDiagNetlinkSocket {
1275    fn connect(
1276        &self,
1277        _locked: &mut Locked<FileOpsCore>,
1278        _socket: &SocketHandle,
1279        current_task: &CurrentTask,
1280        peer: SocketPeer,
1281    ) -> Result<(), Errno> {
1282        self.inner.lock().connect(current_task, peer)
1283    }
1284
1285    fn listen(
1286        &self,
1287        _locked: &mut Locked<FileOpsCore>,
1288        _socket: &Socket,
1289        _backlog: i32,
1290        _credentials: ucred,
1291    ) -> Result<(), Errno> {
1292        error!(EOPNOTSUPP)
1293    }
1294
1295    fn accept(
1296        &self,
1297        _locked: &mut Locked<FileOpsCore>,
1298        _socket: &Socket,
1299        _current_task: &CurrentTask,
1300    ) -> Result<SocketHandle, Errno> {
1301        error!(EOPNOTSUPP)
1302    }
1303
1304    fn bind(
1305        &self,
1306        _locked: &mut Locked<FileOpsCore>,
1307        _socket: &Socket,
1308        current_task: &CurrentTask,
1309        socket_address: SocketAddress,
1310    ) -> Result<(), Errno> {
1311        self.inner.lock().bind(current_task, socket_address)
1312    }
1313
1314    fn read(
1315        &self,
1316        _locked: &mut Locked<FileOpsCore>,
1317        _socket: &Socket,
1318        _current_task: &CurrentTask,
1319        data: &mut dyn OutputBuffer,
1320        flags: SocketMessageFlags,
1321    ) -> Result<MessageReadInfo, Errno> {
1322        self.inner.lock().read_datagram(data, flags)
1323    }
1324
1325    fn write(
1326        &self,
1327        _locked: &mut Locked<FileOpsCore>,
1328        _socket: &Socket,
1329        _current_task: &CurrentTask,
1330        _data: &mut dyn InputBuffer,
1331        _dest_address: &mut Option<SocketAddress>,
1332        _ancillary_data: &mut Vec<AncillaryData>,
1333    ) -> Result<usize, Errno> {
1334        track_stub!(TODO("https://fxbug.dev/323590076"), "NETLINK_SOCK_DIAG handle request");
1335        error!(ENOTSUP)
1336    }
1337
1338    fn wait_async(
1339        &self,
1340        _locked: &mut Locked<FileOpsCore>,
1341        _socket: &Socket,
1342        _current_task: &CurrentTask,
1343        waiter: &Waiter,
1344        events: FdEvents,
1345        handler: EventHandler,
1346    ) -> WaitCanceler {
1347        self.inner.lock().wait_async(waiter, events, handler)
1348    }
1349
1350    fn query_events(
1351        &self,
1352        _locked: &mut Locked<FileOpsCore>,
1353        _socket: &Socket,
1354        _current_task: &CurrentTask,
1355    ) -> Result<FdEvents, Errno> {
1356        Ok(self.inner.lock().query_events() & FdEvents::POLLIN)
1357    }
1358
1359    fn shutdown(
1360        &self,
1361        _locked: &mut Locked<FileOpsCore>,
1362        _socket: &Socket,
1363        _how: SocketShutdownFlags,
1364    ) -> Result<(), Errno> {
1365        error!(EOPNOTSUPP)
1366    }
1367
1368    fn close(
1369        &self,
1370        _locked: &mut Locked<FileOpsCore>,
1371        _current_task: &CurrentTask,
1372        _socket: &Socket,
1373    ) {
1374    }
1375
1376    fn getsockname(
1377        &self,
1378        _locked: &mut Locked<FileOpsCore>,
1379        _socket: &Socket,
1380    ) -> Result<SocketAddress, Errno> {
1381        self.inner.lock().getsockname()
1382    }
1383
1384    fn getpeername(
1385        &self,
1386        _locked: &mut Locked<FileOpsCore>,
1387        _socket: &Socket,
1388    ) -> Result<SocketAddress, Errno> {
1389        self.inner.lock().getpeername()
1390    }
1391
1392    fn getsockopt(
1393        &self,
1394        _locked: &mut Locked<FileOpsCore>,
1395        _socket: &Socket,
1396        _current_task: &CurrentTask,
1397        level: u32,
1398        optname: u32,
1399        _optlen: u32,
1400    ) -> Result<Vec<u8>, Errno> {
1401        self.inner.lock().getsockopt(level, optname)
1402    }
1403
1404    fn setsockopt(
1405        &self,
1406        _locked: &mut Locked<FileOpsCore>,
1407        _socket: &Socket,
1408        current_task: &CurrentTask,
1409        level: u32,
1410        optname: u32,
1411        optval: SockOptValue,
1412    ) -> Result<(), Errno> {
1413        self.inner.lock().setsockopt(current_task, level, optname, optval)
1414    }
1415}
1416
1417/// Socket implementation for the NETLINK_GENERIC family of netlink sockets.
1418struct GenericNetlinkSocket {
1419    inner: Arc<Mutex<NetlinkSocketInner>>,
1420    client: GenericNetlinkClientHandle<NetlinkToClientSender<GenericMessage>>,
1421    message_sender: mpsc::UnboundedSender<NetlinkMessage<GenericMessage>>,
1422}
1423
1424impl GenericNetlinkSocket {
1425    pub fn new(kernel: &Kernel) -> Result<Self, Errno> {
1426        let inner = Arc::new(Mutex::new(NetlinkSocketInner::new(NetlinkFamily::Generic)));
1427        let (message_sender, message_receiver) = mpsc::unbounded();
1428        match kernel
1429            .generic_netlink()
1430            .new_generic_client(NetlinkToClientSender::new(inner.clone()), message_receiver)
1431        {
1432            Ok(client) => Ok(Self { inner, client, message_sender }),
1433            Err(e) => {
1434                log_warn!(
1435                    tag = NETLINK_LOG_TAG;
1436                    "Failed to connect to generic netlink server. Errno: {:?}",
1437                    e
1438                );
1439                error!(EPIPE)
1440            }
1441        }
1442    }
1443
1444    /// Locks and returns the inner state of the Socket.
1445    fn lock(&self) -> starnix_sync::MutexGuard<'_, NetlinkSocketInner> {
1446        self.inner.lock()
1447    }
1448}
1449
1450impl SocketOps for GenericNetlinkSocket {
1451    fn connect(
1452        &self,
1453        _locked: &mut Locked<FileOpsCore>,
1454        _socket: &SocketHandle,
1455        current_task: &CurrentTask,
1456        peer: SocketPeer,
1457    ) -> Result<(), Errno> {
1458        let mut state = self.lock();
1459        state.connect(current_task, peer)
1460    }
1461
1462    fn listen(
1463        &self,
1464        _locked: &mut Locked<FileOpsCore>,
1465        _socket: &Socket,
1466        _backlog: i32,
1467        _credentials: ucred,
1468    ) -> Result<(), Errno> {
1469        error!(EOPNOTSUPP)
1470    }
1471
1472    fn accept(
1473        &self,
1474        _locked: &mut Locked<FileOpsCore>,
1475        _socket: &Socket,
1476        _current_task: &CurrentTask,
1477    ) -> Result<SocketHandle, Errno> {
1478        error!(EOPNOTSUPP)
1479    }
1480
1481    fn bind(
1482        &self,
1483        _locked: &mut Locked<FileOpsCore>,
1484        _socket: &Socket,
1485        current_task: &CurrentTask,
1486        socket_address: SocketAddress,
1487    ) -> Result<(), Errno> {
1488        let mut state = self.lock();
1489        state.bind(current_task, socket_address)
1490    }
1491
1492    fn read(
1493        &self,
1494        _locked: &mut Locked<FileOpsCore>,
1495        _socket: &Socket,
1496        _current_task: &CurrentTask,
1497        data: &mut dyn OutputBuffer,
1498        flags: SocketMessageFlags,
1499    ) -> Result<MessageReadInfo, Errno> {
1500        self.lock().read_datagram(data, flags)
1501    }
1502
1503    fn write(
1504        &self,
1505        _locked: &mut Locked<FileOpsCore>,
1506        _socket: &Socket,
1507        _current_task: &CurrentTask,
1508        data: &mut dyn InputBuffer,
1509        _dest_address: &mut Option<SocketAddress>,
1510        _ancillary_data: &mut Vec<AncillaryData>,
1511    ) -> Result<usize, Errno> {
1512        let bytes = data.read_all()?;
1513        match NetlinkMessage::<GenericMessage>::deserialize(&bytes) {
1514            Err(e) => {
1515                log_warn!("Failed to process write; data could not be deserialized: {:?}", e);
1516                error!(EINVAL)
1517            }
1518            Ok(msg) => match self.message_sender.unbounded_send(msg) {
1519                Ok(()) => Ok(bytes.len()),
1520                Err(e) => {
1521                    log_warn!("Netlink receiver unexpectedly disconnected for socket: {:?}", e);
1522                    error!(EPIPE)
1523                }
1524            },
1525        }
1526    }
1527
1528    fn wait_async(
1529        &self,
1530        _locked: &mut Locked<FileOpsCore>,
1531        _socket: &Socket,
1532        _current_task: &CurrentTask,
1533        waiter: &Waiter,
1534        events: FdEvents,
1535        handler: EventHandler,
1536    ) -> WaitCanceler {
1537        self.lock().wait_async(waiter, events, handler)
1538    }
1539
1540    fn query_events(
1541        &self,
1542        _locked: &mut Locked<FileOpsCore>,
1543        _socket: &Socket,
1544        _current_task: &CurrentTask,
1545    ) -> Result<FdEvents, Errno> {
1546        Ok(self.lock().query_events() & FdEvents::POLLIN)
1547    }
1548
1549    fn shutdown(
1550        &self,
1551        _locked: &mut Locked<FileOpsCore>,
1552        _socket: &Socket,
1553        _how: SocketShutdownFlags,
1554    ) -> Result<(), Errno> {
1555        track_stub!(TODO("https://fxbug.dev/322875507"), "GenericNetlinkSocket::shutdown");
1556        Ok(())
1557    }
1558
1559    fn close(
1560        &self,
1561        _locked: &mut Locked<FileOpsCore>,
1562        _current_task: &CurrentTask,
1563        _socket: &Socket,
1564    ) {
1565    }
1566
1567    fn getsockname(
1568        &self,
1569        _locked: &mut Locked<FileOpsCore>,
1570        _socket: &Socket,
1571    ) -> Result<SocketAddress, Errno> {
1572        self.lock().getsockname()
1573    }
1574
1575    fn getpeername(
1576        &self,
1577        _locked: &mut Locked<FileOpsCore>,
1578        _socket: &Socket,
1579    ) -> Result<SocketAddress, Errno> {
1580        self.lock().getpeername()
1581    }
1582
1583    fn getsockopt(
1584        &self,
1585        _locked: &mut Locked<FileOpsCore>,
1586        _socket: &Socket,
1587        _current_task: &CurrentTask,
1588        level: u32,
1589        optname: u32,
1590        _optlen: u32,
1591    ) -> Result<Vec<u8>, Errno> {
1592        self.lock().getsockopt(level, optname)
1593    }
1594
1595    fn setsockopt(
1596        &self,
1597        _locked: &mut Locked<FileOpsCore>,
1598        _socket: &Socket,
1599        current_task: &CurrentTask,
1600        level: u32,
1601        optname: u32,
1602        optval: SockOptValue,
1603    ) -> Result<(), Errno> {
1604        match (level, optname) {
1605            (SOL_NETLINK, NETLINK_ADD_MEMBERSHIP) => {
1606                let group_id: u32 = optval.read(current_task)?;
1607                self.client.add_membership(ModernGroup(group_id))
1608            }
1609            _ => self.lock().setsockopt(current_task, level, optname, optval),
1610        }
1611    }
1612}
1613
1614/// Audit client that can be attached to the `AuditLogger`.
1615pub struct AuditNetlinkClient {
1616    /// Reference to the `AuditLogger`.
1617    audit_logger: Arc<AuditLogger>,
1618    /// The waiters queue present in `AuditNetlinkSocket`.
1619    waiters: WaitQueue,
1620    /// Optional response from the `AuditLogger`.
1621    audit_response: Mutex<Option<NetlinkMessage<GenericMessage>>>,
1622}
1623
1624impl AuditNetlinkClient {
1625    fn new(audit_logger: Arc<AuditLogger>) -> Self {
1626        Self { audit_logger, waiters: Default::default(), audit_response: Mutex::new(None) }
1627    }
1628
1629    pub fn notify(&self) {
1630        self.waiters.notify_fd_events(FdEvents::POLLIN);
1631    }
1632
1633    /// Function to check the capabilities of the current task against CAP_AUDIT_*
1634    fn check_audit_access(
1635        &self,
1636        current_task: &CurrentTask,
1637        request_type: &AuditRequest,
1638    ) -> Result<(), Errno> {
1639        match request_type {
1640            AuditRequest::AuditGet | AuditRequest::AuditSet => {
1641                security::check_task_capable(current_task, CAP_AUDIT_CONTROL)
1642            }
1643            AuditRequest::AuditUser => security::check_task_capable(current_task, CAP_AUDIT_WRITE),
1644        }
1645    }
1646
1647    /// Function to process request coming from userspace, it returns the response after processing
1648    fn process_request(
1649        self: &Arc<Self>,
1650        current_task: &CurrentTask,
1651        nl_message: NetlinkMessage<GenericMessage>,
1652    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1653        let (nl_header, nl_payload) = nl_message.into_parts();
1654        let audit_request_type = AuditRequest::try_from(nl_header.message_type as u32)?;
1655        self.check_audit_access(current_task, &audit_request_type)?;
1656
1657        // If there is no GenericMessage, return an ErrorMessage.
1658        let NetlinkPayload::InnerMessage(GenericMessage::Other { payload, .. }) = nl_payload else {
1659            return error!(EINVAL);
1660        };
1661        match audit_request_type {
1662            AuditRequest::AuditGet => self.process_get_status(nl_header.sequence_number),
1663            AuditRequest::AuditSet => self.process_set_status(current_task, nl_header, payload),
1664            AuditRequest::AuditUser => self.process_user_audit(nl_header, payload),
1665        }
1666    }
1667
1668    fn get_nl_response(&self, flags: SocketMessageFlags) -> Option<Vec<u8>> {
1669        if flags.contains(SocketMessageFlags::PEEK) {
1670            if let Some(message) = self.audit_response.lock().as_ref() {
1671                return Some(AuditNetlinkClient::serialize_nlmsg(message.clone()));
1672            }
1673        } else if let Some(message) = self.audit_response.lock().take() {
1674            return Some(AuditNetlinkClient::serialize_nlmsg(message));
1675        }
1676        None
1677    }
1678
1679    /// Function to read an audit message from `AuditLogger`.
1680    fn read_audit_log(self: &Arc<Self>) -> Option<Vec<u8>> {
1681        if let Some(AuditMessage { audit_type, message }) = self.audit_logger.read_audit_log(self) {
1682            return Some(AuditNetlinkClient::serialize_nlmsg(
1683                AuditNetlinkClient::build_audit_nlmsg(0, audit_type, message),
1684            ));
1685        }
1686        None
1687    }
1688
1689    /// Function to read the optional response if present or an audit message.
1690    fn read_nlmsg(self: &Arc<Self>, flags: SocketMessageFlags) -> Result<Vec<u8>, Errno> {
1691        // First check if there is a response and send it if present.
1692        // Send an audit message otherwise or return EAGAIN.
1693        self.get_nl_response(flags).or_else(|| self.read_audit_log()).ok_or_else(|| errno!(EAGAIN))
1694    }
1695
1696    fn process_get_status(
1697        &self,
1698        sequence_number: u32,
1699    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1700        Ok(AuditNetlinkClient::build_audit_nlmsg(
1701            sequence_number,
1702            AUDIT_GET as u16,
1703            self.audit_logger.get_status().as_bytes().to_vec(),
1704        ))
1705    }
1706
1707    fn process_set_status(
1708        self: &Arc<Self>,
1709        current_task: &CurrentTask,
1710        nl_hdr: NetlinkHeader,
1711        nl_payload: Vec<u8>,
1712    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1713        let Some(status) = audit_status::read_from_bytes(nl_payload.as_bytes()).ok() else {
1714            return error!(EINVAL);
1715        };
1716        self.audit_logger.set_status(current_task, status, self)?;
1717        Ok(AuditNetlinkClient::build_audit_ack(Ok(()), nl_hdr))
1718    }
1719
1720    fn process_user_audit(
1721        &self,
1722        nl_hdr: NetlinkHeader,
1723        nl_payload: Vec<u8>,
1724    ) -> Result<NetlinkMessage<GenericMessage>, Errno> {
1725        let audit_msg = String::from_utf8_lossy(nl_payload.as_bytes());
1726        self.audit_logger.audit_log(nl_hdr.message_type, move || audit_msg);
1727        Ok(AuditNetlinkClient::build_audit_ack(Ok(()), nl_hdr))
1728    }
1729
1730    fn query_events(self: &Arc<Self>) -> FdEvents {
1731        if self.audit_response.lock().is_some() || self.audit_logger.get_backlog_count(self) != 0 {
1732            return FdEvents::POLLIN;
1733        }
1734        FdEvents::empty()
1735    }
1736
1737    fn detach(self: &Arc<Self>) {
1738        self.audit_logger.detach_client(self);
1739    }
1740
1741    fn build_audit_nlmsg(
1742        seq_number: u32,
1743        msg_type: u16,
1744        payload: Vec<u8>,
1745    ) -> NetlinkMessage<GenericMessage> {
1746        // The family in GenericMessage can be used for message type, not only for the Netlink Family,
1747        // because after finalizing the message, the message type is equal to family.
1748        let nl_payload =
1749            NetlinkPayload::InnerMessage(GenericMessage::Other { family: msg_type, payload });
1750        let mut nl_header = NetlinkHeader::default();
1751        nl_header.sequence_number = seq_number;
1752        let mut message = NetlinkMessage::new(nl_header, nl_payload);
1753        message.finalize();
1754        message
1755    }
1756
1757    fn build_audit_ack(
1758        error: Result<(), Errno>,
1759        req_header: NetlinkHeader,
1760    ) -> NetlinkMessage<GenericMessage> {
1761        let error = {
1762            assert_eq!(req_header.buffer_len(), NETLINK_HEADER_LEN);
1763            let mut buffer = vec![0; NETLINK_HEADER_LEN];
1764            req_header.emit(&mut buffer);
1765
1766            let code = match error {
1767                Ok(()) => None,
1768                Err(e) => Some(
1769                    // Audit netlink errors are negative.
1770                    NonZeroI32::new(-(e.code.error_code() as i32))
1771                        .expect("Errno's code must be non-zero"),
1772                ),
1773            };
1774
1775            let mut error = ErrorMessage::default();
1776            error.code = code;
1777            error.header = buffer;
1778            error
1779        };
1780
1781        let payload = NetlinkPayload::<GenericMessage>::Error(error);
1782        let mut resp_header = NetlinkHeader::default();
1783        resp_header.message_type = NLMSG_ERROR;
1784        resp_header.sequence_number = req_header.sequence_number;
1785        let mut message = NetlinkMessage::new(resp_header, payload);
1786        message.finalize();
1787        message
1788    }
1789
1790    fn serialize_nlmsg(message: NetlinkMessage<GenericMessage>) -> Vec<u8> {
1791        let mut buf = vec![0; message.buffer_len()];
1792        message.serialize(&mut buf);
1793        buf
1794    }
1795}
1796
1797/// Audit Netlink Socket structure.
1798pub struct AuditNetlinkSocket {
1799    /// Reference to the `AuditNetlinkClient` associated with self.
1800    audit_client: Arc<AuditNetlinkClient>,
1801}
1802
1803impl AuditNetlinkSocket {
1804    pub fn new(kernel: &Kernel) -> Result<Self, Errno> {
1805        if kernel.audit_logger().is_disabled() {
1806            return error!(EPROTONOSUPPORT);
1807        }
1808        Ok(Self { audit_client: Arc::new(AuditNetlinkClient::new(kernel.audit_logger())) })
1809    }
1810}
1811
1812impl SocketOps for AuditNetlinkSocket {
1813    fn read(
1814        &self,
1815        _locked: &mut Locked<FileOpsCore>,
1816        _socket: &Socket,
1817        _current_task: &CurrentTask,
1818        data: &mut dyn OutputBuffer,
1819        flags: SocketMessageFlags,
1820    ) -> Result<MessageReadInfo, Errno> {
1821        let buf = self.audit_client.read_nlmsg(flags)?;
1822
1823        let size = data.write_all(buf.as_bytes())?;
1824        Ok(MessageReadInfo {
1825            bytes_read: size,
1826            message_length: size,
1827            address: Some(SocketAddress::Netlink(NetlinkAddress::default())),
1828            ancillary_data: vec![],
1829        })
1830    }
1831
1832    fn write(
1833        &self,
1834        _locked: &mut Locked<FileOpsCore>,
1835        socket: &Socket,
1836        current_task: &CurrentTask,
1837        data: &mut dyn InputBuffer,
1838        _dest_address: &mut Option<SocketAddress>,
1839        _ancillary_data: &mut Vec<AncillaryData>,
1840    ) -> Result<usize, Errno> {
1841        match NetlinkMessage::<GenericMessage>::deserialize(&(data.peek_all()?)) {
1842            Ok(nl_message) => {
1843                let header = nl_message.header;
1844                security::check_netlink_send_access(current_task, socket, header.message_type)?;
1845
1846                // Send request to the `AuditNetlinkClient`.
1847                let audit_ack = self
1848                    .audit_client
1849                    .process_request(current_task, nl_message)
1850                    .map_err(|e| AuditNetlinkClient::build_audit_ack(Err(e), header))
1851                    .unwrap_or_else(|nlerr| nlerr);
1852                *self.audit_client.audit_response.lock() = Some(audit_ack);
1853                data.drain();
1854                Ok(header.length as usize)
1855            }
1856            Err(e) => {
1857                log_warn!("Failed to process write; data could not be deserialized: {:?}", e);
1858                error!(EINVAL)
1859            }
1860        }
1861    }
1862
1863    fn wait_async(
1864        &self,
1865        _locked: &mut Locked<FileOpsCore>,
1866        _socket: &Socket,
1867        _current_task: &CurrentTask,
1868        waiter: &Waiter,
1869        events: FdEvents,
1870        handler: EventHandler,
1871    ) -> WaitCanceler {
1872        self.audit_client.waiters.wait_async_fd_events(waiter, events, handler)
1873    }
1874
1875    fn query_events(
1876        &self,
1877        _locked: &mut Locked<FileOpsCore>,
1878        _socket: &Socket,
1879        _current_task: &CurrentTask,
1880    ) -> Result<FdEvents, Errno> {
1881        Ok(self.audit_client.query_events() & FdEvents::POLLIN)
1882    }
1883
1884    fn close(
1885        &self,
1886        _locked: &mut Locked<FileOpsCore>,
1887        _current_task: &CurrentTask,
1888        _socket: &Socket,
1889    ) {
1890        // If the `AuditNetlinkClient` disconnects, detach it.
1891        self.audit_client.detach();
1892    }
1893
1894    fn shutdown(
1895        &self,
1896        _locked: &mut Locked<FileOpsCore>,
1897        _socket: &Socket,
1898        _how: SocketShutdownFlags,
1899    ) -> Result<(), Errno> {
1900        error!(EOPNOTSUPP)
1901    }
1902
1903    fn connect(
1904        &self,
1905        _locked: &mut Locked<FileOpsCore>,
1906        _socket: &SocketHandle,
1907        _current_task: &CurrentTask,
1908        _peer: SocketPeer,
1909    ) -> Result<(), Errno> {
1910        error!(EOPNOTSUPP)
1911    }
1912
1913    fn listen(
1914        &self,
1915        _locked: &mut Locked<FileOpsCore>,
1916        _socket: &Socket,
1917        _backlog: i32,
1918        _credentials: ucred,
1919    ) -> Result<(), Errno> {
1920        error!(EOPNOTSUPP)
1921    }
1922
1923    fn accept(
1924        &self,
1925        _locked: &mut Locked<FileOpsCore>,
1926        _socket: &Socket,
1927        _current_task: &CurrentTask,
1928    ) -> Result<SocketHandle, Errno> {
1929        error!(EOPNOTSUPP)
1930    }
1931
1932    fn bind(
1933        &self,
1934        _locked: &mut Locked<FileOpsCore>,
1935        _socket: &Socket,
1936        _current_task: &CurrentTask,
1937        _socket_address: SocketAddress,
1938    ) -> Result<(), Errno> {
1939        error!(EOPNOTSUPP)
1940    }
1941
1942    fn getsockname(
1943        &self,
1944        _locked: &mut Locked<FileOpsCore>,
1945        _socket: &Socket,
1946    ) -> Result<SocketAddress, Errno> {
1947        error!(EOPNOTSUPP)
1948    }
1949
1950    fn getpeername(
1951        &self,
1952        _locked: &mut Locked<FileOpsCore>,
1953        _socket: &Socket,
1954    ) -> Result<SocketAddress, Errno> {
1955        error!(EOPNOTSUPP)
1956    }
1957
1958    fn getsockopt(
1959        &self,
1960        _locked: &mut Locked<FileOpsCore>,
1961        _socket: &Socket,
1962        _current_task: &CurrentTask,
1963        _level: u32,
1964        _optname: u32,
1965        _optlen: u32,
1966    ) -> Result<Vec<u8>, Errno> {
1967        error!(EOPNOTSUPP)
1968    }
1969
1970    fn setsockopt(
1971        &self,
1972        _locked: &mut Locked<FileOpsCore>,
1973        _socket: &Socket,
1974        _current_task: &CurrentTask,
1975        _level: u32,
1976        _optname: u32,
1977        _optval: SockOptValue,
1978    ) -> Result<(), Errno> {
1979        error!(EOPNOTSUPP)
1980    }
1981}
1982
1983#[cfg(test)]
1984mod tests {
1985    use super::*;
1986
1987    use netlink_packet_route::route::RouteMessage;
1988    use test_case::test_case;
1989
1990    // Successfully send the message and observe it's stored in the queue.
1991    #[test_case(true; "sufficient_capacity")]
1992    // Attempting to send when the queue is full should succeed by increasing
1993    // the size of the queue.
1994    #[test_case(false; "insufficient_capacity")]
1995    fn test_netlink_to_client_sender(sufficient_capacity: bool) {
1996        const MODERN_GROUP: u32 = 5;
1997
1998        let mut message: NetlinkMessage<RouteNetlinkMessage> =
1999            RouteNetlinkMessage::NewRoute(RouteMessage::default()).into();
2000        message.finalize();
2001
2002        let (initial_queue_size, final_queue_size) = if sufficient_capacity {
2003            (SOCKET_DEFAULT_SIZE, SOCKET_DEFAULT_SIZE)
2004        } else {
2005            (0, message.buffer_len())
2006        };
2007
2008        let socket_inner = Arc::new(Mutex::new(NetlinkSocketInner {
2009            receive_buffer: MessageQueue::new(initial_queue_size),
2010            ..NetlinkSocketInner::new(NetlinkFamily::Route)
2011        }));
2012
2013        let mut sender = NetlinkToClientSender::<RouteNetlinkMessage>::new(socket_inner.clone());
2014        sender.send(message.clone(), Some(ModernGroup(MODERN_GROUP)));
2015        let Message { data, address, ancillary_data: _ } =
2016            socket_inner.lock().read_message().expect("should read message");
2017
2018        assert_eq!(
2019            address,
2020            Some(SocketAddress::Netlink(NetlinkAddress { pid: 0, groups: 1 << MODERN_GROUP }))
2021        );
2022        let actual_message = NetlinkMessage::<RouteNetlinkMessage>::deserialize(&data)
2023            .expect("message should deserialize into RtnlMessage");
2024        assert_eq!(actual_message, message);
2025        assert_eq!(socket_inner.lock().receive_buffer.capacity(), final_queue_size);
2026    }
2027
2028    fn getsockopt_u32(socket: &NetlinkSocketInner, level: u32, optname: u32) -> u32 {
2029        let byte_vec = socket.getsockopt(level, optname).expect("getsockopt should succeed");
2030        let bytes: [u8; 4] = byte_vec.as_slice().try_into().expect("expected 4 bytes");
2031        u32::from_ne_bytes(bytes)
2032    }
2033
2034    fn sock_opt_value(val: u32) -> SockOptValue {
2035        SockOptValue::Value(val.to_ne_bytes().to_vec())
2036    }
2037
2038    #[::fuchsia::test]
2039    async fn test_set_get_snd_rcv_buf() {
2040        crate::testing::spawn_kernel_and_run_sync(|_locked, current_task| {
2041            let mut socket = NetlinkSocketInner::new(NetlinkFamily::Route);
2042
2043            // Verify initialization uses the default value.
2044            let expected_default = u32::try_from(SOCKET_DEFAULT_SIZE).unwrap();
2045            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), expected_default);
2046            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), expected_default);
2047
2048            // Set new values and observe that they were applied.
2049            // Note that applied value is 2 times the requested value.
2050            const SNDBUF_SIZE: u32 = 12345;
2051            const RCVBUF_SIZE: u32 = 54321;
2052            socket
2053                .setsockopt(current_task, SOL_SOCKET, SO_SNDBUF, sock_opt_value(SNDBUF_SIZE))
2054                .expect("setsockopt should succeed");
2055            socket
2056                .setsockopt(current_task, SOL_SOCKET, SO_RCVBUF, sock_opt_value(RCVBUF_SIZE))
2057                .expect("setsockopt should succeed");
2058            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), SNDBUF_SIZE * 2);
2059            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), RCVBUF_SIZE * 2);
2060        })
2061        .await;
2062    }
2063
2064    #[::fuchsia::test]
2065    async fn test_snd_rcv_buf_limits() {
2066        crate::testing::spawn_kernel_and_run_sync(|_locked, current_task| {
2067            let mut socket = NetlinkSocketInner::new(NetlinkFamily::Route);
2068            let too_big = u32::try_from(SOCKET_MAX_SIZE).unwrap() + 1;
2069
2070            // SO_SNDBUF and SO_RCVBUF clamp the size to the limit.
2071            socket
2072                .setsockopt(current_task, SOL_SOCKET, SO_SNDBUF, sock_opt_value(too_big))
2073                .expect("setsockopt should succeed");
2074            socket
2075                .setsockopt(current_task, SOL_SOCKET, SO_RCVBUF, sock_opt_value(too_big))
2076                .expect("setsockopt should succeed");
2077            let expected_max = u32::try_from(SOCKET_MAX_SIZE).unwrap();
2078            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), expected_max);
2079            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), expected_max);
2080
2081            // SO_SNDBUFFORCE and SO_RCVBUFFORCE do not.
2082            // Note that the applied value is two times the requested value.
2083            socket
2084                .setsockopt(current_task, SOL_SOCKET, SO_SNDBUFFORCE, sock_opt_value(too_big))
2085                .expect("setsockopt should succeed");
2086            socket
2087                .setsockopt(current_task, SOL_SOCKET, SO_RCVBUFFORCE, sock_opt_value(too_big))
2088                .expect("setsockopt should succeed");
2089            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_SNDBUF), too_big * 2);
2090            assert_eq!(getsockopt_u32(&socket, SOL_SOCKET, SO_RCVBUF), too_big * 2);
2091        })
2092        .await;
2093    }
2094}