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 #[error("address resolution failed")]
88 AddressResolutionFailed,
89}
90
91impl<A> From<SerializeError<A>> for SendFrameErrorReason {
92 fn from(e: SerializeError<A>) -> Self {
93 match e {
94 SerializeError::Alloc(_) => Self::Alloc,
95 SerializeError::SizeLimitExceeded => Self::SizeConstraintsViolation,
96 }
97 }
98}
99
100pub type SendFrameError<S> = ErrorAndSerializer<SendFrameErrorReason, S>;
102
103pub trait SendFrameContext<BC, Meta> {
105 fn send_frame<S>(
114 &mut self,
115 bindings_ctx: &mut BC,
116 metadata: Meta,
117 frame: S,
118 ) -> Result<(), SendFrameError<S>>
119 where
120 S: NetworkSerializer,
121 S::Buffer: BufferMut;
122}
123
124pub trait SendableFrameMeta<CC, BC> {
132 fn send_meta<S>(
134 self,
135 core_ctx: &mut CC,
136 bindings_ctx: &mut BC,
137 frame: S,
138 ) -> Result<(), SendFrameError<S>>
139 where
140 S: NetworkSerializer,
141 S::Buffer: BufferMut;
142}
143
144impl<CC, BC, Meta> SendFrameContext<BC, Meta> for CC
145where
146 Meta: SendableFrameMeta<CC, BC>,
147{
148 fn send_frame<S>(
149 &mut self,
150 bindings_ctx: &mut BC,
151 metadata: Meta,
152 frame: S,
153 ) -> Result<(), SendFrameError<S>>
154 where
155 S: NetworkSerializer,
156 S::Buffer: BufferMut,
157 {
158 metadata.send_meta(self, bindings_ctx, frame)
159 }
160}
161
162#[derive(Copy, Clone, Debug, Eq, PartialEq)]
168pub enum FrameDestination<L = bool> {
169 Individual {
171 local: L,
173 },
174 Multicast,
178 Broadcast,
182}
183
184pub type LocalFrameDestination = FrameDestination<()>;
187
188impl<L> FrameDestination<L> {
189 pub fn is_broadcast(self) -> bool {
191 matches!(self, FrameDestination::Broadcast)
192 }
193}
194
195impl FrameDestination<bool> {
196 pub fn from_dest(destination: Mac, local_mac: Mac) -> Self {
198 BroadcastAddr::new(destination)
199 .map(Into::into)
200 .or_else(|| MulticastAddr::new(destination).map(Into::into))
201 .unwrap_or_else(|| FrameDestination::Individual { local: destination == local_mac })
202 }
203
204 pub fn check_local(self) -> Option<LocalFrameDestination> {
209 match self {
210 FrameDestination::Individual { local: true } => {
211 Some(FrameDestination::Individual { local: () })
212 }
213 FrameDestination::Individual { local: false } => None,
214 FrameDestination::Multicast => Some(FrameDestination::Multicast),
215 FrameDestination::Broadcast => Some(FrameDestination::Broadcast),
216 }
217 }
218}
219
220impl<L> From<BroadcastAddr<Mac>> for FrameDestination<L> {
221 fn from(_value: BroadcastAddr<Mac>) -> Self {
222 Self::Broadcast
223 }
224}
225
226impl<L> From<MulticastAddr<Mac>> for FrameDestination<L> {
227 fn from(_value: MulticastAddr<Mac>) -> Self {
228 Self::Multicast
229 }
230}
231
232pub struct RecvIpFrameMeta<D, M, I: Ip> {
234 pub device: D,
236 pub frame_dst: Option<LocalFrameDestination>,
243 pub ip_layer_metadata: M,
246 pub marker: IpVersionMarker<I>,
248 pub parsing_context: NetworkParsingContext,
250}
251
252impl<D, M, I: Ip> RecvIpFrameMeta<D, M, I> {
253 pub fn new(
256 device: D,
257 frame_dst: Option<LocalFrameDestination>,
258 ip_layer_metadata: M,
259 parsing_context: NetworkParsingContext,
260 ) -> RecvIpFrameMeta<D, M, I> {
261 RecvIpFrameMeta {
262 device,
263 frame_dst,
264 ip_layer_metadata,
265 marker: IpVersionMarker::new(),
266 parsing_context,
267 }
268 }
269}
270
271pub trait TxMetadata: Default + Debug + Send + Sync + 'static {
276 fn socket_info(&self) -> Option<SocketInfo>;
279
280 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult>;
282
283 fn set_checksum_offload_result(&mut self, result: Option<ChecksumOffloadResult>);
286}
287
288pub trait TxMetadataBindingsTypes {
300 type TxMetadata: TxMetadata;
302}
303
304pub trait CoreTxMetadataContext<T, BT: TxMetadataBindingsTypes> {
309 fn convert_tx_meta(&self, tx_meta: T) -> BT::TxMetadata;
315}
316
317pub struct NeverBuffer(core::convert::Infallible);
325
326impl packet::FragmentedBuffer for NeverBuffer {
327 fn len(&self) -> usize {
328 match self.0 {}
329 }
330
331 fn with_bytes<'a, R, F>(&'a self, _f: F) -> R
332 where
333 F: for<'b> FnOnce(packet::FragmentedBytes<'b, 'a>) -> R,
334 {
335 match self.0 {}
336 }
337}
338
339impl AsMut<[u8]> for NeverBuffer {
340 fn as_mut(&mut self) -> &mut [u8] {
341 match self.0 {}
342 }
343}
344
345#[cfg(any(test, feature = "testutils"))]
346pub(crate) mod testutil {
347 use super::*;
348 use alloc::boxed::Box;
349 use alloc::vec::Vec;
350
351 use crate::packet::NetworkSerializationContext;
352 use crate::testutil::FakeBindingsCtx;
353
354 pub struct FakeFrameCtx<Meta> {
356 frames: Vec<(Meta, Vec<u8>)>,
357 should_error_for_frame:
358 Option<Box<dyn FnMut(&Meta) -> Option<SendFrameErrorReason> + Send>>,
359 }
360
361 impl<Meta> FakeFrameCtx<Meta> {
362 pub fn set_should_error_for_frame<
365 F: Fn(&Meta) -> Option<SendFrameErrorReason> + Send + 'static,
366 >(
367 &mut self,
368 f: F,
369 ) {
370 self.should_error_for_frame = Some(Box::new(f));
371 }
372 }
373
374 impl<Meta> Default for FakeFrameCtx<Meta> {
375 fn default() -> FakeFrameCtx<Meta> {
376 FakeFrameCtx { frames: Vec::new(), should_error_for_frame: None }
377 }
378 }
379
380 impl<Meta> FakeFrameCtx<Meta> {
381 pub fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
383 core::mem::take(&mut self.frames)
384 }
385
386 pub fn frames(&self) -> &[(Meta, Vec<u8>)] {
388 self.frames.as_slice()
389 }
390
391 pub fn push(&mut self, meta: Meta, frame: Vec<u8>) {
393 self.frames.push((meta, frame))
394 }
395 }
396
397 impl<Meta, BC> SendableFrameMeta<FakeFrameCtx<Meta>, BC> for Meta {
398 fn send_meta<S>(
399 self,
400 core_ctx: &mut FakeFrameCtx<Meta>,
401 _bindings_ctx: &mut BC,
402 frame: S,
403 ) -> Result<(), SendFrameError<S>>
404 where
405 S: NetworkSerializer,
406 S::Buffer: BufferMut,
407 {
408 if let Some(error) = core_ctx.should_error_for_frame.as_mut().and_then(|f| f(&self)) {
409 return Err(SendFrameError { serializer: frame, error });
410 }
411
412 let buffer = frame
413 .serialize_vec_outer(&mut NetworkSerializationContext::default())
414 .map_err(|(e, serializer)| SendFrameError { error: e.into(), serializer })?;
415 core_ctx.push(self, buffer.as_ref().to_vec());
416 Ok(())
417 }
418 }
419
420 pub trait WithFakeFrameContext<SendMeta> {
422 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
424 &mut self,
425 f: F,
426 ) -> O;
427 }
428
429 impl<SendMeta> WithFakeFrameContext<SendMeta> for FakeFrameCtx<SendMeta> {
430 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
431 &mut self,
432 f: F,
433 ) -> O {
434 f(self)
435 }
436 }
437
438 impl<TimerId, Event: Debug, State, FrameMeta> TxMetadataBindingsTypes
439 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
440 {
441 type TxMetadata = FakeTxMetadata;
442 }
443
444 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
446 pub struct FakeTxMetadata;
447
448 impl TxMetadata for FakeTxMetadata {
449 fn socket_info(&self) -> Option<SocketInfo> {
450 None
451 }
452
453 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult> {
454 None
455 }
456
457 fn set_checksum_offload_result(&mut self, _result: Option<ChecksumOffloadResult>) {}
458 }
459}
460
461#[cfg(test)]
462mod tests {
463 use super::*;
464
465 use net_declare::net_mac;
466 use net_types::{UnicastAddr, Witness as _};
467
468 #[test]
469 fn frame_destination_from_dest() {
470 const LOCAL_ADDR: Mac = net_mac!("88:88:88:88:88:88");
471
472 assert_eq!(
473 FrameDestination::from_dest(
474 UnicastAddr::new(net_mac!("00:11:22:33:44:55")).unwrap().get(),
475 LOCAL_ADDR
476 ),
477 FrameDestination::Individual { local: false }
478 );
479 assert_eq!(
480 FrameDestination::from_dest(LOCAL_ADDR, LOCAL_ADDR),
481 FrameDestination::Individual { local: true }
482 );
483 assert_eq!(
484 FrameDestination::from_dest(Mac::BROADCAST, LOCAL_ADDR),
485 FrameDestination::Broadcast,
486 );
487 assert_eq!(
488 FrameDestination::from_dest(
489 MulticastAddr::new(net_mac!("11:11:11:11:11:11")).unwrap().get(),
490 LOCAL_ADDR
491 ),
492 FrameDestination::Multicast
493 );
494 }
495}