Skip to content

Commit 55bcafe

Browse files
committed
use --virtio-net,unixgram=<path>,offloading=<on|off> to call krun_add_net_unixgram
Signed-off-by: Jake Correnti <jakecorrenti+github@proton.me>
1 parent b78153a commit 55bcafe

1 file changed

Lines changed: 108 additions & 19 deletions

File tree

src/virtio.rs

Lines changed: 108 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::cmdline::{check_required_args, check_unknown_args, parse_args};
44

55
use std::{
6-
ffi::{c_char, CString},
6+
ffi::{c_char, c_int, CString},
77
os::unix::ffi::OsStrExt,
88
path::{Path, PathBuf},
99
str::FromStr,
@@ -12,6 +12,28 @@ use std::{
1212
use anyhow::{anyhow, Context, Result};
1313
use mac_address::MacAddress;
1414

15+
/* Taken from uapi/linux/virtio_net.h */
16+
const NET_FEATURE_CSUM: u32 = 1 << 0;
17+
const NET_FEATURE_GUEST_CSUM: u32 = 1 << 1;
18+
const NET_FEATURE_GUEST_TSO4: u32 = 1 << 7;
19+
const NET_FEATURE_GUEST_TSO6: u32 = 1 << 8;
20+
const NET_FEATURE_GUEST_UFO: u32 = 1 << 10;
21+
const NET_FEATURE_HOST_TSO4: u32 = 1 << 11;
22+
const NET_FEATURE_HOST_TSO6: u32 = 1 << 12;
23+
const NET_FEATURE_HOST_UFO: u32 = 1 << 14;
24+
/*
25+
* These are the flags enabled by default on each virtio-net instance
26+
* before the introduction of "krun_add_net_*". They are now used in
27+
* the legacy API ("krun_set_passt_fd" and "krun_set_gvproxy_path")
28+
* for compatiblity reasons.
29+
*/
30+
const NET_COMPAT_FEATURES: u32 = NET_FEATURE_CSUM
31+
| NET_FEATURE_GUEST_CSUM
32+
| NET_FEATURE_GUEST_TSO4
33+
| NET_FEATURE_GUEST_UFO
34+
| NET_FEATURE_HOST_TSO4
35+
| NET_FEATURE_HOST_UFO;
36+
1537
#[link(name = "krun-efi")]
1638
extern "C" {
1739
fn krun_add_disk2(
@@ -26,6 +48,14 @@ extern "C" {
2648
fn krun_set_gvproxy_path(ctx_id: u32, c_path: *const c_char) -> i32;
2749
fn krun_set_net_mac(ctx_id: u32, c_mac: *const u8) -> i32;
2850
fn krun_set_console_output(ctx_id: u32, c_filepath: *const c_char) -> i32;
51+
fn krun_add_net_unixgram(
52+
ctx_id: u32,
53+
c_path: *const c_char,
54+
fd: c_int,
55+
c_mac: *const u8,
56+
features: u32,
57+
flags: u32,
58+
) -> i32;
2959
}
3060

3161
#[repr(u32)]
@@ -296,11 +326,18 @@ impl FromStr for VsockAction {
296326
}
297327
}
298328

329+
#[derive(Clone, Debug, PartialEq, Eq)]
330+
pub enum SocketConfig {
331+
/// Path to the gvproxy socket
332+
UnixSocketPath(PathBuf),
333+
UnixGram(PathBuf, bool, bool),
334+
}
335+
299336
/// Configuration of a virtio-net device.
300-
#[derive(Clone, Debug, Default, PartialEq)]
337+
#[derive(Clone, Debug, PartialEq)]
301338
pub struct NetConfig {
302-
/// Path to underlying gvproxy socket.
303-
pub unix_socket_path: PathBuf,
339+
/// Socket configuration
340+
pub socket: SocketConfig,
304341

305342
/// Network MAC address.
306343
pub mac_address: MacAddress,
@@ -310,17 +347,45 @@ impl FromStr for NetConfig {
310347
type Err = anyhow::Error;
311348

312349
fn from_str(s: &str) -> Result<Self, Self::Err> {
313-
let mut net_config = Self::default();
314350
let mut args = parse_args(s.to_string())?;
315-
check_required_args(&args, "virtio-net", &["unixSocketPath", "mac"])?;
316351

317-
let unix_socket_path = args.remove("unixSocketPath").unwrap();
318-
net_config.unix_socket_path = PathBuf::from_str(unix_socket_path.as_str())
319-
.context("unixSocketPath argument not a valid path")?;
352+
let socket = if args.contains_key("unixSocketPath") {
353+
check_required_args(&args, "virtio-net", &["mac"])?;
354+
let path = args.remove("unixSocketPath").unwrap();
355+
356+
SocketConfig::UnixSocketPath(
357+
PathBuf::from_str(path.as_str())
358+
.context("unixSocketPath argument is not a valid path")?,
359+
)
360+
} else if args.contains_key("unixgram") {
361+
check_required_args(&args, "virtio-net", &["mac", "offloading"])?;
362+
let path = args.remove("unixgram").unwrap();
363+
let offloading = args.remove("offloading").unwrap();
364+
let send_vfkit_magic = if args.contains_key("vfkitMagic") {
365+
args.remove("vfkitMagic").unwrap().parse::<bool>()?
366+
} else {
367+
false
368+
};
369+
370+
SocketConfig::UnixGram(
371+
PathBuf::from_str(path.as_str())
372+
.context("unixSocketPath argument is not a valid path")?,
373+
offloading.parse::<bool>()?,
374+
send_vfkit_magic,
375+
)
376+
} else {
377+
return Err(anyhow!(
378+
"virtio-net device is missing a socket path argument"
379+
));
380+
};
320381

321382
let mac = args.remove("mac").unwrap();
322-
net_config.mac_address = MacAddress::from_str(mac.as_str())
323-
.context("unable to parse mac address from argument")?;
383+
384+
let net_config = NetConfig {
385+
socket,
386+
mac_address: MacAddress::from_str(mac.as_str())
387+
.context("unable to parse mac address from argument")?,
388+
};
324389

325390
check_unknown_args(args, "virtio-net")?;
326391

@@ -331,15 +396,39 @@ impl FromStr for NetConfig {
331396
/// Set the gvproxy's path and network MAC address.
332397
impl KrunContextSet for NetConfig {
333398
unsafe fn krun_ctx_set(&self, id: u32) -> Result<(), anyhow::Error> {
334-
let path_cstr = path_to_cstring(&self.unix_socket_path)?;
335-
let mac = self.mac_address.bytes();
336-
337-
if krun_set_gvproxy_path(id, path_cstr.as_ptr()) < 0 {
338-
return Err(anyhow!(format!(
339-
"unable to set gvproxy path {}",
340-
&self.unix_socket_path.display()
341-
)));
399+
match &self.socket {
400+
SocketConfig::UnixSocketPath(path) => {
401+
let path_cstr = path_to_cstring(path)?;
402+
if krun_set_gvproxy_path(id, path_cstr.as_ptr()) < 0 {
403+
return Err(anyhow!(format!(
404+
"unable to set gvproxy path {}",
405+
path_cstr.into_string().unwrap(),
406+
)));
407+
}
408+
}
409+
SocketConfig::UnixGram(path, offloading, send_vfkit_magic) => {
410+
let path_cstr = path_to_cstring(path)?;
411+
let features = if *offloading { NET_COMPAT_FEATURES } else { 0 };
412+
413+
if krun_add_net_unixgram(
414+
id,
415+
path_cstr.as_ptr(),
416+
-1,
417+
self.mac_address.bytes().as_ptr(),
418+
features,
419+
// Send the VFKIT magic after establishing the connection,
420+
// as required by gvproxy in vfkit mode.
421+
*send_vfkit_magic as u32,
422+
) < 0
423+
{
424+
return Err(anyhow!(format!(
425+
"unable to add unixgram {}",
426+
path_cstr.into_string().unwrap(),
427+
)));
428+
}
429+
}
342430
}
431+
let mac = self.mac_address.bytes();
343432

344433
if krun_set_net_mac(id, mac.as_ptr()) < 0 {
345434
return Err(anyhow!(format!(

0 commit comments

Comments
 (0)