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