Skip to content

Commit 955f5c3

Browse files
committed
socket: implement the receive path for ethernet sockets
1 parent 52d67c9 commit 955f5c3

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
@@ -892,6 +892,28 @@ impl InterfaceInner {
892892
handled_by_raw_socket
893893
}
894894

895+
#[cfg(feature = "socket-eth")]
896+
fn eth_socket_filter(
897+
&mut self,
898+
sockets: &mut SocketSet,
899+
eth_repr: &EthernetRepr,
900+
eth_payload: &[u8],
901+
) -> bool {
902+
let mut handled_by_eth_socket = false;
903+
904+
// Pass every IP packet to all raw sockets we have registered.
905+
for eth_socket in sockets
906+
.items_mut()
907+
.filter_map(|i| eth::Socket::downcast_mut(&mut i.socket))
908+
{
909+
if eth_socket.accepts(eth_repr) {
910+
eth_socket.process(self, eth_repr, eth_payload);
911+
handled_by_eth_socket = true;
912+
}
913+
}
914+
handled_by_eth_socket
915+
}
916+
895917
/// Checks if an address is broadcast, taking into account ipv4 subnet-local
896918
/// broadcast addresses.
897919
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)