Skip to main content

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