1use 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, Inspectable,
19 Inspector, InspectorDeviceExt, InspectorExt, NetworkSerializer, ReferenceNotifiers,
20 ReferenceNotifiersExt as _, RemoveResourceResultWithContext, ResourceCounterContext,
21 SendFrameContext, SendFrameErrorReason, StrongDeviceIdentifier, WeakDeviceIdentifier as _,
22};
23use netstack3_hashmap::{HashMap, HashSet};
24use packet::{BufferMut, ParsablePacket as _};
25use packet_formats::error::ParseError;
26use packet_formats::ethernet::{EtherType, EthernetFrameLengthCheck};
27
28use crate::internal::base::DeviceLayerTypes;
29use crate::internal::id::WeakDeviceId;
30
31#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
33pub enum Protocol {
34 All,
36 Specific(NonZeroU16),
38}
39
40#[derive(Clone, Debug, Derivative, Eq, Hash, PartialEq)]
42#[derivative(Default(bound = ""))]
43pub enum TargetDevice<D> {
44 #[derivative(Default)]
46 AnyDevice,
47 SpecificDevice(D),
49}
50
51#[derive(Debug)]
53#[cfg_attr(test, derive(PartialEq))]
54pub struct SocketInfo<D> {
55 pub protocol: Option<Protocol>,
57 pub device: TargetDevice<D>,
59}
60
61pub trait DeviceSocketTypes {
64 type SocketState<D: Send + Sync + Debug>: Send + Sync + Debug;
66}
67
68pub enum ReceiveFrameError {
70 QueueFull,
72}
73
74pub trait DeviceSocketBindingsContext<DeviceId: StrongDeviceIdentifier>:
76 DeviceSocketTypes + Sized
77{
78 fn receive_frame(
82 &self,
83 socket_id: &DeviceSocketId<DeviceId::Weak, Self>,
84 device: &DeviceId,
85 frame: Frame<&[u8]>,
86 raw_frame: &[u8],
87 ) -> Result<(), ReceiveFrameError>;
88}
89
90#[derive(Debug)]
94pub struct PrimaryDeviceSocketId<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
95 PrimaryRc<SocketState<D, BT>>,
96);
97
98impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> PrimaryDeviceSocketId<D, BT> {
99 fn new(external_state: BT::SocketState<D>) -> Self {
101 Self(PrimaryRc::new(SocketState {
102 external_state,
103 counters: Default::default(),
104 target: Default::default(),
105 }))
106 }
107
108 fn clone_strong(&self) -> DeviceSocketId<D, BT> {
110 let PrimaryDeviceSocketId(rc) = self;
111 DeviceSocketId(PrimaryRc::clone_strong(rc))
112 }
113}
114
115#[derive(Derivative)]
120#[derivative(Clone(bound = ""), Hash(bound = ""), Eq(bound = ""), PartialEq(bound = ""))]
121pub struct DeviceSocketId<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
122 StrongRc<SocketState<D, BT>>,
123);
124
125impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> DeviceSocketId<D, BT> {
126 pub fn socket_cookie(&self) -> SocketCookie {
128 let Self(rc) = self;
129 SocketCookie::new(rc.resource_token())
130 }
131}
132
133impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> Debug for DeviceSocketId<D, BT> {
134 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
135 let Self(rc) = self;
136 f.debug_tuple("DeviceSocketId").field(&StrongRc::debug_id(rc)).finish()
137 }
138}
139
140impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> OrderedLockAccess<Target<D>>
141 for DeviceSocketId<D, BT>
142{
143 type Lock = Mutex<Target<D>>;
144 fn ordered_lock_access(&self) -> OrderedLockRef<'_, Self::Lock> {
145 let Self(rc) = self;
146 OrderedLockRef::new(&rc.target)
147 }
148}
149
150#[derive(Derivative)]
155#[derivative(Clone(bound = ""), Hash(bound = ""), Eq(bound = ""), PartialEq(bound = ""))]
156pub struct WeakDeviceSocketId<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
157 WeakRc<SocketState<D, BT>>,
158);
159
160impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> Debug for WeakDeviceSocketId<D, BT> {
161 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162 let Self(rc) = self;
163 f.debug_tuple("WeakDeviceSocketId").field(&WeakRc::debug_id(rc)).finish()
164 }
165}
166
167#[derive(Derivative)]
169#[derivative(Default(bound = ""))]
170pub struct Sockets<D: Send + Sync + Debug, BT: DeviceSocketTypes> {
171 any_device_sockets: RwLock<AnyDeviceSockets<D, BT>>,
174
175 all_sockets: RwLock<AllSockets<D, BT>>,
182}
183
184#[derive(Derivative)]
186#[derivative(Default(bound = ""))]
187pub struct AnyDeviceSockets<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
188 HashSet<DeviceSocketId<D, BT>>,
189);
190
191#[derive(Derivative)]
193#[derivative(Default(bound = ""))]
194pub struct AllSockets<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
195 HashMap<DeviceSocketId<D, BT>, PrimaryDeviceSocketId<D, BT>>,
196);
197
198#[derive(Debug)]
200pub struct SocketState<D: Send + Sync + Debug, BT: DeviceSocketTypes> {
201 pub external_state: BT::SocketState<D>,
203 target: Mutex<Target<D>>,
207 counters: DeviceSocketCounters,
209}
210
211#[derive(Debug, Derivative)]
213#[derivative(Default(bound = ""))]
214pub struct Target<D> {
215 protocol: Option<Protocol>,
216 device: TargetDevice<D>,
217}
218
219#[derive(Derivative)]
224#[derivative(Default(bound = ""))]
225#[cfg_attr(
226 test,
227 derivative(Debug, PartialEq(bound = "BT::SocketState<D>: Hash + Eq, D: Hash + Eq"))
228)]
229pub struct DeviceSockets<D: Send + Sync + Debug, BT: DeviceSocketTypes>(
230 HashSet<DeviceSocketId<D, BT>>,
231);
232
233pub type HeldDeviceSockets<BT> = DeviceSockets<WeakDeviceId<BT>, BT>;
235
236pub type HeldSockets<BT> = Sockets<WeakDeviceId<BT>, BT>;
240
241pub trait DeviceSocketContext<BT: DeviceSocketTypes>: DeviceIdContext<AnyDevice> {
243 type SocketTablesCoreCtx<'a>: DeviceSocketAccessor<BT, DeviceId = Self::DeviceId, WeakDeviceId = Self::WeakDeviceId>;
245
246 fn with_all_device_sockets<
249 F: FnOnce(&AllSockets<Self::WeakDeviceId, BT>, &mut Self::SocketTablesCoreCtx<'_>) -> R,
250 R,
251 >(
252 &mut self,
253 cb: F,
254 ) -> R;
255
256 fn with_all_device_sockets_mut<F: FnOnce(&mut AllSockets<Self::WeakDeviceId, BT>) -> R, R>(
259 &mut self,
260 cb: F,
261 ) -> R;
262
263 fn with_any_device_sockets<
265 F: FnOnce(&AnyDeviceSockets<Self::WeakDeviceId, BT>, &mut Self::SocketTablesCoreCtx<'_>) -> R,
266 R,
267 >(
268 &mut self,
269 cb: F,
270 ) -> R;
271
272 fn with_any_device_sockets_mut<
274 F: FnOnce(
275 &mut AnyDeviceSockets<Self::WeakDeviceId, BT>,
276 &mut Self::SocketTablesCoreCtx<'_>,
277 ) -> R,
278 R,
279 >(
280 &mut self,
281 cb: F,
282 ) -> R;
283}
284
285pub trait SocketStateAccessor<BT: DeviceSocketTypes>: DeviceIdContext<AnyDevice> {
287 fn with_socket_state<F: FnOnce(&Target<Self::WeakDeviceId>) -> R, R>(
289 &mut self,
290 socket: &DeviceSocketId<Self::WeakDeviceId, BT>,
291 cb: F,
292 ) -> R;
293
294 fn with_socket_state_mut<F: FnOnce(&mut Target<Self::WeakDeviceId>) -> R, R>(
296 &mut self,
297 socket: &DeviceSocketId<Self::WeakDeviceId, BT>,
298 cb: F,
299 ) -> R;
300}
301
302pub trait DeviceSocketAccessor<BT: DeviceSocketTypes>: SocketStateAccessor<BT> {
304 type DeviceSocketCoreCtx<'a>: SocketStateAccessor<BT, DeviceId = Self::DeviceId, WeakDeviceId = Self::WeakDeviceId>
306 + ResourceCounterContext<DeviceSocketId<Self::WeakDeviceId, BT>, DeviceSocketCounters>;
307
308 fn with_device_sockets<
311 F: FnOnce(&DeviceSockets<Self::WeakDeviceId, BT>, &mut Self::DeviceSocketCoreCtx<'_>) -> R,
312 R,
313 >(
314 &mut self,
315 device: &Self::DeviceId,
316 cb: F,
317 ) -> R;
318
319 fn with_device_sockets_mut<
322 F: FnOnce(&mut DeviceSockets<Self::WeakDeviceId, BT>, &mut Self::DeviceSocketCoreCtx<'_>) -> R,
323 R,
324 >(
325 &mut self,
326 device: &Self::DeviceId,
327 cb: F,
328 ) -> R;
329}
330
331enum MaybeUpdate<T> {
332 NoChange,
333 NewValue(T),
334}
335
336fn update_device_and_protocol<CC: DeviceSocketContext<BT>, BT: DeviceSocketTypes>(
337 core_ctx: &mut CC,
338 socket: &DeviceSocketId<CC::WeakDeviceId, BT>,
339 new_device: TargetDevice<&CC::DeviceId>,
340 protocol_update: MaybeUpdate<Protocol>,
341) {
342 core_ctx.with_any_device_sockets_mut(|AnyDeviceSockets(any_device_sockets), core_ctx| {
343 let old_device = core_ctx.with_socket_state_mut(socket, |Target { protocol, device }| {
349 match protocol_update {
350 MaybeUpdate::NewValue(p) => *protocol = Some(p),
351 MaybeUpdate::NoChange => (),
352 };
353 let old_device = match &device {
354 TargetDevice::SpecificDevice(device) => device.upgrade(),
355 TargetDevice::AnyDevice => {
356 assert!(any_device_sockets.remove(socket));
357 None
358 }
359 };
360 *device = match &new_device {
361 TargetDevice::AnyDevice => TargetDevice::AnyDevice,
362 TargetDevice::SpecificDevice(d) => TargetDevice::SpecificDevice(d.downgrade()),
363 };
364 old_device
365 });
366
367 if let Some(device) = old_device {
373 core_ctx.with_device_sockets_mut(
376 &device,
377 |DeviceSockets(device_sockets), _core_ctx| {
378 assert!(device_sockets.remove(socket), "socket not found in device state");
379 },
380 );
381 }
382
383 match &new_device {
385 TargetDevice::SpecificDevice(new_device) => core_ctx.with_device_sockets_mut(
386 new_device,
387 |DeviceSockets(device_sockets), _core_ctx| {
388 assert!(device_sockets.insert(socket.clone()));
389 },
390 ),
391 TargetDevice::AnyDevice => {
392 assert!(any_device_sockets.insert(socket.clone()))
393 }
394 }
395 })
396}
397
398pub struct DeviceSocketApi<C>(C);
400
401impl<C> DeviceSocketApi<C> {
402 pub fn new(ctx: C) -> Self {
404 Self(ctx)
405 }
406}
407
408type ApiSocketId<C> = DeviceSocketId<
413 <<C as ContextPair>::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId,
414 <C as ContextPair>::BindingsContext,
415>;
416
417impl<C> DeviceSocketApi<C>
418where
419 C: ContextPair,
420 C::CoreContext: DeviceSocketContext<C::BindingsContext>
421 + SocketStateAccessor<C::BindingsContext>
422 + ResourceCounterContext<ApiSocketId<C>, DeviceSocketCounters>,
423 C::BindingsContext: DeviceSocketBindingsContext<<C::CoreContext as DeviceIdContext<AnyDevice>>::DeviceId>
424 + ReferenceNotifiers
425 + 'static,
426{
427 fn core_ctx(&mut self) -> &mut C::CoreContext {
428 let Self(pair) = self;
429 pair.core_ctx()
430 }
431
432 fn contexts(&mut self) -> (&mut C::CoreContext, &mut C::BindingsContext) {
433 let Self(pair) = self;
434 pair.contexts()
435 }
436
437 pub fn create(
439 &mut self,
440 external_state: <C::BindingsContext as DeviceSocketTypes>::SocketState<
441 <C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId,
442 >,
443 ) -> ApiSocketId<C> {
444 let core_ctx = self.core_ctx();
445
446 let strong = core_ctx.with_all_device_sockets_mut(|AllSockets(sockets)| {
447 let primary = PrimaryDeviceSocketId::new(external_state);
448 let strong = primary.clone_strong();
449 assert!(sockets.insert(strong.clone(), primary).is_none());
450 strong
451 });
452 core_ctx.with_any_device_sockets_mut(|AnyDeviceSockets(any_device_sockets), _core_ctx| {
453 assert!(any_device_sockets.insert(strong.clone()));
460 });
461 strong
462 }
463
464 pub fn set_device(
466 &mut self,
467 socket: &ApiSocketId<C>,
468 device: TargetDevice<&<C::CoreContext as DeviceIdContext<AnyDevice>>::DeviceId>,
469 ) {
470 update_device_and_protocol(self.core_ctx(), socket, device, MaybeUpdate::NoChange)
471 }
472
473 pub fn set_device_and_protocol(
475 &mut self,
476 socket: &ApiSocketId<C>,
477 device: TargetDevice<&<C::CoreContext as DeviceIdContext<AnyDevice>>::DeviceId>,
478 protocol: Protocol,
479 ) {
480 update_device_and_protocol(self.core_ctx(), socket, device, MaybeUpdate::NewValue(protocol))
481 }
482
483 pub fn get_info(
485 &mut self,
486 id: &ApiSocketId<C>,
487 ) -> SocketInfo<<C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId> {
488 self.core_ctx().with_socket_state(id, |Target { device, protocol }| SocketInfo {
489 device: device.clone(),
490 protocol: *protocol,
491 })
492 }
493
494 pub fn remove(
496 &mut self,
497 id: ApiSocketId<C>,
498 ) -> RemoveResourceResultWithContext<
499 <C::BindingsContext as DeviceSocketTypes>::SocketState<
500 <C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId,
501 >,
502 C::BindingsContext,
503 > {
504 let core_ctx = self.core_ctx();
505 core_ctx.with_any_device_sockets_mut(|AnyDeviceSockets(any_device_sockets), core_ctx| {
506 let old_device = core_ctx.with_socket_state_mut(&id, |target| {
507 let Target { device, protocol: _ } = target;
508 match &device {
509 TargetDevice::SpecificDevice(device) => device.upgrade(),
510 TargetDevice::AnyDevice => {
511 assert!(any_device_sockets.remove(&id));
512 None
513 }
514 }
515 });
516 if let Some(device) = old_device {
517 core_ctx.with_device_sockets_mut(
518 &device,
519 |DeviceSockets(device_sockets), _core_ctx| {
520 assert!(device_sockets.remove(&id), "device doesn't have socket");
521 },
522 )
523 }
524 });
525
526 core_ctx.with_all_device_sockets_mut(|AllSockets(sockets)| {
527 let primary = sockets
528 .remove(&id)
529 .unwrap_or_else(|| panic!("{id:?} not present in all socket map"));
530 drop(id);
533
534 let PrimaryDeviceSocketId(primary) = primary;
535 C::BindingsContext::unwrap_or_notify_with_new_reference_notifier(
536 primary,
537 |SocketState { external_state, counters: _, target: _ }| external_state,
538 )
539 })
540 }
541
542 pub fn send_frame<S, D>(
544 &mut self,
545 id: &ApiSocketId<C>,
546 metadata: DeviceSocketMetadata<D, <C::CoreContext as DeviceIdContext<D>>::DeviceId>,
547 body: S,
548 ) -> Result<(), SendFrameErrorReason>
549 where
550 S: NetworkSerializer,
551 S::Buffer: BufferMut,
552 D: DeviceSocketSendTypes,
553 C::CoreContext: DeviceIdContext<D>
554 + SendFrameContext<
555 C::BindingsContext,
556 DeviceSocketMetadata<D, <C::CoreContext as DeviceIdContext<D>>::DeviceId>,
557 >,
558 C::BindingsContext: DeviceLayerTypes,
559 {
560 let (core_ctx, bindings_ctx) = self.contexts();
561 let result = core_ctx.send_frame(bindings_ctx, metadata, body).map_err(|e| e.into_err());
562 match &result {
563 Ok(()) => {
564 core_ctx.increment_both(id, |counters: &DeviceSocketCounters| &counters.tx_frames)
565 }
566 Err(SendFrameErrorReason::QueueFull) => core_ctx
567 .increment_both(id, |counters: &DeviceSocketCounters| &counters.tx_err_queue_full),
568 Err(SendFrameErrorReason::Alloc) => core_ctx
569 .increment_both(id, |counters: &DeviceSocketCounters| &counters.tx_err_alloc),
570 Err(SendFrameErrorReason::SizeConstraintsViolation) => core_ctx
571 .increment_both(id, |counters: &DeviceSocketCounters| {
572 &counters.tx_err_size_constraint
573 }),
574 Err(SendFrameErrorReason::AddressResolutionFailed) => {
575 unreachable!("device socket send should not perform link-layer address resolution");
576 }
577 }
578 result
579 }
580
581 pub fn inspect<N>(&mut self, inspector: &mut N)
583 where
584 N: Inspector
585 + InspectorDeviceExt<<C::CoreContext as DeviceIdContext<AnyDevice>>::WeakDeviceId>,
586 {
587 self.core_ctx().with_all_device_sockets(|AllSockets(sockets), core_ctx| {
588 sockets.keys().for_each(|socket| {
589 inspector.record_debug_child(socket, |node| {
590 core_ctx.with_socket_state(socket, |Target { protocol, device }| {
591 node.record_debug("Protocol", protocol);
592 match device {
593 TargetDevice::AnyDevice => node.record_str("Device", "Any"),
594 TargetDevice::SpecificDevice(d) => N::record_device(node, "Device", d),
595 }
596 });
597 node.record_child("Counters", |node| {
598 node.delegate_inspectable(socket.counters())
599 })
600 })
601 })
602 })
603 }
604}
605
606pub trait DeviceSocketSendTypes: Device {
608 type Metadata;
610}
611
612#[derive(Debug, PartialEq)]
614pub struct DeviceSocketMetadata<D: DeviceSocketSendTypes, DeviceId> {
615 pub device_id: DeviceId,
617 pub metadata: D::Metadata,
619 }
622
623#[derive(Debug, PartialEq)]
625pub struct EthernetHeaderParams {
626 pub dest_addr: Mac,
628 pub protocol: EtherType,
630}
631
632pub type SocketId<BC> = DeviceSocketId<WeakDeviceId<BC>, BC>;
637
638impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> DeviceSocketId<D, BT> {
639 pub fn socket_state(&self) -> &BT::SocketState<D> {
642 let Self(strong) = self;
643 let SocketState { external_state, counters: _, target: _ } = &**strong;
644 external_state
645 }
646
647 pub fn downgrade(&self) -> WeakDeviceSocketId<D, BT> {
649 let Self(inner) = self;
650 WeakDeviceSocketId(StrongRc::downgrade(inner))
651 }
652
653 pub fn counters(&self) -> &DeviceSocketCounters {
655 let Self(strong) = self;
656 let SocketState { external_state: _, counters, target: _ } = &**strong;
657 counters
658 }
659}
660
661pub trait DeviceSocketHandler<D: Device, BC>: DeviceIdContext<D> {
666 fn handle_frame(
668 &mut self,
669 bindings_ctx: &mut BC,
670 device: &Self::DeviceId,
671 frame: Frame<&[u8]>,
672 whole_frame: &[u8],
673 );
674}
675
676#[derive(Clone, Copy, Debug, Eq, PartialEq)]
678pub enum ReceivedFrame<B> {
679 Ethernet {
681 destination: FrameDestination,
683 frame: EthernetFrame<B>,
685 },
686 Ip(IpFrame<B>),
691}
692
693#[derive(Clone, Copy, Debug, Eq, PartialEq)]
695pub enum SentFrame<B> {
696 Ethernet(EthernetFrame<B>),
698 Ip(IpFrame<B>),
703}
704
705#[derive(Debug)]
707pub struct ParseSentFrameError;
708
709impl SentFrame<&[u8]> {
710 pub fn try_parse_as_ethernet(mut buf: &[u8]) -> Result<SentFrame<&[u8]>, ParseSentFrameError> {
712 packet_formats::ethernet::EthernetFrame::parse(&mut buf, EthernetFrameLengthCheck::NoCheck)
713 .map_err(|_: ParseError| ParseSentFrameError)
714 .map(|frame| SentFrame::Ethernet(frame.into()))
715 }
716}
717
718#[derive(Clone, Copy, Debug, Eq, PartialEq)]
720pub struct EthernetFrame<B> {
721 pub src_mac: Mac,
723 pub dst_mac: Mac,
725 pub ethertype: Option<EtherType>,
727 pub body_offset: usize,
729 pub body: B,
731}
732
733#[derive(Clone, Copy, Debug, Eq, PartialEq)]
735pub struct IpFrame<B> {
736 pub ip_version: IpVersion,
738 pub body: B,
740}
741
742impl<B> IpFrame<B> {
743 fn ethertype(&self) -> EtherType {
744 let IpFrame { ip_version, body: _ } = self;
745 EtherType::from_ip_version(*ip_version)
746 }
747}
748
749#[derive(Clone, Copy, Debug, Eq, PartialEq)]
751pub enum Frame<B> {
752 Sent(SentFrame<B>),
754 Received(ReceivedFrame<B>),
756}
757
758impl<B> From<SentFrame<B>> for Frame<B> {
759 fn from(value: SentFrame<B>) -> Self {
760 Self::Sent(value)
761 }
762}
763
764impl<B> From<ReceivedFrame<B>> for Frame<B> {
765 fn from(value: ReceivedFrame<B>) -> Self {
766 Self::Received(value)
767 }
768}
769
770impl<'a> From<packet_formats::ethernet::EthernetFrame<&'a [u8]>> for EthernetFrame<&'a [u8]> {
771 fn from(frame: packet_formats::ethernet::EthernetFrame<&'a [u8]>) -> Self {
772 Self {
773 src_mac: frame.src_mac(),
774 dst_mac: frame.dst_mac(),
775 ethertype: frame.ethertype(),
776 body_offset: frame.parse_metadata().header_len(),
777 body: frame.into_body(),
778 }
779 }
780}
781
782impl<'a> ReceivedFrame<&'a [u8]> {
783 pub(crate) fn from_ethernet(
784 frame: packet_formats::ethernet::EthernetFrame<&'a [u8]>,
785 destination: FrameDestination,
786 ) -> Self {
787 Self::Ethernet { destination, frame: frame.into() }
788 }
789}
790
791impl<B> Frame<B> {
792 pub fn protocol(&self) -> Option<u16> {
794 let ethertype = match self {
795 Self::Sent(SentFrame::Ethernet(frame))
796 | Self::Received(ReceivedFrame::Ethernet { destination: _, frame }) => frame.ethertype,
797 Self::Sent(SentFrame::Ip(frame)) | Self::Received(ReceivedFrame::Ip(frame)) => {
798 Some(frame.ethertype())
799 }
800 };
801 ethertype.map(Into::into)
802 }
803
804 pub fn into_body(self) -> B {
806 match self {
807 Self::Received(ReceivedFrame::Ethernet { destination: _, frame })
808 | Self::Sent(SentFrame::Ethernet(frame)) => frame.body,
809 Self::Received(ReceivedFrame::Ip(frame)) | Self::Sent(SentFrame::Ip(frame)) => {
810 frame.body
811 }
812 }
813 }
814
815 pub fn body_offset(&self) -> usize {
817 match self {
818 Self::Received(ReceivedFrame::Ethernet { destination: _, frame })
819 | Self::Sent(SentFrame::Ethernet(frame)) => frame.body_offset,
820 Self::Received(ReceivedFrame::Ip(_)) | Self::Sent(SentFrame::Ip(_)) => 0,
821 }
822 }
823}
824
825impl<
826 D: Device,
827 BC: DeviceSocketBindingsContext<<CC as DeviceIdContext<AnyDevice>>::DeviceId>,
828 CC: DeviceSocketContext<BC> + DeviceIdContext<D>,
829> DeviceSocketHandler<D, BC> for CC
830where
831 <CC as DeviceIdContext<D>>::DeviceId: Into<<CC as DeviceIdContext<AnyDevice>>::DeviceId>,
832{
833 fn handle_frame(
834 &mut self,
835 bindings_ctx: &mut BC,
836 device: &Self::DeviceId,
837 frame: Frame<&[u8]>,
838 whole_frame: &[u8],
839 ) {
840 let device = device.clone().into();
841
842 self.with_any_device_sockets(|AnyDeviceSockets(any_device_sockets), core_ctx| {
846 core_ctx.with_device_sockets(&device, |DeviceSockets(device_sockets), core_ctx| {
861 for socket in any_device_sockets.iter().chain(device_sockets) {
862 let delivered =
863 core_ctx.with_socket_state(socket, |Target { protocol, device: _ }| {
864 let should_deliver = match protocol {
865 None => false,
866 Some(p) => match p {
867 Protocol::Specific(p) => match frame {
871 Frame::Received(_) => Some(p.get()) == frame.protocol(),
872 Frame::Sent(_) => false,
873 },
874 Protocol::All => true,
875 },
876 };
877 should_deliver.then(|| {
878 bindings_ctx.receive_frame(socket, &device, frame, whole_frame)
879 })
880 });
881 match delivered {
882 None => {}
883 Some(result) => {
884 core_ctx.increment_both(socket, |counters: &DeviceSocketCounters| {
885 &counters.rx_frames
886 });
887 match result {
888 Ok(()) => {}
889 Err(ReceiveFrameError::QueueFull) => {
890 core_ctx.increment_both(
891 socket,
892 |counters: &DeviceSocketCounters| &counters.rx_queue_full,
893 );
894 }
895 }
896 }
897 }
898 }
899 })
900 })
901 }
902}
903
904#[derive(Debug, Default)]
908pub struct DeviceSocketCounters {
909 rx_frames: Counter,
915 rx_queue_full: Counter,
918 tx_frames: Counter,
920 tx_err_queue_full: Counter,
922 tx_err_alloc: Counter,
924 tx_err_size_constraint: Counter,
926}
927
928impl Inspectable for DeviceSocketCounters {
929 fn record<I: Inspector>(&self, inspector: &mut I) {
930 let Self {
931 rx_frames,
932 rx_queue_full,
933 tx_frames,
934 tx_err_queue_full,
935 tx_err_alloc,
936 tx_err_size_constraint,
937 } = self;
938 inspector.record_child("Rx", |inspector| {
939 inspector.record_counter("DeliveredFrames", rx_frames);
940 inspector.record_counter("DroppedQueueFull", rx_queue_full);
941 });
942 inspector.record_child("Tx", |inspector| {
943 inspector.record_counter("SentFrames", tx_frames);
944 inspector.record_counter("QueueFullError", tx_err_queue_full);
945 inspector.record_counter("AllocError", tx_err_alloc);
946 inspector.record_counter("SizeConstraintError", tx_err_size_constraint);
947 });
948 }
949}
950
951impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> OrderedLockAccess<AnyDeviceSockets<D, BT>>
952 for Sockets<D, BT>
953{
954 type Lock = RwLock<AnyDeviceSockets<D, BT>>;
955 fn ordered_lock_access(&self) -> OrderedLockRef<'_, Self::Lock> {
956 OrderedLockRef::new(&self.any_device_sockets)
957 }
958}
959
960impl<D: Send + Sync + Debug, BT: DeviceSocketTypes> OrderedLockAccess<AllSockets<D, BT>>
961 for Sockets<D, BT>
962{
963 type Lock = RwLock<AllSockets<D, BT>>;
964 fn ordered_lock_access(&self) -> OrderedLockRef<'_, Self::Lock> {
965 OrderedLockRef::new(&self.all_sockets)
966 }
967}
968
969#[cfg(any(test, feature = "testutils"))]
970mod testutil {
971 use alloc::vec::Vec;
972 use core::num::NonZeroU64;
973 use core::ops::DerefMut;
974 use netstack3_base::StrongDeviceIdentifier;
975 use netstack3_base::testutil::{FakeBindingsCtx, MonotonicIdentifier};
976
977 use super::*;
978 use crate::internal::base::{
979 DeviceClassMatcher, DeviceIdAndNameMatcher, DeviceLayerStateTypes,
980 };
981
982 #[derive(Derivative, Debug)]
983 #[derivative(Default(bound = ""))]
984 pub struct RxQueue<D> {
985 pub frames: Vec<ReceivedFrame<D>>,
986 #[derivative(Default(value = "usize::MAX"))]
987 pub max_size: usize,
988 }
989
990 #[derive(Clone, Debug, PartialEq)]
991 pub struct ReceivedFrame<D> {
992 pub device: D,
993 pub frame: Frame<Vec<u8>>,
994 pub raw: Vec<u8>,
995 }
996
997 #[derive(Debug, Derivative)]
998 #[derivative(Default(bound = ""))]
999 pub struct ExternalSocketState<D>(pub Mutex<RxQueue<D>>);
1000
1001 impl<TimerId, Event: Debug, State> DeviceSocketTypes
1002 for FakeBindingsCtx<TimerId, Event, State, ()>
1003 {
1004 type SocketState<D: Send + Sync + Debug> = ExternalSocketState<D>;
1005 }
1006
1007 impl Frame<&[u8]> {
1008 pub(crate) fn cloned(self) -> Frame<Vec<u8>> {
1009 match self {
1010 Self::Sent(SentFrame::Ethernet(frame)) => {
1011 Frame::Sent(SentFrame::Ethernet(frame.cloned()))
1012 }
1013 Self::Received(super::ReceivedFrame::Ethernet { destination, frame }) => {
1014 Frame::Received(super::ReceivedFrame::Ethernet {
1015 destination,
1016 frame: frame.cloned(),
1017 })
1018 }
1019 Self::Sent(SentFrame::Ip(frame)) => Frame::Sent(SentFrame::Ip(frame.cloned())),
1020 Self::Received(super::ReceivedFrame::Ip(frame)) => {
1021 Frame::Received(super::ReceivedFrame::Ip(frame.cloned()))
1022 }
1023 }
1024 }
1025 }
1026
1027 impl EthernetFrame<&[u8]> {
1028 fn cloned(self) -> EthernetFrame<Vec<u8>> {
1029 let Self { src_mac, dst_mac, ethertype, body_offset, body } = self;
1030 EthernetFrame { src_mac, dst_mac, ethertype, body_offset, body: Vec::from(body) }
1031 }
1032 }
1033
1034 impl IpFrame<&[u8]> {
1035 fn cloned(self) -> IpFrame<Vec<u8>> {
1036 let Self { ip_version, body } = self;
1037 IpFrame { ip_version, body: Vec::from(body) }
1038 }
1039 }
1040
1041 impl<TimerId, Event: Debug, State, D: StrongDeviceIdentifier> DeviceSocketBindingsContext<D>
1042 for FakeBindingsCtx<TimerId, Event, State, ()>
1043 {
1044 fn receive_frame(
1045 &self,
1046 state: &DeviceSocketId<D::Weak, Self>,
1047 device: &D,
1048 frame: Frame<&[u8]>,
1049 raw_frame: &[u8],
1050 ) -> Result<(), ReceiveFrameError> {
1051 let ExternalSocketState(queue) = state.socket_state();
1052 let mut lock_guard = queue.lock();
1053 let RxQueue { frames, max_size } = lock_guard.deref_mut();
1054 if frames.len() < *max_size {
1055 frames.push(ReceivedFrame {
1056 device: device.downgrade(),
1057 frame: frame.cloned(),
1058 raw: raw_frame.into(),
1059 });
1060 Ok(())
1061 } else {
1062 Err(ReceiveFrameError::QueueFull)
1063 }
1064 }
1065 }
1066
1067 impl<
1068 TimerId: Debug + PartialEq + Clone + Send + Sync + 'static,
1069 Event: Debug + 'static,
1070 State: 'static,
1071 > DeviceLayerStateTypes for FakeBindingsCtx<TimerId, Event, State, ()>
1072 {
1073 type EthernetDeviceState = ();
1074 type LoopbackDeviceState = ();
1075 type PureIpDeviceState = ();
1076 type BlackholeDeviceState = ();
1077 type DeviceIdentifier = MonotonicIdentifier;
1078 }
1079
1080 impl DeviceClassMatcher<()> for () {
1081 fn device_class_matches(&self, (): &()) -> bool {
1082 unimplemented!()
1083 }
1084 }
1085
1086 impl DeviceIdAndNameMatcher for MonotonicIdentifier {
1087 fn id_matches(&self, _id: &NonZeroU64) -> bool {
1088 unimplemented!()
1089 }
1090
1091 fn name_matches(&self, _name: &str) -> bool {
1092 unimplemented!()
1093 }
1094 }
1095}
1096
1097#[cfg(test)]
1098mod tests {
1099 use alloc::vec;
1100 use alloc::vec::Vec;
1101 use core::marker::PhantomData;
1102 use core::ops::Deref;
1103
1104 use crate::internal::socket::testutil::{ExternalSocketState, ReceivedFrame};
1105 use netstack3_base::testutil::{
1106 FakeReferencyDeviceId, FakeStrongDeviceId, FakeWeakDeviceId, MultipleDevicesId,
1107 };
1108 use netstack3_base::{
1109 CounterContext, CtxPair, NetworkSerializationContext, SendFrameError, SendableFrameMeta,
1110 };
1111 use netstack3_hashmap::HashMap;
1112 use packet::ParsablePacket;
1113 use test_case::test_case;
1114
1115 use super::*;
1116
1117 type FakeCoreCtx<D> = netstack3_base::testutil::FakeCoreCtx<FakeSockets<D>, (), D>;
1118 type FakeBindingsCtx = netstack3_base::testutil::FakeBindingsCtx<(), (), (), ()>;
1119 type FakeCtx<D> = CtxPair<FakeCoreCtx<D>, FakeBindingsCtx>;
1120
1121 trait DeviceSocketApiExt: ContextPair + Sized {
1124 fn device_socket_api(&mut self) -> DeviceSocketApi<&mut Self> {
1125 DeviceSocketApi::new(self)
1126 }
1127 }
1128
1129 impl<O> DeviceSocketApiExt for O where O: ContextPair + Sized {}
1130
1131 #[derive(Derivative)]
1132 #[derivative(Default(bound = ""))]
1133 struct FakeSockets<D: FakeStrongDeviceId> {
1134 any_device_sockets: AnyDeviceSockets<D::Weak, FakeBindingsCtx>,
1135 device_sockets: HashMap<D, DeviceSockets<D::Weak, FakeBindingsCtx>>,
1136 all_sockets: AllSockets<D::Weak, FakeBindingsCtx>,
1137 counters: DeviceSocketCounters,
1139 sent_frames: Vec<Vec<u8>>,
1140 }
1141
1142 pub struct FakeSocketsMutRefs<'m, AnyDevice, AllSockets, Devices, Device>(
1144 &'m mut AnyDevice,
1145 &'m mut AllSockets,
1146 &'m mut Devices,
1147 PhantomData<Device>,
1148 &'m DeviceSocketCounters,
1149 );
1150
1151 pub trait AsFakeSocketsMutRefs {
1154 type AnyDevice: 'static;
1155 type AllSockets: 'static;
1156 type Devices: 'static;
1157 type Device: 'static;
1158 fn as_sockets_ref(
1159 &mut self,
1160 ) -> FakeSocketsMutRefs<'_, Self::AnyDevice, Self::AllSockets, Self::Devices, Self::Device>;
1161 }
1162
1163 impl<D: FakeStrongDeviceId> AsFakeSocketsMutRefs for FakeCoreCtx<D> {
1164 type AnyDevice = AnyDeviceSockets<D::Weak, FakeBindingsCtx>;
1165 type AllSockets = AllSockets<D::Weak, FakeBindingsCtx>;
1166 type Devices = HashMap<D, DeviceSockets<D::Weak, FakeBindingsCtx>>;
1167 type Device = D;
1168
1169 fn as_sockets_ref(
1170 &mut self,
1171 ) -> FakeSocketsMutRefs<
1172 '_,
1173 AnyDeviceSockets<D::Weak, FakeBindingsCtx>,
1174 AllSockets<D::Weak, FakeBindingsCtx>,
1175 HashMap<D, DeviceSockets<D::Weak, FakeBindingsCtx>>,
1176 D,
1177 > {
1178 let FakeSockets {
1179 any_device_sockets,
1180 device_sockets,
1181 all_sockets,
1182 counters,
1183 sent_frames: _,
1184 } = &mut self.state;
1185 FakeSocketsMutRefs(
1186 any_device_sockets,
1187 all_sockets,
1188 device_sockets,
1189 PhantomData,
1190 counters,
1191 )
1192 }
1193 }
1194
1195 impl<'m, AnyDevice: 'static, AllSockets: 'static, Devices: 'static, Device: 'static>
1196 AsFakeSocketsMutRefs for FakeSocketsMutRefs<'m, AnyDevice, AllSockets, Devices, Device>
1197 {
1198 type AnyDevice = AnyDevice;
1199 type AllSockets = AllSockets;
1200 type Devices = Devices;
1201 type Device = Device;
1202
1203 fn as_sockets_ref(
1204 &mut self,
1205 ) -> FakeSocketsMutRefs<'_, AnyDevice, AllSockets, Devices, Device> {
1206 let Self(any_device, all_sockets, devices, PhantomData, counters) = self;
1207 FakeSocketsMutRefs(any_device, all_sockets, devices, PhantomData, counters)
1208 }
1209 }
1210
1211 impl<D: Clone> TargetDevice<&D> {
1212 fn with_weak_id(&self) -> TargetDevice<FakeWeakDeviceId<D>> {
1213 match self {
1214 TargetDevice::AnyDevice => TargetDevice::AnyDevice,
1215 TargetDevice::SpecificDevice(d) => {
1216 TargetDevice::SpecificDevice(FakeWeakDeviceId((*d).clone()))
1217 }
1218 }
1219 }
1220 }
1221
1222 impl<D: Eq + Hash + FakeStrongDeviceId> FakeSockets<D> {
1223 fn new(devices: impl IntoIterator<Item = D>) -> Self {
1224 let device_sockets =
1225 devices.into_iter().map(|d| (d, DeviceSockets::default())).collect();
1226 Self {
1227 any_device_sockets: AnyDeviceSockets::default(),
1228 device_sockets,
1229 all_sockets: Default::default(),
1230 counters: Default::default(),
1231 sent_frames: Default::default(),
1232 }
1233 }
1234 }
1235
1236 impl<
1237 'm,
1238 DeviceId: FakeStrongDeviceId,
1239 As: AsFakeSocketsMutRefs
1240 + DeviceIdContext<AnyDevice, DeviceId = DeviceId, WeakDeviceId = DeviceId::Weak>,
1241 > SocketStateAccessor<FakeBindingsCtx> for As
1242 {
1243 fn with_socket_state<F: FnOnce(&Target<Self::WeakDeviceId>) -> R, R>(
1244 &mut self,
1245 socket: &DeviceSocketId<Self::WeakDeviceId, FakeBindingsCtx>,
1246 cb: F,
1247 ) -> R {
1248 let DeviceSocketId(rc) = socket;
1249 let target = rc.target.lock();
1251 cb(&target)
1252 }
1253
1254 fn with_socket_state_mut<F: FnOnce(&mut Target<Self::WeakDeviceId>) -> R, R>(
1255 &mut self,
1256 socket: &DeviceSocketId<Self::WeakDeviceId, FakeBindingsCtx>,
1257 cb: F,
1258 ) -> R {
1259 let DeviceSocketId(rc) = socket;
1260 let mut target = rc.target.lock();
1262 cb(&mut target)
1263 }
1264 }
1265
1266 impl<
1267 'm,
1268 DeviceId: FakeStrongDeviceId,
1269 As: AsFakeSocketsMutRefs<
1270 Devices = HashMap<DeviceId, DeviceSockets<DeviceId::Weak, FakeBindingsCtx>>,
1271 > + DeviceIdContext<AnyDevice, DeviceId = DeviceId, WeakDeviceId = DeviceId::Weak>,
1272 > DeviceSocketAccessor<FakeBindingsCtx> for As
1273 {
1274 type DeviceSocketCoreCtx<'a> =
1275 FakeSocketsMutRefs<'a, As::AnyDevice, As::AllSockets, HashSet<DeviceId>, DeviceId>;
1276 fn with_device_sockets<
1277 F: FnOnce(
1278 &DeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1279 &mut Self::DeviceSocketCoreCtx<'_>,
1280 ) -> R,
1281 R,
1282 >(
1283 &mut self,
1284 device: &Self::DeviceId,
1285 cb: F,
1286 ) -> R {
1287 let FakeSocketsMutRefs(any_device, all_sockets, device_sockets, PhantomData, counters) =
1288 self.as_sockets_ref();
1289 let mut devices = device_sockets.keys().cloned().collect();
1290 let device = device_sockets.get(device).unwrap();
1291 cb(
1292 device,
1293 &mut FakeSocketsMutRefs(
1294 any_device,
1295 all_sockets,
1296 &mut devices,
1297 PhantomData,
1298 counters,
1299 ),
1300 )
1301 }
1302 fn with_device_sockets_mut<
1303 F: FnOnce(
1304 &mut DeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1305 &mut Self::DeviceSocketCoreCtx<'_>,
1306 ) -> R,
1307 R,
1308 >(
1309 &mut self,
1310 device: &Self::DeviceId,
1311 cb: F,
1312 ) -> R {
1313 let FakeSocketsMutRefs(any_device, all_sockets, device_sockets, PhantomData, counters) =
1314 self.as_sockets_ref();
1315 let mut devices = device_sockets.keys().cloned().collect();
1316 let device = device_sockets.get_mut(device).unwrap();
1317 cb(
1318 device,
1319 &mut FakeSocketsMutRefs(
1320 any_device,
1321 all_sockets,
1322 &mut devices,
1323 PhantomData,
1324 counters,
1325 ),
1326 )
1327 }
1328 }
1329
1330 impl<
1331 'm,
1332 DeviceId: FakeStrongDeviceId,
1333 As: AsFakeSocketsMutRefs<
1334 AnyDevice = AnyDeviceSockets<DeviceId::Weak, FakeBindingsCtx>,
1335 AllSockets = AllSockets<DeviceId::Weak, FakeBindingsCtx>,
1336 Devices = HashMap<DeviceId, DeviceSockets<DeviceId::Weak, FakeBindingsCtx>>,
1337 > + DeviceIdContext<AnyDevice, DeviceId = DeviceId, WeakDeviceId = DeviceId::Weak>,
1338 > DeviceSocketContext<FakeBindingsCtx> for As
1339 {
1340 type SocketTablesCoreCtx<'a> = FakeSocketsMutRefs<
1341 'a,
1342 (),
1343 (),
1344 HashMap<DeviceId, DeviceSockets<DeviceId::Weak, FakeBindingsCtx>>,
1345 DeviceId,
1346 >;
1347
1348 fn with_any_device_sockets<
1349 F: FnOnce(
1350 &AnyDeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1351 &mut Self::SocketTablesCoreCtx<'_>,
1352 ) -> R,
1353 R,
1354 >(
1355 &mut self,
1356 cb: F,
1357 ) -> R {
1358 let FakeSocketsMutRefs(
1359 any_device_sockets,
1360 _all_sockets,
1361 device_sockets,
1362 PhantomData,
1363 counters,
1364 ) = self.as_sockets_ref();
1365 cb(
1366 any_device_sockets,
1367 &mut FakeSocketsMutRefs(&mut (), &mut (), device_sockets, PhantomData, counters),
1368 )
1369 }
1370 fn with_any_device_sockets_mut<
1371 F: FnOnce(
1372 &mut AnyDeviceSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1373 &mut Self::SocketTablesCoreCtx<'_>,
1374 ) -> R,
1375 R,
1376 >(
1377 &mut self,
1378 cb: F,
1379 ) -> R {
1380 let FakeSocketsMutRefs(
1381 any_device_sockets,
1382 _all_sockets,
1383 device_sockets,
1384 PhantomData,
1385 counters,
1386 ) = self.as_sockets_ref();
1387 cb(
1388 any_device_sockets,
1389 &mut FakeSocketsMutRefs(&mut (), &mut (), device_sockets, PhantomData, counters),
1390 )
1391 }
1392
1393 fn with_all_device_sockets<
1394 F: FnOnce(
1395 &AllSockets<Self::WeakDeviceId, FakeBindingsCtx>,
1396 &mut Self::SocketTablesCoreCtx<'_>,
1397 ) -> R,
1398 R,
1399 >(
1400 &mut self,
1401 cb: F,
1402 ) -> R {
1403 let FakeSocketsMutRefs(
1404 _any_device_sockets,
1405 all_sockets,
1406 device_sockets,
1407 PhantomData,
1408 counters,
1409 ) = self.as_sockets_ref();
1410 cb(
1411 all_sockets,
1412 &mut FakeSocketsMutRefs(&mut (), &mut (), device_sockets, PhantomData, counters),
1413 )
1414 }
1415
1416 fn with_all_device_sockets_mut<
1417 F: FnOnce(&mut AllSockets<Self::WeakDeviceId, FakeBindingsCtx>) -> R,
1418 R,
1419 >(
1420 &mut self,
1421 cb: F,
1422 ) -> R {
1423 let FakeSocketsMutRefs(_, all_sockets, _, _, _) = self.as_sockets_ref();
1424 cb(all_sockets)
1425 }
1426 }
1427
1428 impl<'m, X, Y, Z, D: FakeStrongDeviceId> DeviceIdContext<AnyDevice>
1429 for FakeSocketsMutRefs<'m, X, Y, Z, D>
1430 {
1431 type DeviceId = D;
1432 type WeakDeviceId = FakeWeakDeviceId<D>;
1433 }
1434
1435 impl<D: FakeStrongDeviceId> CounterContext<DeviceSocketCounters> for FakeCoreCtx<D> {
1436 fn counters(&self) -> &DeviceSocketCounters {
1437 &self.state.counters
1438 }
1439 }
1440
1441 impl<D: FakeStrongDeviceId>
1442 ResourceCounterContext<DeviceSocketId<D::Weak, FakeBindingsCtx>, DeviceSocketCounters>
1443 for FakeCoreCtx<D>
1444 {
1445 fn per_resource_counters<'a>(
1446 &'a self,
1447 socket: &'a DeviceSocketId<D::Weak, FakeBindingsCtx>,
1448 ) -> &'a DeviceSocketCounters {
1449 socket.counters()
1450 }
1451 }
1452
1453 impl<'m, X, Y, Z, D> CounterContext<DeviceSocketCounters> for FakeSocketsMutRefs<'m, X, Y, Z, D> {
1454 fn counters(&self) -> &DeviceSocketCounters {
1455 let FakeSocketsMutRefs(_, _, _, _, counters) = self;
1456 counters
1457 }
1458 }
1459
1460 impl<'m, X, Y, Z, D: FakeStrongDeviceId>
1461 ResourceCounterContext<DeviceSocketId<D::Weak, FakeBindingsCtx>, DeviceSocketCounters>
1462 for FakeSocketsMutRefs<'m, X, Y, Z, D>
1463 {
1464 fn per_resource_counters<'a>(
1465 &'a self,
1466 socket: &'a DeviceSocketId<D::Weak, FakeBindingsCtx>,
1467 ) -> &'a DeviceSocketCounters {
1468 socket.counters()
1469 }
1470 }
1471
1472 const SOME_PROTOCOL: NonZeroU16 = NonZeroU16::new(2000).unwrap();
1473
1474 #[test]
1475 fn create_remove() {
1476 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1477 MultipleDevicesId::all(),
1478 )));
1479 let mut api = ctx.device_socket_api();
1480
1481 let bound = api.create(Default::default());
1482 assert_eq!(
1483 api.get_info(&bound),
1484 SocketInfo { device: TargetDevice::AnyDevice, protocol: None }
1485 );
1486
1487 let ExternalSocketState(_received_frames) = api.remove(bound).into_removed();
1488 }
1489
1490 #[test_case(TargetDevice::AnyDevice)]
1491 #[test_case(TargetDevice::SpecificDevice(&MultipleDevicesId::A))]
1492 fn test_set_device(device: TargetDevice<&MultipleDevicesId>) {
1493 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1494 MultipleDevicesId::all(),
1495 )));
1496 let mut api = ctx.device_socket_api();
1497
1498 let bound = api.create(Default::default());
1499 api.set_device(&bound, device.clone());
1500 assert_eq!(
1501 api.get_info(&bound),
1502 SocketInfo { device: device.with_weak_id(), protocol: None }
1503 );
1504
1505 let device_sockets = &api.core_ctx().state.device_sockets;
1506 if let TargetDevice::SpecificDevice(d) = device {
1507 let DeviceSockets(socket_ids) = device_sockets.get(&d).expect("device state exists");
1508 assert_eq!(socket_ids, &HashSet::from([bound]));
1509 }
1510 }
1511
1512 #[test]
1513 fn update_device() {
1514 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1515 MultipleDevicesId::all(),
1516 )));
1517 let mut api = ctx.device_socket_api();
1518 let bound = api.create(Default::default());
1519
1520 api.set_device(&bound, TargetDevice::SpecificDevice(&MultipleDevicesId::A));
1521
1522 api.set_device(&bound, TargetDevice::SpecificDevice(&MultipleDevicesId::B));
1525 assert_eq!(
1526 api.get_info(&bound),
1527 SocketInfo {
1528 device: TargetDevice::SpecificDevice(FakeWeakDeviceId(MultipleDevicesId::B)),
1529 protocol: None
1530 }
1531 );
1532
1533 let device_sockets = &api.core_ctx().state.device_sockets;
1534 let device_socket_lists = device_sockets
1535 .iter()
1536 .map(|(d, DeviceSockets(indexes))| (d, indexes.iter().collect()))
1537 .collect::<HashMap<_, _>>();
1538
1539 assert_eq!(
1540 device_socket_lists,
1541 HashMap::from([
1542 (&MultipleDevicesId::A, vec![]),
1543 (&MultipleDevicesId::B, vec![&bound]),
1544 (&MultipleDevicesId::C, vec![])
1545 ])
1546 );
1547 }
1548
1549 #[test_case(Protocol::All, TargetDevice::AnyDevice)]
1550 #[test_case(Protocol::Specific(SOME_PROTOCOL), TargetDevice::AnyDevice)]
1551 #[test_case(Protocol::All, TargetDevice::SpecificDevice(&MultipleDevicesId::A))]
1552 #[test_case(
1553 Protocol::Specific(SOME_PROTOCOL),
1554 TargetDevice::SpecificDevice(&MultipleDevicesId::A)
1555 )]
1556 fn create_set_device_and_protocol_remove_multiple(
1557 protocol: Protocol,
1558 device: TargetDevice<&MultipleDevicesId>,
1559 ) {
1560 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1561 MultipleDevicesId::all(),
1562 )));
1563 let mut api = ctx.device_socket_api();
1564
1565 let mut sockets = [(); 3].map(|()| api.create(Default::default()));
1566 for socket in &mut sockets {
1567 api.set_device_and_protocol(socket, device.clone(), protocol);
1568 assert_eq!(
1569 api.get_info(socket),
1570 SocketInfo { device: device.with_weak_id(), protocol: Some(protocol) }
1571 );
1572 }
1573
1574 for socket in sockets {
1575 let ExternalSocketState(_received_frames) = api.remove(socket).into_removed();
1576 }
1577 }
1578
1579 #[test]
1580 fn change_device_after_removal() {
1581 let device_to_remove = FakeReferencyDeviceId::default();
1582 let device_to_maintain = FakeReferencyDeviceId::default();
1583 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new([
1584 device_to_remove.clone(),
1585 device_to_maintain.clone(),
1586 ])));
1587 let mut api = ctx.device_socket_api();
1588
1589 let bound = api.create(Default::default());
1590 api.set_device(&bound, TargetDevice::SpecificDevice(&device_to_remove));
1593
1594 device_to_remove.mark_removed();
1597
1598 api.set_device(&bound, TargetDevice::SpecificDevice(&device_to_maintain));
1601 assert_eq!(
1602 api.get_info(&bound),
1603 SocketInfo {
1604 device: TargetDevice::SpecificDevice(FakeWeakDeviceId(device_to_maintain.clone())),
1605 protocol: None,
1606 }
1607 );
1608
1609 let device_sockets = &api.core_ctx().state.device_sockets;
1610 let DeviceSockets(weak_sockets) =
1611 device_sockets.get(&device_to_maintain).expect("device state exists");
1612 assert_eq!(weak_sockets, &HashSet::from([bound]));
1613 }
1614
1615 struct TestData;
1616 impl TestData {
1617 const SRC_MAC: Mac = Mac::new([0, 1, 2, 3, 4, 5]);
1618 const DST_MAC: Mac = Mac::new([6, 7, 8, 9, 10, 11]);
1619 const PROTO: NonZeroU16 = NonZeroU16::new(0x08AB).unwrap();
1621 const BODY: &'static [u8] = b"some pig";
1622 const BUFFER: &'static [u8] = &[
1623 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',
1624 b'i', b'g',
1625 ];
1626 const BUFFER_OFFSET: usize = Self::BUFFER.len() - Self::BODY.len();
1627
1628 fn frame() -> packet_formats::ethernet::EthernetFrame<&'static [u8]> {
1630 let mut buffer_view = Self::BUFFER;
1631 packet_formats::ethernet::EthernetFrame::parse(
1632 &mut buffer_view,
1633 EthernetFrameLengthCheck::NoCheck,
1634 )
1635 .unwrap()
1636 }
1637 }
1638
1639 const WRONG_PROTO: NonZeroU16 = NonZeroU16::new(0x08ff).unwrap();
1640
1641 fn make_bound<D: FakeStrongDeviceId>(
1642 ctx: &mut FakeCtx<D>,
1643 device: TargetDevice<D>,
1644 protocol: Option<Protocol>,
1645 state: ExternalSocketState<D::Weak>,
1646 ) -> DeviceSocketId<D::Weak, FakeBindingsCtx> {
1647 let mut api = ctx.device_socket_api();
1648 let id = api.create(state);
1649 let device = match &device {
1650 TargetDevice::AnyDevice => TargetDevice::AnyDevice,
1651 TargetDevice::SpecificDevice(d) => TargetDevice::SpecificDevice(d),
1652 };
1653 match protocol {
1654 Some(protocol) => api.set_device_and_protocol(&id, device, protocol),
1655 None => api.set_device(&id, device),
1656 };
1657 id
1658 }
1659
1660 fn deliver_one_frame(
1663 delivered_frame: Frame<&[u8]>,
1664 FakeCtx { core_ctx, bindings_ctx }: &mut FakeCtx<MultipleDevicesId>,
1665 ) -> HashSet<DeviceSocketId<FakeWeakDeviceId<MultipleDevicesId>, FakeBindingsCtx>> {
1666 DeviceSocketHandler::handle_frame(
1667 core_ctx,
1668 bindings_ctx,
1669 &MultipleDevicesId::A,
1670 delivered_frame.clone(),
1671 TestData::BUFFER,
1672 );
1673
1674 let FakeSockets {
1675 all_sockets: AllSockets(all_sockets),
1676 any_device_sockets: _,
1677 device_sockets: _,
1678 counters: _,
1679 sent_frames: _,
1680 } = &core_ctx.state;
1681
1682 all_sockets
1683 .iter()
1684 .filter_map(|(id, _primary)| {
1685 let DeviceSocketId(rc) = &id;
1686 let ExternalSocketState(frames) = &rc.external_state;
1687 let lock_guard = frames.lock();
1688 let testutil::RxQueue { frames, .. } = lock_guard.deref();
1689 (!frames.is_empty()).then(|| {
1690 assert_eq!(
1691 &*frames,
1692 &[ReceivedFrame {
1693 device: FakeWeakDeviceId(MultipleDevicesId::A),
1694 frame: delivered_frame.cloned(),
1695 raw: TestData::BUFFER.into(),
1696 }]
1697 );
1698 id.clone()
1699 })
1700 })
1701 .collect()
1702 }
1703
1704 #[test]
1705 fn receive_frame_deliver_to_multiple() {
1706 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1707 MultipleDevicesId::all(),
1708 )));
1709
1710 use Protocol::*;
1711 use TargetDevice::*;
1712 let never_bound = {
1713 let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1714 ctx.device_socket_api().create(state)
1715 };
1716
1717 let mut make_bound = |device, protocol| {
1718 let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1719 make_bound(&mut ctx, device, protocol, state)
1720 };
1721 let bound_a_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::A), None);
1722 let bound_a_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::A), Some(All));
1723 let bound_a_right_protocol =
1724 make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(TestData::PROTO)));
1725 let bound_a_wrong_protocol =
1726 make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(WRONG_PROTO)));
1727 let bound_b_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::B), None);
1728 let bound_b_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::B), Some(All));
1729 let bound_b_right_protocol =
1730 make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(TestData::PROTO)));
1731 let bound_b_wrong_protocol =
1732 make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(WRONG_PROTO)));
1733 let bound_any_no_protocol = make_bound(AnyDevice, None);
1734 let bound_any_all_protocols = make_bound(AnyDevice, Some(All));
1735 let bound_any_right_protocol = make_bound(AnyDevice, Some(Specific(TestData::PROTO)));
1736 let bound_any_wrong_protocol = make_bound(AnyDevice, Some(Specific(WRONG_PROTO)));
1737
1738 let mut sockets_with_received_frames = deliver_one_frame(
1739 super::ReceivedFrame::from_ethernet(
1740 TestData::frame(),
1741 FrameDestination::Individual { local: true },
1742 )
1743 .into(),
1744 &mut ctx,
1745 );
1746
1747 let sockets_not_expecting_frames = [
1748 never_bound,
1749 bound_a_no_protocol,
1750 bound_a_wrong_protocol,
1751 bound_b_no_protocol,
1752 bound_b_all_protocols,
1753 bound_b_right_protocol,
1754 bound_b_wrong_protocol,
1755 bound_any_no_protocol,
1756 bound_any_wrong_protocol,
1757 ];
1758 let sockets_expecting_frames = [
1759 bound_a_all_protocols,
1760 bound_a_right_protocol,
1761 bound_any_all_protocols,
1762 bound_any_right_protocol,
1763 ];
1764
1765 for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1766 assert!(
1767 sockets_with_received_frames.remove(&socket),
1768 "socket {n} didn't receive the frame"
1769 );
1770 }
1771 assert!(sockets_with_received_frames.is_empty());
1772
1773 for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1775 assert_eq!(socket.counters().rx_frames.get(), 1, "socket {n} has wrong rx_frames");
1776 }
1777 for (n, socket) in sockets_not_expecting_frames.iter().enumerate() {
1778 assert_eq!(socket.counters().rx_frames.get(), 0, "socket {n} has wrong rx_frames");
1779 }
1780 }
1781
1782 #[test]
1783 fn sent_frame_deliver_to_multiple() {
1784 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1785 MultipleDevicesId::all(),
1786 )));
1787
1788 use Protocol::*;
1789 use TargetDevice::*;
1790 let never_bound = {
1791 let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1792 ctx.device_socket_api().create(state)
1793 };
1794
1795 let mut make_bound = |device, protocol| {
1796 let state = ExternalSocketState::<FakeWeakDeviceId<MultipleDevicesId>>::default();
1797 make_bound(&mut ctx, device, protocol, state)
1798 };
1799 let bound_a_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::A), None);
1800 let bound_a_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::A), Some(All));
1801 let bound_a_same_protocol =
1802 make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(TestData::PROTO)));
1803 let bound_a_wrong_protocol =
1804 make_bound(SpecificDevice(MultipleDevicesId::A), Some(Specific(WRONG_PROTO)));
1805 let bound_b_no_protocol = make_bound(SpecificDevice(MultipleDevicesId::B), None);
1806 let bound_b_all_protocols = make_bound(SpecificDevice(MultipleDevicesId::B), Some(All));
1807 let bound_b_same_protocol =
1808 make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(TestData::PROTO)));
1809 let bound_b_wrong_protocol =
1810 make_bound(SpecificDevice(MultipleDevicesId::B), Some(Specific(WRONG_PROTO)));
1811 let bound_any_no_protocol = make_bound(AnyDevice, None);
1812 let bound_any_all_protocols = make_bound(AnyDevice, Some(All));
1813 let bound_any_same_protocol = make_bound(AnyDevice, Some(Specific(TestData::PROTO)));
1814 let bound_any_wrong_protocol = make_bound(AnyDevice, Some(Specific(WRONG_PROTO)));
1815
1816 let mut sockets_with_received_frames =
1817 deliver_one_frame(SentFrame::Ethernet(TestData::frame().into()).into(), &mut ctx);
1818
1819 let sockets_not_expecting_frames = [
1820 never_bound,
1821 bound_a_no_protocol,
1822 bound_a_same_protocol,
1823 bound_a_wrong_protocol,
1824 bound_b_no_protocol,
1825 bound_b_all_protocols,
1826 bound_b_same_protocol,
1827 bound_b_wrong_protocol,
1828 bound_any_no_protocol,
1829 bound_any_same_protocol,
1830 bound_any_wrong_protocol,
1831 ];
1832 let sockets_expecting_frames = [bound_a_all_protocols, bound_any_all_protocols];
1834
1835 for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1836 assert!(
1837 sockets_with_received_frames.remove(&socket),
1838 "socket {n} didn't receive the frame"
1839 );
1840 }
1841 assert!(sockets_with_received_frames.is_empty());
1842
1843 for (n, socket) in sockets_expecting_frames.iter().enumerate() {
1845 assert_eq!(socket.counters().rx_frames.get(), 1, "socket {n} has wrong rx_frames");
1846 }
1847 for (n, socket) in sockets_not_expecting_frames.iter().enumerate() {
1848 assert_eq!(socket.counters().rx_frames.get(), 0, "socket {n} has wrong rx_frames");
1849 }
1850 }
1851
1852 #[test]
1853 fn deliver_multiple_frames() {
1854 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1855 MultipleDevicesId::all(),
1856 )));
1857 let socket = make_bound(
1858 &mut ctx,
1859 TargetDevice::AnyDevice,
1860 Some(Protocol::All),
1861 ExternalSocketState::default(),
1862 );
1863 let FakeCtx { mut core_ctx, mut bindings_ctx } = ctx;
1864
1865 const RECEIVE_COUNT: usize = 10;
1866 for _ in 0..RECEIVE_COUNT {
1867 DeviceSocketHandler::handle_frame(
1868 &mut core_ctx,
1869 &mut bindings_ctx,
1870 &MultipleDevicesId::A,
1871 super::ReceivedFrame::from_ethernet(
1872 TestData::frame(),
1873 FrameDestination::Individual { local: true },
1874 )
1875 .into(),
1876 TestData::BUFFER,
1877 );
1878 }
1879
1880 let FakeSockets {
1881 all_sockets: AllSockets(mut all_sockets),
1882 any_device_sockets: _,
1883 device_sockets: _,
1884 counters: _,
1885 sent_frames: _,
1886 } = core_ctx.into_state();
1887 let primary = all_sockets.remove(&socket).unwrap();
1888 let PrimaryDeviceSocketId(primary) = primary;
1889 assert!(all_sockets.is_empty());
1890 drop(socket);
1891 let SocketState { external_state: ExternalSocketState(received), counters, target: _ } =
1892 PrimaryRc::unwrap(primary);
1893 assert_eq!(
1894 received.into_inner().frames,
1895 vec![
1896 ReceivedFrame {
1897 device: FakeWeakDeviceId(MultipleDevicesId::A),
1898 frame: Frame::Received(super::ReceivedFrame::Ethernet {
1899 destination: FrameDestination::Individual { local: true },
1900 frame: EthernetFrame {
1901 src_mac: TestData::SRC_MAC,
1902 dst_mac: TestData::DST_MAC,
1903 ethertype: Some(TestData::PROTO.get().into()),
1904 body_offset: TestData::BUFFER_OFFSET,
1905 body: Vec::from(TestData::BODY),
1906 }
1907 }),
1908 raw: TestData::BUFFER.into()
1909 };
1910 RECEIVE_COUNT
1911 ]
1912 );
1913 assert_eq!(counters.rx_frames.get(), u64::try_from(RECEIVE_COUNT).unwrap());
1914 }
1915
1916 #[test]
1917 fn deliver_frame_queue_full() {
1918 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1919 MultipleDevicesId::all(),
1920 )));
1921
1922 let sock1 = make_bound(
1924 &mut ctx,
1925 TargetDevice::AnyDevice,
1926 Some(Protocol::All),
1927 ExternalSocketState(Mutex::new(testutil::RxQueue { frames: vec![], max_size: 0 })),
1928 );
1929 let sock2 = make_bound(
1930 &mut ctx,
1931 TargetDevice::AnyDevice,
1932 Some(Protocol::All),
1933 ExternalSocketState::default(),
1934 );
1935
1936 let FakeCtx { mut core_ctx, mut bindings_ctx } = ctx;
1937
1938 DeviceSocketHandler::handle_frame(
1939 &mut core_ctx,
1940 &mut bindings_ctx,
1941 &MultipleDevicesId::A,
1942 super::ReceivedFrame::from_ethernet(
1943 TestData::frame(),
1944 FrameDestination::Individual { local: true },
1945 )
1946 .into(),
1947 TestData::BUFFER,
1948 );
1949
1950 assert_eq!(core_ctx.state.counters.rx_frames.get(), 2);
1951 assert_eq!(core_ctx.state.counters.rx_queue_full.get(), 1);
1952 assert_eq!(sock1.counters().rx_frames.get(), 1);
1953 assert_eq!(sock1.counters().rx_queue_full.get(), 1);
1954 assert_eq!(sock2.counters().rx_frames.get(), 1);
1955 assert_eq!(sock2.counters().rx_queue_full.get(), 0);
1956
1957 drop(sock1);
1960 drop(sock2);
1961 }
1962
1963 pub struct FakeSendMetadata;
1964 impl DeviceSocketSendTypes for AnyDevice {
1965 type Metadata = FakeSendMetadata;
1966 }
1967 impl<BC, D: FakeStrongDeviceId> SendableFrameMeta<FakeCoreCtx<D>, BC>
1968 for DeviceSocketMetadata<AnyDevice, D>
1969 {
1970 fn send_meta<S>(
1971 self,
1972 core_ctx: &mut FakeCoreCtx<D>,
1973 _bindings_ctx: &mut BC,
1974 frame: S,
1975 ) -> Result<(), SendFrameError<S>>
1976 where
1977 S: NetworkSerializer,
1978 S::Buffer: BufferMut,
1979 {
1980 let frame = match frame.serialize_vec_outer(&mut NetworkSerializationContext::default())
1981 {
1982 Err(e) => {
1983 let _: (packet::SerializeError<core::convert::Infallible>, _) = e;
1984 unreachable!()
1985 }
1986 Ok(frame) => frame.unwrap_a().as_ref().to_vec(),
1987 };
1988 core_ctx.state.sent_frames.push(frame);
1989 Ok(())
1990 }
1991 }
1992
1993 #[test]
1994 fn send_multiple_frames() {
1995 let mut ctx = FakeCtx::with_core_ctx(FakeCoreCtx::with_state(FakeSockets::new(
1996 MultipleDevicesId::all(),
1997 )));
1998
1999 const DEVICE: MultipleDevicesId = MultipleDevicesId::A;
2000 let socket = make_bound(
2001 &mut ctx,
2002 TargetDevice::SpecificDevice(DEVICE),
2003 Some(Protocol::All),
2004 ExternalSocketState::default(),
2005 );
2006 let mut api = ctx.device_socket_api();
2007
2008 const SEND_COUNT: usize = 10;
2009 const PAYLOAD: &'static [u8] = &[1, 2, 3, 4, 5];
2010 for _ in 0..SEND_COUNT {
2011 let buf = packet::Buf::new(PAYLOAD.to_vec(), ..);
2012 api.send_frame(
2013 &socket,
2014 DeviceSocketMetadata { device_id: DEVICE, metadata: FakeSendMetadata },
2015 buf,
2016 )
2017 .expect("send failed");
2018 }
2019
2020 assert_eq!(ctx.core_ctx().state.sent_frames, vec![PAYLOAD.to_vec(); SEND_COUNT]);
2021
2022 assert_eq!(socket.counters().tx_frames.get(), u64::try_from(SEND_COUNT).unwrap());
2023 }
2024}