1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
| | // SPDX-License-Identifier: EUPL-1.2+
// SPDX-FileCopyrightText: 2025 Yureka Lilian <yureka@cyberchaos.dev>
// SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is>
pub(crate) mod packet;
pub(crate) mod protocol;
mod router;
mod upstream;
use packet::*;
use router::{InterfaceId, Router};
use upstream::Upstream;
use anyhow::anyhow;
use futures_util::{SinkExt, TryStreamExt};
use listenfd::ListenFd;
use log::{error, info};
use tokio::net::UnixListener;
use vhost_device_net::{IncomingPacket, VhostDeviceNet};
use vm_memory::GuestMemoryMmap;
fn main() -> anyhow::Result<()> {
env_logger::init();
run_router()
}
#[tokio::main(flavor = "current_thread")]
async fn run_router() -> anyhow::Result<()> {
let mut listenfd = ListenFd::from_env();
let Some(driver_listener) = listenfd.take_unix_listener(0)? else {
return Err(anyhow!("not activated with driver socket"));
};
let Some(app_listener) = listenfd.take_unix_listener(1)? else {
return Err(anyhow!("not activated with app socket"));
};
let driver_listener = UnixListener::from_std(driver_listener)?;
let app_listener = UnixListener::from_std(app_listener)?;
let mut router = Router::<GuestMemoryMmap>::new(InterfaceId::Upstream);
let (mut upstream, upstream_tx, upstream_rx) = Upstream::new(driver_listener);
router.add_iface(InterfaceId::Upstream, upstream_tx, upstream_rx);
tokio::spawn(async move { upstream.run().await });
let mut app_num = 0;
loop {
tokio::select! {
app_conn = app_listener.accept() => {
info!("app connected");
match app_conn {
Ok((stream, _addr)) => {
let device = VhostDeviceNet::from_unix_stream(stream).await?;
let stream = Box::pin(device.tx().await?.map_ok(|buf| Packet::Incoming { buf: Some(buf), decap_vlan: false }));
let sink = Box::pin(device.rx().await?.with(|packet: Packet<IncomingPacket<GuestMemoryMmap>>| async move { Ok(packet.out(None)?.into_reader()) }));
router.add_iface(InterfaceId::App(app_num), stream, sink);
app_num = app_num.checked_add(1).unwrap();
}
Err(e) => error!("app connection failed: {}", e),
}
}
_ = router.run() => {}
}
}
}
|