From 11eabaf97de28c5a7130d4a7f74947e4be75d65a Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Tue, 21 Oct 2025 15:37:48 +0100 Subject: [PATCH] tests: Add second network interface definition to guest Add a second L1 network interface definition to the guest Cloud Init configuration, including an additional host IP. Do this by splitting the network range into two /25s. For clarity the network struct members have also been renamed. Signed-off-by: Rob Bradford --- performance-metrics/src/performance_tests.rs | 8 +- test_data/cloud-init/ubuntu/ci/network-config | 14 ++- test_infra/src/lib.rs | 60 ++++++----- tests/integration.rs | 100 +++++++++--------- 4 files changed, 99 insertions(+), 83 deletions(-) diff --git a/performance-metrics/src/performance_tests.rs b/performance-metrics/src/performance_tests.rs index e29dca174..f52156c70 100644 --- a/performance-metrics/src/performance_tests.rs +++ b/performance-metrics/src/performance_tests.rs @@ -119,8 +119,8 @@ pub fn performance_net_throughput(control: &PerformanceTestControl) -> f64 { let num_queues = control.num_queues.unwrap(); let queue_size = control.queue_size.unwrap(); let net_params = format!( - "tap=,mac={},ip={},mask=255.255.255.0,num_queues={},queue_size={}", - guest.network.guest_mac, guest.network.host_ip, num_queues, queue_size, + "tap=,mac={},ip={},mask=255.255.255.128,num_queues={},queue_size={}", + guest.network.guest_mac0, guest.network.host_ip0, num_queues, queue_size, ); let mut child = GuestCommand::new(&guest) @@ -160,8 +160,8 @@ pub fn performance_net_latency(control: &PerformanceTestControl) -> f64 { let num_queues = control.num_queues.unwrap(); let queue_size = control.queue_size.unwrap(); let net_params = format!( - "tap=,mac={},ip={},mask=255.255.255.0,num_queues={},queue_size={}", - guest.network.guest_mac, guest.network.host_ip, num_queues, queue_size, + "tap=,mac={},ip={},mask=255.255.255.128,num_queues={},queue_size={}", + guest.network.guest_mac0, guest.network.host_ip0, num_queues, queue_size, ); let mut child = GuestCommand::new(&guest) diff --git a/test_data/cloud-init/ubuntu/ci/network-config b/test_data/cloud-init/ubuntu/ci/network-config index ce5ed03f5..4ec7e0330 100644 --- a/test_data/cloud-init/ubuntu/ci/network-config +++ b/test_data/cloud-init/ubuntu/ci/network-config @@ -4,23 +4,29 @@ ethernets: match: macaddress: 12:34:56:78:90:ab addresses: - - 192.168.2.2/24 + - 192.168.2.2/25 gateway4: 192.168.2.1 id1: match: macaddress: de:ad:be:ef:12:34 addresses: - - 192.168.2.3/24 + - 192.168.2.3/25 gateway4: 192.168.2.1 id2: match: macaddress: de:ad:be:ef:34:56 addresses: - - 192.168.2.4/24 + - 192.168.2.4/25 gateway4: 192.168.2.1 id3: match: macaddress: de:ad:be:ef:56:78 addresses: - - 192.168.2.5/24 + - 192.168.2.5/25 gateway4: 192.168.2.1 + id4: + match: + macaddress: de:ad:be:ef:78:90 + addresses: + - 192.168.2.130/25 + gateway4: 192.168.2.129 diff --git a/test_infra/src/lib.rs b/test_infra/src/lib.rs index 8b260a0a6..24a818c19 100644 --- a/test_infra/src/lib.rs +++ b/test_infra/src/lib.rs @@ -57,12 +57,15 @@ pub enum Error { } pub struct GuestNetworkConfig { - pub guest_ip: String, + pub guest_ip0: String, + pub host_ip0: String, + pub guest_mac0: String, + pub guest_ip1: String, + pub host_ip1: String, + pub guest_mac1: String, pub l2_guest_ip1: String, pub l2_guest_ip2: String, pub l2_guest_ip3: String, - pub host_ip: String, - pub guest_mac: String, pub l2_guest_mac1: String, pub l2_guest_mac2: String, pub l2_guest_mac3: String, @@ -92,7 +95,7 @@ impl GuestNetworkConfig { let start = std::time::Instant::now(); // The 'port' is unique per 'GUEST' and listening to wild-card ip avoids retrying on 'TcpListener::bind()' let listen_addr = format!("0.0.0.0:{}", self.tcp_listener_port); - let expected_guest_addr = self.guest_ip.as_str(); + let expected_guest_addr = self.guest_ip0.as_str(); let mut s = String::new(); let timeout = match custom_timeout { Some(t) => t, @@ -277,7 +280,7 @@ impl DiskConfig for UbuntuDiskConfig { "@DEFAULT_TCP_LISTENER_MESSAGE", DEFAULT_TCP_LISTENER_MESSAGE, ); - user_data_string = user_data_string.replace("@HOST_IP", &network.host_ip); + user_data_string = user_data_string.replace("@HOST_IP", &network.host_ip0); user_data_string = user_data_string.replace("@TCP_LISTENER_PORT", &network.tcp_listener_port.to_string()); @@ -293,13 +296,17 @@ impl DiskConfig for UbuntuDiskConfig { .read_to_string(&mut network_config_string) .expect("Expected reading network-config file to succeed"); - network_config_string = network_config_string.replace("192.168.2.1", &network.host_ip); - network_config_string = network_config_string.replace("192.168.2.2", &network.guest_ip); + network_config_string = network_config_string.replace("192.168.2.1", &network.host_ip0); + network_config_string = network_config_string.replace("192.168.2.2", &network.guest_ip0); + network_config_string = network_config_string.replace("192.168.2.129", &network.host_ip1); + network_config_string = network_config_string.replace("192.168.2.130", &network.guest_ip1); network_config_string = network_config_string.replace("192.168.2.3", &network.l2_guest_ip1); network_config_string = network_config_string.replace("192.168.2.4", &network.l2_guest_ip2); network_config_string = network_config_string.replace("192.168.2.5", &network.l2_guest_ip3); network_config_string = - network_config_string.replace("12:34:56:78:90:ab", &network.guest_mac); + network_config_string.replace("12:34:56:78:90:ab", &network.guest_mac0); + network_config_string = + network_config_string.replace("de:ad:be:ef:78:90", &network.guest_mac1); network_config_string = network_config_string.replace("de:ad:be:ef:12:34", &network.l2_guest_mac1); network_config_string = @@ -858,12 +865,15 @@ impl Guest { let tmp_dir = TempDir::new_with_prefix("/tmp/ch").unwrap(); let network = GuestNetworkConfig { - guest_ip: format!("{class}.{id}.2"), + guest_ip0: format!("{class}.{id}.2"), + host_ip0: format!("{class}.{id}.1"), + guest_mac0: format!("12:34:56:78:90:{id:02x}"), + guest_ip1: format!("{class}.{id}.130"), + host_ip1: format!("{class}.{id}.129"), + guest_mac1: format!("de:ad:be:ef:78:{id:02x}"), l2_guest_ip1: format!("{class}.{id}.3"), l2_guest_ip2: format!("{class}.{id}.4"), l2_guest_ip3: format!("{class}.{id}.5"), - host_ip: format!("{class}.{id}.1"), - guest_mac: format!("12:34:56:78:90:{id:02x}"), l2_guest_mac1: format!("de:ad:be:ef:12:{id:02x}"), l2_guest_mac2: format!("de:ad:be:ef:34:{id:02x}"), l2_guest_mac3: format!("de:ad:be:ef:56:{id:02x}"), @@ -889,29 +899,29 @@ impl Guest { pub fn default_net_string(&self) -> String { format!( - "tap=,mac={},ip={},mask=255.255.255.0", - self.network.guest_mac, self.network.host_ip + "tap=,mac={},ip={},mask=255.255.255.128", + self.network.guest_mac0, self.network.host_ip0 ) } pub fn default_net_string_w_iommu(&self) -> String { format!( - "tap=,mac={},ip={},mask=255.255.255.0,iommu=on", - self.network.guest_mac, self.network.host_ip + "tap=,mac={},ip={},mask=255.255.255.128,iommu=on", + self.network.guest_mac0, self.network.host_ip0 ) } pub fn default_net_string_w_mtu(&self, mtu: u16) -> String { format!( - "tap=,mac={},ip={},mask=255.255.255.0,mtu={}", - self.network.guest_mac, self.network.host_ip, mtu + "tap=,mac={},ip={},mask=255.255.255.128,mtu={}", + self.network.guest_mac0, self.network.host_ip0, mtu ) } pub fn ssh_command(&self, command: &str) -> Result { ssh_command_ip( command, - &self.network.guest_ip, + &self.network.guest_ip0, DEFAULT_SSH_RETRIES, DEFAULT_SSH_TIMEOUT, ) @@ -921,7 +931,7 @@ impl Guest { pub fn ssh_command_l1(&self, command: &str) -> Result { ssh_command_ip( command, - &self.network.guest_ip, + &self.network.guest_ip0, DEFAULT_SSH_RETRIES, DEFAULT_SSH_TIMEOUT, ) @@ -963,8 +973,8 @@ impl Guest { cpu_count, kernel_path, kernel_cmd, - self.network.host_ip, - self.network.guest_mac, + self.network.host_ip0, + self.network.guest_mac0, self.disk_config.disk(DiskType::OperatingSystem).unwrap().as_str(), self.disk_config.disk(DiskType::CloudInit).unwrap().as_str(), } @@ -1109,7 +1119,7 @@ impl Guest { pub fn check_vsock(&self, socket: &str) { // Listen from guest on vsock CID=3 PORT=16 // SOCKET-LISTEN::: - let guest_ip = self.network.guest_ip.clone(); + let guest_ip = self.network.guest_ip0.clone(); let listen_socat = thread::spawn(move || { ssh_command_ip("sudo socat - SOCKET-LISTEN:40:0:x00x00x10x00x00x00x03x00x00x00x00x00x00x00 > vsock_log", &guest_ip, DEFAULT_SSH_RETRIES, DEFAULT_SSH_TIMEOUT).unwrap(); }); @@ -1612,7 +1622,7 @@ pub fn measure_virtio_net_throughput( cmd.args([ "-J", // Output in JSON format "-c", - &guest.network.guest_ip, + &guest.network.guest_ip0, "-p", &format!("{}", default_port + n), "-t", @@ -1710,7 +1720,7 @@ pub fn measure_virtio_net_latency(guest: &Guest, test_timeout: u32) -> Result Result std::process::Child { - let listen_address = format!("--listen-address={}", self.guest.network.host_ip); + let listen_address = format!("--listen-address={}", self.guest.network.host_ip0); let dhcp_host = format!( "--dhcp-host={},{}", - self.guest.network.guest_mac, self.guest.network.guest_ip + self.guest.network.guest_mac0, self.guest.network.guest_ip0 ); let dhcp_range = format!( "--dhcp-range=eth,{},{}", - self.guest.network.guest_ip, self.guest.network.guest_ip + self.guest.network.guest_ip0, self.guest.network.guest_ip0 ); Command::new("dnsmasq") @@ -8820,7 +8820,7 @@ mod windows { let out = ssh_command_ip_with_auth( cmd, &self.auth, - &self.guest.network.guest_ip, + &self.guest.network.guest_ip0, { let mut ret = 1; let mut tmo_acc = 0; @@ -8954,9 +8954,9 @@ mod windows { .args([ "--net", format!( - "tap=,mac={},ip={},mask=255.255.255.0,num_queues=8", - windows_guest.guest().network.guest_mac, - windows_guest.guest().network.host_ip + "tap=,mac={},ip={},mask=255.255.255.128,num_queues=8", + windows_guest.guest().network.guest_mac0, + windows_guest.guest().network.host_ip0 ) .as_str(), ]) @@ -9923,8 +9923,8 @@ mod live_migration { let console_text = String::from("On a branch floating down river a cricket, singing."); let net_id = "net123"; let net_params = format!( - "id={},tap=,mac={},ip={},mask=255.255.255.0", - net_id, guest.network.guest_mac, guest.network.host_ip + "id={},tap=,mac={},ip={},mask=255.255.255.128", + net_id, guest.network.guest_mac0, guest.network.host_ip0 ); let memory_param: &[&str] = if local { @@ -10077,8 +10077,8 @@ mod live_migration { let console_text = String::from("On a branch floating down river a cricket, singing."); let net_id = "net123"; let net_params = format!( - "id={},tap=,mac={},ip={},mask=255.255.255.0", - net_id, guest.network.guest_mac, guest.network.host_ip + "id={},tap=,mac={},ip={},mask=255.255.255.128", + net_id, guest.network.guest_mac0, guest.network.host_ip0 ); let memory_param: &[&str] = if local { @@ -10266,8 +10266,8 @@ mod live_migration { let console_text = String::from("On a branch floating down river a cricket, singing."); let net_id = "net123"; let net_params = format!( - "id={},tap=,mac={},ip={},mask=255.255.255.0", - net_id, guest.network.guest_mac, guest.network.host_ip + "id={},tap=,mac={},ip={},mask=255.255.255.128", + net_id, guest.network.guest_mac0, guest.network.host_ip0 ); let memory_param: &[&str] = if local { @@ -10513,8 +10513,8 @@ mod live_migration { let console_text = String::from("On a branch floating down river a cricket, singing."); let net_id = "net123"; let net_params = format!( - "id={},tap=,mac={},ip={},mask=255.255.255.0", - net_id, guest.network.guest_mac, guest.network.host_ip + "id={},tap=,mac={},ip={},mask=255.255.255.128", + net_id, guest.network.guest_mac0, guest.network.host_ip0 ); let memory_param: &[&str] = if local { @@ -10771,7 +10771,7 @@ mod live_migration { let r = std::panic::catch_unwind(|| { // Perform same checks to validate VM has been properly migrated // Spawn a new netcat listener in the OVS VM - let guest_ip = ovs_guest.network.guest_ip.clone(); + let guest_ip = ovs_guest.network.guest_ip0.clone(); thread::spawn(move || { ssh_command_ip( "nc -l 12345", @@ -10819,8 +10819,8 @@ mod live_migration { let kernel_path = direct_kernel_boot_path(); let net_id = "net123"; let net_params = format!( - "id={},tap=,mac={},ip={},mask=255.255.255.0", - net_id, guest.network.guest_mac, guest.network.host_ip + "id={},tap=,mac={},ip={},mask=255.255.255.128", + net_id, guest.network.guest_mac0, guest.network.host_ip0 ); let boot_vcpus = 2; @@ -11027,8 +11027,8 @@ mod live_migration { let console_text = String::from("On a branch floating down river a cricket, singing."); let net_id = "net123"; let net_params = format!( - "id={},tap=,mac={},ip={},mask=255.255.255.0", - net_id, guest.network.guest_mac, guest.network.host_ip + "id={},tap=,mac={},ip={},mask=255.255.255.128", + net_id, guest.network.guest_mac0, guest.network.host_ip0 ); let memory_param: &[&str] = &["--memory", "size=4G,shared=on"]; let boot_vcpus = 2; @@ -11382,9 +11382,9 @@ mod rate_limiter { let limit_bps = (bw_size * 8 * 1000) as f64 / bw_refill_time as f64; let net_params = format!( - "tap=,mac={},ip={},mask=255.255.255.0,num_queues={},queue_size={},bw_size={},bw_refill_time={}", - guest.network.guest_mac, - guest.network.host_ip, + "tap=,mac={},ip={},mask=255.255.255.128,num_queues={},queue_size={},bw_size={},bw_refill_time={}", + guest.network.guest_mac0, + guest.network.host_ip0, num_queues, queue_size, bw_size,