Skip to content

Commit f123988

Browse files
committed
devices/vsock: documentation and changelog update
Updated CHANGELOG.md to reflect the vsock implementation change, and added a vsock how-to doc in `docs/vsock.md`. Signed-off-by: Dan Horobeanu <[email protected]>
1 parent c99c0cc commit f123988

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@
22

33
## [Unreleased]
44

5+
### Added
6+
7+
- New device: virtio-vsock, backed by Unix domain sockets. See
8+
`docs/vsock.md`.
9+
510
### Fixed
611

712
- Corrected firecracker-experimental.yaml indentation issues that
813
prevented code generation.
914
- Updated the documentation for integration tests.
1015

16+
### Removed
17+
- Removed experimental support for vhost-based vsock devices.
18+
1119
## [0.17.0]
1220

1321
### Added

docs/vsock.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Using the Firecracker Virtio-vsock Device
2+
3+
## Table of Contents
4+
5+
- [Prerequisites](#prerequisites)
6+
- [Firecracker Virtio-vsock Design](#firecracker-virtio-vsock-design)
7+
- [Setting up the Virtio-vsock Device](#setting-up-the-virtio-vsock-device)
8+
- [Examples](#examples)
9+
10+
## Prerequisites
11+
12+
This document assumes the reader is familiar with running Firecracker and
13+
issuing API commands over its API socket. For a more details on how to run
14+
Firecracker, check out the [getting started guide](getting-started.md).
15+
16+
Familiarty with socket programming, in particular Unix sockets, is also
17+
assumed.
18+
19+
## Firecracker Virtio-vsock Design
20+
21+
The Firecracker vsock device aims to provide full virtio-vsock support to
22+
software running inside the guest VM, while bypassing vhost kernel code on the
23+
host. To that end, Firecracker implements the virtio-vsock device model, and
24+
mediate communication between AF_UNIX sockets (on the host end) and AF_VSOCK
25+
sockets (on the guest end).
26+
27+
In order to provide channel multiplexing, AF_VSOCK ports are translated into
28+
multiple AF_UNIX sockets (one Unix socket per vsock port). The virtio-vsock
29+
device must be configured with a file path to an AF_UNIX socket (e.g.
30+
`/path/to/v.sock`). There are two scenarios to be considered, depending on
31+
where the connection is initiated.
32+
33+
### Host-Initiated Connections
34+
35+
When a microvm having a vsock device attached is started, Firecracker will
36+
begin listening on an AF_UNIX socket (e.g. `/path/to/v.sock`). When the host
37+
needs to initiate a connection, it should connect to that Unix socket, then
38+
send a connect command, in text form, specifying the destination AF_VSOCK port:
39+
"CONNECT PORT\n". Where PORT is the decimal port number, and "\n" is EOL (ASCII
40+
0x0A). Following that, the same connection will be forwarded by Firecracker to
41+
the guest software listening on that port, thus establishing the requested
42+
channel. If no one is listening, Firecracker will terminate the host
43+
connection.
44+
45+
1. Host: At VM configuration time, add a virtio-vsock device, with some path
46+
specified in `uds_path`;
47+
2. Guest: create an AF_VSOCK socket and `listen()` on `<port_num>`;
48+
3. Host: `connect()` to AF_UNIX at `uds_path`.
49+
4. Host: `send()` "CONNECT <port_num>\n".
50+
5. Guest: `accept()` the new connection.
51+
52+
The channel is established between the sockets obtained at steps 3 (host)
53+
and 5 (guest).
54+
55+
### Guest-Initiated Connections
56+
57+
When the virtio-vsock device model in Firecracker detects a connection request
58+
coming from the guest (a VIRTIO_VSOCK_OP_REQUEST packet), it tries to forward
59+
the connection to an AF_UNIX socket listening on the host, at
60+
`/path/to/v.sock_PORT` (or whatever path was configured via the `uds_path`
61+
property of the vsock device), where `PORT` is the destination port (in
62+
decimal), as specified in the connection request packet. If no such socket
63+
exists, or no one is listening on it, a connection cannot be established, and a
64+
VIRTIO_VSOCK_OP_RST packet will be sent back to the guest.
65+
66+
From the user perspective, these would be the steps taken to establish a
67+
communication channel:
68+
69+
1. Host: At VM configuration time, add a virtio-vsock device, with some
70+
`uds_path` (e.g. `/path/to/v.sock`).
71+
2. Host: create and listen on an AF_UNIX socket at `/path/to/v.sock_PORT`.
72+
3. Guest: create an AF_VSOCK socket and connect to `HOST_CID` (i.e. integer
73+
value 2) and `PORT`;
74+
4. Host: `accept()` the new connection.
75+
76+
The channel is established between the sockets obtained at steps 4 (host)
77+
and 3 (guest).
78+
79+
## Setting up the virtio-vsock device
80+
81+
The virtio-vsock device will require an ID, a CID, and the path to a backing
82+
AF_UNIX socket:
83+
84+
```bash
85+
curl -X PUT \
86+
--unix-socket ./firecracker-api.sock \
87+
/vsocks/1 \
88+
-H accept:application/json \
89+
-H content-type:application/json \
90+
-d '{
91+
"vsock_id": "1",
92+
"guest_cid": 3,
93+
"uds_path": "./v.sock"
94+
}'
95+
```
96+
97+
Once the microvm is started, Firecracker will create and start listening on the
98+
AF_UNIX socket at `uds_path`. Incoming connections will get forwarded to the
99+
guest microvm, and translated to AF_VSOCK. The destination port is expected to
100+
be specified by sending the text command "CONNECT <port_num>\n", immediately
101+
after the AF_UNIX connection is established. Connections initiated from within
102+
the guest will be forwarded to AF_UNIX sockets expected to be listening at
103+
`./v.sock_<port_num>`. I.e. a guest connection to port 52 will get forwarded to
104+
`./v.sock_52`.
105+
106+
## Examples
107+
108+
The examples below assume a running microvm, with a vsock device configured as
109+
shown [above](#setting-up-the-virtio-vsock-device).
110+
111+
112+
### Using External Socket Tools (`nc-vsock` and `socat`)
113+
114+
#### Connecting From Host to Guest
115+
116+
First, make sure the vsock port is bound and listened to on the guest side.
117+
Say, port 52:
118+
119+
```bash
120+
$ nc-vsock -l 52
121+
```
122+
123+
On the host side, connect to `./v.sock` and issue a connection request to that
124+
port:
125+
126+
```bash
127+
$ socat - UNIX-CONNECT:./v.sock
128+
CONNECT 52
129+
130+
```
131+
132+
The connection should now be established (in the above example, between
133+
`nc-vsock` on the guest side, and `socat` on the host side).
134+
135+
#### Connecting From Guest To Host
136+
137+
First make sure the AF_UNIX corresponding to your desired port is listened to
138+
on the host side:
139+
140+
```bash
141+
$ socat - UNIX-LISTEN:./v.sock_52
142+
```
143+
144+
On the guest side, create an AF_VSOCK socket and connect it to the previously
145+
chosen port on the host (CID=2):
146+
147+
```bash
148+
$ nc-vsock 2 52
149+
```

0 commit comments

Comments
 (0)