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
241pub const MAX_GSO_PAYLOAD_LEN: u16 = u16::MAX;
244
245#[derive(Clone, Copy, Debug, Eq, PartialEq)]
247pub struct GsoInfo {
248 pub gso_size: core::num::NonZeroU16,
251 pub gso_segs: core::num::NonZeroU16,
254 pub ipv4_id_mode: Option<Ipv4IdMode>,
257}
258
259#[derive(Copy, Clone, Debug, Eq, PartialEq)]
264pub enum PacketType {
265 Host,
267 Broadcast,
269 Multicast,
271 OtherHost,
274 Outgoing,
276 Loopback,
282}
283
284impl From<FrameDestination<bool>> for PacketType {
285 fn from(dst: FrameDestination<bool>) -> Self {
286 match dst {
287 FrameDestination::Individual { local: true } => PacketType::Host,
288 FrameDestination::Individual { local: false } => PacketType::OtherHost,
289 FrameDestination::Broadcast => PacketType::Broadcast,
290 FrameDestination::Multicast => PacketType::Multicast,
291 }
292 }
293}
294
295impl From<LocalFrameDestination> for PacketType {
296 fn from(dst: LocalFrameDestination) -> Self {
297 match dst {
298 FrameDestination::Individual { local: () } => PacketType::Host,
299 FrameDestination::Broadcast => PacketType::Broadcast,
300 FrameDestination::Multicast => PacketType::Multicast,
301 }
302 }
303}
304
305pub struct RecvIpFrameMeta<D, M, I: Ip> {
307 pub device: D,
309 pub frame_dst: Option<LocalFrameDestination>,
316 pub ip_layer_metadata: M,
319 pub marker: IpVersionMarker<I>,
321 pub parsing_context: NetworkParsingContext,
323 pub gso_info: Option<GsoInfo>,
325}
326
327impl<D, M, I: Ip> RecvIpFrameMeta<D, M, I> {
328 pub fn new(
331 device: D,
332 frame_dst: Option<LocalFrameDestination>,
333 ip_layer_metadata: M,
334 parsing_context: NetworkParsingContext,
335 gso_info: Option<GsoInfo>,
336 ) -> RecvIpFrameMeta<D, M, I> {
337 RecvIpFrameMeta {
338 device,
339 frame_dst,
340 ip_layer_metadata,
341 marker: IpVersionMarker::new(),
342 parsing_context,
343 gso_info,
344 }
345 }
346}
347
348pub trait TxMetadata: Default + Debug + Send + Sync + 'static {
353 fn socket_info(&self) -> Option<SocketInfo>;
356
357 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult>;
359
360 fn set_checksum_offload_result(&mut self, result: Option<ChecksumOffloadResult>);
363}
364
365pub trait TxMetadataBindingsTypes {
377 type TxMetadata: TxMetadata;
379}
380
381pub trait CoreTxMetadataContext<T, BT: TxMetadataBindingsTypes> {
386 fn convert_tx_meta(&self, tx_meta: T) -> BT::TxMetadata;
392}
393
394pub struct NeverBuffer(!);
402
403impl packet::FragmentedBuffer for NeverBuffer {
404 fn len(&self) -> usize {
405 match self.0 {}
406 }
407
408 fn with_bytes<'a, R, F>(&'a self, _f: F) -> R
409 where
410 F: for<'b> FnOnce(packet::FragmentedBytes<'b, 'a>) -> R,
411 {
412 match self.0 {}
413 }
414}
415
416impl AsMut<[u8]> for NeverBuffer {
417 fn as_mut(&mut self) -> &mut [u8] {
418 match self.0 {}
419 }
420}
421
422#[cfg(any(test, feature = "testutils"))]
423pub(crate) mod testutil {
424 use super::*;
425 use alloc::boxed::Box;
426 use alloc::vec::Vec;
427
428 use crate::packet::NetworkSerializationContext;
429 use crate::testutil::FakeBindingsCtx;
430
431 pub struct FakeFrameCtx<Meta> {
433 frames: Vec<(Meta, Vec<u8>)>,
434 should_error_for_frame:
435 Option<Box<dyn FnMut(&Meta) -> Option<SendFrameErrorReason> + Send>>,
436 }
437
438 impl<Meta> FakeFrameCtx<Meta> {
439 pub fn set_should_error_for_frame<
442 F: Fn(&Meta) -> Option<SendFrameErrorReason> + Send + 'static,
443 >(
444 &mut self,
445 f: F,
446 ) {
447 self.should_error_for_frame = Some(Box::new(f));
448 }
449 }
450
451 impl<Meta> Default for FakeFrameCtx<Meta> {
452 fn default() -> FakeFrameCtx<Meta> {
453 FakeFrameCtx { frames: Vec::new(), should_error_for_frame: None }
454 }
455 }
456
457 impl<Meta> FakeFrameCtx<Meta> {
458 pub fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
460 core::mem::take(&mut self.frames)
461 }
462
463 pub fn frames(&self) -> &[(Meta, Vec<u8>)] {
465 self.frames.as_slice()
466 }
467
468 pub fn push(&mut self, meta: Meta, frame: Vec<u8>) {
470 self.frames.push((meta, frame))
471 }
472 }
473
474 impl<Meta, BC> SendableFrameMeta<FakeFrameCtx<Meta>, BC> for Meta {
475 fn send_meta<S>(
476 self,
477 core_ctx: &mut FakeFrameCtx<Meta>,
478 _bindings_ctx: &mut BC,
479 frame: S,
480 ) -> Result<(), SendFrameError<S>>
481 where
482 S: NetworkSerializer,
483 S::Buffer: BufferMut,
484 {
485 if let Some(error) = core_ctx.should_error_for_frame.as_mut().and_then(|f| f(&self)) {
486 return Err(SendFrameError { serializer: frame, error });
487 }
488
489 let buffer = frame
490 .serialize_vec_outer(&mut NetworkSerializationContext::default())
491 .map_err(|(e, serializer)| SendFrameError { error: e.into(), serializer })?;
492 core_ctx.push(self, buffer.as_ref().to_vec());
493 Ok(())
494 }
495 }
496
497 pub trait WithFakeFrameContext<SendMeta> {
499 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
501 &mut self,
502 f: F,
503 ) -> O;
504 }
505
506 impl<SendMeta> WithFakeFrameContext<SendMeta> for FakeFrameCtx<SendMeta> {
507 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
508 &mut self,
509 f: F,
510 ) -> O {
511 f(self)
512 }
513 }
514
515 impl<TimerId, Event: Debug, State, FrameMeta> TxMetadataBindingsTypes
516 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
517 {
518 type TxMetadata = FakeTxMetadata;
519 }
520
521 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
523 pub struct FakeTxMetadata;
524
525 impl TxMetadata for FakeTxMetadata {
526 fn socket_info(&self) -> Option<SocketInfo> {
527 None
528 }
529
530 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult> {
531 None
532 }
533
534 fn set_checksum_offload_result(&mut self, _result: Option<ChecksumOffloadResult>) {}
535 }
536}
537
538#[cfg(test)]
539mod tests {
540 use super::*;
541
542 use net_declare::net_mac;
543 use net_types::{UnicastAddr, Witness as _};
544
545 #[test]
546 fn frame_destination_from_dest() {
547 const LOCAL_ADDR: Mac = net_mac!("88:88:88:88:88:88");
548
549 assert_eq!(
550 FrameDestination::from_dest(
551 UnicastAddr::new(net_mac!("00:11:22:33:44:55")).unwrap().get(),
552 LOCAL_ADDR
553 ),
554 FrameDestination::Individual { local: false }
555 );
556 assert_eq!(
557 FrameDestination::from_dest(LOCAL_ADDR, LOCAL_ADDR),
558 FrameDestination::Individual { local: true }
559 );
560 assert_eq!(
561 FrameDestination::from_dest(Mac::BROADCAST, LOCAL_ADDR),
562 FrameDestination::Broadcast,
563 );
564 assert_eq!(
565 FrameDestination::from_dest(
566 MulticastAddr::new(net_mac!("11:11:11:11:11:11")).unwrap().get(),
567 LOCAL_ADDR
568 ),
569 FrameDestination::Multicast
570 );
571 }
572}