Skip to content

Commit 833d319

Browse files
committed
socket: add metadata support for eth sockets
1 parent 1146477 commit 833d319

File tree

3 files changed

+95
-38
lines changed

3 files changed

+95
-38
lines changed

src/iface/interface/ethernet.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ impl InterfaceInner {
2121
#[cfg(feature = "socket-eth")]
2222
let _ = self.eth_socket_filter(
2323
sockets,
24+
meta,
2425
&EthernetRepr::parse(&eth_frame).unwrap(),
2526
eth_frame.payload(),
2627
);

src/iface/interface/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -745,11 +745,12 @@ impl Interface {
745745
}),
746746
#[cfg(feature = "socket-eth")]
747747
Socket::Eth(socket) => {
748-
socket.dispatch(&mut self.inner, |inner, (eth_repr, payload)| {
749-
let token = device.transmit(inner.now).ok_or_else(|| {
748+
socket.dispatch(&mut self.inner, |inner, meta, (eth_repr, payload)| {
749+
let mut token = device.transmit(inner.now).ok_or_else(|| {
750750
net_debug!("failed to transmit raw ETH: device exhausted");
751751
EgressError::Exhausted
752752
})?;
753+
token.set_meta(meta);
753754
inner.dispatch_ethernet(token, payload.len(), |mut frame| {
754755
frame.set_dst_addr(eth_repr.dst_addr);
755756
frame.set_src_addr(eth_repr.src_addr);
@@ -920,18 +921,19 @@ impl InterfaceInner {
920921
fn eth_socket_filter(
921922
&mut self,
922923
sockets: &mut SocketSet,
924+
meta: PacketMeta,
923925
eth_repr: &EthernetRepr,
924926
eth_payload: &[u8],
925927
) -> bool {
926928
let mut handled_by_eth_socket = false;
927929

928-
// Pass every IP packet to all raw sockets we have registered.
930+
// Pass every packet to all eth sockets we have registered.
929931
for eth_socket in sockets
930932
.items_mut()
931933
.filter_map(|i| eth::Socket::downcast_mut(&mut i.socket))
932934
{
933935
if eth_socket.accepts(eth_repr) {
934-
eth_socket.process(self, eth_repr, eth_payload);
936+
eth_socket.process(self, meta, eth_repr, eth_payload);
935937
handled_by_eth_socket = true;
936938
}
937939
}

src/socket/eth.rs

Lines changed: 88 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use core::cmp::min;
33
use core::task::Waker;
44

55
use crate::iface::Context;
6+
use crate::phy::PacketMeta;
67
use crate::socket::PollAt;
78
#[cfg(feature = "async")]
89
use crate::socket::WakerRegistration;
@@ -50,11 +51,25 @@ impl core::fmt::Display for RecvError {
5051
#[cfg(feature = "std")]
5152
impl std::error::Error for RecvError {}
5253

54+
/// Metadata for a sent or received ETH packet.
55+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
56+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
57+
pub struct EthMetadata {
58+
pub meta: PacketMeta,
59+
}
60+
61+
impl core::fmt::Display for EthMetadata {
62+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
63+
#[cfg(feature = "packetmeta-id")]
64+
return write!(f, "PacketID: {:?}", self.meta);
65+
}
66+
}
67+
5368
/// A Eth packet metadata.
54-
pub type PacketMetadata = crate::storage::PacketMetadata<()>;
69+
pub type PacketMetadata = crate::storage::PacketMetadata<EthMetadata>;
5570

5671
/// A Eth packet ring buffer.
57-
pub type PacketBuffer<'a> = crate::storage::PacketBuffer<'a, ()>;
72+
pub type PacketBuffer<'a> = crate::storage::PacketBuffer<'a, EthMetadata>;
5873

5974
pub type Ethertype = u16;
6075

@@ -176,10 +191,15 @@ impl<'a> Socket<'a> {
176191
///
177192
/// If the buffer is filled in a way that does not match the socket's
178193
/// ethertype, the packet will be silently dropped.
179-
pub fn send(&mut self, size: usize) -> Result<&mut [u8], SendError> {
194+
pub fn send(
195+
&mut self,
196+
size: usize,
197+
meta: impl Into<EthMetadata>,
198+
) -> Result<&mut [u8], SendError> {
199+
let meta = meta.into();
180200
let packet_buf = self
181201
.tx_buffer
182-
.enqueue(size, ())
202+
.enqueue(size, meta)
183203
.map_err(|_| SendError::BufferFull)?;
184204

185205
net_trace!(
@@ -194,13 +214,19 @@ impl<'a> Socket<'a> {
194214
/// The closure then returns the size of the data written into the buffer.
195215
///
196216
/// Also see [send](#method.send).
197-
pub fn send_with<F>(&mut self, max_size: usize, f: F) -> Result<usize, SendError>
217+
pub fn send_with<F>(
218+
&mut self,
219+
max_size: usize,
220+
meta: impl Into<EthMetadata>,
221+
f: F,
222+
) -> Result<usize, SendError>
198223
where
199224
F: FnOnce(&mut [u8]) -> usize,
200225
{
226+
let meta = meta.into();
201227
let size = self
202228
.tx_buffer
203-
.enqueue_with_infallible(max_size, (), f)
229+
.enqueue_with_infallible(max_size, meta, f)
204230
.map_err(|_| SendError::BufferFull)?;
205231

206232
net_trace!(
@@ -215,23 +241,27 @@ impl<'a> Socket<'a> {
215241
/// Enqueue a packet to send, and fill it from a slice.
216242
///
217243
/// See also [send](#method.send).
218-
pub fn send_slice(&mut self, data: &[u8]) -> Result<(), SendError> {
219-
self.send(data.len())?.copy_from_slice(data);
244+
pub fn send_slice(
245+
&mut self,
246+
data: &[u8],
247+
meta: impl Into<EthMetadata>,
248+
) -> Result<(), SendError> {
249+
self.send(data.len(), meta)?.copy_from_slice(data);
220250
Ok(())
221251
}
222252

223253
/// Dequeue a packet, and return a pointer to the payload.
224254
///
225255
/// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
226-
pub fn recv(&mut self) -> Result<&[u8], RecvError> {
227-
let ((), packet_buf) = self.rx_buffer.dequeue().map_err(|_| RecvError::Exhausted)?;
256+
pub fn recv(&mut self) -> Result<(&[u8], EthMetadata), RecvError> {
257+
let (meta, packet_buf) = self.rx_buffer.dequeue().map_err(|_| RecvError::Exhausted)?;
228258

229259
net_trace!(
230260
"eth:{}: receive {} buffered octets",
231261
self.ethertype.unwrap_or(0),
232262
packet_buf.len()
233263
);
234-
Ok(packet_buf)
264+
Ok((packet_buf, meta))
235265
}
236266

237267
/// Dequeue a packet, and copy the payload into the given slice.
@@ -240,32 +270,32 @@ impl<'a> Socket<'a> {
240270
/// the packet is dropped and a `RecvError::Truncated` error is returned.
241271
///
242272
/// See also [recv](#method.recv).
243-
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize, RecvError> {
244-
let buffer = self.recv()?;
273+
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, EthMetadata), RecvError> {
274+
let (buffer, meta) = self.recv()?;
245275
if data.len() < buffer.len() {
246276
return Err(RecvError::Truncated);
247277
}
248278

249279
let length = min(data.len(), buffer.len());
250280
data[..length].copy_from_slice(&buffer[..length]);
251-
Ok(length)
281+
Ok((length, meta))
252282
}
253283

254284
/// Peek at a packet in the receive buffer and return a pointer to the
255285
/// payload without removing the packet from the receive buffer.
256286
/// This function otherwise behaves identically to [recv](#method.recv).
257287
///
258288
/// It returns `Err(Error::Exhausted)` if the receive buffer is empty.
259-
pub fn peek(&mut self) -> Result<&[u8], RecvError> {
260-
let ((), packet_buf) = self.rx_buffer.peek().map_err(|_| RecvError::Exhausted)?;
289+
pub fn peek(&mut self) -> Result<(&[u8], &EthMetadata), RecvError> {
290+
let (meta, packet_buf) = self.rx_buffer.peek().map_err(|_| RecvError::Exhausted)?;
261291

262292
net_trace!(
263293
"eth:{}: receive {} buffered octets",
264294
self.ethertype.unwrap_or(0),
265295
packet_buf.len()
266296
);
267297

268-
Ok(packet_buf)
298+
Ok((packet_buf, meta))
269299
}
270300

271301
/// Peek at a packet in the receive buffer, copy the payload into the given slice,
@@ -276,15 +306,15 @@ impl<'a> Socket<'a> {
276306
/// no data is copied into the provided buffer and a `RecvError::Truncated` error is returned.
277307
///
278308
/// See also [peek](#method.peek).
279-
pub fn peek_slice(&mut self, data: &mut [u8]) -> Result<usize, RecvError> {
280-
let buffer = self.peek()?;
309+
pub fn peek_slice(&mut self, data: &mut [u8]) -> Result<(usize, &EthMetadata), RecvError> {
310+
let (buffer, meta) = self.peek()?;
281311
if data.len() < buffer.len() {
282312
return Err(RecvError::Truncated);
283313
}
284314

285315
let length = min(data.len(), buffer.len());
286316
data[..length].copy_from_slice(&buffer[..length]);
287-
Ok(length)
317+
Ok((length, meta))
288318
}
289319

290320
/// Return the amount of octets queued in the transmit buffer.
@@ -305,7 +335,13 @@ impl<'a> Socket<'a> {
305335
}
306336
}
307337

308-
pub(crate) fn process(&mut self, _cx: &mut Context, eth_repr: &EthernetRepr, payload: &[u8]) {
338+
pub(crate) fn process(
339+
&mut self,
340+
_cx: &mut Context,
341+
meta: PacketMeta,
342+
eth_repr: &EthernetRepr,
343+
payload: &[u8],
344+
) {
309345
debug_assert!(self.accepts(eth_repr));
310346

311347
let header_len = eth_repr.buffer_len();
@@ -317,7 +353,9 @@ impl<'a> Socket<'a> {
317353
total_len
318354
);
319355

320-
match self.rx_buffer.enqueue(total_len, ()) {
356+
let metadata = EthMetadata { meta };
357+
358+
match self.rx_buffer.enqueue(total_len, metadata) {
321359
Ok(buf) => {
322360
let mut frame = EthernetFrame::new_checked(buf).expect("internal ethernet error");
323361
eth_repr.emit(&mut frame);
@@ -335,10 +373,10 @@ impl<'a> Socket<'a> {
335373

336374
pub(crate) fn dispatch<F, E>(&mut self, cx: &mut Context, emit: F) -> Result<(), E>
337375
where
338-
F: FnOnce(&mut Context, (EthernetRepr, &[u8])) -> Result<(), E>,
376+
F: FnOnce(&mut Context, PacketMeta, (EthernetRepr, &[u8])) -> Result<(), E>,
339377
{
340378
let ethertype = self.ethertype;
341-
let res = self.tx_buffer.dequeue_with(|&mut (), buffer| {
379+
let res = self.tx_buffer.dequeue_with(|meta, buffer| {
342380
#[allow(clippy::useless_asref)]
343381
let frame = match EthernetFrame::new_checked(buffer.as_ref()) {
344382
Ok(x) => x,
@@ -355,7 +393,7 @@ impl<'a> Socket<'a> {
355393
}
356394
};
357395
net_trace!("eth:{}: sending", ethertype.unwrap_or(0));
358-
emit(cx, (eth_repr, frame.payload()))
396+
emit(cx, meta.meta, (eth_repr, frame.payload()))
359397
});
360398
match res {
361399
Err(Empty) => Ok(()),
@@ -415,12 +453,21 @@ mod test {
415453
let (mut iface, _, _) = setup(Medium::Ethernet);
416454
let cx = iface.context();
417455
let mut socket = socket(buffer(1), buffer(1));
456+
let dummymeta = EthMetadata {
457+
meta: PacketMeta {
458+
#[cfg(feature = "packetmeta-id")]
459+
id: 42,
460+
},
461+
};
418462
assert!(socket.can_send());
419-
assert_eq!(socket.send_slice(&PACKET_BYTES[..]), Ok(()));
420-
assert_eq!(socket.send_slice(b""), Err(SendError::BufferFull));
463+
assert_eq!(socket.send_slice(&PACKET_BYTES[..], dummymeta), Ok(()));
464+
assert_eq!(
465+
socket.send_slice(b"", dummymeta),
466+
Err(SendError::BufferFull)
467+
);
421468
assert!(!socket.can_send());
422469
assert_eq!(
423-
socket.dispatch(cx, |_, (eth_repr, eth_payload)| {
470+
socket.dispatch(cx, |_, _, (eth_repr, eth_payload)| {
424471
assert_eq!(eth_repr.ethertype, EtherType::from(ETHER_TYPE));
425472
assert_eq!(eth_payload, PACKET_PAYLOAD);
426473
Err(())
@@ -429,7 +476,7 @@ mod test {
429476
);
430477
assert!(!socket.can_send());
431478
assert_eq!(
432-
socket.dispatch(cx, |_, (eth_repr, eth_payload)| {
479+
socket.dispatch(cx, |_, _, (eth_repr, eth_payload)| {
433480
assert_eq!(eth_repr.ethertype, EtherType::from(ETHER_TYPE));
434481
assert_eq!(eth_payload, PACKET_PAYLOAD);
435482
Ok::<_, ()>(())
@@ -449,22 +496,29 @@ mod test {
449496
assert_eq!(socket.recv(), Err(RecvError::Exhausted));
450497
assert_eq!(socket.peek(), Err(RecvError::Exhausted));
451498

499+
let pktmeta = PacketMeta {
500+
#[cfg(feature = "packetmeta-id")]
501+
id: 43,
502+
};
503+
504+
let ethmeta = EthMetadata { meta: pktmeta };
505+
452506
let frameinfo = EthernetRepr {
453507
src_addr: EthernetAddress::from_bytes(&PACKET_SENDER),
454508
dst_addr: EthernetAddress::from_bytes(&PACKET_RECEIVER),
455509
ethertype: ETHER_TYPE.into(),
456510
};
457511

458512
assert!(socket.accepts(&frameinfo));
459-
socket.process(cx, &frameinfo, &PACKET_PAYLOAD);
513+
socket.process(cx, pktmeta, &frameinfo, &PACKET_PAYLOAD);
460514
assert!(socket.can_recv());
461515

462516
assert!(socket.accepts(&frameinfo));
463-
socket.process(cx, &frameinfo, &PACKET_PAYLOAD);
517+
socket.process(cx, pktmeta, &frameinfo, &PACKET_PAYLOAD);
464518

465-
assert_eq!(socket.peek(), Ok(&PACKET_BYTES[..]));
466-
assert_eq!(socket.peek(), Ok(&PACKET_BYTES[..]));
467-
assert_eq!(socket.recv(), Ok(&PACKET_BYTES[..]));
519+
assert_eq!(socket.peek(), Ok((&PACKET_BYTES[..], &ethmeta)));
520+
assert_eq!(socket.peek(), Ok((&PACKET_BYTES[..], &ethmeta)));
521+
assert_eq!(socket.recv(), Ok((&PACKET_BYTES[..], ethmeta)));
468522
assert!(!socket.can_recv());
469523
assert_eq!(socket.peek(), Err(RecvError::Exhausted));
470524
}

0 commit comments

Comments
 (0)