Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 27 additions & 14 deletions dpd-client/tests/integration_tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//
// Copyright 2026 Oxide Computer Company

use std::borrow::Cow;
use std::fmt::Write;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::sync::atomic::AtomicBool;
Expand Down Expand Up @@ -168,10 +169,18 @@ impl TestPacket {
println!("port: {}: {:?}", self.port, self.packet);
}
if verbosity & SHOW_HEX != 0 {
let data = self.packet.deparse().unwrap();
dump_hex(&data);
let data = self.deconstruct_pkt();
dump_hex(data.as_ref());
}
}

/// Returns the deparsed bytes of the contained packet if possible.
/// Otherwise, just returns the body bytes.
fn deconstruct_pkt(&self) -> Cow<'_, [u8]> {
self.packet.deparse().map(|pkt| pkt.to_vec().into()).unwrap_or_else(
|_| Cow::Borrowed(self.packet.body.as_deref().unwrap_or(&[])),
)
}
}

impl PartialEq for TestPacket {
Expand Down Expand Up @@ -579,7 +588,7 @@ impl Switch {
if phys_port == NO_PORT {
None
} else if let Some(port) = &self.ports[idx] {
Some((port.port_id.clone(), port.link_id.clone()))
Some((port.port_id.clone(), port.link_id))
} else {
panic!("request for missing port: {phys_port}");
}
Expand Down Expand Up @@ -607,7 +616,7 @@ impl Switch {
let Some(p) = p else {
unreachable!("Filtered to only Some(_)");
};
(p.port_id.clone(), p.link_id.clone())
(p.port_id.clone(), p.link_id)
})
}

Expand All @@ -631,21 +640,21 @@ impl Switch {
tx: mpsc::Sender<TestPacket>,
) {
loop {
match hdl.next_owned() {
let raw = match hdl.next_owned() {
pcap::Ternary::None => break,
pcap::Ternary::Err(e) => {
println!("port {port} got pcap error: {e}");
break;
}
pcap::Ternary::Ok(data) => {
let packet = packet::Packet::parse(&data).unwrap();
let copy =
Packet { hdrs: packet.hdrs.clone(), body: packet.body };
pcap::Ternary::Ok(d) => d,
};

let cap = TestPacket { port, packet: Arc::new(copy) };
tx.send(cap).unwrap();
}
}
let packet = packet::Packet::parse(&raw).unwrap_or_else(|e| {
eprintln!("Packet failed to parse: {e:?}");
Packet { body: Some(raw), ..Default::default() }
});

tx.send(TestPacket { port, packet: Arc::new(packet) }).unwrap();
}
}

Expand Down Expand Up @@ -736,7 +745,11 @@ impl Switch {
let mut found = Vec::new();
for (s, sent) in send.iter().enumerate() {
for (g, got) in captured.iter().enumerate() {
if sent == got {
// Compare raw bytes to support sending degenerate packets
// that might not parse into a normal header.
if sent.port == got.port
&& sent.deconstruct_pkt() == got.deconstruct_pkt()
{
found.push(s);
captured.remove(g);
break;
Expand Down
26 changes: 18 additions & 8 deletions dpd-client/tests/integration_tests/geneve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use std::sync::Arc;

use packet::Endpoint;
use packet::Packet;
use packet::eth;
use packet::geneve;

Expand All @@ -19,7 +20,17 @@ use crate::integration_tests::common::prelude::*;
#[ignore]
async fn test_geneve() -> TestResult {
let switch = &*get_switch().await;
test_geneve_impl(switch, |_| Ok(())).await
}

/// Runs a packet test between VPC peers.
///
/// The `modify_inner` callback can be used to arbitrarily
/// change the packet before encapsulation.
async fn test_geneve_impl(
switch: &Switch,
modify_inner: impl FnOnce(&mut Packet) -> anyhow::Result<()>,
) -> TestResult {
let ingress_port = PhysPort(10);
let uplink_port = PhysPort(14);
let router_ip = "fd00:1122:3344:0101::1";
Expand All @@ -35,13 +46,12 @@ async fn test_geneve() -> TestResult {
let vpc_dst_ip = "10.10.10.2";
let vpc_dst_mac = "04:01:01:01:01:02";
let vpc_dst_port = 4444;
let payload = common::gen_udp_packet(
let mut inner = common::gen_udp_packet(
Endpoint::parse(vpc_src_mac, vpc_src_ip, vpc_src_port).unwrap(),
Endpoint::parse(vpc_dst_mac, vpc_dst_ip, vpc_dst_port).unwrap(),
)
.deparse()
.unwrap()
.to_vec();
);
modify_inner(&mut inner)?;
let payload = inner.deparse().unwrap().to_vec();

let mut to_send = common::gen_geneve_packet(
Endpoint::parse("e0:d5:5e:67:89:ab", "fd00:1122:7788:0101::4", 3333)
Expand All @@ -52,7 +62,7 @@ async fn test_geneve() -> TestResult {
geneve::GENEVE_UDP_PORT,
)
.unwrap(),
eth::ETHER_IPV4,
eth::ETHER_ETHER,
345,
&[],
&payload,
Expand Down Expand Up @@ -105,7 +115,7 @@ async fn test_geneve_multiopt() -> TestResult {
geneve::GENEVE_UDP_PORT,
)
.unwrap(),
eth::ETHER_IPV4,
eth::ETHER_ETHER,
345,
&[
// Does this combination make sense? Maybe not today, but
Expand Down Expand Up @@ -137,7 +147,7 @@ async fn test_geneve_multiopt() -> TestResult {
geneve::GENEVE_UDP_PORT,
)
.unwrap(),
eth::ETHER_IPV4,
eth::ETHER_ETHER,
345,
&[
// Swapped!
Expand Down
Loading
Loading