1use net_types::ethernet::Mac;
8use net_types::ip::{Ip, IpVersionMarker};
9use net_types::{BroadcastAddr, MulticastAddr};
10
11use core::convert::Infallible as Never;
12use core::fmt::Debug;
13use packet::{BufferMut, SerializeError};
14use thiserror::Error;
15
16use crate::error::ErrorAndSerializer;
17use crate::socket::SocketInfo;
18use crate::{ChecksumOffloadResult, NetworkParsingContext, NetworkSerializer};
19
20pub trait RecvFrameContext<Meta, BC> {
26 fn receive_frame<B: BufferMut + Debug>(
30 &mut self,
31 bindings_ctx: &mut BC,
32 metadata: Meta,
33 frame: B,
34 );
35}
36
37impl<CC, BC> ReceivableFrameMeta<CC, BC> for Never {
38 fn receive_meta<B: BufferMut + Debug>(
39 self,
40 _core_ctx: &mut CC,
41 _bindings_ctx: &mut BC,
42 _frame: B,
43 ) {
44 match self {}
45 }
46}
47
48pub trait ReceivableFrameMeta<CC, BC> {
56 fn receive_meta<B: BufferMut + Debug>(self, core_ctx: &mut CC, bindings_ctx: &mut BC, frame: B);
58}
59
60impl<CC, BC, Meta> RecvFrameContext<Meta, BC> for CC
61where
62 Meta: ReceivableFrameMeta<CC, BC>,
63{
64 fn receive_frame<B: BufferMut + Debug>(
65 &mut self,
66 bindings_ctx: &mut BC,
67 metadata: Meta,
68 frame: B,
69 ) {
70 metadata.receive_meta(self, bindings_ctx, frame)
71 }
72}
73
74#[derive(Error, Debug, PartialEq)]
76pub enum SendFrameErrorReason {
77 #[error("size constraints violated")]
79 SizeConstraintsViolation,
80 #[error("failed to allocate")]
82 Alloc,
83 #[error("transmit queue is full")]
85 QueueFull,
86}
87
88impl<A> From<SerializeError<A>> for SendFrameErrorReason {
89 fn from(e: SerializeError<A>) -> Self {
90 match e {
91 SerializeError::Alloc(_) => Self::Alloc,
92 SerializeError::SizeLimitExceeded => Self::SizeConstraintsViolation,
93 }
94 }
95}
96
97pub type SendFrameError<S> = ErrorAndSerializer<SendFrameErrorReason, S>;
99
100pub trait SendFrameContext<BC, Meta> {
102 fn send_frame<S>(
111 &mut self,
112 bindings_ctx: &mut BC,
113 metadata: Meta,
114 frame: S,
115 ) -> Result<(), SendFrameError<S>>
116 where
117 S: NetworkSerializer,
118 S::Buffer: BufferMut;
119}
120
121pub trait SendableFrameMeta<CC, BC> {
129 fn send_meta<S>(
131 self,
132 core_ctx: &mut CC,
133 bindings_ctx: &mut BC,
134 frame: S,
135 ) -> Result<(), SendFrameError<S>>
136 where
137 S: NetworkSerializer,
138 S::Buffer: BufferMut;
139}
140
141impl<CC, BC, Meta> SendFrameContext<BC, Meta> for CC
142where
143 Meta: SendableFrameMeta<CC, BC>,
144{
145 fn send_frame<S>(
146 &mut self,
147 bindings_ctx: &mut BC,
148 metadata: Meta,
149 frame: S,
150 ) -> Result<(), SendFrameError<S>>
151 where
152 S: NetworkSerializer,
153 S::Buffer: BufferMut,
154 {
155 metadata.send_meta(self, bindings_ctx, frame)
156 }
157}
158
159#[derive(Copy, Clone, Debug, Eq, PartialEq)]
165pub enum FrameDestination<L = bool> {
166 Individual {
168 local: L,
170 },
171 Multicast,
175 Broadcast,
179}
180
181pub type LocalFrameDestination = FrameDestination<()>;
184
185impl<L> FrameDestination<L> {
186 pub fn is_broadcast(self) -> bool {
188 matches!(self, FrameDestination::Broadcast)
189 }
190}
191
192impl FrameDestination<bool> {
193 pub fn from_dest(destination: Mac, local_mac: Mac) -> Self {
195 BroadcastAddr::new(destination)
196 .map(Into::into)
197 .or_else(|| MulticastAddr::new(destination).map(Into::into))
198 .unwrap_or_else(|| FrameDestination::Individual { local: destination == local_mac })
199 }
200
201 pub fn check_local(self) -> Option<LocalFrameDestination> {
206 match self {
207 FrameDestination::Individual { local: true } => {
208 Some(FrameDestination::Individual { local: () })
209 }
210 FrameDestination::Individual { local: false } => None,
211 FrameDestination::Multicast => Some(FrameDestination::Multicast),
212 FrameDestination::Broadcast => Some(FrameDestination::Broadcast),
213 }
214 }
215}
216
217impl<L> From<BroadcastAddr<Mac>> for FrameDestination<L> {
218 fn from(_value: BroadcastAddr<Mac>) -> Self {
219 Self::Broadcast
220 }
221}
222
223impl<L> From<MulticastAddr<Mac>> for FrameDestination<L> {
224 fn from(_value: MulticastAddr<Mac>) -> Self {
225 Self::Multicast
226 }
227}
228
229pub struct RecvIpFrameMeta<D, M, I: Ip> {
231 pub device: D,
233 pub frame_dst: Option<LocalFrameDestination>,
240 pub ip_layer_metadata: M,
243 pub marker: IpVersionMarker<I>,
245 pub parsing_context: NetworkParsingContext,
247}
248
249impl<D, M, I: Ip> RecvIpFrameMeta<D, M, I> {
250 pub fn new(
253 device: D,
254 frame_dst: Option<LocalFrameDestination>,
255 ip_layer_metadata: M,
256 parsing_context: NetworkParsingContext,
257 ) -> RecvIpFrameMeta<D, M, I> {
258 RecvIpFrameMeta {
259 device,
260 frame_dst,
261 ip_layer_metadata,
262 marker: IpVersionMarker::new(),
263 parsing_context,
264 }
265 }
266}
267
268pub trait TxMetadata: Default + Debug + Send + Sync + 'static {
273 fn socket_info(&self) -> Option<SocketInfo>;
276
277 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult>;
279
280 fn set_checksum_offload_result(&mut self, result: Option<ChecksumOffloadResult>);
283}
284
285pub trait TxMetadataBindingsTypes {
297 type TxMetadata: TxMetadata;
299}
300
301pub trait CoreTxMetadataContext<T, BT: TxMetadataBindingsTypes> {
306 fn convert_tx_meta(&self, tx_meta: T) -> BT::TxMetadata;
312}
313
314pub struct NeverBuffer(core::convert::Infallible);
322
323impl packet::FragmentedBuffer for NeverBuffer {
324 fn len(&self) -> usize {
325 match self.0 {}
326 }
327
328 fn with_bytes<'a, R, F>(&'a self, _f: F) -> R
329 where
330 F: for<'b> FnOnce(packet::FragmentedBytes<'b, 'a>) -> R,
331 {
332 match self.0 {}
333 }
334}
335
336impl AsMut<[u8]> for NeverBuffer {
337 fn as_mut(&mut self) -> &mut [u8] {
338 match self.0 {}
339 }
340}
341
342#[cfg(any(test, feature = "testutils"))]
343pub(crate) mod testutil {
344 use super::*;
345 use alloc::boxed::Box;
346 use alloc::vec::Vec;
347
348 use crate::packet::NetworkSerializationContext;
349 use crate::testutil::FakeBindingsCtx;
350
351 pub struct FakeFrameCtx<Meta> {
353 frames: Vec<(Meta, Vec<u8>)>,
354 should_error_for_frame:
355 Option<Box<dyn FnMut(&Meta) -> Option<SendFrameErrorReason> + Send>>,
356 }
357
358 impl<Meta> FakeFrameCtx<Meta> {
359 pub fn set_should_error_for_frame<
362 F: Fn(&Meta) -> Option<SendFrameErrorReason> + Send + 'static,
363 >(
364 &mut self,
365 f: F,
366 ) {
367 self.should_error_for_frame = Some(Box::new(f));
368 }
369 }
370
371 impl<Meta> Default for FakeFrameCtx<Meta> {
372 fn default() -> FakeFrameCtx<Meta> {
373 FakeFrameCtx { frames: Vec::new(), should_error_for_frame: None }
374 }
375 }
376
377 impl<Meta> FakeFrameCtx<Meta> {
378 pub fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
380 core::mem::take(&mut self.frames)
381 }
382
383 pub fn frames(&self) -> &[(Meta, Vec<u8>)] {
385 self.frames.as_slice()
386 }
387
388 pub fn push(&mut self, meta: Meta, frame: Vec<u8>) {
390 self.frames.push((meta, frame))
391 }
392 }
393
394 impl<Meta, BC> SendableFrameMeta<FakeFrameCtx<Meta>, BC> for Meta {
395 fn send_meta<S>(
396 self,
397 core_ctx: &mut FakeFrameCtx<Meta>,
398 _bindings_ctx: &mut BC,
399 frame: S,
400 ) -> Result<(), SendFrameError<S>>
401 where
402 S: NetworkSerializer,
403 S::Buffer: BufferMut,
404 {
405 if let Some(error) = core_ctx.should_error_for_frame.as_mut().and_then(|f| f(&self)) {
406 return Err(SendFrameError { serializer: frame, error });
407 }
408
409 let buffer = frame
410 .serialize_vec_outer(&mut NetworkSerializationContext::default())
411 .map_err(|(e, serializer)| SendFrameError { error: e.into(), serializer })?;
412 core_ctx.push(self, buffer.as_ref().to_vec());
413 Ok(())
414 }
415 }
416
417 pub trait WithFakeFrameContext<SendMeta> {
419 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
421 &mut self,
422 f: F,
423 ) -> O;
424 }
425
426 impl<SendMeta> WithFakeFrameContext<SendMeta> for FakeFrameCtx<SendMeta> {
427 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
428 &mut self,
429 f: F,
430 ) -> O {
431 f(self)
432 }
433 }
434
435 impl<TimerId, Event: Debug, State, FrameMeta> TxMetadataBindingsTypes
436 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
437 {
438 type TxMetadata = FakeTxMetadata;
439 }
440
441 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
443 pub struct FakeTxMetadata;
444
445 impl TxMetadata for FakeTxMetadata {
446 fn socket_info(&self) -> Option<SocketInfo> {
447 None
448 }
449
450 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult> {
451 None
452 }
453
454 fn set_checksum_offload_result(&mut self, _result: Option<ChecksumOffloadResult>) {}
455 }
456}
457
458#[cfg(test)]
459mod tests {
460 use super::*;
461
462 use net_declare::net_mac;
463 use net_types::{UnicastAddr, Witness as _};
464
465 #[test]
466 fn frame_destination_from_dest() {
467 const LOCAL_ADDR: Mac = net_mac!("88:88:88:88:88:88");
468
469 assert_eq!(
470 FrameDestination::from_dest(
471 UnicastAddr::new(net_mac!("00:11:22:33:44:55")).unwrap().get(),
472 LOCAL_ADDR
473 ),
474 FrameDestination::Individual { local: false }
475 );
476 assert_eq!(
477 FrameDestination::from_dest(LOCAL_ADDR, LOCAL_ADDR),
478 FrameDestination::Individual { local: true }
479 );
480 assert_eq!(
481 FrameDestination::from_dest(Mac::BROADCAST, LOCAL_ADDR),
482 FrameDestination::Broadcast,
483 );
484 assert_eq!(
485 FrameDestination::from_dest(
486 MulticastAddr::new(net_mac!("11:11:11:11:11:11")).unwrap().get(),
487 LOCAL_ADDR
488 ),
489 FrameDestination::Multicast
490 );
491 }
492}