From f9dbb235a2fb6233e6c76071b4f3c9466caf7a9f Mon Sep 17 00:00:00 2001 From: sylvain-pierrot Date: Thu, 2 May 2024 10:24:22 +0200 Subject: [PATCH 1/7] feat: create bridge interface Signed-off-by: sylvain-pierrot --- src/vmm/Cargo.toml | 4 +- src/vmm/src/core/devices/virtio/net/bridge.rs | 54 +++++++++++++++++++ src/vmm/src/core/devices/virtio/net/device.rs | 5 +- src/vmm/src/core/devices/virtio/net/mod.rs | 1 + .../src/core/devices/virtio/net/tuntap/tap.rs | 5 ++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/vmm/src/core/devices/virtio/net/bridge.rs diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index 6f5aa30..bdda86e 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -14,6 +14,7 @@ clap = { version = "4.5.1", features = ["derive", "env"] } clap-verbosity-flag = "2.2.0" epoll = "4.3.3" event-manager = { version = "0.4.0", features = ["remote_endpoint"] } +futures = "0.3.30" kvm-bindings = { version = "0.7.0", features = ["fam-wrappers"] } kvm-ioctls = "0.16.0" libc = "0.2.153" @@ -22,7 +23,9 @@ log = "0.4.20" nix = { version = "0.28.0", features = ["term"] } openpty = "0.2.0" prost = "0.11" +rtnetlink = "0.14.1" tokio = { version = "1.37.0", features = ["full"] } +tokio-stream = "0.1.15" tonic = "0.9" tracing = "0.1.40" tracing-subscriber = "0.3.18" @@ -34,7 +37,6 @@ vm-device = "0.1.0" vm-memory = { version = "0.14.1", features = ["backend-mmap"] } vm-superio = "0.7.0" vmm-sys-util = "0.12.1" -tokio-stream = "0.1.15" [build-dependencies] tonic-build = "0.9" diff --git a/src/vmm/src/core/devices/virtio/net/bridge.rs b/src/vmm/src/core/devices/virtio/net/bridge.rs new file mode 100644 index 0000000..58b731f --- /dev/null +++ b/src/vmm/src/core/devices/virtio/net/bridge.rs @@ -0,0 +1,54 @@ +use futures::stream::TryStreamExt; +use rtnetlink::{new_connection, Error, Handle}; + +pub fn host_bridge(tap_name: String, bridge_name: String) { + let (connection, handle, _) = new_connection().unwrap(); + tokio::spawn(connection); + + futures::executor::block_on(async { + let _ = create_bridge(handle.clone(), bridge_name.clone()).await; + let _ = attach_link_to_bridge(handle, tap_name, bridge_name).await; + }) +} + +async fn create_bridge(handle: Handle, name: String) -> Result<(), Error> { + handle + .link() + .add() + .bridge(name) + .execute() + .await + .map_err(|_| Error::RequestFailed) +} + +async fn attach_link_to_bridge( + handle: Handle, + link_name: String, + master_name: String, +) -> Result<(), Error> { + let mut link_names = handle.link().get().match_name(link_name.clone()).execute(); + let mut master_names = handle + .link() + .get() + .match_name(master_name.clone()) + .execute(); + + let link_index = match link_names.try_next().await? { + Some(link) => link.header.index, + None => panic!(), + }; + let master_index = match master_names.try_next().await? { + Some(link) => link.header.index, + None => panic!(), + }; + + handle + .link() + .set(link_index) + .controller(master_index) + .execute() + .await + .unwrap(); + + Ok(()) +} diff --git a/src/vmm/src/core/devices/virtio/net/device.rs b/src/vmm/src/core/devices/virtio/net/device.rs index bf8acf8..94b5199 100644 --- a/src/vmm/src/core/devices/virtio/net/device.rs +++ b/src/vmm/src/core/devices/virtio/net/device.rs @@ -1,3 +1,4 @@ +use super::bridge::host_bridge; use super::queue_handler::QueueHandler; use super::{ simple_handler::SimpleHandler, tuntap::tap::Tap, Error, Result, NET_DEVICE_ID, @@ -85,7 +86,7 @@ impl Net { let net = Arc::new(Mutex::new(Net { mem, config: cfg, - tap: Arc::new(Mutex::new(tap)), + tap: Arc::new(Mutex::new(tap.clone())), })); let vmmio_param = register_mmio_device(mmio_cfg, device_mgr, irq, None, net.clone()) @@ -98,6 +99,8 @@ impl Net { cmdline_extra_parameters.push(vmmio_param); cmdline_extra_parameters.push(ip_pnp_param); + host_bridge(tap.get_name().map_err(Error::Tap)?, "br0".to_string()); + Ok(net) } } diff --git a/src/vmm/src/core/devices/virtio/net/mod.rs b/src/vmm/src/core/devices/virtio/net/mod.rs index 765986e..c254ae1 100644 --- a/src/vmm/src/core/devices/virtio/net/mod.rs +++ b/src/vmm/src/core/devices/virtio/net/mod.rs @@ -1,3 +1,4 @@ +mod bridge; pub mod device; mod queue_handler; mod simple_handler; diff --git a/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs b/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs index 0eb1ec3..3b4ea86 100644 --- a/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs +++ b/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs @@ -200,6 +200,11 @@ impl Tap { unsafe { Self::ioctl_with_ref(&sock, net_gen::sockios::SIOCSIFHWADDR as c_ulong, &ifreq) } } + /// Get tap name + pub fn get_name(&self) -> Result { + Ok(String::from_utf8(self.if_name.clone()).map_err(|_| Error::InvalidIfname)?) + } + /// Get mac addr for tap interface. pub fn get_mac_addr(&self) -> Result { let sock = create_unix_socket().map_err(Error::NetUtil)?; From 8c477b2f1d718366ab48ceeda2e16ddf70ffeedc Mon Sep 17 00:00:00 2001 From: sylvain-pierrot Date: Thu, 2 May 2024 10:50:11 +0200 Subject: [PATCH 2/7] feat: create bridge only if not exist Signed-off-by: sylvain-pierrot --- src/vmm/src/core/devices/virtio/net/bridge.rs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/vmm/src/core/devices/virtio/net/bridge.rs b/src/vmm/src/core/devices/virtio/net/bridge.rs index 58b731f..30c0c78 100644 --- a/src/vmm/src/core/devices/virtio/net/bridge.rs +++ b/src/vmm/src/core/devices/virtio/net/bridge.rs @@ -6,19 +6,24 @@ pub fn host_bridge(tap_name: String, bridge_name: String) { tokio::spawn(connection); futures::executor::block_on(async { - let _ = create_bridge(handle.clone(), bridge_name.clone()).await; + let _ = create_bridge_if_not_exist(handle.clone(), bridge_name.clone()).await; let _ = attach_link_to_bridge(handle, tap_name, bridge_name).await; }) } -async fn create_bridge(handle: Handle, name: String) -> Result<(), Error> { - handle - .link() - .add() - .bridge(name) - .execute() - .await - .map_err(|_| Error::RequestFailed) +async fn create_bridge_if_not_exist(handle: Handle, name: String) -> Result<(), Error> { + let mut bridge_names = handle.link().get().match_name(name.clone()).execute(); + + match bridge_names.try_next().await? { + Some(_) => Ok(()), + None => handle + .link() + .add() + .bridge(name) + .execute() + .await + .map_err(|_| Error::RequestFailed), + } } async fn attach_link_to_bridge( @@ -42,13 +47,13 @@ async fn attach_link_to_bridge( None => panic!(), }; - handle + let _ = handle .link() .set(link_index) .controller(master_index) .execute() .await - .unwrap(); + .map_err(|_| Error::RequestFailed); Ok(()) } From c0528ed2ad2f26ff382d46d90ce12efd2a7e9dda Mon Sep 17 00:00:00 2001 From: sylvain-pierrot Date: Thu, 2 May 2024 10:55:43 +0200 Subject: [PATCH 3/7] fix: cargo clippy Signed-off-by: sylvain-pierrot --- src/vmm/src/core/devices/virtio/net/tuntap/tap.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs b/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs index 3b4ea86..1dbabb9 100644 --- a/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs +++ b/src/vmm/src/core/devices/virtio/net/tuntap/tap.rs @@ -202,7 +202,8 @@ impl Tap { /// Get tap name pub fn get_name(&self) -> Result { - Ok(String::from_utf8(self.if_name.clone()).map_err(|_| Error::InvalidIfname)?) + let name = String::from_utf8(self.if_name.clone()).map_err(|_| Error::InvalidIfname)?; + Ok(name) } /// Get mac addr for tap interface. From 8629b2283601920bd1a67ea3a93abdd29cb7d533 Mon Sep 17 00:00:00 2001 From: sylvain-pierrot Date: Thu, 2 May 2024 21:54:15 +0200 Subject: [PATCH 4/7] feat: internet works Signed-off-by: sylvain-pierrot --- Justfile | 2 +- src/vmm/Cargo.toml | 1 + src/vmm/src/args.rs | 4 + src/vmm/src/core/devices/virtio/net/bridge.rs | 178 +++++++++++++----- src/vmm/src/core/devices/virtio/net/device.rs | 23 ++- .../src/core/devices/virtio/net/iptables.rs | 16 ++ src/vmm/src/core/devices/virtio/net/mod.rs | 5 + src/vmm/src/core/vmm.rs | 16 +- src/vmm/src/grpc/server.rs | 4 +- src/vmm/src/main.rs | 1 + 10 files changed, 187 insertions(+), 63 deletions(-) create mode 100644 src/vmm/src/core/devices/virtio/net/iptables.rs diff --git a/Justfile b/Justfile index cfd7891..7bca018 100644 --- a/Justfile +++ b/Justfile @@ -12,7 +12,7 @@ run: sudo -E capsh --keep=1 --user=$USER --inh=cap_net_admin --addamb=cap_net_admin -- -c \ 'RUST_BACKTRACE=1 '$CARGO_PATH' run --bin vmm -- cli --memory 512 --cpus 1 \ --kernel tools/kernel/linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ - --iface-host-addr 172.29.0.1 --netmask 255.255.0.0 --iface-guest-addr 172.29.0.2 \ + --iface-host-addr 172.29.0.1 --netmask 255.255.0.0 --network 172.29.0.0 --iface-guest-addr 172.29.0.2 \ --initramfs=tools/rootfs/initramfs.img' build-kernel: diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index bdda86e..c57316c 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -15,6 +15,7 @@ clap-verbosity-flag = "2.2.0" epoll = "4.3.3" event-manager = { version = "0.4.0", features = ["remote_endpoint"] } futures = "0.3.30" +iptables = "0.5.1" kvm-bindings = { version = "0.7.0", features = ["fam-wrappers"] } kvm-ioctls = "0.16.0" libc = "0.2.153" diff --git a/src/vmm/src/args.rs b/src/vmm/src/args.rs index 3feceef..3759420 100644 --- a/src/vmm/src/args.rs +++ b/src/vmm/src/args.rs @@ -44,6 +44,10 @@ pub struct CliArguments { #[clap(long, env, required = true)] pub iface_host_addr: Ipv4Addr, + /// Network. + #[clap(long, env, required = true)] + pub network: Ipv4Addr, + /// Subnet mask for network. #[clap(long, env, required = true)] pub netmask: Ipv4Addr, diff --git a/src/vmm/src/core/devices/virtio/net/bridge.rs b/src/vmm/src/core/devices/virtio/net/bridge.rs index 30c0c78..6412cb4 100644 --- a/src/vmm/src/core/devices/virtio/net/bridge.rs +++ b/src/vmm/src/core/devices/virtio/net/bridge.rs @@ -1,59 +1,137 @@ +use std::net::{IpAddr, Ipv4Addr}; + use futures::stream::TryStreamExt; use rtnetlink::{new_connection, Error, Handle}; -pub fn host_bridge(tap_name: String, bridge_name: String) { - let (connection, handle, _) = new_connection().unwrap(); - tokio::spawn(connection); +use super::xx_netmask_width; - futures::executor::block_on(async { - let _ = create_bridge_if_not_exist(handle.clone(), bridge_name.clone()).await; - let _ = attach_link_to_bridge(handle, tap_name, bridge_name).await; - }) +#[derive(Clone)] +pub struct Bridge { + name: String, + handle: Handle, } -async fn create_bridge_if_not_exist(handle: Handle, name: String) -> Result<(), Error> { - let mut bridge_names = handle.link().get().match_name(name.clone()).execute(); - - match bridge_names.try_next().await? { - Some(_) => Ok(()), - None => handle - .link() - .add() - .bridge(name) - .execute() - .await - .map_err(|_| Error::RequestFailed), +impl Bridge { + pub fn new(name: String) -> Self { + let (connection, handle, _) = new_connection().unwrap(); + tokio::spawn(connection); + + let br = Self { name, handle }; + let _ = br.create_bridge_if_not_exist(); + + br } -} -async fn attach_link_to_bridge( - handle: Handle, - link_name: String, - master_name: String, -) -> Result<(), Error> { - let mut link_names = handle.link().get().match_name(link_name.clone()).execute(); - let mut master_names = handle - .link() - .get() - .match_name(master_name.clone()) - .execute(); - - let link_index = match link_names.try_next().await? { - Some(link) => link.header.index, - None => panic!(), - }; - let master_index = match master_names.try_next().await? { - Some(link) => link.header.index, - None => panic!(), - }; - - let _ = handle - .link() - .set(link_index) - .controller(master_index) - .execute() - .await - .map_err(|_| Error::RequestFailed); - - Ok(()) + fn create_bridge_if_not_exist(&self) { + futures::executor::block_on(async { + let mut bridge_names = self + .handle + .link() + .get() + .match_name(self.name.clone()) + .execute(); + + let _ = match bridge_names.try_next().await { + Ok(_) => Ok(()), + Err(_) => self + .handle + .link() + .add() + .bridge(self.name.clone()) + .execute() + .await + .map_err(|_| Error::RequestFailed), + }; + }); + } + + pub fn set_addr(&self, addr: Ipv4Addr, netmask: Ipv4Addr) { + futures::executor::block_on(async { + let mut bridge_names = self + .handle + .link() + .get() + .match_name(self.name.clone()) + .execute(); + + let bridge_index = match bridge_names.try_next().await { + Ok(Some(link)) => link.header.index, + Ok(None) => panic!(), + Err(_) => panic!(), + }; + + let prefix_len = xx_netmask_width(netmask.octets()); + + let _ = self + .handle + .address() + .add(bridge_index, IpAddr::V4(addr), prefix_len) + .execute() + .await + .map_err(|_| Error::RequestFailed); + }); + } + + pub fn set_up(&self) { + futures::executor::block_on(async { + let mut bridge_names = self + .handle + .link() + .get() + .match_name(self.name.clone()) + .execute(); + + let bridge_index = match bridge_names.try_next().await { + Ok(Some(link)) => link.header.index, + Ok(None) => panic!(), + Err(_) => panic!(), + }; + + let _ = self + .handle + .link() + .set(bridge_index) + .up() + .execute() + .await + .map_err(|_| Error::RequestFailed); + }); + } + + pub fn attach_link(&self, link_name: String) { + futures::executor::block_on(async { + let mut link_names = self + .handle + .link() + .get() + .match_name(link_name.clone()) + .execute(); + let mut master_names = self + .handle + .link() + .get() + .match_name(self.name.clone()) + .execute(); + + let link_index = match link_names.try_next().await { + Ok(Some(link)) => link.header.index, + Ok(None) => panic!(), + Err(_) => panic!(), + }; + let master_index = match master_names.try_next().await { + Ok(Some(link)) => link.header.index, + Ok(None) => panic!(), + Err(_) => panic!(), + }; + + let _ = self + .handle + .link() + .set(link_index) + .controller(master_index) + .execute() + .await + .map_err(|_| Error::RequestFailed); + }); + } } diff --git a/src/vmm/src/core/devices/virtio/net/device.rs b/src/vmm/src/core/devices/virtio/net/device.rs index 94b5199..3698d84 100644 --- a/src/vmm/src/core/devices/virtio/net/device.rs +++ b/src/vmm/src/core/devices/virtio/net/device.rs @@ -1,4 +1,5 @@ -use super::bridge::host_bridge; +use super::bridge::Bridge; +use super::iptables::iptables_ip_masq; use super::queue_handler::QueueHandler; use super::{ simple_handler::SimpleHandler, tuntap::tap::Tap, Error, Result, NET_DEVICE_ID, @@ -35,6 +36,7 @@ pub struct Net { mem: Arc, pub config: Config, tap: Arc>, + _bridge: Bridge, } impl Net { @@ -43,7 +45,8 @@ impl Net { mem: Arc, device_mgr: Arc>, mmio_cfg: MmioConfig, - tap_addr: Ipv4Addr, + iface_host_addr: Ipv4Addr, + network: Ipv4Addr, netmask: Ipv4Addr, iface_guest_addr: Ipv4Addr, irq: u32, @@ -75,32 +78,38 @@ impl Net { // Set offload flags to match the relevant virtio features of the device (for now, // statically set in the constructor. - let tap = open_tap(None, Some(tap_addr), Some(netmask), &mut None, None, None) - .map_err(Error::TunTap)?; + let tap = open_tap(None, None, None, &mut None, None, None).map_err(Error::TunTap)?; // The layout of the header is specified in the standard and is 12 bytes in size. We // should define this somewhere. tap.set_vnet_hdr_size(VIRTIO_NET_HDR_SIZE as i32) .map_err(Error::Tap)?; + let bridge = Bridge::new("br0".to_string()); + bridge.set_addr(iface_host_addr, netmask); + bridge.attach_link(tap.get_name().map_err(Error::Tap)?); + bridge.set_up(); + + // Get internet access + iptables_ip_masq(network, netmask); + let net = Arc::new(Mutex::new(Net { mem, config: cfg, tap: Arc::new(Mutex::new(tap.clone())), + _bridge: bridge, })); let vmmio_param = register_mmio_device(mmio_cfg, device_mgr, irq, None, net.clone()) .map_err(Error::Virtio)?; let ip_pnp_param: String = format!( "ip={}::{}:{}::eth0:off", - iface_guest_addr, tap_addr, netmask + iface_guest_addr, iface_host_addr, netmask ); cmdline_extra_parameters.push(vmmio_param); cmdline_extra_parameters.push(ip_pnp_param); - host_bridge(tap.get_name().map_err(Error::Tap)?, "br0".to_string()); - Ok(net) } } diff --git a/src/vmm/src/core/devices/virtio/net/iptables.rs b/src/vmm/src/core/devices/virtio/net/iptables.rs new file mode 100644 index 0000000..bbe22f5 --- /dev/null +++ b/src/vmm/src/core/devices/virtio/net/iptables.rs @@ -0,0 +1,16 @@ +use std::net::Ipv4Addr; + +use super::xx_netmask_width; + +pub fn iptables_ip_masq(network: Ipv4Addr, netmask: Ipv4Addr) { + let prefix_len = xx_netmask_width(netmask.octets()); + let source = format!("{}/{}", network.to_string(), prefix_len); + + let ipt = iptables::new(false).unwrap(); + let rule = format!("-s {} ! -o br0 -j MASQUERADE", source); + + let exists = ipt.exists("nat", "POSTROUTING", rule.as_str()).unwrap(); + if !exists { + let _ = ipt.insert_unique("nat", "POSTROUTING", rule.as_str(), 1); + } +} diff --git a/src/vmm/src/core/devices/virtio/net/mod.rs b/src/vmm/src/core/devices/virtio/net/mod.rs index c254ae1..1277932 100644 --- a/src/vmm/src/core/devices/virtio/net/mod.rs +++ b/src/vmm/src/core/devices/virtio/net/mod.rs @@ -1,5 +1,6 @@ mod bridge; pub mod device; +pub mod iptables; mod queue_handler; mod simple_handler; pub mod tuntap; @@ -21,3 +22,7 @@ pub enum Error { } pub type Result = std::result::Result; + +pub fn xx_netmask_width(netmask: [u8; SZ]) -> u8 { + netmask.iter().map(|x| x.count_ones() as u8).sum() +} diff --git a/src/vmm/src/core/vmm.rs b/src/vmm/src/core/vmm.rs index c111a4c..c1a2121 100644 --- a/src/vmm/src/core/vmm.rs +++ b/src/vmm/src/core/vmm.rs @@ -58,7 +58,8 @@ pub struct VMM { event_mgr: EventMgr, vcpus: Vec, - tap_addr: Ipv4Addr, + iface_host_addr: Ipv4Addr, + network: Ipv4Addr, netmask: Ipv4Addr, iface_guest_addr: Ipv4Addr, net_devices: Vec>>, @@ -69,7 +70,12 @@ pub struct VMM { impl VMM { /// Create a new VMM. - pub fn new(tap_addr: Ipv4Addr, netmask: Ipv4Addr, iface_guest_addr: Ipv4Addr) -> Result { + pub fn new( + iface_host_addr: Ipv4Addr, + network: Ipv4Addr, + netmask: Ipv4Addr, + iface_guest_addr: Ipv4Addr, + ) -> Result { // Open /dev/kvm and get a file descriptor to it. let kvm = Kvm::new().map_err(Error::KvmIoctl)?; @@ -111,7 +117,8 @@ impl VMM { )), slip_pty: Arc::new(Mutex::new(slip_pty)), epoll, - tap_addr, + iface_host_addr, + network, netmask, iface_guest_addr, net_devices: Vec::new(), @@ -382,7 +389,8 @@ impl VMM { mem, self.device_mgr.clone(), mmio_cfg, - self.tap_addr, + self.iface_host_addr, + self.network, self.netmask, self.iface_guest_addr, irq, diff --git a/src/vmm/src/grpc/server.rs b/src/vmm/src/grpc/server.rs index e5c6919..6383c29 100644 --- a/src/vmm/src/grpc/server.rs +++ b/src/vmm/src/grpc/server.rs @@ -51,6 +51,7 @@ impl VmmServiceTrait for VmmService { const HOST_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 1); const HOST_NETMASK: Ipv4Addr = Ipv4Addr::new(255, 255, 0, 0); + const NETWORK: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 0); const GUEST_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 2); // get current directory @@ -157,7 +158,8 @@ impl VmmServiceTrait for VmmService { } let initramfs_path = PathBuf::from(&initramfs_entire_file_path); - let mut vmm = VMM::new(HOST_IP, HOST_NETMASK, GUEST_IP).map_err(VmmErrors::VmmNew)?; + let mut vmm = + VMM::new(HOST_IP, NETWORK, HOST_NETMASK, GUEST_IP).map_err(VmmErrors::VmmNew)?; // Configure the VMM parameters might need to be calculated rather than hardcoded vmm.configure(1, 4000, kernel_path, &Some(initramfs_path)) diff --git a/src/vmm/src/main.rs b/src/vmm/src/main.rs index 7f6a748..364a377 100644 --- a/src/vmm/src/main.rs +++ b/src/vmm/src/main.rs @@ -42,6 +42,7 @@ async fn main() -> Result<(), Box> { // Create a new VMM let mut vmm = VMM::new( cli_args.iface_host_addr, + cli_args.network, cli_args.netmask, cli_args.iface_guest_addr, ) From 1cbd327694e5000999f345ade5091ce0621575f0 Mon Sep 17 00:00:00 2001 From: sylvain-pierrot Date: Thu, 2 May 2024 21:58:11 +0200 Subject: [PATCH 5/7] fix: cargo clippy Signed-off-by: sylvain-pierrot --- src/vmm/src/core/devices/virtio/net/bridge.rs | 2 +- src/vmm/src/core/devices/virtio/net/iptables.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vmm/src/core/devices/virtio/net/bridge.rs b/src/vmm/src/core/devices/virtio/net/bridge.rs index 6412cb4..a0f1500 100644 --- a/src/vmm/src/core/devices/virtio/net/bridge.rs +++ b/src/vmm/src/core/devices/virtio/net/bridge.rs @@ -17,7 +17,7 @@ impl Bridge { tokio::spawn(connection); let br = Self { name, handle }; - let _ = br.create_bridge_if_not_exist(); + br.create_bridge_if_not_exist(); br } diff --git a/src/vmm/src/core/devices/virtio/net/iptables.rs b/src/vmm/src/core/devices/virtio/net/iptables.rs index bbe22f5..d7d66de 100644 --- a/src/vmm/src/core/devices/virtio/net/iptables.rs +++ b/src/vmm/src/core/devices/virtio/net/iptables.rs @@ -4,7 +4,7 @@ use super::xx_netmask_width; pub fn iptables_ip_masq(network: Ipv4Addr, netmask: Ipv4Addr) { let prefix_len = xx_netmask_width(netmask.octets()); - let source = format!("{}/{}", network.to_string(), prefix_len); + let source = format!("{}/{}", network, prefix_len); let ipt = iptables::new(false).unwrap(); let rule = format!("-s {} ! -o br0 -j MASQUERADE", source); From 4a60c7a63f77dcd26c69ebb9c1fcde60094bf249 Mon Sep 17 00:00:00 2001 From: sylvain-pierrot Date: Thu, 2 May 2024 22:13:20 +0200 Subject: [PATCH 6/7] refactor: clean code Signed-off-by: sylvain-pierrot --- src/vmm/src/core/devices/virtio/net/device.rs | 5 +++-- src/vmm/src/core/devices/virtio/net/iptables.rs | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vmm/src/core/devices/virtio/net/device.rs b/src/vmm/src/core/devices/virtio/net/device.rs index 3698d84..96acde6 100644 --- a/src/vmm/src/core/devices/virtio/net/device.rs +++ b/src/vmm/src/core/devices/virtio/net/device.rs @@ -85,13 +85,14 @@ impl Net { tap.set_vnet_hdr_size(VIRTIO_NET_HDR_SIZE as i32) .map_err(Error::Tap)?; - let bridge = Bridge::new("br0".to_string()); + let bridge_name = "br0".to_string(); + let bridge = Bridge::new(bridge_name.clone()); bridge.set_addr(iface_host_addr, netmask); bridge.attach_link(tap.get_name().map_err(Error::Tap)?); bridge.set_up(); // Get internet access - iptables_ip_masq(network, netmask); + iptables_ip_masq(network, netmask, bridge_name); let net = Arc::new(Mutex::new(Net { mem, diff --git a/src/vmm/src/core/devices/virtio/net/iptables.rs b/src/vmm/src/core/devices/virtio/net/iptables.rs index d7d66de..2c61579 100644 --- a/src/vmm/src/core/devices/virtio/net/iptables.rs +++ b/src/vmm/src/core/devices/virtio/net/iptables.rs @@ -2,12 +2,12 @@ use std::net::Ipv4Addr; use super::xx_netmask_width; -pub fn iptables_ip_masq(network: Ipv4Addr, netmask: Ipv4Addr) { +pub fn iptables_ip_masq(network: Ipv4Addr, netmask: Ipv4Addr, link_name: String) { let prefix_len = xx_netmask_width(netmask.octets()); let source = format!("{}/{}", network, prefix_len); let ipt = iptables::new(false).unwrap(); - let rule = format!("-s {} ! -o br0 -j MASQUERADE", source); + let rule = format!("-s {} ! -o {} -j MASQUERADE", source, link_name); let exists = ipt.exists("nat", "POSTROUTING", rule.as_str()).unwrap(); if !exists { From f6fe499567a327ebeeec069a51b40355ba96d1e6 Mon Sep 17 00:00:00 2001 From: sylvain-pierrot Date: Thu, 2 May 2024 22:37:04 +0200 Subject: [PATCH 7/7] remove network var + add symlink for dns in initfile Signed-off-by: sylvain-pierrot --- Justfile | 4 ++-- src/fs-gen/resources/initfile | 2 ++ src/vmm/src/args.rs | 4 ---- src/vmm/src/core/devices/virtio/net/device.rs | 5 ++--- src/vmm/src/core/vmm.rs | 4 ---- src/vmm/src/grpc/server.rs | 4 +--- src/vmm/src/main.rs | 1 - 7 files changed, 7 insertions(+), 17 deletions(-) diff --git a/Justfile b/Justfile index 7bca018..12b3d68 100644 --- a/Justfile +++ b/Justfile @@ -12,8 +12,8 @@ run: sudo -E capsh --keep=1 --user=$USER --inh=cap_net_admin --addamb=cap_net_admin -- -c \ 'RUST_BACKTRACE=1 '$CARGO_PATH' run --bin vmm -- cli --memory 512 --cpus 1 \ --kernel tools/kernel/linux-cloud-hypervisor/arch/x86/boot/compressed/vmlinux.bin \ - --iface-host-addr 172.29.0.1 --netmask 255.255.0.0 --network 172.29.0.0 --iface-guest-addr 172.29.0.2 \ - --initramfs=tools/rootfs/initramfs.img' + --iface-host-addr 172.29.0.1 --netmask 255.255.0.0 --iface-guest-addr 172.29.0.2 \ + --initramfs=../virt-do/initramfs.img' build-kernel: #!/bin/bash diff --git a/src/fs-gen/resources/initfile b/src/fs-gen/resources/initfile index 4d72bc6..14945cd 100644 --- a/src/fs-gen/resources/initfile +++ b/src/fs-gen/resources/initfile @@ -14,6 +14,8 @@ export RUST_VERSION='1.77.2' export PATH=$CARGO_HOME/bin:$PATH +ln -s /proc/net/pnp /etc/resolv.conf + /agent reboot \ No newline at end of file diff --git a/src/vmm/src/args.rs b/src/vmm/src/args.rs index 3759420..3feceef 100644 --- a/src/vmm/src/args.rs +++ b/src/vmm/src/args.rs @@ -44,10 +44,6 @@ pub struct CliArguments { #[clap(long, env, required = true)] pub iface_host_addr: Ipv4Addr, - /// Network. - #[clap(long, env, required = true)] - pub network: Ipv4Addr, - /// Subnet mask for network. #[clap(long, env, required = true)] pub netmask: Ipv4Addr, diff --git a/src/vmm/src/core/devices/virtio/net/device.rs b/src/vmm/src/core/devices/virtio/net/device.rs index 96acde6..5432cce 100644 --- a/src/vmm/src/core/devices/virtio/net/device.rs +++ b/src/vmm/src/core/devices/virtio/net/device.rs @@ -46,7 +46,6 @@ impl Net { device_mgr: Arc>, mmio_cfg: MmioConfig, iface_host_addr: Ipv4Addr, - network: Ipv4Addr, netmask: Ipv4Addr, iface_guest_addr: Ipv4Addr, irq: u32, @@ -92,7 +91,7 @@ impl Net { bridge.set_up(); // Get internet access - iptables_ip_masq(network, netmask, bridge_name); + iptables_ip_masq(iface_host_addr & netmask, netmask, bridge_name); let net = Arc::new(Mutex::new(Net { mem, @@ -104,7 +103,7 @@ impl Net { let vmmio_param = register_mmio_device(mmio_cfg, device_mgr, irq, None, net.clone()) .map_err(Error::Virtio)?; let ip_pnp_param: String = format!( - "ip={}::{}:{}::eth0:off", + "ip={}::{}:{}::eth0:off:1.1.1.1", iface_guest_addr, iface_host_addr, netmask ); diff --git a/src/vmm/src/core/vmm.rs b/src/vmm/src/core/vmm.rs index c1a2121..4eb2ce6 100644 --- a/src/vmm/src/core/vmm.rs +++ b/src/vmm/src/core/vmm.rs @@ -59,7 +59,6 @@ pub struct VMM { vcpus: Vec, iface_host_addr: Ipv4Addr, - network: Ipv4Addr, netmask: Ipv4Addr, iface_guest_addr: Ipv4Addr, net_devices: Vec>>, @@ -72,7 +71,6 @@ impl VMM { /// Create a new VMM. pub fn new( iface_host_addr: Ipv4Addr, - network: Ipv4Addr, netmask: Ipv4Addr, iface_guest_addr: Ipv4Addr, ) -> Result { @@ -118,7 +116,6 @@ impl VMM { slip_pty: Arc::new(Mutex::new(slip_pty)), epoll, iface_host_addr, - network, netmask, iface_guest_addr, net_devices: Vec::new(), @@ -390,7 +387,6 @@ impl VMM { self.device_mgr.clone(), mmio_cfg, self.iface_host_addr, - self.network, self.netmask, self.iface_guest_addr, irq, diff --git a/src/vmm/src/grpc/server.rs b/src/vmm/src/grpc/server.rs index 6383c29..e5c6919 100644 --- a/src/vmm/src/grpc/server.rs +++ b/src/vmm/src/grpc/server.rs @@ -51,7 +51,6 @@ impl VmmServiceTrait for VmmService { const HOST_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 1); const HOST_NETMASK: Ipv4Addr = Ipv4Addr::new(255, 255, 0, 0); - const NETWORK: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 0); const GUEST_IP: Ipv4Addr = Ipv4Addr::new(172, 29, 0, 2); // get current directory @@ -158,8 +157,7 @@ impl VmmServiceTrait for VmmService { } let initramfs_path = PathBuf::from(&initramfs_entire_file_path); - let mut vmm = - VMM::new(HOST_IP, NETWORK, HOST_NETMASK, GUEST_IP).map_err(VmmErrors::VmmNew)?; + let mut vmm = VMM::new(HOST_IP, HOST_NETMASK, GUEST_IP).map_err(VmmErrors::VmmNew)?; // Configure the VMM parameters might need to be calculated rather than hardcoded vmm.configure(1, 4000, kernel_path, &Some(initramfs_path)) diff --git a/src/vmm/src/main.rs b/src/vmm/src/main.rs index 364a377..7f6a748 100644 --- a/src/vmm/src/main.rs +++ b/src/vmm/src/main.rs @@ -42,7 +42,6 @@ async fn main() -> Result<(), Box> { // Create a new VMM let mut vmm = VMM::new( cli_args.iface_host_addr, - cli_args.network, cli_args.netmask, cli_args.iface_guest_addr, )