1use net_types::ethernet::Mac;
8use net_types::ip::{Ip, IpVersionMarker};
9use net_types::{BroadcastAddr, MulticastAddr};
10
11use core::fmt::Debug;
12use packet::{BufferMut, SerializeError};
13use thiserror::Error;
14
15use crate::error::ErrorAndSerializer;
16use crate::socket::SocketInfo;
17use crate::{ChecksumOffloadResult, NetworkParsingContext, NetworkSerializer};
18
19pub trait RecvFrameContext<Meta, BC> {
25 fn receive_frame<B: BufferMut + Debug>(
29 &mut self,
30 bindings_ctx: &mut BC,
31 metadata: Meta,
32 frame: B,
33 );
34}
35
36impl<CC, BC> ReceivableFrameMeta<CC, BC> for ! {
37 fn receive_meta<B: BufferMut + Debug>(
38 self,
39 _core_ctx: &mut CC,
40 _bindings_ctx: &mut BC,
41 _frame: B,
42 ) {
43 match self {}
44 }
45}
46
47pub trait ReceivableFrameMeta<CC, BC> {
55 fn receive_meta<B: BufferMut + Debug>(self, core_ctx: &mut CC, bindings_ctx: &mut BC, frame: B);
57}
58
59impl<CC, BC, Meta> RecvFrameContext<Meta, BC> for CC
60where
61 Meta: ReceivableFrameMeta<CC, BC>,
62{
63 fn receive_frame<B: BufferMut + Debug>(
64 &mut self,
65 bindings_ctx: &mut BC,
66 metadata: Meta,
67 frame: B,
68 ) {
69 metadata.receive_meta(self, bindings_ctx, frame)
70 }
71}
72
73#[derive(Error, Debug, PartialEq)]
75pub enum SendFrameErrorReason {
76 #[error("size constraints violated")]
78 SizeConstraintsViolation,
79 #[error("failed to allocate")]
81 Alloc,
82 #[error("transmit queue is full")]
84 QueueFull,
85 #[error("address resolution failed")]
87 AddressResolutionFailed,
88}
89
90impl<A> From<SerializeError<A>> for SendFrameErrorReason {
91 fn from(e: SerializeError<A>) -> Self {
92 match e {
93 SerializeError::Alloc(_) => Self::Alloc,
94 SerializeError::SizeLimitExceeded => Self::SizeConstraintsViolation,
95 }
96 }
97}
98
99pub type SendFrameError<S> = ErrorAndSerializer<SendFrameErrorReason, S>;
101
102pub trait SendFrameContext<BC, Meta> {
104 fn send_frame<S>(
113 &mut self,
114 bindings_ctx: &mut BC,
115 metadata: Meta,
116 frame: S,
117 ) -> Result<(), SendFrameError<S>>
118 where
119 S: NetworkSerializer,
120 S::Buffer: BufferMut;
121}
122
123pub trait SendableFrameMeta<CC, BC> {
131 fn send_meta<S>(
133 self,
134 core_ctx: &mut CC,
135 bindings_ctx: &mut BC,
136 frame: S,
137 ) -> Result<(), SendFrameError<S>>
138 where
139 S: NetworkSerializer,
140 S::Buffer: BufferMut;
141}
142
143impl<CC, BC, Meta> SendFrameContext<BC, Meta> for CC
144where
145 Meta: SendableFrameMeta<CC, BC>,
146{
147 fn send_frame<S>(
148 &mut self,
149 bindings_ctx: &mut BC,
150 metadata: Meta,
151 frame: S,
152 ) -> Result<(), SendFrameError<S>>
153 where
154 S: NetworkSerializer,
155 S::Buffer: BufferMut,
156 {
157 metadata.send_meta(self, bindings_ctx, frame)
158 }
159}
160
161#[derive(Copy, Clone, Debug, Eq, PartialEq)]
167pub enum FrameDestination<L = bool> {
168 Individual {
170 local: L,
172 },
173 Multicast,
177 Broadcast,
181}
182
183pub type LocalFrameDestination = FrameDestination<()>;
186
187impl<L> FrameDestination<L> {
188 pub fn is_broadcast(self) -> bool {
190 matches!(self, FrameDestination::Broadcast)
191 }
192}
193
194impl FrameDestination<bool> {
195 pub fn from_dest(destination: Mac, local_mac: Mac) -> Self {
197 BroadcastAddr::new(destination)
198 .map(Into::into)
199 .or_else(|| MulticastAddr::new(destination).map(Into::into))
200 .unwrap_or_else(|| FrameDestination::Individual { local: destination == local_mac })
201 }
202
203 pub fn check_local(self) -> Option<LocalFrameDestination> {
208 match self {
209 FrameDestination::Individual { local: true } => {
210 Some(FrameDestination::Individual { local: () })
211 }
212 FrameDestination::Individual { local: false } => None,
213 FrameDestination::Multicast => Some(FrameDestination::Multicast),
214 FrameDestination::Broadcast => Some(FrameDestination::Broadcast),
215 }
216 }
217}
218
219impl<L> From<BroadcastAddr<Mac>> for FrameDestination<L> {
220 fn from(_value: BroadcastAddr<Mac>) -> Self {
221 Self::Broadcast
222 }
223}
224
225impl<L> From<MulticastAddr<Mac>> for FrameDestination<L> {
226 fn from(_value: MulticastAddr<Mac>) -> Self {
227 Self::Multicast
228 }
229}
230
231#[derive(Clone, Copy, Debug, Eq, PartialEq)]
233pub enum Ipv4IdMode {
234 Fixed,
236 Incrementing,
239}
240
241#[derive(Clone, Copy, Debug, Eq, PartialEq)]
243pub struct GsoInfo {
244 pub gso_size: core::num::NonZeroU16,
247 pub ipv4_id_mode: Option<Ipv4IdMode>,
250}
251
252pub struct RecvIpFrameMeta<D, M, I: Ip> {
254 pub device: D,
256 pub frame_dst: Option<LocalFrameDestination>,
263 pub ip_layer_metadata: M,
266 pub marker: IpVersionMarker<I>,
268 pub parsing_context: NetworkParsingContext,
270 pub gso_info: Option<GsoInfo>,
272}
273
274impl<D, M, I: Ip> RecvIpFrameMeta<D, M, I> {
275 pub fn new(
278 device: D,
279 frame_dst: Option<LocalFrameDestination>,
280 ip_layer_metadata: M,
281 parsing_context: NetworkParsingContext,
282 gso_info: Option<GsoInfo>,
283 ) -> RecvIpFrameMeta<D, M, I> {
284 RecvIpFrameMeta {
285 device,
286 frame_dst,
287 ip_layer_metadata,
288 marker: IpVersionMarker::new(),
289 parsing_context,
290 gso_info,
291 }
292 }
293}
294
295pub trait TxMetadata: Default + Debug + Send + Sync + 'static {
300 fn socket_info(&self) -> Option<SocketInfo>;
303
304 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult>;
306
307 fn set_checksum_offload_result(&mut self, result: Option<ChecksumOffloadResult>);
310}
311
312pub trait TxMetadataBindingsTypes {
324 type TxMetadata: TxMetadata;
326}
327
328pub trait CoreTxMetadataContext<T, BT: TxMetadataBindingsTypes> {
333 fn convert_tx_meta(&self, tx_meta: T) -> BT::TxMetadata;
339}
340
341pub struct NeverBuffer(!);
349
350impl packet::FragmentedBuffer for NeverBuffer {
351 fn len(&self) -> usize {
352 match self.0 {}
353 }
354
355 fn with_bytes<'a, R, F>(&'a self, _f: F) -> R
356 where
357 F: for<'b> FnOnce(packet::FragmentedBytes<'b, 'a>) -> R,
358 {
359 match self.0 {}
360 }
361}
362
363impl AsMut<[u8]> for NeverBuffer {
364 fn as_mut(&mut self) -> &mut [u8] {
365 match self.0 {}
366 }
367}
368
369#[cfg(any(test, feature = "testutils"))]
370pub(crate) mod testutil {
371 use super::*;
372 use alloc::boxed::Box;
373 use alloc::vec::Vec;
374
375 use crate::packet::NetworkSerializationContext;
376 use crate::testutil::FakeBindingsCtx;
377
378 pub struct FakeFrameCtx<Meta> {
380 frames: Vec<(Meta, Vec<u8>)>,
381 should_error_for_frame:
382 Option<Box<dyn FnMut(&Meta) -> Option<SendFrameErrorReason> + Send>>,
383 }
384
385 impl<Meta> FakeFrameCtx<Meta> {
386 pub fn set_should_error_for_frame<
389 F: Fn(&Meta) -> Option<SendFrameErrorReason> + Send + 'static,
390 >(
391 &mut self,
392 f: F,
393 ) {
394 self.should_error_for_frame = Some(Box::new(f));
395 }
396 }
397
398 impl<Meta> Default for FakeFrameCtx<Meta> {
399 fn default() -> FakeFrameCtx<Meta> {
400 FakeFrameCtx { frames: Vec::new(), should_error_for_frame: None }
401 }
402 }
403
404 impl<Meta> FakeFrameCtx<Meta> {
405 pub fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
407 core::mem::take(&mut self.frames)
408 }
409
410 pub fn frames(&self) -> &[(Meta, Vec<u8>)] {
412 self.frames.as_slice()
413 }
414
415 pub fn push(&mut self, meta: Meta, frame: Vec<u8>) {
417 self.frames.push((meta, frame))
418 }
419 }
420
421 impl<Meta, BC> SendableFrameMeta<FakeFrameCtx<Meta>, BC> for Meta {
422 fn send_meta<S>(
423 self,
424 core_ctx: &mut FakeFrameCtx<Meta>,
425 _bindings_ctx: &mut BC,
426 frame: S,
427 ) -> Result<(), SendFrameError<S>>
428 where
429 S: NetworkSerializer,
430 S::Buffer: BufferMut,
431 {
432 if let Some(error) = core_ctx.should_error_for_frame.as_mut().and_then(|f| f(&self)) {
433 return Err(SendFrameError { serializer: frame, error });
434 }
435
436 let buffer = frame
437 .serialize_vec_outer(&mut NetworkSerializationContext::default())
438 .map_err(|(e, serializer)| SendFrameError { error: e.into(), serializer })?;
439 core_ctx.push(self, buffer.as_ref().to_vec());
440 Ok(())
441 }
442 }
443
444 pub trait WithFakeFrameContext<SendMeta> {
446 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
448 &mut self,
449 f: F,
450 ) -> O;
451 }
452
453 impl<SendMeta> WithFakeFrameContext<SendMeta> for FakeFrameCtx<SendMeta> {
454 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
455 &mut self,
456 f: F,
457 ) -> O {
458 f(self)
459 }
460 }
461
462 impl<TimerId, Event: Debug, State, FrameMeta> TxMetadataBindingsTypes
463 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
464 {
465 type TxMetadata = FakeTxMetadata;
466 }
467
468 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
470 pub struct FakeTxMetadata;
471
472 impl TxMetadata for FakeTxMetadata {
473 fn socket_info(&self) -> Option<SocketInfo> {
474 None
475 }
476
477 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult> {
478 None
479 }
480
481 fn set_checksum_offload_result(&mut self, _result: Option<ChecksumOffloadResult>) {}
482 }
483}
484
485#[cfg(test)]
486mod tests {
487 use super::*;
488
489 use net_declare::net_mac;
490 use net_types::{UnicastAddr, Witness as _};
491
492 #[test]
493 fn frame_destination_from_dest() {
494 const LOCAL_ADDR: Mac = net_mac!("88:88:88:88:88:88");
495
496 assert_eq!(
497 FrameDestination::from_dest(
498 UnicastAddr::new(net_mac!("00:11:22:33:44:55")).unwrap().get(),
499 LOCAL_ADDR
500 ),
501 FrameDestination::Individual { local: false }
502 );
503 assert_eq!(
504 FrameDestination::from_dest(LOCAL_ADDR, LOCAL_ADDR),
505 FrameDestination::Individual { local: true }
506 );
507 assert_eq!(
508 FrameDestination::from_dest(Mac::BROADCAST, LOCAL_ADDR),
509 FrameDestination::Broadcast,
510 );
511 assert_eq!(
512 FrameDestination::from_dest(
513 MulticastAddr::new(net_mac!("11:11:11:11:11:11")).unwrap().get(),
514 LOCAL_ADDR
515 ),
516 FrameDestination::Multicast
517 );
518 }
519}