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::SocketCookie;
18use crate::{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_cookie(&self) -> Option<SocketCookie>;
256}
257
258pub trait TxMetadataBindingsTypes {
270 type TxMetadata: TxMetadata;
272}
273
274pub trait CoreTxMetadataContext<T, BT: TxMetadataBindingsTypes> {
279 fn convert_tx_meta(&self, tx_meta: T) -> BT::TxMetadata;
285}
286
287pub struct NeverBuffer(core::convert::Infallible);
295
296impl packet::FragmentedBuffer for NeverBuffer {
297 fn len(&self) -> usize {
298 match self.0 {}
299 }
300
301 fn with_bytes<'a, R, F>(&'a self, _f: F) -> R
302 where
303 F: for<'b> FnOnce(packet::FragmentedBytes<'b, 'a>) -> R,
304 {
305 match self.0 {}
306 }
307}
308
309impl AsMut<[u8]> for NeverBuffer {
310 fn as_mut(&mut self) -> &mut [u8] {
311 match self.0 {}
312 }
313}
314
315#[cfg(any(test, feature = "testutils"))]
316pub(crate) mod testutil {
317 use super::*;
318 use alloc::boxed::Box;
319 use alloc::vec::Vec;
320
321 use crate::packet::NetworkSerializationContext;
322 use crate::testutil::FakeBindingsCtx;
323
324 pub struct FakeFrameCtx<Meta> {
326 frames: Vec<(Meta, Vec<u8>)>,
327 should_error_for_frame:
328 Option<Box<dyn FnMut(&Meta) -> Option<SendFrameErrorReason> + Send>>,
329 }
330
331 impl<Meta> FakeFrameCtx<Meta> {
332 pub fn set_should_error_for_frame<
335 F: Fn(&Meta) -> Option<SendFrameErrorReason> + Send + 'static,
336 >(
337 &mut self,
338 f: F,
339 ) {
340 self.should_error_for_frame = Some(Box::new(f));
341 }
342 }
343
344 impl<Meta> Default for FakeFrameCtx<Meta> {
345 fn default() -> FakeFrameCtx<Meta> {
346 FakeFrameCtx { frames: Vec::new(), should_error_for_frame: None }
347 }
348 }
349
350 impl<Meta> FakeFrameCtx<Meta> {
351 pub fn take_frames(&mut self) -> Vec<(Meta, Vec<u8>)> {
353 core::mem::take(&mut self.frames)
354 }
355
356 pub fn frames(&self) -> &[(Meta, Vec<u8>)] {
358 self.frames.as_slice()
359 }
360
361 pub fn push(&mut self, meta: Meta, frame: Vec<u8>) {
363 self.frames.push((meta, frame))
364 }
365 }
366
367 impl<Meta, BC> SendableFrameMeta<FakeFrameCtx<Meta>, BC> for Meta {
368 fn send_meta<S>(
369 self,
370 core_ctx: &mut FakeFrameCtx<Meta>,
371 _bindings_ctx: &mut BC,
372 frame: S,
373 ) -> Result<(), SendFrameError<S>>
374 where
375 S: NetworkSerializer,
376 S::Buffer: BufferMut,
377 {
378 if let Some(error) = core_ctx.should_error_for_frame.as_mut().and_then(|f| f(&self)) {
379 return Err(SendFrameError { serializer: frame, error });
380 }
381
382 let buffer = frame
383 .serialize_vec_outer(&mut NetworkSerializationContext::default())
384 .map_err(|(e, serializer)| SendFrameError { error: e.into(), serializer })?;
385 core_ctx.push(self, buffer.as_ref().to_vec());
386 Ok(())
387 }
388 }
389
390 pub trait WithFakeFrameContext<SendMeta> {
392 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
394 &mut self,
395 f: F,
396 ) -> O;
397 }
398
399 impl<SendMeta> WithFakeFrameContext<SendMeta> for FakeFrameCtx<SendMeta> {
400 fn with_fake_frame_ctx_mut<O, F: FnOnce(&mut FakeFrameCtx<SendMeta>) -> O>(
401 &mut self,
402 f: F,
403 ) -> O {
404 f(self)
405 }
406 }
407
408 impl<TimerId, Event: Debug, State, FrameMeta> TxMetadataBindingsTypes
409 for FakeBindingsCtx<TimerId, Event, State, FrameMeta>
410 {
411 type TxMetadata = FakeTxMetadata;
412 }
413
414 #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
416 pub struct FakeTxMetadata;
417
418 impl TxMetadata for FakeTxMetadata {
419 fn socket_cookie(&self) -> Option<SocketCookie> {
420 None
421 }
422 }
423}
424
425#[cfg(test)]
426mod tests {
427 use super::*;
428
429 use net_declare::net_mac;
430 use net_types::{UnicastAddr, Witness as _};
431
432 #[test]
433 fn frame_destination_from_dest() {
434 const LOCAL_ADDR: Mac = net_mac!("88:88:88:88:88:88");
435
436 assert_eq!(
437 FrameDestination::from_dest(
438 UnicastAddr::new(net_mac!("00:11:22:33:44:55")).unwrap().get(),
439 LOCAL_ADDR
440 ),
441 FrameDestination::Individual { local: false }
442 );
443 assert_eq!(
444 FrameDestination::from_dest(LOCAL_ADDR, LOCAL_ADDR),
445 FrameDestination::Individual { local: true }
446 );
447 assert_eq!(
448 FrameDestination::from_dest(Mac::BROADCAST, LOCAL_ADDR),
449 FrameDestination::Broadcast,
450 );
451 assert_eq!(
452 FrameDestination::from_dest(
453 MulticastAddr::new(net_mac!("11:11:11:11:11:11")).unwrap().get(),
454 LOCAL_ADDR
455 ),
456 FrameDestination::Multicast
457 );
458 }
459}