Skip to main content

netstack3_device/
socket.rs

1// Copyright 2023 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
5//! Link-layer sockets (analogous to Linux's AF_PACKET sockets).
6
7use core::fmt::Debug;
8use core::hash::Hash;
9use core::num::NonZeroU16;
10
11use derivative::Derivative;
12use lock_order::lock::{OrderedLockAccess, OrderedLockRef};
13use net_types::ethernet::Mac;
14use net_types::ip::IpVersion;
15use netstack3_base::socket::SocketCookie;
16use netstack3_base::sync::{BindingsSyncTypes, Mutex, PrimaryRc, RwLock, StrongRc, WeakRc};
17use netstack3_base::{
18    AnyDevice, ContextPair, Counter, Device, DeviceIdContext, FrameDestination, GsoInfo,
19    Inspectable, Inspector, InspectorDeviceExt, InspectorExt, NetworkSerializer, PacketType,
20    ReferenceNotifiers, ReferenceNotifiersExt as _, RemoveResourceResultWithContext,
21    ResourceCounterContext, SendFrameContext, SendFrameErrorReason, StrongDeviceIdentifier,
22    TxMetadataBindingsTypes, WeakDeviceIdentifier as _,
23};
24use netstack3_hashmap::{HashMap, HashSet};
25use netstack3_ip::DeviceIpLayerMetadata;
26use packet::{BufferMut, ParsablePacket as _};
27use packet_formats::error::ParseError;
28use packet_formats::ethernet::{EtherType, EthernetFrameLengthCheck};
29
30use crate::internal::base::DeviceLayerTypes;
31use crate::internal::id::WeakDeviceId;
32
33/// A selector for frames based on link-layer protocol number.
34#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
35pub enum Protocol {
36    /// Select all frames, regardless of protocol number.
37    All,
38    /// Select frames with the given protocol number.
39    Specific(NonZeroU16),
40}
41
42/// Selector for devices to send and receive packets on.
43#[derive(Clone, Debug, Derivative, Eq, Hash, PartialEq)]
44#[derivative(Default(bound = ""))]
45pub enum TargetDevice<D> {
46    /// Act on any device in the system.
47    #[derivative(Default)]
48    AnyDevice,
49    /// Act on a specific device.
50    SpecificDevice(D),
51}
52
53/// Information about the bound state of a socket.
54#[derive(Debug)]
55#[cfg_attr(test, derive(PartialEq))]
56pub struct SocketInfo<D> {
57    /// The protocol the socket is bound to, or `None` if no protocol is set.
58    pub protocol: Option<Protocol>,
59    /// The device selector for which the socket is set.
60    pub device: TargetDevice<D>,
61}
62
63/// Provides associated types for device sockets provided by the bindings
64/// context.
65pub trait DeviceSocketTypes: BindingsSyncTypes {
66    /// State for the socket held by core and exposed to bindings.
67    type SocketState<D: Send + Sync + Debug>: Send + Sync + Debug;
68}
69
70/// Errors that Bindings may encounter when receiving frames on a Device Socket.
71pub enum ReceiveFrameError {
72    /// The socket's receive queue is full and can't hold the frame.
73    QueueFull,
74}
75
76/// The execution context for device sockets provided by bindings.
77pub trait DeviceSocketBindingsContext<DeviceId: StrongDeviceIdentifier>:
78    DeviceSocketTypes + Sized
79{
80    /// Called for each received frame that matches the provided socket.
81    ///
82    /// `frame` and `raw_frame` are parsed and raw views into the same data.
83    fn receive_frame(
84        &self,
85        socket_id: &DeviceSocketId<DeviceId::Weak, Self>,
86        device: &DeviceId,
87        frame: Frame<&[u8]>,
88        raw_frame: &[u8],
89    ) -> Result<(), ReceiveFrameError>;
90}
91
92/// Strong owner of socket state.
93///
94/// This type strongly owns the socket state.
95#[derive(Debug)]
96pub struct PrimaryDeviceSocketId<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
97    PrimaryRc<SocketState<D, BT>>,
98);
99
100impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> PrimaryDeviceSocketId<D, BT> {
101    /// Creates a new socket ID with `external_state`.
102    fn new(external_state: BT::SocketState<D>) -> Self {
103        Self(PrimaryRc::new(SocketState {
104            external_state,
105            counters: Default::default(),
106            target: Default::default(),
107        }))
108    }
109
110    /// Clones the primary's underlying reference and returns as a strong id.
111    fn clone_strong(&self) -> DeviceSocketId<D, BT> {
112        let PrimaryDeviceSocketId(rc) = self;
113        DeviceSocketId(PrimaryRc::clone_strong(rc))
114    }
115}
116
117/// Reference to live socket state.
118///
119/// The existence of a `StrongId` attests to the liveness of the state of the
120/// backing socket.
121#[derive(Derivative)]
122#[derivative(Clone(bound = ""), Hash(bound = ""), Eq(bound = ""), PartialEq(bound = ""))]
123pub struct DeviceSocketId<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
124    StrongRc<SocketState<D, BT>>,
125);
126
127impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> DeviceSocketId<D, BT> {
128    /// Returns [`SocketCookie`] for this socket.
129    pub fn socket_cookie(&self) -> SocketCookie {
130        let Self(rc) = self;
131        SocketCookie::new(rc.resource_token())
132    }
133}
134
135impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> Debug for DeviceSocketId<D, BT> {
136    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
137        let Self(rc) = self;
138        f.debug_tuple("DeviceSocketId").field(&StrongRc::debug_id(rc)).finish()
139    }
140}
141
142impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> OrderedLockAccess<Target<D>>
143    for DeviceSocketId<D, BT>
144{
145    type Lock = Mutex<Target<D>, BT::Mutex>;
146    fn ordered_lock_access(&self) -> OrderedLockRef<'_, Self::Lock> {
147        let Self(rc) = self;
148        OrderedLockRef::new(&rc.target)
149    }
150}
151
152/// A weak reference to socket state.
153///
154/// The existence of a [`WeakSocketDeviceId`] does not attest to the liveness of
155/// the backing socket.
156#[derive(Derivative)]
157#[derivative(Clone(bound = ""), Hash(bound = ""), Eq(bound = ""), PartialEq(bound = ""))]
158pub struct WeakDeviceSocketId<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
159    WeakRc<SocketState<D, BT>>,
160);
161
162impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> Debug for WeakDeviceSocketId<D, BT> {
163    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
164        let Self(rc) = self;
165        f.debug_tuple("WeakDeviceSocketId").field(&WeakRc::debug_id(rc)).finish()
166    }
167}
168
169/// Holds shared state for sockets.
170#[derive(Derivative)]
171#[derivative(Default(bound = ""))]
172pub struct Sockets<D: Send + Sync + Debug, BT: DeviceSocketTypes> {
173    /// Holds strong (but not owning) references to sockets that aren't
174    /// targeting a particular device.
175    any_device_sockets: RwLock<AnyDeviceSockets<D, BT>, BT::RwLock>,
176
177    /// Table of all sockets in the system, regardless of target.
178    ///
179    /// Holds the primary (owning) reference for all sockets.
180    // This needs to be after `any_device_sockets` so that when an instance of
181    // this type is dropped, any strong IDs get dropped before their
182    // corresponding primary IDs.
183    all_sockets: RwLock<AllSockets<D, BT>, BT::RwLock>,
184}
185
186/// The set of sockets associated with a device.
187#[derive(Derivative)]
188#[derivative(Default(bound = ""))]
189pub struct AnyDeviceSockets<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
190    HashSet<DeviceSocketId<D, BT>>,
191);
192
193/// A collection of all device sockets in the system.
194#[derive(Derivative)]
195#[derivative(Default(bound = ""))]
196pub struct AllSockets<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
197    HashMap<DeviceSocketId<D, BT>, PrimaryDeviceSocketId<D, BT>>,
198);
199
200/// State held by a device socket.
201#[derive(Derivative)]
202#[derivative(Debug(bound = ""))]
203pub struct SocketState<D: Send + Sync + Debug, BT: DeviceSocketTypes> {
204    /// State provided by bindings that is held in core.
205    pub external_state: BT::SocketState<D>,
206    /// The socket's target device and protocol.
207    // TODO(https://fxbug.dev/42077026): Consider splitting up the state here to
208    // improve performance.
209    target: Mutex<Target<D>, BT::Mutex>,
210    /// Statistics about the socket's usage.
211    counters: DeviceSocketCounters,
212}
213
214/// A device socket's binding information.
215#[derive(Debug, Derivative)]
216#[derivative(Default(bound = ""))]
217pub struct Target<D> {
218    protocol: Option<Protocol>,
219    device: TargetDevice<D>,
220}
221
222/// Per-device state for packet sockets.
223///
224/// Holds sockets that are bound to a particular device. An instance of this
225/// should be held in the state for each device in the system.
226#[derive(Derivative)]
227#[derivative(Default(bound = ""))]
228#[cfg_attr(
229    test,
230    derivative(Debug, PartialEq(bound = "BT::SocketState<D>: Hash + Eq, D: Hash + Eq"))
231)]
232pub struct DeviceSockets<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
233    HashSet<DeviceSocketId<D, BT>>,
234);
235
236/// Convenience alias for use in device state storage.
237pub type HeldDeviceSockets<BT> = DeviceSockets<WeakDeviceId<BT>, BT>;
238
239/// Convenience alias for use in shared storage.
240///
241/// The type parameter is expected to implement [`DeviceSocketTypes`].
242pub type HeldSockets<BT> = Sockets<WeakDeviceId<BT>, BT>;
243
244/// Core context for accessing socket state.
245pub trait DeviceSocketContext<BT: DeviceSocketTypes>: DeviceIdContext<AnyDevice> {
246    /// The core context available in callbacks to methods on this context.
247    type SocketTablesCoreCtx<'a>: DeviceSocketAccessor<BT, DeviceId = Self::DeviceId, WeakDeviceId = Self::WeakDeviceId>;
248
249    /// Executes the provided callback with access to the collection of all
250    /// sockets.
251    fn with_all_device_sockets<
252        F: FnOnce(&AllSockets<Self::WeakDeviceId, BT>, &mut Self::SocketTablesCoreCtx<'_>) -> R,
253        R,
254    >(
255        &mut self,
256        cb: F,
257    ) -> R;
258
259    /// Executes the provided callback with mutable access to the collection of
260    /// all sockets.
261    fn with_all_device_sockets_mut<F: FnOnce(&mut AllSockets<Self::WeakDeviceId, BT>) -> R, R>(
262        &mut self,
263        cb: F,
264    ) -> R;
265
266    /// Executes the provided callback with immutable access to socket state.
267    fn with_any_device_sockets<
268        F: FnOnce(&AnyDeviceSockets<Self::WeakDeviceId, BT>, &mut Self::SocketTablesCoreCtx<'_>) -> R,
269        R,
270    >(
271        &mut self,
272        cb: F,
273    ) -> R;
274
275    /// Executes the provided callback with mutable access to socket state.
276    fn with_any_device_sockets_mut<
277        F: FnOnce(
278            &mut AnyDeviceSockets<Self::WeakDeviceId, BT>,
279            &mut Self::SocketTablesCoreCtx<'_>,
280        ) -> R,
281        R,
282    >(
283        &mut self,
284        cb: F,
285    ) -> R;
286}
287
288/// Core context for accessing the state of an individual socket.
289pub trait SocketStateAccessor<BT: DeviceSocketTypes>: DeviceIdContext<AnyDevice> {
290    /// Provides read-only access to the state of a socket.
291    fn with_socket_state<F: FnOnce(&Target<Self::WeakDeviceId>) -> R, R>(
292        &mut self,
293        socket: &DeviceSocketId<Self::WeakDeviceId, BT>,
294        cb: F,
295    ) -> R;
296
297    /// Provides mutable access to the state of a socket.
298    fn with_socket_state_mut<F: FnOnce(&mut Target<Self::WeakDeviceId>) -> R, R>(
299        &mut self,
300        socket: &DeviceSocketId<Self::WeakDeviceId, BT>,
301        cb: F,
302    ) -> R;
303}
304
305/// Core context for accessing the socket state for a device.
306pub trait DeviceSocketAccessor<BT: DeviceSocketTypes>: SocketStateAccessor<BT> {
307    /// Core context available in callbacks to methods on this context.
308    type DeviceSocketCoreCtx<'a>: SocketStateAccessor<BT, DeviceId = Self::DeviceId, WeakDeviceId = Self::WeakDeviceId>
309        + ResourceCounterContext<DeviceSocketId<Self::WeakDeviceId, BT>, DeviceSocketCounters>;
310
311    /// Executes the provided callback with immutable access to device-specific
312    /// socket state.
313    fn with_device_sockets<
314        F: FnOnce(&DeviceSockets<Self::WeakDeviceId, BT>, &mut Self::DeviceSocketCoreCtx<'_>) -> R,
315        R,
316    >(
317        &mut self,
318        device: &Self::DeviceId,
319        cb: F,
320    ) -> R;
321
322    /// Executes the provided callback with mutable access to device-specific
323    /// socket state.
324    fn with_device_sockets_mut<
325        F: FnOnce(&mut DeviceSockets<Self::WeakDeviceId, BT>, &mut Self::DeviceSocketCoreCtx<'_>) -> R,
326        R,
327    >(
328        &mut self,
329        device: &Self::DeviceId,
330        cb: F,
331    ) -> R;
332}
333
334enum MaybeUpdate<T> {
335    NoChange,
336    NewValue(T),
337}
338
339fn update_device_and_protocol<CC: DeviceSocketContext<BT>, BT: DeviceSocketTypes>(
340    core_ctx: &mut CC,
341    socket: &DeviceSocketId<CC::WeakDeviceId, BT>,
342    new_device: TargetDevice<&CC::DeviceId>,
343    protocol_update: MaybeUpdate<Protocol>,
344) {
345    core_ctx.with_any_device_sockets_mut(|AnyDeviceSockets(any_device_sockets), core_ctx| {
346        // Even if we're never moving the socket from/to the any-device
347        // state, we acquire the lock to make the move between devices
348        // atomic from the perspective of frame delivery. Otherwise there
349        // would be a brief period during which arriving frames wouldn't be
350        // delivered to the socket from either device.
351        let old_device = core_ctx.with_socket_state_mut(socket, |Target { protocol, device }| {
352            match protocol_update {
353                MaybeUpdate::NewValue(p) => *protocol = Some(p),
354                MaybeUpdate::NoChange => (),
355            };
356            let old_device = match &device {
357                TargetDevice::SpecificDevice(device) => device.upgrade(),
358                TargetDevice::AnyDevice => {
359                    assert!(any_device_sockets.remove(socket));
360                    None
361                }
362            };
363            *device = match &new_device {
364                TargetDevice::AnyDevice => TargetDevice::AnyDevice,
365                TargetDevice::SpecificDevice(d) => TargetDevice::SpecificDevice(d.downgrade()),
366            };
367            old_device
368        });
369
370        // This modification occurs without holding the socket's individual
371        // lock. That's safe because all modifications to the socket's
372        // device are done within a `with_sockets_mut` call, which
373        // synchronizes them.
374
375        if let Some(device) = old_device {
376            // Remove the reference to the socket from the old device if
377            // there is one, and it hasn't been removed.
378            core_ctx.with_device_sockets_mut(
379                &device,
380                |DeviceSockets(device_sockets), _core_ctx| {
381                    assert!(device_sockets.remove(socket), "socket not found in device state");
382                },
383            );
384        }
385
386        // Add the reference to the new device, if there is one.
387        match &new_device {
388            TargetDevice::SpecificDevice(new_device) => core_ctx.with_device_sockets_mut(
389                new_device,
390                |DeviceSockets(device_sockets), _core_ctx| {
391                    assert!(device_sockets.insert(socket.clone()));
392                },
393            ),
394            TargetDevice::AnyDevice => {
395                assert!(any_device_sockets.insert(socket.clone()))
396            }
397        }
398    })
399}
400
401/// The device socket API.
402pub struct DeviceSocketApi<C>(C);
403
404impl<C> DeviceSocketApi<C> {
405    /// Creates a new `DeviceSocketApi` for `ctx`.
406    pub fn new(ctx: C) -> Self {
407        Self(ctx)
408    }
409}
410
411/// A local alias for [`DeviceSocketId`] for use in [`DeviceSocketApi`].
412///
413/// TODO(https://github.com/rust-lang/rust/issues/8995): Make this an inherent
414/// associated type.
415type ApiSocketId<C> = DeviceSocketId<
416    <<C as ContextPair>::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId,
417    <C as ContextPair>::BindingsContext,
418>;
419
420impl<C> DeviceSocketApi<C>
421where
422    C: ContextPair,
423    C::CoreContext: DeviceSocketContext<C::BindingsContext>
424        + SocketStateAccessor<C::BindingsContext>
425        + ResourceCounterContext<ApiSocketId<C>, DeviceSocketCounters>,
426    C::BindingsContext: DeviceSocketBindingsContext<<C::CoreContext as DeviceIdContext<AnyDevice>>::DeviceId>
427        + ReferenceNotifiers
428        + 'static,
429{
430    fn core_ctx(&mut self) -> &mut C::CoreContext {
431        let Self(pair) = self;
432        pair.core_ctx()
433    }
434
435    fn contexts(&mut self) -> (&mut C::CoreContext, &mut C::BindingsContext) {
436        let Self(pair) = self;
437        pair.contexts()
438    }
439
440    /// Creates an packet socket with no protocol set configured for all devices.
441    pub fn create(
442        &mut self,
443        external_state: <C::BindingsContext as DeviceSocketTypes>::SocketState<
444            <C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId,
445        >,
446    ) -> ApiSocketId<C> {
447        let core_ctx = self.core_ctx();
448
449        let strong = core_ctx.with_all_device_sockets_mut(|AllSockets(sockets)| {
450            let primary = PrimaryDeviceSocketId::new(external_state);
451            let strong = primary.clone_strong();
452            assert!(sockets.insert(strong.clone(), primary).is_none());
453            strong
454        });
455        core_ctx.with_any_device_sockets_mut(|AnyDeviceSockets(any_device_sockets), _core_ctx| {
456            // On creation, sockets do not target any device or protocol.
457            // Inserting them into the `any_device_sockets` table lets us treat
458            // newly-created sockets uniformly with sockets whose target device
459            // or protocol was set. The difference is unobservable at runtime
460            // since newly-created sockets won't match any frames being
461            // delivered.
462            assert!(any_device_sockets.insert(strong.clone()));
463        });
464        strong
465    }
466
467    /// Sets the device for which a packet socket will receive packets.
468    pub fn set_device(
469        &mut self,
470        socket: &ApiSocketId<C>,
471        device: TargetDevice<&<C::CoreContext as DeviceIdContext<AnyDevice>>::DeviceId>,
472    ) {
473        update_device_and_protocol(self.core_ctx(), socket, device, MaybeUpdate::NoChange)
474    }
475
476    /// Sets the device and protocol for which a socket will receive packets.
477    pub fn set_device_and_protocol(
478        &mut self,
479        socket: &ApiSocketId<C>,
480        device: TargetDevice<&<C::CoreContext as DeviceIdContext<AnyDevice>>::DeviceId>,
481        protocol: Protocol,
482    ) {
483        update_device_and_protocol(self.core_ctx(), socket, device, MaybeUpdate::NewValue(protocol))
484    }
485
486    /// Gets the bound info for a socket.
487    pub fn get_info(
488        &mut self,
489        id: &ApiSocketId<C>,
490    ) -> SocketInfo<<C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId> {
491        self.core_ctx().with_socket_state(id, |Target { device, protocol }| SocketInfo {
492            device: device.clone(),
493            protocol: *protocol,
494        })
495    }
496
497    /// Removes a bound socket.
498    pub fn remove(
499        &mut self,
500        id: ApiSocketId<C>,
501    ) -> RemoveResourceResultWithContext<
502        <C::BindingsContext as DeviceSocketTypes>::SocketState<
503            <C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId,
504        >,
505        C::BindingsContext,
506    > {
507        let core_ctx = self.core_ctx();
508        core_ctx.with_any_device_sockets_mut(|AnyDeviceSockets(any_device_sockets), core_ctx| {
509            let old_device = core_ctx.with_socket_state_mut(&id, |target| {
510                let Target { device, protocol: _ } = target;
511                match &device {
512                    TargetDevice::SpecificDevice(device) => device.upgrade(),
513                    TargetDevice::AnyDevice => {
514                        assert!(any_device_sockets.remove(&id));
515                        None
516                    }
517                }
518            });
519            if let Some(device) = old_device {
520                core_ctx.with_device_sockets_mut(
521                    &device,
522                    |DeviceSockets(device_sockets), _core_ctx| {
523                        assert!(device_sockets.remove(&id), "device doesn't have socket");
524                    },
525                )
526            }
527        });
528
529        core_ctx.with_all_device_sockets_mut(|AllSockets(sockets)| {
530            let primary = sockets
531                .remove(&id)
532                .unwrap_or_else(|| panic!("{id:?} not present in all socket map"));
533            // Make sure to drop the strong ID before trying to unwrap the primary
534            // ID.
535            drop(id);
536
537            let PrimaryDeviceSocketId(primary) = primary;
538            C::BindingsContext::unwrap_or_notify_with_new_reference_notifier(
539                primary,
540                |SocketState { external_state, counters: _, target: _ }| external_state,
541            )
542        })
543    }
544
545    /// Sends a frame for the specified socket.
546    pub fn send_frame<S, D>(
547        &mut self,
548        id: &ApiSocketId<C>,
549        metadata: DeviceSocketMetadata<D, C::CoreContext, C::BindingsContext>,
550        body: S,
551    ) -> Result<(), SendFrameErrorReason>
552    where
553        S: NetworkSerializer,
554        S::Buffer: BufferMut,
555        D: DeviceSocketSendTypes,
556        C::CoreContext: DeviceIdContext<D>
557            + SendFrameContext<
558                C::BindingsContext,
559                DeviceSocketMetadata<D, C::CoreContext, C::BindingsContext>,
560            >,
561        C::BindingsContext: DeviceLayerTypes,
562    {
563        let (core_ctx, bindings_ctx) = self.contexts();
564        let result = core_ctx.send_frame(bindings_ctx, metadata, body).map_err(|e| e.into_err());
565        match &result {
566            Ok(()) => {
567                core_ctx.increment_both(id, |counters: &DeviceSocketCounters| &counters.tx_frames)
568            }
569            Err(SendFrameErrorReason::QueueFull) => core_ctx
570                .increment_both(id, |counters: &DeviceSocketCounters| &counters.tx_err_queue_full),
571            Err(SendFrameErrorReason::Alloc) => core_ctx
572                .increment_both(id, |counters: &DeviceSocketCounters| &counters.tx_err_alloc),
573            Err(SendFrameErrorReason::SizeConstraintsViolation) => core_ctx
574                .increment_both(id, |counters: &DeviceSocketCounters| {
575                    &counters.tx_err_size_constraint
576                }),
577            Err(SendFrameErrorReason::AddressResolutionFailed) => {
578                unreachable!("device socket send should not perform link-layer address resolution");
579            }
580        }
581        result
582    }
583
584    /// Provides inspect data for raw IP sockets.
585    pub fn inspect<N>(&mut self, inspector: &mut N)
586    where
587        N: Inspector
588            + InspectorDeviceExt<<C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId>,
589    {
590        self.core_ctx().with_all_device_sockets(|AllSockets(sockets), core_ctx| {
591            sockets.keys().for_each(|socket| {
592                inspector.record_debug_child(socket, |node| {
593                    core_ctx.with_socket_state(socket, |Target { protocol, device }| {
594                        node.record_debug("Protocol", protocol);
595                        match device {
596                            TargetDevice::AnyDevice => node.record_str("Device", "Any"),
597                            TargetDevice::SpecificDevice(d) => N::record_device(node, "Device", d),
598                        }
599                    });
600                    node.record_child("Counters", |node| {
601                        node.delegate_inspectable(socket.counters())
602                    })
603                })
604            })
605        })
606    }
607}
608
609/// A provider of the types required to send on a device socket.
610pub trait DeviceSocketSendTypes: Device {
611    /// The metadata required to send a frame on the device.
612    type Metadata;
613}
614
615/// Metadata required to send a frame on a device socket.
616#[derive(Derivative)]
617#[derivative(Debug(bound = "D::Metadata: Debug"))]
618pub struct DeviceSocketMetadata<D, C, BT>
619where
620    D: DeviceSocketSendTypes,
621    C: DeviceIdContext<D>,
622    BT: TxMetadataBindingsTypes,
623{
624    /// The device ID to send via.
625    pub device_id: C::DeviceId,
626    /// The metadata required to send that's specific to the device type.
627    pub metadata: D::Metadata,
628    /// IP layer metadata associated with the frame, including the send buffer
629    /// ownership metadata.
630    pub ip_layer_metadata: DeviceIpLayerMetadata<BT>,
631}
632
633/// Parameters needed to apply system-framing of an Ethernet frame.
634#[derive(Debug, PartialEq)]
635pub struct EthernetHeaderParams {
636    /// The destination MAC address to send to.
637    pub dest_addr: Mac,
638    /// The upperlayer protocol of the data contained in this Ethernet frame.
639    pub protocol: EtherType,
640}
641
642/// Public identifier for a socket.
643///
644/// Strongly owns the state of the socket. So long as the `SocketId` for a
645/// socket is not dropped, the socket is guaranteed to exist.
646pub type SocketId<BC> = DeviceSocketId<WeakDeviceId<BC>, BC>;
647
648impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> DeviceSocketId<D, BT> {
649    /// Provides immutable access to [`DeviceSocketTypes::SocketState`] for the
650    /// socket.
651    pub fn socket_state(&self) -> &BT::SocketState<D> {
652        let Self(strong) = self;
653        let SocketState { external_state, counters: _, target: _ } = &**strong;
654        external_state
655    }
656
657    /// Obtain a [`WeakDeviceSocketId`] from this [`DeviceSocketId`].
658    pub fn downgrade(&self) -> WeakDeviceSocketId<D, BT> {
659        let Self(inner) = self;
660        WeakDeviceSocketId(StrongRc::downgrade(inner))
661    }
662
663    /// Provides access to the socket's counters.
664    pub fn counters(&self) -> &DeviceSocketCounters {
665        let Self(strong) = self;
666        let SocketState { external_state: _, counters, target: _ } = &**strong;
667        counters
668    }
669}
670
671/// Allows the rest of the stack to dispatch packets to listening sockets.
672///
673/// This is implemented on top of [`DeviceSocketContext`] and abstracts packet
674/// socket delivery from the rest of the system.
675pub trait DeviceSocketHandler<D: Device, BC>: DeviceIdContext<D> {
676    /// Dispatch a received frame to sockets.
677    fn handle_frame(
678        &mut self,
679        bindings_ctx: &mut BC,
680        device: &Self::DeviceId,
681        frame: Frame<&[u8]>,
682        whole_frame: &[u8],
683    );
684}
685
686/// A frame received on a device.
687#[derive(Clone, Copy, Debug, Eq, PartialEq)]
688pub enum ReceivedFrame<B> {
689    /// An ethernet frame received on a device.
690    Ethernet {
691        /// Where the frame was destined.
692        destination: FrameDestination,
693        /// The parsed ethernet frame.
694        frame: EthernetFrame<B>,
695        /// The packet type.
696        packet_type: PacketType,
697        /// GSO metadata if the frame was coalesced from multiple segments.
698        gso_info: Option<GsoInfo>,
699    },
700    /// An IP frame received on a device.
701    ///
702    /// Note that this is not an IP packet within an Ethernet Frame. This is an
703    /// IP packet received directly from the device (e.g. a pure IP device).
704    Ip {
705        /// The IP frame.
706        frame: IpFrame<B>,
707        /// GSO metadata if the frame was coalesced from multiple segments.
708        gso_info: Option<GsoInfo>,
709    },
710}
711
712/// A frame sent on a device.
713#[derive(Clone, Copy, Debug, Eq, PartialEq)]
714pub enum SentFrame<B> {
715    /// An ethernet frame sent on a device.
716    Ethernet(EthernetFrame<B>),
717    /// An IP frame sent on a device.
718    ///
719    /// Note that this is not an IP packet within an Ethernet Frame. This is an
720    /// IP Packet send directly on the device (e.g. a pure IP device).
721    Ip(IpFrame<B>),
722}
723
724/// A frame couldn't be parsed as a [`SentFrame`].
725#[derive(Debug)]
726pub struct ParseSentFrameError;
727
728impl SentFrame<&[u8]> {
729    /// Tries to parse the given frame as an Ethernet frame.
730    pub fn try_parse_as_ethernet(mut buf: &[u8]) -> Result<SentFrame<&[u8]>, ParseSentFrameError> {
731        packet_formats::ethernet::EthernetFrame::parse(&mut buf, EthernetFrameLengthCheck::NoCheck)
732            .map_err(|_: ParseError| ParseSentFrameError)
733            .map(|frame| SentFrame::Ethernet(frame.into()))
734    }
735}
736
737/// Data from an Ethernet frame.
738#[derive(Clone, Copy, Debug, Eq, PartialEq)]
739pub struct EthernetFrame<B> {
740    /// The source address of the frame.
741    pub src_mac: Mac,
742    /// The destination address of the frame.
743    pub dst_mac: Mac,
744    /// The EtherType of the frame, or `None` if there was none.
745    pub ethertype: Option<EtherType>,
746    /// The offset of the body within the frame.
747    pub body_offset: usize,
748    /// The body of the frame.
749    pub body: B,
750}
751
752/// Data from an IP frame.
753#[derive(Clone, Copy, Debug, Eq, PartialEq)]
754pub struct IpFrame<B> {
755    /// The IP version of the frame.
756    pub ip_version: IpVersion,
757    /// The body of the frame.
758    pub body: B,
759}
760
761impl<B> IpFrame<B> {
762    fn ethertype(&self) -> EtherType {
763        let IpFrame { ip_version, body: _ } = self;
764        EtherType::from_ip_version(*ip_version)
765    }
766}
767
768// All packets received through pure_ip device are marked with
769// `PacketType::Host` (i.e. `PACKET_HOST`).
770pub const PURE_IP_PACKET_TYPE: PacketType = PacketType::Host;
771
772/// A frame sent or received on a device.
773#[derive(Clone, Copy, Debug, Eq, PartialEq)]
774pub enum Frame<B> {
775    /// A sent frame.
776    Sent(SentFrame<B>),
777    /// A received frame.
778    Received(ReceivedFrame<B>),
779}
780
781impl<B> From<SentFrame<B>> for Frame<B> {
782    fn from(value: SentFrame<B>) -> Self {
783        Self::Sent(value)
784    }
785}
786
787impl<B> From<ReceivedFrame<B>> for Frame<B> {
788    fn from(value: ReceivedFrame<B>) -> Self {
789        Self::Received(value)
790    }
791}
792
793impl<'a> From<packet_formats::ethernet::EthernetFrame<&'a [u8]>> for EthernetFrame<&'a [u8]> {
794    fn from(frame: packet_formats::ethernet::EthernetFrame<&'a [u8]>) -> Self {
795        Self {
796            src_mac: frame.src_mac(),
797            dst_mac: frame.dst_mac(),
798            ethertype: frame.ethertype(),
799            body_offset: frame.parse_metadata().header_len(),
800            body: frame.into_body(),
801        }
802    }
803}
804
805impl<'a> ReceivedFrame<&'a [u8]> {
806    pub(crate) fn from_ethernet(
807        frame: packet_formats::ethernet::EthernetFrame<&'a [u8]>,
808        destination: FrameDestination,
809        packet_type: PacketType,
810        gso_info: Option<GsoInfo>,
811    ) -> Self {
812        Self::Ethernet { destination, frame: frame.into(), packet_type, gso_info }
813    }
814}
815
816impl<B> Frame<B> {
817    /// Returns the packet type for the frame.
818    pub fn packet_type(&self) -> PacketType {
819        match self {
820            Self::Sent(_) => PacketType::Outgoing,
821            Self::Received(ReceivedFrame::Ethernet {
822                destination: _,
823                frame: _,
824                packet_type,
825                gso_info: _,
826            }) => *packet_type,
827            Self::Received(ReceivedFrame::Ip { frame: _, gso_info: _ }) => PURE_IP_PACKET_TYPE,
828        }
829    }
830
831    /// Returns ether type for the packet if it's known.
832    pub fn protocol(&self) -> Option<u16> {
833        let ethertype = match self {
834            Self::Sent(SentFrame::Ethernet(frame))
835            | Self::Received(ReceivedFrame::Ethernet {
836                destination: _,
837                frame,
838                packet_type: _,
839                gso_info: _,
840            }) => frame.ethertype,
841            Self::Sent(SentFrame::Ip(frame))
842            | Self::Received(ReceivedFrame::Ip { frame, gso_info: _ }) => Some(frame.ethertype()),
843        };
844        ethertype.map(Into::into)
845    }
846
847    /// Returns the GSO metadata for the frame, if any.
848    pub fn gso_info(&self) -> Option<GsoInfo> {
849        match self {
850            Self::Sent(_) => None,
851            Self::Received(ReceivedFrame::Ethernet {
852                destination: _,
853                frame: _,
854                packet_type: _,
855                gso_info,
856            })
857            | Self::Received(ReceivedFrame::Ip { frame: _, gso_info }) => *gso_info,
858        }
859    }
860
861    /// Convenience method for consuming the `Frame` and producing the body.
862    pub fn into_body(self) -> B {
863        match self {
864            Self::Received(ReceivedFrame::Ethernet {
865                destination: _,
866                frame,
867                packet_type: _,
868                gso_info: _,
869            })
870            | Self::Sent(SentFrame::Ethernet(frame)) => frame.body,
871            Self::Received(ReceivedFrame::Ip { frame, gso_info: _ })
872            | Self::Sent(SentFrame::Ip(frame)) => frame.body,
873        }
874    }
875
876    /// Returns the offset of the body within the frame.
877    pub fn body_offset(&self) -> usize {
878        match self {
879            Self::Received(ReceivedFrame::Ethernet {
880                destination: _,
881                frame,
882                packet_type: _,
883                gso_info: _,
884            })
885            | Self::Sent(SentFrame::Ethernet(frame)) => frame.body_offset,
886            Self::Received(ReceivedFrame::Ip { frame: _, gso_info: _ })
887            | Self::Sent(SentFrame::Ip(_)) => 0,
888        }
889    }
890}
891
892impl<
893    D: Device,
894    BC: DeviceSocketBindingsContext<<CC as DeviceIdContext<AnyDevice>>::DeviceId>,
895    CC: DeviceSocketContext<BC> + DeviceIdContext<D>,
896> DeviceSocketHandler<D, BC> for CC
897where
898    <CC as DeviceIdContext<D>>::DeviceId: Into<<CC as DeviceIdContext<AnyDevice>>::DeviceId>,
899{
900    fn handle_frame(
901        &mut self,
902        bindings_ctx: &mut BC,
903        device: &Self::DeviceId,
904        frame: Frame<&[u8]>,
905        whole_frame: &[u8],
906    ) {
907        let device = device.clone().into();
908
909        // TODO(https://fxbug.dev/42076496): Invert the order of acquisition
910        // for the lock on the sockets held in the device and the any-device
911        // sockets lock.
912        self.with_any_device_sockets(|AnyDeviceSockets(any_device_sockets), core_ctx| {
913            // Iterate through the device's sockets while also holding the
914            // any-device sockets lock. This prevents double delivery to the
915            // same socket. If the two tables were locked independently,
916            // we could end up with a race, with the following thread
917            // interleaving (thread A is executing this code for device D,
918            // thread B is updating the device to D for the same socket X):
919            //   A) lock the any device sockets table
920            //   A) deliver to socket X in the table
921            //   A) unlock the any device sockets table
922            //   B) lock the any device sockets table, then D's sockets
923            //   B) remove X from the any table and add to D's
924            //   B) unlock D's sockets and any device sockets
925            //   A) lock D's sockets
926            //   A) deliver to socket X in D's table (!)
927            core_ctx.with_device_sockets(&device, |DeviceSockets(device_sockets), core_ctx| {
928                for socket in any_device_sockets.iter().chain(device_sockets) {
929                    let delivered =
930                        core_ctx.with_socket_state(socket, |Target { protocol, device: _ }| {
931                            let should_deliver = match protocol {
932                                None => false,
933                                Some(p) => match p {
934                                    // Sent frames are only delivered to sockets
935                                    // matching all protocols for Linux
936                                    // compatibility. See https://github.com/google/gvisor/blob/68eae979409452209e4faaeac12aee4191b3d6f0/test/syscalls/linux/packet_socket.cc#L331-L392.
937                                    Protocol::Specific(p) => match frame {
938                                        Frame::Received(_) => Some(p.get()) == frame.protocol(),
939                                        Frame::Sent(_) => false,
940                                    },
941                                    Protocol::All => true,
942                                },
943                            };
944                            should_deliver.then(|| {
945                                bindings_ctx.receive_frame(socket, &device, frame, whole_frame)
946                            })
947                        });
948                    match delivered {
949                        None => {}
950                        Some(result) => {
951                            core_ctx.increment_both(socket, |counters: &DeviceSocketCounters| {
952                                &counters.rx_frames
953                            });
954                            match result {
955                                Ok(()) => {}
956                                Err(ReceiveFrameError::QueueFull) => {
957                                    core_ctx.increment_both(
958                                        socket,
959                                        |counters: &DeviceSocketCounters| &counters.rx_queue_full,
960                                    );
961                                }
962                            }
963                        }
964                    }
965                }
966            })
967        })
968    }
969}
970
971/// Usage statistics about Device Sockets.
972///
973/// Tracked stack-wide and per-socket.
974#[derive(Debug, Default)]
975pub struct DeviceSocketCounters {
976    /// Count of incoming frames that were delivered to the socket.
977    ///
978    /// Note that a single frame may be delivered to multiple device sockets.
979    /// Thus this counter, when tracking the stack-wide aggregate, may exceed
980    /// the total number of frames received by the stack.
981    rx_frames: Counter,
982    /// Count of incoming frames that could not be delivered to a socket because
983    /// its receive buffer was full.
984    rx_queue_full: Counter,
985    /// Count of outgoing frames that were sent by the socket.
986    tx_frames: Counter,
987    /// Count of failed tx frames due to [`SendFrameErrorReason::QueueFull`].
988    tx_err_queue_full: Counter,
989    /// Count of failed tx frames due to [`SendFrameErrorReason::Alloc`].
990    tx_err_alloc: Counter,
991    /// Count of failed tx frames due to [`SendFrameErrorReason::SizeConstraintsViolation`].
992    tx_err_size_constraint: Counter,
993}
994
995impl Inspectable for DeviceSocketCounters {
996    fn record<I: Inspector>(&self, inspector: &mut I) {
997        let Self {
998            rx_frames,
999            rx_queue_full,
1000            tx_frames,
1001            tx_err_queue_full,
1002            tx_err_alloc,
1003            tx_err_size_constraint,
1004        } = self;
1005        inspector.record_child("Rx", |inspector| {
1006            inspector.record_counter("DeliveredFrames", rx_frames);
1007            inspector.record_counter("DroppedQueueFull", rx_queue_full);
1008        });
1009        inspector.record_child("Tx", |inspector| {
1010            inspector.record_counter("SentFrames", tx_frames);
1011            inspector.record_counter("QueueFullError", tx_err_queue_full);
1012            inspector.record_counter("AllocError", tx_err_alloc);
1013            inspector.record_counter("SizeConstraintError", tx_err_size_constraint);
1014        });
1015    }
1016}
1017
1018impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> OrderedLockAccess<AnyDeviceSockets<D, BT>>
1019    for Sockets<D, BT>
1020{
1021    type Lock = RwLock<AnyDeviceSockets<D, BT>, BT::RwLock>;
1022    fn ordered_lock_access(&self) -> OrderedLockRef<'_, Self::Lock> {
1023        OrderedLockRef::new(&self.any_device_sockets)
1024    }
1025}
1026
1027impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> OrderedLockAccess<AllSockets<D, BT>>
1028    for Sockets<D, BT>
1029{
1030    type Lock = RwLock<AllSockets<D, BT>, BT::RwLock>;
1031    fn ordered_lock_access(&self) -> OrderedLockRef<'_, Self::Lock> {
1032        OrderedLockRef::new(&self.all_sockets)
1033    }
1034}
1035
1036#[cfg(any(test, feature = "testutils"))]
1037mod testutil {
1038    use alloc::vec::Vec;
1039    use core::num::NonZeroU64;
1040    use core::ops::DerefMut;
1041    use netstack3_base::StrongDeviceIdentifier;
1042    use netstack3_base::testutil::{FakeBindingsCtx, MonotonicIdentifier};
1043
1044    use super::*;
1045    use crate::internal::base::{
1046        DeviceClassMatcher, DeviceIdAndNameMatcher, DeviceLayerStateTypes,
1047    };
1048
1049    #[derive(Derivative, Debug)]
1050    #[derivative(Default(bound = ""))]
1051    pub struct RxQueue<D> {
1052        pub frames: Vec<ReceivedFrame<D>>,
1053        #[derivative(Default(value = "usize::MAX"))]
1054        pub max_size: usize,
1055    }
1056
1057    #[derive(Clone, Debug, PartialEq)]
1058    pub struct ReceivedFrame<D> {
1059        pub device: D,
1060        pub frame: Frame<Vec<u8>>,
1061        pub raw: Vec<u8>,
1062    }
1063
1064    #[derive(Debug, Derivative)]
1065    #[derivative(Default(bound = ""))]
1066    pub struct ExternalSocketState<D>(
1067        pub Mutex<RxQueue<D>, netstack3_base::sync::lock_impl::RawMutex>,
1068    );
1069
1070    impl<TimerId, Event: Debug, State> DeviceSocketTypes
1071        for FakeBindingsCtx<TimerId, Event, State, ()>
1072    {
1073        type SocketState<D: Send + Sync + Debug> = ExternalSocketState<D>;
1074    }
1075
1076    impl Frame<&[u8]> {
1077        pub(crate) fn cloned(self) -> Frame<Vec<u8>> {
1078            match self {
1079                Self::Sent(SentFrame::Ethernet(frame)) => {
1080                    Frame::Sent(SentFrame::Ethernet(frame.cloned()))
1081                }
1082                Self::Received(super::ReceivedFrame::Ethernet {
1083                    destination,
1084                    frame,
1085                    packet_type,
1086                    gso_info,
1087                }) => Frame::Received(super::ReceivedFrame::Ethernet {
1088                    destination,
1089                    frame: frame.cloned(),
1090                    packet_type,
1091                    gso_info,
1092                }),
1093                Self::Sent(SentFrame::Ip(frame)) => Frame::Sent(SentFrame::Ip(frame.cloned())),
1094                Self::Received(super::ReceivedFrame::Ip { frame, gso_info }) => {
1095                    Frame::Received(super::ReceivedFrame::Ip { frame: frame.cloned(), gso_info })
1096                }
1097            }
1098        }
1099    }
1100
1101    impl EthernetFrame<&[u8]> {
1102        fn cloned(self) -> EthernetFrame<Vec<u8>> {
1103            let Self { src_mac, dst_mac, ethertype, body_offset, body } = self;
1104            EthernetFrame { src_mac, dst_mac, ethertype, body_offset, body: Vec::from(body) }
1105        }
1106    }
1107
1108    impl IpFrame<&[u8]> {
1109        fn cloned(self) -> IpFrame<Vec<u8>> {
1110            let Self { ip_version, body } = self;
1111            IpFrame { ip_version, body: Vec::from(body) }
1112        }
1113    }
1114
1115    impl<TimerId, Event: Debug, State, D: StrongDeviceIdentifier> DeviceSocketBindingsContext<D>
1116        for FakeBindingsCtx<TimerId, Event, State, ()>
1117    {
1118        fn receive_frame(
1119            &self,
1120            state: &DeviceSocketId<D::Weak, Self>,
1121            device: &D,
1122            frame: Frame<&[u8]>,
1123            raw_frame: &[u8],
1124        ) -> Result<(), ReceiveFrameError> {
1125            let ExternalSocketState(queue) = state.socket_state();
1126            let mut lock_guard = queue.lock();
1127            let RxQueue { frames, max_size } = lock_guard.deref_mut();
1128            if frames.len() < *max_size {
1129                frames.push(ReceivedFrame {
1130                    device: device.downgrade(),
1131                    frame: frame.cloned(),
1132                    raw: raw_frame.into(),
1133                });
1134                Ok(())
1135            } else {
1136                Err(ReceiveFrameError::QueueFull)
1137            }
1138        }
1139    }
1140
1141    impl<
1142        TimerId: Debug + PartialEq + Clone + Send + Sync + 'static,
1143        Event: Debug + 'static,
1144        State: 'static,
1145    > DeviceLayerStateTypes for FakeBindingsCtx<TimerId, Event, State, ()>
1146    {
1147        type EthernetDeviceState = ();
1148        type LoopbackDeviceState = ();
1149        type PureIpDeviceState = ();
1150        type BlackholeDeviceState = ();
1151        type DeviceIdentifier = MonotonicIdentifier;
1152    }
1153
1154    impl DeviceClassMatcher<()> for () {
1155        fn device_class_matches(&self, (): &()) -> bool {
1156            unimplemented!()
1157        }
1158    }
1159
1160    impl DeviceIdAndNameMatcher for MonotonicIdentifier {
1161        fn id_matches(&self, _id: &NonZeroU64) -> bool {
1162            unimplemented!()
1163        }
1164
1165        fn name_matches(&self, _name: &str) -> bool {
1166            unimplemented!()
1167        }
1168    }
1169}
1170
1171#[cfg(test)]
1172mod tests {
1173    use alloc::vec;
1174    use alloc::vec::Vec;
1175    use core::marker::PhantomData;
1176    use core::ops::Deref;
1177
1178    use crate::internal::socket::testutil::{ExternalSocketState, ReceivedFrame};
1179    use netstack3_base::testutil::{
1180        FakeReferencyDeviceId, FakeStrongDeviceId, FakeWeakDeviceId, MultipleDevicesId,
1181    };
1182    use netstack3_base::{
1183        CounterContext, CtxPair, NetworkSerializationContext, SendFrameError, SendableFrameMeta,
1184    };
1185    use netstack3_hashmap::HashMap;
1186    use packet::ParsablePacket;
1187    use test_case::test_case;
1188
1189    use super::*;
1190
1191    type FakeCoreCtx<D> = netstack3_base::testutil::FakeCoreCtx<FakeSockets<D>, (), D>;
1192    type FakeBindingsCtx = netstack3_base::testutil::FakeBindingsCtx<(), (), (), ()>;
1193    type FakeCtx<D> = CtxPair<FakeCoreCtx<D>, FakeBindingsCtx>;
1194
1195    /// A trait providing a shortcut to instantiate a [`DeviceSocketApi`] from a
1196    /// context.
1197    trait DeviceSocketApiExt: ContextPair + Sized {
1198        fn device_socket_api(&mut self) -> DeviceSocketApi<&mut Self> {
1199            DeviceSocketApi::new(self)
1200        }
1201    }
1202
1203    impl<O> DeviceSocketApiExt for O where O: ContextPair + Sized {}
1204
1205    #[derive(Derivative)]
1206    #[derivative(Default(bound = ""))]
1207    struct FakeSockets<D: FakeStrongDeviceId> {
1208        any_device_sockets: AnyDeviceSockets<D::Weak, FakeBindingsCtx>,
1209        device_sockets: HashMap<D, DeviceSockets<D::Weak, FakeBindingsCtx>>,
1210        all_sockets: AllSockets<D::Weak, FakeBindingsCtx>,
1211        /// The stack-wide counters for device sockets.
1212        counters: DeviceSocketCounters,
1213        sent_frames: Vec<Vec<u8>>,
1214    }
1215
1216    /// Tuple of references
1217    pub struct FakeSocketsMutRefs<'m, AnyDevice, AllSockets, Devices, Device>(
1218        &'m mut AnyDevice,
1219        &'m mut AllSockets,
1220        &'m mut Devices,
1221        PhantomData<Device>,
1222        &'m DeviceSocketCounters,
1223    );
1224
1225    /// Helper trait to allow treating a `&mut self` as a
1226    /// [`FakeSocketsMutRefs`].
1227    pub trait AsFakeSocketsMutRefs {
1228        type AnyDevice: 'static;
1229        type AllSockets: 'static;
1230        type Devices: 'static;
1231        type Device: 'static;
1232        fn as_sockets_ref(
1233            &mut self,
1234        ) -> FakeSocketsMutRefs<'_, Self::AnyDevice, Self::AllSockets, Self::Devices, Self::Device>;
1235    }
1236
1237    impl<D: FakeStrongDeviceId> AsFakeSocketsMutRefs for FakeCoreCtx<D> {
1238        type AnyDevice = AnyDeviceSockets<D::Weak, FakeBindingsCtx>;
1239        type AllSockets = AllSockets<D::Weak, FakeBindingsCtx>;
1240        type Devices = HashMap<D, DeviceSockets<D::Weak, FakeBindingsCtx>>;
1241        type Device = D;
1242
1243        fn as_sockets_ref(
1244            &mut self,
1245        ) -> FakeSocketsMutRefs<
1246            '_,
1247            AnyDeviceSockets<D::Weak, FakeBindingsCtx>,
1248            AllSockets<D::Weak, FakeBindingsCtx>,
1249            HashMap<D, DeviceSockets<D::Weak, FakeBindingsCtx>>,
1250            D,
1251        > {
1252            let FakeSockets {
1253                any_device_sockets,
1254                device_sockets,
1255                all_sockets,
1256                counters,
1257                sent_frames: _,
1258            } = &mut self.state;
1259            FakeSocketsMutRefs(
1260                any_device_sockets,
1261                all_sockets,
1262                device_sockets,
1263                PhantomData,
1264                counters,
1265            )
1266        }
1267    }
1268
1269    impl<'m, AnyDevice: 'static, AllSockets: 'static, Devices: 'static, Device: 'static>
1270        AsFakeSocketsMutRefs for FakeSocketsMutRefs<'m, AnyDevice, AllSockets, Devices, Device>
1271    {
1272        type AnyDevice = AnyDevice;
1273        type AllSockets = AllSockets;
1274        type Devices = Devices;
1275        type Device = Device;
1276
1277        fn as_sockets_ref(
1278            &mut self,
1279        ) -> FakeSocketsMutRefs<'_, AnyDevice, AllSockets, Devices, Device> {
1280            let Self(any_device, all_sockets, devices, PhantomData, counters) = self;
1281            FakeSocketsMutRefs(any_device, all_sockets, devices, PhantomData, counters)
1282        }
1283    }
1284
1285    impl<D: Clone> TargetDevice<&D> {
1286        fn with_weak_id(&self) -> TargetDevice<FakeWeakDeviceId<D>> {
1287            match self {
1288                TargetDevice::AnyDevice => TargetDevice::AnyDevice,
1289                TargetDevice::SpecificDevice(d) => {
1290                    TargetDevice::SpecificDevice(FakeWeakDeviceId((*d).clone()))
1291                }
1292            }
1293        }
1294    }
1295
1296    impl<D: Eq + Hash + FakeStrongDeviceId> FakeSockets<D> {
1297        fn new(devices: impl IntoIterator<Item = D>) -> Self {
1298            let device_sockets =
1299                devices.into_iter().map(|d| (d, DeviceSockets::default())).collect();
1300            Self {
1301                any_device_sockets: AnyDeviceSockets::default(),
1302                device_sockets,
1303                all_sockets: Default::default(),
1304                counters: Default::default(),
1305                sent_frames: Default::default(),
1306            }
1307        }
1308    }
1309
1310    impl<
1311        'm,
1312        DeviceId: FakeStrongDeviceId,
1313        As: AsFakeSocketsMutRefs
1314            + DeviceIdContext<AnyDevice, DeviceId = DeviceId, WeakDeviceId = DeviceId::Weak>,
1315    > SocketStateAccessor<FakeBindingsCtx> for As
1316    {
1317        fn with_socket_state<F: FnOnce(&Target<Self::WeakDeviceId>) -> R, R>(
1318            &mut self,
1319            socket: &DeviceSocketId<Self::WeakDeviceId, FakeBindingsCtx>,
1320            cb: F,
1321        ) -> R {
1322            let DeviceSocketId(rc) = socket;
1323            // NB: Circumvent lock ordering for tests.
1324            let target = rc.target.lock();
1325            cb(&target)
1326        }
1327
1328        fn with_socket_state_mut<F: FnOnce(&mut Target<Self::WeakDeviceId>) -> R, R>(
1329            &mut self,
1330            socket: &DeviceSocketId<Self::WeakDeviceId, FakeBindingsCtx>,
1331            cb: F,
1332        ) -> R {
1333            let DeviceSocketId(rc) = socket;
1334            // NB: Circumvent lock ordering for tests.
1335            let mut target = rc.target.lock();
1336            cb(&mut target)
1337        }
1338    }
1339
1340    impl<
1341        'm,
1342        DeviceId: FakeStrongDeviceId,
1343        As: AsFakeSocketsMutRefs<
1344                Devices = HashMap<DeviceId, DeviceSockets<DeviceId::Weak, FakeBindingsCtx>>,
1345            > + DeviceIdContext<AnyDevice, DeviceId = DeviceId, WeakDeviceId = DeviceId::Weak>,
1346    > DeviceSocketAccessor<FakeBindingsCtx> for As
1347    {
1348        type DeviceSocketCoreCtx<'a> =
1349            FakeSocketsMutRefs<'a, As::AnyDevice, As::AllSockets, HashSet<DeviceId>, DeviceId>;
1350        fn with_device_sockets<
1351            F: FnOnce(
1352                &DeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1353                &mut Self::DeviceSocketCoreCtx<'_>,
1354            ) -> R,
1355            R,
1356        >(
1357            &mut self,
1358            device: &Self::DeviceId,
1359            cb: F,
1360        ) -> R {
1361            let FakeSocketsMutRefs(any_device, all_sockets, device_sockets, PhantomData, counters) =
1362                self.as_sockets_ref();
1363            let mut devices = device_sockets.keys().cloned().collect();
1364            let device = device_sockets.get(device).unwrap();
1365            cb(
1366                device,
1367                &mut FakeSocketsMutRefs(
1368                    any_device,
1369                    all_sockets,
1370                    &mut devices,
1371                    PhantomData,
1372                    counters,
1373                ),
1374            )
1375        }
1376        fn with_device_sockets_mut<
1377            F: FnOnce(
1378                &mut DeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1379                &mut Self::DeviceSocketCoreCtx<'_>,
1380            ) -> R,
1381            R,
1382        >(
1383            &mut self,
1384            device: &Self::DeviceId,
1385            cb: F,
1386        ) -> R {
1387            let FakeSocketsMutRefs(any_device, all_sockets, device_sockets, PhantomData, counters) =
1388                self.as_sockets_ref();
1389            let mut devices = device_sockets.keys().cloned().collect();
1390            let device = device_sockets.get_mut(device).unwrap();
1391            cb(
1392                device,
1393                &mut FakeSocketsMutRefs(
1394                    any_device,
1395                    all_sockets,
1396                    &mut devices,
1397                    PhantomData,
1398                    counters,
1399                ),
1400            )
1401        }
1402    }
1403
1404    impl<
1405        'm,
1406        DeviceId: FakeStrongDeviceId,
1407        As: AsFakeSocketsMutRefs<
1408                AnyDevice = AnyDeviceSockets<DeviceId::Weak, FakeBindingsCtx>,
1409                AllSockets = AllSockets<DeviceId::Weak, FakeBindingsCtx>,
1410                Devices = HashMap<DeviceId, DeviceSockets<DeviceId::Weak, FakeBindingsCtx>>,
1411            > + DeviceIdContext<AnyDevice, DeviceId = DeviceId, WeakDeviceId = DeviceId::Weak>,
1412    > DeviceSocketContext<FakeBindingsCtx> for As
1413    {
1414        type SocketTablesCoreCtx<'a> = FakeSocketsMutRefs<
1415            'a,
1416            (),
1417            (),
1418            HashMap<DeviceId, DeviceSockets<DeviceId::Weak, FakeBindingsCtx>>,
1419            DeviceId,
1420        >;
1421
1422        fn with_any_device_sockets<
1423            F: FnOnce(
1424                &AnyDeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1425                &mut Self::SocketTablesCoreCtx<'_>,
1426            ) -> R,
1427            R,
1428        >(
1429            &mut self,
1430            cb: F,
1431        ) -> R {
1432            let FakeSocketsMutRefs(
1433                any_device_sockets,
1434                _all_sockets,
1435                device_sockets,
1436                PhantomData,
1437                counters,
1438            ) = self.as_sockets_ref();
1439            cb(
1440                any_device_sockets,
1441                &mut FakeSocketsMutRefs(&mut (), &mut (), device_sockets, PhantomData, counters),
1442            )
1443        }
1444        fn with_any_device_sockets_mut<
1445            F: FnOnce(
1446                &mut AnyDeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1447                &mut Self::SocketTablesCoreCtx<'_>,
1448            ) -> R,
1449            R,
1450        >(
1451            &mut self,
1452            cb: F,
1453        ) -> R {
1454            let FakeSocketsMutRefs(
1455                any_device_sockets,
1456                _all_sockets,
1457                device_sockets,
1458                PhantomData,
1459                counters,
1460            ) = self.as_sockets_ref();
1461            cb(
1462                any_device_sockets,
1463                &mut FakeSocketsMutRefs(&mut (), &mut (), device_sockets, PhantomData, counters),
1464            )
1465        }
1466
1467        fn with_all_device_sockets<
1468            F: FnOnce(
1469                &AllSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1470                &mut Self::SocketTablesCoreCtx<'_>,
1471            ) -> R,
1472            R,
1473        >(
1474            &mut self,
1475            cb: F,
1476        ) -> R {
1477            let FakeSocketsMutRefs(
1478                _any_device_sockets,
1479                all_sockets,
1480                device_sockets,
1481                PhantomData,
1482                counters,
1483            ) = self.as_sockets_ref();
1484            cb(
1485                all_sockets,
1486                &mut FakeSocketsMutRefs(&mut (), &mut (), device_sockets, PhantomData, counters),
1487            )
1488        }
1489
1490        fn with_all_device_sockets_mut<
1491            F: FnOnce(&mut AllSockets<Self::WeakDeviceId, FakeBindingsCtx>) -> R,
1492            R,
1493        >(
1494            &mut self,
1495            cb: F,
1496        ) -> R {
1497            let FakeSocketsMutRefs(_, all_sockets, _, _, _) = self.as_sockets_ref();
1498            cb(all_sockets)
1499        }
1500    }
1501
1502    impl<'m, X, Y, Z, D: FakeStrongDeviceId> DeviceIdContext<AnyDevice>
1503        for FakeSocketsMutRefs<'m, X, Y, Z, D>
1504    {
1505        type DeviceId = D;
1506        type WeakDeviceId = FakeWeakDeviceId<D>;
1507    }
1508
1509    impl<D: FakeStrongDeviceId> CounterContext<DeviceSocketCounters> for FakeCoreCtx<D> {
1510        fn counters(&self) -> &DeviceSocketCounters {
1511            &self.state.counters
1512        }
1513    }
1514
1515    impl<D: FakeStrongDeviceId>
1516        ResourceCounterContext<DeviceSocketId<D::Weak, FakeBindingsCtx>, DeviceSocketCounters>
1517        for FakeCoreCtx<D>
1518    {
1519        fn per_resource_counters<'a>(
1520            &'a self,
1521            socket: &'a DeviceSocketId<D::Weak, FakeBindingsCtx>,
1522        ) -> &'a DeviceSocketCounters {
1523            socket.counters()
1524        }
1525    }
1526
1527    impl<'m, X, Y, Z, D> CounterContext<DeviceSocketCounters> for FakeSocketsMutRefs<'m, X, Y, Z, D> {
1528        fn counters(&self) -> &DeviceSocketCounters {
1529            let FakeSocketsMutRefs(_, _, _, _, counters) = self;
1530            counters
1531        }
1532    }
1533
1534    impl<'m, X, Y, Z, D: FakeStrongDeviceId>
1535        ResourceCounterContext<DeviceSocketId<D::Weak, FakeBindingsCtx>, DeviceSocketCounters>
1536        for FakeSocketsMutRefs<'m, X, Y, Z, D>
1537    {
1538        fn per_resource_counters<'a>(
1539            &'a self,
1540            socket: &'a DeviceSocketId<D::Weak, FakeBindingsCtx>,
1541        ) -> &'a DeviceSocketCounters {
1542            socket.counters()
1543        }
1544    }
1545
1546    const SOME_PROTOCOL: NonZeroU16 = NonZeroU16::new(2000).unwrap();
1547
1548    #[test]
1549    fn create_remove() {
1550        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1551            MultipleDevicesId::all(),
1552        )));
1553        let mut api = ctx.device_socket_api();
1554
1555        let bound = api.create(Default::default());
1556        assert_eq!(
1557            api.get_info(&bound),
1558            SocketInfo { device: TargetDevice::AnyDevice, protocol: None }
1559        );
1560
1561        let ExternalSocketState(_received_frames) = api.remove(bound).into_removed();
1562    }
1563
1564    #[test_case(TargetDevice::AnyDevice)]
1565    #[test_case(TargetDevice::SpecificDevice(&MultipleDevicesId::A))]
1566    fn test_set_device(device: TargetDevice<&MultipleDevicesId>) {
1567        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1568            MultipleDevicesId::all(),
1569        )));
1570        let mut api = ctx.device_socket_api();
1571
1572        let bound = api.create(Default::default());
1573        api.set_device(&bound, device.clone());
1574        assert_eq!(
1575            api.get_info(&bound),
1576            SocketInfo { device: device.with_weak_id(), protocol: None }
1577        );
1578
1579        let device_sockets = &api.core_ctx().state.device_sockets;
1580        if let TargetDevice::SpecificDevice(d) = device {
1581            let DeviceSockets(socket_ids) = device_sockets.get(d).expect("device state exists");
1582            assert_eq!(socket_ids, &HashSet::from([bound]));
1583        }
1584    }
1585
1586    #[test]
1587    fn update_device() {
1588        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1589            MultipleDevicesId::all(),
1590        )));
1591        let mut api = ctx.device_socket_api();
1592        let bound = api.create(Default::default());
1593
1594        api.set_device(&bound, TargetDevice::SpecificDevice(&MultipleDevicesId::A));
1595
1596        // Now update the device and make sure the socket only appears in the
1597        // one device's list.
1598        api.set_device(&bound, TargetDevice::SpecificDevice(&MultipleDevicesId::B));
1599        assert_eq!(
1600            api.get_info(&bound),
1601            SocketInfo {
1602                device: TargetDevice::SpecificDevice(FakeWeakDeviceId(MultipleDevicesId::B)),
1603                protocol: None
1604            }
1605        );
1606
1607        let device_sockets = &api.core_ctx().state.device_sockets;
1608        let device_socket_lists = device_sockets
1609            .iter()
1610            .map(|(d, DeviceSockets(indexes))| (d, indexes.iter().collect()))
1611            .collect::<HashMap<_, _>>();
1612
1613        assert_eq!(
1614            device_socket_lists,
1615            HashMap::from([
1616                (&MultipleDevicesId::A, vec![]),
1617                (&MultipleDevicesId::B, vec![&bound]),
1618                (&MultipleDevicesId::C, vec![])
1619            ])
1620        );
1621    }
1622
1623    #[test_case(Protocol::All, TargetDevice::AnyDevice)]
1624    #[test_case(Protocol::Specific(SOME_PROTOCOL), TargetDevice::AnyDevice)]
1625    #[test_case(Protocol::All, TargetDevice::SpecificDevice(&MultipleDevicesId::A))]
1626    #[test_case(
1627        Protocol::Specific(SOME_PROTOCOL),
1628        TargetDevice::SpecificDevice(&MultipleDevicesId::A)
1629    )]
1630    fn create_set_device_and_protocol_remove_multiple(
1631        protocol: Protocol,
1632        device: TargetDevice<&MultipleDevicesId>,
1633    ) {
1634        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1635            MultipleDevicesId::all(),
1636        )));
1637        let mut api = ctx.device_socket_api();
1638
1639        let mut sockets = [(); 3].map(|()| api.create(Default::default()));
1640        for socket in &mut sockets {
1641            api.set_device_and_protocol(socket, device.clone(), protocol);
1642            assert_eq!(
1643                api.get_info(socket),
1644                SocketInfo { device: device.with_weak_id(), protocol: Some(protocol) }
1645            );
1646        }
1647
1648        for socket in sockets {
1649            let ExternalSocketState(_received_frames) = api.remove(socket).into_removed();
1650        }
1651    }
1652
1653    #[test]
1654    fn change_device_after_removal() {
1655        let device_to_remove = FakeReferencyDeviceId::default();
1656        let device_to_maintain = FakeReferencyDeviceId::default();
1657        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new([
1658            device_to_remove.clone(),
1659            device_to_maintain.clone(),
1660        ])));
1661        let mut api = ctx.device_socket_api();
1662
1663        let bound = api.create(Default::default());
1664        // Set the device for the socket before removing the device state
1665        // entirely.
1666        api.set_device(&bound, TargetDevice::SpecificDevice(&device_to_remove));
1667
1668        // Now remove the device; this should cause future attempts to upgrade
1669        // the device ID to fail.
1670        device_to_remove.mark_removed();
1671
1672        // Changing the device should gracefully handle the fact that the
1673        // earlier-bound device is now gone.
1674        api.set_device(&bound, TargetDevice::SpecificDevice(&device_to_maintain));
1675        assert_eq!(
1676            api.get_info(&bound),
1677            SocketInfo {
1678                device: TargetDevice::SpecificDevice(FakeWeakDeviceId(device_to_maintain.clone())),
1679                protocol: None,
1680            }
1681        );
1682
1683        let device_sockets = &api.core_ctx().state.device_sockets;
1684        let DeviceSockets(weak_sockets) =
1685            device_sockets.get(&device_to_maintain).expect("device state exists");
1686        assert_eq!(weak_sockets, &HashSet::from([bound]));
1687    }
1688
1689    struct TestData;
1690    impl TestData {
1691        const SRC_MAC: Mac = Mac::new([0, 1, 2, 3, 4, 5]);
1692        const DST_MAC: Mac = Mac::new([6, 7, 8, 9, 10, 11]);
1693        /// Arbitrary protocol number.
1694        const PROTO: NonZeroU16 = NonZeroU16::new(0x08AB).unwrap();
1695        const BODY: &'static [u8] = b"some pig";
1696        const BUFFER: &'static [u8] = &[
1697            6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 0x08, 0xAB, b's', b'o', b'm', b'e', b' ', b'p',
1698            b'i', b'g',
1699        ];
1700        const BUFFER_OFFSET: usize = Self::BUFFER.len() - Self::BODY.len();
1701
1702        /// Creates an EthernetFrame with the values specified above.
1703        fn frame() -> packet_formats::ethernet::EthernetFrame<&'static [u8]> {
1704            let mut buffer_view = Self::BUFFER;
1705            packet_formats::ethernet::EthernetFrame::parse(
1706                &mut buffer_view,
1707                EthernetFrameLengthCheck::NoCheck,
1708            )
1709            .unwrap()
1710        }
1711    }
1712
1713    const WRONG_PROTO: NonZeroU16 = NonZeroU16::new(0x08ff).unwrap();
1714
1715    fn make_bound<D: FakeStrongDeviceId>(
1716        ctx: &mut FakeCtx<D>,
1717        device: TargetDevice<D>,
1718        protocol: Option<Protocol>,
1719        state: ExternalSocketState<D::Weak>,
1720    ) -> DeviceSocketId<D::Weak, FakeBindingsCtx> {
1721        let mut api = ctx.device_socket_api();
1722        let id = api.create(state);
1723        let device = match &device {
1724            TargetDevice::AnyDevice => TargetDevice::AnyDevice,
1725            TargetDevice::SpecificDevice(d) => TargetDevice::SpecificDevice(d),
1726        };
1727        match protocol {
1728            Some(protocol) => api.set_device_and_protocol(&id, device, protocol),
1729            None => api.set_device(&id, device),
1730        };
1731        id
1732    }
1733
1734    /// Deliver one frame to the provided contexts and return the IDs of the
1735    /// sockets it was delivered to.
1736    fn deliver_one_frame(
1737        delivered_frame: Frame<&[u8]>,
1738        FakeCtx { core_ctx, bindings_ctx }: &mut FakeCtx<MultipleDevicesId>,
1739    ) -> HashSet<DeviceSocketId<FakeWeakDeviceId<MultipleDevicesId>, FakeBindingsCtx>> {
1740        DeviceSocketHandler::handle_frame(
1741            core_ctx,
1742            bindings_ctx,
1743            &MultipleDevicesId::A,
1744            delivered_frame.clone(),
1745            TestData::BUFFER,
1746        );
1747
1748        let FakeSockets {
1749            all_sockets: AllSockets(all_sockets),
1750            any_device_sockets: _,
1751            device_sockets: _,
1752            counters: _,
1753            sent_frames: _,
1754        } = &core_ctx.state;
1755
1756        all_sockets
1757            .iter()
1758            .filter_map(|(id, _primary)| {
1759                let DeviceSocketId(rc) = &id;
1760                let ExternalSocketState(frames) = &rc.external_state;
1761                let lock_guard = frames.lock();
1762                let testutil::RxQueue { frames, .. } = lock_guard.deref();
1763                (!frames.is_empty()).then(|| {
1764                    assert_eq!(
1765                        &*frames,
1766                        &[ReceivedFrame {
1767                            device: FakeWeakDeviceId(MultipleDevicesId::A),
1768                            frame: delivered_frame.cloned(),
1769                            raw: TestData::BUFFER.into(),
1770                        }]
1771                    );
1772                    id.clone()
1773                })
1774            })
1775            .collect()
1776    }
1777
1778    #[test]
1779    fn receive_frame_deliver_to_multiple() {
1780        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1781            MultipleDevicesId::all(),
1782        )));
1783
1784        use Protocol::*;
1785        use TargetDevice::*;
1786        let never_bound = {
1787            let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1788            ctx.device_socket_api().create(state)
1789        };
1790
1791        let mut make_bound = |device, protocol| {
1792            let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1793            make_bound(&mut ctx, device, protocol, state)
1794        };
1795        let bound_a_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::A), None);
1796        let bound_a_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::A), Some(All));
1797        let bound_a_right_protocol =
1798            make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(TestData::PROTO)));
1799        let bound_a_wrong_protocol =
1800            make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(WRONG_PROTO)));
1801        let bound_b_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::B), None);
1802        let bound_b_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::B), Some(All));
1803        let bound_b_right_protocol =
1804            make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(TestData::PROTO)));
1805        let bound_b_wrong_protocol =
1806            make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(WRONG_PROTO)));
1807        let bound_any_no_protocol = make_bound(AnyDevice, None);
1808        let bound_any_all_protocols = make_bound(AnyDevice, Some(All));
1809        let bound_any_right_protocol = make_bound(AnyDevice, Some(Specific(TestData::PROTO)));
1810        let bound_any_wrong_protocol = make_bound(AnyDevice, Some(Specific(WRONG_PROTO)));
1811
1812        let mut sockets_with_received_frames = deliver_one_frame(
1813            super::ReceivedFrame::from_ethernet(
1814                TestData::frame(),
1815                FrameDestination::Individual { local: true },
1816                PacketType::Host,
1817                None,
1818            )
1819            .into(),
1820            &mut ctx,
1821        );
1822
1823        let sockets_not_expecting_frames = [
1824            never_bound,
1825            bound_a_no_protocol,
1826            bound_a_wrong_protocol,
1827            bound_b_no_protocol,
1828            bound_b_all_protocols,
1829            bound_b_right_protocol,
1830            bound_b_wrong_protocol,
1831            bound_any_no_protocol,
1832            bound_any_wrong_protocol,
1833        ];
1834        let sockets_expecting_frames = [
1835            bound_a_all_protocols,
1836            bound_a_right_protocol,
1837            bound_any_all_protocols,
1838            bound_any_right_protocol,
1839        ];
1840
1841        for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1842            assert!(
1843                sockets_with_received_frames.remove(socket),
1844                "socket {n} didn't receive the frame"
1845            );
1846        }
1847        assert!(sockets_with_received_frames.is_empty());
1848
1849        // Verify Counters were set appropriately for each socket.
1850        for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1851            assert_eq!(socket.counters().rx_frames.get(), 1, "socket {n} has wrong rx_frames");
1852        }
1853        for (n, socket) in sockets_not_expecting_frames.iter().enumerate() {
1854            assert_eq!(socket.counters().rx_frames.get(), 0, "socket {n} has wrong rx_frames");
1855        }
1856    }
1857
1858    #[test]
1859    fn sent_frame_deliver_to_multiple() {
1860        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1861            MultipleDevicesId::all(),
1862        )));
1863
1864        use Protocol::*;
1865        use TargetDevice::*;
1866        let never_bound = {
1867            let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1868            ctx.device_socket_api().create(state)
1869        };
1870
1871        let mut make_bound = |device, protocol| {
1872            let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1873            make_bound(&mut ctx, device, protocol, state)
1874        };
1875        let bound_a_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::A), None);
1876        let bound_a_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::A), Some(All));
1877        let bound_a_same_protocol =
1878            make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(TestData::PROTO)));
1879        let bound_a_wrong_protocol =
1880            make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(WRONG_PROTO)));
1881        let bound_b_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::B), None);
1882        let bound_b_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::B), Some(All));
1883        let bound_b_same_protocol =
1884            make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(TestData::PROTO)));
1885        let bound_b_wrong_protocol =
1886            make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(WRONG_PROTO)));
1887        let bound_any_no_protocol = make_bound(AnyDevice, None);
1888        let bound_any_all_protocols = make_bound(AnyDevice, Some(All));
1889        let bound_any_same_protocol = make_bound(AnyDevice, Some(Specific(TestData::PROTO)));
1890        let bound_any_wrong_protocol = make_bound(AnyDevice, Some(Specific(WRONG_PROTO)));
1891
1892        let mut sockets_with_received_frames =
1893            deliver_one_frame(SentFrame::Ethernet(TestData::frame().into()).into(), &mut ctx);
1894
1895        let sockets_not_expecting_frames = [
1896            never_bound,
1897            bound_a_no_protocol,
1898            bound_a_same_protocol,
1899            bound_a_wrong_protocol,
1900            bound_b_no_protocol,
1901            bound_b_all_protocols,
1902            bound_b_same_protocol,
1903            bound_b_wrong_protocol,
1904            bound_any_no_protocol,
1905            bound_any_same_protocol,
1906            bound_any_wrong_protocol,
1907        ];
1908        // Only any-protocol sockets receive sent frames.
1909        let sockets_expecting_frames = [bound_a_all_protocols, bound_any_all_protocols];
1910
1911        for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1912            assert!(
1913                sockets_with_received_frames.remove(socket),
1914                "socket {n} didn't receive the frame"
1915            );
1916        }
1917        assert!(sockets_with_received_frames.is_empty());
1918
1919        // Verify Counters were set appropriately for each socket.
1920        for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1921            assert_eq!(socket.counters().rx_frames.get(), 1, "socket {n} has wrong rx_frames");
1922        }
1923        for (n, socket) in sockets_not_expecting_frames.iter().enumerate() {
1924            assert_eq!(socket.counters().rx_frames.get(), 0, "socket {n} has wrong rx_frames");
1925        }
1926    }
1927
1928    #[test]
1929    fn deliver_multiple_frames() {
1930        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1931            MultipleDevicesId::all(),
1932        )));
1933        let socket = make_bound(
1934            &mut ctx,
1935            TargetDevice::AnyDevice,
1936            Some(Protocol::All),
1937            ExternalSocketState::default(),
1938        );
1939        let FakeCtx { mut core_ctx, mut bindings_ctx } = ctx;
1940
1941        // Attach GSO metadata to verify it's delivered alongside the frame.
1942        const GSO_INFO: GsoInfo = GsoInfo {
1943            gso_size: NonZeroU16::new(1000).unwrap(),
1944            gso_segs: NonZeroU16::new(3).unwrap(),
1945            ipv4_id_mode: None,
1946        };
1947
1948        const RECEIVE_COUNT: usize = 10;
1949        for _ in 0..RECEIVE_COUNT {
1950            DeviceSocketHandler::handle_frame(
1951                &mut core_ctx,
1952                &mut bindings_ctx,
1953                &MultipleDevicesId::A,
1954                super::ReceivedFrame::from_ethernet(
1955                    TestData::frame(),
1956                    FrameDestination::Individual { local: true },
1957                    PacketType::Host,
1958                    Some(GSO_INFO),
1959                )
1960                .into(),
1961                TestData::BUFFER,
1962            );
1963        }
1964
1965        let FakeSockets {
1966            all_sockets: AllSockets(mut all_sockets),
1967            any_device_sockets: _,
1968            device_sockets: _,
1969            counters: _,
1970            sent_frames: _,
1971        } = core_ctx.into_state();
1972        let primary = all_sockets.remove(&socket).unwrap();
1973        let PrimaryDeviceSocketId(primary) = primary;
1974        assert!(all_sockets.is_empty());
1975        drop(socket);
1976        let SocketState { external_state: ExternalSocketState(received), counters, target: _ } =
1977            PrimaryRc::unwrap(primary);
1978        assert_eq!(
1979            received.into_inner().frames,
1980            vec![
1981                ReceivedFrame {
1982                    device: FakeWeakDeviceId(MultipleDevicesId::A),
1983                    frame: Frame::Received(super::ReceivedFrame::Ethernet {
1984                        destination: FrameDestination::Individual { local: true },
1985                        frame: EthernetFrame {
1986                            src_mac: TestData::SRC_MAC,
1987                            dst_mac: TestData::DST_MAC,
1988                            ethertype: Some(TestData::PROTO.get().into()),
1989                            body_offset: TestData::BUFFER_OFFSET,
1990                            body: Vec::from(TestData::BODY),
1991                        },
1992                        packet_type: PacketType::Host,
1993                        gso_info: Some(GSO_INFO),
1994                    }),
1995                    raw: TestData::BUFFER.into()
1996                };
1997                RECEIVE_COUNT
1998            ]
1999        );
2000        assert_eq!(counters.rx_frames.get(), u64::try_from(RECEIVE_COUNT).unwrap());
2001    }
2002
2003    #[test]
2004    fn deliver_frame_queue_full() {
2005        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
2006            MultipleDevicesId::all(),
2007        )));
2008
2009        // Simulate a full RX queue for sock1.
2010        let sock1 = make_bound(
2011            &mut ctx,
2012            TargetDevice::AnyDevice,
2013            Some(Protocol::All),
2014            ExternalSocketState(Mutex::new(testutil::RxQueue { frames: vec![], max_size: 0 })),
2015        );
2016        let sock2 = make_bound(
2017            &mut ctx,
2018            TargetDevice::AnyDevice,
2019            Some(Protocol::All),
2020            ExternalSocketState::default(),
2021        );
2022
2023        let FakeCtx { mut core_ctx, mut bindings_ctx } = ctx;
2024
2025        DeviceSocketHandler::handle_frame(
2026            &mut core_ctx,
2027            &mut bindings_ctx,
2028            &MultipleDevicesId::A,
2029            super::ReceivedFrame::from_ethernet(
2030                TestData::frame(),
2031                FrameDestination::Individual { local: true },
2032                PacketType::Host,
2033                None,
2034            )
2035            .into(),
2036            TestData::BUFFER,
2037        );
2038
2039        assert_eq!(core_ctx.state.counters.rx_frames.get(), 2);
2040        assert_eq!(core_ctx.state.counters.rx_queue_full.get(), 1);
2041        assert_eq!(sock1.counters().rx_frames.get(), 1);
2042        assert_eq!(sock1.counters().rx_queue_full.get(), 1);
2043        assert_eq!(sock2.counters().rx_frames.get(), 1);
2044        assert_eq!(sock2.counters().rx_queue_full.get(), 0);
2045
2046        // Drop our strong references to the sockets so that `core_ctx` can tear
2047        // down successfully.
2048        drop(sock1);
2049        drop(sock2);
2050    }
2051
2052    pub struct FakeSendMetadata;
2053    impl DeviceSocketSendTypes for AnyDevice {
2054        type Metadata = FakeSendMetadata;
2055    }
2056    impl<BC: TxMetadataBindingsTypes, D: FakeStrongDeviceId> SendableFrameMeta<FakeCoreCtx<D>, BC>
2057        for DeviceSocketMetadata<AnyDevice, FakeCoreCtx<D>, BC>
2058    {
2059        fn send_meta<S>(
2060            self,
2061            core_ctx: &mut FakeCoreCtx<D>,
2062            _bindings_ctx: &mut BC,
2063            frame: S,
2064        ) -> Result<(), SendFrameError<S>>
2065        where
2066            S: NetworkSerializer,
2067            S::Buffer: BufferMut,
2068        {
2069            let frame = match frame.serialize_vec_outer(&mut NetworkSerializationContext::default())
2070            {
2071                Err(e) => {
2072                    let _: (packet::SerializeError<!>, _) = e;
2073                    unreachable!()
2074                }
2075                Ok(frame) => frame.unwrap_a().as_ref().to_vec(),
2076            };
2077            core_ctx.state.sent_frames.push(frame);
2078            Ok(())
2079        }
2080    }
2081
2082    #[test]
2083    fn send_multiple_frames() {
2084        let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
2085            MultipleDevicesId::all(),
2086        )));
2087
2088        const DEVICE: MultipleDevicesId = MultipleDevicesId::A;
2089        let socket = make_bound(
2090            &mut ctx,
2091            TargetDevice::SpecificDevice(DEVICE),
2092            Some(Protocol::All),
2093            ExternalSocketState::default(),
2094        );
2095        let mut api = ctx.device_socket_api();
2096
2097        const SEND_COUNT: usize = 10;
2098        const PAYLOAD: &'static [u8] = &[1, 2, 3, 4, 5];
2099        for _ in 0..SEND_COUNT {
2100            let buf = packet::Buf::new(PAYLOAD.to_vec(), ..);
2101            api.send_frame(
2102                &socket,
2103                DeviceSocketMetadata {
2104                    device_id: DEVICE,
2105                    metadata: FakeSendMetadata,
2106                    ip_layer_metadata: DeviceIpLayerMetadata::empty(),
2107                },
2108                buf,
2109            )
2110            .expect("send failed");
2111        }
2112
2113        assert_eq!(ctx.core_ctx().state.sent_frames, vec![PAYLOAD.to_vec(); SEND_COUNT]);
2114
2115        assert_eq!(socket.counters().tx_frames.get(), u64::try_from(SEND_COUNT).unwrap());
2116    }
2117}