Skip to content

Commit fc96be7

Browse files
committed
socket: implement the receive path for ethernet sockets
1 parent 70ef042 commit fc96be7

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

src/iface/interface/ethernet.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ impl InterfaceInner {
1818
return None;
1919
}
2020

21+
#[cfg(feature = "socket-eth")]
22+
let _ = self.eth_socket_filter(
23+
sockets,
24+
&EthernetRepr::parse(&eth_frame).unwrap(),
25+
eth_frame.payload(),
26+
);
27+
2128
match eth_frame.ethertype() {
2229
#[cfg(feature = "proto-ipv4")]
2330
EthernetProtocol::Arp => self.process_arp(self.now, &eth_frame),

src/iface/interface/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,28 @@ impl InterfaceInner {
901901
handled_by_raw_socket
902902
}
903903

904+
#[cfg(feature = "socket-eth")]
905+
fn eth_socket_filter(
906+
&mut self,
907+
sockets: &mut SocketSet,
908+
eth_repr: &EthernetRepr,
909+
eth_payload: &[u8],
910+
) -> bool {
911+
let mut handled_by_eth_socket = false;
912+
913+
// Pass every IP packet to all raw sockets we have registered.
914+
for eth_socket in sockets
915+
.items_mut()
916+
.filter_map(|i| eth::Socket::downcast_mut(&mut i.socket))
917+
{
918+
if eth_socket.accepts(eth_repr) {
919+
eth_socket.process(self, eth_repr, eth_payload);
920+
handled_by_eth_socket = true;
921+
}
922+
}
923+
handled_by_eth_socket
924+
}
925+
904926
/// Checks if an address is broadcast, taking into account ipv4 subnet-local
905927
/// broadcast addresses.
906928
pub(crate) fn is_broadcast(&self, address: &IpAddress) -> bool {

src/socket/eth.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ use crate::socket::WakerRegistration;
99

1010
use crate::storage::Empty;
1111

12+
use crate::wire::EthernetFrame;
13+
use crate::wire::EthernetRepr;
14+
1215
/// Error returned by [`Socket::send`]
1316
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
1417
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@@ -294,6 +297,42 @@ impl<'a> Socket<'a> {
294297
self.rx_buffer.payload_bytes_count()
295298
}
296299

300+
pub(crate) fn accepts(&self, eth_repr: &EthernetRepr) -> bool {
301+
match self.ethertype {
302+
Some(e) if e == eth_repr.ethertype.into() => true,
303+
Some(_) => false,
304+
None => true,
305+
}
306+
}
307+
308+
pub(crate) fn process(&mut self, _cx: &mut Context, eth_repr: &EthernetRepr, payload: &[u8]) {
309+
debug_assert!(self.accepts(eth_repr));
310+
311+
let header_len = eth_repr.buffer_len();
312+
let total_len = header_len + payload.len();
313+
314+
net_trace!(
315+
"eth:{}: receiving {} octets",
316+
self.ethertype.unwrap_or(0),
317+
total_len
318+
);
319+
320+
match self.rx_buffer.enqueue(total_len, ()) {
321+
Ok(buf) => {
322+
let mut frame = EthernetFrame::new_checked(buf).expect("internal ethernet error");
323+
eth_repr.emit(&mut frame);
324+
frame.payload_mut().copy_from_slice(payload);
325+
}
326+
Err(_) => net_trace!(
327+
"eth:{}: buffer full, dropped incoming packet",
328+
self.ethertype.unwrap_or(0)
329+
),
330+
}
331+
332+
#[cfg(feature = "async")]
333+
self.rx_waker.wake();
334+
}
335+
297336
pub(crate) fn poll_at(&self, _cx: &mut Context) -> PollAt {
298337
if self.tx_buffer.is_empty() {
299338
PollAt::Ingress

0 commit comments

Comments
 (0)