Skip to content

Commit 1b41dfe

Browse files
committed
integration-test: SNP: improve clarity
Interestingly, the interrupt status never shows that we can receive a packet. Buggy OVMF firmware?
1 parent c35afad commit 1b41dfe

File tree

1 file changed

+61
-31
lines changed
  • uefi-test-runner/src/proto/network

1 file changed

+61
-31
lines changed

uefi-test-runner/src/proto/network/snp.rs

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
11
// SPDX-License-Identifier: MIT OR Apache-2.0
22

3+
use core::ops::DerefMut;
34
use core::time::Duration;
45

56
use uefi::proto::network::snp::{InterruptStatus, NetworkState, ReceiveFlags, SimpleNetwork};
67
use uefi::proto::network::MacAddress;
78
use uefi::{boot, Status};
89

10+
const ETHERNET_PROTOCOL_IPV4: u16 = 0x0800;
11+
12+
/// Receives the next IPv4 packet and prints corresponding metadata.
13+
fn receive(simple_network: &mut SimpleNetwork, buffer: &mut [u8]) -> uefi::Result<usize> {
14+
let mut recv_src_mac = MacAddress([0; 32]);
15+
let mut recv_dst_mac = MacAddress([0; 32]);
16+
let mut recv_ethernet_protocol = 0;
17+
18+
let res = simple_network.receive(
19+
buffer,
20+
None,
21+
Some(&mut recv_src_mac),
22+
Some(&mut recv_dst_mac),
23+
Some(&mut recv_ethernet_protocol),
24+
);
25+
26+
res.inspect(|_| {
27+
debug!("Received:");
28+
debug!(" src_mac = {:x?}", recv_src_mac);
29+
debug!(" dst_mac = {:x?}", recv_dst_mac);
30+
debug!(" ethernet_proto=0x{:x?}", recv_ethernet_protocol);
31+
32+
// Ensure that we do not accidentally get an ARP packet, which we
33+
// do not expect in this test.
34+
assert_eq!(recv_ethernet_protocol, ETHERNET_PROTOCOL_IPV4);
35+
})
36+
}
37+
38+
/// This test sends a simple UDP/IP packet to the `EchoService` (created by
39+
/// `cargo xtask run`) and receives its message.
940
pub fn test() {
1041
info!("Testing the simple network protocol");
1142

1243
let handles = boot::find_handles::<SimpleNetwork>().unwrap_or_default();
1344

1445
for handle in handles {
15-
let Ok(simple_network) = boot::open_protocol_exclusive::<SimpleNetwork>(handle) else {
46+
let Ok(mut simple_network) = boot::open_protocol_exclusive::<SimpleNetwork>(handle) else {
1647
continue;
1748
};
1849

@@ -55,6 +86,12 @@ pub fn test() {
5586
)
5687
.expect("Failed to set receive filters");
5788

89+
// EthernetFrame(IPv4Packet(UDPPacket(Payload))).
90+
// The ethernet frame header will be filled by `transmit()`.
91+
// The UDP packet contains the byte sequence `4, 4, 3, 2, 1`.
92+
//
93+
// The packet is sent to the `EchoService` created by
94+
// `cargo xtask run`. It runs on UDP port 21572.
5895
let payload = b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\
5996
\x45\x00\
6097
\x00\x21\
@@ -71,7 +108,6 @@ pub fn test() {
71108
\xa9\xe4\
72109
\x04\x01\x02\x03\x04";
73110

74-
let dest_addr = MacAddress([0xffu8; 32]);
75111
assert!(!simple_network
76112
.get_interrupt_status()
77113
.unwrap()
@@ -83,8 +119,8 @@ pub fn test() {
83119
simple_network.mode().media_header_size as usize,
84120
payload,
85121
None,
86-
Some(dest_addr),
87-
Some(0x0800),
122+
Some(simple_network.mode().broadcast_address),
123+
Some(ETHERNET_PROTOCOL_IPV4),
88124
)
89125
.expect("Failed to transmit frame");
90126

@@ -99,37 +135,31 @@ pub fn test() {
99135
let mut buffer = [0u8; 1500];
100136

101137
info!("Waiting for the reception");
102-
if simple_network.receive(&mut buffer, None, None, None, None)
103-
== Err(Status::NOT_READY.into())
104-
{
105-
boot::stall(Duration::from_secs(1));
106-
107-
simple_network
108-
.receive(&mut buffer, None, None, None, None)
109-
.unwrap();
110-
}
138+
let n = receive(simple_network.deref_mut(), &mut buffer).unwrap();
139+
debug!("Reply has {n} bytes");
111140

112-
assert_eq!(buffer[42..47], [4, 4, 3, 2, 1]);
141+
// Check payload in UDP packet that was reversed by our EchoService.
142+
assert_eq!(buffer[42..47], [4, 4, 3, 2, 1]);
113143

114-
// Get stats
115-
let res = simple_network.collect_statistics();
116-
match res {
117-
Ok(stats) => {
118-
info!("Stats: {:?}", stats);
144+
// Get stats
145+
let res = simple_network.collect_statistics();
146+
match res {
147+
Ok(stats) => {
148+
info!("Stats: {:?}", stats);
119149

120-
// One frame should have been transmitted and one received
121-
assert_eq!(stats.tx_total_frames().unwrap(), 1);
122-
assert_eq!(stats.rx_total_frames().unwrap(), 1);
123-
}
124-
Err(e) => {
125-
if e == Status::UNSUPPORTED.into() {
126-
info!("Stats: unsupported.");
127-
} else {
128-
panic!("{e}");
150+
// One frame should have been transmitted and one received
151+
assert_eq!(stats.tx_total_frames().unwrap(), 1);
152+
assert_eq!(stats.rx_total_frames().unwrap(), 1);
153+
}
154+
Err(e) => {
155+
if e == Status::UNSUPPORTED.into() {
156+
info!("Stats: unsupported.");
157+
} else {
158+
panic!("{e}");
159+
}
129160
}
130161
}
131-
}
132162

133-
simple_network.shutdown().unwrap();
163+
simple_network.shutdown().unwrap();
164+
}
134165
}
135-
}

0 commit comments

Comments
 (0)