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 {
166 Individual {
168 local: bool,
170 },
171 Multicast,
175 Broadcast,
179}
180
181impl FrameDestination {
182 pub fn is_broadcast(self) -> bool {
184 self == FrameDestination::Broadcast
185 }
186
187 pub fn from_dest(destination: Mac, local_mac: Mac) -> Self {
189 BroadcastAddr::new(destination)
190 .map(Into::into)
191 .or_else(|| MulticastAddr::new(destination).map(Into::into))
192 .unwrap_or_else(|| FrameDestination::Individual { local: destination == local_mac })
193 }
194}
195
196impl From<BroadcastAddr<Mac>> for FrameDestination {
197 fn from(_value: BroadcastAddr<Mac>) -> Self {
198 Self::Broadcast
199 }
200}
201
202impl From<MulticastAddr<Mac>> for FrameDestination {
203 fn from(_value: MulticastAddr<Mac>) -> Self {
204 Self::Multicast
205 }
206}
207
208pub struct RecvIpFrameMeta<D, M, I: Ip> {
210 pub device: D,
212 pub frame_dst: Option<FrameDestination>,
219 pub ip_layer_metadata: M,
222 pub marker: IpVersionMarker<I>,
224 pub parsing_context: NetworkParsingContext,
226}
227
228impl<D, M, I: Ip> RecvIpFrameMeta<D, M, I> {
229 pub fn new(
232 device: D,
233 frame_dst: Option<FrameDestination>,
234 ip_layer_metadata: M,
235 parsing_context: NetworkParsingContext,
236 ) -> RecvIpFrameMeta<D, M, I> {
237 RecvIpFrameMeta {
238 device,
239 frame_dst,
240 ip_layer_metadata,
241 marker: IpVersionMarker::new(),
242 parsing_context,
243 }
244 }
245}
246
247pub trait TxMetadata: Default + Debug + Send + Sync + 'static {
252 fn socket_info(&self) -> Option<SocketInfo>;
255
256 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult>;
258
259 fn set_checksum_offload_result(&mut self, result: Option<ChecksumOffloadResult>);
262}
263
264pub trait TxMetadataBindingsTypes {
276 type TxMetadata: TxMetadata;
278}
279
280pub trait CoreTxMetadataContext<T, BT: TxMetadataBindingsTypes> {
285 fn convert_tx_meta(&self, tx_meta: T) -> BT::TxMetadata;
291}
292
293pub struct NeverBuffer(core::convert::Infallible);
301
302impl packet::FragmentedBuffer for NeverBuffer {
303 fn len(&self) -> usize {
304 match self.0 {}
305 }
306
307 fn with_bytes<'a, R, F>(&'a self, _f: F) -> R
308 where
309 F: for<'b> FnOnce(packet::FragmentedBytes<'b, 'a>) -> R,
310 {
311 match self.0 {}
312 }
313}
314
315impl AsMut<[u8]> for NeverBuffer {
316 fn as_mut(&mut self) -> &mut [u8] {
317 match self.0 {}
318 }
319}
320
321#[cfg(any(test, feature = "testutils"))]
322pub(crate) mod testutil {
323 use super::*;
324 use alloc::boxed::Box;
325 use alloc::vec::Vec;
326
327 use crate::packet::NetworkSerializationContext;
328 use crate::testutil::FakeBindingsCtx;
329
330 pub struct FakeFrameCtx<Meta> {
332 frames: Vec<(Meta, Vec<u8>)>,
333 should_error_for_frame:
334 Option<Box<dyn FnMut(&Meta) -> Option<SendFrameErrorReason> + Send>>,
335 }
336
337 impl<Meta> FakeFrameCtx<Meta> {
338 pub fn set_should_error_for_frame<
341 F: Fn(&Meta) -> Option<SendFrameErrorReason> + Send + 'static,
342 >(
343 &mut self,
344 f: F,
345 ) {
346 self.should_error_for_frame = Some(Box::new(f));
347 }
348 }
349
350 impl<Meta> Default for FakeFrameCtx<Meta> {
351 fn default() -> FakeFrameCtx<Meta> {
352 FakeFrameCtx { frames: Vec::new(), should_error_for_frame: None }
353 }
354 }
355
356 impl<Meta> FakeFrameCtx<Meta> {
357 pub fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
359 core::mem::take(&mut self.frames)
360 }
361
362 pub fn frames(&self) -> &[(Meta, Vec<u8>)] {
364 self.frames.as_slice()
365 }
366
367 pub fn push(&mut self, meta: Meta, frame: Vec<u8>) {
369 self.frames.push((meta, frame))
370 }
371 }
372
373 impl<Meta, BC> SendableFrameMeta<FakeFrameCtx<Meta>, BC> for Meta {
374 fn send_meta<S>(
375 self,
376 core_ctx: &mut FakeFrameCtx<Meta>,
377 _bindings_ctx: &mut BC,
378 frame: S,
379 ) -> Result<(), SendFrameError<S>>
380 where
381 S: NetworkSerializer,
382 S::Buffer: BufferMut,
383 {
384 if let Some(error) = core_ctx.should_error_for_frame.as_mut().and_then(|f| f(&self)) {
385 return Err(SendFrameError { serializer: frame, error });
386 }
387
388 let buffer = frame
389 .serialize_vec_outer(&mut NetworkSerializationContext::default())
390 .map_err(|(e, serializer)| SendFrameError { error: e.into(), serializer })?;
391 core_ctx.push(self, buffer.as_ref().to_vec());
392 Ok(())
393 }
394 }
395
396 pub trait WithFakeFrameContext<SendMeta> {
398 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
400 &mut self,
401 f: F,
402 ) -> O;
403 }
404
405 impl<SendMeta> WithFakeFrameContext<SendMeta> for FakeFrameCtx<SendMeta> {
406 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
407 &mut self,
408 f: F,
409 ) -> O {
410 f(self)
411 }
412 }
413
414 impl<TimerId, Event: Debug, State, FrameMeta> TxMetadataBindingsTypes
415 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
416 {
417 type TxMetadata = FakeTxMetadata;
418 }
419
420 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
422 pub struct FakeTxMetadata;
423
424 impl TxMetadata for FakeTxMetadata {
425 fn socket_info(&self) -> Option<SocketInfo> {
426 None
427 }
428
429 fn checksum_offload_result(&self) -> Option<ChecksumOffloadResult> {
430 None
431 }
432
433 fn set_checksum_offload_result(&mut self, _result: Option<ChecksumOffloadResult>) {}
434 }
435}
436
437#[cfg(test)]
438mod tests {
439 use super::*;
440
441 use net_declare::net_mac;
442 use net_types::{UnicastAddr, Witness as _};
443
444 #[test]
445 fn frame_destination_from_dest() {
446 const LOCAL_ADDR: Mac = net_mac!("88:88:88:88:88:88");
447
448 assert_eq!(
449 FrameDestination::from_dest(
450 UnicastAddr::new(net_mac!("00:11:22:33:44:55")).unwrap().get(),
451 LOCAL_ADDR
452 ),
453 FrameDestination::Individual { local: false }
454 );
455 assert_eq!(
456 FrameDestination::from_dest(LOCAL_ADDR, LOCAL_ADDR),
457 FrameDestination::Individual { local: true }
458 );
459 assert_eq!(
460 FrameDestination::from_dest(Mac::BROADCAST, LOCAL_ADDR),
461 FrameDestination::Broadcast,
462 );
463 assert_eq!(
464 FrameDestination::from_dest(
465 MulticastAddr::new(net_mac!("11:11:11:11:11:11")).unwrap().get(),
466 LOCAL_ADDR
467 ),
468 FrameDestination::Multicast
469 );
470 }
471}