Skip to content

Commit 640e377

Browse files
mtjhrcslp
authored andcommitted
[1/4] Introduce krun_set_passt_fd API and use it in chroot_vm
For now chroot_vm is hardcoded to use /tmp/passt_1.socket as a passt socket. krun_set_passt_fd will be implemented in the next commit. Signed-off-by: Matej Hrica <[email protected]>
1 parent df6fbfa commit 640e377

File tree

3 files changed

+89
-6
lines changed

3 files changed

+89
-6
lines changed

examples/chroot_vm.c

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <stdio.h>
1010
#include <stdlib.h>
1111
#include <string.h>
12+
#include <sys/socket.h>
13+
#include <sys/un.h>
1214
#include <unistd.h>
1315
#include <libkrun.h>
1416
#include <getopt.h>
@@ -20,12 +22,19 @@
2022
#define MAX_PATH 4096
2123
#endif
2224

25+
enum net_mode {
26+
NET_MODE_PASST = 0,
27+
NET_MODE_TSI,
28+
};
29+
2330
static void print_help(char *const name)
2431
{
2532
fprintf(stderr,
2633
"Usage: %s [OPTIONS] NEWROOT COMMAND [COMMAND_ARGS...]\n"
2734
"OPTIONS: \n"
2835
" -h --help Show help\n"
36+
" --net=NET_MODE Set network mode\n"
37+
"NET_MODE can be either TSI (default) or PASST\n"
2938
"\n"
3039
"NEWROOT: the root directory of the vm\n"
3140
"COMMAND: the command you want to execute in the vm\n"
@@ -36,11 +45,13 @@ static void print_help(char *const name)
3645

3746
static const struct option long_options[] = {
3847
{ "help", no_argument, NULL, 'h' },
48+
{ "net_mode", required_argument, NULL, 'N' },
3949
{ NULL, 0, NULL, 0 }
4050
};
4151

4252
struct cmdline {
4353
bool show_help;
54+
enum net_mode net_mode;
4455
char const *new_root;
4556
char *const *guest_argv;
4657
};
@@ -52,6 +63,7 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
5263
// set the defaults
5364
*cmdline = (struct cmdline){
5465
.show_help = false,
66+
.net_mode = NET_MODE_TSI,
5567
.new_root = NULL,
5668
.guest_argv = NULL,
5769
};
@@ -64,6 +76,16 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
6476
case 'h':
6577
cmdline->show_help = true;
6678
return true;
79+
case 'N':
80+
if (strcasecmp("TSI", optarg) == 0) {
81+
cmdline->net_mode = NET_MODE_TSI;
82+
} else if(strcasecmp("PASST", optarg) == 0) {
83+
cmdline->net_mode = NET_MODE_PASST;
84+
} else {
85+
fprintf(stderr, "Unknown mode %s\n", optarg);
86+
return false;
87+
}
88+
break;
6789
case '?':
6890
return false;
6991
default:
@@ -89,6 +111,27 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
89111
return false;
90112
}
91113

114+
int connect_to_passt()
115+
{
116+
struct sockaddr_un addr;
117+
int socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
118+
if (socket_fd < 0) {
119+
perror("Failed to create passt socket fd");
120+
return -1;
121+
}
122+
123+
memset(&addr, 0, sizeof(addr));
124+
addr.sun_family = AF_UNIX;
125+
strncpy(addr.sun_path, "/tmp/passt_1.socket", sizeof(addr.sun_path) - 1);
126+
127+
if (connect(socket_fd, (const struct sockaddr *) &addr, sizeof(addr)) < 0) {
128+
perror("Failed to bind passt socket");
129+
return -1;
130+
}
131+
132+
return socket_fd;
133+
}
134+
92135

93136
int main(int argc, char *const argv[])
94137
{
@@ -182,11 +225,24 @@ int main(int argc, char *const argv[])
182225
return -1;
183226
}
184227

185-
// Map port 18000 in the host to 8000 in the guest.
186-
if (err = krun_set_port_map(ctx_id, &port_map[0])) {
187-
errno = -err;
188-
perror("Error configuring port map");
189-
return -1;
228+
// Map port 18000 in the host to 8000 in the guest (if networking uses TSI)
229+
if (cmdline.net_mode == NET_MODE_TSI) {
230+
if (err = krun_set_port_map(ctx_id, &port_map[0])) {
231+
errno = -err;
232+
perror("Error configuring port map");
233+
return -1;
234+
}
235+
} else {
236+
int passt_fd = connect_to_passt();
237+
if (passt_fd < 0) {
238+
return -1;
239+
}
240+
241+
if (err = krun_set_passt_fd(ctx_id, passt_fd)) {
242+
errno = -err;
243+
perror("Error configuring net mode");
244+
return -1;
245+
}
190246
}
191247

192248
// Configure the rlimits that will be set in the guest

include/libkrun.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,23 @@ int32_t krun_set_data_disk(uint32_t ctx_id, const char *disk_path);
103103
*/
104104
int32_t krun_set_mapped_volumes(uint32_t ctx_id, char *const mapped_volumes[]);
105105

106+
/*
107+
* Configures the networking to use passt.
108+
* Call to this function disables TSI backend to use passt instead.
109+
*
110+
* Arguments:
111+
* "ctx_id" - the configuration context ID.
112+
* "fd" - a file descriptor to communicate with passt
113+
*
114+
* Notes:
115+
* If you never call this function, networking uses the TSI backend.
116+
* This function should be called before krun_set_port_map.
117+
*
118+
* Returns:
119+
* Zero on success or a negative error number on failure.
120+
*/
121+
int32_t krun_set_passt_fd(uint32_t ctx_id, int fd);
122+
106123
/*
107124
* Configures a map of host to guest TCP ports for the microVM.
108125
*
@@ -112,6 +129,8 @@ int32_t krun_set_mapped_volumes(uint32_t ctx_id, char *const mapped_volumes[]);
112129
*
113130
* Returns:
114131
* Zero on success or a negative error number on failure.
132+
* Documented errors:
133+
* -ENOTSUP when passt networking is used
115134
*
116135
* Notes:
117136
* Passing NULL (or not calling this function) as "port_map" has a different meaning than
@@ -123,6 +142,8 @@ int32_t krun_set_mapped_volumes(uint32_t ctx_id, char *const mapped_volumes[]);
123142
* means that for a map such as "8080:80", applications running inside the guest will also
124143
* need to access the service through the "8080" port.
125144
*
145+
* If past networking mode is used (krun_set_passt_fd was called), port mapping is not supported
146+
* as an API of libkrun (but you can still do port mapping using command line arguments of passt)
126147
*/
127148
int32_t krun_set_port_map(uint32_t ctx_id, char *const port_map[]);
128149

src/libkrun/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::sync::Mutex;
1919
#[cfg(feature = "tee")]
2020
use devices::virtio::CacheType;
2121
use env_logger::Env;
22-
use libc::{c_char, size_t};
22+
use libc::{c_char, c_int, size_t};
2323
use once_cell::sync::Lazy;
2424
use polly::event_manager::EventManager;
2525
use vmm::resources::VmResources;
@@ -458,6 +458,12 @@ pub unsafe extern "C" fn krun_set_data_disk(ctx_id: u32, c_disk_path: *const c_c
458458
KRUN_SUCCESS
459459
}
460460

461+
#[allow(clippy::missing_safety_doc)]
462+
#[no_mangle]
463+
pub unsafe extern "C" fn krun_set_passt_fd(ctx_id: u32, fd: c_int) -> i32 {
464+
todo!("krun_set_passt_fd({},{})", ctx_id, fd);
465+
}
466+
461467
#[allow(clippy::missing_safety_doc)]
462468
#[no_mangle]
463469
pub unsafe extern "C" fn krun_set_port_map(ctx_id: u32, c_port_map: *const *const c_char) -> i32 {

0 commit comments

Comments
 (0)