Skip to content

Commit a4cee91

Browse files
authored
Merge pull request #628 from datdenkikniet/unique_packet_id
Device-level packet metadata identifiers
2 parents 6139bc8 + 2b0ad1a commit a4cee91

File tree

14 files changed

+397
-126
lines changed

14 files changed

+397
-126
lines changed

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ defmt = [ "dep:defmt", "heapless/defmt", "heapless/defmt-impl" ]
6363
"socket-dns" = ["socket", "proto-dns"]
6464
"socket-mdns" = ["socket-dns"]
6565

66+
"packetmeta-id" = []
67+
6668
"async" = []
6769

6870
default = [
@@ -72,7 +74,7 @@ default = [
7274
"proto-ipv4", "proto-igmp", "proto-dhcpv4", "proto-ipv6", "proto-dns",
7375
"proto-ipv4-fragmentation", "proto-sixlowpan-fragmentation",
7476
"socket-raw", "socket-icmp", "socket-udp", "socket-tcp", "socket-dhcpv4", "socket-dns", "socket-mdns",
75-
"async"
77+
"packetmeta-id", "async"
7678
]
7779

7880
# Private features

src/iface/interface/ethernet.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ impl InterfaceInner {
1414
pub(super) fn process_ethernet<'frame, T: AsRef<[u8]>>(
1515
&mut self,
1616
sockets: &mut SocketSet,
17+
meta: crate::phy::PacketMeta,
1718
frame: &'frame T,
1819
fragments: &'frame mut FragmentsBuffer,
1920
) -> Option<EthernetPacket<'frame>> {
@@ -34,13 +35,13 @@ impl InterfaceInner {
3435
EthernetProtocol::Ipv4 => {
3536
let ipv4_packet = check!(Ipv4Packet::new_checked(eth_frame.payload()));
3637

37-
self.process_ipv4(sockets, &ipv4_packet, fragments)
38+
self.process_ipv4(sockets, meta, &ipv4_packet, fragments)
3839
.map(EthernetPacket::Ip)
3940
}
4041
#[cfg(feature = "proto-ipv6")]
4142
EthernetProtocol::Ipv6 => {
4243
let ipv6_packet = check!(Ipv6Packet::new_checked(eth_frame.payload()));
43-
self.process_ipv6(sockets, &ipv6_packet)
44+
self.process_ipv6(sockets, meta, &ipv6_packet)
4445
.map(EthernetPacket::Ip)
4546
}
4647
// Drop all other traffic.

src/iface/interface/ieee802154.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ impl InterfaceInner {
77
pub(super) fn process_ieee802154<'output, 'payload: 'output, T: AsRef<[u8]> + ?Sized>(
88
&mut self,
99
sockets: &mut SocketSet,
10+
meta: PacketMeta,
1011
sixlowpan_payload: &'payload T,
1112
_fragments: &'output mut FragmentsBuffer,
1213
) -> Option<IpPacket<'output>> {
@@ -32,7 +33,9 @@ impl InterfaceInner {
3233
}
3334

3435
match ieee802154_frame.payload() {
35-
Some(payload) => self.process_sixlowpan(sockets, &ieee802154_repr, payload, _fragments),
36+
Some(payload) => {
37+
self.process_sixlowpan(sockets, meta, &ieee802154_repr, payload, _fragments)
38+
}
3639
None => None,
3740
}
3841
}

src/iface/interface/ipv4.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ impl InterfaceInner {
1414
pub(super) fn process_ipv4<'a, T: AsRef<[u8]> + ?Sized>(
1515
&mut self,
1616
sockets: &mut SocketSet,
17+
meta: PacketMeta,
1718
ipv4_packet: &Ipv4Packet<&'a T>,
1819
frag: &'a mut FragmentsBuffer,
1920
) -> Option<IpPacket<'a>> {
@@ -138,6 +139,7 @@ impl InterfaceInner {
138139

139140
self.process_udp(
140141
sockets,
142+
meta,
141143
ip_repr,
142144
udp_repr,
143145
handled_by_raw_socket,

src/iface/interface/ipv6.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ use super::SocketSet;
88
use crate::socket::icmp;
99
use crate::socket::AnySocket;
1010

11+
use crate::phy::PacketMeta;
1112
use crate::wire::*;
1213

1314
impl InterfaceInner {
1415
#[cfg(feature = "proto-ipv6")]
1516
pub(super) fn process_ipv6<'frame, T: AsRef<[u8]> + ?Sized>(
1617
&mut self,
1718
sockets: &mut SocketSet,
19+
meta: PacketMeta,
1820
ipv6_packet: &Ipv6Packet<&'frame T>,
1921
) -> Option<IpPacket<'frame>> {
2022
let ipv6_repr = check!(Ipv6Repr::parse(ipv6_packet));
@@ -34,6 +36,7 @@ impl InterfaceInner {
3436

3537
self.process_nxt_hdr(
3638
sockets,
39+
meta,
3740
ipv6_repr,
3841
ipv6_repr.next_header,
3942
handled_by_raw_socket,
@@ -47,6 +50,7 @@ impl InterfaceInner {
4750
pub(super) fn process_nxt_hdr<'frame>(
4851
&mut self,
4952
sockets: &mut SocketSet,
53+
meta: PacketMeta,
5054
ipv6_repr: Ipv6Repr,
5155
nxt_hdr: IpProtocol,
5256
handled_by_raw_socket: bool,
@@ -67,6 +71,7 @@ impl InterfaceInner {
6771

6872
self.process_udp(
6973
sockets,
74+
meta,
7075
ipv6_repr.into(),
7176
udp_repr,
7277
handled_by_raw_socket,
@@ -79,7 +84,7 @@ impl InterfaceInner {
7984
IpProtocol::Tcp => self.process_tcp(sockets, ipv6_repr.into(), ip_payload),
8085

8186
IpProtocol::HopByHop => {
82-
self.process_hopbyhop(sockets, ipv6_repr, handled_by_raw_socket, ip_payload)
87+
self.process_hopbyhop(sockets, meta, ipv6_repr, handled_by_raw_socket, ip_payload)
8388
}
8489

8590
#[cfg(feature = "socket-raw")]
@@ -240,6 +245,7 @@ impl InterfaceInner {
240245
pub(super) fn process_hopbyhop<'frame>(
241246
&mut self,
242247
sockets: &mut SocketSet,
248+
meta: PacketMeta,
243249
ipv6_repr: Ipv6Repr,
244250
handled_by_raw_socket: bool,
245251
ip_payload: &'frame [u8],
@@ -272,6 +278,7 @@ impl InterfaceInner {
272278
}
273279
self.process_nxt_hdr(
274280
sockets,
281+
meta,
275282
ipv6_repr,
276283
hbh_repr.next_header,
277284
handled_by_raw_socket,

src/iface/interface/mod.rs

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use crate::config::{
3737
IFACE_MAX_SIXLOWPAN_ADDRESS_CONTEXT_COUNT,
3838
};
3939
use crate::iface::Routes;
40+
use crate::phy::PacketMeta;
4041
use crate::phy::{ChecksumCapabilities, Device, DeviceCapabilities, Medium, RxToken, TxToken};
4142
use crate::rand::Rand;
4243
#[cfg(feature = "socket-dns")]
@@ -320,7 +321,7 @@ pub(crate) enum IpPacket<'a> {
320321
#[cfg(feature = "socket-raw")]
321322
Raw((IpRepr, &'a [u8])),
322323
#[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
323-
Udp((IpRepr, UdpRepr, &'a [u8])),
324+
Udp((IpRepr, UdpRepr, &'a [u8], PacketMeta)),
324325
#[cfg(feature = "socket-tcp")]
325326
Tcp((IpRepr, TcpRepr<'a>)),
326327
#[cfg(feature = "socket-dhcpv4")]
@@ -339,14 +340,22 @@ impl<'a> IpPacket<'a> {
339340
#[cfg(feature = "socket-raw")]
340341
IpPacket::Raw((ip_repr, _)) => ip_repr.clone(),
341342
#[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
342-
IpPacket::Udp((ip_repr, _, _)) => ip_repr.clone(),
343+
IpPacket::Udp((ip_repr, _, _, _)) => ip_repr.clone(),
343344
#[cfg(feature = "socket-tcp")]
344345
IpPacket::Tcp((ip_repr, _)) => ip_repr.clone(),
345346
#[cfg(feature = "socket-dhcpv4")]
346347
IpPacket::Dhcpv4((ipv4_repr, _, _)) => IpRepr::Ipv4(*ipv4_repr),
347348
}
348349
}
349350

351+
pub(crate) fn meta(&self) -> PacketMeta {
352+
match self {
353+
#[cfg(feature = "socket-udp")]
354+
IpPacket::Udp((_, _, _, meta)) => *meta,
355+
_ => PacketMeta::default(),
356+
}
357+
}
358+
350359
pub(crate) fn emit_payload(
351360
&self,
352361
_ip_repr: &IpRepr,
@@ -372,14 +381,16 @@ impl<'a> IpPacket<'a> {
372381
#[cfg(feature = "socket-raw")]
373382
IpPacket::Raw((_, raw_packet)) => payload.copy_from_slice(raw_packet),
374383
#[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
375-
IpPacket::Udp((_, udp_repr, inner_payload)) => udp_repr.emit(
376-
&mut UdpPacket::new_unchecked(payload),
377-
&_ip_repr.src_addr(),
378-
&_ip_repr.dst_addr(),
379-
inner_payload.len(),
380-
|buf| buf.copy_from_slice(inner_payload),
381-
&caps.checksum,
382-
),
384+
IpPacket::Udp((_, udp_repr, inner_payload, _)) => {
385+
udp_repr.emit(
386+
&mut UdpPacket::new_unchecked(payload),
387+
&_ip_repr.src_addr(),
388+
&_ip_repr.dst_addr(),
389+
inner_payload.len(),
390+
|buf| buf.copy_from_slice(inner_payload),
391+
&caps.checksum,
392+
);
393+
}
383394
#[cfg(feature = "socket-tcp")]
384395
IpPacket::Tcp((_, mut tcp_repr)) => {
385396
// This is a terrible hack to make TCP performance more acceptable on systems
@@ -416,7 +427,7 @@ impl<'a> IpPacket<'a> {
416427
|buf| dhcp_repr.emit(&mut DhcpPacket::new_unchecked(buf)).unwrap(),
417428
&caps.checksum,
418429
),
419-
}
430+
};
420431
}
421432
}
422433

@@ -803,14 +814,17 @@ impl Interface {
803814
let mut processed_any = false;
804815

805816
while let Some((rx_token, tx_token)) = device.receive(self.inner.now) {
817+
let rx_meta = rx_token.meta();
806818
rx_token.consume(|frame| {
807819
match self.inner.caps.medium {
808820
#[cfg(feature = "medium-ethernet")]
809821
Medium::Ethernet => {
810-
if let Some(packet) =
811-
self.inner
812-
.process_ethernet(sockets, &frame, &mut self.fragments)
813-
{
822+
if let Some(packet) = self.inner.process_ethernet(
823+
sockets,
824+
rx_meta,
825+
&frame,
826+
&mut self.fragments,
827+
) {
814828
if let Err(err) =
815829
self.inner.dispatch(tx_token, packet, &mut self.fragmenter)
816830
{
@@ -821,7 +835,8 @@ impl Interface {
821835
#[cfg(feature = "medium-ip")]
822836
Medium::Ip => {
823837
if let Some(packet) =
824-
self.inner.process_ip(sockets, &frame, &mut self.fragments)
838+
self.inner
839+
.process_ip(sockets, rx_meta, &frame, &mut self.fragments)
825840
{
826841
if let Err(err) =
827842
self.inner
@@ -833,10 +848,12 @@ impl Interface {
833848
}
834849
#[cfg(feature = "medium-ieee802154")]
835850
Medium::Ieee802154 => {
836-
if let Some(packet) =
837-
self.inner
838-
.process_ieee802154(sockets, &frame, &mut self.fragments)
839-
{
851+
if let Some(packet) = self.inner.process_ieee802154(
852+
sockets,
853+
rx_meta,
854+
&frame,
855+
&mut self.fragments,
856+
) {
840857
if let Err(err) =
841858
self.inner
842859
.dispatch_ip(tx_token, packet, &mut self.fragmenter)
@@ -923,9 +940,14 @@ impl Interface {
923940
respond(inner, IpPacket::Dhcpv4(response))
924941
}),
925942
#[cfg(feature = "socket-dns")]
926-
Socket::Dns(socket) => socket.dispatch(&mut self.inner, |inner, response| {
927-
respond(inner, IpPacket::Udp(response))
928-
}),
943+
Socket::Dns(socket) => {
944+
socket.dispatch(&mut self.inner, |inner, (ip, udp, payload)| {
945+
respond(
946+
inner,
947+
IpPacket::Udp((ip, udp, payload, PacketMeta::default())),
948+
)
949+
})
950+
}
929951
};
930952

931953
match result {
@@ -1263,6 +1285,7 @@ impl InterfaceInner {
12631285
fn process_ip<'frame, T: AsRef<[u8]>>(
12641286
&mut self,
12651287
sockets: &mut SocketSet,
1288+
meta: PacketMeta,
12661289
ip_payload: &'frame T,
12671290
frag: &'frame mut FragmentsBuffer,
12681291
) -> Option<IpPacket<'frame>> {
@@ -1271,12 +1294,12 @@ impl InterfaceInner {
12711294
Ok(IpVersion::Ipv4) => {
12721295
let ipv4_packet = check!(Ipv4Packet::new_checked(ip_payload));
12731296

1274-
self.process_ipv4(sockets, &ipv4_packet, frag)
1297+
self.process_ipv4(sockets, meta, &ipv4_packet, frag)
12751298
}
12761299
#[cfg(feature = "proto-ipv6")]
12771300
Ok(IpVersion::Ipv6) => {
12781301
let ipv6_packet = check!(Ipv6Packet::new_checked(ip_payload));
1279-
self.process_ipv6(sockets, &ipv6_packet)
1302+
self.process_ipv6(sockets, meta, &ipv6_packet)
12801303
}
12811304
// Drop all other traffic.
12821305
_ => None,
@@ -1341,9 +1364,11 @@ impl InterfaceInner {
13411364
}
13421365

13431366
#[cfg(any(feature = "socket-udp", feature = "socket-dns"))]
1367+
#[allow(clippy::too_many_arguments)]
13441368
fn process_udp<'frame>(
13451369
&mut self,
13461370
sockets: &mut SocketSet,
1371+
meta: PacketMeta,
13471372
ip_repr: IpRepr,
13481373
udp_repr: UdpRepr,
13491374
handled_by_raw_socket: bool,
@@ -1356,7 +1381,7 @@ impl InterfaceInner {
13561381
.filter_map(|i| udp::Socket::downcast_mut(&mut i.socket))
13571382
{
13581383
if udp_socket.accepts(self, &ip_repr, &udp_repr) {
1359-
udp_socket.process(self, &ip_repr, &udp_repr, udp_payload);
1384+
udp_socket.process(self, meta, &ip_repr, &udp_repr, udp_payload);
13601385
return None;
13611386
}
13621387
}
@@ -1643,7 +1668,9 @@ impl InterfaceInner {
16431668

16441669
fn dispatch_ip<Tx: TxToken>(
16451670
&mut self,
1646-
tx_token: Tx,
1671+
// NOTE(unused_mut): tx_token isn't always mutated, depending on
1672+
// the feature set that is used.
1673+
#[allow(unused_mut)] mut tx_token: Tx,
16471674
packet: IpPacket,
16481675
frag: &mut Fragmenter,
16491676
) -> Result<(), DispatchError> {
@@ -1684,7 +1711,7 @@ impl InterfaceInner {
16841711

16851712
// If the medium is Ethernet, then we need to retrieve the destination hardware address.
16861713
#[cfg(feature = "medium-ethernet")]
1687-
let (dst_hardware_addr, tx_token) = match self.caps.medium {
1714+
let (dst_hardware_addr, mut tx_token) = match self.caps.medium {
16881715
Medium::Ethernet => {
16891716
match self.lookup_hardware_addr(
16901717
tx_token,
@@ -1723,7 +1750,7 @@ impl InterfaceInner {
17231750
repr.emit(&mut tx_buffer, &self.caps.checksum);
17241751

17251752
let payload = &mut tx_buffer[repr.header_len()..];
1726-
packet.emit_payload(repr, payload, &caps);
1753+
packet.emit_payload(repr, payload, &caps)
17271754
};
17281755

17291756
let total_ip_len = ip_repr.buffer_len();
@@ -1771,6 +1798,7 @@ impl InterfaceInner {
17711798

17721799
// Emit the IP header to the buffer.
17731800
emit_ip(&ip_repr, &mut frag.buffer);
1801+
17741802
let mut ipv4_packet = Ipv4Packet::new_unchecked(&mut frag.buffer[..]);
17751803
frag.ipv4.ident = ipv4_id;
17761804
ipv4_packet.set_ident(ipv4_id);
@@ -1807,6 +1835,8 @@ impl InterfaceInner {
18071835
Ok(())
18081836
}
18091837
} else {
1838+
tx_token.set_meta(packet.meta());
1839+
18101840
// No fragmentation is required.
18111841
tx_token.consume(total_len, |mut tx_buffer| {
18121842
#[cfg(feature = "medium-ethernet")]

0 commit comments

Comments
 (0)