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