Skip to content

Commit fb9eae3

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

File tree

3 files changed

+78
-38
lines changed

3 files changed

+78
-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: 71 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,26 @@ impl core::fmt::Display for RecvError {
5051
#[cfg(feature = "std")]
5152
impl std::error::Error for RecvError {}
5253

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

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

5975
pub type Ethertype = u16;
6076

@@ -176,10 +192,11 @@ impl<'a> Socket<'a> {
176192
///
177193
/// If the buffer is filled in a way that does not match the socket's
178194
/// ethertype, the packet will be silently dropped.
179-
pub fn send(&mut self, size: usize) -> Result<&mut [u8], SendError> {
195+
pub fn send(&mut self, size: usize, meta: impl Into<EthMetadata>) -> Result<&mut [u8], SendError> {
196+
let meta = meta.into();
180197
let packet_buf = self
181198
.tx_buffer
182-
.enqueue(size, ())
199+
.enqueue(size, meta)
183200
.map_err(|_| SendError::BufferFull)?;
184201

185202
net_trace!(
@@ -194,13 +211,14 @@ impl<'a> Socket<'a> {
194211
/// The closure then returns the size of the data written into the buffer.
195212
///
196213
/// Also see [send](#method.send).
197-
pub fn send_with<F>(&mut self, max_size: usize, f: F) -> Result<usize, SendError>
214+
pub fn send_with<F>(&mut self, max_size: usize, meta: impl Into<EthMetadata>, f: F) -> Result<usize, SendError>
198215
where
199216
F: FnOnce(&mut [u8]) -> usize,
200217
{
218+
let meta = meta.into();
201219
let size = self
202220
.tx_buffer
203-
.enqueue_with_infallible(max_size, (), f)
221+
.enqueue_with_infallible(max_size, meta, f)
204222
.map_err(|_| SendError::BufferFull)?;
205223

206224
net_trace!(
@@ -215,23 +233,23 @@ impl<'a> Socket<'a> {
215233
/// Enqueue a packet to send, and fill it from a slice.
216234
///
217235
/// 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);
236+
pub fn send_slice(&mut self, data: &[u8], meta: impl Into<EthMetadata>) -> Result<(), SendError> {
237+
self.send(data.len(), meta)?.copy_from_slice(data);
220238
Ok(())
221239
}
222240

223241
/// Dequeue a packet, and return a pointer to the payload.
224242
///
225243
/// 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)?;
244+
pub fn recv(&mut self) -> Result<(&[u8], EthMetadata), RecvError> {
245+
let (meta, packet_buf) = self.rx_buffer.dequeue().map_err(|_| RecvError::Exhausted)?;
228246

229247
net_trace!(
230248
"eth:{}: receive {} buffered octets",
231249
self.ethertype.unwrap_or(0),
232250
packet_buf.len()
233251
);
234-
Ok(packet_buf)
252+
Ok((packet_buf, meta))
235253
}
236254

237255
/// Dequeue a packet, and copy the payload into the given slice.
@@ -240,32 +258,32 @@ impl<'a> Socket<'a> {
240258
/// the packet is dropped and a `RecvError::Truncated` error is returned.
241259
///
242260
/// See also [recv](#method.recv).
243-
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize, RecvError> {
244-
let buffer = self.recv()?;
261+
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<(usize, EthMetadata), RecvError> {
262+
let (buffer, meta) = self.recv()?;
245263
if data.len() < buffer.len() {
246264
return Err(RecvError::Truncated);
247265
}
248266

249267
let length = min(data.len(), buffer.len());
250268
data[..length].copy_from_slice(&buffer[..length]);
251-
Ok(length)
269+
Ok((length, meta))
252270
}
253271

254272
/// Peek at a packet in the receive buffer and return a pointer to the
255273
/// payload without removing the packet from the receive buffer.
256274
/// This function otherwise behaves identically to [recv](#method.recv).
257275
///
258276
/// 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)?;
277+
pub fn peek(&mut self) -> Result<(&[u8], &EthMetadata), RecvError> {
278+
let (meta, packet_buf) = self.rx_buffer.peek().map_err(|_| RecvError::Exhausted)?;
261279

262280
net_trace!(
263281
"eth:{}: receive {} buffered octets",
264282
self.ethertype.unwrap_or(0),
265283
packet_buf.len()
266284
);
267285

268-
Ok(packet_buf)
286+
Ok((packet_buf, meta))
269287
}
270288

271289
/// Peek at a packet in the receive buffer, copy the payload into the given slice,
@@ -276,15 +294,15 @@ impl<'a> Socket<'a> {
276294
/// no data is copied into the provided buffer and a `RecvError::Truncated` error is returned.
277295
///
278296
/// See also [peek](#method.peek).
279-
pub fn peek_slice(&mut self, data: &mut [u8]) -> Result<usize, RecvError> {
280-
let buffer = self.peek()?;
297+
pub fn peek_slice(&mut self, data: &mut [u8]) -> Result<(usize, &EthMetadata), RecvError> {
298+
let (buffer, meta) = self.peek()?;
281299
if data.len() < buffer.len() {
282300
return Err(RecvError::Truncated);
283301
}
284302

285303
let length = min(data.len(), buffer.len());
286304
data[..length].copy_from_slice(&buffer[..length]);
287-
Ok(length)
305+
Ok((length, meta))
288306
}
289307

290308
/// Return the amount of octets queued in the transmit buffer.
@@ -305,7 +323,7 @@ impl<'a> Socket<'a> {
305323
}
306324
}
307325

308-
pub(crate) fn process(&mut self, _cx: &mut Context, eth_repr: &EthernetRepr, payload: &[u8]) {
326+
pub(crate) fn process(&mut self, _cx: &mut Context, meta: PacketMeta, eth_repr: &EthernetRepr, payload: &[u8]) {
309327
debug_assert!(self.accepts(eth_repr));
310328

311329
let header_len = eth_repr.buffer_len();
@@ -317,7 +335,11 @@ impl<'a> Socket<'a> {
317335
total_len
318336
);
319337

320-
match self.rx_buffer.enqueue(total_len, ()) {
338+
let metadata = EthMetadata {
339+
meta,
340+
};
341+
342+
match self.rx_buffer.enqueue(total_len, metadata) {
321343
Ok(buf) => {
322344
let mut frame = EthernetFrame::new_checked(buf).expect("internal ethernet error");
323345
eth_repr.emit(&mut frame);
@@ -335,10 +357,10 @@ impl<'a> Socket<'a> {
335357

336358
pub(crate) fn dispatch<F, E>(&mut self, cx: &mut Context, emit: F) -> Result<(), E>
337359
where
338-
F: FnOnce(&mut Context, (EthernetRepr, &[u8])) -> Result<(), E>,
360+
F: FnOnce(&mut Context, PacketMeta, (EthernetRepr, &[u8])) -> Result<(), E>,
339361
{
340362
let ethertype = self.ethertype;
341-
let res = self.tx_buffer.dequeue_with(|&mut (), buffer| {
363+
let res = self.tx_buffer.dequeue_with(|meta, buffer| {
342364
#[allow(clippy::useless_asref)]
343365
let frame = match EthernetFrame::new_checked(buffer.as_ref()) {
344366
Ok(x) => x,
@@ -355,7 +377,7 @@ impl<'a> Socket<'a> {
355377
}
356378
};
357379
net_trace!("eth:{}: sending", ethertype.unwrap_or(0));
358-
emit(cx, (eth_repr, frame.payload()))
380+
emit(cx, meta.meta, (eth_repr, frame.payload()))
359381
});
360382
match res {
361383
Err(Empty) => Ok(()),
@@ -415,12 +437,18 @@ mod test {
415437
let (mut iface, _, _) = setup(Medium::Ethernet);
416438
let cx = iface.context();
417439
let mut socket = socket(buffer(1), buffer(1));
440+
let dummymeta = EthMetadata {
441+
meta: PacketMeta {
442+
#[cfg(feature = "packetmeta-id")]
443+
id: 42,
444+
}
445+
};
418446
assert!(socket.can_send());
419-
assert_eq!(socket.send_slice(&PACKET_BYTES[..]), Ok(()));
420-
assert_eq!(socket.send_slice(b""), Err(SendError::BufferFull));
447+
assert_eq!(socket.send_slice(&PACKET_BYTES[..], dummymeta), Ok(()));
448+
assert_eq!(socket.send_slice(b"", dummymeta), Err(SendError::BufferFull));
421449
assert!(!socket.can_send());
422450
assert_eq!(
423-
socket.dispatch(cx, |_, (eth_repr, eth_payload)| {
451+
socket.dispatch(cx, |_, _, (eth_repr, eth_payload)| {
424452
assert_eq!(eth_repr.ethertype, EtherType::from(ETHER_TYPE));
425453
assert_eq!(eth_payload, PACKET_PAYLOAD);
426454
Err(())
@@ -429,7 +457,7 @@ mod test {
429457
);
430458
assert!(!socket.can_send());
431459
assert_eq!(
432-
socket.dispatch(cx, |_, (eth_repr, eth_payload)| {
460+
socket.dispatch(cx, |_, _, (eth_repr, eth_payload)| {
433461
assert_eq!(eth_repr.ethertype, EtherType::from(ETHER_TYPE));
434462
assert_eq!(eth_payload, PACKET_PAYLOAD);
435463
Ok::<_, ()>(())
@@ -449,22 +477,31 @@ mod test {
449477
assert_eq!(socket.recv(), Err(RecvError::Exhausted));
450478
assert_eq!(socket.peek(), Err(RecvError::Exhausted));
451479

480+
let pktmeta = PacketMeta {
481+
#[cfg(feature = "packetmeta-id")]
482+
id: 43,
483+
};
484+
485+
let ethmeta = EthMetadata {
486+
meta: pktmeta,
487+
};
488+
452489
let frameinfo = EthernetRepr {
453490
src_addr: EthernetAddress::from_bytes(&PACKET_SENDER),
454491
dst_addr: EthernetAddress::from_bytes(&PACKET_RECEIVER),
455492
ethertype: ETHER_TYPE.into(),
456493
};
457494

458495
assert!(socket.accepts(&frameinfo));
459-
socket.process(cx, &frameinfo, &PACKET_PAYLOAD);
496+
socket.process(cx, pktmeta, &frameinfo, &PACKET_PAYLOAD);
460497
assert!(socket.can_recv());
461498

462499
assert!(socket.accepts(&frameinfo));
463-
socket.process(cx, &frameinfo, &PACKET_PAYLOAD);
500+
socket.process(cx, pktmeta, &frameinfo, &PACKET_PAYLOAD);
464501

465-
assert_eq!(socket.peek(), Ok(&PACKET_BYTES[..]));
466-
assert_eq!(socket.peek(), Ok(&PACKET_BYTES[..]));
467-
assert_eq!(socket.recv(), Ok(&PACKET_BYTES[..]));
502+
assert_eq!(socket.peek(), Ok((&PACKET_BYTES[..], &ethmeta)));
503+
assert_eq!(socket.peek(), Ok((&PACKET_BYTES[..], &ethmeta)));
504+
assert_eq!(socket.recv(), Ok((&PACKET_BYTES[..], ethmeta)));
468505
assert!(!socket.can_recv());
469506
assert_eq!(socket.peek(), Err(RecvError::Exhausted));
470507
}

0 commit comments

Comments
 (0)