Skip to content

Commit 28e2f81

Browse files
authored
Merge branch 'main' into pipewire
2 parents 323d7ec + 8330325 commit 28e2f81

File tree

11 files changed

+344
-103
lines changed

11 files changed

+344
-103
lines changed

include/libkrun.h

+15
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,21 @@ int32_t krun_set_tee_config_file(uint32_t ctx_id, const char *filepath);
441441
int32_t krun_add_vsock_port(uint32_t ctx_id,
442442
uint32_t port,
443443
const char *c_filepath);
444+
445+
/**
446+
* Adds a port-path pairing for guest IPC with a process in the host.
447+
*
448+
* Arguments:
449+
* "ctx_id" - the configuration context ID.
450+
* "port" - a vsock port that the guest will connect to for IPC.
451+
* "filepath" - a null-terminated string representing the path of the UNIX
452+
* socket in the host.
453+
* "listen" - true if guest expects connections to be initiated from host side
454+
*/
455+
int32_t krun_add_vsock_port2(uint32_t ctx_id,
456+
uint32_t port,
457+
const char *c_filepath,
458+
bool listen);
444459
/**
445460
* Returns the eventfd file descriptor to signal the guest to shut down orderly. This must be
446461
* called before starting the microVM with "krun_start_event". Only available in libkrun-efi.

src/devices/src/virtio/queue.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,7 @@ impl<'a> DescriptorChain<'a> {
230230
return None;
231231
}
232232

233-
let desc_head = match mem.checked_offset(desc_table, (index as usize) * 16) {
234-
Some(a) => a,
235-
None => return None,
236-
};
233+
let desc_head = mem.checked_offset(desc_table, (index as usize) * 16)?;
237234
mem.checked_offset(desc_head, 16)?;
238235

239236
// These reads can't fail unless Guest memory is hopelessly broken.

src/devices/src/virtio/vsock/device.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl Vsock {
5959
cid: u64,
6060
host_port_map: Option<HashMap<u16, u16>>,
6161
queues: Vec<VirtQueue>,
62-
unix_ipc_port_map: Option<HashMap<u32, PathBuf>>,
62+
unix_ipc_port_map: Option<HashMap<u32, (PathBuf, bool)>>,
6363
) -> super::Result<Vsock> {
6464
let mut queue_events = Vec::new();
6565
for _ in 0..queues.len() {
@@ -103,7 +103,7 @@ impl Vsock {
103103
pub fn new(
104104
cid: u64,
105105
host_port_map: Option<HashMap<u16, u16>>,
106-
unix_ipc_port_map: Option<HashMap<u32, PathBuf>>,
106+
unix_ipc_port_map: Option<HashMap<u32, (PathBuf, bool)>>,
107107
) -> super::Result<Vsock> {
108108
let queues: Vec<VirtQueue> = defs::QUEUE_SIZES
109109
.iter()

src/devices/src/virtio/vsock/muxer.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub struct VsockMuxer {
111111
irq_line: Option<u32>,
112112
proxy_map: ProxyMap,
113113
reaper_sender: Option<Sender<u64>>,
114-
unix_ipc_port_map: Option<HashMap<u32, PathBuf>>,
114+
unix_ipc_port_map: Option<HashMap<u32, (PathBuf, bool)>>,
115115
}
116116

117117
impl VsockMuxer {
@@ -120,7 +120,7 @@ impl VsockMuxer {
120120
host_port_map: Option<HashMap<u16, u16>>,
121121
interrupt_evt: EventFd,
122122
interrupt_status: Arc<AtomicUsize>,
123-
unix_ipc_port_map: Option<HashMap<u32, PathBuf>>,
123+
unix_ipc_port_map: Option<HashMap<u32, (PathBuf, bool)>>,
124124
) -> Self {
125125
VsockMuxer {
126126
cid,
@@ -179,6 +179,7 @@ impl VsockMuxer {
179179
intc,
180180
irq_line,
181181
sender.clone(),
182+
self.unix_ipc_port_map.clone().unwrap_or_default(),
182183
);
183184
thread.run();
184185

@@ -499,9 +500,18 @@ impl VsockMuxer {
499500
if let Some(proxy) = proxy_map.get(&id) {
500501
proxy.lock().unwrap().confirm_connect(pkt)
501502
} else if let Some(ref mut ipc_map) = &mut self.unix_ipc_port_map {
502-
if let Some(path) = ipc_map.get(&pkt.dst_port()) {
503+
if let Some((path, listen)) = ipc_map.get(&pkt.dst_port()) {
503504
let mem = self.mem.as_ref().unwrap();
504505
let queue = self.queue.as_ref().unwrap();
506+
if *listen {
507+
warn!("vsock: Attempting to connect a socket that is listening, sending rst");
508+
let rx = MuxerRx::Reset {
509+
local_port: pkt.dst_port(),
510+
peer_port: pkt.src_port(),
511+
};
512+
push_packet(self.cid, rx, &self.rxq, queue, mem);
513+
return;
514+
}
505515
let rxq = self.rxq.clone();
506516

507517
let mut unix = UnixProxy::new(

src/devices/src/virtio/vsock/muxer_thread.rs

+57-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use std::collections::HashMap;
12
use std::os::unix::io::RawFd;
3+
use std::path::PathBuf;
24
use std::sync::atomic::{AtomicUsize, Ordering};
35
use std::sync::{Arc, Mutex};
46
use std::thread;
@@ -8,9 +10,11 @@ use super::super::Queue as VirtQueue;
810
use super::super::VIRTIO_MMIO_INT_VRING;
911
use super::muxer::{push_packet, MuxerRx, ProxyMap};
1012
use super::muxer_rxq::MuxerRxQ;
11-
use super::proxy::{ProxyRemoval, ProxyUpdate};
13+
use super::proxy::{NewProxyType, Proxy, ProxyRemoval, ProxyUpdate};
1214
use super::tcp::TcpProxy;
1315

16+
use crate::virtio::vsock::defs;
17+
use crate::virtio::vsock::unix::{UnixAcceptorProxy, UnixProxy};
1418
use crossbeam_channel::Sender;
1519
use rand::{rngs::ThreadRng, thread_rng, Rng};
1620
use utils::epoll::{ControlOperation, Epoll, EpollEvent, EventSet};
@@ -29,6 +33,7 @@ pub struct MuxerThread {
2933
intc: Option<GicV3>,
3034
irq_line: Option<u32>,
3135
reaper_sender: Sender<u64>,
36+
unix_ipc_port_map: HashMap<u32, (PathBuf, bool)>,
3237
}
3338

3439
impl MuxerThread {
@@ -45,6 +50,7 @@ impl MuxerThread {
4550
intc: Option<GicV3>,
4651
irq_line: Option<u32>,
4752
reaper_sender: Sender<u64>,
53+
unix_ipc_port_map: HashMap<u32, (PathBuf, bool)>,
4854
) -> Self {
4955
MuxerThread {
5056
cid,
@@ -58,6 +64,7 @@ impl MuxerThread {
5864
intc,
5965
irq_line,
6066
reaper_sender,
67+
unix_ipc_port_map,
6168
}
6269
}
6370

@@ -111,24 +118,36 @@ impl MuxerThread {
111118

112119
let mut should_signal = update.signal_queue;
113120

114-
if let Some((peer_port, accept_fd)) = update.new_proxy {
121+
if let Some((peer_port, accept_fd, proxy_type)) = update.new_proxy {
115122
let local_port: u32 = thread_rng.gen_range(1024..u32::MAX);
116123
let new_id: u64 = (peer_port as u64) << 32 | local_port as u64;
117-
let new_proxy = TcpProxy::new_reverse(
118-
new_id,
119-
self.cid,
120-
id,
121-
local_port,
122-
peer_port,
123-
accept_fd,
124-
self.mem.clone(),
125-
self.queue.clone(),
126-
self.rxq.clone(),
127-
);
124+
let new_proxy: Box<dyn Proxy> = match proxy_type {
125+
NewProxyType::Tcp => Box::new(TcpProxy::new_reverse(
126+
new_id,
127+
self.cid,
128+
id,
129+
local_port,
130+
peer_port,
131+
accept_fd,
132+
self.mem.clone(),
133+
self.queue.clone(),
134+
self.rxq.clone(),
135+
)),
136+
NewProxyType::Unix => Box::new(UnixProxy::new_reverse(
137+
new_id,
138+
self.cid,
139+
local_port,
140+
peer_port,
141+
accept_fd,
142+
self.mem.clone(),
143+
self.queue.clone(),
144+
self.rxq.clone(),
145+
)),
146+
};
128147
self.proxy_map
129148
.write()
130149
.unwrap()
131-
.insert(new_id, Mutex::new(Box::new(new_proxy)));
150+
.insert(new_id, Mutex::new(new_proxy));
132151
if let Some(proxy) = self.proxy_map.read().unwrap().get(&new_id) {
133152
proxy.lock().unwrap().push_op_request();
134153
};
@@ -147,8 +166,32 @@ impl MuxerThread {
147166
}
148167
}
149168

169+
fn create_lisening_ipc_sockets(&self) {
170+
for (port, (path, do_listen)) in &self.unix_ipc_port_map {
171+
if !do_listen {
172+
continue;
173+
}
174+
let id = (*port as u64) << 32 | defs::TSI_PROXY_PORT as u64;
175+
let proxy = match UnixAcceptorProxy::new(id, path, *port) {
176+
Ok(proxy) => proxy,
177+
Err(e) => {
178+
warn!("Failed to create listening proxy at {:?}: {:?}", path, e);
179+
continue;
180+
}
181+
};
182+
self.proxy_map
183+
.write()
184+
.unwrap()
185+
.insert(id, Mutex::new(Box::new(proxy)));
186+
if let Some(proxy) = self.proxy_map.read().unwrap().get(&id) {
187+
self.update_polling(id, proxy.lock().unwrap().as_raw_fd(), EventSet::IN);
188+
};
189+
}
190+
}
191+
150192
fn work(self) {
151193
let mut thread_rng = thread_rng();
194+
self.create_lisening_ipc_sockets();
152195
loop {
153196
let mut epoll_events = vec![EpollEvent::new(EventSet::empty(), 0); 32];
154197
match self

src/devices/src/virtio/vsock/proxy.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,19 @@ pub enum ProxyRemoval {
4141
Deferred,
4242
}
4343

44+
#[derive(Default)]
45+
pub enum NewProxyType {
46+
#[default]
47+
Tcp,
48+
Unix,
49+
}
50+
4451
#[derive(Default)]
4552
pub struct ProxyUpdate {
4653
pub signal_queue: bool,
4754
pub remove_proxy: ProxyRemoval,
4855
pub polling: Option<(u64, RawFd, EventSet)>,
49-
pub new_proxy: Option<(u32, RawFd)>,
56+
pub new_proxy: Option<(u32, RawFd, NewProxyType)>,
5057
pub push_accept: Option<(u64, u64)>,
5158
pub push_credit_req: Option<MuxerRx>,
5259
}

src/devices/src/virtio/vsock/tcp.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ use super::muxer_rxq::MuxerRxQ;
2121
use super::packet::{
2222
TsiAcceptReq, TsiConnectReq, TsiGetnameRsp, TsiListenReq, TsiSendtoAddr, VsockPacket,
2323
};
24-
use super::proxy::{Proxy, ProxyError, ProxyRemoval, ProxyStatus, ProxyUpdate, RecvPkt};
24+
use super::proxy::{
25+
NewProxyType, Proxy, ProxyError, ProxyRemoval, ProxyStatus, ProxyUpdate, RecvPkt,
26+
};
2527
use utils::epoll::EventSet;
2628

2729
use vm_memory::GuestMemoryMmap;
@@ -729,7 +731,7 @@ impl Proxy for TcpProxy {
729731
{
730732
match accept(self.fd) {
731733
Ok(accept_fd) => {
732-
update.new_proxy = Some((self.peer_port, accept_fd));
734+
update.new_proxy = Some((self.peer_port, accept_fd, NewProxyType::Tcp));
733735
}
734736
Err(e) => warn!("error accepting connection: id={}, err={}", self.id, e),
735737
};

0 commit comments

Comments
 (0)