From 908283526230f7daca724e334d50f78dd6884344 Mon Sep 17 00:00:00 2001 From: Nulo Date: Sat, 24 Jun 2023 16:19:26 -0300 Subject: [PATCH] networking dentro de las VMs --- rootfs/init/Cargo.lock | 441 +++++++++++++++++++++++++++++++++++++++- rootfs/init/Cargo.toml | 4 + rootfs/init/src/main.rs | 176 ++++++++++++++-- server/index.js | 41 +++- server/package.json | 2 +- 5 files changed, 643 insertions(+), 21 deletions(-) diff --git a/rootfs/init/Cargo.lock b/rootfs/init/Cargo.lock index db3cebb..f5405cb 100644 --- a/rootfs/init/Cargo.lock +++ b/rootfs/init/Cargo.lock @@ -2,12 +2,36 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + [[package]] name = "cc" version = "1.0.79" @@ -20,13 +44,114 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "init" version = "0.1.0" dependencies = [ - "nix", + "futures", + "nix 0.19.1", + "rtnetlink", "serde", "serde_json", + "tokio", ] [[package]] @@ -41,6 +166,95 @@ version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "netlink-packet-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5cf0b54effda4b91615c40ff0fd12d0d4c9a6e0f5116874f03941792ff535a" +dependencies = [ + "anyhow", + "byteorder", + "libc", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea993e32c77d87f01236c38f572ecb6c311d592e56a06262a007fd2a6e31253c" +dependencies = [ + "anyhow", + "bitflags", + "byteorder", + "libc", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-utils" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror", +] + +[[package]] +name = "netlink-proto" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26305d12193227ef7b8227e7d61ae4eaf174607f79bd8eeceff07aacaefde497" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror", + "tokio", +] + +[[package]] +name = "netlink-sys" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6471bf08e7ac0135876a9581bf3217ef0333c191c128d34878079f42ee150411" +dependencies = [ + "bytes", + "futures", + "libc", + "log", + "tokio", +] + [[package]] name = "nix" version = "0.19.1" @@ -53,6 +267,46 @@ dependencies = [ "libc", ] +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "static_assertions", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "paste" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "proc-macro2" version = "1.0.60" @@ -71,6 +325,24 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rtnetlink" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7d42da676fdf7e470e2502717587dd1089d8b48d9d1b846dcc3c01072858cb" +dependencies = [ + "futures", + "log", + "netlink-packet-core", + "netlink-packet-route", + "netlink-packet-utils", + "netlink-proto", + "netlink-sys", + "nix 0.26.2", + "thiserror", + "tokio", +] + [[package]] name = "ryu" version = "1.0.13" @@ -108,6 +380,31 @@ dependencies = [ "serde", ] +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "syn" version = "2.0.18" @@ -119,8 +416,150 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio" +version = "1.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +dependencies = [ + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "unicode-ident" version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" diff --git a/rootfs/init/Cargo.toml b/rootfs/init/Cargo.toml index 5314b56..63c4ebd 100644 --- a/rootfs/init/Cargo.toml +++ b/rootfs/init/Cargo.toml @@ -9,3 +9,7 @@ edition = "2021" serde = { version = "1.0.164", features = ["derive"] } serde_json = "1.0.97" nix = "0.19" +rtnetlink = { version = "0.12.0" } +tokio = { version = "1.0", features = ["macros", "rt", "rt-multi-thread"] } +futures = "0.3.28" + diff --git a/rootfs/init/src/main.rs b/rootfs/init/src/main.rs index 4c54768..b346ce1 100644 --- a/rootfs/init/src/main.rs +++ b/rootfs/init/src/main.rs @@ -1,7 +1,9 @@ +use futures::TryStreamExt; use nix::mount::MsFlags; use serde::{Deserialize, Serialize}; use std::fs; -use std::{env, io, os::unix, path::Path, process}; +use std::net::Ipv4Addr; +use std::{env, io, io::Write, iter::Iterator, os::unix, path::Path, process}; // inspirado en https://github.com/superfly/init-snapshot/blob/public/src/bin/init/main.rs#L230 #[derive(Serialize, Deserialize, Debug)] @@ -18,26 +20,19 @@ struct ImageConfig { config: Config, } -fn main() -> Result<(), io::Error> { - let src_path = "/image_root"; - fs::create_dir_all(src_path)?; - - nix::mount::mount::<_, _, _, [u8]>( - Some("/dev/vdb"), - src_path, - Some("squashfs"), - MsFlags::MS_RDONLY, - None, - ) - .unwrap(); - - let config_file = Path::new(&src_path).join(".fireactions-image-config.json"); +#[tokio::main] +async fn main() -> Result<(), io::Error> { + let new_root = mount_new_root()?; + // TODO: move to after chroot after we start mounting /proc (uses /proc/cmdline) + setup_net_interface() + .await + .expect("couldn't set up network interace"); + let config_file = Path::new(&new_root).join(".fireactions-image-config.json"); let config_text = fs::read(config_file)?; let config: ImageConfig = serde_json::from_slice(&config_text).unwrap(); - println!("{:#?}", config); - unix::fs::chroot(src_path)?; + unix::fs::chroot(new_root)?; env::set_current_dir("/")?; // https://github.com/opencontainers/image-spec/blob/b5ec432b1c946c09e1568b18ef70b654a93739f6/conversion.md#verbatim-fields @@ -52,6 +47,10 @@ fn main() -> Result<(), io::Error> { } }; + // TODO: setup hostname + // TODO: setup /etc/hosts + populate_resolvconf()?; + let mut child = process::Command::new(&args[0]) .args(&args[1..]) .env_clear() @@ -66,3 +65,146 @@ fn main() -> Result<(), io::Error> { .unwrap(); Ok(()) } + +// async fn get_link(handle: &rtnetlink::Handle, name: &'static str) -> _ { +// handle +// .link() +// .get() +// .match_name(name.to_string()) +// .execute() +// .try_next() +// .await +// .expect("no lo link found") +// } + +async fn setup_net_interface() -> Result<(), rtnetlink::Error> { + let (connection, handle, _) = rtnetlink::new_connection().unwrap(); + tokio::spawn(connection); + + println!("netlink: getting lo link"); + let lo = handle + .link() + .get() + .match_name("lo".to_string()) + .execute() + .try_next() + .await? + .expect("no lo link found"); + + println!("netlink: setting lo link \"up\""); + handle.link().set(lo.header.index).up().execute().await?; + + let cmdline = fs::read("/proc/cmdline").expect("couldn't read /proc/cmdline"); + let (guest_addr, host_addr) = cmdline + .split(|c| *c == b' ') + .map(|keyval| std::str::from_utf8(keyval).unwrap().split_once("=")) + .filter_map(|o| o) + .find(|(key, _)| *key == "fireactions_ip") + .expect("didn't find fireactions_ip cmdline") + .1 + .split_once(":") + .unwrap(); + + println!("netlink: getting eth0 link"); + let eth0 = handle + .link() + .get() + .match_name("eth0".to_string()) + .execute() + .try_next() + .await? + .expect("no eth0 link found"); + + println!("netlink: setting eth0 link \"up\""); + handle + .link() + .set(eth0.header.index) + .up() + .mtu(1420) + .execute() + .await?; + + // XXX: la impl en init-snapshot es sketchy. pareciera que lo Ășnico que hace + // es desactivar el chequeo de checksum de paquetes, osea una mejora de perf. + // let _ = ethtool_set("eth0", ETHTOOL_SRXCSUM, 0); + // ethtool_set("eth0", ETHTOOL_STXCSUM, 0)?; + + println!("netlink: adding ip"); + let address = handle.address(); + address + .add(eth0.header.index, guest_addr.parse().unwrap(), 24) + .execute() + .await?; + + println!("netlink: adding route"); + let route = handle.route(); + route + .add() + .v4() + .gateway(host_addr.parse().unwrap()) + .execute() + .await?; + // TODO: ipv6 + + Ok(()) +} + +fn populate_resolvconf() -> Result<(), io::Error> { + let mut file = fs::OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open("/etc/resolv.conf")?; + // XXX: usar otro DNS? + write!(&mut file, "nameserver\t{}\n", "1.1.1.1") +} + +fn mount_new_root() -> Result<&'static str, io::Error> { + // process::Command::new("modprobe") + // .args(&["overlay"]) + // .spawn()? + // .wait()?; + + let image_root = "/image_src"; + fs::create_dir_all(image_root)?; + nix::mount::mount::<_, _, _, [u8]>( + Some("/dev/vdb"), + image_root, + Some("squashfs"), + MsFlags::MS_RDONLY, + None, + ) + .unwrap(); + + let tmp_rw = "/tmp_rw"; + fs::create_dir_all(tmp_rw)?; + nix::mount::mount::<_, _, _, [u8]>( + Some("overlaytemp"), + tmp_rw, + Some("tmpfs"), + MsFlags::empty(), + None, + ) + .unwrap(); + let tmp_upper = "/tmp_rw/upper"; + fs::create_dir_all(tmp_upper)?; + let tmp_work = "/tmp_rw/work"; + fs::create_dir_all(tmp_work)?; + + let new_root = "/new_root"; + fs::create_dir_all(new_root)?; + let overlay_opts = format!( + "lowerdir={},upperdir={},workdir={}", + image_root, tmp_upper, tmp_work + ); + nix::mount::mount::<_, _, _, [u8]>( + Some("overlay-root"), + new_root, + Some("overlay"), + MsFlags::empty(), + Some(overlay_opts.as_bytes()), + ) + .unwrap(); + + Ok(new_root) +} diff --git a/server/index.js b/server/index.js index 5284ccd..71c875e 100644 --- a/server/index.js +++ b/server/index.js @@ -1,10 +1,12 @@ import { delay } from "nanodelay"; import { nanoid } from "nanoid"; -import { spawn } from "node:child_process"; +import { spawn, execFile as _execFile } from "node:child_process"; import { createServer, request as _request } from "node:http"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { downloadImage, parseImageRef } from "./container-baby.js"; +import { promisify } from "node:util"; +const execFile = promisify(_execFile); const server = createServer(listener); @@ -83,9 +85,11 @@ class FirecrackerInstance { // TODO: retry until success await delay(15); + const { ifname, hostAddr, guestAddr } = await createNetworkInterface(); + await self.request("PUT", "/boot-source", { kernel_image_path: "../vmlinux.bin", - boot_args: "console=ttyS0 reboot=k panic=1 pci=off", + boot_args: `console=ttyS0 reboot=k panic=1 pci=off fireactions_ip=${guestAddr}:${hostAddr}`, }); await self.request("PUT", "/drives/rootfs", { drive_id: "rootfs", @@ -99,6 +103,11 @@ class FirecrackerInstance { await self.request("PUT", "/drives/" + drive.drive_id, drive); } } + await self.request("PUT", "/network-interfaces/eth0", { + iface_id: "eth0", + guest_mac: "AA:FC:00:00:00:01", + host_dev_name: ifname, + }); // API requests are handled asynchronously, it is important the configuration is // set, before `InstanceStart`. @@ -175,4 +184,32 @@ function request(opts, body) { }); } +/** + * @type {string[]} + */ +let interfaces = []; +let ifIndex = 2; +async function createNetworkInterface() { + const ifname = "f" + nanoid(13); + await execFile("ip", ["tuntap", "add", ifname, "mode", "tap"]); + interfaces.push(ifname); + + const hostAddr = `172.16.0.${ifIndex}`; + const guestAddr = `172.16.0.${ifIndex + 1}`; + ifIndex += 2; + + await execFile("ip", ["addr", "add", `${hostAddr}/31`, "dev", ifname]); + await execFile("ip", ["link", "set", ifname, "up"]); + // TODO: setup masquerade + + return { hostAddr, guestAddr, ifname }; +} + +process.on("beforeExit", async () => { + for (const ifname of interfaces) { + await execFile("ip", ["tuntap", "del", ifname, "mode", "tap"]); + } + process.exit(0); +}); + server.listen("8080"); diff --git a/server/package.json b/server/package.json index 3c2b706..3d6449e 100644 --- a/server/package.json +++ b/server/package.json @@ -5,7 +5,7 @@ "description": "", "main": "index.js", "scripts": { - "start": "esbuild --bundle index.js --platform=node --sourcemap > build.cjs && node --enable-source-maps build.cjs" + "start": "esbuild --bundle index.js --platform=node --sourcemap > build.cjs && sudo node --enable-source-maps build.cjs" }, "keywords": [], "author": "",