diff options
| author | David Lönnhager <david.l@mullvad.net> | 2023-10-23 22:53:28 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2023-10-24 09:45:34 +0200 |
| commit | 3aabe487c6247a053d11dac345215737cee7cfb0 (patch) | |
| tree | 76cd2c3a994b418258ff154edd44863cd5da3c7d | |
| parent | 51b34719239a8780ef3885017d2d450cae6da87c (diff) | |
| download | mullvadvpn-3aabe487c6247a053d11dac345215737cee7cfb0.tar.xz mullvadvpn-3aabe487c6247a053d11dac345215737cee7cfb0.zip | |
Set up dummy interface on macOS
| -rw-r--r-- | test/test-manager/src/vm/network/macos.rs | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/test/test-manager/src/vm/network/macos.rs b/test/test-manager/src/vm/network/macos.rs index bfef3a9ddb..ef815f203a 100644 --- a/test/test-manager/src/vm/network/macos.rs +++ b/test/test-manager/src/vm/network/macos.rs @@ -1,11 +1,11 @@ use std::net::{Ipv4Addr, SocketAddrV4}; use anyhow::{anyhow, Context, Result}; +use futures::future::{self, Either}; use tokio::{io::AsyncWriteExt, process::Command}; /// Pingable dummy LAN interface (IP) -/// TODO: This should probably be a different host, not the gateway -pub const DUMMY_LAN_INTERFACE_IP: Ipv4Addr = Ipv4Addr::new(192, 168, 64, 1); +pub const DUMMY_LAN_INTERFACE_IP: Ipv4Addr = Ipv4Addr::new(192, 168, 64, 254); // Private key of the wireguard remote peer on host. const CUSTOM_TUN_REMOTE_PRIVKEY: &str = "gLvQuyqazziyf+pUCAFUgTnWIwn6fPE5MOReOqPEGHU="; @@ -36,6 +36,8 @@ pub const NON_TUN_GATEWAY: Ipv4Addr = Ipv4Addr::new(192, 168, 64, 1); /// Name of the wireguard interface on the host pub const CUSTOM_TUN_INTERFACE_NAME: &str = "utun123"; +use std::time::Duration; + /// Timeout for wireguard-go to create an interface const INTERFACE_SETUP_TIMEOUT: Duration = Duration::from_secs(5); @@ -48,9 +50,41 @@ pub async fn setup_test_network() -> Result<()> { .await .context("Failed to create WireGuard interface")?; + // A bit of trickery to detect when the bridge is available. + tokio::spawn(async move { + for _ in 0..30 { + let Ok(interface) = find_vm_bridge() else { + tokio::time::sleep(Duration::from_secs(1)).await; + continue; + }; + match create_dummy_interface(interface).await { + Ok(_) => log::debug!("Created dummy interface"), + Err(error) => log::error!("Failed to create dummy interface: {error}"), + } + return; + } + log::error!("Failed to create dummy interface: timed out"); + }); + Ok(()) } +async fn create_dummy_interface(interface: String) -> Result<()> { + let mut cmd = Command::new("/usr/bin/sudo"); + cmd.args([ + "/sbin/ifconfig", + &interface, + "alias", + &DUMMY_LAN_INTERFACE_IP.to_string(), + ]); + let output = cmd.output().await.context("Create dummy interface")?; + if output.status.success() { + Ok(()) + } else { + Err(anyhow!("ifconfig failed: {:?}", output.status.code())) + } +} + /// A hack to find the Tart bridge interface using `NON_TUN_GATEWAY`. /// It should be possible to retrieve this using the virtualization framework instead, /// but that requires an entitlement. |
